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 "code/codeCache.hpp"
  28 #include "memory/oopFactory.hpp"
  29 #include "memory/resourceArea.hpp"
  30 #include "oops/objArrayOop.inline.hpp"
  31 #include "oops/typeArrayOop.inline.hpp"
  32 #include "runtime/jniHandles.inline.hpp"
  33 #include "runtime/javaCalls.hpp"
  34 #include "jvmci/jniAccessMark.inline.hpp"
  35 #include "jvmci/jvmciRuntime.hpp"
  36 
  37 JVMCICompileState::JVMCICompileState(CompileTask* task, int system_dictionary_modification_counter):
  38   _task(task),
  39   _system_dictionary_modification_counter(system_dictionary_modification_counter),
  40   _retryable(true),
  41   _failure_reason(NULL),
  42   _failure_reason_on_C_heap(false) {
  43   // Get Jvmti capabilities under lock to get consistent values.
  44   MutexLocker mu(JvmtiThreadState_lock);
  45   _jvmti_can_hotswap_or_post_breakpoint = JvmtiExport::can_hotswap_or_post_breakpoint() ? 1 : 0;
  46   _jvmti_can_access_local_variables     = JvmtiExport::can_access_local_variables() ? 1 : 0;
  47   _jvmti_can_post_on_exceptions         = JvmtiExport::can_post_on_exceptions() ? 1 : 0;
  48   _jvmti_can_pop_frame                  = JvmtiExport::can_pop_frame() ? 1 : 0;
  49 }
  50 
  51 bool JVMCICompileState::jvmti_state_changed() const {
  52   if (!jvmti_can_access_local_variables() &&
  53       JvmtiExport::can_access_local_variables()) {
  54     return true;
  55   }
  56   if (!jvmti_can_hotswap_or_post_breakpoint() &&
  57       JvmtiExport::can_hotswap_or_post_breakpoint()) {
  58     return true;
  59   }
  60   if (!jvmti_can_post_on_exceptions() &&
  61       JvmtiExport::can_post_on_exceptions()) {
  62     return true;
  63   }
  64   if (!jvmti_can_pop_frame() &&
  65       JvmtiExport::can_pop_frame()) {
  66     return true;
  67   }
  68   return false;
  69 }
  70 
  71 JavaVM* JVMCIEnv::_shared_library_javavm = NULL;
  72 void* JVMCIEnv::_shared_library_handle = NULL;
  73 char* JVMCIEnv::_shared_library_path = NULL;
  74 
  75 void JVMCIEnv::copy_saved_properties() {
  76   assert(!is_hotspot(), "can only copy saved properties from HotSpot to native image");
  77 
  78   JavaThread* THREAD = JavaThread::current();
  79 
  80   Klass* k = SystemDictionary::resolve_or_fail(vmSymbols::jdk_vm_ci_services_Services(), Handle(), Handle(), true, THREAD);
  81   if (HAS_PENDING_EXCEPTION) {
  82     JVMCIRuntime::exit_on_pending_exception(NULL, "Error initializing jdk.vm.ci.services.Services");
  83   }
  84   InstanceKlass* ik = InstanceKlass::cast(k);
  85   if (ik->should_be_initialized()) {
  86     ik->initialize(THREAD);
  87     if (HAS_PENDING_EXCEPTION) {
  88       JVMCIRuntime::exit_on_pending_exception(NULL, "Error initializing jdk.vm.ci.services.Services");
  89     }
  90   }
  91 
  92   // Get the serialized saved properties from HotSpot
  93   TempNewSymbol serializeSavedProperties = SymbolTable::new_symbol("serializeSavedProperties", CHECK_EXIT);
  94   JavaValue result(T_OBJECT);
  95   JavaCallArguments args;
  96   JavaCalls::call_static(&result, ik, serializeSavedProperties, vmSymbols::serializePropertiesToByteArray_signature(), &args, THREAD);
  97   if (HAS_PENDING_EXCEPTION) {
  98     JVMCIRuntime::exit_on_pending_exception(NULL, "Error calling jdk.vm.ci.services.Services.serializeSavedProperties");
  99   }
 100   oop res = (oop) result.get_jobject();
 101   assert(res->is_typeArray(), "must be");
 102   assert(TypeArrayKlass::cast(res->klass())->element_type() == T_BYTE, "must be");
 103   typeArrayOop ba = typeArrayOop(res);
 104   int serialized_properties_len = ba->length();
 105 
 106   // Copy serialized saved properties from HotSpot object into native buffer
 107   jbyte* serialized_properties = NEW_RESOURCE_ARRAY(jbyte, serialized_properties_len);
 108   memcpy(serialized_properties, ba->byte_at_addr(0), serialized_properties_len);
 109 
 110   // Copy native buffer into shared library object
 111   JVMCIPrimitiveArray buf = new_byteArray(serialized_properties_len, this);
 112   if (has_pending_exception()) {
 113     describe_pending_exception(true);
 114     fatal("Error in copy_saved_properties");
 115   }
 116   copy_bytes_from(serialized_properties, buf, 0, serialized_properties_len);
 117   if (has_pending_exception()) {
 118     describe_pending_exception(true);
 119     fatal("Error in copy_saved_properties");
 120   }
 121 
 122   // Initialize saved properties in shared library
 123   jclass servicesClass = JNIJVMCI::Services::clazz();
 124   jmethodID initializeSavedProperties = JNIJVMCI::Services::initializeSavedProperties_method();
 125   JNIAccessMark jni(this);
 126   jni()->CallStaticVoidMethod(servicesClass, initializeSavedProperties, buf.as_jobject());
 127   if (jni()->ExceptionCheck()) {
 128     jni()->ExceptionDescribe();
 129     fatal("Error calling jdk.vm.ci.services.Services.initializeSavedProperties");
 130   }
 131 }
 132 
 133 JNIEnv* JVMCIEnv::init_shared_library(JavaThread* thread) {
 134   if (_shared_library_javavm == NULL) {
 135     MutexLocker locker(JVMCI_lock);
 136     if (_shared_library_javavm == NULL) {
 137       char path[JVM_MAXPATHLEN];
 138       char ebuf[1024];
 139       if (JVMCILibPath != NULL) {
 140         if (!os::dll_locate_lib(path, sizeof(path), JVMCILibPath, JVMCI_SHARED_LIBRARY_NAME)) {
 141           vm_exit_during_initialization("Unable to create JVMCI shared library path from -XX:JVMCILibPath value", JVMCILibPath);
 142         }
 143       } else {
 144         if (!os::dll_locate_lib(path, sizeof(path), Arguments::get_dll_dir(), JVMCI_SHARED_LIBRARY_NAME)) {
 145           vm_exit_during_initialization("Unable to create path to JVMCI shared library");
 146         }
 147       }
 148 
 149       void* handle = os::dll_load(path, ebuf, sizeof ebuf);
 150       if (handle == NULL) {
 151         vm_exit_during_initialization("Unable to load JVMCI shared library", ebuf);
 152       }
 153       _shared_library_handle = handle;
 154       _shared_library_path = strdup(path);
 155       jint (*JNI_CreateJavaVM)(JavaVM **pvm, void **penv, void *args);
 156       typedef jint (*JNI_CreateJavaVM_t)(JavaVM **pvm, void **penv, void *args);
 157 
 158       JNI_CreateJavaVM = CAST_TO_FN_PTR(JNI_CreateJavaVM_t, os::dll_lookup(handle, "JNI_CreateJavaVM"));
 159       JNIEnv* env;
 160       if (JNI_CreateJavaVM == NULL) {
 161         vm_exit_during_initialization("Unable to find JNI_CreateJavaVM", path);
 162       }
 163 
 164       ResourceMark rm;
 165       JavaVMInitArgs vm_args;
 166       vm_args.version = JNI_VERSION_1_2;
 167       vm_args.ignoreUnrecognized = JNI_TRUE;
 168       vm_args.options = NULL;
 169       vm_args.nOptions = 0;
 170 
 171       JavaVM* the_javavm = NULL;
 172       int result = (*JNI_CreateJavaVM)(&the_javavm, (void**) &env, &vm_args);
 173       if (result == JNI_OK) {
 174         guarantee(env != NULL, "missing env");
 175         _shared_library_javavm = the_javavm;
 176         return env;
 177       } else {
 178         vm_exit_during_initialization(err_msg("JNI_CreateJavaVM failed with return value %d", result), path);
 179       }
 180     }
 181   }
 182   return NULL;
 183 }
 184 
 185 void JVMCIEnv::init_env_mode_runtime(JavaThread* thread, JNIEnv* parent_env) {
 186   assert(thread != NULL, "npe");
 187   // By default there is only one runtime which is the compiler runtime.
 188   _runtime = JVMCI::compiler_runtime();
 189   _env = NULL;
 190   _pop_frame_on_close = false;
 191   _detach_on_close = false;
 192   if (!UseJVMCINativeLibrary) {
 193     // In HotSpot mode, JNI isn't used at all.

 194     _is_hotspot = true;
 195     return;
 196   }
 197 
 198   if (parent_env != NULL) {
 199     // If the parent JNI environment is non-null then figure out whether it
 200     // is a HotSpot or shared library JNIEnv and set the state appropriately.
 201     _is_hotspot = thread->jni_environment() == parent_env;
 202     if (_is_hotspot) {
 203       // Select the Java runtime
 204       _runtime = JVMCI::java_runtime();
 205       return;
 206     }


 207     _env = parent_env;
 208     return;
 209   }
 210 
 211   // Running in JVMCI shared library mode so ensure the shared library
 212   // is loaded and initialized and get a shared library JNIEnv
 213   _is_hotspot = false;
 214   _env = init_shared_library(thread);


 215 
 216   if (_env != NULL) {
 217     // Creating the JVMCI shared library VM also attaches the current thread
 218     _detach_on_close = true;
 219   } else {
 220     _shared_library_javavm->GetEnv((void**)&parent_env, JNI_VERSION_1_2);
 221     if (parent_env != NULL) {
 222       // Even though there's a parent JNI env, there's no guarantee
 223       // it was opened by a JVMCIEnv scope and thus may not have
 224       // pushed a local JNI frame. As such, we use a new JNI local
 225       // frame in this scope to ensure local JNI refs are collected
 226       // in a timely manner after leaving this scope.
 227       _env = parent_env;
 228     } else {
 229       ResourceMark rm; // Thread name is resource allocated
 230       JavaVMAttachArgs attach_args;
 231       attach_args.version = JNI_VERSION_1_2;
 232       attach_args.name = thread->name();
 233       attach_args.group = NULL;
 234       if (_shared_library_javavm->AttachCurrentThread((void**)&_env, &attach_args) != JNI_OK) {
 235         fatal("Error attaching current thread (%s) to JVMCI shared library JNI interface", attach_args.name);
 236       }
 237       _detach_on_close = true;
 238     }
 239   }
 240 
 241   assert(_env != NULL, "missing env");
 242   assert(_throw_to_caller == false, "must be");
 243 
 244   JNIAccessMark jni(this);
 245   jint result = _env->PushLocalFrame(32);
 246   if (result != JNI_OK) {
 247     char message[256];
 248     jio_snprintf(message, 256, "Uncaught exception pushing local frame for JVMCIEnv scope entered at %s:%d", _file, _line);
 249     JVMCIRuntime::exit_on_pending_exception(this, message);
 250   }
 251   _pop_frame_on_close = true;
 252 }
 253 
 254 JVMCIEnv::JVMCIEnv(JavaThread* thread, JVMCICompileState* compile_state, const char* file, int line):
 255     _throw_to_caller(false), _file(file), _line(line), _compile_state(compile_state) {
 256   init_env_mode_runtime(thread, NULL);
 257 }
 258 
 259 JVMCIEnv::JVMCIEnv(JavaThread* thread, const char* file, int line):
 260     _throw_to_caller(false), _file(file), _line(line), _compile_state(NULL) {
 261   init_env_mode_runtime(thread, NULL);
 262 }
 263 
 264 JVMCIEnv::JVMCIEnv(JavaThread* thread, JNIEnv* parent_env, const char* file, int line):
 265     _throw_to_caller(true), _file(file), _line(line), _compile_state(NULL) {
 266   init_env_mode_runtime(thread, parent_env);
 267   assert(_env == NULL || parent_env == _env, "mismatched JNIEnvironment");
 268 }
 269 
 270 void JVMCIEnv::init(JavaThread* thread, bool is_hotspot, const char* file, int line) {
 271   _compile_state = NULL;
 272   _throw_to_caller = false;
 273   _file = file;
 274   _line = line;
 275   if (is_hotspot) {
 276     _env = NULL;
 277     _pop_frame_on_close = false;
 278     _detach_on_close = false;
 279     _is_hotspot = true;
 280     _runtime = JVMCI::java_runtime();
 281   } else {
 282     init_env_mode_runtime(thread, NULL);
 283   }
 284 }
 285 
 286 // Prints a pending exception (if any) and its stack trace.
 287 void JVMCIEnv::describe_pending_exception(bool clear) {

 288   if (!is_hotspot()) {
 289     JNIAccessMark jni(this);
 290     if (jni()->ExceptionCheck()) {
 291       jthrowable ex = !clear ? jni()->ExceptionOccurred() : NULL;
 292       jni()->ExceptionDescribe();
 293       if (ex != NULL) {
 294         jni()->Throw(ex);
 295       }
 296     }
 297   } else {
 298     Thread* THREAD = Thread::current();
 299     if (HAS_PENDING_EXCEPTION) {
 300       JVMCIRuntime::describe_pending_hotspot_exception((JavaThread*) THREAD, clear);
 301     }
 302   }
 303 }
 304 
 305 void JVMCIEnv::translate_hotspot_exception_to_jni_exception(JavaThread* THREAD, const Handle& throwable) {
 306   assert(!is_hotspot(), "must_be");
 307   // Resolve HotSpotJVMCIRuntime class explicitly as HotSpotJVMCI::compute_offsets
 308   // may not have been called.
 309   Klass* runtimeKlass = SystemDictionary::resolve_or_fail(vmSymbols::jdk_vm_ci_hotspot_HotSpotJVMCIRuntime(), true, CHECK);
 310   JavaCallArguments jargs;
 311   jargs.push_oop(throwable);
 312   JavaValue result(T_OBJECT);
 313   JavaCalls::call_static(&result,
 314                           runtimeKlass,
 315                           vmSymbols::encodeThrowable_name(),
 316                           vmSymbols::encodeThrowable_signature(), &jargs, THREAD);
 317   if (HAS_PENDING_EXCEPTION) {
 318     JVMCIRuntime::exit_on_pending_exception(this, "HotSpotJVMCIRuntime.encodeThrowable should not throw an exception");
 319   }
 320 
 321   oop encoded_throwable_string = (oop) result.get_jobject();
 322 
 323   ResourceMark rm;
 324   const char* encoded_throwable_chars = java_lang_String::as_utf8_string(encoded_throwable_string);
 325 
 326   JNIAccessMark jni(this);
 327   jobject jni_encoded_throwable_string = jni()->NewStringUTF(encoded_throwable_chars);
 328   jthrowable jni_throwable = (jthrowable) jni()->CallStaticObjectMethod(JNIJVMCI::HotSpotJVMCIRuntime::clazz(),
 329                                 JNIJVMCI::HotSpotJVMCIRuntime::decodeThrowable_method(),
 330                                 jni_encoded_throwable_string);
 331   jni()->Throw(jni_throwable);
 332 }
 333 
 334 JVMCIEnv::~JVMCIEnv() {
 335   if (_throw_to_caller) {
 336     if (is_hotspot()) {
 337       // Nothing to do
 338     } else {
 339       if (Thread::current()->is_Java_thread()) {
 340         JavaThread* THREAD = JavaThread::current();
 341         if (HAS_PENDING_EXCEPTION) {
 342           Handle throwable = Handle(THREAD, PENDING_EXCEPTION);
 343           CLEAR_PENDING_EXCEPTION;
 344           translate_hotspot_exception_to_jni_exception(THREAD, throwable);
 345         }
 346       }
 347     }
 348   } else {
 349     if (_pop_frame_on_close) {
 350       // Pop the JNI local frame that was pushed when entering this JVMCIEnv scope.
 351       JNIAccessMark jni(this);
 352       jni()->PopLocalFrame(NULL);
 353     }
 354 
 355     if (has_pending_exception()) {
 356       char message[256];
 357       jio_snprintf(message, 256, "Uncaught exception exiting JVMCIEnv scope entered at %s:%d", _file, _line);
 358       JVMCIRuntime::exit_on_pending_exception(this, message);
 359     }
 360 
 361     if (_detach_on_close) {
 362       get_shared_library_javavm()->DetachCurrentThread();
 363     }
 364   }
 365 }
 366 
 367 jboolean JVMCIEnv::has_pending_exception() {
 368   if (is_hotspot()) {
 369     Thread* THREAD = Thread::current();
 370     return HAS_PENDING_EXCEPTION;
 371   } else {
 372     JNIAccessMark jni(this);
 373     return jni()->ExceptionCheck();
 374   }
 375 }
 376 
 377 void JVMCIEnv::clear_pending_exception() {
 378   if (is_hotspot()) {
 379     Thread* THREAD = Thread::current();
 380     CLEAR_PENDING_EXCEPTION;
 381   } else {
 382     JNIAccessMark jni(this);
 383     jni()->ExceptionClear();
 384   }
 385 }
 386 
 387 int JVMCIEnv::get_length(JVMCIArray array) {
 388   if (is_hotspot()) {
 389     return HotSpotJVMCI::resolve(array)->length();
 390   } else {
 391     JNIAccessMark jni(this);
 392     return jni()->GetArrayLength(get_jarray(array));
 393   }
 394 }
 395 
 396 JVMCIObject JVMCIEnv::get_object_at(JVMCIObjectArray array, int index) {
 397   if (is_hotspot()) {
 398     oop result = HotSpotJVMCI::resolve(array)->obj_at(index);
 399     return wrap(result);
 400   } else {
 401     JNIAccessMark jni(this);
 402     jobject result = jni()->GetObjectArrayElement(get_jobjectArray(array), index);
 403     return wrap(result);
 404   }
 405 }
 406 
 407 void JVMCIEnv::put_object_at(JVMCIObjectArray array, int index, JVMCIObject value) {
 408   if (is_hotspot()) {
 409     HotSpotJVMCI::resolve(array)->obj_at_put(index, HotSpotJVMCI::resolve(value));
 410   } else {
 411     JNIAccessMark jni(this);
 412     jni()->SetObjectArrayElement(get_jobjectArray(array), index, get_jobject(value));
 413   }
 414 }
 415 
 416 jboolean JVMCIEnv::get_bool_at(JVMCIPrimitiveArray array, int index) {
 417   if (is_hotspot()) {
 418     return HotSpotJVMCI::resolve(array)->bool_at(index);
 419   } else {
 420     JNIAccessMark jni(this);
 421     jboolean result;
 422     jni()->GetBooleanArrayRegion(array.as_jbooleanArray(), index, 1, &result);
 423     return result;
 424   }
 425 }
 426 void JVMCIEnv::put_bool_at(JVMCIPrimitiveArray array, int index, jboolean value) {
 427   if (is_hotspot()) {
 428     HotSpotJVMCI::resolve(array)->bool_at_put(index, value);
 429   } else {
 430     JNIAccessMark jni(this);
 431     jni()->SetBooleanArrayRegion(array.as_jbooleanArray(), index, 1, &value);
 432   }
 433 }
 434 
 435 jbyte JVMCIEnv::get_byte_at(JVMCIPrimitiveArray array, int index) {
 436   if (is_hotspot()) {
 437     return HotSpotJVMCI::resolve(array)->byte_at(index);
 438   } else {
 439     JNIAccessMark jni(this);
 440     jbyte result;
 441     jni()->GetByteArrayRegion(array.as_jbyteArray(), index, 1, &result);
 442     return result;
 443   }
 444 }
 445 void JVMCIEnv::put_byte_at(JVMCIPrimitiveArray array, int index, jbyte value) {
 446   if (is_hotspot()) {
 447     HotSpotJVMCI::resolve(array)->byte_at_put(index, value);
 448   } else {
 449     JNIAccessMark jni(this);
 450     jni()->SetByteArrayRegion(array.as_jbyteArray(), index, 1, &value);
 451   }
 452 }
 453 
 454 jint JVMCIEnv::get_int_at(JVMCIPrimitiveArray array, int index) {
 455   if (is_hotspot()) {
 456     return HotSpotJVMCI::resolve(array)->int_at(index);
 457   } else {
 458     JNIAccessMark jni(this);
 459     jint result;
 460     jni()->GetIntArrayRegion(array.as_jintArray(), index, 1, &result);
 461     return result;
 462   }
 463 }
 464 void JVMCIEnv::put_int_at(JVMCIPrimitiveArray array, int index, jint value) {
 465   if (is_hotspot()) {
 466     HotSpotJVMCI::resolve(array)->int_at_put(index, value);
 467   } else {
 468     JNIAccessMark jni(this);
 469     jni()->SetIntArrayRegion(array.as_jintArray(), index, 1, &value);
 470   }
 471 }
 472 
 473 long JVMCIEnv::get_long_at(JVMCIPrimitiveArray array, int index) {
 474   if (is_hotspot()) {
 475     return HotSpotJVMCI::resolve(array)->long_at(index);
 476   } else {
 477     JNIAccessMark jni(this);
 478     jlong result;
 479     jni()->GetLongArrayRegion(array.as_jlongArray(), index, 1, &result);
 480     return result;
 481   }
 482 }
 483 void JVMCIEnv::put_long_at(JVMCIPrimitiveArray array, int index, jlong value) {
 484   if (is_hotspot()) {
 485     HotSpotJVMCI::resolve(array)->long_at_put(index, value);
 486   } else {
 487     JNIAccessMark jni(this);
 488     jni()->SetLongArrayRegion(array.as_jlongArray(), index, 1, &value);
 489   }
 490 }
 491 
 492 void JVMCIEnv::copy_bytes_to(JVMCIPrimitiveArray src, jbyte* dest, int offset, jsize length) {
 493   if (length == 0) {
 494     return;
 495   }
 496   if (is_hotspot()) {
 497     memcpy(dest, HotSpotJVMCI::resolve(src)->byte_at_addr(offset), length);
 498   } else {
 499     JNIAccessMark jni(this);
 500     jni()->GetByteArrayRegion(src.as_jbyteArray(), offset, length, dest);
 501   }
 502 }
 503 void JVMCIEnv::copy_bytes_from(jbyte* src, JVMCIPrimitiveArray dest, int offset, jsize length) {
 504   if (length == 0) {
 505     return;
 506   }
 507   if (is_hotspot()) {
 508     memcpy(HotSpotJVMCI::resolve(dest)->byte_at_addr(offset), src, length);
 509   } else {
 510     JNIAccessMark jni(this);
 511     jni()->SetByteArrayRegion(dest.as_jbyteArray(), offset, length, src);
 512   }
 513 }
 514 
 515 void JVMCIEnv::copy_longs_from(jlong* src, JVMCIPrimitiveArray dest, int offset, jsize length) {
 516   if (length == 0) {
 517     return;
 518   }
 519   if (is_hotspot()) {
 520     memcpy(HotSpotJVMCI::resolve(dest)->long_at_addr(offset), src, length * sizeof(jlong));
 521   } else {
 522     JNIAccessMark jni(this);
 523     jni()->SetLongArrayRegion(dest.as_jlongArray(), offset, length, src);
 524   }
 525 }
 526 
 527 jboolean JVMCIEnv::is_boxing_object(BasicType type, JVMCIObject object) {
 528   if (is_hotspot()) {
 529     return java_lang_boxing_object::is_instance(HotSpotJVMCI::resolve(object), type);
 530   } else {
 531     JNIAccessMark jni(this);
 532     return jni()->IsInstanceOf(get_jobject(object), JNIJVMCI::box_class(type));
 533   }
 534 }
 535 
 536 // Get the primitive value from a Java boxing object.  It's hard error to
 537 // pass a non-primitive BasicType.
 538 jvalue JVMCIEnv::get_boxed_value(BasicType type, JVMCIObject object) {
 539   jvalue result;
 540   if (is_hotspot()) {
 541     if (java_lang_boxing_object::get_value(HotSpotJVMCI::resolve(object), &result) == T_ILLEGAL) {
 542       ShouldNotReachHere();
 543     }
 544   } else {
 545     JNIAccessMark jni(this);
 546     jfieldID field = JNIJVMCI::box_field(type);
 547     switch (type) {
 548       case T_BOOLEAN: result.z = jni()->GetBooleanField(get_jobject(object), field); break;
 549       case T_BYTE:    result.b = jni()->GetByteField(get_jobject(object), field); break;
 550       case T_SHORT:   result.s = jni()->GetShortField(get_jobject(object), field); break;
 551       case T_CHAR:    result.c = jni()->GetCharField(get_jobject(object), field); break;
 552       case T_INT:     result.i = jni()->GetIntField(get_jobject(object), field); break;
 553       case T_LONG:    result.j = jni()->GetLongField(get_jobject(object), field); break;
 554       case T_FLOAT:   result.f = jni()->GetFloatField(get_jobject(object), field); break;
 555       case T_DOUBLE:  result.d = jni()->GetDoubleField(get_jobject(object), field); break;
 556       default:
 557         ShouldNotReachHere();
 558     }
 559   }
 560   return result;
 561 }
 562 
 563 // Return the BasicType of the object if it's a boxing object, otherwise return T_ILLEGAL.
 564 BasicType JVMCIEnv::get_box_type(JVMCIObject object) {
 565   if (is_hotspot()) {
 566     return java_lang_boxing_object::basic_type(HotSpotJVMCI::resolve(object));
 567   } else {
 568     JNIAccessMark jni(this);
 569     jclass clazz = jni()->GetObjectClass(get_jobject(object));
 570     if (jni()->IsSameObject(clazz, JNIJVMCI::box_class(T_BOOLEAN))) return T_BOOLEAN;
 571     if (jni()->IsSameObject(clazz, JNIJVMCI::box_class(T_BYTE))) return T_BYTE;
 572     if (jni()->IsSameObject(clazz, JNIJVMCI::box_class(T_SHORT))) return T_SHORT;
 573     if (jni()->IsSameObject(clazz, JNIJVMCI::box_class(T_CHAR))) return T_CHAR;
 574     if (jni()->IsSameObject(clazz, JNIJVMCI::box_class(T_INT))) return T_INT;
 575     if (jni()->IsSameObject(clazz, JNIJVMCI::box_class(T_LONG))) return T_LONG;
 576     if (jni()->IsSameObject(clazz, JNIJVMCI::box_class(T_FLOAT))) return T_FLOAT;
 577     if (jni()->IsSameObject(clazz, JNIJVMCI::box_class(T_DOUBLE))) return T_DOUBLE;
 578     return T_ILLEGAL;
 579   }
 580 }
 581 
 582 // Create a boxing object of the appropriate primitive type.
 583 JVMCIObject JVMCIEnv::create_box(BasicType type, jvalue* value, JVMCI_TRAPS) {
 584   switch (type) {
 585     case T_BOOLEAN:
 586     case T_BYTE:
 587     case T_CHAR:
 588     case T_SHORT:
 589     case T_INT:
 590     case T_LONG:
 591     case T_FLOAT:
 592     case T_DOUBLE:
 593       break;
 594     default:
 595       JVMCI_THROW_MSG_(IllegalArgumentException, "Only boxes for primitive values can be created", JVMCIObject());
 596   }
 597   if (is_hotspot()) {
 598     JavaThread* THREAD = JavaThread::current();

 599     oop box = java_lang_boxing_object::create(type, value, CHECK_(JVMCIObject()));
 600     return HotSpotJVMCI::wrap(box);
 601   } else {
 602     JNIAccessMark jni(this);
 603     jobject box = jni()->NewObjectA(JNIJVMCI::box_class(type), JNIJVMCI::box_constructor(type), value);
 604     assert(box != NULL, "");
 605     return wrap(box);
 606   }
 607 }
 608 
 609 const char* JVMCIEnv::as_utf8_string(JVMCIObject str) {
 610   if (is_hotspot()) {
 611     return java_lang_String::as_utf8_string(HotSpotJVMCI::resolve(str));
 612   } else {
 613     JNIAccessMark jni(this);
 614     int length = jni()->GetStringLength(str.as_jstring());
 615     char* result = NEW_RESOURCE_ARRAY(char, length + 1);
 616     jni()->GetStringUTFRegion(str.as_jstring(), 0, length, result);
 617     return result;
 618   }
 619 }
 620 
 621 char* JVMCIEnv::as_utf8_string(JVMCIObject str, char* buf, int buflen) {
 622   if (is_hotspot()) {
 623     return java_lang_String::as_utf8_string(HotSpotJVMCI::resolve(str), buf, buflen);
 624   } else {
 625     JNIAccessMark jni(this);
 626     int length = jni()->GetStringLength(str.as_jstring());
 627     if (length >= buflen) {
 628       length = buflen;
 629     }
 630     jni()->GetStringUTFRegion(str.as_jstring(), 0, length, buf);
 631     return buf;
 632   }
 633 }
 634 
 635 #define DO_THROW(name)                             \
 636 void JVMCIEnv::throw_##name(const char* msg) {     \
 637   if (is_hotspot()) {                              \
 638     JavaThread* THREAD = JavaThread::current();    \
 639     THROW_MSG(HotSpotJVMCI::name::symbol(), msg);  \
 640   } else {                                         \
 641     JNIAccessMark jni(this);                       \
 642     jni()->ThrowNew(JNIJVMCI::name::clazz(), msg); \
 643   }                                                \
 644 }
 645 
 646 DO_THROW(InternalError)
 647 DO_THROW(ArrayIndexOutOfBoundsException)
 648 DO_THROW(IllegalStateException)
 649 DO_THROW(NullPointerException)
 650 DO_THROW(IllegalArgumentException)
 651 DO_THROW(InvalidInstalledCodeException)
 652 DO_THROW(UnsatisfiedLinkError)
 653 DO_THROW(UnsupportedOperationException)
 654 DO_THROW(ClassNotFoundException)
 655 
 656 #undef DO_THROW
 657 
 658 void JVMCIEnv::fthrow_error(const char* file, int line, const char* format, ...) {
 659   const int max_msg_size = 1024;
 660   va_list ap;
 661   va_start(ap, format);
 662   char msg[max_msg_size];
 663   vsnprintf(msg, max_msg_size, format, ap);
 664   msg[max_msg_size-1] = '\0';
 665   va_end(ap);
 666   if (is_hotspot()) {
 667     JavaThread* THREAD = JavaThread::current();

 668     Handle h_loader = Handle();
 669     Handle h_protection_domain = Handle();
 670     Exceptions::_throw_msg(THREAD, file, line, vmSymbols::jdk_vm_ci_common_JVMCIError(), msg, h_loader, h_protection_domain);
 671   } else {
 672     JNIAccessMark jni(this);
 673     jni()->ThrowNew(JNIJVMCI::JVMCIError::clazz(), msg);
 674   }
 675 }
 676 
 677 JVMCIObject JVMCIEnv::call_HotSpotJVMCIRuntime_compileMethod (JVMCIObject runtime, JVMCIObject method, int entry_bci,
 678                                                               jlong compile_state, int id) {
 679   if (is_hotspot()) {
 680     Thread* THREAD = Thread::current();
 681     JavaCallArguments jargs;
 682     jargs.push_oop(Handle(THREAD, HotSpotJVMCI::resolve(runtime)));
 683     jargs.push_oop(Handle(THREAD, HotSpotJVMCI::resolve(method)));
 684     jargs.push_int(entry_bci);
 685     jargs.push_long(compile_state);
 686     jargs.push_int(id);
 687     JavaValue result(T_OBJECT);
 688     JavaCalls::call_special(&result,
 689                             HotSpotJVMCI::HotSpotJVMCIRuntime::klass(),
 690                             vmSymbols::compileMethod_name(),
 691                             vmSymbols::compileMethod_signature(), &jargs, CHECK_(JVMCIObject()));
 692     return wrap((oop) result.get_jobject());
 693   } else {
 694     JNIAccessMark jni(this);
 695     jobject result = jni()->CallNonvirtualObjectMethod(runtime.as_jobject(),
 696                                                      JNIJVMCI::HotSpotJVMCIRuntime::clazz(),
 697                                                      JNIJVMCI::HotSpotJVMCIRuntime::compileMethod_method(),
 698                                                      method.as_jobject(), entry_bci, compile_state, id);
 699     if (jni()->ExceptionCheck()) {
 700       return JVMCIObject();
 701     }
 702     return wrap(result);
 703   }
 704 }
 705 
 706 void JVMCIEnv::call_HotSpotJVMCIRuntime_bootstrapFinished (JVMCIObject runtime, JVMCIEnv* JVMCIENV) {
 707   if (is_hotspot()) {
 708     Thread* THREAD = Thread::current();
 709     JavaCallArguments jargs;
 710     jargs.push_oop(Handle(THREAD, HotSpotJVMCI::resolve(runtime)));
 711     JavaValue result(T_VOID);
 712     JavaCalls::call_special(&result, HotSpotJVMCI::HotSpotJVMCIRuntime::klass(), vmSymbols::bootstrapFinished_name(), vmSymbols::void_method_signature(), &jargs, CHECK);
 713   } else {
 714     JNIAccessMark jni(this);
 715     jni()->CallNonvirtualVoidMethod(runtime.as_jobject(), JNIJVMCI::HotSpotJVMCIRuntime::clazz(), JNIJVMCI::HotSpotJVMCIRuntime::bootstrapFinished_method());
 716 
 717   }
 718 }
 719 
 720 void JVMCIEnv::call_HotSpotJVMCIRuntime_shutdown (JVMCIObject runtime) {
 721   HandleMark hm;
 722   JavaThread* THREAD = JavaThread::current();
 723   if (is_hotspot()) {
 724     JavaCallArguments jargs;
 725     jargs.push_oop(Handle(THREAD, HotSpotJVMCI::resolve(runtime)));
 726     JavaValue result(T_VOID);
 727     JavaCalls::call_special(&result, HotSpotJVMCI::HotSpotJVMCIRuntime::klass(), vmSymbols::shutdown_name(), vmSymbols::void_method_signature(), &jargs, THREAD);
 728   } else {
 729     JNIAccessMark jni(this);
 730     jni()->CallNonvirtualVoidMethod(runtime.as_jobject(), JNIJVMCI::HotSpotJVMCIRuntime::clazz(), JNIJVMCI::HotSpotJVMCIRuntime::shutdown_method());
 731   }
 732   if (has_pending_exception()) {
 733     // This should never happen as HotSpotJVMCIRuntime.shutdown() should
 734     // handle all exceptions.
 735     describe_pending_exception(true);
 736   }
 737 }
 738 
 739 JVMCIObject JVMCIEnv::call_HotSpotJVMCIRuntime_runtime (JVMCIEnv* JVMCIENV) {
 740   JavaThread* THREAD = JavaThread::current();
 741   if (is_hotspot()) {
 742     JavaCallArguments jargs;
 743     JavaValue result(T_OBJECT);
 744     JavaCalls::call_static(&result, HotSpotJVMCI::HotSpotJVMCIRuntime::klass(), vmSymbols::runtime_name(), vmSymbols::runtime_signature(), &jargs, CHECK_(JVMCIObject()));
 745     return wrap((oop) result.get_jobject());
 746   } else {
 747     JNIAccessMark jni(this);
 748     jobject result = jni()->CallStaticObjectMethod(JNIJVMCI::HotSpotJVMCIRuntime::clazz(), JNIJVMCI::HotSpotJVMCIRuntime::runtime_method());
 749     if (jni()->ExceptionCheck()) {
 750       return JVMCIObject();
 751     }
 752     return wrap(result);
 753   }
 754 }
 755 
 756 JVMCIObject JVMCIEnv::call_JVMCI_getRuntime (JVMCIEnv* JVMCIENV) {
 757   JavaThread* THREAD = JavaThread::current();
 758   if (is_hotspot()) {
 759     JavaCallArguments jargs;
 760     JavaValue result(T_OBJECT);
 761     JavaCalls::call_static(&result, HotSpotJVMCI::JVMCI::klass(), vmSymbols::getRuntime_name(), vmSymbols::getRuntime_signature(), &jargs, CHECK_(JVMCIObject()));
 762     return wrap((oop) result.get_jobject());
 763   } else {
 764     JNIAccessMark jni(this);
 765     jobject result = jni()->CallStaticObjectMethod(JNIJVMCI::JVMCI::clazz(), JNIJVMCI::JVMCI::getRuntime_method());
 766     if (jni()->ExceptionCheck()) {
 767       return JVMCIObject();
 768     }
 769     return wrap(result);
 770   }
 771 }
 772 
 773 JVMCIObject JVMCIEnv::call_HotSpotJVMCIRuntime_getCompiler (JVMCIObject runtime, JVMCIEnv* JVMCIENV) {
 774   JavaThread* THREAD = JavaThread::current();
 775   if (is_hotspot()) {
 776     JavaCallArguments jargs;
 777     jargs.push_oop(Handle(THREAD, HotSpotJVMCI::resolve(runtime)));
 778     JavaValue result(T_OBJECT);
 779     JavaCalls::call_virtual(&result, HotSpotJVMCI::HotSpotJVMCIRuntime::klass(), vmSymbols::getCompiler_name(), vmSymbols::getCompiler_signature(), &jargs, CHECK_(JVMCIObject()));
 780     return wrap((oop) result.get_jobject());
 781   } else {
 782     JNIAccessMark jni(this);
 783     jobject result = jni()->CallObjectMethod(runtime.as_jobject(), JNIJVMCI::HotSpotJVMCIRuntime::getCompiler_method());
 784     if (jni()->ExceptionCheck()) {
 785       return JVMCIObject();
 786     }
 787     return wrap(result);
 788   }
 789 }
 790 
 791 
 792 JVMCIObject JVMCIEnv::call_HotSpotJVMCIRuntime_callToString(JVMCIObject object, JVMCIEnv* JVMCIENV) {
 793   JavaThread* THREAD = JavaThread::current();
 794   if (is_hotspot()) {
 795     JavaCallArguments jargs;
 796     jargs.push_oop(Handle(THREAD, HotSpotJVMCI::resolve(object)));
 797     JavaValue result(T_OBJECT);
 798     JavaCalls::call_static(&result,
 799                            HotSpotJVMCI::HotSpotJVMCIRuntime::klass(),
 800                            vmSymbols::callToString_name(),
 801                            vmSymbols::callToString_signature(), &jargs, CHECK_(JVMCIObject()));
 802     return wrap((oop) result.get_jobject());
 803   } else {
 804     JNIAccessMark jni(this);
 805     jobject result = (jstring) jni()->CallStaticObjectMethod(JNIJVMCI::HotSpotJVMCIRuntime::clazz(),
 806                                                      JNIJVMCI::HotSpotJVMCIRuntime::callToString_method(),
 807                                                      object.as_jobject());
 808     if (jni()->ExceptionCheck()) {
 809       return JVMCIObject();
 810     }
 811     return wrap(result);
 812   }
 813 }
 814 
 815 
 816 JVMCIObject JVMCIEnv::call_PrimitiveConstant_forTypeChar(jchar kind, jlong value, JVMCI_TRAPS) {
 817   JavaThread* THREAD = JavaThread::current();
 818   if (is_hotspot()) {
 819     JavaCallArguments jargs;
 820     jargs.push_int(kind);
 821     jargs.push_long(value);
 822     JavaValue result(T_OBJECT);
 823     JavaCalls::call_static(&result,
 824                            HotSpotJVMCI::PrimitiveConstant::klass(),
 825                            vmSymbols::forTypeChar_name(),
 826                            vmSymbols::forTypeChar_signature(), &jargs, CHECK_(JVMCIObject()));
 827     return wrap((oop) result.get_jobject());
 828   } else {
 829     JNIAccessMark jni(this);
 830     jobject result = (jstring) jni()->CallStaticObjectMethod(JNIJVMCI::PrimitiveConstant::clazz(),
 831                                                      JNIJVMCI::PrimitiveConstant::forTypeChar_method(),
 832                                                      kind, value);
 833     if (jni()->ExceptionCheck()) {
 834       return JVMCIObject();
 835     }
 836     return wrap(result);
 837   }
 838 }
 839 
 840 JVMCIObject JVMCIEnv::call_JavaConstant_forFloat(float value, JVMCI_TRAPS) {
 841   JavaThread* THREAD = JavaThread::current();
 842   if (is_hotspot()) {
 843     JavaCallArguments jargs;
 844     jargs.push_float(value);
 845     JavaValue result(T_OBJECT);
 846     JavaCalls::call_static(&result,
 847                            HotSpotJVMCI::JavaConstant::klass(),
 848                            vmSymbols::forFloat_name(),
 849                            vmSymbols::forFloat_signature(), &jargs, CHECK_(JVMCIObject()));
 850     return wrap((oop) result.get_jobject());
 851   } else {
 852     JNIAccessMark jni(this);
 853     jobject result = (jstring) jni()->CallStaticObjectMethod(JNIJVMCI::JavaConstant::clazz(),
 854                                                      JNIJVMCI::JavaConstant::forFloat_method(),
 855                                                      value);
 856     if (jni()->ExceptionCheck()) {
 857       return JVMCIObject();
 858     }
 859     return wrap(result);
 860   }
 861 }
 862 
 863 JVMCIObject JVMCIEnv::call_JavaConstant_forDouble(double value, JVMCI_TRAPS) {
 864   JavaThread* THREAD = JavaThread::current();
 865   if (is_hotspot()) {
 866     JavaCallArguments jargs;
 867     jargs.push_double(value);
 868     JavaValue result(T_OBJECT);
 869     JavaCalls::call_static(&result,
 870                            HotSpotJVMCI::JavaConstant::klass(),
 871                            vmSymbols::forDouble_name(),
 872                            vmSymbols::forDouble_signature(), &jargs, CHECK_(JVMCIObject()));
 873     return wrap((oop) result.get_jobject());
 874   } else {
 875     JNIAccessMark jni(this);
 876     jobject result = (jstring) jni()->CallStaticObjectMethod(JNIJVMCI::JavaConstant::clazz(),
 877                                                      JNIJVMCI::JavaConstant::forDouble_method(),
 878                                                      value);
 879     if (jni()->ExceptionCheck()) {
 880       return JVMCIObject();
 881     }
 882     return wrap(result);
 883   }
 884 }
 885 
 886 JVMCIObject JVMCIEnv::get_jvmci_primitive_type(BasicType type) {
 887   JVMCIObjectArray primitives = get_HotSpotResolvedPrimitiveType_primitives();
 888   JVMCIObject result = get_object_at(primitives, type);
 889   return result;
 890 }
 891 
 892 JVMCIObject JVMCIEnv::new_StackTraceElement(const methodHandle& method, int bci, JVMCI_TRAPS) {
 893   JavaThread* THREAD = JavaThread::current();
 894   Symbol* file_name_sym;
 895   int line_number;
 896   java_lang_StackTraceElement::decode(method, bci, file_name_sym, line_number, CHECK_(JVMCIObject()));
 897 
 898   Symbol* method_name_sym = method->name();
 899   InstanceKlass* holder = method->method_holder();
 900   const char* declaring_class_str = holder->external_name();
 901 
 902   if (is_hotspot()) {
 903     HotSpotJVMCI::StackTraceElement::klass()->initialize(CHECK_(JVMCIObject()));
 904     oop objOop = HotSpotJVMCI::StackTraceElement::klass()->allocate_instance(CHECK_(JVMCIObject()));
 905     Handle obj = Handle(THREAD, objOop);
 906 
 907     oop declaring_class = StringTable::intern((char*) declaring_class_str, CHECK_(JVMCIObject()));
 908     HotSpotJVMCI::StackTraceElement::set_declaringClass(this, obj(), declaring_class);
 909 
 910     oop method_name = StringTable::intern(method_name_sym, CHECK_(JVMCIObject()));
 911     HotSpotJVMCI::StackTraceElement::set_methodName(this, obj(), method_name);
 912 
 913     if (file_name_sym != NULL) {
 914       oop file_name = StringTable::intern(file_name_sym, CHECK_(JVMCIObject()));
 915       HotSpotJVMCI::StackTraceElement::set_fileName(this, obj(), file_name);
 916     }
 917     HotSpotJVMCI::StackTraceElement::set_lineNumber(this, obj(), line_number);
 918     return wrap(obj());
 919   } else {
 920     JNIAccessMark jni(this);
 921     jobject declaring_class = jni()->NewStringUTF(declaring_class_str);
 922     if (jni()->ExceptionCheck()) {
 923       return JVMCIObject();
 924     }
 925     jobject method_name = jni()->NewStringUTF(method_name_sym->as_C_string());
 926     if (jni()->ExceptionCheck()) {
 927       return JVMCIObject();
 928     }
 929     jobject file_name = NULL;
 930     if (file_name_sym != NULL) {
 931       file_name = jni()->NewStringUTF(file_name_sym->as_C_string());
 932       if (jni()->ExceptionCheck()) {
 933         return JVMCIObject();
 934       }
 935     }
 936 
 937     jobject result = jni()->NewObject(JNIJVMCI::StackTraceElement::clazz(),
 938                                       JNIJVMCI::StackTraceElement::constructor(),
 939                                       declaring_class, method_name, file_name, line_number);
 940     return wrap(result);
 941   }
 942 }
 943 
 944 JVMCIObject JVMCIEnv::new_HotSpotNmethod(const methodHandle& method, const char* name, jboolean isDefault, jlong compileId, JVMCI_TRAPS) {
 945   JavaThread* THREAD = JavaThread::current();
 946 
 947   JVMCIObject methodObject = get_jvmci_method(method(), JVMCI_CHECK_(JVMCIObject()));
 948 
 949   if (is_hotspot()) {
 950     InstanceKlass* ik = InstanceKlass::cast(HotSpotJVMCI::HotSpotNmethod::klass());
 951     if (ik->should_be_initialized()) {
 952       ik->initialize(CHECK_(JVMCIObject()));
 953     }
 954     oop obj = ik->allocate_instance(CHECK_(JVMCIObject()));
 955     Handle obj_h(THREAD, obj);
 956     Handle nameStr = java_lang_String::create_from_str(name, CHECK_(JVMCIObject()));
 957 
 958     // Call constructor
 959     JavaCallArguments jargs;
 960     jargs.push_oop(obj_h);
 961     jargs.push_oop(Handle(THREAD, HotSpotJVMCI::resolve(methodObject)));
 962     jargs.push_oop(nameStr);
 963     jargs.push_int(isDefault);
 964     jargs.push_long(compileId);
 965     JavaValue result(T_VOID);
 966     JavaCalls::call_special(&result, ik,
 967                             vmSymbols::object_initializer_name(),
 968                             vmSymbols::method_string_bool_long_signature(),
 969                             &jargs, CHECK_(JVMCIObject()));
 970     return wrap(obj_h());
 971   } else {
 972     JNIAccessMark jni(this);
 973     jobject nameStr = name == NULL ? NULL : jni()->NewStringUTF(name);
 974     if (jni()->ExceptionCheck()) {
 975       return JVMCIObject();
 976     }
 977 
 978     jobject result = jni()->NewObject(JNIJVMCI::HotSpotNmethod::clazz(),
 979                                       JNIJVMCI::HotSpotNmethod::constructor(),
 980                                       methodObject.as_jobject(), nameStr, isDefault);
 981     return wrap(result);
 982   }
 983 }
 984 
 985 JVMCIObject JVMCIEnv::make_local(JVMCIObject object) {
 986   if (object.is_null()) {
 987     return JVMCIObject();
 988   }
 989   if (is_hotspot()) {
 990     return wrap(JNIHandles::make_local(HotSpotJVMCI::resolve(object)));
 991   } else {
 992     JNIAccessMark jni(this);
 993     return wrap(jni()->NewLocalRef(object.as_jobject()));
 994   }
 995 }
 996 
 997 JVMCIObject JVMCIEnv::make_global(JVMCIObject object) {
 998   if (object.is_null()) {
 999     return JVMCIObject();
1000   }
1001   if (is_hotspot()) {
1002     return wrap(JNIHandles::make_global(Handle(Thread::current(), HotSpotJVMCI::resolve(object))));
1003   } else {
1004     JNIAccessMark jni(this);
1005     return wrap(jni()->NewGlobalRef(object.as_jobject()));
1006   }
1007 }
1008 
1009 JVMCIObject JVMCIEnv::make_weak(JVMCIObject object) {
1010   if (object.is_null()) {
1011     return JVMCIObject();
1012   }
1013   if (is_hotspot()) {
1014     return wrap(JNIHandles::make_weak_global(Handle(Thread::current(), HotSpotJVMCI::resolve(object))));
1015   } else {
1016     JNIAccessMark jni(this);
1017     return wrap(jni()->NewWeakGlobalRef(object.as_jobject()));
1018   }
1019 }
1020 
1021 void JVMCIEnv::destroy_local(JVMCIObject object) {
1022   if (is_hotspot()) {
1023     JNIHandles::destroy_local(object.as_jobject());
1024   } else {
1025     JNIAccessMark jni(this);
1026     jni()->DeleteLocalRef(object.as_jobject());
1027   }
1028 }
1029 
1030 void JVMCIEnv::destroy_global(JVMCIObject object) {
1031   if (is_hotspot()) {
1032     JNIHandles::destroy_global(object.as_jobject());
1033   } else {
1034     JNIAccessMark jni(this);
1035     jni()->DeleteGlobalRef(object.as_jobject());
1036   }
1037 }
1038 
1039 void JVMCIEnv::destroy_weak(JVMCIObject object) {
1040   if (is_hotspot()) {
1041     JNIHandles::destroy_weak_global(object.as_jweak());
1042   } else {
1043     JNIAccessMark jni(this);
1044     jni()->DeleteWeakGlobalRef(object.as_jweak());
1045   }
1046 }
1047 
1048 const char* JVMCIEnv::klass_name(JVMCIObject object) {
1049   if (is_hotspot()) {
1050     return HotSpotJVMCI::resolve(object)->klass()->signature_name();
1051   } else {
1052     JVMCIObject name;
1053     {
1054       JNIAccessMark jni(this);
1055       jclass jcl = jni()->GetObjectClass(object.as_jobject());
1056       jobject result = jni()->CallObjectMethod(jcl, JNIJVMCI::Class_getName_method());
1057       name = JVMCIObject::create(result, is_hotspot());
1058     }
1059     return as_utf8_string(name);
1060   }
1061 }
1062 
1063 JVMCIObject JVMCIEnv::get_jvmci_method(const methodHandle& method, JVMCI_TRAPS) {
1064   JVMCIObject method_object;
1065   if (method() == NULL) {
1066     return method_object;
1067   }
1068 
1069   Thread* THREAD = Thread::current();
1070   jmetadata handle = JVMCI::allocate_handle(method);
1071   jboolean exception = false;
1072   if (is_hotspot()) {
1073     JavaValue result(T_OBJECT);
1074     JavaCallArguments args;
1075     args.push_long((jlong) handle);
1076     JavaCalls::call_static(&result, HotSpotJVMCI::HotSpotResolvedJavaMethodImpl::klass(),
1077                            vmSymbols::fromMetaspace_name(),
1078                            vmSymbols::method_fromMetaspace_signature(), &args, THREAD);
1079     if (HAS_PENDING_EXCEPTION) {
1080       exception = true;
1081     } else {
1082       method_object = wrap((oop)result.get_jobject());
1083     }
1084   } else {
1085     JNIAccessMark jni(this);
1086     method_object = JNIJVMCI::wrap(jni()->CallStaticObjectMethod(JNIJVMCI::HotSpotResolvedJavaMethodImpl::clazz(),
1087                                                                   JNIJVMCI::HotSpotResolvedJavaMethodImpl_fromMetaspace_method(),
1088                                                                   (jlong) handle));
1089     exception = jni()->ExceptionCheck();
1090   }
1091 
1092   if (exception) {
1093     JVMCI::release_handle(handle);
1094     return JVMCIObject();
1095   }
1096 
1097   assert(asMethod(method_object) == method(), "must be");
1098   if (get_HotSpotResolvedJavaMethodImpl_metadataHandle(method_object) != (jlong) handle) {
1099     JVMCI::release_handle(handle);
1100   }
1101   assert(!method_object.is_null(), "must be");
1102   return method_object;
1103 }
1104 
1105 JVMCIObject JVMCIEnv::get_jvmci_type(const JVMCIKlassHandle& klass, JVMCI_TRAPS) {
1106   JVMCIObject type;
1107   if (klass.is_null()) {
1108     return type;
1109   }
1110 
1111   jlong pointer = (jlong) klass();
1112   JavaThread* THREAD = JavaThread::current();
1113   JVMCIObject signature = create_string(klass->signature_name(), JVMCI_CHECK_(JVMCIObject()));
1114   jboolean exception = false;
1115   if (is_hotspot()) {
1116     JavaValue result(T_OBJECT);
1117     JavaCallArguments args;
1118     args.push_long(pointer);
1119     args.push_oop(Handle(THREAD, HotSpotJVMCI::resolve(signature)));
1120     JavaCalls::call_static(&result,
1121                            HotSpotJVMCI::HotSpotResolvedObjectTypeImpl::klass(),
1122                            vmSymbols::fromMetaspace_name(),
1123                            vmSymbols::klass_fromMetaspace_signature(), &args, THREAD);
1124 
1125     if (HAS_PENDING_EXCEPTION) {
1126       exception = true;
1127     } else {
1128       type = wrap((oop)result.get_jobject());
1129     }
1130   } else {
1131     JNIAccessMark jni(this);
1132 
1133     HandleMark hm(THREAD);
1134     type = JNIJVMCI::wrap(jni()->CallStaticObjectMethod(JNIJVMCI::HotSpotResolvedObjectTypeImpl::clazz(),
1135                                                         JNIJVMCI::HotSpotResolvedObjectTypeImpl_fromMetaspace_method(),
1136                                                         pointer, signature.as_jstring()));
1137     exception = jni()->ExceptionCheck();
1138   }
1139   if (exception) {
1140     return JVMCIObject();
1141   }
1142 
1143   assert(type.is_non_null(), "must have result");
1144   return type;
1145 }
1146 
1147 JVMCIObject JVMCIEnv::get_jvmci_constant_pool(const constantPoolHandle& cp, JVMCI_TRAPS) {
1148   JVMCIObject cp_object;
1149   jmetadata handle = JVMCI::allocate_handle(cp);
1150   jboolean exception = false;
1151   if (is_hotspot()) {
1152     JavaThread* THREAD = JavaThread::current();

1153     JavaValue result(T_OBJECT);
1154     JavaCallArguments args;
1155     args.push_long((jlong) handle);
1156     JavaCalls::call_static(&result,
1157                            HotSpotJVMCI::HotSpotConstantPool::klass(),
1158                            vmSymbols::fromMetaspace_name(),
1159                            vmSymbols::constantPool_fromMetaspace_signature(), &args, THREAD);
1160     if (HAS_PENDING_EXCEPTION) {
1161       exception = true;
1162     } else {
1163       cp_object = wrap((oop)result.get_jobject());
1164     }
1165   } else {
1166     JNIAccessMark jni(this);
1167     cp_object = JNIJVMCI::wrap(jni()->CallStaticObjectMethod(JNIJVMCI::HotSpotConstantPool::clazz(),
1168                                                              JNIJVMCI::HotSpotConstantPool_fromMetaspace_method(),
1169                                                              (jlong) handle));
1170     exception = jni()->ExceptionCheck();
1171   }
1172 
1173   if (exception) {
1174     JVMCI::release_handle(handle);
1175     return JVMCIObject();
1176   }
1177 
1178   assert(!cp_object.is_null(), "must be");
1179   // Constant pools aren't cached so this is always a newly created object using the handle
1180   assert(get_HotSpotConstantPool_metadataHandle(cp_object) == (jlong) handle, "must use same handle");
1181   return cp_object;
1182 }
1183 
1184 JVMCIPrimitiveArray JVMCIEnv::new_booleanArray(int length, JVMCI_TRAPS) {
1185   if (is_hotspot()) {
1186     JavaThread* THREAD = JavaThread::current();

1187     typeArrayOop result = oopFactory::new_boolArray(length, CHECK_(JVMCIObject()));
1188     return wrap(result);
1189   } else {
1190     JNIAccessMark jni(this);
1191     jbooleanArray result = jni()->NewBooleanArray(length);
1192     return wrap(result);
1193   }
1194 }
1195 
1196 JVMCIPrimitiveArray JVMCIEnv::new_byteArray(int length, JVMCI_TRAPS) {
1197   if (is_hotspot()) {
1198     JavaThread* THREAD = JavaThread::current();

1199     typeArrayOop result = oopFactory::new_byteArray(length, CHECK_(JVMCIObject()));
1200     return wrap(result);
1201   } else {
1202     JNIAccessMark jni(this);
1203     jbyteArray result = jni()->NewByteArray(length);
1204     return wrap(result);
1205   }
1206 }
1207 
1208 JVMCIObjectArray JVMCIEnv::new_byte_array_array(int length, JVMCI_TRAPS) {
1209   if (is_hotspot()) {
1210     JavaThread* THREAD = JavaThread::current();

1211     Klass* byteArrayArrayKlass = TypeArrayKlass::cast(Universe::byteArrayKlassObj  ())->array_klass(CHECK_(JVMCIObject()));
1212     objArrayOop result = ObjArrayKlass::cast(byteArrayArrayKlass) ->allocate(length, CHECK_(JVMCIObject()));
1213     return wrap(result);
1214   } else {
1215     JNIAccessMark jni(this);
1216     jobjectArray result = jni()->NewObjectArray(length, JNIJVMCI::byte_array(), NULL);
1217     return wrap(result);
1218   }
1219 }
1220 
1221 JVMCIPrimitiveArray JVMCIEnv::new_intArray(int length, JVMCI_TRAPS) {
1222   if (is_hotspot()) {
1223     JavaThread* THREAD = JavaThread::current();

1224     typeArrayOop result = oopFactory::new_intArray(length, CHECK_(JVMCIObject()));
1225     return wrap(result);
1226   } else {
1227     JNIAccessMark jni(this);
1228     jintArray result = jni()->NewIntArray(length);
1229     return wrap(result);
1230   }
1231 }
1232 
1233 JVMCIPrimitiveArray JVMCIEnv::new_longArray(int length, JVMCI_TRAPS) {
1234   if (is_hotspot()) {
1235     JavaThread* THREAD = JavaThread::current();

1236     typeArrayOop result = oopFactory::new_longArray(length, CHECK_(JVMCIObject()));
1237     return wrap(result);
1238   } else {
1239     JNIAccessMark jni(this);
1240     jlongArray result = jni()->NewLongArray(length);
1241     return wrap(result);
1242   }
1243 }
1244 
1245 JVMCIObject JVMCIEnv::new_VMField(JVMCIObject name, JVMCIObject type, jlong offset, jlong address, JVMCIObject value, JVMCI_TRAPS) {
1246   if (is_hotspot()) {
1247     JavaThread* THREAD = JavaThread::current();

1248     HotSpotJVMCI::VMField::klass()->initialize(CHECK_(JVMCIObject()));
1249     oop obj = HotSpotJVMCI::VMField::klass()->allocate_instance(CHECK_(JVMCIObject()));
1250     HotSpotJVMCI::VMField::set_name(this, obj, HotSpotJVMCI::resolve(name));
1251     HotSpotJVMCI::VMField::set_type(this, obj, HotSpotJVMCI::resolve(type));
1252     HotSpotJVMCI::VMField::set_offset(this, obj, offset);
1253     HotSpotJVMCI::VMField::set_address(this, obj, address);
1254     HotSpotJVMCI::VMField::set_value(this, obj, HotSpotJVMCI::resolve(value));
1255     return wrap(obj);
1256   } else {
1257     JNIAccessMark jni(this);
1258     jobject result = jni()->NewObject(JNIJVMCI::VMField::clazz(),
1259                                     JNIJVMCI::VMField::constructor(),
1260                                     get_jobject(name), get_jobject(type), offset, address, get_jobject(value));
1261     return wrap(result);
1262   }
1263 }
1264 
1265 JVMCIObject JVMCIEnv::new_VMFlag(JVMCIObject name, JVMCIObject type, JVMCIObject value, JVMCI_TRAPS) {
1266   if (is_hotspot()) {
1267     JavaThread* THREAD = JavaThread::current();

1268     HotSpotJVMCI::VMFlag::klass()->initialize(CHECK_(JVMCIObject()));
1269     oop obj = HotSpotJVMCI::VMFlag::klass()->allocate_instance(CHECK_(JVMCIObject()));
1270     HotSpotJVMCI::VMFlag::set_name(this, obj, HotSpotJVMCI::resolve(name));
1271     HotSpotJVMCI::VMFlag::set_type(this, obj, HotSpotJVMCI::resolve(type));
1272     HotSpotJVMCI::VMFlag::set_value(this, obj, HotSpotJVMCI::resolve(value));
1273     return wrap(obj);
1274   } else {
1275     JNIAccessMark jni(this);
1276     jobject result = jni()->NewObject(JNIJVMCI::VMFlag::clazz(),
1277                                     JNIJVMCI::VMFlag::constructor(),
1278                                     get_jobject(name), get_jobject(type), get_jobject(value));
1279     return wrap(result);
1280   }
1281 }
1282 
1283 JVMCIObject JVMCIEnv::new_VMIntrinsicMethod(JVMCIObject declaringClass, JVMCIObject name, JVMCIObject descriptor, int id, JVMCI_TRAPS) {
1284   if (is_hotspot()) {
1285     JavaThread* THREAD = JavaThread::current();

1286     HotSpotJVMCI::VMIntrinsicMethod::klass()->initialize(CHECK_(JVMCIObject()));
1287     oop obj = HotSpotJVMCI::VMIntrinsicMethod::klass()->allocate_instance(CHECK_(JVMCIObject()));
1288     HotSpotJVMCI::VMIntrinsicMethod::set_declaringClass(this, obj, HotSpotJVMCI::resolve(declaringClass));
1289     HotSpotJVMCI::VMIntrinsicMethod::set_name(this, obj, HotSpotJVMCI::resolve(name));
1290     HotSpotJVMCI::VMIntrinsicMethod::set_descriptor(this, obj, HotSpotJVMCI::resolve(descriptor));
1291     HotSpotJVMCI::VMIntrinsicMethod::set_id(this, obj, id);
1292     return wrap(obj);
1293   } else {
1294     JNIAccessMark jni(this);
1295     jobject result = jni()->NewObject(JNIJVMCI::VMIntrinsicMethod::clazz(),
1296                                     JNIJVMCI::VMIntrinsicMethod::constructor(),
1297                                     get_jobject(declaringClass), get_jobject(name), get_jobject(descriptor), id);
1298     return wrap(result);
1299   }
1300 }
1301 
1302 JVMCIObject JVMCIEnv::new_HotSpotStackFrameReference(JVMCI_TRAPS) {
1303   if (is_hotspot()) {
1304     JavaThread* THREAD = JavaThread::current();
1305     HotSpotJVMCI::HotSpotStackFrameReference::klass()->initialize(CHECK_(JVMCIObject()));
1306     oop obj = HotSpotJVMCI::HotSpotStackFrameReference::klass()->allocate_instance(CHECK_(JVMCIObject()));
1307     return wrap(obj);
1308   } else {
1309     ShouldNotReachHere();
1310     return JVMCIObject();
1311   }
1312 }
1313 JVMCIObject JVMCIEnv::new_JVMCIError(JVMCI_TRAPS) {
1314   if (is_hotspot()) {
1315     JavaThread* THREAD = JavaThread::current();
1316     HotSpotJVMCI::JVMCIError::klass()->initialize(CHECK_(JVMCIObject()));
1317     oop obj = HotSpotJVMCI::JVMCIError::klass()->allocate_instance(CHECK_(JVMCIObject()));
1318     return wrap(obj);
1319   } else {
1320     ShouldNotReachHere();
1321     return JVMCIObject();
1322   }
1323 }
1324 
1325 
1326 JVMCIObject JVMCIEnv::get_object_constant(oop objOop, bool compressed, bool dont_register) {
1327   JavaThread* THREAD = JavaThread::current();
1328   Handle obj = Handle(THREAD, objOop);
1329   if (obj.is_null()) {
1330     return JVMCIObject();
1331   }
1332   if (is_hotspot()) {
1333     HotSpotJVMCI::DirectHotSpotObjectConstantImpl::klass()->initialize(CHECK_(JVMCIObject()));
1334     oop constant = HotSpotJVMCI::DirectHotSpotObjectConstantImpl::klass()->allocate_instance(CHECK_(JVMCIObject()));
1335     HotSpotJVMCI::DirectHotSpotObjectConstantImpl::set_object(this, constant, obj());
1336     HotSpotJVMCI::HotSpotObjectConstantImpl::set_compressed(this, constant, compressed);
1337     return wrap(constant);
1338   } else {
1339     jlong handle = make_handle(obj);
1340     JNIAccessMark jni(this);
1341     jobject result = jni()->NewObject(JNIJVMCI::IndirectHotSpotObjectConstantImpl::clazz(),
1342                                       JNIJVMCI::IndirectHotSpotObjectConstantImpl::constructor(),
1343                                       handle, compressed, dont_register);
1344     return wrap(result);
1345   }
1346 }
1347 
1348 
1349 Handle JVMCIEnv::asConstant(JVMCIObject constant, JVMCI_TRAPS) {
1350   if (constant.is_null()) {
1351     return Handle();
1352   }
1353   JavaThread* THREAD = JavaThread::current();
1354   if (is_hotspot()) {
1355     assert(HotSpotJVMCI::DirectHotSpotObjectConstantImpl::is_instance(this, constant), "wrong type");
1356     oop obj = HotSpotJVMCI::DirectHotSpotObjectConstantImpl::object(this, HotSpotJVMCI::resolve(constant));
1357     return Handle(THREAD, obj);
1358   } else if (isa_IndirectHotSpotObjectConstantImpl(constant)) {
1359     jlong object_handle = get_IndirectHotSpotObjectConstantImpl_objectHandle(constant);
1360     if (object_handle == 0L) {
1361       JVMCI_THROW_MSG_(NullPointerException, "Foreign object reference has been cleared", Handle());
1362     }
1363     oop result = resolve_handle(object_handle);
1364     if (result == NULL) {
1365       JVMCI_THROW_MSG_(InternalError, "Constant was unexpectedly NULL", Handle());
1366     }
1367     return Handle(THREAD, result);
1368   } else {
1369     JVMCI_THROW_MSG_(IllegalArgumentException, "DirectHotSpotObjectConstantImpl shouldn't reach JVMCI in SVM mode", Handle());
1370   }
1371 }
1372 
1373 JVMCIObject JVMCIEnv::wrap(jobject object) {
1374   return JVMCIObject::create(object, is_hotspot());
1375 }
1376 
1377 jlong JVMCIEnv::make_handle(const Handle& obj) {
1378   assert(!obj.is_null(), "should only create handle for non-NULL oops");
1379   jobject handle = JVMCI::make_global(obj);
1380   return (jlong) handle;
1381 }
1382 
1383 oop JVMCIEnv::resolve_handle(jlong objectHandle) {
1384   assert(objectHandle != 0, "should be a valid handle");
1385   oop obj = *((oopDesc**)objectHandle);
1386   if (obj != NULL) {
1387     obj->verify();
1388   }
1389   return obj;
1390 }
1391 
1392 JVMCIObject JVMCIEnv::create_string(const char* str, JVMCI_TRAPS) {
1393   if (is_hotspot()) {
1394     JavaThread* THREAD = JavaThread::current();

1395     Handle result = java_lang_String::create_from_str(str, CHECK_(JVMCIObject()));
1396     return HotSpotJVMCI::wrap(result());
1397   } else {
1398     jobject result;
1399     jboolean exception = false;
1400     {
1401       JNIAccessMark jni(this);
1402       result = jni()->NewStringUTF(str);
1403       exception = jni()->ExceptionCheck();
1404     }
1405     return wrap(result);
1406   }
1407 }
1408 
1409 bool JVMCIEnv::equals(JVMCIObject a, JVMCIObject b) {
1410   if (is_hotspot()) {
1411     return HotSpotJVMCI::resolve(a) == HotSpotJVMCI::resolve(b);
1412   } else {
1413     JNIAccessMark jni(this);
1414     return jni()->IsSameObject(a.as_jobject(), b.as_jobject()) != 0;
1415   }
1416 }
1417 
1418 BasicType JVMCIEnv::kindToBasicType(JVMCIObject kind, JVMCI_TRAPS) {
1419   if (kind.is_null()) {
1420     JVMCI_THROW_(NullPointerException, T_ILLEGAL);
1421   }
1422   jchar ch = get_JavaKind_typeChar(kind);
1423   switch(ch) {
1424     case 'Z': return T_BOOLEAN;
1425     case 'B': return T_BYTE;
1426     case 'S': return T_SHORT;
1427     case 'C': return T_CHAR;
1428     case 'I': return T_INT;
1429     case 'F': return T_FLOAT;
1430     case 'J': return T_LONG;
1431     case 'D': return T_DOUBLE;
1432     case 'A': return T_OBJECT;
1433     case '-': return T_ILLEGAL;
1434     default:
1435       JVMCI_ERROR_(T_ILLEGAL, "unexpected Kind: %c", ch);
1436   }
1437 }
1438 
1439 void JVMCIEnv::initialize_installed_code(JVMCIObject installed_code, CodeBlob* cb, JVMCI_TRAPS) {
1440   // Ensure that all updates to the InstalledCode fields are consistent.
1441   if (get_InstalledCode_address(installed_code) != 0) {
1442     JVMCI_THROW_MSG(InternalError, "InstalledCode instance already in use");
1443   }
1444   if (!isa_HotSpotInstalledCode(installed_code)) {
1445     JVMCI_THROW_MSG(InternalError, "InstalledCode instance must be a subclass of HotSpotInstalledCode");
1446   }
1447 
1448   // Ignore the version which can stay at 0
1449   if (cb->is_nmethod()) {
1450     nmethod* nm = cb->as_nmethod_or_null();
1451     if (!nm->is_alive()) {
1452       JVMCI_THROW_MSG(InternalError, "nmethod has been reclaimed");
1453     }
1454     if (nm->is_in_use()) {
1455       set_InstalledCode_entryPoint(installed_code, (jlong) nm->verified_entry_point());
1456     }
1457   } else {
1458     set_InstalledCode_entryPoint(installed_code, (jlong) cb->code_begin());
1459   }
1460   set_InstalledCode_address(installed_code, (jlong) cb);
1461   set_HotSpotInstalledCode_size(installed_code, cb->size());
1462   set_HotSpotInstalledCode_codeStart(installed_code, (jlong) cb->code_begin());
1463   set_HotSpotInstalledCode_codeSize(installed_code, cb->code_size());
1464 }
1465 
1466 
1467 void JVMCIEnv::invalidate_nmethod_mirror(JVMCIObject mirror, JVMCI_TRAPS) {
1468   if (mirror.is_null()) {
1469     JVMCI_THROW(NullPointerException);
1470   }
1471 
1472   nmethodLocker locker;
1473   nmethod* nm = JVMCIENV->get_nmethod(mirror, locker);
1474   if (nm == NULL) {
1475     // Nothing to do
1476     return;
1477   }
1478 
1479   Thread* THREAD = Thread::current();
1480   if (!mirror.is_hotspot() && !THREAD->is_Java_thread()) {
1481     // Calling back into native might cause the execution to block, so only allow this when calling
1482     // from a JavaThread, which is the normal case anyway.
1483     JVMCI_THROW_MSG(IllegalArgumentException,
1484                     "Cannot invalidate HotSpotNmethod object in shared library VM heap from non-JavaThread");
1485   }
1486 
1487   VM_DeoptimizeNMethod::invalidate(nm);
1488 
1489   // A HotSpotNmethod instance can only reference a single nmethod
1490   // during its lifetime so simply clear it here.
1491   set_InstalledCode_address(mirror, 0);
1492 }
1493 
1494 Klass* JVMCIEnv::asKlass(JVMCIObject obj) {
1495   return (Klass*) get_HotSpotResolvedObjectTypeImpl_metadataPointer(obj);
1496 }
1497 
1498 Method* JVMCIEnv::asMethod(JVMCIObject obj) {
1499   Method** metadataHandle = (Method**) get_HotSpotResolvedJavaMethodImpl_metadataHandle(obj);
1500   return *metadataHandle;
1501 }
1502 
1503 ConstantPool* JVMCIEnv::asConstantPool(JVMCIObject obj) {
1504   ConstantPool** metadataHandle = (ConstantPool**) get_HotSpotConstantPool_metadataHandle(obj);
1505   return *metadataHandle;
1506 }
1507 
1508 CodeBlob* JVMCIEnv::get_code_blob(JVMCIObject obj, nmethodLocker& locker) {
1509   address code = (address) get_InstalledCode_address(obj);
1510   if (code == NULL) {
1511     return NULL;
1512   }
1513   if (isa_HotSpotNmethod(obj)) {
1514     nmethod* nm = NULL;
1515     {
1516       // Lookup the CodeBlob while holding the CodeCache_lock to ensure the nmethod can't be freed
1517       // by nmethod::flush while we're interrogating it.
1518       MutexLockerEx cm_lock(CodeCache_lock, Mutex::_no_safepoint_check_flag);
1519       CodeBlob* cb = CodeCache::find_blob_unsafe(code);
1520       if (cb == (CodeBlob*) code) {
1521         nmethod* the_nm = cb->as_nmethod_or_null();
1522         if (the_nm != NULL && the_nm->is_alive()) {
1523           // Lock the nmethod to stop any further transitions by the sweeper.  It's still possible
1524           // for this code to execute in the middle of the sweeping of the nmethod but that will be
1525           // handled below.
1526           locker.set_code(nm, true);
1527           nm = the_nm;
1528         }
1529       }
1530     }
1531 
1532     if (nm != NULL) {
1533       // We found the nmethod but it could be in the process of being freed.  Check the state of the
1534       // nmethod while holding the Patching_lock.  This ensures that any transitions by other
1535       // threads have seen the is_locked_by_vm() update above.
1536       MutexLockerEx cm_lock(Patching_lock, Mutex::_no_safepoint_check_flag);
1537       if (!nm->is_alive()) {
1538         //  It was alive when we looked it up but it's no longer alive so release it.
1539         locker.set_code(NULL);
1540         nm = NULL;
1541       }
1542     }
1543 
1544     jlong compile_id_snapshot = get_HotSpotNmethod_compileIdSnapshot(obj);
1545     if (compile_id_snapshot != 0L) {
1546       // Found a live nmethod with the same address, make sure it's the same nmethod
1547       if (nm == (nmethod*) code && nm->compile_id() == compile_id_snapshot && nm->is_alive()) {
1548         if (nm->is_not_entrant()) {
1549           // Zero the entry point so that the nmethod
1550           // cannot be invoked by the mirror but can
1551           // still be deoptimized.
1552           set_InstalledCode_entryPoint(obj, 0);
1553         }
1554         return nm;
1555       }
1556       // The HotSpotNmethod no longer refers to a valid nmethod so clear the state
1557       locker.set_code(NULL);
1558       nm = NULL;
1559     }
1560 
1561     if (nm == NULL) {
1562       // The HotSpotNmethod was pointing at some nmethod but the nmethod is no longer valid, so
1563       // clear the InstalledCode fields of this HotSpotNmethod so that it no longer refers to a
1564       // nmethod in the code cache.
1565       set_InstalledCode_address(obj, 0);
1566       set_InstalledCode_entryPoint(obj, 0);
1567     }
1568     return nm;
1569   }
1570 
1571   CodeBlob* cb = (CodeBlob*) code;
1572   assert(!cb->is_nmethod(), "unexpected nmethod");
1573   return cb;
1574 }
1575 
1576 nmethod* JVMCIEnv::get_nmethod(JVMCIObject obj, nmethodLocker& locker) {
1577   CodeBlob* cb = get_code_blob(obj, locker);
1578   if (cb != NULL) {
1579     return cb->as_nmethod_or_null();
1580   }
1581   return NULL;
1582 }
1583 
1584 // Generate implementations for the initialize, new, isa, get and set methods for all the types and
1585 // fields declared in the JVMCI_CLASSES_DO macro.
1586 
1587 #define START_CLASS(className, fullClassName)                                                                        \
1588   void JVMCIEnv::className##_initialize(JVMCI_TRAPS) {                                                               \
1589     if (is_hotspot()) {                                                                                              \
1590       HotSpotJVMCI::className::initialize(JVMCI_CHECK);                                                              \
1591     } else {                                                                                                         \
1592       JNIJVMCI::className::initialize(JVMCI_CHECK);                                                                  \
1593     }                                                                                                                \
1594   }                                                                                                                  \
1595   JVMCIObjectArray JVMCIEnv::new_##className##_array(int length, JVMCI_TRAPS) {                                      \
1596     if (is_hotspot()) {                                                                                              \
1597       Thread* THREAD = Thread::current();                                                                            \
1598       objArrayOop array = oopFactory::new_objArray(HotSpotJVMCI::className::klass(), length, CHECK_(JVMCIObject())); \
1599       return (JVMCIObjectArray) wrap(array);                                                                         \
1600     } else {                                                                                                         \
1601       JNIAccessMark jni(this);                                                                                       \
1602       jobjectArray result = jni()->NewObjectArray(length, JNIJVMCI::className::clazz(), NULL);                       \
1603       return wrap(result);                                                                                           \
1604     }                                                                                                                \
1605   }                                                                                                                  \
1606   bool JVMCIEnv::isa_##className(JVMCIObject object) {                                                               \
1607     if (is_hotspot()) {                                                                                              \
1608       return HotSpotJVMCI::className::is_instance(this, object);                                                     \
1609     } else {                                                                                                         \
1610       return JNIJVMCI::className::is_instance(this, object);                                                         \
1611     }                                                                                                                \
1612   }
1613 
1614 #define END_CLASS
1615 
1616 #define FIELD(className, name, type, accessor, cast)                 \
1617   type JVMCIEnv::get_##className##_##name(JVMCIObject obj) {         \
1618     if (is_hotspot()) {                                              \
1619       return HotSpotJVMCI::className::get_##name(this, obj);         \
1620     } else {                                                         \
1621       return JNIJVMCI::className::get_##name(this, obj);             \
1622     }                                                                \
1623   }                                                                  \
1624   void JVMCIEnv::set_##className##_##name(JVMCIObject obj, type x) { \
1625     if (is_hotspot()) {                                              \
1626       HotSpotJVMCI::className::set_##name(this, obj, x);             \
1627     } else {                                                         \
1628       JNIJVMCI::className::set_##name(this, obj, x);                 \
1629     }                                                                \
1630   }
1631 
1632 #define EMPTY_CAST
1633 #define CHAR_FIELD(className, name)                    FIELD(className, name, jchar, Char, EMPTY_CAST)
1634 #define INT_FIELD(className, name)                     FIELD(className, name, jint, Int, EMPTY_CAST)
1635 #define BOOLEAN_FIELD(className, name)                 FIELD(className, name, jboolean, Boolean, EMPTY_CAST)
1636 #define LONG_FIELD(className, name)                    FIELD(className, name, jlong, Long, EMPTY_CAST)
1637 #define FLOAT_FIELD(className, name)                   FIELD(className, name, jfloat, Float, EMPTY_CAST)
1638 
1639 #define OBJECT_FIELD(className, name, signature)              OOPISH_FIELD(className, name, JVMCIObject, Object, EMPTY_CAST)
1640 #define OBJECTARRAY_FIELD(className, name, signature)         OOPISH_FIELD(className, name, JVMCIObjectArray, Object, (JVMCIObjectArray))
1641 #define PRIMARRAY_FIELD(className, name, signature)           OOPISH_FIELD(className, name, JVMCIPrimitiveArray, Object, (JVMCIPrimitiveArray))
1642 
1643 #define STATIC_OBJECT_FIELD(className, name, signature)       STATIC_OOPISH_FIELD(className, name, JVMCIObject, Object, (JVMCIObject))
1644 #define STATIC_OBJECTARRAY_FIELD(className, name, signature)  STATIC_OOPISH_FIELD(className, name, JVMCIObjectArray, Object, (JVMCIObjectArray))
1645 
1646 #define OOPISH_FIELD(className, name, type, accessor, cast)           \
1647   type JVMCIEnv::get_##className##_##name(JVMCIObject obj) {          \
1648     if (is_hotspot()) {                                               \
1649       return HotSpotJVMCI::className::get_##name(this, obj);          \
1650     } else {                                                          \
1651       return JNIJVMCI::className::get_##name(this, obj);              \
1652     }                                                                 \
1653   }                                                                   \
1654   void JVMCIEnv::set_##className##_##name(JVMCIObject obj, type x) {  \
1655     if (is_hotspot()) {                                               \
1656       HotSpotJVMCI::className::set_##name(this, obj, x);              \
1657     } else {                                                          \
1658       JNIJVMCI::className::set_##name(this, obj, x);                  \
1659     }                                                                 \
1660   }
1661 
1662 #define STATIC_OOPISH_FIELD(className, name, type, accessor, cast)    \
1663   type JVMCIEnv::get_##className##_##name() {                         \
1664     if (is_hotspot()) {                                               \
1665       return HotSpotJVMCI::className::get_##name(this);               \
1666     } else {                                                          \
1667       return JNIJVMCI::className::get_##name(this);                   \
1668     }                                                                 \
1669   }                                                                   \
1670   void JVMCIEnv::set_##className##_##name(type x) {                   \
1671     if (is_hotspot()) {                                               \
1672       HotSpotJVMCI::className::set_##name(this, x);                   \
1673     } else {                                                          \
1674       JNIJVMCI::className::set_##name(this, x);                       \
1675     }                                                                 \
1676   }
1677 
1678 #define STATIC_PRIMITIVE_FIELD(className, name, type, accessor, cast) \
1679   type JVMCIEnv::get_##className##_##name() {                         \
1680     if (is_hotspot()) {                                               \
1681       return HotSpotJVMCI::className::get_##name(this);               \
1682     } else {                                                          \
1683       return JNIJVMCI::className::get_##name(this);                   \
1684     }                                                                 \
1685   }                                                                   \
1686   void JVMCIEnv::set_##className##_##name(type x) {                   \
1687     if (is_hotspot()) {                                               \
1688       HotSpotJVMCI::className::set_##name(this, x);                   \
1689     } else {                                                          \
1690       JNIJVMCI::className::set_##name(this, x);                       \
1691     }                                                                 \
1692   }
1693 #define STATIC_INT_FIELD(className, name) STATIC_PRIMITIVE_FIELD(className, name, jint, Int, EMPTY_CAST)
1694 #define STATIC_BOOLEAN_FIELD(className, name) STATIC_PRIMITIVE_FIELD(className, name, jboolean, Boolean, EMPTY_CAST)
1695 #define METHOD(jniCallType, jniGetMethod, hsCallType, returnType, className, methodName, signatureSymbolName, args)
1696 #define CONSTRUCTOR(className, signature)
1697 
1698 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)
1699 
1700 #undef START_CLASS
1701 #undef END_CLASS
1702 #undef METHOD
1703 #undef CONSTRUCTOR
1704 #undef FIELD
1705 #undef CHAR_FIELD
1706 #undef INT_FIELD
1707 #undef BOOLEAN_FIELD
1708 #undef LONG_FIELD
1709 #undef FLOAT_FIELD
1710 #undef OBJECT_FIELD
1711 #undef PRIMARRAY_FIELD
1712 #undef OBJECTARRAY_FIELD
1713 #undef STATIC_OOPISH_FIELD
1714 #undef STATIC_OBJECT_FIELD
1715 #undef STATIC_OBJECTARRAY_FIELD
1716 #undef STATIC_INT_FIELD
1717 #undef STATIC_BOOLEAN_FIELD
1718 #undef EMPTY_CAST
--- EOF ---