Mercurial > hg > truffle
annotate src/share/vm/utilities/exceptions.cpp @ 1721:413ad0331a0c
6977924: Changes for 6975078 produce build error with certain gcc versions
Summary: The changes introduced for 6975078 assign badHeapOopVal to the _allocation field in the ResourceObj class. In 32 bit linux builds with certain versions of gcc this assignment will be flagged as an error while compiling allocation.cpp. In 32 bit builds the constant value badHeapOopVal (which is cast to an intptr_t) is negative. The _allocation field is typed as an unsigned intptr_t and gcc catches this as an error.
Reviewed-by: jcoomes, ysr, phh
author | johnc |
---|---|
date | Wed, 18 Aug 2010 10:59:06 -0700 |
parents | 66c5dadb4d61 |
children | b6aedd1acdc0 |
rev | line source |
---|---|
0 | 1 /* |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1490
diff
changeset
|
2 * Copyright (c) 1998, 2007, Oracle and/or its affiliates. All rights reserved. |
0 | 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 * | |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1490
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1490
diff
changeset
|
20 * or visit www.oracle.com if you need additional information or have any |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1490
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
25 #include "incls/_precompiled.incl" | |
26 #include "incls/_exceptions.cpp.incl" | |
27 | |
28 | |
29 // Implementation of ThreadShadow | |
30 void check_ThreadShadow() { | |
31 const ByteSize offset1 = byte_offset_of(ThreadShadow, _pending_exception); | |
32 const ByteSize offset2 = Thread::pending_exception_offset(); | |
33 if (offset1 != offset2) fatal("ThreadShadow::_pending_exception is not positioned correctly"); | |
34 } | |
35 | |
36 | |
37 void ThreadShadow::set_pending_exception(oop exception, const char* file, int line) { | |
38 assert(exception != NULL && exception->is_oop(), "invalid exception oop"); | |
39 _pending_exception = exception; | |
40 _exception_file = file; | |
41 _exception_line = line; | |
42 } | |
43 | |
44 void ThreadShadow::clear_pending_exception() { | |
45 if (TraceClearedExceptions) { | |
46 if (_pending_exception != NULL) { | |
47 tty->print_cr("Thread::clear_pending_exception: cleared exception:"); | |
48 _pending_exception->print(); | |
49 } | |
50 } | |
51 _pending_exception = NULL; | |
52 _exception_file = NULL; | |
53 _exception_line = 0; | |
54 } | |
55 // Implementation of Exceptions | |
56 | |
57 bool Exceptions::special_exception(Thread* thread, const char* file, int line, Handle h_exception) { | |
58 // bootstrapping check | |
59 if (!Universe::is_fully_initialized()) { | |
60 vm_exit_during_initialization(h_exception); | |
61 ShouldNotReachHere(); | |
62 } | |
63 | |
64 if (thread->is_VM_thread() | |
65 || thread->is_Compiler_thread() ) { | |
66 // We do not care what kind of exception we get for the vm-thread or a thread which | |
67 // is compiling. We just install a dummy exception object | |
68 thread->set_pending_exception(Universe::vm_exception(), file, line); | |
69 return true; | |
70 } | |
71 | |
72 return false; | |
73 } | |
74 | |
75 bool Exceptions::special_exception(Thread* thread, const char* file, int line, symbolHandle h_name, const char* message) { | |
76 // bootstrapping check | |
77 if (!Universe::is_fully_initialized()) { | |
78 if (h_name.is_null()) { | |
79 // atleast an informative message. | |
80 vm_exit_during_initialization("Exception", message); | |
81 } else { | |
82 vm_exit_during_initialization(h_name, message); | |
83 } | |
84 ShouldNotReachHere(); | |
85 } | |
86 | |
87 if (thread->is_VM_thread() | |
88 || thread->is_Compiler_thread() ) { | |
89 // We do not care what kind of exception we get for the vm-thread or a thread which | |
90 // is compiling. We just install a dummy exception object | |
91 thread->set_pending_exception(Universe::vm_exception(), file, line); | |
92 return true; | |
93 } | |
94 | |
95 return false; | |
96 } | |
97 | |
98 // This method should only be called from generated code, | |
99 // therefore the exception oop should be in the oopmap. | |
100 void Exceptions::_throw_oop(Thread* thread, const char* file, int line, oop exception) { | |
101 assert(exception != NULL, "exception should not be NULL"); | |
102 Handle h_exception = Handle(thread, exception); | |
103 _throw(thread, file, line, h_exception); | |
104 } | |
105 | |
1011
fcb148c6b605
6889302: TraceExceptions output should include detail message
never
parents:
0
diff
changeset
|
106 void Exceptions::_throw(Thread* thread, const char* file, int line, Handle h_exception, const char* message) { |
0 | 107 assert(h_exception() != NULL, "exception should not be NULL"); |
108 | |
109 // tracing (do this up front - so it works during boot strapping) | |
110 if (TraceExceptions) { | |
111 ttyLocker ttyl; | |
112 ResourceMark rm; | |
1011
fcb148c6b605
6889302: TraceExceptions output should include detail message
never
parents:
0
diff
changeset
|
113 tty->print_cr("Exception <%s>%s%s (" INTPTR_FORMAT " ) \n" |
fcb148c6b605
6889302: TraceExceptions output should include detail message
never
parents:
0
diff
changeset
|
114 "thrown [%s, line %d]\nfor thread " INTPTR_FORMAT, |
fcb148c6b605
6889302: TraceExceptions output should include detail message
never
parents:
0
diff
changeset
|
115 h_exception->print_value_string(), |
fcb148c6b605
6889302: TraceExceptions output should include detail message
never
parents:
0
diff
changeset
|
116 message ? ": " : "", message ? message : "", |
fcb148c6b605
6889302: TraceExceptions output should include detail message
never
parents:
0
diff
changeset
|
117 (address)h_exception(), file, line, thread); |
0 | 118 } |
119 // for AbortVMOnException flag | |
1684
66c5dadb4d61
6973308: Missing zero length check before repne scas in check_klass_subtype_slow_path()
kvn
parents:
1552
diff
changeset
|
120 NOT_PRODUCT(Exceptions::debug_check_abort(h_exception, message)); |
0 | 121 |
122 // Check for special boot-strapping/vm-thread handling | |
123 if (special_exception(thread, file, line, h_exception)) return; | |
124 | |
1142 | 125 assert(h_exception->is_a(SystemDictionary::Throwable_klass()), "exception is not a subclass of java/lang/Throwable"); |
0 | 126 |
127 // set the pending exception | |
128 thread->set_pending_exception(h_exception(), file, line); | |
129 | |
130 // vm log | |
131 Events::log("throw_exception " INTPTR_FORMAT, (address)h_exception()); | |
132 } | |
133 | |
134 | |
135 void Exceptions::_throw_msg(Thread* thread, const char* file, int line, symbolHandle h_name, const char* message, Handle h_loader, Handle h_protection_domain) { | |
136 // Check for special boot-strapping/vm-thread handling | |
137 if (special_exception(thread, file, line, h_name, message)) return; | |
138 // Create and throw exception | |
139 Handle h_cause(thread, NULL); | |
140 Handle h_exception = new_exception(thread, h_name, message, h_cause, h_loader, h_protection_domain); | |
1011
fcb148c6b605
6889302: TraceExceptions output should include detail message
never
parents:
0
diff
changeset
|
141 _throw(thread, file, line, h_exception, message); |
0 | 142 } |
143 | |
144 // Throw an exception with a message and a cause | |
145 void Exceptions::_throw_msg_cause(Thread* thread, const char* file, int line, symbolHandle h_name, const char* message, Handle h_cause, Handle h_loader, Handle h_protection_domain) { | |
146 // Check for special boot-strapping/vm-thread handling | |
147 if (special_exception(thread, file, line, h_name, message)) return; | |
148 // Create and throw exception and init cause | |
149 Handle h_exception = new_exception(thread, h_name, message, h_cause, h_loader, h_protection_domain); | |
1011
fcb148c6b605
6889302: TraceExceptions output should include detail message
never
parents:
0
diff
changeset
|
150 _throw(thread, file, line, h_exception, message); |
0 | 151 } |
152 | |
153 // This version creates handles and calls the other version | |
154 void Exceptions::_throw_msg(Thread* thread, const char* file, int line, | |
155 symbolOop name, const char* message) { | |
156 symbolHandle h_name(thread, name); | |
157 Handle h_loader(thread, NULL); | |
158 Handle h_protection_domain(thread, NULL); | |
159 Exceptions::_throw_msg(thread, file, line, h_name, message, h_loader, h_protection_domain); | |
160 } | |
161 | |
162 // This version already has a handle for name | |
163 void Exceptions::_throw_msg(Thread* thread, const char* file, int line, | |
164 symbolHandle name, const char* message) { | |
165 Handle h_loader(thread, NULL); | |
166 Handle h_protection_domain(thread, NULL); | |
167 Exceptions::_throw_msg(thread, file, line, name, message, h_loader, h_protection_domain); | |
168 } | |
169 | |
170 // This version already has a handle for name | |
171 void Exceptions::_throw_msg_cause(Thread* thread, const char* file, int line, | |
172 symbolHandle name, const char* message, Handle cause) { | |
173 Handle h_loader(thread, NULL); | |
174 Handle h_protection_domain(thread, NULL); | |
175 Exceptions::_throw_msg_cause(thread, file, line, name, message, cause, h_loader, h_protection_domain); | |
176 } | |
177 | |
178 void Exceptions::_throw_args(Thread* thread, const char* file, int line, symbolHandle h_name, symbolHandle h_signature, JavaCallArguments *args) { | |
179 // Check for special boot-strapping/vm-thread handling | |
180 if (special_exception(thread, file, line, h_name, NULL)) return; | |
181 // Create and throw exception | |
182 Handle h_loader(thread, NULL); | |
183 Handle h_prot(thread, NULL); | |
184 Handle h_cause(thread, NULL); | |
185 Handle exception = new_exception(thread, h_name, h_signature, args, h_cause, h_loader, h_prot); | |
186 _throw(thread, file, line, exception); | |
187 } | |
188 | |
189 | |
190 void Exceptions::throw_stack_overflow_exception(Thread* THREAD, const char* file, int line) { | |
191 Handle exception; | |
192 if (!THREAD->has_pending_exception()) { | |
193 klassOop k = SystemDictionary::StackOverflowError_klass(); | |
194 oop e = instanceKlass::cast(k)->allocate_instance(CHECK); | |
195 exception = Handle(THREAD, e); // fill_in_stack trace does gc | |
196 if (StackTraceInThrowable) { | |
197 java_lang_Throwable::fill_in_stack_trace(exception); | |
198 } | |
199 } else { | |
200 // if prior exception, throw that one instead | |
201 exception = Handle(THREAD, THREAD->pending_exception()); | |
202 } | |
203 _throw_oop(THREAD, file, line, exception()); | |
204 } | |
205 | |
206 void Exceptions::fthrow(Thread* thread, const char* file, int line, symbolHandle h_name, const char* format, ...) { | |
207 const int max_msg_size = 1024; | |
208 va_list ap; | |
209 va_start(ap, format); | |
210 char msg[max_msg_size]; | |
211 vsnprintf(msg, max_msg_size, format, ap); | |
212 msg[max_msg_size-1] = '\0'; | |
213 va_end(ap); | |
214 _throw_msg(thread, file, line, h_name, msg); | |
215 } | |
216 | |
217 // Creates an exception oop, calls the <init> method with the given signature. | |
218 // and returns a Handle | |
219 // Initializes the cause if cause non-null | |
220 Handle Exceptions::new_exception(Thread *thread, symbolHandle h_name, | |
221 symbolHandle signature, | |
222 JavaCallArguments *args, | |
223 Handle h_cause, Handle h_loader, | |
224 Handle h_protection_domain) { | |
225 assert(Universe::is_fully_initialized(), | |
226 "cannot be called during initialization"); | |
227 assert(thread->is_Java_thread(), "can only be called by a Java thread"); | |
228 assert(!thread->has_pending_exception(), "already has exception"); | |
229 | |
230 Handle h_exception; | |
231 | |
232 // Resolve exception klass | |
233 klassOop ik = SystemDictionary::resolve_or_fail(h_name, h_loader, h_protection_domain, true, thread); | |
234 instanceKlassHandle klass (thread, ik); | |
235 | |
236 if (!thread->has_pending_exception()) { | |
237 assert(klass.not_null(), "klass must exist"); | |
238 // We are about to create an instance - so make sure that klass is initialized | |
239 klass->initialize(thread); | |
240 if (!thread->has_pending_exception()) { | |
241 // Allocate new exception | |
242 h_exception = klass->allocate_instance_handle(thread); | |
243 if (!thread->has_pending_exception()) { | |
244 JavaValue result(T_VOID); | |
245 args->set_receiver(h_exception); | |
246 // Call constructor | |
247 JavaCalls::call_special(&result, klass, | |
248 vmSymbolHandles::object_initializer_name(), | |
249 signature, | |
250 args, | |
251 thread); | |
252 | |
253 } | |
254 } | |
255 | |
256 // Future: object initializer should take a cause argument | |
257 if (h_cause() != NULL) { | |
1142 | 258 assert(h_cause->is_a(SystemDictionary::Throwable_klass()), |
0 | 259 "exception cause is not a subclass of java/lang/Throwable"); |
260 JavaValue result1(T_OBJECT); | |
261 JavaCallArguments args1; | |
262 args1.set_receiver(h_exception); | |
263 args1.push_oop(h_cause); | |
264 JavaCalls::call_virtual(&result1, klass, | |
265 vmSymbolHandles::initCause_name(), | |
266 vmSymbolHandles::throwable_throwable_signature(), | |
267 &args1, | |
268 thread); | |
269 } | |
270 } | |
271 | |
272 // Check if another exception was thrown in the process, if so rethrow that one | |
273 if (thread->has_pending_exception()) { | |
274 h_exception = Handle(thread, thread->pending_exception()); | |
275 thread->clear_pending_exception(); | |
276 } | |
277 return h_exception; | |
278 } | |
279 | |
280 // Convenience method. Calls either the <init>() or <init>(String) method when | |
281 // creating a new exception | |
282 Handle Exceptions::new_exception(Thread* thread, symbolHandle h_name, | |
283 const char* message, Handle h_cause, | |
284 Handle h_loader, | |
285 Handle h_protection_domain, | |
286 ExceptionMsgToUtf8Mode to_utf8_safe) { | |
287 JavaCallArguments args; | |
288 symbolHandle signature; | |
289 if (message == NULL) { | |
290 signature = vmSymbolHandles::void_method_signature(); | |
291 } else { | |
292 // We want to allocate storage, but we can't do that if there's | |
293 // a pending exception, so we preserve any pending exception | |
294 // around the allocation. | |
295 // If we get an exception from the allocation, prefer that to | |
296 // the exception we are trying to build, or the pending exception. | |
297 // This is sort of like what PRESERVE_EXCEPTION_MARK does, except | |
298 // for the preferencing and the early returns. | |
299 Handle incoming_exception (thread, NULL); | |
300 if (thread->has_pending_exception()) { | |
301 incoming_exception = Handle(thread, thread->pending_exception()); | |
302 thread->clear_pending_exception(); | |
303 } | |
304 Handle msg; | |
305 if (to_utf8_safe == safe_to_utf8) { | |
306 // Make a java UTF8 string. | |
307 msg = java_lang_String::create_from_str(message, thread); | |
308 } else { | |
309 // Make a java string keeping the encoding scheme of the original string. | |
310 msg = java_lang_String::create_from_platform_dependent_str(message, thread); | |
311 } | |
312 if (thread->has_pending_exception()) { | |
313 Handle exception(thread, thread->pending_exception()); | |
314 thread->clear_pending_exception(); | |
315 return exception; | |
316 } | |
317 if (incoming_exception.not_null()) { | |
318 return incoming_exception; | |
319 } | |
320 args.push_oop(msg); | |
321 signature = vmSymbolHandles::string_void_signature(); | |
322 } | |
323 return new_exception(thread, h_name, signature, &args, h_cause, h_loader, h_protection_domain); | |
324 } | |
325 | |
326 // Another convenience method that creates handles for null class loaders and | |
327 // protection domains and null causes. | |
328 // If the last parameter 'to_utf8_mode' is safe_to_utf8, | |
329 // it means we can safely ignore the encoding scheme of the message string and | |
330 // convert it directly to a java UTF8 string. Otherwise, we need to take the | |
331 // encoding scheme of the string into account. One thing we should do at some | |
332 // point is to push this flag down to class java_lang_String since other | |
333 // classes may need similar functionalities. | |
334 Handle Exceptions::new_exception(Thread* thread, | |
335 symbolOop name, | |
336 const char* message, | |
337 ExceptionMsgToUtf8Mode to_utf8_safe) { | |
338 | |
339 symbolHandle h_name(thread, name); | |
340 Handle h_loader(thread, NULL); | |
341 Handle h_prot(thread, NULL); | |
342 Handle h_cause(thread, NULL); | |
343 return Exceptions::new_exception(thread, h_name, message, h_cause, h_loader, | |
344 h_prot, to_utf8_safe); | |
345 } | |
346 | |
347 // Implementation of ExceptionMark | |
348 | |
349 ExceptionMark::ExceptionMark(Thread*& thread) { | |
350 thread = Thread::current(); | |
351 _thread = thread; | |
352 if (_thread->has_pending_exception()) { | |
353 oop exception = _thread->pending_exception(); | |
354 _thread->clear_pending_exception(); // Needed to avoid infinite recursion | |
355 exception->print(); | |
356 fatal("ExceptionMark constructor expects no pending exceptions"); | |
357 } | |
358 } | |
359 | |
360 | |
361 ExceptionMark::~ExceptionMark() { | |
362 if (_thread->has_pending_exception()) { | |
363 Handle exception(_thread, _thread->pending_exception()); | |
364 _thread->clear_pending_exception(); // Needed to avoid infinite recursion | |
365 if (is_init_completed()) { | |
366 exception->print(); | |
367 fatal("ExceptionMark destructor expects no pending exceptions"); | |
368 } else { | |
369 vm_exit_during_initialization(exception); | |
370 } | |
371 } | |
372 } | |
373 | |
374 // ---------------------------------------------------------------------------------------- | |
375 | |
376 #ifndef PRODUCT | |
377 // caller frees value_string if necessary | |
1684
66c5dadb4d61
6973308: Missing zero length check before repne scas in check_klass_subtype_slow_path()
kvn
parents:
1552
diff
changeset
|
378 void Exceptions::debug_check_abort(const char *value_string, const char* message) { |
0 | 379 if (AbortVMOnException != NULL && value_string != NULL && |
380 strstr(value_string, AbortVMOnException)) { | |
1684
66c5dadb4d61
6973308: Missing zero length check before repne scas in check_klass_subtype_slow_path()
kvn
parents:
1552
diff
changeset
|
381 if (AbortVMOnExceptionMessage == NULL || message == NULL || |
66c5dadb4d61
6973308: Missing zero length check before repne scas in check_klass_subtype_slow_path()
kvn
parents:
1552
diff
changeset
|
382 strcmp(message, AbortVMOnExceptionMessage) == 0) { |
66c5dadb4d61
6973308: Missing zero length check before repne scas in check_klass_subtype_slow_path()
kvn
parents:
1552
diff
changeset
|
383 fatal(err_msg("Saw %s, aborting", value_string)); |
66c5dadb4d61
6973308: Missing zero length check before repne scas in check_klass_subtype_slow_path()
kvn
parents:
1552
diff
changeset
|
384 } |
0 | 385 } |
386 } | |
387 | |
1684
66c5dadb4d61
6973308: Missing zero length check before repne scas in check_klass_subtype_slow_path()
kvn
parents:
1552
diff
changeset
|
388 void Exceptions::debug_check_abort(Handle exception, const char* message) { |
0 | 389 if (AbortVMOnException != NULL) { |
390 ResourceMark rm; | |
1684
66c5dadb4d61
6973308: Missing zero length check before repne scas in check_klass_subtype_slow_path()
kvn
parents:
1552
diff
changeset
|
391 if (message == NULL && exception->is_a(SystemDictionary::Throwable_klass())) { |
66c5dadb4d61
6973308: Missing zero length check before repne scas in check_klass_subtype_slow_path()
kvn
parents:
1552
diff
changeset
|
392 oop msg = java_lang_Throwable::message(exception); |
66c5dadb4d61
6973308: Missing zero length check before repne scas in check_klass_subtype_slow_path()
kvn
parents:
1552
diff
changeset
|
393 if (msg != NULL) { |
66c5dadb4d61
6973308: Missing zero length check before repne scas in check_klass_subtype_slow_path()
kvn
parents:
1552
diff
changeset
|
394 message = java_lang_String::as_utf8_string(msg); |
66c5dadb4d61
6973308: Missing zero length check before repne scas in check_klass_subtype_slow_path()
kvn
parents:
1552
diff
changeset
|
395 } |
66c5dadb4d61
6973308: Missing zero length check before repne scas in check_klass_subtype_slow_path()
kvn
parents:
1552
diff
changeset
|
396 } |
66c5dadb4d61
6973308: Missing zero length check before repne scas in check_klass_subtype_slow_path()
kvn
parents:
1552
diff
changeset
|
397 debug_check_abort(instanceKlass::cast(exception()->klass())->external_name(), message); |
0 | 398 } |
399 } | |
400 #endif |