< prev index next >

src/hotspot/share/opto/runtime.cpp

Print this page

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


  48 #include "oops/objArrayKlass.hpp"
  49 #include "oops/klass.inline.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/output.hpp"
  62 #include "opto/runtime.hpp"
  63 #include "opto/subnode.hpp"
  64 #include "prims/jvmtiExport.hpp"
  65 #include "runtime/atomic.hpp"
  66 #include "runtime/frame.inline.hpp"
  67 #include "runtime/handles.inline.hpp"

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

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

 146   //   variable/name                       type-function-gen              , runtime method                  ,fncy_jp, tls,retpc
 147   // -------------------------------------------------------------------------------------------------------------------------------
 148   gen(env, _new_instance_Java              , new_instance_Type            , new_instance_C                  ,    0 , true, false);
 149   gen(env, _new_array_Java                 , new_array_Type               , new_array_C                     ,    0 , true, false);
 150   gen(env, _new_array_nozero_Java          , new_array_Type               , new_array_nozero_C              ,    0 , true, false);
 151   gen(env, _multianewarray2_Java           , multianewarray2_Type         , multianewarray2_C               ,    0 , true, false);
 152   gen(env, _multianewarray3_Java           , multianewarray3_Type         , multianewarray3_C               ,    0 , true, false);
 153   gen(env, _multianewarray4_Java           , multianewarray4_Type         , multianewarray4_C               ,    0 , true, false);
 154   gen(env, _multianewarray5_Java           , multianewarray5_Type         , multianewarray5_C               ,    0 , true, false);
 155   gen(env, _multianewarrayN_Java           , multianewarrayN_Type         , multianewarrayN_C               ,    0 , true, false);
 156 #if INCLUDE_JVMTI
 157   gen(env, _notify_jvmti_vthread_start     , notify_jvmti_vthread_Type    , SharedRuntime::notify_jvmti_vthread_start, 0, true, false);
 158   gen(env, _notify_jvmti_vthread_end       , notify_jvmti_vthread_Type    , SharedRuntime::notify_jvmti_vthread_end,   0, true, false);
 159   gen(env, _notify_jvmti_vthread_mount     , notify_jvmti_vthread_Type    , SharedRuntime::notify_jvmti_vthread_mount, 0, true, false);
 160   gen(env, _notify_jvmti_vthread_unmount   , notify_jvmti_vthread_Type    , SharedRuntime::notify_jvmti_vthread_unmount, 0, true, false);
 161 #endif
 162   gen(env, _complete_monitor_locking_Java  , complete_monitor_enter_Type  , SharedRuntime::complete_monitor_locking_C, 0, false, false);
 163   gen(env, _monitor_notify_Java            , monitor_notify_Type          , monitor_notify_C                ,    0 , false, false);
 164   gen(env, _monitor_notifyAll_Java         , monitor_notify_Type          , monitor_notifyAll_C             ,    0 , false, false);
 165   gen(env, _rethrow_Java                   , rethrow_Type                 , rethrow_C                       ,    2 , true , true );
 166 
 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 
 170   return true;
 171 }
 172 
 173 #undef gen
 174 
 175 
 176 // Helper method to do generation of RunTimeStub's
 177 address OptoRuntime::generate_stub(ciEnv* env,
 178                                    TypeFunc_generator gen, address C_function,
 179                                    const char *name, int is_fancy_jump,
 180                                    bool pass_tls,
 181                                    bool return_pc) {
 182 
 183   // Matching the default directive, we currently have no method to match.
 184   DirectiveSet* directive = DirectivesStack::getDefaultDirective(CompileBroker::compiler(CompLevel_full_optimization));
 185   ResourceMark rm;
 186   Compile C(env, gen, C_function, name, is_fancy_jump, pass_tls, return_pc, directive);
 187   DirectivesStack::release(directive);
 188   return  C.stub_entry_point();

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




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



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

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

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

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

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

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









































































































  28 #include "code/codeCache.hpp"
  29 #include "code/compiledMethod.inline.hpp"
  30 #include "code/compiledIC.hpp"
  31 #include "code/nmethod.hpp"
  32 #include "code/pcDesc.hpp"
  33 #include "code/scopeDesc.hpp"
  34 #include "code/vtableStubs.hpp"
  35 #include "compiler/compileBroker.hpp"
  36 #include "compiler/oopMap.hpp"
  37 #include "gc/g1/heapRegion.hpp"
  38 #include "gc/shared/barrierSet.hpp"
  39 #include "gc/shared/collectedHeap.hpp"
  40 #include "gc/shared/gcLocker.hpp"
  41 #include "interpreter/bytecode.hpp"
  42 #include "interpreter/interpreter.hpp"
  43 #include "interpreter/linkResolver.hpp"
  44 #include "logging/log.hpp"
  45 #include "logging/logStream.hpp"
  46 #include "memory/oopFactory.hpp"
  47 #include "memory/resourceArea.hpp"
  48 #include "oops/flatArrayKlass.hpp"
  49 #include "oops/flatArrayOop.inline.hpp"
  50 #include "oops/objArrayKlass.hpp"
  51 #include "oops/klass.inline.hpp"
  52 #include "oops/oop.inline.hpp"
  53 #include "oops/typeArrayOop.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/output.hpp"
  64 #include "opto/runtime.hpp"
  65 #include "opto/subnode.hpp"
  66 #include "prims/jvmtiExport.hpp"
  67 #include "runtime/atomic.hpp"
  68 #include "runtime/frame.inline.hpp"
  69 #include "runtime/handles.inline.hpp"

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

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

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

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

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



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

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

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

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

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

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