Path: blob/master/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp
40949 views
/*1* Copyright (c) 2011, 2021, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223#include "precompiled.hpp"24#include "classfile/classLoaderData.inline.hpp"25#include "classfile/javaClasses.inline.hpp"26#include "classfile/stringTable.hpp"27#include "classfile/symbolTable.hpp"28#include "classfile/systemDictionary.hpp"29#include "classfile/vmClasses.hpp"30#include "code/scopeDesc.hpp"31#include "compiler/compileBroker.hpp"32#include "compiler/compilerEvent.hpp"33#include "compiler/disassembler.hpp"34#include "compiler/oopMap.hpp"35#include "interpreter/linkResolver.hpp"36#include "interpreter/bytecodeStream.hpp"37#include "jfr/jfrEvents.hpp"38#include "jvmci/jvmciCompilerToVM.hpp"39#include "jvmci/jvmciCodeInstaller.hpp"40#include "jvmci/jvmciRuntime.hpp"41#include "logging/log.hpp"42#include "logging/logTag.hpp"43#include "memory/oopFactory.hpp"44#include "memory/universe.hpp"45#include "oops/constantPool.inline.hpp"46#include "oops/instanceMirrorKlass.hpp"47#include "oops/instanceKlass.inline.hpp"48#include "oops/method.inline.hpp"49#include "oops/typeArrayOop.inline.hpp"50#include "prims/jvmtiExport.hpp"51#include "prims/methodHandles.hpp"52#include "prims/nativeLookup.hpp"53#include "runtime/atomic.hpp"54#include "runtime/deoptimization.hpp"55#include "runtime/fieldDescriptor.inline.hpp"56#include "runtime/frame.inline.hpp"57#include "runtime/globals_extension.hpp"58#include "runtime/interfaceSupport.inline.hpp"59#include "runtime/jniHandles.inline.hpp"60#include "runtime/reflectionUtils.hpp"61#include "runtime/stackFrameStream.inline.hpp"62#include "runtime/timerTrace.hpp"63#include "runtime/vframe_hp.hpp"6465JVMCIKlassHandle::JVMCIKlassHandle(Thread* thread, Klass* klass) {66_thread = thread;67_klass = klass;68if (klass != NULL) {69_holder = Handle(_thread, klass->klass_holder());70}71}7273JVMCIKlassHandle& JVMCIKlassHandle::operator=(Klass* klass) {74_klass = klass;75if (klass != NULL) {76_holder = Handle(_thread, klass->klass_holder());77}78return *this;79}8081static void requireInHotSpot(const char* caller, JVMCI_TRAPS) {82if (!JVMCIENV->is_hotspot()) {83JVMCI_THROW_MSG(IllegalStateException, err_msg("Cannot call %s from JVMCI shared library", caller));84}85}8687void JNIHandleMark::push_jni_handle_block(JavaThread* thread) {88if (thread != NULL) {89// Allocate a new block for JNI handles.90// Inlined code from jni_PushLocalFrame()91JNIHandleBlock* java_handles = thread->active_handles();92JNIHandleBlock* compile_handles = JNIHandleBlock::allocate_block(thread);93assert(compile_handles != NULL && java_handles != NULL, "should not be NULL");94compile_handles->set_pop_frame_link(java_handles);95thread->set_active_handles(compile_handles);96}97}9899void JNIHandleMark::pop_jni_handle_block(JavaThread* thread) {100if (thread != NULL) {101// Release our JNI handle block102JNIHandleBlock* compile_handles = thread->active_handles();103JNIHandleBlock* java_handles = compile_handles->pop_frame_link();104thread->set_active_handles(java_handles);105compile_handles->set_pop_frame_link(NULL);106JNIHandleBlock::release_block(compile_handles, thread); // may block107}108}109110class JVMCITraceMark : public StackObj {111const char* _msg;112public:113JVMCITraceMark(const char* msg) {114_msg = msg;115JVMCI_event_2("Enter %s", _msg);116}117~JVMCITraceMark() {118JVMCI_event_2(" Exit %s", _msg);119}120};121122123Handle JavaArgumentUnboxer::next_arg(BasicType expectedType) {124assert(_index < _args->length(), "out of bounds");125oop arg=((objArrayOop) (_args))->obj_at(_index++);126assert(expectedType == T_OBJECT || java_lang_boxing_object::is_instance(arg, expectedType), "arg type mismatch");127return Handle(Thread::current(), arg);128}129130// Bring the JVMCI compiler thread into the VM state.131#define JVMCI_VM_ENTRY_MARK \132MACOS_AARCH64_ONLY(ThreadWXEnable __wx(WXWrite, thread)); \133ThreadInVMfromNative __tiv(thread); \134HandleMarkCleaner __hm(thread); \135JavaThread* THREAD = thread; \136debug_only(VMNativeEntryWrapper __vew;)137138// Native method block that transitions current thread to '_thread_in_vm'.139#define C2V_BLOCK(result_type, name, signature) \140JVMCI_VM_ENTRY_MARK; \141ResourceMark rm; \142JNI_JVMCIENV(JVMCI::compilation_tick(thread), env);143144static JavaThread* get_current_thread(bool allow_null=true) {145Thread* thread = Thread::current_or_null_safe();146if (thread == NULL) {147assert(allow_null, "npe");148return NULL;149}150return thread->as_Java_thread();151}152153// Entry to native method implementation that transitions154// current thread to '_thread_in_vm'.155#define C2V_VMENTRY(result_type, name, signature) \156JNIEXPORT result_type JNICALL c2v_ ## name signature { \157JavaThread* thread = get_current_thread(); \158if (thread == NULL) { \159env->ThrowNew(JNIJVMCI::InternalError::clazz(), \160err_msg("Cannot call into HotSpot from JVMCI shared library without attaching current thread")); \161return; \162} \163JVMCITraceMark jtm("CompilerToVM::" #name); \164C2V_BLOCK(result_type, name, signature)165166#define C2V_VMENTRY_(result_type, name, signature, result) \167JNIEXPORT result_type JNICALL c2v_ ## name signature { \168JavaThread* thread = get_current_thread(); \169if (thread == NULL) { \170env->ThrowNew(JNIJVMCI::InternalError::clazz(), \171err_msg("Cannot call into HotSpot from JVMCI shared library without attaching current thread")); \172return result; \173} \174JVMCITraceMark jtm("CompilerToVM::" #name); \175C2V_BLOCK(result_type, name, signature)176177#define C2V_VMENTRY_NULL(result_type, name, signature) C2V_VMENTRY_(result_type, name, signature, NULL)178#define C2V_VMENTRY_0(result_type, name, signature) C2V_VMENTRY_(result_type, name, signature, 0)179180// Entry to native method implementation that does not transition181// current thread to '_thread_in_vm'.182#define C2V_VMENTRY_PREFIX(result_type, name, signature) \183JNIEXPORT result_type JNICALL c2v_ ## name signature { \184JavaThread* thread = get_current_thread();185186#define C2V_END }187188#define JNI_THROW(caller, name, msg) do { \189jint __throw_res = env->ThrowNew(JNIJVMCI::name::clazz(), msg); \190if (__throw_res != JNI_OK) { \191tty->print_cr("Throwing " #name " in " caller " returned %d", __throw_res); \192} \193return; \194} while (0);195196#define JNI_THROW_(caller, name, msg, result) do { \197jint __throw_res = env->ThrowNew(JNIJVMCI::name::clazz(), msg); \198if (__throw_res != JNI_OK) { \199tty->print_cr("Throwing " #name " in " caller " returned %d", __throw_res); \200} \201return result; \202} while (0)203204jobjectArray readConfiguration0(JNIEnv *env, JVMCI_TRAPS);205206C2V_VMENTRY_NULL(jobjectArray, readConfiguration, (JNIEnv* env))207jobjectArray config = readConfiguration0(env, JVMCI_CHECK_NULL);208return config;209}210211C2V_VMENTRY_NULL(jobject, getFlagValue, (JNIEnv* env, jobject c2vm, jobject name_handle))212#define RETURN_BOXED_LONG(value) jvalue p; p.j = (jlong) (value); JVMCIObject box = JVMCIENV->create_box(T_LONG, &p, JVMCI_CHECK_NULL); return box.as_jobject();213#define RETURN_BOXED_DOUBLE(value) jvalue p; p.d = (jdouble) (value); JVMCIObject box = JVMCIENV->create_box(T_DOUBLE, &p, JVMCI_CHECK_NULL); return box.as_jobject();214JVMCIObject name = JVMCIENV->wrap(name_handle);215if (name.is_null()) {216JVMCI_THROW_NULL(NullPointerException);217}218const char* cstring = JVMCIENV->as_utf8_string(name);219const JVMFlag* flag = JVMFlag::find_declared_flag(cstring);220if (flag == NULL) {221return c2vm;222}223if (flag->is_bool()) {224jvalue prim;225prim.z = flag->get_bool();226JVMCIObject box = JVMCIENV->create_box(T_BOOLEAN, &prim, JVMCI_CHECK_NULL);227return JVMCIENV->get_jobject(box);228} else if (flag->is_ccstr()) {229JVMCIObject value = JVMCIENV->create_string(flag->get_ccstr(), JVMCI_CHECK_NULL);230return JVMCIENV->get_jobject(value);231} else if (flag->is_intx()) {232RETURN_BOXED_LONG(flag->get_intx());233} else if (flag->is_int()) {234RETURN_BOXED_LONG(flag->get_int());235} else if (flag->is_uint()) {236RETURN_BOXED_LONG(flag->get_uint());237} else if (flag->is_uint64_t()) {238RETURN_BOXED_LONG(flag->get_uint64_t());239} else if (flag->is_size_t()) {240RETURN_BOXED_LONG(flag->get_size_t());241} else if (flag->is_uintx()) {242RETURN_BOXED_LONG(flag->get_uintx());243} else if (flag->is_double()) {244RETURN_BOXED_DOUBLE(flag->get_double());245} else {246JVMCI_ERROR_NULL("VM flag %s has unsupported type %s", flag->name(), flag->type_string());247}248#undef RETURN_BOXED_LONG249#undef RETURN_BOXED_DOUBLE250C2V_END251252C2V_VMENTRY_NULL(jbyteArray, getBytecode, (JNIEnv* env, jobject, jobject jvmci_method))253methodHandle method(THREAD, JVMCIENV->asMethod(jvmci_method));254255int code_size = method->code_size();256jbyte* reconstituted_code = NEW_RESOURCE_ARRAY(jbyte, code_size);257258guarantee(method->method_holder()->is_rewritten(), "Method's holder should be rewritten");259// iterate over all bytecodes and replace non-Java bytecodes260261for (BytecodeStream s(method); s.next() != Bytecodes::_illegal; ) {262Bytecodes::Code code = s.code();263Bytecodes::Code raw_code = s.raw_code();264int bci = s.bci();265int len = s.instruction_size();266267// Restore original byte code.268reconstituted_code[bci] = (jbyte) (s.is_wide()? Bytecodes::_wide : code);269if (len > 1) {270memcpy(reconstituted_code + (bci + 1), s.bcp()+1, len-1);271}272273if (len > 1) {274// Restore the big-endian constant pool indexes.275// Cf. Rewriter::scan_method276switch (code) {277case Bytecodes::_getstatic:278case Bytecodes::_putstatic:279case Bytecodes::_getfield:280case Bytecodes::_putfield:281case Bytecodes::_invokevirtual:282case Bytecodes::_invokespecial:283case Bytecodes::_invokestatic:284case Bytecodes::_invokeinterface:285case Bytecodes::_invokehandle: {286int cp_index = Bytes::get_native_u2((address) reconstituted_code + (bci + 1));287Bytes::put_Java_u2((address) reconstituted_code + (bci + 1), (u2) cp_index);288break;289}290291case Bytecodes::_invokedynamic: {292int cp_index = Bytes::get_native_u4((address) reconstituted_code + (bci + 1));293Bytes::put_Java_u4((address) reconstituted_code + (bci + 1), (u4) cp_index);294break;295}296297default:298break;299}300301// Not all ldc byte code are rewritten.302switch (raw_code) {303case Bytecodes::_fast_aldc: {304int cpc_index = reconstituted_code[bci + 1] & 0xff;305int cp_index = method->constants()->object_to_cp_index(cpc_index);306assert(cp_index < method->constants()->length(), "sanity check");307reconstituted_code[bci + 1] = (jbyte) cp_index;308break;309}310311case Bytecodes::_fast_aldc_w: {312int cpc_index = Bytes::get_native_u2((address) reconstituted_code + (bci + 1));313int cp_index = method->constants()->object_to_cp_index(cpc_index);314assert(cp_index < method->constants()->length(), "sanity check");315Bytes::put_Java_u2((address) reconstituted_code + (bci + 1), (u2) cp_index);316break;317}318319default:320break;321}322}323}324325JVMCIPrimitiveArray result = JVMCIENV->new_byteArray(code_size, JVMCI_CHECK_NULL);326JVMCIENV->copy_bytes_from(reconstituted_code, result, 0, code_size);327return JVMCIENV->get_jbyteArray(result);328C2V_END329330C2V_VMENTRY_0(jint, getExceptionTableLength, (JNIEnv* env, jobject, jobject jvmci_method))331Method* method = JVMCIENV->asMethod(jvmci_method);332return method->exception_table_length();333C2V_END334335C2V_VMENTRY_0(jlong, getExceptionTableStart, (JNIEnv* env, jobject, jobject jvmci_method))336Method* method = JVMCIENV->asMethod(jvmci_method);337if (method->exception_table_length() == 0) {338return 0L;339}340return (jlong) (address) method->exception_table_start();341C2V_END342343C2V_VMENTRY_NULL(jobject, asResolvedJavaMethod, (JNIEnv* env, jobject, jobject executable_handle))344requireInHotSpot("asResolvedJavaMethod", JVMCI_CHECK_NULL);345oop executable = JNIHandles::resolve(executable_handle);346oop mirror = NULL;347int slot = 0;348349if (executable->klass() == vmClasses::reflect_Constructor_klass()) {350mirror = java_lang_reflect_Constructor::clazz(executable);351slot = java_lang_reflect_Constructor::slot(executable);352} else {353assert(executable->klass() == vmClasses::reflect_Method_klass(), "wrong type");354mirror = java_lang_reflect_Method::clazz(executable);355slot = java_lang_reflect_Method::slot(executable);356}357Klass* holder = java_lang_Class::as_Klass(mirror);358methodHandle method (THREAD, InstanceKlass::cast(holder)->method_with_idnum(slot));359JVMCIObject result = JVMCIENV->get_jvmci_method(method, JVMCI_CHECK_NULL);360return JVMCIENV->get_jobject(result);361}362363C2V_VMENTRY_NULL(jobject, getResolvedJavaMethod, (JNIEnv* env, jobject, jobject base, jlong offset))364Method* method = NULL;365JVMCIObject base_object = JVMCIENV->wrap(base);366if (base_object.is_null()) {367method = *((Method**)(offset));368} else if (JVMCIENV->isa_HotSpotObjectConstantImpl(base_object)) {369Handle obj = JVMCIENV->asConstant(base_object, JVMCI_CHECK_NULL);370if (obj->is_a(vmClasses::ResolvedMethodName_klass())) {371method = (Method*) (intptr_t) obj->long_field(offset);372} else {373JVMCI_THROW_MSG_NULL(IllegalArgumentException, err_msg("Unexpected type: %s", obj->klass()->external_name()));374}375} else if (JVMCIENV->isa_HotSpotResolvedJavaMethodImpl(base_object)) {376method = JVMCIENV->asMethod(base_object);377}378if (method == NULL) {379JVMCI_THROW_MSG_NULL(IllegalArgumentException, err_msg("Unexpected type: %s", JVMCIENV->klass_name(base_object)));380}381assert (method->is_method(), "invalid read");382JVMCIObject result = JVMCIENV->get_jvmci_method(methodHandle(THREAD, method), JVMCI_CHECK_NULL);383return JVMCIENV->get_jobject(result);384}385386C2V_VMENTRY_NULL(jobject, getConstantPool, (JNIEnv* env, jobject, jobject object_handle))387ConstantPool* cp = NULL;388JVMCIObject object = JVMCIENV->wrap(object_handle);389if (object.is_null()) {390JVMCI_THROW_NULL(NullPointerException);391}392if (JVMCIENV->isa_HotSpotResolvedJavaMethodImpl(object)) {393cp = JVMCIENV->asMethod(object)->constMethod()->constants();394} else if (JVMCIENV->isa_HotSpotResolvedObjectTypeImpl(object)) {395cp = InstanceKlass::cast(JVMCIENV->asKlass(object))->constants();396} else {397JVMCI_THROW_MSG_NULL(IllegalArgumentException,398err_msg("Unexpected type: %s", JVMCIENV->klass_name(object)));399}400assert(cp != NULL, "npe");401402JVMCIObject result = JVMCIENV->get_jvmci_constant_pool(constantPoolHandle(THREAD, cp), JVMCI_CHECK_NULL);403return JVMCIENV->get_jobject(result);404}405406C2V_VMENTRY_NULL(jobject, getResolvedJavaType0, (JNIEnv* env, jobject, jobject base, jlong offset, jboolean compressed))407JVMCIKlassHandle klass(THREAD);408JVMCIObject base_object = JVMCIENV->wrap(base);409jlong base_address = 0;410if (base_object.is_non_null() && offset == oopDesc::klass_offset_in_bytes()) {411// klass = JVMCIENV->unhandle(base_object)->klass();412if (JVMCIENV->isa_HotSpotObjectConstantImpl(base_object)) {413Handle base_oop = JVMCIENV->asConstant(base_object, JVMCI_CHECK_NULL);414klass = base_oop->klass();415} else {416assert(false, "What types are we actually expecting here?");417}418} else if (!compressed) {419if (base_object.is_non_null()) {420if (JVMCIENV->isa_HotSpotResolvedJavaMethodImpl(base_object)) {421base_address = (intptr_t) JVMCIENV->asMethod(base_object);422} else if (JVMCIENV->isa_HotSpotConstantPool(base_object)) {423base_address = (intptr_t) JVMCIENV->asConstantPool(base_object);424} else if (JVMCIENV->isa_HotSpotResolvedObjectTypeImpl(base_object)) {425base_address = (intptr_t) JVMCIENV->asKlass(base_object);426} else if (JVMCIENV->isa_HotSpotObjectConstantImpl(base_object)) {427Handle base_oop = JVMCIENV->asConstant(base_object, JVMCI_CHECK_NULL);428if (base_oop->is_a(vmClasses::Class_klass())) {429base_address = cast_from_oop<jlong>(base_oop());430}431}432if (base_address == 0) {433JVMCI_THROW_MSG_NULL(IllegalArgumentException,434err_msg("Unexpected arguments: %s " JLONG_FORMAT " %s", JVMCIENV->klass_name(base_object), offset, compressed ? "true" : "false"));435}436}437klass = *((Klass**) (intptr_t) (base_address + offset));438} else {439JVMCI_THROW_MSG_NULL(IllegalArgumentException,440err_msg("Unexpected arguments: %s " JLONG_FORMAT " %s",441base_object.is_non_null() ? JVMCIENV->klass_name(base_object) : "null",442offset, compressed ? "true" : "false"));443}444assert (klass == NULL || klass->is_klass(), "invalid read");445JVMCIObject result = JVMCIENV->get_jvmci_type(klass, JVMCI_CHECK_NULL);446return JVMCIENV->get_jobject(result);447}448449C2V_VMENTRY_NULL(jobject, findUniqueConcreteMethod, (JNIEnv* env, jobject, jobject jvmci_type, jobject jvmci_method))450methodHandle method (THREAD, JVMCIENV->asMethod(jvmci_method));451InstanceKlass* holder = InstanceKlass::cast(JVMCIENV->asKlass(jvmci_type));452if (holder->is_interface()) {453JVMCI_THROW_MSG_NULL(InternalError, err_msg("Interface %s should be handled in Java code", holder->external_name()));454}455if (method->can_be_statically_bound()) {456JVMCI_THROW_MSG_NULL(InternalError, err_msg("Effectively static method %s.%s should be handled in Java code", method->method_holder()->external_name(), method->external_name()));457}458459if (method->is_abstract()) {460return NULL;461}462463methodHandle ucm;464{465MutexLocker locker(Compile_lock);466ucm = methodHandle(THREAD, Dependencies::find_unique_concrete_method(holder, method()));467}468JVMCIObject result = JVMCIENV->get_jvmci_method(ucm, JVMCI_CHECK_NULL);469return JVMCIENV->get_jobject(result);470C2V_END471472C2V_VMENTRY_NULL(jobject, getImplementor, (JNIEnv* env, jobject, jobject jvmci_type))473Klass* klass = JVMCIENV->asKlass(jvmci_type);474if (!klass->is_interface()) {475THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(),476err_msg("Expected interface type, got %s", klass->external_name()));477}478InstanceKlass* iklass = InstanceKlass::cast(klass);479JVMCIKlassHandle handle(THREAD);480{481// Need Compile_lock around implementor()482MutexLocker locker(Compile_lock);483handle = iklass->implementor();484}485JVMCIObject implementor = JVMCIENV->get_jvmci_type(handle, JVMCI_CHECK_NULL);486return JVMCIENV->get_jobject(implementor);487C2V_END488489C2V_VMENTRY_0(jboolean, methodIsIgnoredBySecurityStackWalk,(JNIEnv* env, jobject, jobject jvmci_method))490Method* method = JVMCIENV->asMethod(jvmci_method);491return method->is_ignored_by_security_stack_walk();492C2V_END493494C2V_VMENTRY_0(jboolean, isCompilable,(JNIEnv* env, jobject, jobject jvmci_method))495Method* method = JVMCIENV->asMethod(jvmci_method);496// Skip redefined methods497if (method->is_old()) {498return false;499}500return !method->is_not_compilable(CompLevel_full_optimization);501C2V_END502503C2V_VMENTRY_0(jboolean, hasNeverInlineDirective,(JNIEnv* env, jobject, jobject jvmci_method))504methodHandle method (THREAD, JVMCIENV->asMethod(jvmci_method));505return !Inline || CompilerOracle::should_not_inline(method) || method->dont_inline();506C2V_END507508C2V_VMENTRY_0(jboolean, shouldInlineMethod,(JNIEnv* env, jobject, jobject jvmci_method))509methodHandle method (THREAD, JVMCIENV->asMethod(jvmci_method));510return CompilerOracle::should_inline(method) || method->force_inline();511C2V_END512513C2V_VMENTRY_NULL(jobject, lookupType, (JNIEnv* env, jobject, jstring jname, jclass accessing_class, jboolean resolve))514JVMCIObject name = JVMCIENV->wrap(jname);515const char* str = JVMCIENV->as_utf8_string(name);516TempNewSymbol class_name = SymbolTable::new_symbol(str);517518if (class_name->utf8_length() <= 1) {519JVMCI_THROW_MSG_0(InternalError, err_msg("Primitive type %s should be handled in Java code", class_name->as_C_string()));520}521522JVMCIKlassHandle resolved_klass(THREAD);523Klass* accessing_klass = NULL;524Handle class_loader;525Handle protection_domain;526if (accessing_class != NULL) {527accessing_klass = JVMCIENV->asKlass(accessing_class);528class_loader = Handle(THREAD, accessing_klass->class_loader());529protection_domain = Handle(THREAD, accessing_klass->protection_domain());530} else {531// Use the System class loader532class_loader = Handle(THREAD, SystemDictionary::java_system_loader());533JVMCIENV->runtime()->initialize(JVMCIENV);534}535536if (resolve) {537resolved_klass = SystemDictionary::resolve_or_null(class_name, class_loader, protection_domain, CHECK_NULL);538if (resolved_klass == NULL) {539JVMCI_THROW_MSG_NULL(ClassNotFoundException, str);540}541} else {542if (Signature::has_envelope(class_name)) {543// This is a name from a signature. Strip off the trimmings.544// Call recursive to keep scope of strippedsym.545TempNewSymbol strippedsym = Signature::strip_envelope(class_name);546resolved_klass = SystemDictionary::find_instance_klass(strippedsym,547class_loader,548protection_domain);549} else if (Signature::is_array(class_name)) {550SignatureStream ss(class_name, false);551int ndim = ss.skip_array_prefix();552if (ss.type() == T_OBJECT) {553Symbol* strippedsym = ss.as_symbol();554resolved_klass = SystemDictionary::find_instance_klass(strippedsym,555class_loader,556protection_domain);557if (!resolved_klass.is_null()) {558resolved_klass = resolved_klass->array_klass(ndim, CHECK_NULL);559}560} else {561resolved_klass = TypeArrayKlass::cast(Universe::typeArrayKlassObj(ss.type()))->array_klass(ndim, CHECK_NULL);562}563} else {564resolved_klass = SystemDictionary::find_instance_klass(class_name,565class_loader,566protection_domain);567}568}569JVMCIObject result = JVMCIENV->get_jvmci_type(resolved_klass, JVMCI_CHECK_NULL);570return JVMCIENV->get_jobject(result);571C2V_END572573C2V_VMENTRY_NULL(jobject, getArrayType, (JNIEnv* env, jobject, jobject jvmci_type))574if (jvmci_type == NULL) {575JVMCI_THROW_0(NullPointerException);576}577578JVMCIObject jvmci_type_object = JVMCIENV->wrap(jvmci_type);579JVMCIKlassHandle array_klass(THREAD);580if (JVMCIENV->isa_HotSpotResolvedPrimitiveType(jvmci_type_object)) {581BasicType type = JVMCIENV->kindToBasicType(JVMCIENV->get_HotSpotResolvedPrimitiveType_kind(jvmci_type_object), JVMCI_CHECK_0);582if (type == T_VOID) {583return NULL;584}585array_klass = Universe::typeArrayKlassObj(type);586if (array_klass == NULL) {587JVMCI_THROW_MSG_NULL(InternalError, err_msg("No array klass for primitive type %s", type2name(type)));588}589} else {590Klass* klass = JVMCIENV->asKlass(jvmci_type);591if (klass == NULL) {592JVMCI_THROW_0(NullPointerException);593}594array_klass = klass->array_klass(CHECK_NULL);595}596JVMCIObject result = JVMCIENV->get_jvmci_type(array_klass, JVMCI_CHECK_NULL);597return JVMCIENV->get_jobject(result);598C2V_END599600C2V_VMENTRY_NULL(jobject, lookupClass, (JNIEnv* env, jobject, jclass mirror))601requireInHotSpot("lookupClass", JVMCI_CHECK_NULL);602if (mirror == NULL) {603return NULL;604}605JVMCIKlassHandle klass(THREAD);606klass = java_lang_Class::as_Klass(JNIHandles::resolve(mirror));607if (klass == NULL) {608JVMCI_THROW_MSG_NULL(IllegalArgumentException, "Primitive classes are unsupported");609}610JVMCIObject result = JVMCIENV->get_jvmci_type(klass, JVMCI_CHECK_NULL);611return JVMCIENV->get_jobject(result);612}613614C2V_VMENTRY_NULL(jobject, resolvePossiblyCachedConstantInPool, (JNIEnv* env, jobject, jobject jvmci_constant_pool, jint index))615constantPoolHandle cp(THREAD, JVMCIENV->asConstantPool(jvmci_constant_pool));616oop obj = cp->resolve_possibly_cached_constant_at(index, CHECK_NULL);617constantTag tag = cp->tag_at(index);618if (tag.is_dynamic_constant() || tag.is_dynamic_constant_in_error()) {619if (obj == Universe::the_null_sentinel()) {620return JVMCIENV->get_jobject(JVMCIENV->get_JavaConstant_NULL_POINTER());621}622BasicType bt = Signature::basic_type(cp->uncached_signature_ref_at(index));623if (!is_reference_type(bt)) {624if (!is_java_primitive(bt)) {625return JVMCIENV->get_jobject(JVMCIENV->get_JavaConstant_ILLEGAL());626}627628// Convert standard box (e.g. java.lang.Integer) to JVMCI box (e.g. jdk.vm.ci.meta.PrimitiveConstant)629jvalue value;630jlong raw_value;631JVMCIObject kind;632BasicType bt2 = java_lang_boxing_object::get_value(obj, &value);633assert(bt2 == bt, "");634switch (bt2) {635case T_LONG: kind = JVMCIENV->get_JavaKind_Long(); raw_value = value.j; break;636case T_DOUBLE: kind = JVMCIENV->get_JavaKind_Double(); raw_value = value.j; break;637case T_FLOAT: kind = JVMCIENV->get_JavaKind_Float(); raw_value = value.i; break;638case T_INT: kind = JVMCIENV->get_JavaKind_Int(); raw_value = value.i; break;639case T_SHORT: kind = JVMCIENV->get_JavaKind_Short(); raw_value = value.s; break;640case T_BYTE: kind = JVMCIENV->get_JavaKind_Byte(); raw_value = value.b; break;641case T_CHAR: kind = JVMCIENV->get_JavaKind_Char(); raw_value = value.c; break;642case T_BOOLEAN: kind = JVMCIENV->get_JavaKind_Boolean(); raw_value = value.z; break;643default: return JVMCIENV->get_jobject(JVMCIENV->get_JavaConstant_ILLEGAL());644}645646JVMCIObject result = JVMCIENV->call_JavaConstant_forPrimitive(kind, raw_value, JVMCI_CHECK_NULL);647return JVMCIENV->get_jobject(result);648}649}650return JVMCIENV->get_jobject(JVMCIENV->get_object_constant(obj));651C2V_END652653C2V_VMENTRY_0(jint, lookupNameAndTypeRefIndexInPool, (JNIEnv* env, jobject, jobject jvmci_constant_pool, jint index))654constantPoolHandle cp(THREAD, JVMCIENV->asConstantPool(jvmci_constant_pool));655return cp->name_and_type_ref_index_at(index);656C2V_END657658C2V_VMENTRY_NULL(jobject, lookupNameInPool, (JNIEnv* env, jobject, jobject jvmci_constant_pool, jint which))659constantPoolHandle cp(THREAD, JVMCIENV->asConstantPool(jvmci_constant_pool));660JVMCIObject sym = JVMCIENV->create_string(cp->name_ref_at(which), JVMCI_CHECK_NULL);661return JVMCIENV->get_jobject(sym);662C2V_END663664C2V_VMENTRY_NULL(jobject, lookupSignatureInPool, (JNIEnv* env, jobject, jobject jvmci_constant_pool, jint which))665constantPoolHandle cp(THREAD, JVMCIENV->asConstantPool(jvmci_constant_pool));666JVMCIObject sym = JVMCIENV->create_string(cp->signature_ref_at(which), JVMCI_CHECK_NULL);667return JVMCIENV->get_jobject(sym);668C2V_END669670C2V_VMENTRY_0(jint, lookupKlassRefIndexInPool, (JNIEnv* env, jobject, jobject jvmci_constant_pool, jint index))671constantPoolHandle cp(THREAD, JVMCIENV->asConstantPool(jvmci_constant_pool));672return cp->klass_ref_index_at(index);673C2V_END674675C2V_VMENTRY_NULL(jobject, resolveTypeInPool, (JNIEnv* env, jobject, jobject jvmci_constant_pool, jint index))676constantPoolHandle cp(THREAD, JVMCIENV->asConstantPool(jvmci_constant_pool));677Klass* klass = cp->klass_at(index, CHECK_NULL);678JVMCIKlassHandle resolved_klass(THREAD, klass);679if (resolved_klass->is_instance_klass()) {680InstanceKlass::cast(resolved_klass())->link_class(CHECK_NULL);681if (!InstanceKlass::cast(resolved_klass())->is_linked()) {682// link_class() should not return here if there is an issue.683JVMCI_THROW_MSG_NULL(InternalError, err_msg("Class %s must be linked", resolved_klass()->external_name()));684}685}686JVMCIObject klassObject = JVMCIENV->get_jvmci_type(resolved_klass, JVMCI_CHECK_NULL);687return JVMCIENV->get_jobject(klassObject);688C2V_END689690C2V_VMENTRY_NULL(jobject, lookupKlassInPool, (JNIEnv* env, jobject, jobject jvmci_constant_pool, jint index, jbyte opcode))691constantPoolHandle cp(THREAD, JVMCIENV->asConstantPool(jvmci_constant_pool));692Klass* loading_klass = cp->pool_holder();693bool is_accessible = false;694JVMCIKlassHandle klass(THREAD, JVMCIRuntime::get_klass_by_index(cp, index, is_accessible, loading_klass));695Symbol* symbol = NULL;696if (klass.is_null()) {697constantTag tag = cp->tag_at(index);698if (tag.is_klass()) {699// The klass has been inserted into the constant pool700// very recently.701klass = cp->resolved_klass_at(index);702} else if (tag.is_symbol()) {703symbol = cp->symbol_at(index);704} else {705assert(cp->tag_at(index).is_unresolved_klass(), "wrong tag");706symbol = cp->klass_name_at(index);707}708}709JVMCIObject result;710if (!klass.is_null()) {711result = JVMCIENV->get_jvmci_type(klass, JVMCI_CHECK_NULL);712} else {713result = JVMCIENV->create_string(symbol, JVMCI_CHECK_NULL);714}715return JVMCIENV->get_jobject(result);716C2V_END717718C2V_VMENTRY_NULL(jobject, lookupAppendixInPool, (JNIEnv* env, jobject, jobject jvmci_constant_pool, jint index))719constantPoolHandle cp(THREAD, JVMCIENV->asConstantPool(jvmci_constant_pool));720oop appendix_oop = ConstantPool::appendix_at_if_loaded(cp, index);721return JVMCIENV->get_jobject(JVMCIENV->get_object_constant(appendix_oop));722C2V_END723724C2V_VMENTRY_NULL(jobject, lookupMethodInPool, (JNIEnv* env, jobject, jobject jvmci_constant_pool, jint index, jbyte opcode))725constantPoolHandle cp(THREAD, JVMCIENV->asConstantPool(jvmci_constant_pool));726InstanceKlass* pool_holder = cp->pool_holder();727Bytecodes::Code bc = (Bytecodes::Code) (((int) opcode) & 0xFF);728methodHandle method(THREAD, JVMCIRuntime::get_method_by_index(cp, index, bc, pool_holder));729JVMCIObject result = JVMCIENV->get_jvmci_method(method, JVMCI_CHECK_NULL);730return JVMCIENV->get_jobject(result);731C2V_END732733C2V_VMENTRY_0(jint, constantPoolRemapInstructionOperandFromCache, (JNIEnv* env, jobject, jobject jvmci_constant_pool, jint index))734constantPoolHandle cp(THREAD, JVMCIENV->asConstantPool(jvmci_constant_pool));735return cp->remap_instruction_operand_from_cache(index);736C2V_END737738C2V_VMENTRY_NULL(jobject, resolveFieldInPool, (JNIEnv* env, jobject, jobject jvmci_constant_pool, jint index, jobject jvmci_method, jbyte opcode, jintArray info_handle))739constantPoolHandle cp(THREAD, JVMCIENV->asConstantPool(jvmci_constant_pool));740Bytecodes::Code code = (Bytecodes::Code)(((int) opcode) & 0xFF);741fieldDescriptor fd;742methodHandle mh(THREAD, (jvmci_method != NULL) ? JVMCIENV->asMethod(jvmci_method) : NULL);743LinkInfo link_info(cp, index, mh, CHECK_NULL);744LinkResolver::resolve_field(fd, link_info, Bytecodes::java_code(code), false, CHECK_NULL);745JVMCIPrimitiveArray info = JVMCIENV->wrap(info_handle);746if (info.is_null() || JVMCIENV->get_length(info) != 3) {747JVMCI_ERROR_NULL("info must not be null and have a length of 3");748}749JVMCIENV->put_int_at(info, 0, fd.access_flags().as_int());750JVMCIENV->put_int_at(info, 1, fd.offset());751JVMCIENV->put_int_at(info, 2, fd.index());752JVMCIKlassHandle handle(THREAD, fd.field_holder());753JVMCIObject field_holder = JVMCIENV->get_jvmci_type(handle, JVMCI_CHECK_NULL);754return JVMCIENV->get_jobject(field_holder);755C2V_END756757C2V_VMENTRY_0(jint, getVtableIndexForInterfaceMethod, (JNIEnv* env, jobject, jobject jvmci_type, jobject jvmci_method))758Klass* klass = JVMCIENV->asKlass(jvmci_type);759methodHandle method(THREAD, JVMCIENV->asMethod(jvmci_method));760InstanceKlass* holder = method->method_holder();761if (klass->is_interface()) {762JVMCI_THROW_MSG_0(InternalError, err_msg("Interface %s should be handled in Java code", klass->external_name()));763}764if (!holder->is_interface()) {765JVMCI_THROW_MSG_0(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()));766}767if (!klass->is_instance_klass()) {768JVMCI_THROW_MSG_0(InternalError, err_msg("Class %s must be instance klass", klass->external_name()));769}770if (!InstanceKlass::cast(klass)->is_linked()) {771JVMCI_THROW_MSG_0(InternalError, err_msg("Class %s must be linked", klass->external_name()));772}773if (!klass->is_subtype_of(holder)) {774JVMCI_THROW_MSG_0(InternalError, err_msg("Class %s does not implement interface %s", klass->external_name(), holder->external_name()));775}776return LinkResolver::vtable_index_of_interface_method(klass, method);777C2V_END778779C2V_VMENTRY_NULL(jobject, resolveMethod, (JNIEnv* env, jobject, jobject receiver_jvmci_type, jobject jvmci_method, jobject caller_jvmci_type))780Klass* recv_klass = JVMCIENV->asKlass(receiver_jvmci_type);781Klass* caller_klass = JVMCIENV->asKlass(caller_jvmci_type);782methodHandle method(THREAD, JVMCIENV->asMethod(jvmci_method));783784Klass* resolved = method->method_holder();785Symbol* h_name = method->name();786Symbol* h_signature = method->signature();787788if (MethodHandles::is_signature_polymorphic_method(method())) {789// Signature polymorphic methods are already resolved, JVMCI just returns NULL in this case.790return NULL;791}792793if (method->name() == vmSymbols::clone_name() &&794resolved == vmClasses::Object_klass() &&795recv_klass->is_array_klass()) {796// Resolution of the clone method on arrays always returns Object.clone even though that method797// has protected access. There's some trickery in the access checking to make this all work out798// so it's necessary to pass in the array class as the resolved class to properly trigger this.799// Otherwise it's impossible to resolve the array clone methods through JVMCI. See800// LinkResolver::check_method_accessability for the matching logic.801resolved = recv_klass;802}803804LinkInfo link_info(resolved, h_name, h_signature, caller_klass);805Method* m = NULL;806// Only do exact lookup if receiver klass has been linked. Otherwise,807// the vtable has not been setup, and the LinkResolver will fail.808if (recv_klass->is_array_klass() ||809(InstanceKlass::cast(recv_klass)->is_linked() && !recv_klass->is_interface())) {810if (resolved->is_interface()) {811m = LinkResolver::resolve_interface_call_or_null(recv_klass, link_info);812} else {813m = LinkResolver::resolve_virtual_call_or_null(recv_klass, link_info);814}815}816817if (m == NULL) {818// Return NULL if there was a problem with lookup (uninitialized class, etc.)819return NULL;820}821822JVMCIObject result = JVMCIENV->get_jvmci_method(methodHandle(THREAD, m), JVMCI_CHECK_NULL);823return JVMCIENV->get_jobject(result);824C2V_END825826C2V_VMENTRY_0(jboolean, hasFinalizableSubclass,(JNIEnv* env, jobject, jobject jvmci_type))827Klass* klass = JVMCIENV->asKlass(jvmci_type);828assert(klass != NULL, "method must not be called for primitive types");829if (!klass->is_instance_klass()) {830return false;831}832InstanceKlass* iklass = InstanceKlass::cast(klass);833return Dependencies::find_finalizable_subclass(iklass) != NULL;834C2V_END835836C2V_VMENTRY_NULL(jobject, getClassInitializer, (JNIEnv* env, jobject, jobject jvmci_type))837Klass* klass = JVMCIENV->asKlass(jvmci_type);838if (!klass->is_instance_klass()) {839return NULL;840}841InstanceKlass* iklass = InstanceKlass::cast(klass);842methodHandle clinit(THREAD, iklass->class_initializer());843JVMCIObject result = JVMCIENV->get_jvmci_method(clinit, JVMCI_CHECK_NULL);844return JVMCIENV->get_jobject(result);845C2V_END846847C2V_VMENTRY_0(jlong, getMaxCallTargetOffset, (JNIEnv* env, jobject, jlong addr))848address target_addr = (address) addr;849if (target_addr != 0x0) {850int64_t off_low = (int64_t)target_addr - ((int64_t)CodeCache::low_bound() + sizeof(int));851int64_t off_high = (int64_t)target_addr - ((int64_t)CodeCache::high_bound() + sizeof(int));852return MAX2(ABS(off_low), ABS(off_high));853}854return -1;855C2V_END856857C2V_VMENTRY(void, setNotInlinableOrCompilable,(JNIEnv* env, jobject, jobject jvmci_method))858methodHandle method(THREAD, JVMCIENV->asMethod(jvmci_method));859method->set_not_c1_compilable();860method->set_not_c2_compilable();861method->set_dont_inline(true);862C2V_END863864C2V_VMENTRY_0(jint, installCode, (JNIEnv *env, jobject, jobject target, jobject compiled_code,865jobject installed_code, jlong failed_speculations_address, jbyteArray speculations_obj))866HandleMark hm(THREAD);867JNIHandleMark jni_hm(thread);868869JVMCIObject target_handle = JVMCIENV->wrap(target);870JVMCIObject compiled_code_handle = JVMCIENV->wrap(compiled_code);871CodeBlob* cb = NULL;872JVMCIObject installed_code_handle = JVMCIENV->wrap(installed_code);873JVMCIPrimitiveArray speculations_handle = JVMCIENV->wrap(speculations_obj);874875int speculations_len = JVMCIENV->get_length(speculations_handle);876char* speculations = NEW_RESOURCE_ARRAY(char, speculations_len);877JVMCIENV->copy_bytes_to(speculations_handle, (jbyte*) speculations, 0, speculations_len);878879JVMCICompiler* compiler = JVMCICompiler::instance(true, CHECK_JNI_ERR);880881TraceTime install_time("installCode", JVMCICompiler::codeInstallTimer(!thread->is_Compiler_thread()));882883CodeInstaller installer(JVMCIENV);884JVMCI::CodeInstallResult result = installer.install(compiler,885target_handle,886compiled_code_handle,887cb,888installed_code_handle,889(FailedSpeculation**)(address) failed_speculations_address,890speculations,891speculations_len,892JVMCI_CHECK_0);893894if (PrintCodeCacheOnCompilation) {895stringStream s;896// Dump code cache into a buffer before locking the tty,897{898MutexLocker mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);899CodeCache::print_summary(&s, false);900}901ttyLocker ttyl;902tty->print_raw_cr(s.as_string());903}904905if (result != JVMCI::ok) {906assert(cb == NULL, "should be");907} else {908if (installed_code_handle.is_non_null()) {909if (cb->is_nmethod()) {910assert(JVMCIENV->isa_HotSpotNmethod(installed_code_handle), "wrong type");911// Clear the link to an old nmethod first912JVMCIObject nmethod_mirror = installed_code_handle;913JVMCIENV->invalidate_nmethod_mirror(nmethod_mirror, JVMCI_CHECK_0);914} else {915assert(JVMCIENV->isa_InstalledCode(installed_code_handle), "wrong type");916}917// Initialize the link to the new code blob918JVMCIENV->initialize_installed_code(installed_code_handle, cb, JVMCI_CHECK_0);919}920}921return result;922C2V_END923924C2V_VMENTRY_0(jint, getMetadata, (JNIEnv *env, jobject, jobject target, jobject compiled_code, jobject metadata))925JVMCI_THROW_MSG_0(InternalError, "unimplemented");926C2V_END927928C2V_VMENTRY(void, resetCompilationStatistics, (JNIEnv* env, jobject))929JVMCICompiler* compiler = JVMCICompiler::instance(true, CHECK);930CompilerStatistics* stats = compiler->stats();931stats->_standard.reset();932stats->_osr.reset();933C2V_END934935C2V_VMENTRY_NULL(jobject, disassembleCodeBlob, (JNIEnv* env, jobject, jobject installedCode))936HandleMark hm(THREAD);937938if (installedCode == NULL) {939JVMCI_THROW_MSG_NULL(NullPointerException, "installedCode is null");940}941942JVMCIObject installedCodeObject = JVMCIENV->wrap(installedCode);943nmethodLocker locker;944CodeBlob* cb = JVMCIENV->get_code_blob(installedCodeObject, locker);945if (cb == NULL) {946return NULL;947}948949// We don't want the stringStream buffer to resize during disassembly as it950// uses scoped resource memory. If a nested function called during disassembly uses951// a ResourceMark and the buffer expands within the scope of the mark,952// the buffer becomes garbage when that scope is exited. Experience shows that953// the disassembled code is typically about 10x the code size so a fixed buffer954// sized to 20x code size plus a fixed amount for header info should be sufficient.955int bufferSize = cb->code_size() * 20 + 1024;956char* buffer = NEW_RESOURCE_ARRAY(char, bufferSize);957stringStream st(buffer, bufferSize);958if (cb->is_nmethod()) {959nmethod* nm = (nmethod*) cb;960if (!nm->is_alive()) {961return NULL;962}963}964Disassembler::decode(cb, &st);965if (st.size() <= 0) {966return NULL;967}968969JVMCIObject result = JVMCIENV->create_string(st.as_string(), JVMCI_CHECK_NULL);970return JVMCIENV->get_jobject(result);971C2V_END972973C2V_VMENTRY_NULL(jobject, getStackTraceElement, (JNIEnv* env, jobject, jobject jvmci_method, int bci))974HandleMark hm(THREAD);975976methodHandle method(THREAD, JVMCIENV->asMethod(jvmci_method));977JVMCIObject element = JVMCIENV->new_StackTraceElement(method, bci, JVMCI_CHECK_NULL);978return JVMCIENV->get_jobject(element);979C2V_END980981C2V_VMENTRY_NULL(jobject, executeHotSpotNmethod, (JNIEnv* env, jobject, jobject args, jobject hs_nmethod))982// The incoming arguments array would have to contain JavaConstants instead of regular objects983// and the return value would have to be wrapped as a JavaConstant.984requireInHotSpot("executeHotSpotNmethod", JVMCI_CHECK_NULL);985986HandleMark hm(THREAD);987988JVMCIObject nmethod_mirror = JVMCIENV->wrap(hs_nmethod);989nmethodLocker locker;990nmethod* nm = JVMCIENV->get_nmethod(nmethod_mirror, locker);991if (nm == NULL || !nm->is_in_use()) {992JVMCI_THROW_NULL(InvalidInstalledCodeException);993}994methodHandle mh(THREAD, nm->method());995Symbol* signature = mh->signature();996JavaCallArguments jca(mh->size_of_parameters());997998JavaArgumentUnboxer jap(signature, &jca, (arrayOop) JNIHandles::resolve(args), mh->is_static());999JavaValue result(jap.return_type());1000jca.set_alternative_target(Handle(THREAD, JNIHandles::resolve(nmethod_mirror.as_jobject())));1001JavaCalls::call(&result, mh, &jca, CHECK_NULL);10021003if (jap.return_type() == T_VOID) {1004return NULL;1005} else if (is_reference_type(jap.return_type())) {1006return JNIHandles::make_local(THREAD, result.get_oop());1007} else {1008jvalue *value = (jvalue *) result.get_value_addr();1009// Narrow the value down if required (Important on big endian machines)1010switch (jap.return_type()) {1011case T_BOOLEAN:1012value->z = (jboolean) value->i;1013break;1014case T_BYTE:1015value->b = (jbyte) value->i;1016break;1017case T_CHAR:1018value->c = (jchar) value->i;1019break;1020case T_SHORT:1021value->s = (jshort) value->i;1022break;1023default:1024break;1025}1026JVMCIObject o = JVMCIENV->create_box(jap.return_type(), value, JVMCI_CHECK_NULL);1027return JVMCIENV->get_jobject(o);1028}1029C2V_END10301031C2V_VMENTRY_NULL(jlongArray, getLineNumberTable, (JNIEnv* env, jobject, jobject jvmci_method))1032Method* method = JVMCIENV->asMethod(jvmci_method);1033if (!method->has_linenumber_table()) {1034return NULL;1035}1036u2 num_entries = 0;1037CompressedLineNumberReadStream streamForSize(method->compressed_linenumber_table());1038while (streamForSize.read_pair()) {1039num_entries++;1040}10411042CompressedLineNumberReadStream stream(method->compressed_linenumber_table());1043JVMCIPrimitiveArray result = JVMCIENV->new_longArray(2 * num_entries, JVMCI_CHECK_NULL);10441045int i = 0;1046jlong value;1047while (stream.read_pair()) {1048value = ((long) stream.bci());1049JVMCIENV->put_long_at(result, i, value);1050value = ((long) stream.line());1051JVMCIENV->put_long_at(result, i + 1, value);1052i += 2;1053}10541055return (jlongArray) JVMCIENV->get_jobject(result);1056C2V_END10571058C2V_VMENTRY_0(jlong, getLocalVariableTableStart, (JNIEnv* env, jobject, jobject jvmci_method))1059Method* method = JVMCIENV->asMethod(jvmci_method);1060if (!method->has_localvariable_table()) {1061return 0;1062}1063return (jlong) (address) method->localvariable_table_start();1064C2V_END10651066C2V_VMENTRY_0(jint, getLocalVariableTableLength, (JNIEnv* env, jobject, jobject jvmci_method))1067Method* method = JVMCIENV->asMethod(jvmci_method);1068return method->localvariable_table_length();1069C2V_END10701071C2V_VMENTRY(void, reprofile, (JNIEnv* env, jobject, jobject jvmci_method))1072methodHandle method(THREAD, JVMCIENV->asMethod(jvmci_method));1073MethodCounters* mcs = method->method_counters();1074if (mcs != NULL) {1075mcs->clear_counters();1076}1077NOT_PRODUCT(method->set_compiled_invocation_count(0));10781079CompiledMethod* code = method->code();1080if (code != NULL) {1081code->make_not_entrant();1082}10831084MethodData* method_data = method->method_data();1085if (method_data == NULL) {1086ClassLoaderData* loader_data = method->method_holder()->class_loader_data();1087method_data = MethodData::allocate(loader_data, method, CHECK);1088method->set_method_data(method_data);1089} else {1090method_data->initialize();1091}1092C2V_END109310941095C2V_VMENTRY(void, invalidateHotSpotNmethod, (JNIEnv* env, jobject, jobject hs_nmethod))1096JVMCIObject nmethod_mirror = JVMCIENV->wrap(hs_nmethod);1097JVMCIENV->invalidate_nmethod_mirror(nmethod_mirror, JVMCI_CHECK);1098C2V_END10991100C2V_VMENTRY_NULL(jlongArray, collectCounters, (JNIEnv* env, jobject))1101// Returns a zero length array if counters aren't enabled1102JVMCIPrimitiveArray array = JVMCIENV->new_longArray(JVMCICounterSize, JVMCI_CHECK_NULL);1103if (JVMCICounterSize > 0) {1104jlong* temp_array = NEW_RESOURCE_ARRAY(jlong, JVMCICounterSize);1105JavaThread::collect_counters(temp_array, JVMCICounterSize);1106JVMCIENV->copy_longs_from(temp_array, array, 0, JVMCICounterSize);1107}1108return (jlongArray) JVMCIENV->get_jobject(array);1109C2V_END11101111C2V_VMENTRY_0(jint, getCountersSize, (JNIEnv* env, jobject))1112return (jint) JVMCICounterSize;1113C2V_END11141115C2V_VMENTRY_0(jboolean, setCountersSize, (JNIEnv* env, jobject, jint new_size))1116return JavaThread::resize_all_jvmci_counters(new_size);1117C2V_END11181119C2V_VMENTRY_0(jint, allocateCompileId, (JNIEnv* env, jobject, jobject jvmci_method, int entry_bci))1120HandleMark hm(THREAD);1121if (jvmci_method == NULL) {1122JVMCI_THROW_0(NullPointerException);1123}1124methodHandle method(THREAD, JVMCIENV->asMethod(jvmci_method));1125if (entry_bci >= method->code_size() || entry_bci < -1) {1126JVMCI_THROW_MSG_0(IllegalArgumentException, err_msg("Unexpected bci %d", entry_bci));1127}1128return CompileBroker::assign_compile_id_unlocked(THREAD, method, entry_bci);1129C2V_END113011311132C2V_VMENTRY_0(jboolean, isMature, (JNIEnv* env, jobject, jlong metaspace_method_data))1133MethodData* mdo = JVMCIENV->asMethodData(metaspace_method_data);1134return mdo != NULL && mdo->is_mature();1135C2V_END11361137C2V_VMENTRY_0(jboolean, hasCompiledCodeForOSR, (JNIEnv* env, jobject, jobject jvmci_method, int entry_bci, int comp_level))1138Method* method = JVMCIENV->asMethod(jvmci_method);1139return method->lookup_osr_nmethod_for(entry_bci, comp_level, true) != NULL;1140C2V_END11411142C2V_VMENTRY_NULL(jobject, getSymbol, (JNIEnv* env, jobject, jlong symbol))1143JVMCIObject sym = JVMCIENV->create_string((Symbol*)(address)symbol, JVMCI_CHECK_NULL);1144return JVMCIENV->get_jobject(sym);1145C2V_END11461147bool matches(jobjectArray methods, Method* method, JVMCIEnv* JVMCIENV) {1148objArrayOop methods_oop = (objArrayOop) JNIHandles::resolve(methods);11491150for (int i = 0; i < methods_oop->length(); i++) {1151oop resolved = methods_oop->obj_at(i);1152if ((resolved->klass() == HotSpotJVMCI::HotSpotResolvedJavaMethodImpl::klass()) && HotSpotJVMCI::asMethod(JVMCIENV, resolved) == method) {1153return true;1154}1155}1156return false;1157}11581159void call_interface(JavaValue* result, Klass* spec_klass, Symbol* name, Symbol* signature, JavaCallArguments* args, TRAPS) {1160CallInfo callinfo;1161Handle receiver = args->receiver();1162Klass* recvrKlass = receiver.is_null() ? (Klass*)NULL : receiver->klass();1163LinkInfo link_info(spec_klass, name, signature);1164LinkResolver::resolve_interface_call(1165callinfo, receiver, recvrKlass, link_info, true, CHECK);1166methodHandle method(THREAD, callinfo.selected_method());1167assert(method.not_null(), "should have thrown exception");11681169// Invoke the method1170JavaCalls::call(result, method, args, CHECK);1171}11721173C2V_VMENTRY_NULL(jobject, iterateFrames, (JNIEnv* env, jobject compilerToVM, jobjectArray initial_methods, jobjectArray match_methods, jint initialSkip, jobject visitor_handle))11741175if (!thread->has_last_Java_frame()) {1176return NULL;1177}1178Handle visitor(THREAD, JNIHandles::resolve_non_null(visitor_handle));11791180requireInHotSpot("iterateFrames", JVMCI_CHECK_NULL);11811182HotSpotJVMCI::HotSpotStackFrameReference::klass()->initialize(CHECK_NULL);1183Handle frame_reference = HotSpotJVMCI::HotSpotStackFrameReference::klass()->allocate_instance_handle(CHECK_NULL);11841185StackFrameStream fst(thread, true /* update */, true /* process_frames */);1186jobjectArray methods = initial_methods;11871188int frame_number = 0;1189vframe* vf = vframe::new_vframe(fst, thread);11901191while (true) {1192// look for the given method1193bool realloc_called = false;1194while (true) {1195StackValueCollection* locals = NULL;1196if (vf->is_compiled_frame()) {1197// compiled method frame1198compiledVFrame* cvf = compiledVFrame::cast(vf);1199if (methods == NULL || matches(methods, cvf->method(), JVMCIENV)) {1200if (initialSkip > 0) {1201initialSkip--;1202} else {1203ScopeDesc* scope = cvf->scope();1204// native wrappers do not have a scope1205if (scope != NULL && scope->objects() != NULL) {1206GrowableArray<ScopeValue*>* objects;1207if (!realloc_called) {1208objects = scope->objects();1209} else {1210// some object might already have been re-allocated, only reallocate the non-allocated ones1211objects = new GrowableArray<ScopeValue*>(scope->objects()->length());1212for (int i = 0; i < scope->objects()->length(); i++) {1213ObjectValue* sv = (ObjectValue*) scope->objects()->at(i);1214if (sv->value().is_null()) {1215objects->append(sv);1216}1217}1218}1219bool realloc_failures = Deoptimization::realloc_objects(thread, fst.current(), fst.register_map(), objects, CHECK_NULL);1220Deoptimization::reassign_fields(fst.current(), fst.register_map(), objects, realloc_failures, false);1221realloc_called = true;12221223GrowableArray<ScopeValue*>* local_values = scope->locals();1224assert(local_values != NULL, "NULL locals");1225typeArrayOop array_oop = oopFactory::new_boolArray(local_values->length(), CHECK_NULL);1226typeArrayHandle array(THREAD, array_oop);1227for (int i = 0; i < local_values->length(); i++) {1228ScopeValue* value = local_values->at(i);1229if (value->is_object()) {1230array->bool_at_put(i, true);1231}1232}1233HotSpotJVMCI::HotSpotStackFrameReference::set_localIsVirtual(JVMCIENV, frame_reference(), array());1234} else {1235HotSpotJVMCI::HotSpotStackFrameReference::set_localIsVirtual(JVMCIENV, frame_reference(), NULL);1236}12371238locals = cvf->locals();1239HotSpotJVMCI::HotSpotStackFrameReference::set_bci(JVMCIENV, frame_reference(), cvf->bci());1240methodHandle mh(THREAD, cvf->method());1241JVMCIObject method = JVMCIENV->get_jvmci_method(mh, JVMCI_CHECK_NULL);1242HotSpotJVMCI::HotSpotStackFrameReference::set_method(JVMCIENV, frame_reference(), JNIHandles::resolve(method.as_jobject()));1243}1244}1245} else if (vf->is_interpreted_frame()) {1246// interpreted method frame1247interpretedVFrame* ivf = interpretedVFrame::cast(vf);1248if (methods == NULL || matches(methods, ivf->method(), JVMCIENV)) {1249if (initialSkip > 0) {1250initialSkip--;1251} else {1252locals = ivf->locals();1253HotSpotJVMCI::HotSpotStackFrameReference::set_bci(JVMCIENV, frame_reference(), ivf->bci());1254methodHandle mh(THREAD, ivf->method());1255JVMCIObject method = JVMCIENV->get_jvmci_method(mh, JVMCI_CHECK_NULL);1256HotSpotJVMCI::HotSpotStackFrameReference::set_method(JVMCIENV, frame_reference(), JNIHandles::resolve(method.as_jobject()));1257HotSpotJVMCI::HotSpotStackFrameReference::set_localIsVirtual(JVMCIENV, frame_reference(), NULL);1258}1259}1260}12611262// locals != NULL means that we found a matching frame and result is already partially initialized1263if (locals != NULL) {1264methods = match_methods;1265HotSpotJVMCI::HotSpotStackFrameReference::set_compilerToVM(JVMCIENV, frame_reference(), JNIHandles::resolve(compilerToVM));1266HotSpotJVMCI::HotSpotStackFrameReference::set_stackPointer(JVMCIENV, frame_reference(), (jlong) fst.current()->sp());1267HotSpotJVMCI::HotSpotStackFrameReference::set_frameNumber(JVMCIENV, frame_reference(), frame_number);12681269// initialize the locals array1270objArrayOop array_oop = oopFactory::new_objectArray(locals->size(), CHECK_NULL);1271objArrayHandle array(THREAD, array_oop);1272for (int i = 0; i < locals->size(); i++) {1273StackValue* var = locals->at(i);1274if (var->type() == T_OBJECT) {1275array->obj_at_put(i, locals->at(i)->get_obj()());1276}1277}1278HotSpotJVMCI::HotSpotStackFrameReference::set_locals(JVMCIENV, frame_reference(), array());1279HotSpotJVMCI::HotSpotStackFrameReference::set_objectsMaterialized(JVMCIENV, frame_reference(), JNI_FALSE);12801281JavaValue result(T_OBJECT);1282JavaCallArguments args(visitor);1283args.push_oop(frame_reference);1284call_interface(&result, HotSpotJVMCI::InspectedFrameVisitor::klass(), vmSymbols::visitFrame_name(), vmSymbols::visitFrame_signature(), &args, CHECK_NULL);1285if (result.get_oop() != NULL) {1286return JNIHandles::make_local(thread, result.get_oop());1287}1288assert(initialSkip == 0, "There should be no match before initialSkip == 0");1289if (HotSpotJVMCI::HotSpotStackFrameReference::objectsMaterialized(JVMCIENV, frame_reference()) == JNI_TRUE) {1290// the frame has been deoptimized, we need to re-synchronize the frame and vframe1291intptr_t* stack_pointer = (intptr_t*) HotSpotJVMCI::HotSpotStackFrameReference::stackPointer(JVMCIENV, frame_reference());1292fst = StackFrameStream(thread, true /* update */, true /* process_frames */);1293while (fst.current()->sp() != stack_pointer && !fst.is_done()) {1294fst.next();1295}1296if (fst.current()->sp() != stack_pointer) {1297THROW_MSG_NULL(vmSymbols::java_lang_IllegalStateException(), "stack frame not found after deopt")1298}1299vf = vframe::new_vframe(fst, thread);1300if (!vf->is_compiled_frame()) {1301THROW_MSG_NULL(vmSymbols::java_lang_IllegalStateException(), "compiled stack frame expected")1302}1303for (int i = 0; i < frame_number; i++) {1304if (vf->is_top()) {1305THROW_MSG_NULL(vmSymbols::java_lang_IllegalStateException(), "vframe not found after deopt")1306}1307vf = vf->sender();1308assert(vf->is_compiled_frame(), "Wrong frame type");1309}1310}1311frame_reference = HotSpotJVMCI::HotSpotStackFrameReference::klass()->allocate_instance_handle(CHECK_NULL);1312HotSpotJVMCI::HotSpotStackFrameReference::klass()->initialize(CHECK_NULL);1313}13141315if (vf->is_top()) {1316break;1317}1318frame_number++;1319vf = vf->sender();1320} // end of vframe loop13211322if (fst.is_done()) {1323break;1324}1325fst.next();1326vf = vframe::new_vframe(fst, thread);1327frame_number = 0;1328} // end of frame loop13291330// the end was reached without finding a matching method1331return NULL;1332C2V_END13331334C2V_VMENTRY(void, resolveInvokeDynamicInPool, (JNIEnv* env, jobject, jobject jvmci_constant_pool, jint index))1335constantPoolHandle cp(THREAD, JVMCIENV->asConstantPool(jvmci_constant_pool));1336CallInfo callInfo;1337LinkResolver::resolve_invoke(callInfo, Handle(), cp, index, Bytecodes::_invokedynamic, CHECK);1338ConstantPoolCacheEntry* cp_cache_entry = cp->invokedynamic_cp_cache_entry_at(index);1339cp_cache_entry->set_dynamic_call(cp, callInfo);1340C2V_END13411342C2V_VMENTRY(void, resolveInvokeHandleInPool, (JNIEnv* env, jobject, jobject jvmci_constant_pool, jint index))1343constantPoolHandle cp(THREAD, JVMCIENV->asConstantPool(jvmci_constant_pool));1344Klass* holder = cp->klass_ref_at(index, CHECK);1345Symbol* name = cp->name_ref_at(index);1346if (MethodHandles::is_signature_polymorphic_name(holder, name)) {1347CallInfo callInfo;1348LinkResolver::resolve_invoke(callInfo, Handle(), cp, index, Bytecodes::_invokehandle, CHECK);1349ConstantPoolCacheEntry* cp_cache_entry = cp->cache()->entry_at(cp->decode_cpcache_index(index));1350cp_cache_entry->set_method_handle(cp, callInfo);1351}1352C2V_END13531354C2V_VMENTRY_0(jint, isResolvedInvokeHandleInPool, (JNIEnv* env, jobject, jobject jvmci_constant_pool, jint index))1355constantPoolHandle cp(THREAD, JVMCIENV->asConstantPool(jvmci_constant_pool));1356ConstantPoolCacheEntry* cp_cache_entry = cp->cache()->entry_at(cp->decode_cpcache_index(index));1357if (cp_cache_entry->is_resolved(Bytecodes::_invokehandle)) {1358// MethodHandle.invoke* --> LambdaForm?1359ResourceMark rm;13601361LinkInfo link_info(cp, index, CATCH);13621363Klass* resolved_klass = link_info.resolved_klass();13641365Symbol* name_sym = cp->name_ref_at(index);13661367vmassert(MethodHandles::is_method_handle_invoke_name(resolved_klass, name_sym), "!");1368vmassert(MethodHandles::is_signature_polymorphic_name(resolved_klass, name_sym), "!");13691370methodHandle adapter_method(THREAD, cp_cache_entry->f1_as_method());13711372methodHandle resolved_method(adapter_method);13731374// Can we treat it as a regular invokevirtual?1375if (resolved_method->method_holder() == resolved_klass && resolved_method->name() == name_sym) {1376vmassert(!resolved_method->is_static(),"!");1377vmassert(MethodHandles::is_signature_polymorphic_method(resolved_method()),"!");1378vmassert(!MethodHandles::is_signature_polymorphic_static(resolved_method->intrinsic_id()), "!");1379vmassert(cp_cache_entry->appendix_if_resolved(cp) == NULL, "!");13801381methodHandle m(THREAD, LinkResolver::linktime_resolve_virtual_method_or_null(link_info));1382vmassert(m == resolved_method, "!!");1383return -1;1384}13851386return Bytecodes::_invokevirtual;1387}1388if (cp_cache_entry->is_resolved(Bytecodes::_invokedynamic)) {1389return Bytecodes::_invokedynamic;1390}1391return -1;1392C2V_END139313941395C2V_VMENTRY_NULL(jobject, getSignaturePolymorphicHolders, (JNIEnv* env, jobject))1396JVMCIObjectArray holders = JVMCIENV->new_String_array(2, JVMCI_CHECK_NULL);1397JVMCIObject mh = JVMCIENV->create_string("Ljava/lang/invoke/MethodHandle;", JVMCI_CHECK_NULL);1398JVMCIObject vh = JVMCIENV->create_string("Ljava/lang/invoke/VarHandle;", JVMCI_CHECK_NULL);1399JVMCIENV->put_object_at(holders, 0, mh);1400JVMCIENV->put_object_at(holders, 1, vh);1401return JVMCIENV->get_jobject(holders);1402C2V_END14031404C2V_VMENTRY_0(jboolean, shouldDebugNonSafepoints, (JNIEnv* env, jobject))1405//see compute_recording_non_safepoints in debugInfroRec.cpp1406if (JvmtiExport::should_post_compiled_method_load() && FLAG_IS_DEFAULT(DebugNonSafepoints)) {1407return true;1408}1409return DebugNonSafepoints;1410C2V_END14111412// public native void materializeVirtualObjects(HotSpotStackFrameReference stackFrame, boolean invalidate);1413C2V_VMENTRY(void, materializeVirtualObjects, (JNIEnv* env, jobject, jobject _hs_frame, bool invalidate))1414JVMCIObject hs_frame = JVMCIENV->wrap(_hs_frame);1415if (hs_frame.is_null()) {1416JVMCI_THROW_MSG(NullPointerException, "stack frame is null");1417}14181419requireInHotSpot("materializeVirtualObjects", JVMCI_CHECK);14201421JVMCIENV->HotSpotStackFrameReference_initialize(JVMCI_CHECK);14221423// look for the given stack frame1424StackFrameStream fst(thread, false /* update */, true /* process_frames */);1425intptr_t* stack_pointer = (intptr_t*) JVMCIENV->get_HotSpotStackFrameReference_stackPointer(hs_frame);1426while (fst.current()->sp() != stack_pointer && !fst.is_done()) {1427fst.next();1428}1429if (fst.current()->sp() != stack_pointer) {1430JVMCI_THROW_MSG(IllegalStateException, "stack frame not found");1431}14321433if (invalidate) {1434if (!fst.current()->is_compiled_frame()) {1435JVMCI_THROW_MSG(IllegalStateException, "compiled stack frame expected");1436}1437assert(fst.current()->cb()->is_nmethod(), "nmethod expected");1438((nmethod*) fst.current()->cb())->make_not_entrant();1439}1440Deoptimization::deoptimize(thread, *fst.current(), Deoptimization::Reason_none);1441// look for the frame again as it has been updated by deopt (pc, deopt state...)1442StackFrameStream fstAfterDeopt(thread, true /* update */, true /* process_frames */);1443while (fstAfterDeopt.current()->sp() != stack_pointer && !fstAfterDeopt.is_done()) {1444fstAfterDeopt.next();1445}1446if (fstAfterDeopt.current()->sp() != stack_pointer) {1447JVMCI_THROW_MSG(IllegalStateException, "stack frame not found after deopt");1448}14491450vframe* vf = vframe::new_vframe(fstAfterDeopt.current(), fstAfterDeopt.register_map(), thread);1451if (!vf->is_compiled_frame()) {1452JVMCI_THROW_MSG(IllegalStateException, "compiled stack frame expected");1453}14541455GrowableArray<compiledVFrame*>* virtualFrames = new GrowableArray<compiledVFrame*>(10);1456while (true) {1457assert(vf->is_compiled_frame(), "Wrong frame type");1458virtualFrames->push(compiledVFrame::cast(vf));1459if (vf->is_top()) {1460break;1461}1462vf = vf->sender();1463}14641465int last_frame_number = JVMCIENV->get_HotSpotStackFrameReference_frameNumber(hs_frame);1466if (last_frame_number >= virtualFrames->length()) {1467JVMCI_THROW_MSG(IllegalStateException, "invalid frame number");1468}14691470// Reallocate the non-escaping objects and restore their fields.1471assert (virtualFrames->at(last_frame_number)->scope() != NULL,"invalid scope");1472GrowableArray<ScopeValue*>* objects = virtualFrames->at(last_frame_number)->scope()->objects();14731474if (objects == NULL) {1475// no objects to materialize1476return;1477}14781479bool realloc_failures = Deoptimization::realloc_objects(thread, fstAfterDeopt.current(), fstAfterDeopt.register_map(), objects, CHECK);1480Deoptimization::reassign_fields(fstAfterDeopt.current(), fstAfterDeopt.register_map(), objects, realloc_failures, false);14811482for (int frame_index = 0; frame_index < virtualFrames->length(); frame_index++) {1483compiledVFrame* cvf = virtualFrames->at(frame_index);14841485GrowableArray<ScopeValue*>* scopeLocals = cvf->scope()->locals();1486StackValueCollection* locals = cvf->locals();1487if (locals != NULL) {1488for (int i2 = 0; i2 < locals->size(); i2++) {1489StackValue* var = locals->at(i2);1490if (var->type() == T_OBJECT && scopeLocals->at(i2)->is_object()) {1491jvalue val;1492val.l = cast_from_oop<jobject>(locals->at(i2)->get_obj()());1493cvf->update_local(T_OBJECT, i2, val);1494}1495}1496}14971498GrowableArray<ScopeValue*>* scopeExpressions = cvf->scope()->expressions();1499StackValueCollection* expressions = cvf->expressions();1500if (expressions != NULL) {1501for (int i2 = 0; i2 < expressions->size(); i2++) {1502StackValue* var = expressions->at(i2);1503if (var->type() == T_OBJECT && scopeExpressions->at(i2)->is_object()) {1504jvalue val;1505val.l = cast_from_oop<jobject>(expressions->at(i2)->get_obj()());1506cvf->update_stack(T_OBJECT, i2, val);1507}1508}1509}15101511GrowableArray<MonitorValue*>* scopeMonitors = cvf->scope()->monitors();1512GrowableArray<MonitorInfo*>* monitors = cvf->monitors();1513if (monitors != NULL) {1514for (int i2 = 0; i2 < monitors->length(); i2++) {1515cvf->update_monitor(i2, monitors->at(i2));1516}1517}1518}15191520// all locals are materialized by now1521JVMCIENV->set_HotSpotStackFrameReference_localIsVirtual(hs_frame, NULL);1522// update the locals array1523JVMCIObjectArray array = JVMCIENV->get_HotSpotStackFrameReference_locals(hs_frame);1524StackValueCollection* locals = virtualFrames->at(last_frame_number)->locals();1525for (int i = 0; i < locals->size(); i++) {1526StackValue* var = locals->at(i);1527if (var->type() == T_OBJECT) {1528JVMCIENV->put_object_at(array, i, HotSpotJVMCI::wrap(locals->at(i)->get_obj()()));1529}1530}1531HotSpotJVMCI::HotSpotStackFrameReference::set_objectsMaterialized(JVMCIENV, hs_frame, JNI_TRUE);1532C2V_END15331534// Use of tty does not require the current thread to be attached to the VM1535// so no need for a full C2V_VMENTRY transition.1536C2V_VMENTRY_PREFIX(void, writeDebugOutput, (JNIEnv* env, jobject, jlong buffer, jint length, bool flush))1537if (length <= 8) {1538tty->write((char*) &buffer, length);1539} else {1540tty->write((char*) buffer, length);1541}1542if (flush) {1543tty->flush();1544}1545C2V_END15461547// Use of tty does not require the current thread to be attached to the VM1548// so no need for a full C2V_VMENTRY transition.1549C2V_VMENTRY_PREFIX(void, flushDebugOutput, (JNIEnv* env, jobject))1550tty->flush();1551C2V_END15521553C2V_VMENTRY_0(jint, methodDataProfileDataSize, (JNIEnv* env, jobject, jlong metaspace_method_data, jint position))1554MethodData* mdo = JVMCIENV->asMethodData(metaspace_method_data);1555ProfileData* profile_data = mdo->data_at(position);1556if (mdo->is_valid(profile_data)) {1557return profile_data->size_in_bytes();1558}1559DataLayout* data = mdo->extra_data_base();1560DataLayout* end = mdo->extra_data_limit();1561for (;; data = mdo->next_extra(data)) {1562assert(data < end, "moved past end of extra data");1563profile_data = data->data_in();1564if (mdo->dp_to_di(profile_data->dp()) == position) {1565return profile_data->size_in_bytes();1566}1567}1568JVMCI_THROW_MSG_0(IllegalArgumentException, err_msg("Invalid profile data position %d", position));1569C2V_END15701571C2V_VMENTRY_0(jlong, getFingerprint, (JNIEnv* env, jobject, jlong metaspace_klass))1572JVMCI_THROW_MSG_0(InternalError, "unimplemented");1573C2V_END15741575C2V_VMENTRY_NULL(jobject, getInterfaces, (JNIEnv* env, jobject, jobject jvmci_type))1576if (jvmci_type == NULL) {1577JVMCI_THROW_0(NullPointerException);1578}15791580Klass* klass = JVMCIENV->asKlass(jvmci_type);1581if (klass == NULL) {1582JVMCI_THROW_0(NullPointerException);1583}1584if (!klass->is_instance_klass()) {1585JVMCI_THROW_MSG_0(InternalError, err_msg("Class %s must be instance klass", klass->external_name()));1586}1587InstanceKlass* iklass = InstanceKlass::cast(klass);15881589// Regular instance klass, fill in all local interfaces1590int size = iklass->local_interfaces()->length();1591JVMCIObjectArray interfaces = JVMCIENV->new_HotSpotResolvedObjectTypeImpl_array(size, JVMCI_CHECK_NULL);1592for (int index = 0; index < size; index++) {1593JVMCIKlassHandle klass(THREAD);1594Klass* k = iklass->local_interfaces()->at(index);1595klass = k;1596JVMCIObject type = JVMCIENV->get_jvmci_type(klass, JVMCI_CHECK_NULL);1597JVMCIENV->put_object_at(interfaces, index, type);1598}1599return JVMCIENV->get_jobject(interfaces);1600C2V_END16011602C2V_VMENTRY_NULL(jobject, getComponentType, (JNIEnv* env, jobject, jobject jvmci_type))1603if (jvmci_type == NULL) {1604JVMCI_THROW_0(NullPointerException);1605}16061607Klass* klass = JVMCIENV->asKlass(jvmci_type);1608oop mirror = klass->java_mirror();1609if (java_lang_Class::is_primitive(mirror) ||1610!java_lang_Class::as_Klass(mirror)->is_array_klass()) {1611return NULL;1612}16131614oop component_mirror = java_lang_Class::component_mirror(mirror);1615if (component_mirror == NULL) {1616return NULL;1617}1618Klass* component_klass = java_lang_Class::as_Klass(component_mirror);1619if (component_klass != NULL) {1620JVMCIKlassHandle klass_handle(THREAD);1621klass_handle = component_klass;1622JVMCIObject result = JVMCIENV->get_jvmci_type(klass_handle, JVMCI_CHECK_NULL);1623return JVMCIENV->get_jobject(result);1624}1625BasicType type = java_lang_Class::primitive_type(component_mirror);1626JVMCIObject result = JVMCIENV->get_jvmci_primitive_type(type);1627return JVMCIENV->get_jobject(result);1628C2V_END16291630C2V_VMENTRY(void, ensureInitialized, (JNIEnv* env, jobject, jobject jvmci_type))1631if (jvmci_type == NULL) {1632JVMCI_THROW(NullPointerException);1633}16341635Klass* klass = JVMCIENV->asKlass(jvmci_type);1636if (klass != NULL && klass->should_be_initialized()) {1637InstanceKlass* k = InstanceKlass::cast(klass);1638k->initialize(CHECK);1639}1640C2V_END16411642C2V_VMENTRY(void, ensureLinked, (JNIEnv* env, jobject, jobject jvmci_type))1643if (jvmci_type == NULL) {1644JVMCI_THROW(NullPointerException);1645}16461647Klass* klass = JVMCIENV->asKlass(jvmci_type);1648if (klass != NULL && klass->is_instance_klass()) {1649InstanceKlass* k = InstanceKlass::cast(klass);1650k->link_class(CHECK);1651}1652C2V_END16531654C2V_VMENTRY_0(jint, interpreterFrameSize, (JNIEnv* env, jobject, jobject bytecode_frame_handle))1655if (bytecode_frame_handle == NULL) {1656JVMCI_THROW_0(NullPointerException);1657}16581659JVMCIObject top_bytecode_frame = JVMCIENV->wrap(bytecode_frame_handle);1660JVMCIObject bytecode_frame = top_bytecode_frame;1661int size = 0;1662int callee_parameters = 0;1663int callee_locals = 0;1664Method* method = JVMCIENV->asMethod(JVMCIENV->get_BytecodePosition_method(bytecode_frame));1665int extra_args = method->max_stack() - JVMCIENV->get_BytecodeFrame_numStack(bytecode_frame);16661667while (bytecode_frame.is_non_null()) {1668int locks = JVMCIENV->get_BytecodeFrame_numLocks(bytecode_frame);1669int temps = JVMCIENV->get_BytecodeFrame_numStack(bytecode_frame);1670bool is_top_frame = (JVMCIENV->equals(bytecode_frame, top_bytecode_frame));1671Method* method = JVMCIENV->asMethod(JVMCIENV->get_BytecodePosition_method(bytecode_frame));16721673int frame_size = BytesPerWord * Interpreter::size_activation(method->max_stack(),1674temps + callee_parameters,1675extra_args,1676locks,1677callee_parameters,1678callee_locals,1679is_top_frame);1680size += frame_size;16811682callee_parameters = method->size_of_parameters();1683callee_locals = method->max_locals();1684extra_args = 0;1685bytecode_frame = JVMCIENV->get_BytecodePosition_caller(bytecode_frame);1686}1687return size + Deoptimization::last_frame_adjust(0, callee_locals) * BytesPerWord;1688C2V_END16891690C2V_VMENTRY(void, compileToBytecode, (JNIEnv* env, jobject, jobject lambda_form_handle))1691Handle lambda_form = JVMCIENV->asConstant(JVMCIENV->wrap(lambda_form_handle), JVMCI_CHECK);1692if (lambda_form->is_a(vmClasses::LambdaForm_klass())) {1693TempNewSymbol compileToBytecode = SymbolTable::new_symbol("compileToBytecode");1694JavaValue result(T_VOID);1695JavaCalls::call_special(&result, lambda_form, vmClasses::LambdaForm_klass(), compileToBytecode, vmSymbols::void_method_signature(), CHECK);1696} else {1697JVMCI_THROW_MSG(IllegalArgumentException,1698err_msg("Unexpected type: %s", lambda_form->klass()->external_name()))1699}1700C2V_END17011702C2V_VMENTRY_0(jint, getIdentityHashCode, (JNIEnv* env, jobject, jobject object))1703Handle obj = JVMCIENV->asConstant(JVMCIENV->wrap(object), JVMCI_CHECK_0);1704return obj->identity_hash();1705C2V_END17061707C2V_VMENTRY_0(jboolean, isInternedString, (JNIEnv* env, jobject, jobject object))1708Handle str = JVMCIENV->asConstant(JVMCIENV->wrap(object), JVMCI_CHECK_0);1709if (!java_lang_String::is_instance(str())) {1710return false;1711}1712int len;1713jchar* name = java_lang_String::as_unicode_string(str(), len, CHECK_false);1714return (StringTable::lookup(name, len) != NULL);1715C2V_END171617171718C2V_VMENTRY_NULL(jobject, unboxPrimitive, (JNIEnv* env, jobject, jobject object))1719if (object == NULL) {1720JVMCI_THROW_0(NullPointerException);1721}1722Handle box = JVMCIENV->asConstant(JVMCIENV->wrap(object), JVMCI_CHECK_NULL);1723BasicType type = java_lang_boxing_object::basic_type(box());1724jvalue result;1725if (java_lang_boxing_object::get_value(box(), &result) == T_ILLEGAL) {1726return NULL;1727}1728JVMCIObject boxResult = JVMCIENV->create_box(type, &result, JVMCI_CHECK_NULL);1729return JVMCIENV->get_jobject(boxResult);1730C2V_END17311732C2V_VMENTRY_NULL(jobject, boxPrimitive, (JNIEnv* env, jobject, jobject object))1733if (object == NULL) {1734JVMCI_THROW_0(NullPointerException);1735}1736JVMCIObject box = JVMCIENV->wrap(object);1737BasicType type = JVMCIENV->get_box_type(box);1738if (type == T_ILLEGAL) {1739return NULL;1740}1741jvalue value = JVMCIENV->get_boxed_value(type, box);1742JavaValue box_result(T_OBJECT);1743JavaCallArguments jargs;1744Klass* box_klass = NULL;1745Symbol* box_signature = NULL;1746#define BOX_CASE(bt, v, argtype, name) \1747case bt: \1748jargs.push_##argtype(value.v); \1749box_klass = vmClasses::name##_klass(); \1750box_signature = vmSymbols::name##_valueOf_signature(); \1751break17521753switch (type) {1754BOX_CASE(T_BOOLEAN, z, int, Boolean);1755BOX_CASE(T_BYTE, b, int, Byte);1756BOX_CASE(T_CHAR, c, int, Character);1757BOX_CASE(T_SHORT, s, int, Short);1758BOX_CASE(T_INT, i, int, Integer);1759BOX_CASE(T_LONG, j, long, Long);1760BOX_CASE(T_FLOAT, f, float, Float);1761BOX_CASE(T_DOUBLE, d, double, Double);1762default:1763ShouldNotReachHere();1764}1765#undef BOX_CASE17661767JavaCalls::call_static(&box_result,1768box_klass,1769vmSymbols::valueOf_name(),1770box_signature, &jargs, CHECK_NULL);1771oop hotspot_box = box_result.get_oop();1772JVMCIObject result = JVMCIENV->get_object_constant(hotspot_box, false);1773return JVMCIENV->get_jobject(result);1774C2V_END17751776C2V_VMENTRY_NULL(jobjectArray, getDeclaredConstructors, (JNIEnv* env, jobject, jobject holder))1777if (holder == NULL) {1778JVMCI_THROW_0(NullPointerException);1779}1780Klass* klass = JVMCIENV->asKlass(holder);1781if (!klass->is_instance_klass()) {1782JVMCIObjectArray methods = JVMCIENV->new_ResolvedJavaMethod_array(0, JVMCI_CHECK_NULL);1783return JVMCIENV->get_jobjectArray(methods);1784}17851786InstanceKlass* iklass = InstanceKlass::cast(klass);1787// Ensure class is linked1788iklass->link_class(CHECK_NULL);17891790GrowableArray<Method*> constructors_array;1791for (int i = 0; i < iklass->methods()->length(); i++) {1792Method* m = iklass->methods()->at(i);1793if (m->is_initializer() && !m->is_static()) {1794constructors_array.append(m);1795}1796}1797JVMCIObjectArray methods = JVMCIENV->new_ResolvedJavaMethod_array(constructors_array.length(), JVMCI_CHECK_NULL);1798for (int i = 0; i < constructors_array.length(); i++) {1799methodHandle ctor(THREAD, constructors_array.at(i));1800JVMCIObject method = JVMCIENV->get_jvmci_method(ctor, JVMCI_CHECK_NULL);1801JVMCIENV->put_object_at(methods, i, method);1802}1803return JVMCIENV->get_jobjectArray(methods);1804C2V_END18051806C2V_VMENTRY_NULL(jobjectArray, getDeclaredMethods, (JNIEnv* env, jobject, jobject holder))1807if (holder == NULL) {1808JVMCI_THROW_0(NullPointerException);1809}1810Klass* klass = JVMCIENV->asKlass(holder);1811if (!klass->is_instance_klass()) {1812JVMCIObjectArray methods = JVMCIENV->new_ResolvedJavaMethod_array(0, JVMCI_CHECK_NULL);1813return JVMCIENV->get_jobjectArray(methods);1814}18151816InstanceKlass* iklass = InstanceKlass::cast(klass);1817// Ensure class is linked1818iklass->link_class(CHECK_NULL);18191820GrowableArray<Method*> methods_array;1821for (int i = 0; i < iklass->methods()->length(); i++) {1822Method* m = iklass->methods()->at(i);1823if (!m->is_initializer() && !m->is_overpass()) {1824methods_array.append(m);1825}1826}1827JVMCIObjectArray methods = JVMCIENV->new_ResolvedJavaMethod_array(methods_array.length(), JVMCI_CHECK_NULL);1828for (int i = 0; i < methods_array.length(); i++) {1829methodHandle mh(THREAD, methods_array.at(i));1830JVMCIObject method = JVMCIENV->get_jvmci_method(mh, JVMCI_CHECK_NULL);1831JVMCIENV->put_object_at(methods, i, method);1832}1833return JVMCIENV->get_jobjectArray(methods);1834C2V_END18351836C2V_VMENTRY_NULL(jobject, readFieldValue, (JNIEnv* env, jobject, jobject object, jobject expected_type, long displacement, jboolean is_volatile, jobject kind_object))1837if (object == NULL || kind_object == NULL) {1838JVMCI_THROW_0(NullPointerException);1839}18401841JVMCIObject kind = JVMCIENV->wrap(kind_object);1842BasicType basic_type = JVMCIENV->kindToBasicType(kind, JVMCI_CHECK_NULL);18431844InstanceKlass* holder = NULL;1845if (expected_type != NULL) {1846holder = InstanceKlass::cast(JVMCIENV->asKlass(JVMCIENV->wrap(expected_type)));1847}18481849bool is_static = false;1850Handle obj;1851JVMCIObject base = JVMCIENV->wrap(object);1852if (JVMCIENV->isa_HotSpotObjectConstantImpl(base)) {1853obj = JVMCIENV->asConstant(base, JVMCI_CHECK_NULL);1854// asConstant will throw an NPE if a constant contains NULL18551856if (holder != NULL && !obj->is_a(holder)) {1857// Not a subtype of field holder1858return NULL;1859}1860is_static = false;1861if (holder == NULL && java_lang_Class::is_instance(obj()) && displacement >= InstanceMirrorKlass::offset_of_static_fields()) {1862is_static = true;1863}1864} else if (JVMCIENV->isa_HotSpotResolvedObjectTypeImpl(base)) {1865is_static = true;1866Klass* klass = JVMCIENV->asKlass(base);1867if (holder != NULL && holder != klass) {1868return NULL;1869}1870obj = Handle(THREAD, klass->java_mirror());1871} else {1872// The Java code is expected to guard against this path1873ShouldNotReachHere();1874}18751876if (displacement < 0 || ((long) displacement + type2aelembytes(basic_type) > HeapWordSize * obj->size())) {1877// Reading outside of the object bounds1878JVMCI_THROW_MSG_NULL(IllegalArgumentException, "reading outside object bounds");1879}18801881// Perform basic sanity checks on the read. Primitive reads are permitted to read outside the1882// bounds of their fields but object reads must map exactly onto the underlying oop slot.1883if (basic_type == T_OBJECT) {1884if (obj->is_objArray()) {1885if (displacement < arrayOopDesc::base_offset_in_bytes(T_OBJECT)) {1886JVMCI_THROW_MSG_NULL(IllegalArgumentException, "reading from array header");1887}1888if (displacement + heapOopSize > arrayOopDesc::base_offset_in_bytes(T_OBJECT) + arrayOop(obj())->length() * heapOopSize) {1889JVMCI_THROW_MSG_NULL(IllegalArgumentException, "reading after last array element");1890}1891if (((displacement - arrayOopDesc::base_offset_in_bytes(T_OBJECT)) % heapOopSize) != 0) {1892JVMCI_THROW_MSG_NULL(IllegalArgumentException, "misaligned object read from array");1893}1894} else if (obj->is_instance()) {1895InstanceKlass* klass = InstanceKlass::cast(is_static ? java_lang_Class::as_Klass(obj()) : obj->klass());1896fieldDescriptor fd;1897if (!klass->find_field_from_offset(displacement, is_static, &fd)) {1898JVMCI_THROW_MSG_NULL(IllegalArgumentException, err_msg("Can't find field at displacement %d in object of type %s", (int) displacement, klass->external_name()));1899}1900if (fd.field_type() != T_OBJECT && fd.field_type() != T_ARRAY) {1901JVMCI_THROW_MSG_NULL(IllegalArgumentException, err_msg("Field at displacement %d in object of type %s is %s but expected %s", (int) displacement,1902klass->external_name(), type2name(fd.field_type()), type2name(basic_type)));1903}1904} else if (obj->is_typeArray()) {1905JVMCI_THROW_MSG_NULL(IllegalArgumentException, "Can't read objects from primitive array");1906} else {1907ShouldNotReachHere();1908}1909} else {1910if (obj->is_objArray()) {1911JVMCI_THROW_MSG_NULL(IllegalArgumentException, "Reading primitive from object array");1912} else if (obj->is_typeArray()) {1913if (displacement < arrayOopDesc::base_offset_in_bytes(ArrayKlass::cast(obj->klass())->element_type())) {1914JVMCI_THROW_MSG_NULL(IllegalArgumentException, "reading from array header");1915}1916}1917}19181919jlong value = 0;1920switch (basic_type) {1921case T_BOOLEAN: value = is_volatile ? obj->bool_field_acquire(displacement) : obj->bool_field(displacement); break;1922case T_BYTE: value = is_volatile ? obj->byte_field_acquire(displacement) : obj->byte_field(displacement); break;1923case T_SHORT: value = is_volatile ? obj->short_field_acquire(displacement) : obj->short_field(displacement); break;1924case T_CHAR: value = is_volatile ? obj->char_field_acquire(displacement) : obj->char_field(displacement); break;1925case T_FLOAT:1926case T_INT: value = is_volatile ? obj->int_field_acquire(displacement) : obj->int_field(displacement); break;1927case T_DOUBLE:1928case T_LONG: value = is_volatile ? obj->long_field_acquire(displacement) : obj->long_field(displacement); break;19291930case T_OBJECT: {1931if (displacement == java_lang_Class::component_mirror_offset() && java_lang_Class::is_instance(obj()) &&1932(java_lang_Class::as_Klass(obj()) == NULL || !java_lang_Class::as_Klass(obj())->is_array_klass())) {1933// Class.componentType for non-array classes can transiently contain an int[] that's1934// used for locking so always return null to mimic Class.getComponentType()1935return JVMCIENV->get_jobject(JVMCIENV->get_JavaConstant_NULL_POINTER());1936}19371938oop value = is_volatile ? obj->obj_field_acquire(displacement) : obj->obj_field(displacement);1939if (value == NULL) {1940return JVMCIENV->get_jobject(JVMCIENV->get_JavaConstant_NULL_POINTER());1941} else {1942if (value != NULL && !oopDesc::is_oop(value)) {1943// Throw an exception to improve debuggability. This check isn't totally reliable because1944// is_oop doesn't try to be completety safe but for most invalid values it provides a good1945// enough answer. It possible to crash in the is_oop call but that just means the crash happens1946// closer to where things went wrong.1947JVMCI_THROW_MSG_NULL(InternalError, err_msg("Read bad oop " INTPTR_FORMAT " at offset " JLONG_FORMAT " in object " INTPTR_FORMAT " of type %s",1948p2i(value), displacement, p2i(obj()), obj->klass()->external_name()));1949}19501951JVMCIObject result = JVMCIENV->get_object_constant(value);1952return JVMCIENV->get_jobject(result);1953}1954}19551956default:1957ShouldNotReachHere();1958}1959JVMCIObject result = JVMCIENV->call_JavaConstant_forPrimitive(kind, value, JVMCI_CHECK_NULL);1960return JVMCIENV->get_jobject(result);1961C2V_END19621963C2V_VMENTRY_0(jboolean, isInstance, (JNIEnv* env, jobject, jobject holder, jobject object))1964if (object == NULL || holder == NULL) {1965JVMCI_THROW_0(NullPointerException);1966}1967Handle obj = JVMCIENV->asConstant(JVMCIENV->wrap(object), JVMCI_CHECK_0);1968Klass* klass = JVMCIENV->asKlass(JVMCIENV->wrap(holder));1969return obj->is_a(klass);1970C2V_END19711972C2V_VMENTRY_0(jboolean, isAssignableFrom, (JNIEnv* env, jobject, jobject holder, jobject otherHolder))1973if (holder == NULL || otherHolder == NULL) {1974JVMCI_THROW_0(NullPointerException);1975}1976Klass* klass = JVMCIENV->asKlass(JVMCIENV->wrap(holder));1977Klass* otherKlass = JVMCIENV->asKlass(JVMCIENV->wrap(otherHolder));1978return otherKlass->is_subtype_of(klass);1979C2V_END19801981C2V_VMENTRY_0(jboolean, isTrustedForIntrinsics, (JNIEnv* env, jobject, jobject holder))1982if (holder == NULL) {1983JVMCI_THROW_0(NullPointerException);1984}1985InstanceKlass* ik = InstanceKlass::cast(JVMCIENV->asKlass(JVMCIENV->wrap(holder)));1986if (ik->class_loader_data()->is_boot_class_loader_data() || ik->class_loader_data()->is_platform_class_loader_data()) {1987return true;1988}1989return false;1990C2V_END19911992C2V_VMENTRY_NULL(jobject, asJavaType, (JNIEnv* env, jobject, jobject object))1993if (object == NULL) {1994JVMCI_THROW_0(NullPointerException);1995}1996Handle obj = JVMCIENV->asConstant(JVMCIENV->wrap(object), JVMCI_CHECK_NULL);1997if (java_lang_Class::is_instance(obj())) {1998if (java_lang_Class::is_primitive(obj())) {1999JVMCIObject type = JVMCIENV->get_jvmci_primitive_type(java_lang_Class::primitive_type(obj()));2000return JVMCIENV->get_jobject(type);2001}2002Klass* klass = java_lang_Class::as_Klass(obj());2003JVMCIKlassHandle klass_handle(THREAD);2004klass_handle = klass;2005JVMCIObject type = JVMCIENV->get_jvmci_type(klass_handle, JVMCI_CHECK_NULL);2006return JVMCIENV->get_jobject(type);2007}2008return NULL;2009C2V_END201020112012C2V_VMENTRY_NULL(jobject, asString, (JNIEnv* env, jobject, jobject object))2013if (object == NULL) {2014JVMCI_THROW_0(NullPointerException);2015}2016Handle obj = JVMCIENV->asConstant(JVMCIENV->wrap(object), JVMCI_CHECK_NULL);2017const char* str = java_lang_String::as_utf8_string(obj());2018JVMCIObject result = JVMCIENV->create_string(str, JVMCI_CHECK_NULL);2019return JVMCIENV->get_jobject(result);2020C2V_END202120222023C2V_VMENTRY_0(jboolean, equals, (JNIEnv* env, jobject, jobject x, jlong xHandle, jobject y, jlong yHandle))2024if (x == NULL || y == NULL) {2025JVMCI_THROW_0(NullPointerException);2026}2027return JVMCIENV->resolve_handle(xHandle) == JVMCIENV->resolve_handle(yHandle);2028C2V_END20292030C2V_VMENTRY_NULL(jobject, getJavaMirror, (JNIEnv* env, jobject, jobject object))2031if (object == NULL) {2032JVMCI_THROW_0(NullPointerException);2033}2034JVMCIObject base_object = JVMCIENV->wrap(object);2035Handle mirror;2036if (JVMCIENV->isa_HotSpotResolvedObjectTypeImpl(base_object)) {2037mirror = Handle(THREAD, JVMCIENV->asKlass(base_object)->java_mirror());2038} else if (JVMCIENV->isa_HotSpotResolvedPrimitiveType(base_object)) {2039mirror = JVMCIENV->asConstant(JVMCIENV->get_HotSpotResolvedPrimitiveType_mirror(base_object), JVMCI_CHECK_NULL);2040} else {2041JVMCI_THROW_MSG_NULL(IllegalArgumentException,2042err_msg("Unexpected type: %s", JVMCIENV->klass_name(base_object)));2043}2044JVMCIObject result = JVMCIENV->get_object_constant(mirror());2045return JVMCIENV->get_jobject(result);2046C2V_END204720482049C2V_VMENTRY_0(jint, getArrayLength, (JNIEnv* env, jobject, jobject x))2050if (x == NULL) {2051JVMCI_THROW_0(NullPointerException);2052}2053Handle xobj = JVMCIENV->asConstant(JVMCIENV->wrap(x), JVMCI_CHECK_0);2054if (xobj->klass()->is_array_klass()) {2055return arrayOop(xobj())->length();2056}2057return -1;2058C2V_END205920602061C2V_VMENTRY_NULL(jobject, readArrayElement, (JNIEnv* env, jobject, jobject x, int index))2062if (x == NULL) {2063JVMCI_THROW_0(NullPointerException);2064}2065Handle xobj = JVMCIENV->asConstant(JVMCIENV->wrap(x), JVMCI_CHECK_NULL);2066if (xobj->klass()->is_array_klass()) {2067arrayOop array = arrayOop(xobj());2068BasicType element_type = ArrayKlass::cast(array->klass())->element_type();2069if (index < 0 || index >= array->length()) {2070return NULL;2071}2072JVMCIObject result;20732074if (element_type == T_OBJECT) {2075result = JVMCIENV->get_object_constant(objArrayOop(xobj())->obj_at(index));2076if (result.is_null()) {2077result = JVMCIENV->get_JavaConstant_NULL_POINTER();2078}2079} else {2080jvalue value;2081switch (element_type) {2082case T_DOUBLE: value.d = typeArrayOop(xobj())->double_at(index); break;2083case T_FLOAT: value.f = typeArrayOop(xobj())->float_at(index); break;2084case T_LONG: value.j = typeArrayOop(xobj())->long_at(index); break;2085case T_INT: value.i = typeArrayOop(xobj())->int_at(index); break;2086case T_SHORT: value.s = typeArrayOop(xobj())->short_at(index); break;2087case T_CHAR: value.c = typeArrayOop(xobj())->char_at(index); break;2088case T_BYTE: value.b = typeArrayOop(xobj())->byte_at(index); break;2089case T_BOOLEAN: value.z = typeArrayOop(xobj())->byte_at(index) & 1; break;2090default: ShouldNotReachHere();2091}2092result = JVMCIENV->create_box(element_type, &value, JVMCI_CHECK_NULL);2093}2094assert(!result.is_null(), "must have a value");2095return JVMCIENV->get_jobject(result);2096}2097return NULL;;2098C2V_END209921002101C2V_VMENTRY_0(jint, arrayBaseOffset, (JNIEnv* env, jobject, jobject kind))2102if (kind == NULL) {2103JVMCI_THROW_0(NullPointerException);2104}2105BasicType type = JVMCIENV->kindToBasicType(JVMCIENV->wrap(kind), JVMCI_CHECK_0);2106return arrayOopDesc::header_size(type) * HeapWordSize;2107C2V_END21082109C2V_VMENTRY_0(jint, arrayIndexScale, (JNIEnv* env, jobject, jobject kind))2110if (kind == NULL) {2111JVMCI_THROW_0(NullPointerException);2112}2113BasicType type = JVMCIENV->kindToBasicType(JVMCIENV->wrap(kind), JVMCI_CHECK_0);2114return type2aelembytes(type);2115C2V_END21162117C2V_VMENTRY(void, deleteGlobalHandle, (JNIEnv* env, jobject, jlong h))2118jobject handle = (jobject)(address)h;2119if (handle != NULL) {2120JVMCIENV->runtime()->destroy_global(handle);2121}2122}21232124static void requireJVMCINativeLibrary(JVMCI_TRAPS) {2125if (!UseJVMCINativeLibrary) {2126JVMCI_THROW_MSG(UnsupportedOperationException, "JVMCI shared library is not enabled (requires -XX:+UseJVMCINativeLibrary)");2127}2128}21292130C2V_VMENTRY_NULL(jlongArray, registerNativeMethods, (JNIEnv* env, jobject, jclass mirror))2131requireJVMCINativeLibrary(JVMCI_CHECK_NULL);2132requireInHotSpot("registerNativeMethods", JVMCI_CHECK_NULL);2133char* sl_path;2134void* sl_handle;2135JVMCIRuntime* runtime = JVMCI::compiler_runtime();2136{2137// Ensure the JVMCI shared library runtime is initialized.2138JVMCIEnv __peer_jvmci_env__(thread, false, __FILE__, __LINE__);2139JVMCIEnv* peerEnv = &__peer_jvmci_env__;2140HandleMark hm(THREAD);2141JVMCIObject receiver = runtime->get_HotSpotJVMCIRuntime(peerEnv);2142if (peerEnv->has_pending_exception()) {2143peerEnv->describe_pending_exception(true);2144}2145sl_handle = JVMCI::get_shared_library(sl_path, false);2146if (sl_handle == NULL) {2147JVMCI_THROW_MSG_0(InternalError, err_msg("Error initializing JVMCI runtime %d", runtime->id()));2148}2149}21502151if (mirror == NULL) {2152JVMCI_THROW_0(NullPointerException);2153}2154Klass* klass = java_lang_Class::as_Klass(JNIHandles::resolve(mirror));2155if (klass == NULL || !klass->is_instance_klass()) {2156JVMCI_THROW_MSG_0(IllegalArgumentException, "clazz is for primitive type");2157}21582159InstanceKlass* iklass = InstanceKlass::cast(klass);2160for (int i = 0; i < iklass->methods()->length(); i++) {2161methodHandle method(THREAD, iklass->methods()->at(i));2162if (method->is_native()) {21632164// Compute argument size2165int args_size = 1 // JNIEnv2166+ (method->is_static() ? 1 : 0) // class for static methods2167+ method->size_of_parameters(); // actual parameters21682169// 1) Try JNI short style2170stringStream st;2171char* pure_name = NativeLookup::pure_jni_name(method);2172guarantee(pure_name != NULL, "Illegal native method name encountered");2173os::print_jni_name_prefix_on(&st, args_size);2174st.print_raw(pure_name);2175os::print_jni_name_suffix_on(&st, args_size);2176char* jni_name = st.as_string();21772178address entry = (address) os::dll_lookup(sl_handle, jni_name);2179if (entry == NULL) {2180// 2) Try JNI long style2181st.reset();2182char* long_name = NativeLookup::long_jni_name(method);2183guarantee(long_name != NULL, "Illegal native method name encountered");2184os::print_jni_name_prefix_on(&st, args_size);2185st.print_raw(pure_name);2186st.print_raw(long_name);2187os::print_jni_name_suffix_on(&st, args_size);2188char* jni_long_name = st.as_string();2189entry = (address) os::dll_lookup(sl_handle, jni_long_name);2190if (entry == NULL) {2191JVMCI_THROW_MSG_0(UnsatisfiedLinkError, err_msg("%s [neither %s nor %s exist in %s]",2192method->name_and_sig_as_C_string(),2193jni_name, jni_long_name, sl_path));2194}2195}21962197if (method->has_native_function() && entry != method->native_function()) {2198JVMCI_THROW_MSG_0(UnsatisfiedLinkError, err_msg("%s [cannot re-link from " PTR_FORMAT " to " PTR_FORMAT "]",2199method->name_and_sig_as_C_string(), p2i(method->native_function()), p2i(entry)));2200}2201method->set_native_function(entry, Method::native_bind_event_is_interesting);2202log_debug(jni, resolve)("[Dynamic-linking native method %s.%s ... JNI] @ " PTR_FORMAT,2203method->method_holder()->external_name(),2204method->name()->as_C_string(),2205p2i((void*) entry));2206}2207}22082209typeArrayOop info_oop = oopFactory::new_longArray(4, CHECK_0);2210jlongArray info = (jlongArray) JNIHandles::make_local(THREAD, info_oop);2211runtime->init_JavaVM_info(info, JVMCI_CHECK_0);2212return info;2213}22142215C2V_VMENTRY_PREFIX(jboolean, isCurrentThreadAttached, (JNIEnv* env, jobject c2vm))2216if (thread == NULL) {2217// Called from unattached JVMCI shared library thread2218return false;2219}2220JVMCITraceMark jtm("isCurrentThreadAttached");2221if (thread->jni_environment() == env) {2222C2V_BLOCK(jboolean, isCurrentThreadAttached, (JNIEnv* env, jobject))2223requireJVMCINativeLibrary(JVMCI_CHECK_0);2224JVMCIRuntime* runtime = JVMCI::compiler_runtime();2225if (runtime == NULL || !runtime->has_shared_library_javavm()) {2226JVMCI_THROW_MSG_0(IllegalStateException, "Require JVMCI shared library JavaVM to be initialized in isCurrentThreadAttached");2227}2228JNIEnv* peerEnv;2229return runtime->GetEnv(thread, (void**) &peerEnv, JNI_VERSION_1_2) == JNI_OK;2230}2231return true;2232C2V_END22332234C2V_VMENTRY_PREFIX(jlong, getCurrentJavaThread, (JNIEnv* env, jobject c2vm))2235if (thread == NULL) {2236// Called from unattached JVMCI shared library thread2237return 0L;2238}2239JVMCITraceMark jtm("getCurrentJavaThread");2240return (jlong) p2i(thread);2241C2V_END22422243C2V_VMENTRY_PREFIX(jboolean, attachCurrentThread, (JNIEnv* env, jobject c2vm, jbyteArray name, jboolean as_daemon))2244if (thread == NULL) {2245// Called from unattached JVMCI shared library thread2246guarantee(name != NULL, "libjvmci caller must pass non-null name");22472248extern struct JavaVM_ main_vm;2249JNIEnv* hotspotEnv;22502251int name_len = env->GetArrayLength(name);2252char name_buf[64]; // Cannot use Resource heap as it requires a current thread2253int to_copy = MIN2(name_len, (int) sizeof(name_buf) - 1);2254env->GetByteArrayRegion(name, 0, to_copy, (jbyte*) name_buf);2255name_buf[to_copy] = '\0';2256JavaVMAttachArgs attach_args;2257attach_args.version = JNI_VERSION_1_2;2258attach_args.name = name_buf;2259attach_args.group = NULL;2260jint res = as_daemon ? main_vm.AttachCurrentThreadAsDaemon((void**) &hotspotEnv, &attach_args) :2261main_vm.AttachCurrentThread((void**) &hotspotEnv, &attach_args);2262if (res != JNI_OK) {2263JNI_THROW_("attachCurrentThread", InternalError, err_msg("Trying to attach thread returned %d", res), false);2264}2265return true;2266}2267JVMCITraceMark jtm("attachCurrentThread");2268if (thread->jni_environment() == env) {2269// Called from HotSpot2270C2V_BLOCK(jboolean, attachCurrentThread, (JNIEnv* env, jobject, jboolean))2271requireJVMCINativeLibrary(JVMCI_CHECK_0);2272JVMCIRuntime* runtime = JVMCI::compiler_runtime();2273if (runtime == NULL || !runtime->has_shared_library_javavm()) {2274JVMCI_THROW_MSG_0(IllegalStateException, "Require JVMCI shared library JavaVM to be initialized in attachCurrentThread");2275}22762277JavaVMAttachArgs attach_args;2278attach_args.version = JNI_VERSION_1_2;2279attach_args.name = thread->name();2280attach_args.group = NULL;2281JNIEnv* peerJNIEnv;2282if (runtime->GetEnv(thread, (void**) &peerJNIEnv, JNI_VERSION_1_2) == JNI_OK) {2283return false;2284}2285jint res = as_daemon ? runtime->AttachCurrentThreadAsDaemon(thread, (void**) &peerJNIEnv, &attach_args) :2286runtime->AttachCurrentThread(thread, (void**) &peerJNIEnv, &attach_args);22872288if (res == JNI_OK) {2289guarantee(peerJNIEnv != NULL, "must be");2290JVMCI_event_1("attached to JavaVM for JVMCI runtime %d", runtime->id());2291return true;2292}2293JVMCI_THROW_MSG_0(InternalError, err_msg("Error %d while attaching %s", res, attach_args.name));2294}2295// Called from JVMCI shared library2296return false;2297C2V_END22982299C2V_VMENTRY_PREFIX(void, detachCurrentThread, (JNIEnv* env, jobject c2vm))2300if (thread == NULL) {2301// Called from unattached JVMCI shared library thread2302JNI_THROW("detachCurrentThread", IllegalStateException, "Cannot detach non-attached thread");2303}2304JVMCITraceMark jtm("detachCurrentThread");2305if (thread->jni_environment() == env) {2306// Called from HotSpot2307C2V_BLOCK(void, detachCurrentThread, (JNIEnv* env, jobject))2308requireJVMCINativeLibrary(JVMCI_CHECK);2309requireInHotSpot("detachCurrentThread", JVMCI_CHECK);2310JVMCIRuntime* runtime = JVMCI::compiler_runtime();2311if (runtime == NULL || !runtime->has_shared_library_javavm()) {2312JVMCI_THROW_MSG(IllegalStateException, "Require JVMCI shared library JavaVM to be initialized in detachCurrentThread");2313}2314JNIEnv* peerJNIEnv;2315if (runtime->GetEnv(thread, (void**) &peerJNIEnv, JNI_VERSION_1_2) != JNI_OK) {2316JVMCI_THROW_MSG(IllegalStateException, err_msg("Cannot detach non-attached thread: %s", thread->name()));2317}2318jint res = runtime->DetachCurrentThread(thread);2319if (res != JNI_OK) {2320JVMCI_THROW_MSG(InternalError, err_msg("Error %d while attaching %s", res, thread->name()));2321}2322} else {2323// Called from attached JVMCI shared library thread2324extern struct JavaVM_ main_vm;2325jint res = main_vm.DetachCurrentThread();2326if (res != JNI_OK) {2327JNI_THROW("detachCurrentThread", InternalError, "Cannot detach non-attached thread");2328}2329}2330C2V_END23312332C2V_VMENTRY_0(jlong, translate, (JNIEnv* env, jobject, jobject obj_handle))2333requireJVMCINativeLibrary(JVMCI_CHECK_0);2334if (obj_handle == NULL) {2335return 0L;2336}2337JVMCIEnv __peer_jvmci_env__(thread, !JVMCIENV->is_hotspot(), __FILE__, __LINE__);2338JVMCIEnv* peerEnv = &__peer_jvmci_env__;2339JVMCIEnv* thisEnv = JVMCIENV;23402341JVMCIObject obj = thisEnv->wrap(obj_handle);2342JVMCIObject result;2343if (thisEnv->isa_HotSpotResolvedJavaMethodImpl(obj)) {2344methodHandle method(THREAD, thisEnv->asMethod(obj));2345result = peerEnv->get_jvmci_method(method, JVMCI_CHECK_0);2346} else if (thisEnv->isa_HotSpotResolvedObjectTypeImpl(obj)) {2347Klass* klass = thisEnv->asKlass(obj);2348JVMCIKlassHandle klass_handle(THREAD);2349klass_handle = klass;2350result = peerEnv->get_jvmci_type(klass_handle, JVMCI_CHECK_0);2351} else if (thisEnv->isa_HotSpotResolvedPrimitiveType(obj)) {2352BasicType type = JVMCIENV->kindToBasicType(JVMCIENV->get_HotSpotResolvedPrimitiveType_kind(obj), JVMCI_CHECK_0);2353result = peerEnv->get_jvmci_primitive_type(type);2354} else if (thisEnv->isa_IndirectHotSpotObjectConstantImpl(obj) ||2355thisEnv->isa_DirectHotSpotObjectConstantImpl(obj)) {2356Handle constant = thisEnv->asConstant(obj, JVMCI_CHECK_0);2357result = peerEnv->get_object_constant(constant());2358} else if (thisEnv->isa_HotSpotNmethod(obj)) {2359nmethodLocker locker;2360nmethod* nm = JVMCIENV->get_nmethod(obj, locker);2361if (nm != NULL) {2362JVMCINMethodData* data = nm->jvmci_nmethod_data();2363if (data != NULL) {2364if (peerEnv->is_hotspot()) {2365// Only the mirror in the HotSpot heap is accessible2366// through JVMCINMethodData2367oop nmethod_mirror = data->get_nmethod_mirror(nm, /* phantom_ref */ true);2368if (nmethod_mirror != NULL) {2369result = HotSpotJVMCI::wrap(nmethod_mirror);2370}2371}2372}2373}2374if (result.is_null()) {2375JVMCIObject methodObject = thisEnv->get_HotSpotNmethod_method(obj);2376methodHandle mh(THREAD, thisEnv->asMethod(methodObject));2377jboolean isDefault = thisEnv->get_HotSpotNmethod_isDefault(obj);2378jlong compileIdSnapshot = thisEnv->get_HotSpotNmethod_compileIdSnapshot(obj);2379JVMCIObject name_string = thisEnv->get_InstalledCode_name(obj);2380const char* cstring = name_string.is_null() ? NULL : thisEnv->as_utf8_string(name_string);2381// Create a new HotSpotNmethod instance in the peer runtime2382result = peerEnv->new_HotSpotNmethod(mh, cstring, isDefault, compileIdSnapshot, JVMCI_CHECK_0);2383if (nm == NULL) {2384// nmethod must have been unloaded2385} else {2386// Link the new HotSpotNmethod to the nmethod2387peerEnv->initialize_installed_code(result, nm, JVMCI_CHECK_0);2388// Only HotSpotNmethod instances in the HotSpot heap are tracked directly by the runtime.2389if (peerEnv->is_hotspot()) {2390JVMCINMethodData* data = nm->jvmci_nmethod_data();2391if (data == NULL) {2392JVMCI_THROW_MSG_0(IllegalArgumentException, "Cannot set HotSpotNmethod mirror for default nmethod");2393}2394if (data->get_nmethod_mirror(nm, /* phantom_ref */ false) != NULL) {2395JVMCI_THROW_MSG_0(IllegalArgumentException, "Cannot overwrite existing HotSpotNmethod mirror for nmethod");2396}2397oop nmethod_mirror = HotSpotJVMCI::resolve(result);2398data->set_nmethod_mirror(nm, nmethod_mirror);2399}2400}2401}2402} else {2403JVMCI_THROW_MSG_0(IllegalArgumentException,2404err_msg("Cannot translate object of type: %s", thisEnv->klass_name(obj)));2405}2406return (jlong) peerEnv->make_global(result).as_jobject();2407}24082409C2V_VMENTRY_NULL(jobject, unhand, (JNIEnv* env, jobject, jlong obj_handle))2410requireJVMCINativeLibrary(JVMCI_CHECK_NULL);2411if (obj_handle == 0L) {2412return NULL;2413}2414jobject global_handle = (jobject) obj_handle;2415JVMCIObject global_handle_obj = JVMCIENV->wrap((jobject) obj_handle);2416jobject result = JVMCIENV->make_local(global_handle_obj).as_jobject();24172418JVMCIENV->destroy_global(global_handle_obj);2419return result;2420}24212422C2V_VMENTRY(void, updateHotSpotNmethod, (JNIEnv* env, jobject, jobject code_handle))2423JVMCIObject code = JVMCIENV->wrap(code_handle);2424// Execute this operation for the side effect of updating the InstalledCode state2425nmethodLocker locker;2426JVMCIENV->get_nmethod(code, locker);2427}24282429C2V_VMENTRY_NULL(jbyteArray, getCode, (JNIEnv* env, jobject, jobject code_handle))2430JVMCIObject code = JVMCIENV->wrap(code_handle);2431nmethodLocker locker;2432CodeBlob* cb = JVMCIENV->get_code_blob(code, locker);2433if (cb == NULL) {2434return NULL;2435}2436int code_size = cb->code_size();2437JVMCIPrimitiveArray result = JVMCIENV->new_byteArray(code_size, JVMCI_CHECK_NULL);2438JVMCIENV->copy_bytes_from((jbyte*) cb->code_begin(), result, 0, code_size);2439return JVMCIENV->get_jbyteArray(result);2440}24412442C2V_VMENTRY_NULL(jobject, asReflectionExecutable, (JNIEnv* env, jobject, jobject jvmci_method))2443requireInHotSpot("asReflectionExecutable", JVMCI_CHECK_NULL);2444methodHandle m(THREAD, JVMCIENV->asMethod(jvmci_method));2445oop executable;2446if (m->is_initializer()) {2447if (m->is_static_initializer()) {2448JVMCI_THROW_MSG_NULL(IllegalArgumentException,2449"Cannot create java.lang.reflect.Method for class initializer");2450}2451executable = Reflection::new_constructor(m, CHECK_NULL);2452} else {2453executable = Reflection::new_method(m, false, CHECK_NULL);2454}2455return JNIHandles::make_local(THREAD, executable);2456}24572458C2V_VMENTRY_NULL(jobject, asReflectionField, (JNIEnv* env, jobject, jobject jvmci_type, jint index))2459requireInHotSpot("asReflectionField", JVMCI_CHECK_NULL);2460Klass* klass = JVMCIENV->asKlass(jvmci_type);2461if (!klass->is_instance_klass()) {2462JVMCI_THROW_MSG_NULL(IllegalArgumentException,2463err_msg("Expected non-primitive type, got %s", klass->external_name()));2464}2465InstanceKlass* iklass = InstanceKlass::cast(klass);2466Array<u2>* fields = iklass->fields();2467if (index < 0 ||index > fields->length()) {2468JVMCI_THROW_MSG_NULL(IllegalArgumentException,2469err_msg("Field index %d out of bounds for %s", index, klass->external_name()));2470}2471fieldDescriptor fd(iklass, index);2472oop reflected = Reflection::new_field(&fd, CHECK_NULL);2473return JNIHandles::make_local(THREAD, reflected);2474}24752476C2V_VMENTRY_NULL(jobjectArray, getFailedSpeculations, (JNIEnv* env, jobject, jlong failed_speculations_address, jobjectArray current))2477FailedSpeculation* head = *((FailedSpeculation**)(address) failed_speculations_address);2478int result_length = 0;2479for (FailedSpeculation* fs = head; fs != NULL; fs = fs->next()) {2480result_length++;2481}2482int current_length = 0;2483JVMCIObjectArray current_array = NULL;2484if (current != NULL) {2485current_array = JVMCIENV->wrap(current);2486current_length = JVMCIENV->get_length(current_array);2487if (current_length == result_length) {2488// No new failures2489return current;2490}2491}2492JVMCIObjectArray result = JVMCIENV->new_byte_array_array(result_length, JVMCI_CHECK_NULL);2493int result_index = 0;2494for (FailedSpeculation* fs = head; result_index < result_length; fs = fs->next()) {2495assert(fs != NULL, "npe");2496JVMCIPrimitiveArray entry;2497if (result_index < current_length) {2498entry = (JVMCIPrimitiveArray) JVMCIENV->get_object_at(current_array, result_index);2499} else {2500entry = JVMCIENV->new_byteArray(fs->data_len(), JVMCI_CHECK_NULL);2501JVMCIENV->copy_bytes_from((jbyte*) fs->data(), entry, 0, fs->data_len());2502}2503JVMCIENV->put_object_at(result, result_index++, entry);2504}2505return JVMCIENV->get_jobjectArray(result);2506}25072508C2V_VMENTRY_0(jlong, getFailedSpeculationsAddress, (JNIEnv* env, jobject, jobject jvmci_method))2509methodHandle method(THREAD, JVMCIENV->asMethod(jvmci_method));2510MethodData* method_data = method->method_data();2511if (method_data == NULL) {2512ClassLoaderData* loader_data = method->method_holder()->class_loader_data();2513method_data = MethodData::allocate(loader_data, method, CHECK_0);2514method->set_method_data(method_data);2515}2516return (jlong) method_data->get_failed_speculations_address();2517}25182519C2V_VMENTRY(void, releaseFailedSpeculations, (JNIEnv* env, jobject, jlong failed_speculations_address))2520FailedSpeculation::free_failed_speculations((FailedSpeculation**)(address) failed_speculations_address);2521}25222523C2V_VMENTRY_0(jboolean, addFailedSpeculation, (JNIEnv* env, jobject, jlong failed_speculations_address, jbyteArray speculation_obj))2524JVMCIPrimitiveArray speculation_handle = JVMCIENV->wrap(speculation_obj);2525int speculation_len = JVMCIENV->get_length(speculation_handle);2526char* speculation = NEW_RESOURCE_ARRAY(char, speculation_len);2527JVMCIENV->copy_bytes_to(speculation_handle, (jbyte*) speculation, 0, speculation_len);2528return FailedSpeculation::add_failed_speculation(NULL, (FailedSpeculation**)(address) failed_speculations_address, (address) speculation, speculation_len);2529}25302531C2V_VMENTRY(void, callSystemExit, (JNIEnv* env, jobject, jint status))2532JavaValue result(T_VOID);2533JavaCallArguments jargs(1);2534jargs.push_int(status);2535JavaCalls::call_static(&result,2536vmClasses::System_klass(),2537vmSymbols::exit_method_name(),2538vmSymbols::int_void_signature(),2539&jargs,2540CHECK);2541}25422543C2V_VMENTRY_0(jlong, ticksNow, (JNIEnv* env, jobject))2544return CompilerEvent::ticksNow();2545}25462547C2V_VMENTRY_0(jint, registerCompilerPhase, (JNIEnv* env, jobject, jstring jphase_name))2548#if INCLUDE_JFR2549JVMCIObject phase_name = JVMCIENV->wrap(jphase_name);2550const char *name = JVMCIENV->as_utf8_string(phase_name);2551return CompilerEvent::PhaseEvent::get_phase_id(name, true, true, true);2552#else2553return -1;2554#endif // !INCLUDE_JFR2555}25562557C2V_VMENTRY(void, notifyCompilerPhaseEvent, (JNIEnv* env, jobject, jlong startTime, jint phase, jint compileId, jint level))2558EventCompilerPhase event;2559if (event.should_commit()) {2560CompilerEvent::PhaseEvent::post(event, startTime, phase, compileId, level);2561}2562}25632564C2V_VMENTRY(void, notifyCompilerInliningEvent, (JNIEnv* env, jobject, jint compileId, jobject caller, jobject callee, jboolean succeeded, jstring jmessage, jint bci))2565EventCompilerInlining event;2566if (event.should_commit()) {2567Method* caller_method = JVMCIENV->asMethod(caller);2568Method* callee_method = JVMCIENV->asMethod(callee);2569JVMCIObject message = JVMCIENV->wrap(jmessage);2570CompilerEvent::InlineEvent::post(event, compileId, caller_method, callee_method, succeeded, JVMCIENV->as_utf8_string(message), bci);2571}2572}25732574#define CC (char*) /*cast a literal from (const char*)*/2575#define FN_PTR(f) CAST_FROM_FN_PTR(void*, &(c2v_ ## f))25762577#define STRING "Ljava/lang/String;"2578#define OBJECT "Ljava/lang/Object;"2579#define CLASS "Ljava/lang/Class;"2580#define OBJECTCONSTANT "Ljdk/vm/ci/hotspot/HotSpotObjectConstantImpl;"2581#define HANDLECONSTANT "Ljdk/vm/ci/hotspot/IndirectHotSpotObjectConstantImpl;"2582#define EXECUTABLE "Ljava/lang/reflect/Executable;"2583#define STACK_TRACE_ELEMENT "Ljava/lang/StackTraceElement;"2584#define INSTALLED_CODE "Ljdk/vm/ci/code/InstalledCode;"2585#define TARGET_DESCRIPTION "Ljdk/vm/ci/code/TargetDescription;"2586#define BYTECODE_FRAME "Ljdk/vm/ci/code/BytecodeFrame;"2587#define JAVACONSTANT "Ljdk/vm/ci/meta/JavaConstant;"2588#define INSPECTED_FRAME_VISITOR "Ljdk/vm/ci/code/stack/InspectedFrameVisitor;"2589#define RESOLVED_METHOD "Ljdk/vm/ci/meta/ResolvedJavaMethod;"2590#define HS_RESOLVED_METHOD "Ljdk/vm/ci/hotspot/HotSpotResolvedJavaMethodImpl;"2591#define HS_RESOLVED_KLASS "Ljdk/vm/ci/hotspot/HotSpotResolvedObjectTypeImpl;"2592#define HS_RESOLVED_TYPE "Ljdk/vm/ci/hotspot/HotSpotResolvedJavaType;"2593#define HS_RESOLVED_FIELD "Ljdk/vm/ci/hotspot/HotSpotResolvedJavaField;"2594#define HS_INSTALLED_CODE "Ljdk/vm/ci/hotspot/HotSpotInstalledCode;"2595#define HS_NMETHOD "Ljdk/vm/ci/hotspot/HotSpotNmethod;"2596#define HS_CONSTANT_POOL "Ljdk/vm/ci/hotspot/HotSpotConstantPool;"2597#define HS_COMPILED_CODE "Ljdk/vm/ci/hotspot/HotSpotCompiledCode;"2598#define HS_CONFIG "Ljdk/vm/ci/hotspot/HotSpotVMConfig;"2599#define HS_METADATA "Ljdk/vm/ci/hotspot/HotSpotMetaData;"2600#define HS_STACK_FRAME_REF "Ljdk/vm/ci/hotspot/HotSpotStackFrameReference;"2601#define HS_SPECULATION_LOG "Ljdk/vm/ci/hotspot/HotSpotSpeculationLog;"2602#define METASPACE_OBJECT "Ljdk/vm/ci/hotspot/MetaspaceObject;"2603#define REFLECTION_EXECUTABLE "Ljava/lang/reflect/Executable;"2604#define REFLECTION_FIELD "Ljava/lang/reflect/Field;"2605#define METASPACE_METHOD_DATA "J"26062607JNINativeMethod CompilerToVM::methods[] = {2608{CC "getBytecode", CC "(" HS_RESOLVED_METHOD ")[B", FN_PTR(getBytecode)},2609{CC "getExceptionTableStart", CC "(" HS_RESOLVED_METHOD ")J", FN_PTR(getExceptionTableStart)},2610{CC "getExceptionTableLength", CC "(" HS_RESOLVED_METHOD ")I", FN_PTR(getExceptionTableLength)},2611{CC "findUniqueConcreteMethod", CC "(" HS_RESOLVED_KLASS HS_RESOLVED_METHOD ")" HS_RESOLVED_METHOD, FN_PTR(findUniqueConcreteMethod)},2612{CC "getImplementor", CC "(" HS_RESOLVED_KLASS ")" HS_RESOLVED_KLASS, FN_PTR(getImplementor)},2613{CC "getStackTraceElement", CC "(" HS_RESOLVED_METHOD "I)" STACK_TRACE_ELEMENT, FN_PTR(getStackTraceElement)},2614{CC "methodIsIgnoredBySecurityStackWalk", CC "(" HS_RESOLVED_METHOD ")Z", FN_PTR(methodIsIgnoredBySecurityStackWalk)},2615{CC "setNotInlinableOrCompilable", CC "(" HS_RESOLVED_METHOD ")V", FN_PTR(setNotInlinableOrCompilable)},2616{CC "isCompilable", CC "(" HS_RESOLVED_METHOD ")Z", FN_PTR(isCompilable)},2617{CC "hasNeverInlineDirective", CC "(" HS_RESOLVED_METHOD ")Z", FN_PTR(hasNeverInlineDirective)},2618{CC "shouldInlineMethod", CC "(" HS_RESOLVED_METHOD ")Z", FN_PTR(shouldInlineMethod)},2619{CC "lookupType", CC "(" STRING HS_RESOLVED_KLASS "Z)" HS_RESOLVED_TYPE, FN_PTR(lookupType)},2620{CC "getArrayType", CC "(" HS_RESOLVED_TYPE ")" HS_RESOLVED_KLASS, FN_PTR(getArrayType)},2621{CC "lookupClass", CC "(" CLASS ")" HS_RESOLVED_TYPE, FN_PTR(lookupClass)},2622{CC "lookupNameInPool", CC "(" HS_CONSTANT_POOL "I)" STRING, FN_PTR(lookupNameInPool)},2623{CC "lookupNameAndTypeRefIndexInPool", CC "(" HS_CONSTANT_POOL "I)I", FN_PTR(lookupNameAndTypeRefIndexInPool)},2624{CC "lookupSignatureInPool", CC "(" HS_CONSTANT_POOL "I)" STRING, FN_PTR(lookupSignatureInPool)},2625{CC "lookupKlassRefIndexInPool", CC "(" HS_CONSTANT_POOL "I)I", FN_PTR(lookupKlassRefIndexInPool)},2626{CC "lookupKlassInPool", CC "(" HS_CONSTANT_POOL "I)Ljava/lang/Object;", FN_PTR(lookupKlassInPool)},2627{CC "lookupAppendixInPool", CC "(" HS_CONSTANT_POOL "I)" OBJECTCONSTANT, FN_PTR(lookupAppendixInPool)},2628{CC "lookupMethodInPool", CC "(" HS_CONSTANT_POOL "IB)" HS_RESOLVED_METHOD, FN_PTR(lookupMethodInPool)},2629{CC "constantPoolRemapInstructionOperandFromCache", CC "(" HS_CONSTANT_POOL "I)I", FN_PTR(constantPoolRemapInstructionOperandFromCache)},2630{CC "resolvePossiblyCachedConstantInPool", CC "(" HS_CONSTANT_POOL "I)" JAVACONSTANT, FN_PTR(resolvePossiblyCachedConstantInPool)},2631{CC "resolveTypeInPool", CC "(" HS_CONSTANT_POOL "I)" HS_RESOLVED_KLASS, FN_PTR(resolveTypeInPool)},2632{CC "resolveFieldInPool", CC "(" HS_CONSTANT_POOL "I" HS_RESOLVED_METHOD "B[I)" HS_RESOLVED_KLASS, FN_PTR(resolveFieldInPool)},2633{CC "resolveInvokeDynamicInPool", CC "(" HS_CONSTANT_POOL "I)V", FN_PTR(resolveInvokeDynamicInPool)},2634{CC "resolveInvokeHandleInPool", CC "(" HS_CONSTANT_POOL "I)V", FN_PTR(resolveInvokeHandleInPool)},2635{CC "isResolvedInvokeHandleInPool", CC "(" HS_CONSTANT_POOL "I)I", FN_PTR(isResolvedInvokeHandleInPool)},2636{CC "resolveMethod", CC "(" HS_RESOLVED_KLASS HS_RESOLVED_METHOD HS_RESOLVED_KLASS ")" HS_RESOLVED_METHOD, FN_PTR(resolveMethod)},2637{CC "getSignaturePolymorphicHolders", CC "()[" STRING, FN_PTR(getSignaturePolymorphicHolders)},2638{CC "getVtableIndexForInterfaceMethod", CC "(" HS_RESOLVED_KLASS HS_RESOLVED_METHOD ")I", FN_PTR(getVtableIndexForInterfaceMethod)},2639{CC "getClassInitializer", CC "(" HS_RESOLVED_KLASS ")" HS_RESOLVED_METHOD, FN_PTR(getClassInitializer)},2640{CC "hasFinalizableSubclass", CC "(" HS_RESOLVED_KLASS ")Z", FN_PTR(hasFinalizableSubclass)},2641{CC "getMaxCallTargetOffset", CC "(J)J", FN_PTR(getMaxCallTargetOffset)},2642{CC "asResolvedJavaMethod", CC "(" EXECUTABLE ")" HS_RESOLVED_METHOD, FN_PTR(asResolvedJavaMethod)},2643{CC "getResolvedJavaMethod", CC "(" OBJECTCONSTANT "J)" HS_RESOLVED_METHOD, FN_PTR(getResolvedJavaMethod)},2644{CC "getConstantPool", CC "(" METASPACE_OBJECT ")" HS_CONSTANT_POOL, FN_PTR(getConstantPool)},2645{CC "getResolvedJavaType0", CC "(Ljava/lang/Object;JZ)" HS_RESOLVED_KLASS, FN_PTR(getResolvedJavaType0)},2646{CC "readConfiguration", CC "()[" OBJECT, FN_PTR(readConfiguration)},2647{CC "installCode", CC "(" TARGET_DESCRIPTION HS_COMPILED_CODE INSTALLED_CODE "J[B)I", FN_PTR(installCode)},2648{CC "getMetadata", CC "(" TARGET_DESCRIPTION HS_COMPILED_CODE HS_METADATA ")I", FN_PTR(getMetadata)},2649{CC "resetCompilationStatistics", CC "()V", FN_PTR(resetCompilationStatistics)},2650{CC "disassembleCodeBlob", CC "(" INSTALLED_CODE ")" STRING, FN_PTR(disassembleCodeBlob)},2651{CC "executeHotSpotNmethod", CC "([" OBJECT HS_NMETHOD ")" OBJECT, FN_PTR(executeHotSpotNmethod)},2652{CC "getLineNumberTable", CC "(" HS_RESOLVED_METHOD ")[J", FN_PTR(getLineNumberTable)},2653{CC "getLocalVariableTableStart", CC "(" HS_RESOLVED_METHOD ")J", FN_PTR(getLocalVariableTableStart)},2654{CC "getLocalVariableTableLength", CC "(" HS_RESOLVED_METHOD ")I", FN_PTR(getLocalVariableTableLength)},2655{CC "reprofile", CC "(" HS_RESOLVED_METHOD ")V", FN_PTR(reprofile)},2656{CC "invalidateHotSpotNmethod", CC "(" HS_NMETHOD ")V", FN_PTR(invalidateHotSpotNmethod)},2657{CC "collectCounters", CC "()[J", FN_PTR(collectCounters)},2658{CC "getCountersSize", CC "()I", FN_PTR(getCountersSize)},2659{CC "setCountersSize", CC "(I)Z", FN_PTR(setCountersSize)},2660{CC "allocateCompileId", CC "(" HS_RESOLVED_METHOD "I)I", FN_PTR(allocateCompileId)},2661{CC "isMature", CC "(" METASPACE_METHOD_DATA ")Z", FN_PTR(isMature)},2662{CC "hasCompiledCodeForOSR", CC "(" HS_RESOLVED_METHOD "II)Z", FN_PTR(hasCompiledCodeForOSR)},2663{CC "getSymbol", CC "(J)" STRING, FN_PTR(getSymbol)},2664{CC "iterateFrames", CC "([" RESOLVED_METHOD "[" RESOLVED_METHOD "I" INSPECTED_FRAME_VISITOR ")" OBJECT, FN_PTR(iterateFrames)},2665{CC "materializeVirtualObjects", CC "(" HS_STACK_FRAME_REF "Z)V", FN_PTR(materializeVirtualObjects)},2666{CC "shouldDebugNonSafepoints", CC "()Z", FN_PTR(shouldDebugNonSafepoints)},2667{CC "writeDebugOutput", CC "(JIZ)V", FN_PTR(writeDebugOutput)},2668{CC "flushDebugOutput", CC "()V", FN_PTR(flushDebugOutput)},2669{CC "methodDataProfileDataSize", CC "(JI)I", FN_PTR(methodDataProfileDataSize)},2670{CC "getFingerprint", CC "(J)J", FN_PTR(getFingerprint)},2671{CC "interpreterFrameSize", CC "(" BYTECODE_FRAME ")I", FN_PTR(interpreterFrameSize)},2672{CC "compileToBytecode", CC "(" OBJECTCONSTANT ")V", FN_PTR(compileToBytecode)},2673{CC "getFlagValue", CC "(" STRING ")" OBJECT, FN_PTR(getFlagValue)},2674{CC "getInterfaces", CC "(" HS_RESOLVED_KLASS ")[" HS_RESOLVED_KLASS, FN_PTR(getInterfaces)},2675{CC "getComponentType", CC "(" HS_RESOLVED_KLASS ")" HS_RESOLVED_TYPE, FN_PTR(getComponentType)},2676{CC "ensureInitialized", CC "(" HS_RESOLVED_KLASS ")V", FN_PTR(ensureInitialized)},2677{CC "ensureLinked", CC "(" HS_RESOLVED_KLASS ")V", FN_PTR(ensureLinked)},2678{CC "getIdentityHashCode", CC "(" OBJECTCONSTANT ")I", FN_PTR(getIdentityHashCode)},2679{CC "isInternedString", CC "(" OBJECTCONSTANT ")Z", FN_PTR(isInternedString)},2680{CC "unboxPrimitive", CC "(" OBJECTCONSTANT ")" OBJECT, FN_PTR(unboxPrimitive)},2681{CC "boxPrimitive", CC "(" OBJECT ")" OBJECTCONSTANT, FN_PTR(boxPrimitive)},2682{CC "getDeclaredConstructors", CC "(" HS_RESOLVED_KLASS ")[" RESOLVED_METHOD, FN_PTR(getDeclaredConstructors)},2683{CC "getDeclaredMethods", CC "(" HS_RESOLVED_KLASS ")[" RESOLVED_METHOD, FN_PTR(getDeclaredMethods)},2684{CC "readFieldValue", CC "(" HS_RESOLVED_KLASS HS_RESOLVED_KLASS "JZLjdk/vm/ci/meta/JavaKind;)" JAVACONSTANT, FN_PTR(readFieldValue)},2685{CC "readFieldValue", CC "(" OBJECTCONSTANT HS_RESOLVED_KLASS "JZLjdk/vm/ci/meta/JavaKind;)" JAVACONSTANT, FN_PTR(readFieldValue)},2686{CC "isInstance", CC "(" HS_RESOLVED_KLASS OBJECTCONSTANT ")Z", FN_PTR(isInstance)},2687{CC "isAssignableFrom", CC "(" HS_RESOLVED_KLASS HS_RESOLVED_KLASS ")Z", FN_PTR(isAssignableFrom)},2688{CC "isTrustedForIntrinsics", CC "(" HS_RESOLVED_KLASS ")Z", FN_PTR(isTrustedForIntrinsics)},2689{CC "asJavaType", CC "(" OBJECTCONSTANT ")" HS_RESOLVED_TYPE, FN_PTR(asJavaType)},2690{CC "asString", CC "(" OBJECTCONSTANT ")" STRING, FN_PTR(asString)},2691{CC "equals", CC "(" OBJECTCONSTANT "J" OBJECTCONSTANT "J)Z", FN_PTR(equals)},2692{CC "getJavaMirror", CC "(" HS_RESOLVED_TYPE ")" OBJECTCONSTANT, FN_PTR(getJavaMirror)},2693{CC "getArrayLength", CC "(" OBJECTCONSTANT ")I", FN_PTR(getArrayLength)},2694{CC "readArrayElement", CC "(" OBJECTCONSTANT "I)Ljava/lang/Object;", FN_PTR(readArrayElement)},2695{CC "arrayBaseOffset", CC "(Ljdk/vm/ci/meta/JavaKind;)I", FN_PTR(arrayBaseOffset)},2696{CC "arrayIndexScale", CC "(Ljdk/vm/ci/meta/JavaKind;)I", FN_PTR(arrayIndexScale)},2697{CC "deleteGlobalHandle", CC "(J)V", FN_PTR(deleteGlobalHandle)},2698{CC "registerNativeMethods", CC "(" CLASS ")[J", FN_PTR(registerNativeMethods)},2699{CC "isCurrentThreadAttached", CC "()Z", FN_PTR(isCurrentThreadAttached)},2700{CC "getCurrentJavaThread", CC "()J", FN_PTR(getCurrentJavaThread)},2701{CC "attachCurrentThread", CC "([BZ)Z", FN_PTR(attachCurrentThread)},2702{CC "detachCurrentThread", CC "()V", FN_PTR(detachCurrentThread)},2703{CC "translate", CC "(" OBJECT ")J", FN_PTR(translate)},2704{CC "unhand", CC "(J)" OBJECT, FN_PTR(unhand)},2705{CC "updateHotSpotNmethod", CC "(" HS_NMETHOD ")V", FN_PTR(updateHotSpotNmethod)},2706{CC "getCode", CC "(" HS_INSTALLED_CODE ")[B", FN_PTR(getCode)},2707{CC "asReflectionExecutable", CC "(" HS_RESOLVED_METHOD ")" REFLECTION_EXECUTABLE, FN_PTR(asReflectionExecutable)},2708{CC "asReflectionField", CC "(" HS_RESOLVED_KLASS "I)" REFLECTION_FIELD, FN_PTR(asReflectionField)},2709{CC "getFailedSpeculations", CC "(J[[B)[[B", FN_PTR(getFailedSpeculations)},2710{CC "getFailedSpeculationsAddress", CC "(" HS_RESOLVED_METHOD ")J", FN_PTR(getFailedSpeculationsAddress)},2711{CC "releaseFailedSpeculations", CC "(J)V", FN_PTR(releaseFailedSpeculations)},2712{CC "addFailedSpeculation", CC "(J[B)Z", FN_PTR(addFailedSpeculation)},2713{CC "callSystemExit", CC "(I)V", FN_PTR(callSystemExit)},2714{CC "ticksNow", CC "()J", FN_PTR(ticksNow)},2715{CC "registerCompilerPhase", CC "(" STRING ")I", FN_PTR(registerCompilerPhase)},2716{CC "notifyCompilerPhaseEvent", CC "(JIII)V", FN_PTR(notifyCompilerPhaseEvent)},2717{CC "notifyCompilerInliningEvent", CC "(I" HS_RESOLVED_METHOD HS_RESOLVED_METHOD "ZLjava/lang/String;I)V", FN_PTR(notifyCompilerInliningEvent)},2718};27192720int CompilerToVM::methods_count() {2721return sizeof(methods) / sizeof(JNINativeMethod);2722}272327242725