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