Mercurial > hg > graal-compiler
annotate src/share/vm/interpreter/interpreterRuntime.cpp @ 3992:d1bdeef3e3e2
7098282: G1: assert(interval >= 0) failed: Sanity check, referencePolicy.cpp: 76
Summary: There is a race between one thread successfully forwarding and copying the klass mirror for the SoftReference class (including the static master clock) and another thread attempting to use the master clock while attempting to discover a soft reference object. Maintain a shadow copy of the soft reference master clock and use the shadow during reference discovery and reference processing.
Reviewed-by: tonyp, brutisso, ysr
author | johnc |
---|---|
date | Wed, 12 Oct 2011 10:25:51 -0700 |
parents | e6b1331a51d2 |
children | 12d38ffcba2a |
rev | line source |
---|---|
0 | 1 /* |
2142 | 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:
1507
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1507
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:
1507
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 "compiler/compileBroker.hpp" | |
29 #include "gc_interface/collectedHeap.hpp" | |
30 #include "interpreter/interpreter.hpp" | |
31 #include "interpreter/interpreterRuntime.hpp" | |
32 #include "interpreter/linkResolver.hpp" | |
33 #include "interpreter/templateTable.hpp" | |
34 #include "memory/oopFactory.hpp" | |
35 #include "memory/universe.inline.hpp" | |
36 #include "oops/constantPoolOop.hpp" | |
37 #include "oops/cpCacheOop.hpp" | |
38 #include "oops/instanceKlass.hpp" | |
39 #include "oops/methodDataOop.hpp" | |
40 #include "oops/objArrayKlass.hpp" | |
41 #include "oops/oop.inline.hpp" | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2144
diff
changeset
|
42 #include "oops/symbol.hpp" |
1972 | 43 #include "prims/jvmtiExport.hpp" |
44 #include "prims/nativeLookup.hpp" | |
45 #include "runtime/biasedLocking.hpp" | |
46 #include "runtime/compilationPolicy.hpp" | |
47 #include "runtime/deoptimization.hpp" | |
48 #include "runtime/fieldDescriptor.hpp" | |
49 #include "runtime/handles.inline.hpp" | |
50 #include "runtime/interfaceSupport.hpp" | |
51 #include "runtime/java.hpp" | |
52 #include "runtime/jfieldIDWorkaround.hpp" | |
53 #include "runtime/osThread.hpp" | |
54 #include "runtime/sharedRuntime.hpp" | |
55 #include "runtime/stubRoutines.hpp" | |
56 #include "runtime/synchronizer.hpp" | |
57 #include "runtime/threadCritical.hpp" | |
58 #include "utilities/events.hpp" | |
59 #ifdef TARGET_ARCH_x86 | |
60 # include "vm_version_x86.hpp" | |
61 #endif | |
62 #ifdef TARGET_ARCH_sparc | |
63 # include "vm_version_sparc.hpp" | |
64 #endif | |
65 #ifdef TARGET_ARCH_zero | |
66 # include "vm_version_zero.hpp" | |
67 #endif | |
2192
b92c45f2bc75
7016023: Enable building ARM and PPC from src/closed repository
bobv
parents:
2177
diff
changeset
|
68 #ifdef TARGET_ARCH_arm |
b92c45f2bc75
7016023: Enable building ARM and PPC from src/closed repository
bobv
parents:
2177
diff
changeset
|
69 # include "vm_version_arm.hpp" |
b92c45f2bc75
7016023: Enable building ARM and PPC from src/closed repository
bobv
parents:
2177
diff
changeset
|
70 #endif |
b92c45f2bc75
7016023: Enable building ARM and PPC from src/closed repository
bobv
parents:
2177
diff
changeset
|
71 #ifdef TARGET_ARCH_ppc |
b92c45f2bc75
7016023: Enable building ARM and PPC from src/closed repository
bobv
parents:
2177
diff
changeset
|
72 # include "vm_version_ppc.hpp" |
b92c45f2bc75
7016023: Enable building ARM and PPC from src/closed repository
bobv
parents:
2177
diff
changeset
|
73 #endif |
1972 | 74 #ifdef COMPILER2 |
75 #include "opto/runtime.hpp" | |
76 #endif | |
0 | 77 |
78 class UnlockFlagSaver { | |
79 private: | |
80 JavaThread* _thread; | |
81 bool _do_not_unlock; | |
82 public: | |
83 UnlockFlagSaver(JavaThread* t) { | |
84 _thread = t; | |
85 _do_not_unlock = t->do_not_unlock_if_synchronized(); | |
86 t->set_do_not_unlock_if_synchronized(false); | |
87 } | |
88 ~UnlockFlagSaver() { | |
89 _thread->set_do_not_unlock_if_synchronized(_do_not_unlock); | |
90 } | |
91 }; | |
92 | |
93 //------------------------------------------------------------------------------------------------------------------------ | |
94 // State accessors | |
95 | |
96 void InterpreterRuntime::set_bcp_and_mdp(address bcp, JavaThread *thread) { | |
97 last_frame(thread).interpreter_frame_set_bcp(bcp); | |
98 if (ProfileInterpreter) { | |
99 // ProfileTraps uses MDOs independently of ProfileInterpreter. | |
100 // That is why we must check both ProfileInterpreter and mdo != NULL. | |
101 methodDataOop mdo = last_frame(thread).interpreter_frame_method()->method_data(); | |
102 if (mdo != NULL) { | |
103 NEEDS_CLEANUP; | |
104 last_frame(thread).interpreter_frame_set_mdp(mdo->bci_to_dp(last_frame(thread).interpreter_frame_bci())); | |
105 } | |
106 } | |
107 } | |
108 | |
109 //------------------------------------------------------------------------------------------------------------------------ | |
110 // Constants | |
111 | |
112 | |
113 IRT_ENTRY(void, InterpreterRuntime::ldc(JavaThread* thread, bool wide)) | |
114 // access constant pool | |
115 constantPoolOop pool = method(thread)->constants(); | |
1565 | 116 int index = wide ? get_index_u2(thread, Bytecodes::_ldc_w) : get_index_u1(thread, Bytecodes::_ldc); |
0 | 117 constantTag tag = pool->tag_at(index); |
118 | |
119 if (tag.is_unresolved_klass() || tag.is_klass()) { | |
120 klassOop klass = pool->klass_at(index, CHECK); | |
2376
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2357
diff
changeset
|
121 oop java_class = klass->java_mirror(); |
0 | 122 thread->set_vm_result(java_class); |
123 } else { | |
124 #ifdef ASSERT | |
125 // If we entered this runtime routine, we believed the tag contained | |
126 // an unresolved string, an unresolved class or a resolved class. | |
127 // However, another thread could have resolved the unresolved string | |
128 // or class by the time we go there. | |
129 assert(tag.is_unresolved_string()|| tag.is_string(), "expected string"); | |
130 #endif | |
131 oop s_oop = pool->string_at(index, CHECK); | |
132 thread->set_vm_result(s_oop); | |
133 } | |
134 IRT_END | |
135 | |
1602 | 136 IRT_ENTRY(void, InterpreterRuntime::resolve_ldc(JavaThread* thread, Bytecodes::Code bytecode)) { |
137 assert(bytecode == Bytecodes::_fast_aldc || | |
138 bytecode == Bytecodes::_fast_aldc_w, "wrong bc"); | |
139 ResourceMark rm(thread); | |
140 methodHandle m (thread, method(thread)); | |
2142 | 141 Bytecode_loadconstant ldc(m, bci(thread)); |
3403
7db2b9499c36
7046732: JSR 292 assert(result == cpce->f1()) failed: expected result for assembly code
never
parents:
2460
diff
changeset
|
142 oop result = ldc.resolve_constant(CHECK); |
7db2b9499c36
7046732: JSR 292 assert(result == cpce->f1()) failed: expected result for assembly code
never
parents:
2460
diff
changeset
|
143 #ifdef ASSERT |
7db2b9499c36
7046732: JSR 292 assert(result == cpce->f1()) failed: expected result for assembly code
never
parents:
2460
diff
changeset
|
144 { |
7db2b9499c36
7046732: JSR 292 assert(result == cpce->f1()) failed: expected result for assembly code
never
parents:
2460
diff
changeset
|
145 // The bytecode wrappers aren't GC-safe so construct a new one |
7db2b9499c36
7046732: JSR 292 assert(result == cpce->f1()) failed: expected result for assembly code
never
parents:
2460
diff
changeset
|
146 Bytecode_loadconstant ldc2(m, bci(thread)); |
7db2b9499c36
7046732: JSR 292 assert(result == cpce->f1()) failed: expected result for assembly code
never
parents:
2460
diff
changeset
|
147 ConstantPoolCacheEntry* cpce = m->constants()->cache()->entry_at(ldc2.cache_index()); |
7db2b9499c36
7046732: JSR 292 assert(result == cpce->f1()) failed: expected result for assembly code
never
parents:
2460
diff
changeset
|
148 assert(result == cpce->f1(), "expected result for assembly code"); |
7db2b9499c36
7046732: JSR 292 assert(result == cpce->f1()) failed: expected result for assembly code
never
parents:
2460
diff
changeset
|
149 } |
7db2b9499c36
7046732: JSR 292 assert(result == cpce->f1()) failed: expected result for assembly code
never
parents:
2460
diff
changeset
|
150 #endif |
1602 | 151 } |
152 IRT_END | |
153 | |
0 | 154 |
155 //------------------------------------------------------------------------------------------------------------------------ | |
156 // Allocation | |
157 | |
158 IRT_ENTRY(void, InterpreterRuntime::_new(JavaThread* thread, constantPoolOopDesc* pool, int index)) | |
159 klassOop k_oop = pool->klass_at(index, CHECK); | |
160 instanceKlassHandle klass (THREAD, k_oop); | |
161 | |
162 // Make sure we are not instantiating an abstract klass | |
163 klass->check_valid_for_instantiation(true, CHECK); | |
164 | |
165 // Make sure klass is initialized | |
166 klass->initialize(CHECK); | |
167 | |
168 // At this point the class may not be fully initialized | |
169 // because of recursive initialization. If it is fully | |
170 // initialized & has_finalized is not set, we rewrite | |
171 // it into its fast version (Note: no locking is needed | |
172 // here since this is an atomic byte write and can be | |
173 // done more than once). | |
174 // | |
175 // Note: In case of classes with has_finalized we don't | |
176 // rewrite since that saves us an extra check in | |
177 // the fast version which then would call the | |
178 // slow version anyway (and do a call back into | |
179 // Java). | |
180 // If we have a breakpoint, then we don't rewrite | |
181 // because the _breakpoint bytecode would be lost. | |
182 oop obj = klass->allocate_instance(CHECK); | |
183 thread->set_vm_result(obj); | |
184 IRT_END | |
185 | |
186 | |
187 IRT_ENTRY(void, InterpreterRuntime::newarray(JavaThread* thread, BasicType type, jint size)) | |
188 oop obj = oopFactory::new_typeArray(type, size, CHECK); | |
189 thread->set_vm_result(obj); | |
190 IRT_END | |
191 | |
192 | |
193 IRT_ENTRY(void, InterpreterRuntime::anewarray(JavaThread* thread, constantPoolOopDesc* pool, int index, jint size)) | |
194 // Note: no oopHandle for pool & klass needed since they are not used | |
195 // anymore after new_objArray() and no GC can happen before. | |
196 // (This may have to change if this code changes!) | |
197 klassOop klass = pool->klass_at(index, CHECK); | |
198 objArrayOop obj = oopFactory::new_objArray(klass, size, CHECK); | |
199 thread->set_vm_result(obj); | |
200 IRT_END | |
201 | |
202 | |
203 IRT_ENTRY(void, InterpreterRuntime::multianewarray(JavaThread* thread, jint* first_size_address)) | |
204 // We may want to pass in more arguments - could make this slightly faster | |
205 constantPoolOop constants = method(thread)->constants(); | |
1565 | 206 int i = get_index_u2(thread, Bytecodes::_multianewarray); |
0 | 207 klassOop klass = constants->klass_at(i, CHECK); |
208 int nof_dims = number_of_dimensions(thread); | |
209 assert(oop(klass)->is_klass(), "not a class"); | |
210 assert(nof_dims >= 1, "multianewarray rank must be nonzero"); | |
211 | |
212 // We must create an array of jints to pass to multi_allocate. | |
213 ResourceMark rm(thread); | |
214 const int small_dims = 10; | |
215 jint dim_array[small_dims]; | |
216 jint *dims = &dim_array[0]; | |
217 if (nof_dims > small_dims) { | |
218 dims = (jint*) NEW_RESOURCE_ARRAY(jint, nof_dims); | |
219 } | |
220 for (int index = 0; index < nof_dims; index++) { | |
221 // offset from first_size_address is addressed as local[index] | |
222 int n = Interpreter::local_offset_in_bytes(index)/jintSize; | |
223 dims[index] = first_size_address[n]; | |
224 } | |
225 oop obj = arrayKlass::cast(klass)->multi_allocate(nof_dims, dims, CHECK); | |
226 thread->set_vm_result(obj); | |
227 IRT_END | |
228 | |
229 | |
230 IRT_ENTRY(void, InterpreterRuntime::register_finalizer(JavaThread* thread, oopDesc* obj)) | |
231 assert(obj->is_oop(), "must be a valid oop"); | |
232 assert(obj->klass()->klass_part()->has_finalizer(), "shouldn't be here otherwise"); | |
233 instanceKlass::register_finalizer(instanceOop(obj), CHECK); | |
234 IRT_END | |
235 | |
236 | |
237 // Quicken instance-of and check-cast bytecodes | |
238 IRT_ENTRY(void, InterpreterRuntime::quicken_io_cc(JavaThread* thread)) | |
239 // Force resolving; quicken the bytecode | |
1565 | 240 int which = get_index_u2(thread, Bytecodes::_checkcast); |
0 | 241 constantPoolOop cpool = method(thread)->constants(); |
242 // We'd expect to assert that we're only here to quicken bytecodes, but in a multithreaded | |
243 // program we might have seen an unquick'd bytecode in the interpreter but have another | |
244 // thread quicken the bytecode before we get here. | |
245 // assert( cpool->tag_at(which).is_unresolved_klass(), "should only come here to quicken bytecodes" ); | |
246 klassOop klass = cpool->klass_at(which, CHECK); | |
247 thread->set_vm_result(klass); | |
248 IRT_END | |
249 | |
250 | |
251 //------------------------------------------------------------------------------------------------------------------------ | |
252 // Exceptions | |
253 | |
254 // Assume the compiler is (or will be) interested in this event. | |
255 // If necessary, create an MDO to hold the information, and record it. | |
256 void InterpreterRuntime::note_trap(JavaThread* thread, int reason, TRAPS) { | |
257 assert(ProfileTraps, "call me only if profiling"); | |
258 methodHandle trap_method(thread, method(thread)); | |
1793
d257356e35f0
6939224: MethodHandle.invokeGeneric needs to perform the correct set of conversions
jrose
parents:
1783
diff
changeset
|
259 |
0 | 260 if (trap_method.not_null()) { |
261 methodDataHandle trap_mdo(thread, trap_method->method_data()); | |
262 if (trap_mdo.is_null()) { | |
263 methodOopDesc::build_interpreter_method_data(trap_method, THREAD); | |
264 if (HAS_PENDING_EXCEPTION) { | |
265 assert((PENDING_EXCEPTION->is_a(SystemDictionary::OutOfMemoryError_klass())), "we expect only an OOM error here"); | |
266 CLEAR_PENDING_EXCEPTION; | |
267 } | |
268 trap_mdo = methodDataHandle(thread, trap_method->method_data()); | |
269 // and fall through... | |
270 } | |
271 if (trap_mdo.not_null()) { | |
272 // Update per-method count of trap events. The interpreter | |
273 // is updating the MDO to simulate the effect of compiler traps. | |
274 int trap_bci = trap_method->bci_from(bcp(thread)); | |
275 Deoptimization::update_method_data_from_interpreter(trap_mdo, trap_bci, reason); | |
276 } | |
277 } | |
278 } | |
279 | |
280 static Handle get_preinitialized_exception(klassOop k, TRAPS) { | |
281 // get klass | |
282 instanceKlass* klass = instanceKlass::cast(k); | |
283 assert(klass->is_initialized(), | |
284 "this klass should have been initialized during VM initialization"); | |
285 // create instance - do not call constructor since we may have no | |
286 // (java) stack space left (should assert constructor is empty) | |
287 Handle exception; | |
288 oop exception_oop = klass->allocate_instance(CHECK_(exception)); | |
289 exception = Handle(THREAD, exception_oop); | |
290 if (StackTraceInThrowable) { | |
291 java_lang_Throwable::fill_in_stack_trace(exception); | |
292 } | |
293 return exception; | |
294 } | |
295 | |
296 // Special handling for stack overflow: since we don't have any (java) stack | |
297 // space left we use the pre-allocated & pre-initialized StackOverflowError | |
298 // klass to create an stack overflow error instance. We do not call its | |
299 // constructor for the same reason (it is empty, anyway). | |
300 IRT_ENTRY(void, InterpreterRuntime::throw_StackOverflowError(JavaThread* thread)) | |
301 Handle exception = get_preinitialized_exception( | |
302 SystemDictionary::StackOverflowError_klass(), | |
303 CHECK); | |
304 THROW_HANDLE(exception); | |
305 IRT_END | |
306 | |
307 | |
308 IRT_ENTRY(void, InterpreterRuntime::create_exception(JavaThread* thread, char* name, char* message)) | |
309 // lookup exception klass | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2144
diff
changeset
|
310 TempNewSymbol s = SymbolTable::new_symbol(name, CHECK); |
0 | 311 if (ProfileTraps) { |
312 if (s == vmSymbols::java_lang_ArithmeticException()) { | |
313 note_trap(thread, Deoptimization::Reason_div0_check, CHECK); | |
314 } else if (s == vmSymbols::java_lang_NullPointerException()) { | |
315 note_trap(thread, Deoptimization::Reason_null_check, CHECK); | |
316 } | |
317 } | |
318 // create exception | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2144
diff
changeset
|
319 Handle exception = Exceptions::new_exception(thread, s, message); |
0 | 320 thread->set_vm_result(exception()); |
321 IRT_END | |
322 | |
323 | |
324 IRT_ENTRY(void, InterpreterRuntime::create_klass_exception(JavaThread* thread, char* name, oopDesc* obj)) | |
325 ResourceMark rm(thread); | |
326 const char* klass_name = Klass::cast(obj->klass())->external_name(); | |
327 // lookup exception klass | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2144
diff
changeset
|
328 TempNewSymbol s = SymbolTable::new_symbol(name, CHECK); |
0 | 329 if (ProfileTraps) { |
330 note_trap(thread, Deoptimization::Reason_class_check, CHECK); | |
331 } | |
332 // create exception, with klass name as detail message | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2144
diff
changeset
|
333 Handle exception = Exceptions::new_exception(thread, s, klass_name); |
0 | 334 thread->set_vm_result(exception()); |
335 IRT_END | |
336 | |
337 | |
338 IRT_ENTRY(void, InterpreterRuntime::throw_ArrayIndexOutOfBoundsException(JavaThread* thread, char* name, jint index)) | |
339 char message[jintAsStringSize]; | |
340 // lookup exception klass | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2144
diff
changeset
|
341 TempNewSymbol s = SymbolTable::new_symbol(name, CHECK); |
0 | 342 if (ProfileTraps) { |
343 note_trap(thread, Deoptimization::Reason_range_check, CHECK); | |
344 } | |
345 // create exception | |
346 sprintf(message, "%d", index); | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2144
diff
changeset
|
347 THROW_MSG(s, message); |
0 | 348 IRT_END |
349 | |
350 IRT_ENTRY(void, InterpreterRuntime::throw_ClassCastException( | |
351 JavaThread* thread, oopDesc* obj)) | |
352 | |
353 ResourceMark rm(thread); | |
354 char* message = SharedRuntime::generate_class_cast_message( | |
355 thread, Klass::cast(obj->klass())->external_name()); | |
356 | |
357 if (ProfileTraps) { | |
358 note_trap(thread, Deoptimization::Reason_class_check, CHECK); | |
359 } | |
360 | |
361 // create exception | |
362 THROW_MSG(vmSymbols::java_lang_ClassCastException(), message); | |
363 IRT_END | |
364 | |
365 // exception_handler_for_exception(...) returns the continuation address, | |
366 // the exception oop (via TLS) and sets the bci/bcp for the continuation. | |
367 // The exception oop is returned to make sure it is preserved over GC (it | |
368 // is only on the stack if the exception was thrown explicitly via athrow). | |
369 // During this operation, the expression stack contains the values for the | |
370 // bci where the exception happened. If the exception was propagated back | |
371 // from a call, the expression stack contains the values for the bci at the | |
372 // invoke w/o arguments (i.e., as if one were inside the call). | |
373 IRT_ENTRY(address, InterpreterRuntime::exception_handler_for_exception(JavaThread* thread, oopDesc* exception)) | |
374 | |
375 Handle h_exception(thread, exception); | |
376 methodHandle h_method (thread, method(thread)); | |
377 constantPoolHandle h_constants(thread, h_method->constants()); | |
378 typeArrayHandle h_extable (thread, h_method->exception_table()); | |
379 bool should_repeat; | |
380 int handler_bci; | |
1602 | 381 int current_bci = bci(thread); |
0 | 382 |
383 // Need to do this check first since when _do_not_unlock_if_synchronized | |
384 // is set, we don't want to trigger any classloading which may make calls | |
385 // into java, or surprisingly find a matching exception handler for bci 0 | |
386 // since at this moment the method hasn't been "officially" entered yet. | |
387 if (thread->do_not_unlock_if_synchronized()) { | |
388 ResourceMark rm; | |
389 assert(current_bci == 0, "bci isn't zero for do_not_unlock_if_synchronized"); | |
390 thread->set_vm_result(exception); | |
391 #ifdef CC_INTERP | |
392 return (address) -1; | |
393 #else | |
394 return Interpreter::remove_activation_entry(); | |
395 #endif | |
396 } | |
397 | |
398 do { | |
399 should_repeat = false; | |
400 | |
401 // assertions | |
402 #ifdef ASSERT | |
403 assert(h_exception.not_null(), "NULL exceptions should be handled by athrow"); | |
404 assert(h_exception->is_oop(), "just checking"); | |
405 // Check that exception is a subclass of Throwable, otherwise we have a VerifyError | |
1142 | 406 if (!(h_exception->is_a(SystemDictionary::Throwable_klass()))) { |
0 | 407 if (ExitVMOnVerifyError) vm_exit(-1); |
408 ShouldNotReachHere(); | |
409 } | |
410 #endif | |
411 | |
412 // tracing | |
413 if (TraceExceptions) { | |
414 ttyLocker ttyl; | |
415 ResourceMark rm(thread); | |
416 tty->print_cr("Exception <%s> (" INTPTR_FORMAT ")", h_exception->print_value_string(), (address)h_exception()); | |
417 tty->print_cr(" thrown in interpreter method <%s>", h_method->print_value_string()); | |
418 tty->print_cr(" at bci %d for thread " INTPTR_FORMAT, current_bci, thread); | |
419 } | |
420 // Don't go paging in something which won't be used. | |
421 // else if (h_extable->length() == 0) { | |
422 // // disabled for now - interpreter is not using shortcut yet | |
423 // // (shortcut is not to call runtime if we have no exception handlers) | |
424 // // warning("performance bug: should not call runtime if method has no exception handlers"); | |
425 // } | |
426 // for AbortVMOnException flag | |
427 NOT_PRODUCT(Exceptions::debug_check_abort(h_exception)); | |
428 | |
429 // exception handler lookup | |
430 KlassHandle h_klass(THREAD, h_exception->klass()); | |
431 handler_bci = h_method->fast_exception_handler_bci_for(h_klass, current_bci, THREAD); | |
432 if (HAS_PENDING_EXCEPTION) { | |
433 // We threw an exception while trying to find the exception handler. | |
434 // Transfer the new exception to the exception handle which will | |
435 // be set into thread local storage, and do another lookup for an | |
436 // exception handler for this exception, this time starting at the | |
437 // BCI of the exception handler which caused the exception to be | |
438 // thrown (bug 4307310). | |
439 h_exception = Handle(THREAD, PENDING_EXCEPTION); | |
440 CLEAR_PENDING_EXCEPTION; | |
441 if (handler_bci >= 0) { | |
442 current_bci = handler_bci; | |
443 should_repeat = true; | |
444 } | |
445 } | |
446 } while (should_repeat == true); | |
447 | |
448 // notify JVMTI of an exception throw; JVMTI will detect if this is a first | |
449 // time throw or a stack unwinding throw and accordingly notify the debugger | |
1213
6deeaebad47a
6902182: 4/4 Starting with jdwp agent should not incur performance penalty
dcubed
parents:
1142
diff
changeset
|
450 if (JvmtiExport::can_post_on_exceptions()) { |
0 | 451 JvmtiExport::post_exception_throw(thread, h_method(), bcp(thread), h_exception()); |
452 } | |
453 | |
454 #ifdef CC_INTERP | |
455 address continuation = (address)(intptr_t) handler_bci; | |
456 #else | |
457 address continuation = NULL; | |
458 #endif | |
459 address handler_pc = NULL; | |
460 if (handler_bci < 0 || !thread->reguard_stack((address) &continuation)) { | |
461 // Forward exception to callee (leaving bci/bcp untouched) because (a) no | |
462 // handler in this method, or (b) after a stack overflow there is not yet | |
463 // enough stack space available to reprotect the stack. | |
464 #ifndef CC_INTERP | |
465 continuation = Interpreter::remove_activation_entry(); | |
466 #endif | |
467 // Count this for compilation purposes | |
468 h_method->interpreter_throwout_increment(); | |
469 } else { | |
470 // handler in this method => change bci/bcp to handler bci/bcp and continue there | |
471 handler_pc = h_method->code_base() + handler_bci; | |
472 #ifndef CC_INTERP | |
473 set_bcp_and_mdp(handler_pc, thread); | |
474 continuation = Interpreter::dispatch_table(vtos)[*handler_pc]; | |
475 #endif | |
476 } | |
477 // notify debugger of an exception catch | |
478 // (this is good for exceptions caught in native methods as well) | |
1213
6deeaebad47a
6902182: 4/4 Starting with jdwp agent should not incur performance penalty
dcubed
parents:
1142
diff
changeset
|
479 if (JvmtiExport::can_post_on_exceptions()) { |
0 | 480 JvmtiExport::notice_unwind_due_to_exception(thread, h_method(), handler_pc, h_exception(), (handler_pc != NULL)); |
481 } | |
482 | |
483 thread->set_vm_result(h_exception()); | |
484 return continuation; | |
485 IRT_END | |
486 | |
487 | |
488 IRT_ENTRY(void, InterpreterRuntime::throw_pending_exception(JavaThread* thread)) | |
489 assert(thread->has_pending_exception(), "must only ne called if there's an exception pending"); | |
490 // nothing to do - eventually we should remove this code entirely (see comments @ call sites) | |
491 IRT_END | |
492 | |
493 | |
494 IRT_ENTRY(void, InterpreterRuntime::throw_AbstractMethodError(JavaThread* thread)) | |
495 THROW(vmSymbols::java_lang_AbstractMethodError()); | |
496 IRT_END | |
497 | |
498 | |
499 IRT_ENTRY(void, InterpreterRuntime::throw_IncompatibleClassChangeError(JavaThread* thread)) | |
500 THROW(vmSymbols::java_lang_IncompatibleClassChangeError()); | |
501 IRT_END | |
502 | |
503 | |
504 //------------------------------------------------------------------------------------------------------------------------ | |
505 // Fields | |
506 // | |
507 | |
508 IRT_ENTRY(void, InterpreterRuntime::resolve_get_put(JavaThread* thread, Bytecodes::Code bytecode)) | |
509 // resolve field | |
510 FieldAccessInfo info; | |
511 constantPoolHandle pool(thread, method(thread)->constants()); | |
3852
fdb992d83a87
7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents:
3791
diff
changeset
|
512 bool is_put = (bytecode == Bytecodes::_putfield || bytecode == Bytecodes::_putstatic); |
0 | 513 bool is_static = (bytecode == Bytecodes::_getstatic || bytecode == Bytecodes::_putstatic); |
514 | |
515 { | |
516 JvmtiHideSingleStepping jhss(thread); | |
1565 | 517 LinkResolver::resolve_field(info, pool, get_index_u2_cpcache(thread, bytecode), |
0 | 518 bytecode, false, CHECK); |
519 } // end JvmtiHideSingleStepping | |
520 | |
521 // check if link resolution caused cpCache to be updated | |
522 if (already_resolved(thread)) return; | |
523 | |
524 // compute auxiliary field attributes | |
525 TosState state = as_TosState(info.field_type()); | |
526 | |
527 // We need to delay resolving put instructions on final fields | |
528 // until we actually invoke one. This is required so we throw | |
529 // exceptions at the correct place. If we do not resolve completely | |
530 // in the current pass, leaving the put_code set to zero will | |
531 // cause the next put instruction to reresolve. | |
532 Bytecodes::Code put_code = (Bytecodes::Code)0; | |
533 | |
534 // We also need to delay resolving getstatic instructions until the | |
535 // class is intitialized. This is required so that access to the static | |
536 // field will call the initialization function every time until the class | |
537 // is completely initialized ala. in 2.17.5 in JVM Specification. | |
538 instanceKlass *klass = instanceKlass::cast(info.klass()->as_klassOop()); | |
539 bool uninitialized_static = ((bytecode == Bytecodes::_getstatic || bytecode == Bytecodes::_putstatic) && | |
540 !klass->is_initialized()); | |
541 Bytecodes::Code get_code = (Bytecodes::Code)0; | |
542 | |
543 if (!uninitialized_static) { | |
544 get_code = ((is_static) ? Bytecodes::_getstatic : Bytecodes::_getfield); | |
545 if (is_put || !info.access_flags().is_final()) { | |
546 put_code = ((is_static) ? Bytecodes::_putstatic : Bytecodes::_putfield); | |
547 } | |
548 } | |
549 | |
3852
fdb992d83a87
7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents:
3791
diff
changeset
|
550 if (is_put && !is_static && klass->is_subclass_of(SystemDictionary::CallSite_klass()) && (info.name() == vmSymbols::target_name())) { |
fdb992d83a87
7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents:
3791
diff
changeset
|
551 const jint direction = frame::interpreter_frame_expression_stack_direction(); |
fdb992d83a87
7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents:
3791
diff
changeset
|
552 oop call_site = *((oop*) thread->last_frame().interpreter_frame_tos_at(-1 * direction)); |
fdb992d83a87
7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents:
3791
diff
changeset
|
553 oop method_handle = *((oop*) thread->last_frame().interpreter_frame_tos_at( 0 * direction)); |
fdb992d83a87
7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents:
3791
diff
changeset
|
554 assert(call_site ->is_a(SystemDictionary::CallSite_klass()), "must be"); |
fdb992d83a87
7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents:
3791
diff
changeset
|
555 assert(method_handle->is_a(SystemDictionary::MethodHandle_klass()), "must be"); |
fdb992d83a87
7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents:
3791
diff
changeset
|
556 |
fdb992d83a87
7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents:
3791
diff
changeset
|
557 { |
3901
aa67216400d3
7085404: JSR 292: VolatileCallSites should have push notification too
twisti
parents:
3852
diff
changeset
|
558 // Walk all nmethods depending on this call site. |
3852
fdb992d83a87
7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents:
3791
diff
changeset
|
559 MutexLocker mu(Compile_lock, thread); |
fdb992d83a87
7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents:
3791
diff
changeset
|
560 Universe::flush_dependents_on(call_site, method_handle); |
fdb992d83a87
7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents:
3791
diff
changeset
|
561 } |
fdb992d83a87
7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents:
3791
diff
changeset
|
562 |
fdb992d83a87
7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents:
3791
diff
changeset
|
563 // Don't allow fast path for setting CallSite.target and sub-classes. |
fdb992d83a87
7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents:
3791
diff
changeset
|
564 put_code = (Bytecodes::Code) 0; |
fdb992d83a87
7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents:
3791
diff
changeset
|
565 } |
fdb992d83a87
7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents:
3791
diff
changeset
|
566 |
0 | 567 cache_entry(thread)->set_field( |
568 get_code, | |
569 put_code, | |
570 info.klass(), | |
571 info.field_index(), | |
572 info.field_offset(), | |
573 state, | |
574 info.access_flags().is_final(), | |
575 info.access_flags().is_volatile() | |
576 ); | |
577 IRT_END | |
578 | |
579 | |
580 //------------------------------------------------------------------------------------------------------------------------ | |
581 // Synchronization | |
582 // | |
583 // The interpreter's synchronization code is factored out so that it can | |
584 // be shared by method invocation and synchronized blocks. | |
585 //%note synchronization_3 | |
586 | |
587 static void trace_locking(Handle& h_locking_obj, bool is_locking) { | |
588 ObjectSynchronizer::trace_locking(h_locking_obj, false, true, is_locking); | |
589 } | |
590 | |
591 | |
592 //%note monitor_1 | |
593 IRT_ENTRY_NO_ASYNC(void, InterpreterRuntime::monitorenter(JavaThread* thread, BasicObjectLock* elem)) | |
594 #ifdef ASSERT | |
595 thread->last_frame().interpreter_frame_verify_monitor(elem); | |
596 #endif | |
597 if (PrintBiasedLockingStatistics) { | |
598 Atomic::inc(BiasedLocking::slow_path_entry_count_addr()); | |
599 } | |
600 Handle h_obj(thread, elem->obj()); | |
601 assert(Universe::heap()->is_in_reserved_or_null(h_obj()), | |
602 "must be NULL or an object"); | |
603 if (UseBiasedLocking) { | |
604 // Retry fast entry if bias is revoked to avoid unnecessary inflation | |
605 ObjectSynchronizer::fast_enter(h_obj, elem->lock(), true, CHECK); | |
606 } else { | |
607 ObjectSynchronizer::slow_enter(h_obj, elem->lock(), CHECK); | |
608 } | |
609 assert(Universe::heap()->is_in_reserved_or_null(elem->obj()), | |
610 "must be NULL or an object"); | |
611 #ifdef ASSERT | |
612 thread->last_frame().interpreter_frame_verify_monitor(elem); | |
613 #endif | |
614 IRT_END | |
615 | |
616 | |
617 //%note monitor_1 | |
618 IRT_ENTRY_NO_ASYNC(void, InterpreterRuntime::monitorexit(JavaThread* thread, BasicObjectLock* elem)) | |
619 #ifdef ASSERT | |
620 thread->last_frame().interpreter_frame_verify_monitor(elem); | |
621 #endif | |
622 Handle h_obj(thread, elem->obj()); | |
623 assert(Universe::heap()->is_in_reserved_or_null(h_obj()), | |
624 "must be NULL or an object"); | |
625 if (elem == NULL || h_obj()->is_unlocked()) { | |
626 THROW(vmSymbols::java_lang_IllegalMonitorStateException()); | |
627 } | |
628 ObjectSynchronizer::slow_exit(h_obj(), elem->lock(), thread); | |
629 // Free entry. This must be done here, since a pending exception might be installed on | |
630 // exit. If it is not cleared, the exception handling code will try to unlock the monitor again. | |
631 elem->set_obj(NULL); | |
632 #ifdef ASSERT | |
633 thread->last_frame().interpreter_frame_verify_monitor(elem); | |
634 #endif | |
635 IRT_END | |
636 | |
637 | |
638 IRT_ENTRY(void, InterpreterRuntime::throw_illegal_monitor_state_exception(JavaThread* thread)) | |
639 THROW(vmSymbols::java_lang_IllegalMonitorStateException()); | |
640 IRT_END | |
641 | |
642 | |
643 IRT_ENTRY(void, InterpreterRuntime::new_illegal_monitor_state_exception(JavaThread* thread)) | |
644 // Returns an illegal exception to install into the current thread. The | |
645 // pending_exception flag is cleared so normal exception handling does not | |
646 // trigger. Any current installed exception will be overwritten. This | |
647 // method will be called during an exception unwind. | |
648 | |
649 assert(!HAS_PENDING_EXCEPTION, "no pending exception"); | |
650 Handle exception(thread, thread->vm_result()); | |
651 assert(exception() != NULL, "vm result should be set"); | |
652 thread->set_vm_result(NULL); // clear vm result before continuing (may cause memory leaks and assert failures) | |
1142 | 653 if (!exception->is_a(SystemDictionary::ThreadDeath_klass())) { |
0 | 654 exception = get_preinitialized_exception( |
655 SystemDictionary::IllegalMonitorStateException_klass(), | |
656 CATCH); | |
657 } | |
658 thread->set_vm_result(exception()); | |
659 IRT_END | |
660 | |
661 | |
662 //------------------------------------------------------------------------------------------------------------------------ | |
663 // Invokes | |
664 | |
665 IRT_ENTRY(Bytecodes::Code, InterpreterRuntime::get_original_bytecode_at(JavaThread* thread, methodOopDesc* method, address bcp)) | |
666 return method->orig_bytecode_at(method->bci_from(bcp)); | |
667 IRT_END | |
668 | |
669 IRT_ENTRY(void, InterpreterRuntime::set_original_bytecode_at(JavaThread* thread, methodOopDesc* method, address bcp, Bytecodes::Code new_code)) | |
670 method->set_orig_bytecode_at(method->bci_from(bcp), new_code); | |
671 IRT_END | |
672 | |
673 IRT_ENTRY(void, InterpreterRuntime::_breakpoint(JavaThread* thread, methodOopDesc* method, address bcp)) | |
674 JvmtiExport::post_raw_breakpoint(thread, method, bcp); | |
675 IRT_END | |
676 | |
677 IRT_ENTRY(void, InterpreterRuntime::resolve_invoke(JavaThread* thread, Bytecodes::Code bytecode)) | |
678 // extract receiver from the outgoing argument list if necessary | |
679 Handle receiver(thread, NULL); | |
680 if (bytecode == Bytecodes::_invokevirtual || bytecode == Bytecodes::_invokeinterface) { | |
681 ResourceMark rm(thread); | |
682 methodHandle m (thread, method(thread)); | |
2142 | 683 Bytecode_invoke call(m, bci(thread)); |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2144
diff
changeset
|
684 Symbol* signature = call.signature(); |
0 | 685 receiver = Handle(thread, |
686 thread->last_frame().interpreter_callee_receiver(signature)); | |
687 assert(Universe::heap()->is_in_reserved_or_null(receiver()), | |
688 "sanity check"); | |
689 assert(receiver.is_null() || | |
690 Universe::heap()->is_in_reserved(receiver->klass()), | |
691 "sanity check"); | |
692 } | |
693 | |
694 // resolve method | |
695 CallInfo info; | |
696 constantPoolHandle pool(thread, method(thread)->constants()); | |
697 | |
698 { | |
699 JvmtiHideSingleStepping jhss(thread); | |
700 LinkResolver::resolve_invoke(info, receiver, pool, | |
1565 | 701 get_index_u2_cpcache(thread, bytecode), bytecode, CHECK); |
0 | 702 if (JvmtiExport::can_hotswap_or_post_breakpoint()) { |
703 int retry_count = 0; | |
704 while (info.resolved_method()->is_old()) { | |
705 // It is very unlikely that method is redefined more than 100 times | |
706 // in the middle of resolve. If it is looping here more than 100 times | |
707 // means then there could be a bug here. | |
708 guarantee((retry_count++ < 100), | |
709 "Could not resolve to latest version of redefined method"); | |
710 // method is redefined in the middle of resolve so re-try. | |
711 LinkResolver::resolve_invoke(info, receiver, pool, | |
1565 | 712 get_index_u2_cpcache(thread, bytecode), bytecode, CHECK); |
0 | 713 } |
714 } | |
715 } // end JvmtiHideSingleStepping | |
716 | |
717 // check if link resolution caused cpCache to be updated | |
718 if (already_resolved(thread)) return; | |
719 | |
720 if (bytecode == Bytecodes::_invokeinterface) { | |
721 | |
722 if (TraceItables && Verbose) { | |
723 ResourceMark rm(thread); | |
724 tty->print_cr("Resolving: klass: %s to method: %s", info.resolved_klass()->name()->as_C_string(), info.resolved_method()->name()->as_C_string()); | |
725 } | |
726 if (info.resolved_method()->method_holder() == | |
1142 | 727 SystemDictionary::Object_klass()) { |
0 | 728 // NOTE: THIS IS A FIX FOR A CORNER CASE in the JVM spec |
729 // (see also cpCacheOop.cpp for details) | |
730 methodHandle rm = info.resolved_method(); | |
731 assert(rm->is_final() || info.has_vtable_index(), | |
732 "should have been set already"); | |
733 cache_entry(thread)->set_method(bytecode, rm, info.vtable_index()); | |
734 } else { | |
735 // Setup itable entry | |
736 int index = klassItable::compute_itable_index(info.resolved_method()()); | |
737 cache_entry(thread)->set_interface_call(info.resolved_method(), index); | |
738 } | |
739 } else { | |
740 cache_entry(thread)->set_method( | |
741 bytecode, | |
742 info.resolved_method(), | |
743 info.vtable_index()); | |
744 } | |
745 IRT_END | |
746 | |
747 | |
1059
389049f3f393
6858164: invokedynamic code needs some cleanup (post-6655638)
jrose
parents:
941
diff
changeset
|
748 // First time execution: Resolve symbols, create a permanent CallSite object. |
726
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
710
diff
changeset
|
749 IRT_ENTRY(void, InterpreterRuntime::resolve_invokedynamic(JavaThread* thread)) { |
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
710
diff
changeset
|
750 ResourceMark rm(thread); |
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
710
diff
changeset
|
751 |
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
710
diff
changeset
|
752 assert(EnableInvokeDynamic, ""); |
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
710
diff
changeset
|
753 |
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
710
diff
changeset
|
754 const Bytecodes::Code bytecode = Bytecodes::_invokedynamic; |
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
710
diff
changeset
|
755 |
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
710
diff
changeset
|
756 methodHandle caller_method(thread, method(thread)); |
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
710
diff
changeset
|
757 |
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
710
diff
changeset
|
758 constantPoolHandle pool(thread, caller_method->constants()); |
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
710
diff
changeset
|
759 pool->set_invokedynamic(); // mark header to flag active call sites |
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
710
diff
changeset
|
760 |
1507
cd5dbf694d45
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
1506
diff
changeset
|
761 int caller_bci = 0; |
cd5dbf694d45
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
1506
diff
changeset
|
762 int site_index = 0; |
cd5dbf694d45
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
1506
diff
changeset
|
763 { address caller_bcp = bcp(thread); |
cd5dbf694d45
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
1506
diff
changeset
|
764 caller_bci = caller_method->bci_from(caller_bcp); |
cd5dbf694d45
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
1506
diff
changeset
|
765 site_index = Bytes::get_native_u4(caller_bcp+1); |
cd5dbf694d45
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
1506
diff
changeset
|
766 } |
2142 | 767 assert(site_index == InterpreterRuntime::bytecode(thread).get_index_u4(bytecode), ""); |
1507
cd5dbf694d45
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
1506
diff
changeset
|
768 assert(constantPoolCacheOopDesc::is_secondary_index(site_index), "proper format"); |
1059
389049f3f393
6858164: invokedynamic code needs some cleanup (post-6655638)
jrose
parents:
941
diff
changeset
|
769 // there is a second CPC entries that is of interest; it caches signature info: |
389049f3f393
6858164: invokedynamic code needs some cleanup (post-6655638)
jrose
parents:
941
diff
changeset
|
770 int main_index = pool->cache()->secondary_entry_at(site_index)->main_entry_index(); |
1913
3b2dea75431e
6984311: JSR 292 needs optional bootstrap method parameters
jrose
parents:
1903
diff
changeset
|
771 int pool_index = pool->cache()->entry_at(main_index)->constant_pool_index(); |
726
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
710
diff
changeset
|
772 |
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
710
diff
changeset
|
773 // first resolve the signature to a MH.invoke methodOop |
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
710
diff
changeset
|
774 if (!pool->cache()->entry_at(main_index)->is_resolved(bytecode)) { |
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
710
diff
changeset
|
775 JvmtiHideSingleStepping jhss(thread); |
1903 | 776 CallInfo callinfo; |
777 LinkResolver::resolve_invoke(callinfo, Handle(), pool, | |
1059
389049f3f393
6858164: invokedynamic code needs some cleanup (post-6655638)
jrose
parents:
941
diff
changeset
|
778 site_index, bytecode, CHECK); |
1660
083fde3b838e
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
1603
diff
changeset
|
779 // The main entry corresponds to a JVM_CONSTANT_InvokeDynamic, and serves |
726
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
710
diff
changeset
|
780 // as a common reference point for all invokedynamic call sites with |
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
710
diff
changeset
|
781 // that exact call descriptor. We will link it in the CP cache exactly |
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
710
diff
changeset
|
782 // as if it were an invokevirtual of MethodHandle.invoke. |
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
710
diff
changeset
|
783 pool->cache()->entry_at(main_index)->set_method( |
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
710
diff
changeset
|
784 bytecode, |
1903 | 785 callinfo.resolved_method(), |
786 callinfo.vtable_index()); | |
726
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
710
diff
changeset
|
787 } |
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
710
diff
changeset
|
788 |
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
710
diff
changeset
|
789 // The method (f2 entry) of the main entry is the MH.invoke for the |
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
710
diff
changeset
|
790 // invokedynamic target call signature. |
1660
083fde3b838e
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
1603
diff
changeset
|
791 oop f1_value = pool->cache()->entry_at(main_index)->f1(); |
083fde3b838e
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
1603
diff
changeset
|
792 methodHandle signature_invoker(THREAD, (methodOop) f1_value); |
1507
cd5dbf694d45
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
1506
diff
changeset
|
793 assert(signature_invoker.not_null() && signature_invoker->is_method() && signature_invoker->is_method_handle_invoke(), |
726
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
710
diff
changeset
|
794 "correct result from LinkResolver::resolve_invokedynamic"); |
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
710
diff
changeset
|
795 |
1913
3b2dea75431e
6984311: JSR 292 needs optional bootstrap method parameters
jrose
parents:
1903
diff
changeset
|
796 Handle info; // optional argument(s) in JVM_CONSTANT_InvokeDynamic |
1660
083fde3b838e
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
1603
diff
changeset
|
797 Handle bootm = SystemDictionary::find_bootstrap_method(caller_method, caller_bci, |
1913
3b2dea75431e
6984311: JSR 292 needs optional bootstrap method parameters
jrose
parents:
1903
diff
changeset
|
798 main_index, info, CHECK); |
2357
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2194
diff
changeset
|
799 if (!java_lang_invoke_MethodHandle::is_instance(bootm())) { |
1660
083fde3b838e
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
1603
diff
changeset
|
800 THROW_MSG(vmSymbols::java_lang_IllegalStateException(), |
083fde3b838e
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
1603
diff
changeset
|
801 "no bootstrap method found for invokedynamic"); |
083fde3b838e
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
1603
diff
changeset
|
802 } |
083fde3b838e
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
1603
diff
changeset
|
803 |
083fde3b838e
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
1603
diff
changeset
|
804 // Short circuit if CallSite has been bound already: |
083fde3b838e
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
1603
diff
changeset
|
805 if (!pool->cache()->secondary_entry_at(site_index)->is_f1_null()) |
083fde3b838e
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
1603
diff
changeset
|
806 return; |
083fde3b838e
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
1603
diff
changeset
|
807 |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2144
diff
changeset
|
808 Symbol* call_site_name = pool->name_ref_at(site_index); |
1507
cd5dbf694d45
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
1506
diff
changeset
|
809 |
726
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
710
diff
changeset
|
810 Handle call_site |
1507
cd5dbf694d45
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
1506
diff
changeset
|
811 = SystemDictionary::make_dynamic_call_site(bootm, |
cd5dbf694d45
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
1506
diff
changeset
|
812 // Callee information: |
726
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
710
diff
changeset
|
813 call_site_name, |
1507
cd5dbf694d45
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
1506
diff
changeset
|
814 signature_invoker, |
cd5dbf694d45
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
1506
diff
changeset
|
815 info, |
cd5dbf694d45
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
1506
diff
changeset
|
816 // Caller information: |
cd5dbf694d45
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
1506
diff
changeset
|
817 caller_method, |
cd5dbf694d45
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
1506
diff
changeset
|
818 caller_bci, |
726
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
710
diff
changeset
|
819 CHECK); |
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
710
diff
changeset
|
820 |
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
710
diff
changeset
|
821 // In the secondary entry, the f1 field is the call site, and the f2 (index) |
1507
cd5dbf694d45
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
1506
diff
changeset
|
822 // field is some data about the invoke site. Currently, it is just the BCI. |
cd5dbf694d45
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
1506
diff
changeset
|
823 // Later, it might be changed to help manage inlining dependencies. |
cd5dbf694d45
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
1506
diff
changeset
|
824 pool->cache()->secondary_entry_at(site_index)->set_dynamic_call(call_site, signature_invoker); |
726
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
710
diff
changeset
|
825 } |
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
710
diff
changeset
|
826 IRT_END |
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
710
diff
changeset
|
827 |
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
710
diff
changeset
|
828 |
0 | 829 //------------------------------------------------------------------------------------------------------------------------ |
830 // Miscellaneous | |
831 | |
832 | |
941 | 833 nmethod* InterpreterRuntime::frequency_counter_overflow(JavaThread* thread, address branch_bcp) { |
834 nmethod* nm = frequency_counter_overflow_inner(thread, branch_bcp); | |
835 assert(branch_bcp != NULL || nm == NULL, "always returns null for non OSR requests"); | |
836 if (branch_bcp != NULL && nm != NULL) { | |
837 // This was a successful request for an OSR nmethod. Because | |
838 // frequency_counter_overflow_inner ends with a safepoint check, | |
839 // nm could have been unloaded so look it up again. It's unsafe | |
840 // to examine nm directly since it might have been freed and used | |
841 // for something else. | |
842 frame fr = thread->last_frame(); | |
843 methodOop method = fr.interpreter_frame_method(); | |
844 int bci = method->bci_from(fr.interpreter_frame_bcp()); | |
1783 | 845 nm = method->lookup_osr_nmethod_for(bci, CompLevel_none, false); |
941 | 846 } |
847 return nm; | |
848 } | |
849 | |
0 | 850 IRT_ENTRY(nmethod*, |
941 | 851 InterpreterRuntime::frequency_counter_overflow_inner(JavaThread* thread, address branch_bcp)) |
0 | 852 // use UnlockFlagSaver to clear and restore the _do_not_unlock_if_synchronized |
853 // flag, in case this method triggers classloading which will call into Java. | |
854 UnlockFlagSaver fs(thread); | |
855 | |
856 frame fr = thread->last_frame(); | |
857 assert(fr.is_interpreted_frame(), "must come from interpreter"); | |
858 methodHandle method(thread, fr.interpreter_frame_method()); | |
1783 | 859 const int branch_bci = branch_bcp != NULL ? method->bci_from(branch_bcp) : InvocationEntryBci; |
860 const int bci = branch_bcp != NULL ? method->bci_from(fr.interpreter_frame_bcp()) : InvocationEntryBci; | |
861 | |
3791
2c359f27615c
7057120: Tiered: Allow C1 to inline methods with loops
iveresov
parents:
3781
diff
changeset
|
862 nmethod* osr_nm = CompilationPolicy::policy()->event(method, method, branch_bci, bci, CompLevel_none, NULL, thread); |
0 | 863 |
1783 | 864 if (osr_nm != NULL) { |
865 // We may need to do on-stack replacement which requires that no | |
866 // monitors in the activation are biased because their | |
867 // BasicObjectLocks will need to migrate during OSR. Force | |
868 // unbiasing of all monitors in the activation now (even though | |
869 // the OSR nmethod might be invalidated) because we don't have a | |
870 // safepoint opportunity later once the migration begins. | |
871 if (UseBiasedLocking) { | |
872 ResourceMark rm; | |
873 GrowableArray<Handle>* objects_to_revoke = new GrowableArray<Handle>(); | |
874 for( BasicObjectLock *kptr = fr.interpreter_frame_monitor_end(); | |
875 kptr < fr.interpreter_frame_monitor_begin(); | |
876 kptr = fr.next_monitor_in_interpreter_frame(kptr) ) { | |
877 if( kptr->obj() != NULL ) { | |
878 objects_to_revoke->append(Handle(THREAD, kptr->obj())); | |
879 } | |
0 | 880 } |
1783 | 881 BiasedLocking::revoke(objects_to_revoke); |
0 | 882 } |
883 } | |
1783 | 884 return osr_nm; |
0 | 885 IRT_END |
886 | |
887 IRT_LEAF(jint, InterpreterRuntime::bcp_to_di(methodOopDesc* method, address cur_bcp)) | |
888 assert(ProfileInterpreter, "must be profiling interpreter"); | |
889 int bci = method->bci_from(cur_bcp); | |
890 methodDataOop mdo = method->method_data(); | |
891 if (mdo == NULL) return 0; | |
892 return mdo->bci_to_di(bci); | |
893 IRT_END | |
894 | |
2118
dd031b2226de
4930919: race condition in MDO creation at back branch locations
iveresov
parents:
1986
diff
changeset
|
895 IRT_ENTRY(void, InterpreterRuntime::profile_method(JavaThread* thread)) |
0 | 896 // use UnlockFlagSaver to clear and restore the _do_not_unlock_if_synchronized |
897 // flag, in case this method triggers classloading which will call into Java. | |
898 UnlockFlagSaver fs(thread); | |
899 | |
900 assert(ProfileInterpreter, "must be profiling interpreter"); | |
901 frame fr = thread->last_frame(); | |
902 assert(fr.is_interpreted_frame(), "must come from interpreter"); | |
903 methodHandle method(thread, fr.interpreter_frame_method()); | |
904 methodOopDesc::build_interpreter_method_data(method, THREAD); | |
905 if (HAS_PENDING_EXCEPTION) { | |
906 assert((PENDING_EXCEPTION->is_a(SystemDictionary::OutOfMemoryError_klass())), "we expect only an OOM error here"); | |
907 CLEAR_PENDING_EXCEPTION; | |
908 // and fall through... | |
909 } | |
910 IRT_END | |
911 | |
912 | |
913 #ifdef ASSERT | |
914 IRT_LEAF(void, InterpreterRuntime::verify_mdp(methodOopDesc* method, address bcp, address mdp)) | |
915 assert(ProfileInterpreter, "must be profiling interpreter"); | |
916 | |
917 methodDataOop mdo = method->method_data(); | |
918 assert(mdo != NULL, "must not be null"); | |
919 | |
920 int bci = method->bci_from(bcp); | |
921 | |
922 address mdp2 = mdo->bci_to_dp(bci); | |
923 if (mdp != mdp2) { | |
924 ResourceMark rm; | |
925 ResetNoHandleMark rnm; // In a LEAF entry. | |
926 HandleMark hm; | |
927 tty->print_cr("FAILED verify : actual mdp %p expected mdp %p @ bci %d", mdp, mdp2, bci); | |
928 int current_di = mdo->dp_to_di(mdp); | |
929 int expected_di = mdo->dp_to_di(mdp2); | |
930 tty->print_cr(" actual di %d expected di %d", current_di, expected_di); | |
931 int expected_approx_bci = mdo->data_at(expected_di)->bci(); | |
932 int approx_bci = -1; | |
933 if (current_di >= 0) { | |
934 approx_bci = mdo->data_at(current_di)->bci(); | |
935 } | |
936 tty->print_cr(" actual bci is %d expected bci %d", approx_bci, expected_approx_bci); | |
937 mdo->print_on(tty); | |
938 method->print_codes(); | |
939 } | |
940 assert(mdp == mdp2, "wrong mdp"); | |
941 IRT_END | |
942 #endif // ASSERT | |
943 | |
944 IRT_ENTRY(void, InterpreterRuntime::update_mdp_for_ret(JavaThread* thread, int return_bci)) | |
945 assert(ProfileInterpreter, "must be profiling interpreter"); | |
946 ResourceMark rm(thread); | |
947 HandleMark hm(thread); | |
948 frame fr = thread->last_frame(); | |
949 assert(fr.is_interpreted_frame(), "must come from interpreter"); | |
950 methodDataHandle h_mdo(thread, fr.interpreter_frame_method()->method_data()); | |
951 | |
952 // Grab a lock to ensure atomic access to setting the return bci and | |
953 // the displacement. This can block and GC, invalidating all naked oops. | |
954 MutexLocker ml(RetData_lock); | |
955 | |
956 // ProfileData is essentially a wrapper around a derived oop, so we | |
957 // need to take the lock before making any ProfileData structures. | |
958 ProfileData* data = h_mdo->data_at(h_mdo->dp_to_di(fr.interpreter_frame_mdp())); | |
959 RetData* rdata = data->as_RetData(); | |
960 address new_mdp = rdata->fixup_ret(return_bci, h_mdo); | |
961 fr.interpreter_frame_set_mdp(new_mdp); | |
962 IRT_END | |
963 | |
964 | |
965 IRT_ENTRY(void, InterpreterRuntime::at_safepoint(JavaThread* thread)) | |
966 // We used to need an explict preserve_arguments here for invoke bytecodes. However, | |
967 // stack traversal automatically takes care of preserving arguments for invoke, so | |
968 // this is no longer needed. | |
969 | |
970 // IRT_END does an implicit safepoint check, hence we are guaranteed to block | |
971 // if this is called during a safepoint | |
972 | |
973 if (JvmtiExport::should_post_single_step()) { | |
974 // We are called during regular safepoints and when the VM is | |
975 // single stepping. If any thread is marked for single stepping, | |
976 // then we may have JVMTI work to do. | |
977 JvmtiExport::at_single_stepping_point(thread, method(thread), bcp(thread)); | |
978 } | |
979 IRT_END | |
980 | |
981 IRT_ENTRY(void, InterpreterRuntime::post_field_access(JavaThread *thread, oopDesc* obj, | |
982 ConstantPoolCacheEntry *cp_entry)) | |
983 | |
984 // check the access_flags for the field in the klass | |
2376
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2357
diff
changeset
|
985 |
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2357
diff
changeset
|
986 instanceKlass* ik = instanceKlass::cast(java_lang_Class::as_klassOop(cp_entry->f1())); |
0 | 987 int index = cp_entry->field_index(); |
3938 | 988 if ((ik->field_access_flags(index) & JVM_ACC_FIELD_ACCESS_WATCHED) == 0) return; |
0 | 989 |
990 switch(cp_entry->flag_state()) { | |
991 case btos: // fall through | |
992 case ctos: // fall through | |
993 case stos: // fall through | |
994 case itos: // fall through | |
995 case ftos: // fall through | |
996 case ltos: // fall through | |
997 case dtos: // fall through | |
998 case atos: break; | |
999 default: ShouldNotReachHere(); return; | |
1000 } | |
1001 bool is_static = (obj == NULL); | |
1002 HandleMark hm(thread); | |
1003 | |
1004 Handle h_obj; | |
1005 if (!is_static) { | |
1006 // non-static field accessors have an object, but we need a handle | |
1007 h_obj = Handle(thread, obj); | |
1008 } | |
2376
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2357
diff
changeset
|
1009 instanceKlassHandle h_cp_entry_f1(thread, java_lang_Class::as_klassOop(cp_entry->f1())); |
0 | 1010 jfieldID fid = jfieldIDWorkaround::to_jfieldID(h_cp_entry_f1, cp_entry->f2(), is_static); |
1011 JvmtiExport::post_field_access(thread, method(thread), bcp(thread), h_cp_entry_f1, h_obj, fid); | |
1012 IRT_END | |
1013 | |
1014 IRT_ENTRY(void, InterpreterRuntime::post_field_modification(JavaThread *thread, | |
1015 oopDesc* obj, ConstantPoolCacheEntry *cp_entry, jvalue *value)) | |
1016 | |
2376
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2357
diff
changeset
|
1017 klassOop k = java_lang_Class::as_klassOop(cp_entry->f1()); |
0 | 1018 |
1019 // check the access_flags for the field in the klass | |
1020 instanceKlass* ik = instanceKlass::cast(k); | |
1021 int index = cp_entry->field_index(); | |
1022 // bail out if field modifications are not watched | |
3938 | 1023 if ((ik->field_access_flags(index) & JVM_ACC_FIELD_MODIFICATION_WATCHED) == 0) return; |
0 | 1024 |
1025 char sig_type = '\0'; | |
1026 | |
1027 switch(cp_entry->flag_state()) { | |
1028 case btos: sig_type = 'Z'; break; | |
1029 case ctos: sig_type = 'C'; break; | |
1030 case stos: sig_type = 'S'; break; | |
1031 case itos: sig_type = 'I'; break; | |
1032 case ftos: sig_type = 'F'; break; | |
1033 case atos: sig_type = 'L'; break; | |
1034 case ltos: sig_type = 'J'; break; | |
1035 case dtos: sig_type = 'D'; break; | |
1036 default: ShouldNotReachHere(); return; | |
1037 } | |
1038 bool is_static = (obj == NULL); | |
1039 | |
1040 HandleMark hm(thread); | |
1041 instanceKlassHandle h_klass(thread, k); | |
1042 jfieldID fid = jfieldIDWorkaround::to_jfieldID(h_klass, cp_entry->f2(), is_static); | |
1043 jvalue fvalue; | |
1044 #ifdef _LP64 | |
1045 fvalue = *value; | |
1046 #else | |
1047 // Long/double values are stored unaligned and also noncontiguously with | |
1048 // tagged stacks. We can't just do a simple assignment even in the non- | |
1049 // J/D cases because a C++ compiler is allowed to assume that a jvalue is | |
1050 // 8-byte aligned, and interpreter stack slots are only 4-byte aligned. | |
1051 // We assume that the two halves of longs/doubles are stored in interpreter | |
1052 // stack slots in platform-endian order. | |
1053 jlong_accessor u; | |
1054 jint* newval = (jint*)value; | |
1055 u.words[0] = newval[0]; | |
1506 | 1056 u.words[1] = newval[Interpreter::stackElementWords]; // skip if tag |
0 | 1057 fvalue.j = u.long_value; |
1058 #endif // _LP64 | |
1059 | |
1060 Handle h_obj; | |
1061 if (!is_static) { | |
1062 // non-static field accessors have an object, but we need a handle | |
1063 h_obj = Handle(thread, obj); | |
1064 } | |
1065 | |
1066 JvmtiExport::post_raw_field_modification(thread, method(thread), bcp(thread), h_klass, h_obj, | |
1067 fid, sig_type, &fvalue); | |
1068 IRT_END | |
1069 | |
1070 IRT_ENTRY(void, InterpreterRuntime::post_method_entry(JavaThread *thread)) | |
1071 JvmtiExport::post_method_entry(thread, InterpreterRuntime::method(thread), InterpreterRuntime::last_frame(thread)); | |
1072 IRT_END | |
1073 | |
1074 | |
1075 IRT_ENTRY(void, InterpreterRuntime::post_method_exit(JavaThread *thread)) | |
1076 JvmtiExport::post_method_exit(thread, InterpreterRuntime::method(thread), InterpreterRuntime::last_frame(thread)); | |
1077 IRT_END | |
1078 | |
1079 IRT_LEAF(int, InterpreterRuntime::interpreter_contains(address pc)) | |
1080 { | |
1081 return (Interpreter::contains(pc) ? 1 : 0); | |
1082 } | |
1083 IRT_END | |
1084 | |
1085 | |
1086 // Implementation of SignatureHandlerLibrary | |
1087 | |
1088 address SignatureHandlerLibrary::set_handler_blob() { | |
1089 BufferBlob* handler_blob = BufferBlob::create("native signature handlers", blob_size); | |
1090 if (handler_blob == NULL) { | |
1091 return NULL; | |
1092 } | |
1748 | 1093 address handler = handler_blob->code_begin(); |
0 | 1094 _handler_blob = handler_blob; |
1095 _handler = handler; | |
1096 return handler; | |
1097 } | |
1098 | |
1099 void SignatureHandlerLibrary::initialize() { | |
1100 if (_fingerprints != NULL) { | |
1101 return; | |
1102 } | |
1103 if (set_handler_blob() == NULL) { | |
1104 vm_exit_out_of_memory(blob_size, "native signature handlers"); | |
1105 } | |
1106 | |
1107 BufferBlob* bb = BufferBlob::create("Signature Handler Temp Buffer", | |
1108 SignatureHandlerLibrary::buffer_size); | |
1748 | 1109 _buffer = bb->code_begin(); |
0 | 1110 |
1111 _fingerprints = new(ResourceObj::C_HEAP)GrowableArray<uint64_t>(32, true); | |
1112 _handlers = new(ResourceObj::C_HEAP)GrowableArray<address>(32, true); | |
1113 } | |
1114 | |
1115 address SignatureHandlerLibrary::set_handler(CodeBuffer* buffer) { | |
1116 address handler = _handler; | |
1748 | 1117 int insts_size = buffer->pure_insts_size(); |
1118 if (handler + insts_size > _handler_blob->code_end()) { | |
0 | 1119 // get a new handler blob |
1120 handler = set_handler_blob(); | |
1121 } | |
1122 if (handler != NULL) { | |
1748 | 1123 memcpy(handler, buffer->insts_begin(), insts_size); |
0 | 1124 pd_set_handler(handler); |
1748 | 1125 ICache::invalidate_range(handler, insts_size); |
1126 _handler = handler + insts_size; | |
0 | 1127 } |
1128 return handler; | |
1129 } | |
1130 | |
1131 void SignatureHandlerLibrary::add(methodHandle method) { | |
1132 if (method->signature_handler() == NULL) { | |
1133 // use slow signature handler if we can't do better | |
1134 int handler_index = -1; | |
1135 // check if we can use customized (fast) signature handler | |
1136 if (UseFastSignatureHandlers && method->size_of_parameters() <= Fingerprinter::max_size_of_parameters) { | |
1137 // use customized signature handler | |
1138 MutexLocker mu(SignatureHandlerLibrary_lock); | |
1139 // make sure data structure is initialized | |
1140 initialize(); | |
1141 // lookup method signature's fingerprint | |
1142 uint64_t fingerprint = Fingerprinter(method).fingerprint(); | |
1143 handler_index = _fingerprints->find(fingerprint); | |
1144 // create handler if necessary | |
1145 if (handler_index < 0) { | |
1146 ResourceMark rm; | |
1147 ptrdiff_t align_offset = (address) | |
1148 round_to((intptr_t)_buffer, CodeEntryAlignment) - (address)_buffer; | |
1149 CodeBuffer buffer((address)(_buffer + align_offset), | |
1150 SignatureHandlerLibrary::buffer_size - align_offset); | |
1151 InterpreterRuntime::SignatureHandlerGenerator(method, &buffer).generate(fingerprint); | |
1152 // copy into code heap | |
1153 address handler = set_handler(&buffer); | |
1154 if (handler == NULL) { | |
1155 // use slow signature handler | |
1156 } else { | |
1157 // debugging suppport | |
1158 if (PrintSignatureHandlers) { | |
1159 tty->cr(); | |
1160 tty->print_cr("argument handler #%d for: %s %s (fingerprint = " UINT64_FORMAT ", %d bytes generated)", | |
1161 _handlers->length(), | |
1162 (method->is_static() ? "static" : "receiver"), | |
1163 method->name_and_sig_as_C_string(), | |
1164 fingerprint, | |
1748 | 1165 buffer.insts_size()); |
1166 Disassembler::decode(handler, handler + buffer.insts_size()); | |
0 | 1167 #ifndef PRODUCT |
1168 tty->print_cr(" --- associated result handler ---"); | |
1169 address rh_begin = Interpreter::result_handler(method()->result_type()); | |
1170 address rh_end = rh_begin; | |
1171 while (*(int*)rh_end != 0) { | |
1172 rh_end += sizeof(int); | |
1173 } | |
1174 Disassembler::decode(rh_begin, rh_end); | |
1175 #endif | |
1176 } | |
1177 // add handler to library | |
1178 _fingerprints->append(fingerprint); | |
1179 _handlers->append(handler); | |
1180 // set handler index | |
1181 assert(_fingerprints->length() == _handlers->length(), "sanity check"); | |
1182 handler_index = _fingerprints->length() - 1; | |
1183 } | |
1184 } | |
2194
face83fc8882
7012088: jump to 0 address because of lack of memory ordering in SignatureHandlerLibrary::add
coleenp
parents:
2192
diff
changeset
|
1185 // Set handler under SignatureHandlerLibrary_lock |
0 | 1186 if (handler_index < 0) { |
1187 // use generic signature handler | |
1188 method->set_signature_handler(Interpreter::slow_signature_handler()); | |
1189 } else { | |
1190 // set handler | |
1191 method->set_signature_handler(_handlers->at(handler_index)); | |
1192 } | |
2194
face83fc8882
7012088: jump to 0 address because of lack of memory ordering in SignatureHandlerLibrary::add
coleenp
parents:
2192
diff
changeset
|
1193 } else { |
face83fc8882
7012088: jump to 0 address because of lack of memory ordering in SignatureHandlerLibrary::add
coleenp
parents:
2192
diff
changeset
|
1194 CHECK_UNHANDLED_OOPS_ONLY(Thread::current()->clear_unhandled_oops()); |
face83fc8882
7012088: jump to 0 address because of lack of memory ordering in SignatureHandlerLibrary::add
coleenp
parents:
2192
diff
changeset
|
1195 // use generic signature handler |
face83fc8882
7012088: jump to 0 address because of lack of memory ordering in SignatureHandlerLibrary::add
coleenp
parents:
2192
diff
changeset
|
1196 method->set_signature_handler(Interpreter::slow_signature_handler()); |
face83fc8882
7012088: jump to 0 address because of lack of memory ordering in SignatureHandlerLibrary::add
coleenp
parents:
2192
diff
changeset
|
1197 } |
0 | 1198 } |
1986
9bc798875b2a
6704010: Internal Error (src/share/vm/interpreter/interpreterRuntime.cpp:1106)
coleenp
parents:
1972
diff
changeset
|
1199 #ifdef ASSERT |
2194
face83fc8882
7012088: jump to 0 address because of lack of memory ordering in SignatureHandlerLibrary::add
coleenp
parents:
2192
diff
changeset
|
1200 int handler_index = -1; |
face83fc8882
7012088: jump to 0 address because of lack of memory ordering in SignatureHandlerLibrary::add
coleenp
parents:
2192
diff
changeset
|
1201 int fingerprint_index = -2; |
1986
9bc798875b2a
6704010: Internal Error (src/share/vm/interpreter/interpreterRuntime.cpp:1106)
coleenp
parents:
1972
diff
changeset
|
1202 { |
9bc798875b2a
6704010: Internal Error (src/share/vm/interpreter/interpreterRuntime.cpp:1106)
coleenp
parents:
1972
diff
changeset
|
1203 // '_handlers' and '_fingerprints' are 'GrowableArray's and are NOT synchronized |
9bc798875b2a
6704010: Internal Error (src/share/vm/interpreter/interpreterRuntime.cpp:1106)
coleenp
parents:
1972
diff
changeset
|
1204 // in any way if accessed from multiple threads. To avoid races with another |
9bc798875b2a
6704010: Internal Error (src/share/vm/interpreter/interpreterRuntime.cpp:1106)
coleenp
parents:
1972
diff
changeset
|
1205 // thread which may change the arrays in the above, mutex protected block, we |
9bc798875b2a
6704010: Internal Error (src/share/vm/interpreter/interpreterRuntime.cpp:1106)
coleenp
parents:
1972
diff
changeset
|
1206 // have to protect this read access here with the same mutex as well! |
9bc798875b2a
6704010: Internal Error (src/share/vm/interpreter/interpreterRuntime.cpp:1106)
coleenp
parents:
1972
diff
changeset
|
1207 MutexLocker mu(SignatureHandlerLibrary_lock); |
2194
face83fc8882
7012088: jump to 0 address because of lack of memory ordering in SignatureHandlerLibrary::add
coleenp
parents:
2192
diff
changeset
|
1208 if (_handlers != NULL) { |
1986
9bc798875b2a
6704010: Internal Error (src/share/vm/interpreter/interpreterRuntime.cpp:1106)
coleenp
parents:
1972
diff
changeset
|
1209 handler_index = _handlers->find(method->signature_handler()); |
9bc798875b2a
6704010: Internal Error (src/share/vm/interpreter/interpreterRuntime.cpp:1106)
coleenp
parents:
1972
diff
changeset
|
1210 fingerprint_index = _fingerprints->find(Fingerprinter(method).fingerprint()); |
9bc798875b2a
6704010: Internal Error (src/share/vm/interpreter/interpreterRuntime.cpp:1106)
coleenp
parents:
1972
diff
changeset
|
1211 } |
2194
face83fc8882
7012088: jump to 0 address because of lack of memory ordering in SignatureHandlerLibrary::add
coleenp
parents:
2192
diff
changeset
|
1212 } |
0 | 1213 assert(method->signature_handler() == Interpreter::slow_signature_handler() || |
1986
9bc798875b2a
6704010: Internal Error (src/share/vm/interpreter/interpreterRuntime.cpp:1106)
coleenp
parents:
1972
diff
changeset
|
1214 handler_index == fingerprint_index, "sanity check"); |
2194
face83fc8882
7012088: jump to 0 address because of lack of memory ordering in SignatureHandlerLibrary::add
coleenp
parents:
2192
diff
changeset
|
1215 #endif // ASSERT |
0 | 1216 } |
1217 | |
1218 | |
1219 BufferBlob* SignatureHandlerLibrary::_handler_blob = NULL; | |
1220 address SignatureHandlerLibrary::_handler = NULL; | |
1221 GrowableArray<uint64_t>* SignatureHandlerLibrary::_fingerprints = NULL; | |
1222 GrowableArray<address>* SignatureHandlerLibrary::_handlers = NULL; | |
1223 address SignatureHandlerLibrary::_buffer = NULL; | |
1224 | |
1225 | |
1226 IRT_ENTRY(void, InterpreterRuntime::prepare_native_call(JavaThread* thread, methodOopDesc* method)) | |
1227 methodHandle m(thread, method); | |
1228 assert(m->is_native(), "sanity check"); | |
1229 // lookup native function entry point if it doesn't exist | |
1230 bool in_base_library; | |
1231 if (!m->has_native_function()) { | |
1232 NativeLookup::lookup(m, in_base_library, CHECK); | |
1233 } | |
1234 // make sure signature handler is installed | |
1235 SignatureHandlerLibrary::add(m); | |
1236 // The interpreter entry point checks the signature handler first, | |
1237 // before trying to fetch the native entry point and klass mirror. | |
1238 // We must set the signature handler last, so that multiple processors | |
1239 // preparing the same method will be sure to see non-null entry & mirror. | |
1240 IRT_END | |
1241 | |
3911
2fecca53a2c6
7085012: ARM: com/sun/jdi/PopSynchronousTest.java still fails
roland
parents:
3852
diff
changeset
|
1242 #if defined(IA32) || defined(AMD64) || defined(ARM) |
0 | 1243 IRT_LEAF(void, InterpreterRuntime::popframe_move_outgoing_args(JavaThread* thread, void* src_address, void* dest_address)) |
1244 if (src_address == dest_address) { | |
1245 return; | |
1246 } | |
1247 ResetNoHandleMark rnm; // In a LEAF entry. | |
1248 HandleMark hm; | |
1249 ResourceMark rm; | |
1250 frame fr = thread->last_frame(); | |
1251 assert(fr.is_interpreted_frame(), ""); | |
1252 jint bci = fr.interpreter_frame_bci(); | |
1253 methodHandle mh(thread, fr.interpreter_frame_method()); | |
2142 | 1254 Bytecode_invoke invoke(mh, bci); |
1255 ArgumentSizeComputer asc(invoke.signature()); | |
1256 int size_of_arguments = (asc.size() + (invoke.has_receiver() ? 1 : 0)); // receiver | |
1603
d93949c5bdcc
6730276: JDI_REGRESSION tests fail with "Error: count must be non-zero" error on x86
kvn
parents:
1602
diff
changeset
|
1257 Copy::conjoint_jbytes(src_address, dest_address, |
1506 | 1258 size_of_arguments * Interpreter::stackElementSize); |
0 | 1259 IRT_END |
1260 #endif |