annotate src/share/vm/utilities/exceptions.cpp @ 1091:6aa7255741f3

6906727: UseCompressedOops: some card-marking fixes related to object arrays Summary: Introduced a new write_ref_array(HeapWords* start, size_t count) method that does the requisite MemRegion range calculation so (some of the) clients of the erstwhile write_ref_array(MemRegion mr) do not need to worry. This removed all external uses of array_size(), which was also simplified and made private. Asserts were added to catch other possible issues. Further, less essential, fixes stemming from this investigation are deferred to CR 6904516 (to follow shortly in hs17). Reviewed-by: kvn, coleenp, jmasa
author ysr
date Thu, 03 Dec 2009 15:01:57 -0800
parents fcb148c6b605
children 4ce7240d622c
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1 /*
a61af66fc99e Initial load
duke
parents:
diff changeset
2 * Copyright 1998-2007 Sun Microsystems, Inc. All Rights Reserved.
a61af66fc99e Initial load
duke
parents:
diff changeset
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
a61af66fc99e Initial load
duke
parents:
diff changeset
4 *
a61af66fc99e Initial load
duke
parents:
diff changeset
5 * This code is free software; you can redistribute it and/or modify it
a61af66fc99e Initial load
duke
parents:
diff changeset
6 * under the terms of the GNU General Public License version 2 only, as
a61af66fc99e Initial load
duke
parents:
diff changeset
7 * published by the Free Software Foundation.
a61af66fc99e Initial load
duke
parents:
diff changeset
8 *
a61af66fc99e Initial load
duke
parents:
diff changeset
9 * This code is distributed in the hope that it will be useful, but WITHOUT
a61af66fc99e Initial load
duke
parents:
diff changeset
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
a61af66fc99e Initial load
duke
parents:
diff changeset
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
a61af66fc99e Initial load
duke
parents:
diff changeset
12 * version 2 for more details (a copy is included in the LICENSE file that
a61af66fc99e Initial load
duke
parents:
diff changeset
13 * accompanied this code).
a61af66fc99e Initial load
duke
parents:
diff changeset
14 *
a61af66fc99e Initial load
duke
parents:
diff changeset
15 * You should have received a copy of the GNU General Public License version
a61af66fc99e Initial load
duke
parents:
diff changeset
16 * 2 along with this work; if not, write to the Free Software Foundation,
a61af66fc99e Initial load
duke
parents:
diff changeset
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
a61af66fc99e Initial load
duke
parents:
diff changeset
18 *
a61af66fc99e Initial load
duke
parents:
diff changeset
19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
a61af66fc99e Initial load
duke
parents:
diff changeset
20 * CA 95054 USA or visit www.sun.com if you need additional information or
a61af66fc99e Initial load
duke
parents:
diff changeset
21 * have any questions.
a61af66fc99e Initial load
duke
parents:
diff changeset
22 *
a61af66fc99e Initial load
duke
parents:
diff changeset
23 */
a61af66fc99e Initial load
duke
parents:
diff changeset
24
a61af66fc99e Initial load
duke
parents:
diff changeset
25 #include "incls/_precompiled.incl"
a61af66fc99e Initial load
duke
parents:
diff changeset
26 #include "incls/_exceptions.cpp.incl"
a61af66fc99e Initial load
duke
parents:
diff changeset
27
a61af66fc99e Initial load
duke
parents:
diff changeset
28
a61af66fc99e Initial load
duke
parents:
diff changeset
29 // Implementation of ThreadShadow
a61af66fc99e Initial load
duke
parents:
diff changeset
30 void check_ThreadShadow() {
a61af66fc99e Initial load
duke
parents:
diff changeset
31 const ByteSize offset1 = byte_offset_of(ThreadShadow, _pending_exception);
a61af66fc99e Initial load
duke
parents:
diff changeset
32 const ByteSize offset2 = Thread::pending_exception_offset();
a61af66fc99e Initial load
duke
parents:
diff changeset
33 if (offset1 != offset2) fatal("ThreadShadow::_pending_exception is not positioned correctly");
a61af66fc99e Initial load
duke
parents:
diff changeset
34 }
a61af66fc99e Initial load
duke
parents:
diff changeset
35
a61af66fc99e Initial load
duke
parents:
diff changeset
36
a61af66fc99e Initial load
duke
parents:
diff changeset
37 void ThreadShadow::set_pending_exception(oop exception, const char* file, int line) {
a61af66fc99e Initial load
duke
parents:
diff changeset
38 assert(exception != NULL && exception->is_oop(), "invalid exception oop");
a61af66fc99e Initial load
duke
parents:
diff changeset
39 _pending_exception = exception;
a61af66fc99e Initial load
duke
parents:
diff changeset
40 _exception_file = file;
a61af66fc99e Initial load
duke
parents:
diff changeset
41 _exception_line = line;
a61af66fc99e Initial load
duke
parents:
diff changeset
42 }
a61af66fc99e Initial load
duke
parents:
diff changeset
43
a61af66fc99e Initial load
duke
parents:
diff changeset
44 void ThreadShadow::clear_pending_exception() {
a61af66fc99e Initial load
duke
parents:
diff changeset
45 if (TraceClearedExceptions) {
a61af66fc99e Initial load
duke
parents:
diff changeset
46 if (_pending_exception != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
47 tty->print_cr("Thread::clear_pending_exception: cleared exception:");
a61af66fc99e Initial load
duke
parents:
diff changeset
48 _pending_exception->print();
a61af66fc99e Initial load
duke
parents:
diff changeset
49 }
a61af66fc99e Initial load
duke
parents:
diff changeset
50 }
a61af66fc99e Initial load
duke
parents:
diff changeset
51 _pending_exception = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
52 _exception_file = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
53 _exception_line = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
54 }
a61af66fc99e Initial load
duke
parents:
diff changeset
55 // Implementation of Exceptions
a61af66fc99e Initial load
duke
parents:
diff changeset
56
a61af66fc99e Initial load
duke
parents:
diff changeset
57 bool Exceptions::special_exception(Thread* thread, const char* file, int line, Handle h_exception) {
a61af66fc99e Initial load
duke
parents:
diff changeset
58 // bootstrapping check
a61af66fc99e Initial load
duke
parents:
diff changeset
59 if (!Universe::is_fully_initialized()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
60 vm_exit_during_initialization(h_exception);
a61af66fc99e Initial load
duke
parents:
diff changeset
61 ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
62 }
a61af66fc99e Initial load
duke
parents:
diff changeset
63
a61af66fc99e Initial load
duke
parents:
diff changeset
64 if (thread->is_VM_thread()
a61af66fc99e Initial load
duke
parents:
diff changeset
65 || thread->is_Compiler_thread() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
66 // We do not care what kind of exception we get for the vm-thread or a thread which
a61af66fc99e Initial load
duke
parents:
diff changeset
67 // is compiling. We just install a dummy exception object
a61af66fc99e Initial load
duke
parents:
diff changeset
68 thread->set_pending_exception(Universe::vm_exception(), file, line);
a61af66fc99e Initial load
duke
parents:
diff changeset
69 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
70 }
a61af66fc99e Initial load
duke
parents:
diff changeset
71
a61af66fc99e Initial load
duke
parents:
diff changeset
72 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
73 }
a61af66fc99e Initial load
duke
parents:
diff changeset
74
a61af66fc99e Initial load
duke
parents:
diff changeset
75 bool Exceptions::special_exception(Thread* thread, const char* file, int line, symbolHandle h_name, const char* message) {
a61af66fc99e Initial load
duke
parents:
diff changeset
76 // bootstrapping check
a61af66fc99e Initial load
duke
parents:
diff changeset
77 if (!Universe::is_fully_initialized()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
78 if (h_name.is_null()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
79 // atleast an informative message.
a61af66fc99e Initial load
duke
parents:
diff changeset
80 vm_exit_during_initialization("Exception", message);
a61af66fc99e Initial load
duke
parents:
diff changeset
81 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
82 vm_exit_during_initialization(h_name, message);
a61af66fc99e Initial load
duke
parents:
diff changeset
83 }
a61af66fc99e Initial load
duke
parents:
diff changeset
84 ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
85 }
a61af66fc99e Initial load
duke
parents:
diff changeset
86
a61af66fc99e Initial load
duke
parents:
diff changeset
87 if (thread->is_VM_thread()
a61af66fc99e Initial load
duke
parents:
diff changeset
88 || thread->is_Compiler_thread() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
89 // We do not care what kind of exception we get for the vm-thread or a thread which
a61af66fc99e Initial load
duke
parents:
diff changeset
90 // is compiling. We just install a dummy exception object
a61af66fc99e Initial load
duke
parents:
diff changeset
91 thread->set_pending_exception(Universe::vm_exception(), file, line);
a61af66fc99e Initial load
duke
parents:
diff changeset
92 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
93 }
a61af66fc99e Initial load
duke
parents:
diff changeset
94
a61af66fc99e Initial load
duke
parents:
diff changeset
95 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
96 }
a61af66fc99e Initial load
duke
parents:
diff changeset
97
a61af66fc99e Initial load
duke
parents:
diff changeset
98 // This method should only be called from generated code,
a61af66fc99e Initial load
duke
parents:
diff changeset
99 // therefore the exception oop should be in the oopmap.
a61af66fc99e Initial load
duke
parents:
diff changeset
100 void Exceptions::_throw_oop(Thread* thread, const char* file, int line, oop exception) {
a61af66fc99e Initial load
duke
parents:
diff changeset
101 assert(exception != NULL, "exception should not be NULL");
a61af66fc99e Initial load
duke
parents:
diff changeset
102 Handle h_exception = Handle(thread, exception);
a61af66fc99e Initial load
duke
parents:
diff changeset
103 _throw(thread, file, line, h_exception);
a61af66fc99e Initial load
duke
parents:
diff changeset
104 }
a61af66fc99e Initial load
duke
parents:
diff changeset
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
a61af66fc99e Initial load
duke
parents:
diff changeset
107 assert(h_exception() != NULL, "exception should not be NULL");
a61af66fc99e Initial load
duke
parents:
diff changeset
108
a61af66fc99e Initial load
duke
parents:
diff changeset
109 // tracing (do this up front - so it works during boot strapping)
a61af66fc99e Initial load
duke
parents:
diff changeset
110 if (TraceExceptions) {
a61af66fc99e Initial load
duke
parents:
diff changeset
111 ttyLocker ttyl;
a61af66fc99e Initial load
duke
parents:
diff changeset
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
a61af66fc99e Initial load
duke
parents:
diff changeset
118 }
a61af66fc99e Initial load
duke
parents:
diff changeset
119 // for AbortVMOnException flag
a61af66fc99e Initial load
duke
parents:
diff changeset
120 NOT_PRODUCT(Exceptions::debug_check_abort(h_exception));
a61af66fc99e Initial load
duke
parents:
diff changeset
121
a61af66fc99e Initial load
duke
parents:
diff changeset
122 // Check for special boot-strapping/vm-thread handling
a61af66fc99e Initial load
duke
parents:
diff changeset
123 if (special_exception(thread, file, line, h_exception)) return;
a61af66fc99e Initial load
duke
parents:
diff changeset
124
a61af66fc99e Initial load
duke
parents:
diff changeset
125 assert(h_exception->is_a(SystemDictionary::throwable_klass()), "exception is not a subclass of java/lang/Throwable");
a61af66fc99e Initial load
duke
parents:
diff changeset
126
a61af66fc99e Initial load
duke
parents:
diff changeset
127 // set the pending exception
a61af66fc99e Initial load
duke
parents:
diff changeset
128 thread->set_pending_exception(h_exception(), file, line);
a61af66fc99e Initial load
duke
parents:
diff changeset
129
a61af66fc99e Initial load
duke
parents:
diff changeset
130 // vm log
a61af66fc99e Initial load
duke
parents:
diff changeset
131 Events::log("throw_exception " INTPTR_FORMAT, (address)h_exception());
a61af66fc99e Initial load
duke
parents:
diff changeset
132 }
a61af66fc99e Initial load
duke
parents:
diff changeset
133
a61af66fc99e Initial load
duke
parents:
diff changeset
134
a61af66fc99e Initial load
duke
parents:
diff changeset
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) {
a61af66fc99e Initial load
duke
parents:
diff changeset
136 // Check for special boot-strapping/vm-thread handling
a61af66fc99e Initial load
duke
parents:
diff changeset
137 if (special_exception(thread, file, line, h_name, message)) return;
a61af66fc99e Initial load
duke
parents:
diff changeset
138 // Create and throw exception
a61af66fc99e Initial load
duke
parents:
diff changeset
139 Handle h_cause(thread, NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
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
a61af66fc99e Initial load
duke
parents:
diff changeset
142 }
a61af66fc99e Initial load
duke
parents:
diff changeset
143
a61af66fc99e Initial load
duke
parents:
diff changeset
144 // Throw an exception with a message and a cause
a61af66fc99e Initial load
duke
parents:
diff changeset
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) {
a61af66fc99e Initial load
duke
parents:
diff changeset
146 // Check for special boot-strapping/vm-thread handling
a61af66fc99e Initial load
duke
parents:
diff changeset
147 if (special_exception(thread, file, line, h_name, message)) return;
a61af66fc99e Initial load
duke
parents:
diff changeset
148 // Create and throw exception and init cause
a61af66fc99e Initial load
duke
parents:
diff changeset
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
a61af66fc99e Initial load
duke
parents:
diff changeset
151 }
a61af66fc99e Initial load
duke
parents:
diff changeset
152
a61af66fc99e Initial load
duke
parents:
diff changeset
153 // This version creates handles and calls the other version
a61af66fc99e Initial load
duke
parents:
diff changeset
154 void Exceptions::_throw_msg(Thread* thread, const char* file, int line,
a61af66fc99e Initial load
duke
parents:
diff changeset
155 symbolOop name, const char* message) {
a61af66fc99e Initial load
duke
parents:
diff changeset
156 symbolHandle h_name(thread, name);
a61af66fc99e Initial load
duke
parents:
diff changeset
157 Handle h_loader(thread, NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
158 Handle h_protection_domain(thread, NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
159 Exceptions::_throw_msg(thread, file, line, h_name, message, h_loader, h_protection_domain);
a61af66fc99e Initial load
duke
parents:
diff changeset
160 }
a61af66fc99e Initial load
duke
parents:
diff changeset
161
a61af66fc99e Initial load
duke
parents:
diff changeset
162 // This version already has a handle for name
a61af66fc99e Initial load
duke
parents:
diff changeset
163 void Exceptions::_throw_msg(Thread* thread, const char* file, int line,
a61af66fc99e Initial load
duke
parents:
diff changeset
164 symbolHandle name, const char* message) {
a61af66fc99e Initial load
duke
parents:
diff changeset
165 Handle h_loader(thread, NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
166 Handle h_protection_domain(thread, NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
167 Exceptions::_throw_msg(thread, file, line, name, message, h_loader, h_protection_domain);
a61af66fc99e Initial load
duke
parents:
diff changeset
168 }
a61af66fc99e Initial load
duke
parents:
diff changeset
169
a61af66fc99e Initial load
duke
parents:
diff changeset
170 // This version already has a handle for name
a61af66fc99e Initial load
duke
parents:
diff changeset
171 void Exceptions::_throw_msg_cause(Thread* thread, const char* file, int line,
a61af66fc99e Initial load
duke
parents:
diff changeset
172 symbolHandle name, const char* message, Handle cause) {
a61af66fc99e Initial load
duke
parents:
diff changeset
173 Handle h_loader(thread, NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
174 Handle h_protection_domain(thread, NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
175 Exceptions::_throw_msg_cause(thread, file, line, name, message, cause, h_loader, h_protection_domain);
a61af66fc99e Initial load
duke
parents:
diff changeset
176 }
a61af66fc99e Initial load
duke
parents:
diff changeset
177
a61af66fc99e Initial load
duke
parents:
diff changeset
178 void Exceptions::_throw_args(Thread* thread, const char* file, int line, symbolHandle h_name, symbolHandle h_signature, JavaCallArguments *args) {
a61af66fc99e Initial load
duke
parents:
diff changeset
179 // Check for special boot-strapping/vm-thread handling
a61af66fc99e Initial load
duke
parents:
diff changeset
180 if (special_exception(thread, file, line, h_name, NULL)) return;
a61af66fc99e Initial load
duke
parents:
diff changeset
181 // Create and throw exception
a61af66fc99e Initial load
duke
parents:
diff changeset
182 Handle h_loader(thread, NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
183 Handle h_prot(thread, NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
184 Handle h_cause(thread, NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
185 Handle exception = new_exception(thread, h_name, h_signature, args, h_cause, h_loader, h_prot);
a61af66fc99e Initial load
duke
parents:
diff changeset
186 _throw(thread, file, line, exception);
a61af66fc99e Initial load
duke
parents:
diff changeset
187 }
a61af66fc99e Initial load
duke
parents:
diff changeset
188
a61af66fc99e Initial load
duke
parents:
diff changeset
189
a61af66fc99e Initial load
duke
parents:
diff changeset
190 void Exceptions::throw_stack_overflow_exception(Thread* THREAD, const char* file, int line) {
a61af66fc99e Initial load
duke
parents:
diff changeset
191 Handle exception;
a61af66fc99e Initial load
duke
parents:
diff changeset
192 if (!THREAD->has_pending_exception()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
193 klassOop k = SystemDictionary::StackOverflowError_klass();
a61af66fc99e Initial load
duke
parents:
diff changeset
194 oop e = instanceKlass::cast(k)->allocate_instance(CHECK);
a61af66fc99e Initial load
duke
parents:
diff changeset
195 exception = Handle(THREAD, e); // fill_in_stack trace does gc
a61af66fc99e Initial load
duke
parents:
diff changeset
196 if (StackTraceInThrowable) {
a61af66fc99e Initial load
duke
parents:
diff changeset
197 java_lang_Throwable::fill_in_stack_trace(exception);
a61af66fc99e Initial load
duke
parents:
diff changeset
198 }
a61af66fc99e Initial load
duke
parents:
diff changeset
199 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
200 // if prior exception, throw that one instead
a61af66fc99e Initial load
duke
parents:
diff changeset
201 exception = Handle(THREAD, THREAD->pending_exception());
a61af66fc99e Initial load
duke
parents:
diff changeset
202 }
a61af66fc99e Initial load
duke
parents:
diff changeset
203 _throw_oop(THREAD, file, line, exception());
a61af66fc99e Initial load
duke
parents:
diff changeset
204 }
a61af66fc99e Initial load
duke
parents:
diff changeset
205
a61af66fc99e Initial load
duke
parents:
diff changeset
206 void Exceptions::fthrow(Thread* thread, const char* file, int line, symbolHandle h_name, const char* format, ...) {
a61af66fc99e Initial load
duke
parents:
diff changeset
207 const int max_msg_size = 1024;
a61af66fc99e Initial load
duke
parents:
diff changeset
208 va_list ap;
a61af66fc99e Initial load
duke
parents:
diff changeset
209 va_start(ap, format);
a61af66fc99e Initial load
duke
parents:
diff changeset
210 char msg[max_msg_size];
a61af66fc99e Initial load
duke
parents:
diff changeset
211 vsnprintf(msg, max_msg_size, format, ap);
a61af66fc99e Initial load
duke
parents:
diff changeset
212 msg[max_msg_size-1] = '\0';
a61af66fc99e Initial load
duke
parents:
diff changeset
213 va_end(ap);
a61af66fc99e Initial load
duke
parents:
diff changeset
214 _throw_msg(thread, file, line, h_name, msg);
a61af66fc99e Initial load
duke
parents:
diff changeset
215 }
a61af66fc99e Initial load
duke
parents:
diff changeset
216
a61af66fc99e Initial load
duke
parents:
diff changeset
217 // Creates an exception oop, calls the <init> method with the given signature.
a61af66fc99e Initial load
duke
parents:
diff changeset
218 // and returns a Handle
a61af66fc99e Initial load
duke
parents:
diff changeset
219 // Initializes the cause if cause non-null
a61af66fc99e Initial load
duke
parents:
diff changeset
220 Handle Exceptions::new_exception(Thread *thread, symbolHandle h_name,
a61af66fc99e Initial load
duke
parents:
diff changeset
221 symbolHandle signature,
a61af66fc99e Initial load
duke
parents:
diff changeset
222 JavaCallArguments *args,
a61af66fc99e Initial load
duke
parents:
diff changeset
223 Handle h_cause, Handle h_loader,
a61af66fc99e Initial load
duke
parents:
diff changeset
224 Handle h_protection_domain) {
a61af66fc99e Initial load
duke
parents:
diff changeset
225 assert(Universe::is_fully_initialized(),
a61af66fc99e Initial load
duke
parents:
diff changeset
226 "cannot be called during initialization");
a61af66fc99e Initial load
duke
parents:
diff changeset
227 assert(thread->is_Java_thread(), "can only be called by a Java thread");
a61af66fc99e Initial load
duke
parents:
diff changeset
228 assert(!thread->has_pending_exception(), "already has exception");
a61af66fc99e Initial load
duke
parents:
diff changeset
229
a61af66fc99e Initial load
duke
parents:
diff changeset
230 Handle h_exception;
a61af66fc99e Initial load
duke
parents:
diff changeset
231
a61af66fc99e Initial load
duke
parents:
diff changeset
232 // Resolve exception klass
a61af66fc99e Initial load
duke
parents:
diff changeset
233 klassOop ik = SystemDictionary::resolve_or_fail(h_name, h_loader, h_protection_domain, true, thread);
a61af66fc99e Initial load
duke
parents:
diff changeset
234 instanceKlassHandle klass (thread, ik);
a61af66fc99e Initial load
duke
parents:
diff changeset
235
a61af66fc99e Initial load
duke
parents:
diff changeset
236 if (!thread->has_pending_exception()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
237 assert(klass.not_null(), "klass must exist");
a61af66fc99e Initial load
duke
parents:
diff changeset
238 // We are about to create an instance - so make sure that klass is initialized
a61af66fc99e Initial load
duke
parents:
diff changeset
239 klass->initialize(thread);
a61af66fc99e Initial load
duke
parents:
diff changeset
240 if (!thread->has_pending_exception()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
241 // Allocate new exception
a61af66fc99e Initial load
duke
parents:
diff changeset
242 h_exception = klass->allocate_instance_handle(thread);
a61af66fc99e Initial load
duke
parents:
diff changeset
243 if (!thread->has_pending_exception()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
244 JavaValue result(T_VOID);
a61af66fc99e Initial load
duke
parents:
diff changeset
245 args->set_receiver(h_exception);
a61af66fc99e Initial load
duke
parents:
diff changeset
246 // Call constructor
a61af66fc99e Initial load
duke
parents:
diff changeset
247 JavaCalls::call_special(&result, klass,
a61af66fc99e Initial load
duke
parents:
diff changeset
248 vmSymbolHandles::object_initializer_name(),
a61af66fc99e Initial load
duke
parents:
diff changeset
249 signature,
a61af66fc99e Initial load
duke
parents:
diff changeset
250 args,
a61af66fc99e Initial load
duke
parents:
diff changeset
251 thread);
a61af66fc99e Initial load
duke
parents:
diff changeset
252
a61af66fc99e Initial load
duke
parents:
diff changeset
253 }
a61af66fc99e Initial load
duke
parents:
diff changeset
254 }
a61af66fc99e Initial load
duke
parents:
diff changeset
255
a61af66fc99e Initial load
duke
parents:
diff changeset
256 // Future: object initializer should take a cause argument
a61af66fc99e Initial load
duke
parents:
diff changeset
257 if (h_cause() != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
258 assert(h_cause->is_a(SystemDictionary::throwable_klass()),
a61af66fc99e Initial load
duke
parents:
diff changeset
259 "exception cause is not a subclass of java/lang/Throwable");
a61af66fc99e Initial load
duke
parents:
diff changeset
260 JavaValue result1(T_OBJECT);
a61af66fc99e Initial load
duke
parents:
diff changeset
261 JavaCallArguments args1;
a61af66fc99e Initial load
duke
parents:
diff changeset
262 args1.set_receiver(h_exception);
a61af66fc99e Initial load
duke
parents:
diff changeset
263 args1.push_oop(h_cause);
a61af66fc99e Initial load
duke
parents:
diff changeset
264 JavaCalls::call_virtual(&result1, klass,
a61af66fc99e Initial load
duke
parents:
diff changeset
265 vmSymbolHandles::initCause_name(),
a61af66fc99e Initial load
duke
parents:
diff changeset
266 vmSymbolHandles::throwable_throwable_signature(),
a61af66fc99e Initial load
duke
parents:
diff changeset
267 &args1,
a61af66fc99e Initial load
duke
parents:
diff changeset
268 thread);
a61af66fc99e Initial load
duke
parents:
diff changeset
269 }
a61af66fc99e Initial load
duke
parents:
diff changeset
270 }
a61af66fc99e Initial load
duke
parents:
diff changeset
271
a61af66fc99e Initial load
duke
parents:
diff changeset
272 // Check if another exception was thrown in the process, if so rethrow that one
a61af66fc99e Initial load
duke
parents:
diff changeset
273 if (thread->has_pending_exception()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
274 h_exception = Handle(thread, thread->pending_exception());
a61af66fc99e Initial load
duke
parents:
diff changeset
275 thread->clear_pending_exception();
a61af66fc99e Initial load
duke
parents:
diff changeset
276 }
a61af66fc99e Initial load
duke
parents:
diff changeset
277 return h_exception;
a61af66fc99e Initial load
duke
parents:
diff changeset
278 }
a61af66fc99e Initial load
duke
parents:
diff changeset
279
a61af66fc99e Initial load
duke
parents:
diff changeset
280 // Convenience method. Calls either the <init>() or <init>(String) method when
a61af66fc99e Initial load
duke
parents:
diff changeset
281 // creating a new exception
a61af66fc99e Initial load
duke
parents:
diff changeset
282 Handle Exceptions::new_exception(Thread* thread, symbolHandle h_name,
a61af66fc99e Initial load
duke
parents:
diff changeset
283 const char* message, Handle h_cause,
a61af66fc99e Initial load
duke
parents:
diff changeset
284 Handle h_loader,
a61af66fc99e Initial load
duke
parents:
diff changeset
285 Handle h_protection_domain,
a61af66fc99e Initial load
duke
parents:
diff changeset
286 ExceptionMsgToUtf8Mode to_utf8_safe) {
a61af66fc99e Initial load
duke
parents:
diff changeset
287 JavaCallArguments args;
a61af66fc99e Initial load
duke
parents:
diff changeset
288 symbolHandle signature;
a61af66fc99e Initial load
duke
parents:
diff changeset
289 if (message == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
290 signature = vmSymbolHandles::void_method_signature();
a61af66fc99e Initial load
duke
parents:
diff changeset
291 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
292 // We want to allocate storage, but we can't do that if there's
a61af66fc99e Initial load
duke
parents:
diff changeset
293 // a pending exception, so we preserve any pending exception
a61af66fc99e Initial load
duke
parents:
diff changeset
294 // around the allocation.
a61af66fc99e Initial load
duke
parents:
diff changeset
295 // If we get an exception from the allocation, prefer that to
a61af66fc99e Initial load
duke
parents:
diff changeset
296 // the exception we are trying to build, or the pending exception.
a61af66fc99e Initial load
duke
parents:
diff changeset
297 // This is sort of like what PRESERVE_EXCEPTION_MARK does, except
a61af66fc99e Initial load
duke
parents:
diff changeset
298 // for the preferencing and the early returns.
a61af66fc99e Initial load
duke
parents:
diff changeset
299 Handle incoming_exception (thread, NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
300 if (thread->has_pending_exception()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
301 incoming_exception = Handle(thread, thread->pending_exception());
a61af66fc99e Initial load
duke
parents:
diff changeset
302 thread->clear_pending_exception();
a61af66fc99e Initial load
duke
parents:
diff changeset
303 }
a61af66fc99e Initial load
duke
parents:
diff changeset
304 Handle msg;
a61af66fc99e Initial load
duke
parents:
diff changeset
305 if (to_utf8_safe == safe_to_utf8) {
a61af66fc99e Initial load
duke
parents:
diff changeset
306 // Make a java UTF8 string.
a61af66fc99e Initial load
duke
parents:
diff changeset
307 msg = java_lang_String::create_from_str(message, thread);
a61af66fc99e Initial load
duke
parents:
diff changeset
308 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
309 // Make a java string keeping the encoding scheme of the original string.
a61af66fc99e Initial load
duke
parents:
diff changeset
310 msg = java_lang_String::create_from_platform_dependent_str(message, thread);
a61af66fc99e Initial load
duke
parents:
diff changeset
311 }
a61af66fc99e Initial load
duke
parents:
diff changeset
312 if (thread->has_pending_exception()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
313 Handle exception(thread, thread->pending_exception());
a61af66fc99e Initial load
duke
parents:
diff changeset
314 thread->clear_pending_exception();
a61af66fc99e Initial load
duke
parents:
diff changeset
315 return exception;
a61af66fc99e Initial load
duke
parents:
diff changeset
316 }
a61af66fc99e Initial load
duke
parents:
diff changeset
317 if (incoming_exception.not_null()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
318 return incoming_exception;
a61af66fc99e Initial load
duke
parents:
diff changeset
319 }
a61af66fc99e Initial load
duke
parents:
diff changeset
320 args.push_oop(msg);
a61af66fc99e Initial load
duke
parents:
diff changeset
321 signature = vmSymbolHandles::string_void_signature();
a61af66fc99e Initial load
duke
parents:
diff changeset
322 }
a61af66fc99e Initial load
duke
parents:
diff changeset
323 return new_exception(thread, h_name, signature, &args, h_cause, h_loader, h_protection_domain);
a61af66fc99e Initial load
duke
parents:
diff changeset
324 }
a61af66fc99e Initial load
duke
parents:
diff changeset
325
a61af66fc99e Initial load
duke
parents:
diff changeset
326 // Another convenience method that creates handles for null class loaders and
a61af66fc99e Initial load
duke
parents:
diff changeset
327 // protection domains and null causes.
a61af66fc99e Initial load
duke
parents:
diff changeset
328 // If the last parameter 'to_utf8_mode' is safe_to_utf8,
a61af66fc99e Initial load
duke
parents:
diff changeset
329 // it means we can safely ignore the encoding scheme of the message string and
a61af66fc99e Initial load
duke
parents:
diff changeset
330 // convert it directly to a java UTF8 string. Otherwise, we need to take the
a61af66fc99e Initial load
duke
parents:
diff changeset
331 // encoding scheme of the string into account. One thing we should do at some
a61af66fc99e Initial load
duke
parents:
diff changeset
332 // point is to push this flag down to class java_lang_String since other
a61af66fc99e Initial load
duke
parents:
diff changeset
333 // classes may need similar functionalities.
a61af66fc99e Initial load
duke
parents:
diff changeset
334 Handle Exceptions::new_exception(Thread* thread,
a61af66fc99e Initial load
duke
parents:
diff changeset
335 symbolOop name,
a61af66fc99e Initial load
duke
parents:
diff changeset
336 const char* message,
a61af66fc99e Initial load
duke
parents:
diff changeset
337 ExceptionMsgToUtf8Mode to_utf8_safe) {
a61af66fc99e Initial load
duke
parents:
diff changeset
338
a61af66fc99e Initial load
duke
parents:
diff changeset
339 symbolHandle h_name(thread, name);
a61af66fc99e Initial load
duke
parents:
diff changeset
340 Handle h_loader(thread, NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
341 Handle h_prot(thread, NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
342 Handle h_cause(thread, NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
343 return Exceptions::new_exception(thread, h_name, message, h_cause, h_loader,
a61af66fc99e Initial load
duke
parents:
diff changeset
344 h_prot, to_utf8_safe);
a61af66fc99e Initial load
duke
parents:
diff changeset
345 }
a61af66fc99e Initial load
duke
parents:
diff changeset
346
a61af66fc99e Initial load
duke
parents:
diff changeset
347 // Implementation of ExceptionMark
a61af66fc99e Initial load
duke
parents:
diff changeset
348
a61af66fc99e Initial load
duke
parents:
diff changeset
349 ExceptionMark::ExceptionMark(Thread*& thread) {
a61af66fc99e Initial load
duke
parents:
diff changeset
350 thread = Thread::current();
a61af66fc99e Initial load
duke
parents:
diff changeset
351 _thread = thread;
a61af66fc99e Initial load
duke
parents:
diff changeset
352 if (_thread->has_pending_exception()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
353 oop exception = _thread->pending_exception();
a61af66fc99e Initial load
duke
parents:
diff changeset
354 _thread->clear_pending_exception(); // Needed to avoid infinite recursion
a61af66fc99e Initial load
duke
parents:
diff changeset
355 exception->print();
a61af66fc99e Initial load
duke
parents:
diff changeset
356 fatal("ExceptionMark constructor expects no pending exceptions");
a61af66fc99e Initial load
duke
parents:
diff changeset
357 }
a61af66fc99e Initial load
duke
parents:
diff changeset
358 }
a61af66fc99e Initial load
duke
parents:
diff changeset
359
a61af66fc99e Initial load
duke
parents:
diff changeset
360
a61af66fc99e Initial load
duke
parents:
diff changeset
361 ExceptionMark::~ExceptionMark() {
a61af66fc99e Initial load
duke
parents:
diff changeset
362 if (_thread->has_pending_exception()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
363 Handle exception(_thread, _thread->pending_exception());
a61af66fc99e Initial load
duke
parents:
diff changeset
364 _thread->clear_pending_exception(); // Needed to avoid infinite recursion
a61af66fc99e Initial load
duke
parents:
diff changeset
365 if (is_init_completed()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
366 exception->print();
a61af66fc99e Initial load
duke
parents:
diff changeset
367 fatal("ExceptionMark destructor expects no pending exceptions");
a61af66fc99e Initial load
duke
parents:
diff changeset
368 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
369 vm_exit_during_initialization(exception);
a61af66fc99e Initial load
duke
parents:
diff changeset
370 }
a61af66fc99e Initial load
duke
parents:
diff changeset
371 }
a61af66fc99e Initial load
duke
parents:
diff changeset
372 }
a61af66fc99e Initial load
duke
parents:
diff changeset
373
a61af66fc99e Initial load
duke
parents:
diff changeset
374 // ----------------------------------------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
375
a61af66fc99e Initial load
duke
parents:
diff changeset
376 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
377 // caller frees value_string if necessary
a61af66fc99e Initial load
duke
parents:
diff changeset
378 void Exceptions::debug_check_abort(const char *value_string) {
a61af66fc99e Initial load
duke
parents:
diff changeset
379 if (AbortVMOnException != NULL && value_string != NULL &&
a61af66fc99e Initial load
duke
parents:
diff changeset
380 strstr(value_string, AbortVMOnException)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
381 fatal1("Saw %s, aborting", value_string);
a61af66fc99e Initial load
duke
parents:
diff changeset
382 }
a61af66fc99e Initial load
duke
parents:
diff changeset
383 }
a61af66fc99e Initial load
duke
parents:
diff changeset
384
a61af66fc99e Initial load
duke
parents:
diff changeset
385 void Exceptions::debug_check_abort(Handle exception) {
a61af66fc99e Initial load
duke
parents:
diff changeset
386 if (AbortVMOnException != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
387 ResourceMark rm;
a61af66fc99e Initial load
duke
parents:
diff changeset
388 debug_check_abort(instanceKlass::cast(exception()->klass())->external_name());
a61af66fc99e Initial load
duke
parents:
diff changeset
389 }
a61af66fc99e Initial load
duke
parents:
diff changeset
390 }
a61af66fc99e Initial load
duke
parents:
diff changeset
391 #endif