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