< prev index next >

src/hotspot/share/opto/runtime.cpp

Print this page

  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/compilationMemoryStatistic.hpp"
  35 #include "compiler/compileBroker.hpp"
  36 #include "compiler/oopMap.hpp"
  37 #include "gc/g1/g1HeapRegion.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/klass.inline.hpp"
  49 #include "oops/objArrayKlass.hpp"
  50 #include "oops/oop.inline.hpp"
  51 #include "oops/typeArrayOop.inline.hpp"

  52 #include "opto/ad.hpp"
  53 #include "opto/addnode.hpp"
  54 #include "opto/callnode.hpp"
  55 #include "opto/cfgnode.hpp"
  56 #include "opto/graphKit.hpp"
  57 #include "opto/machnode.hpp"
  58 #include "opto/matcher.hpp"
  59 #include "opto/memnode.hpp"
  60 #include "opto/mulnode.hpp"
  61 #include "opto/output.hpp"
  62 #include "opto/runtime.hpp"
  63 #include "opto/subnode.hpp"
  64 #include "prims/jvmtiExport.hpp"
  65 #include "runtime/atomicAccess.hpp"
  66 #include "runtime/frame.inline.hpp"
  67 #include "runtime/handles.inline.hpp"
  68 #include "runtime/interfaceSupport.inline.hpp"
  69 #include "runtime/javaCalls.hpp"
  70 #include "runtime/mountUnmountDisabler.hpp"
  71 #include "runtime/sharedRuntime.hpp"

 155 bool OptoRuntime::generate(ciEnv* env) {
 156 
 157   C2_STUBS_DO(GEN_C2_BLOB, GEN_C2_STUB)
 158   // disallow any further c2 stub generation
 159   AOTCodeCache::set_c2_stubs_complete();
 160   return true;
 161 }
 162 
 163 #undef GEN_C2_BLOB
 164 
 165 #undef C2_STUB_FIELD_NAME
 166 #undef C2_STUB_TYPEFUNC
 167 #undef C2_STUB_C_FUNC
 168 #undef C2_STUB_NAME
 169 #undef GEN_C2_STUB
 170 
 171 // #undef gen
 172 
 173 const TypeFunc* OptoRuntime::_new_instance_Type                   = nullptr;
 174 const TypeFunc* OptoRuntime::_new_array_Type                      = nullptr;

 175 const TypeFunc* OptoRuntime::_multianewarray2_Type                = nullptr;
 176 const TypeFunc* OptoRuntime::_multianewarray3_Type                = nullptr;
 177 const TypeFunc* OptoRuntime::_multianewarray4_Type                = nullptr;
 178 const TypeFunc* OptoRuntime::_multianewarray5_Type                = nullptr;
 179 const TypeFunc* OptoRuntime::_multianewarrayN_Type                = nullptr;
 180 const TypeFunc* OptoRuntime::_complete_monitor_enter_Type         = nullptr;
 181 const TypeFunc* OptoRuntime::_complete_monitor_exit_Type          = nullptr;
 182 const TypeFunc* OptoRuntime::_monitor_notify_Type                 = nullptr;
 183 const TypeFunc* OptoRuntime::_uncommon_trap_Type                  = nullptr;
 184 const TypeFunc* OptoRuntime::_athrow_Type                         = nullptr;
 185 const TypeFunc* OptoRuntime::_rethrow_Type                        = nullptr;
 186 const TypeFunc* OptoRuntime::_Math_D_D_Type                       = nullptr;
 187 const TypeFunc* OptoRuntime::_Math_DD_D_Type                      = nullptr;
 188 const TypeFunc* OptoRuntime::_modf_Type                           = nullptr;
 189 const TypeFunc* OptoRuntime::_l2f_Type                            = nullptr;
 190 const TypeFunc* OptoRuntime::_void_long_Type                      = nullptr;
 191 const TypeFunc* OptoRuntime::_void_void_Type                      = nullptr;
 192 const TypeFunc* OptoRuntime::_jfr_write_checkpoint_Type           = nullptr;
 193 const TypeFunc* OptoRuntime::_flush_windows_Type                  = nullptr;
 194 const TypeFunc* OptoRuntime::_fast_arraycopy_Type                 = nullptr;

 323     // Scavenge and allocate an instance.
 324     Handle holder(current, klass->klass_holder()); // keep the klass alive
 325     oop result = InstanceKlass::cast(klass)->allocate_instance(THREAD);
 326     current->set_vm_result_oop(result);
 327 
 328     // Pass oops back through thread local storage.  Our apparent type to Java
 329     // is that we return an oop, but we can block on exit from this routine and
 330     // a GC can trash the oop in C's return register.  The generated stub will
 331     // fetch the oop from TLS after any possible GC.
 332   }
 333 
 334   deoptimize_caller_frame(current, HAS_PENDING_EXCEPTION);
 335   JRT_BLOCK_END;
 336 
 337   // inform GC that we won't do card marks for initializing writes.
 338   SharedRuntime::on_slowpath_allocation_exit(current);
 339 JRT_END
 340 
 341 
 342 // array allocation
 343 JRT_BLOCK_ENTRY(void, OptoRuntime::new_array_C(Klass* array_type, int len, JavaThread* current))
 344   JRT_BLOCK;
 345 #ifndef PRODUCT
 346   SharedRuntime::_new_array_ctr++;            // new array requires GC
 347 #endif
 348   assert(check_compiled_frame(current), "incorrect caller");
 349 
 350   // Scavenge and allocate an instance.
 351   oop result;

 352 
 353   if (array_type->is_typeArray_klass()) {
 354     // The oopFactory likes to work with the element type.
 355     // (We could bypass the oopFactory, since it doesn't add much value.)
 356     BasicType elem_type = TypeArrayKlass::cast(array_type)->element_type();
 357     result = oopFactory::new_typeArray(elem_type, len, THREAD);
 358   } else {
 359     // Although the oopFactory likes to work with the elem_type,
 360     // the compiler prefers the array_type, since it must already have
 361     // that latter value in hand for the fast path.
 362     Handle holder(current, array_type->klass_holder()); // keep the array klass alive
 363     Klass* elem_type = ObjArrayKlass::cast(array_type)->element_klass();
 364     result = oopFactory::new_objArray(elem_type, len, THREAD);










 365   }
 366 
 367   // Pass oops back through thread local storage.  Our apparent type to Java
 368   // is that we return an oop, but we can block on exit from this routine and
 369   // a GC can trash the oop in C's return register.  The generated stub will
 370   // fetch the oop from TLS after any possible GC.
 371   deoptimize_caller_frame(current, HAS_PENDING_EXCEPTION);
 372   current->set_vm_result_oop(result);
 373   JRT_BLOCK_END;
 374 
 375   // inform GC that we won't do card marks for initializing writes.
 376   SharedRuntime::on_slowpath_allocation_exit(current);
 377 JRT_END
 378 
 379 // array allocation without zeroing
 380 JRT_BLOCK_ENTRY(void, OptoRuntime::new_array_nozero_C(Klass* array_type, int len, JavaThread* current))
 381   JRT_BLOCK;
 382 #ifndef PRODUCT
 383   SharedRuntime::_new_array_ctr++;            // new array requires GC
 384 #endif

 604   const TypeTuple* range = TypeTuple::make(TypeFunc::Parms, fields);
 605 
 606   return TypeFunc::make(domain,range);
 607 }
 608 
 609 static const TypeFunc* make_athrow_Type() {
 610   // create input type (domain)
 611   const Type **fields = TypeTuple::fields(1);
 612   fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; // Klass to be allocated
 613   const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+1, fields);
 614 
 615   // create result type (range)
 616   fields = TypeTuple::fields(0);
 617 
 618   const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0, fields);
 619 
 620   return TypeFunc::make(domain, range);
 621 }
 622 
 623 static const TypeFunc* make_new_array_Type() {

















 624   // create input type (domain)
 625   const Type **fields = TypeTuple::fields(2);
 626   fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL;   // element klass
 627   fields[TypeFunc::Parms+1] = TypeInt::INT;       // array size
 628   const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+2, fields);
 629 
 630   // create result type (range)
 631   fields = TypeTuple::fields(1);
 632   fields[TypeFunc::Parms+0] = TypeRawPtr::NOTNULL; // Returned oop
 633 
 634   const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+1, fields);
 635 
 636   return TypeFunc::make(domain, range);
 637 }
 638 
 639 const TypeFunc* OptoRuntime::multianewarray_Type(int ndim) {
 640   // create input type (domain)
 641   const int nargs = ndim + 1;
 642   const Type **fields = TypeTuple::fields(nargs);
 643   fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL;   // element klass

 679   const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0, fields);
 680 
 681   return TypeFunc::make(domain, range);
 682 }
 683 
 684 //-----------------------------------------------------------------------------
 685 // Monitor Handling
 686 
 687 static const TypeFunc* make_complete_monitor_enter_Type() {
 688   // create input type (domain)
 689   const Type **fields = TypeTuple::fields(2);
 690   fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL;  // Object to be Locked
 691   fields[TypeFunc::Parms+1] = TypeRawPtr::BOTTOM;   // Address of stack location for lock
 692   const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+2,fields);
 693 
 694   // create result type (range)
 695   fields = TypeTuple::fields(0);
 696 
 697   const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0,fields);
 698 
 699   return TypeFunc::make(domain,range);
 700 }
 701 
 702 //-----------------------------------------------------------------------------
 703 
 704 static const TypeFunc* make_complete_monitor_exit_Type() {
 705   // create input type (domain)
 706   const Type **fields = TypeTuple::fields(3);
 707   fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL;  // Object to be Locked
 708   fields[TypeFunc::Parms+1] = TypeRawPtr::BOTTOM;    // Address of stack location for lock - BasicLock
 709   fields[TypeFunc::Parms+2] = TypeRawPtr::BOTTOM;    // Thread pointer (Self)
 710   const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+3, fields);
 711 
 712   // create result type (range)
 713   fields = TypeTuple::fields(0);
 714 
 715   const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0, fields);
 716 
 717   return TypeFunc::make(domain, range);
 718 }
 719 

2170                       RegisterMap::WalkContinuation::skip);
2171   frame stub_frame = thread->last_frame();
2172   assert(stub_frame.is_runtime_frame() || exception_blob()->contains(stub_frame.pc()), "sanity check");
2173   frame caller_frame = stub_frame.sender(&reg_map);
2174   return caller_frame.is_deoptimized_frame();
2175 }
2176 
2177 static const TypeFunc* make_register_finalizer_Type() {
2178   // create input type (domain)
2179   const Type **fields = TypeTuple::fields(1);
2180   fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL;  // oop;          Receiver
2181   // // The JavaThread* is passed to each routine as the last argument
2182   // fields[TypeFunc::Parms+1] = TypeRawPtr::NOTNULL;  // JavaThread *; Executing thread
2183   const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+1,fields);
2184 
2185   // create result type (range)
2186   fields = TypeTuple::fields(0);
2187 
2188   const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0,fields);
2189 
2190   return TypeFunc::make(domain,range);
2191 }
2192 
2193 #if INCLUDE_JFR
2194 static const TypeFunc* make_class_id_load_barrier_Type() {
2195   // create input type (domain)
2196   const Type **fields = TypeTuple::fields(1);
2197   fields[TypeFunc::Parms+0] = TypeInstPtr::KLASS;
2198   const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms + 1, fields);
2199 
2200   // create result type (range)
2201   fields = TypeTuple::fields(0);
2202 
2203   const TypeTuple *range = TypeTuple::make(TypeFunc::Parms + 0, fields);
2204 
2205   return TypeFunc::make(domain,range);
2206 }
2207 #endif // INCLUDE_JFR
2208 
2209 //-----------------------------------------------------------------------------
2210 static const TypeFunc* make_dtrace_method_entry_exit_Type() {
2211   // create input type (domain)
2212   const Type **fields = TypeTuple::fields(2);
2213   fields[TypeFunc::Parms+0] = TypeRawPtr::BOTTOM; // Thread-local storage
2214   fields[TypeFunc::Parms+1] = TypeMetadataPtr::BOTTOM;  // Method*;    Method we are entering
2215   const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+2,fields);
2216 
2217   // create result type (range)
2218   fields = TypeTuple::fields(0);
2219 
2220   const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0,fields);
2221 
2222   return TypeFunc::make(domain,range);
2223 }
2224 
2225 static const TypeFunc* make_dtrace_object_alloc_Type() {
2226   // create input type (domain)
2227   const Type **fields = TypeTuple::fields(2);
2228   fields[TypeFunc::Parms+0] = TypeRawPtr::BOTTOM; // Thread-local storage
2229   fields[TypeFunc::Parms+1] = TypeInstPtr::NOTNULL;  // oop;    newly allocated object
2230 
2231   const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+2,fields);
2232 
2233   // create result type (range)
2234   fields = TypeTuple::fields(0);
2235 
2236   const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0,fields);
2237 
2238   return TypeFunc::make(domain,range);
2239 }
2240 
2241 JRT_ENTRY_NO_ASYNC(void, OptoRuntime::register_finalizer_C(oopDesc* obj, JavaThread* current))
2242   assert(oopDesc::is_oop(obj), "must be a valid oop");
2243   assert(obj->klass()->has_finalizer(), "shouldn't be here otherwise");
2244   InstanceKlass::register_finalizer(instanceOop(obj), CHECK);
2245 JRT_END
2246 
2247 //-----------------------------------------------------------------------------
2248 
2249 NamedCounter * volatile OptoRuntime::_named_counters = nullptr;
2250 
2251 //
2252 // dump the collected NamedCounters.
2253 //
2254 void OptoRuntime::print_named_counters() {
2255   int total_lock_count = 0;
2256   int eliminated_lock_count = 0;
2257 
2258   NamedCounter* c = _named_counters;

2309     }
2310     st.print("@%d", bci);
2311     // To print linenumbers instead of bci use: m->line_number_from_bci(bci)
2312   }
2313   NamedCounter* c = new NamedCounter(st.freeze(), tag);
2314 
2315   // atomically add the new counter to the head of the list.  We only
2316   // add counters so this is safe.
2317   NamedCounter* head;
2318   do {
2319     c->set_next(nullptr);
2320     head = _named_counters;
2321     c->set_next(head);
2322   } while (AtomicAccess::cmpxchg(&_named_counters, head, c) != head);
2323   return c;
2324 }
2325 
2326 void OptoRuntime::initialize_types() {
2327   _new_instance_Type                  = make_new_instance_Type();
2328   _new_array_Type                     = make_new_array_Type();

2329   _multianewarray2_Type               = multianewarray_Type(2);
2330   _multianewarray3_Type               = multianewarray_Type(3);
2331   _multianewarray4_Type               = multianewarray_Type(4);
2332   _multianewarray5_Type               = multianewarray_Type(5);
2333   _multianewarrayN_Type               = make_multianewarrayN_Type();
2334   _complete_monitor_enter_Type        = make_complete_monitor_enter_Type();
2335   _complete_monitor_exit_Type         = make_complete_monitor_exit_Type();
2336   _monitor_notify_Type                = make_monitor_notify_Type();
2337   _uncommon_trap_Type                 = make_uncommon_trap_Type();
2338   _athrow_Type                        = make_athrow_Type();
2339   _rethrow_Type                       = make_rethrow_Type();
2340   _Math_D_D_Type                      = make_Math_D_D_Type();
2341   _Math_DD_D_Type                     = make_Math_DD_D_Type();
2342   _modf_Type                          = make_modf_Type();
2343   _l2f_Type                           = make_l2f_Type();
2344   _void_long_Type                     = make_void_long_Type();
2345   _void_void_Type                     = make_void_void_Type();
2346   _jfr_write_checkpoint_Type          = make_jfr_write_checkpoint_Type();
2347   _flush_windows_Type                 = make_flush_windows_Type();
2348   _fast_arraycopy_Type                = make_arraycopy_Type(ac_fast);

2410 static void trace_exception(outputStream* st, oop exception_oop, address exception_pc, const char* msg) {
2411   trace_exception_counter++;
2412   stringStream tempst;
2413 
2414   tempst.print("%d [Exception (%s): ", trace_exception_counter, msg);
2415   exception_oop->print_value_on(&tempst);
2416   tempst.print(" in ");
2417   CodeBlob* blob = CodeCache::find_blob(exception_pc);
2418   if (blob->is_nmethod()) {
2419     blob->as_nmethod()->method()->print_value_on(&tempst);
2420   } else if (blob->is_runtime_stub()) {
2421     tempst.print("<runtime-stub>");
2422   } else {
2423     tempst.print("<unknown>");
2424   }
2425   tempst.print(" at " INTPTR_FORMAT,  p2i(exception_pc));
2426   tempst.print("]");
2427 
2428   st->print_raw_cr(tempst.freeze());
2429 }










































































































  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/compilationMemoryStatistic.hpp"
  35 #include "compiler/compileBroker.hpp"
  36 #include "compiler/oopMap.hpp"
  37 #include "gc/g1/g1HeapRegion.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/inlineKlass.inline.hpp"
  51 #include "oops/klass.inline.hpp"
  52 #include "oops/objArrayKlass.hpp"
  53 #include "oops/oop.inline.hpp"
  54 #include "oops/typeArrayOop.inline.hpp"
  55 #include "oops/valuePayload.inline.hpp"
  56 #include "opto/ad.hpp"
  57 #include "opto/addnode.hpp"
  58 #include "opto/callnode.hpp"
  59 #include "opto/cfgnode.hpp"
  60 #include "opto/graphKit.hpp"
  61 #include "opto/machnode.hpp"
  62 #include "opto/matcher.hpp"
  63 #include "opto/memnode.hpp"
  64 #include "opto/mulnode.hpp"
  65 #include "opto/output.hpp"
  66 #include "opto/runtime.hpp"
  67 #include "opto/subnode.hpp"
  68 #include "prims/jvmtiExport.hpp"
  69 #include "runtime/atomicAccess.hpp"
  70 #include "runtime/frame.inline.hpp"
  71 #include "runtime/handles.inline.hpp"
  72 #include "runtime/interfaceSupport.inline.hpp"
  73 #include "runtime/javaCalls.hpp"
  74 #include "runtime/mountUnmountDisabler.hpp"
  75 #include "runtime/sharedRuntime.hpp"

 159 bool OptoRuntime::generate(ciEnv* env) {
 160 
 161   C2_STUBS_DO(GEN_C2_BLOB, GEN_C2_STUB)
 162   // disallow any further c2 stub generation
 163   AOTCodeCache::set_c2_stubs_complete();
 164   return true;
 165 }
 166 
 167 #undef GEN_C2_BLOB
 168 
 169 #undef C2_STUB_FIELD_NAME
 170 #undef C2_STUB_TYPEFUNC
 171 #undef C2_STUB_C_FUNC
 172 #undef C2_STUB_NAME
 173 #undef GEN_C2_STUB
 174 
 175 // #undef gen
 176 
 177 const TypeFunc* OptoRuntime::_new_instance_Type                   = nullptr;
 178 const TypeFunc* OptoRuntime::_new_array_Type                      = nullptr;
 179 const TypeFunc* OptoRuntime::_new_array_nozero_Type               = nullptr;
 180 const TypeFunc* OptoRuntime::_multianewarray2_Type                = nullptr;
 181 const TypeFunc* OptoRuntime::_multianewarray3_Type                = nullptr;
 182 const TypeFunc* OptoRuntime::_multianewarray4_Type                = nullptr;
 183 const TypeFunc* OptoRuntime::_multianewarray5_Type                = nullptr;
 184 const TypeFunc* OptoRuntime::_multianewarrayN_Type                = nullptr;
 185 const TypeFunc* OptoRuntime::_complete_monitor_enter_Type         = nullptr;
 186 const TypeFunc* OptoRuntime::_complete_monitor_exit_Type          = nullptr;
 187 const TypeFunc* OptoRuntime::_monitor_notify_Type                 = nullptr;
 188 const TypeFunc* OptoRuntime::_uncommon_trap_Type                  = nullptr;
 189 const TypeFunc* OptoRuntime::_athrow_Type                         = nullptr;
 190 const TypeFunc* OptoRuntime::_rethrow_Type                        = nullptr;
 191 const TypeFunc* OptoRuntime::_Math_D_D_Type                       = nullptr;
 192 const TypeFunc* OptoRuntime::_Math_DD_D_Type                      = nullptr;
 193 const TypeFunc* OptoRuntime::_modf_Type                           = nullptr;
 194 const TypeFunc* OptoRuntime::_l2f_Type                            = nullptr;
 195 const TypeFunc* OptoRuntime::_void_long_Type                      = nullptr;
 196 const TypeFunc* OptoRuntime::_void_void_Type                      = nullptr;
 197 const TypeFunc* OptoRuntime::_jfr_write_checkpoint_Type           = nullptr;
 198 const TypeFunc* OptoRuntime::_flush_windows_Type                  = nullptr;
 199 const TypeFunc* OptoRuntime::_fast_arraycopy_Type                 = nullptr;

 328     // Scavenge and allocate an instance.
 329     Handle holder(current, klass->klass_holder()); // keep the klass alive
 330     oop result = InstanceKlass::cast(klass)->allocate_instance(THREAD);
 331     current->set_vm_result_oop(result);
 332 
 333     // Pass oops back through thread local storage.  Our apparent type to Java
 334     // is that we return an oop, but we can block on exit from this routine and
 335     // a GC can trash the oop in C's return register.  The generated stub will
 336     // fetch the oop from TLS after any possible GC.
 337   }
 338 
 339   deoptimize_caller_frame(current, HAS_PENDING_EXCEPTION);
 340   JRT_BLOCK_END;
 341 
 342   // inform GC that we won't do card marks for initializing writes.
 343   SharedRuntime::on_slowpath_allocation_exit(current);
 344 JRT_END
 345 
 346 
 347 // array allocation
 348 JRT_BLOCK_ENTRY(void, OptoRuntime::new_array_C(Klass* array_type, int len, oopDesc* init_val, JavaThread* current))
 349   JRT_BLOCK;
 350 #ifndef PRODUCT
 351   SharedRuntime::_new_array_ctr++;            // new array requires GC
 352 #endif
 353   assert(check_compiled_frame(current), "incorrect caller");
 354 
 355   // Scavenge and allocate an instance.
 356   oop result;
 357   Handle h_init_val(current, init_val); // keep the init_val object alive
 358 
 359   if (array_type->is_typeArray_klass()) {
 360     // The oopFactory likes to work with the element type.
 361     // (We could bypass the oopFactory, since it doesn't add much value.)
 362     BasicType elem_type = TypeArrayKlass::cast(array_type)->element_type();
 363     result = oopFactory::new_typeArray(elem_type, len, THREAD);
 364   } else {



 365     Handle holder(current, array_type->klass_holder()); // keep the array klass alive
 366     ObjArrayKlass* oak = ObjArrayKlass::cast(array_type);
 367     result = oopFactory::new_objArray(oak->element_klass(), len, oak->properties(), THREAD);
 368     if (!HAS_PENDING_EXCEPTION && array_type->is_null_free_array_klass() && !h_init_val.is_null()) {
 369       // Null-free arrays need to be initialized
 370 #ifdef ASSERT
 371       ObjArrayKlass* result_oak = ObjArrayKlass::cast(result->klass());
 372       assert(result_oak->is_null_free_array_klass(), "Sanity check");
 373 #endif
 374       for (int i = 0; i < len; i++) {
 375         ((objArrayOop)result)->obj_at_put(i, h_init_val());
 376       }
 377     }
 378   }
 379 
 380   // Pass oops back through thread local storage.  Our apparent type to Java
 381   // is that we return an oop, but we can block on exit from this routine and
 382   // a GC can trash the oop in C's return register.  The generated stub will
 383   // fetch the oop from TLS after any possible GC.
 384   deoptimize_caller_frame(current, HAS_PENDING_EXCEPTION);
 385   current->set_vm_result_oop(result);
 386   JRT_BLOCK_END;
 387 
 388   // inform GC that we won't do card marks for initializing writes.
 389   SharedRuntime::on_slowpath_allocation_exit(current);
 390 JRT_END
 391 
 392 // array allocation without zeroing
 393 JRT_BLOCK_ENTRY(void, OptoRuntime::new_array_nozero_C(Klass* array_type, int len, JavaThread* current))
 394   JRT_BLOCK;
 395 #ifndef PRODUCT
 396   SharedRuntime::_new_array_ctr++;            // new array requires GC
 397 #endif

 617   const TypeTuple* range = TypeTuple::make(TypeFunc::Parms, fields);
 618 
 619   return TypeFunc::make(domain,range);
 620 }
 621 
 622 static const TypeFunc* make_athrow_Type() {
 623   // create input type (domain)
 624   const Type **fields = TypeTuple::fields(1);
 625   fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; // Klass to be allocated
 626   const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+1, fields);
 627 
 628   // create result type (range)
 629   fields = TypeTuple::fields(0);
 630 
 631   const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0, fields);
 632 
 633   return TypeFunc::make(domain, range);
 634 }
 635 
 636 static const TypeFunc* make_new_array_Type() {
 637   // create input type (domain)
 638   const Type **fields = TypeTuple::fields(3);
 639   fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL;   // element klass
 640   fields[TypeFunc::Parms+1] = TypeInt::INT;       // array size
 641   fields[TypeFunc::Parms+2] = TypeInstPtr::NOTNULL;       // init value
 642   const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+3, fields);
 643 
 644   // create result type (range)
 645   fields = TypeTuple::fields(1);
 646   fields[TypeFunc::Parms+0] = TypeRawPtr::NOTNULL; // Returned oop
 647 
 648   const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+1, fields);
 649 
 650   return TypeFunc::make(domain, range);
 651 }
 652 
 653 static const TypeFunc* make_new_array_nozero_Type() {
 654   // create input type (domain)
 655   const Type **fields = TypeTuple::fields(2);
 656   fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL;   // element klass
 657   fields[TypeFunc::Parms+1] = TypeInt::INT;       // array size
 658   const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+2, fields);
 659 
 660   // create result type (range)
 661   fields = TypeTuple::fields(1);
 662   fields[TypeFunc::Parms+0] = TypeRawPtr::NOTNULL; // Returned oop
 663 
 664   const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+1, fields);
 665 
 666   return TypeFunc::make(domain, range);
 667 }
 668 
 669 const TypeFunc* OptoRuntime::multianewarray_Type(int ndim) {
 670   // create input type (domain)
 671   const int nargs = ndim + 1;
 672   const Type **fields = TypeTuple::fields(nargs);
 673   fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL;   // element klass

 709   const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0, fields);
 710 
 711   return TypeFunc::make(domain, range);
 712 }
 713 
 714 //-----------------------------------------------------------------------------
 715 // Monitor Handling
 716 
 717 static const TypeFunc* make_complete_monitor_enter_Type() {
 718   // create input type (domain)
 719   const Type **fields = TypeTuple::fields(2);
 720   fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL;  // Object to be Locked
 721   fields[TypeFunc::Parms+1] = TypeRawPtr::BOTTOM;   // Address of stack location for lock
 722   const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+2,fields);
 723 
 724   // create result type (range)
 725   fields = TypeTuple::fields(0);
 726 
 727   const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0,fields);
 728 
 729   return TypeFunc::make(domain, range);
 730 }
 731 
 732 //-----------------------------------------------------------------------------
 733 
 734 static const TypeFunc* make_complete_monitor_exit_Type() {
 735   // create input type (domain)
 736   const Type **fields = TypeTuple::fields(3);
 737   fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL;  // Object to be Locked
 738   fields[TypeFunc::Parms+1] = TypeRawPtr::BOTTOM;    // Address of stack location for lock - BasicLock
 739   fields[TypeFunc::Parms+2] = TypeRawPtr::BOTTOM;    // Thread pointer (Self)
 740   const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+3, fields);
 741 
 742   // create result type (range)
 743   fields = TypeTuple::fields(0);
 744 
 745   const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0, fields);
 746 
 747   return TypeFunc::make(domain, range);
 748 }
 749 

2200                       RegisterMap::WalkContinuation::skip);
2201   frame stub_frame = thread->last_frame();
2202   assert(stub_frame.is_runtime_frame() || exception_blob()->contains(stub_frame.pc()), "sanity check");
2203   frame caller_frame = stub_frame.sender(&reg_map);
2204   return caller_frame.is_deoptimized_frame();
2205 }
2206 
2207 static const TypeFunc* make_register_finalizer_Type() {
2208   // create input type (domain)
2209   const Type **fields = TypeTuple::fields(1);
2210   fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL;  // oop;          Receiver
2211   // // The JavaThread* is passed to each routine as the last argument
2212   // fields[TypeFunc::Parms+1] = TypeRawPtr::NOTNULL;  // JavaThread *; Executing thread
2213   const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+1,fields);
2214 
2215   // create result type (range)
2216   fields = TypeTuple::fields(0);
2217 
2218   const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0,fields);
2219 
2220   return TypeFunc::make(domain, range);
2221 }
2222 
2223 #if INCLUDE_JFR
2224 static const TypeFunc* make_class_id_load_barrier_Type() {
2225   // create input type (domain)
2226   const Type **fields = TypeTuple::fields(1);
2227   fields[TypeFunc::Parms+0] = TypeInstPtr::KLASS;
2228   const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms + 1, fields);
2229 
2230   // create result type (range)
2231   fields = TypeTuple::fields(0);
2232 
2233   const TypeTuple *range = TypeTuple::make(TypeFunc::Parms + 0, fields);
2234 
2235   return TypeFunc::make(domain,range);
2236 }
2237 #endif // INCLUDE_JFR
2238 
2239 //-----------------------------------------------------------------------------
2240 static const TypeFunc* make_dtrace_method_entry_exit_Type() {
2241   // create input type (domain)
2242   const Type **fields = TypeTuple::fields(2);
2243   fields[TypeFunc::Parms+0] = TypeRawPtr::BOTTOM; // Thread-local storage
2244   fields[TypeFunc::Parms+1] = TypeMetadataPtr::BOTTOM;  // Method*;    Method we are entering
2245   const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+2,fields);
2246 
2247   // create result type (range)
2248   fields = TypeTuple::fields(0);
2249 
2250   const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0,fields);
2251 
2252   return TypeFunc::make(domain, range);
2253 }
2254 
2255 static const TypeFunc* make_dtrace_object_alloc_Type() {
2256   // create input type (domain)
2257   const Type **fields = TypeTuple::fields(2);
2258   fields[TypeFunc::Parms+0] = TypeRawPtr::BOTTOM; // Thread-local storage
2259   fields[TypeFunc::Parms+1] = TypeInstPtr::NOTNULL;  // oop;    newly allocated object
2260 
2261   const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+2,fields);
2262 
2263   // create result type (range)
2264   fields = TypeTuple::fields(0);
2265 
2266   const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0,fields);
2267 
2268   return TypeFunc::make(domain, range);
2269 }
2270 
2271 JRT_ENTRY_NO_ASYNC(void, OptoRuntime::register_finalizer_C(oopDesc* obj, JavaThread* current))
2272   assert(oopDesc::is_oop(obj), "must be a valid oop");
2273   assert(obj->klass()->has_finalizer(), "shouldn't be here otherwise");
2274   InstanceKlass::register_finalizer(instanceOop(obj), CHECK);
2275 JRT_END
2276 
2277 //-----------------------------------------------------------------------------
2278 
2279 NamedCounter * volatile OptoRuntime::_named_counters = nullptr;
2280 
2281 //
2282 // dump the collected NamedCounters.
2283 //
2284 void OptoRuntime::print_named_counters() {
2285   int total_lock_count = 0;
2286   int eliminated_lock_count = 0;
2287 
2288   NamedCounter* c = _named_counters;

2339     }
2340     st.print("@%d", bci);
2341     // To print linenumbers instead of bci use: m->line_number_from_bci(bci)
2342   }
2343   NamedCounter* c = new NamedCounter(st.freeze(), tag);
2344 
2345   // atomically add the new counter to the head of the list.  We only
2346   // add counters so this is safe.
2347   NamedCounter* head;
2348   do {
2349     c->set_next(nullptr);
2350     head = _named_counters;
2351     c->set_next(head);
2352   } while (AtomicAccess::cmpxchg(&_named_counters, head, c) != head);
2353   return c;
2354 }
2355 
2356 void OptoRuntime::initialize_types() {
2357   _new_instance_Type                  = make_new_instance_Type();
2358   _new_array_Type                     = make_new_array_Type();
2359   _new_array_nozero_Type              = make_new_array_nozero_Type();
2360   _multianewarray2_Type               = multianewarray_Type(2);
2361   _multianewarray3_Type               = multianewarray_Type(3);
2362   _multianewarray4_Type               = multianewarray_Type(4);
2363   _multianewarray5_Type               = multianewarray_Type(5);
2364   _multianewarrayN_Type               = make_multianewarrayN_Type();
2365   _complete_monitor_enter_Type        = make_complete_monitor_enter_Type();
2366   _complete_monitor_exit_Type         = make_complete_monitor_exit_Type();
2367   _monitor_notify_Type                = make_monitor_notify_Type();
2368   _uncommon_trap_Type                 = make_uncommon_trap_Type();
2369   _athrow_Type                        = make_athrow_Type();
2370   _rethrow_Type                       = make_rethrow_Type();
2371   _Math_D_D_Type                      = make_Math_D_D_Type();
2372   _Math_DD_D_Type                     = make_Math_DD_D_Type();
2373   _modf_Type                          = make_modf_Type();
2374   _l2f_Type                           = make_l2f_Type();
2375   _void_long_Type                     = make_void_long_Type();
2376   _void_void_Type                     = make_void_void_Type();
2377   _jfr_write_checkpoint_Type          = make_jfr_write_checkpoint_Type();
2378   _flush_windows_Type                 = make_flush_windows_Type();
2379   _fast_arraycopy_Type                = make_arraycopy_Type(ac_fast);

2441 static void trace_exception(outputStream* st, oop exception_oop, address exception_pc, const char* msg) {
2442   trace_exception_counter++;
2443   stringStream tempst;
2444 
2445   tempst.print("%d [Exception (%s): ", trace_exception_counter, msg);
2446   exception_oop->print_value_on(&tempst);
2447   tempst.print(" in ");
2448   CodeBlob* blob = CodeCache::find_blob(exception_pc);
2449   if (blob->is_nmethod()) {
2450     blob->as_nmethod()->method()->print_value_on(&tempst);
2451   } else if (blob->is_runtime_stub()) {
2452     tempst.print("<runtime-stub>");
2453   } else {
2454     tempst.print("<unknown>");
2455   }
2456   tempst.print(" at " INTPTR_FORMAT,  p2i(exception_pc));
2457   tempst.print("]");
2458 
2459   st->print_raw_cr(tempst.freeze());
2460 }
2461 
2462 const TypeFunc *OptoRuntime::store_inline_type_fields_Type() {
2463   // create input type (domain)
2464   uint total = SharedRuntime::java_return_convention_max_int + SharedRuntime::java_return_convention_max_float*2;
2465   const Type **fields = TypeTuple::fields(total);
2466   // We don't know the number of returned values and their
2467   // types. Assume all registers available to the return convention
2468   // are used.
2469   fields[TypeFunc::Parms] = TypePtr::BOTTOM;
2470   uint i = 1;
2471   for (; i < SharedRuntime::java_return_convention_max_int; i++) {
2472     fields[TypeFunc::Parms+i] = TypeInt::INT;
2473   }
2474   for (; i < total; i+=2) {
2475     fields[TypeFunc::Parms+i] = Type::DOUBLE;
2476     fields[TypeFunc::Parms+i+1] = Type::HALF;
2477   }
2478   const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms + total, fields);
2479 
2480   // create result type (range)
2481   fields = TypeTuple::fields(1);
2482   fields[TypeFunc::Parms+0] = TypeInstPtr::BOTTOM;
2483 
2484   const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+1,fields);
2485 
2486   return TypeFunc::make(domain, range);
2487 }
2488 
2489 const TypeFunc *OptoRuntime::pack_inline_type_Type() {
2490   // create input type (domain)
2491   uint total = 1 + SharedRuntime::java_return_convention_max_int + SharedRuntime::java_return_convention_max_float*2;
2492   const Type **fields = TypeTuple::fields(total);
2493   // We don't know the number of returned values and their
2494   // types. Assume all registers available to the return convention
2495   // are used.
2496   fields[TypeFunc::Parms] = TypeRawPtr::BOTTOM;
2497   fields[TypeFunc::Parms+1] = TypeRawPtr::BOTTOM;
2498   uint i = 2;
2499   for (; i < SharedRuntime::java_return_convention_max_int+1; i++) {
2500     fields[TypeFunc::Parms+i] = TypeInt::INT;
2501   }
2502   for (; i < total; i+=2) {
2503     fields[TypeFunc::Parms+i] = Type::DOUBLE;
2504     fields[TypeFunc::Parms+i+1] = Type::HALF;
2505   }
2506   const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms + total, fields);
2507 
2508   // create result type (range)
2509   fields = TypeTuple::fields(1);
2510   fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL;
2511 
2512   const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+1,fields);
2513 
2514   return TypeFunc::make(domain, range);
2515 }
2516 
2517 JRT_BLOCK_ENTRY(void, OptoRuntime::load_unknown_inline_C(flatArrayOopDesc* array, int index, JavaThread* current))
2518   JRT_BLOCK;
2519   oop buffer = array->obj_at(index, THREAD);
2520   deoptimize_caller_frame(current, HAS_PENDING_EXCEPTION);
2521   current->set_vm_result_oop(buffer);
2522   JRT_BLOCK_END;
2523 JRT_END
2524 
2525 const TypeFunc* OptoRuntime::load_unknown_inline_Type() {
2526   // create input type (domain)
2527   const Type** fields = TypeTuple::fields(2);
2528   fields[TypeFunc::Parms] = TypeOopPtr::NOTNULL;
2529   fields[TypeFunc::Parms+1] = TypeInt::POS;
2530 
2531   const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms+2, fields);
2532 
2533   // create result type (range)
2534   fields = TypeTuple::fields(1);
2535   fields[TypeFunc::Parms] = TypeInstPtr::BOTTOM;
2536 
2537   const TypeTuple* range = TypeTuple::make(TypeFunc::Parms+1, fields);
2538 
2539   return TypeFunc::make(domain, range);
2540 }
2541 
2542 JRT_BLOCK_ENTRY(void, OptoRuntime::store_unknown_inline_C(instanceOopDesc* buffer, flatArrayOopDesc* array, int index, JavaThread* current))
2543   JRT_BLOCK;
2544   array->obj_at_put(index, buffer, THREAD);
2545   if (HAS_PENDING_EXCEPTION) {
2546       fatal("This entry must be changed to be a non-leaf entry because writing to a flat array can now throw an exception");
2547   }
2548   JRT_BLOCK_END;
2549 JRT_END
2550 
2551 const TypeFunc* OptoRuntime::store_unknown_inline_Type() {
2552   // create input type (domain)
2553   const Type** fields = TypeTuple::fields(3);
2554   fields[TypeFunc::Parms] = TypeInstPtr::NOTNULL;
2555   fields[TypeFunc::Parms+1] = TypeOopPtr::NOTNULL;
2556   fields[TypeFunc::Parms+2] = TypeInt::POS;
2557 
2558   const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms+3, fields);
2559 
2560   // create result type (range)
2561   fields = TypeTuple::fields(0);
2562   const TypeTuple* range = TypeTuple::make(TypeFunc::Parms, fields);
2563 
2564   return TypeFunc::make(domain, range);
2565 }
< prev index next >