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