1 /*
   2  * Copyright (c) 1999, 2019, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 #include "precompiled.hpp"
  26 #include "classfile/stringTable.hpp"
  27 #include "classfile/symbolTable.hpp"
  28 #include "code/codeCache.hpp"
  29 #include "memory/oopFactory.hpp"
  30 #include "memory/resourceArea.hpp"
  31 #include "memory/universe.hpp"
  32 #include "oops/objArrayKlass.hpp"
  33 #include "oops/typeArrayOop.inline.hpp"
  34 #include "runtime/deoptimization.hpp"
  35 #include "runtime/jniHandles.inline.hpp"
  36 #include "runtime/javaCalls.hpp"
  37 #include "jvmci/jniAccessMark.inline.hpp"
  38 #include "jvmci/jvmciRuntime.hpp"
  39 
  40 JVMCICompileState::JVMCICompileState(CompileTask* task, int system_dictionary_modification_counter):
  41   _task(task),
  42   _system_dictionary_modification_counter(system_dictionary_modification_counter),
  43   _retryable(true),
  44   _failure_reason(NULL),
  45   _failure_reason_on_C_heap(false) {
  46   // Get Jvmti capabilities under lock to get consistent values.
  47   MutexLocker mu(JvmtiThreadState_lock);
  48   _jvmti_can_hotswap_or_post_breakpoint = JvmtiExport::can_hotswap_or_post_breakpoint() ? 1 : 0;
  49   _jvmti_can_access_local_variables     = JvmtiExport::can_access_local_variables() ? 1 : 0;
  50   _jvmti_can_post_on_exceptions         = JvmtiExport::can_post_on_exceptions() ? 1 : 0;
  51   _jvmti_can_pop_frame                  = JvmtiExport::can_pop_frame() ? 1 : 0;
  52 }
  53 
  54 bool JVMCICompileState::jvmti_state_changed() const {
  55   if (!jvmti_can_access_local_variables() &&
  56       JvmtiExport::can_access_local_variables()) {
  57     return true;
  58   }
  59   if (!jvmti_can_hotswap_or_post_breakpoint() &&
  60       JvmtiExport::can_hotswap_or_post_breakpoint()) {
  61     return true;
  62   }
  63   if (!jvmti_can_post_on_exceptions() &&
  64       JvmtiExport::can_post_on_exceptions()) {
  65     return true;
  66   }
  67   if (!jvmti_can_pop_frame() &&
  68       JvmtiExport::can_pop_frame()) {
  69     return true;
  70   }
  71   return false;
  72 }
  73 
  74 JavaVM* JVMCIEnv::_shared_library_javavm = NULL;
  75 void* JVMCIEnv::_shared_library_handle = NULL;
  76 char* JVMCIEnv::_shared_library_path = NULL;
  77 
  78 void JVMCIEnv::copy_saved_properties() {
  79   assert(!is_hotspot(), "can only copy saved properties from HotSpot to native image");
  80 
  81   JavaThread* THREAD = JavaThread::current();
  82 
  83   Klass* k = SystemDictionary::resolve_or_fail(vmSymbols::jdk_vm_ci_services_Services(), Handle(), Handle(), true, THREAD);
  84   if (HAS_PENDING_EXCEPTION) {
  85     JVMCIRuntime::exit_on_pending_exception(NULL, "Error initializing jdk.vm.ci.services.Services");
  86   }
  87   InstanceKlass* ik = InstanceKlass::cast(k);
  88   if (ik->should_be_initialized()) {
  89     ik->initialize(THREAD);
  90     if (HAS_PENDING_EXCEPTION) {
  91       JVMCIRuntime::exit_on_pending_exception(NULL, "Error initializing jdk.vm.ci.services.Services");
  92     }
  93   }
  94 
  95   // Get the serialized saved properties from HotSpot
  96   TempNewSymbol serializeSavedProperties = SymbolTable::new_symbol("serializeSavedProperties");
  97   JavaValue result(T_OBJECT);
  98   JavaCallArguments args;
  99   JavaCalls::call_static(&result, ik, serializeSavedProperties, vmSymbols::serializePropertiesToByteArray_signature(), &args, THREAD);
 100   if (HAS_PENDING_EXCEPTION) {
 101     JVMCIRuntime::exit_on_pending_exception(NULL, "Error calling jdk.vm.ci.services.Services.serializeSavedProperties");
 102   }
 103   oop res = (oop) result.get_jobject();
 104   assert(res->is_typeArray(), "must be");
 105   assert(TypeArrayKlass::cast(res->klass())->element_type() == T_BYTE, "must be");
 106   typeArrayOop ba = typeArrayOop(res);
 107   int serialized_properties_len = ba->length();
 108 
 109   // Copy serialized saved properties from HotSpot object into native buffer
 110   jbyte* serialized_properties = NEW_RESOURCE_ARRAY(jbyte, serialized_properties_len);
 111   memcpy(serialized_properties, ba->byte_at_addr(0), serialized_properties_len);
 112 
 113   // Copy native buffer into shared library object
 114   JVMCIPrimitiveArray buf = new_byteArray(serialized_properties_len, this);
 115   if (has_pending_exception()) {
 116     describe_pending_exception(true);
 117     fatal("Error in copy_saved_properties");
 118   }
 119   copy_bytes_from(serialized_properties, buf, 0, serialized_properties_len);
 120   if (has_pending_exception()) {
 121     describe_pending_exception(true);
 122     fatal("Error in copy_saved_properties");
 123   }
 124 
 125   // Initialize saved properties in shared library
 126   jclass servicesClass = JNIJVMCI::Services::clazz();
 127   jmethodID initializeSavedProperties = JNIJVMCI::Services::initializeSavedProperties_method();
 128   JNIAccessMark jni(this);
 129   jni()->CallStaticVoidMethod(servicesClass, initializeSavedProperties, buf.as_jobject());
 130   if (jni()->ExceptionCheck()) {
 131     jni()->ExceptionDescribe();
 132     fatal("Error calling jdk.vm.ci.services.Services.initializeSavedProperties");
 133   }
 134 }
 135 
 136 JNIEnv* JVMCIEnv::init_shared_library(JavaThread* thread) {
 137   if (_shared_library_javavm == NULL) {
 138     MutexLocker locker(JVMCI_lock);
 139     if (_shared_library_javavm == NULL) {
 140       char path[JVM_MAXPATHLEN];
 141       char ebuf[1024];
 142       if (JVMCILibPath != NULL) {
 143         if (!os::dll_locate_lib(path, sizeof(path), JVMCILibPath, JVMCI_SHARED_LIBRARY_NAME)) {
 144           vm_exit_during_initialization("Unable to create JVMCI shared library path from -XX:JVMCILibPath value", JVMCILibPath);
 145         }
 146       } else {
 147         if (!os::dll_locate_lib(path, sizeof(path), Arguments::get_dll_dir(), JVMCI_SHARED_LIBRARY_NAME)) {
 148           vm_exit_during_initialization("Unable to create path to JVMCI shared library");
 149         }
 150       }
 151 
 152       void* handle = os::dll_load(path, ebuf, sizeof ebuf);
 153       if (handle == NULL) {
 154         vm_exit_during_initialization("Unable to load JVMCI shared library", ebuf);
 155       }
 156       _shared_library_handle = handle;
 157       _shared_library_path = strdup(path);
 158       jint (*JNI_CreateJavaVM)(JavaVM **pvm, void **penv, void *args);
 159       typedef jint (*JNI_CreateJavaVM_t)(JavaVM **pvm, void **penv, void *args);
 160 
 161       JNI_CreateJavaVM = CAST_TO_FN_PTR(JNI_CreateJavaVM_t, os::dll_lookup(handle, "JNI_CreateJavaVM"));
 162       JNIEnv* env;
 163       if (JNI_CreateJavaVM == NULL) {
 164         vm_exit_during_initialization("Unable to find JNI_CreateJavaVM", path);
 165       }
 166 
 167       ResourceMark rm;
 168       JavaVMInitArgs vm_args;
 169       vm_args.version = JNI_VERSION_1_2;
 170       vm_args.ignoreUnrecognized = JNI_TRUE;
 171       vm_args.options = NULL;
 172       vm_args.nOptions = 0;
 173 
 174       JavaVM* the_javavm = NULL;
 175       int result = (*JNI_CreateJavaVM)(&the_javavm, (void**) &env, &vm_args);
 176       if (result == JNI_OK) {
 177         guarantee(env != NULL, "missing env");
 178         _shared_library_javavm = the_javavm;
 179         return env;
 180       } else {
 181         vm_exit_during_initialization(err_msg("JNI_CreateJavaVM failed with return value %d", result), path);
 182       }
 183     }
 184   }
 185   return NULL;
 186 }
 187 
 188 void JVMCIEnv::init_env_mode_runtime(JavaThread* thread, JNIEnv* parent_env) {
 189   assert(thread != NULL, "npe");
 190   // By default there is only one runtime which is the compiler runtime.
 191   _runtime = JVMCI::compiler_runtime();
 192   _env = NULL;
 193   _pop_frame_on_close = false;
 194   _detach_on_close = false;
 195   if (!UseJVMCINativeLibrary) {
 196     // In HotSpot mode, JNI isn't used at all.
 197     _is_hotspot = true;
 198     return;
 199   }
 200 
 201   if (parent_env != NULL) {
 202     // If the parent JNI environment is non-null then figure out whether it
 203     // is a HotSpot or shared library JNIEnv and set the state appropriately.
 204     _is_hotspot = thread->jni_environment() == parent_env;
 205     if (_is_hotspot) {
 206       // Select the Java runtime
 207       _runtime = JVMCI::java_runtime();
 208       return;
 209     }
 210     _env = parent_env;
 211     return;
 212   }
 213 
 214   // Running in JVMCI shared library mode so ensure the shared library
 215   // is loaded and initialized and get a shared library JNIEnv
 216   _is_hotspot = false;
 217   _env = init_shared_library(thread);
 218 
 219   if (_env != NULL) {
 220     // Creating the JVMCI shared library VM also attaches the current thread
 221     _detach_on_close = true;
 222   } else {
 223     _shared_library_javavm->GetEnv((void**)&parent_env, JNI_VERSION_1_2);
 224     if (parent_env != NULL) {
 225       // Even though there's a parent JNI env, there's no guarantee
 226       // it was opened by a JVMCIEnv scope and thus may not have
 227       // pushed a local JNI frame. As such, we use a new JNI local
 228       // frame in this scope to ensure local JNI refs are collected
 229       // in a timely manner after leaving this scope.
 230       _env = parent_env;
 231     } else {
 232       ResourceMark rm; // Thread name is resource allocated
 233       JavaVMAttachArgs attach_args;
 234       attach_args.version = JNI_VERSION_1_2;
 235       attach_args.name = thread->name();
 236       attach_args.group = NULL;
 237       if (_shared_library_javavm->AttachCurrentThread((void**)&_env, &attach_args) != JNI_OK) {
 238         fatal("Error attaching current thread (%s) to JVMCI shared library JNI interface", attach_args.name);
 239       }
 240       _detach_on_close = true;
 241     }
 242   }
 243 
 244   assert(_env != NULL, "missing env");
 245   assert(_throw_to_caller == false, "must be");
 246 
 247   JNIAccessMark jni(this);
 248   jint result = _env->PushLocalFrame(32);
 249   if (result != JNI_OK) {
 250     char message[256];
 251     jio_snprintf(message, 256, "Uncaught exception pushing local frame for JVMCIEnv scope entered at %s:%d", _file, _line);
 252     JVMCIRuntime::exit_on_pending_exception(this, message);
 253   }
 254   _pop_frame_on_close = true;
 255 }
 256 
 257 JVMCIEnv::JVMCIEnv(JavaThread* thread, JVMCICompileState* compile_state, const char* file, int line):
 258     _throw_to_caller(false), _file(file), _line(line), _compile_state(compile_state) {
 259   init_env_mode_runtime(thread, NULL);
 260 }
 261 
 262 JVMCIEnv::JVMCIEnv(JavaThread* thread, const char* file, int line):
 263     _throw_to_caller(false), _file(file), _line(line), _compile_state(NULL) {
 264   init_env_mode_runtime(thread, NULL);
 265 }
 266 
 267 JVMCIEnv::JVMCIEnv(JavaThread* thread, JNIEnv* parent_env, const char* file, int line):
 268     _throw_to_caller(true), _file(file), _line(line), _compile_state(NULL) {
 269   init_env_mode_runtime(thread, parent_env);
 270   assert(_env == NULL || parent_env == _env, "mismatched JNIEnvironment");
 271 }
 272 
 273 void JVMCIEnv::init(JavaThread* thread, bool is_hotspot, const char* file, int line) {
 274   _compile_state = NULL;
 275   _throw_to_caller = false;
 276   _file = file;
 277   _line = line;
 278   if (is_hotspot) {
 279     _env = NULL;
 280     _pop_frame_on_close = false;
 281     _detach_on_close = false;
 282     _is_hotspot = true;
 283     _runtime = JVMCI::java_runtime();
 284   } else {
 285     init_env_mode_runtime(thread, NULL);
 286   }
 287 }
 288 
 289 // Prints a pending exception (if any) and its stack trace.
 290 void JVMCIEnv::describe_pending_exception(bool clear) {
 291   if (!is_hotspot()) {
 292     JNIAccessMark jni(this);
 293     if (jni()->ExceptionCheck()) {
 294       jthrowable ex = !clear ? jni()->ExceptionOccurred() : NULL;
 295       jni()->ExceptionDescribe();
 296       if (ex != NULL) {
 297         jni()->Throw(ex);
 298       }
 299     }
 300   } else {
 301     Thread* THREAD = Thread::current();
 302     if (HAS_PENDING_EXCEPTION) {
 303       JVMCIRuntime::describe_pending_hotspot_exception((JavaThread*) THREAD, clear);
 304     }
 305   }
 306 }
 307 
 308 void JVMCIEnv::translate_hotspot_exception_to_jni_exception(JavaThread* THREAD, const Handle& throwable) {
 309   assert(!is_hotspot(), "must_be");
 310   // Resolve HotSpotJVMCIRuntime class explicitly as HotSpotJVMCI::compute_offsets
 311   // may not have been called.
 312   Klass* runtimeKlass = SystemDictionary::resolve_or_fail(vmSymbols::jdk_vm_ci_hotspot_HotSpotJVMCIRuntime(), true, CHECK);
 313   JavaCallArguments jargs;
 314   jargs.push_oop(throwable);
 315   JavaValue result(T_OBJECT);
 316   JavaCalls::call_static(&result,
 317                           runtimeKlass,
 318                           vmSymbols::encodeThrowable_name(),
 319                           vmSymbols::encodeThrowable_signature(), &jargs, THREAD);
 320   if (HAS_PENDING_EXCEPTION) {
 321     JVMCIRuntime::exit_on_pending_exception(this, "HotSpotJVMCIRuntime.encodeThrowable should not throw an exception");
 322   }
 323 
 324   oop encoded_throwable_string = (oop) result.get_jobject();
 325 
 326   ResourceMark rm;
 327   const char* encoded_throwable_chars = java_lang_String::as_utf8_string(encoded_throwable_string);
 328 
 329   JNIAccessMark jni(this);
 330   jobject jni_encoded_throwable_string = jni()->NewStringUTF(encoded_throwable_chars);
 331   jthrowable jni_throwable = (jthrowable) jni()->CallStaticObjectMethod(JNIJVMCI::HotSpotJVMCIRuntime::clazz(),
 332                                 JNIJVMCI::HotSpotJVMCIRuntime::decodeThrowable_method(),
 333                                 jni_encoded_throwable_string);
 334   jni()->Throw(jni_throwable);
 335 }
 336 
 337 JVMCIEnv::~JVMCIEnv() {
 338   if (_throw_to_caller) {
 339     if (is_hotspot()) {
 340       // Nothing to do
 341     } else {
 342       if (Thread::current()->is_Java_thread()) {
 343         JavaThread* THREAD = JavaThread::current();
 344         if (HAS_PENDING_EXCEPTION) {
 345           Handle throwable = Handle(THREAD, PENDING_EXCEPTION);
 346           CLEAR_PENDING_EXCEPTION;
 347           translate_hotspot_exception_to_jni_exception(THREAD, throwable);
 348         }
 349       }
 350     }
 351   } else {
 352     if (_pop_frame_on_close) {
 353       // Pop the JNI local frame that was pushed when entering this JVMCIEnv scope.
 354       JNIAccessMark jni(this);
 355       jni()->PopLocalFrame(NULL);
 356     }
 357 
 358     if (has_pending_exception()) {
 359       char message[256];
 360       jio_snprintf(message, 256, "Uncaught exception exiting JVMCIEnv scope entered at %s:%d", _file, _line);
 361       JVMCIRuntime::exit_on_pending_exception(this, message);
 362     }
 363 
 364     if (_detach_on_close) {
 365       get_shared_library_javavm()->DetachCurrentThread();
 366     }
 367   }
 368 }
 369 
 370 jboolean JVMCIEnv::has_pending_exception() {
 371   if (is_hotspot()) {
 372     Thread* THREAD = Thread::current();
 373     return HAS_PENDING_EXCEPTION;
 374   } else {
 375     JNIAccessMark jni(this);
 376     return jni()->ExceptionCheck();
 377   }
 378 }
 379 
 380 void JVMCIEnv::clear_pending_exception() {
 381   if (is_hotspot()) {
 382     Thread* THREAD = Thread::current();
 383     CLEAR_PENDING_EXCEPTION;
 384   } else {
 385     JNIAccessMark jni(this);
 386     jni()->ExceptionClear();
 387   }
 388 }
 389 
 390 int JVMCIEnv::get_length(JVMCIArray array) {
 391   if (is_hotspot()) {
 392     return HotSpotJVMCI::resolve(array)->length();
 393   } else {
 394     JNIAccessMark jni(this);
 395     return jni()->GetArrayLength(get_jarray(array));
 396   }
 397 }
 398 
 399 JVMCIObject JVMCIEnv::get_object_at(JVMCIObjectArray array, int index) {
 400   if (is_hotspot()) {
 401     oop result = HotSpotJVMCI::resolve(array)->obj_at(index);
 402     return wrap(result);
 403   } else {
 404     JNIAccessMark jni(this);
 405     jobject result = jni()->GetObjectArrayElement(get_jobjectArray(array), index);
 406     return wrap(result);
 407   }
 408 }
 409 
 410 void JVMCIEnv::put_object_at(JVMCIObjectArray array, int index, JVMCIObject value) {
 411   if (is_hotspot()) {
 412     HotSpotJVMCI::resolve(array)->obj_at_put(index, HotSpotJVMCI::resolve(value));
 413   } else {
 414     JNIAccessMark jni(this);
 415     jni()->SetObjectArrayElement(get_jobjectArray(array), index, get_jobject(value));
 416   }
 417 }
 418 
 419 jboolean JVMCIEnv::get_bool_at(JVMCIPrimitiveArray array, int index) {
 420   if (is_hotspot()) {
 421     return HotSpotJVMCI::resolve(array)->bool_at(index);
 422   } else {
 423     JNIAccessMark jni(this);
 424     jboolean result;
 425     jni()->GetBooleanArrayRegion(array.as_jbooleanArray(), index, 1, &result);
 426     return result;
 427   }
 428 }
 429 void JVMCIEnv::put_bool_at(JVMCIPrimitiveArray array, int index, jboolean value) {
 430   if (is_hotspot()) {
 431     HotSpotJVMCI::resolve(array)->bool_at_put(index, value);
 432   } else {
 433     JNIAccessMark jni(this);
 434     jni()->SetBooleanArrayRegion(array.as_jbooleanArray(), index, 1, &value);
 435   }
 436 }
 437 
 438 jbyte JVMCIEnv::get_byte_at(JVMCIPrimitiveArray array, int index) {
 439   if (is_hotspot()) {
 440     return HotSpotJVMCI::resolve(array)->byte_at(index);
 441   } else {
 442     JNIAccessMark jni(this);
 443     jbyte result;
 444     jni()->GetByteArrayRegion(array.as_jbyteArray(), index, 1, &result);
 445     return result;
 446   }
 447 }
 448 void JVMCIEnv::put_byte_at(JVMCIPrimitiveArray array, int index, jbyte value) {
 449   if (is_hotspot()) {
 450     HotSpotJVMCI::resolve(array)->byte_at_put(index, value);
 451   } else {
 452     JNIAccessMark jni(this);
 453     jni()->SetByteArrayRegion(array.as_jbyteArray(), index, 1, &value);
 454   }
 455 }
 456 
 457 jint JVMCIEnv::get_int_at(JVMCIPrimitiveArray array, int index) {
 458   if (is_hotspot()) {
 459     return HotSpotJVMCI::resolve(array)->int_at(index);
 460   } else {
 461     JNIAccessMark jni(this);
 462     jint result;
 463     jni()->GetIntArrayRegion(array.as_jintArray(), index, 1, &result);
 464     return result;
 465   }
 466 }
 467 void JVMCIEnv::put_int_at(JVMCIPrimitiveArray array, int index, jint value) {
 468   if (is_hotspot()) {
 469     HotSpotJVMCI::resolve(array)->int_at_put(index, value);
 470   } else {
 471     JNIAccessMark jni(this);
 472     jni()->SetIntArrayRegion(array.as_jintArray(), index, 1, &value);
 473   }
 474 }
 475 
 476 long JVMCIEnv::get_long_at(JVMCIPrimitiveArray array, int index) {
 477   if (is_hotspot()) {
 478     return HotSpotJVMCI::resolve(array)->long_at(index);
 479   } else {
 480     JNIAccessMark jni(this);
 481     jlong result;
 482     jni()->GetLongArrayRegion(array.as_jlongArray(), index, 1, &result);
 483     return result;
 484   }
 485 }
 486 void JVMCIEnv::put_long_at(JVMCIPrimitiveArray array, int index, jlong value) {
 487   if (is_hotspot()) {
 488     HotSpotJVMCI::resolve(array)->long_at_put(index, value);
 489   } else {
 490     JNIAccessMark jni(this);
 491     jni()->SetLongArrayRegion(array.as_jlongArray(), index, 1, &value);
 492   }
 493 }
 494 
 495 void JVMCIEnv::copy_bytes_to(JVMCIPrimitiveArray src, jbyte* dest, int offset, jsize length) {
 496   if (length == 0) {
 497     return;
 498   }
 499   if (is_hotspot()) {
 500     memcpy(dest, HotSpotJVMCI::resolve(src)->byte_at_addr(offset), length);
 501   } else {
 502     JNIAccessMark jni(this);
 503     jni()->GetByteArrayRegion(src.as_jbyteArray(), offset, length, dest);
 504   }
 505 }
 506 void JVMCIEnv::copy_bytes_from(jbyte* src, JVMCIPrimitiveArray dest, int offset, jsize length) {
 507   if (length == 0) {
 508     return;
 509   }
 510   if (is_hotspot()) {
 511     memcpy(HotSpotJVMCI::resolve(dest)->byte_at_addr(offset), src, length);
 512   } else {
 513     JNIAccessMark jni(this);
 514     jni()->SetByteArrayRegion(dest.as_jbyteArray(), offset, length, src);
 515   }
 516 }
 517 
 518 void JVMCIEnv::copy_longs_from(jlong* src, JVMCIPrimitiveArray dest, int offset, jsize length) {
 519   if (length == 0) {
 520     return;
 521   }
 522   if (is_hotspot()) {
 523     memcpy(HotSpotJVMCI::resolve(dest)->long_at_addr(offset), src, length * sizeof(jlong));
 524   } else {
 525     JNIAccessMark jni(this);
 526     jni()->SetLongArrayRegion(dest.as_jlongArray(), offset, length, src);
 527   }
 528 }
 529 
 530 jboolean JVMCIEnv::is_boxing_object(BasicType type, JVMCIObject object) {
 531   if (is_hotspot()) {
 532     return java_lang_boxing_object::is_instance(HotSpotJVMCI::resolve(object), type);
 533   } else {
 534     JNIAccessMark jni(this);
 535     return jni()->IsInstanceOf(get_jobject(object), JNIJVMCI::box_class(type));
 536   }
 537 }
 538 
 539 // Get the primitive value from a Java boxing object.  It's hard error to
 540 // pass a non-primitive BasicType.
 541 jvalue JVMCIEnv::get_boxed_value(BasicType type, JVMCIObject object) {
 542   jvalue result;
 543   if (is_hotspot()) {
 544     if (java_lang_boxing_object::get_value(HotSpotJVMCI::resolve(object), &result) == T_ILLEGAL) {
 545       ShouldNotReachHere();
 546     }
 547   } else {
 548     JNIAccessMark jni(this);
 549     jfieldID field = JNIJVMCI::box_field(type);
 550     switch (type) {
 551       case T_BOOLEAN: result.z = jni()->GetBooleanField(get_jobject(object), field); break;
 552       case T_BYTE:    result.b = jni()->GetByteField(get_jobject(object), field); break;
 553       case T_SHORT:   result.s = jni()->GetShortField(get_jobject(object), field); break;
 554       case T_CHAR:    result.c = jni()->GetCharField(get_jobject(object), field); break;
 555       case T_INT:     result.i = jni()->GetIntField(get_jobject(object), field); break;
 556       case T_LONG:    result.j = jni()->GetLongField(get_jobject(object), field); break;
 557       case T_FLOAT:   result.f = jni()->GetFloatField(get_jobject(object), field); break;
 558       case T_DOUBLE:  result.d = jni()->GetDoubleField(get_jobject(object), field); break;
 559       default:
 560         ShouldNotReachHere();
 561     }
 562   }
 563   return result;
 564 }
 565 
 566 // Return the BasicType of the object if it's a boxing object, otherwise return T_ILLEGAL.
 567 BasicType JVMCIEnv::get_box_type(JVMCIObject object) {
 568   if (is_hotspot()) {
 569     return java_lang_boxing_object::basic_type(HotSpotJVMCI::resolve(object));
 570   } else {
 571     JNIAccessMark jni(this);
 572     jclass clazz = jni()->GetObjectClass(get_jobject(object));
 573     if (jni()->IsSameObject(clazz, JNIJVMCI::box_class(T_BOOLEAN))) return T_BOOLEAN;
 574     if (jni()->IsSameObject(clazz, JNIJVMCI::box_class(T_BYTE))) return T_BYTE;
 575     if (jni()->IsSameObject(clazz, JNIJVMCI::box_class(T_SHORT))) return T_SHORT;
 576     if (jni()->IsSameObject(clazz, JNIJVMCI::box_class(T_CHAR))) return T_CHAR;
 577     if (jni()->IsSameObject(clazz, JNIJVMCI::box_class(T_INT))) return T_INT;
 578     if (jni()->IsSameObject(clazz, JNIJVMCI::box_class(T_LONG))) return T_LONG;
 579     if (jni()->IsSameObject(clazz, JNIJVMCI::box_class(T_FLOAT))) return T_FLOAT;
 580     if (jni()->IsSameObject(clazz, JNIJVMCI::box_class(T_DOUBLE))) return T_DOUBLE;
 581     return T_ILLEGAL;
 582   }
 583 }
 584 
 585 // Create a boxing object of the appropriate primitive type.
 586 JVMCIObject JVMCIEnv::create_box(BasicType type, jvalue* value, JVMCI_TRAPS) {
 587   switch (type) {
 588     case T_BOOLEAN:
 589     case T_BYTE:
 590     case T_CHAR:
 591     case T_SHORT:
 592     case T_INT:
 593     case T_LONG:
 594     case T_FLOAT:
 595     case T_DOUBLE:
 596       break;
 597     default:
 598       JVMCI_THROW_MSG_(IllegalArgumentException, "Only boxes for primitive values can be created", JVMCIObject());
 599   }
 600   if (is_hotspot()) {
 601     JavaThread* THREAD = JavaThread::current();
 602     oop box = java_lang_boxing_object::create(type, value, CHECK_(JVMCIObject()));
 603     return HotSpotJVMCI::wrap(box);
 604   } else {
 605     JNIAccessMark jni(this);
 606     jobject box = jni()->NewObjectA(JNIJVMCI::box_class(type), JNIJVMCI::box_constructor(type), value);
 607     assert(box != NULL, "");
 608     return wrap(box);
 609   }
 610 }
 611 
 612 const char* JVMCIEnv::as_utf8_string(JVMCIObject str) {
 613   if (is_hotspot()) {
 614     return java_lang_String::as_utf8_string(HotSpotJVMCI::resolve(str));
 615   } else {
 616     JNIAccessMark jni(this);
 617     int length = jni()->GetStringLength(str.as_jstring());
 618     char* result = NEW_RESOURCE_ARRAY(char, length + 1);
 619     jni()->GetStringUTFRegion(str.as_jstring(), 0, length, result);
 620     return result;
 621   }
 622 }
 623 
 624 char* JVMCIEnv::as_utf8_string(JVMCIObject str, char* buf, int buflen) {
 625   if (is_hotspot()) {
 626     return java_lang_String::as_utf8_string(HotSpotJVMCI::resolve(str), buf, buflen);
 627   } else {
 628     JNIAccessMark jni(this);
 629     int length = jni()->GetStringLength(str.as_jstring());
 630     if (length >= buflen) {
 631       length = buflen;
 632     }
 633     jni()->GetStringUTFRegion(str.as_jstring(), 0, length, buf);
 634     return buf;
 635   }
 636 }
 637 
 638 #define DO_THROW(name)                             \
 639 void JVMCIEnv::throw_##name(const char* msg) {     \
 640   if (is_hotspot()) {                              \
 641     JavaThread* THREAD = JavaThread::current();    \
 642     THROW_MSG(HotSpotJVMCI::name::symbol(), msg);  \
 643   } else {                                         \
 644     JNIAccessMark jni(this);                       \
 645     jni()->ThrowNew(JNIJVMCI::name::clazz(), msg); \
 646   }                                                \
 647 }
 648 
 649 DO_THROW(InternalError)
 650 DO_THROW(ArrayIndexOutOfBoundsException)
 651 DO_THROW(IllegalStateException)
 652 DO_THROW(NullPointerException)
 653 DO_THROW(IllegalArgumentException)
 654 DO_THROW(InvalidInstalledCodeException)
 655 DO_THROW(UnsatisfiedLinkError)
 656 DO_THROW(UnsupportedOperationException)
 657 DO_THROW(ClassNotFoundException)
 658 
 659 #undef DO_THROW
 660 
 661 void JVMCIEnv::fthrow_error(const char* file, int line, const char* format, ...) {
 662   const int max_msg_size = 1024;
 663   va_list ap;
 664   va_start(ap, format);
 665   char msg[max_msg_size];
 666   vsnprintf(msg, max_msg_size, format, ap);
 667   msg[max_msg_size-1] = '\0';
 668   va_end(ap);
 669   if (is_hotspot()) {
 670     JavaThread* THREAD = JavaThread::current();
 671     Handle h_loader = Handle();
 672     Handle h_protection_domain = Handle();
 673     Exceptions::_throw_msg(THREAD, file, line, vmSymbols::jdk_vm_ci_common_JVMCIError(), msg, h_loader, h_protection_domain);
 674   } else {
 675     JNIAccessMark jni(this);
 676     jni()->ThrowNew(JNIJVMCI::JVMCIError::clazz(), msg);
 677   }
 678 }
 679 
 680 JVMCIObject JVMCIEnv::call_HotSpotJVMCIRuntime_compileMethod (JVMCIObject runtime, JVMCIObject method, int entry_bci,
 681                                                               jlong compile_state, int id) {
 682   if (is_hotspot()) {
 683     Thread* THREAD = Thread::current();
 684     JavaCallArguments jargs;
 685     jargs.push_oop(Handle(THREAD, HotSpotJVMCI::resolve(runtime)));
 686     jargs.push_oop(Handle(THREAD, HotSpotJVMCI::resolve(method)));
 687     jargs.push_int(entry_bci);
 688     jargs.push_long(compile_state);
 689     jargs.push_int(id);
 690     JavaValue result(T_OBJECT);
 691     JavaCalls::call_special(&result,
 692                             HotSpotJVMCI::HotSpotJVMCIRuntime::klass(),
 693                             vmSymbols::compileMethod_name(),
 694                             vmSymbols::compileMethod_signature(), &jargs, CHECK_(JVMCIObject()));
 695     return wrap((oop) result.get_jobject());
 696   } else {
 697     JNIAccessMark jni(this);
 698     jobject result = jni()->CallNonvirtualObjectMethod(runtime.as_jobject(),
 699                                                      JNIJVMCI::HotSpotJVMCIRuntime::clazz(),
 700                                                      JNIJVMCI::HotSpotJVMCIRuntime::compileMethod_method(),
 701                                                      method.as_jobject(), entry_bci, compile_state, id);
 702     if (jni()->ExceptionCheck()) {
 703       return JVMCIObject();
 704     }
 705     return wrap(result);
 706   }
 707 }
 708 
 709 void JVMCIEnv::call_HotSpotJVMCIRuntime_bootstrapFinished (JVMCIObject runtime, JVMCIEnv* JVMCIENV) {
 710   if (is_hotspot()) {
 711     Thread* THREAD = Thread::current();
 712     JavaCallArguments jargs;
 713     jargs.push_oop(Handle(THREAD, HotSpotJVMCI::resolve(runtime)));
 714     JavaValue result(T_VOID);
 715     JavaCalls::call_special(&result, HotSpotJVMCI::HotSpotJVMCIRuntime::klass(), vmSymbols::bootstrapFinished_name(), vmSymbols::void_method_signature(), &jargs, CHECK);
 716   } else {
 717     JNIAccessMark jni(this);
 718     jni()->CallNonvirtualVoidMethod(runtime.as_jobject(), JNIJVMCI::HotSpotJVMCIRuntime::clazz(), JNIJVMCI::HotSpotJVMCIRuntime::bootstrapFinished_method());
 719 
 720   }
 721 }
 722 
 723 void JVMCIEnv::call_HotSpotJVMCIRuntime_shutdown (JVMCIObject runtime) {
 724   HandleMark hm;
 725   JavaThread* THREAD = JavaThread::current();
 726   if (is_hotspot()) {
 727     JavaCallArguments jargs;
 728     jargs.push_oop(Handle(THREAD, HotSpotJVMCI::resolve(runtime)));
 729     JavaValue result(T_VOID);
 730     JavaCalls::call_special(&result, HotSpotJVMCI::HotSpotJVMCIRuntime::klass(), vmSymbols::shutdown_name(), vmSymbols::void_method_signature(), &jargs, THREAD);
 731   } else {
 732     JNIAccessMark jni(this);
 733     jni()->CallNonvirtualVoidMethod(runtime.as_jobject(), JNIJVMCI::HotSpotJVMCIRuntime::clazz(), JNIJVMCI::HotSpotJVMCIRuntime::shutdown_method());
 734   }
 735   if (has_pending_exception()) {
 736     // This should never happen as HotSpotJVMCIRuntime.shutdown() should
 737     // handle all exceptions.
 738     describe_pending_exception(true);
 739   }
 740 }
 741 
 742 JVMCIObject JVMCIEnv::call_HotSpotJVMCIRuntime_runtime (JVMCIEnv* JVMCIENV) {
 743   JavaThread* THREAD = JavaThread::current();
 744   if (is_hotspot()) {
 745     JavaCallArguments jargs;
 746     JavaValue result(T_OBJECT);
 747     JavaCalls::call_static(&result, HotSpotJVMCI::HotSpotJVMCIRuntime::klass(), vmSymbols::runtime_name(), vmSymbols::runtime_signature(), &jargs, CHECK_(JVMCIObject()));
 748     return wrap((oop) result.get_jobject());
 749   } else {
 750     JNIAccessMark jni(this);
 751     jobject result = jni()->CallStaticObjectMethod(JNIJVMCI::HotSpotJVMCIRuntime::clazz(), JNIJVMCI::HotSpotJVMCIRuntime::runtime_method());
 752     if (jni()->ExceptionCheck()) {
 753       return JVMCIObject();
 754     }
 755     return wrap(result);
 756   }
 757 }
 758 
 759 JVMCIObject JVMCIEnv::call_JVMCI_getRuntime (JVMCIEnv* JVMCIENV) {
 760   JavaThread* THREAD = JavaThread::current();
 761   if (is_hotspot()) {
 762     JavaCallArguments jargs;
 763     JavaValue result(T_OBJECT);
 764     JavaCalls::call_static(&result, HotSpotJVMCI::JVMCI::klass(), vmSymbols::getRuntime_name(), vmSymbols::getRuntime_signature(), &jargs, CHECK_(JVMCIObject()));
 765     return wrap((oop) result.get_jobject());
 766   } else {
 767     JNIAccessMark jni(this);
 768     jobject result = jni()->CallStaticObjectMethod(JNIJVMCI::JVMCI::clazz(), JNIJVMCI::JVMCI::getRuntime_method());
 769     if (jni()->ExceptionCheck()) {
 770       return JVMCIObject();
 771     }
 772     return wrap(result);
 773   }
 774 }
 775 
 776 JVMCIObject JVMCIEnv::call_HotSpotJVMCIRuntime_getCompiler (JVMCIObject runtime, JVMCIEnv* JVMCIENV) {
 777   JavaThread* THREAD = JavaThread::current();
 778   if (is_hotspot()) {
 779     JavaCallArguments jargs;
 780     jargs.push_oop(Handle(THREAD, HotSpotJVMCI::resolve(runtime)));
 781     JavaValue result(T_OBJECT);
 782     JavaCalls::call_virtual(&result, HotSpotJVMCI::HotSpotJVMCIRuntime::klass(), vmSymbols::getCompiler_name(), vmSymbols::getCompiler_signature(), &jargs, CHECK_(JVMCIObject()));
 783     return wrap((oop) result.get_jobject());
 784   } else {
 785     JNIAccessMark jni(this);
 786     jobject result = jni()->CallObjectMethod(runtime.as_jobject(), JNIJVMCI::HotSpotJVMCIRuntime::getCompiler_method());
 787     if (jni()->ExceptionCheck()) {
 788       return JVMCIObject();
 789     }
 790     return wrap(result);
 791   }
 792 }
 793 
 794 
 795 JVMCIObject JVMCIEnv::call_HotSpotJVMCIRuntime_callToString(JVMCIObject object, JVMCIEnv* JVMCIENV) {
 796   JavaThread* THREAD = JavaThread::current();
 797   if (is_hotspot()) {
 798     JavaCallArguments jargs;
 799     jargs.push_oop(Handle(THREAD, HotSpotJVMCI::resolve(object)));
 800     JavaValue result(T_OBJECT);
 801     JavaCalls::call_static(&result,
 802                            HotSpotJVMCI::HotSpotJVMCIRuntime::klass(),
 803                            vmSymbols::callToString_name(),
 804                            vmSymbols::callToString_signature(), &jargs, CHECK_(JVMCIObject()));
 805     return wrap((oop) result.get_jobject());
 806   } else {
 807     JNIAccessMark jni(this);
 808     jobject result = (jstring) jni()->CallStaticObjectMethod(JNIJVMCI::HotSpotJVMCIRuntime::clazz(),
 809                                                      JNIJVMCI::HotSpotJVMCIRuntime::callToString_method(),
 810                                                      object.as_jobject());
 811     if (jni()->ExceptionCheck()) {
 812       return JVMCIObject();
 813     }
 814     return wrap(result);
 815   }
 816 }
 817 
 818 
 819 JVMCIObject JVMCIEnv::call_PrimitiveConstant_forTypeChar(jchar kind, jlong value, JVMCI_TRAPS) {
 820   JavaThread* THREAD = JavaThread::current();
 821   if (is_hotspot()) {
 822     JavaCallArguments jargs;
 823     jargs.push_int(kind);
 824     jargs.push_long(value);
 825     JavaValue result(T_OBJECT);
 826     JavaCalls::call_static(&result,
 827                            HotSpotJVMCI::PrimitiveConstant::klass(),
 828                            vmSymbols::forTypeChar_name(),
 829                            vmSymbols::forTypeChar_signature(), &jargs, CHECK_(JVMCIObject()));
 830     return wrap((oop) result.get_jobject());
 831   } else {
 832     JNIAccessMark jni(this);
 833     jobject result = (jstring) jni()->CallStaticObjectMethod(JNIJVMCI::PrimitiveConstant::clazz(),
 834                                                      JNIJVMCI::PrimitiveConstant::forTypeChar_method(),
 835                                                      kind, value);
 836     if (jni()->ExceptionCheck()) {
 837       return JVMCIObject();
 838     }
 839     return wrap(result);
 840   }
 841 }
 842 
 843 JVMCIObject JVMCIEnv::call_JavaConstant_forFloat(float value, JVMCI_TRAPS) {
 844   JavaThread* THREAD = JavaThread::current();
 845   if (is_hotspot()) {
 846     JavaCallArguments jargs;
 847     jargs.push_float(value);
 848     JavaValue result(T_OBJECT);
 849     JavaCalls::call_static(&result,
 850                            HotSpotJVMCI::JavaConstant::klass(),
 851                            vmSymbols::forFloat_name(),
 852                            vmSymbols::forFloat_signature(), &jargs, CHECK_(JVMCIObject()));
 853     return wrap((oop) result.get_jobject());
 854   } else {
 855     JNIAccessMark jni(this);
 856     jobject result = (jstring) jni()->CallStaticObjectMethod(JNIJVMCI::JavaConstant::clazz(),
 857                                                      JNIJVMCI::JavaConstant::forFloat_method(),
 858                                                      value);
 859     if (jni()->ExceptionCheck()) {
 860       return JVMCIObject();
 861     }
 862     return wrap(result);
 863   }
 864 }
 865 
 866 JVMCIObject JVMCIEnv::call_JavaConstant_forDouble(double value, JVMCI_TRAPS) {
 867   JavaThread* THREAD = JavaThread::current();
 868   if (is_hotspot()) {
 869     JavaCallArguments jargs;
 870     jargs.push_double(value);
 871     JavaValue result(T_OBJECT);
 872     JavaCalls::call_static(&result,
 873                            HotSpotJVMCI::JavaConstant::klass(),
 874                            vmSymbols::forDouble_name(),
 875                            vmSymbols::forDouble_signature(), &jargs, CHECK_(JVMCIObject()));
 876     return wrap((oop) result.get_jobject());
 877   } else {
 878     JNIAccessMark jni(this);
 879     jobject result = (jstring) jni()->CallStaticObjectMethod(JNIJVMCI::JavaConstant::clazz(),
 880                                                      JNIJVMCI::JavaConstant::forDouble_method(),
 881                                                      value);
 882     if (jni()->ExceptionCheck()) {
 883       return JVMCIObject();
 884     }
 885     return wrap(result);
 886   }
 887 }
 888 
 889 JVMCIObject JVMCIEnv::get_jvmci_primitive_type(BasicType type) {
 890   JVMCIObjectArray primitives = get_HotSpotResolvedPrimitiveType_primitives();
 891   JVMCIObject result = get_object_at(primitives, type);
 892   return result;
 893 }
 894 
 895 JVMCIObject JVMCIEnv::new_StackTraceElement(const methodHandle& method, int bci, JVMCI_TRAPS) {
 896   JavaThread* THREAD = JavaThread::current();
 897   Symbol* method_name_sym;
 898   Symbol* file_name_sym;
 899   int line_number;
 900   Handle mirror (THREAD, method->method_holder()->java_mirror());
 901   java_lang_StackTraceElement::decode(mirror, method, bci, method_name_sym, file_name_sym, line_number);
 902 
 903   InstanceKlass* holder = method->method_holder();
 904   const char* declaring_class_str = holder->external_name();
 905 
 906   if (is_hotspot()) {
 907     HotSpotJVMCI::StackTraceElement::klass()->initialize(CHECK_(JVMCIObject()));
 908     oop objOop = HotSpotJVMCI::StackTraceElement::klass()->allocate_instance(CHECK_(JVMCIObject()));
 909     Handle obj = Handle(THREAD, objOop);
 910 
 911     oop declaring_class = StringTable::intern((char*) declaring_class_str, CHECK_(JVMCIObject()));
 912     HotSpotJVMCI::StackTraceElement::set_declaringClass(this, obj(), declaring_class);
 913 
 914     oop method_name = StringTable::intern(method_name_sym, CHECK_(JVMCIObject()));
 915     HotSpotJVMCI::StackTraceElement::set_methodName(this, obj(), method_name);
 916 
 917     if (file_name_sym != NULL) {
 918       oop file_name = StringTable::intern(file_name_sym, CHECK_(JVMCIObject()));
 919       HotSpotJVMCI::StackTraceElement::set_fileName(this, obj(), file_name);
 920     }
 921     HotSpotJVMCI::StackTraceElement::set_lineNumber(this, obj(), line_number);
 922     return wrap(obj());
 923   } else {
 924     JNIAccessMark jni(this);
 925     jobject declaring_class = jni()->NewStringUTF(declaring_class_str);
 926     if (jni()->ExceptionCheck()) {
 927       return JVMCIObject();
 928     }
 929     jobject method_name = jni()->NewStringUTF(method_name_sym->as_C_string());
 930     if (jni()->ExceptionCheck()) {
 931       return JVMCIObject();
 932     }
 933     jobject file_name = NULL;
 934     if (file_name_sym != NULL) {
 935       file_name = jni()->NewStringUTF(file_name_sym->as_C_string());
 936       if (jni()->ExceptionCheck()) {
 937         return JVMCIObject();
 938       }
 939     }
 940 
 941     jobject result = jni()->NewObject(JNIJVMCI::StackTraceElement::clazz(),
 942                                       JNIJVMCI::StackTraceElement::constructor(),
 943                                       declaring_class, method_name, file_name, line_number);
 944     return wrap(result);
 945   }
 946 }
 947 
 948 JVMCIObject JVMCIEnv::new_HotSpotNmethod(const methodHandle& method, const char* name, jboolean isDefault, jlong compileId, JVMCI_TRAPS) {
 949   JavaThread* THREAD = JavaThread::current();
 950 
 951   JVMCIObject methodObject = get_jvmci_method(method(), JVMCI_CHECK_(JVMCIObject()));
 952 
 953   if (is_hotspot()) {
 954     InstanceKlass* ik = InstanceKlass::cast(HotSpotJVMCI::HotSpotNmethod::klass());
 955     if (ik->should_be_initialized()) {
 956       ik->initialize(CHECK_(JVMCIObject()));
 957     }
 958     oop obj = ik->allocate_instance(CHECK_(JVMCIObject()));
 959     Handle obj_h(THREAD, obj);
 960     Handle nameStr = java_lang_String::create_from_str(name, CHECK_(JVMCIObject()));
 961 
 962     // Call constructor
 963     JavaCallArguments jargs;
 964     jargs.push_oop(obj_h);
 965     jargs.push_oop(Handle(THREAD, HotSpotJVMCI::resolve(methodObject)));
 966     jargs.push_oop(nameStr);
 967     jargs.push_int(isDefault);
 968     jargs.push_long(compileId);
 969     JavaValue result(T_VOID);
 970     JavaCalls::call_special(&result, ik,
 971                             vmSymbols::object_initializer_name(),
 972                             vmSymbols::method_string_bool_long_signature(),
 973                             &jargs, CHECK_(JVMCIObject()));
 974     return wrap(obj_h());
 975   } else {
 976     JNIAccessMark jni(this);
 977     jobject nameStr = name == NULL ? NULL : jni()->NewStringUTF(name);
 978     if (jni()->ExceptionCheck()) {
 979       return JVMCIObject();
 980     }
 981 
 982     jobject result = jni()->NewObject(JNIJVMCI::HotSpotNmethod::clazz(),
 983                                       JNIJVMCI::HotSpotNmethod::constructor(),
 984                                       methodObject.as_jobject(), nameStr, isDefault);
 985     return wrap(result);
 986   }
 987 }
 988 
 989 JVMCIObject JVMCIEnv::make_local(JVMCIObject object) {
 990   if (object.is_null()) {
 991     return JVMCIObject();
 992   }
 993   if (is_hotspot()) {
 994     return wrap(JNIHandles::make_local(HotSpotJVMCI::resolve(object)));
 995   } else {
 996     JNIAccessMark jni(this);
 997     return wrap(jni()->NewLocalRef(object.as_jobject()));
 998   }
 999 }
1000 
1001 JVMCIObject JVMCIEnv::make_global(JVMCIObject object) {
1002   if (object.is_null()) {
1003     return JVMCIObject();
1004   }
1005   if (is_hotspot()) {
1006     return wrap(JNIHandles::make_global(Handle(Thread::current(), HotSpotJVMCI::resolve(object))));
1007   } else {
1008     JNIAccessMark jni(this);
1009     return wrap(jni()->NewGlobalRef(object.as_jobject()));
1010   }
1011 }
1012 
1013 JVMCIObject JVMCIEnv::make_weak(JVMCIObject object) {
1014   if (object.is_null()) {
1015     return JVMCIObject();
1016   }
1017   if (is_hotspot()) {
1018     return wrap(JNIHandles::make_weak_global(Handle(Thread::current(), HotSpotJVMCI::resolve(object))));
1019   } else {
1020     JNIAccessMark jni(this);
1021     return wrap(jni()->NewWeakGlobalRef(object.as_jobject()));
1022   }
1023 }
1024 
1025 void JVMCIEnv::destroy_local(JVMCIObject object) {
1026   if (is_hotspot()) {
1027     JNIHandles::destroy_local(object.as_jobject());
1028   } else {
1029     JNIAccessMark jni(this);
1030     jni()->DeleteLocalRef(object.as_jobject());
1031   }
1032 }
1033 
1034 void JVMCIEnv::destroy_global(JVMCIObject object) {
1035   if (is_hotspot()) {
1036     JNIHandles::destroy_global(object.as_jobject());
1037   } else {
1038     JNIAccessMark jni(this);
1039     jni()->DeleteGlobalRef(object.as_jobject());
1040   }
1041 }
1042 
1043 void JVMCIEnv::destroy_weak(JVMCIObject object) {
1044   if (is_hotspot()) {
1045     JNIHandles::destroy_weak_global(object.as_jweak());
1046   } else {
1047     JNIAccessMark jni(this);
1048     jni()->DeleteWeakGlobalRef(object.as_jweak());
1049   }
1050 }
1051 
1052 const char* JVMCIEnv::klass_name(JVMCIObject object) {
1053   if (is_hotspot()) {
1054     return HotSpotJVMCI::resolve(object)->klass()->signature_name();
1055   } else {
1056     JVMCIObject name;
1057     {
1058       JNIAccessMark jni(this);
1059       jclass jcl = jni()->GetObjectClass(object.as_jobject());
1060       jobject result = jni()->CallObjectMethod(jcl, JNIJVMCI::Class_getName_method());
1061       name = JVMCIObject::create(result, is_hotspot());
1062     }
1063     return as_utf8_string(name);
1064   }
1065 }
1066 
1067 JVMCIObject JVMCIEnv::get_jvmci_method(const methodHandle& method, JVMCI_TRAPS) {
1068   JVMCIObject method_object;
1069   if (method() == NULL) {
1070     return method_object;
1071   }
1072 
1073   Thread* THREAD = Thread::current();
1074   jmetadata handle = JVMCI::allocate_handle(method);
1075   jboolean exception = false;
1076   if (is_hotspot()) {
1077     JavaValue result(T_OBJECT);
1078     JavaCallArguments args;
1079     args.push_long((jlong) handle);
1080     JavaCalls::call_static(&result, HotSpotJVMCI::HotSpotResolvedJavaMethodImpl::klass(),
1081                            vmSymbols::fromMetaspace_name(),
1082                            vmSymbols::method_fromMetaspace_signature(), &args, THREAD);
1083     if (HAS_PENDING_EXCEPTION) {
1084       exception = true;
1085     } else {
1086       method_object = wrap((oop)result.get_jobject());
1087     }
1088   } else {
1089     JNIAccessMark jni(this);
1090     method_object = JNIJVMCI::wrap(jni()->CallStaticObjectMethod(JNIJVMCI::HotSpotResolvedJavaMethodImpl::clazz(),
1091                                                                   JNIJVMCI::HotSpotResolvedJavaMethodImpl_fromMetaspace_method(),
1092                                                                   (jlong) handle));
1093     exception = jni()->ExceptionCheck();
1094   }
1095 
1096   if (exception) {
1097     JVMCI::release_handle(handle);
1098     return JVMCIObject();
1099   }
1100 
1101   assert(asMethod(method_object) == method(), "must be");
1102   if (get_HotSpotResolvedJavaMethodImpl_metadataHandle(method_object) != (jlong) handle) {
1103     JVMCI::release_handle(handle);
1104   }
1105   assert(!method_object.is_null(), "must be");
1106   return method_object;
1107 }
1108 
1109 JVMCIObject JVMCIEnv::get_jvmci_type(const JVMCIKlassHandle& klass, JVMCI_TRAPS) {
1110   JVMCIObject type;
1111   if (klass.is_null()) {
1112     return type;
1113   }
1114 
1115   jlong pointer = (jlong) klass();
1116   JavaThread* THREAD = JavaThread::current();
1117   JVMCIObject signature = create_string(klass->signature_name(), JVMCI_CHECK_(JVMCIObject()));
1118   jboolean exception = false;
1119   if (is_hotspot()) {
1120     JavaValue result(T_OBJECT);
1121     JavaCallArguments args;
1122     args.push_long(pointer);
1123     args.push_oop(Handle(THREAD, HotSpotJVMCI::resolve(signature)));
1124     JavaCalls::call_static(&result,
1125                            HotSpotJVMCI::HotSpotResolvedObjectTypeImpl::klass(),
1126                            vmSymbols::fromMetaspace_name(),
1127                            vmSymbols::klass_fromMetaspace_signature(), &args, THREAD);
1128 
1129     if (HAS_PENDING_EXCEPTION) {
1130       exception = true;
1131     } else {
1132       type = wrap((oop)result.get_jobject());
1133     }
1134   } else {
1135     JNIAccessMark jni(this);
1136 
1137     HandleMark hm(THREAD);
1138     type = JNIJVMCI::wrap(jni()->CallStaticObjectMethod(JNIJVMCI::HotSpotResolvedObjectTypeImpl::clazz(),
1139                                                         JNIJVMCI::HotSpotResolvedObjectTypeImpl_fromMetaspace_method(),
1140                                                         pointer, signature.as_jstring()));
1141     exception = jni()->ExceptionCheck();
1142   }
1143   if (exception) {
1144     return JVMCIObject();
1145   }
1146 
1147   assert(type.is_non_null(), "must have result");
1148   return type;
1149 }
1150 
1151 JVMCIObject JVMCIEnv::get_jvmci_constant_pool(const constantPoolHandle& cp, JVMCI_TRAPS) {
1152   JVMCIObject cp_object;
1153   jmetadata handle = JVMCI::allocate_handle(cp);
1154   jboolean exception = false;
1155   if (is_hotspot()) {
1156     JavaThread* THREAD = JavaThread::current();
1157     JavaValue result(T_OBJECT);
1158     JavaCallArguments args;
1159     args.push_long((jlong) handle);
1160     JavaCalls::call_static(&result,
1161                            HotSpotJVMCI::HotSpotConstantPool::klass(),
1162                            vmSymbols::fromMetaspace_name(),
1163                            vmSymbols::constantPool_fromMetaspace_signature(), &args, THREAD);
1164     if (HAS_PENDING_EXCEPTION) {
1165       exception = true;
1166     } else {
1167       cp_object = wrap((oop)result.get_jobject());
1168     }
1169   } else {
1170     JNIAccessMark jni(this);
1171     cp_object = JNIJVMCI::wrap(jni()->CallStaticObjectMethod(JNIJVMCI::HotSpotConstantPool::clazz(),
1172                                                              JNIJVMCI::HotSpotConstantPool_fromMetaspace_method(),
1173                                                              (jlong) handle));
1174     exception = jni()->ExceptionCheck();
1175   }
1176 
1177   if (exception) {
1178     JVMCI::release_handle(handle);
1179     return JVMCIObject();
1180   }
1181 
1182   assert(!cp_object.is_null(), "must be");
1183   // Constant pools aren't cached so this is always a newly created object using the handle
1184   assert(get_HotSpotConstantPool_metadataHandle(cp_object) == (jlong) handle, "must use same handle");
1185   return cp_object;
1186 }
1187 
1188 JVMCIPrimitiveArray JVMCIEnv::new_booleanArray(int length, JVMCI_TRAPS) {
1189   if (is_hotspot()) {
1190     JavaThread* THREAD = JavaThread::current();
1191     typeArrayOop result = oopFactory::new_boolArray(length, CHECK_(JVMCIObject()));
1192     return wrap(result);
1193   } else {
1194     JNIAccessMark jni(this);
1195     jbooleanArray result = jni()->NewBooleanArray(length);
1196     return wrap(result);
1197   }
1198 }
1199 
1200 JVMCIPrimitiveArray JVMCIEnv::new_byteArray(int length, JVMCI_TRAPS) {
1201   if (is_hotspot()) {
1202     JavaThread* THREAD = JavaThread::current();
1203     typeArrayOop result = oopFactory::new_byteArray(length, CHECK_(JVMCIObject()));
1204     return wrap(result);
1205   } else {
1206     JNIAccessMark jni(this);
1207     jbyteArray result = jni()->NewByteArray(length);
1208     return wrap(result);
1209   }
1210 }
1211 
1212 JVMCIObjectArray JVMCIEnv::new_byte_array_array(int length, JVMCI_TRAPS) {
1213   if (is_hotspot()) {
1214     JavaThread* THREAD = JavaThread::current();
1215     Klass* byteArrayArrayKlass = TypeArrayKlass::cast(Universe::byteArrayKlassObj  ())->array_klass(CHECK_(JVMCIObject()));
1216     objArrayOop result = ObjArrayKlass::cast(byteArrayArrayKlass) ->allocate(length, CHECK_(JVMCIObject()));
1217     return wrap(result);
1218   } else {
1219     JNIAccessMark jni(this);
1220     jobjectArray result = jni()->NewObjectArray(length, JNIJVMCI::byte_array(), NULL);
1221     return wrap(result);
1222   }
1223 }
1224 
1225 JVMCIPrimitiveArray JVMCIEnv::new_intArray(int length, JVMCI_TRAPS) {
1226   if (is_hotspot()) {
1227     JavaThread* THREAD = JavaThread::current();
1228     typeArrayOop result = oopFactory::new_intArray(length, CHECK_(JVMCIObject()));
1229     return wrap(result);
1230   } else {
1231     JNIAccessMark jni(this);
1232     jintArray result = jni()->NewIntArray(length);
1233     return wrap(result);
1234   }
1235 }
1236 
1237 JVMCIPrimitiveArray JVMCIEnv::new_longArray(int length, JVMCI_TRAPS) {
1238   if (is_hotspot()) {
1239     JavaThread* THREAD = JavaThread::current();
1240     typeArrayOop result = oopFactory::new_longArray(length, CHECK_(JVMCIObject()));
1241     return wrap(result);
1242   } else {
1243     JNIAccessMark jni(this);
1244     jlongArray result = jni()->NewLongArray(length);
1245     return wrap(result);
1246   }
1247 }
1248 
1249 JVMCIObject JVMCIEnv::new_VMField(JVMCIObject name, JVMCIObject type, jlong offset, jlong address, JVMCIObject value, JVMCI_TRAPS) {
1250   if (is_hotspot()) {
1251     JavaThread* THREAD = JavaThread::current();
1252     HotSpotJVMCI::VMField::klass()->initialize(CHECK_(JVMCIObject()));
1253     oop obj = HotSpotJVMCI::VMField::klass()->allocate_instance(CHECK_(JVMCIObject()));
1254     HotSpotJVMCI::VMField::set_name(this, obj, HotSpotJVMCI::resolve(name));
1255     HotSpotJVMCI::VMField::set_type(this, obj, HotSpotJVMCI::resolve(type));
1256     HotSpotJVMCI::VMField::set_offset(this, obj, offset);
1257     HotSpotJVMCI::VMField::set_address(this, obj, address);
1258     HotSpotJVMCI::VMField::set_value(this, obj, HotSpotJVMCI::resolve(value));
1259     return wrap(obj);
1260   } else {
1261     JNIAccessMark jni(this);
1262     jobject result = jni()->NewObject(JNIJVMCI::VMField::clazz(),
1263                                     JNIJVMCI::VMField::constructor(),
1264                                     get_jobject(name), get_jobject(type), offset, address, get_jobject(value));
1265     return wrap(result);
1266   }
1267 }
1268 
1269 JVMCIObject JVMCIEnv::new_VMFlag(JVMCIObject name, JVMCIObject type, JVMCIObject value, JVMCI_TRAPS) {
1270   if (is_hotspot()) {
1271     JavaThread* THREAD = JavaThread::current();
1272     HotSpotJVMCI::VMFlag::klass()->initialize(CHECK_(JVMCIObject()));
1273     oop obj = HotSpotJVMCI::VMFlag::klass()->allocate_instance(CHECK_(JVMCIObject()));
1274     HotSpotJVMCI::VMFlag::set_name(this, obj, HotSpotJVMCI::resolve(name));
1275     HotSpotJVMCI::VMFlag::set_type(this, obj, HotSpotJVMCI::resolve(type));
1276     HotSpotJVMCI::VMFlag::set_value(this, obj, HotSpotJVMCI::resolve(value));
1277     return wrap(obj);
1278   } else {
1279     JNIAccessMark jni(this);
1280     jobject result = jni()->NewObject(JNIJVMCI::VMFlag::clazz(),
1281                                     JNIJVMCI::VMFlag::constructor(),
1282                                     get_jobject(name), get_jobject(type), get_jobject(value));
1283     return wrap(result);
1284   }
1285 }
1286 
1287 JVMCIObject JVMCIEnv::new_VMIntrinsicMethod(JVMCIObject declaringClass, JVMCIObject name, JVMCIObject descriptor, int id, JVMCI_TRAPS) {
1288   if (is_hotspot()) {
1289     JavaThread* THREAD = JavaThread::current();
1290     HotSpotJVMCI::VMIntrinsicMethod::klass()->initialize(CHECK_(JVMCIObject()));
1291     oop obj = HotSpotJVMCI::VMIntrinsicMethod::klass()->allocate_instance(CHECK_(JVMCIObject()));
1292     HotSpotJVMCI::VMIntrinsicMethod::set_declaringClass(this, obj, HotSpotJVMCI::resolve(declaringClass));
1293     HotSpotJVMCI::VMIntrinsicMethod::set_name(this, obj, HotSpotJVMCI::resolve(name));
1294     HotSpotJVMCI::VMIntrinsicMethod::set_descriptor(this, obj, HotSpotJVMCI::resolve(descriptor));
1295     HotSpotJVMCI::VMIntrinsicMethod::set_id(this, obj, id);
1296     return wrap(obj);
1297   } else {
1298     JNIAccessMark jni(this);
1299     jobject result = jni()->NewObject(JNIJVMCI::VMIntrinsicMethod::clazz(),
1300                                     JNIJVMCI::VMIntrinsicMethod::constructor(),
1301                                     get_jobject(declaringClass), get_jobject(name), get_jobject(descriptor), id);
1302     return wrap(result);
1303   }
1304 }
1305 
1306 JVMCIObject JVMCIEnv::new_HotSpotStackFrameReference(JVMCI_TRAPS) {
1307   if (is_hotspot()) {
1308     JavaThread* THREAD = JavaThread::current();
1309     HotSpotJVMCI::HotSpotStackFrameReference::klass()->initialize(CHECK_(JVMCIObject()));
1310     oop obj = HotSpotJVMCI::HotSpotStackFrameReference::klass()->allocate_instance(CHECK_(JVMCIObject()));
1311     return wrap(obj);
1312   } else {
1313     ShouldNotReachHere();
1314     return JVMCIObject();
1315   }
1316 }
1317 JVMCIObject JVMCIEnv::new_JVMCIError(JVMCI_TRAPS) {
1318   if (is_hotspot()) {
1319     JavaThread* THREAD = JavaThread::current();
1320     HotSpotJVMCI::JVMCIError::klass()->initialize(CHECK_(JVMCIObject()));
1321     oop obj = HotSpotJVMCI::JVMCIError::klass()->allocate_instance(CHECK_(JVMCIObject()));
1322     return wrap(obj);
1323   } else {
1324     ShouldNotReachHere();
1325     return JVMCIObject();
1326   }
1327 }
1328 
1329 
1330 JVMCIObject JVMCIEnv::get_object_constant(oop objOop, bool compressed, bool dont_register) {
1331   JavaThread* THREAD = JavaThread::current();
1332   Handle obj = Handle(THREAD, objOop);
1333   if (obj.is_null()) {
1334     return JVMCIObject();
1335   }
1336   if (is_hotspot()) {
1337     HotSpotJVMCI::DirectHotSpotObjectConstantImpl::klass()->initialize(CHECK_(JVMCIObject()));
1338     oop constant = HotSpotJVMCI::DirectHotSpotObjectConstantImpl::klass()->allocate_instance(CHECK_(JVMCIObject()));
1339     HotSpotJVMCI::DirectHotSpotObjectConstantImpl::set_object(this, constant, obj());
1340     HotSpotJVMCI::HotSpotObjectConstantImpl::set_compressed(this, constant, compressed);
1341     return wrap(constant);
1342   } else {
1343     jlong handle = make_handle(obj);
1344     JNIAccessMark jni(this);
1345     jobject result = jni()->NewObject(JNIJVMCI::IndirectHotSpotObjectConstantImpl::clazz(),
1346                                       JNIJVMCI::IndirectHotSpotObjectConstantImpl::constructor(),
1347                                       handle, compressed, dont_register);
1348     return wrap(result);
1349   }
1350 }
1351 
1352 
1353 Handle JVMCIEnv::asConstant(JVMCIObject constant, JVMCI_TRAPS) {
1354   if (constant.is_null()) {
1355     return Handle();
1356   }
1357   JavaThread* THREAD = JavaThread::current();
1358   if (is_hotspot()) {
1359     assert(HotSpotJVMCI::DirectHotSpotObjectConstantImpl::is_instance(this, constant), "wrong type");
1360     oop obj = HotSpotJVMCI::DirectHotSpotObjectConstantImpl::object(this, HotSpotJVMCI::resolve(constant));
1361     return Handle(THREAD, obj);
1362   } else if (isa_IndirectHotSpotObjectConstantImpl(constant)) {
1363     jlong object_handle = get_IndirectHotSpotObjectConstantImpl_objectHandle(constant);
1364     oop result = resolve_handle(object_handle);
1365     if (result == NULL) {
1366       JVMCI_THROW_MSG_(InternalError, "Constant was unexpectedly NULL", Handle());
1367     }
1368     return Handle(THREAD, result);
1369   } else {
1370     JVMCI_THROW_MSG_(IllegalArgumentException, "DirectHotSpotObjectConstantImpl shouldn't reach JVMCI in SVM mode", Handle());
1371   }
1372 }
1373 
1374 JVMCIObject JVMCIEnv::wrap(jobject object) {
1375   return JVMCIObject::create(object, is_hotspot());
1376 }
1377 
1378 jlong JVMCIEnv::make_handle(const Handle& obj) {
1379   assert(!obj.is_null(), "should only create handle for non-NULL oops");
1380   jobject handle = JVMCI::make_global(obj);
1381   return (jlong) handle;
1382 }
1383 
1384 oop JVMCIEnv::resolve_handle(jlong objectHandle) {
1385   assert(objectHandle != 0, "should be a valid handle");
1386   oop obj = *((oopDesc**)objectHandle);
1387   if (obj != NULL) {
1388     oopDesc::verify(obj);
1389   }
1390   return obj;
1391 }
1392 
1393 JVMCIObject JVMCIEnv::create_string(const char* str, JVMCI_TRAPS) {
1394   if (is_hotspot()) {
1395     JavaThread* THREAD = JavaThread::current();
1396     Handle result = java_lang_String::create_from_str(str, CHECK_(JVMCIObject()));
1397     return HotSpotJVMCI::wrap(result());
1398   } else {
1399     jobject result;
1400     jboolean exception = false;
1401     {
1402       JNIAccessMark jni(this);
1403       result = jni()->NewStringUTF(str);
1404       exception = jni()->ExceptionCheck();
1405     }
1406     return wrap(result);
1407   }
1408 }
1409 
1410 bool JVMCIEnv::equals(JVMCIObject a, JVMCIObject b) {
1411   if (is_hotspot()) {
1412     return HotSpotJVMCI::resolve(a) == HotSpotJVMCI::resolve(b);
1413   } else {
1414     JNIAccessMark jni(this);
1415     return jni()->IsSameObject(a.as_jobject(), b.as_jobject()) != 0;
1416   }
1417 }
1418 
1419 BasicType JVMCIEnv::kindToBasicType(JVMCIObject kind, JVMCI_TRAPS) {
1420   if (kind.is_null()) {
1421     JVMCI_THROW_(NullPointerException, T_ILLEGAL);
1422   }
1423   jchar ch = get_JavaKind_typeChar(kind);
1424   switch(ch) {
1425     case 'Z': return T_BOOLEAN;
1426     case 'B': return T_BYTE;
1427     case 'S': return T_SHORT;
1428     case 'C': return T_CHAR;
1429     case 'I': return T_INT;
1430     case 'F': return T_FLOAT;
1431     case 'J': return T_LONG;
1432     case 'D': return T_DOUBLE;
1433     case 'A': return T_OBJECT;
1434     case '-': return T_ILLEGAL;
1435     default:
1436       JVMCI_ERROR_(T_ILLEGAL, "unexpected Kind: %c", ch);
1437   }
1438 }
1439 
1440 void JVMCIEnv::initialize_installed_code(JVMCIObject installed_code, CodeBlob* cb, JVMCI_TRAPS) {
1441   // Ensure that all updates to the InstalledCode fields are consistent.
1442   if (get_InstalledCode_address(installed_code) != 0) {
1443     JVMCI_THROW_MSG(InternalError, "InstalledCode instance already in use");
1444   }
1445   if (!isa_HotSpotInstalledCode(installed_code)) {
1446     JVMCI_THROW_MSG(InternalError, "InstalledCode instance must be a subclass of HotSpotInstalledCode");
1447   }
1448 
1449   // Ignore the version which can stay at 0
1450   if (cb->is_nmethod()) {
1451     nmethod* nm = cb->as_nmethod_or_null();
1452     if (!nm->is_alive()) {
1453       JVMCI_THROW_MSG(InternalError, "nmethod has been reclaimed");
1454     }
1455     if (nm->is_in_use()) {
1456       set_InstalledCode_entryPoint(installed_code, (jlong) nm->verified_entry_point());
1457     }
1458   } else {
1459     set_InstalledCode_entryPoint(installed_code, (jlong) cb->code_begin());
1460   }
1461   set_InstalledCode_address(installed_code, (jlong) cb);
1462   set_HotSpotInstalledCode_size(installed_code, cb->size());
1463   set_HotSpotInstalledCode_codeStart(installed_code, (jlong) cb->code_begin());
1464   set_HotSpotInstalledCode_codeSize(installed_code, cb->code_size());
1465 }
1466 
1467 
1468 void JVMCIEnv::invalidate_nmethod_mirror(JVMCIObject mirror, JVMCI_TRAPS) {
1469   if (mirror.is_null()) {
1470     JVMCI_THROW(NullPointerException);
1471   }
1472 
1473   jlong nativeMethod = get_InstalledCode_address(mirror);
1474   nmethod* nm = JVMCIENV->asNmethod(mirror);
1475   if (nm == NULL) {
1476     // Nothing to do
1477     return;
1478   }
1479 
1480   Thread* THREAD = Thread::current();
1481   if (!mirror.is_hotspot() && !THREAD->is_Java_thread()) {
1482     // Calling back into native might cause the execution to block, so only allow this when calling
1483     // from a JavaThread, which is the normal case anyway.
1484     JVMCI_THROW_MSG(IllegalArgumentException,
1485                     "Cannot invalidate HotSpotNmethod object in shared library VM heap from non-JavaThread");
1486   }
1487 
1488   nmethodLocker nml(nm);
1489   if (nm->is_alive()) {
1490     // Invalidating the HotSpotNmethod means we want the nmethod
1491     // to be deoptimized.
1492     nm->mark_for_deoptimization();
1493     Deoptimization::deoptimize_all_marked();
1494   }
1495 
1496   // A HotSpotNmethod instance can only reference a single nmethod
1497   // during its lifetime so simply clear it here.
1498   set_InstalledCode_address(mirror, 0);
1499 }
1500 
1501 Klass* JVMCIEnv::asKlass(JVMCIObject obj) {
1502   return (Klass*) get_HotSpotResolvedObjectTypeImpl_metadataPointer(obj);
1503 }
1504 
1505 Method* JVMCIEnv::asMethod(JVMCIObject obj) {
1506   Method** metadataHandle = (Method**) get_HotSpotResolvedJavaMethodImpl_metadataHandle(obj);
1507   return *metadataHandle;
1508 }
1509 
1510 ConstantPool* JVMCIEnv::asConstantPool(JVMCIObject obj) {
1511   ConstantPool** metadataHandle = (ConstantPool**) get_HotSpotConstantPool_metadataHandle(obj);
1512   return *metadataHandle;
1513 }
1514 
1515 
1516 CodeBlob* JVMCIEnv::asCodeBlob(JVMCIObject obj) {
1517   address code = (address) get_InstalledCode_address(obj);
1518   if (code == NULL) {
1519     return NULL;
1520   }
1521   if (isa_HotSpotNmethod(obj)) {
1522     jlong compile_id_snapshot = get_HotSpotNmethod_compileIdSnapshot(obj);
1523     if (compile_id_snapshot != 0L) {
1524       // A HotSpotNMethod not in an nmethod's oops table so look up
1525       // the nmethod and then update the fields based on its state.
1526       CodeBlob* cb = CodeCache::find_blob_unsafe(code);
1527       if (cb == (CodeBlob*) code) {
1528         // Found a live CodeBlob with the same address, make sure it's the same nmethod
1529         nmethod* nm = cb->as_nmethod_or_null();
1530         if (nm != NULL && nm->compile_id() == compile_id_snapshot) {
1531           if (!nm->is_alive()) {
1532             // Break the links from the mirror to the nmethod
1533             set_InstalledCode_address(obj, 0);
1534             set_InstalledCode_entryPoint(obj, 0);
1535           } else if (nm->is_not_entrant()) {
1536             // Zero the entry point so that the nmethod
1537             // cannot be invoked by the mirror but can
1538             // still be deoptimized.
1539             set_InstalledCode_entryPoint(obj, 0);
1540           }
1541           return cb;
1542         }
1543       }
1544       // Clear the InstalledCode fields of this HotSpotNmethod
1545       // that no longer refers to an nmethod in the code cache.
1546       set_InstalledCode_address(obj, 0);
1547       set_InstalledCode_entryPoint(obj, 0);
1548       return NULL;
1549     }
1550   }
1551   return (CodeBlob*) code;
1552 }
1553 
1554 
1555 // Generate implementations for the initialize, new, isa, get and set methods for all the types and
1556 // fields declared in the JVMCI_CLASSES_DO macro.
1557 
1558 #define START_CLASS(className, fullClassName)                                                                        \
1559   void JVMCIEnv::className##_initialize(JVMCI_TRAPS) {                                                               \
1560     if (is_hotspot()) {                                                                                              \
1561       HotSpotJVMCI::className::initialize(JVMCI_CHECK);                                                              \
1562     } else {                                                                                                         \
1563       JNIJVMCI::className::initialize(JVMCI_CHECK);                                                                  \
1564     }                                                                                                                \
1565   }                                                                                                                  \
1566   JVMCIObjectArray JVMCIEnv::new_##className##_array(int length, JVMCI_TRAPS) {                                      \
1567     if (is_hotspot()) {                                                                                              \
1568       Thread* THREAD = Thread::current();                                                                            \
1569       objArrayOop array = oopFactory::new_objArray(HotSpotJVMCI::className::klass(), length, CHECK_(JVMCIObject())); \
1570       return (JVMCIObjectArray) wrap(array);                                                                         \
1571     } else {                                                                                                         \
1572       JNIAccessMark jni(this);                                                                                       \
1573       jobjectArray result = jni()->NewObjectArray(length, JNIJVMCI::className::clazz(), NULL);                       \
1574       return wrap(result);                                                                                           \
1575     }                                                                                                                \
1576   }                                                                                                                  \
1577   bool JVMCIEnv::isa_##className(JVMCIObject object) {                                                               \
1578     if (is_hotspot()) {                                                                                              \
1579       return HotSpotJVMCI::className::is_instance(this, object);                                                     \
1580     } else {                                                                                                         \
1581       return JNIJVMCI::className::is_instance(this, object);                                                         \
1582     }                                                                                                                \
1583   }
1584 
1585 #define END_CLASS
1586 
1587 #define FIELD(className, name, type, accessor, cast)                 \
1588   type JVMCIEnv::get_##className##_##name(JVMCIObject obj) {         \
1589     if (is_hotspot()) {                                              \
1590       return HotSpotJVMCI::className::get_##name(this, obj);         \
1591     } else {                                                         \
1592       return JNIJVMCI::className::get_##name(this, obj);             \
1593     }                                                                \
1594   }                                                                  \
1595   void JVMCIEnv::set_##className##_##name(JVMCIObject obj, type x) { \
1596     if (is_hotspot()) {                                              \
1597       HotSpotJVMCI::className::set_##name(this, obj, x);             \
1598     } else {                                                         \
1599       JNIJVMCI::className::set_##name(this, obj, x);                 \
1600     }                                                                \
1601   }
1602 
1603 #define EMPTY_CAST
1604 #define CHAR_FIELD(className, name)                    FIELD(className, name, jchar, Char, EMPTY_CAST)
1605 #define INT_FIELD(className, name)                     FIELD(className, name, jint, Int, EMPTY_CAST)
1606 #define BOOLEAN_FIELD(className, name)                 FIELD(className, name, jboolean, Boolean, EMPTY_CAST)
1607 #define LONG_FIELD(className, name)                    FIELD(className, name, jlong, Long, EMPTY_CAST)
1608 #define FLOAT_FIELD(className, name)                   FIELD(className, name, jfloat, Float, EMPTY_CAST)
1609 
1610 #define OBJECT_FIELD(className, name, signature)              OOPISH_FIELD(className, name, JVMCIObject, Object, EMPTY_CAST)
1611 #define OBJECTARRAY_FIELD(className, name, signature)         OOPISH_FIELD(className, name, JVMCIObjectArray, Object, (JVMCIObjectArray))
1612 #define PRIMARRAY_FIELD(className, name, signature)           OOPISH_FIELD(className, name, JVMCIPrimitiveArray, Object, (JVMCIPrimitiveArray))
1613 
1614 #define STATIC_OBJECT_FIELD(className, name, signature)       STATIC_OOPISH_FIELD(className, name, JVMCIObject, Object, (JVMCIObject))
1615 #define STATIC_OBJECTARRAY_FIELD(className, name, signature)  STATIC_OOPISH_FIELD(className, name, JVMCIObjectArray, Object, (JVMCIObjectArray))
1616 
1617 #define OOPISH_FIELD(className, name, type, accessor, cast)           \
1618   type JVMCIEnv::get_##className##_##name(JVMCIObject obj) {          \
1619     if (is_hotspot()) {                                               \
1620       return HotSpotJVMCI::className::get_##name(this, obj);          \
1621     } else {                                                          \
1622       return JNIJVMCI::className::get_##name(this, obj);              \
1623     }                                                                 \
1624   }                                                                   \
1625   void JVMCIEnv::set_##className##_##name(JVMCIObject obj, type x) {  \
1626     if (is_hotspot()) {                                               \
1627       HotSpotJVMCI::className::set_##name(this, obj, x);              \
1628     } else {                                                          \
1629       JNIJVMCI::className::set_##name(this, obj, x);                  \
1630     }                                                                 \
1631   }
1632 
1633 #define STATIC_OOPISH_FIELD(className, name, type, accessor, cast)    \
1634   type JVMCIEnv::get_##className##_##name() {                         \
1635     if (is_hotspot()) {                                               \
1636       return HotSpotJVMCI::className::get_##name(this);               \
1637     } else {                                                          \
1638       return JNIJVMCI::className::get_##name(this);                   \
1639     }                                                                 \
1640   }                                                                   \
1641   void JVMCIEnv::set_##className##_##name(type x) {                   \
1642     if (is_hotspot()) {                                               \
1643       HotSpotJVMCI::className::set_##name(this, x);                   \
1644     } else {                                                          \
1645       JNIJVMCI::className::set_##name(this, x);                       \
1646     }                                                                 \
1647   }
1648 
1649 #define STATIC_PRIMITIVE_FIELD(className, name, type, accessor, cast) \
1650   type JVMCIEnv::get_##className##_##name() {                         \
1651     if (is_hotspot()) {                                               \
1652       return HotSpotJVMCI::className::get_##name(this);               \
1653     } else {                                                          \
1654       return JNIJVMCI::className::get_##name(this);                   \
1655     }                                                                 \
1656   }                                                                   \
1657   void JVMCIEnv::set_##className##_##name(type x) {                   \
1658     if (is_hotspot()) {                                               \
1659       HotSpotJVMCI::className::set_##name(this, x);                   \
1660     } else {                                                          \
1661       JNIJVMCI::className::set_##name(this, x);                       \
1662     }                                                                 \
1663   }
1664 #define STATIC_INT_FIELD(className, name) STATIC_PRIMITIVE_FIELD(className, name, jint, Int, EMPTY_CAST)
1665 #define STATIC_BOOLEAN_FIELD(className, name) STATIC_PRIMITIVE_FIELD(className, name, jboolean, Boolean, EMPTY_CAST)
1666 #define METHOD(jniCallType, jniGetMethod, hsCallType, returnType, className, methodName, signatureSymbolName, args)
1667 #define CONSTRUCTOR(className, signature)
1668 
1669 JVMCI_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)
1670 
1671 #undef START_CLASS
1672 #undef END_CLASS
1673 #undef METHOD
1674 #undef CONSTRUCTOR
1675 #undef FIELD
1676 #undef CHAR_FIELD
1677 #undef INT_FIELD
1678 #undef BOOLEAN_FIELD
1679 #undef LONG_FIELD
1680 #undef FLOAT_FIELD
1681 #undef OBJECT_FIELD
1682 #undef PRIMARRAY_FIELD
1683 #undef OBJECTARRAY_FIELD
1684 #undef STATIC_OOPISH_FIELD
1685 #undef STATIC_OBJECT_FIELD
1686 #undef STATIC_OBJECTARRAY_FIELD
1687 #undef STATIC_INT_FIELD
1688 #undef STATIC_BOOLEAN_FIELD
1689 #undef EMPTY_CAST