27 #include "code/codeCache.hpp"
28 #include "code/compiledIC.hpp"
29 #include "code/nmethod.hpp"
30 #include "code/pcDesc.hpp"
31 #include "code/scopeDesc.hpp"
32 #include "code/vtableStubs.hpp"
33 #include "compiler/compilationMemoryStatistic.hpp"
34 #include "compiler/compileBroker.hpp"
35 #include "compiler/oopMap.hpp"
36 #include "gc/g1/g1HeapRegion.hpp"
37 #include "gc/shared/barrierSet.hpp"
38 #include "gc/shared/collectedHeap.hpp"
39 #include "gc/shared/gcLocker.hpp"
40 #include "interpreter/bytecode.hpp"
41 #include "interpreter/interpreter.hpp"
42 #include "interpreter/linkResolver.hpp"
43 #include "logging/log.hpp"
44 #include "logging/logStream.hpp"
45 #include "memory/oopFactory.hpp"
46 #include "memory/resourceArea.hpp"
47 #include "oops/objArrayKlass.hpp"
48 #include "oops/klass.inline.hpp"
49 #include "oops/oop.inline.hpp"
50 #include "oops/typeArrayOop.inline.hpp"
51 #include "opto/ad.hpp"
52 #include "opto/addnode.hpp"
53 #include "opto/callnode.hpp"
54 #include "opto/cfgnode.hpp"
55 #include "opto/graphKit.hpp"
56 #include "opto/machnode.hpp"
57 #include "opto/matcher.hpp"
58 #include "opto/memnode.hpp"
59 #include "opto/mulnode.hpp"
60 #include "opto/output.hpp"
61 #include "opto/runtime.hpp"
62 #include "opto/subnode.hpp"
63 #include "prims/jvmtiExport.hpp"
64 #include "runtime/atomic.hpp"
65 #include "runtime/frame.inline.hpp"
66 #include "runtime/handles.inline.hpp"
179
180 C2_STUBS_DO(GEN_C2_BLOB, GEN_C2_STUB, GEN_C2_JVMTI_STUB)
181
182 return true;
183 }
184
185 #undef GEN_C2_BLOB
186
187 #undef C2_STUB_FIELD_NAME
188 #undef C2_STUB_TYPEFUNC
189 #undef C2_STUB_C_FUNC
190 #undef C2_STUB_NAME
191 #undef GEN_C2_STUB
192
193 #undef C2_JVMTI_STUB_C_FUNC
194 #undef GEN_C2_JVMTI_STUB
195 // #undef gen
196
197 const TypeFunc* OptoRuntime::_new_instance_Type = nullptr;
198 const TypeFunc* OptoRuntime::_new_array_Type = nullptr;
199 const TypeFunc* OptoRuntime::_multianewarray2_Type = nullptr;
200 const TypeFunc* OptoRuntime::_multianewarray3_Type = nullptr;
201 const TypeFunc* OptoRuntime::_multianewarray4_Type = nullptr;
202 const TypeFunc* OptoRuntime::_multianewarray5_Type = nullptr;
203 const TypeFunc* OptoRuntime::_multianewarrayN_Type = nullptr;
204 const TypeFunc* OptoRuntime::_complete_monitor_enter_Type = nullptr;
205 const TypeFunc* OptoRuntime::_complete_monitor_exit_Type = nullptr;
206 const TypeFunc* OptoRuntime::_monitor_notify_Type = nullptr;
207 const TypeFunc* OptoRuntime::_uncommon_trap_Type = nullptr;
208 const TypeFunc* OptoRuntime::_athrow_Type = nullptr;
209 const TypeFunc* OptoRuntime::_rethrow_Type = nullptr;
210 const TypeFunc* OptoRuntime::_Math_D_D_Type = nullptr;
211 const TypeFunc* OptoRuntime::_Math_DD_D_Type = nullptr;
212 const TypeFunc* OptoRuntime::_modf_Type = nullptr;
213 const TypeFunc* OptoRuntime::_l2f_Type = nullptr;
214 const TypeFunc* OptoRuntime::_void_long_Type = nullptr;
215 const TypeFunc* OptoRuntime::_void_void_Type = nullptr;
216 const TypeFunc* OptoRuntime::_jfr_write_checkpoint_Type = nullptr;
217 const TypeFunc* OptoRuntime::_flush_windows_Type = nullptr;
218 const TypeFunc* OptoRuntime::_fast_arraycopy_Type = nullptr;
309 oopDesc* dest, jint dest_pos,
310 jint length, JavaThread* thread) {
311 SharedRuntime::slow_arraycopy_C(src, src_pos, dest, dest_pos, length, thread);
312 }
313
314 void OptoRuntime::complete_monitor_locking_C(oopDesc* obj, BasicLock* lock, JavaThread* current) {
315 SharedRuntime::complete_monitor_locking_C(obj, lock, current);
316 }
317
318
319 //=============================================================================
320 // Opto compiler runtime routines
321 //=============================================================================
322
323
324 //=============================allocation======================================
325 // We failed the fast-path allocation. Now we need to do a scavenge or GC
326 // and try allocation again.
327
328 // object allocation
329 JRT_BLOCK_ENTRY(void, OptoRuntime::new_instance_C(Klass* klass, JavaThread* current))
330 JRT_BLOCK;
331 #ifndef PRODUCT
332 SharedRuntime::_new_instance_ctr++; // new instance requires GC
333 #endif
334 assert(check_compiled_frame(current), "incorrect caller");
335
336 // These checks are cheap to make and support reflective allocation.
337 int lh = klass->layout_helper();
338 if (Klass::layout_helper_needs_slow_path(lh) || !InstanceKlass::cast(klass)->is_initialized()) {
339 Handle holder(current, klass->klass_holder()); // keep the klass alive
340 klass->check_valid_for_instantiation(false, THREAD);
341 if (!HAS_PENDING_EXCEPTION) {
342 InstanceKlass::cast(klass)->initialize(THREAD);
343 }
344 }
345
346 if (!HAS_PENDING_EXCEPTION) {
347 // Scavenge and allocate an instance.
348 Handle holder(current, klass->klass_holder()); // keep the klass alive
349 oop result = InstanceKlass::cast(klass)->allocate_instance(THREAD);
350 current->set_vm_result_oop(result);
351
352 // Pass oops back through thread local storage. Our apparent type to Java
353 // is that we return an oop, but we can block on exit from this routine and
354 // a GC can trash the oop in C's return register. The generated stub will
355 // fetch the oop from TLS after any possible GC.
356 }
357
358 deoptimize_caller_frame(current, HAS_PENDING_EXCEPTION);
359 JRT_BLOCK_END;
360
361 // inform GC that we won't do card marks for initializing writes.
362 SharedRuntime::on_slowpath_allocation_exit(current);
363 JRT_END
364
365
366 // array allocation
367 JRT_BLOCK_ENTRY(void, OptoRuntime::new_array_C(Klass* array_type, int len, JavaThread* current))
368 JRT_BLOCK;
369 #ifndef PRODUCT
370 SharedRuntime::_new_array_ctr++; // new array requires GC
371 #endif
372 assert(check_compiled_frame(current), "incorrect caller");
373
374 // Scavenge and allocate an instance.
375 oop result;
376
377 if (array_type->is_typeArray_klass()) {
378 // The oopFactory likes to work with the element type.
379 // (We could bypass the oopFactory, since it doesn't add much value.)
380 BasicType elem_type = TypeArrayKlass::cast(array_type)->element_type();
381 result = oopFactory::new_typeArray(elem_type, len, THREAD);
382 } else {
383 // Although the oopFactory likes to work with the elem_type,
384 // the compiler prefers the array_type, since it must already have
385 // that latter value in hand for the fast path.
386 Handle holder(current, array_type->klass_holder()); // keep the array klass alive
387 Klass* elem_type = ObjArrayKlass::cast(array_type)->element_klass();
388 result = oopFactory::new_objArray(elem_type, len, THREAD);
389 }
390
391 // Pass oops back through thread local storage. Our apparent type to Java
392 // is that we return an oop, but we can block on exit from this routine and
393 // a GC can trash the oop in C's return register. The generated stub will
394 // fetch the oop from TLS after any possible GC.
395 deoptimize_caller_frame(current, HAS_PENDING_EXCEPTION);
396 current->set_vm_result_oop(result);
397 JRT_BLOCK_END;
398
399 // inform GC that we won't do card marks for initializing writes.
400 SharedRuntime::on_slowpath_allocation_exit(current);
401 JRT_END
402
403 // array allocation without zeroing
404 JRT_BLOCK_ENTRY(void, OptoRuntime::new_array_nozero_C(Klass* array_type, int len, JavaThread* current))
405 JRT_BLOCK;
406 #ifndef PRODUCT
407 SharedRuntime::_new_array_ctr++; // new array requires GC
408 #endif
565 JRT_BLOCK_ENTRY(void, OptoRuntime::monitor_notifyAll_C(oopDesc* obj, JavaThread* current))
566
567 if (!SafepointSynchronize::is_synchronizing() ) {
568 if (ObjectSynchronizer::quick_notify(obj, current, true)) {
569 return;
570 }
571 }
572
573 // This is the case the fast-path above isn't provisioned to handle.
574 // The fast-path is designed to handle frequently arising cases in an efficient manner.
575 // (The fast-path is just a degenerate variant of the slow-path).
576 // Perform the dreaded state transition and pass control into the slow-path.
577 JRT_BLOCK;
578 Handle h_obj(current, obj);
579 ObjectSynchronizer::notifyall(h_obj, CHECK);
580 JRT_BLOCK_END;
581 JRT_END
582
583 static const TypeFunc* make_new_instance_Type() {
584 // create input type (domain)
585 const Type **fields = TypeTuple::fields(1);
586 fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; // Klass to be allocated
587 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+1, fields);
588
589 // create result type (range)
590 fields = TypeTuple::fields(1);
591 fields[TypeFunc::Parms+0] = TypeRawPtr::NOTNULL; // Returned oop
592
593 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+1, fields);
594
595 return TypeFunc::make(domain, range);
596 }
597
598 #if INCLUDE_JVMTI
599 static const TypeFunc* make_notify_jvmti_vthread_Type() {
600 // create input type (domain)
601 const Type **fields = TypeTuple::fields(2);
602 fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; // VirtualThread oop
603 fields[TypeFunc::Parms+1] = TypeInt::BOOL; // jboolean
604 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+2,fields);
605
606 // no result type needed
607 fields = TypeTuple::fields(1);
610
611 return TypeFunc::make(domain,range);
612 }
613 #endif
614
615 static const TypeFunc* make_athrow_Type() {
616 // create input type (domain)
617 const Type **fields = TypeTuple::fields(1);
618 fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; // Klass to be allocated
619 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+1, fields);
620
621 // create result type (range)
622 fields = TypeTuple::fields(0);
623
624 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0, fields);
625
626 return TypeFunc::make(domain, range);
627 }
628
629 static const TypeFunc* make_new_array_Type() {
630 // create input type (domain)
631 const Type **fields = TypeTuple::fields(2);
632 fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; // element klass
633 fields[TypeFunc::Parms+1] = TypeInt::INT; // array size
634 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+2, fields);
635
636 // create result type (range)
637 fields = TypeTuple::fields(1);
638 fields[TypeFunc::Parms+0] = TypeRawPtr::NOTNULL; // Returned oop
639
640 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+1, fields);
641
642 return TypeFunc::make(domain, range);
643 }
644
645 const TypeFunc* OptoRuntime::multianewarray_Type(int ndim) {
646 // create input type (domain)
647 const int nargs = ndim + 1;
648 const Type **fields = TypeTuple::fields(nargs);
649 fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; // element klass
685 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0, fields);
686
687 return TypeFunc::make(domain, range);
688 }
689
690 //-----------------------------------------------------------------------------
691 // Monitor Handling
692
693 static const TypeFunc* make_complete_monitor_enter_Type() {
694 // create input type (domain)
695 const Type **fields = TypeTuple::fields(2);
696 fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; // Object to be Locked
697 fields[TypeFunc::Parms+1] = TypeRawPtr::BOTTOM; // Address of stack location for lock
698 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+2,fields);
699
700 // create result type (range)
701 fields = TypeTuple::fields(0);
702
703 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0,fields);
704
705 return TypeFunc::make(domain,range);
706 }
707
708 //-----------------------------------------------------------------------------
709
710 static const TypeFunc* make_complete_monitor_exit_Type() {
711 // create input type (domain)
712 const Type **fields = TypeTuple::fields(3);
713 fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; // Object to be Locked
714 fields[TypeFunc::Parms+1] = TypeRawPtr::BOTTOM; // Address of stack location for lock - BasicLock
715 fields[TypeFunc::Parms+2] = TypeRawPtr::BOTTOM; // Thread pointer (Self)
716 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+3, fields);
717
718 // create result type (range)
719 fields = TypeTuple::fields(0);
720
721 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0, fields);
722
723 return TypeFunc::make(domain, range);
724 }
725
2063 RegisterMap::WalkContinuation::skip);
2064 frame stub_frame = thread->last_frame();
2065 assert(stub_frame.is_runtime_frame() || exception_blob()->contains(stub_frame.pc()), "sanity check");
2066 frame caller_frame = stub_frame.sender(®_map);
2067 return caller_frame.is_deoptimized_frame();
2068 }
2069
2070 static const TypeFunc* make_register_finalizer_Type() {
2071 // create input type (domain)
2072 const Type **fields = TypeTuple::fields(1);
2073 fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; // oop; Receiver
2074 // // The JavaThread* is passed to each routine as the last argument
2075 // fields[TypeFunc::Parms+1] = TypeRawPtr::NOTNULL; // JavaThread *; Executing thread
2076 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+1,fields);
2077
2078 // create result type (range)
2079 fields = TypeTuple::fields(0);
2080
2081 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0,fields);
2082
2083 return TypeFunc::make(domain,range);
2084 }
2085
2086 #if INCLUDE_JFR
2087 static const TypeFunc* make_class_id_load_barrier_Type() {
2088 // create input type (domain)
2089 const Type **fields = TypeTuple::fields(1);
2090 fields[TypeFunc::Parms+0] = TypeInstPtr::KLASS;
2091 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms + 1, fields);
2092
2093 // create result type (range)
2094 fields = TypeTuple::fields(0);
2095
2096 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms + 0, fields);
2097
2098 return TypeFunc::make(domain,range);
2099 }
2100 #endif // INCLUDE_JFR
2101
2102 //-----------------------------------------------------------------------------
2103 static const TypeFunc* make_dtrace_method_entry_exit_Type() {
2104 // create input type (domain)
2105 const Type **fields = TypeTuple::fields(2);
2106 fields[TypeFunc::Parms+0] = TypeRawPtr::BOTTOM; // Thread-local storage
2107 fields[TypeFunc::Parms+1] = TypeMetadataPtr::BOTTOM; // Method*; Method we are entering
2108 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+2,fields);
2109
2110 // create result type (range)
2111 fields = TypeTuple::fields(0);
2112
2113 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0,fields);
2114
2115 return TypeFunc::make(domain,range);
2116 }
2117
2118 static const TypeFunc* make_dtrace_object_alloc_Type() {
2119 // create input type (domain)
2120 const Type **fields = TypeTuple::fields(2);
2121 fields[TypeFunc::Parms+0] = TypeRawPtr::BOTTOM; // Thread-local storage
2122 fields[TypeFunc::Parms+1] = TypeInstPtr::NOTNULL; // oop; newly allocated object
2123
2124 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+2,fields);
2125
2126 // create result type (range)
2127 fields = TypeTuple::fields(0);
2128
2129 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0,fields);
2130
2131 return TypeFunc::make(domain,range);
2132 }
2133
2134 JRT_ENTRY_NO_ASYNC(void, OptoRuntime::register_finalizer_C(oopDesc* obj, JavaThread* current))
2135 assert(oopDesc::is_oop(obj), "must be a valid oop");
2136 assert(obj->klass()->has_finalizer(), "shouldn't be here otherwise");
2137 InstanceKlass::register_finalizer(instanceOop(obj), CHECK);
2138 JRT_END
2139
2140 //-----------------------------------------------------------------------------
2141
2142 NamedCounter * volatile OptoRuntime::_named_counters = nullptr;
2143
2144 //
2145 // dump the collected NamedCounters.
2146 //
2147 void OptoRuntime::print_named_counters() {
2148 int total_lock_count = 0;
2149 int eliminated_lock_count = 0;
2150
2151 NamedCounter* c = _named_counters;
2202 }
2203 st.print("@%d", bci);
2204 // To print linenumbers instead of bci use: m->line_number_from_bci(bci)
2205 }
2206 NamedCounter* c = new NamedCounter(st.freeze(), tag);
2207
2208 // atomically add the new counter to the head of the list. We only
2209 // add counters so this is safe.
2210 NamedCounter* head;
2211 do {
2212 c->set_next(nullptr);
2213 head = _named_counters;
2214 c->set_next(head);
2215 } while (Atomic::cmpxchg(&_named_counters, head, c) != head);
2216 return c;
2217 }
2218
2219 void OptoRuntime::initialize_types() {
2220 _new_instance_Type = make_new_instance_Type();
2221 _new_array_Type = make_new_array_Type();
2222 _multianewarray2_Type = multianewarray_Type(2);
2223 _multianewarray3_Type = multianewarray_Type(3);
2224 _multianewarray4_Type = multianewarray_Type(4);
2225 _multianewarray5_Type = multianewarray_Type(5);
2226 _multianewarrayN_Type = make_multianewarrayN_Type();
2227 _complete_monitor_enter_Type = make_complete_monitor_enter_Type();
2228 _complete_monitor_exit_Type = make_complete_monitor_exit_Type();
2229 _monitor_notify_Type = make_monitor_notify_Type();
2230 _uncommon_trap_Type = make_uncommon_trap_Type();
2231 _athrow_Type = make_athrow_Type();
2232 _rethrow_Type = make_rethrow_Type();
2233 _Math_D_D_Type = make_Math_D_D_Type();
2234 _Math_DD_D_Type = make_Math_DD_D_Type();
2235 _modf_Type = make_modf_Type();
2236 _l2f_Type = make_l2f_Type();
2237 _void_long_Type = make_void_long_Type();
2238 _void_void_Type = make_void_void_Type();
2239 _jfr_write_checkpoint_Type = make_jfr_write_checkpoint_Type();
2240 _flush_windows_Type = make_flush_windows_Type();
2241 _fast_arraycopy_Type = make_arraycopy_Type(ac_fast);
2302 static void trace_exception(outputStream* st, oop exception_oop, address exception_pc, const char* msg) {
2303 trace_exception_counter++;
2304 stringStream tempst;
2305
2306 tempst.print("%d [Exception (%s): ", trace_exception_counter, msg);
2307 exception_oop->print_value_on(&tempst);
2308 tempst.print(" in ");
2309 CodeBlob* blob = CodeCache::find_blob(exception_pc);
2310 if (blob->is_nmethod()) {
2311 blob->as_nmethod()->method()->print_value_on(&tempst);
2312 } else if (blob->is_runtime_stub()) {
2313 tempst.print("<runtime-stub>");
2314 } else {
2315 tempst.print("<unknown>");
2316 }
2317 tempst.print(" at " INTPTR_FORMAT, p2i(exception_pc));
2318 tempst.print("]");
2319
2320 st->print_raw_cr(tempst.freeze());
2321 }
|
27 #include "code/codeCache.hpp"
28 #include "code/compiledIC.hpp"
29 #include "code/nmethod.hpp"
30 #include "code/pcDesc.hpp"
31 #include "code/scopeDesc.hpp"
32 #include "code/vtableStubs.hpp"
33 #include "compiler/compilationMemoryStatistic.hpp"
34 #include "compiler/compileBroker.hpp"
35 #include "compiler/oopMap.hpp"
36 #include "gc/g1/g1HeapRegion.hpp"
37 #include "gc/shared/barrierSet.hpp"
38 #include "gc/shared/collectedHeap.hpp"
39 #include "gc/shared/gcLocker.hpp"
40 #include "interpreter/bytecode.hpp"
41 #include "interpreter/interpreter.hpp"
42 #include "interpreter/linkResolver.hpp"
43 #include "logging/log.hpp"
44 #include "logging/logStream.hpp"
45 #include "memory/oopFactory.hpp"
46 #include "memory/resourceArea.hpp"
47 #include "oops/flatArrayKlass.hpp"
48 #include "oops/flatArrayOop.inline.hpp"
49 #include "oops/objArrayKlass.hpp"
50 #include "oops/klass.inline.hpp"
51 #include "oops/oop.inline.hpp"
52 #include "oops/typeArrayOop.inline.hpp"
53 #include "opto/ad.hpp"
54 #include "opto/addnode.hpp"
55 #include "opto/callnode.hpp"
56 #include "opto/cfgnode.hpp"
57 #include "opto/graphKit.hpp"
58 #include "opto/machnode.hpp"
59 #include "opto/matcher.hpp"
60 #include "opto/memnode.hpp"
61 #include "opto/mulnode.hpp"
62 #include "opto/output.hpp"
63 #include "opto/runtime.hpp"
64 #include "opto/subnode.hpp"
65 #include "prims/jvmtiExport.hpp"
66 #include "runtime/atomic.hpp"
67 #include "runtime/frame.inline.hpp"
68 #include "runtime/handles.inline.hpp"
181
182 C2_STUBS_DO(GEN_C2_BLOB, GEN_C2_STUB, GEN_C2_JVMTI_STUB)
183
184 return true;
185 }
186
187 #undef GEN_C2_BLOB
188
189 #undef C2_STUB_FIELD_NAME
190 #undef C2_STUB_TYPEFUNC
191 #undef C2_STUB_C_FUNC
192 #undef C2_STUB_NAME
193 #undef GEN_C2_STUB
194
195 #undef C2_JVMTI_STUB_C_FUNC
196 #undef GEN_C2_JVMTI_STUB
197 // #undef gen
198
199 const TypeFunc* OptoRuntime::_new_instance_Type = nullptr;
200 const TypeFunc* OptoRuntime::_new_array_Type = nullptr;
201 const TypeFunc* OptoRuntime::_new_array_nozero_Type = nullptr;
202 const TypeFunc* OptoRuntime::_multianewarray2_Type = nullptr;
203 const TypeFunc* OptoRuntime::_multianewarray3_Type = nullptr;
204 const TypeFunc* OptoRuntime::_multianewarray4_Type = nullptr;
205 const TypeFunc* OptoRuntime::_multianewarray5_Type = nullptr;
206 const TypeFunc* OptoRuntime::_multianewarrayN_Type = nullptr;
207 const TypeFunc* OptoRuntime::_complete_monitor_enter_Type = nullptr;
208 const TypeFunc* OptoRuntime::_complete_monitor_exit_Type = nullptr;
209 const TypeFunc* OptoRuntime::_monitor_notify_Type = nullptr;
210 const TypeFunc* OptoRuntime::_uncommon_trap_Type = nullptr;
211 const TypeFunc* OptoRuntime::_athrow_Type = nullptr;
212 const TypeFunc* OptoRuntime::_rethrow_Type = nullptr;
213 const TypeFunc* OptoRuntime::_Math_D_D_Type = nullptr;
214 const TypeFunc* OptoRuntime::_Math_DD_D_Type = nullptr;
215 const TypeFunc* OptoRuntime::_modf_Type = nullptr;
216 const TypeFunc* OptoRuntime::_l2f_Type = nullptr;
217 const TypeFunc* OptoRuntime::_void_long_Type = nullptr;
218 const TypeFunc* OptoRuntime::_void_void_Type = nullptr;
219 const TypeFunc* OptoRuntime::_jfr_write_checkpoint_Type = nullptr;
220 const TypeFunc* OptoRuntime::_flush_windows_Type = nullptr;
221 const TypeFunc* OptoRuntime::_fast_arraycopy_Type = nullptr;
312 oopDesc* dest, jint dest_pos,
313 jint length, JavaThread* thread) {
314 SharedRuntime::slow_arraycopy_C(src, src_pos, dest, dest_pos, length, thread);
315 }
316
317 void OptoRuntime::complete_monitor_locking_C(oopDesc* obj, BasicLock* lock, JavaThread* current) {
318 SharedRuntime::complete_monitor_locking_C(obj, lock, current);
319 }
320
321
322 //=============================================================================
323 // Opto compiler runtime routines
324 //=============================================================================
325
326
327 //=============================allocation======================================
328 // We failed the fast-path allocation. Now we need to do a scavenge or GC
329 // and try allocation again.
330
331 // object allocation
332 JRT_BLOCK_ENTRY(void, OptoRuntime::new_instance_C(Klass* klass, bool is_larval, JavaThread* current))
333 JRT_BLOCK;
334 #ifndef PRODUCT
335 SharedRuntime::_new_instance_ctr++; // new instance requires GC
336 #endif
337 assert(check_compiled_frame(current), "incorrect caller");
338
339 // These checks are cheap to make and support reflective allocation.
340 int lh = klass->layout_helper();
341 if (Klass::layout_helper_needs_slow_path(lh) || !InstanceKlass::cast(klass)->is_initialized()) {
342 Handle holder(current, klass->klass_holder()); // keep the klass alive
343 klass->check_valid_for_instantiation(false, THREAD);
344 if (!HAS_PENDING_EXCEPTION) {
345 InstanceKlass::cast(klass)->initialize(THREAD);
346 }
347 }
348
349 if (!HAS_PENDING_EXCEPTION) {
350 // Scavenge and allocate an instance.
351 Handle holder(current, klass->klass_holder()); // keep the klass alive
352 instanceOop result = InstanceKlass::cast(klass)->allocate_instance(THREAD);
353 if (is_larval) {
354 // Check if this is a larval buffer allocation
355 result->set_mark(result->mark().enter_larval_state());
356 }
357 current->set_vm_result_oop(result);
358
359 // Pass oops back through thread local storage. Our apparent type to Java
360 // is that we return an oop, but we can block on exit from this routine and
361 // a GC can trash the oop in C's return register. The generated stub will
362 // fetch the oop from TLS after any possible GC.
363 }
364
365 deoptimize_caller_frame(current, HAS_PENDING_EXCEPTION);
366 JRT_BLOCK_END;
367
368 // inform GC that we won't do card marks for initializing writes.
369 SharedRuntime::on_slowpath_allocation_exit(current);
370 JRT_END
371
372
373 // array allocation
374 JRT_BLOCK_ENTRY(void, OptoRuntime::new_array_C(Klass* array_type, int len, oopDesc* init_val, JavaThread* current))
375 JRT_BLOCK;
376 #ifndef PRODUCT
377 SharedRuntime::_new_array_ctr++; // new array requires GC
378 #endif
379 assert(check_compiled_frame(current), "incorrect caller");
380
381 // Scavenge and allocate an instance.
382 oop result;
383 Handle h_init_val(current, init_val); // keep the init_val object alive
384
385 if (array_type->is_flatArray_klass()) {
386 Handle holder(current, array_type->klass_holder()); // keep the array klass alive
387 FlatArrayKlass* fak = FlatArrayKlass::cast(array_type);
388 InlineKlass* vk = fak->element_klass();
389 result = oopFactory::new_flatArray(vk, len, fak->layout_kind(), THREAD);
390 if (array_type->is_null_free_array_klass() && !h_init_val.is_null()) {
391 // Null-free arrays need to be initialized
392 for (int i = 0; i < len; i++) {
393 vk->write_value_to_addr(h_init_val(), ((flatArrayOop)result)->value_at_addr(i, fak->layout_helper()), fak->layout_kind(), true, CHECK);
394 }
395 }
396 } else if (array_type->is_typeArray_klass()) {
397 // The oopFactory likes to work with the element type.
398 // (We could bypass the oopFactory, since it doesn't add much value.)
399 BasicType elem_type = TypeArrayKlass::cast(array_type)->element_type();
400 result = oopFactory::new_typeArray(elem_type, len, THREAD);
401 } else {
402 Handle holder(current, array_type->klass_holder()); // keep the array klass alive
403 ObjArrayKlass* array_klass = ObjArrayKlass::cast(array_type);
404 result = array_klass->allocate(len, THREAD);
405 if (array_type->is_null_free_array_klass() && !h_init_val.is_null()) {
406 // Null-free arrays need to be initialized
407 for (int i = 0; i < len; i++) {
408 ((objArrayOop)result)->obj_at_put(i, h_init_val());
409 }
410 }
411 }
412
413 // Pass oops back through thread local storage. Our apparent type to Java
414 // is that we return an oop, but we can block on exit from this routine and
415 // a GC can trash the oop in C's return register. The generated stub will
416 // fetch the oop from TLS after any possible GC.
417 deoptimize_caller_frame(current, HAS_PENDING_EXCEPTION);
418 current->set_vm_result_oop(result);
419 JRT_BLOCK_END;
420
421 // inform GC that we won't do card marks for initializing writes.
422 SharedRuntime::on_slowpath_allocation_exit(current);
423 JRT_END
424
425 // array allocation without zeroing
426 JRT_BLOCK_ENTRY(void, OptoRuntime::new_array_nozero_C(Klass* array_type, int len, JavaThread* current))
427 JRT_BLOCK;
428 #ifndef PRODUCT
429 SharedRuntime::_new_array_ctr++; // new array requires GC
430 #endif
587 JRT_BLOCK_ENTRY(void, OptoRuntime::monitor_notifyAll_C(oopDesc* obj, JavaThread* current))
588
589 if (!SafepointSynchronize::is_synchronizing() ) {
590 if (ObjectSynchronizer::quick_notify(obj, current, true)) {
591 return;
592 }
593 }
594
595 // This is the case the fast-path above isn't provisioned to handle.
596 // The fast-path is designed to handle frequently arising cases in an efficient manner.
597 // (The fast-path is just a degenerate variant of the slow-path).
598 // Perform the dreaded state transition and pass control into the slow-path.
599 JRT_BLOCK;
600 Handle h_obj(current, obj);
601 ObjectSynchronizer::notifyall(h_obj, CHECK);
602 JRT_BLOCK_END;
603 JRT_END
604
605 static const TypeFunc* make_new_instance_Type() {
606 // create input type (domain)
607 const Type **fields = TypeTuple::fields(2);
608 fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; // Klass to be allocated
609 fields[TypeFunc::Parms+1] = TypeInt::BOOL; // is_larval
610 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+2, fields);
611
612 // create result type (range)
613 fields = TypeTuple::fields(1);
614 fields[TypeFunc::Parms+0] = TypeRawPtr::NOTNULL; // Returned oop
615
616 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+1, fields);
617
618 return TypeFunc::make(domain, range);
619 }
620
621 #if INCLUDE_JVMTI
622 static const TypeFunc* make_notify_jvmti_vthread_Type() {
623 // create input type (domain)
624 const Type **fields = TypeTuple::fields(2);
625 fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; // VirtualThread oop
626 fields[TypeFunc::Parms+1] = TypeInt::BOOL; // jboolean
627 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+2,fields);
628
629 // no result type needed
630 fields = TypeTuple::fields(1);
633
634 return TypeFunc::make(domain,range);
635 }
636 #endif
637
638 static const TypeFunc* make_athrow_Type() {
639 // create input type (domain)
640 const Type **fields = TypeTuple::fields(1);
641 fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; // Klass to be allocated
642 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+1, fields);
643
644 // create result type (range)
645 fields = TypeTuple::fields(0);
646
647 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0, fields);
648
649 return TypeFunc::make(domain, range);
650 }
651
652 static const TypeFunc* make_new_array_Type() {
653 // create input type (domain)
654 const Type **fields = TypeTuple::fields(3);
655 fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; // element klass
656 fields[TypeFunc::Parms+1] = TypeInt::INT; // array size
657 fields[TypeFunc::Parms+2] = TypeInstPtr::NOTNULL; // init value
658 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+3, 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 static const TypeFunc* make_new_array_nozero_Type() {
670 // create input type (domain)
671 const Type **fields = TypeTuple::fields(2);
672 fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; // element klass
673 fields[TypeFunc::Parms+1] = TypeInt::INT; // array size
674 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+2, fields);
675
676 // create result type (range)
677 fields = TypeTuple::fields(1);
678 fields[TypeFunc::Parms+0] = TypeRawPtr::NOTNULL; // Returned oop
679
680 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+1, fields);
681
682 return TypeFunc::make(domain, range);
683 }
684
685 const TypeFunc* OptoRuntime::multianewarray_Type(int ndim) {
686 // create input type (domain)
687 const int nargs = ndim + 1;
688 const Type **fields = TypeTuple::fields(nargs);
689 fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; // element klass
725 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0, fields);
726
727 return TypeFunc::make(domain, range);
728 }
729
730 //-----------------------------------------------------------------------------
731 // Monitor Handling
732
733 static const TypeFunc* make_complete_monitor_enter_Type() {
734 // create input type (domain)
735 const Type **fields = TypeTuple::fields(2);
736 fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; // Object to be Locked
737 fields[TypeFunc::Parms+1] = TypeRawPtr::BOTTOM; // Address of stack location for lock
738 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+2,fields);
739
740 // create result type (range)
741 fields = TypeTuple::fields(0);
742
743 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0,fields);
744
745 return TypeFunc::make(domain, range);
746 }
747
748 //-----------------------------------------------------------------------------
749
750 static const TypeFunc* make_complete_monitor_exit_Type() {
751 // create input type (domain)
752 const Type **fields = TypeTuple::fields(3);
753 fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; // Object to be Locked
754 fields[TypeFunc::Parms+1] = TypeRawPtr::BOTTOM; // Address of stack location for lock - BasicLock
755 fields[TypeFunc::Parms+2] = TypeRawPtr::BOTTOM; // Thread pointer (Self)
756 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+3, fields);
757
758 // create result type (range)
759 fields = TypeTuple::fields(0);
760
761 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0, fields);
762
763 return TypeFunc::make(domain, range);
764 }
765
2103 RegisterMap::WalkContinuation::skip);
2104 frame stub_frame = thread->last_frame();
2105 assert(stub_frame.is_runtime_frame() || exception_blob()->contains(stub_frame.pc()), "sanity check");
2106 frame caller_frame = stub_frame.sender(®_map);
2107 return caller_frame.is_deoptimized_frame();
2108 }
2109
2110 static const TypeFunc* make_register_finalizer_Type() {
2111 // create input type (domain)
2112 const Type **fields = TypeTuple::fields(1);
2113 fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; // oop; Receiver
2114 // // The JavaThread* is passed to each routine as the last argument
2115 // fields[TypeFunc::Parms+1] = TypeRawPtr::NOTNULL; // JavaThread *; Executing thread
2116 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+1,fields);
2117
2118 // create result type (range)
2119 fields = TypeTuple::fields(0);
2120
2121 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0,fields);
2122
2123 return TypeFunc::make(domain, range);
2124 }
2125
2126 #if INCLUDE_JFR
2127 static const TypeFunc* make_class_id_load_barrier_Type() {
2128 // create input type (domain)
2129 const Type **fields = TypeTuple::fields(1);
2130 fields[TypeFunc::Parms+0] = TypeInstPtr::KLASS;
2131 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms + 1, fields);
2132
2133 // create result type (range)
2134 fields = TypeTuple::fields(0);
2135
2136 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms + 0, fields);
2137
2138 return TypeFunc::make(domain,range);
2139 }
2140 #endif // INCLUDE_JFR
2141
2142 //-----------------------------------------------------------------------------
2143 static const TypeFunc* make_dtrace_method_entry_exit_Type() {
2144 // create input type (domain)
2145 const Type **fields = TypeTuple::fields(2);
2146 fields[TypeFunc::Parms+0] = TypeRawPtr::BOTTOM; // Thread-local storage
2147 fields[TypeFunc::Parms+1] = TypeMetadataPtr::BOTTOM; // Method*; Method we are entering
2148 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+2,fields);
2149
2150 // create result type (range)
2151 fields = TypeTuple::fields(0);
2152
2153 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0,fields);
2154
2155 return TypeFunc::make(domain, range);
2156 }
2157
2158 static const TypeFunc* make_dtrace_object_alloc_Type() {
2159 // create input type (domain)
2160 const Type **fields = TypeTuple::fields(2);
2161 fields[TypeFunc::Parms+0] = TypeRawPtr::BOTTOM; // Thread-local storage
2162 fields[TypeFunc::Parms+1] = TypeInstPtr::NOTNULL; // oop; newly allocated object
2163
2164 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+2,fields);
2165
2166 // create result type (range)
2167 fields = TypeTuple::fields(0);
2168
2169 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0,fields);
2170
2171 return TypeFunc::make(domain, range);
2172 }
2173
2174 JRT_ENTRY_NO_ASYNC(void, OptoRuntime::register_finalizer_C(oopDesc* obj, JavaThread* current))
2175 assert(oopDesc::is_oop(obj), "must be a valid oop");
2176 assert(obj->klass()->has_finalizer(), "shouldn't be here otherwise");
2177 InstanceKlass::register_finalizer(instanceOop(obj), CHECK);
2178 JRT_END
2179
2180 //-----------------------------------------------------------------------------
2181
2182 NamedCounter * volatile OptoRuntime::_named_counters = nullptr;
2183
2184 //
2185 // dump the collected NamedCounters.
2186 //
2187 void OptoRuntime::print_named_counters() {
2188 int total_lock_count = 0;
2189 int eliminated_lock_count = 0;
2190
2191 NamedCounter* c = _named_counters;
2242 }
2243 st.print("@%d", bci);
2244 // To print linenumbers instead of bci use: m->line_number_from_bci(bci)
2245 }
2246 NamedCounter* c = new NamedCounter(st.freeze(), tag);
2247
2248 // atomically add the new counter to the head of the list. We only
2249 // add counters so this is safe.
2250 NamedCounter* head;
2251 do {
2252 c->set_next(nullptr);
2253 head = _named_counters;
2254 c->set_next(head);
2255 } while (Atomic::cmpxchg(&_named_counters, head, c) != head);
2256 return c;
2257 }
2258
2259 void OptoRuntime::initialize_types() {
2260 _new_instance_Type = make_new_instance_Type();
2261 _new_array_Type = make_new_array_Type();
2262 _new_array_nozero_Type = make_new_array_nozero_Type();
2263 _multianewarray2_Type = multianewarray_Type(2);
2264 _multianewarray3_Type = multianewarray_Type(3);
2265 _multianewarray4_Type = multianewarray_Type(4);
2266 _multianewarray5_Type = multianewarray_Type(5);
2267 _multianewarrayN_Type = make_multianewarrayN_Type();
2268 _complete_monitor_enter_Type = make_complete_monitor_enter_Type();
2269 _complete_monitor_exit_Type = make_complete_monitor_exit_Type();
2270 _monitor_notify_Type = make_monitor_notify_Type();
2271 _uncommon_trap_Type = make_uncommon_trap_Type();
2272 _athrow_Type = make_athrow_Type();
2273 _rethrow_Type = make_rethrow_Type();
2274 _Math_D_D_Type = make_Math_D_D_Type();
2275 _Math_DD_D_Type = make_Math_DD_D_Type();
2276 _modf_Type = make_modf_Type();
2277 _l2f_Type = make_l2f_Type();
2278 _void_long_Type = make_void_long_Type();
2279 _void_void_Type = make_void_void_Type();
2280 _jfr_write_checkpoint_Type = make_jfr_write_checkpoint_Type();
2281 _flush_windows_Type = make_flush_windows_Type();
2282 _fast_arraycopy_Type = make_arraycopy_Type(ac_fast);
2343 static void trace_exception(outputStream* st, oop exception_oop, address exception_pc, const char* msg) {
2344 trace_exception_counter++;
2345 stringStream tempst;
2346
2347 tempst.print("%d [Exception (%s): ", trace_exception_counter, msg);
2348 exception_oop->print_value_on(&tempst);
2349 tempst.print(" in ");
2350 CodeBlob* blob = CodeCache::find_blob(exception_pc);
2351 if (blob->is_nmethod()) {
2352 blob->as_nmethod()->method()->print_value_on(&tempst);
2353 } else if (blob->is_runtime_stub()) {
2354 tempst.print("<runtime-stub>");
2355 } else {
2356 tempst.print("<unknown>");
2357 }
2358 tempst.print(" at " INTPTR_FORMAT, p2i(exception_pc));
2359 tempst.print("]");
2360
2361 st->print_raw_cr(tempst.freeze());
2362 }
2363
2364 const TypeFunc *OptoRuntime::store_inline_type_fields_Type() {
2365 // create input type (domain)
2366 uint total = SharedRuntime::java_return_convention_max_int + SharedRuntime::java_return_convention_max_float*2;
2367 const Type **fields = TypeTuple::fields(total);
2368 // We don't know the number of returned values and their
2369 // types. Assume all registers available to the return convention
2370 // are used.
2371 fields[TypeFunc::Parms] = TypePtr::BOTTOM;
2372 uint i = 1;
2373 for (; i < SharedRuntime::java_return_convention_max_int; i++) {
2374 fields[TypeFunc::Parms+i] = TypeInt::INT;
2375 }
2376 for (; i < total; i+=2) {
2377 fields[TypeFunc::Parms+i] = Type::DOUBLE;
2378 fields[TypeFunc::Parms+i+1] = Type::HALF;
2379 }
2380 const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms + total, fields);
2381
2382 // create result type (range)
2383 fields = TypeTuple::fields(1);
2384 fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL;
2385
2386 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+1,fields);
2387
2388 return TypeFunc::make(domain, range);
2389 }
2390
2391 const TypeFunc *OptoRuntime::pack_inline_type_Type() {
2392 // create input type (domain)
2393 uint total = 1 + SharedRuntime::java_return_convention_max_int + SharedRuntime::java_return_convention_max_float*2;
2394 const Type **fields = TypeTuple::fields(total);
2395 // We don't know the number of returned values and their
2396 // types. Assume all registers available to the return convention
2397 // are used.
2398 fields[TypeFunc::Parms] = TypeRawPtr::BOTTOM;
2399 fields[TypeFunc::Parms+1] = TypeRawPtr::BOTTOM;
2400 uint i = 2;
2401 for (; i < SharedRuntime::java_return_convention_max_int+1; i++) {
2402 fields[TypeFunc::Parms+i] = TypeInt::INT;
2403 }
2404 for (; i < total; i+=2) {
2405 fields[TypeFunc::Parms+i] = Type::DOUBLE;
2406 fields[TypeFunc::Parms+i+1] = Type::HALF;
2407 }
2408 const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms + total, fields);
2409
2410 // create result type (range)
2411 fields = TypeTuple::fields(1);
2412 fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL;
2413
2414 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+1,fields);
2415
2416 return TypeFunc::make(domain, range);
2417 }
2418
2419 JRT_BLOCK_ENTRY(void, OptoRuntime::load_unknown_inline_C(flatArrayOopDesc* array, int index, JavaThread* current))
2420 JRT_BLOCK;
2421 oop buffer = array->read_value_from_flat_array(index, THREAD);
2422 deoptimize_caller_frame(current, HAS_PENDING_EXCEPTION);
2423 current->set_vm_result_oop(buffer);
2424 JRT_BLOCK_END;
2425 JRT_END
2426
2427 const TypeFunc* OptoRuntime::load_unknown_inline_Type() {
2428 // create input type (domain)
2429 const Type** fields = TypeTuple::fields(2);
2430 fields[TypeFunc::Parms] = TypeOopPtr::NOTNULL;
2431 fields[TypeFunc::Parms+1] = TypeInt::POS;
2432
2433 const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms+2, fields);
2434
2435 // create result type (range)
2436 fields = TypeTuple::fields(1);
2437 fields[TypeFunc::Parms] = TypeInstPtr::BOTTOM;
2438
2439 const TypeTuple* range = TypeTuple::make(TypeFunc::Parms+1, fields);
2440
2441 return TypeFunc::make(domain, range);
2442 }
2443
2444 JRT_BLOCK_ENTRY(void, OptoRuntime::store_unknown_inline_C(instanceOopDesc* buffer, flatArrayOopDesc* array, int index, JavaThread* current))
2445 JRT_BLOCK;
2446 array->write_value_to_flat_array(buffer, index, THREAD);
2447 if (HAS_PENDING_EXCEPTION) {
2448 fatal("This entry must be changed to be a non-leaf entry because writing to a flat array can now throw an exception");
2449 }
2450 JRT_BLOCK_END;
2451 JRT_END
2452
2453 const TypeFunc* OptoRuntime::store_unknown_inline_Type() {
2454 // create input type (domain)
2455 const Type** fields = TypeTuple::fields(3);
2456 fields[TypeFunc::Parms] = TypeInstPtr::NOTNULL;
2457 fields[TypeFunc::Parms+1] = TypeOopPtr::NOTNULL;
2458 fields[TypeFunc::Parms+2] = TypeInt::POS;
2459
2460 const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms+3, fields);
2461
2462 // create result type (range)
2463 fields = TypeTuple::fields(0);
2464 const TypeTuple* range = TypeTuple::make(TypeFunc::Parms, fields);
2465
2466 return TypeFunc::make(domain, range);
2467 }
|