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