Mercurial > hg > truffle
annotate src/share/vm/opto/runtime.cpp @ 1994:6cd6d394f280
7001033: assert(gch->gc_cause() == GCCause::_scavenge_alot || !gch->incremental_collection_failed())
7002546: regression on SpecJbb2005 on 7b118 comparing to 7b117 on small heaps
Summary: Relaxed assertion checking related to incremental_collection_failed flag to allow for ExplicitGCInvokesConcurrent behaviour where we do not want a failing scavenge to bail to a stop-world collection. Parameterized incremental_collection_will_fail() so we can selectively use, or not use, as appropriate, the statistical prediction at specific use sites. This essentially reverts the scavenge bail-out logic to what it was prior to some recent changes that had inadvertently started using the statistical prediction which can be noisy in the presence of bursty loads. Added some associated verbose non-product debugging messages.
Reviewed-by: johnc, tonyp
author | ysr |
---|---|
date | Tue, 07 Dec 2010 21:55:53 -0800 |
parents | f95d63e2154a |
children | 3582bf76420e |
rev | line source |
---|---|
0 | 1 /* |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1368
diff
changeset
|
2 * Copyright (c) 1998, 2010, 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:
1368
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1368
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:
1368
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
1972 | 25 #include "precompiled.hpp" |
26 #include "classfile/systemDictionary.hpp" | |
27 #include "classfile/vmSymbols.hpp" | |
28 #include "code/compiledIC.hpp" | |
29 #include "code/icBuffer.hpp" | |
30 #include "code/nmethod.hpp" | |
31 #include "code/pcDesc.hpp" | |
32 #include "code/scopeDesc.hpp" | |
33 #include "code/vtableStubs.hpp" | |
34 #include "compiler/compileBroker.hpp" | |
35 #include "compiler/compilerOracle.hpp" | |
36 #include "compiler/oopMap.hpp" | |
37 #include "gc_implementation/g1/g1SATBCardTableModRefBS.hpp" | |
38 #include "gc_implementation/g1/heapRegion.hpp" | |
39 #include "gc_interface/collectedHeap.hpp" | |
40 #include "interpreter/bytecode.hpp" | |
41 #include "interpreter/interpreter.hpp" | |
42 #include "interpreter/linkResolver.hpp" | |
43 #include "memory/barrierSet.hpp" | |
44 #include "memory/gcLocker.inline.hpp" | |
45 #include "memory/oopFactory.hpp" | |
46 #include "oops/objArrayKlass.hpp" | |
47 #include "oops/oop.inline.hpp" | |
48 #include "opto/addnode.hpp" | |
49 #include "opto/callnode.hpp" | |
50 #include "opto/cfgnode.hpp" | |
51 #include "opto/connode.hpp" | |
52 #include "opto/graphKit.hpp" | |
53 #include "opto/machnode.hpp" | |
54 #include "opto/matcher.hpp" | |
55 #include "opto/memnode.hpp" | |
56 #include "opto/mulnode.hpp" | |
57 #include "opto/runtime.hpp" | |
58 #include "opto/subnode.hpp" | |
59 #include "runtime/fprofiler.hpp" | |
60 #include "runtime/handles.inline.hpp" | |
61 #include "runtime/interfaceSupport.hpp" | |
62 #include "runtime/javaCalls.hpp" | |
63 #include "runtime/sharedRuntime.hpp" | |
64 #include "runtime/signature.hpp" | |
65 #include "runtime/threadCritical.hpp" | |
66 #include "runtime/vframe.hpp" | |
67 #include "runtime/vframeArray.hpp" | |
68 #include "runtime/vframe_hp.hpp" | |
69 #include "utilities/copy.hpp" | |
70 #include "utilities/preserveException.hpp" | |
71 #ifdef TARGET_ARCH_MODEL_x86_32 | |
72 # include "adfiles/ad_x86_32.hpp" | |
73 #endif | |
74 #ifdef TARGET_ARCH_MODEL_x86_64 | |
75 # include "adfiles/ad_x86_64.hpp" | |
76 #endif | |
77 #ifdef TARGET_ARCH_MODEL_sparc | |
78 # include "adfiles/ad_sparc.hpp" | |
79 #endif | |
80 #ifdef TARGET_ARCH_MODEL_zero | |
81 # include "adfiles/ad_zero.hpp" | |
82 #endif | |
0 | 83 |
84 | |
85 // For debugging purposes: | |
86 // To force FullGCALot inside a runtime function, add the following two lines | |
87 // | |
88 // Universe::release_fullgc_alot_dummy(); | |
89 // MarkSweep::invoke(0, "Debugging"); | |
90 // | |
91 // At command line specify the parameters: -XX:+FullGCALot -XX:FullGCALotStart=100000000 | |
92 | |
93 | |
94 | |
95 | |
96 // Compiled code entry points | |
97 address OptoRuntime::_new_instance_Java = NULL; | |
98 address OptoRuntime::_new_array_Java = NULL; | |
99 address OptoRuntime::_multianewarray2_Java = NULL; | |
100 address OptoRuntime::_multianewarray3_Java = NULL; | |
101 address OptoRuntime::_multianewarray4_Java = NULL; | |
102 address OptoRuntime::_multianewarray5_Java = NULL; | |
342 | 103 address OptoRuntime::_g1_wb_pre_Java = NULL; |
104 address OptoRuntime::_g1_wb_post_Java = NULL; | |
0 | 105 address OptoRuntime::_vtable_must_compile_Java = NULL; |
106 address OptoRuntime::_complete_monitor_locking_Java = NULL; | |
107 address OptoRuntime::_rethrow_Java = NULL; | |
108 | |
109 address OptoRuntime::_slow_arraycopy_Java = NULL; | |
110 address OptoRuntime::_register_finalizer_Java = NULL; | |
111 | |
112 # ifdef ENABLE_ZAP_DEAD_LOCALS | |
113 address OptoRuntime::_zap_dead_Java_locals_Java = NULL; | |
114 address OptoRuntime::_zap_dead_native_locals_Java = NULL; | |
115 # endif | |
116 | |
117 | |
118 // This should be called in an assertion at the start of OptoRuntime routines | |
119 // which are entered from compiled code (all of them) | |
120 #ifndef PRODUCT | |
121 static bool check_compiled_frame(JavaThread* thread) { | |
122 assert(thread->last_frame().is_runtime_frame(), "cannot call runtime directly from compiled code"); | |
123 #ifdef ASSERT | |
124 RegisterMap map(thread, false); | |
125 frame caller = thread->last_frame().sender(&map); | |
126 assert(caller.is_compiled_frame(), "not being called from compiled like code"); | |
127 #endif /* ASSERT */ | |
128 return true; | |
129 } | |
130 #endif | |
131 | |
132 | |
133 #define gen(env, var, type_func_gen, c_func, fancy_jump, pass_tls, save_arg_regs, return_pc) \ | |
134 var = generate_stub(env, type_func_gen, CAST_FROM_FN_PTR(address, c_func), #var, fancy_jump, pass_tls, save_arg_regs, return_pc) | |
135 | |
136 void OptoRuntime::generate(ciEnv* env) { | |
137 | |
138 generate_exception_blob(); | |
139 | |
140 // Note: tls: Means fetching the return oop out of the thread-local storage | |
141 // | |
142 // variable/name type-function-gen , runtime method ,fncy_jp, tls,save_args,retpc | |
143 // ------------------------------------------------------------------------------------------------------------------------------- | |
144 gen(env, _new_instance_Java , new_instance_Type , new_instance_C , 0 , true , false, false); | |
145 gen(env, _new_array_Java , new_array_Type , new_array_C , 0 , true , false, false); | |
146 gen(env, _multianewarray2_Java , multianewarray2_Type , multianewarray2_C , 0 , true , false, false); | |
147 gen(env, _multianewarray3_Java , multianewarray3_Type , multianewarray3_C , 0 , true , false, false); | |
148 gen(env, _multianewarray4_Java , multianewarray4_Type , multianewarray4_C , 0 , true , false, false); | |
149 gen(env, _multianewarray5_Java , multianewarray5_Type , multianewarray5_C , 0 , true , false, false); | |
342 | 150 gen(env, _g1_wb_pre_Java , g1_wb_pre_Type , SharedRuntime::g1_wb_pre , 0 , false, false, false); |
151 gen(env, _g1_wb_post_Java , g1_wb_post_Type , SharedRuntime::g1_wb_post , 0 , false, false, false); | |
0 | 152 gen(env, _complete_monitor_locking_Java , complete_monitor_enter_Type , SharedRuntime::complete_monitor_locking_C , 0 , false, false, false); |
153 gen(env, _rethrow_Java , rethrow_Type , rethrow_C , 2 , true , false, true ); | |
154 | |
155 gen(env, _slow_arraycopy_Java , slow_arraycopy_Type , SharedRuntime::slow_arraycopy_C , 0 , false, false, false); | |
156 gen(env, _register_finalizer_Java , register_finalizer_Type , register_finalizer , 0 , false, false, false); | |
157 | |
158 # ifdef ENABLE_ZAP_DEAD_LOCALS | |
159 gen(env, _zap_dead_Java_locals_Java , zap_dead_locals_Type , zap_dead_Java_locals_C , 0 , false, true , false ); | |
160 gen(env, _zap_dead_native_locals_Java , zap_dead_locals_Type , zap_dead_native_locals_C , 0 , false, true , false ); | |
161 # endif | |
162 | |
163 } | |
164 | |
165 #undef gen | |
166 | |
167 | |
168 // Helper method to do generation of RunTimeStub's | |
169 address OptoRuntime::generate_stub( ciEnv* env, | |
170 TypeFunc_generator gen, address C_function, | |
171 const char *name, int is_fancy_jump, | |
172 bool pass_tls, | |
173 bool save_argument_registers, | |
174 bool return_pc ) { | |
175 ResourceMark rm; | |
176 Compile C( env, gen, C_function, name, is_fancy_jump, pass_tls, save_argument_registers, return_pc ); | |
177 return C.stub_entry_point(); | |
178 } | |
179 | |
180 const char* OptoRuntime::stub_name(address entry) { | |
181 #ifndef PRODUCT | |
182 CodeBlob* cb = CodeCache::find_blob(entry); | |
183 RuntimeStub* rs =(RuntimeStub *)cb; | |
184 assert(rs != NULL && rs->is_runtime_stub(), "not a runtime stub"); | |
185 return rs->name(); | |
186 #else | |
187 // Fast implementation for product mode (maybe it should be inlined too) | |
188 return "runtime stub"; | |
189 #endif | |
190 } | |
191 | |
192 | |
193 //============================================================================= | |
194 // Opto compiler runtime routines | |
195 //============================================================================= | |
196 | |
197 | |
198 //=============================allocation====================================== | |
199 // We failed the fast-path allocation. Now we need to do a scavenge or GC | |
200 // and try allocation again. | |
201 | |
1166 | 202 void OptoRuntime::new_store_pre_barrier(JavaThread* thread) { |
0 | 203 // After any safepoint, just before going back to compiled code, |
1027
39b01ab7035a
6888898: CMS: ReduceInitialCardMarks unsafe in the presence of cms precleaning
ysr
parents:
605
diff
changeset
|
204 // we inform the GC that we will be doing initializing writes to |
39b01ab7035a
6888898: CMS: ReduceInitialCardMarks unsafe in the presence of cms precleaning
ysr
parents:
605
diff
changeset
|
205 // this object in the future without emitting card-marks, so |
39b01ab7035a
6888898: CMS: ReduceInitialCardMarks unsafe in the presence of cms precleaning
ysr
parents:
605
diff
changeset
|
206 // GC may take any compensating steps. |
39b01ab7035a
6888898: CMS: ReduceInitialCardMarks unsafe in the presence of cms precleaning
ysr
parents:
605
diff
changeset
|
207 // NOTE: Keep this code consistent with GraphKit::store_barrier. |
0 | 208 |
209 oop new_obj = thread->vm_result(); | |
210 if (new_obj == NULL) return; | |
211 | |
212 assert(Universe::heap()->can_elide_tlab_store_barriers(), | |
213 "compiler must check this first"); | |
1027
39b01ab7035a
6888898: CMS: ReduceInitialCardMarks unsafe in the presence of cms precleaning
ysr
parents:
605
diff
changeset
|
214 // GC may decide to give back a safer copy of new_obj. |
1166 | 215 new_obj = Universe::heap()->new_store_pre_barrier(thread, new_obj); |
0 | 216 thread->set_vm_result(new_obj); |
217 } | |
218 | |
219 // object allocation | |
220 JRT_BLOCK_ENTRY(void, OptoRuntime::new_instance_C(klassOopDesc* klass, JavaThread* thread)) | |
221 JRT_BLOCK; | |
222 #ifndef PRODUCT | |
223 SharedRuntime::_new_instance_ctr++; // new instance requires GC | |
224 #endif | |
225 assert(check_compiled_frame(thread), "incorrect caller"); | |
226 | |
227 // These checks are cheap to make and support reflective allocation. | |
228 int lh = Klass::cast(klass)->layout_helper(); | |
229 if (Klass::layout_helper_needs_slow_path(lh) | |
230 || !instanceKlass::cast(klass)->is_initialized()) { | |
231 KlassHandle kh(THREAD, klass); | |
232 kh->check_valid_for_instantiation(false, THREAD); | |
233 if (!HAS_PENDING_EXCEPTION) { | |
234 instanceKlass::cast(kh())->initialize(THREAD); | |
235 } | |
236 if (!HAS_PENDING_EXCEPTION) { | |
237 klass = kh(); | |
238 } else { | |
239 klass = NULL; | |
240 } | |
241 } | |
242 | |
243 if (klass != NULL) { | |
244 // Scavenge and allocate an instance. | |
245 oop result = instanceKlass::cast(klass)->allocate_instance(THREAD); | |
246 thread->set_vm_result(result); | |
247 | |
248 // Pass oops back through thread local storage. Our apparent type to Java | |
249 // is that we return an oop, but we can block on exit from this routine and | |
250 // a GC can trash the oop in C's return register. The generated stub will | |
251 // fetch the oop from TLS after any possible GC. | |
252 } | |
253 | |
254 deoptimize_caller_frame(thread, HAS_PENDING_EXCEPTION); | |
255 JRT_BLOCK_END; | |
256 | |
257 if (GraphKit::use_ReduceInitialCardMarks()) { | |
1027
39b01ab7035a
6888898: CMS: ReduceInitialCardMarks unsafe in the presence of cms precleaning
ysr
parents:
605
diff
changeset
|
258 // inform GC that we won't do card marks for initializing writes. |
1166 | 259 new_store_pre_barrier(thread); |
0 | 260 } |
261 JRT_END | |
262 | |
263 | |
264 // array allocation | |
265 JRT_BLOCK_ENTRY(void, OptoRuntime::new_array_C(klassOopDesc* array_type, int len, JavaThread *thread)) | |
266 JRT_BLOCK; | |
267 #ifndef PRODUCT | |
268 SharedRuntime::_new_array_ctr++; // new array requires GC | |
269 #endif | |
270 assert(check_compiled_frame(thread), "incorrect caller"); | |
271 | |
272 // Scavenge and allocate an instance. | |
273 oop result; | |
274 | |
275 if (Klass::cast(array_type)->oop_is_typeArray()) { | |
276 // The oopFactory likes to work with the element type. | |
277 // (We could bypass the oopFactory, since it doesn't add much value.) | |
278 BasicType elem_type = typeArrayKlass::cast(array_type)->element_type(); | |
279 result = oopFactory::new_typeArray(elem_type, len, THREAD); | |
280 } else { | |
281 // Although the oopFactory likes to work with the elem_type, | |
282 // the compiler prefers the array_type, since it must already have | |
283 // that latter value in hand for the fast path. | |
284 klassOopDesc* elem_type = objArrayKlass::cast(array_type)->element_klass(); | |
285 result = oopFactory::new_objArray(elem_type, len, THREAD); | |
286 } | |
287 | |
288 // Pass oops back through thread local storage. Our apparent type to Java | |
289 // is that we return an oop, but we can block on exit from this routine and | |
290 // a GC can trash the oop in C's return register. The generated stub will | |
291 // fetch the oop from TLS after any possible GC. | |
292 deoptimize_caller_frame(thread, HAS_PENDING_EXCEPTION); | |
293 thread->set_vm_result(result); | |
294 JRT_BLOCK_END; | |
295 | |
296 if (GraphKit::use_ReduceInitialCardMarks()) { | |
1027
39b01ab7035a
6888898: CMS: ReduceInitialCardMarks unsafe in the presence of cms precleaning
ysr
parents:
605
diff
changeset
|
297 // inform GC that we won't do card marks for initializing writes. |
1166 | 298 new_store_pre_barrier(thread); |
0 | 299 } |
300 JRT_END | |
301 | |
302 // Note: multianewarray for one dimension is handled inline by GraphKit::new_array. | |
303 | |
304 // multianewarray for 2 dimensions | |
305 JRT_ENTRY(void, OptoRuntime::multianewarray2_C(klassOopDesc* elem_type, int len1, int len2, JavaThread *thread)) | |
306 #ifndef PRODUCT | |
307 SharedRuntime::_multi2_ctr++; // multianewarray for 1 dimension | |
308 #endif | |
309 assert(check_compiled_frame(thread), "incorrect caller"); | |
310 assert(oop(elem_type)->is_klass(), "not a class"); | |
311 jint dims[2]; | |
312 dims[0] = len1; | |
313 dims[1] = len2; | |
314 oop obj = arrayKlass::cast(elem_type)->multi_allocate(2, dims, THREAD); | |
315 deoptimize_caller_frame(thread, HAS_PENDING_EXCEPTION); | |
316 thread->set_vm_result(obj); | |
317 JRT_END | |
318 | |
319 // multianewarray for 3 dimensions | |
320 JRT_ENTRY(void, OptoRuntime::multianewarray3_C(klassOopDesc* elem_type, int len1, int len2, int len3, JavaThread *thread)) | |
321 #ifndef PRODUCT | |
322 SharedRuntime::_multi3_ctr++; // multianewarray for 1 dimension | |
323 #endif | |
324 assert(check_compiled_frame(thread), "incorrect caller"); | |
325 assert(oop(elem_type)->is_klass(), "not a class"); | |
326 jint dims[3]; | |
327 dims[0] = len1; | |
328 dims[1] = len2; | |
329 dims[2] = len3; | |
330 oop obj = arrayKlass::cast(elem_type)->multi_allocate(3, dims, THREAD); | |
331 deoptimize_caller_frame(thread, HAS_PENDING_EXCEPTION); | |
332 thread->set_vm_result(obj); | |
333 JRT_END | |
334 | |
335 // multianewarray for 4 dimensions | |
336 JRT_ENTRY(void, OptoRuntime::multianewarray4_C(klassOopDesc* elem_type, int len1, int len2, int len3, int len4, JavaThread *thread)) | |
337 #ifndef PRODUCT | |
338 SharedRuntime::_multi4_ctr++; // multianewarray for 1 dimension | |
339 #endif | |
340 assert(check_compiled_frame(thread), "incorrect caller"); | |
341 assert(oop(elem_type)->is_klass(), "not a class"); | |
342 jint dims[4]; | |
343 dims[0] = len1; | |
344 dims[1] = len2; | |
345 dims[2] = len3; | |
346 dims[3] = len4; | |
347 oop obj = arrayKlass::cast(elem_type)->multi_allocate(4, dims, THREAD); | |
348 deoptimize_caller_frame(thread, HAS_PENDING_EXCEPTION); | |
349 thread->set_vm_result(obj); | |
350 JRT_END | |
351 | |
352 // multianewarray for 5 dimensions | |
353 JRT_ENTRY(void, OptoRuntime::multianewarray5_C(klassOopDesc* elem_type, int len1, int len2, int len3, int len4, int len5, JavaThread *thread)) | |
354 #ifndef PRODUCT | |
355 SharedRuntime::_multi5_ctr++; // multianewarray for 1 dimension | |
356 #endif | |
357 assert(check_compiled_frame(thread), "incorrect caller"); | |
358 assert(oop(elem_type)->is_klass(), "not a class"); | |
359 jint dims[5]; | |
360 dims[0] = len1; | |
361 dims[1] = len2; | |
362 dims[2] = len3; | |
363 dims[3] = len4; | |
364 dims[4] = len5; | |
365 oop obj = arrayKlass::cast(elem_type)->multi_allocate(5, dims, THREAD); | |
366 deoptimize_caller_frame(thread, HAS_PENDING_EXCEPTION); | |
367 thread->set_vm_result(obj); | |
368 JRT_END | |
369 | |
370 const TypeFunc *OptoRuntime::new_instance_Type() { | |
371 // create input type (domain) | |
372 const Type **fields = TypeTuple::fields(1); | |
373 fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; // Klass to be allocated | |
374 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+1, fields); | |
375 | |
376 // create result type (range) | |
377 fields = TypeTuple::fields(1); | |
378 fields[TypeFunc::Parms+0] = TypeRawPtr::NOTNULL; // Returned oop | |
379 | |
380 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+1, fields); | |
381 | |
382 return TypeFunc::make(domain, range); | |
383 } | |
384 | |
385 | |
386 const TypeFunc *OptoRuntime::athrow_Type() { | |
387 // create input type (domain) | |
388 const Type **fields = TypeTuple::fields(1); | |
389 fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; // Klass to be allocated | |
390 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+1, fields); | |
391 | |
392 // create result type (range) | |
393 fields = TypeTuple::fields(0); | |
394 | |
395 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0, fields); | |
396 | |
397 return TypeFunc::make(domain, range); | |
398 } | |
399 | |
400 | |
401 const TypeFunc *OptoRuntime::new_array_Type() { | |
402 // create input type (domain) | |
403 const Type **fields = TypeTuple::fields(2); | |
404 fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; // element klass | |
405 fields[TypeFunc::Parms+1] = TypeInt::INT; // array size | |
406 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+2, fields); | |
407 | |
408 // create result type (range) | |
409 fields = TypeTuple::fields(1); | |
410 fields[TypeFunc::Parms+0] = TypeRawPtr::NOTNULL; // Returned oop | |
411 | |
412 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+1, fields); | |
413 | |
414 return TypeFunc::make(domain, range); | |
415 } | |
416 | |
417 const TypeFunc *OptoRuntime::multianewarray_Type(int ndim) { | |
418 // create input type (domain) | |
419 const int nargs = ndim + 1; | |
420 const Type **fields = TypeTuple::fields(nargs); | |
421 fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; // element klass | |
422 for( int i = 1; i < nargs; i++ ) | |
423 fields[TypeFunc::Parms + i] = TypeInt::INT; // array size | |
424 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+nargs, fields); | |
425 | |
426 // create result type (range) | |
427 fields = TypeTuple::fields(1); | |
428 fields[TypeFunc::Parms+0] = TypeRawPtr::NOTNULL; // Returned oop | |
429 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+1, fields); | |
430 | |
431 return TypeFunc::make(domain, range); | |
432 } | |
433 | |
434 const TypeFunc *OptoRuntime::multianewarray2_Type() { | |
435 return multianewarray_Type(2); | |
436 } | |
437 | |
438 const TypeFunc *OptoRuntime::multianewarray3_Type() { | |
439 return multianewarray_Type(3); | |
440 } | |
441 | |
442 const TypeFunc *OptoRuntime::multianewarray4_Type() { | |
443 return multianewarray_Type(4); | |
444 } | |
445 | |
446 const TypeFunc *OptoRuntime::multianewarray5_Type() { | |
447 return multianewarray_Type(5); | |
448 } | |
449 | |
342 | 450 const TypeFunc *OptoRuntime::g1_wb_pre_Type() { |
451 const Type **fields = TypeTuple::fields(2); | |
452 fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; // original field value | |
453 fields[TypeFunc::Parms+1] = TypeRawPtr::NOTNULL; // thread | |
454 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+2, fields); | |
455 | |
456 // create result type (range) | |
457 fields = TypeTuple::fields(0); | |
458 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0, fields); | |
459 | |
460 return TypeFunc::make(domain, range); | |
461 } | |
462 | |
463 const TypeFunc *OptoRuntime::g1_wb_post_Type() { | |
464 | |
465 const Type **fields = TypeTuple::fields(2); | |
466 fields[TypeFunc::Parms+0] = TypeRawPtr::NOTNULL; // Card addr | |
467 fields[TypeFunc::Parms+1] = TypeRawPtr::NOTNULL; // thread | |
468 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+2, fields); | |
469 | |
470 // create result type (range) | |
471 fields = TypeTuple::fields(0); | |
472 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms, fields); | |
473 | |
474 return TypeFunc::make(domain, range); | |
475 } | |
476 | |
0 | 477 const TypeFunc *OptoRuntime::uncommon_trap_Type() { |
478 // create input type (domain) | |
479 const Type **fields = TypeTuple::fields(1); | |
480 // symbolOop name of class to be loaded | |
481 fields[TypeFunc::Parms+0] = TypeInt::INT; | |
482 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+1, fields); | |
483 | |
484 // create result type (range) | |
485 fields = TypeTuple::fields(0); | |
486 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0, fields); | |
487 | |
488 return TypeFunc::make(domain, range); | |
489 } | |
490 | |
491 # ifdef ENABLE_ZAP_DEAD_LOCALS | |
492 // Type used for stub generation for zap_dead_locals. | |
493 // No inputs or outputs | |
494 const TypeFunc *OptoRuntime::zap_dead_locals_Type() { | |
495 // create input type (domain) | |
496 const Type **fields = TypeTuple::fields(0); | |
497 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms,fields); | |
498 | |
499 // create result type (range) | |
500 fields = TypeTuple::fields(0); | |
501 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms,fields); | |
502 | |
503 return TypeFunc::make(domain,range); | |
504 } | |
505 # endif | |
506 | |
507 | |
508 //----------------------------------------------------------------------------- | |
509 // Monitor Handling | |
510 const TypeFunc *OptoRuntime::complete_monitor_enter_Type() { | |
511 // create input type (domain) | |
512 const Type **fields = TypeTuple::fields(2); | |
513 fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; // Object to be Locked | |
514 fields[TypeFunc::Parms+1] = TypeRawPtr::BOTTOM; // Address of stack location for lock | |
515 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+2,fields); | |
516 | |
517 // create result type (range) | |
518 fields = TypeTuple::fields(0); | |
519 | |
520 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0,fields); | |
521 | |
522 return TypeFunc::make(domain,range); | |
523 } | |
524 | |
525 | |
526 //----------------------------------------------------------------------------- | |
527 const TypeFunc *OptoRuntime::complete_monitor_exit_Type() { | |
528 // create input type (domain) | |
529 const Type **fields = TypeTuple::fields(2); | |
530 fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; // Object to be Locked | |
531 fields[TypeFunc::Parms+1] = TypeRawPtr::BOTTOM; // Address of stack location for lock | |
532 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+2,fields); | |
533 | |
534 // create result type (range) | |
535 fields = TypeTuple::fields(0); | |
536 | |
537 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0,fields); | |
538 | |
539 return TypeFunc::make(domain,range); | |
540 } | |
541 | |
542 const TypeFunc* OptoRuntime::flush_windows_Type() { | |
543 // create input type (domain) | |
544 const Type** fields = TypeTuple::fields(1); | |
545 fields[TypeFunc::Parms+0] = NULL; // void | |
546 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms, fields); | |
547 | |
548 // create result type | |
549 fields = TypeTuple::fields(1); | |
550 fields[TypeFunc::Parms+0] = NULL; // void | |
551 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms, fields); | |
552 | |
553 return TypeFunc::make(domain, range); | |
554 } | |
555 | |
556 const TypeFunc* OptoRuntime::l2f_Type() { | |
557 // create input type (domain) | |
558 const Type **fields = TypeTuple::fields(2); | |
559 fields[TypeFunc::Parms+0] = TypeLong::LONG; | |
560 fields[TypeFunc::Parms+1] = Type::HALF; | |
561 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+2, fields); | |
562 | |
563 // create result type (range) | |
564 fields = TypeTuple::fields(1); | |
565 fields[TypeFunc::Parms+0] = Type::FLOAT; | |
566 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+1, fields); | |
567 | |
568 return TypeFunc::make(domain, range); | |
569 } | |
570 | |
571 const TypeFunc* OptoRuntime::modf_Type() { | |
572 const Type **fields = TypeTuple::fields(2); | |
573 fields[TypeFunc::Parms+0] = Type::FLOAT; | |
574 fields[TypeFunc::Parms+1] = Type::FLOAT; | |
575 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+2, fields); | |
576 | |
577 // create result type (range) | |
578 fields = TypeTuple::fields(1); | |
579 fields[TypeFunc::Parms+0] = Type::FLOAT; | |
580 | |
581 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+1, fields); | |
582 | |
583 return TypeFunc::make(domain, range); | |
584 } | |
585 | |
586 const TypeFunc *OptoRuntime::Math_D_D_Type() { | |
587 // create input type (domain) | |
588 const Type **fields = TypeTuple::fields(2); | |
589 // symbolOop name of class to be loaded | |
590 fields[TypeFunc::Parms+0] = Type::DOUBLE; | |
591 fields[TypeFunc::Parms+1] = Type::HALF; | |
592 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+2, fields); | |
593 | |
594 // create result type (range) | |
595 fields = TypeTuple::fields(2); | |
596 fields[TypeFunc::Parms+0] = Type::DOUBLE; | |
597 fields[TypeFunc::Parms+1] = Type::HALF; | |
598 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+2, fields); | |
599 | |
600 return TypeFunc::make(domain, range); | |
601 } | |
602 | |
603 const TypeFunc* OptoRuntime::Math_DD_D_Type() { | |
604 const Type **fields = TypeTuple::fields(4); | |
605 fields[TypeFunc::Parms+0] = Type::DOUBLE; | |
606 fields[TypeFunc::Parms+1] = Type::HALF; | |
607 fields[TypeFunc::Parms+2] = Type::DOUBLE; | |
608 fields[TypeFunc::Parms+3] = Type::HALF; | |
609 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+4, fields); | |
610 | |
611 // create result type (range) | |
612 fields = TypeTuple::fields(2); | |
613 fields[TypeFunc::Parms+0] = Type::DOUBLE; | |
614 fields[TypeFunc::Parms+1] = Type::HALF; | |
615 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+2, fields); | |
616 | |
617 return TypeFunc::make(domain, range); | |
618 } | |
619 | |
620 //-------------- currentTimeMillis | |
621 | |
622 const TypeFunc* OptoRuntime::current_time_millis_Type() { | |
623 // create input type (domain) | |
624 const Type **fields = TypeTuple::fields(0); | |
625 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+0, fields); | |
626 | |
627 // create result type (range) | |
628 fields = TypeTuple::fields(2); | |
629 fields[TypeFunc::Parms+0] = TypeLong::LONG; | |
630 fields[TypeFunc::Parms+1] = Type::HALF; | |
631 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+2, fields); | |
632 | |
633 return TypeFunc::make(domain, range); | |
634 } | |
635 | |
636 // arraycopy stub variations: | |
637 enum ArrayCopyType { | |
638 ac_fast, // void(ptr, ptr, size_t) | |
639 ac_checkcast, // int(ptr, ptr, size_t, size_t, ptr) | |
640 ac_slow, // void(ptr, int, ptr, int, int) | |
641 ac_generic // int(ptr, int, ptr, int, int) | |
642 }; | |
643 | |
644 static const TypeFunc* make_arraycopy_Type(ArrayCopyType act) { | |
645 // create input type (domain) | |
646 int num_args = (act == ac_fast ? 3 : 5); | |
647 int num_size_args = (act == ac_fast ? 1 : act == ac_checkcast ? 2 : 0); | |
648 int argcnt = num_args; | |
649 LP64_ONLY(argcnt += num_size_args); // halfwords for lengths | |
650 const Type** fields = TypeTuple::fields(argcnt); | |
651 int argp = TypeFunc::Parms; | |
652 fields[argp++] = TypePtr::NOTNULL; // src | |
653 if (num_size_args == 0) { | |
654 fields[argp++] = TypeInt::INT; // src_pos | |
655 } | |
656 fields[argp++] = TypePtr::NOTNULL; // dest | |
657 if (num_size_args == 0) { | |
658 fields[argp++] = TypeInt::INT; // dest_pos | |
659 fields[argp++] = TypeInt::INT; // length | |
660 } | |
661 while (num_size_args-- > 0) { | |
662 fields[argp++] = TypeX_X; // size in whatevers (size_t) | |
663 LP64_ONLY(fields[argp++] = Type::HALF); // other half of long length | |
664 } | |
665 if (act == ac_checkcast) { | |
666 fields[argp++] = TypePtr::NOTNULL; // super_klass | |
667 } | |
668 assert(argp == TypeFunc::Parms+argcnt, "correct decoding of act"); | |
669 const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms+argcnt, fields); | |
670 | |
671 // create result type if needed | |
672 int retcnt = (act == ac_checkcast || act == ac_generic ? 1 : 0); | |
673 fields = TypeTuple::fields(1); | |
674 if (retcnt == 0) | |
675 fields[TypeFunc::Parms+0] = NULL; // void | |
676 else | |
677 fields[TypeFunc::Parms+0] = TypeInt::INT; // status result, if needed | |
678 const TypeTuple* range = TypeTuple::make(TypeFunc::Parms+retcnt, fields); | |
679 return TypeFunc::make(domain, range); | |
680 } | |
681 | |
682 const TypeFunc* OptoRuntime::fast_arraycopy_Type() { | |
683 // This signature is simple: Two base pointers and a size_t. | |
684 return make_arraycopy_Type(ac_fast); | |
685 } | |
686 | |
687 const TypeFunc* OptoRuntime::checkcast_arraycopy_Type() { | |
688 // An extension of fast_arraycopy_Type which adds type checking. | |
689 return make_arraycopy_Type(ac_checkcast); | |
690 } | |
691 | |
692 const TypeFunc* OptoRuntime::slow_arraycopy_Type() { | |
693 // This signature is exactly the same as System.arraycopy. | |
694 // There are no intptr_t (int/long) arguments. | |
695 return make_arraycopy_Type(ac_slow); | |
696 } | |
697 | |
698 const TypeFunc* OptoRuntime::generic_arraycopy_Type() { | |
699 // This signature is like System.arraycopy, except that it returns status. | |
700 return make_arraycopy_Type(ac_generic); | |
701 } | |
702 | |
703 | |
1763 | 704 const TypeFunc* OptoRuntime::array_fill_Type() { |
1844
75588558f1bf
6980792: Crash "exception happened outside interpreter, nmethods and vtable stubs (1)"
never
parents:
1763
diff
changeset
|
705 // create input type (domain): pointer, int, size_t |
75588558f1bf
6980792: Crash "exception happened outside interpreter, nmethods and vtable stubs (1)"
never
parents:
1763
diff
changeset
|
706 const Type** fields = TypeTuple::fields(3 LP64_ONLY( + 1)); |
75588558f1bf
6980792: Crash "exception happened outside interpreter, nmethods and vtable stubs (1)"
never
parents:
1763
diff
changeset
|
707 int argp = TypeFunc::Parms; |
75588558f1bf
6980792: Crash "exception happened outside interpreter, nmethods and vtable stubs (1)"
never
parents:
1763
diff
changeset
|
708 fields[argp++] = TypePtr::NOTNULL; |
75588558f1bf
6980792: Crash "exception happened outside interpreter, nmethods and vtable stubs (1)"
never
parents:
1763
diff
changeset
|
709 fields[argp++] = TypeInt::INT; |
75588558f1bf
6980792: Crash "exception happened outside interpreter, nmethods and vtable stubs (1)"
never
parents:
1763
diff
changeset
|
710 fields[argp++] = TypeX_X; // size in whatevers (size_t) |
75588558f1bf
6980792: Crash "exception happened outside interpreter, nmethods and vtable stubs (1)"
never
parents:
1763
diff
changeset
|
711 LP64_ONLY(fields[argp++] = Type::HALF); // other half of long length |
75588558f1bf
6980792: Crash "exception happened outside interpreter, nmethods and vtable stubs (1)"
never
parents:
1763
diff
changeset
|
712 const TypeTuple *domain = TypeTuple::make(argp, fields); |
1763 | 713 |
714 // create result type | |
715 fields = TypeTuple::fields(1); | |
716 fields[TypeFunc::Parms+0] = NULL; // void | |
717 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms, fields); | |
718 | |
719 return TypeFunc::make(domain, range); | |
720 } | |
721 | |
0 | 722 //------------- Interpreter state access for on stack replacement |
723 const TypeFunc* OptoRuntime::osr_end_Type() { | |
724 // create input type (domain) | |
725 const Type **fields = TypeTuple::fields(1); | |
726 fields[TypeFunc::Parms+0] = TypeRawPtr::BOTTOM; // OSR temp buf | |
727 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+1, fields); | |
728 | |
729 // create result type | |
730 fields = TypeTuple::fields(1); | |
731 // fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; // locked oop | |
732 fields[TypeFunc::Parms+0] = NULL; // void | |
733 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms, fields); | |
734 return TypeFunc::make(domain, range); | |
735 } | |
736 | |
737 //-------------- methodData update helpers | |
738 | |
739 const TypeFunc* OptoRuntime::profile_receiver_type_Type() { | |
740 // create input type (domain) | |
741 const Type **fields = TypeTuple::fields(2); | |
742 fields[TypeFunc::Parms+0] = TypeAryPtr::NOTNULL; // methodData pointer | |
743 fields[TypeFunc::Parms+1] = TypeInstPtr::BOTTOM; // receiver oop | |
744 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+2, fields); | |
745 | |
746 // create result type | |
747 fields = TypeTuple::fields(1); | |
748 fields[TypeFunc::Parms+0] = NULL; // void | |
749 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms, fields); | |
750 return TypeFunc::make(domain,range); | |
751 } | |
752 | |
753 JRT_LEAF(void, OptoRuntime::profile_receiver_type_C(DataLayout* data, oopDesc* receiver)) | |
754 if (receiver == NULL) return; | |
755 klassOop receiver_klass = receiver->klass(); | |
756 | |
757 intptr_t* mdp = ((intptr_t*)(data)) + DataLayout::header_size_in_cells(); | |
758 int empty_row = -1; // free row, if any is encountered | |
759 | |
760 // ReceiverTypeData* vc = new ReceiverTypeData(mdp); | |
761 for (uint row = 0; row < ReceiverTypeData::row_limit(); row++) { | |
762 // if (vc->receiver(row) == receiver_klass) | |
763 int receiver_off = ReceiverTypeData::receiver_cell_index(row); | |
764 intptr_t row_recv = *(mdp + receiver_off); | |
765 if (row_recv == (intptr_t) receiver_klass) { | |
766 // vc->set_receiver_count(row, vc->receiver_count(row) + DataLayout::counter_increment); | |
767 int count_off = ReceiverTypeData::receiver_count_cell_index(row); | |
768 *(mdp + count_off) += DataLayout::counter_increment; | |
769 return; | |
770 } else if (row_recv == 0) { | |
771 // else if (vc->receiver(row) == NULL) | |
772 empty_row = (int) row; | |
773 } | |
774 } | |
775 | |
776 if (empty_row != -1) { | |
777 int receiver_off = ReceiverTypeData::receiver_cell_index(empty_row); | |
778 // vc->set_receiver(empty_row, receiver_klass); | |
779 *(mdp + receiver_off) = (intptr_t) receiver_klass; | |
780 // vc->set_receiver_count(empty_row, DataLayout::counter_increment); | |
781 int count_off = ReceiverTypeData::receiver_count_cell_index(empty_row); | |
782 *(mdp + count_off) = DataLayout::counter_increment; | |
1206
87684f1a88b5
6614597: Performance variability in jvm2008 xml.validation
kvn
parents:
1166
diff
changeset
|
783 } else { |
87684f1a88b5
6614597: Performance variability in jvm2008 xml.validation
kvn
parents:
1166
diff
changeset
|
784 // Receiver did not match any saved receiver and there is no empty row for it. |
1251
576e77447e3c
6923002: assert(false,"this call site should not be polymorphic")
kvn
parents:
1206
diff
changeset
|
785 // Increment total counter to indicate polymorphic case. |
1206
87684f1a88b5
6614597: Performance variability in jvm2008 xml.validation
kvn
parents:
1166
diff
changeset
|
786 intptr_t* count_p = (intptr_t*)(((byte*)(data)) + in_bytes(CounterData::count_offset())); |
87684f1a88b5
6614597: Performance variability in jvm2008 xml.validation
kvn
parents:
1166
diff
changeset
|
787 *count_p += DataLayout::counter_increment; |
0 | 788 } |
789 JRT_END | |
790 | |
791 //----------------------------------------------------------------------------- | |
792 // implicit exception support. | |
793 | |
794 static void report_null_exception_in_code_cache(address exception_pc) { | |
795 ResourceMark rm; | |
796 CodeBlob* n = CodeCache::find_blob(exception_pc); | |
797 if (n != NULL) { | |
798 tty->print_cr("#"); | |
799 tty->print_cr("# HotSpot Runtime Error, null exception in generated code"); | |
800 tty->print_cr("#"); | |
801 tty->print_cr("# pc where exception happened = " INTPTR_FORMAT, exception_pc); | |
802 | |
803 if (n->is_nmethod()) { | |
804 methodOop method = ((nmethod*)n)->method(); | |
805 tty->print_cr("# Method where it happened %s.%s ", Klass::cast(method->method_holder())->name()->as_C_string(), method->name()->as_C_string()); | |
806 tty->print_cr("#"); | |
807 if (ShowMessageBoxOnError && UpdateHotSpotCompilerFileOnError) { | |
808 const char* title = "HotSpot Runtime Error"; | |
809 const char* question = "Do you want to exclude compilation of this method in future runs?"; | |
810 if (os::message_box(title, question)) { | |
811 CompilerOracle::append_comment_to_file(""); | |
812 CompilerOracle::append_comment_to_file("Null exception in compiled code resulted in the following exclude"); | |
813 CompilerOracle::append_comment_to_file(""); | |
814 CompilerOracle::append_exclude_to_file(method); | |
815 tty->print_cr("#"); | |
816 tty->print_cr("# %s has been updated to exclude the specified method", CompileCommandFile); | |
817 tty->print_cr("#"); | |
818 } | |
819 } | |
820 fatal("Implicit null exception happened in compiled method"); | |
821 } else { | |
822 n->print(); | |
823 fatal("Implicit null exception happened in generated stub"); | |
824 } | |
825 } | |
826 fatal("Implicit null exception at wrong place"); | |
827 } | |
828 | |
829 | |
830 //------------------------------------------------------------------------------------- | |
831 // register policy | |
832 | |
833 bool OptoRuntime::is_callee_saved_register(MachRegisterNumbers reg) { | |
834 assert(reg >= 0 && reg < _last_Mach_Reg, "must be a machine register"); | |
835 switch (register_save_policy[reg]) { | |
836 case 'C': return false; //SOC | |
837 case 'E': return true ; //SOE | |
838 case 'N': return false; //NS | |
839 case 'A': return false; //AS | |
840 } | |
841 ShouldNotReachHere(); | |
842 return false; | |
843 } | |
844 | |
845 //----------------------------------------------------------------------- | |
846 // Exceptions | |
847 // | |
848 | |
849 static void trace_exception(oop exception_oop, address exception_pc, const char* msg) PRODUCT_RETURN; | |
850 | |
851 // The method is an entry that is always called by a C++ method not | |
852 // directly from compiled code. Compiled code will call the C++ method following. | |
853 // We can't allow async exception to be installed during exception processing. | |
854 JRT_ENTRY_NO_ASYNC(address, OptoRuntime::handle_exception_C_helper(JavaThread* thread, nmethod* &nm)) | |
855 | |
856 // Do not confuse exception_oop with pending_exception. The exception_oop | |
857 // is only used to pass arguments into the method. Not for general | |
858 // exception handling. DO NOT CHANGE IT to use pending_exception, since | |
859 // the runtime stubs checks this on exit. | |
860 assert(thread->exception_oop() != NULL, "exception oop is found"); | |
861 address handler_address = NULL; | |
862 | |
863 Handle exception(thread, thread->exception_oop()); | |
864 | |
865 if (TraceExceptions) { | |
866 trace_exception(exception(), thread->exception_pc(), ""); | |
867 } | |
868 // for AbortVMOnException flag | |
869 NOT_PRODUCT(Exceptions::debug_check_abort(exception)); | |
870 | |
871 #ifdef ASSERT | |
1142 | 872 if (!(exception->is_a(SystemDictionary::Throwable_klass()))) { |
0 | 873 // should throw an exception here |
874 ShouldNotReachHere(); | |
875 } | |
876 #endif | |
877 | |
878 | |
879 // new exception handling: this method is entered only from adapters | |
880 // exceptions from compiled java methods are handled in compiled code | |
881 // using rethrow node | |
882 | |
883 address pc = thread->exception_pc(); | |
884 nm = CodeCache::find_nmethod(pc); | |
885 assert(nm != NULL, "No NMethod found"); | |
886 if (nm->is_native_method()) { | |
887 fatal("Native mathod should not have path to exception handling"); | |
888 } else { | |
889 // we are switching to old paradigm: search for exception handler in caller_frame | |
890 // instead in exception handler of caller_frame.sender() | |
891 | |
1213
6deeaebad47a
6902182: 4/4 Starting with jdwp agent should not incur performance penalty
dcubed
parents:
1166
diff
changeset
|
892 if (JvmtiExport::can_post_on_exceptions()) { |
0 | 893 // "Full-speed catching" is not necessary here, |
894 // since we're notifying the VM on every catch. | |
895 // Force deoptimization and the rest of the lookup | |
896 // will be fine. | |
897 deoptimize_caller_frame(thread, true); | |
898 } | |
899 | |
900 // Check the stack guard pages. If enabled, look for handler in this frame; | |
901 // otherwise, forcibly unwind the frame. | |
902 // | |
903 // 4826555: use default current sp for reguard_stack instead of &nm: it's more accurate. | |
904 bool force_unwind = !thread->reguard_stack(); | |
905 bool deopting = false; | |
906 if (nm->is_deopt_pc(pc)) { | |
907 deopting = true; | |
908 RegisterMap map(thread, false); | |
909 frame deoptee = thread->last_frame().sender(&map); | |
910 assert(deoptee.is_deoptimized_frame(), "must be deopted"); | |
911 // Adjust the pc back to the original throwing pc | |
912 pc = deoptee.pc(); | |
913 } | |
914 | |
915 // If we are forcing an unwind because of stack overflow then deopt is | |
916 // irrelevant sice we are throwing the frame away anyway. | |
917 | |
918 if (deopting && !force_unwind) { | |
919 handler_address = SharedRuntime::deopt_blob()->unpack_with_exception(); | |
920 } else { | |
921 | |
922 handler_address = | |
923 force_unwind ? NULL : nm->handler_for_exception_and_pc(exception, pc); | |
924 | |
925 if (handler_address == NULL) { | |
926 handler_address = SharedRuntime::compute_compiled_exc_handler(nm, pc, exception, force_unwind, true); | |
927 assert (handler_address != NULL, "must have compiled handler"); | |
928 // Update the exception cache only when the unwind was not forced. | |
929 if (!force_unwind) { | |
930 nm->add_handler_for_exception_and_pc(exception,pc,handler_address); | |
931 } | |
932 } else { | |
933 assert(handler_address == SharedRuntime::compute_compiled_exc_handler(nm, pc, exception, force_unwind, true), "Must be the same"); | |
934 } | |
935 } | |
936 | |
937 thread->set_exception_pc(pc); | |
938 thread->set_exception_handler_pc(handler_address); | |
939 thread->set_exception_stack_size(0); | |
1135
e66fd840cb6b
6893081: method handle & invokedynamic code needs additional cleanup (post 6815692, 6858164)
twisti
parents:
1027
diff
changeset
|
940 |
1295 | 941 // Check if the exception PC is a MethodHandle call site. |
1368
93767e6a2dfd
6941529: SharedRuntime::raw_exception_handler_for_return_address must reset thread MethodHandle flag
twisti
parents:
1295
diff
changeset
|
942 thread->set_is_method_handle_return(nm->is_method_handle_return(pc)); |
0 | 943 } |
944 | |
945 // Restore correct return pc. Was saved above. | |
946 thread->set_exception_oop(exception()); | |
947 return handler_address; | |
948 | |
949 JRT_END | |
950 | |
951 // We are entering here from exception_blob | |
952 // If there is a compiled exception handler in this method, we will continue there; | |
953 // otherwise we will unwind the stack and continue at the caller of top frame method | |
954 // Note we enter without the usual JRT wrapper. We will call a helper routine that | |
955 // will do the normal VM entry. We do it this way so that we can see if the nmethod | |
956 // we looked up the handler for has been deoptimized in the meantime. If it has been | |
957 // we must not use the handler and instread return the deopt blob. | |
958 address OptoRuntime::handle_exception_C(JavaThread* thread) { | |
959 // | |
960 // We are in Java not VM and in debug mode we have a NoHandleMark | |
961 // | |
962 #ifndef PRODUCT | |
963 SharedRuntime::_find_handler_ctr++; // find exception handler | |
964 #endif | |
965 debug_only(NoHandleMark __hm;) | |
966 nmethod* nm = NULL; | |
967 address handler_address = NULL; | |
968 { | |
969 // Enter the VM | |
970 | |
971 ResetNoHandleMark rnhm; | |
972 handler_address = handle_exception_C_helper(thread, nm); | |
973 } | |
974 | |
975 // Back in java: Use no oops, DON'T safepoint | |
976 | |
977 // Now check to see if the handler we are returning is in a now | |
978 // deoptimized frame | |
979 | |
980 if (nm != NULL) { | |
981 RegisterMap map(thread, false); | |
982 frame caller = thread->last_frame().sender(&map); | |
983 #ifdef ASSERT | |
984 assert(caller.is_compiled_frame(), "must be"); | |
985 #endif // ASSERT | |
986 if (caller.is_deoptimized_frame()) { | |
987 handler_address = SharedRuntime::deopt_blob()->unpack_with_exception(); | |
988 } | |
989 } | |
990 return handler_address; | |
991 } | |
992 | |
993 //------------------------------rethrow---------------------------------------- | |
994 // We get here after compiled code has executed a 'RethrowNode'. The callee | |
995 // is either throwing or rethrowing an exception. The callee-save registers | |
996 // have been restored, synchronized objects have been unlocked and the callee | |
997 // stack frame has been removed. The return address was passed in. | |
998 // Exception oop is passed as the 1st argument. This routine is then called | |
999 // from the stub. On exit, we know where to jump in the caller's code. | |
1000 // After this C code exits, the stub will pop his frame and end in a jump | |
1001 // (instead of a return). We enter the caller's default handler. | |
1002 // | |
1003 // This must be JRT_LEAF: | |
1004 // - caller will not change its state as we cannot block on exit, | |
1005 // therefore raw_exception_handler_for_return_address is all it takes | |
1006 // to handle deoptimized blobs | |
1007 // | |
1008 // However, there needs to be a safepoint check in the middle! So compiled | |
1009 // safepoints are completely watertight. | |
1010 // | |
1011 // Thus, it cannot be a leaf since it contains the No_GC_Verifier. | |
1012 // | |
1013 // *THIS IS NOT RECOMMENDED PROGRAMMING STYLE* | |
1014 // | |
1015 address OptoRuntime::rethrow_C(oopDesc* exception, JavaThread* thread, address ret_pc) { | |
1016 #ifndef PRODUCT | |
1017 SharedRuntime::_rethrow_ctr++; // count rethrows | |
1018 #endif | |
1019 assert (exception != NULL, "should have thrown a NULLPointerException"); | |
1020 #ifdef ASSERT | |
1142 | 1021 if (!(exception->is_a(SystemDictionary::Throwable_klass()))) { |
0 | 1022 // should throw an exception here |
1023 ShouldNotReachHere(); | |
1024 } | |
1025 #endif | |
1026 | |
1027 thread->set_vm_result(exception); | |
1028 // Frame not compiled (handles deoptimization blob) | |
1295 | 1029 return SharedRuntime::raw_exception_handler_for_return_address(thread, ret_pc); |
0 | 1030 } |
1031 | |
1032 | |
1033 const TypeFunc *OptoRuntime::rethrow_Type() { | |
1034 // create input type (domain) | |
1035 const Type **fields = TypeTuple::fields(1); | |
1036 fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; // Exception oop | |
1037 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+1,fields); | |
1038 | |
1039 // create result type (range) | |
1040 fields = TypeTuple::fields(1); | |
1041 fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; // Exception oop | |
1042 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+1, fields); | |
1043 | |
1044 return TypeFunc::make(domain, range); | |
1045 } | |
1046 | |
1047 | |
1048 void OptoRuntime::deoptimize_caller_frame(JavaThread *thread, bool doit) { | |
1049 // Deoptimize frame | |
1050 if (doit) { | |
1051 // Called from within the owner thread, so no need for safepoint | |
1052 RegisterMap reg_map(thread); | |
1053 frame stub_frame = thread->last_frame(); | |
1054 assert(stub_frame.is_runtime_frame() || exception_blob()->contains(stub_frame.pc()), "sanity check"); | |
1055 frame caller_frame = stub_frame.sender(®_map); | |
1056 | |
1213
6deeaebad47a
6902182: 4/4 Starting with jdwp agent should not incur performance penalty
dcubed
parents:
1166
diff
changeset
|
1057 // bypass VM_DeoptimizeFrame and deoptimize the frame directly |
6deeaebad47a
6902182: 4/4 Starting with jdwp agent should not incur performance penalty
dcubed
parents:
1166
diff
changeset
|
1058 Deoptimization::deoptimize_frame(thread, caller_frame.id()); |
0 | 1059 } |
1060 } | |
1061 | |
1062 | |
1063 const TypeFunc *OptoRuntime::register_finalizer_Type() { | |
1064 // create input type (domain) | |
1065 const Type **fields = TypeTuple::fields(1); | |
1066 fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; // oop; Receiver | |
1067 // // The JavaThread* is passed to each routine as the last argument | |
1068 // fields[TypeFunc::Parms+1] = TypeRawPtr::NOTNULL; // JavaThread *; Executing thread | |
1069 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+1,fields); | |
1070 | |
1071 // create result type (range) | |
1072 fields = TypeTuple::fields(0); | |
1073 | |
1074 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0,fields); | |
1075 | |
1076 return TypeFunc::make(domain,range); | |
1077 } | |
1078 | |
1079 | |
1080 //----------------------------------------------------------------------------- | |
1081 // Dtrace support. entry and exit probes have the same signature | |
1082 const TypeFunc *OptoRuntime::dtrace_method_entry_exit_Type() { | |
1083 // create input type (domain) | |
1084 const Type **fields = TypeTuple::fields(2); | |
1085 fields[TypeFunc::Parms+0] = TypeRawPtr::BOTTOM; // Thread-local storage | |
1086 fields[TypeFunc::Parms+1] = TypeInstPtr::NOTNULL; // methodOop; Method we are entering | |
1087 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+2,fields); | |
1088 | |
1089 // create result type (range) | |
1090 fields = TypeTuple::fields(0); | |
1091 | |
1092 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0,fields); | |
1093 | |
1094 return TypeFunc::make(domain,range); | |
1095 } | |
1096 | |
1097 const TypeFunc *OptoRuntime::dtrace_object_alloc_Type() { | |
1098 // create input type (domain) | |
1099 const Type **fields = TypeTuple::fields(2); | |
1100 fields[TypeFunc::Parms+0] = TypeRawPtr::BOTTOM; // Thread-local storage | |
1101 fields[TypeFunc::Parms+1] = TypeInstPtr::NOTNULL; // oop; newly allocated object | |
1102 | |
1103 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+2,fields); | |
1104 | |
1105 // create result type (range) | |
1106 fields = TypeTuple::fields(0); | |
1107 | |
1108 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0,fields); | |
1109 | |
1110 return TypeFunc::make(domain,range); | |
1111 } | |
1112 | |
1113 | |
1114 JRT_ENTRY_NO_ASYNC(void, OptoRuntime::register_finalizer(oopDesc* obj, JavaThread* thread)) | |
1115 assert(obj->is_oop(), "must be a valid oop"); | |
1116 assert(obj->klass()->klass_part()->has_finalizer(), "shouldn't be here otherwise"); | |
1117 instanceKlass::register_finalizer(instanceOop(obj), CHECK); | |
1118 JRT_END | |
1119 | |
1120 //----------------------------------------------------------------------------- | |
1121 | |
1122 NamedCounter * volatile OptoRuntime::_named_counters = NULL; | |
1123 | |
1124 // | |
1125 // dump the collected NamedCounters. | |
1126 // | |
1127 void OptoRuntime::print_named_counters() { | |
1128 int total_lock_count = 0; | |
1129 int eliminated_lock_count = 0; | |
1130 | |
1131 NamedCounter* c = _named_counters; | |
1132 while (c) { | |
1133 if (c->tag() == NamedCounter::LockCounter || c->tag() == NamedCounter::EliminatedLockCounter) { | |
1134 int count = c->count(); | |
1135 if (count > 0) { | |
1136 bool eliminated = c->tag() == NamedCounter::EliminatedLockCounter; | |
1137 if (Verbose) { | |
1138 tty->print_cr("%d %s%s", count, c->name(), eliminated ? " (eliminated)" : ""); | |
1139 } | |
1140 total_lock_count += count; | |
1141 if (eliminated) { | |
1142 eliminated_lock_count += count; | |
1143 } | |
1144 } | |
1145 } else if (c->tag() == NamedCounter::BiasedLockingCounter) { | |
1146 BiasedLockingCounters* blc = ((BiasedLockingNamedCounter*)c)->counters(); | |
1147 if (blc->nonzero()) { | |
1148 tty->print_cr("%s", c->name()); | |
1149 blc->print_on(tty); | |
1150 } | |
1151 } | |
1152 c = c->next(); | |
1153 } | |
1154 if (total_lock_count > 0) { | |
1155 tty->print_cr("dynamic locks: %d", total_lock_count); | |
1156 if (eliminated_lock_count) { | |
1157 tty->print_cr("eliminated locks: %d (%d%%)", eliminated_lock_count, | |
1158 (int)(eliminated_lock_count * 100.0 / total_lock_count)); | |
1159 } | |
1160 } | |
1161 } | |
1162 | |
1163 // | |
1164 // Allocate a new NamedCounter. The JVMState is used to generate the | |
1165 // name which consists of method@line for the inlining tree. | |
1166 // | |
1167 | |
1168 NamedCounter* OptoRuntime::new_named_counter(JVMState* youngest_jvms, NamedCounter::CounterTag tag) { | |
1169 int max_depth = youngest_jvms->depth(); | |
1170 | |
1171 // Visit scopes from youngest to oldest. | |
1172 bool first = true; | |
1173 stringStream st; | |
1174 for (int depth = max_depth; depth >= 1; depth--) { | |
1175 JVMState* jvms = youngest_jvms->of_depth(depth); | |
1176 ciMethod* m = jvms->has_method() ? jvms->method() : NULL; | |
1177 if (!first) { | |
1178 st.print(" "); | |
1179 } else { | |
1180 first = false; | |
1181 } | |
1182 int bci = jvms->bci(); | |
1183 if (bci < 0) bci = 0; | |
1184 st.print("%s.%s@%d", m->holder()->name()->as_utf8(), m->name()->as_utf8(), bci); | |
1185 // To print linenumbers instead of bci use: m->line_number_from_bci(bci) | |
1186 } | |
1187 NamedCounter* c; | |
1188 if (tag == NamedCounter::BiasedLockingCounter) { | |
1189 c = new BiasedLockingNamedCounter(strdup(st.as_string())); | |
1190 } else { | |
1191 c = new NamedCounter(strdup(st.as_string()), tag); | |
1192 } | |
1193 | |
1194 // atomically add the new counter to the head of the list. We only | |
1195 // add counters so this is safe. | |
1196 NamedCounter* head; | |
1197 do { | |
1198 head = _named_counters; | |
1199 c->set_next(head); | |
1200 } while (Atomic::cmpxchg_ptr(c, &_named_counters, head) != head); | |
1201 return c; | |
1202 } | |
1203 | |
1204 //----------------------------------------------------------------------------- | |
1205 // Non-product code | |
1206 #ifndef PRODUCT | |
1207 | |
1208 int trace_exception_counter = 0; | |
1209 static void trace_exception(oop exception_oop, address exception_pc, const char* msg) { | |
1210 ttyLocker ttyl; | |
1211 trace_exception_counter++; | |
1212 tty->print("%d [Exception (%s): ", trace_exception_counter, msg); | |
1213 exception_oop->print_value(); | |
1214 tty->print(" in "); | |
1215 CodeBlob* blob = CodeCache::find_blob(exception_pc); | |
1216 if (blob->is_nmethod()) { | |
1217 ((nmethod*)blob)->method()->print_value(); | |
1218 } else if (blob->is_runtime_stub()) { | |
1219 tty->print("<runtime-stub>"); | |
1220 } else { | |
1221 tty->print("<unknown>"); | |
1222 } | |
1223 tty->print(" at " INTPTR_FORMAT, exception_pc); | |
1224 tty->print_cr("]"); | |
1225 } | |
1226 | |
1227 #endif // PRODUCT | |
1228 | |
1229 | |
1230 # ifdef ENABLE_ZAP_DEAD_LOCALS | |
1231 // Called from call sites in compiled code with oop maps (actually safepoints) | |
1232 // Zaps dead locals in first java frame. | |
1233 // Is entry because may need to lock to generate oop maps | |
1234 // Currently, only used for compiler frames, but someday may be used | |
1235 // for interpreter frames, too. | |
1236 | |
1237 int OptoRuntime::ZapDeadCompiledLocals_count = 0; | |
1238 | |
1239 // avoid pointers to member funcs with these helpers | |
1240 static bool is_java_frame( frame* f) { return f->is_java_frame(); } | |
1241 static bool is_native_frame(frame* f) { return f->is_native_frame(); } | |
1242 | |
1243 | |
1244 void OptoRuntime::zap_dead_java_or_native_locals(JavaThread* thread, | |
1245 bool (*is_this_the_right_frame_to_zap)(frame*)) { | |
1246 assert(JavaThread::current() == thread, "is this needed?"); | |
1247 | |
1248 if ( !ZapDeadCompiledLocals ) return; | |
1249 | |
1250 bool skip = false; | |
1251 | |
1252 if ( ZapDeadCompiledLocalsFirst == 0 ) ; // nothing special | |
1253 else if ( ZapDeadCompiledLocalsFirst > ZapDeadCompiledLocals_count ) skip = true; | |
1254 else if ( ZapDeadCompiledLocalsFirst == ZapDeadCompiledLocals_count ) | |
1255 warning("starting zapping after skipping"); | |
1256 | |
1257 if ( ZapDeadCompiledLocalsLast == -1 ) ; // nothing special | |
1258 else if ( ZapDeadCompiledLocalsLast < ZapDeadCompiledLocals_count ) skip = true; | |
1259 else if ( ZapDeadCompiledLocalsLast == ZapDeadCompiledLocals_count ) | |
1260 warning("about to zap last zap"); | |
1261 | |
1262 ++ZapDeadCompiledLocals_count; // counts skipped zaps, too | |
1263 | |
1264 if ( skip ) return; | |
1265 | |
1266 // find java frame and zap it | |
1267 | |
1268 for (StackFrameStream sfs(thread); !sfs.is_done(); sfs.next()) { | |
1269 if (is_this_the_right_frame_to_zap(sfs.current()) ) { | |
1270 sfs.current()->zap_dead_locals(thread, sfs.register_map()); | |
1271 return; | |
1272 } | |
1273 } | |
1274 warning("no frame found to zap in zap_dead_Java_locals_C"); | |
1275 } | |
1276 | |
1277 JRT_LEAF(void, OptoRuntime::zap_dead_Java_locals_C(JavaThread* thread)) | |
1278 zap_dead_java_or_native_locals(thread, is_java_frame); | |
1279 JRT_END | |
1280 | |
1281 // The following does not work because for one thing, the | |
1282 // thread state is wrong; it expects java, but it is native. | |
605 | 1283 // Also, the invariants in a native stub are different and |
0 | 1284 // I'm not sure it is safe to have a MachCalRuntimeDirectNode |
1285 // in there. | |
1286 // So for now, we do not zap in native stubs. | |
1287 | |
1288 JRT_LEAF(void, OptoRuntime::zap_dead_native_locals_C(JavaThread* thread)) | |
1289 zap_dead_java_or_native_locals(thread, is_native_frame); | |
1290 JRT_END | |
1291 | |
1292 # endif |