< prev index next >

src/hotspot/share/opto/runtime.cpp

Print this page

  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 

1524   frame stub_frame = thread->last_frame();
1525   assert(stub_frame.is_runtime_frame() || exception_blob()->contains(stub_frame.pc()), "sanity check");
1526   frame caller_frame = stub_frame.sender(&reg_map);
1527   return caller_frame.is_deoptimized_frame();
1528 }
1529 
1530 
1531 const TypeFunc *OptoRuntime::register_finalizer_Type() {
1532   // create input type (domain)
1533   const Type **fields = TypeTuple::fields(1);
1534   fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL;  // oop;          Receiver
1535   // // The JavaThread* is passed to each routine as the last argument
1536   // fields[TypeFunc::Parms+1] = TypeRawPtr::NOTNULL;  // JavaThread *; Executing thread
1537   const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+1,fields);
1538 
1539   // create result type (range)
1540   fields = TypeTuple::fields(0);
1541 
1542   const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0,fields);
1543 
1544   return TypeFunc::make(domain,range);
1545 }
1546 
1547 #if INCLUDE_JFR
1548 const TypeFunc *OptoRuntime::get_class_id_intrinsic_Type() {
1549   // create input type (domain)
1550   const Type **fields = TypeTuple::fields(1);
1551   fields[TypeFunc::Parms+0] = TypeInstPtr::KLASS;
1552   const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms + 1, fields);
1553 
1554   // create result type (range)
1555   fields = TypeTuple::fields(0);
1556 
1557   const TypeTuple *range = TypeTuple::make(TypeFunc::Parms + 0, fields);
1558 
1559   return TypeFunc::make(domain,range);
1560 }
1561 #endif
1562 
1563 //-----------------------------------------------------------------------------
1564 // Dtrace support.  entry and exit probes have the same signature
1565 const TypeFunc *OptoRuntime::dtrace_method_entry_exit_Type() {
1566   // create input type (domain)
1567   const Type **fields = TypeTuple::fields(2);
1568   fields[TypeFunc::Parms+0] = TypeRawPtr::BOTTOM; // Thread-local storage
1569   fields[TypeFunc::Parms+1] = TypeMetadataPtr::BOTTOM;  // Method*;    Method we are entering
1570   const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+2,fields);
1571 
1572   // create result type (range)
1573   fields = TypeTuple::fields(0);
1574 
1575   const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0,fields);
1576 
1577   return TypeFunc::make(domain,range);
1578 }
1579 
1580 const TypeFunc *OptoRuntime::dtrace_object_alloc_Type() {
1581   // create input type (domain)
1582   const Type **fields = TypeTuple::fields(2);
1583   fields[TypeFunc::Parms+0] = TypeRawPtr::BOTTOM; // Thread-local storage
1584   fields[TypeFunc::Parms+1] = TypeInstPtr::NOTNULL;  // oop;    newly allocated object
1585 
1586   const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+2,fields);
1587 
1588   // create result type (range)
1589   fields = TypeTuple::fields(0);
1590 
1591   const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0,fields);
1592 
1593   return TypeFunc::make(domain,range);
1594 }
1595 
1596 
1597 JRT_ENTRY_NO_ASYNC(void, OptoRuntime::register_finalizer(oopDesc* obj, JavaThread* current))
1598   assert(oopDesc::is_oop(obj), "must be a valid oop");
1599   assert(obj->klass()->has_finalizer(), "shouldn't be here otherwise");
1600   InstanceKlass::register_finalizer(instanceOop(obj), CHECK);
1601 JRT_END
1602 
1603 //-----------------------------------------------------------------------------
1604 
1605 NamedCounter * volatile OptoRuntime::_named_counters = NULL;
1606 
1607 //
1608 // dump the collected NamedCounters.
1609 //
1610 void OptoRuntime::print_named_counters() {
1611   int total_lock_count = 0;
1612   int eliminated_lock_count = 0;
1613 

1697   trace_exception_counter++;
1698   stringStream tempst;
1699 
1700   tempst.print("%d [Exception (%s): ", trace_exception_counter, msg);
1701   exception_oop->print_value_on(&tempst);
1702   tempst.print(" in ");
1703   CodeBlob* blob = CodeCache::find_blob(exception_pc);
1704   if (blob->is_compiled()) {
1705     CompiledMethod* cm = blob->as_compiled_method_or_null();
1706     cm->method()->print_value_on(&tempst);
1707   } else if (blob->is_runtime_stub()) {
1708     tempst.print("<runtime-stub>");
1709   } else {
1710     tempst.print("<unknown>");
1711   }
1712   tempst.print(" at " INTPTR_FORMAT,  p2i(exception_pc));
1713   tempst.print("]");
1714 
1715   st->print_raw_cr(tempst.as_string());
1716 }









































































































  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_flatArray(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 

1531   frame stub_frame = thread->last_frame();
1532   assert(stub_frame.is_runtime_frame() || exception_blob()->contains(stub_frame.pc()), "sanity check");
1533   frame caller_frame = stub_frame.sender(&reg_map);
1534   return caller_frame.is_deoptimized_frame();
1535 }
1536 
1537 
1538 const TypeFunc *OptoRuntime::register_finalizer_Type() {
1539   // create input type (domain)
1540   const Type **fields = TypeTuple::fields(1);
1541   fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL;  // oop;          Receiver
1542   // // The JavaThread* is passed to each routine as the last argument
1543   // fields[TypeFunc::Parms+1] = TypeRawPtr::NOTNULL;  // JavaThread *; Executing thread
1544   const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+1,fields);
1545 
1546   // create result type (range)
1547   fields = TypeTuple::fields(0);
1548 
1549   const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0,fields);
1550 
1551   return TypeFunc::make(domain, range);
1552 }
1553 
1554 #if INCLUDE_JFR
1555 const TypeFunc *OptoRuntime::get_class_id_intrinsic_Type() {
1556   // create input type (domain)
1557   const Type **fields = TypeTuple::fields(1);
1558   fields[TypeFunc::Parms+0] = TypeInstPtr::KLASS;
1559   const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms + 1, fields);
1560 
1561   // create result type (range)
1562   fields = TypeTuple::fields(0);
1563 
1564   const TypeTuple *range = TypeTuple::make(TypeFunc::Parms + 0, fields);
1565 
1566   return TypeFunc::make(domain,range);
1567 }
1568 #endif
1569 
1570 //-----------------------------------------------------------------------------
1571 // Dtrace support.  entry and exit probes have the same signature
1572 const TypeFunc *OptoRuntime::dtrace_method_entry_exit_Type() {
1573   // create input type (domain)
1574   const Type **fields = TypeTuple::fields(2);
1575   fields[TypeFunc::Parms+0] = TypeRawPtr::BOTTOM; // Thread-local storage
1576   fields[TypeFunc::Parms+1] = TypeMetadataPtr::BOTTOM;  // Method*;    Method we are entering
1577   const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+2,fields);
1578 
1579   // create result type (range)
1580   fields = TypeTuple::fields(0);
1581 
1582   const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0,fields);
1583 
1584   return TypeFunc::make(domain, range);
1585 }
1586 
1587 const TypeFunc *OptoRuntime::dtrace_object_alloc_Type() {
1588   // create input type (domain)
1589   const Type **fields = TypeTuple::fields(2);
1590   fields[TypeFunc::Parms+0] = TypeRawPtr::BOTTOM; // Thread-local storage
1591   fields[TypeFunc::Parms+1] = TypeInstPtr::NOTNULL;  // oop;    newly allocated object
1592 
1593   const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+2,fields);
1594 
1595   // create result type (range)
1596   fields = TypeTuple::fields(0);
1597 
1598   const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0,fields);
1599 
1600   return TypeFunc::make(domain, range);
1601 }
1602 
1603 
1604 JRT_ENTRY_NO_ASYNC(void, OptoRuntime::register_finalizer(oopDesc* obj, JavaThread* current))
1605   assert(oopDesc::is_oop(obj), "must be a valid oop");
1606   assert(obj->klass()->has_finalizer(), "shouldn't be here otherwise");
1607   InstanceKlass::register_finalizer(instanceOop(obj), CHECK);
1608 JRT_END
1609 
1610 //-----------------------------------------------------------------------------
1611 
1612 NamedCounter * volatile OptoRuntime::_named_counters = NULL;
1613 
1614 //
1615 // dump the collected NamedCounters.
1616 //
1617 void OptoRuntime::print_named_counters() {
1618   int total_lock_count = 0;
1619   int eliminated_lock_count = 0;
1620 

1704   trace_exception_counter++;
1705   stringStream tempst;
1706 
1707   tempst.print("%d [Exception (%s): ", trace_exception_counter, msg);
1708   exception_oop->print_value_on(&tempst);
1709   tempst.print(" in ");
1710   CodeBlob* blob = CodeCache::find_blob(exception_pc);
1711   if (blob->is_compiled()) {
1712     CompiledMethod* cm = blob->as_compiled_method_or_null();
1713     cm->method()->print_value_on(&tempst);
1714   } else if (blob->is_runtime_stub()) {
1715     tempst.print("<runtime-stub>");
1716   } else {
1717     tempst.print("<unknown>");
1718   }
1719   tempst.print(" at " INTPTR_FORMAT,  p2i(exception_pc));
1720   tempst.print("]");
1721 
1722   st->print_raw_cr(tempst.as_string());
1723 }
1724 
1725 const TypeFunc *OptoRuntime::store_inline_type_fields_Type() {
1726   // create input type (domain)
1727   uint total = SharedRuntime::java_return_convention_max_int + SharedRuntime::java_return_convention_max_float*2;
1728   const Type **fields = TypeTuple::fields(total);
1729   // We don't know the number of returned values and their
1730   // types. Assume all registers available to the return convention
1731   // are used.
1732   fields[TypeFunc::Parms] = TypePtr::BOTTOM;
1733   uint i = 1;
1734   for (; i < SharedRuntime::java_return_convention_max_int; i++) {
1735     fields[TypeFunc::Parms+i] = TypeInt::INT;
1736   }
1737   for (; i < total; i+=2) {
1738     fields[TypeFunc::Parms+i] = Type::DOUBLE;
1739     fields[TypeFunc::Parms+i+1] = Type::HALF;
1740   }
1741   const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms + total, fields);
1742 
1743   // create result type (range)
1744   fields = TypeTuple::fields(1);
1745   fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL;
1746 
1747   const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+1,fields);
1748 
1749   return TypeFunc::make(domain, range);
1750 }
1751 
1752 const TypeFunc *OptoRuntime::pack_inline_type_Type() {
1753   // create input type (domain)
1754   uint total = 1 + SharedRuntime::java_return_convention_max_int + SharedRuntime::java_return_convention_max_float*2;
1755   const Type **fields = TypeTuple::fields(total);
1756   // We don't know the number of returned values and their
1757   // types. Assume all registers available to the return convention
1758   // are used.
1759   fields[TypeFunc::Parms] = TypeRawPtr::BOTTOM;
1760   fields[TypeFunc::Parms+1] = TypeRawPtr::BOTTOM;
1761   uint i = 2;
1762   for (; i < SharedRuntime::java_return_convention_max_int+1; i++) {
1763     fields[TypeFunc::Parms+i] = TypeInt::INT;
1764   }
1765   for (; i < total; i+=2) {
1766     fields[TypeFunc::Parms+i] = Type::DOUBLE;
1767     fields[TypeFunc::Parms+i+1] = Type::HALF;
1768   }
1769   const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms + total, fields);
1770 
1771   // create result type (range)
1772   fields = TypeTuple::fields(1);
1773   fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL;
1774 
1775   const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+1,fields);
1776 
1777   return TypeFunc::make(domain, range);
1778 }
1779 
1780 JRT_BLOCK_ENTRY(void, OptoRuntime::load_unknown_inline(flatArrayOopDesc* array, int index, JavaThread* current))
1781   JRT_BLOCK;
1782   flatArrayHandle vah(current, array);
1783   oop buffer = flatArrayOopDesc::value_alloc_copy_from_index(vah, index, THREAD);
1784   deoptimize_caller_frame(current, HAS_PENDING_EXCEPTION);
1785   current->set_vm_result(buffer);
1786   JRT_BLOCK_END;
1787 JRT_END
1788 
1789 const TypeFunc* OptoRuntime::load_unknown_inline_type() {
1790   // create input type (domain)
1791   const Type** fields = TypeTuple::fields(2);
1792   fields[TypeFunc::Parms] = TypeOopPtr::NOTNULL;
1793   fields[TypeFunc::Parms+1] = TypeInt::POS;
1794 
1795   const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms+2, fields);
1796 
1797   // create result type (range)
1798   fields = TypeTuple::fields(1);
1799   fields[TypeFunc::Parms] = TypeInstPtr::NOTNULL;
1800 
1801   const TypeTuple* range = TypeTuple::make(TypeFunc::Parms+1, fields);
1802 
1803   return TypeFunc::make(domain, range);
1804 }
1805 
1806 JRT_LEAF(void, OptoRuntime::store_unknown_inline(instanceOopDesc* buffer, flatArrayOopDesc* array, int index))
1807 {
1808   assert(buffer != NULL, "can't store null into flat array");
1809   array->value_copy_to_index(buffer, index);
1810 }
1811 JRT_END
1812 
1813 const TypeFunc* OptoRuntime::store_unknown_inline_type() {
1814   // create input type (domain)
1815   const Type** fields = TypeTuple::fields(3);
1816   fields[TypeFunc::Parms] = TypeInstPtr::NOTNULL;
1817   fields[TypeFunc::Parms+1] = TypeOopPtr::NOTNULL;
1818   fields[TypeFunc::Parms+2] = TypeInt::POS;
1819 
1820   const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms+3, fields);
1821 
1822   // create result type (range)
1823   fields = TypeTuple::fields(0);
1824   const TypeTuple* range = TypeTuple::make(TypeFunc::Parms, fields);
1825 
1826   return TypeFunc::make(domain, range);
1827 }
< prev index next >