Mercurial > hg > truffle
annotate src/share/vm/runtime/javaCalls.cpp @ 6862:8a5ea0a9ccc4
7127708: G1: change task num types from int to uint in concurrent mark
Summary: Change the type of various task num fields, parameters etc to unsigned and rename them to be more consistent with the other collectors. Code changes were also reviewed by Vitaly Davidovich.
Reviewed-by: johnc
Contributed-by: Kaushik Srenevasan <kaushik@twitter.com>
author | johnc |
---|---|
date | Sat, 06 Oct 2012 01:17:44 -0700 |
parents | da91efe96a93 |
children | 18fb7da42534 |
rev | line source |
---|---|
0 | 1 /* |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3960
diff
changeset
|
2 * Copyright (c) 1997, 2012, 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:
1506
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1506
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:
1506
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
1972 | 25 #include "precompiled.hpp" |
26 #include "classfile/systemDictionary.hpp" | |
27 #include "classfile/vmSymbols.hpp" | |
28 #include "code/nmethod.hpp" | |
29 #include "compiler/compileBroker.hpp" | |
30 #include "interpreter/interpreter.hpp" | |
31 #include "interpreter/linkResolver.hpp" | |
32 #include "memory/universe.inline.hpp" | |
33 #include "oops/oop.inline.hpp" | |
34 #include "prims/jniCheck.hpp" | |
35 #include "runtime/compilationPolicy.hpp" | |
36 #include "runtime/handles.inline.hpp" | |
37 #include "runtime/interfaceSupport.hpp" | |
38 #include "runtime/javaCalls.hpp" | |
39 #include "runtime/mutexLocker.hpp" | |
40 #include "runtime/signature.hpp" | |
41 #include "runtime/stubRoutines.hpp" | |
42 #ifdef TARGET_OS_FAMILY_linux | |
43 # include "thread_linux.inline.hpp" | |
44 #endif | |
45 #ifdef TARGET_OS_FAMILY_solaris | |
46 # include "thread_solaris.inline.hpp" | |
47 #endif | |
48 #ifdef TARGET_OS_FAMILY_windows | |
49 # include "thread_windows.inline.hpp" | |
50 #endif | |
3960 | 51 #ifdef TARGET_OS_FAMILY_bsd |
52 # include "thread_bsd.inline.hpp" | |
53 #endif | |
0 | 54 |
55 // ----------------------------------------------------- | |
56 // Implementation of JavaCallWrapper | |
57 | |
58 JavaCallWrapper::JavaCallWrapper(methodHandle callee_method, Handle receiver, JavaValue* result, TRAPS) { | |
59 JavaThread* thread = (JavaThread *)THREAD; | |
60 bool clear_pending_exception = true; | |
61 | |
62 guarantee(thread->is_Java_thread(), "crucial check - the VM thread cannot and must not escape to Java code"); | |
63 assert(!thread->owns_locks(), "must release all locks when leaving VM"); | |
64 guarantee(!thread->is_Compiler_thread(), "cannot make java calls from the compiler"); | |
65 _result = result; | |
66 | |
67 // Allocate handle block for Java code. This must be done before we change thread_state to _thread_in_Java_or_stub, | |
68 // since it can potentially block. | |
69 JNIHandleBlock* new_handles = JNIHandleBlock::allocate_block(thread); | |
70 | |
71 // After this, we are official in JavaCode. This needs to be done before we change any of the thread local | |
72 // info, since we cannot find oops before the new information is set up completely. | |
73 ThreadStateTransition::transition(thread, _thread_in_vm, _thread_in_Java); | |
74 | |
75 // Make sure that we handle asynchronous stops and suspends _before_ we clear all thread state | |
76 // in JavaCallWrapper::JavaCallWrapper(). This way, we can decide if we need to do any pd actions | |
77 // to prepare for stop/suspend (flush register windows on sparcs, cache sp, or other state). | |
78 if (thread->has_special_runtime_exit_condition()) { | |
79 thread->handle_special_runtime_exit_condition(); | |
80 if (HAS_PENDING_EXCEPTION) { | |
81 clear_pending_exception = false; | |
82 } | |
83 } | |
84 | |
85 | |
86 // Make sure to set the oop's after the thread transition - since we can block there. No one is GC'ing | |
87 // the JavaCallWrapper before the entry frame is on the stack. | |
88 _callee_method = callee_method(); | |
89 _receiver = receiver(); | |
90 | |
91 #ifdef CHECK_UNHANDLED_OOPS | |
92 THREAD->allow_unhandled_oop(&_receiver); | |
93 #endif // CHECK_UNHANDLED_OOPS | |
94 | |
95 _thread = (JavaThread *)thread; | |
96 _handles = _thread->active_handles(); // save previous handle block & Java frame linkage | |
97 | |
98 // For the profiler, the last_Java_frame information in thread must always be in | |
99 // legal state. We have no last Java frame if last_Java_sp == NULL so | |
100 // the valid transition is to clear _last_Java_sp and then reset the rest of | |
101 // the (platform specific) state. | |
102 | |
103 _anchor.copy(_thread->frame_anchor()); | |
104 _thread->frame_anchor()->clear(); | |
105 | |
106 debug_only(_thread->inc_java_call_counter()); | |
107 _thread->set_active_handles(new_handles); // install new handle block and reset Java frame linkage | |
108 | |
109 assert (_thread->thread_state() != _thread_in_native, "cannot set native pc to NULL"); | |
110 | |
111 // clear any pending exception in thread (native calls start with no exception pending) | |
112 if(clear_pending_exception) { | |
113 _thread->clear_pending_exception(); | |
114 } | |
115 | |
116 if (_anchor.last_Java_sp() == NULL) { | |
117 _thread->record_base_of_stack_pointer(); | |
118 } | |
119 } | |
120 | |
121 | |
122 JavaCallWrapper::~JavaCallWrapper() { | |
123 assert(_thread == JavaThread::current(), "must still be the same thread"); | |
124 | |
125 // restore previous handle block & Java frame linkage | |
126 JNIHandleBlock *_old_handles = _thread->active_handles(); | |
127 _thread->set_active_handles(_handles); | |
128 | |
129 _thread->frame_anchor()->zap(); | |
130 | |
131 debug_only(_thread->dec_java_call_counter()); | |
132 | |
133 if (_anchor.last_Java_sp() == NULL) { | |
134 _thread->set_base_of_stack_pointer(NULL); | |
135 } | |
136 | |
137 | |
138 // Old thread-local info. has been restored. We are not back in the VM. | |
139 ThreadStateTransition::transition_from_java(_thread, _thread_in_vm); | |
140 | |
141 // State has been restored now make the anchor frame visible for the profiler. | |
142 // Do this after the transition because this allows us to put an assert | |
143 // the Java->vm transition which checks to see that stack is not walkable | |
144 // on sparc/ia64 which will catch violations of the reseting of last_Java_frame | |
145 // invariants (i.e. _flags always cleared on return to Java) | |
146 | |
147 _thread->frame_anchor()->copy(&_anchor); | |
148 | |
149 // Release handles after we are marked as being inside the VM again, since this | |
150 // operation might block | |
151 JNIHandleBlock::release_block(_old_handles, _thread); | |
152 } | |
153 | |
154 | |
155 void JavaCallWrapper::oops_do(OopClosure* f) { | |
156 f->do_oop((oop*)&_receiver); | |
157 handles()->oops_do(f); | |
158 } | |
159 | |
160 | |
161 // Helper methods | |
162 static BasicType runtime_type_from(JavaValue* result) { | |
163 switch (result->get_type()) { | |
164 case T_BOOLEAN: // fall through | |
165 case T_CHAR : // fall through | |
166 case T_SHORT : // fall through | |
167 case T_INT : // fall through | |
168 #ifndef _LP64 | |
169 case T_OBJECT : // fall through | |
170 case T_ARRAY : // fall through | |
171 #endif | |
172 case T_BYTE : // fall through | |
173 case T_VOID : return T_INT; | |
174 case T_LONG : return T_LONG; | |
175 case T_FLOAT : return T_FLOAT; | |
176 case T_DOUBLE : return T_DOUBLE; | |
177 #ifdef _LP64 | |
178 case T_ARRAY : // fall through | |
179 case T_OBJECT: return T_OBJECT; | |
180 #endif | |
181 } | |
182 ShouldNotReachHere(); | |
183 return T_ILLEGAL; | |
184 } | |
185 | |
186 // ===== object constructor calls ===== | |
187 | |
188 void JavaCalls::call_default_constructor(JavaThread* thread, methodHandle method, Handle receiver, TRAPS) { | |
189 assert(method->name() == vmSymbols::object_initializer_name(), "Should only be called for default constructor"); | |
190 assert(method->signature() == vmSymbols::void_method_signature(), "Should only be called for default constructor"); | |
191 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3960
diff
changeset
|
192 InstanceKlass* ik = InstanceKlass::cast(method->method_holder()); |
0 | 193 if (ik->is_initialized() && ik->has_vanilla_constructor()) { |
194 // safe to skip constructor call | |
195 } else { | |
196 static JavaValue result(T_VOID); | |
197 JavaCallArguments args(receiver); | |
198 call(&result, method, &args, CHECK); | |
199 } | |
200 } | |
201 | |
202 // ============ Virtual calls ============ | |
203 | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
204 void JavaCalls::call_virtual(JavaValue* result, KlassHandle spec_klass, Symbol* name, Symbol* signature, JavaCallArguments* args, TRAPS) { |
0 | 205 CallInfo callinfo; |
206 Handle receiver = args->receiver(); | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3960
diff
changeset
|
207 KlassHandle recvrKlass(THREAD, receiver.is_null() ? (Klass*)NULL : receiver->klass()); |
0 | 208 LinkResolver::resolve_virtual_call( |
209 callinfo, receiver, recvrKlass, spec_klass, name, signature, | |
210 KlassHandle(), false, true, CHECK); | |
211 methodHandle method = callinfo.selected_method(); | |
212 assert(method.not_null(), "should have thrown exception"); | |
213 | |
214 // Invoke the method | |
215 JavaCalls::call(result, method, args, CHECK); | |
216 } | |
217 | |
218 | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
219 void JavaCalls::call_virtual(JavaValue* result, Handle receiver, KlassHandle spec_klass, Symbol* name, Symbol* signature, TRAPS) { |
0 | 220 JavaCallArguments args(receiver); // One oop argument |
221 call_virtual(result, spec_klass, name, signature, &args, CHECK); | |
222 } | |
223 | |
224 | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
225 void JavaCalls::call_virtual(JavaValue* result, Handle receiver, KlassHandle spec_klass, Symbol* name, Symbol* signature, Handle arg1, TRAPS) { |
0 | 226 JavaCallArguments args(receiver); // One oop argument |
227 args.push_oop(arg1); | |
228 call_virtual(result, spec_klass, name, signature, &args, CHECK); | |
229 } | |
230 | |
231 | |
232 | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
233 void JavaCalls::call_virtual(JavaValue* result, Handle receiver, KlassHandle spec_klass, Symbol* name, Symbol* signature, Handle arg1, Handle arg2, TRAPS) { |
0 | 234 JavaCallArguments args(receiver); // One oop argument |
235 args.push_oop(arg1); | |
236 args.push_oop(arg2); | |
237 call_virtual(result, spec_klass, name, signature, &args, CHECK); | |
238 } | |
239 | |
240 | |
241 // ============ Special calls ============ | |
242 | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
243 void JavaCalls::call_special(JavaValue* result, KlassHandle klass, Symbol* name, Symbol* signature, JavaCallArguments* args, TRAPS) { |
0 | 244 CallInfo callinfo; |
245 LinkResolver::resolve_special_call(callinfo, klass, name, signature, KlassHandle(), false, CHECK); | |
246 methodHandle method = callinfo.selected_method(); | |
247 assert(method.not_null(), "should have thrown exception"); | |
248 | |
249 // Invoke the method | |
250 JavaCalls::call(result, method, args, CHECK); | |
251 } | |
252 | |
253 | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
254 void JavaCalls::call_special(JavaValue* result, Handle receiver, KlassHandle klass, Symbol* name, Symbol* signature, TRAPS) { |
0 | 255 JavaCallArguments args(receiver); // One oop argument |
256 call_special(result, klass, name, signature, &args, CHECK); | |
257 } | |
258 | |
259 | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
260 void JavaCalls::call_special(JavaValue* result, Handle receiver, KlassHandle klass, Symbol* name, Symbol* signature, Handle arg1, TRAPS) { |
0 | 261 JavaCallArguments args(receiver); // One oop argument |
262 args.push_oop(arg1); | |
263 call_special(result, klass, name, signature, &args, CHECK); | |
264 } | |
265 | |
266 | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
267 void JavaCalls::call_special(JavaValue* result, Handle receiver, KlassHandle klass, Symbol* name, Symbol* signature, Handle arg1, Handle arg2, TRAPS) { |
0 | 268 JavaCallArguments args(receiver); // One oop argument |
269 args.push_oop(arg1); | |
270 args.push_oop(arg2); | |
271 call_special(result, klass, name, signature, &args, CHECK); | |
272 } | |
273 | |
274 | |
275 // ============ Static calls ============ | |
276 | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
277 void JavaCalls::call_static(JavaValue* result, KlassHandle klass, Symbol* name, Symbol* signature, JavaCallArguments* args, TRAPS) { |
0 | 278 CallInfo callinfo; |
279 LinkResolver::resolve_static_call(callinfo, klass, name, signature, KlassHandle(), false, true, CHECK); | |
280 methodHandle method = callinfo.selected_method(); | |
281 assert(method.not_null(), "should have thrown exception"); | |
282 | |
283 // Invoke the method | |
284 JavaCalls::call(result, method, args, CHECK); | |
285 } | |
286 | |
287 | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
288 void JavaCalls::call_static(JavaValue* result, KlassHandle klass, Symbol* name, Symbol* signature, TRAPS) { |
0 | 289 JavaCallArguments args; // No argument |
290 call_static(result, klass, name, signature, &args, CHECK); | |
291 } | |
292 | |
293 | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
294 void JavaCalls::call_static(JavaValue* result, KlassHandle klass, Symbol* name, Symbol* signature, Handle arg1, TRAPS) { |
0 | 295 JavaCallArguments args(arg1); // One oop argument |
296 call_static(result, klass, name, signature, &args, CHECK); | |
297 } | |
298 | |
299 | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
300 void JavaCalls::call_static(JavaValue* result, KlassHandle klass, Symbol* name, Symbol* signature, Handle arg1, Handle arg2, TRAPS) { |
0 | 301 JavaCallArguments args; // One oop argument |
302 args.push_oop(arg1); | |
303 args.push_oop(arg2); | |
304 call_static(result, klass, name, signature, &args, CHECK); | |
305 } | |
306 | |
307 | |
308 // ------------------------------------------------- | |
309 // Implementation of JavaCalls (low level) | |
310 | |
311 | |
312 void JavaCalls::call(JavaValue* result, methodHandle method, JavaCallArguments* args, TRAPS) { | |
313 // Check if we need to wrap a potential OS exception handler around thread | |
314 // This is used for e.g. Win32 structured exception handlers | |
315 assert(THREAD->is_Java_thread(), "only JavaThreads can make JavaCalls"); | |
316 // Need to wrap each and everytime, since there might be native code down the | |
317 // stack that has installed its own exception handlers | |
318 os::os_exception_wrapper(call_helper, result, &method, args, THREAD); | |
319 } | |
320 | |
321 void JavaCalls::call_helper(JavaValue* result, methodHandle* m, JavaCallArguments* args, TRAPS) { | |
322 methodHandle method = *m; | |
323 JavaThread* thread = (JavaThread*)THREAD; | |
324 assert(thread->is_Java_thread(), "must be called by a java thread"); | |
325 assert(method.not_null(), "must have a method to call"); | |
326 assert(!SafepointSynchronize::is_at_safepoint(), "call to Java code during VM operation"); | |
327 assert(!thread->handle_area()->no_handle_mark_active(), "cannot call out to Java here"); | |
328 | |
329 | |
330 CHECK_UNHANDLED_OOPS_ONLY(thread->clear_unhandled_oops();) | |
331 | |
465
dc16daa0329d
6739363: Xcheck jni doesn't check native function arguments
poonam
parents:
0
diff
changeset
|
332 // Verify the arguments |
dc16daa0329d
6739363: Xcheck jni doesn't check native function arguments
poonam
parents:
0
diff
changeset
|
333 |
dc16daa0329d
6739363: Xcheck jni doesn't check native function arguments
poonam
parents:
0
diff
changeset
|
334 if (CheckJNICalls) { |
dc16daa0329d
6739363: Xcheck jni doesn't check native function arguments
poonam
parents:
0
diff
changeset
|
335 args->verify(method, result->get_type(), thread); |
dc16daa0329d
6739363: Xcheck jni doesn't check native function arguments
poonam
parents:
0
diff
changeset
|
336 } |
dc16daa0329d
6739363: Xcheck jni doesn't check native function arguments
poonam
parents:
0
diff
changeset
|
337 else debug_only(args->verify(method, result->get_type(), thread)); |
0 | 338 |
339 // Ignore call if method is empty | |
340 if (method->is_empty_method()) { | |
341 assert(result->get_type() == T_VOID, "an empty method must return a void value"); | |
342 return; | |
343 } | |
344 | |
345 | |
346 #ifdef ASSERT | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3960
diff
changeset
|
347 { Klass* holder = method->method_holder(); |
0 | 348 // A klass might not be initialized since JavaCall's might be used during the executing of |
349 // the <clinit>. For example, a Thread.start might start executing on an object that is | |
350 // not fully initialized! (bad Java programming style) | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3960
diff
changeset
|
351 assert(InstanceKlass::cast(holder)->is_linked(), "rewritting must have taken place"); |
0 | 352 } |
353 #endif | |
354 | |
355 | |
356 assert(!thread->is_Compiler_thread(), "cannot compile from the compiler"); | |
1783 | 357 if (CompilationPolicy::must_be_compiled(method)) { |
0 | 358 CompileBroker::compile_method(method, InvocationEntryBci, |
3837
43f9d800f276
7066339: Tiered: policy should make consistent decisions about osr levels
iveresov
parents:
3272
diff
changeset
|
359 CompilationPolicy::policy()->initial_compile_level(), |
1783 | 360 methodHandle(), 0, "must_be_compiled", CHECK); |
0 | 361 } |
362 | |
363 // Since the call stub sets up like the interpreter we call the from_interpreted_entry | |
364 // so we can go compiled via a i2c. Otherwise initial entry method will always | |
365 // run interpreted. | |
366 address entry_point = method->from_interpreted_entry(); | |
367 if (JvmtiExport::can_post_interpreter_events() && thread->is_interp_only_mode()) { | |
368 entry_point = method->interpreter_entry(); | |
369 } | |
370 | |
371 // Figure out if the result value is an oop or not (Note: This is a different value | |
372 // than result_type. result_type will be T_INT of oops. (it is about size) | |
373 BasicType result_type = runtime_type_from(result); | |
374 bool oop_result_flag = (result->get_type() == T_OBJECT || result->get_type() == T_ARRAY); | |
375 | |
376 // NOTE: if we move the computation of the result_val_address inside | |
377 // the call to call_stub, the optimizer produces wrong code. | |
378 intptr_t* result_val_address = (intptr_t*)(result->get_value_addr()); | |
379 | |
380 // Find receiver | |
381 Handle receiver = (!method->is_static()) ? args->receiver() : Handle(); | |
382 | |
383 // When we reenter Java, we need to reenable the yellow zone which | |
384 // might already be disabled when we are in VM. | |
385 if (thread->stack_yellow_zone_disabled()) { | |
386 thread->reguard_stack(); | |
387 } | |
388 | |
389 // Check that there are shadow pages available before changing thread state | |
390 // to Java | |
391 if (!os::stack_shadow_pages_available(THREAD, method)) { | |
392 // Throw stack overflow exception with preinitialized exception. | |
3272
01147d8aac1d
7009923: JSR 292: VM crash in JavaThread::last_frame
coleenp
parents:
2426
diff
changeset
|
393 Exceptions::throw_stack_overflow_exception(THREAD, __FILE__, __LINE__, method); |
0 | 394 return; |
395 } else { | |
396 // Touch pages checked if the OS needs them to be touched to be mapped. | |
397 os::bang_stack_shadow_pages(); | |
398 } | |
399 | |
400 // do call | |
401 { JavaCallWrapper link(method, receiver, result, CHECK); | |
402 { HandleMark hm(thread); // HandleMark used by HandleMarkCleaner | |
403 | |
404 StubRoutines::call_stub()( | |
405 (address)&link, | |
406 // (intptr_t*)&(result->_value), // see NOTE above (compiler problem) | |
407 result_val_address, // see NOTE above (compiler problem) | |
408 result_type, | |
409 method(), | |
410 entry_point, | |
411 args->parameters(), | |
412 args->size_of_parameters(), | |
413 CHECK | |
414 ); | |
415 | |
416 result = link.result(); // circumvent MS C++ 5.0 compiler bug (result is clobbered across call) | |
417 // Preserve oop return value across possible gc points | |
418 if (oop_result_flag) { | |
419 thread->set_vm_result((oop) result->get_jobject()); | |
420 } | |
421 } | |
422 } // Exit JavaCallWrapper (can block - potential return oop must be preserved) | |
423 | |
424 // Check if a thread stop or suspend should be executed | |
425 // The following assert was not realistic. Thread.stop can set that bit at any moment. | |
426 //assert(!thread->has_special_runtime_exit_condition(), "no async. exceptions should be installed"); | |
427 | |
428 // Restore possible oop return | |
429 if (oop_result_flag) { | |
430 result->set_jobject((jobject)thread->vm_result()); | |
431 thread->set_vm_result(NULL); | |
432 } | |
433 } | |
434 | |
435 | |
436 //-------------------------------------------------------------------------------------- | |
437 // Implementation of JavaCallArguments | |
438 | |
439 intptr_t* JavaCallArguments::parameters() { | |
440 // First convert all handles to oops | |
441 for(int i = 0; i < _size; i++) { | |
442 if (_is_oop[i]) { | |
443 // Handle conversion | |
444 _value[i] = (intptr_t)Handle::raw_resolve((oop *)_value[i]); | |
445 } | |
446 } | |
447 // Return argument vector | |
1506 | 448 return _value; |
0 | 449 } |
450 | |
451 | |
452 class SignatureChekker : public SignatureIterator { | |
453 private: | |
454 bool *_is_oop; | |
455 int _pos; | |
456 BasicType _return_type; | |
465
dc16daa0329d
6739363: Xcheck jni doesn't check native function arguments
poonam
parents:
0
diff
changeset
|
457 intptr_t* _value; |
dc16daa0329d
6739363: Xcheck jni doesn't check native function arguments
poonam
parents:
0
diff
changeset
|
458 Thread* _thread; |
0 | 459 |
460 public: | |
461 bool _is_return; | |
462 | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
463 SignatureChekker(Symbol* signature, BasicType return_type, bool is_static, bool* is_oop, intptr_t* value, Thread* thread) : SignatureIterator(signature) { |
0 | 464 _is_oop = is_oop; |
465 _is_return = false; | |
466 _return_type = return_type; | |
467 _pos = 0; | |
465
dc16daa0329d
6739363: Xcheck jni doesn't check native function arguments
poonam
parents:
0
diff
changeset
|
468 _value = value; |
dc16daa0329d
6739363: Xcheck jni doesn't check native function arguments
poonam
parents:
0
diff
changeset
|
469 _thread = thread; |
dc16daa0329d
6739363: Xcheck jni doesn't check native function arguments
poonam
parents:
0
diff
changeset
|
470 |
0 | 471 if (!is_static) { |
472 check_value(true); // Receiver must be an oop | |
473 } | |
474 } | |
475 | |
476 void check_value(bool type) { | |
477 guarantee(_is_oop[_pos++] == type, "signature does not match pushed arguments"); | |
478 } | |
479 | |
480 void check_doing_return(bool state) { _is_return = state; } | |
481 | |
482 void check_return_type(BasicType t) { | |
483 guarantee(_is_return && t == _return_type, "return type does not match"); | |
484 } | |
485 | |
486 void check_int(BasicType t) { | |
487 if (_is_return) { | |
488 check_return_type(t); | |
489 return; | |
490 } | |
491 check_value(false); | |
492 } | |
493 | |
494 void check_double(BasicType t) { check_long(t); } | |
495 | |
496 void check_long(BasicType t) { | |
497 if (_is_return) { | |
498 check_return_type(t); | |
499 return; | |
500 } | |
501 | |
502 check_value(false); | |
503 check_value(false); | |
504 } | |
505 | |
506 void check_obj(BasicType t) { | |
507 if (_is_return) { | |
508 check_return_type(t); | |
509 return; | |
510 } | |
465
dc16daa0329d
6739363: Xcheck jni doesn't check native function arguments
poonam
parents:
0
diff
changeset
|
511 |
dc16daa0329d
6739363: Xcheck jni doesn't check native function arguments
poonam
parents:
0
diff
changeset
|
512 // verify handle and the oop pointed to by handle |
dc16daa0329d
6739363: Xcheck jni doesn't check native function arguments
poonam
parents:
0
diff
changeset
|
513 int p = _pos; |
dc16daa0329d
6739363: Xcheck jni doesn't check native function arguments
poonam
parents:
0
diff
changeset
|
514 bool bad = false; |
dc16daa0329d
6739363: Xcheck jni doesn't check native function arguments
poonam
parents:
0
diff
changeset
|
515 // If argument is oop |
dc16daa0329d
6739363: Xcheck jni doesn't check native function arguments
poonam
parents:
0
diff
changeset
|
516 if (_is_oop[p]) { |
dc16daa0329d
6739363: Xcheck jni doesn't check native function arguments
poonam
parents:
0
diff
changeset
|
517 intptr_t v = _value[p]; |
dc16daa0329d
6739363: Xcheck jni doesn't check native function arguments
poonam
parents:
0
diff
changeset
|
518 if (v != 0 ) { |
dc16daa0329d
6739363: Xcheck jni doesn't check native function arguments
poonam
parents:
0
diff
changeset
|
519 size_t t = (size_t)v; |
498
c6065343356f
6786340: hs14b09a pit: a lot of tests failed in "-server -Xcomp" on solaris-amd64 using fastdebug bits
poonam
parents:
465
diff
changeset
|
520 bad = (t < (size_t)os::vm_page_size() ) || !Handle::raw_resolve((oop *)v)->is_oop_or_null(true); |
465
dc16daa0329d
6739363: Xcheck jni doesn't check native function arguments
poonam
parents:
0
diff
changeset
|
521 if (CheckJNICalls && bad) { |
dc16daa0329d
6739363: Xcheck jni doesn't check native function arguments
poonam
parents:
0
diff
changeset
|
522 ReportJNIFatalError((JavaThread*)_thread, "Bad JNI oop argument"); |
dc16daa0329d
6739363: Xcheck jni doesn't check native function arguments
poonam
parents:
0
diff
changeset
|
523 } |
dc16daa0329d
6739363: Xcheck jni doesn't check native function arguments
poonam
parents:
0
diff
changeset
|
524 } |
dc16daa0329d
6739363: Xcheck jni doesn't check native function arguments
poonam
parents:
0
diff
changeset
|
525 // for the regular debug case. |
dc16daa0329d
6739363: Xcheck jni doesn't check native function arguments
poonam
parents:
0
diff
changeset
|
526 assert(!bad, "Bad JNI oop argument"); |
dc16daa0329d
6739363: Xcheck jni doesn't check native function arguments
poonam
parents:
0
diff
changeset
|
527 } |
dc16daa0329d
6739363: Xcheck jni doesn't check native function arguments
poonam
parents:
0
diff
changeset
|
528 |
0 | 529 check_value(true); |
530 } | |
531 | |
532 void do_bool() { check_int(T_BOOLEAN); } | |
533 void do_char() { check_int(T_CHAR); } | |
534 void do_float() { check_int(T_FLOAT); } | |
535 void do_double() { check_double(T_DOUBLE); } | |
536 void do_byte() { check_int(T_BYTE); } | |
537 void do_short() { check_int(T_SHORT); } | |
538 void do_int() { check_int(T_INT); } | |
539 void do_long() { check_long(T_LONG); } | |
540 void do_void() { check_return_type(T_VOID); } | |
541 void do_object(int begin, int end) { check_obj(T_OBJECT); } | |
542 void do_array(int begin, int end) { check_obj(T_OBJECT); } | |
543 }; | |
544 | |
465
dc16daa0329d
6739363: Xcheck jni doesn't check native function arguments
poonam
parents:
0
diff
changeset
|
545 |
0 | 546 void JavaCallArguments::verify(methodHandle method, BasicType return_type, |
547 Thread *thread) { | |
548 guarantee(method->size_of_parameters() == size_of_parameters(), "wrong no. of arguments pushed"); | |
549 | |
550 // Treat T_OBJECT and T_ARRAY as the same | |
551 if (return_type == T_ARRAY) return_type = T_OBJECT; | |
552 | |
553 // Check that oop information is correct | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
554 Symbol* signature = method->signature(); |
0 | 555 |
465
dc16daa0329d
6739363: Xcheck jni doesn't check native function arguments
poonam
parents:
0
diff
changeset
|
556 SignatureChekker sc(signature, return_type, method->is_static(),_is_oop, _value, thread); |
0 | 557 sc.iterate_parameters(); |
558 sc.check_doing_return(true); | |
559 sc.iterate_returntype(); | |
560 } |