Mercurial > hg > truffle
annotate src/share/vm/runtime/javaCalls.cpp @ 1721:413ad0331a0c
6977924: Changes for 6975078 produce build error with certain gcc versions
Summary: The changes introduced for 6975078 assign badHeapOopVal to the _allocation field in the ResourceObj class. In 32 bit linux builds with certain versions of gcc this assignment will be flagged as an error while compiling allocation.cpp. In 32 bit builds the constant value badHeapOopVal (which is cast to an intptr_t) is negative. The _allocation field is typed as an unsigned intptr_t and gcc catches this as an error.
Reviewed-by: jcoomes, ysr, phh
author | johnc |
---|---|
date | Wed, 18 Aug 2010 10:59:06 -0700 |
parents | c18cbe5936b8 |
children | d5d065957597 |
rev | line source |
---|---|
0 | 1 /* |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1506
diff
changeset
|
2 * Copyright (c) 1997, 2010, 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 | |
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 } | |
421 // Return argument vector | |
1506 | 422 return _value; |
0 | 423 } |
424 | |
425 | |
426 class SignatureChekker : public SignatureIterator { | |
427 private: | |
428 bool *_is_oop; | |
429 int _pos; | |
430 BasicType _return_type; | |
465
dc16daa0329d
6739363: Xcheck jni doesn't check native function arguments
poonam
parents:
0
diff
changeset
|
431 intptr_t* _value; |
dc16daa0329d
6739363: Xcheck jni doesn't check native function arguments
poonam
parents:
0
diff
changeset
|
432 Thread* _thread; |
0 | 433 |
434 public: | |
435 bool _is_return; | |
436 | |
465
dc16daa0329d
6739363: Xcheck jni doesn't check native function arguments
poonam
parents:
0
diff
changeset
|
437 SignatureChekker(symbolHandle signature, BasicType return_type, bool is_static, bool* is_oop, intptr_t* value, Thread* thread) : SignatureIterator(signature) { |
0 | 438 _is_oop = is_oop; |
439 _is_return = false; | |
440 _return_type = return_type; | |
441 _pos = 0; | |
465
dc16daa0329d
6739363: Xcheck jni doesn't check native function arguments
poonam
parents:
0
diff
changeset
|
442 _value = value; |
dc16daa0329d
6739363: Xcheck jni doesn't check native function arguments
poonam
parents:
0
diff
changeset
|
443 _thread = thread; |
dc16daa0329d
6739363: Xcheck jni doesn't check native function arguments
poonam
parents:
0
diff
changeset
|
444 |
0 | 445 if (!is_static) { |
446 check_value(true); // Receiver must be an oop | |
447 } | |
448 } | |
449 | |
450 void check_value(bool type) { | |
451 guarantee(_is_oop[_pos++] == type, "signature does not match pushed arguments"); | |
452 } | |
453 | |
454 void check_doing_return(bool state) { _is_return = state; } | |
455 | |
456 void check_return_type(BasicType t) { | |
457 guarantee(_is_return && t == _return_type, "return type does not match"); | |
458 } | |
459 | |
460 void check_int(BasicType t) { | |
461 if (_is_return) { | |
462 check_return_type(t); | |
463 return; | |
464 } | |
465 check_value(false); | |
466 } | |
467 | |
468 void check_double(BasicType t) { check_long(t); } | |
469 | |
470 void check_long(BasicType t) { | |
471 if (_is_return) { | |
472 check_return_type(t); | |
473 return; | |
474 } | |
475 | |
476 check_value(false); | |
477 check_value(false); | |
478 } | |
479 | |
480 void check_obj(BasicType t) { | |
481 if (_is_return) { | |
482 check_return_type(t); | |
483 return; | |
484 } | |
465
dc16daa0329d
6739363: Xcheck jni doesn't check native function arguments
poonam
parents:
0
diff
changeset
|
485 |
dc16daa0329d
6739363: Xcheck jni doesn't check native function arguments
poonam
parents:
0
diff
changeset
|
486 // verify handle and the oop pointed to by handle |
dc16daa0329d
6739363: Xcheck jni doesn't check native function arguments
poonam
parents:
0
diff
changeset
|
487 int p = _pos; |
dc16daa0329d
6739363: Xcheck jni doesn't check native function arguments
poonam
parents:
0
diff
changeset
|
488 bool bad = false; |
dc16daa0329d
6739363: Xcheck jni doesn't check native function arguments
poonam
parents:
0
diff
changeset
|
489 // If argument is oop |
dc16daa0329d
6739363: Xcheck jni doesn't check native function arguments
poonam
parents:
0
diff
changeset
|
490 if (_is_oop[p]) { |
dc16daa0329d
6739363: Xcheck jni doesn't check native function arguments
poonam
parents:
0
diff
changeset
|
491 intptr_t v = _value[p]; |
dc16daa0329d
6739363: Xcheck jni doesn't check native function arguments
poonam
parents:
0
diff
changeset
|
492 if (v != 0 ) { |
dc16daa0329d
6739363: Xcheck jni doesn't check native function arguments
poonam
parents:
0
diff
changeset
|
493 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
|
494 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
|
495 if (CheckJNICalls && bad) { |
dc16daa0329d
6739363: Xcheck jni doesn't check native function arguments
poonam
parents:
0
diff
changeset
|
496 ReportJNIFatalError((JavaThread*)_thread, "Bad JNI oop argument"); |
dc16daa0329d
6739363: Xcheck jni doesn't check native function arguments
poonam
parents:
0
diff
changeset
|
497 } |
dc16daa0329d
6739363: Xcheck jni doesn't check native function arguments
poonam
parents:
0
diff
changeset
|
498 } |
dc16daa0329d
6739363: Xcheck jni doesn't check native function arguments
poonam
parents:
0
diff
changeset
|
499 // for the regular debug case. |
dc16daa0329d
6739363: Xcheck jni doesn't check native function arguments
poonam
parents:
0
diff
changeset
|
500 assert(!bad, "Bad JNI oop argument"); |
dc16daa0329d
6739363: Xcheck jni doesn't check native function arguments
poonam
parents:
0
diff
changeset
|
501 } |
dc16daa0329d
6739363: Xcheck jni doesn't check native function arguments
poonam
parents:
0
diff
changeset
|
502 |
0 | 503 check_value(true); |
504 } | |
505 | |
506 void do_bool() { check_int(T_BOOLEAN); } | |
507 void do_char() { check_int(T_CHAR); } | |
508 void do_float() { check_int(T_FLOAT); } | |
509 void do_double() { check_double(T_DOUBLE); } | |
510 void do_byte() { check_int(T_BYTE); } | |
511 void do_short() { check_int(T_SHORT); } | |
512 void do_int() { check_int(T_INT); } | |
513 void do_long() { check_long(T_LONG); } | |
514 void do_void() { check_return_type(T_VOID); } | |
515 void do_object(int begin, int end) { check_obj(T_OBJECT); } | |
516 void do_array(int begin, int end) { check_obj(T_OBJECT); } | |
517 }; | |
518 | |
465
dc16daa0329d
6739363: Xcheck jni doesn't check native function arguments
poonam
parents:
0
diff
changeset
|
519 |
0 | 520 void JavaCallArguments::verify(methodHandle method, BasicType return_type, |
521 Thread *thread) { | |
522 guarantee(method->size_of_parameters() == size_of_parameters(), "wrong no. of arguments pushed"); | |
523 | |
524 // Treat T_OBJECT and T_ARRAY as the same | |
525 if (return_type == T_ARRAY) return_type = T_OBJECT; | |
526 | |
527 // Check that oop information is correct | |
528 symbolHandle signature (thread, method->signature()); | |
529 | |
465
dc16daa0329d
6739363: Xcheck jni doesn't check native function arguments
poonam
parents:
0
diff
changeset
|
530 SignatureChekker sc(signature, return_type, method->is_static(),_is_oop, _value, thread); |
0 | 531 sc.iterate_parameters(); |
532 sc.check_doing_return(true); | |
533 sc.iterate_returntype(); | |
534 } | |
535 |