annotate src/hotspot/share/opto/runtime.cpp @ 54048:744dc9c33676

8217417: Decorator name typo: C2_TIGHLY_COUPLED_ALLOC Summary: Fixed typo in decorator name, variables, and comments. Reviewed-by: tschatzl
author kbarrett
date Mon, 11 Mar 2019 02:05:07 -0400
parents 480a96a43b62
children f9d9bed12d1a
rev   line source
duke@1 1 /*
eosterlund@48961 2 * Copyright (c) 1998, 2018, Oracle and/or its affiliates. All rights reserved.
duke@1 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
duke@1 4 *
duke@1 5 * This code is free software; you can redistribute it and/or modify it
duke@1 6 * under the terms of the GNU General Public License version 2 only, as
duke@1 7 * published by the Free Software Foundation.
duke@1 8 *
duke@1 9 * This code is distributed in the hope that it will be useful, but WITHOUT
duke@1 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
duke@1 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
duke@1 12 * version 2 for more details (a copy is included in the LICENSE file that
duke@1 13 * accompanied this code).
duke@1 14 *
duke@1 15 * You should have received a copy of the GNU General Public License version
duke@1 16 * 2 along with this work; if not, write to the Free Software Foundation,
duke@1 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
duke@1 18 *
trims@5547 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
trims@5547 20 * or visit www.oracle.com if you need additional information or have any
trims@5547 21 * questions.
duke@1 22 *
duke@1 23 */
duke@1 24
stefank@7397 25 #include "precompiled.hpp"
stefank@7397 26 #include "classfile/systemDictionary.hpp"
stefank@7397 27 #include "classfile/vmSymbols.hpp"
goetz@25715 28 #include "code/codeCache.hpp"
coleenp@49480 29 #include "code/compiledMethod.inline.hpp"
stefank@7397 30 #include "code/compiledIC.hpp"
stefank@7397 31 #include "code/icBuffer.hpp"
stefank@7397 32 #include "code/nmethod.hpp"
stefank@7397 33 #include "code/pcDesc.hpp"
stefank@7397 34 #include "code/scopeDesc.hpp"
stefank@7397 35 #include "code/vtableStubs.hpp"
stefank@7397 36 #include "compiler/compileBroker.hpp"
stefank@7397 37 #include "compiler/oopMap.hpp"
pliden@30764 38 #include "gc/g1/heapRegion.hpp"
pliden@30764 39 #include "gc/shared/barrierSet.hpp"
pliden@30764 40 #include "gc/shared/collectedHeap.hpp"
stefank@49594 41 #include "gc/shared/gcLocker.hpp"
stefank@7397 42 #include "interpreter/bytecode.hpp"
stefank@7397 43 #include "interpreter/interpreter.hpp"
stefank@7397 44 #include "interpreter/linkResolver.hpp"
rprotacio@35216 45 #include "logging/log.hpp"
stuefe@46701 46 #include "logging/logStream.hpp"
stefank@7397 47 #include "memory/oopFactory.hpp"
jprovino@37248 48 #include "memory/resourceArea.hpp"
stefank@7397 49 #include "oops/objArrayKlass.hpp"
stefank@7397 50 #include "oops/oop.inline.hpp"
goetz@35498 51 #include "oops/typeArrayOop.inline.hpp"
goetz@25715 52 #include "opto/ad.hpp"
stefank@7397 53 #include "opto/addnode.hpp"
stefank@7397 54 #include "opto/callnode.hpp"
stefank@7397 55 #include "opto/cfgnode.hpp"
stefank@7397 56 #include "opto/graphKit.hpp"
stefank@7397 57 #include "opto/machnode.hpp"
stefank@7397 58 #include "opto/matcher.hpp"
stefank@7397 59 #include "opto/memnode.hpp"
stefank@7397 60 #include "opto/mulnode.hpp"
stefank@7397 61 #include "opto/runtime.hpp"
stefank@7397 62 #include "opto/subnode.hpp"
dholmes@40655 63 #include "runtime/atomic.hpp"
coleenp@49480 64 #include "runtime/frame.inline.hpp"
stefank@7397 65 #include "runtime/handles.inline.hpp"
coleenp@49449 66 #include "runtime/interfaceSupport.inline.hpp"
stefank@7397 67 #include "runtime/javaCalls.hpp"
stefank@7397 68 #include "runtime/sharedRuntime.hpp"
stefank@7397 69 #include "runtime/signature.hpp"
stefank@7397 70 #include "runtime/threadCritical.hpp"
stefank@7397 71 #include "runtime/vframe.hpp"
stefank@7397 72 #include "runtime/vframeArray.hpp"
stefank@7397 73 #include "runtime/vframe_hp.hpp"
stefank@7397 74 #include "utilities/copy.hpp"
stefank@7397 75 #include "utilities/preserveException.hpp"
duke@1 76
duke@1 77
duke@1 78 // For debugging purposes:
duke@1 79 // To force FullGCALot inside a runtime function, add the following two lines
duke@1 80 //
duke@1 81 // Universe::release_fullgc_alot_dummy();
duke@1 82 // MarkSweep::invoke(0, "Debugging");
duke@1 83 //
duke@1 84 // At command line specify the parameters: -XX:+FullGCALot -XX:FullGCALotStart=100000000
duke@1 85
duke@1 86
duke@1 87
duke@1 88
duke@1 89 // Compiled code entry points
duke@1 90 address OptoRuntime::_new_instance_Java = NULL;
duke@1 91 address OptoRuntime::_new_array_Java = NULL;
kvn@10566 92 address OptoRuntime::_new_array_nozero_Java = NULL;
duke@1 93 address OptoRuntime::_multianewarray2_Java = NULL;
duke@1 94 address OptoRuntime::_multianewarray3_Java = NULL;
duke@1 95 address OptoRuntime::_multianewarray4_Java = NULL;
duke@1 96 address OptoRuntime::_multianewarray5_Java = NULL;
iveresov@10028 97 address OptoRuntime::_multianewarrayN_Java = NULL;
duke@1 98 address OptoRuntime::_vtable_must_compile_Java = NULL;
duke@1 99 address OptoRuntime::_complete_monitor_locking_Java = NULL;
dcubed@31856 100 address OptoRuntime::_monitor_notify_Java = NULL;
dcubed@31856 101 address OptoRuntime::_monitor_notifyAll_Java = NULL;
duke@1 102 address OptoRuntime::_rethrow_Java = NULL;
duke@1 103
duke@1 104 address OptoRuntime::_slow_arraycopy_Java = NULL;
duke@1 105 address OptoRuntime::_register_finalizer_Java = NULL;
duke@1 106
never@9976 107 ExceptionBlob* OptoRuntime::_exception_blob;
duke@1 108
duke@1 109 // This should be called in an assertion at the start of OptoRuntime routines
duke@1 110 // which are entered from compiled code (all of them)
roland@17379 111 #ifdef ASSERT
duke@1 112 static bool check_compiled_frame(JavaThread* thread) {
duke@1 113 assert(thread->last_frame().is_runtime_frame(), "cannot call runtime directly from compiled code");
duke@1 114 RegisterMap map(thread, false);
duke@1 115 frame caller = thread->last_frame().sender(&map);
duke@1 116 assert(caller.is_compiled_frame(), "not being called from compiled like code");
duke@1 117 return true;
duke@1 118 }
roland@17379 119 #endif // ASSERT
duke@1 120
duke@1 121
duke@1 122 #define gen(env, var, type_func_gen, c_func, fancy_jump, pass_tls, save_arg_regs, return_pc) \
anoll@20707 123 var = generate_stub(env, type_func_gen, CAST_FROM_FN_PTR(address, c_func), #var, fancy_jump, pass_tls, save_arg_regs, return_pc); \
anoll@20707 124 if (var == NULL) { return false; }
duke@1 125
anoll@20707 126 bool OptoRuntime::generate(ciEnv* env) {
duke@1 127
duke@1 128 generate_exception_blob();
duke@1 129
duke@1 130 // Note: tls: Means fetching the return oop out of the thread-local storage
duke@1 131 //
duke@1 132 // variable/name type-function-gen , runtime method ,fncy_jp, tls,save_args,retpc
duke@1 133 // -------------------------------------------------------------------------------------------------------------------------------
duke@1 134 gen(env, _new_instance_Java , new_instance_Type , new_instance_C , 0 , true , false, false);
duke@1 135 gen(env, _new_array_Java , new_array_Type , new_array_C , 0 , true , false, false);
kvn@10566 136 gen(env, _new_array_nozero_Java , new_array_Type , new_array_nozero_C , 0 , true , false, false);
duke@1 137 gen(env, _multianewarray2_Java , multianewarray2_Type , multianewarray2_C , 0 , true , false, false);
duke@1 138 gen(env, _multianewarray3_Java , multianewarray3_Type , multianewarray3_C , 0 , true , false, false);
duke@1 139 gen(env, _multianewarray4_Java , multianewarray4_Type , multianewarray4_C , 0 , true , false, false);
duke@1 140 gen(env, _multianewarray5_Java , multianewarray5_Type , multianewarray5_C , 0 , true , false, false);
iveresov@10028 141 gen(env, _multianewarrayN_Java , multianewarrayN_Type , multianewarrayN_C , 0 , true , false, false);
anoll@20707 142 gen(env, _complete_monitor_locking_Java , complete_monitor_enter_Type , SharedRuntime::complete_monitor_locking_C, 0, false, false, false);
dcubed@31856 143 gen(env, _monitor_notify_Java , monitor_notify_Type , monitor_notify_C , 0 , false, false, false);
dcubed@31856 144 gen(env, _monitor_notifyAll_Java , monitor_notify_Type , monitor_notifyAll_C , 0 , false, false, false);
duke@1 145 gen(env, _rethrow_Java , rethrow_Type , rethrow_C , 2 , true , false, true );
duke@1 146
duke@1 147 gen(env, _slow_arraycopy_Java , slow_arraycopy_Type , SharedRuntime::slow_arraycopy_C , 0 , false, false, false);
duke@1 148 gen(env, _register_finalizer_Java , register_finalizer_Type , register_finalizer , 0 , false, false, false);
duke@1 149
anoll@20707 150 return true;
duke@1 151 }
duke@1 152
duke@1 153 #undef gen
duke@1 154
duke@1 155
duke@1 156 // Helper method to do generation of RunTimeStub's
duke@1 157 address OptoRuntime::generate_stub( ciEnv* env,
duke@1 158 TypeFunc_generator gen, address C_function,
duke@1 159 const char *name, int is_fancy_jump,
duke@1 160 bool pass_tls,
duke@1 161 bool save_argument_registers,
neliasso@33451 162 bool return_pc) {
neliasso@33451 163
neliasso@33451 164 // Matching the default directive, we currently have no method to match.
neliasso@33451 165 DirectiveSet* directive = DirectivesStack::getDefaultDirective(CompileBroker::compiler(CompLevel_full_optimization));
duke@1 166 ResourceMark rm;
neliasso@33451 167 Compile C( env, gen, C_function, name, is_fancy_jump, pass_tls, save_argument_registers, return_pc, directive);
neliasso@33451 168 DirectivesStack::release(directive);
duke@1 169 return C.stub_entry_point();
duke@1 170 }
duke@1 171
duke@1 172 const char* OptoRuntime::stub_name(address entry) {
duke@1 173 #ifndef PRODUCT
duke@1 174 CodeBlob* cb = CodeCache::find_blob(entry);
duke@1 175 RuntimeStub* rs =(RuntimeStub *)cb;
duke@1 176 assert(rs != NULL && rs->is_runtime_stub(), "not a runtime stub");
duke@1 177 return rs->name();
duke@1 178 #else
duke@1 179 // Fast implementation for product mode (maybe it should be inlined too)
duke@1 180 return "runtime stub";
duke@1 181 #endif
duke@1 182 }
duke@1 183
duke@1 184
duke@1 185 //=============================================================================
duke@1 186 // Opto compiler runtime routines
duke@1 187 //=============================================================================
duke@1 188
duke@1 189
duke@1 190 //=============================allocation======================================
duke@1 191 // We failed the fast-path allocation. Now we need to do a scavenge or GC
duke@1 192 // and try allocation again.
duke@1 193
duke@1 194 // object allocation
coleenp@13728 195 JRT_BLOCK_ENTRY(void, OptoRuntime::new_instance_C(Klass* klass, JavaThread* thread))
duke@1 196 JRT_BLOCK;
duke@1 197 #ifndef PRODUCT
duke@1 198 SharedRuntime::_new_instance_ctr++; // new instance requires GC
duke@1 199 #endif
duke@1 200 assert(check_compiled_frame(thread), "incorrect caller");
duke@1 201
duke@1 202 // These checks are cheap to make and support reflective allocation.
hseigel@14488 203 int lh = klass->layout_helper();
vlivanov@36603 204 if (Klass::layout_helper_needs_slow_path(lh) || !InstanceKlass::cast(klass)->is_initialized()) {
vlivanov@36603 205 Handle holder(THREAD, klass->klass_holder()); // keep the klass alive
vlivanov@36603 206 klass->check_valid_for_instantiation(false, THREAD);
duke@1 207 if (!HAS_PENDING_EXCEPTION) {
vlivanov@36603 208 InstanceKlass::cast(klass)->initialize(THREAD);
duke@1 209 }
duke@1 210 }
duke@1 211
vlivanov@36603 212 if (!HAS_PENDING_EXCEPTION) {
duke@1 213 // Scavenge and allocate an instance.
vlivanov@36603 214 Handle holder(THREAD, klass->klass_holder()); // keep the klass alive
coleenp@13728 215 oop result = InstanceKlass::cast(klass)->allocate_instance(THREAD);
duke@1 216 thread->set_vm_result(result);
duke@1 217
duke@1 218 // Pass oops back through thread local storage. Our apparent type to Java
duke@1 219 // is that we return an oop, but we can block on exit from this routine and
duke@1 220 // a GC can trash the oop in C's return register. The generated stub will
duke@1 221 // fetch the oop from TLS after any possible GC.
duke@1 222 }
duke@1 223
duke@1 224 deoptimize_caller_frame(thread, HAS_PENDING_EXCEPTION);
duke@1 225 JRT_BLOCK_END;
duke@1 226
eosterlund@48961 227 // inform GC that we won't do card marks for initializing writes.
eosterlund@48961 228 SharedRuntime::on_slowpath_allocation_exit(thread);
duke@1 229 JRT_END
duke@1 230
duke@1 231
duke@1 232 // array allocation
coleenp@13728 233 JRT_BLOCK_ENTRY(void, OptoRuntime::new_array_C(Klass* array_type, int len, JavaThread *thread))
duke@1 234 JRT_BLOCK;
duke@1 235 #ifndef PRODUCT
duke@1 236 SharedRuntime::_new_array_ctr++; // new array requires GC
duke@1 237 #endif
duke@1 238 assert(check_compiled_frame(thread), "incorrect caller");
duke@1 239
duke@1 240 // Scavenge and allocate an instance.
duke@1 241 oop result;
duke@1 242
coleenp@33611 243 if (array_type->is_typeArray_klass()) {
duke@1 244 // The oopFactory likes to work with the element type.
duke@1 245 // (We could bypass the oopFactory, since it doesn't add much value.)
coleenp@13952 246 BasicType elem_type = TypeArrayKlass::cast(array_type)->element_type();
duke@1 247 result = oopFactory::new_typeArray(elem_type, len, THREAD);
duke@1 248 } else {
duke@1 249 // Although the oopFactory likes to work with the elem_type,
duke@1 250 // the compiler prefers the array_type, since it must already have
duke@1 251 // that latter value in hand for the fast path.
vlivanov@36603 252 Handle holder(THREAD, array_type->klass_holder()); // keep the array klass alive
coleenp@13952 253 Klass* elem_type = ObjArrayKlass::cast(array_type)->element_klass();
duke@1 254 result = oopFactory::new_objArray(elem_type, len, THREAD);
duke@1 255 }
duke@1 256
duke@1 257 // Pass oops back through thread local storage. Our apparent type to Java
duke@1 258 // is that we return an oop, but we can block on exit from this routine and
duke@1 259 // a GC can trash the oop in C's return register. The generated stub will
duke@1 260 // fetch the oop from TLS after any possible GC.
duke@1 261 deoptimize_caller_frame(thread, HAS_PENDING_EXCEPTION);
duke@1 262 thread->set_vm_result(result);
duke@1 263 JRT_BLOCK_END;
duke@1 264
eosterlund@48961 265 // inform GC that we won't do card marks for initializing writes.
eosterlund@48961 266 SharedRuntime::on_slowpath_allocation_exit(thread);
duke@1 267 JRT_END
duke@1 268
kvn@10566 269 // array allocation without zeroing
coleenp@13728 270 JRT_BLOCK_ENTRY(void, OptoRuntime::new_array_nozero_C(Klass* array_type, int len, JavaThread *thread))
kvn@10566 271 JRT_BLOCK;
kvn@10566 272 #ifndef PRODUCT
kvn@10566 273 SharedRuntime::_new_array_ctr++; // new array requires GC
kvn@10566 274 #endif
kvn@10566 275 assert(check_compiled_frame(thread), "incorrect caller");
kvn@10566 276
kvn@10566 277 // Scavenge and allocate an instance.
kvn@10566 278 oop result;
kvn@10566 279
coleenp@33611 280 assert(array_type->is_typeArray_klass(), "should be called only for type array");
kvn@10566 281 // The oopFactory likes to work with the element type.
coleenp@13952 282 BasicType elem_type = TypeArrayKlass::cast(array_type)->element_type();
kvn@10566 283 result = oopFactory::new_typeArray_nozero(elem_type, len, THREAD);
kvn@10566 284
kvn@10566 285 // Pass oops back through thread local storage. Our apparent type to Java
kvn@10566 286 // is that we return an oop, but we can block on exit from this routine and
kvn@10566 287 // a GC can trash the oop in C's return register. The generated stub will
kvn@10566 288 // fetch the oop from TLS after any possible GC.
kvn@10566 289 deoptimize_caller_frame(thread, HAS_PENDING_EXCEPTION);
kvn@10566 290 thread->set_vm_result(result);
kvn@10566 291 JRT_BLOCK_END;
kvn@10566 292
eosterlund@48961 293
eosterlund@48961 294 // inform GC that we won't do card marks for initializing writes.
eosterlund@48961 295 SharedRuntime::on_slowpath_allocation_exit(thread);
kvn@10987 296
kvn@10987 297 oop result = thread->vm_result();
kvn@10987 298 if ((len > 0) && (result != NULL) &&
kvn@10987 299 is_deoptimized_caller_frame(thread)) {
kvn@10987 300 // Zero array here if the caller is deoptimized.
kvn@10987 301 int size = ((typeArrayOop)result)->object_size();
coleenp@13952 302 BasicType elem_type = TypeArrayKlass::cast(array_type)->element_type();
kvn@10987 303 const size_t hs = arrayOopDesc::header_size(elem_type);
kvn@10987 304 // Align to next 8 bytes to avoid trashing arrays's length.
kvn@10987 305 const size_t aligned_hs = align_object_offset(hs);
kvn@10987 306 HeapWord* obj = (HeapWord*)result;
kvn@10987 307 if (aligned_hs > hs) {
kvn@10987 308 Copy::zero_to_words(obj+hs, aligned_hs-hs);
kvn@10987 309 }
kvn@10987 310 // Optimized zeroing.
kvn@10987 311 Copy::fill_to_aligned_words(obj+aligned_hs, size-aligned_hs);
kvn@10987 312 }
kvn@10987 313
kvn@10566 314 JRT_END
kvn@10566 315
duke@1 316 // Note: multianewarray for one dimension is handled inline by GraphKit::new_array.
duke@1 317
duke@1 318 // multianewarray for 2 dimensions
coleenp@13728 319 JRT_ENTRY(void, OptoRuntime::multianewarray2_C(Klass* elem_type, int len1, int len2, JavaThread *thread))
duke@1 320 #ifndef PRODUCT
duke@1 321 SharedRuntime::_multi2_ctr++; // multianewarray for 1 dimension
duke@1 322 #endif
duke@1 323 assert(check_compiled_frame(thread), "incorrect caller");
coleenp@13728 324 assert(elem_type->is_klass(), "not a class");
duke@1 325 jint dims[2];
duke@1 326 dims[0] = len1;
duke@1 327 dims[1] = len2;
vlivanov@36603 328 Handle holder(THREAD, elem_type->klass_holder()); // keep the klass alive
coleenp@13952 329 oop obj = ArrayKlass::cast(elem_type)->multi_allocate(2, dims, THREAD);
duke@1 330 deoptimize_caller_frame(thread, HAS_PENDING_EXCEPTION);
duke@1 331 thread->set_vm_result(obj);
duke@1 332 JRT_END
duke@1 333
duke@1 334 // multianewarray for 3 dimensions
coleenp@13728 335 JRT_ENTRY(void, OptoRuntime::multianewarray3_C(Klass* elem_type, int len1, int len2, int len3, JavaThread *thread))
duke@1 336 #ifndef PRODUCT
duke@1 337 SharedRuntime::_multi3_ctr++; // multianewarray for 1 dimension
duke@1 338 #endif
duke@1 339 assert(check_compiled_frame(thread), "incorrect caller");
coleenp@13728 340 assert(elem_type->is_klass(), "not a class");
duke@1 341 jint dims[3];
duke@1 342 dims[0] = len1;
duke@1 343 dims[1] = len2;
duke@1 344 dims[2] = len3;
vlivanov@36603 345 Handle holder(THREAD, elem_type->klass_holder()); // keep the klass alive
coleenp@13952 346 oop obj = ArrayKlass::cast(elem_type)->multi_allocate(3, dims, THREAD);
duke@1 347 deoptimize_caller_frame(thread, HAS_PENDING_EXCEPTION);
duke@1 348 thread->set_vm_result(obj);
duke@1 349 JRT_END
duke@1 350
duke@1 351 // multianewarray for 4 dimensions
coleenp@13728 352 JRT_ENTRY(void, OptoRuntime::multianewarray4_C(Klass* elem_type, int len1, int len2, int len3, int len4, JavaThread *thread))
duke@1 353 #ifndef PRODUCT
duke@1 354 SharedRuntime::_multi4_ctr++; // multianewarray for 1 dimension
duke@1 355 #endif
duke@1 356 assert(check_compiled_frame(thread), "incorrect caller");
coleenp@13728 357 assert(elem_type->is_klass(), "not a class");
duke@1 358 jint dims[4];
duke@1 359 dims[0] = len1;
duke@1 360 dims[1] = len2;
duke@1 361 dims[2] = len3;
duke@1 362 dims[3] = len4;
vlivanov@36603 363 Handle holder(THREAD, elem_type->klass_holder()); // keep the klass alive
coleenp@13952 364 oop obj = ArrayKlass::cast(elem_type)->multi_allocate(4, dims, THREAD);
duke@1 365 deoptimize_caller_frame(thread, HAS_PENDING_EXCEPTION);
duke@1 366 thread->set_vm_result(obj);
duke@1 367 JRT_END
duke@1 368
duke@1 369 // multianewarray for 5 dimensions
coleenp@13728 370 JRT_ENTRY(void, OptoRuntime::multianewarray5_C(Klass* elem_type, int len1, int len2, int len3, int len4, int len5, JavaThread *thread))
duke@1 371 #ifndef PRODUCT
duke@1 372 SharedRuntime::_multi5_ctr++; // multianewarray for 1 dimension
duke@1 373 #endif
duke@1 374 assert(check_compiled_frame(thread), "incorrect caller");
coleenp@13728 375 assert(elem_type->is_klass(), "not a class");
duke@1 376 jint dims[5];
duke@1 377 dims[0] = len1;
duke@1 378 dims[1] = len2;
duke@1 379 dims[2] = len3;
duke@1 380 dims[3] = len4;
duke@1 381 dims[4] = len5;
vlivanov@36603 382 Handle holder(THREAD, elem_type->klass_holder()); // keep the klass alive
coleenp@13952 383 oop obj = ArrayKlass::cast(elem_type)->multi_allocate(5, dims, THREAD);
duke@1 384 deoptimize_caller_frame(thread, HAS_PENDING_EXCEPTION);
duke@1 385 thread->set_vm_result(obj);
duke@1 386 JRT_END
duke@1 387
coleenp@13728 388 JRT_ENTRY(void, OptoRuntime::multianewarrayN_C(Klass* elem_type, arrayOopDesc* dims, JavaThread *thread))
iveresov@10028 389 assert(check_compiled_frame(thread), "incorrect caller");
coleenp@13728 390 assert(elem_type->is_klass(), "not a class");
iveresov@10028 391 assert(oop(dims)->is_typeArray(), "not an array");
iveresov@10028 392
iveresov@10028 393 ResourceMark rm;
iveresov@10028 394 jint len = dims->length();
iveresov@10028 395 assert(len > 0, "Dimensions array should contain data");
iveresov@10028 396 jint *c_dims = NEW_RESOURCE_ARRAY(jint, len);
rkennke@50389 397 ArrayAccess<>::arraycopy_to_native<>(dims, typeArrayOopDesc::element_offset<jint>(0),
rkennke@50389 398 c_dims, len);
iveresov@10028 399
vlivanov@36603 400 Handle holder(THREAD, elem_type->klass_holder()); // keep the klass alive
coleenp@13952 401 oop obj = ArrayKlass::cast(elem_type)->multi_allocate(len, c_dims, THREAD);
iveresov@10028 402 deoptimize_caller_frame(thread, HAS_PENDING_EXCEPTION);
iveresov@10028 403 thread->set_vm_result(obj);
iveresov@10028 404 JRT_END
iveresov@10028 405
dcubed@31856 406 JRT_BLOCK_ENTRY(void, OptoRuntime::monitor_notify_C(oopDesc* obj, JavaThread *thread))
dcubed@31856 407
dcubed@31856 408 // Very few notify/notifyAll operations find any threads on the waitset, so
dcubed@31856 409 // the dominant fast-path is to simply return.
dcubed@31856 410 // Relatedly, it's critical that notify/notifyAll be fast in order to
dcubed@31856 411 // reduce lock hold times.
dcubed@31856 412 if (!SafepointSynchronize::is_synchronizing()) {
dcubed@31856 413 if (ObjectSynchronizer::quick_notify(obj, thread, false)) {
dcubed@31856 414 return;
dcubed@31856 415 }
dcubed@31856 416 }
dcubed@31856 417
dcubed@31856 418 // This is the case the fast-path above isn't provisioned to handle.
dcubed@31856 419 // The fast-path is designed to handle frequently arising cases in an efficient manner.
dcubed@31856 420 // (The fast-path is just a degenerate variant of the slow-path).
dcubed@31856 421 // Perform the dreaded state transition and pass control into the slow-path.
dcubed@31856 422 JRT_BLOCK;
dcubed@31856 423 Handle h_obj(THREAD, obj);
dcubed@31856 424 ObjectSynchronizer::notify(h_obj, CHECK);
dcubed@31856 425 JRT_BLOCK_END;
dcubed@31856 426 JRT_END
dcubed@31856 427
dcubed@31856 428 JRT_BLOCK_ENTRY(void, OptoRuntime::monitor_notifyAll_C(oopDesc* obj, JavaThread *thread))
dcubed@31856 429
dcubed@31856 430 if (!SafepointSynchronize::is_synchronizing() ) {
dcubed@31856 431 if (ObjectSynchronizer::quick_notify(obj, thread, true)) {
dcubed@31856 432 return;
dcubed@31856 433 }
dcubed@31856 434 }
dcubed@31856 435
dcubed@31856 436 // This is the case the fast-path above isn't provisioned to handle.
dcubed@31856 437 // The fast-path is designed to handle frequently arising cases in an efficient manner.
dcubed@31856 438 // (The fast-path is just a degenerate variant of the slow-path).
dcubed@31856 439 // Perform the dreaded state transition and pass control into the slow-path.
dcubed@31856 440 JRT_BLOCK;
dcubed@31856 441 Handle h_obj(THREAD, obj);
dcubed@31856 442 ObjectSynchronizer::notifyall(h_obj, CHECK);
dcubed@31856 443 JRT_BLOCK_END;
dcubed@31856 444 JRT_END
iveresov@10028 445
duke@1 446 const TypeFunc *OptoRuntime::new_instance_Type() {
duke@1 447 // create input type (domain)
duke@1 448 const Type **fields = TypeTuple::fields(1);
duke@1 449 fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; // Klass to be allocated
duke@1 450 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+1, fields);
duke@1 451
duke@1 452 // create result type (range)
duke@1 453 fields = TypeTuple::fields(1);
duke@1 454 fields[TypeFunc::Parms+0] = TypeRawPtr::NOTNULL; // Returned oop
duke@1 455
duke@1 456 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+1, fields);
duke@1 457
duke@1 458 return TypeFunc::make(domain, range);
duke@1 459 }
duke@1 460
duke@1 461
duke@1 462 const TypeFunc *OptoRuntime::athrow_Type() {
duke@1 463 // create input type (domain)
duke@1 464 const Type **fields = TypeTuple::fields(1);
duke@1 465 fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; // Klass to be allocated
duke@1 466 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+1, fields);
duke@1 467
duke@1 468 // create result type (range)
duke@1 469 fields = TypeTuple::fields(0);
duke@1 470
duke@1 471 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0, fields);
duke@1 472
duke@1 473 return TypeFunc::make(domain, range);
duke@1 474 }
duke@1 475
duke@1 476
duke@1 477 const TypeFunc *OptoRuntime::new_array_Type() {
duke@1 478 // create input type (domain)
duke@1 479 const Type **fields = TypeTuple::fields(2);
duke@1 480 fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; // element klass
duke@1 481 fields[TypeFunc::Parms+1] = TypeInt::INT; // array size
duke@1 482 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+2, fields);
duke@1 483
duke@1 484 // create result type (range)
duke@1 485 fields = TypeTuple::fields(1);
duke@1 486 fields[TypeFunc::Parms+0] = TypeRawPtr::NOTNULL; // Returned oop
duke@1 487
duke@1 488 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+1, fields);
duke@1 489
duke@1 490 return TypeFunc::make(domain, range);
duke@1 491 }
duke@1 492
duke@1 493 const TypeFunc *OptoRuntime::multianewarray_Type(int ndim) {
duke@1 494 // create input type (domain)
duke@1 495 const int nargs = ndim + 1;
duke@1 496 const Type **fields = TypeTuple::fields(nargs);
duke@1 497 fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; // element klass
duke@1 498 for( int i = 1; i < nargs; i++ )
duke@1 499 fields[TypeFunc::Parms + i] = TypeInt::INT; // array size
duke@1 500 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+nargs, fields);
duke@1 501
duke@1 502 // create result type (range)
duke@1 503 fields = TypeTuple::fields(1);
duke@1 504 fields[TypeFunc::Parms+0] = TypeRawPtr::NOTNULL; // Returned oop
duke@1 505 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+1, fields);
duke@1 506
duke@1 507 return TypeFunc::make(domain, range);
duke@1 508 }
duke@1 509
duke@1 510 const TypeFunc *OptoRuntime::multianewarray2_Type() {
duke@1 511 return multianewarray_Type(2);
duke@1 512 }
duke@1 513
duke@1 514 const TypeFunc *OptoRuntime::multianewarray3_Type() {
duke@1 515 return multianewarray_Type(3);
duke@1 516 }
duke@1 517
duke@1 518 const TypeFunc *OptoRuntime::multianewarray4_Type() {
duke@1 519 return multianewarray_Type(4);
duke@1 520 }
duke@1 521
duke@1 522 const TypeFunc *OptoRuntime::multianewarray5_Type() {
duke@1 523 return multianewarray_Type(5);
duke@1 524 }
duke@1 525
iveresov@10028 526 const TypeFunc *OptoRuntime::multianewarrayN_Type() {
iveresov@10028 527 // create input type (domain)
iveresov@10028 528 const Type **fields = TypeTuple::fields(2);
iveresov@10028 529 fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; // element klass
iveresov@10028 530 fields[TypeFunc::Parms+1] = TypeInstPtr::NOTNULL; // array of dim sizes
iveresov@10028 531 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+2, fields);
iveresov@10028 532
iveresov@10028 533 // create result type (range)
iveresov@10028 534 fields = TypeTuple::fields(1);
iveresov@10028 535 fields[TypeFunc::Parms+0] = TypeRawPtr::NOTNULL; // Returned oop
iveresov@10028 536 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+1, fields);
iveresov@10028 537
iveresov@10028 538 return TypeFunc::make(domain, range);
iveresov@10028 539 }
iveresov@10028 540
duke@1 541 const TypeFunc *OptoRuntime::uncommon_trap_Type() {
duke@1 542 // create input type (domain)
duke@1 543 const Type **fields = TypeTuple::fields(1);
jwilhelm@22551 544 fields[TypeFunc::Parms+0] = TypeInt::INT; // trap_reason (deopt reason and action)
duke@1 545 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+1, fields);
duke@1 546
duke@1 547 // create result type (range)
duke@1 548 fields = TypeTuple::fields(0);
duke@1 549 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0, fields);
duke@1 550
duke@1 551 return TypeFunc::make(domain, range);
duke@1 552 }
duke@1 553
duke@1 554 //-----------------------------------------------------------------------------
duke@1 555 // Monitor Handling
duke@1 556 const TypeFunc *OptoRuntime::complete_monitor_enter_Type() {
duke@1 557 // create input type (domain)
duke@1 558 const Type **fields = TypeTuple::fields(2);
duke@1 559 fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; // Object to be Locked
duke@1 560 fields[TypeFunc::Parms+1] = TypeRawPtr::BOTTOM; // Address of stack location for lock
duke@1 561 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+2,fields);
duke@1 562
duke@1 563 // create result type (range)
duke@1 564 fields = TypeTuple::fields(0);
duke@1 565
duke@1 566 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0,fields);
duke@1 567
duke@1 568 return TypeFunc::make(domain,range);
duke@1 569 }
duke@1 570
duke@1 571
duke@1 572 //-----------------------------------------------------------------------------
duke@1 573 const TypeFunc *OptoRuntime::complete_monitor_exit_Type() {
duke@1 574 // create input type (domain)
dcubed@30244 575 const Type **fields = TypeTuple::fields(3);
duke@1 576 fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; // Object to be Locked
dcubed@30244 577 fields[TypeFunc::Parms+1] = TypeRawPtr::BOTTOM; // Address of stack location for lock - BasicLock
dcubed@30244 578 fields[TypeFunc::Parms+2] = TypeRawPtr::BOTTOM; // Thread pointer (Self)
dcubed@31856 579 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+3, fields);
duke@1 580
duke@1 581 // create result type (range)
duke@1 582 fields = TypeTuple::fields(0);
duke@1 583
dcubed@31856 584 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0, fields);
duke@1 585
dcubed@31856 586 return TypeFunc::make(domain, range);
dcubed@31856 587 }
dcubed@31856 588
dcubed@31856 589 const TypeFunc *OptoRuntime::monitor_notify_Type() {
dcubed@31856 590 // create input type (domain)
dcubed@31856 591 const Type **fields = TypeTuple::fields(1);
dcubed@31856 592 fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; // Object to be Locked
dcubed@31856 593 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+1, fields);
dcubed@31856 594
dcubed@31856 595 // create result type (range)
dcubed@31856 596 fields = TypeTuple::fields(0);
dcubed@31856 597 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0, fields);
dcubed@31856 598 return TypeFunc::make(domain, range);
duke@1 599 }
duke@1 600
duke@1 601 const TypeFunc* OptoRuntime::flush_windows_Type() {
duke@1 602 // create input type (domain)
duke@1 603 const Type** fields = TypeTuple::fields(1);
duke@1 604 fields[TypeFunc::Parms+0] = NULL; // void
duke@1 605 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms, fields);
duke@1 606
duke@1 607 // create result type
duke@1 608 fields = TypeTuple::fields(1);
duke@1 609 fields[TypeFunc::Parms+0] = NULL; // void
duke@1 610 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms, fields);
duke@1 611
duke@1 612 return TypeFunc::make(domain, range);
duke@1 613 }
duke@1 614
duke@1 615 const TypeFunc* OptoRuntime::l2f_Type() {
duke@1 616 // create input type (domain)
duke@1 617 const Type **fields = TypeTuple::fields(2);
duke@1 618 fields[TypeFunc::Parms+0] = TypeLong::LONG;
duke@1 619 fields[TypeFunc::Parms+1] = Type::HALF;
duke@1 620 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+2, fields);
duke@1 621
duke@1 622 // create result type (range)
duke@1 623 fields = TypeTuple::fields(1);
duke@1 624 fields[TypeFunc::Parms+0] = Type::FLOAT;
duke@1 625 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+1, fields);
duke@1 626
duke@1 627 return TypeFunc::make(domain, range);
duke@1 628 }
duke@1 629
duke@1 630 const TypeFunc* OptoRuntime::modf_Type() {
duke@1 631 const Type **fields = TypeTuple::fields(2);
duke@1 632 fields[TypeFunc::Parms+0] = Type::FLOAT;
duke@1 633 fields[TypeFunc::Parms+1] = Type::FLOAT;
duke@1 634 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+2, fields);
duke@1 635
duke@1 636 // create result type (range)
duke@1 637 fields = TypeTuple::fields(1);
duke@1 638 fields[TypeFunc::Parms+0] = Type::FLOAT;
duke@1 639
duke@1 640 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+1, fields);
duke@1 641
duke@1 642 return TypeFunc::make(domain, range);
duke@1 643 }
duke@1 644
duke@1 645 const TypeFunc *OptoRuntime::Math_D_D_Type() {
duke@1 646 // create input type (domain)
duke@1 647 const Type **fields = TypeTuple::fields(2);
coleenp@8076 648 // Symbol* name of class to be loaded
duke@1 649 fields[TypeFunc::Parms+0] = Type::DOUBLE;
duke@1 650 fields[TypeFunc::Parms+1] = Type::HALF;
duke@1 651 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+2, fields);
duke@1 652
duke@1 653 // create result type (range)
duke@1 654 fields = TypeTuple::fields(2);
duke@1 655 fields[TypeFunc::Parms+0] = Type::DOUBLE;
duke@1 656 fields[TypeFunc::Parms+1] = Type::HALF;
duke@1 657 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+2, fields);
duke@1 658
duke@1 659 return TypeFunc::make(domain, range);
duke@1 660 }
duke@1 661
duke@1 662 const TypeFunc* OptoRuntime::Math_DD_D_Type() {
duke@1 663 const Type **fields = TypeTuple::fields(4);
duke@1 664 fields[TypeFunc::Parms+0] = Type::DOUBLE;
duke@1 665 fields[TypeFunc::Parms+1] = Type::HALF;
duke@1 666 fields[TypeFunc::Parms+2] = Type::DOUBLE;
duke@1 667 fields[TypeFunc::Parms+3] = Type::HALF;
duke@1 668 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+4, fields);
duke@1 669
duke@1 670 // create result type (range)
duke@1 671 fields = TypeTuple::fields(2);
duke@1 672 fields[TypeFunc::Parms+0] = Type::DOUBLE;
duke@1 673 fields[TypeFunc::Parms+1] = Type::HALF;
duke@1 674 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+2, fields);
duke@1 675
duke@1 676 return TypeFunc::make(domain, range);
duke@1 677 }
duke@1 678
rbackman@12377 679 //-------------- currentTimeMillis, currentTimeNanos, etc
duke@1 680
rbackman@12377 681 const TypeFunc* OptoRuntime::void_long_Type() {
duke@1 682 // create input type (domain)
duke@1 683 const Type **fields = TypeTuple::fields(0);
duke@1 684 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+0, fields);
duke@1 685
duke@1 686 // create result type (range)
duke@1 687 fields = TypeTuple::fields(2);
duke@1 688 fields[TypeFunc::Parms+0] = TypeLong::LONG;
duke@1 689 fields[TypeFunc::Parms+1] = Type::HALF;
duke@1 690 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+2, fields);
duke@1 691
duke@1 692 return TypeFunc::make(domain, range);
duke@1 693 }
duke@1 694
duke@1 695 // arraycopy stub variations:
duke@1 696 enum ArrayCopyType {
duke@1 697 ac_fast, // void(ptr, ptr, size_t)
duke@1 698 ac_checkcast, // int(ptr, ptr, size_t, size_t, ptr)
duke@1 699 ac_slow, // void(ptr, int, ptr, int, int)
duke@1 700 ac_generic // int(ptr, int, ptr, int, int)
duke@1 701 };
duke@1 702
duke@1 703 static const TypeFunc* make_arraycopy_Type(ArrayCopyType act) {
duke@1 704 // create input type (domain)
duke@1 705 int num_args = (act == ac_fast ? 3 : 5);
duke@1 706 int num_size_args = (act == ac_fast ? 1 : act == ac_checkcast ? 2 : 0);
duke@1 707 int argcnt = num_args;
duke@1 708 LP64_ONLY(argcnt += num_size_args); // halfwords for lengths
duke@1 709 const Type** fields = TypeTuple::fields(argcnt);
duke@1 710 int argp = TypeFunc::Parms;
duke@1 711 fields[argp++] = TypePtr::NOTNULL; // src
duke@1 712 if (num_size_args == 0) {
duke@1 713 fields[argp++] = TypeInt::INT; // src_pos
duke@1 714 }
duke@1 715 fields[argp++] = TypePtr::NOTNULL; // dest
duke@1 716 if (num_size_args == 0) {
duke@1 717 fields[argp++] = TypeInt::INT; // dest_pos
duke@1 718 fields[argp++] = TypeInt::INT; // length
duke@1 719 }
duke@1 720 while (num_size_args-- > 0) {
duke@1 721 fields[argp++] = TypeX_X; // size in whatevers (size_t)
duke@1 722 LP64_ONLY(fields[argp++] = Type::HALF); // other half of long length
duke@1 723 }
duke@1 724 if (act == ac_checkcast) {
duke@1 725 fields[argp++] = TypePtr::NOTNULL; // super_klass
duke@1 726 }
duke@1 727 assert(argp == TypeFunc::Parms+argcnt, "correct decoding of act");
duke@1 728 const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms+argcnt, fields);
duke@1 729
duke@1 730 // create result type if needed
duke@1 731 int retcnt = (act == ac_checkcast || act == ac_generic ? 1 : 0);
duke@1 732 fields = TypeTuple::fields(1);
duke@1 733 if (retcnt == 0)
duke@1 734 fields[TypeFunc::Parms+0] = NULL; // void
duke@1 735 else
duke@1 736 fields[TypeFunc::Parms+0] = TypeInt::INT; // status result, if needed
duke@1 737 const TypeTuple* range = TypeTuple::make(TypeFunc::Parms+retcnt, fields);
duke@1 738 return TypeFunc::make(domain, range);
duke@1 739 }
duke@1 740
duke@1 741 const TypeFunc* OptoRuntime::fast_arraycopy_Type() {
duke@1 742 // This signature is simple: Two base pointers and a size_t.
duke@1 743 return make_arraycopy_Type(ac_fast);
duke@1 744 }
duke@1 745
duke@1 746 const TypeFunc* OptoRuntime::checkcast_arraycopy_Type() {
duke@1 747 // An extension of fast_arraycopy_Type which adds type checking.
duke@1 748 return make_arraycopy_Type(ac_checkcast);
duke@1 749 }
duke@1 750
duke@1 751 const TypeFunc* OptoRuntime::slow_arraycopy_Type() {
duke@1 752 // This signature is exactly the same as System.arraycopy.
duke@1 753 // There are no intptr_t (int/long) arguments.
duke@1 754 return make_arraycopy_Type(ac_slow);
duke@1 755 }
duke@1 756
duke@1 757 const TypeFunc* OptoRuntime::generic_arraycopy_Type() {
duke@1 758 // This signature is like System.arraycopy, except that it returns status.
duke@1 759 return make_arraycopy_Type(ac_generic);
duke@1 760 }
duke@1 761
duke@1 762
never@6433 763 const TypeFunc* OptoRuntime::array_fill_Type() {
goetz@22834 764 const Type** fields;
goetz@22834 765 int argp = TypeFunc::Parms;
never@6770 766 // create input type (domain): pointer, int, size_t
goetz@31590 767 fields = TypeTuple::fields(3 LP64_ONLY( + 1));
goetz@31590 768 fields[argp++] = TypePtr::NOTNULL;
goetz@31590 769 fields[argp++] = TypeInt::INT;
never@6770 770 fields[argp++] = TypeX_X; // size in whatevers (size_t)
never@6770 771 LP64_ONLY(fields[argp++] = Type::HALF); // other half of long length
never@6770 772 const TypeTuple *domain = TypeTuple::make(argp, fields);
never@6433 773
never@6433 774 // create result type
never@6433 775 fields = TypeTuple::fields(1);
never@6433 776 fields[TypeFunc::Parms+0] = NULL; // void
never@6433 777 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms, fields);
never@6433 778
never@6433 779 return TypeFunc::make(domain, range);
never@6433 780 }
never@6433 781
kvn@14132 782 // for aescrypt encrypt/decrypt operations, just three pointers returning void (length is constant)
kvn@14132 783 const TypeFunc* OptoRuntime::aescrypt_block_Type() {
kvn@14132 784 // create input type (domain)
kvn@14132 785 int num_args = 3;
kvn@22505 786 if (Matcher::pass_original_key_for_aes()) {
kvn@22505 787 num_args = 4;
kvn@22505 788 }
kvn@14132 789 int argcnt = num_args;
kvn@14132 790 const Type** fields = TypeTuple::fields(argcnt);
kvn@14132 791 int argp = TypeFunc::Parms;
kvn@14132 792 fields[argp++] = TypePtr::NOTNULL; // src
kvn@14132 793 fields[argp++] = TypePtr::NOTNULL; // dest
kvn@14132 794 fields[argp++] = TypePtr::NOTNULL; // k array
kvn@22505 795 if (Matcher::pass_original_key_for_aes()) {
kvn@22505 796 fields[argp++] = TypePtr::NOTNULL; // original k array
kvn@22505 797 }
kvn@14132 798 assert(argp == TypeFunc::Parms+argcnt, "correct decoding");
kvn@14132 799 const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms+argcnt, fields);
kvn@14132 800
kvn@14132 801 // no result type needed
kvn@14132 802 fields = TypeTuple::fields(1);
kvn@14132 803 fields[TypeFunc::Parms+0] = NULL; // void
kvn@14132 804 const TypeTuple* range = TypeTuple::make(TypeFunc::Parms, fields);
kvn@14132 805 return TypeFunc::make(domain, range);
kvn@14132 806 }
kvn@14132 807
drchase@18507 808 /**
drchase@18507 809 * int updateBytesCRC32(int crc, byte* b, int len)
drchase@18507 810 */
drchase@18507 811 const TypeFunc* OptoRuntime::updateBytesCRC32_Type() {
drchase@18507 812 // create input type (domain)
drchase@18507 813 int num_args = 3;
drchase@18507 814 int argcnt = num_args;
drchase@18507 815 const Type** fields = TypeTuple::fields(argcnt);
drchase@18507 816 int argp = TypeFunc::Parms;
drchase@18507 817 fields[argp++] = TypeInt::INT; // crc
drchase@18507 818 fields[argp++] = TypePtr::NOTNULL; // src
drchase@18507 819 fields[argp++] = TypeInt::INT; // len
drchase@18507 820 assert(argp == TypeFunc::Parms+argcnt, "correct decoding");
drchase@18507 821 const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms+argcnt, fields);
drchase@18507 822
drchase@18507 823 // result type needed
drchase@18507 824 fields = TypeTuple::fields(1);
drchase@18507 825 fields[TypeFunc::Parms+0] = TypeInt::INT; // crc result
drchase@18507 826 const TypeTuple* range = TypeTuple::make(TypeFunc::Parms+1, fields);
drchase@18507 827 return TypeFunc::make(domain, range);
drchase@18507 828 }
drchase@18507 829
kvn@31515 830 /**
kvn@31515 831 * int updateBytesCRC32C(int crc, byte* buf, int len, int* table)
kvn@31515 832 */
kvn@31515 833 const TypeFunc* OptoRuntime::updateBytesCRC32C_Type() {
kvn@31515 834 // create input type (domain)
kvn@31515 835 int num_args = 4;
kvn@31515 836 int argcnt = num_args;
kvn@31515 837 const Type** fields = TypeTuple::fields(argcnt);
kvn@31515 838 int argp = TypeFunc::Parms;
kvn@31515 839 fields[argp++] = TypeInt::INT; // crc
kvn@31515 840 fields[argp++] = TypePtr::NOTNULL; // buf
kvn@31515 841 fields[argp++] = TypeInt::INT; // len
kvn@31515 842 fields[argp++] = TypePtr::NOTNULL; // table
kvn@31515 843 assert(argp == TypeFunc::Parms+argcnt, "correct decoding");
kvn@31515 844 const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms+argcnt, fields);
kvn@31515 845
kvn@31515 846 // result type needed
kvn@31515 847 fields = TypeTuple::fields(1);
kvn@31515 848 fields[TypeFunc::Parms+0] = TypeInt::INT; // crc result
kvn@31515 849 const TypeTuple* range = TypeTuple::make(TypeFunc::Parms+1, fields);
kvn@31515 850 return TypeFunc::make(domain, range);
kvn@31515 851 }
kvn@31515 852
kvn@32581 853 /**
kvn@32581 854 * int updateBytesAdler32(int adler, bytes* b, int off, int len)
kvn@32581 855 */
kvn@32581 856 const TypeFunc* OptoRuntime::updateBytesAdler32_Type() {
kvn@32581 857 // create input type (domain)
kvn@32581 858 int num_args = 3;
kvn@32581 859 int argcnt = num_args;
kvn@32581 860 const Type** fields = TypeTuple::fields(argcnt);
kvn@32581 861 int argp = TypeFunc::Parms;
kvn@32581 862 fields[argp++] = TypeInt::INT; // crc
kvn@32581 863 fields[argp++] = TypePtr::NOTNULL; // src + offset
kvn@32581 864 fields[argp++] = TypeInt::INT; // len
kvn@32581 865 assert(argp == TypeFunc::Parms+argcnt, "correct decoding");
kvn@32581 866 const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms+argcnt, fields);
kvn@32581 867
kvn@32581 868 // result type needed
kvn@32581 869 fields = TypeTuple::fields(1);
kvn@32581 870 fields[TypeFunc::Parms+0] = TypeInt::INT; // crc result
kvn@32581 871 const TypeTuple* range = TypeTuple::make(TypeFunc::Parms+1, fields);
kvn@32581 872 return TypeFunc::make(domain, range);
kvn@32581 873 }
kvn@32581 874
kvn@24328 875 // for cipherBlockChaining calls of aescrypt encrypt/decrypt, four pointers and a length, returning int
kvn@14132 876 const TypeFunc* OptoRuntime::cipherBlockChaining_aescrypt_Type() {
kvn@14132 877 // create input type (domain)
kvn@14132 878 int num_args = 5;
kvn@22505 879 if (Matcher::pass_original_key_for_aes()) {
kvn@22505 880 num_args = 6;
kvn@22505 881 }
kvn@14132 882 int argcnt = num_args;
kvn@14132 883 const Type** fields = TypeTuple::fields(argcnt);
kvn@14132 884 int argp = TypeFunc::Parms;
kvn@14132 885 fields[argp++] = TypePtr::NOTNULL; // src
kvn@14132 886 fields[argp++] = TypePtr::NOTNULL; // dest
kvn@14132 887 fields[argp++] = TypePtr::NOTNULL; // k array
kvn@14132 888 fields[argp++] = TypePtr::NOTNULL; // r array
kvn@14132 889 fields[argp++] = TypeInt::INT; // src len
kvn@22505 890 if (Matcher::pass_original_key_for_aes()) {
kvn@22505 891 fields[argp++] = TypePtr::NOTNULL; // original k array
kvn@22505 892 }
kvn@14132 893 assert(argp == TypeFunc::Parms+argcnt, "correct decoding");
kvn@14132 894 const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms+argcnt, fields);
kvn@14132 895
kvn@22505 896 // returning cipher len (int)
kvn@14132 897 fields = TypeTuple::fields(1);
kvn@22505 898 fields[TypeFunc::Parms+0] = TypeInt::INT;
kvn@22505 899 const TypeTuple* range = TypeTuple::make(TypeFunc::Parms+1, fields);
kvn@14132 900 return TypeFunc::make(domain, range);
kvn@14132 901 }
kvn@14132 902
kvn@35154 903 //for counterMode calls of aescrypt encrypt/decrypt, four pointers and a length, returning int
kvn@35154 904 const TypeFunc* OptoRuntime::counterMode_aescrypt_Type() {
kvn@35154 905 // create input type (domain)
kvn@35154 906 int num_args = 7;
kvn@35154 907 if (Matcher::pass_original_key_for_aes()) {
kvn@35154 908 num_args = 8;
kvn@35154 909 }
kvn@35154 910 int argcnt = num_args;
kvn@35154 911 const Type** fields = TypeTuple::fields(argcnt);
kvn@35154 912 int argp = TypeFunc::Parms;
kvn@35154 913 fields[argp++] = TypePtr::NOTNULL; // src
kvn@35154 914 fields[argp++] = TypePtr::NOTNULL; // dest
kvn@35154 915 fields[argp++] = TypePtr::NOTNULL; // k array
kvn@35154 916 fields[argp++] = TypePtr::NOTNULL; // counter array
kvn@35154 917 fields[argp++] = TypeInt::INT; // src len
kvn@35154 918 fields[argp++] = TypePtr::NOTNULL; // saved_encCounter
kvn@35154 919 fields[argp++] = TypePtr::NOTNULL; // saved used addr
kvn@35154 920 if (Matcher::pass_original_key_for_aes()) {
kvn@35154 921 fields[argp++] = TypePtr::NOTNULL; // original k array
kvn@35154 922 }
kvn@35154 923 assert(argp == TypeFunc::Parms + argcnt, "correct decoding");
kvn@35154 924 const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms + argcnt, fields);
kvn@35154 925 // returning cipher len (int)
kvn@35154 926 fields = TypeTuple::fields(1);
kvn@35154 927 fields[TypeFunc::Parms + 0] = TypeInt::INT;
kvn@35154 928 const TypeTuple* range = TypeTuple::make(TypeFunc::Parms + 1, fields);
kvn@35154 929 return TypeFunc::make(domain, range);
kvn@35154 930 }
kvn@35154 931
kvn@24953 932 /*
kvn@24953 933 * void implCompress(byte[] buf, int ofs)
kvn@24953 934 */
kvn@24953 935 const TypeFunc* OptoRuntime::sha_implCompress_Type() {
kvn@24953 936 // create input type (domain)
kvn@24953 937 int num_args = 2;
kvn@24953 938 int argcnt = num_args;
kvn@24953 939 const Type** fields = TypeTuple::fields(argcnt);
kvn@24953 940 int argp = TypeFunc::Parms;
kvn@24953 941 fields[argp++] = TypePtr::NOTNULL; // buf
kvn@24953 942 fields[argp++] = TypePtr::NOTNULL; // state
kvn@24953 943 assert(argp == TypeFunc::Parms+argcnt, "correct decoding");
kvn@24953 944 const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms+argcnt, fields);
kvn@24953 945
kvn@24953 946 // no result type needed
kvn@24953 947 fields = TypeTuple::fields(1);
kvn@24953 948 fields[TypeFunc::Parms+0] = NULL; // void
kvn@24953 949 const TypeTuple* range = TypeTuple::make(TypeFunc::Parms, fields);
kvn@24953 950 return TypeFunc::make(domain, range);
kvn@24953 951 }
kvn@24953 952
kvn@24953 953 /*
kvn@24953 954 * int implCompressMultiBlock(byte[] b, int ofs, int limit)
kvn@24953 955 */
kvn@24953 956 const TypeFunc* OptoRuntime::digestBase_implCompressMB_Type() {
kvn@24953 957 // create input type (domain)
kvn@24953 958 int num_args = 4;
kvn@24953 959 int argcnt = num_args;
kvn@24953 960 const Type** fields = TypeTuple::fields(argcnt);
kvn@24953 961 int argp = TypeFunc::Parms;
kvn@24953 962 fields[argp++] = TypePtr::NOTNULL; // buf
kvn@24953 963 fields[argp++] = TypePtr::NOTNULL; // state
kvn@24953 964 fields[argp++] = TypeInt::INT; // ofs
kvn@24953 965 fields[argp++] = TypeInt::INT; // limit
kvn@24953 966 assert(argp == TypeFunc::Parms+argcnt, "correct decoding");
kvn@24953 967 const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms+argcnt, fields);
kvn@24953 968
kvn@24953 969 // returning ofs (int)
kvn@24953 970 fields = TypeTuple::fields(1);
kvn@24953 971 fields[TypeFunc::Parms+0] = TypeInt::INT; // ofs
kvn@24953 972 const TypeTuple* range = TypeTuple::make(TypeFunc::Parms+1, fields);
kvn@24953 973 return TypeFunc::make(domain, range);
kvn@24953 974 }
kvn@24953 975
kvn@26434 976 const TypeFunc* OptoRuntime::multiplyToLen_Type() {
kvn@26434 977 // create input type (domain)
kvn@26434 978 int num_args = 6;
kvn@26434 979 int argcnt = num_args;
kvn@26434 980 const Type** fields = TypeTuple::fields(argcnt);
kvn@26434 981 int argp = TypeFunc::Parms;
kvn@26434 982 fields[argp++] = TypePtr::NOTNULL; // x
kvn@26434 983 fields[argp++] = TypeInt::INT; // xlen
kvn@26434 984 fields[argp++] = TypePtr::NOTNULL; // y
kvn@26434 985 fields[argp++] = TypeInt::INT; // ylen
kvn@26434 986 fields[argp++] = TypePtr::NOTNULL; // z
kvn@26434 987 fields[argp++] = TypeInt::INT; // zlen
kvn@26434 988 assert(argp == TypeFunc::Parms+argcnt, "correct decoding");
kvn@26434 989 const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms+argcnt, fields);
kvn@26434 990
kvn@26434 991 // no result type needed
kvn@26434 992 fields = TypeTuple::fields(1);
kvn@26434 993 fields[TypeFunc::Parms+0] = NULL;
kvn@26434 994 const TypeTuple* range = TypeTuple::make(TypeFunc::Parms, fields);
kvn@26434 995 return TypeFunc::make(domain, range);
kvn@26434 996 }
kvn@26434 997
kvn@31129 998 const TypeFunc* OptoRuntime::squareToLen_Type() {
kvn@31129 999 // create input type (domain)
kvn@31129 1000 int num_args = 4;
kvn@31129 1001 int argcnt = num_args;
kvn@31129 1002 const Type** fields = TypeTuple::fields(argcnt);
kvn@31129 1003 int argp = TypeFunc::Parms;
kvn@31129 1004 fields[argp++] = TypePtr::NOTNULL; // x
kvn@31129 1005 fields[argp++] = TypeInt::INT; // len
kvn@31129 1006 fields[argp++] = TypePtr::NOTNULL; // z
kvn@31129 1007 fields[argp++] = TypeInt::INT; // zlen
kvn@31129 1008 assert(argp == TypeFunc::Parms+argcnt, "correct decoding");
kvn@31129 1009 const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms+argcnt, fields);
kvn@31129 1010
kvn@31129 1011 // no result type needed
kvn@31129 1012 fields = TypeTuple::fields(1);
kvn@31129 1013 fields[TypeFunc::Parms+0] = NULL;
kvn@31129 1014 const TypeTuple* range = TypeTuple::make(TypeFunc::Parms, fields);
kvn@31129 1015 return TypeFunc::make(domain, range);
kvn@31129 1016 }
kvn@31129 1017
kvn@31129 1018 // for mulAdd calls, 2 pointers and 3 ints, returning int
kvn@31129 1019 const TypeFunc* OptoRuntime::mulAdd_Type() {
kvn@31129 1020 // create input type (domain)
kvn@31129 1021 int num_args = 5;
kvn@31129 1022 int argcnt = num_args;
kvn@31129 1023 const Type** fields = TypeTuple::fields(argcnt);
kvn@31129 1024 int argp = TypeFunc::Parms;
kvn@31129 1025 fields[argp++] = TypePtr::NOTNULL; // out
kvn@31129 1026 fields[argp++] = TypePtr::NOTNULL; // in
kvn@31129 1027 fields[argp++] = TypeInt::INT; // offset
kvn@31129 1028 fields[argp++] = TypeInt::INT; // len
kvn@31129 1029 fields[argp++] = TypeInt::INT; // k
kvn@31129 1030 assert(argp == TypeFunc::Parms+argcnt, "correct decoding");
kvn@31129 1031 const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms+argcnt, fields);
kvn@31129 1032
kvn@31129 1033 // returning carry (int)
kvn@31129 1034 fields = TypeTuple::fields(1);
kvn@31129 1035 fields[TypeFunc::Parms+0] = TypeInt::INT;
kvn@31129 1036 const TypeTuple* range = TypeTuple::make(TypeFunc::Parms+1, fields);
kvn@31129 1037 return TypeFunc::make(domain, range);
kvn@31129 1038 }
kvn@31129 1039
aph@31583 1040 const TypeFunc* OptoRuntime::montgomeryMultiply_Type() {
aph@31583 1041 // create input type (domain)
aph@31583 1042 int num_args = 7;
aph@31583 1043 int argcnt = num_args;
aph@31583 1044 const Type** fields = TypeTuple::fields(argcnt);
aph@31583 1045 int argp = TypeFunc::Parms;
aph@31583 1046 fields[argp++] = TypePtr::NOTNULL; // a
aph@31583 1047 fields[argp++] = TypePtr::NOTNULL; // b
aph@31583 1048 fields[argp++] = TypePtr::NOTNULL; // n
aph@31583 1049 fields[argp++] = TypeInt::INT; // len
aph@31583 1050 fields[argp++] = TypeLong::LONG; // inv
aph@31583 1051 fields[argp++] = Type::HALF;
aph@31583 1052 fields[argp++] = TypePtr::NOTNULL; // result
aph@31583 1053 assert(argp == TypeFunc::Parms+argcnt, "correct decoding");
aph@31583 1054 const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms+argcnt, fields);
aph@31583 1055
aph@31583 1056 // result type needed
aph@31583 1057 fields = TypeTuple::fields(1);
aph@31583 1058 fields[TypeFunc::Parms+0] = TypePtr::NOTNULL;
aph@31583 1059
aph@31583 1060 const TypeTuple* range = TypeTuple::make(TypeFunc::Parms, fields);
aph@31583 1061 return TypeFunc::make(domain, range);
aph@31583 1062 }
aph@31583 1063
aph@31583 1064 const TypeFunc* OptoRuntime::montgomerySquare_Type() {
aph@31583 1065 // create input type (domain)
aph@31583 1066 int num_args = 6;
aph@31583 1067 int argcnt = num_args;
aph@31583 1068 const Type** fields = TypeTuple::fields(argcnt);
aph@31583 1069 int argp = TypeFunc::Parms;
aph@31583 1070 fields[argp++] = TypePtr::NOTNULL; // a
aph@31583 1071 fields[argp++] = TypePtr::NOTNULL; // n
aph@31583 1072 fields[argp++] = TypeInt::INT; // len
aph@31583 1073 fields[argp++] = TypeLong::LONG; // inv
aph@31583 1074 fields[argp++] = Type::HALF;
aph@31583 1075 fields[argp++] = TypePtr::NOTNULL; // result
aph@31583 1076 assert(argp == TypeFunc::Parms+argcnt, "correct decoding");
aph@31583 1077 const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms+argcnt, fields);
aph@31583 1078
aph@31583 1079 // result type needed
aph@31583 1080 fields = TypeTuple::fields(1);
aph@31583 1081 fields[TypeFunc::Parms+0] = TypePtr::NOTNULL;
aph@31583 1082
aph@31583 1083 const TypeTuple* range = TypeTuple::make(TypeFunc::Parms, fields);
aph@31583 1084 return TypeFunc::make(domain, range);
aph@31583 1085 }
kvn@31129 1086
kvn@35110 1087 const TypeFunc* OptoRuntime::vectorizedMismatch_Type() {
kvn@35110 1088 // create input type (domain)
kvn@35110 1089 int num_args = 4;
kvn@35110 1090 int argcnt = num_args;
kvn@35110 1091 const Type** fields = TypeTuple::fields(argcnt);
kvn@35110 1092 int argp = TypeFunc::Parms;
kvn@35110 1093 fields[argp++] = TypePtr::NOTNULL; // obja
kvn@35110 1094 fields[argp++] = TypePtr::NOTNULL; // objb
kvn@35110 1095 fields[argp++] = TypeInt::INT; // length, number of elements
kvn@35110 1096 fields[argp++] = TypeInt::INT; // log2scale, element size
kvn@35110 1097 assert(argp == TypeFunc::Parms + argcnt, "correct decoding");
kvn@35110 1098 const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms + argcnt, fields);
kvn@35110 1099
kvn@35110 1100 //return mismatch index (int)
kvn@35110 1101 fields = TypeTuple::fields(1);
kvn@35110 1102 fields[TypeFunc::Parms + 0] = TypeInt::INT;
kvn@35110 1103 const TypeTuple* range = TypeTuple::make(TypeFunc::Parms + 1, fields);
kvn@35110 1104 return TypeFunc::make(domain, range);
kvn@35110 1105 }
kvn@35110 1106
ascarpino@31404 1107 // GHASH block processing
ascarpino@31404 1108 const TypeFunc* OptoRuntime::ghash_processBlocks_Type() {
ascarpino@31404 1109 int argcnt = 4;
kvn@26434 1110
ascarpino@31404 1111 const Type** fields = TypeTuple::fields(argcnt);
ascarpino@31404 1112 int argp = TypeFunc::Parms;
ascarpino@31404 1113 fields[argp++] = TypePtr::NOTNULL; // state
ascarpino@31404 1114 fields[argp++] = TypePtr::NOTNULL; // subkeyH
ascarpino@31404 1115 fields[argp++] = TypePtr::NOTNULL; // data
ascarpino@31404 1116 fields[argp++] = TypeInt::INT; // blocks
ascarpino@31404 1117 assert(argp == TypeFunc::Parms+argcnt, "correct decoding");
ascarpino@31404 1118 const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms+argcnt, fields);
ascarpino@31404 1119
ascarpino@31404 1120 // result type needed
ascarpino@31404 1121 fields = TypeTuple::fields(1);
ascarpino@31404 1122 fields[TypeFunc::Parms+0] = NULL; // void
ascarpino@31404 1123 const TypeTuple* range = TypeTuple::make(TypeFunc::Parms, fields);
ascarpino@31404 1124 return TypeFunc::make(domain, range);
ascarpino@31404 1125 }
kvn@50860 1126 // Base64 encode function
kvn@50860 1127 const TypeFunc* OptoRuntime::base64_encodeBlock_Type() {
kvn@50860 1128 int argcnt = 6;
kvn@50860 1129
kvn@50860 1130 const Type** fields = TypeTuple::fields(argcnt);
kvn@50860 1131 int argp = TypeFunc::Parms;
kvn@50860 1132 fields[argp++] = TypePtr::NOTNULL; // src array
kvn@50860 1133 fields[argp++] = TypeInt::INT; // offset
kvn@50860 1134 fields[argp++] = TypeInt::INT; // length
kvn@50860 1135 fields[argp++] = TypePtr::NOTNULL; // dest array
kvn@50860 1136 fields[argp++] = TypeInt::INT; // dp
kvn@50860 1137 fields[argp++] = TypeInt::BOOL; // isURL
kvn@50860 1138 assert(argp == TypeFunc::Parms + argcnt, "correct decoding");
kvn@50860 1139 const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms+argcnt, fields);
kvn@50860 1140
kvn@50860 1141 // result type needed
kvn@50860 1142 fields = TypeTuple::fields(1);
kvn@50860 1143 fields[TypeFunc::Parms + 0] = NULL; // void
kvn@50860 1144 const TypeTuple* range = TypeTuple::make(TypeFunc::Parms, fields);
kvn@50860 1145 return TypeFunc::make(domain, range);
kvn@50860 1146 }
kvn@26434 1147
duke@1 1148 //------------- Interpreter state access for on stack replacement
duke@1 1149 const TypeFunc* OptoRuntime::osr_end_Type() {
duke@1 1150 // create input type (domain)
duke@1 1151 const Type **fields = TypeTuple::fields(1);
duke@1 1152 fields[TypeFunc::Parms+0] = TypeRawPtr::BOTTOM; // OSR temp buf
duke@1 1153 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+1, fields);
duke@1 1154
duke@1 1155 // create result type
duke@1 1156 fields = TypeTuple::fields(1);
duke@1 1157 // fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; // locked oop
duke@1 1158 fields[TypeFunc::Parms+0] = NULL; // void
duke@1 1159 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms, fields);
duke@1 1160 return TypeFunc::make(domain, range);
duke@1 1161 }
duke@1 1162
duke@1 1163 //-------------- methodData update helpers
duke@1 1164
duke@1 1165 const TypeFunc* OptoRuntime::profile_receiver_type_Type() {
duke@1 1166 // create input type (domain)
duke@1 1167 const Type **fields = TypeTuple::fields(2);
duke@1 1168 fields[TypeFunc::Parms+0] = TypeAryPtr::NOTNULL; // methodData pointer
duke@1 1169 fields[TypeFunc::Parms+1] = TypeInstPtr::BOTTOM; // receiver oop
duke@1 1170 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+2, fields);
duke@1 1171
duke@1 1172 // create result type
duke@1 1173 fields = TypeTuple::fields(1);
duke@1 1174 fields[TypeFunc::Parms+0] = NULL; // void
duke@1 1175 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms, fields);
duke@1 1176 return TypeFunc::make(domain,range);
duke@1 1177 }
duke@1 1178
duke@1 1179 JRT_LEAF(void, OptoRuntime::profile_receiver_type_C(DataLayout* data, oopDesc* receiver))
duke@1 1180 if (receiver == NULL) return;
coleenp@13728 1181 Klass* receiver_klass = receiver->klass();
duke@1 1182
duke@1 1183 intptr_t* mdp = ((intptr_t*)(data)) + DataLayout::header_size_in_cells();
duke@1 1184 int empty_row = -1; // free row, if any is encountered
duke@1 1185
duke@1 1186 // ReceiverTypeData* vc = new ReceiverTypeData(mdp);
duke@1 1187 for (uint row = 0; row < ReceiverTypeData::row_limit(); row++) {
duke@1 1188 // if (vc->receiver(row) == receiver_klass)
duke@1 1189 int receiver_off = ReceiverTypeData::receiver_cell_index(row);
duke@1 1190 intptr_t row_recv = *(mdp + receiver_off);
duke@1 1191 if (row_recv == (intptr_t) receiver_klass) {
duke@1 1192 // vc->set_receiver_count(row, vc->receiver_count(row) + DataLayout::counter_increment);
duke@1 1193 int count_off = ReceiverTypeData::receiver_count_cell_index(row);
duke@1 1194 *(mdp + count_off) += DataLayout::counter_increment;
duke@1 1195 return;
duke@1 1196 } else if (row_recv == 0) {
duke@1 1197 // else if (vc->receiver(row) == NULL)
duke@1 1198 empty_row = (int) row;
duke@1 1199 }
duke@1 1200 }
duke@1 1201
duke@1 1202 if (empty_row != -1) {
duke@1 1203 int receiver_off = ReceiverTypeData::receiver_cell_index(empty_row);
duke@1 1204 // vc->set_receiver(empty_row, receiver_klass);
duke@1 1205 *(mdp + receiver_off) = (intptr_t) receiver_klass;
duke@1 1206 // vc->set_receiver_count(empty_row, DataLayout::counter_increment);
duke@1 1207 int count_off = ReceiverTypeData::receiver_count_cell_index(empty_row);
duke@1 1208 *(mdp + count_off) = DataLayout::counter_increment;
kvn@4754 1209 } else {
kvn@4754 1210 // Receiver did not match any saved receiver and there is no empty row for it.
kvn@4892 1211 // Increment total counter to indicate polymorphic case.
zgu@24425 1212 intptr_t* count_p = (intptr_t*)(((uint8_t*)(data)) + in_bytes(CounterData::count_offset()));
kvn@4754 1213 *count_p += DataLayout::counter_increment;
duke@1 1214 }
duke@1 1215 JRT_END
duke@1 1216
duke@1 1217 //-------------------------------------------------------------------------------------
duke@1 1218 // register policy
duke@1 1219
duke@1 1220 bool OptoRuntime::is_callee_saved_register(MachRegisterNumbers reg) {
duke@1 1221 assert(reg >= 0 && reg < _last_Mach_Reg, "must be a machine register");
duke@1 1222 switch (register_save_policy[reg]) {
duke@1 1223 case 'C': return false; //SOC
duke@1 1224 case 'E': return true ; //SOE
duke@1 1225 case 'N': return false; //NS
duke@1 1226 case 'A': return false; //AS
duke@1 1227 }
duke@1 1228 ShouldNotReachHere();
duke@1 1229 return false;
duke@1 1230 }
duke@1 1231
duke@1 1232 //-----------------------------------------------------------------------
duke@1 1233 // Exceptions
duke@1 1234 //
duke@1 1235
rprotacio@35216 1236 static void trace_exception(outputStream* st, oop exception_oop, address exception_pc, const char* msg);
duke@1 1237
duke@1 1238 // The method is an entry that is always called by a C++ method not
duke@1 1239 // directly from compiled code. Compiled code will call the C++ method following.
duke@1 1240 // We can't allow async exception to be installed during exception processing.
duke@1 1241 JRT_ENTRY_NO_ASYNC(address, OptoRuntime::handle_exception_C_helper(JavaThread* thread, nmethod* &nm))
duke@1 1242
duke@1 1243 // Do not confuse exception_oop with pending_exception. The exception_oop
duke@1 1244 // is only used to pass arguments into the method. Not for general
duke@1 1245 // exception handling. DO NOT CHANGE IT to use pending_exception, since
duke@1 1246 // the runtime stubs checks this on exit.
duke@1 1247 assert(thread->exception_oop() != NULL, "exception oop is found");
duke@1 1248 address handler_address = NULL;
duke@1 1249
duke@1 1250 Handle exception(thread, thread->exception_oop());
twisti@20703 1251 address pc = thread->exception_pc();
twisti@20703 1252
twisti@20703 1253 // Clear out the exception oop and pc since looking up an
twisti@20703 1254 // exception handler can cause class loading, which might throw an
twisti@20703 1255 // exception and those fields are expected to be clear during
twisti@20703 1256 // normal bytecode execution.
twisti@20703 1257 thread->clear_exception_oop_and_pc();
duke@1 1258
stuefe@46701 1259 LogTarget(Info, exceptions) lt;
stuefe@46701 1260 if (lt.is_enabled()) {
rprotacio@35216 1261 ResourceMark rm;
stuefe@46701 1262 LogStream ls(lt);
stuefe@46701 1263 trace_exception(&ls, exception(), pc, "");
duke@1 1264 }
twisti@20703 1265
duke@1 1266 // for AbortVMOnException flag
poonam@33208 1267 Exceptions::debug_check_abort(exception);
duke@1 1268
twisti@20703 1269 #ifdef ASSERT
twisti@20703 1270 if (!(exception->is_a(SystemDictionary::Throwable_klass()))) {
twisti@20703 1271 // should throw an exception here
twisti@20703 1272 ShouldNotReachHere();
twisti@20703 1273 }
twisti@20703 1274 #endif
duke@1 1275
duke@1 1276 // new exception handling: this method is entered only from adapters
duke@1 1277 // exceptions from compiled java methods are handled in compiled code
duke@1 1278 // using rethrow node
duke@1 1279
duke@1 1280 nm = CodeCache::find_nmethod(pc);
duke@1 1281 assert(nm != NULL, "No NMethod found");
duke@1 1282 if (nm->is_native_method()) {
twisti@20703 1283 fatal("Native method should not have path to exception handling");
duke@1 1284 } else {
duke@1 1285 // we are switching to old paradigm: search for exception handler in caller_frame
duke@1 1286 // instead in exception handler of caller_frame.sender()
duke@1 1287
dcubed@4761 1288 if (JvmtiExport::can_post_on_exceptions()) {
duke@1 1289 // "Full-speed catching" is not necessary here,
duke@1 1290 // since we're notifying the VM on every catch.
duke@1 1291 // Force deoptimization and the rest of the lookup
duke@1 1292 // will be fine.
kvn@14835 1293 deoptimize_caller_frame(thread);
duke@1 1294 }
duke@1 1295
duke@1 1296 // Check the stack guard pages. If enabled, look for handler in this frame;
duke@1 1297 // otherwise, forcibly unwind the frame.
duke@1 1298 //
duke@1 1299 // 4826555: use default current sp for reguard_stack instead of &nm: it's more accurate.
duke@1 1300 bool force_unwind = !thread->reguard_stack();
duke@1 1301 bool deopting = false;
duke@1 1302 if (nm->is_deopt_pc(pc)) {
duke@1 1303 deopting = true;
duke@1 1304 RegisterMap map(thread, false);
duke@1 1305 frame deoptee = thread->last_frame().sender(&map);
duke@1 1306 assert(deoptee.is_deoptimized_frame(), "must be deopted");
duke@1 1307 // Adjust the pc back to the original throwing pc
duke@1 1308 pc = deoptee.pc();
duke@1 1309 }
duke@1 1310
duke@1 1311 // If we are forcing an unwind because of stack overflow then deopt is
goetz@22807 1312 // irrelevant since we are throwing the frame away anyway.
duke@1 1313
duke@1 1314 if (deopting && !force_unwind) {
duke@1 1315 handler_address = SharedRuntime::deopt_blob()->unpack_with_exception();
duke@1 1316 } else {
duke@1 1317
duke@1 1318 handler_address =
duke@1 1319 force_unwind ? NULL : nm->handler_for_exception_and_pc(exception, pc);
duke@1 1320
duke@1 1321 if (handler_address == NULL) {
thartmann@41057 1322 bool recursive_exception = false;
thartmann@41057 1323 handler_address = SharedRuntime::compute_compiled_exc_handler(nm, pc, exception, force_unwind, true, recursive_exception);
duke@1 1324 assert (handler_address != NULL, "must have compiled handler");
kvn@10731 1325 // Update the exception cache only when the unwind was not forced
kvn@10731 1326 // and there didn't happen another exception during the computation of the
thartmann@41057 1327 // compiled exception handler. Checking for exception oop equality is not
thartmann@41057 1328 // sufficient because some exceptions are pre-allocated and reused.
thartmann@41057 1329 if (!force_unwind && !recursive_exception) {
duke@1 1330 nm->add_handler_for_exception_and_pc(exception,pc,handler_address);
duke@1 1331 }
duke@1 1332 } else {
thartmann@41057 1333 #ifdef ASSERT
thartmann@41057 1334 bool recursive_exception = false;
thartmann@41057 1335 address computed_address = SharedRuntime::compute_compiled_exc_handler(nm, pc, exception, force_unwind, true, recursive_exception);
thartmann@41057 1336 vmassert(recursive_exception || (handler_address == computed_address), "Handler address inconsistency: " PTR_FORMAT " != " PTR_FORMAT,
thartmann@41057 1337 p2i(handler_address), p2i(computed_address));
thartmann@41057 1338 #endif
duke@1 1339 }
duke@1 1340 }
duke@1 1341
duke@1 1342 thread->set_exception_pc(pc);
duke@1 1343 thread->set_exception_handler_pc(handler_address);
twisti@4564 1344
twisti@5046 1345 // Check if the exception PC is a MethodHandle call site.
twisti@5252 1346 thread->set_is_method_handle_return(nm->is_method_handle_return(pc));
duke@1 1347 }
duke@1 1348
duke@1 1349 // Restore correct return pc. Was saved above.
duke@1 1350 thread->set_exception_oop(exception());
duke@1 1351 return handler_address;
duke@1 1352
duke@1 1353 JRT_END
duke@1 1354
duke@1 1355 // We are entering here from exception_blob
duke@1 1356 // If there is a compiled exception handler in this method, we will continue there;
duke@1 1357 // otherwise we will unwind the stack and continue at the caller of top frame method
duke@1 1358 // Note we enter without the usual JRT wrapper. We will call a helper routine that
duke@1 1359 // will do the normal VM entry. We do it this way so that we can see if the nmethod
duke@1 1360 // we looked up the handler for has been deoptimized in the meantime. If it has been
goetz@22807 1361 // we must not use the handler and instead return the deopt blob.
duke@1 1362 address OptoRuntime::handle_exception_C(JavaThread* thread) {
duke@1 1363 //
duke@1 1364 // We are in Java not VM and in debug mode we have a NoHandleMark
duke@1 1365 //
duke@1 1366 #ifndef PRODUCT
duke@1 1367 SharedRuntime::_find_handler_ctr++; // find exception handler
duke@1 1368 #endif
duke@1 1369 debug_only(NoHandleMark __hm;)
duke@1 1370 nmethod* nm = NULL;
duke@1 1371 address handler_address = NULL;
duke@1 1372 {
duke@1 1373 // Enter the VM
duke@1 1374
duke@1 1375 ResetNoHandleMark rnhm;
duke@1 1376 handler_address = handle_exception_C_helper(thread, nm);
duke@1 1377 }
duke@1 1378
duke@1 1379 // Back in java: Use no oops, DON'T safepoint
duke@1 1380
duke@1 1381 // Now check to see if the handler we are returning is in a now
duke@1 1382 // deoptimized frame
duke@1 1383
duke@1 1384 if (nm != NULL) {
duke@1 1385 RegisterMap map(thread, false);
duke@1 1386 frame caller = thread->last_frame().sender(&map);
duke@1 1387 #ifdef ASSERT
duke@1 1388 assert(caller.is_compiled_frame(), "must be");
duke@1 1389 #endif // ASSERT
duke@1 1390 if (caller.is_deoptimized_frame()) {
duke@1 1391 handler_address = SharedRuntime::deopt_blob()->unpack_with_exception();
duke@1 1392 }
duke@1 1393 }
duke@1 1394 return handler_address;
duke@1 1395 }
duke@1 1396
duke@1 1397 //------------------------------rethrow----------------------------------------
duke@1 1398 // We get here after compiled code has executed a 'RethrowNode'. The callee
duke@1 1399 // is either throwing or rethrowing an exception. The callee-save registers
duke@1 1400 // have been restored, synchronized objects have been unlocked and the callee
duke@1 1401 // stack frame has been removed. The return address was passed in.
duke@1 1402 // Exception oop is passed as the 1st argument. This routine is then called
duke@1 1403 // from the stub. On exit, we know where to jump in the caller's code.
duke@1 1404 // After this C code exits, the stub will pop his frame and end in a jump
duke@1 1405 // (instead of a return). We enter the caller's default handler.
duke@1 1406 //
duke@1 1407 // This must be JRT_LEAF:
duke@1 1408 // - caller will not change its state as we cannot block on exit,
duke@1 1409 // therefore raw_exception_handler_for_return_address is all it takes
duke@1 1410 // to handle deoptimized blobs
duke@1 1411 //
duke@1 1412 // However, there needs to be a safepoint check in the middle! So compiled
duke@1 1413 // safepoints are completely watertight.
duke@1 1414 //
david@35492 1415 // Thus, it cannot be a leaf since it contains the NoGCVerifier.
duke@1 1416 //
duke@1 1417 // *THIS IS NOT RECOMMENDED PROGRAMMING STYLE*
duke@1 1418 //
duke@1 1419 address OptoRuntime::rethrow_C(oopDesc* exception, JavaThread* thread, address ret_pc) {
duke@1 1420 #ifndef PRODUCT
duke@1 1421 SharedRuntime::_rethrow_ctr++; // count rethrows
duke@1 1422 #endif
duke@1 1423 assert (exception != NULL, "should have thrown a NULLPointerException");
duke@1 1424 #ifdef ASSERT
never@4571 1425 if (!(exception->is_a(SystemDictionary::Throwable_klass()))) {
duke@1 1426 // should throw an exception here
duke@1 1427 ShouldNotReachHere();
duke@1 1428 }
duke@1 1429 #endif
duke@1 1430
duke@1 1431 thread->set_vm_result(exception);
duke@1 1432 // Frame not compiled (handles deoptimization blob)
twisti@5046 1433 return SharedRuntime::raw_exception_handler_for_return_address(thread, ret_pc);
duke@1 1434 }
duke@1 1435
duke@1 1436
duke@1 1437 const TypeFunc *OptoRuntime::rethrow_Type() {
duke@1 1438 // create input type (domain)
duke@1 1439 const Type **fields = TypeTuple::fields(1);
duke@1 1440 fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; // Exception oop
duke@1 1441 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+1,fields);
duke@1 1442
duke@1 1443 // create result type (range)
duke@1 1444 fields = TypeTuple::fields(1);
duke@1 1445 fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; // Exception oop
duke@1 1446 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+1, fields);
duke@1 1447
duke@1 1448 return TypeFunc::make(domain, range);
duke@1 1449 }
duke@1 1450
duke@1 1451
duke@1 1452 void OptoRuntime::deoptimize_caller_frame(JavaThread *thread, bool doit) {
kvn@14835 1453 // Deoptimize the caller before continuing, as the compiled
kvn@14835 1454 // exception handler table may not be valid.
kvn@14835 1455 if (!StressCompiledExceptionHandlers && doit) {
kvn@14835 1456 deoptimize_caller_frame(thread);
kvn@14835 1457 }
kvn@14835 1458 }
duke@1 1459
kvn@14835 1460 void OptoRuntime::deoptimize_caller_frame(JavaThread *thread) {
kvn@14835 1461 // Called from within the owner thread, so no need for safepoint
kvn@14835 1462 RegisterMap reg_map(thread);
kvn@14835 1463 frame stub_frame = thread->last_frame();
kvn@14835 1464 assert(stub_frame.is_runtime_frame() || exception_blob()->contains(stub_frame.pc()), "sanity check");
kvn@14835 1465 frame caller_frame = stub_frame.sender(&reg_map);
kvn@14835 1466
kvn@14835 1467 // Deoptimize the caller frame.
kvn@14835 1468 Deoptimization::deoptimize_frame(thread, caller_frame.id());
duke@1 1469 }
duke@1 1470
duke@1 1471
kvn@10987 1472 bool OptoRuntime::is_deoptimized_caller_frame(JavaThread *thread) {
kvn@10987 1473 // Called from within the owner thread, so no need for safepoint
kvn@10987 1474 RegisterMap reg_map(thread);
kvn@10987 1475 frame stub_frame = thread->last_frame();
kvn@10987 1476 assert(stub_frame.is_runtime_frame() || exception_blob()->contains(stub_frame.pc()), "sanity check");
kvn@10987 1477 frame caller_frame = stub_frame.sender(&reg_map);
kvn@10987 1478 return caller_frame.is_deoptimized_frame();
kvn@10987 1479 }
kvn@10987 1480
kvn@10987 1481
duke@1 1482 const TypeFunc *OptoRuntime::register_finalizer_Type() {
duke@1 1483 // create input type (domain)
duke@1 1484 const Type **fields = TypeTuple::fields(1);
duke@1 1485 fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; // oop; Receiver
duke@1 1486 // // The JavaThread* is passed to each routine as the last argument
duke@1 1487 // fields[TypeFunc::Parms+1] = TypeRawPtr::NOTNULL; // JavaThread *; Executing thread
duke@1 1488 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+1,fields);
duke@1 1489
duke@1 1490 // create result type (range)
duke@1 1491 fields = TypeTuple::fields(0);
duke@1 1492
duke@1 1493 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0,fields);
duke@1 1494
duke@1 1495 return TypeFunc::make(domain,range);
duke@1 1496 }
duke@1 1497
duke@1 1498
duke@1 1499 //-----------------------------------------------------------------------------
duke@1 1500 // Dtrace support. entry and exit probes have the same signature
duke@1 1501 const TypeFunc *OptoRuntime::dtrace_method_entry_exit_Type() {
duke@1 1502 // create input type (domain)
duke@1 1503 const Type **fields = TypeTuple::fields(2);
duke@1 1504 fields[TypeFunc::Parms+0] = TypeRawPtr::BOTTOM; // Thread-local storage
roland@13742 1505 fields[TypeFunc::Parms+1] = TypeMetadataPtr::BOTTOM; // Method*; Method we are entering
duke@1 1506 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+2,fields);
duke@1 1507
duke@1 1508 // create result type (range)
duke@1 1509 fields = TypeTuple::fields(0);
duke@1 1510
duke@1 1511 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0,fields);
duke@1 1512
duke@1 1513 return TypeFunc::make(domain,range);
duke@1 1514 }
duke@1 1515
duke@1 1516 const TypeFunc *OptoRuntime::dtrace_object_alloc_Type() {
duke@1 1517 // create input type (domain)
duke@1 1518 const Type **fields = TypeTuple::fields(2);
duke@1 1519 fields[TypeFunc::Parms+0] = TypeRawPtr::BOTTOM; // Thread-local storage
duke@1 1520 fields[TypeFunc::Parms+1] = TypeInstPtr::NOTNULL; // oop; newly allocated object
duke@1 1521
duke@1 1522 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+2,fields);
duke@1 1523
duke@1 1524 // create result type (range)
duke@1 1525 fields = TypeTuple::fields(0);
duke@1 1526
duke@1 1527 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0,fields);
duke@1 1528
duke@1 1529 return TypeFunc::make(domain,range);
duke@1 1530 }
duke@1 1531
duke@1 1532
duke@1 1533 JRT_ENTRY_NO_ASYNC(void, OptoRuntime::register_finalizer(oopDesc* obj, JavaThread* thread))
coleenp@46968 1534 assert(oopDesc::is_oop(obj), "must be a valid oop");
coleenp@13728 1535 assert(obj->klass()->has_finalizer(), "shouldn't be here otherwise");
coleenp@13728 1536 InstanceKlass::register_finalizer(instanceOop(obj), CHECK);
duke@1 1537 JRT_END
duke@1 1538
duke@1 1539 //-----------------------------------------------------------------------------
duke@1 1540
duke@1 1541 NamedCounter * volatile OptoRuntime::_named_counters = NULL;
duke@1 1542
duke@1 1543 //
duke@1 1544 // dump the collected NamedCounters.
duke@1 1545 //
duke@1 1546 void OptoRuntime::print_named_counters() {
duke@1 1547 int total_lock_count = 0;
duke@1 1548 int eliminated_lock_count = 0;
duke@1 1549
duke@1 1550 NamedCounter* c = _named_counters;
duke@1 1551 while (c) {
duke@1 1552 if (c->tag() == NamedCounter::LockCounter || c->tag() == NamedCounter::EliminatedLockCounter) {
duke@1 1553 int count = c->count();
duke@1 1554 if (count > 0) {
duke@1 1555 bool eliminated = c->tag() == NamedCounter::EliminatedLockCounter;
duke@1 1556 if (Verbose) {
duke@1 1557 tty->print_cr("%d %s%s", count, c->name(), eliminated ? " (eliminated)" : "");
duke@1 1558 }
duke@1 1559 total_lock_count += count;
duke@1 1560 if (eliminated) {
duke@1 1561 eliminated_lock_count += count;
duke@1 1562 }
duke@1 1563 }
duke@1 1564 } else if (c->tag() == NamedCounter::BiasedLockingCounter) {
duke@1 1565 BiasedLockingCounters* blc = ((BiasedLockingNamedCounter*)c)->counters();
duke@1 1566 if (blc->nonzero()) {
duke@1 1567 tty->print_cr("%s", c->name());
duke@1 1568 blc->print_on(tty);
duke@1 1569 }
kvn@23491 1570 #if INCLUDE_RTM_OPT
kvn@23491 1571 } else if (c->tag() == NamedCounter::RTMLockingCounter) {
kvn@23491 1572 RTMLockingCounters* rlc = ((RTMLockingNamedCounter*)c)->counters();
kvn@23491 1573 if (rlc->nonzero()) {
kvn@23491 1574 tty->print_cr("%s", c->name());
kvn@23491 1575 rlc->print_on(tty);
kvn@23491 1576 }
kvn@23491 1577 #endif
duke@1 1578 }
duke@1 1579 c = c->next();
duke@1 1580 }
duke@1 1581 if (total_lock_count > 0) {
duke@1 1582 tty->print_cr("dynamic locks: %d", total_lock_count);
duke@1 1583 if (eliminated_lock_count) {
duke@1 1584 tty->print_cr("eliminated locks: %d (%d%%)", eliminated_lock_count,
duke@1 1585 (int)(eliminated_lock_count * 100.0 / total_lock_count));
duke@1 1586 }
duke@1 1587 }
duke@1 1588 }
duke@1 1589
duke@1 1590 //
duke@1 1591 // Allocate a new NamedCounter. The JVMState is used to generate the
duke@1 1592 // name which consists of method@line for the inlining tree.
duke@1 1593 //
duke@1 1594
duke@1 1595 NamedCounter* OptoRuntime::new_named_counter(JVMState* youngest_jvms, NamedCounter::CounterTag tag) {
duke@1 1596 int max_depth = youngest_jvms->depth();
duke@1 1597
duke@1 1598 // Visit scopes from youngest to oldest.
duke@1 1599 bool first = true;
duke@1 1600 stringStream st;
duke@1 1601 for (int depth = max_depth; depth >= 1; depth--) {
duke@1 1602 JVMState* jvms = youngest_jvms->of_depth(depth);
duke@1 1603 ciMethod* m = jvms->has_method() ? jvms->method() : NULL;
duke@1 1604 if (!first) {
duke@1 1605 st.print(" ");
duke@1 1606 } else {
duke@1 1607 first = false;
duke@1 1608 }
duke@1 1609 int bci = jvms->bci();
duke@1 1610 if (bci < 0) bci = 0;
goetz@51078 1611 if (m != NULL) {
goetz@51078 1612 st.print("%s.%s", m->holder()->name()->as_utf8(), m->name()->as_utf8());
goetz@51078 1613 } else {
goetz@51078 1614 st.print("no method");
goetz@51078 1615 }
goetz@51078 1616 st.print("@%d", bci);
duke@1 1617 // To print linenumbers instead of bci use: m->line_number_from_bci(bci)
duke@1 1618 }
duke@1 1619 NamedCounter* c;
duke@1 1620 if (tag == NamedCounter::BiasedLockingCounter) {
zgu@25949 1621 c = new BiasedLockingNamedCounter(st.as_string());
kvn@23491 1622 } else if (tag == NamedCounter::RTMLockingCounter) {
zgu@25949 1623 c = new RTMLockingNamedCounter(st.as_string());
duke@1 1624 } else {
zgu@25949 1625 c = new NamedCounter(st.as_string(), tag);
duke@1 1626 }
duke@1 1627
duke@1 1628 // atomically add the new counter to the head of the list. We only
duke@1 1629 // add counters so this is safe.
duke@1 1630 NamedCounter* head;
duke@1 1631 do {
kvn@23491 1632 c->set_next(NULL);
duke@1 1633 head = _named_counters;
duke@1 1634 c->set_next(head);
coleenp@47634 1635 } while (Atomic::cmpxchg(c, &_named_counters, head) != head);
duke@1 1636 return c;
duke@1 1637 }
duke@1 1638
rprotacio@35216 1639 int trace_exception_counter = 0;
rprotacio@35216 1640 static void trace_exception(outputStream* st, oop exception_oop, address exception_pc, const char* msg) {
rprotacio@35216 1641 trace_exception_counter++;
rprotacio@35216 1642 stringStream tempst;
duke@1 1643
rprotacio@35216 1644 tempst.print("%d [Exception (%s): ", trace_exception_counter, msg);
rprotacio@35216 1645 exception_oop->print_value_on(&tempst);
rprotacio@35216 1646 tempst.print(" in ");
duke@1 1647 CodeBlob* blob = CodeCache::find_blob(exception_pc);
rbackman@38133 1648 if (blob->is_compiled()) {
rbackman@38133 1649 CompiledMethod* cm = blob->as_compiled_method_or_null();
rbackman@38133 1650 cm->method()->print_value_on(&tempst);
duke@1 1651 } else if (blob->is_runtime_stub()) {
rprotacio@35216 1652 tempst.print("<runtime-stub>");
duke@1 1653 } else {
rprotacio@35216 1654 tempst.print("<unknown>");
duke@1 1655 }
rprotacio@35216 1656 tempst.print(" at " INTPTR_FORMAT, p2i(exception_pc));
rprotacio@35216 1657 tempst.print("]");
rprotacio@35216 1658
rprotacio@35216 1659 st->print_raw_cr(tempst.as_string());
duke@1 1660 }