Mercurial > hg > truffle
annotate src/share/vm/runtime/javaCalls.cpp @ 9126:bc26f978b0ce
HotSpotResolvedObjectType: implement hasFinalizeSubclass() correctly
don't use the (wrong) cached value, but ask the runtime on each request.
Fixes regression on xml.* benchmarks @ specjvm2008. The problem was:
After the constructor of Object was deoptimized due to an assumption violation,
it was recompiled again after some time. However, on recompilation, the value
of hasFinalizeSubclass for the class was not updated and it was compiled again
with a, now wrong, assumption, which then triggers deoptimization again.
This was repeated until it hit the recompilation limit (defined by
PerMethodRecompilationCutoff), and therefore only executed by the interpreter
from now on, causing the performance regression.
author | Bernhard Urban <bernhard.urban@jku.at> |
---|---|
date | Mon, 15 Apr 2013 19:54:58 +0200 |
parents | f94bb5d20e5d |
children | cefad50507d8 |
rev | line source |
---|---|
0 | 1 /* |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3960
diff
changeset
|
2 * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. |
0 | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | |
5 * This code is free software; you can redistribute it and/or modify it | |
6 * under the terms of the GNU General Public License version 2 only, as | |
7 * published by the Free Software Foundation. | |
8 * | |
9 * This code is distributed in the hope that it will be useful, but WITHOUT | |
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
12 * version 2 for more details (a copy is included in the LICENSE file that | |
13 * accompanied this code). | |
14 * | |
15 * You should have received a copy of the GNU General Public License version | |
16 * 2 along with this work; if not, write to the Free Software Foundation, | |
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
18 * | |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1506
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1506
diff
changeset
|
20 * or visit www.oracle.com if you need additional information or have any |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1506
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
1972 | 25 #include "precompiled.hpp" |
26 #include "classfile/systemDictionary.hpp" | |
27 #include "classfile/vmSymbols.hpp" | |
28 #include "code/nmethod.hpp" | |
29 #include "compiler/compileBroker.hpp" | |
30 #include "interpreter/interpreter.hpp" | |
31 #include "interpreter/linkResolver.hpp" | |
32 #include "memory/universe.inline.hpp" | |
33 #include "oops/oop.inline.hpp" | |
34 #include "prims/jniCheck.hpp" | |
35 #include "runtime/compilationPolicy.hpp" | |
36 #include "runtime/handles.inline.hpp" | |
37 #include "runtime/interfaceSupport.hpp" | |
38 #include "runtime/javaCalls.hpp" | |
39 #include "runtime/mutexLocker.hpp" | |
40 #include "runtime/signature.hpp" | |
41 #include "runtime/stubRoutines.hpp" | |
8151
b8f261ba79c6
Minimize diff to plain HotSpot version.
Thomas Wuerthinger <thomas.wuerthinger@oracle.com>
parents:
7771
diff
changeset
|
42 #include "runtime/thread.inline.hpp" |
0 | 43 |
44 // ----------------------------------------------------- | |
45 // Implementation of JavaCallWrapper | |
46 | |
47 JavaCallWrapper::JavaCallWrapper(methodHandle callee_method, Handle receiver, JavaValue* result, TRAPS) { | |
48 JavaThread* thread = (JavaThread *)THREAD; | |
49 bool clear_pending_exception = true; | |
50 | |
51 guarantee(thread->is_Java_thread(), "crucial check - the VM thread cannot and must not escape to Java code"); | |
52 assert(!thread->owns_locks(), "must release all locks when leaving VM"); | |
53 guarantee(!thread->is_Compiler_thread(), "cannot make java calls from the compiler"); | |
54 _result = result; | |
55 | |
56 // Allocate handle block for Java code. This must be done before we change thread_state to _thread_in_Java_or_stub, | |
57 // since it can potentially block. | |
58 JNIHandleBlock* new_handles = JNIHandleBlock::allocate_block(thread); | |
59 | |
60 // After this, we are official in JavaCode. This needs to be done before we change any of the thread local | |
61 // info, since we cannot find oops before the new information is set up completely. | |
62 ThreadStateTransition::transition(thread, _thread_in_vm, _thread_in_Java); | |
63 | |
64 // Make sure that we handle asynchronous stops and suspends _before_ we clear all thread state | |
65 // in JavaCallWrapper::JavaCallWrapper(). This way, we can decide if we need to do any pd actions | |
66 // to prepare for stop/suspend (flush register windows on sparcs, cache sp, or other state). | |
67 if (thread->has_special_runtime_exit_condition()) { | |
68 thread->handle_special_runtime_exit_condition(); | |
69 if (HAS_PENDING_EXCEPTION) { | |
70 clear_pending_exception = false; | |
71 } | |
72 } | |
73 | |
74 | |
75 // Make sure to set the oop's after the thread transition - since we can block there. No one is GC'ing | |
76 // the JavaCallWrapper before the entry frame is on the stack. | |
77 _callee_method = callee_method(); | |
78 _receiver = receiver(); | |
79 | |
80 #ifdef CHECK_UNHANDLED_OOPS | |
81 THREAD->allow_unhandled_oop(&_receiver); | |
82 #endif // CHECK_UNHANDLED_OOPS | |
83 | |
84 _thread = (JavaThread *)thread; | |
85 _handles = _thread->active_handles(); // save previous handle block & Java frame linkage | |
86 | |
87 // For the profiler, the last_Java_frame information in thread must always be in | |
88 // legal state. We have no last Java frame if last_Java_sp == NULL so | |
89 // the valid transition is to clear _last_Java_sp and then reset the rest of | |
90 // the (platform specific) state. | |
91 | |
92 _anchor.copy(_thread->frame_anchor()); | |
93 _thread->frame_anchor()->clear(); | |
94 | |
95 debug_only(_thread->inc_java_call_counter()); | |
96 _thread->set_active_handles(new_handles); // install new handle block and reset Java frame linkage | |
97 | |
98 assert (_thread->thread_state() != _thread_in_native, "cannot set native pc to NULL"); | |
99 | |
100 // clear any pending exception in thread (native calls start with no exception pending) | |
101 if(clear_pending_exception) { | |
102 _thread->clear_pending_exception(); | |
103 } | |
104 | |
105 if (_anchor.last_Java_sp() == NULL) { | |
106 _thread->record_base_of_stack_pointer(); | |
107 } | |
108 } | |
109 | |
110 | |
111 JavaCallWrapper::~JavaCallWrapper() { | |
112 assert(_thread == JavaThread::current(), "must still be the same thread"); | |
113 | |
114 // restore previous handle block & Java frame linkage | |
115 JNIHandleBlock *_old_handles = _thread->active_handles(); | |
116 _thread->set_active_handles(_handles); | |
117 | |
118 _thread->frame_anchor()->zap(); | |
119 | |
120 debug_only(_thread->dec_java_call_counter()); | |
121 | |
122 if (_anchor.last_Java_sp() == NULL) { | |
123 _thread->set_base_of_stack_pointer(NULL); | |
124 } | |
125 | |
126 | |
127 // Old thread-local info. has been restored. We are not back in the VM. | |
128 ThreadStateTransition::transition_from_java(_thread, _thread_in_vm); | |
129 | |
130 // State has been restored now make the anchor frame visible for the profiler. | |
131 // Do this after the transition because this allows us to put an assert | |
132 // the Java->vm transition which checks to see that stack is not walkable | |
133 // on sparc/ia64 which will catch violations of the reseting of last_Java_frame | |
134 // invariants (i.e. _flags always cleared on return to Java) | |
135 | |
136 _thread->frame_anchor()->copy(&_anchor); | |
137 | |
138 // Release handles after we are marked as being inside the VM again, since this | |
139 // operation might block | |
140 JNIHandleBlock::release_block(_old_handles, _thread); | |
141 } | |
142 | |
143 | |
144 void JavaCallWrapper::oops_do(OopClosure* f) { | |
145 f->do_oop((oop*)&_receiver); | |
146 handles()->oops_do(f); | |
147 } | |
148 | |
149 | |
150 // Helper methods | |
151 static BasicType runtime_type_from(JavaValue* result) { | |
152 switch (result->get_type()) { | |
153 case T_BOOLEAN: // fall through | |
154 case T_CHAR : // fall through | |
155 case T_SHORT : // fall through | |
156 case T_INT : // fall through | |
157 #ifndef _LP64 | |
158 case T_OBJECT : // fall through | |
159 case T_ARRAY : // fall through | |
160 #endif | |
161 case T_BYTE : // fall through | |
162 case T_VOID : return T_INT; | |
163 case T_LONG : return T_LONG; | |
164 case T_FLOAT : return T_FLOAT; | |
165 case T_DOUBLE : return T_DOUBLE; | |
166 #ifdef _LP64 | |
167 case T_ARRAY : // fall through | |
168 case T_OBJECT: return T_OBJECT; | |
169 #endif | |
170 } | |
171 ShouldNotReachHere(); | |
172 return T_ILLEGAL; | |
173 } | |
174 | |
175 // ===== object constructor calls ===== | |
176 | |
177 void JavaCalls::call_default_constructor(JavaThread* thread, methodHandle method, Handle receiver, TRAPS) { | |
178 assert(method->name() == vmSymbols::object_initializer_name(), "Should only be called for default constructor"); | |
179 assert(method->signature() == vmSymbols::void_method_signature(), "Should only be called for default constructor"); | |
180 | |
6940
18fb7da42534
8000725: NPG: method_holder() and pool_holder() and pool_holder field should be InstanceKlass
coleenp
parents:
6725
diff
changeset
|
181 InstanceKlass* ik = method->method_holder(); |
0 | 182 if (ik->is_initialized() && ik->has_vanilla_constructor()) { |
183 // safe to skip constructor call | |
184 } else { | |
185 static JavaValue result(T_VOID); | |
186 JavaCallArguments args(receiver); | |
187 call(&result, method, &args, CHECK); | |
188 } | |
189 } | |
190 | |
1421
6223633ce7dd
changed VMExit/VMEntries to non-static, added eclipse c++ project, CIR interface changes
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1407
diff
changeset
|
191 // ============ Interface calls ============ |
6223633ce7dd
changed VMExit/VMEntries to non-static, added eclipse c++ project, CIR interface changes
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1407
diff
changeset
|
192 |
2182
9569fdf936ff
Made merge compile.
Thomas Wuerthinger <wuerthinger@ssw.jku.at>
parents:
2181
diff
changeset
|
193 void JavaCalls::call_interface(JavaValue* result, KlassHandle spec_klass, Symbol* name, Symbol* signature, JavaCallArguments* args, TRAPS) { |
1421
6223633ce7dd
changed VMExit/VMEntries to non-static, added eclipse c++ project, CIR interface changes
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1407
diff
changeset
|
194 CallInfo callinfo; |
6223633ce7dd
changed VMExit/VMEntries to non-static, added eclipse c++ project, CIR interface changes
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1407
diff
changeset
|
195 Handle receiver = args->receiver(); |
6948
e522a00b91aa
Merge with http://hg.openjdk.java.net/hsx/hsx25/hotspot/ after NPG - C++ build works
Doug Simon <doug.simon@oracle.com>
diff
changeset
|
196 KlassHandle recvrKlass(THREAD, receiver.is_null() ? (Klass*)NULL : receiver->klass()); |
1421
6223633ce7dd
changed VMExit/VMEntries to non-static, added eclipse c++ project, CIR interface changes
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1407
diff
changeset
|
197 LinkResolver::resolve_interface_call( |
6223633ce7dd
changed VMExit/VMEntries to non-static, added eclipse c++ project, CIR interface changes
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1407
diff
changeset
|
198 callinfo, receiver, recvrKlass, spec_klass, name, signature, |
6223633ce7dd
changed VMExit/VMEntries to non-static, added eclipse c++ project, CIR interface changes
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1407
diff
changeset
|
199 KlassHandle(), false, true, CHECK); |
6223633ce7dd
changed VMExit/VMEntries to non-static, added eclipse c++ project, CIR interface changes
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1407
diff
changeset
|
200 methodHandle method = callinfo.selected_method(); |
6223633ce7dd
changed VMExit/VMEntries to non-static, added eclipse c++ project, CIR interface changes
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1407
diff
changeset
|
201 assert(method.not_null(), "should have thrown exception"); |
6223633ce7dd
changed VMExit/VMEntries to non-static, added eclipse c++ project, CIR interface changes
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1407
diff
changeset
|
202 |
6223633ce7dd
changed VMExit/VMEntries to non-static, added eclipse c++ project, CIR interface changes
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1407
diff
changeset
|
203 // Invoke the method |
6223633ce7dd
changed VMExit/VMEntries to non-static, added eclipse c++ project, CIR interface changes
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1407
diff
changeset
|
204 JavaCalls::call(result, method, args, CHECK); |
6223633ce7dd
changed VMExit/VMEntries to non-static, added eclipse c++ project, CIR interface changes
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1407
diff
changeset
|
205 } |
6223633ce7dd
changed VMExit/VMEntries to non-static, added eclipse c++ project, CIR interface changes
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1407
diff
changeset
|
206 |
6223633ce7dd
changed VMExit/VMEntries to non-static, added eclipse c++ project, CIR interface changes
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1407
diff
changeset
|
207 |
0 | 208 // ============ Virtual calls ============ |
209 | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
210 void JavaCalls::call_virtual(JavaValue* result, KlassHandle spec_klass, Symbol* name, Symbol* signature, JavaCallArguments* args, TRAPS) { |
0 | 211 CallInfo callinfo; |
212 Handle receiver = args->receiver(); | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3960
diff
changeset
|
213 KlassHandle recvrKlass(THREAD, receiver.is_null() ? (Klass*)NULL : receiver->klass()); |
0 | 214 LinkResolver::resolve_virtual_call( |
215 callinfo, receiver, recvrKlass, spec_klass, name, signature, | |
216 KlassHandle(), false, true, CHECK); | |
217 methodHandle method = callinfo.selected_method(); | |
218 assert(method.not_null(), "should have thrown exception"); | |
219 | |
220 // Invoke the method | |
221 JavaCalls::call(result, method, args, CHECK); | |
222 } | |
223 | |
224 | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
225 void JavaCalls::call_virtual(JavaValue* result, Handle receiver, KlassHandle spec_klass, Symbol* name, Symbol* signature, TRAPS) { |
0 | 226 JavaCallArguments args(receiver); // One oop argument |
227 call_virtual(result, spec_klass, name, signature, &args, CHECK); | |
228 } | |
229 | |
230 | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
231 void JavaCalls::call_virtual(JavaValue* result, Handle receiver, KlassHandle spec_klass, Symbol* name, Symbol* signature, Handle arg1, TRAPS) { |
0 | 232 JavaCallArguments args(receiver); // One oop argument |
233 args.push_oop(arg1); | |
234 call_virtual(result, spec_klass, name, signature, &args, CHECK); | |
235 } | |
236 | |
237 | |
238 | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
239 void JavaCalls::call_virtual(JavaValue* result, Handle receiver, KlassHandle spec_klass, Symbol* name, Symbol* signature, Handle arg1, Handle arg2, TRAPS) { |
0 | 240 JavaCallArguments args(receiver); // One oop argument |
241 args.push_oop(arg1); | |
242 args.push_oop(arg2); | |
243 call_virtual(result, spec_klass, name, signature, &args, CHECK); | |
244 } | |
245 | |
246 | |
247 // ============ Special calls ============ | |
248 | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
249 void JavaCalls::call_special(JavaValue* result, KlassHandle klass, Symbol* name, Symbol* signature, JavaCallArguments* args, TRAPS) { |
0 | 250 CallInfo callinfo; |
251 LinkResolver::resolve_special_call(callinfo, klass, name, signature, KlassHandle(), false, CHECK); | |
252 methodHandle method = callinfo.selected_method(); | |
253 assert(method.not_null(), "should have thrown exception"); | |
254 | |
255 // Invoke the method | |
256 JavaCalls::call(result, method, args, CHECK); | |
257 } | |
258 | |
259 | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
260 void JavaCalls::call_special(JavaValue* result, Handle receiver, KlassHandle klass, Symbol* name, Symbol* signature, TRAPS) { |
0 | 261 JavaCallArguments args(receiver); // One oop argument |
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, TRAPS) { |
0 | 267 JavaCallArguments args(receiver); // One oop argument |
268 args.push_oop(arg1); | |
269 call_special(result, klass, name, signature, &args, CHECK); | |
270 } | |
271 | |
272 | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
273 void JavaCalls::call_special(JavaValue* result, Handle receiver, KlassHandle klass, Symbol* name, Symbol* signature, Handle arg1, Handle arg2, TRAPS) { |
0 | 274 JavaCallArguments args(receiver); // One oop argument |
275 args.push_oop(arg1); | |
276 args.push_oop(arg2); | |
277 call_special(result, klass, name, signature, &args, CHECK); | |
278 } | |
279 | |
280 | |
281 // ============ Static calls ============ | |
282 | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
283 void JavaCalls::call_static(JavaValue* result, KlassHandle klass, Symbol* name, Symbol* signature, JavaCallArguments* args, TRAPS) { |
0 | 284 CallInfo callinfo; |
285 LinkResolver::resolve_static_call(callinfo, klass, name, signature, KlassHandle(), false, true, CHECK); | |
286 methodHandle method = callinfo.selected_method(); | |
287 assert(method.not_null(), "should have thrown exception"); | |
288 | |
289 // Invoke the method | |
290 JavaCalls::call(result, method, args, CHECK); | |
291 } | |
292 | |
293 | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
294 void JavaCalls::call_static(JavaValue* result, KlassHandle klass, Symbol* name, Symbol* signature, TRAPS) { |
0 | 295 JavaCallArguments args; // No argument |
296 call_static(result, klass, name, signature, &args, CHECK); | |
297 } | |
298 | |
299 | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
300 void JavaCalls::call_static(JavaValue* result, KlassHandle klass, Symbol* name, Symbol* signature, Handle arg1, TRAPS) { |
0 | 301 JavaCallArguments args(arg1); // One oop argument |
302 call_static(result, klass, name, signature, &args, CHECK); | |
303 } | |
304 | |
305 | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
306 void JavaCalls::call_static(JavaValue* result, KlassHandle klass, Symbol* name, Symbol* signature, Handle arg1, Handle arg2, TRAPS) { |
0 | 307 JavaCallArguments args; // One oop argument |
308 args.push_oop(arg1); | |
309 args.push_oop(arg2); | |
310 call_static(result, klass, name, signature, &args, CHECK); | |
311 } | |
312 | |
313 | |
314 // ------------------------------------------------- | |
315 // Implementation of JavaCalls (low level) | |
316 | |
317 | |
318 void JavaCalls::call(JavaValue* result, methodHandle method, JavaCallArguments* args, TRAPS) { | |
319 // Check if we need to wrap a potential OS exception handler around thread | |
320 // This is used for e.g. Win32 structured exception handlers | |
321 assert(THREAD->is_Java_thread(), "only JavaThreads can make JavaCalls"); | |
322 // Need to wrap each and everytime, since there might be native code down the | |
323 // stack that has installed its own exception handlers | |
8151
b8f261ba79c6
Minimize diff to plain HotSpot version.
Thomas Wuerthinger <thomas.wuerthinger@oracle.com>
parents:
7771
diff
changeset
|
324 os::os_exception_wrapper(call_helper, result, &method, args, THREAD); |
0 | 325 } |
326 | |
8151
b8f261ba79c6
Minimize diff to plain HotSpot version.
Thomas Wuerthinger <thomas.wuerthinger@oracle.com>
parents:
7771
diff
changeset
|
327 void JavaCalls::call_helper(JavaValue* result, methodHandle* m, JavaCallArguments* args, TRAPS) { |
0 | 328 methodHandle method = *m; |
329 JavaThread* thread = (JavaThread*)THREAD; | |
330 assert(thread->is_Java_thread(), "must be called by a java thread"); | |
331 assert(method.not_null(), "must have a method to call"); | |
332 assert(!SafepointSynchronize::is_at_safepoint(), "call to Java code during VM operation"); | |
333 assert(!thread->handle_area()->no_handle_mark_active(), "cannot call out to Java here"); | |
334 | |
335 | |
336 CHECK_UNHANDLED_OOPS_ONLY(thread->clear_unhandled_oops();) | |
337 | |
465
dc16daa0329d
6739363: Xcheck jni doesn't check native function arguments
poonam
parents:
0
diff
changeset
|
338 // Verify the arguments |
dc16daa0329d
6739363: Xcheck jni doesn't check native function arguments
poonam
parents:
0
diff
changeset
|
339 |
dc16daa0329d
6739363: Xcheck jni doesn't check native function arguments
poonam
parents:
0
diff
changeset
|
340 if (CheckJNICalls) { |
dc16daa0329d
6739363: Xcheck jni doesn't check native function arguments
poonam
parents:
0
diff
changeset
|
341 args->verify(method, result->get_type(), thread); |
dc16daa0329d
6739363: Xcheck jni doesn't check native function arguments
poonam
parents:
0
diff
changeset
|
342 } |
dc16daa0329d
6739363: Xcheck jni doesn't check native function arguments
poonam
parents:
0
diff
changeset
|
343 else debug_only(args->verify(method, result->get_type(), thread)); |
0 | 344 |
7771
f10843a2d961
Remove assumption that methods without bytecodes are empty.
Roland Schatz <roland.schatz@oracle.com>
parents:
7212
diff
changeset
|
345 #ifndef GRAAL |
0 | 346 // Ignore call if method is empty |
347 if (method->is_empty_method()) { | |
348 assert(result->get_type() == T_VOID, "an empty method must return a void value"); | |
349 return; | |
350 } | |
7771
f10843a2d961
Remove assumption that methods without bytecodes are empty.
Roland Schatz <roland.schatz@oracle.com>
parents:
7212
diff
changeset
|
351 #endif |
0 | 352 |
8151
b8f261ba79c6
Minimize diff to plain HotSpot version.
Thomas Wuerthinger <thomas.wuerthinger@oracle.com>
parents:
7771
diff
changeset
|
353 |
0 | 354 #ifdef ASSERT |
6940
18fb7da42534
8000725: NPG: method_holder() and pool_holder() and pool_holder field should be InstanceKlass
coleenp
parents:
6725
diff
changeset
|
355 { InstanceKlass* holder = method->method_holder(); |
0 | 356 // A klass might not be initialized since JavaCall's might be used during the executing of |
357 // the <clinit>. For example, a Thread.start might start executing on an object that is | |
358 // not fully initialized! (bad Java programming style) | |
6940
18fb7da42534
8000725: NPG: method_holder() and pool_holder() and pool_holder field should be InstanceKlass
coleenp
parents:
6725
diff
changeset
|
359 assert(holder->is_linked(), "rewritting must have taken place"); |
0 | 360 } |
361 #endif | |
362 | |
363 | |
364 assert(!thread->is_Compiler_thread(), "cannot compile from the compiler"); | |
1783 | 365 if (CompilationPolicy::must_be_compiled(method)) { |
0 | 366 CompileBroker::compile_method(method, InvocationEntryBci, |
3837
43f9d800f276
7066339: Tiered: policy should make consistent decisions about osr levels
iveresov
parents:
3272
diff
changeset
|
367 CompilationPolicy::policy()->initial_compile_level(), |
1783 | 368 methodHandle(), 0, "must_be_compiled", CHECK); |
0 | 369 } |
370 | |
371 // Since the call stub sets up like the interpreter we call the from_interpreted_entry | |
372 // so we can go compiled via a i2c. Otherwise initial entry method will always | |
373 // run interpreted. | |
374 address entry_point = method->from_interpreted_entry(); | |
375 if (JvmtiExport::can_post_interpreter_events() && thread->is_interp_only_mode()) { | |
376 entry_point = method->interpreter_entry(); | |
377 } | |
378 | |
379 // Figure out if the result value is an oop or not (Note: This is a different value | |
380 // than result_type. result_type will be T_INT of oops. (it is about size) | |
381 BasicType result_type = runtime_type_from(result); | |
382 bool oop_result_flag = (result->get_type() == T_OBJECT || result->get_type() == T_ARRAY); | |
383 | |
384 // NOTE: if we move the computation of the result_val_address inside | |
385 // the call to call_stub, the optimizer produces wrong code. | |
386 intptr_t* result_val_address = (intptr_t*)(result->get_value_addr()); | |
387 | |
388 // Find receiver | |
389 Handle receiver = (!method->is_static()) ? args->receiver() : Handle(); | |
390 | |
391 // When we reenter Java, we need to reenable the yellow zone which | |
392 // might already be disabled when we are in VM. | |
393 if (thread->stack_yellow_zone_disabled()) { | |
394 thread->reguard_stack(); | |
395 } | |
396 | |
397 // Check that there are shadow pages available before changing thread state | |
398 // to Java | |
399 if (!os::stack_shadow_pages_available(THREAD, method)) { | |
400 // Throw stack overflow exception with preinitialized exception. | |
3272
01147d8aac1d
7009923: JSR 292: VM crash in JavaThread::last_frame
coleenp
parents:
2426
diff
changeset
|
401 Exceptions::throw_stack_overflow_exception(THREAD, __FILE__, __LINE__, method); |
0 | 402 return; |
403 } else { | |
404 // Touch pages checked if the OS needs them to be touched to be mapped. | |
405 os::bang_stack_shadow_pages(); | |
406 } | |
407 | |
8151
b8f261ba79c6
Minimize diff to plain HotSpot version.
Thomas Wuerthinger <thomas.wuerthinger@oracle.com>
parents:
7771
diff
changeset
|
408 #ifdef GRAAL |
b8f261ba79c6
Minimize diff to plain HotSpot version.
Thomas Wuerthinger <thomas.wuerthinger@oracle.com>
parents:
7771
diff
changeset
|
409 nmethod* nm = args->alternative_target(); |
4993
897b7d18bebc
added RiCompiledMethod.execute and the required VM infrastructure
Lukas Stadler <lukas.stadler@jku.at>
parents:
4981
diff
changeset
|
410 if (nm != NULL) { |
897b7d18bebc
added RiCompiledMethod.execute and the required VM infrastructure
Lukas Stadler <lukas.stadler@jku.at>
parents:
4981
diff
changeset
|
411 if (nm->is_alive()) { |
4996
11ce128f8d28
fix for RiCompiledMethod.execute
Lukas Stadler <lukas.stadler@jku.at>
parents:
4993
diff
changeset
|
412 ((JavaThread*) THREAD)->set_graal_alternate_call_target(nm->verified_entry_point()); |
4993
897b7d18bebc
added RiCompiledMethod.execute and the required VM infrastructure
Lukas Stadler <lukas.stadler@jku.at>
parents:
4981
diff
changeset
|
413 entry_point = method->adapter()->get_i2c_entry(); |
897b7d18bebc
added RiCompiledMethod.execute and the required VM infrastructure
Lukas Stadler <lukas.stadler@jku.at>
parents:
4981
diff
changeset
|
414 } else { |
9023
f94bb5d20e5d
Rename MethodInvalidatedException to InvalidInstalledCodeException (and make it a checked exception). Make sure that a compiled code object can always be directly called without first doing a check on the native method pointer.
Thomas Wuerthinger <thomas.wuerthinger@oracle.com>
parents:
8151
diff
changeset
|
415 THROW(vmSymbols::com_oracle_graal_api_code_InvalidInstalledCodeException()); |
4993
897b7d18bebc
added RiCompiledMethod.execute and the required VM infrastructure
Lukas Stadler <lukas.stadler@jku.at>
parents:
4981
diff
changeset
|
416 } |
8151
b8f261ba79c6
Minimize diff to plain HotSpot version.
Thomas Wuerthinger <thomas.wuerthinger@oracle.com>
parents:
7771
diff
changeset
|
417 } |
4993
897b7d18bebc
added RiCompiledMethod.execute and the required VM infrastructure
Lukas Stadler <lukas.stadler@jku.at>
parents:
4981
diff
changeset
|
418 #endif |
5747
120820e30baa
added basic high-level interpreter support to HotSpot
Christian Haeubl <haeubl@ssw.jku.at>
parents:
4996
diff
changeset
|
419 |
0 | 420 // do call |
421 { JavaCallWrapper link(method, receiver, result, CHECK); | |
422 { HandleMark hm(thread); // HandleMark used by HandleMarkCleaner | |
423 | |
424 StubRoutines::call_stub()( | |
425 (address)&link, | |
426 // (intptr_t*)&(result->_value), // see NOTE above (compiler problem) | |
427 result_val_address, // see NOTE above (compiler problem) | |
428 result_type, | |
429 method(), | |
430 entry_point, | |
431 args->parameters(), | |
432 args->size_of_parameters(), | |
433 CHECK | |
434 ); | |
435 | |
436 result = link.result(); // circumvent MS C++ 5.0 compiler bug (result is clobbered across call) | |
437 // Preserve oop return value across possible gc points | |
438 if (oop_result_flag) { | |
439 thread->set_vm_result((oop) result->get_jobject()); | |
440 } | |
441 } | |
442 } // Exit JavaCallWrapper (can block - potential return oop must be preserved) | |
443 | |
444 // Check if a thread stop or suspend should be executed | |
445 // The following assert was not realistic. Thread.stop can set that bit at any moment. | |
446 //assert(!thread->has_special_runtime_exit_condition(), "no async. exceptions should be installed"); | |
447 | |
448 // Restore possible oop return | |
449 if (oop_result_flag) { | |
450 result->set_jobject((jobject)thread->vm_result()); | |
451 thread->set_vm_result(NULL); | |
452 } | |
453 } | |
454 | |
8151
b8f261ba79c6
Minimize diff to plain HotSpot version.
Thomas Wuerthinger <thomas.wuerthinger@oracle.com>
parents:
7771
diff
changeset
|
455 |
0 | 456 //-------------------------------------------------------------------------------------- |
457 // Implementation of JavaCallArguments | |
458 | |
459 intptr_t* JavaCallArguments::parameters() { | |
460 // First convert all handles to oops | |
461 for(int i = 0; i < _size; i++) { | |
462 if (_is_oop[i]) { | |
463 // Handle conversion | |
464 _value[i] = (intptr_t)Handle::raw_resolve((oop *)_value[i]); | |
465 } | |
466 } | |
467 // Return argument vector | |
1506 | 468 return _value; |
0 | 469 } |
470 | |
471 | |
472 class SignatureChekker : public SignatureIterator { | |
473 private: | |
474 bool *_is_oop; | |
475 int _pos; | |
476 BasicType _return_type; | |
465
dc16daa0329d
6739363: Xcheck jni doesn't check native function arguments
poonam
parents:
0
diff
changeset
|
477 intptr_t* _value; |
dc16daa0329d
6739363: Xcheck jni doesn't check native function arguments
poonam
parents:
0
diff
changeset
|
478 Thread* _thread; |
0 | 479 |
480 public: | |
481 bool _is_return; | |
482 | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
483 SignatureChekker(Symbol* signature, BasicType return_type, bool is_static, bool* is_oop, intptr_t* value, Thread* thread) : SignatureIterator(signature) { |
0 | 484 _is_oop = is_oop; |
485 _is_return = false; | |
486 _return_type = return_type; | |
487 _pos = 0; | |
465
dc16daa0329d
6739363: Xcheck jni doesn't check native function arguments
poonam
parents:
0
diff
changeset
|
488 _value = value; |
dc16daa0329d
6739363: Xcheck jni doesn't check native function arguments
poonam
parents:
0
diff
changeset
|
489 _thread = thread; |
dc16daa0329d
6739363: Xcheck jni doesn't check native function arguments
poonam
parents:
0
diff
changeset
|
490 |
0 | 491 if (!is_static) { |
492 check_value(true); // Receiver must be an oop | |
493 } | |
494 } | |
495 | |
496 void check_value(bool type) { | |
497 guarantee(_is_oop[_pos++] == type, "signature does not match pushed arguments"); | |
498 } | |
499 | |
500 void check_doing_return(bool state) { _is_return = state; } | |
501 | |
502 void check_return_type(BasicType t) { | |
503 guarantee(_is_return && t == _return_type, "return type does not match"); | |
504 } | |
505 | |
506 void check_int(BasicType t) { | |
507 if (_is_return) { | |
508 check_return_type(t); | |
509 return; | |
510 } | |
511 check_value(false); | |
512 } | |
513 | |
514 void check_double(BasicType t) { check_long(t); } | |
515 | |
516 void check_long(BasicType t) { | |
517 if (_is_return) { | |
518 check_return_type(t); | |
519 return; | |
520 } | |
521 | |
522 check_value(false); | |
523 check_value(false); | |
524 } | |
525 | |
526 void check_obj(BasicType t) { | |
527 if (_is_return) { | |
528 check_return_type(t); | |
529 return; | |
530 } | |
465
dc16daa0329d
6739363: Xcheck jni doesn't check native function arguments
poonam
parents:
0
diff
changeset
|
531 |
dc16daa0329d
6739363: Xcheck jni doesn't check native function arguments
poonam
parents:
0
diff
changeset
|
532 // verify handle and the oop pointed to by handle |
dc16daa0329d
6739363: Xcheck jni doesn't check native function arguments
poonam
parents:
0
diff
changeset
|
533 int p = _pos; |
dc16daa0329d
6739363: Xcheck jni doesn't check native function arguments
poonam
parents:
0
diff
changeset
|
534 bool bad = false; |
dc16daa0329d
6739363: Xcheck jni doesn't check native function arguments
poonam
parents:
0
diff
changeset
|
535 // If argument is oop |
dc16daa0329d
6739363: Xcheck jni doesn't check native function arguments
poonam
parents:
0
diff
changeset
|
536 if (_is_oop[p]) { |
dc16daa0329d
6739363: Xcheck jni doesn't check native function arguments
poonam
parents:
0
diff
changeset
|
537 intptr_t v = _value[p]; |
dc16daa0329d
6739363: Xcheck jni doesn't check native function arguments
poonam
parents:
0
diff
changeset
|
538 if (v != 0 ) { |
dc16daa0329d
6739363: Xcheck jni doesn't check native function arguments
poonam
parents:
0
diff
changeset
|
539 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
|
540 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
|
541 if (CheckJNICalls && bad) { |
dc16daa0329d
6739363: Xcheck jni doesn't check native function arguments
poonam
parents:
0
diff
changeset
|
542 ReportJNIFatalError((JavaThread*)_thread, "Bad JNI oop argument"); |
dc16daa0329d
6739363: Xcheck jni doesn't check native function arguments
poonam
parents:
0
diff
changeset
|
543 } |
dc16daa0329d
6739363: Xcheck jni doesn't check native function arguments
poonam
parents:
0
diff
changeset
|
544 } |
dc16daa0329d
6739363: Xcheck jni doesn't check native function arguments
poonam
parents:
0
diff
changeset
|
545 // for the regular debug case. |
dc16daa0329d
6739363: Xcheck jni doesn't check native function arguments
poonam
parents:
0
diff
changeset
|
546 assert(!bad, "Bad JNI oop argument"); |
dc16daa0329d
6739363: Xcheck jni doesn't check native function arguments
poonam
parents:
0
diff
changeset
|
547 } |
dc16daa0329d
6739363: Xcheck jni doesn't check native function arguments
poonam
parents:
0
diff
changeset
|
548 |
0 | 549 check_value(true); |
550 } | |
551 | |
552 void do_bool() { check_int(T_BOOLEAN); } | |
553 void do_char() { check_int(T_CHAR); } | |
554 void do_float() { check_int(T_FLOAT); } | |
555 void do_double() { check_double(T_DOUBLE); } | |
556 void do_byte() { check_int(T_BYTE); } | |
557 void do_short() { check_int(T_SHORT); } | |
558 void do_int() { check_int(T_INT); } | |
559 void do_long() { check_long(T_LONG); } | |
560 void do_void() { check_return_type(T_VOID); } | |
561 void do_object(int begin, int end) { check_obj(T_OBJECT); } | |
562 void do_array(int begin, int end) { check_obj(T_OBJECT); } | |
563 }; | |
564 | |
465
dc16daa0329d
6739363: Xcheck jni doesn't check native function arguments
poonam
parents:
0
diff
changeset
|
565 |
0 | 566 void JavaCallArguments::verify(methodHandle method, BasicType return_type, |
567 Thread *thread) { | |
568 guarantee(method->size_of_parameters() == size_of_parameters(), "wrong no. of arguments pushed"); | |
569 | |
570 // Treat T_OBJECT and T_ARRAY as the same | |
571 if (return_type == T_ARRAY) return_type = T_OBJECT; | |
572 | |
573 // Check that oop information is correct | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
574 Symbol* signature = method->signature(); |
0 | 575 |
465
dc16daa0329d
6739363: Xcheck jni doesn't check native function arguments
poonam
parents:
0
diff
changeset
|
576 SignatureChekker sc(signature, return_type, method->is_static(),_is_oop, _value, thread); |
0 | 577 sc.iterate_parameters(); |
578 sc.check_doing_return(true); | |
579 sc.iterate_returntype(); | |
580 } |