Path: blob/master/src/hotspot/share/jvmci/jvmciEnv.cpp
40949 views
/*1* Copyright (c) 1999, 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*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}279280void JVMCIEnv::translate_hotspot_exception_to_jni_exception(JavaThread* THREAD, const Handle& throwable) {281assert(!is_hotspot(), "must_be");282// Resolve HotSpotJVMCIRuntime class explicitly as HotSpotJVMCI::compute_offsets283// may not have been called.284Klass* runtimeKlass = SystemDictionary::resolve_or_fail(vmSymbols::jdk_vm_ci_hotspot_HotSpotJVMCIRuntime(), true, CHECK);285JavaCallArguments jargs;286jargs.push_oop(throwable);287JavaValue result(T_OBJECT);288JavaCalls::call_static(&result,289runtimeKlass,290vmSymbols::encodeThrowable_name(),291vmSymbols::encodeThrowable_signature(), &jargs, THREAD);292if (HAS_PENDING_EXCEPTION) {293JVMCIRuntime::fatal_exception(this, "HotSpotJVMCIRuntime.encodeThrowable should not throw an exception");294}295296oop encoded_throwable_string = result.get_oop();297298ResourceMark rm;299const char* encoded_throwable_chars = java_lang_String::as_utf8_string(encoded_throwable_string);300301JNIAccessMark jni(this, THREAD);302jobject jni_encoded_throwable_string = jni()->NewStringUTF(encoded_throwable_chars);303jthrowable jni_throwable = (jthrowable) jni()->CallStaticObjectMethod(JNIJVMCI::HotSpotJVMCIRuntime::clazz(),304JNIJVMCI::HotSpotJVMCIRuntime::decodeThrowable_method(),305jni_encoded_throwable_string);306jni()->Throw(jni_throwable);307}308309JVMCIEnv::~JVMCIEnv() {310if (_throw_to_caller) {311if (is_hotspot()) {312// Nothing to do313} else {314Thread* thread = Thread::current();315if (thread->is_Java_thread()) {316JavaThread* THREAD = thread->as_Java_thread(); // For exception macros.317if (HAS_PENDING_EXCEPTION) {318Handle throwable = Handle(THREAD, PENDING_EXCEPTION);319CLEAR_PENDING_EXCEPTION;320translate_hotspot_exception_to_jni_exception(THREAD, throwable);321}322}323}324} else {325if (_pop_frame_on_close) {326// Pop the JNI local frame that was pushed when entering this JVMCIEnv scope.327JNIAccessMark jni(this);328jni()->PopLocalFrame(NULL);329}330331if (has_pending_exception()) {332char message[256];333jio_snprintf(message, 256, "Uncaught exception exiting JVMCIEnv scope entered at %s:%d", _file, _line);334JVMCIRuntime::fatal_exception(this, message);335}336337if (_detach_on_close) {338_runtime->DetachCurrentThread(JavaThread::current());339}340}341}342343jboolean JVMCIEnv::has_pending_exception() {344if (is_hotspot()) {345JavaThread* THREAD = JavaThread::current(); // For exception macros.346return HAS_PENDING_EXCEPTION;347} else {348JNIAccessMark jni(this);349return jni()->ExceptionCheck();350}351}352353void JVMCIEnv::clear_pending_exception() {354if (is_hotspot()) {355JavaThread* THREAD = JavaThread::current(); // For exception macros.356CLEAR_PENDING_EXCEPTION;357} else {358JNIAccessMark jni(this);359jni()->ExceptionClear();360}361}362363int JVMCIEnv::get_length(JVMCIArray array) {364if (is_hotspot()) {365return HotSpotJVMCI::resolve(array)->length();366} else {367JNIAccessMark jni(this);368return jni()->GetArrayLength(get_jarray(array));369}370}371372JVMCIObject JVMCIEnv::get_object_at(JVMCIObjectArray array, int index) {373if (is_hotspot()) {374oop result = HotSpotJVMCI::resolve(array)->obj_at(index);375return wrap(result);376} else {377JNIAccessMark jni(this);378jobject result = jni()->GetObjectArrayElement(get_jobjectArray(array), index);379return wrap(result);380}381}382383void JVMCIEnv::put_object_at(JVMCIObjectArray array, int index, JVMCIObject value) {384if (is_hotspot()) {385HotSpotJVMCI::resolve(array)->obj_at_put(index, HotSpotJVMCI::resolve(value));386} else {387JNIAccessMark jni(this);388jni()->SetObjectArrayElement(get_jobjectArray(array), index, get_jobject(value));389}390}391392jboolean JVMCIEnv::get_bool_at(JVMCIPrimitiveArray array, int index) {393if (is_hotspot()) {394return HotSpotJVMCI::resolve(array)->bool_at(index);395} else {396JNIAccessMark jni(this);397jboolean result;398jni()->GetBooleanArrayRegion(array.as_jbooleanArray(), index, 1, &result);399return result;400}401}402void JVMCIEnv::put_bool_at(JVMCIPrimitiveArray array, int index, jboolean value) {403if (is_hotspot()) {404HotSpotJVMCI::resolve(array)->bool_at_put(index, value);405} else {406JNIAccessMark jni(this);407jni()->SetBooleanArrayRegion(array.as_jbooleanArray(), index, 1, &value);408}409}410411jbyte JVMCIEnv::get_byte_at(JVMCIPrimitiveArray array, int index) {412if (is_hotspot()) {413return HotSpotJVMCI::resolve(array)->byte_at(index);414} else {415JNIAccessMark jni(this);416jbyte result;417jni()->GetByteArrayRegion(array.as_jbyteArray(), index, 1, &result);418return result;419}420}421void JVMCIEnv::put_byte_at(JVMCIPrimitiveArray array, int index, jbyte value) {422if (is_hotspot()) {423HotSpotJVMCI::resolve(array)->byte_at_put(index, value);424} else {425JNIAccessMark jni(this);426jni()->SetByteArrayRegion(array.as_jbyteArray(), index, 1, &value);427}428}429430jint JVMCIEnv::get_int_at(JVMCIPrimitiveArray array, int index) {431if (is_hotspot()) {432return HotSpotJVMCI::resolve(array)->int_at(index);433} else {434JNIAccessMark jni(this);435jint result;436jni()->GetIntArrayRegion(array.as_jintArray(), index, 1, &result);437return result;438}439}440void JVMCIEnv::put_int_at(JVMCIPrimitiveArray array, int index, jint value) {441if (is_hotspot()) {442HotSpotJVMCI::resolve(array)->int_at_put(index, value);443} else {444JNIAccessMark jni(this);445jni()->SetIntArrayRegion(array.as_jintArray(), index, 1, &value);446}447}448449long JVMCIEnv::get_long_at(JVMCIPrimitiveArray array, int index) {450if (is_hotspot()) {451return HotSpotJVMCI::resolve(array)->long_at(index);452} else {453JNIAccessMark jni(this);454jlong result;455jni()->GetLongArrayRegion(array.as_jlongArray(), index, 1, &result);456return result;457}458}459void JVMCIEnv::put_long_at(JVMCIPrimitiveArray array, int index, jlong value) {460if (is_hotspot()) {461HotSpotJVMCI::resolve(array)->long_at_put(index, value);462} else {463JNIAccessMark jni(this);464jni()->SetLongArrayRegion(array.as_jlongArray(), index, 1, &value);465}466}467468void JVMCIEnv::copy_bytes_to(JVMCIPrimitiveArray src, jbyte* dest, int offset, jsize length) {469if (length == 0) {470return;471}472if (is_hotspot()) {473memcpy(dest, HotSpotJVMCI::resolve(src)->byte_at_addr(offset), length);474} else {475JNIAccessMark jni(this);476jni()->GetByteArrayRegion(src.as_jbyteArray(), offset, length, dest);477}478}479void JVMCIEnv::copy_bytes_from(jbyte* src, JVMCIPrimitiveArray dest, int offset, jsize length) {480if (length == 0) {481return;482}483if (is_hotspot()) {484memcpy(HotSpotJVMCI::resolve(dest)->byte_at_addr(offset), src, length);485} else {486JNIAccessMark jni(this);487jni()->SetByteArrayRegion(dest.as_jbyteArray(), offset, length, src);488}489}490491void JVMCIEnv::copy_longs_from(jlong* src, JVMCIPrimitiveArray dest, int offset, jsize length) {492if (length == 0) {493return;494}495if (is_hotspot()) {496memcpy(HotSpotJVMCI::resolve(dest)->long_at_addr(offset), src, length * sizeof(jlong));497} else {498JNIAccessMark jni(this);499jni()->SetLongArrayRegion(dest.as_jlongArray(), offset, length, src);500}501}502503jboolean JVMCIEnv::is_boxing_object(BasicType type, JVMCIObject object) {504if (is_hotspot()) {505return java_lang_boxing_object::is_instance(HotSpotJVMCI::resolve(object), type);506} else {507JNIAccessMark jni(this);508return jni()->IsInstanceOf(get_jobject(object), JNIJVMCI::box_class(type));509}510}511512// Get the primitive value from a Java boxing object. It's hard error to513// pass a non-primitive BasicType.514jvalue JVMCIEnv::get_boxed_value(BasicType type, JVMCIObject object) {515jvalue result;516if (is_hotspot()) {517if (java_lang_boxing_object::get_value(HotSpotJVMCI::resolve(object), &result) == T_ILLEGAL) {518ShouldNotReachHere();519}520} else {521JNIAccessMark jni(this);522jfieldID field = JNIJVMCI::box_field(type);523switch (type) {524case T_BOOLEAN: result.z = jni()->GetBooleanField(get_jobject(object), field); break;525case T_BYTE: result.b = jni()->GetByteField(get_jobject(object), field); break;526case T_SHORT: result.s = jni()->GetShortField(get_jobject(object), field); break;527case T_CHAR: result.c = jni()->GetCharField(get_jobject(object), field); break;528case T_INT: result.i = jni()->GetIntField(get_jobject(object), field); break;529case T_LONG: result.j = jni()->GetLongField(get_jobject(object), field); break;530case T_FLOAT: result.f = jni()->GetFloatField(get_jobject(object), field); break;531case T_DOUBLE: result.d = jni()->GetDoubleField(get_jobject(object), field); break;532default:533ShouldNotReachHere();534}535}536return result;537}538539// Return the BasicType of the object if it's a boxing object, otherwise return T_ILLEGAL.540BasicType JVMCIEnv::get_box_type(JVMCIObject object) {541if (is_hotspot()) {542return java_lang_boxing_object::basic_type(HotSpotJVMCI::resolve(object));543} else {544JNIAccessMark jni(this);545jclass clazz = jni()->GetObjectClass(get_jobject(object));546if (jni()->IsSameObject(clazz, JNIJVMCI::box_class(T_BOOLEAN))) return T_BOOLEAN;547if (jni()->IsSameObject(clazz, JNIJVMCI::box_class(T_BYTE))) return T_BYTE;548if (jni()->IsSameObject(clazz, JNIJVMCI::box_class(T_SHORT))) return T_SHORT;549if (jni()->IsSameObject(clazz, JNIJVMCI::box_class(T_CHAR))) return T_CHAR;550if (jni()->IsSameObject(clazz, JNIJVMCI::box_class(T_INT))) return T_INT;551if (jni()->IsSameObject(clazz, JNIJVMCI::box_class(T_LONG))) return T_LONG;552if (jni()->IsSameObject(clazz, JNIJVMCI::box_class(T_FLOAT))) return T_FLOAT;553if (jni()->IsSameObject(clazz, JNIJVMCI::box_class(T_DOUBLE))) return T_DOUBLE;554return T_ILLEGAL;555}556}557558// Create a boxing object of the appropriate primitive type.559JVMCIObject JVMCIEnv::create_box(BasicType type, jvalue* value, JVMCI_TRAPS) {560switch (type) {561case T_BOOLEAN:562case T_BYTE:563case T_CHAR:564case T_SHORT:565case T_INT:566case T_LONG:567case T_FLOAT:568case T_DOUBLE:569break;570default:571JVMCI_THROW_MSG_(IllegalArgumentException, "Only boxes for primitive values can be created", JVMCIObject());572}573JavaThread* THREAD = JavaThread::current(); // For exception macros.574if (is_hotspot()) {575oop box = java_lang_boxing_object::create(type, value, CHECK_(JVMCIObject()));576return HotSpotJVMCI::wrap(box);577} else {578JNIAccessMark jni(this, THREAD);579jobject box = jni()->NewObjectA(JNIJVMCI::box_class(type), JNIJVMCI::box_constructor(type), value);580assert(box != NULL, "");581return wrap(box);582}583}584585const char* JVMCIEnv::as_utf8_string(JVMCIObject str) {586if (is_hotspot()) {587return java_lang_String::as_utf8_string(HotSpotJVMCI::resolve(str));588} else {589JNIAccessMark jni(this);590int length = jni()->GetStringLength(str.as_jstring());591int utf8_length = jni()->GetStringUTFLength(str.as_jstring());592char* result = NEW_RESOURCE_ARRAY(char, utf8_length + 1);593jni()->GetStringUTFRegion(str.as_jstring(), 0, length, result);594return result;595}596}597598#define DO_THROW(name) \599void JVMCIEnv::throw_##name(const char* msg) { \600if (is_hotspot()) { \601JavaThread* THREAD = JavaThread::current(); \602THROW_MSG(HotSpotJVMCI::name::symbol(), msg); \603} else { \604JNIAccessMark jni(this); \605jni()->ThrowNew(JNIJVMCI::name::clazz(), msg); \606} \607}608609DO_THROW(InternalError)610DO_THROW(ArrayIndexOutOfBoundsException)611DO_THROW(IllegalStateException)612DO_THROW(NullPointerException)613DO_THROW(IllegalArgumentException)614DO_THROW(InvalidInstalledCodeException)615DO_THROW(UnsatisfiedLinkError)616DO_THROW(UnsupportedOperationException)617DO_THROW(ClassNotFoundException)618619#undef DO_THROW620621void JVMCIEnv::fthrow_error(const char* file, int line, const char* format, ...) {622const int max_msg_size = 1024;623va_list ap;624va_start(ap, format);625char msg[max_msg_size];626vsnprintf(msg, max_msg_size, format, ap);627msg[max_msg_size-1] = '\0';628va_end(ap);629JavaThread* THREAD = JavaThread::current();630if (is_hotspot()) {631Handle h_loader = Handle();632Handle h_protection_domain = Handle();633Exceptions::_throw_msg(THREAD, file, line, vmSymbols::jdk_vm_ci_common_JVMCIError(), msg, h_loader, h_protection_domain);634} else {635JNIAccessMark jni(this, THREAD);636jni()->ThrowNew(JNIJVMCI::JVMCIError::clazz(), msg);637}638}639640jboolean JVMCIEnv::call_HotSpotJVMCIRuntime_isGCSupported (JVMCIObject runtime, jint gcIdentifier) {641JavaThread* THREAD = JavaThread::current(); // For exception macros.642if (is_hotspot()) {643JavaCallArguments jargs;644jargs.push_oop(Handle(THREAD, HotSpotJVMCI::resolve(runtime)));645jargs.push_int(gcIdentifier);646JavaValue result(T_BOOLEAN);647JavaCalls::call_special(&result,648HotSpotJVMCI::HotSpotJVMCIRuntime::klass(),649vmSymbols::isGCSupported_name(),650vmSymbols::int_bool_signature(), &jargs, CHECK_0);651return result.get_jboolean();652} else {653JNIAccessMark jni(this, THREAD);654jboolean result = jni()->CallNonvirtualBooleanMethod(runtime.as_jobject(),655JNIJVMCI::HotSpotJVMCIRuntime::clazz(),656JNIJVMCI::HotSpotJVMCIRuntime::isGCSupported_method(),657gcIdentifier);658if (jni()->ExceptionCheck()) {659return false;660}661return result;662}663}664665JVMCIObject JVMCIEnv::call_HotSpotJVMCIRuntime_compileMethod (JVMCIObject runtime, JVMCIObject method, int entry_bci,666jlong compile_state, int id) {667JavaThread* THREAD = JVMCI::compilation_tick(JavaThread::current()); // For exception macros.668if (is_hotspot()) {669JavaCallArguments jargs;670jargs.push_oop(Handle(THREAD, HotSpotJVMCI::resolve(runtime)));671jargs.push_oop(Handle(THREAD, HotSpotJVMCI::resolve(method)));672jargs.push_int(entry_bci);673jargs.push_long(compile_state);674jargs.push_int(id);675JavaValue result(T_OBJECT);676JavaCalls::call_special(&result,677HotSpotJVMCI::HotSpotJVMCIRuntime::klass(),678vmSymbols::compileMethod_name(),679vmSymbols::compileMethod_signature(), &jargs, CHECK_(JVMCIObject()));680return wrap(result.get_oop());681} else {682JNIAccessMark jni(this, THREAD);683jobject result = jni()->CallNonvirtualObjectMethod(runtime.as_jobject(),684JNIJVMCI::HotSpotJVMCIRuntime::clazz(),685JNIJVMCI::HotSpotJVMCIRuntime::compileMethod_method(),686method.as_jobject(), entry_bci, compile_state, id);687if (jni()->ExceptionCheck()) {688return JVMCIObject();689}690return wrap(result);691}692}693694void JVMCIEnv::call_HotSpotJVMCIRuntime_bootstrapFinished (JVMCIObject runtime, JVMCIEnv* JVMCIENV) {695JavaThread* THREAD = JVMCI::compilation_tick(JavaThread::current()); // For exception macros.696if (is_hotspot()) {697JavaCallArguments jargs;698jargs.push_oop(Handle(THREAD, HotSpotJVMCI::resolve(runtime)));699JavaValue result(T_VOID);700JavaCalls::call_special(&result, HotSpotJVMCI::HotSpotJVMCIRuntime::klass(), vmSymbols::bootstrapFinished_name(), vmSymbols::void_method_signature(), &jargs, CHECK);701} else {702JNIAccessMark jni(this, THREAD);703jni()->CallNonvirtualVoidMethod(runtime.as_jobject(), JNIJVMCI::HotSpotJVMCIRuntime::clazz(), JNIJVMCI::HotSpotJVMCIRuntime::bootstrapFinished_method());704705}706}707708void JVMCIEnv::call_HotSpotJVMCIRuntime_shutdown (JVMCIObject runtime) {709JavaThread* THREAD = JavaThread::current(); // For exception macros.710HandleMark hm(THREAD);711if (is_hotspot()) {712JavaCallArguments jargs;713jargs.push_oop(Handle(THREAD, HotSpotJVMCI::resolve(runtime)));714JavaValue result(T_VOID);715JavaCalls::call_special(&result, HotSpotJVMCI::HotSpotJVMCIRuntime::klass(), vmSymbols::shutdown_name(), vmSymbols::void_method_signature(), &jargs, THREAD);716} else {717JNIAccessMark jni(this, THREAD);718jni()->CallNonvirtualVoidMethod(runtime.as_jobject(), JNIJVMCI::HotSpotJVMCIRuntime::clazz(), JNIJVMCI::HotSpotJVMCIRuntime::shutdown_method());719}720if (has_pending_exception()) {721// This should never happen as HotSpotJVMCIRuntime.shutdown() should722// handle all exceptions.723describe_pending_exception(true);724}725}726727JVMCIObject JVMCIEnv::call_HotSpotJVMCIRuntime_runtime (JVMCIEnv* JVMCIENV) {728JavaThread* THREAD = JVMCI::compilation_tick(JavaThread::current()); // For exception macros.729if (is_hotspot()) {730JavaCallArguments jargs;731JavaValue result(T_OBJECT);732JavaCalls::call_static(&result, HotSpotJVMCI::HotSpotJVMCIRuntime::klass(), vmSymbols::runtime_name(), vmSymbols::runtime_signature(), &jargs, CHECK_(JVMCIObject()));733return wrap(result.get_oop());734} else {735JNIAccessMark jni(this, THREAD);736jobject result = jni()->CallStaticObjectMethod(JNIJVMCI::HotSpotJVMCIRuntime::clazz(), JNIJVMCI::HotSpotJVMCIRuntime::runtime_method());737if (jni()->ExceptionCheck()) {738return JVMCIObject();739}740return wrap(result);741}742}743744JVMCIObject JVMCIEnv::call_JVMCI_getRuntime (JVMCIEnv* JVMCIENV) {745JavaThread* THREAD = JVMCI::compilation_tick(JavaThread::current()); // For exception macros.746if (is_hotspot()) {747JavaCallArguments jargs;748JavaValue result(T_OBJECT);749JavaCalls::call_static(&result, HotSpotJVMCI::JVMCI::klass(), vmSymbols::getRuntime_name(), vmSymbols::getRuntime_signature(), &jargs, CHECK_(JVMCIObject()));750return wrap(result.get_oop());751} else {752JNIAccessMark jni(this, THREAD);753jobject result = jni()->CallStaticObjectMethod(JNIJVMCI::JVMCI::clazz(), JNIJVMCI::JVMCI::getRuntime_method());754if (jni()->ExceptionCheck()) {755return JVMCIObject();756}757return wrap(result);758}759}760761JVMCIObject JVMCIEnv::call_HotSpotJVMCIRuntime_getCompiler (JVMCIObject runtime, JVMCIEnv* JVMCIENV) {762JavaThread* THREAD = JVMCI::compilation_tick(JavaThread::current()); // For exception macros.763if (is_hotspot()) {764JavaCallArguments jargs;765jargs.push_oop(Handle(THREAD, HotSpotJVMCI::resolve(runtime)));766JavaValue result(T_OBJECT);767JavaCalls::call_virtual(&result, HotSpotJVMCI::HotSpotJVMCIRuntime::klass(), vmSymbols::getCompiler_name(), vmSymbols::getCompiler_signature(), &jargs, CHECK_(JVMCIObject()));768return wrap(result.get_oop());769} else {770JNIAccessMark jni(this, THREAD);771jobject result = jni()->CallObjectMethod(runtime.as_jobject(), JNIJVMCI::HotSpotJVMCIRuntime::getCompiler_method());772if (jni()->ExceptionCheck()) {773return JVMCIObject();774}775return wrap(result);776}777}778779780JVMCIObject JVMCIEnv::call_HotSpotJVMCIRuntime_callToString(JVMCIObject object, JVMCIEnv* JVMCIENV) {781JavaThread* THREAD = JVMCI::compilation_tick(JavaThread::current()); // For exception macros.782if (is_hotspot()) {783JavaCallArguments jargs;784jargs.push_oop(Handle(THREAD, HotSpotJVMCI::resolve(object)));785JavaValue result(T_OBJECT);786JavaCalls::call_static(&result,787HotSpotJVMCI::HotSpotJVMCIRuntime::klass(),788vmSymbols::callToString_name(),789vmSymbols::callToString_signature(), &jargs, CHECK_(JVMCIObject()));790return wrap(result.get_oop());791} else {792JNIAccessMark jni(this, THREAD);793jobject result = (jstring) jni()->CallStaticObjectMethod(JNIJVMCI::HotSpotJVMCIRuntime::clazz(),794JNIJVMCI::HotSpotJVMCIRuntime::callToString_method(),795object.as_jobject());796if (jni()->ExceptionCheck()) {797return JVMCIObject();798}799return wrap(result);800}801}802803804JVMCIObject JVMCIEnv::call_JavaConstant_forPrimitive(JVMCIObject kind, jlong value, JVMCI_TRAPS) {805JavaThread* THREAD = JVMCI::compilation_tick(JavaThread::current()); // For exception macros.806if (is_hotspot()) {807JavaCallArguments jargs;808jargs.push_oop(Handle(THREAD, HotSpotJVMCI::resolve(kind)));809jargs.push_long(value);810JavaValue result(T_OBJECT);811JavaCalls::call_static(&result,812HotSpotJVMCI::JavaConstant::klass(),813vmSymbols::forPrimitive_name(),814vmSymbols::forPrimitive_signature(), &jargs, CHECK_(JVMCIObject()));815return wrap(result.get_oop());816} else {817JNIAccessMark jni(this, THREAD);818jobject result = (jstring) jni()->CallStaticObjectMethod(JNIJVMCI::JavaConstant::clazz(),819JNIJVMCI::JavaConstant::forPrimitive_method(),820kind.as_jobject(), value);821if (jni()->ExceptionCheck()) {822return JVMCIObject();823}824return wrap(result);825}826}827828JVMCIObject JVMCIEnv::get_jvmci_primitive_type(BasicType type) {829JVMCIObjectArray primitives = get_HotSpotResolvedPrimitiveType_primitives();830JVMCIObject result = get_object_at(primitives, type);831return result;832}833834JVMCIObject JVMCIEnv::new_StackTraceElement(const methodHandle& method, int bci, JVMCI_TRAPS) {835JavaThread* THREAD = JavaThread::current(); // For exception macros.836Symbol* file_name_sym;837int line_number;838java_lang_StackTraceElement::decode(method, bci, file_name_sym, line_number, CHECK_(JVMCIObject()));839840Symbol* method_name_sym = method->name();841InstanceKlass* holder = method->method_holder();842const char* declaring_class_str = holder->external_name();843844if (is_hotspot()) {845HotSpotJVMCI::StackTraceElement::klass()->initialize(CHECK_(JVMCIObject()));846oop objOop = HotSpotJVMCI::StackTraceElement::klass()->allocate_instance(CHECK_(JVMCIObject()));847Handle obj = Handle(THREAD, objOop);848849oop declaring_class = StringTable::intern((char*) declaring_class_str, CHECK_(JVMCIObject()));850HotSpotJVMCI::StackTraceElement::set_declaringClass(this, obj(), declaring_class);851852oop method_name = StringTable::intern(method_name_sym, CHECK_(JVMCIObject()));853HotSpotJVMCI::StackTraceElement::set_methodName(this, obj(), method_name);854855if (file_name_sym != NULL) {856oop file_name = StringTable::intern(file_name_sym, CHECK_(JVMCIObject()));857HotSpotJVMCI::StackTraceElement::set_fileName(this, obj(), file_name);858}859HotSpotJVMCI::StackTraceElement::set_lineNumber(this, obj(), line_number);860return wrap(obj());861} else {862JNIAccessMark jni(this, THREAD);863jobject declaring_class = jni()->NewStringUTF(declaring_class_str);864if (jni()->ExceptionCheck()) {865return JVMCIObject();866}867jobject method_name = jni()->NewStringUTF(method_name_sym->as_C_string());868if (jni()->ExceptionCheck()) {869return JVMCIObject();870}871jobject file_name = NULL;872if (file_name_sym != NULL) {873file_name = jni()->NewStringUTF(file_name_sym->as_C_string());874if (jni()->ExceptionCheck()) {875return JVMCIObject();876}877}878879jobject result = jni()->NewObject(JNIJVMCI::StackTraceElement::clazz(),880JNIJVMCI::StackTraceElement::constructor(),881declaring_class, method_name, file_name, line_number);882return wrap(result);883}884}885886JVMCIObject JVMCIEnv::new_HotSpotNmethod(const methodHandle& method, const char* name, jboolean isDefault, jlong compileId, JVMCI_TRAPS) {887JavaThread* THREAD = JVMCI::compilation_tick(JavaThread::current()); // For exception macros.888889JVMCIObject methodObject = get_jvmci_method(method, JVMCI_CHECK_(JVMCIObject()));890891if (is_hotspot()) {892InstanceKlass* ik = InstanceKlass::cast(HotSpotJVMCI::HotSpotNmethod::klass());893if (ik->should_be_initialized()) {894ik->initialize(CHECK_(JVMCIObject()));895}896oop obj = ik->allocate_instance(CHECK_(JVMCIObject()));897Handle obj_h(THREAD, obj);898Handle nameStr = java_lang_String::create_from_str(name, CHECK_(JVMCIObject()));899900// Call constructor901JavaCallArguments jargs;902jargs.push_oop(obj_h);903jargs.push_oop(Handle(THREAD, HotSpotJVMCI::resolve(methodObject)));904jargs.push_oop(nameStr);905jargs.push_int(isDefault);906jargs.push_long(compileId);907JavaValue result(T_VOID);908JavaCalls::call_special(&result, ik,909vmSymbols::object_initializer_name(),910vmSymbols::method_string_bool_long_signature(),911&jargs, CHECK_(JVMCIObject()));912return wrap(obj_h());913} else {914JNIAccessMark jni(this, THREAD);915jobject nameStr = name == NULL ? NULL : jni()->NewStringUTF(name);916if (jni()->ExceptionCheck()) {917return JVMCIObject();918}919920jobject result = jni()->NewObject(JNIJVMCI::HotSpotNmethod::clazz(),921JNIJVMCI::HotSpotNmethod::constructor(),922methodObject.as_jobject(), nameStr, isDefault);923return wrap(result);924}925}926927JVMCIObject JVMCIEnv::make_local(JVMCIObject object) {928if (object.is_null()) {929return JVMCIObject();930}931if (is_hotspot()) {932return wrap(JNIHandles::make_local(HotSpotJVMCI::resolve(object)));933} else {934JNIAccessMark jni(this);935return wrap(jni()->NewLocalRef(object.as_jobject()));936}937}938939JVMCIObject JVMCIEnv::make_global(JVMCIObject object) {940if (object.is_null()) {941return JVMCIObject();942}943if (is_hotspot()) {944return wrap(JNIHandles::make_global(Handle(Thread::current(), HotSpotJVMCI::resolve(object))));945} else {946JNIAccessMark jni(this);947return wrap(jni()->NewGlobalRef(object.as_jobject()));948}949}950951void JVMCIEnv::destroy_local(JVMCIObject object) {952if (is_hotspot()) {953JNIHandles::destroy_local(object.as_jobject());954} else {955JNIAccessMark jni(this);956jni()->DeleteLocalRef(object.as_jobject());957}958}959960void JVMCIEnv::destroy_global(JVMCIObject object) {961if (is_hotspot()) {962JNIHandles::destroy_global(object.as_jobject());963} else {964JNIAccessMark jni(this);965jni()->DeleteGlobalRef(object.as_jobject());966}967}968969const char* JVMCIEnv::klass_name(JVMCIObject object) {970if (is_hotspot()) {971return HotSpotJVMCI::resolve(object)->klass()->signature_name();972} else {973JVMCIObject name;974{975JNIAccessMark jni(this);976jclass jcl = jni()->GetObjectClass(object.as_jobject());977jobject result = jni()->CallObjectMethod(jcl, JNIJVMCI::Class_getName_method());978name = JVMCIObject::create(result, is_hotspot());979}980return as_utf8_string(name);981}982}983984JVMCIObject JVMCIEnv::get_jvmci_method(const methodHandle& method, JVMCI_TRAPS) {985JVMCIObject method_object;986if (method() == NULL) {987return method_object;988}989990CompilerOracle::tag_blackhole_if_possible(method);991992JavaThread* THREAD = JVMCI::compilation_tick(JavaThread::current()); // For exception macros.993jmetadata handle = _runtime->allocate_handle(method);994jboolean exception = false;995if (is_hotspot()) {996JavaValue result(T_OBJECT);997JavaCallArguments args;998args.push_long((jlong) handle);999JavaCalls::call_static(&result, HotSpotJVMCI::HotSpotResolvedJavaMethodImpl::klass(),1000vmSymbols::fromMetaspace_name(),1001vmSymbols::method_fromMetaspace_signature(), &args, THREAD);1002if (HAS_PENDING_EXCEPTION) {1003exception = true;1004} else {1005method_object = wrap(result.get_oop());1006}1007} else {1008JNIAccessMark jni(this, THREAD);1009method_object = JNIJVMCI::wrap(jni()->CallStaticObjectMethod(JNIJVMCI::HotSpotResolvedJavaMethodImpl::clazz(),1010JNIJVMCI::HotSpotResolvedJavaMethodImpl_fromMetaspace_method(),1011(jlong) handle));1012exception = jni()->ExceptionCheck();1013}10141015if (exception) {1016_runtime->release_handle(handle);1017return JVMCIObject();1018}10191020assert(asMethod(method_object) == method(), "must be");1021if (get_HotSpotResolvedJavaMethodImpl_metadataHandle(method_object) != (jlong) handle) {1022_runtime->release_handle(handle);1023}1024assert(!method_object.is_null(), "must be");1025return method_object;1026}10271028JVMCIObject JVMCIEnv::get_jvmci_type(const JVMCIKlassHandle& klass, JVMCI_TRAPS) {1029JVMCIObject type;1030if (klass.is_null()) {1031return type;1032}10331034jlong pointer = (jlong) klass();1035JavaThread* THREAD = JVMCI::compilation_tick(JavaThread::current()); // For exception macros.1036JVMCIObject signature = create_string(klass->signature_name(), JVMCI_CHECK_(JVMCIObject()));1037jboolean exception = false;1038if (is_hotspot()) {1039JavaValue result(T_OBJECT);1040JavaCallArguments args;1041args.push_long(pointer);1042args.push_oop(Handle(THREAD, HotSpotJVMCI::resolve(signature)));1043JavaCalls::call_static(&result,1044HotSpotJVMCI::HotSpotResolvedObjectTypeImpl::klass(),1045vmSymbols::fromMetaspace_name(),1046vmSymbols::klass_fromMetaspace_signature(), &args, THREAD);10471048if (HAS_PENDING_EXCEPTION) {1049exception = true;1050} else {1051type = wrap(result.get_oop());1052}1053} else {1054JNIAccessMark jni(this, THREAD);10551056HandleMark hm(THREAD);1057type = JNIJVMCI::wrap(jni()->CallStaticObjectMethod(JNIJVMCI::HotSpotResolvedObjectTypeImpl::clazz(),1058JNIJVMCI::HotSpotResolvedObjectTypeImpl_fromMetaspace_method(),1059pointer, signature.as_jstring()));1060exception = jni()->ExceptionCheck();1061}1062if (exception) {1063return JVMCIObject();1064}10651066assert(type.is_non_null(), "must have result");1067return type;1068}10691070JVMCIObject JVMCIEnv::get_jvmci_constant_pool(const constantPoolHandle& cp, JVMCI_TRAPS) {1071JVMCIObject cp_object;1072jmetadata handle = _runtime->allocate_handle(cp);1073jboolean exception = false;1074JavaThread* THREAD = JVMCI::compilation_tick(JavaThread::current()); // For exception macros.1075if (is_hotspot()) {1076JavaValue result(T_OBJECT);1077JavaCallArguments args;1078args.push_long((jlong) handle);1079JavaCalls::call_static(&result,1080HotSpotJVMCI::HotSpotConstantPool::klass(),1081vmSymbols::fromMetaspace_name(),1082vmSymbols::constantPool_fromMetaspace_signature(), &args, THREAD);1083if (HAS_PENDING_EXCEPTION) {1084exception = true;1085} else {1086cp_object = wrap(result.get_oop());1087}1088} else {1089JNIAccessMark jni(this, THREAD);1090cp_object = JNIJVMCI::wrap(jni()->CallStaticObjectMethod(JNIJVMCI::HotSpotConstantPool::clazz(),1091JNIJVMCI::HotSpotConstantPool_fromMetaspace_method(),1092(jlong) handle));1093exception = jni()->ExceptionCheck();1094}10951096if (exception) {1097_runtime->release_handle(handle);1098return JVMCIObject();1099}11001101assert(!cp_object.is_null(), "must be");1102// Constant pools aren't cached so this is always a newly created object using the handle1103assert(get_HotSpotConstantPool_metadataHandle(cp_object) == (jlong) handle, "must use same handle");1104return cp_object;1105}11061107JVMCIPrimitiveArray JVMCIEnv::new_booleanArray(int length, JVMCI_TRAPS) {1108JavaThread* THREAD = JavaThread::current(); // For exception macros.1109if (is_hotspot()) {1110typeArrayOop result = oopFactory::new_boolArray(length, CHECK_(JVMCIObject()));1111return wrap(result);1112} else {1113JNIAccessMark jni(this, THREAD);1114jbooleanArray result = jni()->NewBooleanArray(length);1115return wrap(result);1116}1117}11181119JVMCIPrimitiveArray JVMCIEnv::new_byteArray(int length, JVMCI_TRAPS) {1120JavaThread* THREAD = JavaThread::current(); // For exception macros.1121if (is_hotspot()) {1122typeArrayOop result = oopFactory::new_byteArray(length, CHECK_(JVMCIObject()));1123return wrap(result);1124} else {1125JNIAccessMark jni(this, THREAD);1126jbyteArray result = jni()->NewByteArray(length);1127return wrap(result);1128}1129}11301131JVMCIObjectArray JVMCIEnv::new_byte_array_array(int length, JVMCI_TRAPS) {1132JavaThread* THREAD = JavaThread::current(); // For exception macros.1133if (is_hotspot()) {1134Klass* byteArrayArrayKlass = TypeArrayKlass::cast(Universe::byteArrayKlassObj ())->array_klass(CHECK_(JVMCIObject()));1135objArrayOop result = ObjArrayKlass::cast(byteArrayArrayKlass) ->allocate(length, CHECK_(JVMCIObject()));1136return wrap(result);1137} else {1138JNIAccessMark jni(this, THREAD);1139jobjectArray result = jni()->NewObjectArray(length, JNIJVMCI::byte_array(), NULL);1140return wrap(result);1141}1142}11431144JVMCIPrimitiveArray JVMCIEnv::new_intArray(int length, JVMCI_TRAPS) {1145JavaThread* THREAD = JavaThread::current(); // For exception macros.1146if (is_hotspot()) {1147typeArrayOop result = oopFactory::new_intArray(length, CHECK_(JVMCIObject()));1148return wrap(result);1149} else {1150JNIAccessMark jni(this, THREAD);1151jintArray result = jni()->NewIntArray(length);1152return wrap(result);1153}1154}11551156JVMCIPrimitiveArray JVMCIEnv::new_longArray(int length, JVMCI_TRAPS) {1157JavaThread* THREAD = JavaThread::current(); // For exception macros.1158if (is_hotspot()) {1159typeArrayOop result = oopFactory::new_longArray(length, CHECK_(JVMCIObject()));1160return wrap(result);1161} else {1162JNIAccessMark jni(this, THREAD);1163jlongArray result = jni()->NewLongArray(length);1164return wrap(result);1165}1166}11671168JVMCIObject JVMCIEnv::new_VMField(JVMCIObject name, JVMCIObject type, jlong offset, jlong address, JVMCIObject value, JVMCI_TRAPS) {1169JavaThread* THREAD = JavaThread::current(); // For exception macros.1170if (is_hotspot()) {1171HotSpotJVMCI::VMField::klass()->initialize(CHECK_(JVMCIObject()));1172oop obj = HotSpotJVMCI::VMField::klass()->allocate_instance(CHECK_(JVMCIObject()));1173HotSpotJVMCI::VMField::set_name(this, obj, HotSpotJVMCI::resolve(name));1174HotSpotJVMCI::VMField::set_type(this, obj, HotSpotJVMCI::resolve(type));1175HotSpotJVMCI::VMField::set_offset(this, obj, offset);1176HotSpotJVMCI::VMField::set_address(this, obj, address);1177HotSpotJVMCI::VMField::set_value(this, obj, HotSpotJVMCI::resolve(value));1178return wrap(obj);1179} else {1180JNIAccessMark jni(this, THREAD);1181jobject result = jni()->NewObject(JNIJVMCI::VMField::clazz(),1182JNIJVMCI::VMField::constructor(),1183get_jobject(name), get_jobject(type), offset, address, get_jobject(value));1184return wrap(result);1185}1186}11871188JVMCIObject JVMCIEnv::new_VMFlag(JVMCIObject name, JVMCIObject type, JVMCIObject value, JVMCI_TRAPS) {1189JavaThread* THREAD = JavaThread::current(); // For exception macros.1190if (is_hotspot()) {1191HotSpotJVMCI::VMFlag::klass()->initialize(CHECK_(JVMCIObject()));1192oop obj = HotSpotJVMCI::VMFlag::klass()->allocate_instance(CHECK_(JVMCIObject()));1193HotSpotJVMCI::VMFlag::set_name(this, obj, HotSpotJVMCI::resolve(name));1194HotSpotJVMCI::VMFlag::set_type(this, obj, HotSpotJVMCI::resolve(type));1195HotSpotJVMCI::VMFlag::set_value(this, obj, HotSpotJVMCI::resolve(value));1196return wrap(obj);1197} else {1198JNIAccessMark jni(this, THREAD);1199jobject result = jni()->NewObject(JNIJVMCI::VMFlag::clazz(),1200JNIJVMCI::VMFlag::constructor(),1201get_jobject(name), get_jobject(type), get_jobject(value));1202return wrap(result);1203}1204}12051206JVMCIObject JVMCIEnv::new_VMIntrinsicMethod(JVMCIObject declaringClass, JVMCIObject name, JVMCIObject descriptor, int id, JVMCI_TRAPS) {1207JavaThread* THREAD = JavaThread::current(); // For exception macros.1208if (is_hotspot()) {1209HotSpotJVMCI::VMIntrinsicMethod::klass()->initialize(CHECK_(JVMCIObject()));1210oop obj = HotSpotJVMCI::VMIntrinsicMethod::klass()->allocate_instance(CHECK_(JVMCIObject()));1211HotSpotJVMCI::VMIntrinsicMethod::set_declaringClass(this, obj, HotSpotJVMCI::resolve(declaringClass));1212HotSpotJVMCI::VMIntrinsicMethod::set_name(this, obj, HotSpotJVMCI::resolve(name));1213HotSpotJVMCI::VMIntrinsicMethod::set_descriptor(this, obj, HotSpotJVMCI::resolve(descriptor));1214HotSpotJVMCI::VMIntrinsicMethod::set_id(this, obj, id);1215return wrap(obj);1216} else {1217JNIAccessMark jni(this, THREAD);1218jobject result = jni()->NewObject(JNIJVMCI::VMIntrinsicMethod::clazz(),1219JNIJVMCI::VMIntrinsicMethod::constructor(),1220get_jobject(declaringClass), get_jobject(name), get_jobject(descriptor), id);1221return wrap(result);1222}1223}12241225JVMCIObject JVMCIEnv::new_HotSpotStackFrameReference(JVMCI_TRAPS) {1226if (is_hotspot()) {1227JavaThread* THREAD = JavaThread::current(); // For exception macros.1228HotSpotJVMCI::HotSpotStackFrameReference::klass()->initialize(CHECK_(JVMCIObject()));1229oop obj = HotSpotJVMCI::HotSpotStackFrameReference::klass()->allocate_instance(CHECK_(JVMCIObject()));1230return wrap(obj);1231} else {1232ShouldNotReachHere();1233return JVMCIObject();1234}1235}1236JVMCIObject JVMCIEnv::new_JVMCIError(JVMCI_TRAPS) {1237if (is_hotspot()) {1238JavaThread* THREAD = JavaThread::current(); // For exception macros.1239HotSpotJVMCI::JVMCIError::klass()->initialize(CHECK_(JVMCIObject()));1240oop obj = HotSpotJVMCI::JVMCIError::klass()->allocate_instance(CHECK_(JVMCIObject()));1241return wrap(obj);1242} else {1243ShouldNotReachHere();1244return JVMCIObject();1245}1246}124712481249JVMCIObject JVMCIEnv::get_object_constant(oop objOop, bool compressed, bool dont_register) {1250JavaThread* THREAD = JavaThread::current(); // For exception macros.1251Handle obj = Handle(THREAD, objOop);1252if (obj.is_null()) {1253return JVMCIObject();1254}1255if (is_hotspot()) {1256HotSpotJVMCI::DirectHotSpotObjectConstantImpl::klass()->initialize(CHECK_(JVMCIObject()));1257oop constant = HotSpotJVMCI::DirectHotSpotObjectConstantImpl::klass()->allocate_instance(CHECK_(JVMCIObject()));1258HotSpotJVMCI::DirectHotSpotObjectConstantImpl::set_object(this, constant, obj());1259HotSpotJVMCI::HotSpotObjectConstantImpl::set_compressed(this, constant, compressed);1260return wrap(constant);1261} else {1262jlong handle = make_handle(obj);1263JNIAccessMark jni(this, THREAD);1264jobject result = jni()->NewObject(JNIJVMCI::IndirectHotSpotObjectConstantImpl::clazz(),1265JNIJVMCI::IndirectHotSpotObjectConstantImpl::constructor(),1266handle, compressed, dont_register);1267return wrap(result);1268}1269}127012711272Handle JVMCIEnv::asConstant(JVMCIObject constant, JVMCI_TRAPS) {1273if (constant.is_null()) {1274return Handle();1275}1276JavaThread* THREAD = JavaThread::current(); // For exception macros.1277if (is_hotspot()) {1278assert(HotSpotJVMCI::DirectHotSpotObjectConstantImpl::is_instance(this, constant), "wrong type");1279oop obj = HotSpotJVMCI::DirectHotSpotObjectConstantImpl::object(this, HotSpotJVMCI::resolve(constant));1280return Handle(THREAD, obj);1281} else if (isa_IndirectHotSpotObjectConstantImpl(constant)) {1282jlong object_handle = get_IndirectHotSpotObjectConstantImpl_objectHandle(constant);1283if (object_handle == 0L) {1284JVMCI_THROW_MSG_(NullPointerException, "Foreign object reference has been cleared", Handle());1285}1286oop result = resolve_handle(object_handle);1287if (result == NULL) {1288JVMCI_THROW_MSG_(InternalError, "Constant was unexpectedly NULL", Handle());1289}1290return Handle(THREAD, result);1291} else {1292JVMCI_THROW_MSG_(IllegalArgumentException, "DirectHotSpotObjectConstantImpl shouldn't reach JVMCI in SVM mode", Handle());1293}1294}12951296JVMCIObject JVMCIEnv::wrap(jobject object) {1297return JVMCIObject::create(object, is_hotspot());1298}12991300jlong JVMCIEnv::make_handle(const Handle& obj) {1301assert(!obj.is_null(), "should only create handle for non-NULL oops");1302jobject handle = _runtime->make_global(obj);1303return (jlong) handle;1304}13051306oop JVMCIEnv::resolve_handle(jlong objectHandle) {1307assert(objectHandle != 0, "should be a valid handle");1308oop obj = *((oopDesc**)objectHandle);1309if (obj != NULL) {1310oopDesc::verify(obj);1311}1312return obj;1313}13141315JVMCIObject JVMCIEnv::create_string(const char* str, JVMCI_TRAPS) {1316JavaThread* THREAD = JavaThread::current(); // For exception macros.1317if (is_hotspot()) {1318Handle result = java_lang_String::create_from_str(str, CHECK_(JVMCIObject()));1319return HotSpotJVMCI::wrap(result());1320} else {1321jobject result;1322jboolean exception = false;1323{1324JNIAccessMark jni(this, THREAD);1325result = jni()->NewStringUTF(str);1326exception = jni()->ExceptionCheck();1327}1328return wrap(result);1329}1330}13311332bool JVMCIEnv::equals(JVMCIObject a, JVMCIObject b) {1333if (is_hotspot()) {1334return HotSpotJVMCI::resolve(a) == HotSpotJVMCI::resolve(b);1335} else {1336JNIAccessMark jni(this);1337return jni()->IsSameObject(a.as_jobject(), b.as_jobject()) != 0;1338}1339}13401341BasicType JVMCIEnv::kindToBasicType(JVMCIObject kind, JVMCI_TRAPS) {1342if (kind.is_null()) {1343JVMCI_THROW_(NullPointerException, T_ILLEGAL);1344}1345jchar ch = get_JavaKind_typeChar(kind);1346switch(ch) {1347case 'Z': return T_BOOLEAN;1348case 'B': return T_BYTE;1349case 'S': return T_SHORT;1350case 'C': return T_CHAR;1351case 'I': return T_INT;1352case 'F': return T_FLOAT;1353case 'J': return T_LONG;1354case 'D': return T_DOUBLE;1355case 'A': return T_OBJECT;1356case '-': return T_ILLEGAL;1357default:1358JVMCI_ERROR_(T_ILLEGAL, "unexpected Kind: %c", ch);1359}1360}13611362void JVMCIEnv::initialize_installed_code(JVMCIObject installed_code, CodeBlob* cb, JVMCI_TRAPS) {1363// Ensure that all updates to the InstalledCode fields are consistent.1364if (get_InstalledCode_address(installed_code) != 0) {1365JVMCI_THROW_MSG(InternalError, "InstalledCode instance already in use");1366}1367if (!isa_HotSpotInstalledCode(installed_code)) {1368JVMCI_THROW_MSG(InternalError, "InstalledCode instance must be a subclass of HotSpotInstalledCode");1369}13701371// Ignore the version which can stay at 01372if (cb->is_nmethod()) {1373nmethod* nm = cb->as_nmethod_or_null();1374if (!nm->is_alive()) {1375JVMCI_THROW_MSG(InternalError, "nmethod has been reclaimed");1376}1377if (nm->is_in_use()) {1378set_InstalledCode_entryPoint(installed_code, (jlong) nm->verified_entry_point());1379}1380} else {1381set_InstalledCode_entryPoint(installed_code, (jlong) cb->code_begin());1382}1383set_InstalledCode_address(installed_code, (jlong) cb);1384set_HotSpotInstalledCode_size(installed_code, cb->size());1385set_HotSpotInstalledCode_codeStart(installed_code, (jlong) cb->code_begin());1386set_HotSpotInstalledCode_codeSize(installed_code, cb->code_size());1387}138813891390void JVMCIEnv::invalidate_nmethod_mirror(JVMCIObject mirror, JVMCI_TRAPS) {1391if (mirror.is_null()) {1392JVMCI_THROW(NullPointerException);1393}13941395nmethodLocker locker;1396nmethod* nm = JVMCIENV->get_nmethod(mirror, locker);1397if (nm == NULL) {1398// Nothing to do1399return;1400}14011402Thread* current = Thread::current();1403if (!mirror.is_hotspot() && !current->is_Java_thread()) {1404// Calling back into native might cause the execution to block, so only allow this when calling1405// from a JavaThread, which is the normal case anyway.1406JVMCI_THROW_MSG(IllegalArgumentException,1407"Cannot invalidate HotSpotNmethod object in shared library VM heap from non-JavaThread");1408}14091410nmethodLocker nml(nm);1411if (nm->is_alive()) {1412// Invalidating the HotSpotNmethod means we want the nmethod to be deoptimized.1413Deoptimization::deoptimize_all_marked(nm);1414}14151416// A HotSpotNmethod instance can only reference a single nmethod1417// during its lifetime so simply clear it here.1418set_InstalledCode_address(mirror, 0);1419}14201421Klass* JVMCIEnv::asKlass(JVMCIObject obj) {1422return (Klass*) get_HotSpotResolvedObjectTypeImpl_metadataPointer(obj);1423}14241425Method* JVMCIEnv::asMethod(JVMCIObject obj) {1426Method** metadataHandle = (Method**) get_HotSpotResolvedJavaMethodImpl_metadataHandle(obj);1427return *metadataHandle;1428}14291430ConstantPool* JVMCIEnv::asConstantPool(JVMCIObject obj) {1431ConstantPool** metadataHandle = (ConstantPool**) get_HotSpotConstantPool_metadataHandle(obj);1432return *metadataHandle;1433}14341435CodeBlob* JVMCIEnv::get_code_blob(JVMCIObject obj, nmethodLocker& locker) {1436address code = (address) get_InstalledCode_address(obj);1437if (code == NULL) {1438return NULL;1439}1440if (isa_HotSpotNmethod(obj)) {1441nmethod* nm = NULL;1442{1443// Lookup the CodeBlob while holding the CodeCache_lock to ensure the nmethod can't be freed1444// by nmethod::flush while we're interrogating it.1445MutexLocker cm_lock(CodeCache_lock, Mutex::_no_safepoint_check_flag);1446CodeBlob* cb = CodeCache::find_blob_unsafe(code);1447if (cb == (CodeBlob*) code) {1448nmethod* the_nm = cb->as_nmethod_or_null();1449if (the_nm != NULL && the_nm->is_alive()) {1450// Lock the nmethod to stop any further transitions by the sweeper. It's still possible1451// for this code to execute in the middle of the sweeping of the nmethod but that will be1452// handled below.1453locker.set_code(nm, true);1454nm = the_nm;1455}1456}1457}14581459if (nm != NULL) {1460// We found the nmethod but it could be in the process of being freed. Check the state of the1461// nmethod while holding the CompiledMethod_lock. This ensures that any transitions by other1462// threads have seen the is_locked_by_vm() update above.1463MutexLocker cm_lock(CompiledMethod_lock, Mutex::_no_safepoint_check_flag);1464if (!nm->is_alive()) {1465// It was alive when we looked it up but it's no longer alive so release it.1466locker.set_code(NULL);1467nm = NULL;1468}1469}14701471jlong compile_id_snapshot = get_HotSpotNmethod_compileIdSnapshot(obj);1472if (compile_id_snapshot != 0L) {1473// Found a live nmethod with the same address, make sure it's the same nmethod1474if (nm == (nmethod*) code && nm->compile_id() == compile_id_snapshot && nm->is_alive()) {1475if (nm->is_not_entrant()) {1476// Zero the entry point so that the nmethod1477// cannot be invoked by the mirror but can1478// still be deoptimized.1479set_InstalledCode_entryPoint(obj, 0);1480}1481return nm;1482}1483// The HotSpotNmethod no longer refers to a valid nmethod so clear the state1484locker.set_code(NULL);1485nm = NULL;1486}14871488if (nm == NULL) {1489// The HotSpotNmethod was pointing at some nmethod but the nmethod is no longer valid, so1490// clear the InstalledCode fields of this HotSpotNmethod so that it no longer refers to a1491// nmethod in the code cache.1492set_InstalledCode_address(obj, 0);1493set_InstalledCode_entryPoint(obj, 0);1494}1495return nm;1496}14971498CodeBlob* cb = (CodeBlob*) code;1499assert(!cb->is_nmethod(), "unexpected nmethod");1500return cb;1501}15021503nmethod* JVMCIEnv::get_nmethod(JVMCIObject obj, nmethodLocker& locker) {1504CodeBlob* cb = get_code_blob(obj, locker);1505if (cb != NULL) {1506return cb->as_nmethod_or_null();1507}1508return NULL;1509}15101511// Generate implementations for the initialize, new, isa, get and set methods for all the types and1512// fields declared in the JVMCI_CLASSES_DO macro.15131514#define START_CLASS(className, fullClassName) \1515void JVMCIEnv::className##_initialize(JVMCI_TRAPS) { \1516if (is_hotspot()) { \1517HotSpotJVMCI::className::initialize(JVMCI_CHECK); \1518} else { \1519JNIJVMCI::className::initialize(JVMCI_CHECK); \1520} \1521} \1522JVMCIObjectArray JVMCIEnv::new_##className##_array(int length, JVMCI_TRAPS) { \1523if (is_hotspot()) { \1524JavaThread* THREAD = JavaThread::current(); /* For exception macros. */ \1525objArrayOop array = oopFactory::new_objArray(HotSpotJVMCI::className::klass(), length, CHECK_(JVMCIObject())); \1526return (JVMCIObjectArray) wrap(array); \1527} else { \1528JNIAccessMark jni(this); \1529jobjectArray result = jni()->NewObjectArray(length, JNIJVMCI::className::clazz(), NULL); \1530return wrap(result); \1531} \1532} \1533bool JVMCIEnv::isa_##className(JVMCIObject object) { \1534if (is_hotspot()) { \1535return HotSpotJVMCI::className::is_instance(this, object); \1536} else { \1537return JNIJVMCI::className::is_instance(this, object); \1538} \1539}15401541#define END_CLASS15421543#define FIELD(className, name, type, accessor, cast) \1544type JVMCIEnv::get_##className##_##name(JVMCIObject obj) { \1545if (is_hotspot()) { \1546return HotSpotJVMCI::className::get_##name(this, obj); \1547} else { \1548return JNIJVMCI::className::get_##name(this, obj); \1549} \1550} \1551void JVMCIEnv::set_##className##_##name(JVMCIObject obj, type x) { \1552if (is_hotspot()) { \1553HotSpotJVMCI::className::set_##name(this, obj, x); \1554} else { \1555JNIJVMCI::className::set_##name(this, obj, x); \1556} \1557}15581559#define EMPTY_CAST1560#define CHAR_FIELD(className, name) FIELD(className, name, jchar, Char, EMPTY_CAST)1561#define INT_FIELD(className, name) FIELD(className, name, jint, Int, EMPTY_CAST)1562#define BOOLEAN_FIELD(className, name) FIELD(className, name, jboolean, Boolean, EMPTY_CAST)1563#define LONG_FIELD(className, name) FIELD(className, name, jlong, Long, EMPTY_CAST)1564#define FLOAT_FIELD(className, name) FIELD(className, name, jfloat, Float, EMPTY_CAST)15651566#define OBJECT_FIELD(className, name, signature) OOPISH_FIELD(className, name, JVMCIObject, Object, EMPTY_CAST)1567#define OBJECTARRAY_FIELD(className, name, signature) OOPISH_FIELD(className, name, JVMCIObjectArray, Object, (JVMCIObjectArray))1568#define PRIMARRAY_FIELD(className, name, signature) OOPISH_FIELD(className, name, JVMCIPrimitiveArray, Object, (JVMCIPrimitiveArray))15691570#define STATIC_OBJECT_FIELD(className, name, signature) STATIC_OOPISH_FIELD(className, name, JVMCIObject, Object, (JVMCIObject))1571#define STATIC_OBJECTARRAY_FIELD(className, name, signature) STATIC_OOPISH_FIELD(className, name, JVMCIObjectArray, Object, (JVMCIObjectArray))15721573#define OOPISH_FIELD(className, name, type, accessor, cast) \1574type JVMCIEnv::get_##className##_##name(JVMCIObject obj) { \1575if (is_hotspot()) { \1576return HotSpotJVMCI::className::get_##name(this, obj); \1577} else { \1578return JNIJVMCI::className::get_##name(this, obj); \1579} \1580} \1581void JVMCIEnv::set_##className##_##name(JVMCIObject obj, type x) { \1582if (is_hotspot()) { \1583HotSpotJVMCI::className::set_##name(this, obj, x); \1584} else { \1585JNIJVMCI::className::set_##name(this, obj, x); \1586} \1587}15881589#define STATIC_OOPISH_FIELD(className, name, type, accessor, cast) \1590type JVMCIEnv::get_##className##_##name() { \1591if (is_hotspot()) { \1592return HotSpotJVMCI::className::get_##name(this); \1593} else { \1594return JNIJVMCI::className::get_##name(this); \1595} \1596} \1597void JVMCIEnv::set_##className##_##name(type x) { \1598if (is_hotspot()) { \1599HotSpotJVMCI::className::set_##name(this, x); \1600} else { \1601JNIJVMCI::className::set_##name(this, x); \1602} \1603}16041605#define STATIC_PRIMITIVE_FIELD(className, name, type, accessor, cast) \1606type JVMCIEnv::get_##className##_##name() { \1607if (is_hotspot()) { \1608return HotSpotJVMCI::className::get_##name(this); \1609} else { \1610return JNIJVMCI::className::get_##name(this); \1611} \1612} \1613void JVMCIEnv::set_##className##_##name(type x) { \1614if (is_hotspot()) { \1615HotSpotJVMCI::className::set_##name(this, x); \1616} else { \1617JNIJVMCI::className::set_##name(this, x); \1618} \1619}1620#define STATIC_INT_FIELD(className, name) STATIC_PRIMITIVE_FIELD(className, name, jint, Int, EMPTY_CAST)1621#define STATIC_BOOLEAN_FIELD(className, name) STATIC_PRIMITIVE_FIELD(className, name, jboolean, Boolean, EMPTY_CAST)1622#define METHOD(jniCallType, jniGetMethod, hsCallType, returnType, className, methodName, signatureSymbolName, args)1623#define CONSTRUCTOR(className, signature)16241625JVMCI_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)16261627#undef START_CLASS1628#undef END_CLASS1629#undef METHOD1630#undef CONSTRUCTOR1631#undef FIELD1632#undef CHAR_FIELD1633#undef INT_FIELD1634#undef BOOLEAN_FIELD1635#undef LONG_FIELD1636#undef FLOAT_FIELD1637#undef OBJECT_FIELD1638#undef PRIMARRAY_FIELD1639#undef OBJECTARRAY_FIELD1640#undef STATIC_OOPISH_FIELD1641#undef STATIC_OBJECT_FIELD1642#undef STATIC_OBJECTARRAY_FIELD1643#undef STATIC_INT_FIELD1644#undef STATIC_BOOLEAN_FIELD1645#undef EMPTY_CAST164616471648