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/oop.inline.hpp"
51 #include "oops/typeArrayOop.inline.hpp"
52 #include "opto/ad.hpp"
53 #include "opto/addnode.hpp"
54 #include "opto/callnode.hpp"
55 #include "opto/cfgnode.hpp"
56 #include "opto/graphKit.hpp"
57 #include "opto/machnode.hpp"
58 #include "opto/matcher.hpp"
59 #include "opto/memnode.hpp"
60 #include "opto/mulnode.hpp"
61 #include "opto/runtime.hpp"
62 #include "opto/subnode.hpp"
63 #include "runtime/atomic.hpp"
64 #include "runtime/frame.inline.hpp"
65 #include "runtime/handles.inline.hpp"
66 #include "runtime/interfaceSupport.inline.hpp"
67 #include "runtime/javaCalls.hpp"
68 #include "runtime/sharedRuntime.hpp"
69 #include "runtime/signature.hpp"
70 #include "runtime/threadCritical.hpp"
71 #include "runtime/vframe.hpp"
223
224 deoptimize_caller_frame(thread, HAS_PENDING_EXCEPTION);
225 JRT_BLOCK_END;
226
227 // inform GC that we won't do card marks for initializing writes.
228 SharedRuntime::on_slowpath_allocation_exit(thread);
229 JRT_END
230
231
232 // array allocation
233 JRT_BLOCK_ENTRY(void, OptoRuntime::new_array_C(Klass* array_type, int len, JavaThread *thread))
234 JRT_BLOCK;
235 #ifndef PRODUCT
236 SharedRuntime::_new_array_ctr++; // new array requires GC
237 #endif
238 assert(check_compiled_frame(thread), "incorrect caller");
239
240 // Scavenge and allocate an instance.
241 oop result;
242
243 if (array_type->is_typeArray_klass()) {
244 // The oopFactory likes to work with the element type.
245 // (We could bypass the oopFactory, since it doesn't add much value.)
246 BasicType elem_type = TypeArrayKlass::cast(array_type)->element_type();
247 result = oopFactory::new_typeArray(elem_type, len, THREAD);
248 } else {
249 // Although the oopFactory likes to work with the elem_type,
250 // the compiler prefers the array_type, since it must already have
251 // that latter value in hand for the fast path.
252 Handle holder(THREAD, array_type->klass_holder()); // keep the array klass alive
253 Klass* elem_type = ObjArrayKlass::cast(array_type)->element_klass();
254 result = oopFactory::new_objArray(elem_type, len, THREAD);
255 }
256
257 // Pass oops back through thread local storage. Our apparent type to Java
258 // is that we return an oop, but we can block on exit from this routine and
259 // a GC can trash the oop in C's return register. The generated stub will
260 // fetch the oop from TLS after any possible GC.
261 deoptimize_caller_frame(thread, HAS_PENDING_EXCEPTION);
262 thread->set_vm_result(result);
263 JRT_BLOCK_END;
264
265 // inform GC that we won't do card marks for initializing writes.
266 SharedRuntime::on_slowpath_allocation_exit(thread);
267 JRT_END
268
269 // array allocation without zeroing
270 JRT_BLOCK_ENTRY(void, OptoRuntime::new_array_nozero_C(Klass* array_type, int len, JavaThread *thread))
271 JRT_BLOCK;
272 #ifndef PRODUCT
273 SharedRuntime::_new_array_ctr++; // new array requires GC
274 #endif
548 fields = TypeTuple::fields(0);
549 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0, fields);
550
551 return TypeFunc::make(domain, range);
552 }
553
554 //-----------------------------------------------------------------------------
555 // Monitor Handling
556 const TypeFunc *OptoRuntime::complete_monitor_enter_Type() {
557 // create input type (domain)
558 const Type **fields = TypeTuple::fields(2);
559 fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; // Object to be Locked
560 fields[TypeFunc::Parms+1] = TypeRawPtr::BOTTOM; // Address of stack location for lock
561 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+2,fields);
562
563 // create result type (range)
564 fields = TypeTuple::fields(0);
565
566 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0,fields);
567
568 return TypeFunc::make(domain,range);
569 }
570
571
572 //-----------------------------------------------------------------------------
573 const TypeFunc *OptoRuntime::complete_monitor_exit_Type() {
574 // create input type (domain)
575 const Type **fields = TypeTuple::fields(3);
576 fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; // Object to be Locked
577 fields[TypeFunc::Parms+1] = TypeRawPtr::BOTTOM; // Address of stack location for lock - BasicLock
578 fields[TypeFunc::Parms+2] = TypeRawPtr::BOTTOM; // Thread pointer (Self)
579 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+3, fields);
580
581 // create result type (range)
582 fields = TypeTuple::fields(0);
583
584 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0, fields);
585
586 return TypeFunc::make(domain, range);
587 }
588
1156 fields = TypeTuple::fields(1);
1157 // fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; // locked oop
1158 fields[TypeFunc::Parms+0] = NULL; // void
1159 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms, fields);
1160 return TypeFunc::make(domain, range);
1161 }
1162
1163 //-------------- methodData update helpers
1164
1165 const TypeFunc* OptoRuntime::profile_receiver_type_Type() {
1166 // create input type (domain)
1167 const Type **fields = TypeTuple::fields(2);
1168 fields[TypeFunc::Parms+0] = TypeAryPtr::NOTNULL; // methodData pointer
1169 fields[TypeFunc::Parms+1] = TypeInstPtr::BOTTOM; // receiver oop
1170 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+2, fields);
1171
1172 // create result type
1173 fields = TypeTuple::fields(1);
1174 fields[TypeFunc::Parms+0] = NULL; // void
1175 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms, fields);
1176 return TypeFunc::make(domain,range);
1177 }
1178
1179 JRT_LEAF(void, OptoRuntime::profile_receiver_type_C(DataLayout* data, oopDesc* receiver))
1180 if (receiver == NULL) return;
1181 Klass* receiver_klass = receiver->klass();
1182
1183 intptr_t* mdp = ((intptr_t*)(data)) + DataLayout::header_size_in_cells();
1184 int empty_row = -1; // free row, if any is encountered
1185
1186 // ReceiverTypeData* vc = new ReceiverTypeData(mdp);
1187 for (uint row = 0; row < ReceiverTypeData::row_limit(); row++) {
1188 // if (vc->receiver(row) == receiver_klass)
1189 int receiver_off = ReceiverTypeData::receiver_cell_index(row);
1190 intptr_t row_recv = *(mdp + receiver_off);
1191 if (row_recv == (intptr_t) receiver_klass) {
1192 // vc->set_receiver_count(row, vc->receiver_count(row) + DataLayout::counter_increment);
1193 int count_off = ReceiverTypeData::receiver_count_cell_index(row);
1194 *(mdp + count_off) += DataLayout::counter_increment;
1195 return;
1196 } else if (row_recv == 0) {
1475 frame stub_frame = thread->last_frame();
1476 assert(stub_frame.is_runtime_frame() || exception_blob()->contains(stub_frame.pc()), "sanity check");
1477 frame caller_frame = stub_frame.sender(®_map);
1478 return caller_frame.is_deoptimized_frame();
1479 }
1480
1481
1482 const TypeFunc *OptoRuntime::register_finalizer_Type() {
1483 // create input type (domain)
1484 const Type **fields = TypeTuple::fields(1);
1485 fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; // oop; Receiver
1486 // // The JavaThread* is passed to each routine as the last argument
1487 // fields[TypeFunc::Parms+1] = TypeRawPtr::NOTNULL; // JavaThread *; Executing thread
1488 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+1,fields);
1489
1490 // create result type (range)
1491 fields = TypeTuple::fields(0);
1492
1493 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0,fields);
1494
1495 return TypeFunc::make(domain,range);
1496 }
1497
1498
1499 //-----------------------------------------------------------------------------
1500 // Dtrace support. entry and exit probes have the same signature
1501 const TypeFunc *OptoRuntime::dtrace_method_entry_exit_Type() {
1502 // create input type (domain)
1503 const Type **fields = TypeTuple::fields(2);
1504 fields[TypeFunc::Parms+0] = TypeRawPtr::BOTTOM; // Thread-local storage
1505 fields[TypeFunc::Parms+1] = TypeMetadataPtr::BOTTOM; // Method*; Method we are entering
1506 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+2,fields);
1507
1508 // create result type (range)
1509 fields = TypeTuple::fields(0);
1510
1511 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0,fields);
1512
1513 return TypeFunc::make(domain,range);
1514 }
1515
1516 const TypeFunc *OptoRuntime::dtrace_object_alloc_Type() {
1517 // create input type (domain)
1518 const Type **fields = TypeTuple::fields(2);
1519 fields[TypeFunc::Parms+0] = TypeRawPtr::BOTTOM; // Thread-local storage
1520 fields[TypeFunc::Parms+1] = TypeInstPtr::NOTNULL; // oop; newly allocated object
1521
1522 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+2,fields);
1523
1524 // create result type (range)
1525 fields = TypeTuple::fields(0);
1526
1527 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0,fields);
1528
1529 return TypeFunc::make(domain,range);
1530 }
1531
1532
1533 JRT_ENTRY_NO_ASYNC(void, OptoRuntime::register_finalizer(oopDesc* obj, JavaThread* thread))
1534 assert(oopDesc::is_oop(obj), "must be a valid oop");
1535 assert(obj->klass()->has_finalizer(), "shouldn't be here otherwise");
1536 InstanceKlass::register_finalizer(instanceOop(obj), CHECK);
1537 JRT_END
1538
1539 //-----------------------------------------------------------------------------
1540
1541 NamedCounter * volatile OptoRuntime::_named_counters = NULL;
1542
1543 //
1544 // dump the collected NamedCounters.
1545 //
1546 void OptoRuntime::print_named_counters() {
1547 int total_lock_count = 0;
1548 int eliminated_lock_count = 0;
1549
1640 static void trace_exception(outputStream* st, oop exception_oop, address exception_pc, const char* msg) {
1641 trace_exception_counter++;
1642 stringStream tempst;
1643
1644 tempst.print("%d [Exception (%s): ", trace_exception_counter, msg);
1645 exception_oop->print_value_on(&tempst);
1646 tempst.print(" in ");
1647 CodeBlob* blob = CodeCache::find_blob(exception_pc);
1648 if (blob->is_compiled()) {
1649 CompiledMethod* cm = blob->as_compiled_method_or_null();
1650 cm->method()->print_value_on(&tempst);
1651 } else if (blob->is_runtime_stub()) {
1652 tempst.print("<runtime-stub>");
1653 } else {
1654 tempst.print("<unknown>");
1655 }
1656 tempst.print(" at " INTPTR_FORMAT, p2i(exception_pc));
1657 tempst.print("]");
1658
1659 st->print_raw_cr(tempst.as_string());
1660 }
|
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/oop.inline.hpp"
51 #include "oops/typeArrayOop.inline.hpp"
52 #include "oops/valueArrayKlass.hpp"
53 #include "oops/valueArrayOop.inline.hpp"
54 #include "opto/ad.hpp"
55 #include "opto/addnode.hpp"
56 #include "opto/callnode.hpp"
57 #include "opto/cfgnode.hpp"
58 #include "opto/graphKit.hpp"
59 #include "opto/machnode.hpp"
60 #include "opto/matcher.hpp"
61 #include "opto/memnode.hpp"
62 #include "opto/mulnode.hpp"
63 #include "opto/runtime.hpp"
64 #include "opto/subnode.hpp"
65 #include "runtime/atomic.hpp"
66 #include "runtime/frame.inline.hpp"
67 #include "runtime/handles.inline.hpp"
68 #include "runtime/interfaceSupport.inline.hpp"
69 #include "runtime/javaCalls.hpp"
70 #include "runtime/sharedRuntime.hpp"
71 #include "runtime/signature.hpp"
72 #include "runtime/threadCritical.hpp"
73 #include "runtime/vframe.hpp"
225
226 deoptimize_caller_frame(thread, HAS_PENDING_EXCEPTION);
227 JRT_BLOCK_END;
228
229 // inform GC that we won't do card marks for initializing writes.
230 SharedRuntime::on_slowpath_allocation_exit(thread);
231 JRT_END
232
233
234 // array allocation
235 JRT_BLOCK_ENTRY(void, OptoRuntime::new_array_C(Klass* array_type, int len, JavaThread *thread))
236 JRT_BLOCK;
237 #ifndef PRODUCT
238 SharedRuntime::_new_array_ctr++; // new array requires GC
239 #endif
240 assert(check_compiled_frame(thread), "incorrect caller");
241
242 // Scavenge and allocate an instance.
243 oop result;
244
245 if (array_type->is_valueArray_klass()) {
246 // TODO refactor all these checks, is_typeArray_klass should not be true for a value type array
247 // TODO use oopFactory::new_array
248 Klass* elem_type = ValueArrayKlass::cast(array_type)->element_klass();
249 result = oopFactory::new_valueArray(elem_type, len, THREAD);
250 } else if (array_type->is_typeArray_klass()) {
251 // The oopFactory likes to work with the element type.
252 // (We could bypass the oopFactory, since it doesn't add much value.)
253 BasicType elem_type = TypeArrayKlass::cast(array_type)->element_type();
254 result = oopFactory::new_typeArray(elem_type, len, THREAD);
255 } else {
256 // Although the oopFactory likes to work with the elem_type,
257 // the compiler prefers the array_type, since it must already have
258 // that latter value in hand for the fast path.
259 Handle holder(THREAD, array_type->klass_holder()); // keep the array klass alive
260 Klass* elem_type = ObjArrayKlass::cast(array_type)->element_klass();
261 result = oopFactory::new_array(elem_type, len, THREAD);
262 }
263
264 // Pass oops back through thread local storage. Our apparent type to Java
265 // is that we return an oop, but we can block on exit from this routine and
266 // a GC can trash the oop in C's return register. The generated stub will
267 // fetch the oop from TLS after any possible GC.
268 deoptimize_caller_frame(thread, HAS_PENDING_EXCEPTION);
269 thread->set_vm_result(result);
270 JRT_BLOCK_END;
271
272 // inform GC that we won't do card marks for initializing writes.
273 SharedRuntime::on_slowpath_allocation_exit(thread);
274 JRT_END
275
276 // array allocation without zeroing
277 JRT_BLOCK_ENTRY(void, OptoRuntime::new_array_nozero_C(Klass* array_type, int len, JavaThread *thread))
278 JRT_BLOCK;
279 #ifndef PRODUCT
280 SharedRuntime::_new_array_ctr++; // new array requires GC
281 #endif
555 fields = TypeTuple::fields(0);
556 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0, fields);
557
558 return TypeFunc::make(domain, range);
559 }
560
561 //-----------------------------------------------------------------------------
562 // Monitor Handling
563 const TypeFunc *OptoRuntime::complete_monitor_enter_Type() {
564 // create input type (domain)
565 const Type **fields = TypeTuple::fields(2);
566 fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; // Object to be Locked
567 fields[TypeFunc::Parms+1] = TypeRawPtr::BOTTOM; // Address of stack location for lock
568 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+2,fields);
569
570 // create result type (range)
571 fields = TypeTuple::fields(0);
572
573 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0,fields);
574
575 return TypeFunc::make(domain, range);
576 }
577
578
579 //-----------------------------------------------------------------------------
580 const TypeFunc *OptoRuntime::complete_monitor_exit_Type() {
581 // create input type (domain)
582 const Type **fields = TypeTuple::fields(3);
583 fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; // Object to be Locked
584 fields[TypeFunc::Parms+1] = TypeRawPtr::BOTTOM; // Address of stack location for lock - BasicLock
585 fields[TypeFunc::Parms+2] = TypeRawPtr::BOTTOM; // Thread pointer (Self)
586 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+3, fields);
587
588 // create result type (range)
589 fields = TypeTuple::fields(0);
590
591 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0, fields);
592
593 return TypeFunc::make(domain, range);
594 }
595
1163 fields = TypeTuple::fields(1);
1164 // fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; // locked oop
1165 fields[TypeFunc::Parms+0] = NULL; // void
1166 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms, fields);
1167 return TypeFunc::make(domain, range);
1168 }
1169
1170 //-------------- methodData update helpers
1171
1172 const TypeFunc* OptoRuntime::profile_receiver_type_Type() {
1173 // create input type (domain)
1174 const Type **fields = TypeTuple::fields(2);
1175 fields[TypeFunc::Parms+0] = TypeAryPtr::NOTNULL; // methodData pointer
1176 fields[TypeFunc::Parms+1] = TypeInstPtr::BOTTOM; // receiver oop
1177 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+2, fields);
1178
1179 // create result type
1180 fields = TypeTuple::fields(1);
1181 fields[TypeFunc::Parms+0] = NULL; // void
1182 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms, fields);
1183 return TypeFunc::make(domain, range);
1184 }
1185
1186 JRT_LEAF(void, OptoRuntime::profile_receiver_type_C(DataLayout* data, oopDesc* receiver))
1187 if (receiver == NULL) return;
1188 Klass* receiver_klass = receiver->klass();
1189
1190 intptr_t* mdp = ((intptr_t*)(data)) + DataLayout::header_size_in_cells();
1191 int empty_row = -1; // free row, if any is encountered
1192
1193 // ReceiverTypeData* vc = new ReceiverTypeData(mdp);
1194 for (uint row = 0; row < ReceiverTypeData::row_limit(); row++) {
1195 // if (vc->receiver(row) == receiver_klass)
1196 int receiver_off = ReceiverTypeData::receiver_cell_index(row);
1197 intptr_t row_recv = *(mdp + receiver_off);
1198 if (row_recv == (intptr_t) receiver_klass) {
1199 // vc->set_receiver_count(row, vc->receiver_count(row) + DataLayout::counter_increment);
1200 int count_off = ReceiverTypeData::receiver_count_cell_index(row);
1201 *(mdp + count_off) += DataLayout::counter_increment;
1202 return;
1203 } else if (row_recv == 0) {
1482 frame stub_frame = thread->last_frame();
1483 assert(stub_frame.is_runtime_frame() || exception_blob()->contains(stub_frame.pc()), "sanity check");
1484 frame caller_frame = stub_frame.sender(®_map);
1485 return caller_frame.is_deoptimized_frame();
1486 }
1487
1488
1489 const TypeFunc *OptoRuntime::register_finalizer_Type() {
1490 // create input type (domain)
1491 const Type **fields = TypeTuple::fields(1);
1492 fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; // oop; Receiver
1493 // // The JavaThread* is passed to each routine as the last argument
1494 // fields[TypeFunc::Parms+1] = TypeRawPtr::NOTNULL; // JavaThread *; Executing thread
1495 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+1,fields);
1496
1497 // create result type (range)
1498 fields = TypeTuple::fields(0);
1499
1500 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0,fields);
1501
1502 return TypeFunc::make(domain, range);
1503 }
1504
1505
1506 //-----------------------------------------------------------------------------
1507 // Dtrace support. entry and exit probes have the same signature
1508 const TypeFunc *OptoRuntime::dtrace_method_entry_exit_Type() {
1509 // create input type (domain)
1510 const Type **fields = TypeTuple::fields(2);
1511 fields[TypeFunc::Parms+0] = TypeRawPtr::BOTTOM; // Thread-local storage
1512 fields[TypeFunc::Parms+1] = TypeMetadataPtr::BOTTOM; // Method*; Method we are entering
1513 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+2,fields);
1514
1515 // create result type (range)
1516 fields = TypeTuple::fields(0);
1517
1518 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0,fields);
1519
1520 return TypeFunc::make(domain, range);
1521 }
1522
1523 const TypeFunc *OptoRuntime::dtrace_object_alloc_Type() {
1524 // create input type (domain)
1525 const Type **fields = TypeTuple::fields(2);
1526 fields[TypeFunc::Parms+0] = TypeRawPtr::BOTTOM; // Thread-local storage
1527 fields[TypeFunc::Parms+1] = TypeInstPtr::NOTNULL; // oop; newly allocated object
1528
1529 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+2,fields);
1530
1531 // create result type (range)
1532 fields = TypeTuple::fields(0);
1533
1534 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0,fields);
1535
1536 return TypeFunc::make(domain, range);
1537 }
1538
1539
1540 JRT_ENTRY_NO_ASYNC(void, OptoRuntime::register_finalizer(oopDesc* obj, JavaThread* thread))
1541 assert(oopDesc::is_oop(obj), "must be a valid oop");
1542 assert(obj->klass()->has_finalizer(), "shouldn't be here otherwise");
1543 InstanceKlass::register_finalizer(instanceOop(obj), CHECK);
1544 JRT_END
1545
1546 //-----------------------------------------------------------------------------
1547
1548 NamedCounter * volatile OptoRuntime::_named_counters = NULL;
1549
1550 //
1551 // dump the collected NamedCounters.
1552 //
1553 void OptoRuntime::print_named_counters() {
1554 int total_lock_count = 0;
1555 int eliminated_lock_count = 0;
1556
1647 static void trace_exception(outputStream* st, oop exception_oop, address exception_pc, const char* msg) {
1648 trace_exception_counter++;
1649 stringStream tempst;
1650
1651 tempst.print("%d [Exception (%s): ", trace_exception_counter, msg);
1652 exception_oop->print_value_on(&tempst);
1653 tempst.print(" in ");
1654 CodeBlob* blob = CodeCache::find_blob(exception_pc);
1655 if (blob->is_compiled()) {
1656 CompiledMethod* cm = blob->as_compiled_method_or_null();
1657 cm->method()->print_value_on(&tempst);
1658 } else if (blob->is_runtime_stub()) {
1659 tempst.print("<runtime-stub>");
1660 } else {
1661 tempst.print("<unknown>");
1662 }
1663 tempst.print(" at " INTPTR_FORMAT, p2i(exception_pc));
1664 tempst.print("]");
1665
1666 st->print_raw_cr(tempst.as_string());
1667 }
1668
1669 const TypeFunc *OptoRuntime::store_value_type_fields_Type() {
1670 // create input type (domain)
1671 uint total = SharedRuntime::java_return_convention_max_int + SharedRuntime::java_return_convention_max_float*2;
1672 const Type **fields = TypeTuple::fields(total);
1673 // We don't know the number of returned values and their
1674 // types. Assume all registers available to the return convention
1675 // are used.
1676 fields[TypeFunc::Parms] = TypePtr::BOTTOM;
1677 uint i = 1;
1678 for (; i < SharedRuntime::java_return_convention_max_int; i++) {
1679 fields[TypeFunc::Parms+i] = TypeInt::INT;
1680 }
1681 for (; i < total; i+=2) {
1682 fields[TypeFunc::Parms+i] = Type::DOUBLE;
1683 fields[TypeFunc::Parms+i+1] = Type::HALF;
1684 }
1685 const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms + total, fields);
1686
1687 // create result type (range)
1688 fields = TypeTuple::fields(1);
1689 fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL;
1690
1691 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+1,fields);
1692
1693 return TypeFunc::make(domain, range);
1694 }
1695
1696 const TypeFunc *OptoRuntime::pack_value_type_Type() {
1697 // create input type (domain)
1698 uint total = 1 + SharedRuntime::java_return_convention_max_int + SharedRuntime::java_return_convention_max_float*2;
1699 const Type **fields = TypeTuple::fields(total);
1700 // We don't know the number of returned values and their
1701 // types. Assume all registers available to the return convention
1702 // are used.
1703 fields[TypeFunc::Parms] = TypeRawPtr::BOTTOM;
1704 fields[TypeFunc::Parms+1] = TypeRawPtr::BOTTOM;
1705 uint i = 2;
1706 for (; i < SharedRuntime::java_return_convention_max_int+1; i++) {
1707 fields[TypeFunc::Parms+i] = TypeInt::INT;
1708 }
1709 for (; i < total; i+=2) {
1710 fields[TypeFunc::Parms+i] = Type::DOUBLE;
1711 fields[TypeFunc::Parms+i+1] = Type::HALF;
1712 }
1713 const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms + total, fields);
1714
1715 // create result type (range)
1716 fields = TypeTuple::fields(1);
1717 fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL;
1718
1719 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+1,fields);
1720
1721 return TypeFunc::make(domain, range);
1722 }
1723
1724 JRT_LEAF(void, OptoRuntime::load_unknown_value(valueArrayOopDesc* array, int index, instanceOopDesc* buffer))
1725 {
1726 Klass* klass = array->klass();
1727 assert(klass->is_valueArray_klass(), "expected value array oop");
1728
1729 ValueArrayKlass* vaklass = ValueArrayKlass::cast(klass);
1730 ValueKlass* vklass = vaklass->element_klass();
1731 void* src = array->value_at_addr(index, vaklass->layout_helper());
1732 vklass->value_store(src, vklass->data_for_oop(buffer),
1733 vaklass->element_byte_size(), true, false);
1734 }
1735 JRT_END
1736
1737 const TypeFunc *OptoRuntime::load_unknown_value_Type() {
1738 // create input type (domain)
1739 const Type **fields = TypeTuple::fields(3);
1740 // We don't know the number of returned values and their
1741 // types. Assume all registers available to the return convention
1742 // are used.
1743 fields[TypeFunc::Parms] = TypeOopPtr::NOTNULL;
1744 fields[TypeFunc::Parms+1] = TypeInt::POS;
1745 fields[TypeFunc::Parms+2] = TypeInstPtr::NOTNULL;
1746
1747 const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms+3, fields);
1748
1749 // create result type (range)
1750 fields = TypeTuple::fields(0);
1751 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0, fields);
1752
1753 return TypeFunc::make(domain, range);
1754 }
1755
1756 JRT_LEAF(void, OptoRuntime::store_unknown_value(instanceOopDesc* buffer, valueArrayOopDesc* array, int index))
1757 {
1758 assert(buffer != NULL, "can't store null into flat array");
1759 Klass* klass = array->klass();
1760 assert(klass->is_valueArray_klass(), "expected value array");
1761 assert(ArrayKlass::cast(klass)->element_klass() == buffer->klass(), "Store type incorrect");
1762
1763 ValueArrayKlass* vaklass = ValueArrayKlass::cast(klass);
1764 ValueKlass* vklass = vaklass->element_klass();
1765 const int lh = vaklass->layout_helper();
1766 vklass->value_store(vklass->data_for_oop(buffer), array->value_at_addr(index, lh),
1767 vaklass->element_byte_size(), true, false);
1768 }
1769 JRT_END
1770
1771 const TypeFunc *OptoRuntime::store_unknown_value_Type() {
1772 // create input type (domain)
1773 const Type **fields = TypeTuple::fields(3);
1774 // We don't know the number of returned values and their
1775 // types. Assume all registers available to the return convention
1776 // are used.
1777 fields[TypeFunc::Parms] = TypeInstPtr::NOTNULL;
1778 fields[TypeFunc::Parms+1] = TypeOopPtr::NOTNULL;
1779 fields[TypeFunc::Parms+2] = TypeInt::POS;
1780
1781 const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms+3, fields);
1782
1783 // create result type (range)
1784 fields = TypeTuple::fields(0);
1785 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0, fields);
1786
1787 return TypeFunc::make(domain, range);
1788 }
|