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