1 /* 2 * Copyright (c) 1998, 2024, 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 "precompiled.hpp" 26 #include "classfile/vmClasses.hpp" 27 #include "classfile/vmSymbols.hpp" 28 #include "code/codeCache.hpp" 29 #include "code/compiledIC.hpp" 30 #include "code/nmethod.hpp" 31 #include "code/pcDesc.hpp" 32 #include "code/scopeDesc.hpp" 33 #include "code/vtableStubs.hpp" 34 #include "compiler/compileBroker.hpp" 35 #include "compiler/compilerDefinitions.inline.hpp" 36 #include "compiler/oopMap.hpp" 37 #include "gc/g1/g1HeapRegion.hpp" 38 #include "gc/shared/barrierSet.hpp" 39 #include "gc/shared/collectedHeap.hpp" 40 #include "gc/shared/gcLocker.hpp" 41 #include "interpreter/bytecode.hpp" 42 #include "interpreter/interpreter.hpp" 43 #include "interpreter/linkResolver.hpp" 44 #include "logging/log.hpp" 45 #include "logging/logStream.hpp" 46 #include "memory/oopFactory.hpp" 47 #include "memory/resourceArea.hpp" 48 #include "oops/objArrayKlass.hpp" 49 #include "oops/klass.inline.hpp" 50 #include "oops/oop.inline.hpp" 51 #include "oops/typeArrayOop.inline.hpp" 52 #include "opto/ad.hpp" 53 #include "opto/addnode.hpp" 54 #include "opto/callnode.hpp" 55 #include "opto/cfgnode.hpp" 56 #include "opto/graphKit.hpp" 57 #include "opto/machnode.hpp" 58 #include "opto/matcher.hpp" 59 #include "opto/memnode.hpp" 60 #include "opto/mulnode.hpp" 61 #include "opto/output.hpp" 62 #include "opto/runtime.hpp" 63 #include "opto/subnode.hpp" 64 #include "prims/jvmtiExport.hpp" 65 #include "runtime/atomic.hpp" 66 #include "runtime/frame.inline.hpp" 67 #include "runtime/handles.inline.hpp" 68 #include "runtime/interfaceSupport.inline.hpp" 69 #include "runtime/java.hpp" 70 #include "runtime/javaCalls.hpp" 71 #include "runtime/perfData.inline.hpp" 72 #include "runtime/sharedRuntime.hpp" 73 #include "runtime/signature.hpp" 74 #include "runtime/stackWatermarkSet.hpp" 75 #include "runtime/synchronizer.hpp" 76 #include "runtime/threadCritical.hpp" 77 #include "runtime/threadWXSetters.inline.hpp" 78 #include "runtime/vframe.hpp" 79 #include "runtime/vframeArray.hpp" 80 #include "runtime/vframe_hp.hpp" 81 #include "services/management.hpp" 82 #include "utilities/copy.hpp" 83 #include "utilities/preserveException.hpp" 84 85 86 // For debugging purposes: 87 // To force FullGCALot inside a runtime function, add the following two lines 88 // 89 // Universe::release_fullgc_alot_dummy(); 90 // Universe::heap()->collect(); 91 // 92 // At command line specify the parameters: -XX:+FullGCALot -XX:FullGCALotStart=100000000 93 94 95 96 97 // Compiled code entry points 98 address OptoRuntime::_new_instance_Java = nullptr; 99 address OptoRuntime::_new_array_Java = nullptr; 100 address OptoRuntime::_new_array_nozero_Java = nullptr; 101 address OptoRuntime::_multianewarray2_Java = nullptr; 102 address OptoRuntime::_multianewarray3_Java = nullptr; 103 address OptoRuntime::_multianewarray4_Java = nullptr; 104 address OptoRuntime::_multianewarray5_Java = nullptr; 105 address OptoRuntime::_multianewarrayN_Java = nullptr; 106 address OptoRuntime::_vtable_must_compile_Java = nullptr; 107 address OptoRuntime::_complete_monitor_locking_Java = nullptr; 108 address OptoRuntime::_monitor_notify_Java = nullptr; 109 address OptoRuntime::_monitor_notifyAll_Java = nullptr; 110 address OptoRuntime::_rethrow_Java = nullptr; 111 112 address OptoRuntime::_slow_arraycopy_Java = nullptr; 113 address OptoRuntime::_register_finalizer_Java = nullptr; 114 address OptoRuntime::_class_init_barrier_Java = nullptr; 115 #if INCLUDE_JVMTI 116 address OptoRuntime::_notify_jvmti_vthread_start = nullptr; 117 address OptoRuntime::_notify_jvmti_vthread_end = nullptr; 118 address OptoRuntime::_notify_jvmti_vthread_mount = nullptr; 119 address OptoRuntime::_notify_jvmti_vthread_unmount = nullptr; 120 #endif 121 122 ExceptionBlob* OptoRuntime::_exception_blob; 123 124 PerfCounter* _perf_OptoRuntime_class_init_barrier_redundant_count = nullptr; 125 126 // This should be called in an assertion at the start of OptoRuntime routines 127 // which are entered from compiled code (all of them) 128 #ifdef ASSERT 129 static bool check_compiled_frame(JavaThread* thread) { 130 assert(thread->last_frame().is_runtime_frame(), "cannot call runtime directly from compiled code"); 131 RegisterMap map(thread, 132 RegisterMap::UpdateMap::skip, 133 RegisterMap::ProcessFrames::include, 134 RegisterMap::WalkContinuation::skip); 135 frame caller = thread->last_frame().sender(&map); 136 assert(caller.is_compiled_frame(), "not being called from compiled like code"); 137 return true; 138 } 139 #endif // ASSERT 140 141 142 #define gen(env, var, type_func_gen, c_func, fancy_jump, pass_tls, return_pc) \ 143 var = generate_stub(env, type_func_gen, CAST_FROM_FN_PTR(address, c_func), #var, fancy_jump, pass_tls, return_pc); \ 144 if (var == nullptr) { return false; } 145 146 bool OptoRuntime::generate(ciEnv* env) { 147 init_counters(); 148 149 generate_exception_blob(); 150 151 // Note: tls: Means fetching the return oop out of the thread-local storage 152 // 153 // variable/name type-function-gen , runtime method ,fncy_jp, tls,retpc 154 // ------------------------------------------------------------------------------------------------------------------------------- 155 gen(env, _new_instance_Java , new_instance_Type , new_instance_C , 0 , true, false); 156 gen(env, _new_array_Java , new_array_Type , new_array_C , 0 , true, false); 157 gen(env, _new_array_nozero_Java , new_array_Type , new_array_nozero_C , 0 , true, false); 158 gen(env, _multianewarray2_Java , multianewarray2_Type , multianewarray2_C , 0 , true, false); 159 gen(env, _multianewarray3_Java , multianewarray3_Type , multianewarray3_C , 0 , true, false); 160 gen(env, _multianewarray4_Java , multianewarray4_Type , multianewarray4_C , 0 , true, false); 161 gen(env, _multianewarray5_Java , multianewarray5_Type , multianewarray5_C , 0 , true, false); 162 gen(env, _multianewarrayN_Java , multianewarrayN_Type , multianewarrayN_C , 0 , true, false); 163 #if INCLUDE_JVMTI 164 gen(env, _notify_jvmti_vthread_start , notify_jvmti_vthread_Type , SharedRuntime::notify_jvmti_vthread_start, 0, true, false); 165 gen(env, _notify_jvmti_vthread_end , notify_jvmti_vthread_Type , SharedRuntime::notify_jvmti_vthread_end, 0, true, false); 166 gen(env, _notify_jvmti_vthread_mount , notify_jvmti_vthread_Type , SharedRuntime::notify_jvmti_vthread_mount, 0, true, false); 167 gen(env, _notify_jvmti_vthread_unmount , notify_jvmti_vthread_Type , SharedRuntime::notify_jvmti_vthread_unmount, 0, true, false); 168 #endif 169 gen(env, _complete_monitor_locking_Java , complete_monitor_enter_Type , SharedRuntime::complete_monitor_locking_C, 0, false, false); 170 gen(env, _monitor_notify_Java , monitor_notify_Type , monitor_notify_C , 0 , false, false); 171 gen(env, _monitor_notifyAll_Java , monitor_notify_Type , monitor_notifyAll_C , 0 , false, false); 172 gen(env, _rethrow_Java , rethrow_Type , rethrow_C , 2 , true , true ); 173 174 gen(env, _slow_arraycopy_Java , slow_arraycopy_Type , SharedRuntime::slow_arraycopy_C , 0 , false, false); 175 gen(env, _register_finalizer_Java , register_finalizer_Type , register_finalizer , 0 , false, false); 176 gen(env, _class_init_barrier_Java , class_init_barrier_Type , class_init_barrier , 0 , false, false); 177 178 return true; 179 } 180 181 #undef gen 182 183 184 // Helper method to do generation of RunTimeStub's 185 address OptoRuntime::generate_stub(ciEnv* env, 186 TypeFunc_generator gen, address C_function, 187 const char *name, int is_fancy_jump, 188 bool pass_tls, 189 bool return_pc) { 190 191 // Matching the default directive, we currently have no method to match. 192 DirectiveSet* directive = DirectivesStack::getDefaultDirective(CompilerThread::current()->compiler()); 193 ResourceMark rm; 194 Compile C(env, gen, C_function, name, is_fancy_jump, pass_tls, return_pc, directive); 195 DirectivesStack::release(directive); 196 return C.stub_entry_point(); 197 } 198 199 const char* OptoRuntime::stub_name(address entry) { 200 #ifndef PRODUCT 201 CodeBlob* cb = CodeCache::find_blob(entry); 202 RuntimeStub* rs =(RuntimeStub *)cb; 203 assert(rs != nullptr && rs->is_runtime_stub(), "not a runtime stub"); 204 return rs->name(); 205 #else 206 // Fast implementation for product mode (maybe it should be inlined too) 207 return "runtime stub"; 208 #endif 209 } 210 211 212 //============================================================================= 213 // Opto compiler runtime routines 214 //============================================================================= 215 216 217 //=============================allocation====================================== 218 // We failed the fast-path allocation. Now we need to do a scavenge or GC 219 // and try allocation again. 220 221 // object allocation 222 JRT_BLOCK_ENTRY_PROF(void, OptoRuntime, new_instance_C, OptoRuntime::new_instance_C(Klass* klass, JavaThread* current)) 223 JRT_BLOCK; 224 #ifndef PRODUCT 225 SharedRuntime::_new_instance_ctr++; // new instance requires GC 226 #endif 227 assert(check_compiled_frame(current), "incorrect caller"); 228 229 // These checks are cheap to make and support reflective allocation. 230 int lh = klass->layout_helper(); 231 if (Klass::layout_helper_needs_slow_path(lh) || !InstanceKlass::cast(klass)->is_initialized()) { 232 Handle holder(current, klass->klass_holder()); // keep the klass alive 233 klass->check_valid_for_instantiation(false, THREAD); 234 if (!HAS_PENDING_EXCEPTION) { 235 InstanceKlass::cast(klass)->initialize(THREAD); 236 } 237 } 238 239 if (!HAS_PENDING_EXCEPTION) { 240 // Scavenge and allocate an instance. 241 Handle holder(current, klass->klass_holder()); // keep the klass alive 242 oop result = InstanceKlass::cast(klass)->allocate_instance(THREAD); 243 current->set_vm_result(result); 244 245 // Pass oops back through thread local storage. Our apparent type to Java 246 // is that we return an oop, but we can block on exit from this routine and 247 // a GC can trash the oop in C's return register. The generated stub will 248 // fetch the oop from TLS after any possible GC. 249 } 250 251 deoptimize_caller_frame(current, HAS_PENDING_EXCEPTION); 252 JRT_BLOCK_END; 253 254 // inform GC that we won't do card marks for initializing writes. 255 SharedRuntime::on_slowpath_allocation_exit(current); 256 JRT_END 257 258 259 // array allocation 260 JRT_BLOCK_ENTRY_PROF(void, OptoRuntime, new_array_C, OptoRuntime::new_array_C(Klass* array_type, int len, JavaThread* current)) 261 JRT_BLOCK; 262 #ifndef PRODUCT 263 SharedRuntime::_new_array_ctr++; // new array requires GC 264 #endif 265 assert(check_compiled_frame(current), "incorrect caller"); 266 267 // Scavenge and allocate an instance. 268 oop result; 269 270 if (array_type->is_typeArray_klass()) { 271 // The oopFactory likes to work with the element type. 272 // (We could bypass the oopFactory, since it doesn't add much value.) 273 BasicType elem_type = TypeArrayKlass::cast(array_type)->element_type(); 274 result = oopFactory::new_typeArray(elem_type, len, THREAD); 275 } else { 276 // Although the oopFactory likes to work with the elem_type, 277 // the compiler prefers the array_type, since it must already have 278 // that latter value in hand for the fast path. 279 Handle holder(current, array_type->klass_holder()); // keep the array klass alive 280 Klass* elem_type = ObjArrayKlass::cast(array_type)->element_klass(); 281 result = oopFactory::new_objArray(elem_type, len, THREAD); 282 } 283 284 // Pass oops back through thread local storage. Our apparent type to Java 285 // is that we return an oop, but we can block on exit from this routine and 286 // a GC can trash the oop in C's return register. The generated stub will 287 // fetch the oop from TLS after any possible GC. 288 deoptimize_caller_frame(current, HAS_PENDING_EXCEPTION); 289 current->set_vm_result(result); 290 JRT_BLOCK_END; 291 292 // inform GC that we won't do card marks for initializing writes. 293 SharedRuntime::on_slowpath_allocation_exit(current); 294 JRT_END 295 296 // array allocation without zeroing 297 JRT_BLOCK_ENTRY_PROF(void, OptoRuntime, new_array_nozero_C, OptoRuntime::new_array_nozero_C(Klass* array_type, int len, JavaThread* current)) 298 JRT_BLOCK; 299 #ifndef PRODUCT 300 SharedRuntime::_new_array_ctr++; // new array requires GC 301 #endif 302 assert(check_compiled_frame(current), "incorrect caller"); 303 304 // Scavenge and allocate an instance. 305 oop result; 306 307 assert(array_type->is_typeArray_klass(), "should be called only for type array"); 308 // The oopFactory likes to work with the element type. 309 BasicType elem_type = TypeArrayKlass::cast(array_type)->element_type(); 310 result = oopFactory::new_typeArray_nozero(elem_type, len, THREAD); 311 312 // Pass oops back through thread local storage. Our apparent type to Java 313 // is that we return an oop, but we can block on exit from this routine and 314 // a GC can trash the oop in C's return register. The generated stub will 315 // fetch the oop from TLS after any possible GC. 316 deoptimize_caller_frame(current, HAS_PENDING_EXCEPTION); 317 current->set_vm_result(result); 318 JRT_BLOCK_END; 319 320 321 // inform GC that we won't do card marks for initializing writes. 322 SharedRuntime::on_slowpath_allocation_exit(current); 323 324 oop result = current->vm_result(); 325 if ((len > 0) && (result != nullptr) && 326 is_deoptimized_caller_frame(current)) { 327 // Zero array here if the caller is deoptimized. 328 const size_t size = TypeArrayKlass::cast(array_type)->oop_size(result); 329 BasicType elem_type = TypeArrayKlass::cast(array_type)->element_type(); 330 size_t hs_bytes = arrayOopDesc::base_offset_in_bytes(elem_type); 331 assert(is_aligned(hs_bytes, BytesPerInt), "must be 4 byte aligned"); 332 HeapWord* obj = cast_from_oop<HeapWord*>(result); 333 if (!is_aligned(hs_bytes, BytesPerLong)) { 334 *reinterpret_cast<jint*>(reinterpret_cast<char*>(obj) + hs_bytes) = 0; 335 hs_bytes += BytesPerInt; 336 } 337 338 // Optimized zeroing. 339 assert(is_aligned(hs_bytes, BytesPerLong), "must be 8-byte aligned"); 340 const size_t aligned_hs = hs_bytes / BytesPerLong; 341 Copy::fill_to_aligned_words(obj+aligned_hs, size-aligned_hs); 342 } 343 344 JRT_END 345 346 // Note: multianewarray for one dimension is handled inline by GraphKit::new_array. 347 348 // multianewarray for 2 dimensions 349 JRT_ENTRY_PROF(void, OptoRuntime, multianewarray2_C, OptoRuntime::multianewarray2_C(Klass* elem_type, int len1, int len2, JavaThread* current)) 350 #ifndef PRODUCT 351 SharedRuntime::_multi2_ctr++; // multianewarray for 1 dimension 352 #endif 353 assert(check_compiled_frame(current), "incorrect caller"); 354 assert(elem_type->is_klass(), "not a class"); 355 jint dims[2]; 356 dims[0] = len1; 357 dims[1] = len2; 358 Handle holder(current, elem_type->klass_holder()); // keep the klass alive 359 oop obj = ArrayKlass::cast(elem_type)->multi_allocate(2, dims, THREAD); 360 deoptimize_caller_frame(current, HAS_PENDING_EXCEPTION); 361 current->set_vm_result(obj); 362 JRT_END 363 364 // multianewarray for 3 dimensions 365 JRT_ENTRY_PROF(void, OptoRuntime, multianewarray3_C, OptoRuntime::multianewarray3_C(Klass* elem_type, int len1, int len2, int len3, JavaThread* current)) 366 #ifndef PRODUCT 367 SharedRuntime::_multi3_ctr++; // multianewarray for 1 dimension 368 #endif 369 assert(check_compiled_frame(current), "incorrect caller"); 370 assert(elem_type->is_klass(), "not a class"); 371 jint dims[3]; 372 dims[0] = len1; 373 dims[1] = len2; 374 dims[2] = len3; 375 Handle holder(current, elem_type->klass_holder()); // keep the klass alive 376 oop obj = ArrayKlass::cast(elem_type)->multi_allocate(3, dims, THREAD); 377 deoptimize_caller_frame(current, HAS_PENDING_EXCEPTION); 378 current->set_vm_result(obj); 379 JRT_END 380 381 // multianewarray for 4 dimensions 382 JRT_ENTRY_PROF(void, OptoRuntime, multianewarray4_C, OptoRuntime::multianewarray4_C(Klass* elem_type, int len1, int len2, int len3, int len4, JavaThread* current)) 383 #ifndef PRODUCT 384 SharedRuntime::_multi4_ctr++; // multianewarray for 1 dimension 385 #endif 386 assert(check_compiled_frame(current), "incorrect caller"); 387 assert(elem_type->is_klass(), "not a class"); 388 jint dims[4]; 389 dims[0] = len1; 390 dims[1] = len2; 391 dims[2] = len3; 392 dims[3] = len4; 393 Handle holder(current, elem_type->klass_holder()); // keep the klass alive 394 oop obj = ArrayKlass::cast(elem_type)->multi_allocate(4, dims, THREAD); 395 deoptimize_caller_frame(current, HAS_PENDING_EXCEPTION); 396 current->set_vm_result(obj); 397 JRT_END 398 399 // multianewarray for 5 dimensions 400 JRT_ENTRY(void, OptoRuntime::multianewarray5_C(Klass* elem_type, int len1, int len2, int len3, int len4, int len5, JavaThread* current)) 401 #ifndef PRODUCT 402 SharedRuntime::_multi5_ctr++; // multianewarray for 1 dimension 403 #endif 404 assert(check_compiled_frame(current), "incorrect caller"); 405 assert(elem_type->is_klass(), "not a class"); 406 jint dims[5]; 407 dims[0] = len1; 408 dims[1] = len2; 409 dims[2] = len3; 410 dims[3] = len4; 411 dims[4] = len5; 412 Handle holder(current, elem_type->klass_holder()); // keep the klass alive 413 oop obj = ArrayKlass::cast(elem_type)->multi_allocate(5, dims, THREAD); 414 deoptimize_caller_frame(current, HAS_PENDING_EXCEPTION); 415 current->set_vm_result(obj); 416 JRT_END 417 418 JRT_ENTRY_PROF(void, OptoRuntime, multianewarrayN_C, OptoRuntime::multianewarrayN_C(Klass* elem_type, arrayOopDesc* dims, JavaThread* current)) 419 assert(check_compiled_frame(current), "incorrect caller"); 420 assert(elem_type->is_klass(), "not a class"); 421 assert(oop(dims)->is_typeArray(), "not an array"); 422 423 ResourceMark rm; 424 jint len = dims->length(); 425 assert(len > 0, "Dimensions array should contain data"); 426 jint *c_dims = NEW_RESOURCE_ARRAY(jint, len); 427 ArrayAccess<>::arraycopy_to_native<>(dims, typeArrayOopDesc::element_offset<jint>(0), 428 c_dims, len); 429 430 Handle holder(current, elem_type->klass_holder()); // keep the klass alive 431 oop obj = ArrayKlass::cast(elem_type)->multi_allocate(len, c_dims, THREAD); 432 deoptimize_caller_frame(current, HAS_PENDING_EXCEPTION); 433 current->set_vm_result(obj); 434 JRT_END 435 436 JRT_BLOCK_ENTRY_PROF(void, OptoRuntime, monitor_notify_C, OptoRuntime::monitor_notify_C(oopDesc* obj, JavaThread* current)) 437 438 // Very few notify/notifyAll operations find any threads on the waitset, so 439 // the dominant fast-path is to simply return. 440 // Relatedly, it's critical that notify/notifyAll be fast in order to 441 // reduce lock hold times. 442 if (!SafepointSynchronize::is_synchronizing()) { 443 if (ObjectSynchronizer::quick_notify(obj, current, false)) { 444 return; 445 } 446 } 447 448 // This is the case the fast-path above isn't provisioned to handle. 449 // The fast-path is designed to handle frequently arising cases in an efficient manner. 450 // (The fast-path is just a degenerate variant of the slow-path). 451 // Perform the dreaded state transition and pass control into the slow-path. 452 JRT_BLOCK; 453 Handle h_obj(current, obj); 454 ObjectSynchronizer::notify(h_obj, CHECK); 455 JRT_BLOCK_END; 456 JRT_END 457 458 JRT_BLOCK_ENTRY_PROF(void, OptoRuntime, monitor_notifyAll_C, OptoRuntime::monitor_notifyAll_C(oopDesc* obj, JavaThread* current)) 459 460 if (!SafepointSynchronize::is_synchronizing() ) { 461 if (ObjectSynchronizer::quick_notify(obj, current, true)) { 462 return; 463 } 464 } 465 466 // This is the case the fast-path above isn't provisioned to handle. 467 // The fast-path is designed to handle frequently arising cases in an efficient manner. 468 // (The fast-path is just a degenerate variant of the slow-path). 469 // Perform the dreaded state transition and pass control into the slow-path. 470 JRT_BLOCK; 471 Handle h_obj(current, obj); 472 ObjectSynchronizer::notifyall(h_obj, CHECK); 473 JRT_BLOCK_END; 474 JRT_END 475 476 const TypeFunc *OptoRuntime::new_instance_Type() { 477 // create input type (domain) 478 const Type **fields = TypeTuple::fields(1); 479 fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; // Klass to be allocated 480 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+1, fields); 481 482 // create result type (range) 483 fields = TypeTuple::fields(1); 484 fields[TypeFunc::Parms+0] = TypeRawPtr::NOTNULL; // Returned oop 485 486 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+1, fields); 487 488 return TypeFunc::make(domain, range); 489 } 490 491 #if INCLUDE_JVMTI 492 const TypeFunc *OptoRuntime::notify_jvmti_vthread_Type() { 493 // create input type (domain) 494 const Type **fields = TypeTuple::fields(2); 495 fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; // VirtualThread oop 496 fields[TypeFunc::Parms+1] = TypeInt::BOOL; // jboolean 497 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+2,fields); 498 499 // no result type needed 500 fields = TypeTuple::fields(1); 501 fields[TypeFunc::Parms+0] = nullptr; // void 502 const TypeTuple* range = TypeTuple::make(TypeFunc::Parms, fields); 503 504 return TypeFunc::make(domain,range); 505 } 506 #endif 507 508 const TypeFunc *OptoRuntime::athrow_Type() { 509 // create input type (domain) 510 const Type **fields = TypeTuple::fields(1); 511 fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; // Klass to be allocated 512 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+1, fields); 513 514 // create result type (range) 515 fields = TypeTuple::fields(0); 516 517 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0, fields); 518 519 return TypeFunc::make(domain, range); 520 } 521 522 523 const TypeFunc *OptoRuntime::new_array_Type() { 524 // create input type (domain) 525 const Type **fields = TypeTuple::fields(2); 526 fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; // element klass 527 fields[TypeFunc::Parms+1] = TypeInt::INT; // array size 528 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+2, fields); 529 530 // create result type (range) 531 fields = TypeTuple::fields(1); 532 fields[TypeFunc::Parms+0] = TypeRawPtr::NOTNULL; // Returned oop 533 534 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+1, fields); 535 536 return TypeFunc::make(domain, range); 537 } 538 539 const TypeFunc *OptoRuntime::multianewarray_Type(int ndim) { 540 // create input type (domain) 541 const int nargs = ndim + 1; 542 const Type **fields = TypeTuple::fields(nargs); 543 fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; // element klass 544 for( int i = 1; i < nargs; i++ ) 545 fields[TypeFunc::Parms + i] = TypeInt::INT; // array size 546 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+nargs, fields); 547 548 // create result type (range) 549 fields = TypeTuple::fields(1); 550 fields[TypeFunc::Parms+0] = TypeRawPtr::NOTNULL; // Returned oop 551 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+1, fields); 552 553 return TypeFunc::make(domain, range); 554 } 555 556 const TypeFunc *OptoRuntime::multianewarray2_Type() { 557 return multianewarray_Type(2); 558 } 559 560 const TypeFunc *OptoRuntime::multianewarray3_Type() { 561 return multianewarray_Type(3); 562 } 563 564 const TypeFunc *OptoRuntime::multianewarray4_Type() { 565 return multianewarray_Type(4); 566 } 567 568 const TypeFunc *OptoRuntime::multianewarray5_Type() { 569 return multianewarray_Type(5); 570 } 571 572 const TypeFunc *OptoRuntime::multianewarrayN_Type() { 573 // create input type (domain) 574 const Type **fields = TypeTuple::fields(2); 575 fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; // element klass 576 fields[TypeFunc::Parms+1] = TypeInstPtr::NOTNULL; // array of dim sizes 577 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+2, fields); 578 579 // create result type (range) 580 fields = TypeTuple::fields(1); 581 fields[TypeFunc::Parms+0] = TypeRawPtr::NOTNULL; // Returned oop 582 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+1, fields); 583 584 return TypeFunc::make(domain, range); 585 } 586 587 const TypeFunc *OptoRuntime::uncommon_trap_Type() { 588 // create input type (domain) 589 const Type **fields = TypeTuple::fields(1); 590 fields[TypeFunc::Parms+0] = TypeInt::INT; // trap_reason (deopt reason and action) 591 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+1, fields); 592 593 // create result type (range) 594 fields = TypeTuple::fields(0); 595 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0, fields); 596 597 return TypeFunc::make(domain, range); 598 } 599 600 //----------------------------------------------------------------------------- 601 // Monitor Handling 602 const TypeFunc *OptoRuntime::complete_monitor_enter_Type() { 603 // create input type (domain) 604 const Type **fields = TypeTuple::fields(2); 605 fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; // Object to be Locked 606 fields[TypeFunc::Parms+1] = TypeRawPtr::BOTTOM; // Address of stack location for lock 607 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+2,fields); 608 609 // create result type (range) 610 fields = TypeTuple::fields(0); 611 612 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0,fields); 613 614 return TypeFunc::make(domain,range); 615 } 616 617 618 //----------------------------------------------------------------------------- 619 const TypeFunc *OptoRuntime::complete_monitor_exit_Type() { 620 // create input type (domain) 621 const Type **fields = TypeTuple::fields(3); 622 fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; // Object to be Locked 623 fields[TypeFunc::Parms+1] = TypeRawPtr::BOTTOM; // Address of stack location for lock - BasicLock 624 fields[TypeFunc::Parms+2] = TypeRawPtr::BOTTOM; // Thread pointer (Self) 625 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+3, fields); 626 627 // create result type (range) 628 fields = TypeTuple::fields(0); 629 630 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0, fields); 631 632 return TypeFunc::make(domain, range); 633 } 634 635 const TypeFunc *OptoRuntime::monitor_notify_Type() { 636 // create input type (domain) 637 const Type **fields = TypeTuple::fields(1); 638 fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; // Object to be Locked 639 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+1, fields); 640 641 // create result type (range) 642 fields = TypeTuple::fields(0); 643 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0, fields); 644 return TypeFunc::make(domain, range); 645 } 646 647 const TypeFunc* OptoRuntime::flush_windows_Type() { 648 // create input type (domain) 649 const Type** fields = TypeTuple::fields(1); 650 fields[TypeFunc::Parms+0] = nullptr; // void 651 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms, fields); 652 653 // create result type 654 fields = TypeTuple::fields(1); 655 fields[TypeFunc::Parms+0] = nullptr; // void 656 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms, fields); 657 658 return TypeFunc::make(domain, range); 659 } 660 661 const TypeFunc* OptoRuntime::l2f_Type() { 662 // create input type (domain) 663 const Type **fields = TypeTuple::fields(2); 664 fields[TypeFunc::Parms+0] = TypeLong::LONG; 665 fields[TypeFunc::Parms+1] = Type::HALF; 666 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+2, fields); 667 668 // create result type (range) 669 fields = TypeTuple::fields(1); 670 fields[TypeFunc::Parms+0] = Type::FLOAT; 671 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+1, fields); 672 673 return TypeFunc::make(domain, range); 674 } 675 676 const TypeFunc* OptoRuntime::modf_Type() { 677 const Type **fields = TypeTuple::fields(2); 678 fields[TypeFunc::Parms+0] = Type::FLOAT; 679 fields[TypeFunc::Parms+1] = Type::FLOAT; 680 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+2, fields); 681 682 // create result type (range) 683 fields = TypeTuple::fields(1); 684 fields[TypeFunc::Parms+0] = Type::FLOAT; 685 686 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+1, fields); 687 688 return TypeFunc::make(domain, range); 689 } 690 691 const TypeFunc *OptoRuntime::Math_D_D_Type() { 692 // create input type (domain) 693 const Type **fields = TypeTuple::fields(2); 694 // Symbol* name of class to be loaded 695 fields[TypeFunc::Parms+0] = Type::DOUBLE; 696 fields[TypeFunc::Parms+1] = Type::HALF; 697 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+2, fields); 698 699 // create result type (range) 700 fields = TypeTuple::fields(2); 701 fields[TypeFunc::Parms+0] = Type::DOUBLE; 702 fields[TypeFunc::Parms+1] = Type::HALF; 703 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+2, fields); 704 705 return TypeFunc::make(domain, range); 706 } 707 708 const TypeFunc *OptoRuntime::Math_Vector_Vector_Type(uint num_arg, const TypeVect* in_type, const TypeVect* out_type) { 709 // create input type (domain) 710 const Type **fields = TypeTuple::fields(num_arg); 711 // Symbol* name of class to be loaded 712 assert(num_arg > 0, "must have at least 1 input"); 713 for (uint i = 0; i < num_arg; i++) { 714 fields[TypeFunc::Parms+i] = in_type; 715 } 716 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+num_arg, fields); 717 718 // create result type (range) 719 const uint num_ret = 1; 720 fields = TypeTuple::fields(num_ret); 721 fields[TypeFunc::Parms+0] = out_type; 722 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+num_ret, fields); 723 724 return TypeFunc::make(domain, range); 725 } 726 727 const TypeFunc* OptoRuntime::Math_DD_D_Type() { 728 const Type **fields = TypeTuple::fields(4); 729 fields[TypeFunc::Parms+0] = Type::DOUBLE; 730 fields[TypeFunc::Parms+1] = Type::HALF; 731 fields[TypeFunc::Parms+2] = Type::DOUBLE; 732 fields[TypeFunc::Parms+3] = Type::HALF; 733 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+4, fields); 734 735 // create result type (range) 736 fields = TypeTuple::fields(2); 737 fields[TypeFunc::Parms+0] = Type::DOUBLE; 738 fields[TypeFunc::Parms+1] = Type::HALF; 739 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+2, fields); 740 741 return TypeFunc::make(domain, range); 742 } 743 744 //-------------- currentTimeMillis, currentTimeNanos, etc 745 746 const TypeFunc* OptoRuntime::void_long_Type() { 747 // create input type (domain) 748 const Type **fields = TypeTuple::fields(0); 749 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+0, fields); 750 751 // create result type (range) 752 fields = TypeTuple::fields(2); 753 fields[TypeFunc::Parms+0] = TypeLong::LONG; 754 fields[TypeFunc::Parms+1] = Type::HALF; 755 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+2, fields); 756 757 return TypeFunc::make(domain, range); 758 } 759 760 const TypeFunc* OptoRuntime::void_void_Type() { 761 // create input type (domain) 762 const Type **fields = TypeTuple::fields(0); 763 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+0, fields); 764 765 // create result type (range) 766 fields = TypeTuple::fields(0); 767 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0, fields); 768 return TypeFunc::make(domain, range); 769 } 770 771 const TypeFunc* OptoRuntime::jfr_write_checkpoint_Type() { 772 // create input type (domain) 773 const Type **fields = TypeTuple::fields(0); 774 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms, fields); 775 776 // create result type (range) 777 fields = TypeTuple::fields(0); 778 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms, fields); 779 return TypeFunc::make(domain, range); 780 } 781 782 783 // Takes as parameters: 784 // void *dest 785 // long size 786 // uchar byte 787 const TypeFunc* OptoRuntime::make_setmemory_Type() { 788 // create input type (domain) 789 int argcnt = NOT_LP64(3) LP64_ONLY(4); 790 const Type** fields = TypeTuple::fields(argcnt); 791 int argp = TypeFunc::Parms; 792 fields[argp++] = TypePtr::NOTNULL; // dest 793 fields[argp++] = TypeX_X; // size 794 LP64_ONLY(fields[argp++] = Type::HALF); // size 795 fields[argp++] = TypeInt::UBYTE; // bytevalue 796 assert(argp == TypeFunc::Parms+argcnt, "correct decoding"); 797 const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms+argcnt, fields); 798 799 // no result type needed 800 fields = TypeTuple::fields(1); 801 fields[TypeFunc::Parms+0] = nullptr; // void 802 const TypeTuple* range = TypeTuple::make(TypeFunc::Parms, fields); 803 return TypeFunc::make(domain, range); 804 } 805 806 // arraycopy stub variations: 807 enum ArrayCopyType { 808 ac_fast, // void(ptr, ptr, size_t) 809 ac_checkcast, // int(ptr, ptr, size_t, size_t, ptr) 810 ac_slow, // void(ptr, int, ptr, int, int) 811 ac_generic // int(ptr, int, ptr, int, int) 812 }; 813 814 static const TypeFunc* make_arraycopy_Type(ArrayCopyType act) { 815 // create input type (domain) 816 int num_args = (act == ac_fast ? 3 : 5); 817 int num_size_args = (act == ac_fast ? 1 : act == ac_checkcast ? 2 : 0); 818 int argcnt = num_args; 819 LP64_ONLY(argcnt += num_size_args); // halfwords for lengths 820 const Type** fields = TypeTuple::fields(argcnt); 821 int argp = TypeFunc::Parms; 822 fields[argp++] = TypePtr::NOTNULL; // src 823 if (num_size_args == 0) { 824 fields[argp++] = TypeInt::INT; // src_pos 825 } 826 fields[argp++] = TypePtr::NOTNULL; // dest 827 if (num_size_args == 0) { 828 fields[argp++] = TypeInt::INT; // dest_pos 829 fields[argp++] = TypeInt::INT; // length 830 } 831 while (num_size_args-- > 0) { 832 fields[argp++] = TypeX_X; // size in whatevers (size_t) 833 LP64_ONLY(fields[argp++] = Type::HALF); // other half of long length 834 } 835 if (act == ac_checkcast) { 836 fields[argp++] = TypePtr::NOTNULL; // super_klass 837 } 838 assert(argp == TypeFunc::Parms+argcnt, "correct decoding of act"); 839 const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms+argcnt, fields); 840 841 // create result type if needed 842 int retcnt = (act == ac_checkcast || act == ac_generic ? 1 : 0); 843 fields = TypeTuple::fields(1); 844 if (retcnt == 0) 845 fields[TypeFunc::Parms+0] = nullptr; // void 846 else 847 fields[TypeFunc::Parms+0] = TypeInt::INT; // status result, if needed 848 const TypeTuple* range = TypeTuple::make(TypeFunc::Parms+retcnt, fields); 849 return TypeFunc::make(domain, range); 850 } 851 852 const TypeFunc* OptoRuntime::fast_arraycopy_Type() { 853 // This signature is simple: Two base pointers and a size_t. 854 return make_arraycopy_Type(ac_fast); 855 } 856 857 const TypeFunc* OptoRuntime::checkcast_arraycopy_Type() { 858 // An extension of fast_arraycopy_Type which adds type checking. 859 return make_arraycopy_Type(ac_checkcast); 860 } 861 862 const TypeFunc* OptoRuntime::slow_arraycopy_Type() { 863 // This signature is exactly the same as System.arraycopy. 864 // There are no intptr_t (int/long) arguments. 865 return make_arraycopy_Type(ac_slow); 866 } 867 868 const TypeFunc* OptoRuntime::generic_arraycopy_Type() { 869 // This signature is like System.arraycopy, except that it returns status. 870 return make_arraycopy_Type(ac_generic); 871 } 872 873 874 const TypeFunc* OptoRuntime::array_fill_Type() { 875 const Type** fields; 876 int argp = TypeFunc::Parms; 877 // create input type (domain): pointer, int, size_t 878 fields = TypeTuple::fields(3 LP64_ONLY( + 1)); 879 fields[argp++] = TypePtr::NOTNULL; 880 fields[argp++] = TypeInt::INT; 881 fields[argp++] = TypeX_X; // size in whatevers (size_t) 882 LP64_ONLY(fields[argp++] = Type::HALF); // other half of long length 883 const TypeTuple *domain = TypeTuple::make(argp, fields); 884 885 // create result type 886 fields = TypeTuple::fields(1); 887 fields[TypeFunc::Parms+0] = nullptr; // void 888 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms, fields); 889 890 return TypeFunc::make(domain, range); 891 } 892 893 const TypeFunc* OptoRuntime::array_partition_Type() { 894 // create input type (domain) 895 int num_args = 7; 896 int argcnt = num_args; 897 const Type** fields = TypeTuple::fields(argcnt); 898 int argp = TypeFunc::Parms; 899 fields[argp++] = TypePtr::NOTNULL; // array 900 fields[argp++] = TypeInt::INT; // element type 901 fields[argp++] = TypeInt::INT; // low 902 fields[argp++] = TypeInt::INT; // end 903 fields[argp++] = TypePtr::NOTNULL; // pivot_indices (int array) 904 fields[argp++] = TypeInt::INT; // indexPivot1 905 fields[argp++] = TypeInt::INT; // indexPivot2 906 assert(argp == TypeFunc::Parms+argcnt, "correct decoding"); 907 const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms+argcnt, fields); 908 909 // no result type needed 910 fields = TypeTuple::fields(1); 911 fields[TypeFunc::Parms+0] = nullptr; // void 912 const TypeTuple* range = TypeTuple::make(TypeFunc::Parms, fields); 913 return TypeFunc::make(domain, range); 914 } 915 916 const TypeFunc* OptoRuntime::array_sort_Type() { 917 // create input type (domain) 918 int num_args = 4; 919 int argcnt = num_args; 920 const Type** fields = TypeTuple::fields(argcnt); 921 int argp = TypeFunc::Parms; 922 fields[argp++] = TypePtr::NOTNULL; // array 923 fields[argp++] = TypeInt::INT; // element type 924 fields[argp++] = TypeInt::INT; // fromIndex 925 fields[argp++] = TypeInt::INT; // toIndex 926 assert(argp == TypeFunc::Parms+argcnt, "correct decoding"); 927 const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms+argcnt, fields); 928 929 // no result type needed 930 fields = TypeTuple::fields(1); 931 fields[TypeFunc::Parms+0] = nullptr; // void 932 const TypeTuple* range = TypeTuple::make(TypeFunc::Parms, fields); 933 return TypeFunc::make(domain, range); 934 } 935 936 // for aescrypt encrypt/decrypt operations, just three pointers returning void (length is constant) 937 const TypeFunc* OptoRuntime::aescrypt_block_Type() { 938 // create input type (domain) 939 int num_args = 3; 940 int argcnt = num_args; 941 const Type** fields = TypeTuple::fields(argcnt); 942 int argp = TypeFunc::Parms; 943 fields[argp++] = TypePtr::NOTNULL; // src 944 fields[argp++] = TypePtr::NOTNULL; // dest 945 fields[argp++] = TypePtr::NOTNULL; // k array 946 assert(argp == TypeFunc::Parms+argcnt, "correct decoding"); 947 const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms+argcnt, fields); 948 949 // no result type needed 950 fields = TypeTuple::fields(1); 951 fields[TypeFunc::Parms+0] = nullptr; // void 952 const TypeTuple* range = TypeTuple::make(TypeFunc::Parms, fields); 953 return TypeFunc::make(domain, range); 954 } 955 956 /** 957 * int updateBytesCRC32(int crc, byte* b, int len) 958 */ 959 const TypeFunc* OptoRuntime::updateBytesCRC32_Type() { 960 // create input type (domain) 961 int num_args = 3; 962 int argcnt = num_args; 963 const Type** fields = TypeTuple::fields(argcnt); 964 int argp = TypeFunc::Parms; 965 fields[argp++] = TypeInt::INT; // crc 966 fields[argp++] = TypePtr::NOTNULL; // src 967 fields[argp++] = TypeInt::INT; // len 968 assert(argp == TypeFunc::Parms+argcnt, "correct decoding"); 969 const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms+argcnt, fields); 970 971 // result type needed 972 fields = TypeTuple::fields(1); 973 fields[TypeFunc::Parms+0] = TypeInt::INT; // crc result 974 const TypeTuple* range = TypeTuple::make(TypeFunc::Parms+1, fields); 975 return TypeFunc::make(domain, range); 976 } 977 978 /** 979 * int updateBytesCRC32C(int crc, byte* buf, int len, int* table) 980 */ 981 const TypeFunc* OptoRuntime::updateBytesCRC32C_Type() { 982 // create input type (domain) 983 int num_args = 4; 984 int argcnt = num_args; 985 const Type** fields = TypeTuple::fields(argcnt); 986 int argp = TypeFunc::Parms; 987 fields[argp++] = TypeInt::INT; // crc 988 fields[argp++] = TypePtr::NOTNULL; // buf 989 fields[argp++] = TypeInt::INT; // len 990 fields[argp++] = TypePtr::NOTNULL; // table 991 assert(argp == TypeFunc::Parms+argcnt, "correct decoding"); 992 const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms+argcnt, fields); 993 994 // result type needed 995 fields = TypeTuple::fields(1); 996 fields[TypeFunc::Parms+0] = TypeInt::INT; // crc result 997 const TypeTuple* range = TypeTuple::make(TypeFunc::Parms+1, fields); 998 return TypeFunc::make(domain, range); 999 } 1000 1001 /** 1002 * int updateBytesAdler32(int adler, bytes* b, int off, int len) 1003 */ 1004 const TypeFunc* OptoRuntime::updateBytesAdler32_Type() { 1005 // create input type (domain) 1006 int num_args = 3; 1007 int argcnt = num_args; 1008 const Type** fields = TypeTuple::fields(argcnt); 1009 int argp = TypeFunc::Parms; 1010 fields[argp++] = TypeInt::INT; // crc 1011 fields[argp++] = TypePtr::NOTNULL; // src + offset 1012 fields[argp++] = TypeInt::INT; // len 1013 assert(argp == TypeFunc::Parms+argcnt, "correct decoding"); 1014 const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms+argcnt, fields); 1015 1016 // result type needed 1017 fields = TypeTuple::fields(1); 1018 fields[TypeFunc::Parms+0] = TypeInt::INT; // crc result 1019 const TypeTuple* range = TypeTuple::make(TypeFunc::Parms+1, fields); 1020 return TypeFunc::make(domain, range); 1021 } 1022 1023 // for cipherBlockChaining calls of aescrypt encrypt/decrypt, four pointers and a length, returning int 1024 const TypeFunc* OptoRuntime::cipherBlockChaining_aescrypt_Type() { 1025 // create input type (domain) 1026 int num_args = 5; 1027 int argcnt = num_args; 1028 const Type** fields = TypeTuple::fields(argcnt); 1029 int argp = TypeFunc::Parms; 1030 fields[argp++] = TypePtr::NOTNULL; // src 1031 fields[argp++] = TypePtr::NOTNULL; // dest 1032 fields[argp++] = TypePtr::NOTNULL; // k array 1033 fields[argp++] = TypePtr::NOTNULL; // r array 1034 fields[argp++] = TypeInt::INT; // src len 1035 assert(argp == TypeFunc::Parms+argcnt, "correct decoding"); 1036 const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms+argcnt, fields); 1037 1038 // returning cipher len (int) 1039 fields = TypeTuple::fields(1); 1040 fields[TypeFunc::Parms+0] = TypeInt::INT; 1041 const TypeTuple* range = TypeTuple::make(TypeFunc::Parms+1, fields); 1042 return TypeFunc::make(domain, range); 1043 } 1044 1045 // for electronicCodeBook calls of aescrypt encrypt/decrypt, three pointers and a length, returning int 1046 const TypeFunc* OptoRuntime::electronicCodeBook_aescrypt_Type() { 1047 // create input type (domain) 1048 int num_args = 4; 1049 int argcnt = num_args; 1050 const Type** fields = TypeTuple::fields(argcnt); 1051 int argp = TypeFunc::Parms; 1052 fields[argp++] = TypePtr::NOTNULL; // src 1053 fields[argp++] = TypePtr::NOTNULL; // dest 1054 fields[argp++] = TypePtr::NOTNULL; // k array 1055 fields[argp++] = TypeInt::INT; // src len 1056 assert(argp == TypeFunc::Parms + argcnt, "correct decoding"); 1057 const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms + argcnt, fields); 1058 1059 // returning cipher len (int) 1060 fields = TypeTuple::fields(1); 1061 fields[TypeFunc::Parms + 0] = TypeInt::INT; 1062 const TypeTuple* range = TypeTuple::make(TypeFunc::Parms + 1, fields); 1063 return TypeFunc::make(domain, range); 1064 } 1065 1066 //for counterMode calls of aescrypt encrypt/decrypt, four pointers and a length, returning int 1067 const TypeFunc* OptoRuntime::counterMode_aescrypt_Type() { 1068 // create input type (domain) 1069 int num_args = 7; 1070 int argcnt = num_args; 1071 const Type** fields = TypeTuple::fields(argcnt); 1072 int argp = TypeFunc::Parms; 1073 fields[argp++] = TypePtr::NOTNULL; // src 1074 fields[argp++] = TypePtr::NOTNULL; // dest 1075 fields[argp++] = TypePtr::NOTNULL; // k array 1076 fields[argp++] = TypePtr::NOTNULL; // counter array 1077 fields[argp++] = TypeInt::INT; // src len 1078 fields[argp++] = TypePtr::NOTNULL; // saved_encCounter 1079 fields[argp++] = TypePtr::NOTNULL; // saved used addr 1080 assert(argp == TypeFunc::Parms + argcnt, "correct decoding"); 1081 const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms + argcnt, fields); 1082 // returning cipher len (int) 1083 fields = TypeTuple::fields(1); 1084 fields[TypeFunc::Parms + 0] = TypeInt::INT; 1085 const TypeTuple* range = TypeTuple::make(TypeFunc::Parms + 1, fields); 1086 return TypeFunc::make(domain, range); 1087 } 1088 1089 //for counterMode calls of aescrypt encrypt/decrypt, four pointers and a length, returning int 1090 const TypeFunc* OptoRuntime::galoisCounterMode_aescrypt_Type() { 1091 // create input type (domain) 1092 int num_args = 8; 1093 int argcnt = num_args; 1094 const Type** fields = TypeTuple::fields(argcnt); 1095 int argp = TypeFunc::Parms; 1096 fields[argp++] = TypePtr::NOTNULL; // byte[] in + inOfs 1097 fields[argp++] = TypeInt::INT; // int len 1098 fields[argp++] = TypePtr::NOTNULL; // byte[] ct + ctOfs 1099 fields[argp++] = TypePtr::NOTNULL; // byte[] out + outOfs 1100 fields[argp++] = TypePtr::NOTNULL; // byte[] key from AESCrypt obj 1101 fields[argp++] = TypePtr::NOTNULL; // long[] state from GHASH obj 1102 fields[argp++] = TypePtr::NOTNULL; // long[] subkeyHtbl from GHASH obj 1103 fields[argp++] = TypePtr::NOTNULL; // byte[] counter from GCTR obj 1104 1105 assert(argp == TypeFunc::Parms + argcnt, "correct decoding"); 1106 const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms + argcnt, fields); 1107 // returning cipher len (int) 1108 fields = TypeTuple::fields(1); 1109 fields[TypeFunc::Parms + 0] = TypeInt::INT; 1110 const TypeTuple* range = TypeTuple::make(TypeFunc::Parms + 1, fields); 1111 return TypeFunc::make(domain, range); 1112 } 1113 1114 /* 1115 * void implCompress(byte[] buf, int ofs) 1116 */ 1117 const TypeFunc* OptoRuntime::digestBase_implCompress_Type(bool is_sha3) { 1118 // create input type (domain) 1119 int num_args = is_sha3 ? 3 : 2; 1120 int argcnt = num_args; 1121 const Type** fields = TypeTuple::fields(argcnt); 1122 int argp = TypeFunc::Parms; 1123 fields[argp++] = TypePtr::NOTNULL; // buf 1124 fields[argp++] = TypePtr::NOTNULL; // state 1125 if (is_sha3) fields[argp++] = TypeInt::INT; // block_size 1126 assert(argp == TypeFunc::Parms+argcnt, "correct decoding"); 1127 const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms+argcnt, fields); 1128 1129 // no result type needed 1130 fields = TypeTuple::fields(1); 1131 fields[TypeFunc::Parms+0] = nullptr; // void 1132 const TypeTuple* range = TypeTuple::make(TypeFunc::Parms, fields); 1133 return TypeFunc::make(domain, range); 1134 } 1135 1136 /* 1137 * int implCompressMultiBlock(byte[] b, int ofs, int limit) 1138 */ 1139 const TypeFunc* OptoRuntime::digestBase_implCompressMB_Type(bool is_sha3) { 1140 // create input type (domain) 1141 int num_args = is_sha3 ? 5 : 4; 1142 int argcnt = num_args; 1143 const Type** fields = TypeTuple::fields(argcnt); 1144 int argp = TypeFunc::Parms; 1145 fields[argp++] = TypePtr::NOTNULL; // buf 1146 fields[argp++] = TypePtr::NOTNULL; // state 1147 if (is_sha3) fields[argp++] = TypeInt::INT; // block_size 1148 fields[argp++] = TypeInt::INT; // ofs 1149 fields[argp++] = TypeInt::INT; // limit 1150 assert(argp == TypeFunc::Parms+argcnt, "correct decoding"); 1151 const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms+argcnt, fields); 1152 1153 // returning ofs (int) 1154 fields = TypeTuple::fields(1); 1155 fields[TypeFunc::Parms+0] = TypeInt::INT; // ofs 1156 const TypeTuple* range = TypeTuple::make(TypeFunc::Parms+1, fields); 1157 return TypeFunc::make(domain, range); 1158 } 1159 1160 const TypeFunc* OptoRuntime::multiplyToLen_Type() { 1161 // create input type (domain) 1162 int num_args = 5; 1163 int argcnt = num_args; 1164 const Type** fields = TypeTuple::fields(argcnt); 1165 int argp = TypeFunc::Parms; 1166 fields[argp++] = TypePtr::NOTNULL; // x 1167 fields[argp++] = TypeInt::INT; // xlen 1168 fields[argp++] = TypePtr::NOTNULL; // y 1169 fields[argp++] = TypeInt::INT; // ylen 1170 fields[argp++] = TypePtr::NOTNULL; // z 1171 assert(argp == TypeFunc::Parms+argcnt, "correct decoding"); 1172 const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms+argcnt, fields); 1173 1174 // no result type needed 1175 fields = TypeTuple::fields(1); 1176 fields[TypeFunc::Parms+0] = nullptr; 1177 const TypeTuple* range = TypeTuple::make(TypeFunc::Parms, fields); 1178 return TypeFunc::make(domain, range); 1179 } 1180 1181 const TypeFunc* OptoRuntime::squareToLen_Type() { 1182 // create input type (domain) 1183 int num_args = 4; 1184 int argcnt = num_args; 1185 const Type** fields = TypeTuple::fields(argcnt); 1186 int argp = TypeFunc::Parms; 1187 fields[argp++] = TypePtr::NOTNULL; // x 1188 fields[argp++] = TypeInt::INT; // len 1189 fields[argp++] = TypePtr::NOTNULL; // z 1190 fields[argp++] = TypeInt::INT; // zlen 1191 assert(argp == TypeFunc::Parms+argcnt, "correct decoding"); 1192 const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms+argcnt, fields); 1193 1194 // no result type needed 1195 fields = TypeTuple::fields(1); 1196 fields[TypeFunc::Parms+0] = nullptr; 1197 const TypeTuple* range = TypeTuple::make(TypeFunc::Parms, fields); 1198 return TypeFunc::make(domain, range); 1199 } 1200 1201 // for mulAdd calls, 2 pointers and 3 ints, returning int 1202 const TypeFunc* OptoRuntime::mulAdd_Type() { 1203 // create input type (domain) 1204 int num_args = 5; 1205 int argcnt = num_args; 1206 const Type** fields = TypeTuple::fields(argcnt); 1207 int argp = TypeFunc::Parms; 1208 fields[argp++] = TypePtr::NOTNULL; // out 1209 fields[argp++] = TypePtr::NOTNULL; // in 1210 fields[argp++] = TypeInt::INT; // offset 1211 fields[argp++] = TypeInt::INT; // len 1212 fields[argp++] = TypeInt::INT; // k 1213 assert(argp == TypeFunc::Parms+argcnt, "correct decoding"); 1214 const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms+argcnt, fields); 1215 1216 // returning carry (int) 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 const TypeFunc* OptoRuntime::montgomeryMultiply_Type() { 1224 // create input type (domain) 1225 int num_args = 7; 1226 int argcnt = num_args; 1227 const Type** fields = TypeTuple::fields(argcnt); 1228 int argp = TypeFunc::Parms; 1229 fields[argp++] = TypePtr::NOTNULL; // a 1230 fields[argp++] = TypePtr::NOTNULL; // b 1231 fields[argp++] = TypePtr::NOTNULL; // n 1232 fields[argp++] = TypeInt::INT; // len 1233 fields[argp++] = TypeLong::LONG; // inv 1234 fields[argp++] = Type::HALF; 1235 fields[argp++] = TypePtr::NOTNULL; // result 1236 assert(argp == TypeFunc::Parms+argcnt, "correct decoding"); 1237 const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms+argcnt, fields); 1238 1239 // result type needed 1240 fields = TypeTuple::fields(1); 1241 fields[TypeFunc::Parms+0] = TypePtr::NOTNULL; 1242 1243 const TypeTuple* range = TypeTuple::make(TypeFunc::Parms, fields); 1244 return TypeFunc::make(domain, range); 1245 } 1246 1247 const TypeFunc* OptoRuntime::montgomerySquare_Type() { 1248 // create input type (domain) 1249 int num_args = 6; 1250 int argcnt = num_args; 1251 const Type** fields = TypeTuple::fields(argcnt); 1252 int argp = TypeFunc::Parms; 1253 fields[argp++] = TypePtr::NOTNULL; // a 1254 fields[argp++] = TypePtr::NOTNULL; // n 1255 fields[argp++] = TypeInt::INT; // len 1256 fields[argp++] = TypeLong::LONG; // inv 1257 fields[argp++] = Type::HALF; 1258 fields[argp++] = TypePtr::NOTNULL; // result 1259 assert(argp == TypeFunc::Parms+argcnt, "correct decoding"); 1260 const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms+argcnt, fields); 1261 1262 // result type needed 1263 fields = TypeTuple::fields(1); 1264 fields[TypeFunc::Parms+0] = TypePtr::NOTNULL; 1265 1266 const TypeTuple* range = TypeTuple::make(TypeFunc::Parms, fields); 1267 return TypeFunc::make(domain, range); 1268 } 1269 1270 const TypeFunc * OptoRuntime::bigIntegerShift_Type() { 1271 int argcnt = 5; 1272 const Type** fields = TypeTuple::fields(argcnt); 1273 int argp = TypeFunc::Parms; 1274 fields[argp++] = TypePtr::NOTNULL; // newArr 1275 fields[argp++] = TypePtr::NOTNULL; // oldArr 1276 fields[argp++] = TypeInt::INT; // newIdx 1277 fields[argp++] = TypeInt::INT; // shiftCount 1278 fields[argp++] = TypeInt::INT; // numIter 1279 assert(argp == TypeFunc::Parms + argcnt, "correct decoding"); 1280 const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms + argcnt, fields); 1281 1282 // no result type needed 1283 fields = TypeTuple::fields(1); 1284 fields[TypeFunc::Parms + 0] = nullptr; 1285 const TypeTuple* range = TypeTuple::make(TypeFunc::Parms, fields); 1286 return TypeFunc::make(domain, range); 1287 } 1288 1289 const TypeFunc* OptoRuntime::vectorizedMismatch_Type() { 1290 // create input type (domain) 1291 int num_args = 4; 1292 int argcnt = num_args; 1293 const Type** fields = TypeTuple::fields(argcnt); 1294 int argp = TypeFunc::Parms; 1295 fields[argp++] = TypePtr::NOTNULL; // obja 1296 fields[argp++] = TypePtr::NOTNULL; // objb 1297 fields[argp++] = TypeInt::INT; // length, number of elements 1298 fields[argp++] = TypeInt::INT; // log2scale, element size 1299 assert(argp == TypeFunc::Parms + argcnt, "correct decoding"); 1300 const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms + argcnt, fields); 1301 1302 //return mismatch index (int) 1303 fields = TypeTuple::fields(1); 1304 fields[TypeFunc::Parms + 0] = TypeInt::INT; 1305 const TypeTuple* range = TypeTuple::make(TypeFunc::Parms + 1, fields); 1306 return TypeFunc::make(domain, range); 1307 } 1308 1309 // GHASH block processing 1310 const TypeFunc* OptoRuntime::ghash_processBlocks_Type() { 1311 int argcnt = 4; 1312 1313 const Type** fields = TypeTuple::fields(argcnt); 1314 int argp = TypeFunc::Parms; 1315 fields[argp++] = TypePtr::NOTNULL; // state 1316 fields[argp++] = TypePtr::NOTNULL; // subkeyH 1317 fields[argp++] = TypePtr::NOTNULL; // data 1318 fields[argp++] = TypeInt::INT; // blocks 1319 assert(argp == TypeFunc::Parms+argcnt, "correct decoding"); 1320 const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms+argcnt, fields); 1321 1322 // result type needed 1323 fields = TypeTuple::fields(1); 1324 fields[TypeFunc::Parms+0] = nullptr; // void 1325 const TypeTuple* range = TypeTuple::make(TypeFunc::Parms, fields); 1326 return TypeFunc::make(domain, range); 1327 } 1328 1329 // ChaCha20 Block function 1330 const TypeFunc* OptoRuntime::chacha20Block_Type() { 1331 int argcnt = 2; 1332 1333 const Type** fields = TypeTuple::fields(argcnt); 1334 int argp = TypeFunc::Parms; 1335 fields[argp++] = TypePtr::NOTNULL; // state 1336 fields[argp++] = TypePtr::NOTNULL; // result 1337 1338 assert(argp == TypeFunc::Parms + argcnt, "correct decoding"); 1339 const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms + argcnt, fields); 1340 1341 // result type needed 1342 fields = TypeTuple::fields(1); 1343 fields[TypeFunc::Parms + 0] = TypeInt::INT; // key stream outlen as int 1344 const TypeTuple* range = TypeTuple::make(TypeFunc::Parms + 1, fields); 1345 return TypeFunc::make(domain, range); 1346 } 1347 1348 // Base64 encode function 1349 const TypeFunc* OptoRuntime::base64_encodeBlock_Type() { 1350 int argcnt = 6; 1351 1352 const Type** fields = TypeTuple::fields(argcnt); 1353 int argp = TypeFunc::Parms; 1354 fields[argp++] = TypePtr::NOTNULL; // src array 1355 fields[argp++] = TypeInt::INT; // offset 1356 fields[argp++] = TypeInt::INT; // length 1357 fields[argp++] = TypePtr::NOTNULL; // dest array 1358 fields[argp++] = TypeInt::INT; // dp 1359 fields[argp++] = TypeInt::BOOL; // isURL 1360 assert(argp == TypeFunc::Parms + argcnt, "correct decoding"); 1361 const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms+argcnt, fields); 1362 1363 // result type needed 1364 fields = TypeTuple::fields(1); 1365 fields[TypeFunc::Parms + 0] = nullptr; // void 1366 const TypeTuple* range = TypeTuple::make(TypeFunc::Parms, fields); 1367 return TypeFunc::make(domain, range); 1368 } 1369 1370 // String IndexOf function 1371 const TypeFunc* OptoRuntime::string_IndexOf_Type() { 1372 int argcnt = 4; 1373 1374 const Type** fields = TypeTuple::fields(argcnt); 1375 int argp = TypeFunc::Parms; 1376 fields[argp++] = TypePtr::NOTNULL; // haystack array 1377 fields[argp++] = TypeInt::INT; // haystack length 1378 fields[argp++] = TypePtr::NOTNULL; // needle array 1379 fields[argp++] = TypeInt::INT; // needle length 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] = TypeInt::INT; // Index of needle in haystack 1386 const TypeTuple* range = TypeTuple::make(TypeFunc::Parms + 1, fields); 1387 return TypeFunc::make(domain, range); 1388 } 1389 1390 // Base64 decode function 1391 const TypeFunc* OptoRuntime::base64_decodeBlock_Type() { 1392 int argcnt = 7; 1393 1394 const Type** fields = TypeTuple::fields(argcnt); 1395 int argp = TypeFunc::Parms; 1396 fields[argp++] = TypePtr::NOTNULL; // src array 1397 fields[argp++] = TypeInt::INT; // src offset 1398 fields[argp++] = TypeInt::INT; // src length 1399 fields[argp++] = TypePtr::NOTNULL; // dest array 1400 fields[argp++] = TypeInt::INT; // dest offset 1401 fields[argp++] = TypeInt::BOOL; // isURL 1402 fields[argp++] = TypeInt::BOOL; // isMIME 1403 assert(argp == TypeFunc::Parms + argcnt, "correct decoding"); 1404 const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms+argcnt, fields); 1405 1406 // result type needed 1407 fields = TypeTuple::fields(1); 1408 fields[TypeFunc::Parms + 0] = TypeInt::INT; // count of bytes written to dst 1409 const TypeTuple* range = TypeTuple::make(TypeFunc::Parms + 1, fields); 1410 return TypeFunc::make(domain, range); 1411 } 1412 1413 // Poly1305 processMultipleBlocks function 1414 const TypeFunc* OptoRuntime::poly1305_processBlocks_Type() { 1415 int argcnt = 4; 1416 1417 const Type** fields = TypeTuple::fields(argcnt); 1418 int argp = TypeFunc::Parms; 1419 fields[argp++] = TypePtr::NOTNULL; // input array 1420 fields[argp++] = TypeInt::INT; // input length 1421 fields[argp++] = TypePtr::NOTNULL; // accumulator array 1422 fields[argp++] = TypePtr::NOTNULL; // r array 1423 assert(argp == TypeFunc::Parms + argcnt, "correct decoding"); 1424 const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms+argcnt, fields); 1425 1426 // result type needed 1427 fields = TypeTuple::fields(1); 1428 fields[TypeFunc::Parms + 0] = nullptr; // void 1429 const TypeTuple* range = TypeTuple::make(TypeFunc::Parms, fields); 1430 return TypeFunc::make(domain, range); 1431 } 1432 1433 // MontgomeryIntegerPolynomialP256 multiply function 1434 const TypeFunc* OptoRuntime::intpoly_montgomeryMult_P256_Type() { 1435 int argcnt = 3; 1436 1437 const Type** fields = TypeTuple::fields(argcnt); 1438 int argp = TypeFunc::Parms; 1439 fields[argp++] = TypePtr::NOTNULL; // a array 1440 fields[argp++] = TypePtr::NOTNULL; // b array 1441 fields[argp++] = TypePtr::NOTNULL; // r(esult) array 1442 assert(argp == TypeFunc::Parms + argcnt, "correct decoding"); 1443 const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms+argcnt, fields); 1444 1445 // result type needed 1446 fields = TypeTuple::fields(1); 1447 fields[TypeFunc::Parms + 0] = nullptr; // void 1448 const TypeTuple* range = TypeTuple::make(TypeFunc::Parms, fields); 1449 return TypeFunc::make(domain, range); 1450 } 1451 1452 // IntegerPolynomial constant time assignment function 1453 const TypeFunc* OptoRuntime::intpoly_assign_Type() { 1454 int argcnt = 4; 1455 1456 const Type** fields = TypeTuple::fields(argcnt); 1457 int argp = TypeFunc::Parms; 1458 fields[argp++] = TypeInt::INT; // set flag 1459 fields[argp++] = TypePtr::NOTNULL; // a array (result) 1460 fields[argp++] = TypePtr::NOTNULL; // b array (if set is set) 1461 fields[argp++] = TypeInt::INT; // array length 1462 assert(argp == TypeFunc::Parms + argcnt, "correct decoding"); 1463 const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms+argcnt, fields); 1464 1465 // result type needed 1466 fields = TypeTuple::fields(1); 1467 fields[TypeFunc::Parms + 0] = nullptr; // void 1468 const TypeTuple* range = TypeTuple::make(TypeFunc::Parms, fields); 1469 return TypeFunc::make(domain, range); 1470 } 1471 1472 //------------- Interpreter state access for on stack replacement 1473 const TypeFunc* OptoRuntime::osr_end_Type() { 1474 // create input type (domain) 1475 const Type **fields = TypeTuple::fields(1); 1476 fields[TypeFunc::Parms+0] = TypeRawPtr::BOTTOM; // OSR temp buf 1477 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+1, fields); 1478 1479 // create result type 1480 fields = TypeTuple::fields(1); 1481 // fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; // locked oop 1482 fields[TypeFunc::Parms+0] = nullptr; // void 1483 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms, fields); 1484 return TypeFunc::make(domain, range); 1485 } 1486 1487 //------------------------------------------------------------------------------------- 1488 // register policy 1489 1490 bool OptoRuntime::is_callee_saved_register(MachRegisterNumbers reg) { 1491 assert(reg >= 0 && reg < _last_Mach_Reg, "must be a machine register"); 1492 switch (register_save_policy[reg]) { 1493 case 'C': return false; //SOC 1494 case 'E': return true ; //SOE 1495 case 'N': return false; //NS 1496 case 'A': return false; //AS 1497 } 1498 ShouldNotReachHere(); 1499 return false; 1500 } 1501 1502 //----------------------------------------------------------------------- 1503 // Exceptions 1504 // 1505 1506 static void trace_exception(outputStream* st, oop exception_oop, address exception_pc, const char* msg); 1507 1508 // The method is an entry that is always called by a C++ method not 1509 // directly from compiled code. Compiled code will call the C++ method following. 1510 // We can't allow async exception to be installed during exception processing. 1511 JRT_ENTRY_NO_ASYNC_PROF(address, OptoRuntime, handle_exception_C_helper, OptoRuntime::handle_exception_C_helper(JavaThread* current, nmethod* &nm)) 1512 // The frame we rethrow the exception to might not have been processed by the GC yet. 1513 // The stack watermark barrier takes care of detecting that and ensuring the frame 1514 // has updated oops. 1515 StackWatermarkSet::after_unwind(current); 1516 1517 // Do not confuse exception_oop with pending_exception. The exception_oop 1518 // is only used to pass arguments into the method. Not for general 1519 // exception handling. DO NOT CHANGE IT to use pending_exception, since 1520 // the runtime stubs checks this on exit. 1521 assert(current->exception_oop() != nullptr, "exception oop is found"); 1522 address handler_address = nullptr; 1523 1524 Handle exception(current, current->exception_oop()); 1525 address pc = current->exception_pc(); 1526 1527 // Clear out the exception oop and pc since looking up an 1528 // exception handler can cause class loading, which might throw an 1529 // exception and those fields are expected to be clear during 1530 // normal bytecode execution. 1531 current->clear_exception_oop_and_pc(); 1532 1533 LogTarget(Info, exceptions) lt; 1534 if (lt.is_enabled()) { 1535 ResourceMark rm; 1536 LogStream ls(lt); 1537 trace_exception(&ls, exception(), pc, ""); 1538 } 1539 1540 // for AbortVMOnException flag 1541 Exceptions::debug_check_abort(exception); 1542 1543 #ifdef ASSERT 1544 if (!(exception->is_a(vmClasses::Throwable_klass()))) { 1545 // should throw an exception here 1546 ShouldNotReachHere(); 1547 } 1548 #endif 1549 1550 // new exception handling: this method is entered only from adapters 1551 // exceptions from compiled java methods are handled in compiled code 1552 // using rethrow node 1553 1554 nm = CodeCache::find_nmethod(pc); 1555 assert(nm != nullptr, "No NMethod found"); 1556 if (nm->is_native_method()) { 1557 fatal("Native method should not have path to exception handling"); 1558 } else { 1559 // we are switching to old paradigm: search for exception handler in caller_frame 1560 // instead in exception handler of caller_frame.sender() 1561 1562 if (JvmtiExport::can_post_on_exceptions()) { 1563 // "Full-speed catching" is not necessary here, 1564 // since we're notifying the VM on every catch. 1565 // Force deoptimization and the rest of the lookup 1566 // will be fine. 1567 deoptimize_caller_frame(current); 1568 } 1569 1570 // Check the stack guard pages. If enabled, look for handler in this frame; 1571 // otherwise, forcibly unwind the frame. 1572 // 1573 // 4826555: use default current sp for reguard_stack instead of &nm: it's more accurate. 1574 bool force_unwind = !current->stack_overflow_state()->reguard_stack(); 1575 bool deopting = false; 1576 if (nm->is_deopt_pc(pc)) { 1577 deopting = true; 1578 RegisterMap map(current, 1579 RegisterMap::UpdateMap::skip, 1580 RegisterMap::ProcessFrames::include, 1581 RegisterMap::WalkContinuation::skip); 1582 frame deoptee = current->last_frame().sender(&map); 1583 assert(deoptee.is_deoptimized_frame(), "must be deopted"); 1584 // Adjust the pc back to the original throwing pc 1585 pc = deoptee.pc(); 1586 } 1587 1588 // If we are forcing an unwind because of stack overflow then deopt is 1589 // irrelevant since we are throwing the frame away anyway. 1590 1591 if (deopting && !force_unwind) { 1592 handler_address = SharedRuntime::deopt_blob()->unpack_with_exception(); 1593 } else { 1594 1595 handler_address = 1596 force_unwind ? nullptr : nm->handler_for_exception_and_pc(exception, pc); 1597 1598 if (handler_address == nullptr) { 1599 bool recursive_exception = false; 1600 handler_address = SharedRuntime::compute_compiled_exc_handler(nm, pc, exception, force_unwind, true, recursive_exception); 1601 assert (handler_address != nullptr, "must have compiled handler"); 1602 // Update the exception cache only when the unwind was not forced 1603 // and there didn't happen another exception during the computation of the 1604 // compiled exception handler. Checking for exception oop equality is not 1605 // sufficient because some exceptions are pre-allocated and reused. 1606 if (!force_unwind && !recursive_exception) { 1607 nm->add_handler_for_exception_and_pc(exception,pc,handler_address); 1608 } 1609 } else { 1610 #ifdef ASSERT 1611 bool recursive_exception = false; 1612 address computed_address = SharedRuntime::compute_compiled_exc_handler(nm, pc, exception, force_unwind, true, recursive_exception); 1613 vmassert(recursive_exception || (handler_address == computed_address), "Handler address inconsistency: " PTR_FORMAT " != " PTR_FORMAT, 1614 p2i(handler_address), p2i(computed_address)); 1615 #endif 1616 } 1617 } 1618 1619 current->set_exception_pc(pc); 1620 current->set_exception_handler_pc(handler_address); 1621 1622 // Check if the exception PC is a MethodHandle call site. 1623 current->set_is_method_handle_return(nm->is_method_handle_return(pc)); 1624 } 1625 1626 // Restore correct return pc. Was saved above. 1627 current->set_exception_oop(exception()); 1628 return handler_address; 1629 1630 JRT_END 1631 1632 // We are entering here from exception_blob 1633 // If there is a compiled exception handler in this method, we will continue there; 1634 // otherwise we will unwind the stack and continue at the caller of top frame method 1635 // Note we enter without the usual JRT wrapper. We will call a helper routine that 1636 // will do the normal VM entry. We do it this way so that we can see if the nmethod 1637 // we looked up the handler for has been deoptimized in the meantime. If it has been 1638 // we must not use the handler and instead return the deopt blob. 1639 address OptoRuntime::handle_exception_C(JavaThread* current) { 1640 // 1641 // We are in Java not VM and in debug mode we have a NoHandleMark 1642 // 1643 #ifndef PRODUCT 1644 SharedRuntime::_find_handler_ctr++; // find exception handler 1645 #endif 1646 debug_only(NoHandleMark __hm;) 1647 nmethod* nm = nullptr; 1648 address handler_address = nullptr; 1649 { 1650 // Enter the VM 1651 1652 ResetNoHandleMark rnhm; 1653 handler_address = handle_exception_C_helper(current, nm); 1654 } 1655 1656 // Back in java: Use no oops, DON'T safepoint 1657 1658 // Now check to see if the handler we are returning is in a now 1659 // deoptimized frame 1660 1661 if (nm != nullptr) { 1662 RegisterMap map(current, 1663 RegisterMap::UpdateMap::skip, 1664 RegisterMap::ProcessFrames::skip, 1665 RegisterMap::WalkContinuation::skip); 1666 frame caller = current->last_frame().sender(&map); 1667 #ifdef ASSERT 1668 assert(caller.is_compiled_frame(), "must be"); 1669 #endif // ASSERT 1670 if (caller.is_deoptimized_frame()) { 1671 handler_address = SharedRuntime::deopt_blob()->unpack_with_exception(); 1672 } 1673 } 1674 return handler_address; 1675 } 1676 1677 //------------------------------rethrow---------------------------------------- 1678 // We get here after compiled code has executed a 'RethrowNode'. The callee 1679 // is either throwing or rethrowing an exception. The callee-save registers 1680 // have been restored, synchronized objects have been unlocked and the callee 1681 // stack frame has been removed. The return address was passed in. 1682 // Exception oop is passed as the 1st argument. This routine is then called 1683 // from the stub. On exit, we know where to jump in the caller's code. 1684 // After this C code exits, the stub will pop his frame and end in a jump 1685 // (instead of a return). We enter the caller's default handler. 1686 // 1687 // This must be JRT_LEAF: 1688 // - caller will not change its state as we cannot block on exit, 1689 // therefore raw_exception_handler_for_return_address is all it takes 1690 // to handle deoptimized blobs 1691 // 1692 // However, there needs to be a safepoint check in the middle! So compiled 1693 // safepoints are completely watertight. 1694 // 1695 // Thus, it cannot be a leaf since it contains the NoSafepointVerifier. 1696 // 1697 // *THIS IS NOT RECOMMENDED PROGRAMMING STYLE* 1698 // 1699 address OptoRuntime::rethrow_C(oopDesc* exception, JavaThread* thread, address ret_pc) { 1700 // ret_pc will have been loaded from the stack, so for AArch64 will be signed. 1701 AARCH64_PORT_ONLY(ret_pc = pauth_strip_verifiable(ret_pc)); 1702 1703 #ifndef PRODUCT 1704 SharedRuntime::_rethrow_ctr++; // count rethrows 1705 #endif 1706 assert (exception != nullptr, "should have thrown a NullPointerException"); 1707 #ifdef ASSERT 1708 if (!(exception->is_a(vmClasses::Throwable_klass()))) { 1709 // should throw an exception here 1710 ShouldNotReachHere(); 1711 } 1712 #endif 1713 1714 thread->set_vm_result(exception); 1715 // Frame not compiled (handles deoptimization blob) 1716 return SharedRuntime::raw_exception_handler_for_return_address(thread, ret_pc); 1717 } 1718 1719 1720 const TypeFunc *OptoRuntime::rethrow_Type() { 1721 // create input type (domain) 1722 const Type **fields = TypeTuple::fields(1); 1723 fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; // Exception oop 1724 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+1,fields); 1725 1726 // create result type (range) 1727 fields = TypeTuple::fields(1); 1728 fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; // Exception oop 1729 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+1, fields); 1730 1731 return TypeFunc::make(domain, range); 1732 } 1733 1734 1735 void OptoRuntime::deoptimize_caller_frame(JavaThread *thread, bool doit) { 1736 // Deoptimize the caller before continuing, as the compiled 1737 // exception handler table may not be valid. 1738 if (!StressCompiledExceptionHandlers && doit) { 1739 deoptimize_caller_frame(thread); 1740 } 1741 } 1742 1743 void OptoRuntime::deoptimize_caller_frame(JavaThread *thread) { 1744 // Called from within the owner thread, so no need for safepoint 1745 RegisterMap reg_map(thread, 1746 RegisterMap::UpdateMap::include, 1747 RegisterMap::ProcessFrames::include, 1748 RegisterMap::WalkContinuation::skip); 1749 frame stub_frame = thread->last_frame(); 1750 assert(stub_frame.is_runtime_frame() || exception_blob()->contains(stub_frame.pc()), "sanity check"); 1751 frame caller_frame = stub_frame.sender(®_map); 1752 1753 // Deoptimize the caller frame. 1754 Deoptimization::deoptimize_frame(thread, caller_frame.id()); 1755 } 1756 1757 1758 bool OptoRuntime::is_deoptimized_caller_frame(JavaThread *thread) { 1759 // Called from within the owner thread, so no need for safepoint 1760 RegisterMap reg_map(thread, 1761 RegisterMap::UpdateMap::include, 1762 RegisterMap::ProcessFrames::include, 1763 RegisterMap::WalkContinuation::skip); 1764 frame stub_frame = thread->last_frame(); 1765 assert(stub_frame.is_runtime_frame() || exception_blob()->contains(stub_frame.pc()), "sanity check"); 1766 frame caller_frame = stub_frame.sender(®_map); 1767 return caller_frame.is_deoptimized_frame(); 1768 } 1769 1770 1771 const TypeFunc *OptoRuntime::register_finalizer_Type() { 1772 // create input type (domain) 1773 const Type **fields = TypeTuple::fields(1); 1774 fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; // oop; Receiver 1775 // // The JavaThread* is passed to each routine as the last argument 1776 // fields[TypeFunc::Parms+1] = TypeRawPtr::NOTNULL; // JavaThread *; Executing thread 1777 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+1,fields); 1778 1779 // create result type (range) 1780 fields = TypeTuple::fields(0); 1781 1782 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0,fields); 1783 1784 return TypeFunc::make(domain,range); 1785 } 1786 1787 const TypeFunc *OptoRuntime::class_init_barrier_Type() { 1788 // create input type (domain) 1789 const Type** fields = TypeTuple::fields(1); 1790 fields[TypeFunc::Parms+0] = TypeKlassPtr::NOTNULL; 1791 // // The JavaThread* is passed to each routine as the last argument 1792 // fields[TypeFunc::Parms+1] = TypeRawPtr::NOTNULL; // JavaThread *; Executing thread 1793 const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms+1, fields); 1794 1795 // create result type (range) 1796 fields = TypeTuple::fields(0); 1797 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0, fields); 1798 return TypeFunc::make(domain,range); 1799 } 1800 1801 #if INCLUDE_JFR 1802 const TypeFunc *OptoRuntime::class_id_load_barrier_Type() { 1803 // create input type (domain) 1804 const Type **fields = TypeTuple::fields(1); 1805 fields[TypeFunc::Parms+0] = TypeInstPtr::KLASS; 1806 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms + 1, fields); 1807 1808 // create result type (range) 1809 fields = TypeTuple::fields(0); 1810 1811 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms + 0, fields); 1812 1813 return TypeFunc::make(domain,range); 1814 } 1815 #endif 1816 1817 //----------------------------------------------------------------------------- 1818 // Dtrace support. entry and exit probes have the same signature 1819 const TypeFunc *OptoRuntime::dtrace_method_entry_exit_Type() { 1820 // create input type (domain) 1821 const Type **fields = TypeTuple::fields(2); 1822 fields[TypeFunc::Parms+0] = TypeRawPtr::BOTTOM; // Thread-local storage 1823 fields[TypeFunc::Parms+1] = TypeMetadataPtr::BOTTOM; // Method*; Method we are entering 1824 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+2,fields); 1825 1826 // create result type (range) 1827 fields = TypeTuple::fields(0); 1828 1829 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0,fields); 1830 1831 return TypeFunc::make(domain,range); 1832 } 1833 1834 const TypeFunc *OptoRuntime::dtrace_object_alloc_Type() { 1835 // create input type (domain) 1836 const Type **fields = TypeTuple::fields(2); 1837 fields[TypeFunc::Parms+0] = TypeRawPtr::BOTTOM; // Thread-local storage 1838 fields[TypeFunc::Parms+1] = TypeInstPtr::NOTNULL; // oop; newly allocated object 1839 1840 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+2,fields); 1841 1842 // create result type (range) 1843 fields = TypeTuple::fields(0); 1844 1845 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0,fields); 1846 1847 return TypeFunc::make(domain,range); 1848 } 1849 1850 1851 JRT_ENTRY_NO_ASYNC_PROF(void, OptoRuntime, register_finalizer, OptoRuntime::register_finalizer(oopDesc* obj, JavaThread* current)) 1852 assert(oopDesc::is_oop(obj), "must be a valid oop"); 1853 assert(obj->klass()->has_finalizer(), "shouldn't be here otherwise"); 1854 InstanceKlass::register_finalizer(instanceOop(obj), CHECK); 1855 JRT_END 1856 1857 JRT_ENTRY_NO_ASYNC_PROF(void, OptoRuntime, class_init_barrier, OptoRuntime::class_init_barrier(Klass* k, JavaThread* current)) 1858 InstanceKlass* ik = InstanceKlass::cast(k); 1859 if (ik->should_be_initialized()) { 1860 ik->initialize(CHECK); 1861 } else if (UsePerfData) { 1862 _perf_OptoRuntime_class_init_barrier_redundant_count->inc(); 1863 } 1864 JRT_END 1865 1866 //----------------------------------------------------------------------------- 1867 1868 NamedCounter * volatile OptoRuntime::_named_counters = nullptr; 1869 1870 // 1871 // dump the collected NamedCounters. 1872 // 1873 void OptoRuntime::print_named_counters() { 1874 int total_lock_count = 0; 1875 int eliminated_lock_count = 0; 1876 1877 NamedCounter* c = _named_counters; 1878 while (c) { 1879 if (c->tag() == NamedCounter::LockCounter || c->tag() == NamedCounter::EliminatedLockCounter) { 1880 int count = c->count(); 1881 if (count > 0) { 1882 bool eliminated = c->tag() == NamedCounter::EliminatedLockCounter; 1883 if (Verbose) { 1884 tty->print_cr("%d %s%s", count, c->name(), eliminated ? " (eliminated)" : ""); 1885 } 1886 total_lock_count += count; 1887 if (eliminated) { 1888 eliminated_lock_count += count; 1889 } 1890 } 1891 } 1892 c = c->next(); 1893 } 1894 if (total_lock_count > 0) { 1895 tty->print_cr("dynamic locks: %d", total_lock_count); 1896 if (eliminated_lock_count) { 1897 tty->print_cr("eliminated locks: %d (%d%%)", eliminated_lock_count, 1898 (int)(eliminated_lock_count * 100.0 / total_lock_count)); 1899 } 1900 } 1901 } 1902 1903 // 1904 // Allocate a new NamedCounter. The JVMState is used to generate the 1905 // name which consists of method@line for the inlining tree. 1906 // 1907 1908 NamedCounter* OptoRuntime::new_named_counter(JVMState* youngest_jvms, NamedCounter::CounterTag tag) { 1909 int max_depth = youngest_jvms->depth(); 1910 1911 // Visit scopes from youngest to oldest. 1912 bool first = true; 1913 stringStream st; 1914 for (int depth = max_depth; depth >= 1; depth--) { 1915 JVMState* jvms = youngest_jvms->of_depth(depth); 1916 ciMethod* m = jvms->has_method() ? jvms->method() : nullptr; 1917 if (!first) { 1918 st.print(" "); 1919 } else { 1920 first = false; 1921 } 1922 int bci = jvms->bci(); 1923 if (bci < 0) bci = 0; 1924 if (m != nullptr) { 1925 st.print("%s.%s", m->holder()->name()->as_utf8(), m->name()->as_utf8()); 1926 } else { 1927 st.print("no method"); 1928 } 1929 st.print("@%d", bci); 1930 // To print linenumbers instead of bci use: m->line_number_from_bci(bci) 1931 } 1932 NamedCounter* c = new NamedCounter(st.freeze(), tag); 1933 1934 // atomically add the new counter to the head of the list. We only 1935 // add counters so this is safe. 1936 NamedCounter* head; 1937 do { 1938 c->set_next(nullptr); 1939 head = _named_counters; 1940 c->set_next(head); 1941 } while (Atomic::cmpxchg(&_named_counters, head, c) != head); 1942 return c; 1943 } 1944 1945 int trace_exception_counter = 0; 1946 static void trace_exception(outputStream* st, oop exception_oop, address exception_pc, const char* msg) { 1947 trace_exception_counter++; 1948 stringStream tempst; 1949 1950 tempst.print("%d [Exception (%s): ", trace_exception_counter, msg); 1951 exception_oop->print_value_on(&tempst); 1952 tempst.print(" in "); 1953 CodeBlob* blob = CodeCache::find_blob(exception_pc); 1954 if (blob->is_nmethod()) { 1955 blob->as_nmethod()->method()->print_value_on(&tempst); 1956 } else if (blob->is_runtime_stub()) { 1957 tempst.print("<runtime-stub>"); 1958 } else { 1959 tempst.print("<unknown>"); 1960 } 1961 tempst.print(" at " INTPTR_FORMAT, p2i(exception_pc)); 1962 tempst.print("]"); 1963 1964 st->print_raw_cr(tempst.freeze()); 1965 } 1966 1967 #define DO_COUNTERS2(macro2, macro1) \ 1968 macro2(OptoRuntime, new_instance_C) \ 1969 macro2(OptoRuntime, new_array_C) \ 1970 macro2(OptoRuntime, new_array_nozero_C) \ 1971 macro2(OptoRuntime, multianewarray2_C) \ 1972 macro2(OptoRuntime, multianewarray3_C) \ 1973 macro2(OptoRuntime, multianewarray4_C) \ 1974 macro2(OptoRuntime, multianewarrayN_C) \ 1975 macro2(OptoRuntime, monitor_notify_C) \ 1976 macro2(OptoRuntime, monitor_notifyAll_C) \ 1977 macro2(OptoRuntime, handle_exception_C_helper) \ 1978 macro2(OptoRuntime, register_finalizer) \ 1979 macro2(OptoRuntime, class_init_barrier) \ 1980 macro1(OptoRuntime, class_init_barrier_redundant) 1981 1982 #define INIT_COUNTER_TIME_AND_CNT(sub, name) \ 1983 NEWPERFTICKCOUNTERS(_perf_##sub##_##name##_timer, SUN_CI, #sub "::" #name); \ 1984 NEWPERFEVENTCOUNTER(_perf_##sub##_##name##_count, SUN_CI, #sub "::" #name "_count"); 1985 1986 #define INIT_COUNTER_CNT(sub, name) \ 1987 NEWPERFEVENTCOUNTER(_perf_##sub##_##name##_count, SUN_CI, #sub "::" #name "_count"); 1988 1989 void OptoRuntime::init_counters() { 1990 assert(CompilerConfig::is_c2_enabled(), ""); 1991 1992 if (UsePerfData) { 1993 EXCEPTION_MARK; 1994 1995 DO_COUNTERS2(INIT_COUNTER_TIME_AND_CNT, INIT_COUNTER_CNT) 1996 1997 if (HAS_PENDING_EXCEPTION) { 1998 vm_exit_during_initialization("jvm_perf_init failed unexpectedly"); 1999 } 2000 } 2001 } 2002 #undef INIT_COUNTER_TIME_AND_CNT 2003 #undef INIT_COUNTER_CNT 2004 2005 #define PRINT_COUNTER_TIME_AND_CNT(sub, name) { \ 2006 jlong count = _perf_##sub##_##name##_count->get_value(); \ 2007 if (count > 0) { \ 2008 st->print_cr(" %-30s = %4ldms (elapsed) %4ldms (thread) (%5ld events)", #sub "::" #name, \ 2009 _perf_##sub##_##name##_timer->elapsed_counter_value_ms(), \ 2010 _perf_##sub##_##name##_timer->thread_counter_value_ms(), \ 2011 count); \ 2012 }} 2013 2014 #define PRINT_COUNTER_CNT(sub, name) { \ 2015 jlong count = _perf_##sub##_##name##_count->get_value(); \ 2016 if (count > 0) { \ 2017 st->print_cr(" %-30s = %5ld events", #name, count); \ 2018 }} 2019 2020 void OptoRuntime::print_counters_on(outputStream* st) { 2021 if (UsePerfData && ProfileRuntimeCalls && CompilerConfig::is_c2_enabled()) { 2022 DO_COUNTERS2(PRINT_COUNTER_TIME_AND_CNT, PRINT_COUNTER_CNT) 2023 } else { 2024 st->print_cr(" OptoRuntime: no info (%s is disabled)", 2025 (!CompilerConfig::is_c2_enabled() ? "C2" : (UsePerfData ? "ProfileRuntimeCalls" : "UsePerfData"))); 2026 } 2027 } 2028 2029 #undef PRINT_COUNTER_TIME_AND_CNT 2030 #undef PRINT_COUNTER_CNT 2031 #undef DO_COUNTERS2