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