< prev index next >

src/hotspot/share/opto/runtime.cpp

Print this page

  27 #include "classfile/vmSymbols.hpp"
  28 #include "code/codeCache.hpp"
  29 #include "code/compiledIC.hpp"
  30 #include "code/nmethod.hpp"
  31 #include "code/pcDesc.hpp"
  32 #include "code/scopeDesc.hpp"
  33 #include "code/vtableStubs.hpp"
  34 #include "compiler/compileBroker.hpp"
  35 #include "compiler/oopMap.hpp"
  36 #include "gc/g1/g1HeapRegion.hpp"
  37 #include "gc/shared/barrierSet.hpp"
  38 #include "gc/shared/collectedHeap.hpp"
  39 #include "gc/shared/gcLocker.hpp"
  40 #include "interpreter/bytecode.hpp"
  41 #include "interpreter/interpreter.hpp"
  42 #include "interpreter/linkResolver.hpp"
  43 #include "logging/log.hpp"
  44 #include "logging/logStream.hpp"
  45 #include "memory/oopFactory.hpp"
  46 #include "memory/resourceArea.hpp"


  47 #include "oops/objArrayKlass.hpp"
  48 #include "oops/klass.inline.hpp"
  49 #include "oops/oop.inline.hpp"
  50 #include "oops/typeArrayOop.inline.hpp"
  51 #include "opto/ad.hpp"
  52 #include "opto/addnode.hpp"
  53 #include "opto/callnode.hpp"
  54 #include "opto/cfgnode.hpp"
  55 #include "opto/graphKit.hpp"
  56 #include "opto/machnode.hpp"
  57 #include "opto/matcher.hpp"
  58 #include "opto/memnode.hpp"
  59 #include "opto/mulnode.hpp"
  60 #include "opto/output.hpp"
  61 #include "opto/runtime.hpp"
  62 #include "opto/subnode.hpp"
  63 #include "prims/jvmtiExport.hpp"
  64 #include "runtime/atomic.hpp"
  65 #include "runtime/frame.inline.hpp"
  66 #include "runtime/handles.inline.hpp"

  87 //
  88 // At command line specify the parameters: -XX:+FullGCALot -XX:FullGCALotStart=100000000
  89 
  90 
  91 
  92 
  93 // Compiled code entry points
  94 address OptoRuntime::_new_instance_Java                           = nullptr;
  95 address OptoRuntime::_new_array_Java                              = nullptr;
  96 address OptoRuntime::_new_array_nozero_Java                       = nullptr;
  97 address OptoRuntime::_multianewarray2_Java                        = nullptr;
  98 address OptoRuntime::_multianewarray3_Java                        = nullptr;
  99 address OptoRuntime::_multianewarray4_Java                        = nullptr;
 100 address OptoRuntime::_multianewarray5_Java                        = nullptr;
 101 address OptoRuntime::_multianewarrayN_Java                        = nullptr;
 102 address OptoRuntime::_vtable_must_compile_Java                    = nullptr;
 103 address OptoRuntime::_complete_monitor_locking_Java               = nullptr;
 104 address OptoRuntime::_monitor_notify_Java                         = nullptr;
 105 address OptoRuntime::_monitor_notifyAll_Java                      = nullptr;
 106 address OptoRuntime::_rethrow_Java                                = nullptr;
 107 
 108 address OptoRuntime::_slow_arraycopy_Java                         = nullptr;
 109 address OptoRuntime::_register_finalizer_Java                     = nullptr;

 110 #if INCLUDE_JVMTI
 111 address OptoRuntime::_notify_jvmti_vthread_start                  = nullptr;
 112 address OptoRuntime::_notify_jvmti_vthread_end                    = nullptr;
 113 address OptoRuntime::_notify_jvmti_vthread_mount                  = nullptr;
 114 address OptoRuntime::_notify_jvmti_vthread_unmount                = nullptr;
 115 #endif
 116 
 117 ExceptionBlob* OptoRuntime::_exception_blob;
 118 
 119 // This should be called in an assertion at the start of OptoRuntime routines
 120 // which are entered from compiled code (all of them)
 121 #ifdef ASSERT
 122 static bool check_compiled_frame(JavaThread* thread) {
 123   assert(thread->last_frame().is_runtime_frame(), "cannot call runtime directly from compiled code");
 124   RegisterMap map(thread,
 125                   RegisterMap::UpdateMap::skip,
 126                   RegisterMap::ProcessFrames::include,
 127                   RegisterMap::WalkContinuation::skip);
 128   frame caller = thread->last_frame().sender(&map);
 129   assert(caller.is_compiled_frame(), "not being called from compiled like code");

 145   //   variable/name                       type-function-gen              , runtime method                  ,fncy_jp, tls,retpc
 146   // -------------------------------------------------------------------------------------------------------------------------------
 147   gen(env, _new_instance_Java              , new_instance_Type            , new_instance_C                  ,    0 , true, false);
 148   gen(env, _new_array_Java                 , new_array_Type               , new_array_C                     ,    0 , true, false);
 149   gen(env, _new_array_nozero_Java          , new_array_Type               , new_array_nozero_C              ,    0 , true, false);
 150   gen(env, _multianewarray2_Java           , multianewarray2_Type         , multianewarray2_C               ,    0 , true, false);
 151   gen(env, _multianewarray3_Java           , multianewarray3_Type         , multianewarray3_C               ,    0 , true, false);
 152   gen(env, _multianewarray4_Java           , multianewarray4_Type         , multianewarray4_C               ,    0 , true, false);
 153   gen(env, _multianewarray5_Java           , multianewarray5_Type         , multianewarray5_C               ,    0 , true, false);
 154   gen(env, _multianewarrayN_Java           , multianewarrayN_Type         , multianewarrayN_C               ,    0 , true, false);
 155 #if INCLUDE_JVMTI
 156   gen(env, _notify_jvmti_vthread_start     , notify_jvmti_vthread_Type    , SharedRuntime::notify_jvmti_vthread_start, 0, true, false);
 157   gen(env, _notify_jvmti_vthread_end       , notify_jvmti_vthread_Type    , SharedRuntime::notify_jvmti_vthread_end,   0, true, false);
 158   gen(env, _notify_jvmti_vthread_mount     , notify_jvmti_vthread_Type    , SharedRuntime::notify_jvmti_vthread_mount, 0, true, false);
 159   gen(env, _notify_jvmti_vthread_unmount   , notify_jvmti_vthread_Type    , SharedRuntime::notify_jvmti_vthread_unmount, 0, true, false);
 160 #endif
 161   gen(env, _complete_monitor_locking_Java  , complete_monitor_enter_Type  , SharedRuntime::complete_monitor_locking_C, 0, false, false);
 162   gen(env, _monitor_notify_Java            , monitor_notify_Type          , monitor_notify_C                ,    0 , false, false);
 163   gen(env, _monitor_notifyAll_Java         , monitor_notify_Type          , monitor_notifyAll_C             ,    0 , false, false);
 164   gen(env, _rethrow_Java                   , rethrow_Type                 , rethrow_C                       ,    2 , true , true );
 165 
 166   gen(env, _slow_arraycopy_Java            , slow_arraycopy_Type          , SharedRuntime::slow_arraycopy_C ,    0 , false, false);
 167   gen(env, _register_finalizer_Java        , register_finalizer_Type      , register_finalizer              ,    0 , false, false);

 168 
 169   return true;
 170 }
 171 
 172 #undef gen
 173 
 174 
 175 // Helper method to do generation of RunTimeStub's
 176 address OptoRuntime::generate_stub(ciEnv* env,
 177                                    TypeFunc_generator gen, address C_function,
 178                                    const char *name, int is_fancy_jump,
 179                                    bool pass_tls,
 180                                    bool return_pc) {
 181 
 182   // Matching the default directive, we currently have no method to match.
 183   DirectiveSet* directive = DirectivesStack::getDefaultDirective(CompileBroker::compiler(CompLevel_full_optimization));
 184   ResourceMark rm;
 185   Compile C(env, gen, C_function, name, is_fancy_jump, pass_tls, return_pc, directive);
 186   DirectivesStack::release(directive);
 187   return  C.stub_entry_point();

 193   RuntimeStub* rs =(RuntimeStub *)cb;
 194   assert(rs != nullptr && rs->is_runtime_stub(), "not a runtime stub");
 195   return rs->name();
 196 #else
 197   // Fast implementation for product mode (maybe it should be inlined too)
 198   return "runtime stub";
 199 #endif
 200 }
 201 
 202 
 203 //=============================================================================
 204 // Opto compiler runtime routines
 205 //=============================================================================
 206 
 207 
 208 //=============================allocation======================================
 209 // We failed the fast-path allocation.  Now we need to do a scavenge or GC
 210 // and try allocation again.
 211 
 212 // object allocation
 213 JRT_BLOCK_ENTRY(void, OptoRuntime::new_instance_C(Klass* klass, JavaThread* current))
 214   JRT_BLOCK;
 215 #ifndef PRODUCT
 216   SharedRuntime::_new_instance_ctr++;         // new instance requires GC
 217 #endif
 218   assert(check_compiled_frame(current), "incorrect caller");
 219 
 220   // These checks are cheap to make and support reflective allocation.
 221   int lh = klass->layout_helper();
 222   if (Klass::layout_helper_needs_slow_path(lh) || !InstanceKlass::cast(klass)->is_initialized()) {
 223     Handle holder(current, klass->klass_holder()); // keep the klass alive
 224     klass->check_valid_for_instantiation(false, THREAD);
 225     if (!HAS_PENDING_EXCEPTION) {
 226       InstanceKlass::cast(klass)->initialize(THREAD);
 227     }
 228   }
 229 
 230   if (!HAS_PENDING_EXCEPTION) {
 231     // Scavenge and allocate an instance.
 232     Handle holder(current, klass->klass_holder()); // keep the klass alive
 233     oop result = InstanceKlass::cast(klass)->allocate_instance(THREAD);




 234     current->set_vm_result(result);
 235 
 236     // Pass oops back through thread local storage.  Our apparent type to Java
 237     // is that we return an oop, but we can block on exit from this routine and
 238     // a GC can trash the oop in C's return register.  The generated stub will
 239     // fetch the oop from TLS after any possible GC.
 240   }
 241 
 242   deoptimize_caller_frame(current, HAS_PENDING_EXCEPTION);
 243   JRT_BLOCK_END;
 244 
 245   // inform GC that we won't do card marks for initializing writes.
 246   SharedRuntime::on_slowpath_allocation_exit(current);
 247 JRT_END
 248 
 249 
 250 // array allocation
 251 JRT_BLOCK_ENTRY(void, OptoRuntime::new_array_C(Klass* array_type, int len, JavaThread* current))
 252   JRT_BLOCK;
 253 #ifndef PRODUCT
 254   SharedRuntime::_new_array_ctr++;            // new array requires GC
 255 #endif
 256   assert(check_compiled_frame(current), "incorrect caller");
 257 
 258   // Scavenge and allocate an instance.
 259   oop result;
 260 
 261   if (array_type->is_typeArray_klass()) {



 262     // The oopFactory likes to work with the element type.
 263     // (We could bypass the oopFactory, since it doesn't add much value.)
 264     BasicType elem_type = TypeArrayKlass::cast(array_type)->element_type();
 265     result = oopFactory::new_typeArray(elem_type, len, THREAD);
 266   } else {
 267     // Although the oopFactory likes to work with the elem_type,
 268     // the compiler prefers the array_type, since it must already have
 269     // that latter value in hand for the fast path.
 270     Handle holder(current, array_type->klass_holder()); // keep the array klass alive
 271     Klass* elem_type = ObjArrayKlass::cast(array_type)->element_klass();
 272     result = oopFactory::new_objArray(elem_type, len, THREAD);
 273   }
 274 
 275   // Pass oops back through thread local storage.  Our apparent type to Java
 276   // is that we return an oop, but we can block on exit from this routine and
 277   // a GC can trash the oop in C's return register.  The generated stub will
 278   // fetch the oop from TLS after any possible GC.
 279   deoptimize_caller_frame(current, HAS_PENDING_EXCEPTION);
 280   current->set_vm_result(result);
 281   JRT_BLOCK_END;
 282 
 283   // inform GC that we won't do card marks for initializing writes.
 284   SharedRuntime::on_slowpath_allocation_exit(current);
 285 JRT_END
 286 
 287 // array allocation without zeroing
 288 JRT_BLOCK_ENTRY(void, OptoRuntime::new_array_nozero_C(Klass* array_type, int len, JavaThread* current))
 289   JRT_BLOCK;
 290 #ifndef PRODUCT
 291   SharedRuntime::_new_array_ctr++;            // new array requires GC
 292 #endif

 449 JRT_BLOCK_ENTRY(void, OptoRuntime::monitor_notifyAll_C(oopDesc* obj, JavaThread* current))
 450 
 451   if (!SafepointSynchronize::is_synchronizing() ) {
 452     if (ObjectSynchronizer::quick_notify(obj, current, true)) {
 453       return;
 454     }
 455   }
 456 
 457   // This is the case the fast-path above isn't provisioned to handle.
 458   // The fast-path is designed to handle frequently arising cases in an efficient manner.
 459   // (The fast-path is just a degenerate variant of the slow-path).
 460   // Perform the dreaded state transition and pass control into the slow-path.
 461   JRT_BLOCK;
 462   Handle h_obj(current, obj);
 463   ObjectSynchronizer::notifyall(h_obj, CHECK);
 464   JRT_BLOCK_END;
 465 JRT_END
 466 
 467 const TypeFunc *OptoRuntime::new_instance_Type() {
 468   // create input type (domain)
 469   const Type **fields = TypeTuple::fields(1);
 470   fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; // Klass to be allocated
 471   const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+1, fields);

 472 
 473   // create result type (range)
 474   fields = TypeTuple::fields(1);
 475   fields[TypeFunc::Parms+0] = TypeRawPtr::NOTNULL; // Returned oop
 476 
 477   const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+1, fields);
 478 
 479   return TypeFunc::make(domain, range);
 480 }
 481 
 482 #if INCLUDE_JVMTI
 483 const TypeFunc *OptoRuntime::notify_jvmti_vthread_Type() {
 484   // create input type (domain)
 485   const Type **fields = TypeTuple::fields(2);
 486   fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; // VirtualThread oop
 487   fields[TypeFunc::Parms+1] = TypeInt::BOOL;        // jboolean
 488   const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+2,fields);
 489 
 490   // no result type needed
 491   fields = TypeTuple::fields(1);

 585   fields = TypeTuple::fields(0);
 586   const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0, fields);
 587 
 588   return TypeFunc::make(domain, range);
 589 }
 590 
 591 //-----------------------------------------------------------------------------
 592 // Monitor Handling
 593 const TypeFunc *OptoRuntime::complete_monitor_enter_Type() {
 594   // create input type (domain)
 595   const Type **fields = TypeTuple::fields(2);
 596   fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL;  // Object to be Locked
 597   fields[TypeFunc::Parms+1] = TypeRawPtr::BOTTOM;   // Address of stack location for lock
 598   const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+2,fields);
 599 
 600   // create result type (range)
 601   fields = TypeTuple::fields(0);
 602 
 603   const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0,fields);
 604 
 605   return TypeFunc::make(domain,range);
 606 }
 607 
 608 
 609 //-----------------------------------------------------------------------------
 610 const TypeFunc *OptoRuntime::complete_monitor_exit_Type() {
 611   // create input type (domain)
 612   const Type **fields = TypeTuple::fields(3);
 613   fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL;  // Object to be Locked
 614   fields[TypeFunc::Parms+1] = TypeRawPtr::BOTTOM;    // Address of stack location for lock - BasicLock
 615   fields[TypeFunc::Parms+2] = TypeRawPtr::BOTTOM;    // Thread pointer (Self)
 616   const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+3, fields);
 617 
 618   // create result type (range)
 619   fields = TypeTuple::fields(0);
 620 
 621   const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0, fields);
 622 
 623   return TypeFunc::make(domain, range);
 624 }
 625 

1673   frame stub_frame = thread->last_frame();
1674   assert(stub_frame.is_runtime_frame() || exception_blob()->contains(stub_frame.pc()), "sanity check");
1675   frame caller_frame = stub_frame.sender(&reg_map);
1676   return caller_frame.is_deoptimized_frame();
1677 }
1678 
1679 
1680 const TypeFunc *OptoRuntime::register_finalizer_Type() {
1681   // create input type (domain)
1682   const Type **fields = TypeTuple::fields(1);
1683   fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL;  // oop;          Receiver
1684   // // The JavaThread* is passed to each routine as the last argument
1685   // fields[TypeFunc::Parms+1] = TypeRawPtr::NOTNULL;  // JavaThread *; Executing thread
1686   const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+1,fields);
1687 
1688   // create result type (range)
1689   fields = TypeTuple::fields(0);
1690 
1691   const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0,fields);
1692 
1693   return TypeFunc::make(domain,range);
1694 }
1695 
1696 #if INCLUDE_JFR
1697 const TypeFunc *OptoRuntime::class_id_load_barrier_Type() {
1698   // create input type (domain)
1699   const Type **fields = TypeTuple::fields(1);
1700   fields[TypeFunc::Parms+0] = TypeInstPtr::KLASS;
1701   const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms + 1, fields);
1702 
1703   // create result type (range)
1704   fields = TypeTuple::fields(0);
1705 
1706   const TypeTuple *range = TypeTuple::make(TypeFunc::Parms + 0, fields);
1707 
1708   return TypeFunc::make(domain,range);
1709 }
1710 #endif
1711 
1712 //-----------------------------------------------------------------------------
1713 // Dtrace support.  entry and exit probes have the same signature
1714 const TypeFunc *OptoRuntime::dtrace_method_entry_exit_Type() {
1715   // create input type (domain)
1716   const Type **fields = TypeTuple::fields(2);
1717   fields[TypeFunc::Parms+0] = TypeRawPtr::BOTTOM; // Thread-local storage
1718   fields[TypeFunc::Parms+1] = TypeMetadataPtr::BOTTOM;  // Method*;    Method we are entering
1719   const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+2,fields);
1720 
1721   // create result type (range)
1722   fields = TypeTuple::fields(0);
1723 
1724   const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0,fields);
1725 
1726   return TypeFunc::make(domain,range);
1727 }
1728 
1729 const TypeFunc *OptoRuntime::dtrace_object_alloc_Type() {
1730   // create input type (domain)
1731   const Type **fields = TypeTuple::fields(2);
1732   fields[TypeFunc::Parms+0] = TypeRawPtr::BOTTOM; // Thread-local storage
1733   fields[TypeFunc::Parms+1] = TypeInstPtr::NOTNULL;  // oop;    newly allocated object
1734 
1735   const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+2,fields);
1736 
1737   // create result type (range)
1738   fields = TypeTuple::fields(0);
1739 
1740   const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0,fields);
1741 
1742   return TypeFunc::make(domain,range);
1743 }
1744 
1745 
1746 JRT_ENTRY_NO_ASYNC(void, OptoRuntime::register_finalizer(oopDesc* obj, JavaThread* current))
1747   assert(oopDesc::is_oop(obj), "must be a valid oop");
1748   assert(obj->klass()->has_finalizer(), "shouldn't be here otherwise");
1749   InstanceKlass::register_finalizer(instanceOop(obj), CHECK);
1750 JRT_END
1751 
1752 //-----------------------------------------------------------------------------
1753 
1754 NamedCounter * volatile OptoRuntime::_named_counters = nullptr;
1755 
1756 //
1757 // dump the collected NamedCounters.
1758 //
1759 void OptoRuntime::print_named_counters() {
1760   int total_lock_count = 0;
1761   int eliminated_lock_count = 0;
1762 

1845 static void trace_exception(outputStream* st, oop exception_oop, address exception_pc, const char* msg) {
1846   trace_exception_counter++;
1847   stringStream tempst;
1848 
1849   tempst.print("%d [Exception (%s): ", trace_exception_counter, msg);
1850   exception_oop->print_value_on(&tempst);
1851   tempst.print(" in ");
1852   CodeBlob* blob = CodeCache::find_blob(exception_pc);
1853   if (blob->is_nmethod()) {
1854     blob->as_nmethod()->method()->print_value_on(&tempst);
1855   } else if (blob->is_runtime_stub()) {
1856     tempst.print("<runtime-stub>");
1857   } else {
1858     tempst.print("<unknown>");
1859   }
1860   tempst.print(" at " INTPTR_FORMAT,  p2i(exception_pc));
1861   tempst.print("]");
1862 
1863   st->print_raw_cr(tempst.freeze());
1864 }









































































































  27 #include "classfile/vmSymbols.hpp"
  28 #include "code/codeCache.hpp"
  29 #include "code/compiledIC.hpp"
  30 #include "code/nmethod.hpp"
  31 #include "code/pcDesc.hpp"
  32 #include "code/scopeDesc.hpp"
  33 #include "code/vtableStubs.hpp"
  34 #include "compiler/compileBroker.hpp"
  35 #include "compiler/oopMap.hpp"
  36 #include "gc/g1/g1HeapRegion.hpp"
  37 #include "gc/shared/barrierSet.hpp"
  38 #include "gc/shared/collectedHeap.hpp"
  39 #include "gc/shared/gcLocker.hpp"
  40 #include "interpreter/bytecode.hpp"
  41 #include "interpreter/interpreter.hpp"
  42 #include "interpreter/linkResolver.hpp"
  43 #include "logging/log.hpp"
  44 #include "logging/logStream.hpp"
  45 #include "memory/oopFactory.hpp"
  46 #include "memory/resourceArea.hpp"
  47 #include "oops/flatArrayKlass.hpp"
  48 #include "oops/flatArrayOop.inline.hpp"
  49 #include "oops/objArrayKlass.hpp"
  50 #include "oops/klass.inline.hpp"
  51 #include "oops/oop.inline.hpp"
  52 #include "oops/typeArrayOop.inline.hpp"
  53 #include "opto/ad.hpp"
  54 #include "opto/addnode.hpp"
  55 #include "opto/callnode.hpp"
  56 #include "opto/cfgnode.hpp"
  57 #include "opto/graphKit.hpp"
  58 #include "opto/machnode.hpp"
  59 #include "opto/matcher.hpp"
  60 #include "opto/memnode.hpp"
  61 #include "opto/mulnode.hpp"
  62 #include "opto/output.hpp"
  63 #include "opto/runtime.hpp"
  64 #include "opto/subnode.hpp"
  65 #include "prims/jvmtiExport.hpp"
  66 #include "runtime/atomic.hpp"
  67 #include "runtime/frame.inline.hpp"
  68 #include "runtime/handles.inline.hpp"

  89 //
  90 // At command line specify the parameters: -XX:+FullGCALot -XX:FullGCALotStart=100000000
  91 
  92 
  93 
  94 
  95 // Compiled code entry points
  96 address OptoRuntime::_new_instance_Java                           = nullptr;
  97 address OptoRuntime::_new_array_Java                              = nullptr;
  98 address OptoRuntime::_new_array_nozero_Java                       = nullptr;
  99 address OptoRuntime::_multianewarray2_Java                        = nullptr;
 100 address OptoRuntime::_multianewarray3_Java                        = nullptr;
 101 address OptoRuntime::_multianewarray4_Java                        = nullptr;
 102 address OptoRuntime::_multianewarray5_Java                        = nullptr;
 103 address OptoRuntime::_multianewarrayN_Java                        = nullptr;
 104 address OptoRuntime::_vtable_must_compile_Java                    = nullptr;
 105 address OptoRuntime::_complete_monitor_locking_Java               = nullptr;
 106 address OptoRuntime::_monitor_notify_Java                         = nullptr;
 107 address OptoRuntime::_monitor_notifyAll_Java                      = nullptr;
 108 address OptoRuntime::_rethrow_Java                                = nullptr;

 109 address OptoRuntime::_slow_arraycopy_Java                         = nullptr;
 110 address OptoRuntime::_register_finalizer_Java                     = nullptr;
 111 address OptoRuntime::_load_unknown_inline                         = nullptr;
 112 #if INCLUDE_JVMTI
 113 address OptoRuntime::_notify_jvmti_vthread_start                  = nullptr;
 114 address OptoRuntime::_notify_jvmti_vthread_end                    = nullptr;
 115 address OptoRuntime::_notify_jvmti_vthread_mount                  = nullptr;
 116 address OptoRuntime::_notify_jvmti_vthread_unmount                = nullptr;
 117 #endif
 118 
 119 ExceptionBlob* OptoRuntime::_exception_blob;
 120 
 121 // This should be called in an assertion at the start of OptoRuntime routines
 122 // which are entered from compiled code (all of them)
 123 #ifdef ASSERT
 124 static bool check_compiled_frame(JavaThread* thread) {
 125   assert(thread->last_frame().is_runtime_frame(), "cannot call runtime directly from compiled code");
 126   RegisterMap map(thread,
 127                   RegisterMap::UpdateMap::skip,
 128                   RegisterMap::ProcessFrames::include,
 129                   RegisterMap::WalkContinuation::skip);
 130   frame caller = thread->last_frame().sender(&map);
 131   assert(caller.is_compiled_frame(), "not being called from compiled like code");

 147   //   variable/name                       type-function-gen              , runtime method                  ,fncy_jp, tls,retpc
 148   // -------------------------------------------------------------------------------------------------------------------------------
 149   gen(env, _new_instance_Java              , new_instance_Type            , new_instance_C                  ,    0 , true, false);
 150   gen(env, _new_array_Java                 , new_array_Type               , new_array_C                     ,    0 , true, false);
 151   gen(env, _new_array_nozero_Java          , new_array_Type               , new_array_nozero_C              ,    0 , true, false);
 152   gen(env, _multianewarray2_Java           , multianewarray2_Type         , multianewarray2_C               ,    0 , true, false);
 153   gen(env, _multianewarray3_Java           , multianewarray3_Type         , multianewarray3_C               ,    0 , true, false);
 154   gen(env, _multianewarray4_Java           , multianewarray4_Type         , multianewarray4_C               ,    0 , true, false);
 155   gen(env, _multianewarray5_Java           , multianewarray5_Type         , multianewarray5_C               ,    0 , true, false);
 156   gen(env, _multianewarrayN_Java           , multianewarrayN_Type         , multianewarrayN_C               ,    0 , true, false);
 157 #if INCLUDE_JVMTI
 158   gen(env, _notify_jvmti_vthread_start     , notify_jvmti_vthread_Type    , SharedRuntime::notify_jvmti_vthread_start, 0, true, false);
 159   gen(env, _notify_jvmti_vthread_end       , notify_jvmti_vthread_Type    , SharedRuntime::notify_jvmti_vthread_end,   0, true, false);
 160   gen(env, _notify_jvmti_vthread_mount     , notify_jvmti_vthread_Type    , SharedRuntime::notify_jvmti_vthread_mount, 0, true, false);
 161   gen(env, _notify_jvmti_vthread_unmount   , notify_jvmti_vthread_Type    , SharedRuntime::notify_jvmti_vthread_unmount, 0, true, false);
 162 #endif
 163   gen(env, _complete_monitor_locking_Java  , complete_monitor_enter_Type  , SharedRuntime::complete_monitor_locking_C, 0, false, false);
 164   gen(env, _monitor_notify_Java            , monitor_notify_Type          , monitor_notify_C                ,    0 , false, false);
 165   gen(env, _monitor_notifyAll_Java         , monitor_notify_Type          , monitor_notifyAll_C             ,    0 , false, false);
 166   gen(env, _rethrow_Java                   , rethrow_Type                 , rethrow_C                       ,    2 , true , true );

 167   gen(env, _slow_arraycopy_Java            , slow_arraycopy_Type          , SharedRuntime::slow_arraycopy_C ,    0 , false, false);
 168   gen(env, _register_finalizer_Java        , register_finalizer_Type      , register_finalizer              ,    0 , false, false);
 169   gen(env, _load_unknown_inline            , load_unknown_inline_type     , load_unknown_inline             ,    0 , true,  false);
 170 
 171   return true;
 172 }
 173 
 174 #undef gen
 175 
 176 
 177 // Helper method to do generation of RunTimeStub's
 178 address OptoRuntime::generate_stub(ciEnv* env,
 179                                    TypeFunc_generator gen, address C_function,
 180                                    const char *name, int is_fancy_jump,
 181                                    bool pass_tls,
 182                                    bool return_pc) {
 183 
 184   // Matching the default directive, we currently have no method to match.
 185   DirectiveSet* directive = DirectivesStack::getDefaultDirective(CompileBroker::compiler(CompLevel_full_optimization));
 186   ResourceMark rm;
 187   Compile C(env, gen, C_function, name, is_fancy_jump, pass_tls, return_pc, directive);
 188   DirectivesStack::release(directive);
 189   return  C.stub_entry_point();

 195   RuntimeStub* rs =(RuntimeStub *)cb;
 196   assert(rs != nullptr && rs->is_runtime_stub(), "not a runtime stub");
 197   return rs->name();
 198 #else
 199   // Fast implementation for product mode (maybe it should be inlined too)
 200   return "runtime stub";
 201 #endif
 202 }
 203 
 204 
 205 //=============================================================================
 206 // Opto compiler runtime routines
 207 //=============================================================================
 208 
 209 
 210 //=============================allocation======================================
 211 // We failed the fast-path allocation.  Now we need to do a scavenge or GC
 212 // and try allocation again.
 213 
 214 // object allocation
 215 JRT_BLOCK_ENTRY(void, OptoRuntime::new_instance_C(Klass* klass, bool is_larval, JavaThread* current))
 216   JRT_BLOCK;
 217 #ifndef PRODUCT
 218   SharedRuntime::_new_instance_ctr++;         // new instance requires GC
 219 #endif
 220   assert(check_compiled_frame(current), "incorrect caller");
 221 
 222   // These checks are cheap to make and support reflective allocation.
 223   int lh = klass->layout_helper();
 224   if (Klass::layout_helper_needs_slow_path(lh) || !InstanceKlass::cast(klass)->is_initialized()) {
 225     Handle holder(current, klass->klass_holder()); // keep the klass alive
 226     klass->check_valid_for_instantiation(false, THREAD);
 227     if (!HAS_PENDING_EXCEPTION) {
 228       InstanceKlass::cast(klass)->initialize(THREAD);
 229     }
 230   }
 231 
 232   if (!HAS_PENDING_EXCEPTION) {
 233     // Scavenge and allocate an instance.
 234     Handle holder(current, klass->klass_holder()); // keep the klass alive
 235     instanceOop result = InstanceKlass::cast(klass)->allocate_instance(THREAD);
 236     if (is_larval) {
 237       // Check if this is a larval buffer allocation
 238       result->set_mark(result->mark().enter_larval_state());
 239     }
 240     current->set_vm_result(result);
 241 
 242     // Pass oops back through thread local storage.  Our apparent type to Java
 243     // is that we return an oop, but we can block on exit from this routine and
 244     // a GC can trash the oop in C's return register.  The generated stub will
 245     // fetch the oop from TLS after any possible GC.
 246   }
 247 
 248   deoptimize_caller_frame(current, HAS_PENDING_EXCEPTION);
 249   JRT_BLOCK_END;
 250 
 251   // inform GC that we won't do card marks for initializing writes.
 252   SharedRuntime::on_slowpath_allocation_exit(current);
 253 JRT_END
 254 
 255 
 256 // array allocation
 257 JRT_BLOCK_ENTRY(void, OptoRuntime::new_array_C(Klass* array_type, int len, JavaThread* current))
 258   JRT_BLOCK;
 259 #ifndef PRODUCT
 260   SharedRuntime::_new_array_ctr++;            // new array requires GC
 261 #endif
 262   assert(check_compiled_frame(current), "incorrect caller");
 263 
 264   // Scavenge and allocate an instance.
 265   oop result;
 266 
 267   if (array_type->is_flatArray_klass()) {
 268     Klass* elem_type = FlatArrayKlass::cast(array_type)->element_klass();
 269     result = oopFactory::new_valueArray(elem_type, len, THREAD);
 270   } else if (array_type->is_typeArray_klass()) {
 271     // The oopFactory likes to work with the element type.
 272     // (We could bypass the oopFactory, since it doesn't add much value.)
 273     BasicType elem_type = TypeArrayKlass::cast(array_type)->element_type();
 274     result = oopFactory::new_typeArray(elem_type, len, THREAD);
 275   } else {



 276     Handle holder(current, array_type->klass_holder()); // keep the array klass alive
 277     result = ObjArrayKlass::cast(array_type)->allocate(len, THREAD);

 278   }
 279 
 280   // Pass oops back through thread local storage.  Our apparent type to Java
 281   // is that we return an oop, but we can block on exit from this routine and
 282   // a GC can trash the oop in C's return register.  The generated stub will
 283   // fetch the oop from TLS after any possible GC.
 284   deoptimize_caller_frame(current, HAS_PENDING_EXCEPTION);
 285   current->set_vm_result(result);
 286   JRT_BLOCK_END;
 287 
 288   // inform GC that we won't do card marks for initializing writes.
 289   SharedRuntime::on_slowpath_allocation_exit(current);
 290 JRT_END
 291 
 292 // array allocation without zeroing
 293 JRT_BLOCK_ENTRY(void, OptoRuntime::new_array_nozero_C(Klass* array_type, int len, JavaThread* current))
 294   JRT_BLOCK;
 295 #ifndef PRODUCT
 296   SharedRuntime::_new_array_ctr++;            // new array requires GC
 297 #endif

 454 JRT_BLOCK_ENTRY(void, OptoRuntime::monitor_notifyAll_C(oopDesc* obj, JavaThread* current))
 455 
 456   if (!SafepointSynchronize::is_synchronizing() ) {
 457     if (ObjectSynchronizer::quick_notify(obj, current, true)) {
 458       return;
 459     }
 460   }
 461 
 462   // This is the case the fast-path above isn't provisioned to handle.
 463   // The fast-path is designed to handle frequently arising cases in an efficient manner.
 464   // (The fast-path is just a degenerate variant of the slow-path).
 465   // Perform the dreaded state transition and pass control into the slow-path.
 466   JRT_BLOCK;
 467   Handle h_obj(current, obj);
 468   ObjectSynchronizer::notifyall(h_obj, CHECK);
 469   JRT_BLOCK_END;
 470 JRT_END
 471 
 472 const TypeFunc *OptoRuntime::new_instance_Type() {
 473   // create input type (domain)
 474   const Type **fields = TypeTuple::fields(2);
 475   fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; // Klass to be allocated
 476   fields[TypeFunc::Parms+1] = TypeInt::BOOL;        // is_larval
 477   const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+2, fields);
 478 
 479   // create result type (range)
 480   fields = TypeTuple::fields(1);
 481   fields[TypeFunc::Parms+0] = TypeRawPtr::NOTNULL; // Returned oop
 482 
 483   const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+1, fields);
 484 
 485   return TypeFunc::make(domain, range);
 486 }
 487 
 488 #if INCLUDE_JVMTI
 489 const TypeFunc *OptoRuntime::notify_jvmti_vthread_Type() {
 490   // create input type (domain)
 491   const Type **fields = TypeTuple::fields(2);
 492   fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; // VirtualThread oop
 493   fields[TypeFunc::Parms+1] = TypeInt::BOOL;        // jboolean
 494   const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+2,fields);
 495 
 496   // no result type needed
 497   fields = TypeTuple::fields(1);

 591   fields = TypeTuple::fields(0);
 592   const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0, fields);
 593 
 594   return TypeFunc::make(domain, range);
 595 }
 596 
 597 //-----------------------------------------------------------------------------
 598 // Monitor Handling
 599 const TypeFunc *OptoRuntime::complete_monitor_enter_Type() {
 600   // create input type (domain)
 601   const Type **fields = TypeTuple::fields(2);
 602   fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL;  // Object to be Locked
 603   fields[TypeFunc::Parms+1] = TypeRawPtr::BOTTOM;   // Address of stack location for lock
 604   const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+2,fields);
 605 
 606   // create result type (range)
 607   fields = TypeTuple::fields(0);
 608 
 609   const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0,fields);
 610 
 611   return TypeFunc::make(domain, range);
 612 }
 613 
 614 
 615 //-----------------------------------------------------------------------------
 616 const TypeFunc *OptoRuntime::complete_monitor_exit_Type() {
 617   // create input type (domain)
 618   const Type **fields = TypeTuple::fields(3);
 619   fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL;  // Object to be Locked
 620   fields[TypeFunc::Parms+1] = TypeRawPtr::BOTTOM;    // Address of stack location for lock - BasicLock
 621   fields[TypeFunc::Parms+2] = TypeRawPtr::BOTTOM;    // Thread pointer (Self)
 622   const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+3, fields);
 623 
 624   // create result type (range)
 625   fields = TypeTuple::fields(0);
 626 
 627   const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0, fields);
 628 
 629   return TypeFunc::make(domain, range);
 630 }
 631 

1679   frame stub_frame = thread->last_frame();
1680   assert(stub_frame.is_runtime_frame() || exception_blob()->contains(stub_frame.pc()), "sanity check");
1681   frame caller_frame = stub_frame.sender(&reg_map);
1682   return caller_frame.is_deoptimized_frame();
1683 }
1684 
1685 
1686 const TypeFunc *OptoRuntime::register_finalizer_Type() {
1687   // create input type (domain)
1688   const Type **fields = TypeTuple::fields(1);
1689   fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL;  // oop;          Receiver
1690   // // The JavaThread* is passed to each routine as the last argument
1691   // fields[TypeFunc::Parms+1] = TypeRawPtr::NOTNULL;  // JavaThread *; Executing thread
1692   const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+1,fields);
1693 
1694   // create result type (range)
1695   fields = TypeTuple::fields(0);
1696 
1697   const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0,fields);
1698 
1699   return TypeFunc::make(domain, range);
1700 }
1701 
1702 #if INCLUDE_JFR
1703 const TypeFunc *OptoRuntime::class_id_load_barrier_Type() {
1704   // create input type (domain)
1705   const Type **fields = TypeTuple::fields(1);
1706   fields[TypeFunc::Parms+0] = TypeInstPtr::KLASS;
1707   const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms + 1, fields);
1708 
1709   // create result type (range)
1710   fields = TypeTuple::fields(0);
1711 
1712   const TypeTuple *range = TypeTuple::make(TypeFunc::Parms + 0, fields);
1713 
1714   return TypeFunc::make(domain,range);
1715 }
1716 #endif
1717 
1718 //-----------------------------------------------------------------------------
1719 // Dtrace support.  entry and exit probes have the same signature
1720 const TypeFunc *OptoRuntime::dtrace_method_entry_exit_Type() {
1721   // create input type (domain)
1722   const Type **fields = TypeTuple::fields(2);
1723   fields[TypeFunc::Parms+0] = TypeRawPtr::BOTTOM; // Thread-local storage
1724   fields[TypeFunc::Parms+1] = TypeMetadataPtr::BOTTOM;  // Method*;    Method we are entering
1725   const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+2,fields);
1726 
1727   // create result type (range)
1728   fields = TypeTuple::fields(0);
1729 
1730   const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0,fields);
1731 
1732   return TypeFunc::make(domain, range);
1733 }
1734 
1735 const TypeFunc *OptoRuntime::dtrace_object_alloc_Type() {
1736   // create input type (domain)
1737   const Type **fields = TypeTuple::fields(2);
1738   fields[TypeFunc::Parms+0] = TypeRawPtr::BOTTOM; // Thread-local storage
1739   fields[TypeFunc::Parms+1] = TypeInstPtr::NOTNULL;  // oop;    newly allocated object
1740 
1741   const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+2,fields);
1742 
1743   // create result type (range)
1744   fields = TypeTuple::fields(0);
1745 
1746   const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0,fields);
1747 
1748   return TypeFunc::make(domain, range);
1749 }
1750 
1751 
1752 JRT_ENTRY_NO_ASYNC(void, OptoRuntime::register_finalizer(oopDesc* obj, JavaThread* current))
1753   assert(oopDesc::is_oop(obj), "must be a valid oop");
1754   assert(obj->klass()->has_finalizer(), "shouldn't be here otherwise");
1755   InstanceKlass::register_finalizer(instanceOop(obj), CHECK);
1756 JRT_END
1757 
1758 //-----------------------------------------------------------------------------
1759 
1760 NamedCounter * volatile OptoRuntime::_named_counters = nullptr;
1761 
1762 //
1763 // dump the collected NamedCounters.
1764 //
1765 void OptoRuntime::print_named_counters() {
1766   int total_lock_count = 0;
1767   int eliminated_lock_count = 0;
1768 

1851 static void trace_exception(outputStream* st, oop exception_oop, address exception_pc, const char* msg) {
1852   trace_exception_counter++;
1853   stringStream tempst;
1854 
1855   tempst.print("%d [Exception (%s): ", trace_exception_counter, msg);
1856   exception_oop->print_value_on(&tempst);
1857   tempst.print(" in ");
1858   CodeBlob* blob = CodeCache::find_blob(exception_pc);
1859   if (blob->is_nmethod()) {
1860     blob->as_nmethod()->method()->print_value_on(&tempst);
1861   } else if (blob->is_runtime_stub()) {
1862     tempst.print("<runtime-stub>");
1863   } else {
1864     tempst.print("<unknown>");
1865   }
1866   tempst.print(" at " INTPTR_FORMAT,  p2i(exception_pc));
1867   tempst.print("]");
1868 
1869   st->print_raw_cr(tempst.freeze());
1870 }
1871 
1872 const TypeFunc *OptoRuntime::store_inline_type_fields_Type() {
1873   // create input type (domain)
1874   uint total = SharedRuntime::java_return_convention_max_int + SharedRuntime::java_return_convention_max_float*2;
1875   const Type **fields = TypeTuple::fields(total);
1876   // We don't know the number of returned values and their
1877   // types. Assume all registers available to the return convention
1878   // are used.
1879   fields[TypeFunc::Parms] = TypePtr::BOTTOM;
1880   uint i = 1;
1881   for (; i < SharedRuntime::java_return_convention_max_int; i++) {
1882     fields[TypeFunc::Parms+i] = TypeInt::INT;
1883   }
1884   for (; i < total; i+=2) {
1885     fields[TypeFunc::Parms+i] = Type::DOUBLE;
1886     fields[TypeFunc::Parms+i+1] = Type::HALF;
1887   }
1888   const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms + total, fields);
1889 
1890   // create result type (range)
1891   fields = TypeTuple::fields(1);
1892   fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL;
1893 
1894   const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+1,fields);
1895 
1896   return TypeFunc::make(domain, range);
1897 }
1898 
1899 const TypeFunc *OptoRuntime::pack_inline_type_Type() {
1900   // create input type (domain)
1901   uint total = 1 + SharedRuntime::java_return_convention_max_int + SharedRuntime::java_return_convention_max_float*2;
1902   const Type **fields = TypeTuple::fields(total);
1903   // We don't know the number of returned values and their
1904   // types. Assume all registers available to the return convention
1905   // are used.
1906   fields[TypeFunc::Parms] = TypeRawPtr::BOTTOM;
1907   fields[TypeFunc::Parms+1] = TypeRawPtr::BOTTOM;
1908   uint i = 2;
1909   for (; i < SharedRuntime::java_return_convention_max_int+1; i++) {
1910     fields[TypeFunc::Parms+i] = TypeInt::INT;
1911   }
1912   for (; i < total; i+=2) {
1913     fields[TypeFunc::Parms+i] = Type::DOUBLE;
1914     fields[TypeFunc::Parms+i+1] = Type::HALF;
1915   }
1916   const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms + total, fields);
1917 
1918   // create result type (range)
1919   fields = TypeTuple::fields(1);
1920   fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL;
1921 
1922   const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+1,fields);
1923 
1924   return TypeFunc::make(domain, range);
1925 }
1926 
1927 JRT_BLOCK_ENTRY(void, OptoRuntime::load_unknown_inline(flatArrayOopDesc* array, int index, JavaThread* current))
1928   JRT_BLOCK;
1929   flatArrayHandle vah(current, array);
1930   oop buffer = flatArrayOopDesc::value_alloc_copy_from_index(vah, index, THREAD);
1931   deoptimize_caller_frame(current, HAS_PENDING_EXCEPTION);
1932   current->set_vm_result(buffer);
1933   JRT_BLOCK_END;
1934 JRT_END
1935 
1936 const TypeFunc* OptoRuntime::load_unknown_inline_type() {
1937   // create input type (domain)
1938   const Type** fields = TypeTuple::fields(2);
1939   fields[TypeFunc::Parms] = TypeOopPtr::NOTNULL;
1940   fields[TypeFunc::Parms+1] = TypeInt::POS;
1941 
1942   const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms+2, fields);
1943 
1944   // create result type (range)
1945   fields = TypeTuple::fields(1);
1946   fields[TypeFunc::Parms] = TypeInstPtr::NOTNULL;
1947 
1948   const TypeTuple* range = TypeTuple::make(TypeFunc::Parms+1, fields);
1949 
1950   return TypeFunc::make(domain, range);
1951 }
1952 
1953 JRT_LEAF(void, OptoRuntime::store_unknown_inline(instanceOopDesc* buffer, flatArrayOopDesc* array, int index))
1954 {
1955   assert(buffer != nullptr, "can't store null into flat array");
1956   array->value_copy_to_index(buffer, index);
1957 }
1958 JRT_END
1959 
1960 const TypeFunc* OptoRuntime::store_unknown_inline_type() {
1961   // create input type (domain)
1962   const Type** fields = TypeTuple::fields(3);
1963   fields[TypeFunc::Parms] = TypeInstPtr::NOTNULL;
1964   fields[TypeFunc::Parms+1] = TypeOopPtr::NOTNULL;
1965   fields[TypeFunc::Parms+2] = TypeInt::POS;
1966 
1967   const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms+3, fields);
1968 
1969   // create result type (range)
1970   fields = TypeTuple::fields(0);
1971   const TypeTuple* range = TypeTuple::make(TypeFunc::Parms, fields);
1972 
1973   return TypeFunc::make(domain, range);
1974 }
< prev index next >