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"
91
92
93
94 // Compiled code entry points
95 address OptoRuntime::_new_instance_Java = NULL;
96 address OptoRuntime::_new_array_Java = NULL;
97 address OptoRuntime::_new_array_nozero_Java = NULL;
98 address OptoRuntime::_multianewarray2_Java = NULL;
99 address OptoRuntime::_multianewarray3_Java = NULL;
100 address OptoRuntime::_multianewarray4_Java = NULL;
101 address OptoRuntime::_multianewarray5_Java = NULL;
102 address OptoRuntime::_multianewarrayN_Java = NULL;
103 address OptoRuntime::_vtable_must_compile_Java = NULL;
104 address OptoRuntime::_complete_monitor_locking_Java = NULL;
105 address OptoRuntime::_monitor_notify_Java = NULL;
106 address OptoRuntime::_monitor_notifyAll_Java = NULL;
107 address OptoRuntime::_rethrow_Java = NULL;
108
109 address OptoRuntime::_slow_arraycopy_Java = NULL;
110 address OptoRuntime::_register_finalizer_Java = NULL;
111
112 ExceptionBlob* OptoRuntime::_exception_blob;
113
114 // This should be called in an assertion at the start of OptoRuntime routines
115 // which are entered from compiled code (all of them)
116 #ifdef ASSERT
117 static bool check_compiled_frame(JavaThread* thread) {
118 assert(thread->last_frame().is_runtime_frame(), "cannot call runtime directly from compiled code");
119 RegisterMap map(thread, false);
120 frame caller = thread->last_frame().sender(&map);
121 assert(caller.is_compiled_frame(), "not being called from compiled like code");
122 return true;
123 }
124 #endif // ASSERT
125
126
127 #define gen(env, var, type_func_gen, c_func, fancy_jump, pass_tls, return_pc) \
128 var = generate_stub(env, type_func_gen, CAST_FROM_FN_PTR(address, c_func), #var, fancy_jump, pass_tls, return_pc); \
129 if (var == NULL) { return false; }
130
131 bool OptoRuntime::generate(ciEnv* env) {
132
133 generate_exception_blob();
134
135 // Note: tls: Means fetching the return oop out of the thread-local storage
136 //
137 // variable/name type-function-gen , runtime method ,fncy_jp, tls,retpc
138 // -------------------------------------------------------------------------------------------------------------------------------
139 gen(env, _new_instance_Java , new_instance_Type , new_instance_C , 0 , true, false);
140 gen(env, _new_array_Java , new_array_Type , new_array_C , 0 , true, false);
141 gen(env, _new_array_nozero_Java , new_array_Type , new_array_nozero_C , 0 , true, false);
142 gen(env, _multianewarray2_Java , multianewarray2_Type , multianewarray2_C , 0 , true, false);
143 gen(env, _multianewarray3_Java , multianewarray3_Type , multianewarray3_C , 0 , true, false);
144 gen(env, _multianewarray4_Java , multianewarray4_Type , multianewarray4_C , 0 , true, false);
145 gen(env, _multianewarray5_Java , multianewarray5_Type , multianewarray5_C , 0 , true, false);
146 gen(env, _multianewarrayN_Java , multianewarrayN_Type , multianewarrayN_C , 0 , true, false);
147 gen(env, _complete_monitor_locking_Java , complete_monitor_enter_Type , SharedRuntime::complete_monitor_locking_C, 0, false, false);
148 gen(env, _monitor_notify_Java , monitor_notify_Type , monitor_notify_C , 0 , false, false);
149 gen(env, _monitor_notifyAll_Java , monitor_notify_Type , monitor_notifyAll_C , 0 , false, false);
150 gen(env, _rethrow_Java , rethrow_Type , rethrow_C , 2 , true , true );
151
152 gen(env, _slow_arraycopy_Java , slow_arraycopy_Type , SharedRuntime::slow_arraycopy_C , 0 , false, false);
153 gen(env, _register_finalizer_Java , register_finalizer_Type , register_finalizer , 0 , false, false);
154
155 return true;
156 }
157
158 #undef gen
159
160
161 // Helper method to do generation of RunTimeStub's
162 address OptoRuntime::generate_stub(ciEnv* env,
163 TypeFunc_generator gen, address C_function,
164 const char *name, int is_fancy_jump,
165 bool pass_tls,
166 bool return_pc) {
167
168 // Matching the default directive, we currently have no method to match.
169 DirectiveSet* directive = DirectivesStack::getDefaultDirective(CompileBroker::compiler(CompLevel_full_optimization));
170 ResourceMark rm;
171 Compile C(env, gen, C_function, name, is_fancy_jump, pass_tls, return_pc, directive);
172 DirectivesStack::release(directive);
173 return C.stub_entry_point();
179 RuntimeStub* rs =(RuntimeStub *)cb;
180 assert(rs != NULL && rs->is_runtime_stub(), "not a runtime stub");
181 return rs->name();
182 #else
183 // Fast implementation for product mode (maybe it should be inlined too)
184 return "runtime stub";
185 #endif
186 }
187
188
189 //=============================================================================
190 // Opto compiler runtime routines
191 //=============================================================================
192
193
194 //=============================allocation======================================
195 // We failed the fast-path allocation. Now we need to do a scavenge or GC
196 // and try allocation again.
197
198 // object allocation
199 JRT_BLOCK_ENTRY(void, OptoRuntime::new_instance_C(Klass* klass, JavaThread* current))
200 JRT_BLOCK;
201 #ifndef PRODUCT
202 SharedRuntime::_new_instance_ctr++; // new instance requires GC
203 #endif
204 assert(check_compiled_frame(current), "incorrect caller");
205
206 // These checks are cheap to make and support reflective allocation.
207 int lh = klass->layout_helper();
208 if (Klass::layout_helper_needs_slow_path(lh) || !InstanceKlass::cast(klass)->is_initialized()) {
209 Handle holder(current, klass->klass_holder()); // keep the klass alive
210 klass->check_valid_for_instantiation(false, THREAD);
211 if (!HAS_PENDING_EXCEPTION) {
212 InstanceKlass::cast(klass)->initialize(THREAD);
213 }
214 }
215
216 if (!HAS_PENDING_EXCEPTION) {
217 // Scavenge and allocate an instance.
218 Handle holder(current, klass->klass_holder()); // keep the klass alive
219 oop result = InstanceKlass::cast(klass)->allocate_instance(THREAD);
220 current->set_vm_result(result);
221
222 // Pass oops back through thread local storage. Our apparent type to Java
223 // is that we return an oop, but we can block on exit from this routine and
224 // a GC can trash the oop in C's return register. The generated stub will
225 // fetch the oop from TLS after any possible GC.
226 }
227
228 deoptimize_caller_frame(current, HAS_PENDING_EXCEPTION);
229 JRT_BLOCK_END;
230
231 // inform GC that we won't do card marks for initializing writes.
232 SharedRuntime::on_slowpath_allocation_exit(current);
233 JRT_END
234
235
236 // array allocation
237 JRT_BLOCK_ENTRY(void, OptoRuntime::new_array_C(Klass* array_type, int len, JavaThread* current))
238 JRT_BLOCK;
239 #ifndef PRODUCT
240 SharedRuntime::_new_array_ctr++; // new array requires GC
241 #endif
242 assert(check_compiled_frame(current), "incorrect caller");
243
244 // Scavenge and allocate an instance.
245 oop result;
246
247 if (array_type->is_typeArray_klass()) {
248 // The oopFactory likes to work with the element type.
249 // (We could bypass the oopFactory, since it doesn't add much value.)
250 BasicType elem_type = TypeArrayKlass::cast(array_type)->element_type();
251 result = oopFactory::new_typeArray(elem_type, len, THREAD);
252 } else {
253 // Although the oopFactory likes to work with the elem_type,
254 // the compiler prefers the array_type, since it must already have
255 // that latter value in hand for the fast path.
256 Handle holder(current, array_type->klass_holder()); // keep the array klass alive
257 Klass* elem_type = ObjArrayKlass::cast(array_type)->element_klass();
258 result = oopFactory::new_objArray(elem_type, len, THREAD);
259 }
260
261 // Pass oops back through thread local storage. Our apparent type to Java
262 // is that we return an oop, but we can block on exit from this routine and
263 // a GC can trash the oop in C's return register. The generated stub will
264 // fetch the oop from TLS after any possible GC.
265 deoptimize_caller_frame(current, HAS_PENDING_EXCEPTION);
266 current->set_vm_result(result);
267 JRT_BLOCK_END;
268
269 // inform GC that we won't do card marks for initializing writes.
270 SharedRuntime::on_slowpath_allocation_exit(current);
271 JRT_END
272
273 // array allocation without zeroing
274 JRT_BLOCK_ENTRY(void, OptoRuntime::new_array_nozero_C(Klass* array_type, int len, JavaThread* current))
275 JRT_BLOCK;
276 #ifndef PRODUCT
277 SharedRuntime::_new_array_ctr++; // new array requires GC
278 #endif
432 JRT_BLOCK_ENTRY(void, OptoRuntime::monitor_notifyAll_C(oopDesc* obj, JavaThread* current))
433
434 if (!SafepointSynchronize::is_synchronizing() ) {
435 if (ObjectSynchronizer::quick_notify(obj, current, true)) {
436 return;
437 }
438 }
439
440 // This is the case the fast-path above isn't provisioned to handle.
441 // The fast-path is designed to handle frequently arising cases in an efficient manner.
442 // (The fast-path is just a degenerate variant of the slow-path).
443 // Perform the dreaded state transition and pass control into the slow-path.
444 JRT_BLOCK;
445 Handle h_obj(current, obj);
446 ObjectSynchronizer::notifyall(h_obj, CHECK);
447 JRT_BLOCK_END;
448 JRT_END
449
450 const TypeFunc *OptoRuntime::new_instance_Type() {
451 // create input type (domain)
452 const Type **fields = TypeTuple::fields(1);
453 fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; // Klass to be allocated
454 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+1, fields);
455
456 // create result type (range)
457 fields = TypeTuple::fields(1);
458 fields[TypeFunc::Parms+0] = TypeRawPtr::NOTNULL; // Returned oop
459
460 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+1, fields);
461
462 return TypeFunc::make(domain, range);
463 }
464
465
466 const TypeFunc *OptoRuntime::athrow_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(0);
474
552 fields = TypeTuple::fields(0);
553 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0, fields);
554
555 return TypeFunc::make(domain, range);
556 }
557
558 //-----------------------------------------------------------------------------
559 // Monitor Handling
560 const TypeFunc *OptoRuntime::complete_monitor_enter_Type() {
561 // create input type (domain)
562 const Type **fields = TypeTuple::fields(2);
563 fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; // Object to be Locked
564 fields[TypeFunc::Parms+1] = TypeRawPtr::BOTTOM; // Address of stack location for lock
565 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+2,fields);
566
567 // create result type (range)
568 fields = TypeTuple::fields(0);
569
570 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0,fields);
571
572 return TypeFunc::make(domain,range);
573 }
574
575
576 //-----------------------------------------------------------------------------
577 const TypeFunc *OptoRuntime::complete_monitor_exit_Type() {
578 // create input type (domain)
579 const Type **fields = TypeTuple::fields(3);
580 fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; // Object to be Locked
581 fields[TypeFunc::Parms+1] = TypeRawPtr::BOTTOM; // Address of stack location for lock - BasicLock
582 fields[TypeFunc::Parms+2] = TypeRawPtr::BOTTOM; // Thread pointer (Self)
583 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+3, fields);
584
585 // create result type (range)
586 fields = TypeTuple::fields(0);
587
588 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0, fields);
589
590 return TypeFunc::make(domain, range);
591 }
592
1529 frame stub_frame = thread->last_frame();
1530 assert(stub_frame.is_runtime_frame() || exception_blob()->contains(stub_frame.pc()), "sanity check");
1531 frame caller_frame = stub_frame.sender(®_map);
1532 return caller_frame.is_deoptimized_frame();
1533 }
1534
1535
1536 const TypeFunc *OptoRuntime::register_finalizer_Type() {
1537 // create input type (domain)
1538 const Type **fields = TypeTuple::fields(1);
1539 fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; // oop; Receiver
1540 // // The JavaThread* is passed to each routine as the last argument
1541 // fields[TypeFunc::Parms+1] = TypeRawPtr::NOTNULL; // JavaThread *; Executing thread
1542 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+1,fields);
1543
1544 // create result type (range)
1545 fields = TypeTuple::fields(0);
1546
1547 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0,fields);
1548
1549 return TypeFunc::make(domain,range);
1550 }
1551
1552 #if INCLUDE_JFR
1553 const TypeFunc *OptoRuntime::get_class_id_intrinsic_Type() {
1554 // create input type (domain)
1555 const Type **fields = TypeTuple::fields(1);
1556 fields[TypeFunc::Parms+0] = TypeInstPtr::KLASS;
1557 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms + 1, fields);
1558
1559 // create result type (range)
1560 fields = TypeTuple::fields(0);
1561
1562 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms + 0, fields);
1563
1564 return TypeFunc::make(domain,range);
1565 }
1566 #endif
1567
1568 //-----------------------------------------------------------------------------
1569 // Dtrace support. entry and exit probes have the same signature
1570 const TypeFunc *OptoRuntime::dtrace_method_entry_exit_Type() {
1571 // create input type (domain)
1572 const Type **fields = TypeTuple::fields(2);
1573 fields[TypeFunc::Parms+0] = TypeRawPtr::BOTTOM; // Thread-local storage
1574 fields[TypeFunc::Parms+1] = TypeMetadataPtr::BOTTOM; // Method*; Method we are entering
1575 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+2,fields);
1576
1577 // create result type (range)
1578 fields = TypeTuple::fields(0);
1579
1580 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0,fields);
1581
1582 return TypeFunc::make(domain,range);
1583 }
1584
1585 const TypeFunc *OptoRuntime::dtrace_object_alloc_Type() {
1586 // create input type (domain)
1587 const Type **fields = TypeTuple::fields(2);
1588 fields[TypeFunc::Parms+0] = TypeRawPtr::BOTTOM; // Thread-local storage
1589 fields[TypeFunc::Parms+1] = TypeInstPtr::NOTNULL; // oop; newly allocated object
1590
1591 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+2,fields);
1592
1593 // create result type (range)
1594 fields = TypeTuple::fields(0);
1595
1596 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0,fields);
1597
1598 return TypeFunc::make(domain,range);
1599 }
1600
1601
1602 JRT_ENTRY_NO_ASYNC(void, OptoRuntime::register_finalizer(oopDesc* obj, JavaThread* current))
1603 assert(oopDesc::is_oop(obj), "must be a valid oop");
1604 assert(obj->klass()->has_finalizer(), "shouldn't be here otherwise");
1605 InstanceKlass::register_finalizer(instanceOop(obj), CHECK);
1606 JRT_END
1607
1608 //-----------------------------------------------------------------------------
1609
1610 NamedCounter * volatile OptoRuntime::_named_counters = NULL;
1611
1612 //
1613 // dump the collected NamedCounters.
1614 //
1615 void OptoRuntime::print_named_counters() {
1616 int total_lock_count = 0;
1617 int eliminated_lock_count = 0;
1618
1702 trace_exception_counter++;
1703 stringStream tempst;
1704
1705 tempst.print("%d [Exception (%s): ", trace_exception_counter, msg);
1706 exception_oop->print_value_on(&tempst);
1707 tempst.print(" in ");
1708 CodeBlob* blob = CodeCache::find_blob(exception_pc);
1709 if (blob->is_compiled()) {
1710 CompiledMethod* cm = blob->as_compiled_method_or_null();
1711 cm->method()->print_value_on(&tempst);
1712 } else if (blob->is_runtime_stub()) {
1713 tempst.print("<runtime-stub>");
1714 } else {
1715 tempst.print("<unknown>");
1716 }
1717 tempst.print(" at " INTPTR_FORMAT, p2i(exception_pc));
1718 tempst.print("]");
1719
1720 st->print_raw_cr(tempst.as_string());
1721 }
|
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"
93
94
95
96 // Compiled code entry points
97 address OptoRuntime::_new_instance_Java = NULL;
98 address OptoRuntime::_new_array_Java = NULL;
99 address OptoRuntime::_new_array_nozero_Java = NULL;
100 address OptoRuntime::_multianewarray2_Java = NULL;
101 address OptoRuntime::_multianewarray3_Java = NULL;
102 address OptoRuntime::_multianewarray4_Java = NULL;
103 address OptoRuntime::_multianewarray5_Java = NULL;
104 address OptoRuntime::_multianewarrayN_Java = NULL;
105 address OptoRuntime::_vtable_must_compile_Java = NULL;
106 address OptoRuntime::_complete_monitor_locking_Java = NULL;
107 address OptoRuntime::_monitor_notify_Java = NULL;
108 address OptoRuntime::_monitor_notifyAll_Java = NULL;
109 address OptoRuntime::_rethrow_Java = NULL;
110
111 address OptoRuntime::_slow_arraycopy_Java = NULL;
112 address OptoRuntime::_register_finalizer_Java = NULL;
113 address OptoRuntime::_load_unknown_inline = NULL;
114
115 ExceptionBlob* OptoRuntime::_exception_blob;
116
117 // This should be called in an assertion at the start of OptoRuntime routines
118 // which are entered from compiled code (all of them)
119 #ifdef ASSERT
120 static bool check_compiled_frame(JavaThread* thread) {
121 assert(thread->last_frame().is_runtime_frame(), "cannot call runtime directly from compiled code");
122 RegisterMap map(thread, false);
123 frame caller = thread->last_frame().sender(&map);
124 assert(caller.is_compiled_frame(), "not being called from compiled like code");
125 return true;
126 }
127 #endif // ASSERT
128
129
130 #define gen(env, var, type_func_gen, c_func, fancy_jump, pass_tls, return_pc) \
131 var = generate_stub(env, type_func_gen, CAST_FROM_FN_PTR(address, c_func), #var, fancy_jump, pass_tls, return_pc); \
132 if (var == NULL) { return false; }
133
134 bool OptoRuntime::generate(ciEnv* env) {
135
136 generate_exception_blob();
137
138 // Note: tls: Means fetching the return oop out of the thread-local storage
139 //
140 // variable/name type-function-gen , runtime method ,fncy_jp, tls,retpc
141 // -------------------------------------------------------------------------------------------------------------------------------
142 gen(env, _new_instance_Java , new_instance_Type , new_instance_C , 0 , true, false);
143 gen(env, _new_array_Java , new_array_Type , new_array_C , 0 , true, false);
144 gen(env, _new_array_nozero_Java , new_array_Type , new_array_nozero_C , 0 , true, false);
145 gen(env, _multianewarray2_Java , multianewarray2_Type , multianewarray2_C , 0 , true, false);
146 gen(env, _multianewarray3_Java , multianewarray3_Type , multianewarray3_C , 0 , true, false);
147 gen(env, _multianewarray4_Java , multianewarray4_Type , multianewarray4_C , 0 , true, false);
148 gen(env, _multianewarray5_Java , multianewarray5_Type , multianewarray5_C , 0 , true, false);
149 gen(env, _multianewarrayN_Java , multianewarrayN_Type , multianewarrayN_C , 0 , true, false);
150 gen(env, _complete_monitor_locking_Java , complete_monitor_enter_Type , SharedRuntime::complete_monitor_locking_C, 0, false, false);
151 gen(env, _monitor_notify_Java , monitor_notify_Type , monitor_notify_C , 0 , false, false);
152 gen(env, _monitor_notifyAll_Java , monitor_notify_Type , monitor_notifyAll_C , 0 , false, false);
153 gen(env, _rethrow_Java , rethrow_Type , rethrow_C , 2 , true , true );
154 gen(env, _slow_arraycopy_Java , slow_arraycopy_Type , SharedRuntime::slow_arraycopy_C , 0 , false, false);
155 gen(env, _register_finalizer_Java , register_finalizer_Type , register_finalizer , 0 , false, false);
156 gen(env, _load_unknown_inline , load_unknown_inline_type , load_unknown_inline , 0 , true, false);
157
158 return true;
159 }
160
161 #undef gen
162
163
164 // Helper method to do generation of RunTimeStub's
165 address OptoRuntime::generate_stub(ciEnv* env,
166 TypeFunc_generator gen, address C_function,
167 const char *name, int is_fancy_jump,
168 bool pass_tls,
169 bool return_pc) {
170
171 // Matching the default directive, we currently have no method to match.
172 DirectiveSet* directive = DirectivesStack::getDefaultDirective(CompileBroker::compiler(CompLevel_full_optimization));
173 ResourceMark rm;
174 Compile C(env, gen, C_function, name, is_fancy_jump, pass_tls, return_pc, directive);
175 DirectivesStack::release(directive);
176 return C.stub_entry_point();
182 RuntimeStub* rs =(RuntimeStub *)cb;
183 assert(rs != NULL && rs->is_runtime_stub(), "not a runtime stub");
184 return rs->name();
185 #else
186 // Fast implementation for product mode (maybe it should be inlined too)
187 return "runtime stub";
188 #endif
189 }
190
191
192 //=============================================================================
193 // Opto compiler runtime routines
194 //=============================================================================
195
196
197 //=============================allocation======================================
198 // We failed the fast-path allocation. Now we need to do a scavenge or GC
199 // and try allocation again.
200
201 // object allocation
202 JRT_BLOCK_ENTRY(void, OptoRuntime::new_instance_C(Klass* klass, bool is_larval, JavaThread* current))
203 JRT_BLOCK;
204 #ifndef PRODUCT
205 SharedRuntime::_new_instance_ctr++; // new instance requires GC
206 #endif
207 assert(check_compiled_frame(current), "incorrect caller");
208
209 // These checks are cheap to make and support reflective allocation.
210 int lh = klass->layout_helper();
211 if (Klass::layout_helper_needs_slow_path(lh) || !InstanceKlass::cast(klass)->is_initialized()) {
212 Handle holder(current, klass->klass_holder()); // keep the klass alive
213 klass->check_valid_for_instantiation(false, THREAD);
214 if (!HAS_PENDING_EXCEPTION) {
215 InstanceKlass::cast(klass)->initialize(THREAD);
216 }
217 }
218
219 if (!HAS_PENDING_EXCEPTION) {
220 // Scavenge and allocate an instance.
221 Handle holder(current, klass->klass_holder()); // keep the klass alive
222 instanceOop result = InstanceKlass::cast(klass)->allocate_instance(THREAD);
223 if (is_larval) {
224 // Check if this is a larval buffer allocation
225 result->set_mark(result->mark().enter_larval_state());
226 }
227 current->set_vm_result(result);
228
229 // Pass oops back through thread local storage. Our apparent type to Java
230 // is that we return an oop, but we can block on exit from this routine and
231 // a GC can trash the oop in C's return register. The generated stub will
232 // fetch the oop from TLS after any possible GC.
233 }
234
235 deoptimize_caller_frame(current, HAS_PENDING_EXCEPTION);
236 JRT_BLOCK_END;
237
238 // inform GC that we won't do card marks for initializing writes.
239 SharedRuntime::on_slowpath_allocation_exit(current);
240 JRT_END
241
242
243 // array allocation
244 JRT_BLOCK_ENTRY(void, OptoRuntime::new_array_C(Klass* array_type, int len, JavaThread* current))
245 JRT_BLOCK;
246 #ifndef PRODUCT
247 SharedRuntime::_new_array_ctr++; // new array requires GC
248 #endif
249 assert(check_compiled_frame(current), "incorrect caller");
250
251 // Scavenge and allocate an instance.
252 oop result;
253
254 if (array_type->is_flatArray_klass()) {
255 Klass* elem_type = FlatArrayKlass::cast(array_type)->element_klass();
256 result = oopFactory::new_valueArray(elem_type, len, THREAD);
257 } else if (array_type->is_typeArray_klass()) {
258 // The oopFactory likes to work with the element type.
259 // (We could bypass the oopFactory, since it doesn't add much value.)
260 BasicType elem_type = TypeArrayKlass::cast(array_type)->element_type();
261 result = oopFactory::new_typeArray(elem_type, len, THREAD);
262 } else {
263 Handle holder(current, array_type->klass_holder()); // keep the array klass alive
264 result = ObjArrayKlass::cast(array_type)->allocate(len, THREAD);
265 }
266
267 // Pass oops back through thread local storage. Our apparent type to Java
268 // is that we return an oop, but we can block on exit from this routine and
269 // a GC can trash the oop in C's return register. The generated stub will
270 // fetch the oop from TLS after any possible GC.
271 deoptimize_caller_frame(current, HAS_PENDING_EXCEPTION);
272 current->set_vm_result(result);
273 JRT_BLOCK_END;
274
275 // inform GC that we won't do card marks for initializing writes.
276 SharedRuntime::on_slowpath_allocation_exit(current);
277 JRT_END
278
279 // array allocation without zeroing
280 JRT_BLOCK_ENTRY(void, OptoRuntime::new_array_nozero_C(Klass* array_type, int len, JavaThread* current))
281 JRT_BLOCK;
282 #ifndef PRODUCT
283 SharedRuntime::_new_array_ctr++; // new array requires GC
284 #endif
438 JRT_BLOCK_ENTRY(void, OptoRuntime::monitor_notifyAll_C(oopDesc* obj, JavaThread* current))
439
440 if (!SafepointSynchronize::is_synchronizing() ) {
441 if (ObjectSynchronizer::quick_notify(obj, current, true)) {
442 return;
443 }
444 }
445
446 // This is the case the fast-path above isn't provisioned to handle.
447 // The fast-path is designed to handle frequently arising cases in an efficient manner.
448 // (The fast-path is just a degenerate variant of the slow-path).
449 // Perform the dreaded state transition and pass control into the slow-path.
450 JRT_BLOCK;
451 Handle h_obj(current, obj);
452 ObjectSynchronizer::notifyall(h_obj, CHECK);
453 JRT_BLOCK_END;
454 JRT_END
455
456 const TypeFunc *OptoRuntime::new_instance_Type() {
457 // create input type (domain)
458 const Type **fields = TypeTuple::fields(2);
459 fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; // Klass to be allocated
460 fields[TypeFunc::Parms+1] = TypeInt::BOOL; // is_larval
461 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+2, fields);
462
463 // create result type (range)
464 fields = TypeTuple::fields(1);
465 fields[TypeFunc::Parms+0] = TypeRawPtr::NOTNULL; // Returned oop
466
467 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+1, fields);
468
469 return TypeFunc::make(domain, range);
470 }
471
472
473 const TypeFunc *OptoRuntime::athrow_Type() {
474 // create input type (domain)
475 const Type **fields = TypeTuple::fields(1);
476 fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; // Klass to be allocated
477 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+1, fields);
478
479 // create result type (range)
480 fields = TypeTuple::fields(0);
481
559 fields = TypeTuple::fields(0);
560 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0, fields);
561
562 return TypeFunc::make(domain, range);
563 }
564
565 //-----------------------------------------------------------------------------
566 // Monitor Handling
567 const TypeFunc *OptoRuntime::complete_monitor_enter_Type() {
568 // create input type (domain)
569 const Type **fields = TypeTuple::fields(2);
570 fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; // Object to be Locked
571 fields[TypeFunc::Parms+1] = TypeRawPtr::BOTTOM; // Address of stack location for lock
572 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+2,fields);
573
574 // create result type (range)
575 fields = TypeTuple::fields(0);
576
577 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0,fields);
578
579 return TypeFunc::make(domain, range);
580 }
581
582
583 //-----------------------------------------------------------------------------
584 const TypeFunc *OptoRuntime::complete_monitor_exit_Type() {
585 // create input type (domain)
586 const Type **fields = TypeTuple::fields(3);
587 fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; // Object to be Locked
588 fields[TypeFunc::Parms+1] = TypeRawPtr::BOTTOM; // Address of stack location for lock - BasicLock
589 fields[TypeFunc::Parms+2] = TypeRawPtr::BOTTOM; // Thread pointer (Self)
590 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+3, fields);
591
592 // create result type (range)
593 fields = TypeTuple::fields(0);
594
595 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0, fields);
596
597 return TypeFunc::make(domain, range);
598 }
599
1536 frame stub_frame = thread->last_frame();
1537 assert(stub_frame.is_runtime_frame() || exception_blob()->contains(stub_frame.pc()), "sanity check");
1538 frame caller_frame = stub_frame.sender(®_map);
1539 return caller_frame.is_deoptimized_frame();
1540 }
1541
1542
1543 const TypeFunc *OptoRuntime::register_finalizer_Type() {
1544 // create input type (domain)
1545 const Type **fields = TypeTuple::fields(1);
1546 fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; // oop; Receiver
1547 // // The JavaThread* is passed to each routine as the last argument
1548 // fields[TypeFunc::Parms+1] = TypeRawPtr::NOTNULL; // JavaThread *; Executing thread
1549 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+1,fields);
1550
1551 // create result type (range)
1552 fields = TypeTuple::fields(0);
1553
1554 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0,fields);
1555
1556 return TypeFunc::make(domain, range);
1557 }
1558
1559 #if INCLUDE_JFR
1560 const TypeFunc *OptoRuntime::get_class_id_intrinsic_Type() {
1561 // create input type (domain)
1562 const Type **fields = TypeTuple::fields(1);
1563 fields[TypeFunc::Parms+0] = TypeInstPtr::KLASS;
1564 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms + 1, fields);
1565
1566 // create result type (range)
1567 fields = TypeTuple::fields(0);
1568
1569 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms + 0, fields);
1570
1571 return TypeFunc::make(domain,range);
1572 }
1573 #endif
1574
1575 //-----------------------------------------------------------------------------
1576 // Dtrace support. entry and exit probes have the same signature
1577 const TypeFunc *OptoRuntime::dtrace_method_entry_exit_Type() {
1578 // create input type (domain)
1579 const Type **fields = TypeTuple::fields(2);
1580 fields[TypeFunc::Parms+0] = TypeRawPtr::BOTTOM; // Thread-local storage
1581 fields[TypeFunc::Parms+1] = TypeMetadataPtr::BOTTOM; // Method*; Method we are entering
1582 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+2,fields);
1583
1584 // create result type (range)
1585 fields = TypeTuple::fields(0);
1586
1587 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0,fields);
1588
1589 return TypeFunc::make(domain, range);
1590 }
1591
1592 const TypeFunc *OptoRuntime::dtrace_object_alloc_Type() {
1593 // create input type (domain)
1594 const Type **fields = TypeTuple::fields(2);
1595 fields[TypeFunc::Parms+0] = TypeRawPtr::BOTTOM; // Thread-local storage
1596 fields[TypeFunc::Parms+1] = TypeInstPtr::NOTNULL; // oop; newly allocated object
1597
1598 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+2,fields);
1599
1600 // create result type (range)
1601 fields = TypeTuple::fields(0);
1602
1603 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0,fields);
1604
1605 return TypeFunc::make(domain, range);
1606 }
1607
1608
1609 JRT_ENTRY_NO_ASYNC(void, OptoRuntime::register_finalizer(oopDesc* obj, JavaThread* current))
1610 assert(oopDesc::is_oop(obj), "must be a valid oop");
1611 assert(obj->klass()->has_finalizer(), "shouldn't be here otherwise");
1612 InstanceKlass::register_finalizer(instanceOop(obj), CHECK);
1613 JRT_END
1614
1615 //-----------------------------------------------------------------------------
1616
1617 NamedCounter * volatile OptoRuntime::_named_counters = NULL;
1618
1619 //
1620 // dump the collected NamedCounters.
1621 //
1622 void OptoRuntime::print_named_counters() {
1623 int total_lock_count = 0;
1624 int eliminated_lock_count = 0;
1625
1709 trace_exception_counter++;
1710 stringStream tempst;
1711
1712 tempst.print("%d [Exception (%s): ", trace_exception_counter, msg);
1713 exception_oop->print_value_on(&tempst);
1714 tempst.print(" in ");
1715 CodeBlob* blob = CodeCache::find_blob(exception_pc);
1716 if (blob->is_compiled()) {
1717 CompiledMethod* cm = blob->as_compiled_method_or_null();
1718 cm->method()->print_value_on(&tempst);
1719 } else if (blob->is_runtime_stub()) {
1720 tempst.print("<runtime-stub>");
1721 } else {
1722 tempst.print("<unknown>");
1723 }
1724 tempst.print(" at " INTPTR_FORMAT, p2i(exception_pc));
1725 tempst.print("]");
1726
1727 st->print_raw_cr(tempst.as_string());
1728 }
1729
1730 const TypeFunc *OptoRuntime::store_inline_type_fields_Type() {
1731 // create input type (domain)
1732 uint total = SharedRuntime::java_return_convention_max_int + SharedRuntime::java_return_convention_max_float*2;
1733 const Type **fields = TypeTuple::fields(total);
1734 // We don't know the number of returned values and their
1735 // types. Assume all registers available to the return convention
1736 // are used.
1737 fields[TypeFunc::Parms] = TypePtr::BOTTOM;
1738 uint i = 1;
1739 for (; i < SharedRuntime::java_return_convention_max_int; i++) {
1740 fields[TypeFunc::Parms+i] = TypeInt::INT;
1741 }
1742 for (; i < total; i+=2) {
1743 fields[TypeFunc::Parms+i] = Type::DOUBLE;
1744 fields[TypeFunc::Parms+i+1] = Type::HALF;
1745 }
1746 const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms + total, fields);
1747
1748 // create result type (range)
1749 fields = TypeTuple::fields(1);
1750 fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL;
1751
1752 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+1,fields);
1753
1754 return TypeFunc::make(domain, range);
1755 }
1756
1757 const TypeFunc *OptoRuntime::pack_inline_type_Type() {
1758 // create input type (domain)
1759 uint total = 1 + SharedRuntime::java_return_convention_max_int + SharedRuntime::java_return_convention_max_float*2;
1760 const Type **fields = TypeTuple::fields(total);
1761 // We don't know the number of returned values and their
1762 // types. Assume all registers available to the return convention
1763 // are used.
1764 fields[TypeFunc::Parms] = TypeRawPtr::BOTTOM;
1765 fields[TypeFunc::Parms+1] = TypeRawPtr::BOTTOM;
1766 uint i = 2;
1767 for (; i < SharedRuntime::java_return_convention_max_int+1; i++) {
1768 fields[TypeFunc::Parms+i] = TypeInt::INT;
1769 }
1770 for (; i < total; i+=2) {
1771 fields[TypeFunc::Parms+i] = Type::DOUBLE;
1772 fields[TypeFunc::Parms+i+1] = Type::HALF;
1773 }
1774 const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms + total, fields);
1775
1776 // create result type (range)
1777 fields = TypeTuple::fields(1);
1778 fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL;
1779
1780 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+1,fields);
1781
1782 return TypeFunc::make(domain, range);
1783 }
1784
1785 JRT_BLOCK_ENTRY(void, OptoRuntime::load_unknown_inline(flatArrayOopDesc* array, int index, JavaThread* current))
1786 JRT_BLOCK;
1787 flatArrayHandle vah(current, array);
1788 oop buffer = flatArrayOopDesc::value_alloc_copy_from_index(vah, index, THREAD);
1789 deoptimize_caller_frame(current, HAS_PENDING_EXCEPTION);
1790 current->set_vm_result(buffer);
1791 JRT_BLOCK_END;
1792 JRT_END
1793
1794 const TypeFunc* OptoRuntime::load_unknown_inline_type() {
1795 // create input type (domain)
1796 const Type** fields = TypeTuple::fields(2);
1797 fields[TypeFunc::Parms] = TypeOopPtr::NOTNULL;
1798 fields[TypeFunc::Parms+1] = TypeInt::POS;
1799
1800 const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms+2, fields);
1801
1802 // create result type (range)
1803 fields = TypeTuple::fields(1);
1804 fields[TypeFunc::Parms] = TypeInstPtr::NOTNULL;
1805
1806 const TypeTuple* range = TypeTuple::make(TypeFunc::Parms+1, fields);
1807
1808 return TypeFunc::make(domain, range);
1809 }
1810
1811 JRT_LEAF(void, OptoRuntime::store_unknown_inline(instanceOopDesc* buffer, flatArrayOopDesc* array, int index))
1812 {
1813 assert(buffer != NULL, "can't store null into flat array");
1814 array->value_copy_to_index(buffer, index);
1815 }
1816 JRT_END
1817
1818 const TypeFunc* OptoRuntime::store_unknown_inline_type() {
1819 // create input type (domain)
1820 const Type** fields = TypeTuple::fields(3);
1821 fields[TypeFunc::Parms] = TypeInstPtr::NOTNULL;
1822 fields[TypeFunc::Parms+1] = TypeOopPtr::NOTNULL;
1823 fields[TypeFunc::Parms+2] = TypeInt::POS;
1824
1825 const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms+3, fields);
1826
1827 // create result type (range)
1828 fields = TypeTuple::fields(0);
1829 const TypeTuple* range = TypeTuple::make(TypeFunc::Parms, fields);
1830
1831 return TypeFunc::make(domain, range);
1832 }
|