28 #include "code/codeCache.hpp"
29 #include "code/compiledMethod.inline.hpp"
30 #include "code/compiledIC.hpp"
31 #include "code/nmethod.hpp"
32 #include "code/pcDesc.hpp"
33 #include "code/scopeDesc.hpp"
34 #include "code/vtableStubs.hpp"
35 #include "compiler/compileBroker.hpp"
36 #include "compiler/oopMap.hpp"
37 #include "gc/g1/heapRegion.hpp"
38 #include "gc/shared/barrierSet.hpp"
39 #include "gc/shared/collectedHeap.hpp"
40 #include "gc/shared/gcLocker.hpp"
41 #include "interpreter/bytecode.hpp"
42 #include "interpreter/interpreter.hpp"
43 #include "interpreter/linkResolver.hpp"
44 #include "logging/log.hpp"
45 #include "logging/logStream.hpp"
46 #include "memory/oopFactory.hpp"
47 #include "memory/resourceArea.hpp"
48 #include "oops/objArrayKlass.hpp"
49 #include "oops/klass.inline.hpp"
50 #include "oops/oop.inline.hpp"
51 #include "oops/typeArrayOop.inline.hpp"
52 #include "opto/ad.hpp"
53 #include "opto/addnode.hpp"
54 #include "opto/callnode.hpp"
55 #include "opto/cfgnode.hpp"
56 #include "opto/graphKit.hpp"
57 #include "opto/machnode.hpp"
58 #include "opto/matcher.hpp"
59 #include "opto/memnode.hpp"
60 #include "opto/mulnode.hpp"
61 #include "opto/output.hpp"
62 #include "opto/runtime.hpp"
63 #include "opto/subnode.hpp"
64 #include "prims/jvmtiExport.hpp"
65 #include "runtime/atomic.hpp"
66 #include "runtime/frame.inline.hpp"
67 #include "runtime/handles.inline.hpp"
88 //
89 // At command line specify the parameters: -XX:+FullGCALot -XX:FullGCALotStart=100000000
90
91
92
93
94 // Compiled code entry points
95 address OptoRuntime::_new_instance_Java = nullptr;
96 address OptoRuntime::_new_array_Java = nullptr;
97 address OptoRuntime::_new_array_nozero_Java = nullptr;
98 address OptoRuntime::_multianewarray2_Java = nullptr;
99 address OptoRuntime::_multianewarray3_Java = nullptr;
100 address OptoRuntime::_multianewarray4_Java = nullptr;
101 address OptoRuntime::_multianewarray5_Java = nullptr;
102 address OptoRuntime::_multianewarrayN_Java = nullptr;
103 address OptoRuntime::_vtable_must_compile_Java = nullptr;
104 address OptoRuntime::_complete_monitor_locking_Java = nullptr;
105 address OptoRuntime::_monitor_notify_Java = nullptr;
106 address OptoRuntime::_monitor_notifyAll_Java = nullptr;
107 address OptoRuntime::_rethrow_Java = nullptr;
108
109 address OptoRuntime::_slow_arraycopy_Java = nullptr;
110 address OptoRuntime::_register_finalizer_Java = nullptr;
111 #if INCLUDE_JVMTI
112 address OptoRuntime::_notify_jvmti_vthread_start = nullptr;
113 address OptoRuntime::_notify_jvmti_vthread_end = nullptr;
114 address OptoRuntime::_notify_jvmti_vthread_mount = nullptr;
115 address OptoRuntime::_notify_jvmti_vthread_unmount = nullptr;
116 #endif
117
118 ExceptionBlob* OptoRuntime::_exception_blob;
119
120 // This should be called in an assertion at the start of OptoRuntime routines
121 // which are entered from compiled code (all of them)
122 #ifdef ASSERT
123 static bool check_compiled_frame(JavaThread* thread) {
124 assert(thread->last_frame().is_runtime_frame(), "cannot call runtime directly from compiled code");
125 RegisterMap map(thread,
126 RegisterMap::UpdateMap::skip,
127 RegisterMap::ProcessFrames::include,
128 RegisterMap::WalkContinuation::skip);
129 frame caller = thread->last_frame().sender(&map);
130 assert(caller.is_compiled_frame(), "not being called from compiled like code");
146 // variable/name type-function-gen , runtime method ,fncy_jp, tls,retpc
147 // -------------------------------------------------------------------------------------------------------------------------------
148 gen(env, _new_instance_Java , new_instance_Type , new_instance_C , 0 , true, false);
149 gen(env, _new_array_Java , new_array_Type , new_array_C , 0 , true, false);
150 gen(env, _new_array_nozero_Java , new_array_Type , new_array_nozero_C , 0 , true, false);
151 gen(env, _multianewarray2_Java , multianewarray2_Type , multianewarray2_C , 0 , true, false);
152 gen(env, _multianewarray3_Java , multianewarray3_Type , multianewarray3_C , 0 , true, false);
153 gen(env, _multianewarray4_Java , multianewarray4_Type , multianewarray4_C , 0 , true, false);
154 gen(env, _multianewarray5_Java , multianewarray5_Type , multianewarray5_C , 0 , true, false);
155 gen(env, _multianewarrayN_Java , multianewarrayN_Type , multianewarrayN_C , 0 , true, false);
156 #if INCLUDE_JVMTI
157 gen(env, _notify_jvmti_vthread_start , notify_jvmti_vthread_Type , SharedRuntime::notify_jvmti_vthread_start, 0, true, false);
158 gen(env, _notify_jvmti_vthread_end , notify_jvmti_vthread_Type , SharedRuntime::notify_jvmti_vthread_end, 0, true, false);
159 gen(env, _notify_jvmti_vthread_mount , notify_jvmti_vthread_Type , SharedRuntime::notify_jvmti_vthread_mount, 0, true, false);
160 gen(env, _notify_jvmti_vthread_unmount , notify_jvmti_vthread_Type , SharedRuntime::notify_jvmti_vthread_unmount, 0, true, false);
161 #endif
162 gen(env, _complete_monitor_locking_Java , complete_monitor_enter_Type , SharedRuntime::complete_monitor_locking_C, 0, false, false);
163 gen(env, _monitor_notify_Java , monitor_notify_Type , monitor_notify_C , 0 , false, false);
164 gen(env, _monitor_notifyAll_Java , monitor_notify_Type , monitor_notifyAll_C , 0 , false, false);
165 gen(env, _rethrow_Java , rethrow_Type , rethrow_C , 2 , true , true );
166
167 gen(env, _slow_arraycopy_Java , slow_arraycopy_Type , SharedRuntime::slow_arraycopy_C , 0 , false, false);
168 gen(env, _register_finalizer_Java , register_finalizer_Type , register_finalizer , 0 , false, false);
169
170 return true;
171 }
172
173 #undef gen
174
175
176 // Helper method to do generation of RunTimeStub's
177 address OptoRuntime::generate_stub(ciEnv* env,
178 TypeFunc_generator gen, address C_function,
179 const char *name, int is_fancy_jump,
180 bool pass_tls,
181 bool return_pc) {
182
183 // Matching the default directive, we currently have no method to match.
184 DirectiveSet* directive = DirectivesStack::getDefaultDirective(CompileBroker::compiler(CompLevel_full_optimization));
185 ResourceMark rm;
186 Compile C(env, gen, C_function, name, is_fancy_jump, pass_tls, return_pc, directive);
187 DirectivesStack::release(directive);
188 return C.stub_entry_point();
194 RuntimeStub* rs =(RuntimeStub *)cb;
195 assert(rs != nullptr && rs->is_runtime_stub(), "not a runtime stub");
196 return rs->name();
197 #else
198 // Fast implementation for product mode (maybe it should be inlined too)
199 return "runtime stub";
200 #endif
201 }
202
203
204 //=============================================================================
205 // Opto compiler runtime routines
206 //=============================================================================
207
208
209 //=============================allocation======================================
210 // We failed the fast-path allocation. Now we need to do a scavenge or GC
211 // and try allocation again.
212
213 // object allocation
214 JRT_BLOCK_ENTRY(void, OptoRuntime::new_instance_C(Klass* klass, JavaThread* current))
215 JRT_BLOCK;
216 #ifndef PRODUCT
217 SharedRuntime::_new_instance_ctr++; // new instance requires GC
218 #endif
219 assert(check_compiled_frame(current), "incorrect caller");
220
221 // These checks are cheap to make and support reflective allocation.
222 int lh = klass->layout_helper();
223 if (Klass::layout_helper_needs_slow_path(lh) || !InstanceKlass::cast(klass)->is_initialized()) {
224 Handle holder(current, klass->klass_holder()); // keep the klass alive
225 klass->check_valid_for_instantiation(false, THREAD);
226 if (!HAS_PENDING_EXCEPTION) {
227 InstanceKlass::cast(klass)->initialize(THREAD);
228 }
229 }
230
231 if (!HAS_PENDING_EXCEPTION) {
232 // Scavenge and allocate an instance.
233 Handle holder(current, klass->klass_holder()); // keep the klass alive
234 oop result = InstanceKlass::cast(klass)->allocate_instance(THREAD);
235 current->set_vm_result(result);
236
237 // Pass oops back through thread local storage. Our apparent type to Java
238 // is that we return an oop, but we can block on exit from this routine and
239 // a GC can trash the oop in C's return register. The generated stub will
240 // fetch the oop from TLS after any possible GC.
241 }
242
243 deoptimize_caller_frame(current, HAS_PENDING_EXCEPTION);
244 JRT_BLOCK_END;
245
246 // inform GC that we won't do card marks for initializing writes.
247 SharedRuntime::on_slowpath_allocation_exit(current);
248 JRT_END
249
250
251 // array allocation
252 JRT_BLOCK_ENTRY(void, OptoRuntime::new_array_C(Klass* array_type, int len, JavaThread* current))
253 JRT_BLOCK;
254 #ifndef PRODUCT
255 SharedRuntime::_new_array_ctr++; // new array requires GC
256 #endif
257 assert(check_compiled_frame(current), "incorrect caller");
258
259 // Scavenge and allocate an instance.
260 oop result;
261
262 if (array_type->is_typeArray_klass()) {
263 // The oopFactory likes to work with the element type.
264 // (We could bypass the oopFactory, since it doesn't add much value.)
265 BasicType elem_type = TypeArrayKlass::cast(array_type)->element_type();
266 result = oopFactory::new_typeArray(elem_type, len, THREAD);
267 } else {
268 // Although the oopFactory likes to work with the elem_type,
269 // the compiler prefers the array_type, since it must already have
270 // that latter value in hand for the fast path.
271 Handle holder(current, array_type->klass_holder()); // keep the array klass alive
272 Klass* elem_type = ObjArrayKlass::cast(array_type)->element_klass();
273 result = oopFactory::new_objArray(elem_type, len, THREAD);
274 }
275
276 // Pass oops back through thread local storage. Our apparent type to Java
277 // is that we return an oop, but we can block on exit from this routine and
278 // a GC can trash the oop in C's return register. The generated stub will
279 // fetch the oop from TLS after any possible GC.
280 deoptimize_caller_frame(current, HAS_PENDING_EXCEPTION);
281 current->set_vm_result(result);
282 JRT_BLOCK_END;
283
284 // inform GC that we won't do card marks for initializing writes.
285 SharedRuntime::on_slowpath_allocation_exit(current);
286 JRT_END
287
288 // array allocation without zeroing
289 JRT_BLOCK_ENTRY(void, OptoRuntime::new_array_nozero_C(Klass* array_type, int len, JavaThread* current))
290 JRT_BLOCK;
291 #ifndef PRODUCT
292 SharedRuntime::_new_array_ctr++; // new array requires GC
293 #endif
447 JRT_BLOCK_ENTRY(void, OptoRuntime::monitor_notifyAll_C(oopDesc* obj, JavaThread* current))
448
449 if (!SafepointSynchronize::is_synchronizing() ) {
450 if (ObjectSynchronizer::quick_notify(obj, current, true)) {
451 return;
452 }
453 }
454
455 // This is the case the fast-path above isn't provisioned to handle.
456 // The fast-path is designed to handle frequently arising cases in an efficient manner.
457 // (The fast-path is just a degenerate variant of the slow-path).
458 // Perform the dreaded state transition and pass control into the slow-path.
459 JRT_BLOCK;
460 Handle h_obj(current, obj);
461 ObjectSynchronizer::notifyall(h_obj, CHECK);
462 JRT_BLOCK_END;
463 JRT_END
464
465 const TypeFunc *OptoRuntime::new_instance_Type() {
466 // create input type (domain)
467 const Type **fields = TypeTuple::fields(1);
468 fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; // Klass to be allocated
469 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+1, fields);
470
471 // create result type (range)
472 fields = TypeTuple::fields(1);
473 fields[TypeFunc::Parms+0] = TypeRawPtr::NOTNULL; // Returned oop
474
475 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+1, fields);
476
477 return TypeFunc::make(domain, range);
478 }
479
480 #if INCLUDE_JVMTI
481 const TypeFunc *OptoRuntime::notify_jvmti_vthread_Type() {
482 // create input type (domain)
483 const Type **fields = TypeTuple::fields(2);
484 fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; // VirtualThread oop
485 fields[TypeFunc::Parms+1] = TypeInt::BOOL; // jboolean
486 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+2,fields);
487
488 // no result type needed
489 fields = TypeTuple::fields(1);
583 fields = TypeTuple::fields(0);
584 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0, fields);
585
586 return TypeFunc::make(domain, range);
587 }
588
589 //-----------------------------------------------------------------------------
590 // Monitor Handling
591 const TypeFunc *OptoRuntime::complete_monitor_enter_Type() {
592 // create input type (domain)
593 const Type **fields = TypeTuple::fields(2);
594 fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; // Object to be Locked
595 fields[TypeFunc::Parms+1] = TypeRawPtr::BOTTOM; // Address of stack location for lock
596 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+2,fields);
597
598 // create result type (range)
599 fields = TypeTuple::fields(0);
600
601 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0,fields);
602
603 return TypeFunc::make(domain,range);
604 }
605
606
607 //-----------------------------------------------------------------------------
608 const TypeFunc *OptoRuntime::complete_monitor_exit_Type() {
609 // create input type (domain)
610 const Type **fields = TypeTuple::fields(3);
611 fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; // Object to be Locked
612 fields[TypeFunc::Parms+1] = TypeRawPtr::BOTTOM; // Address of stack location for lock - BasicLock
613 fields[TypeFunc::Parms+2] = TypeRawPtr::BOTTOM; // Thread pointer (Self)
614 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+3, fields);
615
616 // create result type (range)
617 fields = TypeTuple::fields(0);
618
619 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0, fields);
620
621 return TypeFunc::make(domain, range);
622 }
623
1671 frame stub_frame = thread->last_frame();
1672 assert(stub_frame.is_runtime_frame() || exception_blob()->contains(stub_frame.pc()), "sanity check");
1673 frame caller_frame = stub_frame.sender(®_map);
1674 return caller_frame.is_deoptimized_frame();
1675 }
1676
1677
1678 const TypeFunc *OptoRuntime::register_finalizer_Type() {
1679 // create input type (domain)
1680 const Type **fields = TypeTuple::fields(1);
1681 fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; // oop; Receiver
1682 // // The JavaThread* is passed to each routine as the last argument
1683 // fields[TypeFunc::Parms+1] = TypeRawPtr::NOTNULL; // JavaThread *; Executing thread
1684 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+1,fields);
1685
1686 // create result type (range)
1687 fields = TypeTuple::fields(0);
1688
1689 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0,fields);
1690
1691 return TypeFunc::make(domain,range);
1692 }
1693
1694 #if INCLUDE_JFR
1695 const TypeFunc *OptoRuntime::class_id_load_barrier_Type() {
1696 // create input type (domain)
1697 const Type **fields = TypeTuple::fields(1);
1698 fields[TypeFunc::Parms+0] = TypeInstPtr::KLASS;
1699 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms + 1, fields);
1700
1701 // create result type (range)
1702 fields = TypeTuple::fields(0);
1703
1704 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms + 0, fields);
1705
1706 return TypeFunc::make(domain,range);
1707 }
1708 #endif
1709
1710 //-----------------------------------------------------------------------------
1711 // Dtrace support. entry and exit probes have the same signature
1712 const TypeFunc *OptoRuntime::dtrace_method_entry_exit_Type() {
1713 // create input type (domain)
1714 const Type **fields = TypeTuple::fields(2);
1715 fields[TypeFunc::Parms+0] = TypeRawPtr::BOTTOM; // Thread-local storage
1716 fields[TypeFunc::Parms+1] = TypeMetadataPtr::BOTTOM; // Method*; Method we are entering
1717 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+2,fields);
1718
1719 // create result type (range)
1720 fields = TypeTuple::fields(0);
1721
1722 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0,fields);
1723
1724 return TypeFunc::make(domain,range);
1725 }
1726
1727 const TypeFunc *OptoRuntime::dtrace_object_alloc_Type() {
1728 // create input type (domain)
1729 const Type **fields = TypeTuple::fields(2);
1730 fields[TypeFunc::Parms+0] = TypeRawPtr::BOTTOM; // Thread-local storage
1731 fields[TypeFunc::Parms+1] = TypeInstPtr::NOTNULL; // oop; newly allocated object
1732
1733 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+2,fields);
1734
1735 // create result type (range)
1736 fields = TypeTuple::fields(0);
1737
1738 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0,fields);
1739
1740 return TypeFunc::make(domain,range);
1741 }
1742
1743
1744 JRT_ENTRY_NO_ASYNC(void, OptoRuntime::register_finalizer(oopDesc* obj, JavaThread* current))
1745 assert(oopDesc::is_oop(obj), "must be a valid oop");
1746 assert(obj->klass()->has_finalizer(), "shouldn't be here otherwise");
1747 InstanceKlass::register_finalizer(instanceOop(obj), CHECK);
1748 JRT_END
1749
1750 //-----------------------------------------------------------------------------
1751
1752 NamedCounter * volatile OptoRuntime::_named_counters = nullptr;
1753
1754 //
1755 // dump the collected NamedCounters.
1756 //
1757 void OptoRuntime::print_named_counters() {
1758 int total_lock_count = 0;
1759 int eliminated_lock_count = 0;
1760
1844 trace_exception_counter++;
1845 stringStream tempst;
1846
1847 tempst.print("%d [Exception (%s): ", trace_exception_counter, msg);
1848 exception_oop->print_value_on(&tempst);
1849 tempst.print(" in ");
1850 CodeBlob* blob = CodeCache::find_blob(exception_pc);
1851 if (blob->is_compiled()) {
1852 CompiledMethod* cm = blob->as_compiled_method_or_null();
1853 cm->method()->print_value_on(&tempst);
1854 } else if (blob->is_runtime_stub()) {
1855 tempst.print("<runtime-stub>");
1856 } else {
1857 tempst.print("<unknown>");
1858 }
1859 tempst.print(" at " INTPTR_FORMAT, p2i(exception_pc));
1860 tempst.print("]");
1861
1862 st->print_raw_cr(tempst.freeze());
1863 }
|
28 #include "code/codeCache.hpp"
29 #include "code/compiledMethod.inline.hpp"
30 #include "code/compiledIC.hpp"
31 #include "code/nmethod.hpp"
32 #include "code/pcDesc.hpp"
33 #include "code/scopeDesc.hpp"
34 #include "code/vtableStubs.hpp"
35 #include "compiler/compileBroker.hpp"
36 #include "compiler/oopMap.hpp"
37 #include "gc/g1/heapRegion.hpp"
38 #include "gc/shared/barrierSet.hpp"
39 #include "gc/shared/collectedHeap.hpp"
40 #include "gc/shared/gcLocker.hpp"
41 #include "interpreter/bytecode.hpp"
42 #include "interpreter/interpreter.hpp"
43 #include "interpreter/linkResolver.hpp"
44 #include "logging/log.hpp"
45 #include "logging/logStream.hpp"
46 #include "memory/oopFactory.hpp"
47 #include "memory/resourceArea.hpp"
48 #include "oops/flatArrayKlass.hpp"
49 #include "oops/flatArrayOop.inline.hpp"
50 #include "oops/objArrayKlass.hpp"
51 #include "oops/klass.inline.hpp"
52 #include "oops/oop.inline.hpp"
53 #include "oops/typeArrayOop.inline.hpp"
54 #include "opto/ad.hpp"
55 #include "opto/addnode.hpp"
56 #include "opto/callnode.hpp"
57 #include "opto/cfgnode.hpp"
58 #include "opto/graphKit.hpp"
59 #include "opto/machnode.hpp"
60 #include "opto/matcher.hpp"
61 #include "opto/memnode.hpp"
62 #include "opto/mulnode.hpp"
63 #include "opto/output.hpp"
64 #include "opto/runtime.hpp"
65 #include "opto/subnode.hpp"
66 #include "prims/jvmtiExport.hpp"
67 #include "runtime/atomic.hpp"
68 #include "runtime/frame.inline.hpp"
69 #include "runtime/handles.inline.hpp"
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 = nullptr;
98 address OptoRuntime::_new_array_Java = nullptr;
99 address OptoRuntime::_new_array_nozero_Java = nullptr;
100 address OptoRuntime::_multianewarray2_Java = nullptr;
101 address OptoRuntime::_multianewarray3_Java = nullptr;
102 address OptoRuntime::_multianewarray4_Java = nullptr;
103 address OptoRuntime::_multianewarray5_Java = nullptr;
104 address OptoRuntime::_multianewarrayN_Java = nullptr;
105 address OptoRuntime::_vtable_must_compile_Java = nullptr;
106 address OptoRuntime::_complete_monitor_locking_Java = nullptr;
107 address OptoRuntime::_monitor_notify_Java = nullptr;
108 address OptoRuntime::_monitor_notifyAll_Java = nullptr;
109 address OptoRuntime::_rethrow_Java = nullptr;
110 address OptoRuntime::_slow_arraycopy_Java = nullptr;
111 address OptoRuntime::_register_finalizer_Java = nullptr;
112 address OptoRuntime::_load_unknown_inline = nullptr;
113 #if INCLUDE_JVMTI
114 address OptoRuntime::_notify_jvmti_vthread_start = nullptr;
115 address OptoRuntime::_notify_jvmti_vthread_end = nullptr;
116 address OptoRuntime::_notify_jvmti_vthread_mount = nullptr;
117 address OptoRuntime::_notify_jvmti_vthread_unmount = nullptr;
118 #endif
119
120 ExceptionBlob* OptoRuntime::_exception_blob;
121
122 // This should be called in an assertion at the start of OptoRuntime routines
123 // which are entered from compiled code (all of them)
124 #ifdef ASSERT
125 static bool check_compiled_frame(JavaThread* thread) {
126 assert(thread->last_frame().is_runtime_frame(), "cannot call runtime directly from compiled code");
127 RegisterMap map(thread,
128 RegisterMap::UpdateMap::skip,
129 RegisterMap::ProcessFrames::include,
130 RegisterMap::WalkContinuation::skip);
131 frame caller = thread->last_frame().sender(&map);
132 assert(caller.is_compiled_frame(), "not being called from compiled like code");
148 // variable/name type-function-gen , runtime method ,fncy_jp, tls,retpc
149 // -------------------------------------------------------------------------------------------------------------------------------
150 gen(env, _new_instance_Java , new_instance_Type , new_instance_C , 0 , true, false);
151 gen(env, _new_array_Java , new_array_Type , new_array_C , 0 , true, false);
152 gen(env, _new_array_nozero_Java , new_array_Type , new_array_nozero_C , 0 , true, false);
153 gen(env, _multianewarray2_Java , multianewarray2_Type , multianewarray2_C , 0 , true, false);
154 gen(env, _multianewarray3_Java , multianewarray3_Type , multianewarray3_C , 0 , true, false);
155 gen(env, _multianewarray4_Java , multianewarray4_Type , multianewarray4_C , 0 , true, false);
156 gen(env, _multianewarray5_Java , multianewarray5_Type , multianewarray5_C , 0 , true, false);
157 gen(env, _multianewarrayN_Java , multianewarrayN_Type , multianewarrayN_C , 0 , true, false);
158 #if INCLUDE_JVMTI
159 gen(env, _notify_jvmti_vthread_start , notify_jvmti_vthread_Type , SharedRuntime::notify_jvmti_vthread_start, 0, true, false);
160 gen(env, _notify_jvmti_vthread_end , notify_jvmti_vthread_Type , SharedRuntime::notify_jvmti_vthread_end, 0, true, false);
161 gen(env, _notify_jvmti_vthread_mount , notify_jvmti_vthread_Type , SharedRuntime::notify_jvmti_vthread_mount, 0, true, false);
162 gen(env, _notify_jvmti_vthread_unmount , notify_jvmti_vthread_Type , SharedRuntime::notify_jvmti_vthread_unmount, 0, true, false);
163 #endif
164 gen(env, _complete_monitor_locking_Java , complete_monitor_enter_Type , SharedRuntime::complete_monitor_locking_C, 0, false, false);
165 gen(env, _monitor_notify_Java , monitor_notify_Type , monitor_notify_C , 0 , false, false);
166 gen(env, _monitor_notifyAll_Java , monitor_notify_Type , monitor_notifyAll_C , 0 , false, false);
167 gen(env, _rethrow_Java , rethrow_Type , rethrow_C , 2 , true , true );
168 gen(env, _slow_arraycopy_Java , slow_arraycopy_Type , SharedRuntime::slow_arraycopy_C , 0 , false, false);
169 gen(env, _register_finalizer_Java , register_finalizer_Type , register_finalizer , 0 , false, false);
170 gen(env, _load_unknown_inline , load_unknown_inline_type , load_unknown_inline , 0 , true, false);
171
172 return true;
173 }
174
175 #undef gen
176
177
178 // Helper method to do generation of RunTimeStub's
179 address OptoRuntime::generate_stub(ciEnv* env,
180 TypeFunc_generator gen, address C_function,
181 const char *name, int is_fancy_jump,
182 bool pass_tls,
183 bool return_pc) {
184
185 // Matching the default directive, we currently have no method to match.
186 DirectiveSet* directive = DirectivesStack::getDefaultDirective(CompileBroker::compiler(CompLevel_full_optimization));
187 ResourceMark rm;
188 Compile C(env, gen, C_function, name, is_fancy_jump, pass_tls, return_pc, directive);
189 DirectivesStack::release(directive);
190 return C.stub_entry_point();
196 RuntimeStub* rs =(RuntimeStub *)cb;
197 assert(rs != nullptr && rs->is_runtime_stub(), "not a runtime stub");
198 return rs->name();
199 #else
200 // Fast implementation for product mode (maybe it should be inlined too)
201 return "runtime stub";
202 #endif
203 }
204
205
206 //=============================================================================
207 // Opto compiler runtime routines
208 //=============================================================================
209
210
211 //=============================allocation======================================
212 // We failed the fast-path allocation. Now we need to do a scavenge or GC
213 // and try allocation again.
214
215 // object allocation
216 JRT_BLOCK_ENTRY(void, OptoRuntime::new_instance_C(Klass* klass, bool is_larval, JavaThread* current))
217 JRT_BLOCK;
218 #ifndef PRODUCT
219 SharedRuntime::_new_instance_ctr++; // new instance requires GC
220 #endif
221 assert(check_compiled_frame(current), "incorrect caller");
222
223 // These checks are cheap to make and support reflective allocation.
224 int lh = klass->layout_helper();
225 if (Klass::layout_helper_needs_slow_path(lh) || !InstanceKlass::cast(klass)->is_initialized()) {
226 Handle holder(current, klass->klass_holder()); // keep the klass alive
227 klass->check_valid_for_instantiation(false, THREAD);
228 if (!HAS_PENDING_EXCEPTION) {
229 InstanceKlass::cast(klass)->initialize(THREAD);
230 }
231 }
232
233 if (!HAS_PENDING_EXCEPTION) {
234 // Scavenge and allocate an instance.
235 Handle holder(current, klass->klass_holder()); // keep the klass alive
236 instanceOop result = InstanceKlass::cast(klass)->allocate_instance(THREAD);
237 if (is_larval) {
238 // Check if this is a larval buffer allocation
239 result->set_mark(result->mark().enter_larval_state());
240 }
241 current->set_vm_result(result);
242
243 // Pass oops back through thread local storage. Our apparent type to Java
244 // is that we return an oop, but we can block on exit from this routine and
245 // a GC can trash the oop in C's return register. The generated stub will
246 // fetch the oop from TLS after any possible GC.
247 }
248
249 deoptimize_caller_frame(current, HAS_PENDING_EXCEPTION);
250 JRT_BLOCK_END;
251
252 // inform GC that we won't do card marks for initializing writes.
253 SharedRuntime::on_slowpath_allocation_exit(current);
254 JRT_END
255
256
257 // array allocation
258 JRT_BLOCK_ENTRY(void, OptoRuntime::new_array_C(Klass* array_type, int len, JavaThread* current))
259 JRT_BLOCK;
260 #ifndef PRODUCT
261 SharedRuntime::_new_array_ctr++; // new array requires GC
262 #endif
263 assert(check_compiled_frame(current), "incorrect caller");
264
265 // Scavenge and allocate an instance.
266 oop result;
267
268 if (array_type->is_flatArray_klass()) {
269 Klass* elem_type = FlatArrayKlass::cast(array_type)->element_klass();
270 result = oopFactory::new_valueArray(elem_type, len, THREAD);
271 } else if (array_type->is_typeArray_klass()) {
272 // The oopFactory likes to work with the element type.
273 // (We could bypass the oopFactory, since it doesn't add much value.)
274 BasicType elem_type = TypeArrayKlass::cast(array_type)->element_type();
275 result = oopFactory::new_typeArray(elem_type, len, THREAD);
276 } else {
277 Handle holder(current, array_type->klass_holder()); // keep the array klass alive
278 result = ObjArrayKlass::cast(array_type)->allocate(len, THREAD);
279 }
280
281 // Pass oops back through thread local storage. Our apparent type to Java
282 // is that we return an oop, but we can block on exit from this routine and
283 // a GC can trash the oop in C's return register. The generated stub will
284 // fetch the oop from TLS after any possible GC.
285 deoptimize_caller_frame(current, HAS_PENDING_EXCEPTION);
286 current->set_vm_result(result);
287 JRT_BLOCK_END;
288
289 // inform GC that we won't do card marks for initializing writes.
290 SharedRuntime::on_slowpath_allocation_exit(current);
291 JRT_END
292
293 // array allocation without zeroing
294 JRT_BLOCK_ENTRY(void, OptoRuntime::new_array_nozero_C(Klass* array_type, int len, JavaThread* current))
295 JRT_BLOCK;
296 #ifndef PRODUCT
297 SharedRuntime::_new_array_ctr++; // new array requires GC
298 #endif
452 JRT_BLOCK_ENTRY(void, OptoRuntime::monitor_notifyAll_C(oopDesc* obj, JavaThread* current))
453
454 if (!SafepointSynchronize::is_synchronizing() ) {
455 if (ObjectSynchronizer::quick_notify(obj, current, true)) {
456 return;
457 }
458 }
459
460 // This is the case the fast-path above isn't provisioned to handle.
461 // The fast-path is designed to handle frequently arising cases in an efficient manner.
462 // (The fast-path is just a degenerate variant of the slow-path).
463 // Perform the dreaded state transition and pass control into the slow-path.
464 JRT_BLOCK;
465 Handle h_obj(current, obj);
466 ObjectSynchronizer::notifyall(h_obj, CHECK);
467 JRT_BLOCK_END;
468 JRT_END
469
470 const TypeFunc *OptoRuntime::new_instance_Type() {
471 // create input type (domain)
472 const Type **fields = TypeTuple::fields(2);
473 fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; // Klass to be allocated
474 fields[TypeFunc::Parms+1] = TypeInt::BOOL; // is_larval
475 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+2, fields);
476
477 // create result type (range)
478 fields = TypeTuple::fields(1);
479 fields[TypeFunc::Parms+0] = TypeRawPtr::NOTNULL; // Returned oop
480
481 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+1, fields);
482
483 return TypeFunc::make(domain, range);
484 }
485
486 #if INCLUDE_JVMTI
487 const TypeFunc *OptoRuntime::notify_jvmti_vthread_Type() {
488 // create input type (domain)
489 const Type **fields = TypeTuple::fields(2);
490 fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; // VirtualThread oop
491 fields[TypeFunc::Parms+1] = TypeInt::BOOL; // jboolean
492 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+2,fields);
493
494 // no result type needed
495 fields = TypeTuple::fields(1);
589 fields = TypeTuple::fields(0);
590 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0, fields);
591
592 return TypeFunc::make(domain, range);
593 }
594
595 //-----------------------------------------------------------------------------
596 // Monitor Handling
597 const TypeFunc *OptoRuntime::complete_monitor_enter_Type() {
598 // create input type (domain)
599 const Type **fields = TypeTuple::fields(2);
600 fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; // Object to be Locked
601 fields[TypeFunc::Parms+1] = TypeRawPtr::BOTTOM; // Address of stack location for lock
602 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+2,fields);
603
604 // create result type (range)
605 fields = TypeTuple::fields(0);
606
607 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0,fields);
608
609 return TypeFunc::make(domain, range);
610 }
611
612
613 //-----------------------------------------------------------------------------
614 const TypeFunc *OptoRuntime::complete_monitor_exit_Type() {
615 // create input type (domain)
616 const Type **fields = TypeTuple::fields(3);
617 fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; // Object to be Locked
618 fields[TypeFunc::Parms+1] = TypeRawPtr::BOTTOM; // Address of stack location for lock - BasicLock
619 fields[TypeFunc::Parms+2] = TypeRawPtr::BOTTOM; // Thread pointer (Self)
620 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+3, fields);
621
622 // create result type (range)
623 fields = TypeTuple::fields(0);
624
625 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0, fields);
626
627 return TypeFunc::make(domain, range);
628 }
629
1677 frame stub_frame = thread->last_frame();
1678 assert(stub_frame.is_runtime_frame() || exception_blob()->contains(stub_frame.pc()), "sanity check");
1679 frame caller_frame = stub_frame.sender(®_map);
1680 return caller_frame.is_deoptimized_frame();
1681 }
1682
1683
1684 const TypeFunc *OptoRuntime::register_finalizer_Type() {
1685 // create input type (domain)
1686 const Type **fields = TypeTuple::fields(1);
1687 fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; // oop; Receiver
1688 // // The JavaThread* is passed to each routine as the last argument
1689 // fields[TypeFunc::Parms+1] = TypeRawPtr::NOTNULL; // JavaThread *; Executing thread
1690 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+1,fields);
1691
1692 // create result type (range)
1693 fields = TypeTuple::fields(0);
1694
1695 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0,fields);
1696
1697 return TypeFunc::make(domain, range);
1698 }
1699
1700 #if INCLUDE_JFR
1701 const TypeFunc *OptoRuntime::class_id_load_barrier_Type() {
1702 // create input type (domain)
1703 const Type **fields = TypeTuple::fields(1);
1704 fields[TypeFunc::Parms+0] = TypeInstPtr::KLASS;
1705 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms + 1, fields);
1706
1707 // create result type (range)
1708 fields = TypeTuple::fields(0);
1709
1710 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms + 0, fields);
1711
1712 return TypeFunc::make(domain,range);
1713 }
1714 #endif
1715
1716 //-----------------------------------------------------------------------------
1717 // Dtrace support. entry and exit probes have the same signature
1718 const TypeFunc *OptoRuntime::dtrace_method_entry_exit_Type() {
1719 // create input type (domain)
1720 const Type **fields = TypeTuple::fields(2);
1721 fields[TypeFunc::Parms+0] = TypeRawPtr::BOTTOM; // Thread-local storage
1722 fields[TypeFunc::Parms+1] = TypeMetadataPtr::BOTTOM; // Method*; Method we are entering
1723 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+2,fields);
1724
1725 // create result type (range)
1726 fields = TypeTuple::fields(0);
1727
1728 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0,fields);
1729
1730 return TypeFunc::make(domain, range);
1731 }
1732
1733 const TypeFunc *OptoRuntime::dtrace_object_alloc_Type() {
1734 // create input type (domain)
1735 const Type **fields = TypeTuple::fields(2);
1736 fields[TypeFunc::Parms+0] = TypeRawPtr::BOTTOM; // Thread-local storage
1737 fields[TypeFunc::Parms+1] = TypeInstPtr::NOTNULL; // oop; newly allocated object
1738
1739 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+2,fields);
1740
1741 // create result type (range)
1742 fields = TypeTuple::fields(0);
1743
1744 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0,fields);
1745
1746 return TypeFunc::make(domain, range);
1747 }
1748
1749
1750 JRT_ENTRY_NO_ASYNC(void, OptoRuntime::register_finalizer(oopDesc* obj, JavaThread* current))
1751 assert(oopDesc::is_oop(obj), "must be a valid oop");
1752 assert(obj->klass()->has_finalizer(), "shouldn't be here otherwise");
1753 InstanceKlass::register_finalizer(instanceOop(obj), CHECK);
1754 JRT_END
1755
1756 //-----------------------------------------------------------------------------
1757
1758 NamedCounter * volatile OptoRuntime::_named_counters = nullptr;
1759
1760 //
1761 // dump the collected NamedCounters.
1762 //
1763 void OptoRuntime::print_named_counters() {
1764 int total_lock_count = 0;
1765 int eliminated_lock_count = 0;
1766
1850 trace_exception_counter++;
1851 stringStream tempst;
1852
1853 tempst.print("%d [Exception (%s): ", trace_exception_counter, msg);
1854 exception_oop->print_value_on(&tempst);
1855 tempst.print(" in ");
1856 CodeBlob* blob = CodeCache::find_blob(exception_pc);
1857 if (blob->is_compiled()) {
1858 CompiledMethod* cm = blob->as_compiled_method_or_null();
1859 cm->method()->print_value_on(&tempst);
1860 } else if (blob->is_runtime_stub()) {
1861 tempst.print("<runtime-stub>");
1862 } else {
1863 tempst.print("<unknown>");
1864 }
1865 tempst.print(" at " INTPTR_FORMAT, p2i(exception_pc));
1866 tempst.print("]");
1867
1868 st->print_raw_cr(tempst.freeze());
1869 }
1870
1871 const TypeFunc *OptoRuntime::store_inline_type_fields_Type() {
1872 // create input type (domain)
1873 uint total = SharedRuntime::java_return_convention_max_int + SharedRuntime::java_return_convention_max_float*2;
1874 const Type **fields = TypeTuple::fields(total);
1875 // We don't know the number of returned values and their
1876 // types. Assume all registers available to the return convention
1877 // are used.
1878 fields[TypeFunc::Parms] = TypePtr::BOTTOM;
1879 uint i = 1;
1880 for (; i < SharedRuntime::java_return_convention_max_int; i++) {
1881 fields[TypeFunc::Parms+i] = TypeInt::INT;
1882 }
1883 for (; i < total; i+=2) {
1884 fields[TypeFunc::Parms+i] = Type::DOUBLE;
1885 fields[TypeFunc::Parms+i+1] = Type::HALF;
1886 }
1887 const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms + total, fields);
1888
1889 // create result type (range)
1890 fields = TypeTuple::fields(1);
1891 fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL;
1892
1893 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+1,fields);
1894
1895 return TypeFunc::make(domain, range);
1896 }
1897
1898 const TypeFunc *OptoRuntime::pack_inline_type_Type() {
1899 // create input type (domain)
1900 uint total = 1 + SharedRuntime::java_return_convention_max_int + SharedRuntime::java_return_convention_max_float*2;
1901 const Type **fields = TypeTuple::fields(total);
1902 // We don't know the number of returned values and their
1903 // types. Assume all registers available to the return convention
1904 // are used.
1905 fields[TypeFunc::Parms] = TypeRawPtr::BOTTOM;
1906 fields[TypeFunc::Parms+1] = TypeRawPtr::BOTTOM;
1907 uint i = 2;
1908 for (; i < SharedRuntime::java_return_convention_max_int+1; i++) {
1909 fields[TypeFunc::Parms+i] = TypeInt::INT;
1910 }
1911 for (; i < total; i+=2) {
1912 fields[TypeFunc::Parms+i] = Type::DOUBLE;
1913 fields[TypeFunc::Parms+i+1] = Type::HALF;
1914 }
1915 const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms + total, fields);
1916
1917 // create result type (range)
1918 fields = TypeTuple::fields(1);
1919 fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL;
1920
1921 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+1,fields);
1922
1923 return TypeFunc::make(domain, range);
1924 }
1925
1926 JRT_BLOCK_ENTRY(void, OptoRuntime::load_unknown_inline(flatArrayOopDesc* array, int index, JavaThread* current))
1927 JRT_BLOCK;
1928 flatArrayHandle vah(current, array);
1929 oop buffer = flatArrayOopDesc::value_alloc_copy_from_index(vah, index, THREAD);
1930 deoptimize_caller_frame(current, HAS_PENDING_EXCEPTION);
1931 current->set_vm_result(buffer);
1932 JRT_BLOCK_END;
1933 JRT_END
1934
1935 const TypeFunc* OptoRuntime::load_unknown_inline_type() {
1936 // create input type (domain)
1937 const Type** fields = TypeTuple::fields(2);
1938 fields[TypeFunc::Parms] = TypeOopPtr::NOTNULL;
1939 fields[TypeFunc::Parms+1] = TypeInt::POS;
1940
1941 const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms+2, fields);
1942
1943 // create result type (range)
1944 fields = TypeTuple::fields(1);
1945 fields[TypeFunc::Parms] = TypeInstPtr::NOTNULL;
1946
1947 const TypeTuple* range = TypeTuple::make(TypeFunc::Parms+1, fields);
1948
1949 return TypeFunc::make(domain, range);
1950 }
1951
1952 JRT_LEAF(void, OptoRuntime::store_unknown_inline(instanceOopDesc* buffer, flatArrayOopDesc* array, int index))
1953 {
1954 assert(buffer != nullptr, "can't store null into flat array");
1955 array->value_copy_to_index(buffer, index);
1956 }
1957 JRT_END
1958
1959 const TypeFunc* OptoRuntime::store_unknown_inline_type() {
1960 // create input type (domain)
1961 const Type** fields = TypeTuple::fields(3);
1962 fields[TypeFunc::Parms] = TypeInstPtr::NOTNULL;
1963 fields[TypeFunc::Parms+1] = TypeOopPtr::NOTNULL;
1964 fields[TypeFunc::Parms+2] = TypeInt::POS;
1965
1966 const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms+3, fields);
1967
1968 // create result type (range)
1969 fields = TypeTuple::fields(0);
1970 const TypeTuple* range = TypeTuple::make(TypeFunc::Parms, fields);
1971
1972 return TypeFunc::make(domain, range);
1973 }
|