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