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