src/share/vm/utilities/exceptions.hpp

Thu, 20 Nov 2008 16:56:09 -0800

author
ysr
date
Thu, 20 Nov 2008 16:56:09 -0800
changeset 888
c96030fff130
parent 435
a61af66fc99e
child 1145
e5b0439ef4ae
permissions
-rw-r--r--

6684579: SoftReference processing can be made more efficient
Summary: For current soft-ref clearing policies, we can decide at marking time if a soft-reference will definitely not be cleared, postponing the decision of whether it will definitely be cleared to the final reference processing phase. This can be especially beneficial in the case of concurrent collectors where the marking is usually concurrent but reference processing is usually not.
Reviewed-by: jmasa

duke@435 1 /*
duke@435 2 * Copyright 1998-2007 Sun Microsystems, Inc. All Rights Reserved.
duke@435 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
duke@435 4 *
duke@435 5 * This code is free software; you can redistribute it and/or modify it
duke@435 6 * under the terms of the GNU General Public License version 2 only, as
duke@435 7 * published by the Free Software Foundation.
duke@435 8 *
duke@435 9 * This code is distributed in the hope that it will be useful, but WITHOUT
duke@435 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
duke@435 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
duke@435 12 * version 2 for more details (a copy is included in the LICENSE file that
duke@435 13 * accompanied this code).
duke@435 14 *
duke@435 15 * You should have received a copy of the GNU General Public License version
duke@435 16 * 2 along with this work; if not, write to the Free Software Foundation,
duke@435 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
duke@435 18 *
duke@435 19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
duke@435 20 * CA 95054 USA or visit www.sun.com if you need additional information or
duke@435 21 * have any questions.
duke@435 22 *
duke@435 23 */
duke@435 24
duke@435 25 // This file provides the basic support for exception handling in the VM.
duke@435 26 // Note: We do not use C++ exceptions to avoid compiler dependencies and
duke@435 27 // unpredictable performance.
duke@435 28 //
duke@435 29 // Scheme: Exceptions are stored with the thread. There is never more
duke@435 30 // than one pending exception per thread. All functions that can throw
duke@435 31 // an exception carry a THREAD argument (usually the last argument and
duke@435 32 // declared with the TRAPS macro). Throwing an exception means setting
duke@435 33 // a pending exception in the thread. Upon return from a function that
duke@435 34 // can throw an exception, we must check if an exception is pending.
duke@435 35 // The CHECK macros do this in a convenient way. Carrying around the
duke@435 36 // thread provides also convenient access to it (e.g. for Handle
duke@435 37 // creation, w/o the need for recomputation).
duke@435 38
duke@435 39
duke@435 40
duke@435 41 // Forward declarations to be independent of the include structure.
duke@435 42 // This allows us to have exceptions.hpp included in top.hpp.
duke@435 43
duke@435 44 class Thread;
duke@435 45 class Handle;
duke@435 46 class symbolHandle;
duke@435 47 class symbolOopDesc;
duke@435 48 class JavaCallArguments;
duke@435 49
duke@435 50 // The ThreadShadow class is a helper class to access the _pending_exception
duke@435 51 // field of the Thread class w/o having access to the Thread's interface (for
duke@435 52 // include hierachy reasons).
duke@435 53
duke@435 54 class ThreadShadow: public CHeapObj {
duke@435 55 protected:
duke@435 56 oop _pending_exception; // Thread has gc actions.
duke@435 57 const char* _exception_file; // file information for exception (debugging only)
duke@435 58 int _exception_line; // line information for exception (debugging only)
duke@435 59 friend void check_ThreadShadow(); // checks _pending_exception offset
duke@435 60
duke@435 61 // The following virtual exists only to force creation of a vtable.
duke@435 62 // We need ThreadShadow to have a vtable, even in product builds,
duke@435 63 // so that its layout will start at an offset of zero relative to Thread.
duke@435 64 // Some C++ compilers are so "clever" that they put the ThreadShadow
duke@435 65 // base class at offset 4 in Thread (after Thread's vtable), if they
duke@435 66 // notice that Thread has a vtable but ThreadShadow does not.
duke@435 67 virtual void unused_initial_virtual() { }
duke@435 68
duke@435 69 public:
duke@435 70 oop pending_exception() const { return _pending_exception; }
duke@435 71 bool has_pending_exception() const { return _pending_exception != NULL; }
duke@435 72 const char* exception_file() const { return _exception_file; }
duke@435 73 int exception_line() const { return _exception_line; }
duke@435 74
duke@435 75 // Code generation support
duke@435 76 static ByteSize pending_exception_offset() { return byte_offset_of(ThreadShadow, _pending_exception); }
duke@435 77
duke@435 78 // use THROW whenever possible!
duke@435 79 void set_pending_exception(oop exception, const char* file, int line);
duke@435 80
duke@435 81 // use CLEAR_PENDING_EXCEPTION whenever possible!
duke@435 82 void clear_pending_exception();
duke@435 83
duke@435 84 ThreadShadow() : _pending_exception(NULL),
duke@435 85 _exception_file(NULL), _exception_line(0) {}
duke@435 86 };
duke@435 87
duke@435 88
duke@435 89 // Exceptions is a helper class that encapsulates all operations
duke@435 90 // that require access to the thread interface and which are
duke@435 91 // relatively rare. The Exceptions operations should only be
duke@435 92 // used directly if the macros below are insufficient.
duke@435 93
duke@435 94 class Exceptions {
duke@435 95 static bool special_exception(Thread *thread, const char* file, int line, Handle exception);
duke@435 96 static bool special_exception(Thread* thread, const char* file, int line, symbolHandle name, const char* message);
duke@435 97 public:
duke@435 98 // this enum is defined to indicate whether it is safe to
duke@435 99 // ignore the encoding scheme of the original message string.
duke@435 100 typedef enum {
duke@435 101 safe_to_utf8 = 0,
duke@435 102 unsafe_to_utf8 = 1
duke@435 103 } ExceptionMsgToUtf8Mode;
duke@435 104 // Throw exceptions: w/o message, w/ message & with formatted message.
duke@435 105 static void _throw_oop(Thread* thread, const char* file, int line, oop exception);
duke@435 106 static void _throw(Thread* thread, const char* file, int line, Handle exception);
duke@435 107 static void _throw_msg(Thread* thread, const char* file, int line,
duke@435 108 symbolHandle name, const char* message, Handle loader,
duke@435 109 Handle protection_domain);
duke@435 110 static void _throw_msg(Thread* thread, const char* file, int line,
duke@435 111 symbolOop name, const char* message);
duke@435 112 static void _throw_msg(Thread* thread, const char* file, int line,
duke@435 113 symbolHandle name, const char* message);
duke@435 114 static void _throw_args(Thread* thread, const char* file, int line,
duke@435 115 symbolHandle name, symbolHandle signature,
duke@435 116 JavaCallArguments* args);
duke@435 117 static void _throw_msg_cause(Thread* thread, const char* file,
duke@435 118 int line, symbolHandle h_name, const char* message,
duke@435 119 Handle h_cause, Handle h_loader, Handle h_protection_domain);
duke@435 120 static void _throw_msg_cause(Thread* thread, const char* file, int line,
duke@435 121 symbolHandle name, const char* message, Handle cause);
duke@435 122
duke@435 123 // There is no THROW... macro for this method. Caller should remember
duke@435 124 // to do a return after calling it.
duke@435 125 static void fthrow(Thread* thread, const char* file, int line, symbolHandle name,
duke@435 126 const char* format, ...);
duke@435 127
duke@435 128 // Create and initialize a new exception
duke@435 129 static Handle new_exception(Thread* thread, symbolHandle name,
duke@435 130 symbolHandle signature, JavaCallArguments* args,
duke@435 131 Handle cause, Handle loader,
duke@435 132 Handle protection_domain);
duke@435 133
duke@435 134 static Handle new_exception(Thread* thread, symbolHandle name,
duke@435 135 const char* message, Handle cause, Handle loader,
duke@435 136 Handle protection_domain,
duke@435 137 ExceptionMsgToUtf8Mode to_utf8_safe = safe_to_utf8);
duke@435 138
duke@435 139 static Handle new_exception(Thread* thread, symbolOop name,
duke@435 140 const char* message,
duke@435 141 ExceptionMsgToUtf8Mode to_utf8_safe = safe_to_utf8);
duke@435 142
duke@435 143 static void throw_stack_overflow_exception(Thread* thread, const char* file, int line);
duke@435 144
duke@435 145 // for AbortVMOnException flag
duke@435 146 NOT_PRODUCT(static void debug_check_abort(Handle exception);)
duke@435 147 NOT_PRODUCT(static void debug_check_abort(const char *value_string);)
duke@435 148 };
duke@435 149
duke@435 150
duke@435 151 // The THREAD & TRAPS macros facilitate the declaration of functions that throw exceptions.
duke@435 152 // Convention: Use the TRAPS macro as the last argument of such a function; e.g.:
duke@435 153 //
duke@435 154 // int this_function_may_trap(int x, float y, TRAPS)
duke@435 155
duke@435 156 #define THREAD __the_thread__
duke@435 157 #define TRAPS Thread* THREAD
duke@435 158
duke@435 159
duke@435 160 // The CHECK... macros should be used to pass along a THREAD reference and to check for pending
duke@435 161 // exceptions. In special situations it is necessary to handle pending exceptions explicitly,
duke@435 162 // in these cases the PENDING_EXCEPTION helper macros should be used.
duke@435 163 //
duke@435 164 // Macro naming conventions: Macros that end with _ require a result value to be returned. They
duke@435 165 // are for functions with non-void result type. The result value is usually ignored because of
duke@435 166 // the exception and is only needed for syntactic correctness. The _0 ending is a shortcut for
duke@435 167 // _(0) since this is a frequent case. Example:
duke@435 168 //
duke@435 169 // int result = this_function_may_trap(x_arg, y_arg, CHECK_0);
duke@435 170 //
duke@435 171 // CAUTION: make sure that the function call using a CHECK macro is not the only statement of a
duke@435 172 // conditional branch w/o enclosing {} braces, since the CHECK macros expand into several state-
duke@435 173 // ments!
duke@435 174
duke@435 175 #define PENDING_EXCEPTION (((ThreadShadow*)THREAD)->pending_exception())
duke@435 176 #define HAS_PENDING_EXCEPTION (((ThreadShadow*)THREAD)->has_pending_exception())
duke@435 177 #define CLEAR_PENDING_EXCEPTION (((ThreadShadow*)THREAD)->clear_pending_exception())
duke@435 178
duke@435 179 #define CHECK THREAD); if (HAS_PENDING_EXCEPTION) return ; (0
duke@435 180 #define CHECK_(result) THREAD); if (HAS_PENDING_EXCEPTION) return result; (0
duke@435 181 #define CHECK_0 CHECK_(0)
duke@435 182 #define CHECK_NH CHECK_(Handle())
duke@435 183 #define CHECK_NULL CHECK_(NULL)
duke@435 184 #define CHECK_false CHECK_(false)
duke@435 185
duke@435 186 // The THROW... macros should be used to throw an exception. They require a THREAD variable to be
duke@435 187 // visible within the scope containing the THROW. Usually this is achieved by declaring the function
duke@435 188 // with a TRAPS argument.
duke@435 189
duke@435 190 #define THREAD_AND_LOCATION THREAD, __FILE__, __LINE__
duke@435 191
duke@435 192 #define THROW_OOP(e) \
duke@435 193 { Exceptions::_throw_oop(THREAD_AND_LOCATION, e); return; }
duke@435 194
duke@435 195 #define THROW_HANDLE(e) \
duke@435 196 { Exceptions::_throw(THREAD_AND_LOCATION, e); return; }
duke@435 197
duke@435 198 #define THROW(name) \
duke@435 199 { Exceptions::_throw_msg(THREAD_AND_LOCATION, name, NULL); return; }
duke@435 200
duke@435 201 #define THROW_MSG(name, message) \
duke@435 202 { Exceptions::_throw_msg(THREAD_AND_LOCATION, name, message); return; }
duke@435 203
duke@435 204 #define THROW_MSG_LOADER(name, message, loader, protection_domain) \
duke@435 205 { Exceptions::_throw_msg(THREAD_AND_LOCATION, name, message, loader, protection_domain); return; }
duke@435 206
duke@435 207 #define THROW_ARG(name, signature, args) \
duke@435 208 { Exceptions::_throw_args(THREAD_AND_LOCATION, name, signature, args); return; }
duke@435 209
duke@435 210 #define THROW_OOP_(e, result) \
duke@435 211 { Exceptions::_throw_oop(THREAD_AND_LOCATION, e); return result; }
duke@435 212
duke@435 213 #define THROW_HANDLE_(e, result) \
duke@435 214 { Exceptions::_throw(THREAD_AND_LOCATION, e); return result; }
duke@435 215
duke@435 216 #define THROW_(name, result) \
duke@435 217 { Exceptions::_throw_msg(THREAD_AND_LOCATION, name, NULL); return result; }
duke@435 218
duke@435 219 #define THROW_MSG_(name, message, result) \
duke@435 220 { Exceptions::_throw_msg(THREAD_AND_LOCATION, name, message); return result; }
duke@435 221
duke@435 222 #define THROW_MSG_LOADER_(name, message, loader, protection_domain, result) \
duke@435 223 { Exceptions::_throw_msg(THREAD_AND_LOCATION, name, message, loader, protection_domain); return result; }
duke@435 224
duke@435 225 #define THROW_ARG_(name, signature, args, result) \
duke@435 226 { Exceptions::_throw_args(THREAD_AND_LOCATION, name, signature, args); return result; }
duke@435 227
duke@435 228 #define THROW_MSG_CAUSE_(name, message, cause, result) \
duke@435 229 { Exceptions::_throw_msg_cause(THREAD_AND_LOCATION, name, message, cause); return result; }
duke@435 230
duke@435 231
duke@435 232 #define THROW_OOP_0(e) THROW_OOP_(e, 0)
duke@435 233 #define THROW_HANDLE_0(e) THROW_HANDLE_(e, 0)
duke@435 234 #define THROW_0(name) THROW_(name, 0)
duke@435 235 #define THROW_MSG_0(name, message) THROW_MSG_(name, message, 0)
duke@435 236 #define THROW_WRAPPED_0(name, oop_to_wrap) THROW_WRAPPED_(name, oop_to_wrap, 0)
duke@435 237 #define THROW_ARG_0(name, signature, arg) THROW_ARG_(name, signature, arg, 0)
duke@435 238 #define THROW_MSG_CAUSE_0(name, message, cause) THROW_MSG_CAUSE_(name, message, cause, 0)
duke@435 239
duke@435 240 // The CATCH macro checks that no exception has been thrown by a function; it is used at
duke@435 241 // call sites about which is statically known that the callee cannot throw an exception
duke@435 242 // even though it is declared with TRAPS.
duke@435 243
duke@435 244 #define CATCH \
duke@435 245 THREAD); if (HAS_PENDING_EXCEPTION) { \
duke@435 246 oop ex = PENDING_EXCEPTION; \
duke@435 247 CLEAR_PENDING_EXCEPTION; \
duke@435 248 ex->print(); \
duke@435 249 ShouldNotReachHere(); \
duke@435 250 } (0
duke@435 251
duke@435 252
duke@435 253 // ExceptionMark is a stack-allocated helper class for local exception handling.
duke@435 254 // It is used with the EXCEPTION_MARK macro.
duke@435 255
duke@435 256 class ExceptionMark {
duke@435 257 private:
duke@435 258 Thread* _thread;
duke@435 259
duke@435 260 public:
duke@435 261 ExceptionMark(Thread*& thread);
duke@435 262 ~ExceptionMark();
duke@435 263 };
duke@435 264
duke@435 265
duke@435 266
duke@435 267 // Use an EXCEPTION_MARK for 'local' exceptions. EXCEPTION_MARK makes sure that no
duke@435 268 // pending exception exists upon entering its scope and tests that no pending exception
duke@435 269 // exists when leaving the scope.
duke@435 270
duke@435 271 // See also preserveException.hpp for PRESERVE_EXCEPTION_MARK macro,
duke@435 272 // which preserves pre-existing exceptions and does not allow new
duke@435 273 // exceptions.
duke@435 274
duke@435 275 #define EXCEPTION_MARK Thread* THREAD; ExceptionMark __em(THREAD);

mercurial