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