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