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