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