Path: blob/master/src/hotspot/share/jvmci/jvmciEnv.cpp
64440 views
/*1* Copyright (c) 1999, 2022, 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*22*/2324#include "precompiled.hpp"25#include "jvm_io.h"26#include "classfile/stringTable.hpp"27#include "classfile/symbolTable.hpp"28#include "classfile/systemDictionary.hpp"29#include "code/codeCache.hpp"30#include "compiler/compilerOracle.hpp"31#include "compiler/compileTask.hpp"32#include "memory/oopFactory.hpp"33#include "memory/resourceArea.hpp"34#include "memory/universe.hpp"35#include "oops/objArrayKlass.hpp"36#include "oops/typeArrayOop.inline.hpp"37#include "prims/jvmtiExport.hpp"38#include "runtime/deoptimization.hpp"39#include "runtime/jniHandles.inline.hpp"40#include "runtime/javaCalls.hpp"41#include "jvmci/jniAccessMark.inline.hpp"42#include "jvmci/jvmciCompiler.hpp"43#include "jvmci/jvmciRuntime.hpp"4445JVMCICompileState::JVMCICompileState(CompileTask* task, JVMCICompiler* compiler):46_task(task),47_compiler(compiler),48_retryable(true),49_failure_reason(NULL),50_failure_reason_on_C_heap(false) {51// Get Jvmti capabilities under lock to get consistent values.52MutexLocker mu(JvmtiThreadState_lock);53_jvmti_redefinition_count = JvmtiExport::redefinition_count();54_jvmti_can_hotswap_or_post_breakpoint = JvmtiExport::can_hotswap_or_post_breakpoint() ? 1 : 0;55_jvmti_can_access_local_variables = JvmtiExport::can_access_local_variables() ? 1 : 0;56_jvmti_can_post_on_exceptions = JvmtiExport::can_post_on_exceptions() ? 1 : 0;57_jvmti_can_pop_frame = JvmtiExport::can_pop_frame() ? 1 : 0;58_target_method_is_old = _task != NULL && _task->method()->is_old();59if (task->is_blocking()) {60task->set_blocking_jvmci_compile_state(this);61}62}6364// Update global JVMCI compilation ticks after 512 thread-local JVMCI compilation ticks.65// This mitigates the overhead of the atomic operation used for the global update.66#define THREAD_TICKS_PER_GLOBAL_TICKS (2 << 9)67#define THREAD_TICKS_PER_GLOBAL_TICKS_MASK (THREAD_TICKS_PER_GLOBAL_TICKS - 1)6869void JVMCICompileState::inc_compilation_ticks() {70if ((++_compilation_ticks & THREAD_TICKS_PER_GLOBAL_TICKS_MASK) == 0) {71_compiler->inc_global_compilation_ticks();72}73}7475bool JVMCICompileState::jvmti_state_changed() const {76// Some classes were redefined77if (jvmti_redefinition_count() != JvmtiExport::redefinition_count()) {78return true;79}80if (!jvmti_can_access_local_variables() &&81JvmtiExport::can_access_local_variables()) {82return true;83}84if (!jvmti_can_hotswap_or_post_breakpoint() &&85JvmtiExport::can_hotswap_or_post_breakpoint()) {86return true;87}88if (!jvmti_can_post_on_exceptions() &&89JvmtiExport::can_post_on_exceptions()) {90return true;91}92if (!jvmti_can_pop_frame() &&93JvmtiExport::can_pop_frame()) {94return true;95}96return false;97}9899void JVMCIEnv::copy_saved_properties() {100assert(!is_hotspot(), "can only copy saved properties from HotSpot to native image");101102JavaThread* THREAD = JavaThread::current(); // For exception macros.103104Klass* k = SystemDictionary::resolve_or_fail(vmSymbols::jdk_vm_ci_services_Services(), Handle(), Handle(), true, THREAD);105if (HAS_PENDING_EXCEPTION) {106JVMCIRuntime::fatal_exception(NULL, "Error initializing jdk.vm.ci.services.Services");107}108InstanceKlass* ik = InstanceKlass::cast(k);109if (ik->should_be_initialized()) {110ik->initialize(THREAD);111if (HAS_PENDING_EXCEPTION) {112JVMCIRuntime::fatal_exception(NULL, "Error initializing jdk.vm.ci.services.Services");113}114}115116// Get the serialized saved properties from HotSpot117TempNewSymbol serializeSavedProperties = SymbolTable::new_symbol("serializeSavedProperties");118JavaValue result(T_OBJECT);119JavaCallArguments args;120JavaCalls::call_static(&result, ik, serializeSavedProperties, vmSymbols::serializePropertiesToByteArray_signature(), &args, THREAD);121if (HAS_PENDING_EXCEPTION) {122JVMCIRuntime::fatal_exception(NULL, "Error calling jdk.vm.ci.services.Services.serializeSavedProperties");123}124oop res = result.get_oop();125assert(res->is_typeArray(), "must be");126assert(TypeArrayKlass::cast(res->klass())->element_type() == T_BYTE, "must be");127typeArrayOop ba = typeArrayOop(res);128int serialized_properties_len = ba->length();129130// Copy serialized saved properties from HotSpot object into native buffer131jbyte* serialized_properties = NEW_RESOURCE_ARRAY(jbyte, serialized_properties_len);132memcpy(serialized_properties, ba->byte_at_addr(0), serialized_properties_len);133134// Copy native buffer into shared library object135JVMCIPrimitiveArray buf = new_byteArray(serialized_properties_len, this);136if (has_pending_exception()) {137describe_pending_exception(true);138fatal("Error in copy_saved_properties");139}140copy_bytes_from(serialized_properties, buf, 0, serialized_properties_len);141if (has_pending_exception()) {142describe_pending_exception(true);143fatal("Error in copy_saved_properties");144}145146// Initialize saved properties in shared library147jclass servicesClass = JNIJVMCI::Services::clazz();148jmethodID initializeSavedProperties = JNIJVMCI::Services::initializeSavedProperties_method();149JNIAccessMark jni(this, THREAD);150jni()->CallStaticVoidMethod(servicesClass, initializeSavedProperties, buf.as_jobject());151if (jni()->ExceptionCheck()) {152jni()->ExceptionDescribe();153fatal("Error calling jdk.vm.ci.services.Services.initializeSavedProperties");154}155}156157void JVMCIEnv::init_env_mode_runtime(JavaThread* thread, JNIEnv* parent_env) {158assert(thread != NULL, "npe");159_env = NULL;160_pop_frame_on_close = false;161_detach_on_close = false;162if (!UseJVMCINativeLibrary) {163// In HotSpot mode, JNI isn't used at all.164_runtime = JVMCI::java_runtime();165_is_hotspot = true;166return;167}168169if (parent_env != NULL) {170// If the parent JNI environment is non-null then figure out whether it171// is a HotSpot or shared library JNIEnv and set the state appropriately.172_is_hotspot = thread->jni_environment() == parent_env;173if (_is_hotspot) {174// Select the Java runtime175_runtime = JVMCI::java_runtime();176return;177}178_runtime = JVMCI::compiler_runtime();179assert(_runtime != NULL, "npe");180_env = parent_env;181return;182}183184// Running in JVMCI shared library mode so ensure the shared library185// is loaded and initialized and get a shared library JNIEnv186_is_hotspot = false;187188_runtime = JVMCI::compiler_runtime();189_env = _runtime->init_shared_library_javavm();190191if (_env != NULL) {192// Creating the JVMCI shared library VM also attaches the current thread193_detach_on_close = true;194} else {195_runtime->GetEnv(thread, (void**)&parent_env, JNI_VERSION_1_2);196if (parent_env != NULL) {197// Even though there's a parent JNI env, there's no guarantee198// it was opened by a JVMCIEnv scope and thus may not have199// pushed a local JNI frame. As such, we use a new JNI local200// frame in this scope to ensure local JNI refs are collected201// in a timely manner after leaving this scope.202_env = parent_env;203} else {204ResourceMark rm; // Thread name is resource allocated205JavaVMAttachArgs attach_args;206attach_args.version = JNI_VERSION_1_2;207attach_args.name = thread->name();208attach_args.group = NULL;209if (_runtime->AttachCurrentThread(thread, (void**) &_env, &attach_args) != JNI_OK) {210fatal("Error attaching current thread (%s) to JVMCI shared library JNI interface", attach_args.name);211}212_detach_on_close = true;213}214}215216assert(_env != NULL, "missing env");217assert(_throw_to_caller == false, "must be");218219JNIAccessMark jni(this, thread);220jint result = _env->PushLocalFrame(32);221if (result != JNI_OK) {222char message[256];223jio_snprintf(message, 256, "Uncaught exception pushing local frame for JVMCIEnv scope entered at %s:%d", _file, _line);224JVMCIRuntime::fatal_exception(this, message);225}226_pop_frame_on_close = true;227}228229JVMCIEnv::JVMCIEnv(JavaThread* thread, JVMCICompileState* compile_state, const char* file, int line):230_throw_to_caller(false), _file(file), _line(line), _compile_state(compile_state) {231init_env_mode_runtime(thread, NULL);232}233234JVMCIEnv::JVMCIEnv(JavaThread* thread, const char* file, int line):235_throw_to_caller(false), _file(file), _line(line), _compile_state(NULL) {236init_env_mode_runtime(thread, NULL);237}238239JVMCIEnv::JVMCIEnv(JavaThread* thread, JNIEnv* parent_env, const char* file, int line):240_throw_to_caller(true), _file(file), _line(line), _compile_state(NULL) {241init_env_mode_runtime(thread, parent_env);242assert(_env == NULL || parent_env == _env, "mismatched JNIEnvironment");243}244245void JVMCIEnv::init(JavaThread* thread, bool is_hotspot, const char* file, int line) {246_compile_state = NULL;247_throw_to_caller = false;248_file = file;249_line = line;250if (is_hotspot) {251_env = NULL;252_pop_frame_on_close = false;253_detach_on_close = false;254_is_hotspot = true;255_runtime = JVMCI::java_runtime();256} else {257init_env_mode_runtime(thread, NULL);258}259}260261// Prints a pending exception (if any) and its stack trace.262void JVMCIEnv::describe_pending_exception(bool clear) {263JavaThread* THREAD = JavaThread::current(); // For exception macros.264if (!is_hotspot()) {265JNIAccessMark jni(this, THREAD);266if (jni()->ExceptionCheck()) {267jthrowable ex = !clear ? jni()->ExceptionOccurred() : NULL;268jni()->ExceptionDescribe();269if (ex != NULL) {270jni()->Throw(ex);271}272}273} else {274if (HAS_PENDING_EXCEPTION) {275JVMCIRuntime::describe_pending_hotspot_exception(THREAD, clear);276}277}278}279280// Shared code for translating an exception from HotSpot to libjvmci or vice versa.281class ExceptionTranslation: public StackObj {282protected:283JVMCIEnv* _from_env; // Source of translation. Can be nullptr.284JVMCIEnv* _to_env; // Destination of translation. Never nullptr.285286ExceptionTranslation(JVMCIEnv* from_env, JVMCIEnv* to_env) : _from_env(from_env), _to_env(to_env) {}287288// Encodes the exception in `_from_env` into `buffer`.289// Where N is the number of bytes needed for the encoding, returns N if N <= `buffer_size`290// and the encoding was written to `buffer` otherwise returns -N.291virtual int encode(JavaThread* THREAD, Klass* runtimeKlass, jlong buffer, int buffer_size) = 0;292293// Decodes the exception in `buffer` in `_to_env` and throws it.294virtual void decode(JavaThread* THREAD, Klass* runtimeKlass, jlong buffer) = 0;295296public:297void doit(JavaThread* THREAD) {298// Resolve HotSpotJVMCIRuntime class explicitly as HotSpotJVMCI::compute_offsets299// may not have been called.300Klass* runtimeKlass = SystemDictionary::resolve_or_fail(vmSymbols::jdk_vm_ci_hotspot_HotSpotJVMCIRuntime(), true, CHECK);301302int buffer_size = 2048;303while (true) {304ResourceMark rm;305jlong buffer = (jlong) NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, jbyte, buffer_size);306int res = encode(THREAD, runtimeKlass, buffer, buffer_size);307if ((_from_env != nullptr && _from_env->has_pending_exception()) || HAS_PENDING_EXCEPTION) {308JVMCIRuntime::fatal_exception(_from_env, "HotSpotJVMCIRuntime.encodeThrowable should not throw an exception");309}310if (res < 0) {311int required_buffer_size = -res;312if (required_buffer_size > buffer_size) {313buffer_size = required_buffer_size;314}315} else {316decode(THREAD, runtimeKlass, buffer);317if (!_to_env->has_pending_exception()) {318JVMCIRuntime::fatal_exception(_to_env, "HotSpotJVMCIRuntime.decodeAndThrowThrowable should throw an exception");319}320return;321}322}323}324};325326// Translates an exception on the HotSpot heap to an exception on the shared library heap.327class HotSpotToSharedLibraryExceptionTranslation : public ExceptionTranslation {328private:329const Handle& _throwable;330331int encode(JavaThread* THREAD, Klass* runtimeKlass, jlong buffer, int buffer_size) {332JavaCallArguments jargs;333jargs.push_oop(_throwable);334jargs.push_long(buffer);335jargs.push_int(buffer_size);336JavaValue result(T_INT);337JavaCalls::call_static(&result,338runtimeKlass,339vmSymbols::encodeThrowable_name(),340vmSymbols::encodeThrowable_signature(), &jargs, THREAD);341return result.get_jint();342}343344void decode(JavaThread* THREAD, Klass* runtimeKlass, jlong buffer) {345JNIAccessMark jni(_to_env, THREAD);346jni()->CallStaticVoidMethod(JNIJVMCI::HotSpotJVMCIRuntime::clazz(),347JNIJVMCI::HotSpotJVMCIRuntime::decodeAndThrowThrowable_method(),348buffer);349}350public:351HotSpotToSharedLibraryExceptionTranslation(JVMCIEnv* hotspot_env, JVMCIEnv* jni_env, const Handle& throwable) :352ExceptionTranslation(hotspot_env, jni_env), _throwable(throwable) {}353};354355// Translates an exception on the shared library heap to an exception on the HotSpot heap.356class SharedLibraryToHotSpotExceptionTranslation : public ExceptionTranslation {357private:358jthrowable _throwable;359360int encode(JavaThread* THREAD, Klass* runtimeKlass, jlong buffer, int buffer_size) {361JNIAccessMark jni(_from_env, THREAD);362return jni()->CallStaticIntMethod(JNIJVMCI::HotSpotJVMCIRuntime::clazz(),363JNIJVMCI::HotSpotJVMCIRuntime::encodeThrowable_method(),364_throwable, buffer, buffer_size);365}366367void decode(JavaThread* THREAD, Klass* runtimeKlass, jlong buffer) {368JavaCallArguments jargs;369jargs.push_long(buffer);370JavaValue result(T_VOID);371JavaCalls::call_static(&result,372runtimeKlass,373vmSymbols::decodeAndThrowThrowable_name(),374vmSymbols::long_void_signature(), &jargs, THREAD);375}376public:377SharedLibraryToHotSpotExceptionTranslation(JVMCIEnv* hotspot_env, JVMCIEnv* jni_env, jthrowable throwable) :378ExceptionTranslation(jni_env, hotspot_env), _throwable(throwable) {}379};380381void JVMCIEnv::translate_to_jni_exception(JavaThread* THREAD, const Handle& throwable, JVMCIEnv* hotspot_env, JVMCIEnv* jni_env) {382HotSpotToSharedLibraryExceptionTranslation(hotspot_env, jni_env, throwable).doit(THREAD);383}384385void JVMCIEnv::translate_from_jni_exception(JavaThread* THREAD, jthrowable throwable, JVMCIEnv* hotspot_env, JVMCIEnv* jni_env) {386SharedLibraryToHotSpotExceptionTranslation(hotspot_env, jni_env, throwable).doit(THREAD);387}388389jboolean JVMCIEnv::transfer_pending_exception(JavaThread* THREAD, JVMCIEnv* peer_env) {390if (is_hotspot()) {391if (HAS_PENDING_EXCEPTION) {392Handle throwable = Handle(THREAD, PENDING_EXCEPTION);393CLEAR_PENDING_EXCEPTION;394translate_to_jni_exception(THREAD, throwable, this, peer_env);395return true;396}397} else {398jthrowable ex = nullptr;399{400JNIAccessMark jni(this, THREAD);401ex = jni()->ExceptionOccurred();402if (ex != nullptr) {403jni()->ExceptionClear();404}405}406if (ex != nullptr) {407translate_from_jni_exception(THREAD, ex, peer_env, this);408return true;409}410}411return false;412}413414415JVMCIEnv::~JVMCIEnv() {416if (_throw_to_caller) {417if (is_hotspot()) {418// Nothing to do419} else {420Thread* thread = Thread::current();421if (thread->is_Java_thread()) {422JavaThread* THREAD = thread->as_Java_thread(); // For exception macros.423if (HAS_PENDING_EXCEPTION) {424Handle throwable = Handle(THREAD, PENDING_EXCEPTION);425CLEAR_PENDING_EXCEPTION;426translate_to_jni_exception(THREAD, throwable, nullptr, this);427}428}429}430} else {431if (_pop_frame_on_close) {432// Pop the JNI local frame that was pushed when entering this JVMCIEnv scope.433JNIAccessMark jni(this);434jni()->PopLocalFrame(NULL);435}436437if (has_pending_exception()) {438char message[256];439jio_snprintf(message, 256, "Uncaught exception exiting JVMCIEnv scope entered at %s:%d", _file, _line);440JVMCIRuntime::fatal_exception(this, message);441}442443if (_detach_on_close) {444_runtime->DetachCurrentThread(JavaThread::current());445}446}447}448449jboolean JVMCIEnv::has_pending_exception() {450if (is_hotspot()) {451JavaThread* THREAD = JavaThread::current(); // For exception macros.452return HAS_PENDING_EXCEPTION;453} else {454JNIAccessMark jni(this);455return jni()->ExceptionCheck();456}457}458459void JVMCIEnv::clear_pending_exception() {460if (is_hotspot()) {461JavaThread* THREAD = JavaThread::current(); // For exception macros.462CLEAR_PENDING_EXCEPTION;463} else {464JNIAccessMark jni(this);465jni()->ExceptionClear();466}467}468469int JVMCIEnv::get_length(JVMCIArray array) {470if (is_hotspot()) {471return HotSpotJVMCI::resolve(array)->length();472} else {473JNIAccessMark jni(this);474return jni()->GetArrayLength(get_jarray(array));475}476}477478JVMCIObject JVMCIEnv::get_object_at(JVMCIObjectArray array, int index) {479if (is_hotspot()) {480oop result = HotSpotJVMCI::resolve(array)->obj_at(index);481return wrap(result);482} else {483JNIAccessMark jni(this);484jobject result = jni()->GetObjectArrayElement(get_jobjectArray(array), index);485return wrap(result);486}487}488489void JVMCIEnv::put_object_at(JVMCIObjectArray array, int index, JVMCIObject value) {490if (is_hotspot()) {491HotSpotJVMCI::resolve(array)->obj_at_put(index, HotSpotJVMCI::resolve(value));492} else {493JNIAccessMark jni(this);494jni()->SetObjectArrayElement(get_jobjectArray(array), index, get_jobject(value));495}496}497498jboolean JVMCIEnv::get_bool_at(JVMCIPrimitiveArray array, int index) {499if (is_hotspot()) {500return HotSpotJVMCI::resolve(array)->bool_at(index);501} else {502JNIAccessMark jni(this);503jboolean result;504jni()->GetBooleanArrayRegion(array.as_jbooleanArray(), index, 1, &result);505return result;506}507}508void JVMCIEnv::put_bool_at(JVMCIPrimitiveArray array, int index, jboolean value) {509if (is_hotspot()) {510HotSpotJVMCI::resolve(array)->bool_at_put(index, value);511} else {512JNIAccessMark jni(this);513jni()->SetBooleanArrayRegion(array.as_jbooleanArray(), index, 1, &value);514}515}516517jbyte JVMCIEnv::get_byte_at(JVMCIPrimitiveArray array, int index) {518if (is_hotspot()) {519return HotSpotJVMCI::resolve(array)->byte_at(index);520} else {521JNIAccessMark jni(this);522jbyte result;523jni()->GetByteArrayRegion(array.as_jbyteArray(), index, 1, &result);524return result;525}526}527void JVMCIEnv::put_byte_at(JVMCIPrimitiveArray array, int index, jbyte value) {528if (is_hotspot()) {529HotSpotJVMCI::resolve(array)->byte_at_put(index, value);530} else {531JNIAccessMark jni(this);532jni()->SetByteArrayRegion(array.as_jbyteArray(), index, 1, &value);533}534}535536jint JVMCIEnv::get_int_at(JVMCIPrimitiveArray array, int index) {537if (is_hotspot()) {538return HotSpotJVMCI::resolve(array)->int_at(index);539} else {540JNIAccessMark jni(this);541jint result;542jni()->GetIntArrayRegion(array.as_jintArray(), index, 1, &result);543return result;544}545}546void JVMCIEnv::put_int_at(JVMCIPrimitiveArray array, int index, jint value) {547if (is_hotspot()) {548HotSpotJVMCI::resolve(array)->int_at_put(index, value);549} else {550JNIAccessMark jni(this);551jni()->SetIntArrayRegion(array.as_jintArray(), index, 1, &value);552}553}554555long JVMCIEnv::get_long_at(JVMCIPrimitiveArray array, int index) {556if (is_hotspot()) {557return HotSpotJVMCI::resolve(array)->long_at(index);558} else {559JNIAccessMark jni(this);560jlong result;561jni()->GetLongArrayRegion(array.as_jlongArray(), index, 1, &result);562return result;563}564}565void JVMCIEnv::put_long_at(JVMCIPrimitiveArray array, int index, jlong value) {566if (is_hotspot()) {567HotSpotJVMCI::resolve(array)->long_at_put(index, value);568} else {569JNIAccessMark jni(this);570jni()->SetLongArrayRegion(array.as_jlongArray(), index, 1, &value);571}572}573574void JVMCIEnv::copy_bytes_to(JVMCIPrimitiveArray src, jbyte* dest, int offset, jsize length) {575if (length == 0) {576return;577}578if (is_hotspot()) {579memcpy(dest, HotSpotJVMCI::resolve(src)->byte_at_addr(offset), length);580} else {581JNIAccessMark jni(this);582jni()->GetByteArrayRegion(src.as_jbyteArray(), offset, length, dest);583}584}585void JVMCIEnv::copy_bytes_from(jbyte* src, JVMCIPrimitiveArray dest, int offset, jsize length) {586if (length == 0) {587return;588}589if (is_hotspot()) {590memcpy(HotSpotJVMCI::resolve(dest)->byte_at_addr(offset), src, length);591} else {592JNIAccessMark jni(this);593jni()->SetByteArrayRegion(dest.as_jbyteArray(), offset, length, src);594}595}596597void JVMCIEnv::copy_longs_from(jlong* src, JVMCIPrimitiveArray dest, int offset, jsize length) {598if (length == 0) {599return;600}601if (is_hotspot()) {602memcpy(HotSpotJVMCI::resolve(dest)->long_at_addr(offset), src, length * sizeof(jlong));603} else {604JNIAccessMark jni(this);605jni()->SetLongArrayRegion(dest.as_jlongArray(), offset, length, src);606}607}608609jboolean JVMCIEnv::is_boxing_object(BasicType type, JVMCIObject object) {610if (is_hotspot()) {611return java_lang_boxing_object::is_instance(HotSpotJVMCI::resolve(object), type);612} else {613JNIAccessMark jni(this);614return jni()->IsInstanceOf(get_jobject(object), JNIJVMCI::box_class(type));615}616}617618// Get the primitive value from a Java boxing object. It's hard error to619// pass a non-primitive BasicType.620jvalue JVMCIEnv::get_boxed_value(BasicType type, JVMCIObject object) {621jvalue result;622if (is_hotspot()) {623if (java_lang_boxing_object::get_value(HotSpotJVMCI::resolve(object), &result) == T_ILLEGAL) {624ShouldNotReachHere();625}626} else {627JNIAccessMark jni(this);628jfieldID field = JNIJVMCI::box_field(type);629switch (type) {630case T_BOOLEAN: result.z = jni()->GetBooleanField(get_jobject(object), field); break;631case T_BYTE: result.b = jni()->GetByteField(get_jobject(object), field); break;632case T_SHORT: result.s = jni()->GetShortField(get_jobject(object), field); break;633case T_CHAR: result.c = jni()->GetCharField(get_jobject(object), field); break;634case T_INT: result.i = jni()->GetIntField(get_jobject(object), field); break;635case T_LONG: result.j = jni()->GetLongField(get_jobject(object), field); break;636case T_FLOAT: result.f = jni()->GetFloatField(get_jobject(object), field); break;637case T_DOUBLE: result.d = jni()->GetDoubleField(get_jobject(object), field); break;638default:639ShouldNotReachHere();640}641}642return result;643}644645// Return the BasicType of the object if it's a boxing object, otherwise return T_ILLEGAL.646BasicType JVMCIEnv::get_box_type(JVMCIObject object) {647if (is_hotspot()) {648return java_lang_boxing_object::basic_type(HotSpotJVMCI::resolve(object));649} else {650JNIAccessMark jni(this);651jclass clazz = jni()->GetObjectClass(get_jobject(object));652if (jni()->IsSameObject(clazz, JNIJVMCI::box_class(T_BOOLEAN))) return T_BOOLEAN;653if (jni()->IsSameObject(clazz, JNIJVMCI::box_class(T_BYTE))) return T_BYTE;654if (jni()->IsSameObject(clazz, JNIJVMCI::box_class(T_SHORT))) return T_SHORT;655if (jni()->IsSameObject(clazz, JNIJVMCI::box_class(T_CHAR))) return T_CHAR;656if (jni()->IsSameObject(clazz, JNIJVMCI::box_class(T_INT))) return T_INT;657if (jni()->IsSameObject(clazz, JNIJVMCI::box_class(T_LONG))) return T_LONG;658if (jni()->IsSameObject(clazz, JNIJVMCI::box_class(T_FLOAT))) return T_FLOAT;659if (jni()->IsSameObject(clazz, JNIJVMCI::box_class(T_DOUBLE))) return T_DOUBLE;660return T_ILLEGAL;661}662}663664// Create a boxing object of the appropriate primitive type.665JVMCIObject JVMCIEnv::create_box(BasicType type, jvalue* value, JVMCI_TRAPS) {666switch (type) {667case T_BOOLEAN:668case T_BYTE:669case T_CHAR:670case T_SHORT:671case T_INT:672case T_LONG:673case T_FLOAT:674case T_DOUBLE:675break;676default:677JVMCI_THROW_MSG_(IllegalArgumentException, "Only boxes for primitive values can be created", JVMCIObject());678}679JavaThread* THREAD = JavaThread::current(); // For exception macros.680if (is_hotspot()) {681oop box = java_lang_boxing_object::create(type, value, CHECK_(JVMCIObject()));682return HotSpotJVMCI::wrap(box);683} else {684JNIAccessMark jni(this, THREAD);685jobject box = jni()->NewObjectA(JNIJVMCI::box_class(type), JNIJVMCI::box_constructor(type), value);686assert(box != NULL, "");687return wrap(box);688}689}690691const char* JVMCIEnv::as_utf8_string(JVMCIObject str) {692if (is_hotspot()) {693return java_lang_String::as_utf8_string(HotSpotJVMCI::resolve(str));694} else {695JNIAccessMark jni(this);696int length = jni()->GetStringLength(str.as_jstring());697int utf8_length = jni()->GetStringUTFLength(str.as_jstring());698char* result = NEW_RESOURCE_ARRAY(char, utf8_length + 1);699jni()->GetStringUTFRegion(str.as_jstring(), 0, length, result);700return result;701}702}703704#define DO_THROW(name) \705void JVMCIEnv::throw_##name(const char* msg) { \706if (is_hotspot()) { \707JavaThread* THREAD = JavaThread::current(); \708THROW_MSG(HotSpotJVMCI::name::symbol(), msg); \709} else { \710JNIAccessMark jni(this); \711jni()->ThrowNew(JNIJVMCI::name::clazz(), msg); \712} \713}714715DO_THROW(InternalError)716DO_THROW(ArrayIndexOutOfBoundsException)717DO_THROW(IllegalStateException)718DO_THROW(NullPointerException)719DO_THROW(IllegalArgumentException)720DO_THROW(InvalidInstalledCodeException)721DO_THROW(UnsatisfiedLinkError)722DO_THROW(UnsupportedOperationException)723DO_THROW(ClassNotFoundException)724725#undef DO_THROW726727void JVMCIEnv::fthrow_error(const char* file, int line, const char* format, ...) {728const int max_msg_size = 1024;729va_list ap;730va_start(ap, format);731char msg[max_msg_size];732vsnprintf(msg, max_msg_size, format, ap);733msg[max_msg_size-1] = '\0';734va_end(ap);735JavaThread* THREAD = JavaThread::current();736if (is_hotspot()) {737Handle h_loader = Handle();738Handle h_protection_domain = Handle();739Exceptions::_throw_msg(THREAD, file, line, vmSymbols::jdk_vm_ci_common_JVMCIError(), msg, h_loader, h_protection_domain);740} else {741JNIAccessMark jni(this, THREAD);742jni()->ThrowNew(JNIJVMCI::JVMCIError::clazz(), msg);743}744}745746jboolean JVMCIEnv::call_HotSpotJVMCIRuntime_isGCSupported (JVMCIObject runtime, jint gcIdentifier) {747JavaThread* THREAD = JavaThread::current(); // For exception macros.748if (is_hotspot()) {749JavaCallArguments jargs;750jargs.push_oop(Handle(THREAD, HotSpotJVMCI::resolve(runtime)));751jargs.push_int(gcIdentifier);752JavaValue result(T_BOOLEAN);753JavaCalls::call_special(&result,754HotSpotJVMCI::HotSpotJVMCIRuntime::klass(),755vmSymbols::isGCSupported_name(),756vmSymbols::int_bool_signature(), &jargs, CHECK_0);757return result.get_jboolean();758} else {759JNIAccessMark jni(this, THREAD);760jboolean result = jni()->CallNonvirtualBooleanMethod(runtime.as_jobject(),761JNIJVMCI::HotSpotJVMCIRuntime::clazz(),762JNIJVMCI::HotSpotJVMCIRuntime::isGCSupported_method(),763gcIdentifier);764if (jni()->ExceptionCheck()) {765return false;766}767return result;768}769}770771JVMCIObject JVMCIEnv::call_HotSpotJVMCIRuntime_compileMethod (JVMCIObject runtime, JVMCIObject method, int entry_bci,772jlong compile_state, int id) {773JavaThread* THREAD = JVMCI::compilation_tick(JavaThread::current()); // For exception macros.774if (is_hotspot()) {775JavaCallArguments jargs;776jargs.push_oop(Handle(THREAD, HotSpotJVMCI::resolve(runtime)));777jargs.push_oop(Handle(THREAD, HotSpotJVMCI::resolve(method)));778jargs.push_int(entry_bci);779jargs.push_long(compile_state);780jargs.push_int(id);781JavaValue result(T_OBJECT);782JavaCalls::call_special(&result,783HotSpotJVMCI::HotSpotJVMCIRuntime::klass(),784vmSymbols::compileMethod_name(),785vmSymbols::compileMethod_signature(), &jargs, CHECK_(JVMCIObject()));786return wrap(result.get_oop());787} else {788JNIAccessMark jni(this, THREAD);789jobject result = jni()->CallNonvirtualObjectMethod(runtime.as_jobject(),790JNIJVMCI::HotSpotJVMCIRuntime::clazz(),791JNIJVMCI::HotSpotJVMCIRuntime::compileMethod_method(),792method.as_jobject(), entry_bci, compile_state, id);793if (jni()->ExceptionCheck()) {794return JVMCIObject();795}796return wrap(result);797}798}799800void JVMCIEnv::call_HotSpotJVMCIRuntime_bootstrapFinished (JVMCIObject runtime, JVMCIEnv* JVMCIENV) {801JavaThread* THREAD = JVMCI::compilation_tick(JavaThread::current()); // For exception macros.802if (is_hotspot()) {803JavaCallArguments jargs;804jargs.push_oop(Handle(THREAD, HotSpotJVMCI::resolve(runtime)));805JavaValue result(T_VOID);806JavaCalls::call_special(&result, HotSpotJVMCI::HotSpotJVMCIRuntime::klass(), vmSymbols::bootstrapFinished_name(), vmSymbols::void_method_signature(), &jargs, CHECK);807} else {808JNIAccessMark jni(this, THREAD);809jni()->CallNonvirtualVoidMethod(runtime.as_jobject(), JNIJVMCI::HotSpotJVMCIRuntime::clazz(), JNIJVMCI::HotSpotJVMCIRuntime::bootstrapFinished_method());810811}812}813814void JVMCIEnv::call_HotSpotJVMCIRuntime_shutdown (JVMCIObject runtime) {815JavaThread* THREAD = JavaThread::current(); // For exception macros.816HandleMark hm(THREAD);817if (is_hotspot()) {818JavaCallArguments jargs;819jargs.push_oop(Handle(THREAD, HotSpotJVMCI::resolve(runtime)));820JavaValue result(T_VOID);821JavaCalls::call_special(&result, HotSpotJVMCI::HotSpotJVMCIRuntime::klass(), vmSymbols::shutdown_name(), vmSymbols::void_method_signature(), &jargs, THREAD);822} else {823JNIAccessMark jni(this, THREAD);824jni()->CallNonvirtualVoidMethod(runtime.as_jobject(), JNIJVMCI::HotSpotJVMCIRuntime::clazz(), JNIJVMCI::HotSpotJVMCIRuntime::shutdown_method());825}826if (has_pending_exception()) {827// This should never happen as HotSpotJVMCIRuntime.shutdown() should828// handle all exceptions.829describe_pending_exception(true);830}831}832833JVMCIObject JVMCIEnv::call_HotSpotJVMCIRuntime_runtime (JVMCIEnv* JVMCIENV) {834JavaThread* THREAD = JVMCI::compilation_tick(JavaThread::current()); // For exception macros.835if (is_hotspot()) {836JavaCallArguments jargs;837JavaValue result(T_OBJECT);838JavaCalls::call_static(&result, HotSpotJVMCI::HotSpotJVMCIRuntime::klass(), vmSymbols::runtime_name(), vmSymbols::runtime_signature(), &jargs, CHECK_(JVMCIObject()));839return wrap(result.get_oop());840} else {841JNIAccessMark jni(this, THREAD);842jobject result = jni()->CallStaticObjectMethod(JNIJVMCI::HotSpotJVMCIRuntime::clazz(), JNIJVMCI::HotSpotJVMCIRuntime::runtime_method());843if (jni()->ExceptionCheck()) {844return JVMCIObject();845}846return wrap(result);847}848}849850JVMCIObject JVMCIEnv::call_JVMCI_getRuntime (JVMCIEnv* JVMCIENV) {851JavaThread* THREAD = JVMCI::compilation_tick(JavaThread::current()); // For exception macros.852if (is_hotspot()) {853JavaCallArguments jargs;854JavaValue result(T_OBJECT);855JavaCalls::call_static(&result, HotSpotJVMCI::JVMCI::klass(), vmSymbols::getRuntime_name(), vmSymbols::getRuntime_signature(), &jargs, CHECK_(JVMCIObject()));856return wrap(result.get_oop());857} else {858JNIAccessMark jni(this, THREAD);859jobject result = jni()->CallStaticObjectMethod(JNIJVMCI::JVMCI::clazz(), JNIJVMCI::JVMCI::getRuntime_method());860if (jni()->ExceptionCheck()) {861return JVMCIObject();862}863return wrap(result);864}865}866867JVMCIObject JVMCIEnv::call_HotSpotJVMCIRuntime_getCompiler (JVMCIObject runtime, JVMCIEnv* JVMCIENV) {868JavaThread* THREAD = JVMCI::compilation_tick(JavaThread::current()); // For exception macros.869if (is_hotspot()) {870JavaCallArguments jargs;871jargs.push_oop(Handle(THREAD, HotSpotJVMCI::resolve(runtime)));872JavaValue result(T_OBJECT);873JavaCalls::call_virtual(&result, HotSpotJVMCI::HotSpotJVMCIRuntime::klass(), vmSymbols::getCompiler_name(), vmSymbols::getCompiler_signature(), &jargs, CHECK_(JVMCIObject()));874return wrap(result.get_oop());875} else {876JNIAccessMark jni(this, THREAD);877jobject result = jni()->CallObjectMethod(runtime.as_jobject(), JNIJVMCI::HotSpotJVMCIRuntime::getCompiler_method());878if (jni()->ExceptionCheck()) {879return JVMCIObject();880}881return wrap(result);882}883}884885886JVMCIObject JVMCIEnv::call_HotSpotJVMCIRuntime_callToString(JVMCIObject object, JVMCIEnv* JVMCIENV) {887JavaThread* THREAD = JVMCI::compilation_tick(JavaThread::current()); // For exception macros.888if (is_hotspot()) {889JavaCallArguments jargs;890jargs.push_oop(Handle(THREAD, HotSpotJVMCI::resolve(object)));891JavaValue result(T_OBJECT);892JavaCalls::call_static(&result,893HotSpotJVMCI::HotSpotJVMCIRuntime::klass(),894vmSymbols::callToString_name(),895vmSymbols::callToString_signature(), &jargs, CHECK_(JVMCIObject()));896return wrap(result.get_oop());897} else {898JNIAccessMark jni(this, THREAD);899jobject result = (jstring) jni()->CallStaticObjectMethod(JNIJVMCI::HotSpotJVMCIRuntime::clazz(),900JNIJVMCI::HotSpotJVMCIRuntime::callToString_method(),901object.as_jobject());902if (jni()->ExceptionCheck()) {903return JVMCIObject();904}905return wrap(result);906}907}908909void JVMCIEnv::call_HotSpotJVMCIRuntime_postTranslation(JVMCIObject object, JVMCIEnv* JVMCIENV) {910JavaThread* THREAD = JVMCI::compilation_tick(JavaThread::current()); // For exception macros.911if (is_hotspot()) {912JavaCallArguments jargs;913jargs.push_oop(Handle(THREAD, HotSpotJVMCI::resolve(object)));914JavaValue result(T_VOID);915JavaCalls::call_static(&result,916HotSpotJVMCI::HotSpotJVMCIRuntime::klass(),917vmSymbols::postTranslation_name(),918vmSymbols::object_void_signature(), &jargs, CHECK);919} else {920JNIAccessMark jni(this, THREAD);921jni()->CallStaticVoidMethod(JNIJVMCI::HotSpotJVMCIRuntime::clazz(),922JNIJVMCI::HotSpotJVMCIRuntime::postTranslation_method(),923object.as_jobject());924}925}926927JVMCIObject JVMCIEnv::call_JavaConstant_forPrimitive(JVMCIObject kind, jlong value, JVMCI_TRAPS) {928JavaThread* THREAD = JVMCI::compilation_tick(JavaThread::current()); // For exception macros.929if (is_hotspot()) {930JavaCallArguments jargs;931jargs.push_oop(Handle(THREAD, HotSpotJVMCI::resolve(kind)));932jargs.push_long(value);933JavaValue result(T_OBJECT);934JavaCalls::call_static(&result,935HotSpotJVMCI::JavaConstant::klass(),936vmSymbols::forPrimitive_name(),937vmSymbols::forPrimitive_signature(), &jargs, CHECK_(JVMCIObject()));938return wrap(result.get_oop());939} else {940JNIAccessMark jni(this, THREAD);941jobject result = (jstring) jni()->CallStaticObjectMethod(JNIJVMCI::JavaConstant::clazz(),942JNIJVMCI::JavaConstant::forPrimitive_method(),943kind.as_jobject(), value);944if (jni()->ExceptionCheck()) {945return JVMCIObject();946}947return wrap(result);948}949}950951JVMCIObject JVMCIEnv::get_jvmci_primitive_type(BasicType type) {952JVMCIObjectArray primitives = get_HotSpotResolvedPrimitiveType_primitives();953JVMCIObject result = get_object_at(primitives, type);954return result;955}956957JVMCIObject JVMCIEnv::new_StackTraceElement(const methodHandle& method, int bci, JVMCI_TRAPS) {958JavaThread* THREAD = JavaThread::current(); // For exception macros.959Symbol* file_name_sym;960int line_number;961java_lang_StackTraceElement::decode(method, bci, file_name_sym, line_number, CHECK_(JVMCIObject()));962963Symbol* method_name_sym = method->name();964InstanceKlass* holder = method->method_holder();965const char* declaring_class_str = holder->external_name();966967if (is_hotspot()) {968HotSpotJVMCI::StackTraceElement::klass()->initialize(CHECK_(JVMCIObject()));969oop objOop = HotSpotJVMCI::StackTraceElement::klass()->allocate_instance(CHECK_(JVMCIObject()));970Handle obj = Handle(THREAD, objOop);971972oop declaring_class = StringTable::intern((char*) declaring_class_str, CHECK_(JVMCIObject()));973HotSpotJVMCI::StackTraceElement::set_declaringClass(this, obj(), declaring_class);974975oop method_name = StringTable::intern(method_name_sym, CHECK_(JVMCIObject()));976HotSpotJVMCI::StackTraceElement::set_methodName(this, obj(), method_name);977978if (file_name_sym != NULL) {979oop file_name = StringTable::intern(file_name_sym, CHECK_(JVMCIObject()));980HotSpotJVMCI::StackTraceElement::set_fileName(this, obj(), file_name);981}982HotSpotJVMCI::StackTraceElement::set_lineNumber(this, obj(), line_number);983return wrap(obj());984} else {985JNIAccessMark jni(this, THREAD);986jobject declaring_class = jni()->NewStringUTF(declaring_class_str);987if (jni()->ExceptionCheck()) {988return JVMCIObject();989}990jobject method_name = jni()->NewStringUTF(method_name_sym->as_C_string());991if (jni()->ExceptionCheck()) {992return JVMCIObject();993}994jobject file_name = NULL;995if (file_name_sym != NULL) {996file_name = jni()->NewStringUTF(file_name_sym->as_C_string());997if (jni()->ExceptionCheck()) {998return JVMCIObject();999}1000}10011002jobject result = jni()->NewObject(JNIJVMCI::StackTraceElement::clazz(),1003JNIJVMCI::StackTraceElement::constructor(),1004declaring_class, method_name, file_name, line_number);1005return wrap(result);1006}1007}10081009JVMCIObject JVMCIEnv::new_HotSpotNmethod(const methodHandle& method, const char* name, jboolean isDefault, jlong compileId, JVMCI_TRAPS) {1010JavaThread* THREAD = JVMCI::compilation_tick(JavaThread::current()); // For exception macros.10111012JVMCIObject methodObject = get_jvmci_method(method, JVMCI_CHECK_(JVMCIObject()));10131014if (is_hotspot()) {1015InstanceKlass* ik = InstanceKlass::cast(HotSpotJVMCI::HotSpotNmethod::klass());1016if (ik->should_be_initialized()) {1017ik->initialize(CHECK_(JVMCIObject()));1018}1019oop obj = ik->allocate_instance(CHECK_(JVMCIObject()));1020Handle obj_h(THREAD, obj);1021Handle nameStr = java_lang_String::create_from_str(name, CHECK_(JVMCIObject()));10221023// Call constructor1024JavaCallArguments jargs;1025jargs.push_oop(obj_h);1026jargs.push_oop(Handle(THREAD, HotSpotJVMCI::resolve(methodObject)));1027jargs.push_oop(nameStr);1028jargs.push_int(isDefault);1029jargs.push_long(compileId);1030JavaValue result(T_VOID);1031JavaCalls::call_special(&result, ik,1032vmSymbols::object_initializer_name(),1033vmSymbols::method_string_bool_long_signature(),1034&jargs, CHECK_(JVMCIObject()));1035return wrap(obj_h());1036} else {1037JNIAccessMark jni(this, THREAD);1038jobject nameStr = name == NULL ? NULL : jni()->NewStringUTF(name);1039if (jni()->ExceptionCheck()) {1040return JVMCIObject();1041}10421043jobject result = jni()->NewObject(JNIJVMCI::HotSpotNmethod::clazz(),1044JNIJVMCI::HotSpotNmethod::constructor(),1045methodObject.as_jobject(), nameStr, isDefault);1046return wrap(result);1047}1048}10491050JVMCIObject JVMCIEnv::make_local(JVMCIObject object) {1051if (object.is_null()) {1052return JVMCIObject();1053}1054if (is_hotspot()) {1055return wrap(JNIHandles::make_local(HotSpotJVMCI::resolve(object)));1056} else {1057JNIAccessMark jni(this);1058return wrap(jni()->NewLocalRef(object.as_jobject()));1059}1060}10611062JVMCIObject JVMCIEnv::make_global(JVMCIObject object) {1063if (object.is_null()) {1064return JVMCIObject();1065}1066if (is_hotspot()) {1067return wrap(JNIHandles::make_global(Handle(Thread::current(), HotSpotJVMCI::resolve(object))));1068} else {1069JNIAccessMark jni(this);1070return wrap(jni()->NewGlobalRef(object.as_jobject()));1071}1072}10731074void JVMCIEnv::destroy_local(JVMCIObject object) {1075if (is_hotspot()) {1076JNIHandles::destroy_local(object.as_jobject());1077} else {1078JNIAccessMark jni(this);1079jni()->DeleteLocalRef(object.as_jobject());1080}1081}10821083void JVMCIEnv::destroy_global(JVMCIObject object) {1084if (is_hotspot()) {1085JNIHandles::destroy_global(object.as_jobject());1086} else {1087JNIAccessMark jni(this);1088jni()->DeleteGlobalRef(object.as_jobject());1089}1090}10911092const char* JVMCIEnv::klass_name(JVMCIObject object) {1093if (is_hotspot()) {1094return HotSpotJVMCI::resolve(object)->klass()->signature_name();1095} else {1096JVMCIObject name;1097{1098JNIAccessMark jni(this);1099jclass jcl = jni()->GetObjectClass(object.as_jobject());1100jobject result = jni()->CallObjectMethod(jcl, JNIJVMCI::Class_getName_method());1101name = JVMCIObject::create(result, is_hotspot());1102}1103return as_utf8_string(name);1104}1105}11061107JVMCIObject JVMCIEnv::get_jvmci_method(const methodHandle& method, JVMCI_TRAPS) {1108JVMCIObject method_object;1109if (method() == NULL) {1110return method_object;1111}11121113CompilerOracle::tag_blackhole_if_possible(method);11141115JavaThread* THREAD = JVMCI::compilation_tick(JavaThread::current()); // For exception macros.1116jmetadata handle = _runtime->allocate_handle(method);1117jboolean exception = false;1118if (is_hotspot()) {1119JavaValue result(T_OBJECT);1120JavaCallArguments args;1121args.push_long((jlong) handle);1122JavaCalls::call_static(&result, HotSpotJVMCI::HotSpotResolvedJavaMethodImpl::klass(),1123vmSymbols::fromMetaspace_name(),1124vmSymbols::method_fromMetaspace_signature(), &args, THREAD);1125if (HAS_PENDING_EXCEPTION) {1126exception = true;1127} else {1128method_object = wrap(result.get_oop());1129}1130} else {1131JNIAccessMark jni(this, THREAD);1132method_object = JNIJVMCI::wrap(jni()->CallStaticObjectMethod(JNIJVMCI::HotSpotResolvedJavaMethodImpl::clazz(),1133JNIJVMCI::HotSpotResolvedJavaMethodImpl_fromMetaspace_method(),1134(jlong) handle));1135exception = jni()->ExceptionCheck();1136}11371138if (exception) {1139_runtime->release_handle(handle);1140return JVMCIObject();1141}11421143assert(asMethod(method_object) == method(), "must be");1144if (get_HotSpotResolvedJavaMethodImpl_metadataHandle(method_object) != (jlong) handle) {1145_runtime->release_handle(handle);1146}1147assert(!method_object.is_null(), "must be");1148return method_object;1149}11501151JVMCIObject JVMCIEnv::get_jvmci_type(const JVMCIKlassHandle& klass, JVMCI_TRAPS) {1152JVMCIObject type;1153if (klass.is_null()) {1154return type;1155}11561157jlong pointer = (jlong) klass();1158JavaThread* THREAD = JVMCI::compilation_tick(JavaThread::current()); // For exception macros.1159JVMCIObject signature = create_string(klass->signature_name(), JVMCI_CHECK_(JVMCIObject()));1160jboolean exception = false;1161if (is_hotspot()) {1162JavaValue result(T_OBJECT);1163JavaCallArguments args;1164args.push_long(pointer);1165args.push_oop(Handle(THREAD, HotSpotJVMCI::resolve(signature)));1166JavaCalls::call_static(&result,1167HotSpotJVMCI::HotSpotResolvedObjectTypeImpl::klass(),1168vmSymbols::fromMetaspace_name(),1169vmSymbols::klass_fromMetaspace_signature(), &args, THREAD);11701171if (HAS_PENDING_EXCEPTION) {1172exception = true;1173} else {1174type = wrap(result.get_oop());1175}1176} else {1177JNIAccessMark jni(this, THREAD);11781179HandleMark hm(THREAD);1180type = JNIJVMCI::wrap(jni()->CallStaticObjectMethod(JNIJVMCI::HotSpotResolvedObjectTypeImpl::clazz(),1181JNIJVMCI::HotSpotResolvedObjectTypeImpl_fromMetaspace_method(),1182pointer, signature.as_jstring()));1183exception = jni()->ExceptionCheck();1184}1185if (exception) {1186return JVMCIObject();1187}11881189assert(type.is_non_null(), "must have result");1190return type;1191}11921193JVMCIObject JVMCIEnv::get_jvmci_constant_pool(const constantPoolHandle& cp, JVMCI_TRAPS) {1194JVMCIObject cp_object;1195jmetadata handle = _runtime->allocate_handle(cp);1196jboolean exception = false;1197JavaThread* THREAD = JVMCI::compilation_tick(JavaThread::current()); // For exception macros.1198if (is_hotspot()) {1199JavaValue result(T_OBJECT);1200JavaCallArguments args;1201args.push_long((jlong) handle);1202JavaCalls::call_static(&result,1203HotSpotJVMCI::HotSpotConstantPool::klass(),1204vmSymbols::fromMetaspace_name(),1205vmSymbols::constantPool_fromMetaspace_signature(), &args, THREAD);1206if (HAS_PENDING_EXCEPTION) {1207exception = true;1208} else {1209cp_object = wrap(result.get_oop());1210}1211} else {1212JNIAccessMark jni(this, THREAD);1213cp_object = JNIJVMCI::wrap(jni()->CallStaticObjectMethod(JNIJVMCI::HotSpotConstantPool::clazz(),1214JNIJVMCI::HotSpotConstantPool_fromMetaspace_method(),1215(jlong) handle));1216exception = jni()->ExceptionCheck();1217}12181219if (exception) {1220_runtime->release_handle(handle);1221return JVMCIObject();1222}12231224assert(!cp_object.is_null(), "must be");1225// Constant pools aren't cached so this is always a newly created object using the handle1226assert(get_HotSpotConstantPool_metadataHandle(cp_object) == (jlong) handle, "must use same handle");1227return cp_object;1228}12291230JVMCIPrimitiveArray JVMCIEnv::new_booleanArray(int length, JVMCI_TRAPS) {1231JavaThread* THREAD = JavaThread::current(); // For exception macros.1232if (is_hotspot()) {1233typeArrayOop result = oopFactory::new_boolArray(length, CHECK_(JVMCIObject()));1234return wrap(result);1235} else {1236JNIAccessMark jni(this, THREAD);1237jbooleanArray result = jni()->NewBooleanArray(length);1238return wrap(result);1239}1240}12411242JVMCIPrimitiveArray JVMCIEnv::new_byteArray(int length, JVMCI_TRAPS) {1243JavaThread* THREAD = JavaThread::current(); // For exception macros.1244if (is_hotspot()) {1245typeArrayOop result = oopFactory::new_byteArray(length, CHECK_(JVMCIObject()));1246return wrap(result);1247} else {1248JNIAccessMark jni(this, THREAD);1249jbyteArray result = jni()->NewByteArray(length);1250return wrap(result);1251}1252}12531254JVMCIObjectArray JVMCIEnv::new_byte_array_array(int length, JVMCI_TRAPS) {1255JavaThread* THREAD = JavaThread::current(); // For exception macros.1256if (is_hotspot()) {1257Klass* byteArrayArrayKlass = TypeArrayKlass::cast(Universe::byteArrayKlassObj ())->array_klass(CHECK_(JVMCIObject()));1258objArrayOop result = ObjArrayKlass::cast(byteArrayArrayKlass) ->allocate(length, CHECK_(JVMCIObject()));1259return wrap(result);1260} else {1261JNIAccessMark jni(this, THREAD);1262jobjectArray result = jni()->NewObjectArray(length, JNIJVMCI::byte_array(), NULL);1263return wrap(result);1264}1265}12661267JVMCIPrimitiveArray JVMCIEnv::new_intArray(int length, JVMCI_TRAPS) {1268JavaThread* THREAD = JavaThread::current(); // For exception macros.1269if (is_hotspot()) {1270typeArrayOop result = oopFactory::new_intArray(length, CHECK_(JVMCIObject()));1271return wrap(result);1272} else {1273JNIAccessMark jni(this, THREAD);1274jintArray result = jni()->NewIntArray(length);1275return wrap(result);1276}1277}12781279JVMCIPrimitiveArray JVMCIEnv::new_longArray(int length, JVMCI_TRAPS) {1280JavaThread* THREAD = JavaThread::current(); // For exception macros.1281if (is_hotspot()) {1282typeArrayOop result = oopFactory::new_longArray(length, CHECK_(JVMCIObject()));1283return wrap(result);1284} else {1285JNIAccessMark jni(this, THREAD);1286jlongArray result = jni()->NewLongArray(length);1287return wrap(result);1288}1289}12901291JVMCIObject JVMCIEnv::new_VMField(JVMCIObject name, JVMCIObject type, jlong offset, jlong address, JVMCIObject value, JVMCI_TRAPS) {1292JavaThread* THREAD = JavaThread::current(); // For exception macros.1293if (is_hotspot()) {1294HotSpotJVMCI::VMField::klass()->initialize(CHECK_(JVMCIObject()));1295oop obj = HotSpotJVMCI::VMField::klass()->allocate_instance(CHECK_(JVMCIObject()));1296HotSpotJVMCI::VMField::set_name(this, obj, HotSpotJVMCI::resolve(name));1297HotSpotJVMCI::VMField::set_type(this, obj, HotSpotJVMCI::resolve(type));1298HotSpotJVMCI::VMField::set_offset(this, obj, offset);1299HotSpotJVMCI::VMField::set_address(this, obj, address);1300HotSpotJVMCI::VMField::set_value(this, obj, HotSpotJVMCI::resolve(value));1301return wrap(obj);1302} else {1303JNIAccessMark jni(this, THREAD);1304jobject result = jni()->NewObject(JNIJVMCI::VMField::clazz(),1305JNIJVMCI::VMField::constructor(),1306get_jobject(name), get_jobject(type), offset, address, get_jobject(value));1307return wrap(result);1308}1309}13101311JVMCIObject JVMCIEnv::new_VMFlag(JVMCIObject name, JVMCIObject type, JVMCIObject value, JVMCI_TRAPS) {1312JavaThread* THREAD = JavaThread::current(); // For exception macros.1313if (is_hotspot()) {1314HotSpotJVMCI::VMFlag::klass()->initialize(CHECK_(JVMCIObject()));1315oop obj = HotSpotJVMCI::VMFlag::klass()->allocate_instance(CHECK_(JVMCIObject()));1316HotSpotJVMCI::VMFlag::set_name(this, obj, HotSpotJVMCI::resolve(name));1317HotSpotJVMCI::VMFlag::set_type(this, obj, HotSpotJVMCI::resolve(type));1318HotSpotJVMCI::VMFlag::set_value(this, obj, HotSpotJVMCI::resolve(value));1319return wrap(obj);1320} else {1321JNIAccessMark jni(this, THREAD);1322jobject result = jni()->NewObject(JNIJVMCI::VMFlag::clazz(),1323JNIJVMCI::VMFlag::constructor(),1324get_jobject(name), get_jobject(type), get_jobject(value));1325return wrap(result);1326}1327}13281329JVMCIObject JVMCIEnv::new_VMIntrinsicMethod(JVMCIObject declaringClass, JVMCIObject name, JVMCIObject descriptor, int id, JVMCI_TRAPS) {1330JavaThread* THREAD = JavaThread::current(); // For exception macros.1331if (is_hotspot()) {1332HotSpotJVMCI::VMIntrinsicMethod::klass()->initialize(CHECK_(JVMCIObject()));1333oop obj = HotSpotJVMCI::VMIntrinsicMethod::klass()->allocate_instance(CHECK_(JVMCIObject()));1334HotSpotJVMCI::VMIntrinsicMethod::set_declaringClass(this, obj, HotSpotJVMCI::resolve(declaringClass));1335HotSpotJVMCI::VMIntrinsicMethod::set_name(this, obj, HotSpotJVMCI::resolve(name));1336HotSpotJVMCI::VMIntrinsicMethod::set_descriptor(this, obj, HotSpotJVMCI::resolve(descriptor));1337HotSpotJVMCI::VMIntrinsicMethod::set_id(this, obj, id);1338return wrap(obj);1339} else {1340JNIAccessMark jni(this, THREAD);1341jobject result = jni()->NewObject(JNIJVMCI::VMIntrinsicMethod::clazz(),1342JNIJVMCI::VMIntrinsicMethod::constructor(),1343get_jobject(declaringClass), get_jobject(name), get_jobject(descriptor), id);1344return wrap(result);1345}1346}13471348JVMCIObject JVMCIEnv::new_HotSpotStackFrameReference(JVMCI_TRAPS) {1349if (is_hotspot()) {1350JavaThread* THREAD = JavaThread::current(); // For exception macros.1351HotSpotJVMCI::HotSpotStackFrameReference::klass()->initialize(CHECK_(JVMCIObject()));1352oop obj = HotSpotJVMCI::HotSpotStackFrameReference::klass()->allocate_instance(CHECK_(JVMCIObject()));1353return wrap(obj);1354} else {1355ShouldNotReachHere();1356return JVMCIObject();1357}1358}1359JVMCIObject JVMCIEnv::new_JVMCIError(JVMCI_TRAPS) {1360if (is_hotspot()) {1361JavaThread* THREAD = JavaThread::current(); // For exception macros.1362HotSpotJVMCI::JVMCIError::klass()->initialize(CHECK_(JVMCIObject()));1363oop obj = HotSpotJVMCI::JVMCIError::klass()->allocate_instance(CHECK_(JVMCIObject()));1364return wrap(obj);1365} else {1366ShouldNotReachHere();1367return JVMCIObject();1368}1369}137013711372JVMCIObject JVMCIEnv::get_object_constant(oop objOop, bool compressed, bool dont_register) {1373JavaThread* THREAD = JavaThread::current(); // For exception macros.1374Handle obj = Handle(THREAD, objOop);1375if (obj.is_null()) {1376return JVMCIObject();1377}1378if (is_hotspot()) {1379HotSpotJVMCI::DirectHotSpotObjectConstantImpl::klass()->initialize(CHECK_(JVMCIObject()));1380oop constant = HotSpotJVMCI::DirectHotSpotObjectConstantImpl::klass()->allocate_instance(CHECK_(JVMCIObject()));1381HotSpotJVMCI::DirectHotSpotObjectConstantImpl::set_object(this, constant, obj());1382HotSpotJVMCI::HotSpotObjectConstantImpl::set_compressed(this, constant, compressed);1383return wrap(constant);1384} else {1385jlong handle = make_handle(obj);1386JNIAccessMark jni(this, THREAD);1387jobject result = jni()->NewObject(JNIJVMCI::IndirectHotSpotObjectConstantImpl::clazz(),1388JNIJVMCI::IndirectHotSpotObjectConstantImpl::constructor(),1389handle, compressed, dont_register);1390return wrap(result);1391}1392}139313941395Handle JVMCIEnv::asConstant(JVMCIObject constant, JVMCI_TRAPS) {1396if (constant.is_null()) {1397return Handle();1398}1399JavaThread* THREAD = JavaThread::current(); // For exception macros.1400if (is_hotspot()) {1401assert(HotSpotJVMCI::DirectHotSpotObjectConstantImpl::is_instance(this, constant), "wrong type");1402oop obj = HotSpotJVMCI::DirectHotSpotObjectConstantImpl::object(this, HotSpotJVMCI::resolve(constant));1403return Handle(THREAD, obj);1404} else if (isa_IndirectHotSpotObjectConstantImpl(constant)) {1405jlong object_handle = get_IndirectHotSpotObjectConstantImpl_objectHandle(constant);1406if (object_handle == 0L) {1407JVMCI_THROW_MSG_(NullPointerException, "Foreign object reference has been cleared", Handle());1408}1409oop result = resolve_handle(object_handle);1410if (result == NULL) {1411JVMCI_THROW_MSG_(InternalError, "Constant was unexpectedly NULL", Handle());1412}1413return Handle(THREAD, result);1414} else {1415JVMCI_THROW_MSG_(IllegalArgumentException, "DirectHotSpotObjectConstantImpl shouldn't reach JVMCI in SVM mode", Handle());1416}1417}14181419JVMCIObject JVMCIEnv::wrap(jobject object) {1420return JVMCIObject::create(object, is_hotspot());1421}14221423jlong JVMCIEnv::make_handle(const Handle& obj) {1424assert(!obj.is_null(), "should only create handle for non-NULL oops");1425jobject handle = _runtime->make_global(obj);1426return (jlong) handle;1427}14281429oop JVMCIEnv::resolve_handle(jlong objectHandle) {1430assert(objectHandle != 0, "should be a valid handle");1431oop obj = *((oopDesc**)objectHandle);1432if (obj != NULL) {1433oopDesc::verify(obj);1434}1435return obj;1436}14371438JVMCIObject JVMCIEnv::create_string(const char* str, JVMCI_TRAPS) {1439JavaThread* THREAD = JavaThread::current(); // For exception macros.1440if (is_hotspot()) {1441Handle result = java_lang_String::create_from_str(str, CHECK_(JVMCIObject()));1442return HotSpotJVMCI::wrap(result());1443} else {1444jobject result;1445jboolean exception = false;1446{1447JNIAccessMark jni(this, THREAD);1448result = jni()->NewStringUTF(str);1449exception = jni()->ExceptionCheck();1450}1451return wrap(result);1452}1453}14541455bool JVMCIEnv::equals(JVMCIObject a, JVMCIObject b) {1456if (is_hotspot()) {1457return HotSpotJVMCI::resolve(a) == HotSpotJVMCI::resolve(b);1458} else {1459JNIAccessMark jni(this);1460return jni()->IsSameObject(a.as_jobject(), b.as_jobject()) != 0;1461}1462}14631464BasicType JVMCIEnv::kindToBasicType(JVMCIObject kind, JVMCI_TRAPS) {1465if (kind.is_null()) {1466JVMCI_THROW_(NullPointerException, T_ILLEGAL);1467}1468jchar ch = get_JavaKind_typeChar(kind);1469switch(ch) {1470case 'Z': return T_BOOLEAN;1471case 'B': return T_BYTE;1472case 'S': return T_SHORT;1473case 'C': return T_CHAR;1474case 'I': return T_INT;1475case 'F': return T_FLOAT;1476case 'J': return T_LONG;1477case 'D': return T_DOUBLE;1478case 'A': return T_OBJECT;1479case '-': return T_ILLEGAL;1480default:1481JVMCI_ERROR_(T_ILLEGAL, "unexpected Kind: %c", ch);1482}1483}14841485void JVMCIEnv::initialize_installed_code(JVMCIObject installed_code, CodeBlob* cb, JVMCI_TRAPS) {1486// Ensure that all updates to the InstalledCode fields are consistent.1487if (get_InstalledCode_address(installed_code) != 0) {1488JVMCI_THROW_MSG(InternalError, "InstalledCode instance already in use");1489}1490if (!isa_HotSpotInstalledCode(installed_code)) {1491JVMCI_THROW_MSG(InternalError, "InstalledCode instance must be a subclass of HotSpotInstalledCode");1492}14931494// Ignore the version which can stay at 01495if (cb->is_nmethod()) {1496nmethod* nm = cb->as_nmethod_or_null();1497if (!nm->is_alive()) {1498JVMCI_THROW_MSG(InternalError, "nmethod has been reclaimed");1499}1500if (nm->is_in_use()) {1501set_InstalledCode_entryPoint(installed_code, (jlong) nm->verified_entry_point());1502}1503} else {1504set_InstalledCode_entryPoint(installed_code, (jlong) cb->code_begin());1505}1506set_InstalledCode_address(installed_code, (jlong) cb);1507set_HotSpotInstalledCode_size(installed_code, cb->size());1508set_HotSpotInstalledCode_codeStart(installed_code, (jlong) cb->code_begin());1509set_HotSpotInstalledCode_codeSize(installed_code, cb->code_size());1510}151115121513void JVMCIEnv::invalidate_nmethod_mirror(JVMCIObject mirror, JVMCI_TRAPS) {1514if (mirror.is_null()) {1515JVMCI_THROW(NullPointerException);1516}15171518nmethodLocker locker;1519nmethod* nm = JVMCIENV->get_nmethod(mirror, locker);1520if (nm == NULL) {1521// Nothing to do1522return;1523}15241525Thread* current = Thread::current();1526if (!mirror.is_hotspot() && !current->is_Java_thread()) {1527// Calling back into native might cause the execution to block, so only allow this when calling1528// from a JavaThread, which is the normal case anyway.1529JVMCI_THROW_MSG(IllegalArgumentException,1530"Cannot invalidate HotSpotNmethod object in shared library VM heap from non-JavaThread");1531}15321533nmethodLocker nml(nm);1534if (nm->is_alive()) {1535// Invalidating the HotSpotNmethod means we want the nmethod to be deoptimized.1536Deoptimization::deoptimize_all_marked(nm);1537}15381539// A HotSpotNmethod instance can only reference a single nmethod1540// during its lifetime so simply clear it here.1541set_InstalledCode_address(mirror, 0);1542}15431544Klass* JVMCIEnv::asKlass(JVMCIObject obj) {1545return (Klass*) get_HotSpotResolvedObjectTypeImpl_metadataPointer(obj);1546}15471548Method* JVMCIEnv::asMethod(JVMCIObject obj) {1549Method** metadataHandle = (Method**) get_HotSpotResolvedJavaMethodImpl_metadataHandle(obj);1550return *metadataHandle;1551}15521553ConstantPool* JVMCIEnv::asConstantPool(JVMCIObject obj) {1554ConstantPool** metadataHandle = (ConstantPool**) get_HotSpotConstantPool_metadataHandle(obj);1555return *metadataHandle;1556}15571558CodeBlob* JVMCIEnv::get_code_blob(JVMCIObject obj, nmethodLocker& locker) {1559address code = (address) get_InstalledCode_address(obj);1560if (code == NULL) {1561return NULL;1562}1563if (isa_HotSpotNmethod(obj)) {1564nmethod* nm = NULL;1565{1566// Lookup the CodeBlob while holding the CodeCache_lock to ensure the nmethod can't be freed1567// by nmethod::flush while we're interrogating it.1568MutexLocker cm_lock(CodeCache_lock, Mutex::_no_safepoint_check_flag);1569CodeBlob* cb = CodeCache::find_blob_unsafe(code);1570if (cb == (CodeBlob*) code) {1571nmethod* the_nm = cb->as_nmethod_or_null();1572if (the_nm != NULL && the_nm->is_alive()) {1573// Lock the nmethod to stop any further transitions by the sweeper. It's still possible1574// for this code to execute in the middle of the sweeping of the nmethod but that will be1575// handled below.1576locker.set_code(nm, true);1577nm = the_nm;1578}1579}1580}15811582if (nm != NULL) {1583// We found the nmethod but it could be in the process of being freed. Check the state of the1584// nmethod while holding the CompiledMethod_lock. This ensures that any transitions by other1585// threads have seen the is_locked_by_vm() update above.1586MutexLocker cm_lock(CompiledMethod_lock, Mutex::_no_safepoint_check_flag);1587if (!nm->is_alive()) {1588// It was alive when we looked it up but it's no longer alive so release it.1589locker.set_code(NULL);1590nm = NULL;1591}1592}15931594jlong compile_id_snapshot = get_HotSpotNmethod_compileIdSnapshot(obj);1595if (compile_id_snapshot != 0L) {1596// Found a live nmethod with the same address, make sure it's the same nmethod1597if (nm == (nmethod*) code && nm->compile_id() == compile_id_snapshot && nm->is_alive()) {1598if (nm->is_not_entrant()) {1599// Zero the entry point so that the nmethod1600// cannot be invoked by the mirror but can1601// still be deoptimized.1602set_InstalledCode_entryPoint(obj, 0);1603}1604return nm;1605}1606// The HotSpotNmethod no longer refers to a valid nmethod so clear the state1607locker.set_code(NULL);1608nm = NULL;1609}16101611if (nm == NULL) {1612// The HotSpotNmethod was pointing at some nmethod but the nmethod is no longer valid, so1613// clear the InstalledCode fields of this HotSpotNmethod so that it no longer refers to a1614// nmethod in the code cache.1615set_InstalledCode_address(obj, 0);1616set_InstalledCode_entryPoint(obj, 0);1617}1618return nm;1619}16201621CodeBlob* cb = (CodeBlob*) code;1622assert(!cb->is_nmethod(), "unexpected nmethod");1623return cb;1624}16251626nmethod* JVMCIEnv::get_nmethod(JVMCIObject obj, nmethodLocker& locker) {1627CodeBlob* cb = get_code_blob(obj, locker);1628if (cb != NULL) {1629return cb->as_nmethod_or_null();1630}1631return NULL;1632}16331634// Generate implementations for the initialize, new, isa, get and set methods for all the types and1635// fields declared in the JVMCI_CLASSES_DO macro.16361637#define START_CLASS(className, fullClassName) \1638void JVMCIEnv::className##_initialize(JVMCI_TRAPS) { \1639if (is_hotspot()) { \1640HotSpotJVMCI::className::initialize(JVMCI_CHECK); \1641} else { \1642JNIJVMCI::className::initialize(JVMCI_CHECK); \1643} \1644} \1645JVMCIObjectArray JVMCIEnv::new_##className##_array(int length, JVMCI_TRAPS) { \1646if (is_hotspot()) { \1647JavaThread* THREAD = JavaThread::current(); /* For exception macros. */ \1648objArrayOop array = oopFactory::new_objArray(HotSpotJVMCI::className::klass(), length, CHECK_(JVMCIObject())); \1649return (JVMCIObjectArray) wrap(array); \1650} else { \1651JNIAccessMark jni(this); \1652jobjectArray result = jni()->NewObjectArray(length, JNIJVMCI::className::clazz(), NULL); \1653return wrap(result); \1654} \1655} \1656bool JVMCIEnv::isa_##className(JVMCIObject object) { \1657if (is_hotspot()) { \1658return HotSpotJVMCI::className::is_instance(this, object); \1659} else { \1660return JNIJVMCI::className::is_instance(this, object); \1661} \1662}16631664#define END_CLASS16651666#define FIELD(className, name, type, accessor, cast) \1667type JVMCIEnv::get_##className##_##name(JVMCIObject obj) { \1668if (is_hotspot()) { \1669return HotSpotJVMCI::className::get_##name(this, obj); \1670} else { \1671return JNIJVMCI::className::get_##name(this, obj); \1672} \1673} \1674void JVMCIEnv::set_##className##_##name(JVMCIObject obj, type x) { \1675if (is_hotspot()) { \1676HotSpotJVMCI::className::set_##name(this, obj, x); \1677} else { \1678JNIJVMCI::className::set_##name(this, obj, x); \1679} \1680}16811682#define EMPTY_CAST1683#define CHAR_FIELD(className, name) FIELD(className, name, jchar, Char, EMPTY_CAST)1684#define INT_FIELD(className, name) FIELD(className, name, jint, Int, EMPTY_CAST)1685#define BOOLEAN_FIELD(className, name) FIELD(className, name, jboolean, Boolean, EMPTY_CAST)1686#define LONG_FIELD(className, name) FIELD(className, name, jlong, Long, EMPTY_CAST)1687#define FLOAT_FIELD(className, name) FIELD(className, name, jfloat, Float, EMPTY_CAST)16881689#define OBJECT_FIELD(className, name, signature) OOPISH_FIELD(className, name, JVMCIObject, Object, EMPTY_CAST)1690#define OBJECTARRAY_FIELD(className, name, signature) OOPISH_FIELD(className, name, JVMCIObjectArray, Object, (JVMCIObjectArray))1691#define PRIMARRAY_FIELD(className, name, signature) OOPISH_FIELD(className, name, JVMCIPrimitiveArray, Object, (JVMCIPrimitiveArray))16921693#define STATIC_OBJECT_FIELD(className, name, signature) STATIC_OOPISH_FIELD(className, name, JVMCIObject, Object, (JVMCIObject))1694#define STATIC_OBJECTARRAY_FIELD(className, name, signature) STATIC_OOPISH_FIELD(className, name, JVMCIObjectArray, Object, (JVMCIObjectArray))16951696#define OOPISH_FIELD(className, name, type, accessor, cast) \1697type JVMCIEnv::get_##className##_##name(JVMCIObject obj) { \1698if (is_hotspot()) { \1699return HotSpotJVMCI::className::get_##name(this, obj); \1700} else { \1701return JNIJVMCI::className::get_##name(this, obj); \1702} \1703} \1704void JVMCIEnv::set_##className##_##name(JVMCIObject obj, type x) { \1705if (is_hotspot()) { \1706HotSpotJVMCI::className::set_##name(this, obj, x); \1707} else { \1708JNIJVMCI::className::set_##name(this, obj, x); \1709} \1710}17111712#define STATIC_OOPISH_FIELD(className, name, type, accessor, cast) \1713type JVMCIEnv::get_##className##_##name() { \1714if (is_hotspot()) { \1715return HotSpotJVMCI::className::get_##name(this); \1716} else { \1717return JNIJVMCI::className::get_##name(this); \1718} \1719} \1720void JVMCIEnv::set_##className##_##name(type x) { \1721if (is_hotspot()) { \1722HotSpotJVMCI::className::set_##name(this, x); \1723} else { \1724JNIJVMCI::className::set_##name(this, x); \1725} \1726}17271728#define STATIC_PRIMITIVE_FIELD(className, name, type, accessor, cast) \1729type JVMCIEnv::get_##className##_##name() { \1730if (is_hotspot()) { \1731return HotSpotJVMCI::className::get_##name(this); \1732} else { \1733return JNIJVMCI::className::get_##name(this); \1734} \1735} \1736void JVMCIEnv::set_##className##_##name(type x) { \1737if (is_hotspot()) { \1738HotSpotJVMCI::className::set_##name(this, x); \1739} else { \1740JNIJVMCI::className::set_##name(this, x); \1741} \1742}1743#define STATIC_INT_FIELD(className, name) STATIC_PRIMITIVE_FIELD(className, name, jint, Int, EMPTY_CAST)1744#define STATIC_BOOLEAN_FIELD(className, name) STATIC_PRIMITIVE_FIELD(className, name, jboolean, Boolean, EMPTY_CAST)1745#define METHOD(jniCallType, jniGetMethod, hsCallType, returnType, className, methodName, signatureSymbolName, args)1746#define CONSTRUCTOR(className, signature)17471748JVMCI_CLASSES_DO(START_CLASS, END_CLASS, CHAR_FIELD, INT_FIELD, BOOLEAN_FIELD, LONG_FIELD, FLOAT_FIELD, OBJECT_FIELD, PRIMARRAY_FIELD, OBJECTARRAY_FIELD, STATIC_OBJECT_FIELD, STATIC_OBJECTARRAY_FIELD, STATIC_INT_FIELD, STATIC_BOOLEAN_FIELD, METHOD, CONSTRUCTOR)17491750#undef START_CLASS1751#undef END_CLASS1752#undef METHOD1753#undef CONSTRUCTOR1754#undef FIELD1755#undef CHAR_FIELD1756#undef INT_FIELD1757#undef BOOLEAN_FIELD1758#undef LONG_FIELD1759#undef FLOAT_FIELD1760#undef OBJECT_FIELD1761#undef PRIMARRAY_FIELD1762#undef OBJECTARRAY_FIELD1763#undef STATIC_OOPISH_FIELD1764#undef STATIC_OBJECT_FIELD1765#undef STATIC_OBJECTARRAY_FIELD1766#undef STATIC_INT_FIELD1767#undef STATIC_BOOLEAN_FIELD1768#undef EMPTY_CAST176917701771