< 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"

  92 
  93 
  94 
  95 // Compiled code entry points
  96 address OptoRuntime::_new_instance_Java                           = NULL;
  97 address OptoRuntime::_new_array_Java                              = NULL;
  98 address OptoRuntime::_new_array_nozero_Java                       = NULL;
  99 address OptoRuntime::_multianewarray2_Java                        = NULL;
 100 address OptoRuntime::_multianewarray3_Java                        = NULL;
 101 address OptoRuntime::_multianewarray4_Java                        = NULL;
 102 address OptoRuntime::_multianewarray5_Java                        = NULL;
 103 address OptoRuntime::_multianewarrayN_Java                        = NULL;
 104 address OptoRuntime::_vtable_must_compile_Java                    = NULL;
 105 address OptoRuntime::_complete_monitor_locking_Java               = NULL;
 106 address OptoRuntime::_monitor_notify_Java                         = NULL;
 107 address OptoRuntime::_monitor_notifyAll_Java                      = NULL;
 108 address OptoRuntime::_rethrow_Java                                = NULL;
 109 
 110 address OptoRuntime::_slow_arraycopy_Java                         = NULL;
 111 address OptoRuntime::_register_finalizer_Java                     = NULL;

 112 
 113 ExceptionBlob* OptoRuntime::_exception_blob;
 114 
 115 // This should be called in an assertion at the start of OptoRuntime routines
 116 // which are entered from compiled code (all of them)
 117 #ifdef ASSERT
 118 static bool check_compiled_frame(JavaThread* thread) {
 119   assert(thread->last_frame().is_runtime_frame(), "cannot call runtime directly from compiled code");
 120   RegisterMap map(thread,
 121                   RegisterMap::UpdateMap::skip,
 122                   RegisterMap::ProcessFrames::include,
 123                   RegisterMap::WalkContinuation::skip);
 124   frame caller = thread->last_frame().sender(&map);
 125   assert(caller.is_compiled_frame(), "not being called from compiled like code");
 126   return true;
 127 }
 128 #endif // ASSERT
 129 
 130 
 131 #define gen(env, var, type_func_gen, c_func, fancy_jump, pass_tls, return_pc) \

 135 bool OptoRuntime::generate(ciEnv* env) {
 136 
 137   generate_exception_blob();
 138 
 139   // Note: tls: Means fetching the return oop out of the thread-local storage
 140   //
 141   //   variable/name                       type-function-gen              , runtime method                  ,fncy_jp, tls,retpc
 142   // -------------------------------------------------------------------------------------------------------------------------------
 143   gen(env, _new_instance_Java              , new_instance_Type            , new_instance_C                  ,    0 , true, false);
 144   gen(env, _new_array_Java                 , new_array_Type               , new_array_C                     ,    0 , true, false);
 145   gen(env, _new_array_nozero_Java          , new_array_Type               , new_array_nozero_C              ,    0 , true, false);
 146   gen(env, _multianewarray2_Java           , multianewarray2_Type         , multianewarray2_C               ,    0 , true, false);
 147   gen(env, _multianewarray3_Java           , multianewarray3_Type         , multianewarray3_C               ,    0 , true, false);
 148   gen(env, _multianewarray4_Java           , multianewarray4_Type         , multianewarray4_C               ,    0 , true, false);
 149   gen(env, _multianewarray5_Java           , multianewarray5_Type         , multianewarray5_C               ,    0 , true, false);
 150   gen(env, _multianewarrayN_Java           , multianewarrayN_Type         , multianewarrayN_C               ,    0 , true, false);
 151   gen(env, _complete_monitor_locking_Java  , complete_monitor_enter_Type  , SharedRuntime::complete_monitor_locking_C, 0, false, false);
 152   gen(env, _monitor_notify_Java            , monitor_notify_Type          , monitor_notify_C                ,    0 , false, false);
 153   gen(env, _monitor_notifyAll_Java         , monitor_notify_Type          , monitor_notifyAll_C             ,    0 , false, false);
 154   gen(env, _rethrow_Java                   , rethrow_Type                 , rethrow_C                       ,    2 , true , true );
 155 
 156   gen(env, _slow_arraycopy_Java            , slow_arraycopy_Type          , SharedRuntime::slow_arraycopy_C ,    0 , false, false);
 157   gen(env, _register_finalizer_Java        , register_finalizer_Type      , register_finalizer              ,    0 , false, false);

 158 
 159   return true;
 160 }
 161 
 162 #undef gen
 163 
 164 
 165 // Helper method to do generation of RunTimeStub's
 166 address OptoRuntime::generate_stub(ciEnv* env,
 167                                    TypeFunc_generator gen, address C_function,
 168                                    const char *name, int is_fancy_jump,
 169                                    bool pass_tls,
 170                                    bool return_pc) {
 171 
 172   // Matching the default directive, we currently have no method to match.
 173   DirectiveSet* directive = DirectivesStack::getDefaultDirective(CompileBroker::compiler(CompLevel_full_optimization));
 174   ResourceMark rm;
 175   Compile C(env, gen, C_function, name, is_fancy_jump, pass_tls, return_pc, directive);
 176   DirectivesStack::release(directive);
 177   return  C.stub_entry_point();

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




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



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

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

 459 
 460   // create result type (range)
 461   fields = TypeTuple::fields(1);
 462   fields[TypeFunc::Parms+0] = TypeRawPtr::NOTNULL; // Returned oop
 463 
 464   const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+1, fields);
 465 
 466   return TypeFunc::make(domain, range);
 467 }
 468 
 469 
 470 const TypeFunc *OptoRuntime::athrow_Type() {
 471   // create input type (domain)
 472   const Type **fields = TypeTuple::fields(1);
 473   fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; // Klass to be allocated
 474   const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+1, fields);
 475 
 476   // create result type (range)
 477   fields = TypeTuple::fields(0);
 478 

 556   fields = TypeTuple::fields(0);
 557   const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0, fields);
 558 
 559   return TypeFunc::make(domain, range);
 560 }
 561 
 562 //-----------------------------------------------------------------------------
 563 // Monitor Handling
 564 const TypeFunc *OptoRuntime::complete_monitor_enter_Type() {
 565   // create input type (domain)
 566   const Type **fields = TypeTuple::fields(2);
 567   fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL;  // Object to be Locked
 568   fields[TypeFunc::Parms+1] = TypeRawPtr::BOTTOM;   // Address of stack location for lock
 569   const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+2,fields);
 570 
 571   // create result type (range)
 572   fields = TypeTuple::fields(0);
 573 
 574   const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0,fields);
 575 
 576   return TypeFunc::make(domain,range);
 577 }
 578 
 579 
 580 //-----------------------------------------------------------------------------
 581 const TypeFunc *OptoRuntime::complete_monitor_exit_Type() {
 582   // create input type (domain)
 583   const Type **fields = TypeTuple::fields(3);
 584   fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL;  // Object to be Locked
 585   fields[TypeFunc::Parms+1] = TypeRawPtr::BOTTOM;    // Address of stack location for lock - BasicLock
 586   fields[TypeFunc::Parms+2] = TypeRawPtr::BOTTOM;    // Thread pointer (Self)
 587   const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+3, fields);
 588 
 589   // create result type (range)
 590   fields = TypeTuple::fields(0);
 591 
 592   const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0, fields);
 593 
 594   return TypeFunc::make(domain, range);
 595 }
 596 

1568   frame stub_frame = thread->last_frame();
1569   assert(stub_frame.is_runtime_frame() || exception_blob()->contains(stub_frame.pc()), "sanity check");
1570   frame caller_frame = stub_frame.sender(&reg_map);
1571   return caller_frame.is_deoptimized_frame();
1572 }
1573 
1574 
1575 const TypeFunc *OptoRuntime::register_finalizer_Type() {
1576   // create input type (domain)
1577   const Type **fields = TypeTuple::fields(1);
1578   fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL;  // oop;          Receiver
1579   // // The JavaThread* is passed to each routine as the last argument
1580   // fields[TypeFunc::Parms+1] = TypeRawPtr::NOTNULL;  // JavaThread *; Executing thread
1581   const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+1,fields);
1582 
1583   // create result type (range)
1584   fields = TypeTuple::fields(0);
1585 
1586   const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0,fields);
1587 
1588   return TypeFunc::make(domain,range);
1589 }
1590 
1591 #if INCLUDE_JFR
1592 const TypeFunc *OptoRuntime::class_id_load_barrier_Type() {
1593   // create input type (domain)
1594   const Type **fields = TypeTuple::fields(1);
1595   fields[TypeFunc::Parms+0] = TypeInstPtr::KLASS;
1596   const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms + 1, fields);
1597 
1598   // create result type (range)
1599   fields = TypeTuple::fields(0);
1600 
1601   const TypeTuple *range = TypeTuple::make(TypeFunc::Parms + 0, fields);
1602 
1603   return TypeFunc::make(domain,range);
1604 }
1605 #endif
1606 
1607 //-----------------------------------------------------------------------------
1608 // Dtrace support.  entry and exit probes have the same signature
1609 const TypeFunc *OptoRuntime::dtrace_method_entry_exit_Type() {
1610   // create input type (domain)
1611   const Type **fields = TypeTuple::fields(2);
1612   fields[TypeFunc::Parms+0] = TypeRawPtr::BOTTOM; // Thread-local storage
1613   fields[TypeFunc::Parms+1] = TypeMetadataPtr::BOTTOM;  // Method*;    Method we are entering
1614   const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+2,fields);
1615 
1616   // create result type (range)
1617   fields = TypeTuple::fields(0);
1618 
1619   const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0,fields);
1620 
1621   return TypeFunc::make(domain,range);
1622 }
1623 
1624 const TypeFunc *OptoRuntime::dtrace_object_alloc_Type() {
1625   // create input type (domain)
1626   const Type **fields = TypeTuple::fields(2);
1627   fields[TypeFunc::Parms+0] = TypeRawPtr::BOTTOM; // Thread-local storage
1628   fields[TypeFunc::Parms+1] = TypeInstPtr::NOTNULL;  // oop;    newly allocated object
1629 
1630   const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+2,fields);
1631 
1632   // create result type (range)
1633   fields = TypeTuple::fields(0);
1634 
1635   const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0,fields);
1636 
1637   return TypeFunc::make(domain,range);
1638 }
1639 
1640 
1641 JRT_ENTRY_NO_ASYNC(void, OptoRuntime::register_finalizer(oopDesc* obj, JavaThread* current))
1642   assert(oopDesc::is_oop(obj), "must be a valid oop");
1643   assert(obj->klass()->has_finalizer(), "shouldn't be here otherwise");
1644   InstanceKlass::register_finalizer(instanceOop(obj), CHECK);
1645 JRT_END
1646 
1647 //-----------------------------------------------------------------------------
1648 
1649 NamedCounter * volatile OptoRuntime::_named_counters = NULL;
1650 
1651 //
1652 // dump the collected NamedCounters.
1653 //
1654 void OptoRuntime::print_named_counters() {
1655   int total_lock_count = 0;
1656   int eliminated_lock_count = 0;
1657 

1741   trace_exception_counter++;
1742   stringStream tempst;
1743 
1744   tempst.print("%d [Exception (%s): ", trace_exception_counter, msg);
1745   exception_oop->print_value_on(&tempst);
1746   tempst.print(" in ");
1747   CodeBlob* blob = CodeCache::find_blob(exception_pc);
1748   if (blob->is_compiled()) {
1749     CompiledMethod* cm = blob->as_compiled_method_or_null();
1750     cm->method()->print_value_on(&tempst);
1751   } else if (blob->is_runtime_stub()) {
1752     tempst.print("<runtime-stub>");
1753   } else {
1754     tempst.print("<unknown>");
1755   }
1756   tempst.print(" at " INTPTR_FORMAT,  p2i(exception_pc));
1757   tempst.print("]");
1758 
1759   st->print_raw_cr(tempst.freeze());
1760 }









































































































  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"

  94 
  95 
  96 
  97 // Compiled code entry points
  98 address OptoRuntime::_new_instance_Java                           = NULL;
  99 address OptoRuntime::_new_array_Java                              = NULL;
 100 address OptoRuntime::_new_array_nozero_Java                       = NULL;
 101 address OptoRuntime::_multianewarray2_Java                        = NULL;
 102 address OptoRuntime::_multianewarray3_Java                        = NULL;
 103 address OptoRuntime::_multianewarray4_Java                        = NULL;
 104 address OptoRuntime::_multianewarray5_Java                        = NULL;
 105 address OptoRuntime::_multianewarrayN_Java                        = NULL;
 106 address OptoRuntime::_vtable_must_compile_Java                    = NULL;
 107 address OptoRuntime::_complete_monitor_locking_Java               = NULL;
 108 address OptoRuntime::_monitor_notify_Java                         = NULL;
 109 address OptoRuntime::_monitor_notifyAll_Java                      = NULL;
 110 address OptoRuntime::_rethrow_Java                                = NULL;
 111 
 112 address OptoRuntime::_slow_arraycopy_Java                         = NULL;
 113 address OptoRuntime::_register_finalizer_Java                     = NULL;
 114 address OptoRuntime::_load_unknown_inline                         = NULL;
 115 
 116 ExceptionBlob* OptoRuntime::_exception_blob;
 117 
 118 // This should be called in an assertion at the start of OptoRuntime routines
 119 // which are entered from compiled code (all of them)
 120 #ifdef ASSERT
 121 static bool check_compiled_frame(JavaThread* thread) {
 122   assert(thread->last_frame().is_runtime_frame(), "cannot call runtime directly from compiled code");
 123   RegisterMap map(thread,
 124                   RegisterMap::UpdateMap::skip,
 125                   RegisterMap::ProcessFrames::include,
 126                   RegisterMap::WalkContinuation::skip);
 127   frame caller = thread->last_frame().sender(&map);
 128   assert(caller.is_compiled_frame(), "not being called from compiled like code");
 129   return true;
 130 }
 131 #endif // ASSERT
 132 
 133 
 134 #define gen(env, var, type_func_gen, c_func, fancy_jump, pass_tls, return_pc) \

 138 bool OptoRuntime::generate(ciEnv* env) {
 139 
 140   generate_exception_blob();
 141 
 142   // Note: tls: Means fetching the return oop out of the thread-local storage
 143   //
 144   //   variable/name                       type-function-gen              , runtime method                  ,fncy_jp, tls,retpc
 145   // -------------------------------------------------------------------------------------------------------------------------------
 146   gen(env, _new_instance_Java              , new_instance_Type            , new_instance_C                  ,    0 , true, false);
 147   gen(env, _new_array_Java                 , new_array_Type               , new_array_C                     ,    0 , true, false);
 148   gen(env, _new_array_nozero_Java          , new_array_Type               , new_array_nozero_C              ,    0 , true, false);
 149   gen(env, _multianewarray2_Java           , multianewarray2_Type         , multianewarray2_C               ,    0 , true, false);
 150   gen(env, _multianewarray3_Java           , multianewarray3_Type         , multianewarray3_C               ,    0 , true, false);
 151   gen(env, _multianewarray4_Java           , multianewarray4_Type         , multianewarray4_C               ,    0 , true, false);
 152   gen(env, _multianewarray5_Java           , multianewarray5_Type         , multianewarray5_C               ,    0 , true, false);
 153   gen(env, _multianewarrayN_Java           , multianewarrayN_Type         , multianewarrayN_C               ,    0 , true, false);
 154   gen(env, _complete_monitor_locking_Java  , complete_monitor_enter_Type  , SharedRuntime::complete_monitor_locking_C, 0, false, false);
 155   gen(env, _monitor_notify_Java            , monitor_notify_Type          , monitor_notify_C                ,    0 , false, false);
 156   gen(env, _monitor_notifyAll_Java         , monitor_notify_Type          , monitor_notifyAll_C             ,    0 , false, false);
 157   gen(env, _rethrow_Java                   , rethrow_Type                 , rethrow_C                       ,    2 , true , true );

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

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

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

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

 563   fields = TypeTuple::fields(0);
 564   const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0, fields);
 565 
 566   return TypeFunc::make(domain, range);
 567 }
 568 
 569 //-----------------------------------------------------------------------------
 570 // Monitor Handling
 571 const TypeFunc *OptoRuntime::complete_monitor_enter_Type() {
 572   // create input type (domain)
 573   const Type **fields = TypeTuple::fields(2);
 574   fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL;  // Object to be Locked
 575   fields[TypeFunc::Parms+1] = TypeRawPtr::BOTTOM;   // Address of stack location for lock
 576   const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+2,fields);
 577 
 578   // create result type (range)
 579   fields = TypeTuple::fields(0);
 580 
 581   const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0,fields);
 582 
 583   return TypeFunc::make(domain, range);
 584 }
 585 
 586 
 587 //-----------------------------------------------------------------------------
 588 const TypeFunc *OptoRuntime::complete_monitor_exit_Type() {
 589   // create input type (domain)
 590   const Type **fields = TypeTuple::fields(3);
 591   fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL;  // Object to be Locked
 592   fields[TypeFunc::Parms+1] = TypeRawPtr::BOTTOM;    // Address of stack location for lock - BasicLock
 593   fields[TypeFunc::Parms+2] = TypeRawPtr::BOTTOM;    // Thread pointer (Self)
 594   const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+3, fields);
 595 
 596   // create result type (range)
 597   fields = TypeTuple::fields(0);
 598 
 599   const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0, fields);
 600 
 601   return TypeFunc::make(domain, range);
 602 }
 603 

1575   frame stub_frame = thread->last_frame();
1576   assert(stub_frame.is_runtime_frame() || exception_blob()->contains(stub_frame.pc()), "sanity check");
1577   frame caller_frame = stub_frame.sender(&reg_map);
1578   return caller_frame.is_deoptimized_frame();
1579 }
1580 
1581 
1582 const TypeFunc *OptoRuntime::register_finalizer_Type() {
1583   // create input type (domain)
1584   const Type **fields = TypeTuple::fields(1);
1585   fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL;  // oop;          Receiver
1586   // // The JavaThread* is passed to each routine as the last argument
1587   // fields[TypeFunc::Parms+1] = TypeRawPtr::NOTNULL;  // JavaThread *; Executing thread
1588   const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+1,fields);
1589 
1590   // create result type (range)
1591   fields = TypeTuple::fields(0);
1592 
1593   const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0,fields);
1594 
1595   return TypeFunc::make(domain, range);
1596 }
1597 
1598 #if INCLUDE_JFR
1599 const TypeFunc *OptoRuntime::class_id_load_barrier_Type() {
1600   // create input type (domain)
1601   const Type **fields = TypeTuple::fields(1);
1602   fields[TypeFunc::Parms+0] = TypeInstPtr::KLASS;
1603   const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms + 1, fields);
1604 
1605   // create result type (range)
1606   fields = TypeTuple::fields(0);
1607 
1608   const TypeTuple *range = TypeTuple::make(TypeFunc::Parms + 0, fields);
1609 
1610   return TypeFunc::make(domain,range);
1611 }
1612 #endif
1613 
1614 //-----------------------------------------------------------------------------
1615 // Dtrace support.  entry and exit probes have the same signature
1616 const TypeFunc *OptoRuntime::dtrace_method_entry_exit_Type() {
1617   // create input type (domain)
1618   const Type **fields = TypeTuple::fields(2);
1619   fields[TypeFunc::Parms+0] = TypeRawPtr::BOTTOM; // Thread-local storage
1620   fields[TypeFunc::Parms+1] = TypeMetadataPtr::BOTTOM;  // Method*;    Method we are entering
1621   const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+2,fields);
1622 
1623   // create result type (range)
1624   fields = TypeTuple::fields(0);
1625 
1626   const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0,fields);
1627 
1628   return TypeFunc::make(domain, range);
1629 }
1630 
1631 const TypeFunc *OptoRuntime::dtrace_object_alloc_Type() {
1632   // create input type (domain)
1633   const Type **fields = TypeTuple::fields(2);
1634   fields[TypeFunc::Parms+0] = TypeRawPtr::BOTTOM; // Thread-local storage
1635   fields[TypeFunc::Parms+1] = TypeInstPtr::NOTNULL;  // oop;    newly allocated object
1636 
1637   const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+2,fields);
1638 
1639   // create result type (range)
1640   fields = TypeTuple::fields(0);
1641 
1642   const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0,fields);
1643 
1644   return TypeFunc::make(domain, range);
1645 }
1646 
1647 
1648 JRT_ENTRY_NO_ASYNC(void, OptoRuntime::register_finalizer(oopDesc* obj, JavaThread* current))
1649   assert(oopDesc::is_oop(obj), "must be a valid oop");
1650   assert(obj->klass()->has_finalizer(), "shouldn't be here otherwise");
1651   InstanceKlass::register_finalizer(instanceOop(obj), CHECK);
1652 JRT_END
1653 
1654 //-----------------------------------------------------------------------------
1655 
1656 NamedCounter * volatile OptoRuntime::_named_counters = NULL;
1657 
1658 //
1659 // dump the collected NamedCounters.
1660 //
1661 void OptoRuntime::print_named_counters() {
1662   int total_lock_count = 0;
1663   int eliminated_lock_count = 0;
1664 

1748   trace_exception_counter++;
1749   stringStream tempst;
1750 
1751   tempst.print("%d [Exception (%s): ", trace_exception_counter, msg);
1752   exception_oop->print_value_on(&tempst);
1753   tempst.print(" in ");
1754   CodeBlob* blob = CodeCache::find_blob(exception_pc);
1755   if (blob->is_compiled()) {
1756     CompiledMethod* cm = blob->as_compiled_method_or_null();
1757     cm->method()->print_value_on(&tempst);
1758   } else if (blob->is_runtime_stub()) {
1759     tempst.print("<runtime-stub>");
1760   } else {
1761     tempst.print("<unknown>");
1762   }
1763   tempst.print(" at " INTPTR_FORMAT,  p2i(exception_pc));
1764   tempst.print("]");
1765 
1766   st->print_raw_cr(tempst.freeze());
1767 }
1768 
1769 const TypeFunc *OptoRuntime::store_inline_type_fields_Type() {
1770   // create input type (domain)
1771   uint total = SharedRuntime::java_return_convention_max_int + SharedRuntime::java_return_convention_max_float*2;
1772   const Type **fields = TypeTuple::fields(total);
1773   // We don't know the number of returned values and their
1774   // types. Assume all registers available to the return convention
1775   // are used.
1776   fields[TypeFunc::Parms] = TypePtr::BOTTOM;
1777   uint i = 1;
1778   for (; i < SharedRuntime::java_return_convention_max_int; i++) {
1779     fields[TypeFunc::Parms+i] = TypeInt::INT;
1780   }
1781   for (; i < total; i+=2) {
1782     fields[TypeFunc::Parms+i] = Type::DOUBLE;
1783     fields[TypeFunc::Parms+i+1] = Type::HALF;
1784   }
1785   const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms + total, fields);
1786 
1787   // create result type (range)
1788   fields = TypeTuple::fields(1);
1789   fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL;
1790 
1791   const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+1,fields);
1792 
1793   return TypeFunc::make(domain, range);
1794 }
1795 
1796 const TypeFunc *OptoRuntime::pack_inline_type_Type() {
1797   // create input type (domain)
1798   uint total = 1 + SharedRuntime::java_return_convention_max_int + SharedRuntime::java_return_convention_max_float*2;
1799   const Type **fields = TypeTuple::fields(total);
1800   // We don't know the number of returned values and their
1801   // types. Assume all registers available to the return convention
1802   // are used.
1803   fields[TypeFunc::Parms] = TypeRawPtr::BOTTOM;
1804   fields[TypeFunc::Parms+1] = TypeRawPtr::BOTTOM;
1805   uint i = 2;
1806   for (; i < SharedRuntime::java_return_convention_max_int+1; i++) {
1807     fields[TypeFunc::Parms+i] = TypeInt::INT;
1808   }
1809   for (; i < total; i+=2) {
1810     fields[TypeFunc::Parms+i] = Type::DOUBLE;
1811     fields[TypeFunc::Parms+i+1] = Type::HALF;
1812   }
1813   const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms + total, fields);
1814 
1815   // create result type (range)
1816   fields = TypeTuple::fields(1);
1817   fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL;
1818 
1819   const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+1,fields);
1820 
1821   return TypeFunc::make(domain, range);
1822 }
1823 
1824 JRT_BLOCK_ENTRY(void, OptoRuntime::load_unknown_inline(flatArrayOopDesc* array, int index, JavaThread* current))
1825   JRT_BLOCK;
1826   flatArrayHandle vah(current, array);
1827   oop buffer = flatArrayOopDesc::value_alloc_copy_from_index(vah, index, THREAD);
1828   deoptimize_caller_frame(current, HAS_PENDING_EXCEPTION);
1829   current->set_vm_result(buffer);
1830   JRT_BLOCK_END;
1831 JRT_END
1832 
1833 const TypeFunc* OptoRuntime::load_unknown_inline_type() {
1834   // create input type (domain)
1835   const Type** fields = TypeTuple::fields(2);
1836   fields[TypeFunc::Parms] = TypeOopPtr::NOTNULL;
1837   fields[TypeFunc::Parms+1] = TypeInt::POS;
1838 
1839   const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms+2, fields);
1840 
1841   // create result type (range)
1842   fields = TypeTuple::fields(1);
1843   fields[TypeFunc::Parms] = TypeInstPtr::NOTNULL;
1844 
1845   const TypeTuple* range = TypeTuple::make(TypeFunc::Parms+1, fields);
1846 
1847   return TypeFunc::make(domain, range);
1848 }
1849 
1850 JRT_LEAF(void, OptoRuntime::store_unknown_inline(instanceOopDesc* buffer, flatArrayOopDesc* array, int index))
1851 {
1852   assert(buffer != NULL, "can't store null into flat array");
1853   array->value_copy_to_index(buffer, index);
1854 }
1855 JRT_END
1856 
1857 const TypeFunc* OptoRuntime::store_unknown_inline_type() {
1858   // create input type (domain)
1859   const Type** fields = TypeTuple::fields(3);
1860   fields[TypeFunc::Parms] = TypeInstPtr::NOTNULL;
1861   fields[TypeFunc::Parms+1] = TypeOopPtr::NOTNULL;
1862   fields[TypeFunc::Parms+2] = TypeInt::POS;
1863 
1864   const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms+3, fields);
1865 
1866   // create result type (range)
1867   fields = TypeTuple::fields(0);
1868   const TypeTuple* range = TypeTuple::make(TypeFunc::Parms, fields);
1869 
1870   return TypeFunc::make(domain, range);
1871 }
< prev index next >