Path: blob/master/src/hotspot/share/utilities/exceptions.hpp
40949 views
/*1* Copyright (c) 1998, 2021, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*22*/2324#ifndef SHARE_UTILITIES_EXCEPTIONS_HPP25#define SHARE_UTILITIES_EXCEPTIONS_HPP2627#include "memory/allocation.hpp"28#include "oops/oopsHierarchy.hpp"29#include "utilities/ostream.hpp"30#include "utilities/sizes.hpp"3132// This file provides the basic support for exception handling in the VM.33// Note: We do not use C++ exceptions to avoid compiler dependencies and34// unpredictable performance.35//36// Scheme: Exceptions are stored with the thread. There is never more37// than one pending exception per thread. All functions that can throw38// an exception carry a THREAD argument (usually the last argument and39// declared with the TRAPS macro). Throwing an exception means setting40// a pending exception in the thread. Upon return from a function that41// can throw an exception, we must check if an exception is pending.42// The CHECK macros do this in a convenient way. Carrying around the43// thread provides also convenient access to it (e.g. for Handle44// creation, w/o the need for recomputation).45464748// Forward declarations to be independent of the include structure.4950class JavaThread;51class Handle;52class Symbol;53class JavaCallArguments;54class methodHandle;5556// The ThreadShadow class is a helper class to access the _pending_exception57// field of the Thread class w/o having access to the Thread's interface (for58// include hierachy reasons).5960class ThreadShadow: public CHeapObj<mtThread> {61friend class VMStructs;62friend class JVMCIVMStructs;6364protected:65oop _pending_exception; // Thread has gc actions.66const char* _exception_file; // file information for exception (debugging only)67int _exception_line; // line information for exception (debugging only)68friend void check_ThreadShadow(); // checks _pending_exception offset6970// The following virtual exists only to force creation of a vtable.71// We need ThreadShadow to have a vtable, even in product builds,72// so that its layout will start at an offset of zero relative to Thread.73// Some C++ compilers are so "clever" that they put the ThreadShadow74// base class at offset 4 in Thread (after Thread's vtable), if they75// notice that Thread has a vtable but ThreadShadow does not.76virtual void unused_initial_virtual() { }7778public:79oop pending_exception() const { return _pending_exception; }80bool has_pending_exception() const { return _pending_exception != NULL; }81const char* exception_file() const { return _exception_file; }82int exception_line() const { return _exception_line; }8384// Code generation support85static ByteSize pending_exception_offset() { return byte_offset_of(ThreadShadow, _pending_exception); }8687// use THROW whenever possible!88void set_pending_exception(oop exception, const char* file, int line);8990// use CLEAR_PENDING_EXCEPTION whenever possible!91void clear_pending_exception();9293// use CLEAR_PENDING_NONASYNC_EXCEPTION to clear probable nonasync exception.94void clear_pending_nonasync_exception();9596ThreadShadow() : _pending_exception(NULL),97_exception_file(NULL), _exception_line(0) {}98};99100101// Exceptions is a helper class that encapsulates all operations102// that require access to the thread interface and which are103// relatively rare. The Exceptions operations should only be104// used directly if the macros below are insufficient.105106class Exceptions {107static bool special_exception(JavaThread* thread, const char* file, int line, Handle exception);108static bool special_exception(JavaThread* thread, const char* file, int line, Symbol* name, const char* message);109110// Count out of memory errors that are interesting in error diagnosis111static volatile int _out_of_memory_error_java_heap_errors;112static volatile int _out_of_memory_error_metaspace_errors;113static volatile int _out_of_memory_error_class_metaspace_errors;114115// Count linkage errors116static volatile int _linkage_errors;117public:118// this enum is defined to indicate whether it is safe to119// ignore the encoding scheme of the original message string.120typedef enum {121safe_to_utf8 = 0,122unsafe_to_utf8 = 1123} ExceptionMsgToUtf8Mode;124// Throw exceptions: w/o message, w/ message & with formatted message.125static void _throw_oop(JavaThread* thread, const char* file, int line, oop exception);126static void _throw(JavaThread* thread, const char* file, int line, Handle exception, const char* msg = NULL);127128static void _throw_msg(JavaThread* thread, const char* file, int line, Symbol* name, const char* message);129static void _throw_msg(JavaThread* thread, const char* file, int line, Symbol* name, const char* message,130Handle loader, Handle protection_domain);131132static void _throw_msg_cause(JavaThread* thread, const char* file, int line, Symbol* name, const char* message, Handle h_cause);133static void _throw_msg_cause(JavaThread* thread, const char* file, int line, Symbol* name, const char* message, Handle h_cause,134Handle h_loader, Handle h_protection_domain);135136static void _throw_cause(JavaThread* thread, const char* file, int line, Symbol* name, Handle h_cause);137static void _throw_cause(JavaThread* thread, const char* file, int line, Symbol* name, Handle h_cause,138Handle h_loader, Handle h_protection_domain);139140static void _throw_args(JavaThread* thread, const char* file, int line,141Symbol* name, Symbol* signature,142JavaCallArguments* args);143144// There is no THROW... macro for this method. Caller should remember145// to do a return after calling it.146static void fthrow(JavaThread* thread, const char* file, int line, Symbol* name,147const char* format, ...) ATTRIBUTE_PRINTF(5, 6);148149// Create and initialize a new exception150static Handle new_exception(JavaThread* thread, Symbol* name,151Symbol* signature, JavaCallArguments* args,152Handle loader, Handle protection_domain);153154static Handle new_exception(JavaThread* thread, Symbol* name,155Symbol* signature, JavaCallArguments* args,156Handle cause,157Handle loader, Handle protection_domain);158159static Handle new_exception(JavaThread* thread, Symbol* name,160Handle cause,161Handle loader, Handle protection_domain,162ExceptionMsgToUtf8Mode to_utf8_safe = safe_to_utf8);163164static Handle new_exception(JavaThread* thread, Symbol* name,165const char* message, Handle cause,166Handle loader, Handle protection_domain,167ExceptionMsgToUtf8Mode to_utf8_safe = safe_to_utf8);168169static Handle new_exception(JavaThread* thread, Symbol* name,170const char* message,171ExceptionMsgToUtf8Mode to_utf8_safe = safe_to_utf8);172173static void throw_stack_overflow_exception(JavaThread* thread, const char* file, int line, const methodHandle& method);174175static void throw_unsafe_access_internal_error(JavaThread* thread, const char* file, int line, const char* message);176177static void wrap_dynamic_exception(bool is_indy, JavaThread* thread);178179// Exception counting for error files of interesting exceptions that may have180// caused a problem for the jvm181static volatile int _stack_overflow_errors;182183static bool has_exception_counts();184static void count_out_of_memory_exceptions(Handle exception);185static void print_exception_counts_on_error(outputStream* st);186187// for AbortVMOnException flag188static void debug_check_abort(Handle exception, const char* message = NULL);189static void debug_check_abort_helper(Handle exception, const char* message = NULL);190static void debug_check_abort(const char *value_string, const char* message = NULL);191192// for logging exceptions193static void log_exception(Handle exception, const char* message);194};195196197// The THREAD & TRAPS macros facilitate the declaration of functions that throw exceptions.198// Convention: Use the TRAPS macro as the last argument of such a function; e.g.:199//200// int this_function_may_trap(int x, float y, TRAPS)201202#define THREAD __the_thread__203#define TRAPS JavaThread* THREAD204205206// The CHECK... macros should be used to pass along a THREAD reference and to check for pending207// exceptions. In special situations it is necessary to handle pending exceptions explicitly,208// in these cases the PENDING_EXCEPTION helper macros should be used.209//210// Macro naming conventions: Macros that end with _ require a result value to be returned. They211// are for functions with non-void result type. The result value is usually ignored because of212// the exception and is only needed for syntactic correctness. The _0 ending is a shortcut for213// _(0) since this is a frequent case. Example:214//215// int result = this_function_may_trap(x_arg, y_arg, CHECK_0);216//217// CAUTION: make sure that the function call using a CHECK macro is not the only statement of a218// conditional branch w/o enclosing {} braces, since the CHECK macros expand into several state-219// ments! Also make sure it is not used on a function call that is part of a return statement!220221#define PENDING_EXCEPTION (((ThreadShadow*)THREAD)->pending_exception())222#define HAS_PENDING_EXCEPTION (((ThreadShadow*)THREAD)->has_pending_exception())223#define CLEAR_PENDING_EXCEPTION (((ThreadShadow*)THREAD)->clear_pending_exception())224225#define CHECK THREAD); if (HAS_PENDING_EXCEPTION) return ; (void)(0226#define CHECK_(result) THREAD); if (HAS_PENDING_EXCEPTION) return result; (void)(0227#define CHECK_0 CHECK_(0)228#define CHECK_NH CHECK_(Handle())229#define CHECK_NULL CHECK_(NULL)230#define CHECK_false CHECK_(false)231#define CHECK_JNI_ERR CHECK_(JNI_ERR)232233// CAUTION: These macros clears all exceptions including async exceptions, use it with caution.234#define CHECK_AND_CLEAR THREAD); if (HAS_PENDING_EXCEPTION) { CLEAR_PENDING_EXCEPTION; return; } (void)(0235#define CHECK_AND_CLEAR_(result) THREAD); if (HAS_PENDING_EXCEPTION) { CLEAR_PENDING_EXCEPTION; return result; } (void)(0236#define CHECK_AND_CLEAR_0 CHECK_AND_CLEAR_(0)237#define CHECK_AND_CLEAR_NH CHECK_AND_CLEAR_(Handle())238#define CHECK_AND_CLEAR_NULL CHECK_AND_CLEAR_(NULL)239#define CHECK_AND_CLEAR_false CHECK_AND_CLEAR_(false)240241// CAUTION: These macros clears all exceptions except probable async exceptions j.l.InternalError and j.l.ThreadDeath.242// So use it with caution.243#define CLEAR_PENDING_NONASYNC_EXCEPTION (((ThreadShadow*)THREAD)->clear_pending_nonasync_exception())244#define CHECK_AND_CLEAR_NONASYNC THREAD); if (HAS_PENDING_EXCEPTION) { CLEAR_PENDING_NONASYNC_EXCEPTION; return; } (void)(0245#define CHECK_AND_CLEAR_NONASYNC_(result) THREAD); if (HAS_PENDING_EXCEPTION) { CLEAR_PENDING_NONASYNC_EXCEPTION; return result; } (void)(0246#define CHECK_AND_CLEAR_NONASYNC_0 CHECK_AND_CLEAR_NONASYNC_(0)247#define CHECK_AND_CLEAR_NONASYNC_NH CHECK_AND_CLEAR_NONASYNC_(Handle())248#define CHECK_AND_CLEAR_NONASYNC_NULL CHECK_AND_CLEAR_NONASYNC_(NULL)249#define CHECK_AND_CLEAR_NONASYNC_false CHECK_AND_CLEAR_NONASYNC_(false)250251// The THROW... macros should be used to throw an exception. They require a THREAD variable to be252// visible within the scope containing the THROW. Usually this is achieved by declaring the function253// with a TRAPS argument.254255#define THREAD_AND_LOCATION THREAD, __FILE__, __LINE__256257#define THROW_OOP(e) \258{ Exceptions::_throw_oop(THREAD_AND_LOCATION, e); return; }259260#define THROW_HANDLE(e) \261{ Exceptions::_throw(THREAD_AND_LOCATION, e); return; }262263#define THROW(name) \264{ Exceptions::_throw_msg(THREAD_AND_LOCATION, name, NULL); return; }265266#define THROW_MSG(name, message) \267{ Exceptions::_throw_msg(THREAD_AND_LOCATION, name, message); return; }268269#define THROW_CAUSE(name, cause) \270{ Exceptions::_throw_cause(THREAD_AND_LOCATION, name, cause); return; }271272#define THROW_MSG_LOADER(name, message, loader, protection_domain) \273{ Exceptions::_throw_msg(THREAD_AND_LOCATION, name, message, loader, protection_domain); return; }274275#define THROW_ARG(name, signature, args) \276{ Exceptions::_throw_args(THREAD_AND_LOCATION, name, signature, args); return; }277278#define THROW_OOP_(e, result) \279{ Exceptions::_throw_oop(THREAD_AND_LOCATION, e); return result; }280281#define THROW_HANDLE_(e, result) \282{ Exceptions::_throw(THREAD_AND_LOCATION, e); return result; }283284#define THROW_(name, result) \285{ Exceptions::_throw_msg(THREAD_AND_LOCATION, name, NULL); return result; }286287#define THROW_MSG_(name, message, result) \288{ Exceptions::_throw_msg(THREAD_AND_LOCATION, name, message); return result; }289290#define THROW_MSG_LOADER_(name, message, loader, protection_domain, result) \291{ Exceptions::_throw_msg(THREAD_AND_LOCATION, name, message, loader, protection_domain); return result; }292293#define THROW_ARG_(name, signature, args, result) \294{ Exceptions::_throw_args(THREAD_AND_LOCATION, name, signature, args); return result; }295296#define THROW_MSG_CAUSE(name, message, cause) \297{ Exceptions::_throw_msg_cause(THREAD_AND_LOCATION, name, message, cause); return; }298299#define THROW_MSG_CAUSE_(name, message, cause, result) \300{ Exceptions::_throw_msg_cause(THREAD_AND_LOCATION, name, message, cause); return result; }301302303#define THROW_OOP_0(e) THROW_OOP_(e, 0)304#define THROW_HANDLE_0(e) THROW_HANDLE_(e, 0)305#define THROW_0(name) THROW_(name, 0)306#define THROW_MSG_0(name, message) THROW_MSG_(name, message, 0)307#define THROW_WRAPPED_0(name, oop_to_wrap) THROW_WRAPPED_(name, oop_to_wrap, 0)308#define THROW_ARG_0(name, signature, arg) THROW_ARG_(name, signature, arg, 0)309#define THROW_MSG_CAUSE_0(name, message, cause) THROW_MSG_CAUSE_(name, message, cause, 0)310#define THROW_MSG_CAUSE_NULL(name, message, cause) THROW_MSG_CAUSE_(name, message, cause, NULL)311312#define THROW_NULL(name) THROW_(name, NULL)313#define THROW_MSG_NULL(name, message) THROW_MSG_(name, message, NULL)314315// The CATCH macro checks that no exception has been thrown by a function; it is used at316// call sites about which is statically known that the callee cannot throw an exception317// even though it is declared with TRAPS.318319#define CATCH \320THREAD); if (HAS_PENDING_EXCEPTION) { \321oop ex = PENDING_EXCEPTION; \322CLEAR_PENDING_EXCEPTION; \323DEBUG_ONLY(ex->print();) \324assert(false, "CATCH"); \325} (void)(0326327// ExceptionMark is a stack-allocated helper class for local exception handling.328// It is used with the EXCEPTION_MARK macro.329330class ExceptionMark {331private:332JavaThread* _thread;333inline void check_no_pending_exception();334335public:336ExceptionMark();337ExceptionMark(JavaThread* thread);338~ExceptionMark();339340JavaThread* thread() {341return _thread;342}343};344345// Use an EXCEPTION_MARK for 'local' exceptions. EXCEPTION_MARK makes sure that no346// pending exception exists upon entering its scope and tests that no pending exception347// exists when leaving the scope.348349// See also preserveException.hpp for PreserveExceptionMark350// which preserves pre-existing exceptions and does not allow new351// exceptions.352353#define EXCEPTION_MARK ExceptionMark __em; JavaThread* THREAD = __em.thread();354355#endif // SHARE_UTILITIES_EXCEPTIONS_HPP356357358