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