Mercurial > hg > truffle
annotate src/share/vm/interpreter/interpreterRuntime.cpp @ 6862:8a5ea0a9ccc4
7127708: G1: change task num types from int to uint in concurrent mark
Summary: Change the type of various task num fields, parameters etc to unsigned and rename them to be more consistent with the other collectors. Code changes were also reviewed by Vitaly Davidovich.
Reviewed-by: johnc
Contributed-by: Kaushik Srenevasan <kaushik@twitter.com>
author | johnc |
---|---|
date | Sat, 06 Oct 2012 01:17:44 -0700 |
parents | f6b0eb4e44cf |
children | 6e5a59a8e4a7 |
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 } | |
214 oop obj = arrayKlass::cast(klass)->multi_allocate(nof_dims, dims, CHECK); | |
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 |
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
6227
diff
changeset
|
736 cache_entry(thread)->set_method_handle( |
6737
4bfe8b33cf66
7196242: vm/mlvm/indy/stress/java/loopsAndThreads crashed
twisti
parents:
6725
diff
changeset
|
737 pool, |
6266
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
6227
diff
changeset
|
738 info.resolved_method(), |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
739 info.resolved_appendix(), |
6822
f6b0eb4e44cf
7200949: JSR 292: rubybench/bench/time/bench_base64.rb fails with jruby.jar not on boot class path
twisti
parents:
6737
diff
changeset
|
740 info.resolved_method_type(), |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
741 pool->resolved_references()); |
6266
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
6227
diff
changeset
|
742 } |
0 | 743 IRT_END |
744 | |
745 | |
1059
389049f3f393
6858164: invokedynamic code needs some cleanup (post-6655638)
jrose
parents:
941
diff
changeset
|
746 // 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
|
747 IRT_ENTRY(void, InterpreterRuntime::resolve_invokedynamic(JavaThread* thread)) { |
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
710
diff
changeset
|
748 assert(EnableInvokeDynamic, ""); |
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
710
diff
changeset
|
749 const Bytecodes::Code bytecode = Bytecodes::_invokedynamic; |
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
710
diff
changeset
|
750 |
6266
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
6227
diff
changeset
|
751 //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
|
752 // int caller_bci = method(thread)->bci_from(bcp(thread)); |
726
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
710
diff
changeset
|
753 |
6266
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
6227
diff
changeset
|
754 // resolve method |
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
6227
diff
changeset
|
755 CallInfo info; |
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
6227
diff
changeset
|
756 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
|
757 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
|
758 { |
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
6227
diff
changeset
|
759 JvmtiHideSingleStepping jhss(thread); |
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
6227
diff
changeset
|
760 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
|
761 index, bytecode, CHECK); |
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
6227
diff
changeset
|
762 } // end JvmtiHideSingleStepping |
1660
083fde3b838e
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
1603
diff
changeset
|
763 |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
764 ConstantPoolCacheEntry* cp_cache_entry = pool->invokedynamic_cp_cache_entry_at(index); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
765 cp_cache_entry->set_dynamic_call( |
6737
4bfe8b33cf66
7196242: vm/mlvm/indy/stress/java/loopsAndThreads crashed
twisti
parents:
6725
diff
changeset
|
766 pool, |
6266
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
6227
diff
changeset
|
767 info.resolved_method(), |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
768 info.resolved_appendix(), |
6822
f6b0eb4e44cf
7200949: JSR 292: rubybench/bench/time/bench_base64.rb fails with jruby.jar not on boot class path
twisti
parents:
6737
diff
changeset
|
769 info.resolved_method_type(), |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
770 pool->resolved_references()); |
726
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
710
diff
changeset
|
771 } |
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
710
diff
changeset
|
772 IRT_END |
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
710
diff
changeset
|
773 |
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
710
diff
changeset
|
774 |
0 | 775 //------------------------------------------------------------------------------------------------------------------------ |
776 // Miscellaneous | |
777 | |
778 | |
941 | 779 nmethod* InterpreterRuntime::frequency_counter_overflow(JavaThread* thread, address branch_bcp) { |
780 nmethod* nm = frequency_counter_overflow_inner(thread, branch_bcp); | |
781 assert(branch_bcp != NULL || nm == NULL, "always returns null for non OSR requests"); | |
782 if (branch_bcp != NULL && nm != NULL) { | |
783 // This was a successful request for an OSR nmethod. Because | |
784 // frequency_counter_overflow_inner ends with a safepoint check, | |
785 // nm could have been unloaded so look it up again. It's unsafe | |
786 // to examine nm directly since it might have been freed and used | |
787 // for something else. | |
788 frame fr = thread->last_frame(); | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
789 Method* method = fr.interpreter_frame_method(); |
941 | 790 int bci = method->bci_from(fr.interpreter_frame_bcp()); |
1783 | 791 nm = method->lookup_osr_nmethod_for(bci, CompLevel_none, false); |
941 | 792 } |
6145
e2fe93124108
7174928: JSR 292: unresolved invokedynamic call sites deopt and osr infinitely
twisti
parents:
4825
diff
changeset
|
793 #ifndef PRODUCT |
e2fe93124108
7174928: JSR 292: unresolved invokedynamic call sites deopt and osr infinitely
twisti
parents:
4825
diff
changeset
|
794 if (TraceOnStackReplacement) { |
e2fe93124108
7174928: JSR 292: unresolved invokedynamic call sites deopt and osr infinitely
twisti
parents:
4825
diff
changeset
|
795 if (nm != NULL) { |
e2fe93124108
7174928: JSR 292: unresolved invokedynamic call sites deopt and osr infinitely
twisti
parents:
4825
diff
changeset
|
796 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
|
797 nm->print(); |
e2fe93124108
7174928: JSR 292: unresolved invokedynamic call sites deopt and osr infinitely
twisti
parents:
4825
diff
changeset
|
798 } |
e2fe93124108
7174928: JSR 292: unresolved invokedynamic call sites deopt and osr infinitely
twisti
parents:
4825
diff
changeset
|
799 } |
e2fe93124108
7174928: JSR 292: unresolved invokedynamic call sites deopt and osr infinitely
twisti
parents:
4825
diff
changeset
|
800 #endif |
941 | 801 return nm; |
802 } | |
803 | |
0 | 804 IRT_ENTRY(nmethod*, |
941 | 805 InterpreterRuntime::frequency_counter_overflow_inner(JavaThread* thread, address branch_bcp)) |
0 | 806 // use UnlockFlagSaver to clear and restore the _do_not_unlock_if_synchronized |
807 // flag, in case this method triggers classloading which will call into Java. | |
808 UnlockFlagSaver fs(thread); | |
809 | |
810 frame fr = thread->last_frame(); | |
811 assert(fr.is_interpreted_frame(), "must come from interpreter"); | |
812 methodHandle method(thread, fr.interpreter_frame_method()); | |
1783 | 813 const int branch_bci = branch_bcp != NULL ? method->bci_from(branch_bcp) : InvocationEntryBci; |
814 const int bci = branch_bcp != NULL ? method->bci_from(fr.interpreter_frame_bcp()) : InvocationEntryBci; | |
815 | |
4825
20334ed5ed3c
7131259: compile_method and CompilationPolicy::event shouldn't be declared TRAPS
iveresov
parents:
4043
diff
changeset
|
816 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
|
817 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
|
818 assert(!HAS_PENDING_EXCEPTION, "Event handler should not throw any exceptions"); |
0 | 819 |
1783 | 820 if (osr_nm != NULL) { |
821 // We may need to do on-stack replacement which requires that no | |
822 // monitors in the activation are biased because their | |
823 // BasicObjectLocks will need to migrate during OSR. Force | |
824 // unbiasing of all monitors in the activation now (even though | |
825 // the OSR nmethod might be invalidated) because we don't have a | |
826 // safepoint opportunity later once the migration begins. | |
827 if (UseBiasedLocking) { | |
828 ResourceMark rm; | |
829 GrowableArray<Handle>* objects_to_revoke = new GrowableArray<Handle>(); | |
830 for( BasicObjectLock *kptr = fr.interpreter_frame_monitor_end(); | |
831 kptr < fr.interpreter_frame_monitor_begin(); | |
832 kptr = fr.next_monitor_in_interpreter_frame(kptr) ) { | |
833 if( kptr->obj() != NULL ) { | |
834 objects_to_revoke->append(Handle(THREAD, kptr->obj())); | |
835 } | |
0 | 836 } |
1783 | 837 BiasedLocking::revoke(objects_to_revoke); |
0 | 838 } |
839 } | |
1783 | 840 return osr_nm; |
0 | 841 IRT_END |
842 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
843 IRT_LEAF(jint, InterpreterRuntime::bcp_to_di(Method* method, address cur_bcp)) |
0 | 844 assert(ProfileInterpreter, "must be profiling interpreter"); |
845 int bci = method->bci_from(cur_bcp); | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
846 MethodData* mdo = method->method_data(); |
0 | 847 if (mdo == NULL) return 0; |
848 return mdo->bci_to_di(bci); | |
849 IRT_END | |
850 | |
2118
dd031b2226de
4930919: race condition in MDO creation at back branch locations
iveresov
parents:
1986
diff
changeset
|
851 IRT_ENTRY(void, InterpreterRuntime::profile_method(JavaThread* thread)) |
0 | 852 // use UnlockFlagSaver to clear and restore the _do_not_unlock_if_synchronized |
853 // flag, in case this method triggers classloading which will call into Java. | |
854 UnlockFlagSaver fs(thread); | |
855 | |
856 assert(ProfileInterpreter, "must be profiling interpreter"); | |
857 frame fr = thread->last_frame(); | |
858 assert(fr.is_interpreted_frame(), "must come from interpreter"); | |
859 methodHandle method(thread, fr.interpreter_frame_method()); | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
860 Method::build_interpreter_method_data(method, THREAD); |
0 | 861 if (HAS_PENDING_EXCEPTION) { |
862 assert((PENDING_EXCEPTION->is_a(SystemDictionary::OutOfMemoryError_klass())), "we expect only an OOM error here"); | |
863 CLEAR_PENDING_EXCEPTION; | |
864 // and fall through... | |
865 } | |
866 IRT_END | |
867 | |
868 | |
869 #ifdef ASSERT | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
870 IRT_LEAF(void, InterpreterRuntime::verify_mdp(Method* method, address bcp, address mdp)) |
0 | 871 assert(ProfileInterpreter, "must be profiling interpreter"); |
872 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
873 MethodData* mdo = method->method_data(); |
0 | 874 assert(mdo != NULL, "must not be null"); |
875 | |
876 int bci = method->bci_from(bcp); | |
877 | |
878 address mdp2 = mdo->bci_to_dp(bci); | |
879 if (mdp != mdp2) { | |
880 ResourceMark rm; | |
881 ResetNoHandleMark rnm; // In a LEAF entry. | |
882 HandleMark hm; | |
883 tty->print_cr("FAILED verify : actual mdp %p expected mdp %p @ bci %d", mdp, mdp2, bci); | |
884 int current_di = mdo->dp_to_di(mdp); | |
885 int expected_di = mdo->dp_to_di(mdp2); | |
886 tty->print_cr(" actual di %d expected di %d", current_di, expected_di); | |
887 int expected_approx_bci = mdo->data_at(expected_di)->bci(); | |
888 int approx_bci = -1; | |
889 if (current_di >= 0) { | |
890 approx_bci = mdo->data_at(current_di)->bci(); | |
891 } | |
892 tty->print_cr(" actual bci is %d expected bci %d", approx_bci, expected_approx_bci); | |
893 mdo->print_on(tty); | |
894 method->print_codes(); | |
895 } | |
896 assert(mdp == mdp2, "wrong mdp"); | |
897 IRT_END | |
898 #endif // ASSERT | |
899 | |
900 IRT_ENTRY(void, InterpreterRuntime::update_mdp_for_ret(JavaThread* thread, int return_bci)) | |
901 assert(ProfileInterpreter, "must be profiling interpreter"); | |
902 ResourceMark rm(thread); | |
903 HandleMark hm(thread); | |
904 frame fr = thread->last_frame(); | |
905 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
|
906 MethodData* h_mdo = fr.interpreter_frame_method()->method_data(); |
0 | 907 |
908 // Grab a lock to ensure atomic access to setting the return bci and | |
909 // the displacement. This can block and GC, invalidating all naked oops. | |
910 MutexLocker ml(RetData_lock); | |
911 | |
912 // ProfileData is essentially a wrapper around a derived oop, so we | |
913 // need to take the lock before making any ProfileData structures. | |
914 ProfileData* data = h_mdo->data_at(h_mdo->dp_to_di(fr.interpreter_frame_mdp())); | |
915 RetData* rdata = data->as_RetData(); | |
916 address new_mdp = rdata->fixup_ret(return_bci, h_mdo); | |
917 fr.interpreter_frame_set_mdp(new_mdp); | |
918 IRT_END | |
919 | |
920 | |
921 IRT_ENTRY(void, InterpreterRuntime::at_safepoint(JavaThread* thread)) | |
922 // We used to need an explict preserve_arguments here for invoke bytecodes. However, | |
923 // stack traversal automatically takes care of preserving arguments for invoke, so | |
924 // this is no longer needed. | |
925 | |
926 // IRT_END does an implicit safepoint check, hence we are guaranteed to block | |
927 // if this is called during a safepoint | |
928 | |
929 if (JvmtiExport::should_post_single_step()) { | |
930 // We are called during regular safepoints and when the VM is | |
931 // single stepping. If any thread is marked for single stepping, | |
932 // then we may have JVMTI work to do. | |
933 JvmtiExport::at_single_stepping_point(thread, method(thread), bcp(thread)); | |
934 } | |
935 IRT_END | |
936 | |
937 IRT_ENTRY(void, InterpreterRuntime::post_field_access(JavaThread *thread, oopDesc* obj, | |
938 ConstantPoolCacheEntry *cp_entry)) | |
939 | |
940 // 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
|
941 |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
942 InstanceKlass* ik = InstanceKlass::cast(cp_entry->f1_as_klass()); |
0 | 943 int index = cp_entry->field_index(); |
3938 | 944 if ((ik->field_access_flags(index) & JVM_ACC_FIELD_ACCESS_WATCHED) == 0) return; |
0 | 945 |
946 switch(cp_entry->flag_state()) { | |
947 case btos: // fall through | |
948 case ctos: // fall through | |
949 case stos: // fall through | |
950 case itos: // fall through | |
951 case ftos: // fall through | |
952 case ltos: // fall through | |
953 case dtos: // fall through | |
954 case atos: break; | |
955 default: ShouldNotReachHere(); return; | |
956 } | |
957 bool is_static = (obj == NULL); | |
958 HandleMark hm(thread); | |
959 | |
960 Handle h_obj; | |
961 if (!is_static) { | |
962 // non-static field accessors have an object, but we need a handle | |
963 h_obj = Handle(thread, obj); | |
964 } | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
965 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
|
966 jfieldID fid = jfieldIDWorkaround::to_jfieldID(h_cp_entry_f1, cp_entry->f2_as_index(), is_static); |
0 | 967 JvmtiExport::post_field_access(thread, method(thread), bcp(thread), h_cp_entry_f1, h_obj, fid); |
968 IRT_END | |
969 | |
970 IRT_ENTRY(void, InterpreterRuntime::post_field_modification(JavaThread *thread, | |
971 oopDesc* obj, ConstantPoolCacheEntry *cp_entry, jvalue *value)) | |
972 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
973 Klass* k = (Klass*)cp_entry->f1_as_klass(); |
0 | 974 |
975 // 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
|
976 InstanceKlass* ik = InstanceKlass::cast(k); |
0 | 977 int index = cp_entry->field_index(); |
978 // bail out if field modifications are not watched | |
3938 | 979 if ((ik->field_access_flags(index) & JVM_ACC_FIELD_MODIFICATION_WATCHED) == 0) return; |
0 | 980 |
981 char sig_type = '\0'; | |
982 | |
983 switch(cp_entry->flag_state()) { | |
984 case btos: sig_type = 'Z'; break; | |
985 case ctos: sig_type = 'C'; break; | |
986 case stos: sig_type = 'S'; break; | |
987 case itos: sig_type = 'I'; break; | |
988 case ftos: sig_type = 'F'; break; | |
989 case atos: sig_type = 'L'; break; | |
990 case ltos: sig_type = 'J'; break; | |
991 case dtos: sig_type = 'D'; break; | |
992 default: ShouldNotReachHere(); return; | |
993 } | |
994 bool is_static = (obj == NULL); | |
995 | |
996 HandleMark hm(thread); | |
997 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
|
998 jfieldID fid = jfieldIDWorkaround::to_jfieldID(h_klass, cp_entry->f2_as_index(), is_static); |
0 | 999 jvalue fvalue; |
1000 #ifdef _LP64 | |
1001 fvalue = *value; | |
1002 #else | |
1003 // Long/double values are stored unaligned and also noncontiguously with | |
1004 // tagged stacks. We can't just do a simple assignment even in the non- | |
1005 // J/D cases because a C++ compiler is allowed to assume that a jvalue is | |
1006 // 8-byte aligned, and interpreter stack slots are only 4-byte aligned. | |
1007 // We assume that the two halves of longs/doubles are stored in interpreter | |
1008 // stack slots in platform-endian order. | |
1009 jlong_accessor u; | |
1010 jint* newval = (jint*)value; | |
1011 u.words[0] = newval[0]; | |
1506 | 1012 u.words[1] = newval[Interpreter::stackElementWords]; // skip if tag |
0 | 1013 fvalue.j = u.long_value; |
1014 #endif // _LP64 | |
1015 | |
1016 Handle h_obj; | |
1017 if (!is_static) { | |
1018 // non-static field accessors have an object, but we need a handle | |
1019 h_obj = Handle(thread, obj); | |
1020 } | |
1021 | |
1022 JvmtiExport::post_raw_field_modification(thread, method(thread), bcp(thread), h_klass, h_obj, | |
1023 fid, sig_type, &fvalue); | |
1024 IRT_END | |
1025 | |
1026 IRT_ENTRY(void, InterpreterRuntime::post_method_entry(JavaThread *thread)) | |
1027 JvmtiExport::post_method_entry(thread, InterpreterRuntime::method(thread), InterpreterRuntime::last_frame(thread)); | |
1028 IRT_END | |
1029 | |
1030 | |
1031 IRT_ENTRY(void, InterpreterRuntime::post_method_exit(JavaThread *thread)) | |
1032 JvmtiExport::post_method_exit(thread, InterpreterRuntime::method(thread), InterpreterRuntime::last_frame(thread)); | |
1033 IRT_END | |
1034 | |
1035 IRT_LEAF(int, InterpreterRuntime::interpreter_contains(address pc)) | |
1036 { | |
1037 return (Interpreter::contains(pc) ? 1 : 0); | |
1038 } | |
1039 IRT_END | |
1040 | |
1041 | |
1042 // Implementation of SignatureHandlerLibrary | |
1043 | |
1044 address SignatureHandlerLibrary::set_handler_blob() { | |
1045 BufferBlob* handler_blob = BufferBlob::create("native signature handlers", blob_size); | |
1046 if (handler_blob == NULL) { | |
1047 return NULL; | |
1048 } | |
1748 | 1049 address handler = handler_blob->code_begin(); |
0 | 1050 _handler_blob = handler_blob; |
1051 _handler = handler; | |
1052 return handler; | |
1053 } | |
1054 | |
1055 void SignatureHandlerLibrary::initialize() { | |
1056 if (_fingerprints != NULL) { | |
1057 return; | |
1058 } | |
1059 if (set_handler_blob() == NULL) { | |
1060 vm_exit_out_of_memory(blob_size, "native signature handlers"); | |
1061 } | |
1062 | |
1063 BufferBlob* bb = BufferBlob::create("Signature Handler Temp Buffer", | |
1064 SignatureHandlerLibrary::buffer_size); | |
1748 | 1065 _buffer = bb->code_begin(); |
0 | 1066 |
6197 | 1067 _fingerprints = new(ResourceObj::C_HEAP, mtCode)GrowableArray<uint64_t>(32, true); |
1068 _handlers = new(ResourceObj::C_HEAP, mtCode)GrowableArray<address>(32, true); | |
0 | 1069 } |
1070 | |
1071 address SignatureHandlerLibrary::set_handler(CodeBuffer* buffer) { | |
1072 address handler = _handler; | |
1748 | 1073 int insts_size = buffer->pure_insts_size(); |
1074 if (handler + insts_size > _handler_blob->code_end()) { | |
0 | 1075 // get a new handler blob |
1076 handler = set_handler_blob(); | |
1077 } | |
1078 if (handler != NULL) { | |
1748 | 1079 memcpy(handler, buffer->insts_begin(), insts_size); |
0 | 1080 pd_set_handler(handler); |
1748 | 1081 ICache::invalidate_range(handler, insts_size); |
1082 _handler = handler + insts_size; | |
0 | 1083 } |
1084 return handler; | |
1085 } | |
1086 | |
1087 void SignatureHandlerLibrary::add(methodHandle method) { | |
1088 if (method->signature_handler() == NULL) { | |
1089 // use slow signature handler if we can't do better | |
1090 int handler_index = -1; | |
1091 // check if we can use customized (fast) signature handler | |
1092 if (UseFastSignatureHandlers && method->size_of_parameters() <= Fingerprinter::max_size_of_parameters) { | |
1093 // use customized signature handler | |
1094 MutexLocker mu(SignatureHandlerLibrary_lock); | |
1095 // make sure data structure is initialized | |
1096 initialize(); | |
1097 // lookup method signature's fingerprint | |
1098 uint64_t fingerprint = Fingerprinter(method).fingerprint(); | |
1099 handler_index = _fingerprints->find(fingerprint); | |
1100 // create handler if necessary | |
1101 if (handler_index < 0) { | |
1102 ResourceMark rm; | |
1103 ptrdiff_t align_offset = (address) | |
1104 round_to((intptr_t)_buffer, CodeEntryAlignment) - (address)_buffer; | |
1105 CodeBuffer buffer((address)(_buffer + align_offset), | |
1106 SignatureHandlerLibrary::buffer_size - align_offset); | |
1107 InterpreterRuntime::SignatureHandlerGenerator(method, &buffer).generate(fingerprint); | |
1108 // copy into code heap | |
1109 address handler = set_handler(&buffer); | |
1110 if (handler == NULL) { | |
1111 // use slow signature handler | |
1112 } else { | |
1113 // debugging suppport | |
1114 if (PrintSignatureHandlers) { | |
1115 tty->cr(); | |
1116 tty->print_cr("argument handler #%d for: %s %s (fingerprint = " UINT64_FORMAT ", %d bytes generated)", | |
1117 _handlers->length(), | |
1118 (method->is_static() ? "static" : "receiver"), | |
1119 method->name_and_sig_as_C_string(), | |
1120 fingerprint, | |
1748 | 1121 buffer.insts_size()); |
1122 Disassembler::decode(handler, handler + buffer.insts_size()); | |
0 | 1123 #ifndef PRODUCT |
1124 tty->print_cr(" --- associated result handler ---"); | |
1125 address rh_begin = Interpreter::result_handler(method()->result_type()); | |
1126 address rh_end = rh_begin; | |
1127 while (*(int*)rh_end != 0) { | |
1128 rh_end += sizeof(int); | |
1129 } | |
1130 Disassembler::decode(rh_begin, rh_end); | |
1131 #endif | |
1132 } | |
1133 // add handler to library | |
1134 _fingerprints->append(fingerprint); | |
1135 _handlers->append(handler); | |
1136 // set handler index | |
1137 assert(_fingerprints->length() == _handlers->length(), "sanity check"); | |
1138 handler_index = _fingerprints->length() - 1; | |
1139 } | |
1140 } | |
2194
face83fc8882
7012088: jump to 0 address because of lack of memory ordering in SignatureHandlerLibrary::add
coleenp
parents:
2192
diff
changeset
|
1141 // Set handler under SignatureHandlerLibrary_lock |
0 | 1142 if (handler_index < 0) { |
1143 // use generic signature handler | |
1144 method->set_signature_handler(Interpreter::slow_signature_handler()); | |
1145 } else { | |
1146 // set handler | |
1147 method->set_signature_handler(_handlers->at(handler_index)); | |
1148 } | |
2194
face83fc8882
7012088: jump to 0 address because of lack of memory ordering in SignatureHandlerLibrary::add
coleenp
parents:
2192
diff
changeset
|
1149 } else { |
face83fc8882
7012088: jump to 0 address because of lack of memory ordering in SignatureHandlerLibrary::add
coleenp
parents:
2192
diff
changeset
|
1150 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
|
1151 // use generic signature handler |
face83fc8882
7012088: jump to 0 address because of lack of memory ordering in SignatureHandlerLibrary::add
coleenp
parents:
2192
diff
changeset
|
1152 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
|
1153 } |
0 | 1154 } |
1986
9bc798875b2a
6704010: Internal Error (src/share/vm/interpreter/interpreterRuntime.cpp:1106)
coleenp
parents:
1972
diff
changeset
|
1155 #ifdef ASSERT |
2194
face83fc8882
7012088: jump to 0 address because of lack of memory ordering in SignatureHandlerLibrary::add
coleenp
parents:
2192
diff
changeset
|
1156 int handler_index = -1; |
face83fc8882
7012088: jump to 0 address because of lack of memory ordering in SignatureHandlerLibrary::add
coleenp
parents:
2192
diff
changeset
|
1157 int fingerprint_index = -2; |
1986
9bc798875b2a
6704010: Internal Error (src/share/vm/interpreter/interpreterRuntime.cpp:1106)
coleenp
parents:
1972
diff
changeset
|
1158 { |
9bc798875b2a
6704010: Internal Error (src/share/vm/interpreter/interpreterRuntime.cpp:1106)
coleenp
parents:
1972
diff
changeset
|
1159 // '_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
|
1160 // 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
|
1161 // 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
|
1162 // 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
|
1163 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
|
1164 if (_handlers != NULL) { |
1986
9bc798875b2a
6704010: Internal Error (src/share/vm/interpreter/interpreterRuntime.cpp:1106)
coleenp
parents:
1972
diff
changeset
|
1165 handler_index = _handlers->find(method->signature_handler()); |
9bc798875b2a
6704010: Internal Error (src/share/vm/interpreter/interpreterRuntime.cpp:1106)
coleenp
parents:
1972
diff
changeset
|
1166 fingerprint_index = _fingerprints->find(Fingerprinter(method).fingerprint()); |
9bc798875b2a
6704010: Internal Error (src/share/vm/interpreter/interpreterRuntime.cpp:1106)
coleenp
parents:
1972
diff
changeset
|
1167 } |
2194
face83fc8882
7012088: jump to 0 address because of lack of memory ordering in SignatureHandlerLibrary::add
coleenp
parents:
2192
diff
changeset
|
1168 } |
0 | 1169 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
|
1170 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
|
1171 #endif // ASSERT |
0 | 1172 } |
1173 | |
1174 | |
1175 BufferBlob* SignatureHandlerLibrary::_handler_blob = NULL; | |
1176 address SignatureHandlerLibrary::_handler = NULL; | |
1177 GrowableArray<uint64_t>* SignatureHandlerLibrary::_fingerprints = NULL; | |
1178 GrowableArray<address>* SignatureHandlerLibrary::_handlers = NULL; | |
1179 address SignatureHandlerLibrary::_buffer = NULL; | |
1180 | |
1181 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
1182 IRT_ENTRY(void, InterpreterRuntime::prepare_native_call(JavaThread* thread, Method* method)) |
0 | 1183 methodHandle m(thread, method); |
1184 assert(m->is_native(), "sanity check"); | |
1185 // lookup native function entry point if it doesn't exist | |
1186 bool in_base_library; | |
1187 if (!m->has_native_function()) { | |
1188 NativeLookup::lookup(m, in_base_library, CHECK); | |
1189 } | |
1190 // make sure signature handler is installed | |
1191 SignatureHandlerLibrary::add(m); | |
1192 // The interpreter entry point checks the signature handler first, | |
1193 // before trying to fetch the native entry point and klass mirror. | |
1194 // We must set the signature handler last, so that multiple processors | |
1195 // preparing the same method will be sure to see non-null entry & mirror. | |
1196 IRT_END | |
1197 | |
3911
2fecca53a2c6
7085012: ARM: com/sun/jdi/PopSynchronousTest.java still fails
roland
parents:
3852
diff
changeset
|
1198 #if defined(IA32) || defined(AMD64) || defined(ARM) |
0 | 1199 IRT_LEAF(void, InterpreterRuntime::popframe_move_outgoing_args(JavaThread* thread, void* src_address, void* dest_address)) |
1200 if (src_address == dest_address) { | |
1201 return; | |
1202 } | |
1203 ResetNoHandleMark rnm; // In a LEAF entry. | |
1204 HandleMark hm; | |
1205 ResourceMark rm; | |
1206 frame fr = thread->last_frame(); | |
1207 assert(fr.is_interpreted_frame(), ""); | |
1208 jint bci = fr.interpreter_frame_bci(); | |
1209 methodHandle mh(thread, fr.interpreter_frame_method()); | |
2142 | 1210 Bytecode_invoke invoke(mh, bci); |
1211 ArgumentSizeComputer asc(invoke.signature()); | |
1212 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
|
1213 Copy::conjoint_jbytes(src_address, dest_address, |
1506 | 1214 size_of_arguments * Interpreter::stackElementSize); |
0 | 1215 IRT_END |
1216 #endif |