1 /* 2 * Copyright (c) 2011, 2015, 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 #include "precompiled.hpp" 25 #include "code/codeCache.hpp" 26 #include "code/scopeDesc.hpp" 27 #include "interpreter/linkResolver.hpp" 28 #include "memory/oopFactory.hpp" 29 #include "oops/generateOopMap.hpp" 30 #include "oops/fieldStreams.hpp" 31 #include "oops/oop.inline.hpp" 32 #include "oops/objArrayOop.inline.hpp" 33 #include "runtime/fieldDescriptor.hpp" 34 #include "runtime/javaCalls.hpp" 35 #include "jvmci/jvmciRuntime.hpp" 36 #include "compiler/abstractCompiler.hpp" 37 #include "compiler/compileBroker.hpp" 38 #include "compiler/compilerOracle.hpp" 39 #include "compiler/disassembler.hpp" 40 #include "compiler/oopMap.hpp" 41 #include "jvmci/jvmciCompilerToVM.hpp" 42 #include "jvmci/jvmciCompiler.hpp" 43 #include "jvmci/jvmciEnv.hpp" 44 #include "jvmci/jvmciJavaClasses.hpp" 45 #include "jvmci/jvmciCodeInstaller.hpp" 46 #include "jvmci/vmStructs_jvmci.hpp" 47 #include "gc/g1/heapRegion.hpp" 48 #include "runtime/javaCalls.hpp" 49 #include "runtime/deoptimization.hpp" 50 #include "runtime/vframe.hpp" 51 #include "runtime/vframe_hp.hpp" 52 #include "runtime/vmStructs.hpp" 53 54 55 // Entry to native method implementation that transitions current thread to '_thread_in_vm'. 56 #define C2V_VMENTRY(result_type, name, signature) \ 57 JNIEXPORT result_type JNICALL c2v_ ## name signature { \ 58 TRACE_jvmci_1("CompilerToVM::" #name); \ 59 TRACE_CALL(result_type, jvmci_ ## name signature) \ 60 JVMCI_VM_ENTRY_MARK; \ 61 62 #define C2V_END } 63 64 oop CompilerToVM::get_jvmci_method(const methodHandle& method, TRAPS) { 65 if (method() != NULL) { 66 JavaValue result(T_OBJECT); 67 JavaCallArguments args; 68 args.push_long((jlong) (address) method()); 69 JavaCalls::call_static(&result, SystemDictionary::HotSpotResolvedJavaMethodImpl_klass(), vmSymbols::fromMetaspace_name(), vmSymbols::method_fromMetaspace_signature(), &args, CHECK_NULL); 70 71 return (oop)result.get_jobject(); 72 } 73 return NULL; 74 } 75 76 oop CompilerToVM::get_jvmci_type(KlassHandle klass, TRAPS) { 77 if (klass() != NULL) { 78 JavaValue result(T_OBJECT); 79 JavaCallArguments args; 80 args.push_oop(klass->java_mirror()); 81 JavaCalls::call_static(&result, SystemDictionary::HotSpotResolvedObjectTypeImpl_klass(), vmSymbols::fromMetaspace_name(), vmSymbols::klass_fromMetaspace_signature(), &args, CHECK_NULL); 82 83 return (oop)result.get_jobject(); 84 } 85 return NULL; 86 } 87 88 extern "C" { 89 extern VMStructEntry* jvmciHotSpotVMStructs; 90 extern uint64_t jvmciHotSpotVMStructEntryTypeNameOffset; 91 extern uint64_t jvmciHotSpotVMStructEntryFieldNameOffset; 92 extern uint64_t jvmciHotSpotVMStructEntryTypeStringOffset; 93 extern uint64_t jvmciHotSpotVMStructEntryIsStaticOffset; 94 extern uint64_t jvmciHotSpotVMStructEntryOffsetOffset; 95 extern uint64_t jvmciHotSpotVMStructEntryAddressOffset; 96 extern uint64_t jvmciHotSpotVMStructEntryArrayStride; 97 98 extern VMTypeEntry* jvmciHotSpotVMTypes; 99 extern uint64_t jvmciHotSpotVMTypeEntryTypeNameOffset; 100 extern uint64_t jvmciHotSpotVMTypeEntrySuperclassNameOffset; 101 extern uint64_t jvmciHotSpotVMTypeEntryIsOopTypeOffset; 102 extern uint64_t jvmciHotSpotVMTypeEntryIsIntegerTypeOffset; 103 extern uint64_t jvmciHotSpotVMTypeEntryIsUnsignedOffset; 104 extern uint64_t jvmciHotSpotVMTypeEntrySizeOffset; 105 extern uint64_t jvmciHotSpotVMTypeEntryArrayStride; 106 107 extern VMIntConstantEntry* jvmciHotSpotVMIntConstants; 108 extern uint64_t jvmciHotSpotVMIntConstantEntryNameOffset; 109 extern uint64_t jvmciHotSpotVMIntConstantEntryValueOffset; 110 extern uint64_t jvmciHotSpotVMIntConstantEntryArrayStride; 111 112 extern VMLongConstantEntry* jvmciHotSpotVMLongConstants; 113 extern uint64_t jvmciHotSpotVMLongConstantEntryNameOffset; 114 extern uint64_t jvmciHotSpotVMLongConstantEntryValueOffset; 115 extern uint64_t jvmciHotSpotVMLongConstantEntryArrayStride; 116 117 extern VMAddressEntry* jvmciHotSpotVMAddresses; 118 extern uint64_t jvmciHotSpotVMAddressEntryNameOffset; 119 extern uint64_t jvmciHotSpotVMAddressEntryValueOffset; 120 extern uint64_t jvmciHotSpotVMAddressEntryArrayStride; 121 } 122 123 int CompilerToVM::Data::InstanceKlass_vtable_start_offset; 124 int CompilerToVM::Data::InstanceKlass_vtable_length_offset; 125 126 int CompilerToVM::Data::Method_extra_stack_entries; 127 128 address CompilerToVM::Data::SharedRuntime_ic_miss_stub; 129 address CompilerToVM::Data::SharedRuntime_handle_wrong_method_stub; 130 address CompilerToVM::Data::SharedRuntime_deopt_blob_unpack; 131 address CompilerToVM::Data::SharedRuntime_deopt_blob_uncommon_trap; 132 133 size_t CompilerToVM::Data::ThreadLocalAllocBuffer_alignment_reserve; 134 135 CollectedHeap* CompilerToVM::Data::Universe_collectedHeap; 136 int CompilerToVM::Data::Universe_base_vtable_size; 137 address CompilerToVM::Data::Universe_narrow_oop_base; 138 int CompilerToVM::Data::Universe_narrow_oop_shift; 139 address CompilerToVM::Data::Universe_narrow_klass_base; 140 int CompilerToVM::Data::Universe_narrow_klass_shift; 141 void* CompilerToVM::Data::Universe_non_oop_bits; 142 uintptr_t CompilerToVM::Data::Universe_verify_oop_mask; 143 uintptr_t CompilerToVM::Data::Universe_verify_oop_bits; 144 145 bool CompilerToVM::Data::_supports_inline_contig_alloc; 146 HeapWord** CompilerToVM::Data::_heap_end_addr; 147 HeapWord** CompilerToVM::Data::_heap_top_addr; 148 149 jbyte* CompilerToVM::Data::cardtable_start_address; 150 int CompilerToVM::Data::cardtable_shift; 151 152 void CompilerToVM::Data::initialize() { 153 InstanceKlass_vtable_start_offset = InstanceKlass::vtable_start_offset(); 154 InstanceKlass_vtable_length_offset = InstanceKlass::vtable_length_offset() * HeapWordSize; 155 156 Method_extra_stack_entries = Method::extra_stack_entries(); 157 158 SharedRuntime_ic_miss_stub = SharedRuntime::get_ic_miss_stub(); 159 SharedRuntime_handle_wrong_method_stub = SharedRuntime::get_handle_wrong_method_stub(); 160 SharedRuntime_deopt_blob_unpack = SharedRuntime::deopt_blob()->unpack(); 161 SharedRuntime_deopt_blob_uncommon_trap = SharedRuntime::deopt_blob()->uncommon_trap(); 162 163 ThreadLocalAllocBuffer_alignment_reserve = ThreadLocalAllocBuffer::alignment_reserve(); 164 165 Universe_collectedHeap = Universe::heap(); 166 Universe_base_vtable_size = Universe::base_vtable_size(); 167 Universe_narrow_oop_base = Universe::narrow_oop_base(); 168 Universe_narrow_oop_shift = Universe::narrow_oop_shift(); 169 Universe_narrow_klass_base = Universe::narrow_klass_base(); 170 Universe_narrow_klass_shift = Universe::narrow_klass_shift(); 171 Universe_non_oop_bits = Universe::non_oop_word(); 172 Universe_verify_oop_mask = Universe::verify_oop_mask(); 173 Universe_verify_oop_bits = Universe::verify_oop_bits(); 174 175 _supports_inline_contig_alloc = Universe::heap()->supports_inline_contig_alloc(); 176 _heap_end_addr = _supports_inline_contig_alloc ? Universe::heap()->end_addr() : (HeapWord**) -1; 177 _heap_top_addr = _supports_inline_contig_alloc ? Universe::heap()->top_addr() : (HeapWord**) -1; 178 179 BarrierSet* bs = Universe::heap()->barrier_set(); 180 switch (bs->kind()) { 181 case BarrierSet::CardTableModRef: 182 case BarrierSet::CardTableForRS: 183 case BarrierSet::CardTableExtension: 184 case BarrierSet::G1SATBCT: 185 case BarrierSet::G1SATBCTLogging: { 186 jbyte* base = barrier_set_cast<CardTableModRefBS>(bs)->byte_map_base; 187 assert(base != 0, "unexpected byte_map_base"); 188 cardtable_start_address = base; 189 cardtable_shift = CardTableModRefBS::card_shift; 190 break; 191 } 192 case BarrierSet::ModRef: 193 cardtable_start_address = 0; 194 cardtable_shift = 0; 195 // No post barriers 196 break; 197 default: 198 ShouldNotReachHere(); 199 break; 200 } 201 } 202 203 /** 204 * We put all jvmciHotSpotVM values in an array so we can read them easily from Java. 205 */ 206 static uintptr_t ciHotSpotVMData[28]; 207 208 C2V_VMENTRY(jlong, initializeConfiguration, (JNIEnv *env, jobject)) 209 ciHotSpotVMData[0] = (uintptr_t) jvmciHotSpotVMStructs; 210 ciHotSpotVMData[1] = jvmciHotSpotVMStructEntryTypeNameOffset; 211 ciHotSpotVMData[2] = jvmciHotSpotVMStructEntryFieldNameOffset; 212 ciHotSpotVMData[3] = jvmciHotSpotVMStructEntryTypeStringOffset; 213 ciHotSpotVMData[4] = jvmciHotSpotVMStructEntryIsStaticOffset; 214 ciHotSpotVMData[5] = jvmciHotSpotVMStructEntryOffsetOffset; 215 ciHotSpotVMData[6] = jvmciHotSpotVMStructEntryAddressOffset; 216 ciHotSpotVMData[7] = jvmciHotSpotVMStructEntryArrayStride; 217 218 ciHotSpotVMData[8] = (uintptr_t) jvmciHotSpotVMTypes; 219 ciHotSpotVMData[9] = jvmciHotSpotVMTypeEntryTypeNameOffset; 220 ciHotSpotVMData[10] = jvmciHotSpotVMTypeEntrySuperclassNameOffset; 221 ciHotSpotVMData[11] = jvmciHotSpotVMTypeEntryIsOopTypeOffset; 222 ciHotSpotVMData[12] = jvmciHotSpotVMTypeEntryIsIntegerTypeOffset; 223 ciHotSpotVMData[13] = jvmciHotSpotVMTypeEntryIsUnsignedOffset; 224 ciHotSpotVMData[14] = jvmciHotSpotVMTypeEntrySizeOffset; 225 ciHotSpotVMData[15] = jvmciHotSpotVMTypeEntryArrayStride; 226 227 ciHotSpotVMData[16] = (uintptr_t) jvmciHotSpotVMIntConstants; 228 ciHotSpotVMData[17] = jvmciHotSpotVMIntConstantEntryNameOffset; 229 ciHotSpotVMData[18] = jvmciHotSpotVMIntConstantEntryValueOffset; 230 ciHotSpotVMData[19] = jvmciHotSpotVMIntConstantEntryArrayStride; 231 232 ciHotSpotVMData[20] = (uintptr_t) jvmciHotSpotVMLongConstants; 233 ciHotSpotVMData[21] = jvmciHotSpotVMLongConstantEntryNameOffset; 234 ciHotSpotVMData[22] = jvmciHotSpotVMLongConstantEntryValueOffset; 235 ciHotSpotVMData[23] = jvmciHotSpotVMLongConstantEntryArrayStride; 236 237 ciHotSpotVMData[24] = (uintptr_t) jvmciHotSpotVMAddresses; 238 ciHotSpotVMData[25] = jvmciHotSpotVMAddressEntryNameOffset; 239 ciHotSpotVMData[26] = jvmciHotSpotVMAddressEntryValueOffset; 240 ciHotSpotVMData[27] = jvmciHotSpotVMAddressEntryArrayStride; 241 242 CompilerToVM::Data::initialize(); 243 244 return (jlong) (address) &ciHotSpotVMData; 245 C2V_END 246 247 C2V_VMENTRY(jbyteArray, getBytecode, (JNIEnv *, jobject, jobject jvmci_method)) 248 methodHandle method = CompilerToVM::asMethod(jvmci_method); 249 ResourceMark rm; 250 251 int code_size = method->code_size(); 252 typeArrayOop reconstituted_code = oopFactory::new_byteArray(code_size, CHECK_NULL); 253 254 guarantee(method->method_holder()->is_rewritten(), "Method's holder should be rewritten"); 255 // iterate over all bytecodes and replace non-Java bytecodes 256 257 for (BytecodeStream s(method); s.next() != Bytecodes::_illegal; ) { 258 Bytecodes::Code code = s.code(); 259 Bytecodes::Code raw_code = s.raw_code(); 260 int bci = s.bci(); 261 int len = s.instruction_size(); 262 263 // Restore original byte code. 264 reconstituted_code->byte_at_put(bci, (jbyte) (s.is_wide()? Bytecodes::_wide : code)); 265 if (len > 1) { 266 memcpy(reconstituted_code->byte_at_addr(bci + 1), s.bcp()+1, len-1); 267 } 268 269 if (len > 1) { 270 // Restore the big-endian constant pool indexes. 271 // Cf. Rewriter::scan_method 272 switch (code) { 273 case Bytecodes::_getstatic: 274 case Bytecodes::_putstatic: 275 case Bytecodes::_getfield: 276 case Bytecodes::_putfield: 277 case Bytecodes::_invokevirtual: 278 case Bytecodes::_invokespecial: 279 case Bytecodes::_invokestatic: 280 case Bytecodes::_invokeinterface: 281 case Bytecodes::_invokehandle: { 282 int cp_index = Bytes::get_native_u2((address) reconstituted_code->byte_at_addr(bci + 1)); 283 Bytes::put_Java_u2((address) reconstituted_code->byte_at_addr(bci + 1), (u2) cp_index); 284 break; 285 } 286 287 case Bytecodes::_invokedynamic: 288 int cp_index = Bytes::get_native_u4((address) reconstituted_code->byte_at_addr(bci + 1)); 289 Bytes::put_Java_u4((address) reconstituted_code->byte_at_addr(bci + 1), (u4) cp_index); 290 break; 291 } 292 293 // Not all ldc byte code are rewritten. 294 switch (raw_code) { 295 case Bytecodes::_fast_aldc: { 296 int cpc_index = reconstituted_code->byte_at(bci + 1) & 0xff; 297 int cp_index = method->constants()->object_to_cp_index(cpc_index); 298 assert(cp_index < method->constants()->length(), "sanity check"); 299 reconstituted_code->byte_at_put(bci + 1, (jbyte) cp_index); 300 break; 301 } 302 303 case Bytecodes::_fast_aldc_w: { 304 int cpc_index = Bytes::get_native_u2((address) reconstituted_code->byte_at_addr(bci + 1)); 305 int cp_index = method->constants()->object_to_cp_index(cpc_index); 306 assert(cp_index < method->constants()->length(), "sanity check"); 307 Bytes::put_Java_u2((address) reconstituted_code->byte_at_addr(bci + 1), (u2) cp_index); 308 break; 309 } 310 } 311 } 312 } 313 314 return (jbyteArray) JNIHandles::make_local(THREAD, reconstituted_code); 315 C2V_END 316 317 C2V_VMENTRY(jint, getExceptionTableLength, (JNIEnv *, jobject, jobject jvmci_method)) 318 ResourceMark rm; 319 methodHandle method = CompilerToVM::asMethod(jvmci_method); 320 return method->exception_table_length(); 321 C2V_END 322 323 C2V_VMENTRY(jlong, getExceptionTableStart, (JNIEnv *, jobject, jobject jvmci_method)) 324 ResourceMark rm; 325 methodHandle method = CompilerToVM::asMethod(jvmci_method); 326 if (method->exception_table_length() == 0) { 327 return 0L; 328 } 329 return (jlong) (address) method->exception_table_start(); 330 C2V_END 331 332 C2V_VMENTRY(jobject, getResolvedJavaMethodAtSlot, (JNIEnv *, jobject, jclass holder_handle, jint slot)) 333 oop java_class = JNIHandles::resolve(holder_handle); 334 Klass* holder = java_lang_Class::as_Klass(java_class); 335 methodHandle method = InstanceKlass::cast(holder)->method_with_idnum(slot); 336 oop result = CompilerToVM::get_jvmci_method(method, CHECK_NULL); 337 return JNIHandles::make_local(THREAD, result); 338 } 339 340 C2V_VMENTRY(jobject, getResolvedJavaMethod, (JNIEnv *, jobject, jobject base, jlong offset)) 341 methodHandle method; 342 oop base_object = JNIHandles::resolve(base); 343 if (base_object == NULL) { 344 method = *((Method**)(offset)); 345 } else if (base_object->is_a(SystemDictionary::MemberName_klass())) { 346 method = (Method*) (intptr_t) base_object->long_field(offset); 347 } else if (base_object->is_a(SystemDictionary::HotSpotResolvedJavaMethodImpl_klass())) { 348 method = *((Method**)(HotSpotResolvedJavaMethodImpl::metaspaceMethod(base_object) + offset)); 349 } else { 350 THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), 351 err_msg("Unexpected type: %s", base_object->klass()->external_name())); 352 } 353 assert (method.is_null() || method->is_method(), "invalid read"); 354 oop result = CompilerToVM::get_jvmci_method(method, CHECK_NULL); 355 return JNIHandles::make_local(THREAD, result); 356 } 357 358 C2V_VMENTRY(jobject, getConstantPool, (JNIEnv *, jobject, jobject base, jlong offset)) 359 constantPoolHandle cp; 360 oop base_object = JNIHandles::resolve(base); 361 jlong base_address = 0; 362 if (base_object != NULL) { 363 if (base_object->is_a(SystemDictionary::HotSpotResolvedJavaMethodImpl_klass())) { 364 base_address = HotSpotResolvedJavaMethodImpl::metaspaceMethod(base_object); 365 } else if (base_object->is_a(SystemDictionary::HotSpotConstantPool_klass())) { 366 base_address = HotSpotConstantPool::metaspaceConstantPool(base_object); 367 } else if (base_object->is_a(SystemDictionary::HotSpotResolvedObjectTypeImpl_klass())) { 368 base_address = (jlong) CompilerToVM::asKlass(base_object); 369 } else { 370 THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), 371 err_msg("Unexpected type: %s", base_object->klass()->external_name())); 372 } 373 } 374 cp = *((ConstantPool**) (intptr_t) (base_address + offset)); 375 if (!cp.is_null()) { 376 JavaValue method_result(T_OBJECT); 377 JavaCallArguments args; 378 args.push_long((jlong) (address) cp()); 379 JavaCalls::call_static(&method_result, SystemDictionary::HotSpotConstantPool_klass(), vmSymbols::fromMetaspace_name(), vmSymbols::constantPool_fromMetaspace_signature(), &args, CHECK_NULL); 380 return JNIHandles::make_local(THREAD, (oop)method_result.get_jobject()); 381 } 382 return NULL; 383 } 384 385 C2V_VMENTRY(jobject, getResolvedJavaType, (JNIEnv *, jobject, jobject base, jlong offset, jboolean compressed)) 386 KlassHandle klass; 387 oop base_object = JNIHandles::resolve(base); 388 jlong base_address = 0; 389 if (base_object != NULL && offset == oopDesc::klass_offset_in_bytes()) { 390 klass = base_object->klass(); 391 } else if (!compressed) { 392 if (base_object != NULL) { 393 if (base_object->is_a(SystemDictionary::HotSpotResolvedJavaMethodImpl_klass())) { 394 base_address = HotSpotResolvedJavaMethodImpl::metaspaceMethod(base_object); 395 } else if (base_object->is_a(SystemDictionary::HotSpotConstantPool_klass())) { 396 base_address = HotSpotConstantPool::metaspaceConstantPool(base_object); 397 } else if (base_object->is_a(SystemDictionary::HotSpotResolvedObjectTypeImpl_klass())) { 398 base_address = (jlong) CompilerToVM::asKlass(base_object); 399 } else if (base_object->is_a(SystemDictionary::Class_klass())) { 400 base_address = (jlong) (address) base_object; 401 } else { 402 THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), 403 err_msg("Unexpected arguments: %s " JLONG_FORMAT " %s", base_object->klass()->external_name(), offset, compressed ? "true" : "false")); 404 } 405 } 406 klass = *((Klass**) (intptr_t) (base_address + offset)); 407 } else { 408 THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), 409 err_msg("Unexpected arguments: %s " JLONG_FORMAT " %s", base_object->klass()->external_name(), offset, compressed ? "true" : "false")); 410 } 411 assert (klass.is_null() || klass->is_klass(), "invalid read"); 412 oop result = CompilerToVM::get_jvmci_type(klass, CHECK_NULL); 413 return JNIHandles::make_local(THREAD, result); 414 } 415 416 C2V_VMENTRY(jobject, findUniqueConcreteMethod, (JNIEnv *, jobject, jobject jvmci_type, jobject jvmci_method)) 417 ResourceMark rm; 418 methodHandle method = CompilerToVM::asMethod(jvmci_method); 419 KlassHandle holder = CompilerToVM::asKlass(jvmci_type); 420 if (holder->is_interface()) { 421 THROW_MSG_0(vmSymbols::java_lang_InternalError(), err_msg("Interface %s should be handled in Java code", holder->external_name())); 422 } 423 424 methodHandle ucm; 425 { 426 MutexLocker locker(Compile_lock); 427 ucm = Dependencies::find_unique_concrete_method(holder(), method()); 428 } 429 oop result = CompilerToVM::get_jvmci_method(ucm, CHECK_NULL); 430 return JNIHandles::make_local(THREAD, result); 431 C2V_END 432 433 C2V_VMENTRY(jobject, getImplementor, (JNIEnv *, jobject, jobject jvmci_type)) 434 InstanceKlass* klass = (InstanceKlass*) CompilerToVM::asKlass(jvmci_type); 435 oop implementor = CompilerToVM::get_jvmci_type(klass->implementor(), CHECK_NULL); 436 return JNIHandles::make_local(THREAD, implementor); 437 C2V_END 438 439 C2V_VMENTRY(jboolean, methodIsIgnoredBySecurityStackWalk,(JNIEnv *, jobject, jobject jvmci_method)) 440 methodHandle method = CompilerToVM::asMethod(jvmci_method); 441 return method->is_ignored_by_security_stack_walk(); 442 C2V_END 443 444 C2V_VMENTRY(jboolean, canInlineMethod,(JNIEnv *, jobject, jobject jvmci_method)) 445 methodHandle method = CompilerToVM::asMethod(jvmci_method); 446 return !method->is_not_compilable() && !CompilerOracle::should_not_inline(method) && !method->dont_inline(); 447 C2V_END 448 449 C2V_VMENTRY(jboolean, shouldInlineMethod,(JNIEnv *, jobject, jobject jvmci_method)) 450 methodHandle method = CompilerToVM::asMethod(jvmci_method); 451 return CompilerOracle::should_inline(method) || method->force_inline(); 452 C2V_END 453 454 C2V_VMENTRY(jobject, lookupType, (JNIEnv*, jobject, jstring jname, jclass accessing_class, jboolean resolve)) 455 ResourceMark rm; 456 Handle name = JNIHandles::resolve(jname); 457 Symbol* class_name = java_lang_String::as_symbol(name, CHECK_0); 458 if (java_lang_String::length(name()) <= 1) { 459 THROW_MSG_0(vmSymbols::java_lang_InternalError(), err_msg("Primitive type %s should be handled in Java code", class_name->as_C_string())); 460 } 461 462 Klass* resolved_klass = NULL; 463 Handle class_loader; 464 Handle protection_domain; 465 if (JNIHandles::resolve(accessing_class) == NULL) { 466 THROW_0(vmSymbols::java_lang_NullPointerException()); 467 } 468 Klass* accessing_klass = java_lang_Class::as_Klass(JNIHandles::resolve(accessing_class)); 469 class_loader = accessing_klass->class_loader(); 470 protection_domain = accessing_klass->protection_domain(); 471 472 if (resolve) { 473 resolved_klass = SystemDictionary::resolve_or_null(class_name, class_loader, protection_domain, CHECK_0); 474 } else { 475 if (class_name->byte_at(0) == 'L' && 476 class_name->byte_at(class_name->utf8_length()-1) == ';') { 477 // This is a name from a signature. Strip off the trimmings. 478 // Call recursive to keep scope of strippedsym. 479 TempNewSymbol strippedsym = SymbolTable::new_symbol(class_name->as_utf8()+1, 480 class_name->utf8_length()-2, 481 CHECK_0); 482 resolved_klass = SystemDictionary::find(strippedsym, class_loader, protection_domain, CHECK_0); 483 } else if (FieldType::is_array(class_name)) { 484 FieldArrayInfo fd; 485 // dimension and object_key in FieldArrayInfo are assigned as a side-effect 486 // of this call 487 BasicType t = FieldType::get_array_info(class_name, fd, CHECK_0); 488 if (t == T_OBJECT) { 489 TempNewSymbol strippedsym = SymbolTable::new_symbol(class_name->as_utf8()+1+fd.dimension(), 490 class_name->utf8_length()-2-fd.dimension(), 491 CHECK_0); 492 // naked oop "k" is OK here -- we assign back into it 493 resolved_klass = SystemDictionary::find(strippedsym, 494 class_loader, 495 protection_domain, 496 CHECK_0); 497 if (resolved_klass != NULL) { 498 resolved_klass = resolved_klass->array_klass(fd.dimension(), CHECK_0); 499 } 500 } else { 501 resolved_klass = Universe::typeArrayKlassObj(t); 502 resolved_klass = TypeArrayKlass::cast(resolved_klass)->array_klass(fd.dimension(), CHECK_0); 503 } 504 } 505 } 506 Handle result = CompilerToVM::get_jvmci_type(resolved_klass, CHECK_NULL); 507 return JNIHandles::make_local(THREAD, result()); 508 C2V_END 509 510 C2V_VMENTRY(jobject, resolveConstantInPool, (JNIEnv*, jobject, jobject jvmci_constant_pool, jint index)) 511 constantPoolHandle cp = CompilerToVM::asConstantPool(jvmci_constant_pool); 512 oop result = cp->resolve_constant_at(index, CHECK_NULL); 513 return JNIHandles::make_local(THREAD, result); 514 C2V_END 515 516 C2V_VMENTRY(jobject, resolvePossiblyCachedConstantInPool, (JNIEnv*, jobject, jobject jvmci_constant_pool, jint index)) 517 constantPoolHandle cp = CompilerToVM::asConstantPool(jvmci_constant_pool); 518 oop result = cp->resolve_possibly_cached_constant_at(index, CHECK_NULL); 519 return JNIHandles::make_local(THREAD, result); 520 C2V_END 521 522 C2V_VMENTRY(jint, lookupNameAndTypeRefIndexInPool, (JNIEnv*, jobject, jobject jvmci_constant_pool, jint index)) 523 constantPoolHandle cp = CompilerToVM::asConstantPool(jvmci_constant_pool); 524 return cp->name_and_type_ref_index_at(index); 525 C2V_END 526 527 C2V_VMENTRY(jobject, lookupNameInPool, (JNIEnv*, jobject, jobject jvmci_constant_pool, jint which)) 528 constantPoolHandle cp = CompilerToVM::asConstantPool(jvmci_constant_pool); 529 Handle sym = java_lang_String::create_from_symbol(cp->name_ref_at(which), CHECK_NULL); 530 return JNIHandles::make_local(THREAD, sym()); 531 C2V_END 532 533 C2V_VMENTRY(jobject, lookupSignatureInPool, (JNIEnv*, jobject, jobject jvmci_constant_pool, jint which)) 534 constantPoolHandle cp = CompilerToVM::asConstantPool(jvmci_constant_pool); 535 Handle sym = java_lang_String::create_from_symbol(cp->signature_ref_at(which), CHECK_NULL); 536 return JNIHandles::make_local(THREAD, sym()); 537 C2V_END 538 539 C2V_VMENTRY(jint, lookupKlassRefIndexInPool, (JNIEnv*, jobject, jobject jvmci_constant_pool, jint index)) 540 constantPoolHandle cp = CompilerToVM::asConstantPool(jvmci_constant_pool); 541 return cp->klass_ref_index_at(index); 542 C2V_END 543 544 C2V_VMENTRY(jobject, resolveTypeInPool, (JNIEnv*, jobject, jobject jvmci_constant_pool, jint index)) 545 constantPoolHandle cp = CompilerToVM::asConstantPool(jvmci_constant_pool); 546 Klass* resolved_klass = cp->klass_at(index, CHECK_NULL); 547 Handle klass = CompilerToVM::get_jvmci_type(resolved_klass, CHECK_NULL); 548 return JNIHandles::make_local(THREAD, klass()); 549 C2V_END 550 551 C2V_VMENTRY(jobject, lookupKlassInPool, (JNIEnv*, jobject, jobject jvmci_constant_pool, jint index, jbyte opcode)) 552 constantPoolHandle cp = CompilerToVM::asConstantPool(jvmci_constant_pool); 553 KlassHandle loading_klass(cp->pool_holder()); 554 bool is_accessible = false; 555 KlassHandle klass = JVMCIEnv::get_klass_by_index(cp, index, is_accessible, loading_klass); 556 Symbol* symbol = NULL; 557 if (klass.is_null()) { 558 symbol = cp->klass_name_at(index); 559 } 560 Handle result; 561 if (!klass.is_null()) { 562 result = CompilerToVM::get_jvmci_type(klass, CHECK_NULL); 563 } else { 564 result = java_lang_String::create_from_symbol(symbol, CHECK_NULL); 565 } 566 return JNIHandles::make_local(THREAD, result()); 567 C2V_END 568 569 C2V_VMENTRY(jobject, lookupAppendixInPool, (JNIEnv*, jobject, jobject jvmci_constant_pool, jint index)) 570 constantPoolHandle cp = CompilerToVM::asConstantPool(jvmci_constant_pool); 571 oop appendix_oop = ConstantPool::appendix_at_if_loaded(cp, index); 572 return JNIHandles::make_local(THREAD, appendix_oop); 573 C2V_END 574 575 C2V_VMENTRY(jobject, lookupMethodInPool, (JNIEnv*, jobject, jobject jvmci_constant_pool, jint index, jbyte opcode)) 576 constantPoolHandle cp = CompilerToVM::asConstantPool(jvmci_constant_pool); 577 instanceKlassHandle pool_holder(cp->pool_holder()); 578 Bytecodes::Code bc = (Bytecodes::Code) (((int) opcode) & 0xFF); 579 methodHandle method = JVMCIEnv::get_method_by_index(cp, index, bc, pool_holder); 580 oop result = CompilerToVM::get_jvmci_method(method, CHECK_NULL); 581 return JNIHandles::make_local(THREAD, result); 582 C2V_END 583 584 C2V_VMENTRY(jint, constantPoolRemapInstructionOperandFromCache, (JNIEnv*, jobject, jobject jvmci_constant_pool, jint index)) 585 constantPoolHandle cp = CompilerToVM::asConstantPool(jvmci_constant_pool); 586 return cp->remap_instruction_operand_from_cache(index); 587 C2V_END 588 589 C2V_VMENTRY(jobject, resolveFieldInPool, (JNIEnv*, jobject, jobject jvmci_constant_pool, jint index, jbyte opcode, jlongArray info_handle)) 590 ResourceMark rm; 591 constantPoolHandle cp = CompilerToVM::asConstantPool(jvmci_constant_pool); 592 Bytecodes::Code code = (Bytecodes::Code)(((int) opcode) & 0xFF); 593 fieldDescriptor fd; 594 LinkInfo link_info(cp, index, CHECK_0); 595 LinkResolver::resolve_field(fd, link_info, Bytecodes::java_code(code), false, CHECK_0); 596 typeArrayOop info = (typeArrayOop) JNIHandles::resolve(info_handle); 597 assert(info != NULL && info->length() == 2, "must be"); 598 info->long_at_put(0, (jlong) fd.access_flags().as_int()); 599 info->long_at_put(1, (jlong) fd.offset()); 600 oop field_holder = CompilerToVM::get_jvmci_type(fd.field_holder(), CHECK_NULL); 601 return JNIHandles::make_local(THREAD, field_holder); 602 C2V_END 603 604 C2V_VMENTRY(jint, getVtableIndexForInterfaceMethod, (JNIEnv *, jobject, jobject jvmci_type, jobject jvmci_method)) 605 ResourceMark rm; 606 Klass* klass = CompilerToVM::asKlass(jvmci_type); 607 Method* method = CompilerToVM::asMethod(jvmci_method); 608 if (klass->is_interface()) { 609 THROW_MSG_0(vmSymbols::java_lang_InternalError(), err_msg("Interface %s should be handled in Java code", klass->external_name())); 610 } 611 if (!method->method_holder()->is_interface()) { 612 THROW_MSG_0(vmSymbols::java_lang_InternalError(), err_msg("Method %s is not held by an interface, this case should be handled in Java code", method->name_and_sig_as_C_string())); 613 } 614 if (!InstanceKlass::cast(klass)->is_linked()) { 615 THROW_MSG_0(vmSymbols::java_lang_InternalError(), err_msg("Class %s must be linked", klass->external_name())); 616 } 617 return LinkResolver::vtable_index_of_interface_method(klass, method); 618 C2V_END 619 620 C2V_VMENTRY(jobject, resolveMethod, (JNIEnv *, jobject, jobject receiver_jvmci_type, jobject jvmci_method, jobject caller_jvmci_type)) 621 Klass* recv_klass = CompilerToVM::asKlass(receiver_jvmci_type); 622 Klass* caller_klass = CompilerToVM::asKlass(caller_jvmci_type); 623 Method* method = CompilerToVM::asMethod(jvmci_method); 624 625 if (recv_klass->is_array_klass() || (InstanceKlass::cast(recv_klass)->is_linked())) { 626 Klass* holder_klass = method->method_holder(); 627 Symbol* method_name = method->name(); 628 Symbol* method_signature = method->signature(); 629 630 if (holder_klass->is_interface()) { 631 // do link-time resolution to check all access rules. 632 LinkInfo link_info(holder_klass, method_name, method_signature, caller_klass, true); 633 methodHandle resolved_method = LinkResolver::linktime_resolve_interface_method_or_null(link_info); 634 if (resolved_method.is_null() || resolved_method->is_private()) { 635 return NULL; 636 } 637 assert(recv_klass->is_subtype_of(holder_klass), ""); 638 // do actual lookup 639 methodHandle sel_method = LinkResolver::lookup_instance_method_in_klasses(recv_klass, resolved_method->name(), resolved_method->signature(), CHECK_AND_CLEAR_0); 640 oop result = CompilerToVM::get_jvmci_method(sel_method, CHECK_NULL); 641 return JNIHandles::make_local(THREAD, result); 642 } else { 643 // do link-time resolution to check all access rules. 644 LinkInfo link_info(holder_klass, method_name, method_signature, caller_klass, true); 645 methodHandle resolved_method = LinkResolver::linktime_resolve_virtual_method_or_null(link_info); 646 if (resolved_method.is_null()) { 647 return NULL; 648 } 649 // do actual lookup (see LinkResolver::runtime_resolve_virtual_method) 650 int vtable_index = Method::invalid_vtable_index; 651 Method* selected_method; 652 653 if (resolved_method->method_holder()->is_interface()) { // miranda method 654 vtable_index = LinkResolver::vtable_index_of_interface_method(holder_klass, resolved_method); 655 assert(vtable_index >= 0 , "we should have valid vtable index at this point"); 656 657 InstanceKlass* inst = InstanceKlass::cast(recv_klass); 658 selected_method = inst->method_at_vtable(vtable_index); 659 } else { 660 // at this point we are sure that resolved_method is virtual and not 661 // a miranda method; therefore, it must have a valid vtable index. 662 assert(!resolved_method->has_itable_index(), ""); 663 vtable_index = resolved_method->vtable_index(); 664 // We could get a negative vtable_index for final methods, 665 // because as an optimization they are they are never put in the vtable, 666 // unless they override an existing method. 667 // If we do get a negative, it means the resolved method is the the selected 668 // method, and it can never be changed by an override. 669 if (vtable_index == Method::nonvirtual_vtable_index) { 670 assert(resolved_method->can_be_statically_bound(), "cannot override this method"); 671 selected_method = resolved_method(); 672 } else { 673 // recv_klass might be an arrayKlassOop but all vtables start at 674 // the same place. The cast is to avoid virtual call and assertion. 675 InstanceKlass* inst = (InstanceKlass*)recv_klass; 676 selected_method = inst->method_at_vtable(vtable_index); 677 } 678 } 679 oop result = CompilerToVM::get_jvmci_method(selected_method, CHECK_NULL); 680 return JNIHandles::make_local(THREAD, result); 681 } 682 } 683 return NULL; 684 C2V_END 685 686 C2V_VMENTRY(jboolean, hasFinalizableSubclass,(JNIEnv *, jobject, jobject jvmci_type)) 687 Klass* klass = CompilerToVM::asKlass(jvmci_type); 688 assert(klass != NULL, "method must not be called for primitive types"); 689 return Dependencies::find_finalizable_subclass(klass) != NULL; 690 C2V_END 691 692 C2V_VMENTRY(jobject, getClassInitializer, (JNIEnv *, jobject, jobject jvmci_type)) 693 InstanceKlass* klass = (InstanceKlass*) CompilerToVM::asKlass(jvmci_type); 694 oop result = CompilerToVM::get_jvmci_method(klass->class_initializer(), CHECK_NULL); 695 return JNIHandles::make_local(THREAD, result); 696 C2V_END 697 698 C2V_VMENTRY(jlong, getMaxCallTargetOffset, (JNIEnv*, jobject, jlong addr)) 699 address target_addr = (address) addr; 700 if (target_addr != 0x0) { 701 int64_t off_low = (int64_t)target_addr - ((int64_t)CodeCache::low_bound() + sizeof(int)); 702 int64_t off_high = (int64_t)target_addr - ((int64_t)CodeCache::high_bound() + sizeof(int)); 703 return MAX2(ABS(off_low), ABS(off_high)); 704 } 705 return -1; 706 C2V_END 707 708 C2V_VMENTRY(void, doNotInlineOrCompile,(JNIEnv *, jobject, jobject jvmci_method)) 709 methodHandle method = CompilerToVM::asMethod(jvmci_method); 710 method->set_not_c1_compilable(); 711 method->set_not_c2_compilable(); 712 method->set_dont_inline(true); 713 C2V_END 714 715 C2V_VMENTRY(jint, installCode, (JNIEnv *jniEnv, jobject, jobject target, jobject compiled_code, jobject installed_code, jobject speculation_log)) 716 ResourceMark rm; 717 HandleMark hm; 718 Handle target_handle = JNIHandles::resolve(target); 719 Handle compiled_code_handle = JNIHandles::resolve(compiled_code); 720 CodeBlob* cb = NULL; 721 Handle installed_code_handle = JNIHandles::resolve(installed_code); 722 Handle speculation_log_handle = JNIHandles::resolve(speculation_log); 723 724 JVMCICompiler* compiler = JVMCICompiler::instance(CHECK_JNI_ERR); 725 726 TraceTime install_time("installCode", JVMCICompiler::codeInstallTimer()); 727 CodeInstaller installer; 728 JVMCIEnv::CodeInstallResult result = installer.install(compiler, target_handle, compiled_code_handle, cb, installed_code_handle, speculation_log_handle, CHECK_0); 729 730 if (PrintCodeCacheOnCompilation) { 731 stringStream s; 732 // Dump code cache into a buffer before locking the tty, 733 { 734 MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); 735 CodeCache::print_summary(&s, false); 736 } 737 ttyLocker ttyl; 738 tty->print_raw_cr(s.as_string()); 739 } 740 741 if (result != JVMCIEnv::ok) { 742 assert(cb == NULL, "should be"); 743 } else { 744 if (!installed_code_handle.is_null()) { 745 assert(installed_code_handle->is_a(InstalledCode::klass()), "wrong type"); 746 nmethod::invalidate_installed_code(installed_code_handle, CHECK_0); 747 { 748 // Ensure that all updates to the InstalledCode fields are consistent. 749 MutexLockerEx pl(Patching_lock, Mutex::_no_safepoint_check_flag); 750 InstalledCode::set_address(installed_code_handle, (jlong) cb); 751 InstalledCode::set_version(installed_code_handle, InstalledCode::version(installed_code_handle) + 1); 752 if (cb->is_nmethod()) { 753 InstalledCode::set_entryPoint(installed_code_handle, (jlong) cb->as_nmethod_or_null()->verified_entry_point()); 754 } else { 755 InstalledCode::set_entryPoint(installed_code_handle, (jlong) cb->code_begin()); 756 } 757 if (installed_code_handle->is_a(HotSpotInstalledCode::klass())) { 758 HotSpotInstalledCode::set_size(installed_code_handle, cb->size()); 759 HotSpotInstalledCode::set_codeStart(installed_code_handle, (jlong) cb->code_begin()); 760 HotSpotInstalledCode::set_codeSize(installed_code_handle, cb->code_size()); 761 } 762 } 763 nmethod* nm = cb->as_nmethod_or_null(); 764 if (nm != NULL && installed_code_handle->is_scavengable()) { 765 assert(nm->detect_scavenge_root_oops(), "nm should be scavengable if installed_code is scavengable"); 766 if (!UseG1GC) { 767 assert(nm->on_scavenge_root_list(), "nm should be on scavengable list"); 768 } 769 } 770 } 771 } 772 return result; 773 C2V_END 774 775 C2V_VMENTRY(jint, getMetadata, (JNIEnv *jniEnv, jobject, jobject target, jobject compiled_code, jobject metadata)) 776 ResourceMark rm; 777 HandleMark hm; 778 779 Handle target_handle = JNIHandles::resolve(target); 780 Handle compiled_code_handle = JNIHandles::resolve(compiled_code); 781 Handle metadata_handle = JNIHandles::resolve(metadata); 782 783 HotSpotOopMap::klass()->initialize(thread); 784 785 CodeMetadata code_metadata; 786 CodeBlob *cb = NULL; 787 CodeInstaller installer; 788 789 JVMCIEnv::CodeInstallResult result = installer.gather_metadata(target_handle, compiled_code_handle, code_metadata, CHECK_0); //cb, pc_descs, nr_pc_descs, scopes_descs, scopes_size, reloc_buffer); 790 if (result != JVMCIEnv::ok) { 791 return result; 792 } 793 794 if (code_metadata.get_nr_pc_desc() > 0) { 795 typeArrayHandle pcArrayOop = oopFactory::new_byteArray(sizeof(PcDesc) * code_metadata.get_nr_pc_desc(), CHECK_(JVMCIEnv::cache_full)); 796 memcpy(pcArrayOop->byte_at_addr(0), code_metadata.get_pc_desc(), sizeof(PcDesc) * code_metadata.get_nr_pc_desc()); 797 HotSpotMetaData::set_pcDescBytes(metadata_handle, pcArrayOop()); 798 } 799 800 if (code_metadata.get_scopes_size() > 0) { 801 typeArrayHandle scopesArrayOop = oopFactory::new_byteArray(code_metadata.get_scopes_size(), CHECK_(JVMCIEnv::cache_full)); 802 memcpy(scopesArrayOop->byte_at_addr(0), code_metadata.get_scopes_desc(), code_metadata.get_scopes_size()); 803 HotSpotMetaData::set_scopesDescBytes(metadata_handle, scopesArrayOop()); 804 } 805 806 RelocBuffer* reloc_buffer = code_metadata.get_reloc_buffer(); 807 typeArrayHandle relocArrayOop = oopFactory::new_byteArray((int) reloc_buffer->size(), CHECK_(JVMCIEnv::cache_full)); 808 if (reloc_buffer->size() > 0) { 809 memcpy(relocArrayOop->byte_at_addr(0), reloc_buffer->begin(), reloc_buffer->size()); 810 } 811 HotSpotMetaData::set_relocBytes(metadata_handle, relocArrayOop()); 812 813 const OopMapSet* oopMapSet = installer.oopMapSet(); 814 { 815 ResourceMark mark; 816 ImmutableOopMapBuilder builder(oopMapSet); 817 int oopmap_size = builder.heap_size(); 818 typeArrayHandle oopMapArrayHandle = oopFactory::new_byteArray(oopmap_size, CHECK_(JVMCIEnv::cache_full)); 819 builder.generate_into((address) oopMapArrayHandle->byte_at_addr(0)); 820 HotSpotMetaData::set_oopMaps(metadata_handle, oopMapArrayHandle()); 821 } 822 823 HotSpotMetaData::set_metadata(metadata_handle, NULL); 824 825 ExceptionHandlerTable* handler = code_metadata.get_exception_table(); 826 int table_size = handler->size_in_bytes(); 827 typeArrayHandle exceptionArrayOop = oopFactory::new_byteArray(table_size, CHECK_(JVMCIEnv::cache_full)); 828 829 if (table_size > 0) { 830 handler->copy_bytes_to((address) exceptionArrayOop->byte_at_addr(0)); 831 } 832 HotSpotMetaData::set_exceptionBytes(metadata_handle, exceptionArrayOop()); 833 834 return result; 835 C2V_END 836 837 C2V_VMENTRY(void, notifyCompilationStatistics, (JNIEnv *jniEnv, jobject, jint id, jobject hotspot_method, jboolean osr, jint processedBytecodes, jlong time, jlong timeUnitsPerSecond, jobject installed_code)) 838 JVMCICompiler* compiler = JVMCICompiler::instance(CHECK); 839 CompilerStatistics* stats = compiler->stats(); 840 841 elapsedTimer timer = elapsedTimer(time, timeUnitsPerSecond); 842 if (osr) { 843 stats->_osr.update(timer, processedBytecodes); 844 } else { 845 stats->_standard.update(timer, processedBytecodes); 846 } 847 Handle installed_code_handle = JNIHandles::resolve(installed_code); 848 if (installed_code_handle->is_a(HotSpotInstalledCode::klass())) { 849 stats->_nmethods_size += HotSpotInstalledCode::size(installed_code_handle); 850 stats->_nmethods_code_size += HotSpotInstalledCode::codeSize(installed_code_handle); 851 } 852 853 if (CITimeEach) { 854 methodHandle method = CompilerToVM::asMethod(hotspot_method); 855 float bytes_per_sec = 1.0 * processedBytecodes / timer.seconds(); 856 tty->print_cr("%3d seconds: %f bytes/sec: %f (bytes %d)", 857 id, timer.seconds(), bytes_per_sec, processedBytecodes); 858 } 859 C2V_END 860 861 C2V_VMENTRY(void, resetCompilationStatistics, (JNIEnv *jniEnv, jobject)) 862 JVMCICompiler* compiler = JVMCICompiler::instance(CHECK); 863 CompilerStatistics* stats = compiler->stats(); 864 stats->_standard.reset(); 865 stats->_osr.reset(); 866 C2V_END 867 868 C2V_VMENTRY(jobject, disassembleCodeBlob, (JNIEnv *jniEnv, jobject, jobject installedCode)) 869 ResourceMark rm; 870 HandleMark hm; 871 872 if (installedCode == NULL) { 873 THROW_MSG_NULL(vmSymbols::java_lang_NullPointerException(), "installedCode is null"); 874 } 875 876 jlong codeBlob = InstalledCode::address(installedCode); 877 if (codeBlob == 0L) { 878 return NULL; 879 } 880 881 CodeBlob* cb = (CodeBlob*) (address) codeBlob; 882 if (cb == NULL) { 883 return NULL; 884 } 885 886 // We don't want the stringStream buffer to resize during disassembly as it 887 // uses scoped resource memory. If a nested function called during disassembly uses 888 // a ResourceMark and the buffer expands within the scope of the mark, 889 // the buffer becomes garbage when that scope is exited. Experience shows that 890 // the disassembled code is typically about 10x the code size so a fixed buffer 891 // sized to 20x code size plus a fixed amount for header info should be sufficient. 892 int bufferSize = cb->code_size() * 20 + 1024; 893 char* buffer = NEW_RESOURCE_ARRAY(char, bufferSize); 894 stringStream st(buffer, bufferSize); 895 if (cb->is_nmethod()) { 896 nmethod* nm = (nmethod*) cb; 897 if (!nm->is_alive()) { 898 return NULL; 899 } 900 } 901 Disassembler::decode(cb, &st); 902 if (st.size() <= 0) { 903 return NULL; 904 } 905 906 Handle result = java_lang_String::create_from_platform_dependent_str(st.as_string(), CHECK_NULL); 907 return JNIHandles::make_local(THREAD, result()); 908 C2V_END 909 910 C2V_VMENTRY(jobject, getStackTraceElement, (JNIEnv*, jobject, jobject jvmci_method, int bci)) 911 ResourceMark rm; 912 HandleMark hm; 913 914 methodHandle method = CompilerToVM::asMethod(jvmci_method); 915 oop element = java_lang_StackTraceElement::create(method, bci, CHECK_NULL); 916 return JNIHandles::make_local(THREAD, element); 917 C2V_END 918 919 C2V_VMENTRY(jobject, executeInstalledCode, (JNIEnv*, jobject, jobject args, jobject hotspotInstalledCode)) 920 ResourceMark rm; 921 HandleMark hm; 922 923 jlong nmethodValue = InstalledCode::address(hotspotInstalledCode); 924 if (nmethodValue == 0L) { 925 THROW_NULL(vmSymbols::jdk_vm_ci_code_InvalidInstalledCodeException()); 926 } 927 nmethod* nm = (nmethod*) (address) nmethodValue; 928 methodHandle mh = nm->method(); 929 Symbol* signature = mh->signature(); 930 JavaCallArguments jca(mh->size_of_parameters()); 931 932 JavaArgumentUnboxer jap(signature, &jca, (arrayOop) JNIHandles::resolve(args), mh->is_static()); 933 JavaValue result(jap.get_ret_type()); 934 jca.set_alternative_target(nm); 935 JavaCalls::call(&result, mh, &jca, CHECK_NULL); 936 937 if (jap.get_ret_type() == T_VOID) { 938 return NULL; 939 } else if (jap.get_ret_type() == T_OBJECT || jap.get_ret_type() == T_ARRAY) { 940 return JNIHandles::make_local(THREAD, (oop) result.get_jobject()); 941 } else { 942 jvalue *value = (jvalue *) result.get_value_addr(); 943 // Narrow the value down if required (Important on big endian machines) 944 switch (jap.get_ret_type()) { 945 case T_BOOLEAN: 946 value->z = (jboolean) value->i; 947 break; 948 case T_BYTE: 949 value->b = (jbyte) value->i; 950 break; 951 case T_CHAR: 952 value->c = (jchar) value->i; 953 break; 954 case T_SHORT: 955 value->s = (jshort) value->i; 956 break; 957 } 958 oop o = java_lang_boxing_object::create(jap.get_ret_type(), value, CHECK_NULL); 959 return JNIHandles::make_local(THREAD, o); 960 } 961 C2V_END 962 963 C2V_VMENTRY(jlongArray, getLineNumberTable, (JNIEnv *, jobject, jobject jvmci_method)) 964 Method* method = CompilerToVM::asMethod(jvmci_method); 965 if (!method->has_linenumber_table()) { 966 return NULL; 967 } 968 u2 num_entries = 0; 969 CompressedLineNumberReadStream streamForSize(method->compressed_linenumber_table()); 970 while (streamForSize.read_pair()) { 971 num_entries++; 972 } 973 974 CompressedLineNumberReadStream stream(method->compressed_linenumber_table()); 975 typeArrayOop result = oopFactory::new_longArray(2 * num_entries, CHECK_NULL); 976 977 int i = 0; 978 jlong value; 979 while (stream.read_pair()) { 980 value = ((long) stream.bci()); 981 result->long_at_put(i, value); 982 value = ((long) stream.line()); 983 result->long_at_put(i + 1, value); 984 i += 2; 985 } 986 987 return (jlongArray) JNIHandles::make_local(THREAD, result); 988 C2V_END 989 990 C2V_VMENTRY(jlong, getLocalVariableTableStart, (JNIEnv *, jobject, jobject jvmci_method)) 991 ResourceMark rm; 992 Method* method = CompilerToVM::asMethod(jvmci_method); 993 if (!method->has_localvariable_table()) { 994 return 0; 995 } 996 return (jlong) (address) method->localvariable_table_start(); 997 C2V_END 998 999 C2V_VMENTRY(jint, getLocalVariableTableLength, (JNIEnv *, jobject, jobject jvmci_method)) 1000 ResourceMark rm; 1001 Method* method = CompilerToVM::asMethod(jvmci_method); 1002 return method->localvariable_table_length(); 1003 C2V_END 1004 1005 C2V_VMENTRY(void, reprofile, (JNIEnv*, jobject, jobject jvmci_method)) 1006 Method* method = CompilerToVM::asMethod(jvmci_method); 1007 MethodCounters* mcs = method->method_counters(); 1008 if (mcs != NULL) { 1009 mcs->clear_counters(); 1010 } 1011 NOT_PRODUCT(method->set_compiled_invocation_count(0)); 1012 1013 nmethod* code = method->code(); 1014 if (code != NULL) { 1015 code->make_not_entrant(); 1016 } 1017 1018 MethodData* method_data = method->method_data(); 1019 if (method_data == NULL) { 1020 ClassLoaderData* loader_data = method->method_holder()->class_loader_data(); 1021 method_data = MethodData::allocate(loader_data, method, CHECK); 1022 method->set_method_data(method_data); 1023 } else { 1024 method_data->initialize(); 1025 } 1026 C2V_END 1027 1028 1029 C2V_VMENTRY(void, invalidateInstalledCode, (JNIEnv*, jobject, jobject installed_code)) 1030 Handle installed_code_handle = JNIHandles::resolve(installed_code); 1031 nmethod::invalidate_installed_code(installed_code_handle, CHECK); 1032 C2V_END 1033 1034 C2V_VMENTRY(jobject, readUncompressedOop, (JNIEnv*, jobject, jlong addr)) 1035 oop ret = oopDesc::load_decode_heap_oop((oop*)(address)addr); 1036 return JNIHandles::make_local(THREAD, ret); 1037 C2V_END 1038 1039 C2V_VMENTRY(jlongArray, collectCounters, (JNIEnv*, jobject)) 1040 typeArrayOop arrayOop = oopFactory::new_longArray(JVMCICounterSize, CHECK_NULL); 1041 JavaThread::collect_counters(arrayOop); 1042 return (jlongArray) JNIHandles::make_local(THREAD, arrayOop); 1043 C2V_END 1044 1045 C2V_VMENTRY(int, allocateCompileId, (JNIEnv*, jobject, jobject jvmci_method, int entry_bci)) 1046 HandleMark hm; 1047 ResourceMark rm; 1048 if (JNIHandles::resolve(jvmci_method) == NULL) { 1049 THROW_0(vmSymbols::java_lang_NullPointerException()); 1050 } 1051 Method* method = CompilerToVM::asMethod(jvmci_method); 1052 if (entry_bci >= method->code_size() || entry_bci < -1) { 1053 THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), err_msg("Unexpected bci %d", entry_bci)); 1054 } 1055 return CompileBroker::assign_compile_id_unlocked(THREAD, method, entry_bci); 1056 C2V_END 1057 1058 1059 C2V_VMENTRY(jboolean, isMature, (JNIEnv*, jobject, jlong metaspace_method_data)) 1060 MethodData* mdo = CompilerToVM::asMethodData(metaspace_method_data); 1061 return mdo != NULL && mdo->is_mature(); 1062 C2V_END 1063 1064 C2V_VMENTRY(jboolean, hasCompiledCodeForOSR, (JNIEnv*, jobject, jobject jvmci_method, int entry_bci, int comp_level)) 1065 Method* method = CompilerToVM::asMethod(jvmci_method); 1066 return method->lookup_osr_nmethod_for(entry_bci, comp_level, true) != NULL; 1067 C2V_END 1068 1069 C2V_VMENTRY(jobject, getSymbol, (JNIEnv*, jobject, jlong symbol)) 1070 Handle sym = java_lang_String::create_from_symbol((Symbol*)(address)symbol, CHECK_NULL); 1071 return JNIHandles::make_local(THREAD, sym()); 1072 C2V_END 1073 1074 bool matches(jobjectArray methods, Method* method) { 1075 objArrayOop methods_oop = (objArrayOop) JNIHandles::resolve(methods); 1076 1077 for (int i = 0; i < methods_oop->length(); i++) { 1078 oop resolved = methods_oop->obj_at(i); 1079 if (resolved->is_a(HotSpotResolvedJavaMethodImpl::klass()) && CompilerToVM::asMethod(resolved) == method) { 1080 return true; 1081 } 1082 } 1083 return false; 1084 } 1085 1086 C2V_VMENTRY(jobject, getNextStackFrame, (JNIEnv*, jobject compilerToVM, jobject hs_frame, jobjectArray methods, jint initialSkip)) 1087 ResourceMark rm; 1088 1089 if (!thread->has_last_Java_frame()) return NULL; 1090 Handle result = HotSpotStackFrameReference::klass()->allocate_instance(thread); 1091 HotSpotStackFrameReference::klass()->initialize(thread); 1092 1093 StackFrameStream fst(thread); 1094 if (hs_frame != NULL) { 1095 // look for the correct stack frame if one is given 1096 intptr_t* stack_pointer = (intptr_t*) HotSpotStackFrameReference::stackPointer(hs_frame); 1097 while (fst.current()->sp() != stack_pointer && !fst.is_done()) { 1098 fst.next(); 1099 } 1100 if (fst.current()->sp() != stack_pointer) { 1101 THROW_MSG_NULL(vmSymbols::java_lang_IllegalStateException(), "stack frame not found") 1102 } 1103 } 1104 1105 int frame_number = 0; 1106 vframe* vf = vframe::new_vframe(fst.current(), fst.register_map(), thread); 1107 if (hs_frame != NULL) { 1108 // look for the correct vframe within the stack frame if one is given 1109 int last_frame_number = HotSpotStackFrameReference::frameNumber(hs_frame); 1110 while (frame_number < last_frame_number) { 1111 if (vf->is_top()) { 1112 THROW_MSG_NULL(vmSymbols::java_lang_IllegalStateException(), "invalid frame number") 1113 } 1114 vf = vf->sender(); 1115 frame_number ++; 1116 } 1117 // move one frame forward 1118 if (vf->is_top()) { 1119 if (fst.is_done()) { 1120 return NULL; 1121 } 1122 fst.next(); 1123 vf = vframe::new_vframe(fst.current(), fst.register_map(), thread); 1124 frame_number = 0; 1125 } else { 1126 vf = vf->sender(); 1127 frame_number++; 1128 } 1129 } 1130 1131 while (true) { 1132 // look for the given method 1133 while (true) { 1134 StackValueCollection* locals = NULL; 1135 if (vf->is_compiled_frame()) { 1136 // compiled method frame 1137 compiledVFrame* cvf = compiledVFrame::cast(vf); 1138 if (methods == NULL || matches(methods, cvf->method())) { 1139 if (initialSkip > 0) { 1140 initialSkip --; 1141 } else { 1142 ScopeDesc* scope = cvf->scope(); 1143 // native wrapper do not have a scope 1144 if (scope != NULL && scope->objects() != NULL) { 1145 bool realloc_failures = Deoptimization::realloc_objects(thread, fst.current(), scope->objects(), THREAD); 1146 Deoptimization::reassign_fields(fst.current(), fst.register_map(), scope->objects(), realloc_failures, false); 1147 1148 GrowableArray<ScopeValue*>* local_values = scope->locals(); 1149 typeArrayHandle array = oopFactory::new_boolArray(local_values->length(), thread); 1150 for (int i = 0; i < local_values->length(); i++) { 1151 ScopeValue* value = local_values->at(i); 1152 if (value->is_object()) { 1153 array->bool_at_put(i, true); 1154 } 1155 } 1156 HotSpotStackFrameReference::set_localIsVirtual(result, array()); 1157 } else { 1158 HotSpotStackFrameReference::set_localIsVirtual(result, NULL); 1159 } 1160 1161 locals = cvf->locals(); 1162 HotSpotStackFrameReference::set_bci(result, cvf->bci()); 1163 oop method = CompilerToVM::get_jvmci_method(cvf->method(), CHECK_NULL); 1164 HotSpotStackFrameReference::set_method(result, method); 1165 } 1166 } 1167 } else if (vf->is_interpreted_frame()) { 1168 // interpreted method frame 1169 interpretedVFrame* ivf = interpretedVFrame::cast(vf); 1170 if (methods == NULL || matches(methods, ivf->method())) { 1171 if (initialSkip > 0) { 1172 initialSkip --; 1173 } else { 1174 locals = ivf->locals(); 1175 HotSpotStackFrameReference::set_bci(result, ivf->bci()); 1176 oop method = CompilerToVM::get_jvmci_method(ivf->method(), CHECK_NULL); 1177 HotSpotStackFrameReference::set_method(result, method); 1178 HotSpotStackFrameReference::set_localIsVirtual(result, NULL); 1179 } 1180 } 1181 } 1182 1183 // locals != NULL means that we found a matching frame and result is already partially initialized 1184 if (locals != NULL) { 1185 HotSpotStackFrameReference::set_compilerToVM(result, JNIHandles::resolve(compilerToVM)); 1186 HotSpotStackFrameReference::set_stackPointer(result, (jlong) fst.current()->sp()); 1187 HotSpotStackFrameReference::set_frameNumber(result, frame_number); 1188 1189 // initialize the locals array 1190 objArrayHandle array = oopFactory::new_objectArray(locals->size(), thread); 1191 for (int i = 0; i < locals->size(); i++) { 1192 StackValue* var = locals->at(i); 1193 if (var->type() == T_OBJECT) { 1194 array->obj_at_put(i, locals->at(i)->get_obj()()); 1195 } 1196 } 1197 HotSpotStackFrameReference::set_locals(result, array()); 1198 1199 return JNIHandles::make_local(thread, result()); 1200 } 1201 1202 if (vf->is_top()) { 1203 break; 1204 } 1205 frame_number++; 1206 vf = vf->sender(); 1207 } // end of vframe loop 1208 1209 if (fst.is_done()) { 1210 break; 1211 } 1212 fst.next(); 1213 vf = vframe::new_vframe(fst.current(), fst.register_map(), thread); 1214 frame_number = 0; 1215 } // end of frame loop 1216 1217 // the end was reached without finding a matching method 1218 return NULL; 1219 C2V_END 1220 1221 C2V_VMENTRY(void, resolveInvokeDynamicInPool, (JNIEnv*, jobject, jobject jvmci_constant_pool, jint index)) 1222 constantPoolHandle cp = CompilerToVM::asConstantPool(jvmci_constant_pool); 1223 CallInfo callInfo; 1224 LinkResolver::resolve_invoke(callInfo, Handle(), cp, index, Bytecodes::_invokedynamic, CHECK); 1225 ConstantPoolCacheEntry* cp_cache_entry = cp->invokedynamic_cp_cache_entry_at(index); 1226 cp_cache_entry->set_dynamic_call(cp, callInfo); 1227 C2V_END 1228 1229 C2V_VMENTRY(void, resolveInvokeHandleInPool, (JNIEnv*, jobject, jobject jvmci_constant_pool, jint index)) 1230 constantPoolHandle cp = CompilerToVM::asConstantPool(jvmci_constant_pool); 1231 CallInfo callInfo; 1232 LinkResolver::resolve_invoke(callInfo, Handle(), cp, index, Bytecodes::_invokehandle, CHECK); 1233 ConstantPoolCacheEntry* cp_cache_entry = cp_cache_entry = cp->cache()->entry_at(cp->decode_cpcache_index(index)); 1234 cp_cache_entry->set_method_handle(cp, callInfo); 1235 C2V_END 1236 1237 C2V_VMENTRY(jboolean, shouldDebugNonSafepoints, (JNIEnv*, jobject)) 1238 //see compute_recording_non_safepoints in debugInfroRec.cpp 1239 if (JvmtiExport::should_post_compiled_method_load() && FLAG_IS_DEFAULT(DebugNonSafepoints)) { 1240 return true; 1241 } 1242 return DebugNonSafepoints; 1243 C2V_END 1244 1245 // public native void materializeVirtualObjects(HotSpotStackFrameReference stackFrame, boolean invalidate); 1246 C2V_VMENTRY(void, materializeVirtualObjects, (JNIEnv*, jobject, jobject hs_frame, bool invalidate)) 1247 ResourceMark rm; 1248 1249 if (hs_frame == NULL) { 1250 THROW_MSG(vmSymbols::java_lang_NullPointerException(), "stack frame is null") 1251 } 1252 1253 HotSpotStackFrameReference::klass()->initialize(thread); 1254 1255 // look for the given stack frame 1256 StackFrameStream fst(thread); 1257 intptr_t* stack_pointer = (intptr_t*) HotSpotStackFrameReference::stackPointer(hs_frame); 1258 while (fst.current()->sp() != stack_pointer && !fst.is_done()) { 1259 fst.next(); 1260 } 1261 if (fst.current()->sp() != stack_pointer) { 1262 THROW_MSG(vmSymbols::java_lang_IllegalStateException(), "stack frame not found") 1263 } 1264 1265 if (invalidate) { 1266 if (!fst.current()->is_compiled_frame()) { 1267 THROW_MSG(vmSymbols::java_lang_IllegalStateException(), "compiled stack frame expected") 1268 } 1269 assert(fst.current()->cb()->is_nmethod(), "nmethod expected"); 1270 ((nmethod*) fst.current()->cb())->make_not_entrant(); 1271 } 1272 Deoptimization::deoptimize(thread, *fst.current(), fst.register_map(), Deoptimization::Reason_none); 1273 // look for the frame again as it has been updated by deopt (pc, deopt state...) 1274 StackFrameStream fstAfterDeopt(thread); 1275 while (fstAfterDeopt.current()->sp() != stack_pointer && !fstAfterDeopt.is_done()) { 1276 fstAfterDeopt.next(); 1277 } 1278 if (fstAfterDeopt.current()->sp() != stack_pointer) { 1279 THROW_MSG(vmSymbols::java_lang_IllegalStateException(), "stack frame not found after deopt") 1280 } 1281 1282 vframe* vf = vframe::new_vframe(fstAfterDeopt.current(), fstAfterDeopt.register_map(), thread); 1283 if (!vf->is_compiled_frame()) { 1284 THROW_MSG(vmSymbols::java_lang_IllegalStateException(), "compiled stack frame expected") 1285 } 1286 1287 GrowableArray<compiledVFrame*>* virtualFrames = new GrowableArray<compiledVFrame*>(10); 1288 while (true) { 1289 assert(vf->is_compiled_frame(), "Wrong frame type"); 1290 virtualFrames->push(compiledVFrame::cast(vf)); 1291 if (vf->is_top()) { 1292 break; 1293 } 1294 vf = vf->sender(); 1295 } 1296 1297 int last_frame_number = HotSpotStackFrameReference::frameNumber(hs_frame); 1298 if (last_frame_number >= virtualFrames->length()) { 1299 THROW_MSG(vmSymbols::java_lang_IllegalStateException(), "invalid frame number") 1300 } 1301 1302 // Reallocate the non-escaping objects and restore their fields. 1303 assert (virtualFrames->at(last_frame_number)->scope() != NULL,"invalid scope"); 1304 GrowableArray<ScopeValue*>* objects = virtualFrames->at(last_frame_number)->scope()->objects(); 1305 1306 if (objects == NULL) { 1307 // no objects to materialize 1308 return; 1309 } 1310 1311 bool realloc_failures = Deoptimization::realloc_objects(thread, fstAfterDeopt.current(), objects, THREAD); 1312 Deoptimization::reassign_fields(fstAfterDeopt.current(), fstAfterDeopt.register_map(), objects, realloc_failures, false); 1313 1314 for (int frame_index = 0; frame_index < virtualFrames->length(); frame_index++) { 1315 compiledVFrame* cvf = virtualFrames->at(frame_index); 1316 1317 GrowableArray<ScopeValue*>* scopeLocals = cvf->scope()->locals(); 1318 StackValueCollection* locals = cvf->locals(); 1319 1320 if (locals != NULL) { 1321 for (int i2 = 0; i2 < locals->size(); i2++) { 1322 StackValue* var = locals->at(i2); 1323 if (var->type() == T_OBJECT && scopeLocals->at(i2)->is_object()) { 1324 jvalue val; 1325 val.l = (jobject) locals->at(i2)->get_obj()(); 1326 cvf->update_local(T_OBJECT, i2, val); 1327 } 1328 } 1329 } 1330 } 1331 1332 // all locals are materialized by now 1333 HotSpotStackFrameReference::set_localIsVirtual(hs_frame, NULL); 1334 1335 // update the locals array 1336 objArrayHandle array = HotSpotStackFrameReference::locals(hs_frame); 1337 StackValueCollection* locals = virtualFrames->at(last_frame_number)->locals(); 1338 for (int i = 0; i < locals->size(); i++) { 1339 StackValue* var = locals->at(i); 1340 if (var->type() == T_OBJECT) { 1341 array->obj_at_put(i, locals->at(i)->get_obj()()); 1342 } 1343 } 1344 C2V_END 1345 1346 C2V_VMENTRY(void, writeDebugOutput, (JNIEnv*, jobject, jbyteArray bytes, jint offset, jint length)) 1347 if (bytes == NULL) { 1348 THROW(vmSymbols::java_lang_NullPointerException()); 1349 } 1350 typeArrayOop array = (typeArrayOop) JNIHandles::resolve(bytes); 1351 1352 // Check if offset and length are non negative. 1353 if (offset < 0 || length < 0) { 1354 THROW(vmSymbols::java_lang_ArrayIndexOutOfBoundsException()); 1355 } 1356 // Check if the range is valid. 1357 if ((((unsigned int) length + (unsigned int) offset) > (unsigned int) array->length())) { 1358 THROW(vmSymbols::java_lang_ArrayIndexOutOfBoundsException()); 1359 } 1360 while (length > 0) { 1361 jbyte* start = array->byte_at_addr(offset); 1362 tty->write((char*) start, MIN2(length, O_BUFLEN)); 1363 length -= O_BUFLEN; 1364 offset += O_BUFLEN; 1365 } 1366 C2V_END 1367 1368 C2V_VMENTRY(void, flushDebugOutput, (JNIEnv*, jobject)) 1369 tty->flush(); 1370 C2V_END 1371 1372 C2V_VMENTRY(int, methodDataProfileDataSize, (JNIEnv*, jobject, jlong metaspace_method_data, jint position)) 1373 ResourceMark rm; 1374 MethodData* mdo = CompilerToVM::asMethodData(metaspace_method_data); 1375 ProfileData* profile_data = mdo->data_at(position); 1376 if (mdo->is_valid(profile_data)) { 1377 return profile_data->size_in_bytes(); 1378 } 1379 DataLayout* data = mdo->extra_data_base(); 1380 DataLayout* end = mdo->extra_data_limit(); 1381 for (;; data = mdo->next_extra(data)) { 1382 assert(data < end, "moved past end of extra data"); 1383 profile_data = data->data_in(); 1384 if (mdo->dp_to_di(profile_data->dp()) == position) { 1385 return profile_data->size_in_bytes(); 1386 } 1387 } 1388 THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), err_msg("Invalid profile data position %d", position)); 1389 C2V_END 1390 1391 1392 #define CC (char*) /*cast a literal from (const char*)*/ 1393 #define FN_PTR(f) CAST_FROM_FN_PTR(void*, &(c2v_ ## f)) 1394 1395 #define STRING "Ljava/lang/String;" 1396 #define OBJECT "Ljava/lang/Object;" 1397 #define CLASS "Ljava/lang/Class;" 1398 #define STACK_TRACE_ELEMENT "Ljava/lang/StackTraceElement;" 1399 #define INSTALLED_CODE "Ljdk/vm/ci/code/InstalledCode;" 1400 #define TARGET_DESCRIPTION "Ljdk/vm/ci/code/TargetDescription;" 1401 #define RESOLVED_METHOD "Ljdk/vm/ci/meta/ResolvedJavaMethod;" 1402 #define HS_RESOLVED_METHOD "Ljdk/vm/ci/hotspot/HotSpotResolvedJavaMethodImpl;" 1403 #define HS_RESOLVED_KLASS "Ljdk/vm/ci/hotspot/HotSpotResolvedObjectTypeImpl;" 1404 #define HS_CONSTANT_POOL "Ljdk/vm/ci/hotspot/HotSpotConstantPool;" 1405 #define HS_COMPILED_CODE "Ljdk/vm/ci/hotspot/HotSpotCompiledCode;" 1406 #define HS_CONFIG "Ljdk/vm/ci/hotspot/HotSpotVMConfig;" 1407 #define HS_METADATA "Ljdk/vm/ci/hotspot/HotSpotMetaData;" 1408 #define HS_STACK_FRAME_REF "Ljdk/vm/ci/hotspot/HotSpotStackFrameReference;" 1409 #define HS_SPECULATION_LOG "Ljdk/vm/ci/hotspot/HotSpotSpeculationLog;" 1410 #define METASPACE_METHOD_DATA "J" 1411 1412 JNINativeMethod CompilerToVM::methods[] = { 1413 {CC"getBytecode", CC"("HS_RESOLVED_METHOD")[B", FN_PTR(getBytecode)}, 1414 {CC"getExceptionTableStart", CC"("HS_RESOLVED_METHOD")J", FN_PTR(getExceptionTableStart)}, 1415 {CC"getExceptionTableLength", CC"("HS_RESOLVED_METHOD")I", FN_PTR(getExceptionTableLength)}, 1416 {CC"findUniqueConcreteMethod", CC"("HS_RESOLVED_KLASS HS_RESOLVED_METHOD")"HS_RESOLVED_METHOD, FN_PTR(findUniqueConcreteMethod)}, 1417 {CC"getImplementor", CC"("HS_RESOLVED_KLASS")"HS_RESOLVED_KLASS, FN_PTR(getImplementor)}, 1418 {CC"getStackTraceElement", CC"("HS_RESOLVED_METHOD"I)"STACK_TRACE_ELEMENT, FN_PTR(getStackTraceElement)}, 1419 {CC"methodIsIgnoredBySecurityStackWalk", CC"("HS_RESOLVED_METHOD")Z", FN_PTR(methodIsIgnoredBySecurityStackWalk)}, 1420 {CC"doNotInlineOrCompile", CC"("HS_RESOLVED_METHOD")V", FN_PTR(doNotInlineOrCompile)}, 1421 {CC"canInlineMethod", CC"("HS_RESOLVED_METHOD")Z", FN_PTR(canInlineMethod)}, 1422 {CC"shouldInlineMethod", CC"("HS_RESOLVED_METHOD")Z", FN_PTR(shouldInlineMethod)}, 1423 {CC"lookupType", CC"("STRING CLASS"Z)"HS_RESOLVED_KLASS, FN_PTR(lookupType)}, 1424 {CC"lookupNameInPool", CC"("HS_CONSTANT_POOL"I)"STRING, FN_PTR(lookupNameInPool)}, 1425 {CC"lookupNameAndTypeRefIndexInPool", CC"("HS_CONSTANT_POOL"I)I", FN_PTR(lookupNameAndTypeRefIndexInPool)}, 1426 {CC"lookupSignatureInPool", CC"("HS_CONSTANT_POOL"I)"STRING, FN_PTR(lookupSignatureInPool)}, 1427 {CC"lookupKlassRefIndexInPool", CC"("HS_CONSTANT_POOL"I)I", FN_PTR(lookupKlassRefIndexInPool)}, 1428 {CC"lookupKlassInPool", CC"("HS_CONSTANT_POOL"I)Ljava/lang/Object;", FN_PTR(lookupKlassInPool)}, 1429 {CC"lookupAppendixInPool", CC"("HS_CONSTANT_POOL"I)"OBJECT, FN_PTR(lookupAppendixInPool)}, 1430 {CC"lookupMethodInPool", CC"("HS_CONSTANT_POOL"IB)"HS_RESOLVED_METHOD, FN_PTR(lookupMethodInPool)}, 1431 {CC"constantPoolRemapInstructionOperandFromCache", CC"("HS_CONSTANT_POOL"I)I", FN_PTR(constantPoolRemapInstructionOperandFromCache)}, 1432 {CC"resolveConstantInPool", CC"("HS_CONSTANT_POOL"I)"OBJECT, FN_PTR(resolveConstantInPool)}, 1433 {CC"resolvePossiblyCachedConstantInPool", CC"("HS_CONSTANT_POOL"I)"OBJECT, FN_PTR(resolvePossiblyCachedConstantInPool)}, 1434 {CC"resolveTypeInPool", CC"("HS_CONSTANT_POOL"I)"HS_RESOLVED_KLASS, FN_PTR(resolveTypeInPool)}, 1435 {CC"resolveFieldInPool", CC"("HS_CONSTANT_POOL"IB[J)"HS_RESOLVED_KLASS, FN_PTR(resolveFieldInPool)}, 1436 {CC"resolveInvokeDynamicInPool", CC"("HS_CONSTANT_POOL"I)V", FN_PTR(resolveInvokeDynamicInPool)}, 1437 {CC"resolveInvokeHandleInPool", CC"("HS_CONSTANT_POOL"I)V", FN_PTR(resolveInvokeHandleInPool)}, 1438 {CC"resolveMethod", CC"("HS_RESOLVED_KLASS HS_RESOLVED_METHOD HS_RESOLVED_KLASS")"HS_RESOLVED_METHOD, FN_PTR(resolveMethod)}, 1439 {CC"getVtableIndexForInterfaceMethod", CC"("HS_RESOLVED_KLASS HS_RESOLVED_METHOD")I", FN_PTR(getVtableIndexForInterfaceMethod)}, 1440 {CC"getClassInitializer", CC"("HS_RESOLVED_KLASS")"HS_RESOLVED_METHOD, FN_PTR(getClassInitializer)}, 1441 {CC"hasFinalizableSubclass", CC"("HS_RESOLVED_KLASS")Z", FN_PTR(hasFinalizableSubclass)}, 1442 {CC"getMaxCallTargetOffset", CC"(J)J", FN_PTR(getMaxCallTargetOffset)}, 1443 {CC"getResolvedJavaMethodAtSlot", CC"("CLASS"I)"HS_RESOLVED_METHOD, FN_PTR(getResolvedJavaMethodAtSlot)}, 1444 {CC"getResolvedJavaMethod", CC"(Ljava/lang/Object;J)"HS_RESOLVED_METHOD, FN_PTR(getResolvedJavaMethod)}, 1445 {CC"getConstantPool", CC"(Ljava/lang/Object;J)"HS_CONSTANT_POOL, FN_PTR(getConstantPool)}, 1446 {CC"getResolvedJavaType", CC"(Ljava/lang/Object;JZ)"HS_RESOLVED_KLASS, FN_PTR(getResolvedJavaType)}, 1447 {CC"initializeConfiguration", CC"("HS_CONFIG")J", FN_PTR(initializeConfiguration)}, 1448 {CC"installCode", CC"("TARGET_DESCRIPTION HS_COMPILED_CODE INSTALLED_CODE HS_SPECULATION_LOG")I", FN_PTR(installCode)}, 1449 {CC"getMetadata", CC"("TARGET_DESCRIPTION HS_COMPILED_CODE HS_METADATA")I", FN_PTR(getMetadata)}, 1450 {CC"notifyCompilationStatistics", CC"(I"HS_RESOLVED_METHOD"ZIJJ"INSTALLED_CODE")V", FN_PTR(notifyCompilationStatistics)}, 1451 {CC"resetCompilationStatistics", CC"()V", FN_PTR(resetCompilationStatistics)}, 1452 {CC"disassembleCodeBlob", CC"("INSTALLED_CODE")"STRING, FN_PTR(disassembleCodeBlob)}, 1453 {CC"executeInstalledCode", CC"(["OBJECT INSTALLED_CODE")"OBJECT, FN_PTR(executeInstalledCode)}, 1454 {CC"getLineNumberTable", CC"("HS_RESOLVED_METHOD")[J", FN_PTR(getLineNumberTable)}, 1455 {CC"getLocalVariableTableStart", CC"("HS_RESOLVED_METHOD")J", FN_PTR(getLocalVariableTableStart)}, 1456 {CC"getLocalVariableTableLength", CC"("HS_RESOLVED_METHOD")I", FN_PTR(getLocalVariableTableLength)}, 1457 {CC"reprofile", CC"("HS_RESOLVED_METHOD")V", FN_PTR(reprofile)}, 1458 {CC"invalidateInstalledCode", CC"("INSTALLED_CODE")V", FN_PTR(invalidateInstalledCode)}, 1459 {CC"readUncompressedOop", CC"(J)"OBJECT, FN_PTR(readUncompressedOop)}, 1460 {CC"collectCounters", CC"()[J", FN_PTR(collectCounters)}, 1461 {CC"allocateCompileId", CC"("HS_RESOLVED_METHOD"I)I", FN_PTR(allocateCompileId)}, 1462 {CC"isMature", CC"("METASPACE_METHOD_DATA")Z", FN_PTR(isMature)}, 1463 {CC"hasCompiledCodeForOSR", CC"("HS_RESOLVED_METHOD"II)Z", FN_PTR(hasCompiledCodeForOSR)}, 1464 {CC"getSymbol", CC"(J)"STRING, FN_PTR(getSymbol)}, 1465 {CC"getNextStackFrame", CC"("HS_STACK_FRAME_REF "["RESOLVED_METHOD"I)"HS_STACK_FRAME_REF, FN_PTR(getNextStackFrame)}, 1466 {CC"materializeVirtualObjects", CC"("HS_STACK_FRAME_REF"Z)V", FN_PTR(materializeVirtualObjects)}, 1467 {CC"shouldDebugNonSafepoints", CC"()Z", FN_PTR(shouldDebugNonSafepoints)}, 1468 {CC"writeDebugOutput", CC"([BII)V", FN_PTR(writeDebugOutput)}, 1469 {CC"flushDebugOutput", CC"()V", FN_PTR(flushDebugOutput)}, 1470 {CC"methodDataProfileDataSize", CC"(JI)I", FN_PTR(methodDataProfileDataSize)}, 1471 }; 1472 1473 int CompilerToVM::methods_count() { 1474 return sizeof(methods) / sizeof(JNINativeMethod); 1475 } 1476