1 /*
2 * Copyright (c) 1998, 2026, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 #include "classfile/vmClasses.hpp"
26 #include "classfile/vmSymbols.hpp"
27 #include "code/aotCodeCache.hpp"
28 #include "code/codeCache.hpp"
29 #include "code/compiledIC.hpp"
30 #include "code/nmethod.hpp"
31 #include "code/pcDesc.hpp"
32 #include "code/scopeDesc.hpp"
33 #include "code/vtableStubs.hpp"
34 #include "compiler/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"
76 #include "runtime/signature.hpp"
77 #include "runtime/stackWatermarkSet.hpp"
78 #include "runtime/synchronizer.hpp"
79 #include "runtime/threadWXSetters.inline.hpp"
80 #include "runtime/vframe.hpp"
81 #include "runtime/vframe_hp.hpp"
82 #include "runtime/vframeArray.hpp"
83 #include "utilities/copy.hpp"
84 #include "utilities/preserveException.hpp"
85
86
87 // For debugging purposes:
88 // To force FullGCALot inside a runtime function, add the following two lines
89 //
90 // Universe::release_fullgc_alot_dummy();
91 // Universe::heap()->collect();
92 //
93 // At command line specify the parameters: -XX:+FullGCALot -XX:FullGCALotStart=100000000
94
95
96 #define C2_BLOB_FIELD_DEFINE(name, type) \
97 type* OptoRuntime:: BLOB_FIELD_NAME(name) = nullptr;
98 #define C2_STUB_FIELD_NAME(name) _ ## name ## _Java
99 #define C2_STUB_FIELD_DEFINE(name, f, t, r) \
100 address OptoRuntime:: C2_STUB_FIELD_NAME(name) = nullptr;
101 C2_STUBS_DO(C2_BLOB_FIELD_DEFINE, C2_STUB_FIELD_DEFINE)
102 #undef C2_BLOB_FIELD_DEFINE
103 #undef C2_STUB_FIELD_DEFINE
104
105 // This should be called in an assertion at the start of OptoRuntime routines
106 // which are entered from compiled code (all of them)
107 #ifdef ASSERT
108 static bool check_compiled_frame(JavaThread* thread) {
109 assert(thread->last_frame().is_runtime_frame(), "cannot call runtime directly from compiled code");
110 RegisterMap map(thread,
111 RegisterMap::UpdateMap::skip,
112 RegisterMap::ProcessFrames::include,
113 RegisterMap::WalkContinuation::skip);
114 frame caller = thread->last_frame().sender(&map);
115 assert(caller.is_compiled_frame(), "not being called from compiled like code");
116 return true;
117 }
118 #endif // ASSERT
119
120 /*
121 #define gen(env, var, type_func_gen, c_func, fancy_jump, pass_tls, return_pc) \
122 var = generate_stub(env, type_func_gen, CAST_FROM_FN_PTR(address, c_func), #var, fancy_jump, pass_tls, return_pc); \
123 if (var == nullptr) { return false; }
124 */
125
126 #define GEN_C2_BLOB(name, type) \
127 BLOB_FIELD_NAME(name) = \
128 generate_ ## name ## _blob(); \
129 if (BLOB_FIELD_NAME(name) == nullptr) { return false; }
130
131 // a few helper macros to conjure up generate_stub call arguments
132 #define C2_STUB_FIELD_NAME(name) _ ## name ## _Java
133 #define C2_STUB_TYPEFUNC(name) name ## _Type
134 #define C2_STUB_C_FUNC(name) CAST_FROM_FN_PTR(address, name ## _C)
135 #define C2_STUB_ID(name) StubId:: JOIN3(c2, name, id)
136 #define C2_STUB_NAME(name) stub_name(C2_STUB_ID(name))
137
138 // Almost all the C functions targeted from the generated stubs are
139 // implemented locally to OptoRuntime with names that can be generated
140 // from the stub name by appending suffix '_C'. However, in two cases
141 // a common target method also needs to be called from shared runtime
142 // stubs. In these two cases the opto stubs rely on method
143 // imlementations defined in class SharedRuntime. The following
144 // defines temporarily rebind the generated names to reference the
145 // relevant implementations.
146
147 #define GEN_C2_STUB(name, fancy_jump, pass_tls, pass_retpc ) \
148 C2_STUB_FIELD_NAME(name) = \
149 generate_stub(env, \
150 C2_STUB_TYPEFUNC(name), \
151 C2_STUB_C_FUNC(name), \
152 C2_STUB_NAME(name), \
153 C2_STUB_ID(name), \
154 fancy_jump, \
155 pass_tls, \
156 pass_retpc); \
157 if (C2_STUB_FIELD_NAME(name) == nullptr) { return false; } \
158
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;
200 const TypeFunc* OptoRuntime::_checkcast_arraycopy_Type = nullptr;
201 const TypeFunc* OptoRuntime::_generic_arraycopy_Type = nullptr;
202 const TypeFunc* OptoRuntime::_slow_arraycopy_Type = nullptr;
203 const TypeFunc* OptoRuntime::_unsafe_setmemory_Type = nullptr;
204 const TypeFunc* OptoRuntime::_array_fill_Type = nullptr;
205 const TypeFunc* OptoRuntime::_array_sort_Type = nullptr;
206 const TypeFunc* OptoRuntime::_array_partition_Type = nullptr;
207 const TypeFunc* OptoRuntime::_aescrypt_block_Type = nullptr;
208 const TypeFunc* OptoRuntime::_cipherBlockChaining_aescrypt_Type = nullptr;
209 const TypeFunc* OptoRuntime::_electronicCodeBook_aescrypt_Type = nullptr;
210 const TypeFunc* OptoRuntime::_counterMode_aescrypt_Type = nullptr;
211 const TypeFunc* OptoRuntime::_galoisCounterMode_aescrypt_Type = nullptr;
212 const TypeFunc* OptoRuntime::_digestBase_implCompress_with_sha3_Type = nullptr;
213 const TypeFunc* OptoRuntime::_digestBase_implCompress_without_sha3_Type = nullptr;
214 const TypeFunc* OptoRuntime::_digestBase_implCompressMB_with_sha3_Type = nullptr;
215 const TypeFunc* OptoRuntime::_digestBase_implCompressMB_without_sha3_Type = nullptr;
216 const TypeFunc* OptoRuntime::_double_keccak_Type = nullptr;
217 const TypeFunc* OptoRuntime::_multiplyToLen_Type = nullptr;
218 const TypeFunc* OptoRuntime::_montgomeryMultiply_Type = nullptr;
219 const TypeFunc* OptoRuntime::_montgomerySquare_Type = nullptr;
220 const TypeFunc* OptoRuntime::_squareToLen_Type = nullptr;
221 const TypeFunc* OptoRuntime::_mulAdd_Type = nullptr;
222 const TypeFunc* OptoRuntime::_bigIntegerShift_Type = nullptr;
223 const TypeFunc* OptoRuntime::_vectorizedMismatch_Type = nullptr;
224 const TypeFunc* OptoRuntime::_ghash_processBlocks_Type = nullptr;
225 const TypeFunc* OptoRuntime::_chacha20Block_Type = nullptr;
226 const TypeFunc* OptoRuntime::_kyberNtt_Type = nullptr;
227 const TypeFunc* OptoRuntime::_kyberInverseNtt_Type = nullptr;
228 const TypeFunc* OptoRuntime::_kyberNttMult_Type = nullptr;
229 const TypeFunc* OptoRuntime::_kyberAddPoly_2_Type = nullptr;
230 const TypeFunc* OptoRuntime::_kyberAddPoly_3_Type = nullptr;
231 const TypeFunc* OptoRuntime::_kyber12To16_Type = nullptr;
232 const TypeFunc* OptoRuntime::_kyberBarrettReduce_Type = nullptr;
233 const TypeFunc* OptoRuntime::_dilithiumAlmostNtt_Type = nullptr;
234 const TypeFunc* OptoRuntime::_dilithiumAlmostInverseNtt_Type = nullptr;
235 const TypeFunc* OptoRuntime::_dilithiumNttMult_Type = nullptr;
236 const TypeFunc* OptoRuntime::_dilithiumMontMulByConstant_Type = nullptr;
237 const TypeFunc* OptoRuntime::_dilithiumDecomposePoly_Type = nullptr;
238 const TypeFunc* OptoRuntime::_base64_encodeBlock_Type = nullptr;
239 const TypeFunc* OptoRuntime::_base64_decodeBlock_Type = nullptr;
240 const TypeFunc* OptoRuntime::_string_IndexOf_Type = nullptr;
241 const TypeFunc* OptoRuntime::_poly1305_processBlocks_Type = nullptr;
242 const TypeFunc* OptoRuntime::_intpoly_montgomeryMult_P256_Type = nullptr;
243 const TypeFunc* OptoRuntime::_intpoly_assign_Type = nullptr;
244 const TypeFunc* OptoRuntime::_updateBytesCRC32_Type = nullptr;
245 const TypeFunc* OptoRuntime::_updateBytesCRC32C_Type = nullptr;
246 const TypeFunc* OptoRuntime::_updateBytesAdler32_Type = nullptr;
247 const TypeFunc* OptoRuntime::_osr_end_Type = nullptr;
248 const TypeFunc* OptoRuntime::_register_finalizer_Type = nullptr;
249 const TypeFunc* OptoRuntime::_vthread_transition_Type = nullptr;
250 #if INCLUDE_JFR
251 const TypeFunc* OptoRuntime::_class_id_load_barrier_Type = nullptr;
252 #endif // INCLUDE_JFR
253 const TypeFunc* OptoRuntime::_dtrace_method_entry_exit_Type = nullptr;
254 const TypeFunc* OptoRuntime::_dtrace_object_alloc_Type = nullptr;
255
256 // Helper method to do generation of RunTimeStub's
257 address OptoRuntime::generate_stub(ciEnv* env,
258 TypeFunc_generator gen, address C_function,
259 const char *name, StubId stub_id,
260 int is_fancy_jump, bool pass_tls,
261 bool return_pc) {
262
263 // Matching the default directive, we currently have no method to match.
264 CompilerDirectiveMatcher default_directive(CompileBroker::compiler(CompLevel_full_optimization));
265 CompilationMemoryStatisticMark cmsm(default_directive.directive_set());
266 ResourceMark rm;
267 Compile C(env, gen, C_function, name, stub_id, is_fancy_jump, pass_tls, return_pc, default_directive.directive_set());
268 return C.stub_entry_point();
269 }
270
271 const char* OptoRuntime::stub_name(address entry) {
272 #ifndef PRODUCT
273 CodeBlob* cb = CodeCache::find_blob(entry);
274 RuntimeStub* rs =(RuntimeStub *)cb;
275 assert(rs != nullptr && rs->is_runtime_stub(), "not a runtime stub");
276 return rs->name();
277 #else
278 // Fast implementation for product mode (maybe it should be inlined too)
279 return "runtime stub";
280 #endif
281 }
282
283 // local methods passed as arguments to stub generator that forward
284 // control to corresponding JRT methods of SharedRuntime
285
286 void OptoRuntime::slow_arraycopy_C(oopDesc* src, jint src_pos,
287 oopDesc* dest, jint dest_pos,
288 jint length, JavaThread* thread) {
289 SharedRuntime::slow_arraycopy_C(src, src_pos, dest, dest_pos, length, thread);
290 }
291
292 void OptoRuntime::complete_monitor_locking_C(oopDesc* obj, BasicLock* lock, JavaThread* current) {
293 SharedRuntime::complete_monitor_locking_C(obj, lock, current);
294 }
295
296
297 //=============================================================================
298 // Opto compiler runtime routines
299 //=============================================================================
300
301
302 //=============================allocation======================================
303 // We failed the fast-path allocation. Now we need to do a scavenge or GC
304 // and try allocation again.
305
306 // object allocation
307 JRT_BLOCK_ENTRY(void, OptoRuntime::new_instance_C(Klass* klass, JavaThread* current))
308 JRT_BLOCK;
309 #ifndef PRODUCT
310 SharedRuntime::_new_instance_ctr++; // new instance requires GC
311 #endif
312 assert(check_compiled_frame(current), "incorrect caller");
313
314 // These checks are cheap to make and support reflective allocation.
315 int lh = klass->layout_helper();
316 if (Klass::layout_helper_needs_slow_path(lh) || !InstanceKlass::cast(klass)->is_initialized()) {
317 Handle holder(current, klass->klass_holder()); // keep the klass alive
318 klass->check_valid_for_instantiation(false, THREAD);
319 if (!HAS_PENDING_EXCEPTION) {
320 InstanceKlass::cast(klass)->initialize(THREAD);
321 }
322 }
323
324 if (!HAS_PENDING_EXCEPTION) {
325 // Scavenge and allocate an instance.
326 Handle holder(current, klass->klass_holder()); // keep the klass alive
327 oop result = InstanceKlass::cast(klass)->allocate_instance(THREAD);
328 current->set_vm_result_oop(result);
329
330 // Pass oops back through thread local storage. Our apparent type to Java
331 // is that we return an oop, but we can block on exit from this routine and
332 // a GC can trash the oop in C's return register. The generated stub will
333 // fetch the oop from TLS after any possible GC.
334 }
335
336 deoptimize_caller_frame(current, HAS_PENDING_EXCEPTION);
337 JRT_BLOCK_END;
338
339 // inform GC that we won't do card marks for initializing writes.
340 SharedRuntime::on_slowpath_allocation_exit(current);
341 JRT_END
342
343
344 // array allocation
345 JRT_BLOCK_ENTRY(void, OptoRuntime::new_array_C(Klass* array_type, int len, oopDesc* init_val, JavaThread* current))
346 JRT_BLOCK;
347 #ifndef PRODUCT
348 SharedRuntime::_new_array_ctr++; // new array requires GC
349 #endif
350 assert(check_compiled_frame(current), "incorrect caller");
351
352 // Scavenge and allocate an instance.
353 oop result;
354 Handle h_init_val(current, init_val); // keep the init_val object alive
355
356 if (array_type->is_typeArray_klass()) {
357 // The oopFactory likes to work with the element type.
358 // (We could bypass the oopFactory, since it doesn't add much value.)
359 BasicType elem_type = TypeArrayKlass::cast(array_type)->element_type();
360 result = oopFactory::new_typeArray(elem_type, len, THREAD);
361 } else {
362 Handle holder(current, array_type->klass_holder()); // keep the array klass alive
363 ObjArrayKlass* oak = ObjArrayKlass::cast(array_type);
364 result = oopFactory::new_objArray(oak->element_klass(), len, oak->properties(), THREAD);
365 if (!HAS_PENDING_EXCEPTION && array_type->is_null_free_array_klass() && !h_init_val.is_null()) {
366 // Null-free arrays need to be initialized
367 #ifdef ASSERT
368 ObjArrayKlass* result_oak = ObjArrayKlass::cast(result->klass());
369 assert(result_oak->is_null_free_array_klass(), "Sanity check");
370 #endif
371 for (int i = 0; i < len; i++) {
372 ((objArrayOop)result)->obj_at_put(i, h_init_val());
373 }
374 }
375 }
376
377 // Pass oops back through thread local storage. Our apparent type to Java
378 // is that we return an oop, but we can block on exit from this routine and
379 // a GC can trash the oop in C's return register. The generated stub will
380 // fetch the oop from TLS after any possible GC.
381 deoptimize_caller_frame(current, HAS_PENDING_EXCEPTION);
382 current->set_vm_result_oop(result);
383 JRT_BLOCK_END;
384
385 // inform GC that we won't do card marks for initializing writes.
386 SharedRuntime::on_slowpath_allocation_exit(current);
387 JRT_END
388
389 // array allocation without zeroing
390 JRT_BLOCK_ENTRY(void, OptoRuntime::new_array_nozero_C(Klass* array_type, int len, JavaThread* current))
391 JRT_BLOCK;
392 #ifndef PRODUCT
393 SharedRuntime::_new_array_ctr++; // new array requires GC
394 #endif
395 assert(check_compiled_frame(current), "incorrect caller");
396
397 // Scavenge and allocate an instance.
398 oop result;
399
400 assert(array_type->is_typeArray_klass(), "should be called only for type array");
401 // The oopFactory likes to work with the element type.
402 BasicType elem_type = TypeArrayKlass::cast(array_type)->element_type();
403 result = oopFactory::new_typeArray_nozero(elem_type, len, THREAD);
404
405 // Pass oops back through thread local storage. Our apparent type to Java
406 // is that we return an oop, but we can block on exit from this routine and
407 // a GC can trash the oop in C's return register. The generated stub will
408 // fetch the oop from TLS after any possible GC.
409 deoptimize_caller_frame(current, HAS_PENDING_EXCEPTION);
410 current->set_vm_result_oop(result);
411 JRT_BLOCK_END;
412
413
414 // inform GC that we won't do card marks for initializing writes.
415 SharedRuntime::on_slowpath_allocation_exit(current);
416
417 oop result = current->vm_result_oop();
418 if ((len > 0) && (result != nullptr) &&
419 is_deoptimized_caller_frame(current)) {
420 // Zero array here if the caller is deoptimized.
421 const size_t size = TypeArrayKlass::cast(array_type)->oop_size(result);
422 BasicType elem_type = TypeArrayKlass::cast(array_type)->element_type();
423 size_t hs_bytes = arrayOopDesc::base_offset_in_bytes(elem_type);
424 assert(is_aligned(hs_bytes, BytesPerInt), "must be 4 byte aligned");
425 HeapWord* obj = cast_from_oop<HeapWord*>(result);
426 if (!is_aligned(hs_bytes, BytesPerLong)) {
427 *reinterpret_cast<jint*>(reinterpret_cast<char*>(obj) + hs_bytes) = 0;
428 hs_bytes += BytesPerInt;
429 }
430
431 // Optimized zeroing.
432 assert(is_aligned(hs_bytes, BytesPerLong), "must be 8-byte aligned");
433 const size_t aligned_hs = hs_bytes / BytesPerLong;
434 Copy::fill_to_aligned_words(obj+aligned_hs, size-aligned_hs);
435 }
436
437 JRT_END
438
439 // Note: multianewarray for one dimension is handled inline by GraphKit::new_array.
440
441 // multianewarray for 2 dimensions
442 JRT_ENTRY(void, OptoRuntime::multianewarray2_C(Klass* elem_type, int len1, int len2, JavaThread* current))
443 #ifndef PRODUCT
444 SharedRuntime::_multi2_ctr++; // multianewarray for 1 dimension
445 #endif
446 assert(check_compiled_frame(current), "incorrect caller");
447 assert(elem_type->is_klass(), "not a class");
448 jint dims[2];
449 dims[0] = len1;
450 dims[1] = len2;
451 Handle holder(current, elem_type->klass_holder()); // keep the klass alive
452 oop obj = ArrayKlass::cast(elem_type)->multi_allocate(2, dims, THREAD);
453 deoptimize_caller_frame(current, HAS_PENDING_EXCEPTION);
454 current->set_vm_result_oop(obj);
455 JRT_END
456
457 // multianewarray for 3 dimensions
458 JRT_ENTRY(void, OptoRuntime::multianewarray3_C(Klass* elem_type, int len1, int len2, int len3, JavaThread* current))
459 #ifndef PRODUCT
460 SharedRuntime::_multi3_ctr++; // multianewarray for 1 dimension
461 #endif
462 assert(check_compiled_frame(current), "incorrect caller");
463 assert(elem_type->is_klass(), "not a class");
464 jint dims[3];
465 dims[0] = len1;
466 dims[1] = len2;
467 dims[2] = len3;
468 Handle holder(current, elem_type->klass_holder()); // keep the klass alive
469 oop obj = ArrayKlass::cast(elem_type)->multi_allocate(3, dims, THREAD);
470 deoptimize_caller_frame(current, HAS_PENDING_EXCEPTION);
471 current->set_vm_result_oop(obj);
472 JRT_END
473
474 // multianewarray for 4 dimensions
475 JRT_ENTRY(void, OptoRuntime::multianewarray4_C(Klass* elem_type, int len1, int len2, int len3, int len4, JavaThread* current))
476 #ifndef PRODUCT
477 SharedRuntime::_multi4_ctr++; // multianewarray for 1 dimension
478 #endif
479 assert(check_compiled_frame(current), "incorrect caller");
480 assert(elem_type->is_klass(), "not a class");
481 jint dims[4];
482 dims[0] = len1;
483 dims[1] = len2;
484 dims[2] = len3;
485 dims[3] = len4;
486 Handle holder(current, elem_type->klass_holder()); // keep the klass alive
487 oop obj = ArrayKlass::cast(elem_type)->multi_allocate(4, dims, THREAD);
488 deoptimize_caller_frame(current, HAS_PENDING_EXCEPTION);
489 current->set_vm_result_oop(obj);
490 JRT_END
491
492 // multianewarray for 5 dimensions
493 JRT_ENTRY(void, OptoRuntime::multianewarray5_C(Klass* elem_type, int len1, int len2, int len3, int len4, int len5, JavaThread* current))
494 #ifndef PRODUCT
495 SharedRuntime::_multi5_ctr++; // multianewarray for 1 dimension
496 #endif
497 assert(check_compiled_frame(current), "incorrect caller");
498 assert(elem_type->is_klass(), "not a class");
499 jint dims[5];
500 dims[0] = len1;
501 dims[1] = len2;
502 dims[2] = len3;
503 dims[3] = len4;
504 dims[4] = len5;
505 Handle holder(current, elem_type->klass_holder()); // keep the klass alive
506 oop obj = ArrayKlass::cast(elem_type)->multi_allocate(5, dims, THREAD);
507 deoptimize_caller_frame(current, HAS_PENDING_EXCEPTION);
508 current->set_vm_result_oop(obj);
509 JRT_END
510
511 JRT_ENTRY(void, OptoRuntime::multianewarrayN_C(Klass* elem_type, arrayOopDesc* dims, JavaThread* current))
512 assert(check_compiled_frame(current), "incorrect caller");
513 assert(elem_type->is_klass(), "not a class");
514 assert(oop(dims)->is_typeArray(), "not an array");
515
516 ResourceMark rm;
517 jint len = dims->length();
518 assert(len > 0, "Dimensions array should contain data");
519 jint *c_dims = NEW_RESOURCE_ARRAY(jint, len);
520 ArrayAccess<>::arraycopy_to_native<>(dims, typeArrayOopDesc::element_offset<jint>(0),
521 c_dims, len);
522
523 Handle holder(current, elem_type->klass_holder()); // keep the klass alive
524 oop obj = ArrayKlass::cast(elem_type)->multi_allocate(len, c_dims, THREAD);
525 deoptimize_caller_frame(current, HAS_PENDING_EXCEPTION);
526 current->set_vm_result_oop(obj);
527 JRT_END
528
529 JRT_BLOCK_ENTRY(void, OptoRuntime::monitor_notify_C(oopDesc* obj, JavaThread* current))
530
531 // Very few notify/notifyAll operations find any threads on the waitset, so
532 // the dominant fast-path is to simply return.
533 // Relatedly, it's critical that notify/notifyAll be fast in order to
534 // reduce lock hold times.
535 if (!SafepointSynchronize::is_synchronizing()) {
536 if (ObjectSynchronizer::quick_notify(obj, current, false)) {
537 return;
538 }
539 }
540
541 // This is the case the fast-path above isn't provisioned to handle.
542 // The fast-path is designed to handle frequently arising cases in an efficient manner.
543 // (The fast-path is just a degenerate variant of the slow-path).
544 // Perform the dreaded state transition and pass control into the slow-path.
545 JRT_BLOCK;
546 Handle h_obj(current, obj);
547 ObjectSynchronizer::notify(h_obj, CHECK);
548 JRT_BLOCK_END;
549 JRT_END
550
551 JRT_BLOCK_ENTRY(void, OptoRuntime::monitor_notifyAll_C(oopDesc* obj, JavaThread* current))
552
553 if (!SafepointSynchronize::is_synchronizing() ) {
554 if (ObjectSynchronizer::quick_notify(obj, current, true)) {
555 return;
556 }
557 }
558
559 // This is the case the fast-path above isn't provisioned to handle.
560 // The fast-path is designed to handle frequently arising cases in an efficient manner.
561 // (The fast-path is just a degenerate variant of the slow-path).
562 // Perform the dreaded state transition and pass control into the slow-path.
563 JRT_BLOCK;
564 Handle h_obj(current, obj);
565 ObjectSynchronizer::notifyall(h_obj, CHECK);
566 JRT_BLOCK_END;
567 JRT_END
568
569 JRT_ENTRY(void, OptoRuntime::vthread_end_first_transition_C(oopDesc* vt, jboolean is_mount, JavaThread* current))
570 MountUnmountDisabler::end_transition(current, vt, true /*is_mount*/, true /*is_thread_start*/);
571 JRT_END
572
573 JRT_ENTRY(void, OptoRuntime::vthread_start_final_transition_C(oopDesc* vt, jboolean is_mount, JavaThread* current))
574 java_lang_Thread::set_is_in_vthread_transition(vt, false);
575 current->set_is_in_vthread_transition(false);
576 MountUnmountDisabler::start_transition(current, vt, false /*is_mount */, true /*is_thread_end*/);
577 JRT_END
578
579 JRT_ENTRY(void, OptoRuntime::vthread_start_transition_C(oopDesc* vt, jboolean is_mount, JavaThread* current))
580 java_lang_Thread::set_is_in_vthread_transition(vt, false);
581 current->set_is_in_vthread_transition(false);
582 MountUnmountDisabler::start_transition(current, vt, is_mount, false /*is_thread_end*/);
583 JRT_END
584
585 JRT_ENTRY(void, OptoRuntime::vthread_end_transition_C(oopDesc* vt, jboolean is_mount, JavaThread* current))
586 MountUnmountDisabler::end_transition(current, vt, is_mount, false /*is_thread_start*/);
587 JRT_END
588
589 static const TypeFunc* make_new_instance_Type() {
590 // create input type (domain)
591 const Type **fields = TypeTuple::fields(1);
592 fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; // Klass to be allocated
593 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+1, fields);
594
595 // create result type (range)
596 fields = TypeTuple::fields(1);
597 fields[TypeFunc::Parms+0] = TypeRawPtr::NOTNULL; // Returned oop
598
599 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+1, fields);
600
601 return TypeFunc::make(domain, range);
602 }
603
604 static const TypeFunc* make_vthread_transition_Type() {
605 // create input type (domain)
606 const Type **fields = TypeTuple::fields(2);
607 fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; // VirtualThread oop
608 fields[TypeFunc::Parms+1] = TypeInt::BOOL; // jboolean
609 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+2,fields);
610
611 // no result type needed
612 fields = TypeTuple::fields(1);
613 fields[TypeFunc::Parms+0] = nullptr; // void
614 const TypeTuple* range = TypeTuple::make(TypeFunc::Parms, fields);
615
616 return TypeFunc::make(domain,range);
617 }
618
619 static const TypeFunc* make_athrow_Type() {
620 // create input type (domain)
621 const Type **fields = TypeTuple::fields(1);
622 fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; // Klass to be allocated
623 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+1, fields);
624
625 // create result type (range)
626 fields = TypeTuple::fields(0);
627
628 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0, fields);
629
630 return TypeFunc::make(domain, range);
631 }
632
633 static const TypeFunc* make_new_array_Type() {
634 // create input type (domain)
635 const Type **fields = TypeTuple::fields(3);
636 fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; // element klass
637 fields[TypeFunc::Parms+1] = TypeInt::INT; // array size
638 fields[TypeFunc::Parms+2] = TypeInstPtr::NOTNULL; // init value
639 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+3, fields);
640
641 // create result type (range)
642 fields = TypeTuple::fields(1);
643 fields[TypeFunc::Parms+0] = TypeRawPtr::NOTNULL; // Returned oop
644
645 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+1, fields);
646
647 return TypeFunc::make(domain, range);
648 }
649
650 static const TypeFunc* make_new_array_nozero_Type() {
651 // create input type (domain)
652 const Type **fields = TypeTuple::fields(2);
653 fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; // element klass
654 fields[TypeFunc::Parms+1] = TypeInt::INT; // array size
655 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+2, fields);
656
657 // create result type (range)
658 fields = TypeTuple::fields(1);
659 fields[TypeFunc::Parms+0] = TypeRawPtr::NOTNULL; // Returned oop
660
661 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+1, fields);
662
663 return TypeFunc::make(domain, range);
664 }
665
666 const TypeFunc* OptoRuntime::multianewarray_Type(int ndim) {
667 // create input type (domain)
668 const int nargs = ndim + 1;
669 const Type **fields = TypeTuple::fields(nargs);
670 fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; // element klass
671 for( int i = 1; i < nargs; i++ )
672 fields[TypeFunc::Parms + i] = TypeInt::INT; // array size
673 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+nargs, fields);
674
675 // create result type (range)
676 fields = TypeTuple::fields(1);
677 fields[TypeFunc::Parms+0] = TypeRawPtr::NOTNULL; // Returned oop
678 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+1, fields);
679
680 return TypeFunc::make(domain, range);
681 }
682
683 static const TypeFunc* make_multianewarrayN_Type() {
684 // create input type (domain)
685 const Type **fields = TypeTuple::fields(2);
686 fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; // element klass
687 fields[TypeFunc::Parms+1] = TypeInstPtr::NOTNULL; // array of dim sizes
688 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+2, fields);
689
690 // create result type (range)
691 fields = TypeTuple::fields(1);
692 fields[TypeFunc::Parms+0] = TypeRawPtr::NOTNULL; // Returned oop
693 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+1, fields);
694
695 return TypeFunc::make(domain, range);
696 }
697
698 static const TypeFunc* make_uncommon_trap_Type() {
699 // create input type (domain)
700 const Type **fields = TypeTuple::fields(1);
701 fields[TypeFunc::Parms+0] = TypeInt::INT; // trap_reason (deopt reason and action)
702 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+1, fields);
703
704 // create result type (range)
705 fields = TypeTuple::fields(0);
706 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0, fields);
707
708 return TypeFunc::make(domain, range);
709 }
710
711 //-----------------------------------------------------------------------------
712 // Monitor Handling
713
714 static const TypeFunc* make_complete_monitor_enter_Type() {
715 // create input type (domain)
716 const Type **fields = TypeTuple::fields(2);
717 fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; // Object to be Locked
718 fields[TypeFunc::Parms+1] = TypeRawPtr::BOTTOM; // Address of stack location for lock
719 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+2,fields);
720
721 // create result type (range)
722 fields = TypeTuple::fields(0);
723
724 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0,fields);
725
726 return TypeFunc::make(domain, range);
727 }
728
729 //-----------------------------------------------------------------------------
730
731 static const TypeFunc* make_complete_monitor_exit_Type() {
732 // create input type (domain)
733 const Type **fields = TypeTuple::fields(3);
734 fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; // Object to be Locked
735 fields[TypeFunc::Parms+1] = TypeRawPtr::BOTTOM; // Address of stack location for lock - BasicLock
736 fields[TypeFunc::Parms+2] = TypeRawPtr::BOTTOM; // Thread pointer (Self)
737 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+3, fields);
738
739 // create result type (range)
740 fields = TypeTuple::fields(0);
741
742 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0, fields);
743
744 return TypeFunc::make(domain, range);
745 }
746
747 static const TypeFunc* make_monitor_notify_Type() {
748 // create input type (domain)
749 const Type **fields = TypeTuple::fields(1);
750 fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; // Object to be Locked
751 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+1, fields);
752
753 // create result type (range)
754 fields = TypeTuple::fields(0);
755 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0, fields);
756 return TypeFunc::make(domain, range);
757 }
758
759 static const TypeFunc* make_flush_windows_Type() {
760 // create input type (domain)
761 const Type** fields = TypeTuple::fields(1);
762 fields[TypeFunc::Parms+0] = nullptr; // void
763 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms, fields);
764
765 // create result type
766 fields = TypeTuple::fields(1);
767 fields[TypeFunc::Parms+0] = nullptr; // void
768 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms, fields);
769
770 return TypeFunc::make(domain, range);
771 }
772
773 static const TypeFunc* make_l2f_Type() {
774 // create input type (domain)
775 const Type **fields = TypeTuple::fields(2);
776 fields[TypeFunc::Parms+0] = TypeLong::LONG;
777 fields[TypeFunc::Parms+1] = Type::HALF;
778 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+2, fields);
779
780 // create result type (range)
781 fields = TypeTuple::fields(1);
782 fields[TypeFunc::Parms+0] = Type::FLOAT;
783 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+1, fields);
784
785 return TypeFunc::make(domain, range);
786 }
787
788 static const TypeFunc* make_modf_Type() {
789 const Type **fields = TypeTuple::fields(2);
790 fields[TypeFunc::Parms+0] = Type::FLOAT;
791 fields[TypeFunc::Parms+1] = Type::FLOAT;
792 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+2, fields);
793
794 // create result type (range)
795 fields = TypeTuple::fields(1);
796 fields[TypeFunc::Parms+0] = Type::FLOAT;
797
798 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+1, fields);
799
800 return TypeFunc::make(domain, range);
801 }
802
803 static const TypeFunc* make_Math_D_D_Type() {
804 // create input type (domain)
805 const Type **fields = TypeTuple::fields(2);
806 // Symbol* name of class to be loaded
807 fields[TypeFunc::Parms+0] = Type::DOUBLE;
808 fields[TypeFunc::Parms+1] = Type::HALF;
809 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+2, fields);
810
811 // create result type (range)
812 fields = TypeTuple::fields(2);
813 fields[TypeFunc::Parms+0] = Type::DOUBLE;
814 fields[TypeFunc::Parms+1] = Type::HALF;
815 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+2, fields);
816
817 return TypeFunc::make(domain, range);
818 }
819
820 const TypeFunc* OptoRuntime::Math_Vector_Vector_Type(uint num_arg, const TypeVect* in_type, const TypeVect* out_type) {
821 // create input type (domain)
822 const Type **fields = TypeTuple::fields(num_arg);
823 // Symbol* name of class to be loaded
824 assert(num_arg > 0, "must have at least 1 input");
825 for (uint i = 0; i < num_arg; i++) {
826 fields[TypeFunc::Parms+i] = in_type;
827 }
828 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+num_arg, fields);
829
830 // create result type (range)
831 const uint num_ret = 1;
832 fields = TypeTuple::fields(num_ret);
833 fields[TypeFunc::Parms+0] = out_type;
834 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+num_ret, fields);
835
836 return TypeFunc::make(domain, range);
837 }
838
839 static const TypeFunc* make_Math_DD_D_Type() {
840 const Type **fields = TypeTuple::fields(4);
841 fields[TypeFunc::Parms+0] = Type::DOUBLE;
842 fields[TypeFunc::Parms+1] = Type::HALF;
843 fields[TypeFunc::Parms+2] = Type::DOUBLE;
844 fields[TypeFunc::Parms+3] = Type::HALF;
845 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+4, fields);
846
847 // create result type (range)
848 fields = TypeTuple::fields(2);
849 fields[TypeFunc::Parms+0] = Type::DOUBLE;
850 fields[TypeFunc::Parms+1] = Type::HALF;
851 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+2, fields);
852
853 return TypeFunc::make(domain, range);
854 }
855
856 //-------------- currentTimeMillis, currentTimeNanos, etc
857
858 static const TypeFunc* make_void_long_Type() {
859 // create input type (domain)
860 const Type **fields = TypeTuple::fields(0);
861 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+0, fields);
862
863 // create result type (range)
864 fields = TypeTuple::fields(2);
865 fields[TypeFunc::Parms+0] = TypeLong::LONG;
866 fields[TypeFunc::Parms+1] = Type::HALF;
867 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+2, fields);
868
869 return TypeFunc::make(domain, range);
870 }
871
872 static const TypeFunc* make_void_void_Type() {
873 // create input type (domain)
874 const Type **fields = TypeTuple::fields(0);
875 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+0, fields);
876
877 // create result type (range)
878 fields = TypeTuple::fields(0);
879 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0, fields);
880 return TypeFunc::make(domain, range);
881 }
882
883 static const TypeFunc* make_jfr_write_checkpoint_Type() {
884 // create input type (domain)
885 const Type **fields = TypeTuple::fields(0);
886 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms, fields);
887
888 // create result type (range)
889 fields = TypeTuple::fields(1);
890 fields[TypeFunc::Parms] = TypeInstPtr::BOTTOM;
891 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms + 1, fields);
892 return TypeFunc::make(domain, range);
893 }
894
895
896 // Takes as parameters:
897 // void *dest
898 // long size
899 // uchar byte
900
901 static const TypeFunc* make_setmemory_Type() {
902 // create input type (domain)
903 int argcnt = NOT_LP64(3) LP64_ONLY(4);
904 const Type** fields = TypeTuple::fields(argcnt);
905 int argp = TypeFunc::Parms;
906 fields[argp++] = TypePtr::NOTNULL; // dest
907 fields[argp++] = TypeX_X; // size
908 LP64_ONLY(fields[argp++] = Type::HALF); // size
909 fields[argp++] = TypeInt::UBYTE; // bytevalue
910 assert(argp == TypeFunc::Parms+argcnt, "correct decoding");
911 const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms+argcnt, fields);
912
913 // no result type needed
914 fields = TypeTuple::fields(1);
915 fields[TypeFunc::Parms+0] = nullptr; // void
916 const TypeTuple* range = TypeTuple::make(TypeFunc::Parms, fields);
917 return TypeFunc::make(domain, range);
918 }
919
920 // arraycopy stub variations:
921 enum ArrayCopyType {
922 ac_fast, // void(ptr, ptr, size_t)
923 ac_checkcast, // int(ptr, ptr, size_t, size_t, ptr)
924 ac_slow, // void(ptr, int, ptr, int, int)
925 ac_generic // int(ptr, int, ptr, int, int)
926 };
927
928 static const TypeFunc* make_arraycopy_Type(ArrayCopyType act) {
929 // create input type (domain)
930 int num_args = (act == ac_fast ? 3 : 5);
931 int num_size_args = (act == ac_fast ? 1 : act == ac_checkcast ? 2 : 0);
932 int argcnt = num_args;
933 LP64_ONLY(argcnt += num_size_args); // halfwords for lengths
934 const Type** fields = TypeTuple::fields(argcnt);
935 int argp = TypeFunc::Parms;
936 fields[argp++] = TypePtr::NOTNULL; // src
937 if (num_size_args == 0) {
938 fields[argp++] = TypeInt::INT; // src_pos
939 }
940 fields[argp++] = TypePtr::NOTNULL; // dest
941 if (num_size_args == 0) {
942 fields[argp++] = TypeInt::INT; // dest_pos
943 fields[argp++] = TypeInt::INT; // length
944 }
945 while (num_size_args-- > 0) {
946 fields[argp++] = TypeX_X; // size in whatevers (size_t)
947 LP64_ONLY(fields[argp++] = Type::HALF); // other half of long length
948 }
949 if (act == ac_checkcast) {
950 fields[argp++] = TypePtr::NOTNULL; // super_klass
951 }
952 assert(argp == TypeFunc::Parms+argcnt, "correct decoding of act");
953 const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms+argcnt, fields);
954
955 // create result type if needed
956 int retcnt = (act == ac_checkcast || act == ac_generic ? 1 : 0);
957 fields = TypeTuple::fields(1);
958 if (retcnt == 0)
959 fields[TypeFunc::Parms+0] = nullptr; // void
960 else
961 fields[TypeFunc::Parms+0] = TypeInt::INT; // status result, if needed
962 const TypeTuple* range = TypeTuple::make(TypeFunc::Parms+retcnt, fields);
963 return TypeFunc::make(domain, range);
964 }
965
966 static const TypeFunc* make_array_fill_Type() {
967 const Type** fields;
968 int argp = TypeFunc::Parms;
969 // create input type (domain): pointer, int, size_t
970 fields = TypeTuple::fields(3 LP64_ONLY( + 1));
971 fields[argp++] = TypePtr::NOTNULL;
972 fields[argp++] = TypeInt::INT;
973 fields[argp++] = TypeX_X; // size in whatevers (size_t)
974 LP64_ONLY(fields[argp++] = Type::HALF); // other half of long length
975 const TypeTuple *domain = TypeTuple::make(argp, fields);
976
977 // create result type
978 fields = TypeTuple::fields(1);
979 fields[TypeFunc::Parms+0] = nullptr; // void
980 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms, fields);
981
982 return TypeFunc::make(domain, range);
983 }
984
985 static const TypeFunc* make_array_partition_Type() {
986 // create input type (domain)
987 int num_args = 7;
988 int argcnt = num_args;
989 const Type** fields = TypeTuple::fields(argcnt);
990 int argp = TypeFunc::Parms;
991 fields[argp++] = TypePtr::NOTNULL; // array
992 fields[argp++] = TypeInt::INT; // element type
993 fields[argp++] = TypeInt::INT; // low
994 fields[argp++] = TypeInt::INT; // end
995 fields[argp++] = TypePtr::NOTNULL; // pivot_indices (int array)
996 fields[argp++] = TypeInt::INT; // indexPivot1
997 fields[argp++] = TypeInt::INT; // indexPivot2
998 assert(argp == TypeFunc::Parms+argcnt, "correct decoding");
999 const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms+argcnt, fields);
1000
1001 // no result type needed
1002 fields = TypeTuple::fields(1);
1003 fields[TypeFunc::Parms+0] = nullptr; // void
1004 const TypeTuple* range = TypeTuple::make(TypeFunc::Parms, fields);
1005 return TypeFunc::make(domain, range);
1006 }
1007
1008 static const TypeFunc* make_array_sort_Type() {
1009 // create input type (domain)
1010 int num_args = 4;
1011 int argcnt = num_args;
1012 const Type** fields = TypeTuple::fields(argcnt);
1013 int argp = TypeFunc::Parms;
1014 fields[argp++] = TypePtr::NOTNULL; // array
1015 fields[argp++] = TypeInt::INT; // element type
1016 fields[argp++] = TypeInt::INT; // fromIndex
1017 fields[argp++] = TypeInt::INT; // toIndex
1018 assert(argp == TypeFunc::Parms+argcnt, "correct decoding");
1019 const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms+argcnt, fields);
1020
1021 // no result type needed
1022 fields = TypeTuple::fields(1);
1023 fields[TypeFunc::Parms+0] = nullptr; // void
1024 const TypeTuple* range = TypeTuple::make(TypeFunc::Parms, fields);
1025 return TypeFunc::make(domain, range);
1026 }
1027
1028 static const TypeFunc* make_aescrypt_block_Type() {
1029 // create input type (domain)
1030 int num_args = 3;
1031 int argcnt = num_args;
1032 const Type** fields = TypeTuple::fields(argcnt);
1033 int argp = TypeFunc::Parms;
1034 fields[argp++] = TypePtr::NOTNULL; // src
1035 fields[argp++] = TypePtr::NOTNULL; // dest
1036 fields[argp++] = TypePtr::NOTNULL; // k array
1037 assert(argp == TypeFunc::Parms+argcnt, "correct decoding");
1038 const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms+argcnt, fields);
1039
1040 // no result type needed
1041 fields = TypeTuple::fields(1);
1042 fields[TypeFunc::Parms+0] = nullptr; // void
1043 const TypeTuple* range = TypeTuple::make(TypeFunc::Parms, fields);
1044 return TypeFunc::make(domain, range);
1045 }
1046
1047 static const TypeFunc* make_updateBytesCRC32_Type() {
1048 // create input type (domain)
1049 int num_args = 3;
1050 int argcnt = num_args;
1051 const Type** fields = TypeTuple::fields(argcnt);
1052 int argp = TypeFunc::Parms;
1053 fields[argp++] = TypeInt::INT; // crc
1054 fields[argp++] = TypePtr::NOTNULL; // src
1055 fields[argp++] = TypeInt::INT; // len
1056 assert(argp == TypeFunc::Parms+argcnt, "correct decoding");
1057 const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms+argcnt, fields);
1058
1059 // result type needed
1060 fields = TypeTuple::fields(1);
1061 fields[TypeFunc::Parms+0] = TypeInt::INT; // crc result
1062 const TypeTuple* range = TypeTuple::make(TypeFunc::Parms+1, fields);
1063 return TypeFunc::make(domain, range);
1064 }
1065
1066 static const TypeFunc* make_updateBytesCRC32C_Type() {
1067 // create input type (domain)
1068 int num_args = 4;
1069 int argcnt = num_args;
1070 const Type** fields = TypeTuple::fields(argcnt);
1071 int argp = TypeFunc::Parms;
1072 fields[argp++] = TypeInt::INT; // crc
1073 fields[argp++] = TypePtr::NOTNULL; // buf
1074 fields[argp++] = TypeInt::INT; // len
1075 fields[argp++] = TypePtr::NOTNULL; // table
1076 assert(argp == TypeFunc::Parms+argcnt, "correct decoding");
1077 const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms+argcnt, fields);
1078
1079 // result type needed
1080 fields = TypeTuple::fields(1);
1081 fields[TypeFunc::Parms+0] = TypeInt::INT; // crc result
1082 const TypeTuple* range = TypeTuple::make(TypeFunc::Parms+1, fields);
1083 return TypeFunc::make(domain, range);
1084 }
1085
1086 static const TypeFunc* make_updateBytesAdler32_Type() {
1087 // create input type (domain)
1088 int num_args = 3;
1089 int argcnt = num_args;
1090 const Type** fields = TypeTuple::fields(argcnt);
1091 int argp = TypeFunc::Parms;
1092 fields[argp++] = TypeInt::INT; // crc
1093 fields[argp++] = TypePtr::NOTNULL; // src + offset
1094 fields[argp++] = TypeInt::INT; // len
1095 assert(argp == TypeFunc::Parms+argcnt, "correct decoding");
1096 const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms+argcnt, fields);
1097
1098 // result type needed
1099 fields = TypeTuple::fields(1);
1100 fields[TypeFunc::Parms+0] = TypeInt::INT; // crc result
1101 const TypeTuple* range = TypeTuple::make(TypeFunc::Parms+1, fields);
1102 return TypeFunc::make(domain, range);
1103 }
1104
1105 static const TypeFunc* make_cipherBlockChaining_aescrypt_Type() {
1106 // create input type (domain)
1107 int num_args = 5;
1108 int argcnt = num_args;
1109 const Type** fields = TypeTuple::fields(argcnt);
1110 int argp = TypeFunc::Parms;
1111 fields[argp++] = TypePtr::NOTNULL; // src
1112 fields[argp++] = TypePtr::NOTNULL; // dest
1113 fields[argp++] = TypePtr::NOTNULL; // k array
1114 fields[argp++] = TypePtr::NOTNULL; // r array
1115 fields[argp++] = TypeInt::INT; // src len
1116 assert(argp == TypeFunc::Parms+argcnt, "correct decoding");
1117 const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms+argcnt, fields);
1118
1119 // returning cipher len (int)
1120 fields = TypeTuple::fields(1);
1121 fields[TypeFunc::Parms+0] = TypeInt::INT;
1122 const TypeTuple* range = TypeTuple::make(TypeFunc::Parms+1, fields);
1123 return TypeFunc::make(domain, range);
1124 }
1125
1126 static const TypeFunc* make_electronicCodeBook_aescrypt_Type() {
1127 // create input type (domain)
1128 int num_args = 4;
1129 int argcnt = num_args;
1130 const Type** fields = TypeTuple::fields(argcnt);
1131 int argp = TypeFunc::Parms;
1132 fields[argp++] = TypePtr::NOTNULL; // src
1133 fields[argp++] = TypePtr::NOTNULL; // dest
1134 fields[argp++] = TypePtr::NOTNULL; // k array
1135 fields[argp++] = TypeInt::INT; // src len
1136 assert(argp == TypeFunc::Parms + argcnt, "correct decoding");
1137 const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms + argcnt, fields);
1138
1139 // returning cipher len (int)
1140 fields = TypeTuple::fields(1);
1141 fields[TypeFunc::Parms + 0] = TypeInt::INT;
1142 const TypeTuple* range = TypeTuple::make(TypeFunc::Parms + 1, fields);
1143 return TypeFunc::make(domain, range);
1144 }
1145
1146 static const TypeFunc* make_counterMode_aescrypt_Type() {
1147 // create input type (domain)
1148 int num_args = 7;
1149 int argcnt = num_args;
1150 const Type** fields = TypeTuple::fields(argcnt);
1151 int argp = TypeFunc::Parms;
1152 fields[argp++] = TypePtr::NOTNULL; // src
1153 fields[argp++] = TypePtr::NOTNULL; // dest
1154 fields[argp++] = TypePtr::NOTNULL; // k array
1155 fields[argp++] = TypePtr::NOTNULL; // counter array
1156 fields[argp++] = TypeInt::INT; // src len
1157 fields[argp++] = TypePtr::NOTNULL; // saved_encCounter
1158 fields[argp++] = TypePtr::NOTNULL; // saved used addr
1159 assert(argp == TypeFunc::Parms + argcnt, "correct decoding");
1160 const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms + argcnt, fields);
1161 // returning cipher len (int)
1162 fields = TypeTuple::fields(1);
1163 fields[TypeFunc::Parms + 0] = TypeInt::INT;
1164 const TypeTuple* range = TypeTuple::make(TypeFunc::Parms + 1, fields);
1165 return TypeFunc::make(domain, range);
1166 }
1167
1168 static const TypeFunc* make_galoisCounterMode_aescrypt_Type() {
1169 // create input type (domain)
1170 int num_args = 8;
1171 int argcnt = num_args;
1172 const Type** fields = TypeTuple::fields(argcnt);
1173 int argp = TypeFunc::Parms;
1174 fields[argp++] = TypePtr::NOTNULL; // byte[] in + inOfs
1175 fields[argp++] = TypeInt::INT; // int len
1176 fields[argp++] = TypePtr::NOTNULL; // byte[] ct + ctOfs
1177 fields[argp++] = TypePtr::NOTNULL; // byte[] out + outOfs
1178 fields[argp++] = TypePtr::NOTNULL; // byte[] key from AESCrypt obj
1179 fields[argp++] = TypePtr::NOTNULL; // long[] state from GHASH obj
1180 fields[argp++] = TypePtr::NOTNULL; // long[] subkeyHtbl from GHASH obj
1181 fields[argp++] = TypePtr::NOTNULL; // byte[] counter from GCTR obj
1182
1183 assert(argp == TypeFunc::Parms + argcnt, "correct decoding");
1184 const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms + argcnt, fields);
1185 // returning cipher len (int)
1186 fields = TypeTuple::fields(1);
1187 fields[TypeFunc::Parms + 0] = TypeInt::INT;
1188 const TypeTuple* range = TypeTuple::make(TypeFunc::Parms + 1, fields);
1189 return TypeFunc::make(domain, range);
1190 }
1191
1192 static const TypeFunc* make_digestBase_implCompress_Type(bool is_sha3) {
1193 // create input type (domain)
1194 int num_args = is_sha3 ? 3 : 2;
1195 int argcnt = num_args;
1196 const Type** fields = TypeTuple::fields(argcnt);
1197 int argp = TypeFunc::Parms;
1198 fields[argp++] = TypePtr::NOTNULL; // buf
1199 fields[argp++] = TypePtr::NOTNULL; // state
1200 if (is_sha3) fields[argp++] = TypeInt::INT; // block_size
1201 assert(argp == TypeFunc::Parms+argcnt, "correct decoding");
1202 const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms+argcnt, fields);
1203
1204 // no result type needed
1205 fields = TypeTuple::fields(1);
1206 fields[TypeFunc::Parms+0] = nullptr; // void
1207 const TypeTuple* range = TypeTuple::make(TypeFunc::Parms, fields);
1208 return TypeFunc::make(domain, range);
1209 }
1210
1211 /*
1212 * int implCompressMultiBlock(byte[] b, int ofs, int limit)
1213 */
1214 static const TypeFunc* make_digestBase_implCompressMB_Type(bool is_sha3) {
1215 // create input type (domain)
1216 int num_args = is_sha3 ? 5 : 4;
1217 int argcnt = num_args;
1218 const Type** fields = TypeTuple::fields(argcnt);
1219 int argp = TypeFunc::Parms;
1220 fields[argp++] = TypePtr::NOTNULL; // buf
1221 fields[argp++] = TypePtr::NOTNULL; // state
1222 if (is_sha3) fields[argp++] = TypeInt::INT; // block_size
1223 fields[argp++] = TypeInt::INT; // ofs
1224 fields[argp++] = TypeInt::INT; // limit
1225 assert(argp == TypeFunc::Parms+argcnt, "correct decoding");
1226 const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms+argcnt, fields);
1227
1228 // returning ofs (int)
1229 fields = TypeTuple::fields(1);
1230 fields[TypeFunc::Parms+0] = TypeInt::INT; // ofs
1231 const TypeTuple* range = TypeTuple::make(TypeFunc::Parms+1, fields);
1232 return TypeFunc::make(domain, range);
1233 }
1234
1235 // SHAKE128Parallel doubleKeccak function
1236 static const TypeFunc* make_double_keccak_Type() {
1237 int argcnt = 2;
1238
1239 const Type** fields = TypeTuple::fields(argcnt);
1240 int argp = TypeFunc::Parms;
1241 fields[argp++] = TypePtr::NOTNULL; // status0
1242 fields[argp++] = TypePtr::NOTNULL; // status1
1243
1244 assert(argp == TypeFunc::Parms + argcnt, "correct decoding");
1245 const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms + argcnt, fields);
1246
1247 // result type needed
1248 fields = TypeTuple::fields(1);
1249 fields[TypeFunc::Parms + 0] = TypeInt::INT;
1250 const TypeTuple* range = TypeTuple::make(TypeFunc::Parms + 1, fields);
1251 return TypeFunc::make(domain, range);
1252 }
1253
1254 static const TypeFunc* make_multiplyToLen_Type() {
1255 // create input type (domain)
1256 int num_args = 5;
1257 int argcnt = num_args;
1258 const Type** fields = TypeTuple::fields(argcnt);
1259 int argp = TypeFunc::Parms;
1260 fields[argp++] = TypePtr::NOTNULL; // x
1261 fields[argp++] = TypeInt::INT; // xlen
1262 fields[argp++] = TypePtr::NOTNULL; // y
1263 fields[argp++] = TypeInt::INT; // ylen
1264 fields[argp++] = TypePtr::NOTNULL; // z
1265 assert(argp == TypeFunc::Parms+argcnt, "correct decoding");
1266 const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms+argcnt, fields);
1267
1268 // no result type needed
1269 fields = TypeTuple::fields(1);
1270 fields[TypeFunc::Parms+0] = nullptr;
1271 const TypeTuple* range = TypeTuple::make(TypeFunc::Parms, fields);
1272 return TypeFunc::make(domain, range);
1273 }
1274
1275 static const TypeFunc* make_squareToLen_Type() {
1276 // create input type (domain)
1277 int num_args = 4;
1278 int argcnt = num_args;
1279 const Type** fields = TypeTuple::fields(argcnt);
1280 int argp = TypeFunc::Parms;
1281 fields[argp++] = TypePtr::NOTNULL; // x
1282 fields[argp++] = TypeInt::INT; // len
1283 fields[argp++] = TypePtr::NOTNULL; // z
1284 fields[argp++] = TypeInt::INT; // zlen
1285 assert(argp == TypeFunc::Parms+argcnt, "correct decoding");
1286 const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms+argcnt, fields);
1287
1288 // no result type needed
1289 fields = TypeTuple::fields(1);
1290 fields[TypeFunc::Parms+0] = nullptr;
1291 const TypeTuple* range = TypeTuple::make(TypeFunc::Parms, fields);
1292 return TypeFunc::make(domain, range);
1293 }
1294
1295 static const TypeFunc* make_mulAdd_Type() {
1296 // create input type (domain)
1297 int num_args = 5;
1298 int argcnt = num_args;
1299 const Type** fields = TypeTuple::fields(argcnt);
1300 int argp = TypeFunc::Parms;
1301 fields[argp++] = TypePtr::NOTNULL; // out
1302 fields[argp++] = TypePtr::NOTNULL; // in
1303 fields[argp++] = TypeInt::INT; // offset
1304 fields[argp++] = TypeInt::INT; // len
1305 fields[argp++] = TypeInt::INT; // k
1306 assert(argp == TypeFunc::Parms+argcnt, "correct decoding");
1307 const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms+argcnt, fields);
1308
1309 // returning carry (int)
1310 fields = TypeTuple::fields(1);
1311 fields[TypeFunc::Parms+0] = TypeInt::INT;
1312 const TypeTuple* range = TypeTuple::make(TypeFunc::Parms+1, fields);
1313 return TypeFunc::make(domain, range);
1314 }
1315
1316 static const TypeFunc* make_montgomeryMultiply_Type() {
1317 // create input type (domain)
1318 int num_args = 7;
1319 int argcnt = num_args;
1320 const Type** fields = TypeTuple::fields(argcnt);
1321 int argp = TypeFunc::Parms;
1322 fields[argp++] = TypePtr::NOTNULL; // a
1323 fields[argp++] = TypePtr::NOTNULL; // b
1324 fields[argp++] = TypePtr::NOTNULL; // n
1325 fields[argp++] = TypeInt::INT; // len
1326 fields[argp++] = TypeLong::LONG; // inv
1327 fields[argp++] = Type::HALF;
1328 fields[argp++] = TypePtr::NOTNULL; // result
1329 assert(argp == TypeFunc::Parms+argcnt, "correct decoding");
1330 const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms+argcnt, fields);
1331
1332 // result type needed
1333 fields = TypeTuple::fields(1);
1334 fields[TypeFunc::Parms+0] = TypePtr::NOTNULL;
1335
1336 const TypeTuple* range = TypeTuple::make(TypeFunc::Parms, fields);
1337 return TypeFunc::make(domain, range);
1338 }
1339
1340 static const TypeFunc* make_montgomerySquare_Type() {
1341 // create input type (domain)
1342 int num_args = 6;
1343 int argcnt = num_args;
1344 const Type** fields = TypeTuple::fields(argcnt);
1345 int argp = TypeFunc::Parms;
1346 fields[argp++] = TypePtr::NOTNULL; // a
1347 fields[argp++] = TypePtr::NOTNULL; // n
1348 fields[argp++] = TypeInt::INT; // len
1349 fields[argp++] = TypeLong::LONG; // inv
1350 fields[argp++] = Type::HALF;
1351 fields[argp++] = TypePtr::NOTNULL; // result
1352 assert(argp == TypeFunc::Parms+argcnt, "correct decoding");
1353 const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms+argcnt, fields);
1354
1355 // result type needed
1356 fields = TypeTuple::fields(1);
1357 fields[TypeFunc::Parms+0] = TypePtr::NOTNULL;
1358
1359 const TypeTuple* range = TypeTuple::make(TypeFunc::Parms, fields);
1360 return TypeFunc::make(domain, range);
1361 }
1362
1363 static const TypeFunc* make_bigIntegerShift_Type() {
1364 int argcnt = 5;
1365 const Type** fields = TypeTuple::fields(argcnt);
1366 int argp = TypeFunc::Parms;
1367 fields[argp++] = TypePtr::NOTNULL; // newArr
1368 fields[argp++] = TypePtr::NOTNULL; // oldArr
1369 fields[argp++] = TypeInt::INT; // newIdx
1370 fields[argp++] = TypeInt::INT; // shiftCount
1371 fields[argp++] = TypeInt::INT; // numIter
1372 assert(argp == TypeFunc::Parms + argcnt, "correct decoding");
1373 const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms + argcnt, fields);
1374
1375 // no result type needed
1376 fields = TypeTuple::fields(1);
1377 fields[TypeFunc::Parms + 0] = nullptr;
1378 const TypeTuple* range = TypeTuple::make(TypeFunc::Parms, fields);
1379 return TypeFunc::make(domain, range);
1380 }
1381
1382 static const TypeFunc* make_vectorizedMismatch_Type() {
1383 // create input type (domain)
1384 int num_args = 4;
1385 int argcnt = num_args;
1386 const Type** fields = TypeTuple::fields(argcnt);
1387 int argp = TypeFunc::Parms;
1388 fields[argp++] = TypePtr::NOTNULL; // obja
1389 fields[argp++] = TypePtr::NOTNULL; // objb
1390 fields[argp++] = TypeInt::INT; // length, number of elements
1391 fields[argp++] = TypeInt::INT; // log2scale, element size
1392 assert(argp == TypeFunc::Parms + argcnt, "correct decoding");
1393 const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms + argcnt, fields);
1394
1395 //return mismatch index (int)
1396 fields = TypeTuple::fields(1);
1397 fields[TypeFunc::Parms + 0] = TypeInt::INT;
1398 const TypeTuple* range = TypeTuple::make(TypeFunc::Parms + 1, fields);
1399 return TypeFunc::make(domain, range);
1400 }
1401
1402 static const TypeFunc* make_ghash_processBlocks_Type() {
1403 int argcnt = 4;
1404
1405 const Type** fields = TypeTuple::fields(argcnt);
1406 int argp = TypeFunc::Parms;
1407 fields[argp++] = TypePtr::NOTNULL; // state
1408 fields[argp++] = TypePtr::NOTNULL; // subkeyH
1409 fields[argp++] = TypePtr::NOTNULL; // data
1410 fields[argp++] = TypeInt::INT; // blocks
1411 assert(argp == TypeFunc::Parms+argcnt, "correct decoding");
1412 const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms+argcnt, fields);
1413
1414 // result type needed
1415 fields = TypeTuple::fields(1);
1416 fields[TypeFunc::Parms+0] = nullptr; // void
1417 const TypeTuple* range = TypeTuple::make(TypeFunc::Parms, fields);
1418 return TypeFunc::make(domain, range);
1419 }
1420
1421 static const TypeFunc* make_chacha20Block_Type() {
1422 int argcnt = 2;
1423
1424 const Type** fields = TypeTuple::fields(argcnt);
1425 int argp = TypeFunc::Parms;
1426 fields[argp++] = TypePtr::NOTNULL; // state
1427 fields[argp++] = TypePtr::NOTNULL; // result
1428
1429 assert(argp == TypeFunc::Parms + argcnt, "correct decoding");
1430 const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms + argcnt, fields);
1431
1432 // result type needed
1433 fields = TypeTuple::fields(1);
1434 fields[TypeFunc::Parms + 0] = TypeInt::INT; // key stream outlen as int
1435 const TypeTuple* range = TypeTuple::make(TypeFunc::Parms + 1, fields);
1436 return TypeFunc::make(domain, range);
1437 }
1438
1439 // Kyber NTT function
1440 static const TypeFunc* make_kyberNtt_Type() {
1441 int argcnt = 2;
1442
1443 const Type** fields = TypeTuple::fields(argcnt);
1444 int argp = TypeFunc::Parms;
1445 fields[argp++] = TypePtr::NOTNULL; // coeffs
1446 fields[argp++] = TypePtr::NOTNULL; // NTT zetas
1447
1448 assert(argp == TypeFunc::Parms + argcnt, "correct decoding");
1449 const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms + argcnt, fields);
1450
1451 // result type needed
1452 fields = TypeTuple::fields(1);
1453 fields[TypeFunc::Parms + 0] = TypeInt::INT;
1454 const TypeTuple* range = TypeTuple::make(TypeFunc::Parms + 1, fields);
1455 return TypeFunc::make(domain, range);
1456 }
1457
1458 // Kyber inverse NTT function
1459 static const TypeFunc* make_kyberInverseNtt_Type() {
1460 int argcnt = 2;
1461
1462 const Type** fields = TypeTuple::fields(argcnt);
1463 int argp = TypeFunc::Parms;
1464 fields[argp++] = TypePtr::NOTNULL; // coeffs
1465 fields[argp++] = TypePtr::NOTNULL; // inverse NTT zetas
1466
1467 assert(argp == TypeFunc::Parms + argcnt, "correct decoding");
1468 const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms + argcnt, fields);
1469
1470 // result type needed
1471 fields = TypeTuple::fields(1);
1472 fields[TypeFunc::Parms + 0] = TypeInt::INT;
1473 const TypeTuple* range = TypeTuple::make(TypeFunc::Parms + 1, fields);
1474 return TypeFunc::make(domain, range);
1475 }
1476
1477 // Kyber NTT multiply function
1478 static const TypeFunc* make_kyberNttMult_Type() {
1479 int argcnt = 4;
1480
1481 const Type** fields = TypeTuple::fields(argcnt);
1482 int argp = TypeFunc::Parms;
1483 fields[argp++] = TypePtr::NOTNULL; // result
1484 fields[argp++] = TypePtr::NOTNULL; // ntta
1485 fields[argp++] = TypePtr::NOTNULL; // nttb
1486 fields[argp++] = TypePtr::NOTNULL; // NTT multiply zetas
1487
1488 assert(argp == TypeFunc::Parms + argcnt, "correct decoding");
1489 const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms + argcnt, fields);
1490
1491 // result type needed
1492 fields = TypeTuple::fields(1);
1493 fields[TypeFunc::Parms + 0] = TypeInt::INT;
1494 const TypeTuple* range = TypeTuple::make(TypeFunc::Parms + 1, fields);
1495 return TypeFunc::make(domain, range);
1496 }
1497
1498 // Kyber add 2 polynomials function
1499 static const TypeFunc* make_kyberAddPoly_2_Type() {
1500 int argcnt = 3;
1501
1502 const Type** fields = TypeTuple::fields(argcnt);
1503 int argp = TypeFunc::Parms;
1504 fields[argp++] = TypePtr::NOTNULL; // result
1505 fields[argp++] = TypePtr::NOTNULL; // a
1506 fields[argp++] = TypePtr::NOTNULL; // b
1507
1508 assert(argp == TypeFunc::Parms + argcnt, "correct decoding");
1509 const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms + argcnt, fields);
1510
1511 // result type needed
1512 fields = TypeTuple::fields(1);
1513 fields[TypeFunc::Parms + 0] = TypeInt::INT;
1514 const TypeTuple* range = TypeTuple::make(TypeFunc::Parms + 1, fields);
1515 return TypeFunc::make(domain, range);
1516 }
1517
1518
1519 // Kyber add 3 polynomials function
1520 static const TypeFunc* make_kyberAddPoly_3_Type() {
1521 int argcnt = 4;
1522
1523 const Type** fields = TypeTuple::fields(argcnt);
1524 int argp = TypeFunc::Parms;
1525 fields[argp++] = TypePtr::NOTNULL; // result
1526 fields[argp++] = TypePtr::NOTNULL; // a
1527 fields[argp++] = TypePtr::NOTNULL; // b
1528 fields[argp++] = TypePtr::NOTNULL; // c
1529
1530 assert(argp == TypeFunc::Parms + argcnt, "correct decoding");
1531 const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms + argcnt, fields);
1532
1533 // result type needed
1534 fields = TypeTuple::fields(1);
1535 fields[TypeFunc::Parms + 0] = TypeInt::INT;
1536 const TypeTuple* range = TypeTuple::make(TypeFunc::Parms + 1, fields);
1537 return TypeFunc::make(domain, range);
1538 }
1539
1540
1541 // Kyber XOF output parsing into polynomial coefficients candidates
1542 // or decompress(12,...) function
1543 static const TypeFunc* make_kyber12To16_Type() {
1544 int argcnt = 4;
1545
1546 const Type** fields = TypeTuple::fields(argcnt);
1547 int argp = TypeFunc::Parms;
1548 fields[argp++] = TypePtr::NOTNULL; // condensed
1549 fields[argp++] = TypeInt::INT; // condensedOffs
1550 fields[argp++] = TypePtr::NOTNULL; // parsed
1551 fields[argp++] = TypeInt::INT; // parsedLength
1552
1553 assert(argp == TypeFunc::Parms + argcnt, "correct decoding");
1554 const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms + argcnt, fields);
1555
1556 // result type needed
1557 fields = TypeTuple::fields(1);
1558 fields[TypeFunc::Parms + 0] = TypeInt::INT;
1559 const TypeTuple* range = TypeTuple::make(TypeFunc::Parms + 1, fields);
1560 return TypeFunc::make(domain, range);
1561 }
1562
1563 // Kyber Barrett reduce function
1564 static const TypeFunc* make_kyberBarrettReduce_Type() {
1565 int argcnt = 1;
1566
1567 const Type** fields = TypeTuple::fields(argcnt);
1568 int argp = TypeFunc::Parms;
1569 fields[argp++] = TypePtr::NOTNULL; // coeffs
1570
1571 assert(argp == TypeFunc::Parms + argcnt, "correct decoding");
1572 const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms + argcnt, fields);
1573
1574 // result type needed
1575 fields = TypeTuple::fields(1);
1576 fields[TypeFunc::Parms + 0] = TypeInt::INT;
1577 const TypeTuple* range = TypeTuple::make(TypeFunc::Parms + 1, fields);
1578 return TypeFunc::make(domain, range);
1579 }
1580
1581 // Dilithium NTT function except for the final "normalization" to |coeff| < Q
1582 static const TypeFunc* make_dilithiumAlmostNtt_Type() {
1583 int argcnt = 2;
1584
1585 const Type** fields = TypeTuple::fields(argcnt);
1586 int argp = TypeFunc::Parms;
1587 fields[argp++] = TypePtr::NOTNULL; // coeffs
1588 fields[argp++] = TypePtr::NOTNULL; // NTT zetas
1589
1590 assert(argp == TypeFunc::Parms + argcnt, "correct decoding");
1591 const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms + argcnt, fields);
1592
1593 // result type needed
1594 fields = TypeTuple::fields(1);
1595 fields[TypeFunc::Parms + 0] = TypeInt::INT;
1596 const TypeTuple* range = TypeTuple::make(TypeFunc::Parms + 1, fields);
1597 return TypeFunc::make(domain, range);
1598 }
1599
1600 // Dilithium inverse NTT function except the final mod Q division by 2^256
1601 static const TypeFunc* make_dilithiumAlmostInverseNtt_Type() {
1602 int argcnt = 2;
1603
1604 const Type** fields = TypeTuple::fields(argcnt);
1605 int argp = TypeFunc::Parms;
1606 fields[argp++] = TypePtr::NOTNULL; // coeffs
1607 fields[argp++] = TypePtr::NOTNULL; // inverse NTT zetas
1608
1609 assert(argp == TypeFunc::Parms + argcnt, "correct decoding");
1610 const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms + argcnt, fields);
1611
1612 // result type needed
1613 fields = TypeTuple::fields(1);
1614 fields[TypeFunc::Parms + 0] = TypeInt::INT;
1615 const TypeTuple* range = TypeTuple::make(TypeFunc::Parms + 1, fields);
1616 return TypeFunc::make(domain, range);
1617 }
1618
1619 // Dilithium NTT multiply function
1620 static const TypeFunc* make_dilithiumNttMult_Type() {
1621 int argcnt = 3;
1622
1623 const Type** fields = TypeTuple::fields(argcnt);
1624 int argp = TypeFunc::Parms;
1625 fields[argp++] = TypePtr::NOTNULL; // result
1626 fields[argp++] = TypePtr::NOTNULL; // ntta
1627 fields[argp++] = TypePtr::NOTNULL; // nttb
1628
1629 assert(argp == TypeFunc::Parms + argcnt, "correct decoding");
1630 const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms + argcnt, fields);
1631
1632 // result type needed
1633 fields = TypeTuple::fields(1);
1634 fields[TypeFunc::Parms + 0] = TypeInt::INT;
1635 const TypeTuple* range = TypeTuple::make(TypeFunc::Parms + 1, fields);
1636 return TypeFunc::make(domain, range);
1637 }
1638
1639 // Dilithium Montgomery multiply a polynome coefficient array by a constant
1640 static const TypeFunc* make_dilithiumMontMulByConstant_Type() {
1641 int argcnt = 2;
1642
1643 const Type** fields = TypeTuple::fields(argcnt);
1644 int argp = TypeFunc::Parms;
1645 fields[argp++] = TypePtr::NOTNULL; // coeffs
1646 fields[argp++] = TypeInt::INT; // constant multiplier
1647
1648 assert(argp == TypeFunc::Parms + argcnt, "correct decoding");
1649 const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms + argcnt, fields);
1650
1651 // result type needed
1652 fields = TypeTuple::fields(1);
1653 fields[TypeFunc::Parms + 0] = TypeInt::INT;
1654 const TypeTuple* range = TypeTuple::make(TypeFunc::Parms + 1, fields);
1655 return TypeFunc::make(domain, range);
1656 }
1657
1658 // Dilithium decompose polynomial
1659 static const TypeFunc* make_dilithiumDecomposePoly_Type() {
1660 int argcnt = 5;
1661
1662 const Type** fields = TypeTuple::fields(argcnt);
1663 int argp = TypeFunc::Parms;
1664 fields[argp++] = TypePtr::NOTNULL; // input
1665 fields[argp++] = TypePtr::NOTNULL; // lowPart
1666 fields[argp++] = TypePtr::NOTNULL; // highPart
1667 fields[argp++] = TypeInt::INT; // 2 * gamma2
1668 fields[argp++] = TypeInt::INT; // multiplier
1669
1670 assert(argp == TypeFunc::Parms + argcnt, "correct decoding");
1671 const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms + argcnt, fields);
1672
1673 // result type needed
1674 fields = TypeTuple::fields(1);
1675 fields[TypeFunc::Parms + 0] = TypeInt::INT;
1676 const TypeTuple* range = TypeTuple::make(TypeFunc::Parms + 1, fields);
1677 return TypeFunc::make(domain, range);
1678 }
1679
1680 static const TypeFunc* make_base64_encodeBlock_Type() {
1681 int argcnt = 6;
1682
1683 const Type** fields = TypeTuple::fields(argcnt);
1684 int argp = TypeFunc::Parms;
1685 fields[argp++] = TypePtr::NOTNULL; // src array
1686 fields[argp++] = TypeInt::INT; // offset
1687 fields[argp++] = TypeInt::INT; // length
1688 fields[argp++] = TypePtr::NOTNULL; // dest array
1689 fields[argp++] = TypeInt::INT; // dp
1690 fields[argp++] = TypeInt::BOOL; // isURL
1691 assert(argp == TypeFunc::Parms + argcnt, "correct decoding");
1692 const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms+argcnt, fields);
1693
1694 // result type needed
1695 fields = TypeTuple::fields(1);
1696 fields[TypeFunc::Parms + 0] = nullptr; // void
1697 const TypeTuple* range = TypeTuple::make(TypeFunc::Parms, fields);
1698 return TypeFunc::make(domain, range);
1699 }
1700
1701 static const TypeFunc* make_string_IndexOf_Type() {
1702 int argcnt = 4;
1703
1704 const Type** fields = TypeTuple::fields(argcnt);
1705 int argp = TypeFunc::Parms;
1706 fields[argp++] = TypePtr::NOTNULL; // haystack array
1707 fields[argp++] = TypeInt::INT; // haystack length
1708 fields[argp++] = TypePtr::NOTNULL; // needle array
1709 fields[argp++] = TypeInt::INT; // needle length
1710 assert(argp == TypeFunc::Parms + argcnt, "correct decoding");
1711 const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms+argcnt, fields);
1712
1713 // result type needed
1714 fields = TypeTuple::fields(1);
1715 fields[TypeFunc::Parms + 0] = TypeInt::INT; // Index of needle in haystack
1716 const TypeTuple* range = TypeTuple::make(TypeFunc::Parms + 1, fields);
1717 return TypeFunc::make(domain, range);
1718 }
1719
1720 static const TypeFunc* make_base64_decodeBlock_Type() {
1721 int argcnt = 7;
1722
1723 const Type** fields = TypeTuple::fields(argcnt);
1724 int argp = TypeFunc::Parms;
1725 fields[argp++] = TypePtr::NOTNULL; // src array
1726 fields[argp++] = TypeInt::INT; // src offset
1727 fields[argp++] = TypeInt::INT; // src length
1728 fields[argp++] = TypePtr::NOTNULL; // dest array
1729 fields[argp++] = TypeInt::INT; // dest offset
1730 fields[argp++] = TypeInt::BOOL; // isURL
1731 fields[argp++] = TypeInt::BOOL; // isMIME
1732 assert(argp == TypeFunc::Parms + argcnt, "correct decoding");
1733 const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms+argcnt, fields);
1734
1735 // result type needed
1736 fields = TypeTuple::fields(1);
1737 fields[TypeFunc::Parms + 0] = TypeInt::INT; // count of bytes written to dst
1738 const TypeTuple* range = TypeTuple::make(TypeFunc::Parms + 1, fields);
1739 return TypeFunc::make(domain, range);
1740 }
1741
1742 static const TypeFunc* make_poly1305_processBlocks_Type() {
1743 int argcnt = 4;
1744
1745 const Type** fields = TypeTuple::fields(argcnt);
1746 int argp = TypeFunc::Parms;
1747 fields[argp++] = TypePtr::NOTNULL; // input array
1748 fields[argp++] = TypeInt::INT; // input length
1749 fields[argp++] = TypePtr::NOTNULL; // accumulator array
1750 fields[argp++] = TypePtr::NOTNULL; // r array
1751 assert(argp == TypeFunc::Parms + argcnt, "correct decoding");
1752 const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms+argcnt, fields);
1753
1754 // result type needed
1755 fields = TypeTuple::fields(1);
1756 fields[TypeFunc::Parms + 0] = nullptr; // void
1757 const TypeTuple* range = TypeTuple::make(TypeFunc::Parms, fields);
1758 return TypeFunc::make(domain, range);
1759 }
1760
1761 static const TypeFunc* make_intpoly_montgomeryMult_P256_Type() {
1762 int argcnt = 3;
1763
1764 const Type** fields = TypeTuple::fields(argcnt);
1765 int argp = TypeFunc::Parms;
1766 fields[argp++] = TypePtr::NOTNULL; // a array
1767 fields[argp++] = TypePtr::NOTNULL; // b array
1768 fields[argp++] = TypePtr::NOTNULL; // r(esult) array
1769 assert(argp == TypeFunc::Parms + argcnt, "correct decoding");
1770 const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms+argcnt, fields);
1771
1772 // result type needed
1773 fields = TypeTuple::fields(1);
1774 fields[TypeFunc::Parms + 0] = nullptr; // void
1775 const TypeTuple* range = TypeTuple::make(TypeFunc::Parms, fields);
1776 return TypeFunc::make(domain, range);
1777 }
1778
1779 static const TypeFunc* make_intpoly_assign_Type() {
1780 int argcnt = 4;
1781
1782 const Type** fields = TypeTuple::fields(argcnt);
1783 int argp = TypeFunc::Parms;
1784 fields[argp++] = TypeInt::INT; // set flag
1785 fields[argp++] = TypePtr::NOTNULL; // a array (result)
1786 fields[argp++] = TypePtr::NOTNULL; // b array (if set is set)
1787 fields[argp++] = TypeInt::INT; // array length
1788 assert(argp == TypeFunc::Parms + argcnt, "correct decoding");
1789 const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms+argcnt, fields);
1790
1791 // result type needed
1792 fields = TypeTuple::fields(1);
1793 fields[TypeFunc::Parms + 0] = nullptr; // void
1794 const TypeTuple* range = TypeTuple::make(TypeFunc::Parms, fields);
1795 return TypeFunc::make(domain, range);
1796 }
1797
1798 //------------- Interpreter state for on stack replacement
1799 static const TypeFunc* make_osr_end_Type() {
1800 // create input type (domain)
1801 const Type **fields = TypeTuple::fields(1);
1802 fields[TypeFunc::Parms+0] = TypeRawPtr::BOTTOM; // OSR temp buf
1803 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+1, fields);
1804
1805 // create result type
1806 fields = TypeTuple::fields(1);
1807 // fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; // locked oop
1808 fields[TypeFunc::Parms+0] = nullptr; // void
1809 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms, fields);
1810 return TypeFunc::make(domain, range);
1811 }
1812
1813 #ifndef PRODUCT
1814 static void debug_print_convert_type(const Type** fields, int* argp, Node *parm) {
1815 const BasicType bt = parm->bottom_type()->basic_type();
1816 fields[(*argp)++] = Type::get_const_basic_type(bt);
1817 if (bt == T_LONG || bt == T_DOUBLE) {
1818 fields[(*argp)++] = Type::HALF;
1819 }
1820 }
1821
1822 static void update_arg_cnt(const Node* parm, int* arg_cnt) {
1823 (*arg_cnt)++;
1824 const BasicType bt = parm->bottom_type()->basic_type();
1825 if (bt == T_LONG || bt == T_DOUBLE) {
1826 (*arg_cnt)++;
1827 }
1828 }
1829
1830 const TypeFunc* OptoRuntime::debug_print_Type(Node* parm0, Node* parm1,
1831 Node* parm2, Node* parm3,
1832 Node* parm4, Node* parm5,
1833 Node* parm6) {
1834 int argcnt = 1;
1835 if (parm0 != nullptr) { update_arg_cnt(parm0, &argcnt);
1836 if (parm1 != nullptr) { update_arg_cnt(parm1, &argcnt);
1837 if (parm2 != nullptr) { update_arg_cnt(parm2, &argcnt);
1838 if (parm3 != nullptr) { update_arg_cnt(parm3, &argcnt);
1839 if (parm4 != nullptr) { update_arg_cnt(parm4, &argcnt);
1840 if (parm5 != nullptr) { update_arg_cnt(parm5, &argcnt);
1841 if (parm6 != nullptr) { update_arg_cnt(parm6, &argcnt);
1842 /* close each nested if ===> */ } } } } } } }
1843
1844 // create input type (domain)
1845 const Type** fields = TypeTuple::fields(argcnt);
1846 int argp = TypeFunc::Parms;
1847 fields[argp++] = TypePtr::NOTNULL; // static string pointer
1848
1849 if (parm0 != nullptr) { debug_print_convert_type(fields, &argp, parm0);
1850 if (parm1 != nullptr) { debug_print_convert_type(fields, &argp, parm1);
1851 if (parm2 != nullptr) { debug_print_convert_type(fields, &argp, parm2);
1852 if (parm3 != nullptr) { debug_print_convert_type(fields, &argp, parm3);
1853 if (parm4 != nullptr) { debug_print_convert_type(fields, &argp, parm4);
1854 if (parm5 != nullptr) { debug_print_convert_type(fields, &argp, parm5);
1855 if (parm6 != nullptr) { debug_print_convert_type(fields, &argp, parm6);
1856 /* close each nested if ===> */ } } } } } } }
1857
1858 assert(argp == TypeFunc::Parms+argcnt, "correct decoding");
1859 const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms+argcnt, fields);
1860
1861 // no result type needed
1862 fields = TypeTuple::fields(1);
1863 fields[TypeFunc::Parms+0] = nullptr; // void
1864 const TypeTuple* range = TypeTuple::make(TypeFunc::Parms, fields);
1865 return TypeFunc::make(domain, range);
1866 }
1867 #endif // PRODUCT
1868
1869 //-------------------------------------------------------------------------------------
1870 // register policy
1871
1872 bool OptoRuntime::is_callee_saved_register(MachRegisterNumbers reg) {
1873 assert(reg >= 0 && reg < _last_Mach_Reg, "must be a machine register");
1874 switch (register_save_policy[reg]) {
1875 case 'C': return false; //SOC
1876 case 'E': return true ; //SOE
1877 case 'N': return false; //NS
1878 case 'A': return false; //AS
1879 }
1880 ShouldNotReachHere();
1881 return false;
1882 }
1883
1884 //-----------------------------------------------------------------------
1885 // Exceptions
1886 //
1887
1888 static void trace_exception(outputStream* st, oop exception_oop, address exception_pc, const char* msg);
1889
1890 // The method is an entry that is always called by a C++ method not
1891 // directly from compiled code. Compiled code will call the C++ method following.
1892 // We can't allow async exception to be installed during exception processing.
1893 JRT_ENTRY_NO_ASYNC(address, OptoRuntime::handle_exception_C_helper(JavaThread* current, nmethod* &nm))
1894 // The frame we rethrow the exception to might not have been processed by the GC yet.
1895 // The stack watermark barrier takes care of detecting that and ensuring the frame
1896 // has updated oops.
1897 StackWatermarkSet::after_unwind(current);
1898
1899 MACOS_AARCH64_ONLY(os::thread_wx_enable_write());
1900
1901 // Do not confuse exception_oop with pending_exception. The exception_oop
1902 // is only used to pass arguments into the method. Not for general
1903 // exception handling. DO NOT CHANGE IT to use pending_exception, since
1904 // the runtime stubs checks this on exit.
1905 assert(current->exception_oop() != nullptr, "exception oop is found");
1906 address handler_address = nullptr;
1907
1908 Handle exception(current, current->exception_oop());
1909 address pc = current->exception_pc();
1910
1911 // Clear out the exception oop and pc since looking up an
1912 // exception handler can cause class loading, which might throw an
1913 // exception and those fields are expected to be clear during
1914 // normal bytecode execution.
1915 current->clear_exception_oop_and_pc();
1916
1917 LogTarget(Info, exceptions) lt;
1918 if (lt.is_enabled()) {
1919 LogStream ls(lt);
1920 trace_exception(&ls, exception(), pc, "");
1921 }
1922
1923 // for AbortVMOnException flag
1924 Exceptions::debug_check_abort(exception);
1925
1926 #ifdef ASSERT
1927 if (!(exception->is_a(vmClasses::Throwable_klass()))) {
1928 // should throw an exception here
1929 ShouldNotReachHere();
1930 }
1931 #endif
1932
1933 // new exception handling: this method is entered only from adapters
1934 // exceptions from compiled java methods are handled in compiled code
1935 // using rethrow node
1936
1937 nm = CodeCache::find_nmethod(pc);
1938 assert(nm != nullptr, "No NMethod found");
1939 if (nm->is_native_method()) {
1940 fatal("Native method should not have path to exception handling");
1941 } else {
1942 // we are switching to old paradigm: search for exception handler in caller_frame
1943 // instead in exception handler of caller_frame.sender()
1944
1945 if (JvmtiExport::can_post_on_exceptions()) {
1946 // "Full-speed catching" is not necessary here,
1947 // since we're notifying the VM on every catch.
1948 // Force deoptimization and the rest of the lookup
1949 // will be fine.
1950 deoptimize_caller_frame(current);
1951 }
1952
1953 // Check the stack guard pages. If enabled, look for handler in this frame;
1954 // otherwise, forcibly unwind the frame.
1955 //
1956 // 4826555: use default current sp for reguard_stack instead of &nm: it's more accurate.
1957 bool force_unwind = !current->stack_overflow_state()->reguard_stack();
1958 bool deopting = false;
1959 if (nm->is_deopt_pc(pc)) {
1960 deopting = true;
1961 RegisterMap map(current,
1962 RegisterMap::UpdateMap::skip,
1963 RegisterMap::ProcessFrames::include,
1964 RegisterMap::WalkContinuation::skip);
1965 frame deoptee = current->last_frame().sender(&map);
1966 assert(deoptee.is_deoptimized_frame(), "must be deopted");
1967 // Adjust the pc back to the original throwing pc
1968 pc = deoptee.pc();
1969 }
1970
1971 // If we are forcing an unwind because of stack overflow then deopt is
1972 // irrelevant since we are throwing the frame away anyway.
1973
1974 if (deopting && !force_unwind) {
1975 handler_address = SharedRuntime::deopt_blob()->unpack_with_exception();
1976 } else {
1977
1978 handler_address =
1979 force_unwind ? nullptr : nm->handler_for_exception_and_pc(exception, pc);
1980
1981 if (handler_address == nullptr) {
1982 bool recursive_exception = false;
1983 handler_address = SharedRuntime::compute_compiled_exc_handler(nm, pc, exception, force_unwind, true, recursive_exception);
1984 assert (handler_address != nullptr, "must have compiled handler");
1985 // Update the exception cache only when the unwind was not forced
1986 // and there didn't happen another exception during the computation of the
1987 // compiled exception handler. Checking for exception oop equality is not
1988 // sufficient because some exceptions are pre-allocated and reused.
1989 if (!force_unwind && !recursive_exception) {
1990 nm->add_handler_for_exception_and_pc(exception,pc,handler_address);
1991 }
1992 } else {
1993 #ifdef ASSERT
1994 bool recursive_exception = false;
1995 address computed_address = SharedRuntime::compute_compiled_exc_handler(nm, pc, exception, force_unwind, true, recursive_exception);
1996 vmassert(recursive_exception || (handler_address == computed_address), "Handler address inconsistency: " PTR_FORMAT " != " PTR_FORMAT,
1997 p2i(handler_address), p2i(computed_address));
1998 #endif
1999 }
2000 }
2001
2002 current->set_exception_pc(pc);
2003 current->set_exception_handler_pc(handler_address);
2004 }
2005
2006 // Restore correct return pc. Was saved above.
2007 current->set_exception_oop(exception());
2008 return handler_address;
2009
2010 JRT_END
2011
2012 // We are entering here from exception_blob
2013 // If there is a compiled exception handler in this method, we will continue there;
2014 // otherwise we will unwind the stack and continue at the caller of top frame method
2015 // Note we enter without the usual JRT wrapper. We will call a helper routine that
2016 // will do the normal VM entry. We do it this way so that we can see if the nmethod
2017 // we looked up the handler for has been deoptimized in the meantime. If it has been
2018 // we must not use the handler and instead return the deopt blob.
2019 address OptoRuntime::handle_exception_C(JavaThread* current) {
2020 //
2021 // We are in Java not VM and in debug mode we have a NoHandleMark
2022 //
2023 #ifndef PRODUCT
2024 SharedRuntime::_find_handler_ctr++; // find exception handler
2025 #endif
2026 DEBUG_ONLY(NoHandleMark __hm;)
2027 nmethod* nm = nullptr;
2028 address handler_address = nullptr;
2029 {
2030 // Enter the VM
2031
2032 ResetNoHandleMark rnhm;
2033 handler_address = handle_exception_C_helper(current, nm);
2034 }
2035
2036 // Back in java: Use no oops, DON'T safepoint
2037
2038 // Now check to see if the handler we are returning is in a now
2039 // deoptimized frame
2040
2041 if (nm != nullptr) {
2042 RegisterMap map(current,
2043 RegisterMap::UpdateMap::skip,
2044 RegisterMap::ProcessFrames::skip,
2045 RegisterMap::WalkContinuation::skip);
2046 frame caller = current->last_frame().sender(&map);
2047 #ifdef ASSERT
2048 assert(caller.is_compiled_frame(), "must be");
2049 #endif // ASSERT
2050 if (caller.is_deoptimized_frame()) {
2051 handler_address = SharedRuntime::deopt_blob()->unpack_with_exception();
2052 }
2053 }
2054 return handler_address;
2055 }
2056
2057 //------------------------------rethrow----------------------------------------
2058 // We get here after compiled code has executed a 'RethrowNode'. The callee
2059 // is either throwing or rethrowing an exception. The callee-save registers
2060 // have been restored, synchronized objects have been unlocked and the callee
2061 // stack frame has been removed. The return address was passed in.
2062 // Exception oop is passed as the 1st argument. This routine is then called
2063 // from the stub. On exit, we know where to jump in the caller's code.
2064 // After this C code exits, the stub will pop his frame and end in a jump
2065 // (instead of a return). We enter the caller's default handler.
2066 //
2067 // This must be JRT_LEAF:
2068 // - caller will not change its state as we cannot block on exit,
2069 // therefore raw_exception_handler_for_return_address is all it takes
2070 // to handle deoptimized blobs
2071 //
2072 // However, there needs to be a safepoint check in the middle! So compiled
2073 // safepoints are completely watertight.
2074 //
2075 // Thus, it cannot be a leaf since it contains the NoSafepointVerifier.
2076 //
2077 // *THIS IS NOT RECOMMENDED PROGRAMMING STYLE*
2078 //
2079 address OptoRuntime::rethrow_C(oopDesc* exception, JavaThread* thread, address ret_pc) {
2080 // ret_pc will have been loaded from the stack, so for AArch64 will be signed.
2081 AARCH64_PORT_ONLY(ret_pc = pauth_strip_verifiable(ret_pc));
2082
2083 #ifndef PRODUCT
2084 SharedRuntime::_rethrow_ctr++; // count rethrows
2085 #endif
2086 assert (exception != nullptr, "should have thrown a NullPointerException");
2087 #ifdef ASSERT
2088 if (!(exception->is_a(vmClasses::Throwable_klass()))) {
2089 // should throw an exception here
2090 ShouldNotReachHere();
2091 }
2092 #endif
2093
2094 thread->set_vm_result_oop(exception);
2095 // Frame not compiled (handles deoptimization blob)
2096 return SharedRuntime::raw_exception_handler_for_return_address(thread, ret_pc);
2097 }
2098
2099 static const TypeFunc* make_rethrow_Type() {
2100 // create input type (domain)
2101 const Type **fields = TypeTuple::fields(1);
2102 fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; // Exception oop
2103 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+1,fields);
2104
2105 // create result type (range)
2106 fields = TypeTuple::fields(1);
2107 fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; // Exception oop
2108 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+1, fields);
2109
2110 return TypeFunc::make(domain, range);
2111 }
2112
2113
2114 void OptoRuntime::deoptimize_caller_frame(JavaThread *thread, bool doit) {
2115 // Deoptimize the caller before continuing, as the compiled
2116 // exception handler table may not be valid.
2117 if (DeoptimizeOnAllocationException && doit) {
2118 deoptimize_caller_frame(thread);
2119 }
2120 }
2121
2122 void OptoRuntime::deoptimize_caller_frame(JavaThread *thread) {
2123 // Called from within the owner thread, so no need for safepoint
2124 RegisterMap reg_map(thread,
2125 RegisterMap::UpdateMap::include,
2126 RegisterMap::ProcessFrames::include,
2127 RegisterMap::WalkContinuation::skip);
2128 frame stub_frame = thread->last_frame();
2129 assert(stub_frame.is_runtime_frame() || exception_blob()->contains(stub_frame.pc()), "sanity check");
2130 frame caller_frame = stub_frame.sender(®_map);
2131
2132 // Deoptimize the caller frame.
2133 Deoptimization::deoptimize_frame(thread, caller_frame.id());
2134 }
2135
2136
2137 bool OptoRuntime::is_deoptimized_caller_frame(JavaThread *thread) {
2138 // Called from within the owner thread, so no need for safepoint
2139 RegisterMap reg_map(thread,
2140 RegisterMap::UpdateMap::include,
2141 RegisterMap::ProcessFrames::include,
2142 RegisterMap::WalkContinuation::skip);
2143 frame stub_frame = thread->last_frame();
2144 assert(stub_frame.is_runtime_frame() || exception_blob()->contains(stub_frame.pc()), "sanity check");
2145 frame caller_frame = stub_frame.sender(®_map);
2146 return caller_frame.is_deoptimized_frame();
2147 }
2148
2149 static const TypeFunc* make_register_finalizer_Type() {
2150 // create input type (domain)
2151 const Type **fields = TypeTuple::fields(1);
2152 fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; // oop; Receiver
2153 // // The JavaThread* is passed to each routine as the last argument
2154 // fields[TypeFunc::Parms+1] = TypeRawPtr::NOTNULL; // JavaThread *; Executing thread
2155 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+1,fields);
2156
2157 // create result type (range)
2158 fields = TypeTuple::fields(0);
2159
2160 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0,fields);
2161
2162 return TypeFunc::make(domain, range);
2163 }
2164
2165 #if INCLUDE_JFR
2166 static const TypeFunc* make_class_id_load_barrier_Type() {
2167 // create input type (domain)
2168 const Type **fields = TypeTuple::fields(1);
2169 fields[TypeFunc::Parms+0] = TypeInstPtr::KLASS;
2170 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms + 1, fields);
2171
2172 // create result type (range)
2173 fields = TypeTuple::fields(0);
2174
2175 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms + 0, fields);
2176
2177 return TypeFunc::make(domain,range);
2178 }
2179 #endif // INCLUDE_JFR
2180
2181 //-----------------------------------------------------------------------------
2182 static const TypeFunc* make_dtrace_method_entry_exit_Type() {
2183 // create input type (domain)
2184 const Type **fields = TypeTuple::fields(2);
2185 fields[TypeFunc::Parms+0] = TypeRawPtr::BOTTOM; // Thread-local storage
2186 fields[TypeFunc::Parms+1] = TypeMetadataPtr::BOTTOM; // Method*; Method we are entering
2187 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+2,fields);
2188
2189 // create result type (range)
2190 fields = TypeTuple::fields(0);
2191
2192 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0,fields);
2193
2194 return TypeFunc::make(domain, range);
2195 }
2196
2197 static const TypeFunc* make_dtrace_object_alloc_Type() {
2198 // create input type (domain)
2199 const Type **fields = TypeTuple::fields(2);
2200 fields[TypeFunc::Parms+0] = TypeRawPtr::BOTTOM; // Thread-local storage
2201 fields[TypeFunc::Parms+1] = TypeInstPtr::NOTNULL; // oop; newly allocated object
2202
2203 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+2,fields);
2204
2205 // create result type (range)
2206 fields = TypeTuple::fields(0);
2207
2208 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0,fields);
2209
2210 return TypeFunc::make(domain, range);
2211 }
2212
2213 JRT_ENTRY_NO_ASYNC(void, OptoRuntime::register_finalizer_C(oopDesc* obj, JavaThread* current))
2214 assert(oopDesc::is_oop(obj), "must be a valid oop");
2215 assert(obj->klass()->has_finalizer(), "shouldn't be here otherwise");
2216 InstanceKlass::register_finalizer(instanceOop(obj), CHECK);
2217 JRT_END
2218
2219 //-----------------------------------------------------------------------------
2220
2221 NamedCounter * volatile OptoRuntime::_named_counters = nullptr;
2222
2223 //
2224 // dump the collected NamedCounters.
2225 //
2226 void OptoRuntime::print_named_counters() {
2227 int total_lock_count = 0;
2228 int eliminated_lock_count = 0;
2229
2230 NamedCounter* c = _named_counters;
2231 while (c) {
2232 if (c->tag() == NamedCounter::LockCounter || c->tag() == NamedCounter::EliminatedLockCounter) {
2233 int count = c->count();
2234 if (count > 0) {
2235 bool eliminated = c->tag() == NamedCounter::EliminatedLockCounter;
2236 if (Verbose) {
2237 tty->print_cr("%d %s%s", count, c->name(), eliminated ? " (eliminated)" : "");
2238 }
2239 total_lock_count += count;
2240 if (eliminated) {
2241 eliminated_lock_count += count;
2242 }
2243 }
2244 }
2245 c = c->next();
2246 }
2247 if (total_lock_count > 0) {
2248 tty->print_cr("dynamic locks: %d", total_lock_count);
2249 if (eliminated_lock_count) {
2250 tty->print_cr("eliminated locks: %d (%d%%)", eliminated_lock_count,
2251 (int)(eliminated_lock_count * 100.0 / total_lock_count));
2252 }
2253 }
2254 }
2255
2256 //
2257 // Allocate a new NamedCounter. The JVMState is used to generate the
2258 // name which consists of method@line for the inlining tree.
2259 //
2260
2261 NamedCounter* OptoRuntime::new_named_counter(JVMState* youngest_jvms, NamedCounter::CounterTag tag) {
2262 int max_depth = youngest_jvms->depth();
2263
2264 // Visit scopes from youngest to oldest.
2265 bool first = true;
2266 stringStream st;
2267 for (int depth = max_depth; depth >= 1; depth--) {
2268 JVMState* jvms = youngest_jvms->of_depth(depth);
2269 ciMethod* m = jvms->has_method() ? jvms->method() : nullptr;
2270 if (!first) {
2271 st.print(" ");
2272 } else {
2273 first = false;
2274 }
2275 int bci = jvms->bci();
2276 if (bci < 0) bci = 0;
2277 if (m != nullptr) {
2278 st.print("%s.%s", m->holder()->name()->as_utf8(), m->name()->as_utf8());
2279 } else {
2280 st.print("no method");
2281 }
2282 st.print("@%d", bci);
2283 // To print linenumbers instead of bci use: m->line_number_from_bci(bci)
2284 }
2285 NamedCounter* c = new NamedCounter(st.freeze(), tag);
2286
2287 // atomically add the new counter to the head of the list. We only
2288 // add counters so this is safe.
2289 NamedCounter* head;
2290 do {
2291 c->set_next(nullptr);
2292 head = _named_counters;
2293 c->set_next(head);
2294 } while (AtomicAccess::cmpxchg(&_named_counters, head, c) != head);
2295 return c;
2296 }
2297
2298 void OptoRuntime::initialize_types() {
2299 _new_instance_Type = make_new_instance_Type();
2300 _new_array_Type = make_new_array_Type();
2301 _new_array_nozero_Type = make_new_array_nozero_Type();
2302 _multianewarray2_Type = multianewarray_Type(2);
2303 _multianewarray3_Type = multianewarray_Type(3);
2304 _multianewarray4_Type = multianewarray_Type(4);
2305 _multianewarray5_Type = multianewarray_Type(5);
2306 _multianewarrayN_Type = make_multianewarrayN_Type();
2307 _complete_monitor_enter_Type = make_complete_monitor_enter_Type();
2308 _complete_monitor_exit_Type = make_complete_monitor_exit_Type();
2309 _monitor_notify_Type = make_monitor_notify_Type();
2310 _uncommon_trap_Type = make_uncommon_trap_Type();
2311 _athrow_Type = make_athrow_Type();
2312 _rethrow_Type = make_rethrow_Type();
2313 _Math_D_D_Type = make_Math_D_D_Type();
2314 _Math_DD_D_Type = make_Math_DD_D_Type();
2315 _modf_Type = make_modf_Type();
2316 _l2f_Type = make_l2f_Type();
2317 _void_long_Type = make_void_long_Type();
2318 _void_void_Type = make_void_void_Type();
2319 _jfr_write_checkpoint_Type = make_jfr_write_checkpoint_Type();
2320 _flush_windows_Type = make_flush_windows_Type();
2321 _fast_arraycopy_Type = make_arraycopy_Type(ac_fast);
2322 _checkcast_arraycopy_Type = make_arraycopy_Type(ac_checkcast);
2323 _generic_arraycopy_Type = make_arraycopy_Type(ac_generic);
2324 _slow_arraycopy_Type = make_arraycopy_Type(ac_slow);
2325 _unsafe_setmemory_Type = make_setmemory_Type();
2326 _array_fill_Type = make_array_fill_Type();
2327 _array_sort_Type = make_array_sort_Type();
2328 _array_partition_Type = make_array_partition_Type();
2329 _aescrypt_block_Type = make_aescrypt_block_Type();
2330 _cipherBlockChaining_aescrypt_Type = make_cipherBlockChaining_aescrypt_Type();
2331 _electronicCodeBook_aescrypt_Type = make_electronicCodeBook_aescrypt_Type();
2332 _counterMode_aescrypt_Type = make_counterMode_aescrypt_Type();
2333 _galoisCounterMode_aescrypt_Type = make_galoisCounterMode_aescrypt_Type();
2334 _digestBase_implCompress_with_sha3_Type = make_digestBase_implCompress_Type( /* is_sha3= */ true);
2335 _digestBase_implCompress_without_sha3_Type = make_digestBase_implCompress_Type( /* is_sha3= */ false);;
2336 _digestBase_implCompressMB_with_sha3_Type = make_digestBase_implCompressMB_Type(/* is_sha3= */ true);
2337 _digestBase_implCompressMB_without_sha3_Type = make_digestBase_implCompressMB_Type(/* is_sha3= */ false);
2338 _double_keccak_Type = make_double_keccak_Type();
2339 _multiplyToLen_Type = make_multiplyToLen_Type();
2340 _montgomeryMultiply_Type = make_montgomeryMultiply_Type();
2341 _montgomerySquare_Type = make_montgomerySquare_Type();
2342 _squareToLen_Type = make_squareToLen_Type();
2343 _mulAdd_Type = make_mulAdd_Type();
2344 _bigIntegerShift_Type = make_bigIntegerShift_Type();
2345 _vectorizedMismatch_Type = make_vectorizedMismatch_Type();
2346 _ghash_processBlocks_Type = make_ghash_processBlocks_Type();
2347 _chacha20Block_Type = make_chacha20Block_Type();
2348 _kyberNtt_Type = make_kyberNtt_Type();
2349 _kyberInverseNtt_Type = make_kyberInverseNtt_Type();
2350 _kyberNttMult_Type = make_kyberNttMult_Type();
2351 _kyberAddPoly_2_Type = make_kyberAddPoly_2_Type();
2352 _kyberAddPoly_3_Type = make_kyberAddPoly_3_Type();
2353 _kyber12To16_Type = make_kyber12To16_Type();
2354 _kyberBarrettReduce_Type = make_kyberBarrettReduce_Type();
2355 _dilithiumAlmostNtt_Type = make_dilithiumAlmostNtt_Type();
2356 _dilithiumAlmostInverseNtt_Type = make_dilithiumAlmostInverseNtt_Type();
2357 _dilithiumNttMult_Type = make_dilithiumNttMult_Type();
2358 _dilithiumMontMulByConstant_Type = make_dilithiumMontMulByConstant_Type();
2359 _dilithiumDecomposePoly_Type = make_dilithiumDecomposePoly_Type();
2360 _base64_encodeBlock_Type = make_base64_encodeBlock_Type();
2361 _base64_decodeBlock_Type = make_base64_decodeBlock_Type();
2362 _string_IndexOf_Type = make_string_IndexOf_Type();
2363 _poly1305_processBlocks_Type = make_poly1305_processBlocks_Type();
2364 _intpoly_montgomeryMult_P256_Type = make_intpoly_montgomeryMult_P256_Type();
2365 _intpoly_assign_Type = make_intpoly_assign_Type();
2366 _updateBytesCRC32_Type = make_updateBytesCRC32_Type();
2367 _updateBytesCRC32C_Type = make_updateBytesCRC32C_Type();
2368 _updateBytesAdler32_Type = make_updateBytesAdler32_Type();
2369 _osr_end_Type = make_osr_end_Type();
2370 _register_finalizer_Type = make_register_finalizer_Type();
2371 _vthread_transition_Type = make_vthread_transition_Type();
2372 JFR_ONLY(
2373 _class_id_load_barrier_Type = make_class_id_load_barrier_Type();
2374 )
2375 _dtrace_method_entry_exit_Type = make_dtrace_method_entry_exit_Type();
2376 _dtrace_object_alloc_Type = make_dtrace_object_alloc_Type();
2377 }
2378
2379 int trace_exception_counter = 0;
2380 static void trace_exception(outputStream* st, oop exception_oop, address exception_pc, const char* msg) {
2381 trace_exception_counter++;
2382 stringStream tempst;
2383
2384 tempst.print("%d [Exception (%s): ", trace_exception_counter, msg);
2385 exception_oop->print_value_on(&tempst);
2386 tempst.print(" in ");
2387 CodeBlob* blob = CodeCache::find_blob(exception_pc);
2388 if (blob->is_nmethod()) {
2389 blob->as_nmethod()->method()->print_value_on(&tempst);
2390 } else if (blob->is_runtime_stub()) {
2391 tempst.print("<runtime-stub>");
2392 } else {
2393 tempst.print("<unknown>");
2394 }
2395 tempst.print(" at " INTPTR_FORMAT, p2i(exception_pc));
2396 tempst.print("]");
2397
2398 st->print_raw_cr(tempst.freeze());
2399 }
2400
2401 const TypeFunc *OptoRuntime::store_inline_type_fields_Type() {
2402 // create input type (domain)
2403 uint total = SharedRuntime::java_return_convention_max_int + SharedRuntime::java_return_convention_max_float*2;
2404 const Type **fields = TypeTuple::fields(total);
2405 // We don't know the number of returned values and their
2406 // types. Assume all registers available to the return convention
2407 // are used.
2408 fields[TypeFunc::Parms] = TypePtr::BOTTOM;
2409 uint i = 1;
2410 for (; i < SharedRuntime::java_return_convention_max_int; i++) {
2411 fields[TypeFunc::Parms+i] = TypeInt::INT;
2412 }
2413 for (; i < total; i+=2) {
2414 fields[TypeFunc::Parms+i] = Type::DOUBLE;
2415 fields[TypeFunc::Parms+i+1] = Type::HALF;
2416 }
2417 const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms + total, fields);
2418
2419 // create result type (range)
2420 fields = TypeTuple::fields(1);
2421 fields[TypeFunc::Parms+0] = TypeInstPtr::BOTTOM;
2422
2423 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+1,fields);
2424
2425 return TypeFunc::make(domain, range);
2426 }
2427
2428 const TypeFunc *OptoRuntime::pack_inline_type_Type() {
2429 // create input type (domain)
2430 uint total = 1 + SharedRuntime::java_return_convention_max_int + SharedRuntime::java_return_convention_max_float*2;
2431 const Type **fields = TypeTuple::fields(total);
2432 // We don't know the number of returned values and their
2433 // types. Assume all registers available to the return convention
2434 // are used.
2435 fields[TypeFunc::Parms] = TypeRawPtr::BOTTOM;
2436 fields[TypeFunc::Parms+1] = TypeRawPtr::BOTTOM;
2437 uint i = 2;
2438 for (; i < SharedRuntime::java_return_convention_max_int+1; i++) {
2439 fields[TypeFunc::Parms+i] = TypeInt::INT;
2440 }
2441 for (; i < total; i+=2) {
2442 fields[TypeFunc::Parms+i] = Type::DOUBLE;
2443 fields[TypeFunc::Parms+i+1] = Type::HALF;
2444 }
2445 const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms + total, fields);
2446
2447 // create result type (range)
2448 fields = TypeTuple::fields(1);
2449 fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL;
2450
2451 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+1,fields);
2452
2453 return TypeFunc::make(domain, range);
2454 }
2455
2456 JRT_BLOCK_ENTRY(void, OptoRuntime::load_unknown_inline_C(flatArrayOopDesc* array, int index, JavaThread* current))
2457 JRT_BLOCK;
2458 oop buffer = array->obj_at(index, THREAD);
2459 deoptimize_caller_frame(current, HAS_PENDING_EXCEPTION);
2460 current->set_vm_result_oop(buffer);
2461 JRT_BLOCK_END;
2462 JRT_END
2463
2464 const TypeFunc* OptoRuntime::load_unknown_inline_Type() {
2465 // create input type (domain)
2466 const Type** fields = TypeTuple::fields(2);
2467 fields[TypeFunc::Parms] = TypeOopPtr::NOTNULL;
2468 fields[TypeFunc::Parms+1] = TypeInt::POS;
2469
2470 const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms+2, fields);
2471
2472 // create result type (range)
2473 fields = TypeTuple::fields(1);
2474 fields[TypeFunc::Parms] = TypeInstPtr::BOTTOM;
2475
2476 const TypeTuple* range = TypeTuple::make(TypeFunc::Parms+1, fields);
2477
2478 return TypeFunc::make(domain, range);
2479 }
2480
2481 JRT_BLOCK_ENTRY(void, OptoRuntime::store_unknown_inline_C(instanceOopDesc* buffer, flatArrayOopDesc* array, int index, JavaThread* current))
2482 JRT_BLOCK;
2483 array->obj_at_put(index, buffer, THREAD);
2484 if (HAS_PENDING_EXCEPTION) {
2485 fatal("This entry must be changed to be a non-leaf entry because writing to a flat array can now throw an exception");
2486 }
2487 JRT_BLOCK_END;
2488 JRT_END
2489
2490 const TypeFunc* OptoRuntime::store_unknown_inline_Type() {
2491 // create input type (domain)
2492 const Type** fields = TypeTuple::fields(3);
2493 fields[TypeFunc::Parms] = TypeInstPtr::NOTNULL;
2494 fields[TypeFunc::Parms+1] = TypeOopPtr::NOTNULL;
2495 fields[TypeFunc::Parms+2] = TypeInt::POS;
2496
2497 const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms+3, fields);
2498
2499 // create result type (range)
2500 fields = TypeTuple::fields(0);
2501 const TypeTuple* range = TypeTuple::make(TypeFunc::Parms, fields);
2502
2503 return TypeFunc::make(domain, range);
2504 }