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