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