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