1 /*
   2  * Copyright (c) 1999, 2025, 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 "classfile/stringTable.hpp"
  26 #include "classfile/symbolTable.hpp"
  27 #include "classfile/systemDictionary.hpp"
  28 #include "code/codeCache.hpp"
  29 #include "compiler/compilerOracle.hpp"
  30 #include "compiler/compileTask.hpp"
  31 #include "gc/shared/barrierSet.hpp"
  32 #include "gc/shared/barrierSetNMethod.hpp"
  33 #include "jvm_io.h"
  34 #include "jvmci/jniAccessMark.inline.hpp"
  35 #include "jvmci/jvmciCompiler.hpp"
  36 #include "jvmci/jvmciRuntime.hpp"
  37 #include "memory/oopFactory.hpp"
  38 #include "memory/resourceArea.hpp"
  39 #include "memory/universe.hpp"
  40 #include "oops/objArrayKlass.hpp"
  41 #include "oops/typeArrayOop.inline.hpp"
  42 #include "prims/jvmtiExport.hpp"
  43 #include "runtime/arguments.hpp"
  44 #include "runtime/deoptimization.hpp"
  45 #include "runtime/fieldDescriptor.inline.hpp"
  46 #include "runtime/javaCalls.hpp"
  47 #include "runtime/jniHandles.inline.hpp"
  48 #include "runtime/os.hpp"
  49 #include "utilities/permitForbiddenFunctions.hpp"
  50 
  51 JVMCICompileState::JVMCICompileState(CompileTask* task, JVMCICompiler* compiler):
  52   _task(task),
  53   _compiler(compiler),
  54   _retryable(true),
  55   _failure_reason(nullptr),
  56   _failure_reason_on_C_heap(false) {
  57   // Get Jvmti capabilities under lock to get consistent values.
  58   MutexLocker mu(JvmtiThreadState_lock);
  59   _jvmti_redefinition_count             = JvmtiExport::redefinition_count();
  60   _jvmti_can_hotswap_or_post_breakpoint = JvmtiExport::can_hotswap_or_post_breakpoint() ? 1 : 0;
  61   _jvmti_can_access_local_variables     = JvmtiExport::can_access_local_variables() ? 1 : 0;
  62   _jvmti_can_post_on_exceptions         = JvmtiExport::can_post_on_exceptions() ? 1 : 0;
  63   _jvmti_can_pop_frame                  = JvmtiExport::can_pop_frame() ? 1 : 0;
  64   _target_method_is_old                 = _task != nullptr && _task->method()->is_old();
  65   if (task->is_blocking()) {
  66     task->set_blocking_jvmci_compile_state(this);
  67   }
  68 }
  69 
  70 void JVMCICompileState::set_failure(bool retryable, const char* reason, bool reason_on_C_heap) {
  71   if (_failure_reason != nullptr && _failure_reason_on_C_heap) {
  72       os::free((void*) _failure_reason);
  73   }
  74   _failure_reason = reason;
  75   _failure_reason_on_C_heap = reason_on_C_heap;
  76   _retryable = retryable;
  77 }
  78 
  79 void JVMCICompileState::notify_libjvmci_oome() {
  80   const char* msg = "Out of memory initializing libjvmci or attaching it to the current thread";
  81   set_failure(true, msg);
  82   _compiler->on_upcall(msg);
  83 }
  84 
  85 // Update global JVMCI compilation ticks after 512 thread-local JVMCI compilation ticks.
  86 // This mitigates the overhead of the atomic operation used for the global update.
  87 #define THREAD_TICKS_PER_GLOBAL_TICKS (2 << 9)
  88 #define THREAD_TICKS_PER_GLOBAL_TICKS_MASK (THREAD_TICKS_PER_GLOBAL_TICKS - 1)
  89 
  90 void JVMCICompileState::inc_compilation_ticks() {
  91   if ((++_compilation_ticks & THREAD_TICKS_PER_GLOBAL_TICKS_MASK) == 0) {
  92     _compiler->inc_global_compilation_ticks();
  93   }
  94 }
  95 
  96 bool JVMCICompileState::jvmti_state_changed() const {
  97   // Some classes were redefined
  98   if (jvmti_redefinition_count() != JvmtiExport::redefinition_count()) {
  99     return true;
 100   }
 101   if (!jvmti_can_access_local_variables() &&
 102       JvmtiExport::can_access_local_variables()) {
 103     return true;
 104   }
 105   if (!jvmti_can_hotswap_or_post_breakpoint() &&
 106       JvmtiExport::can_hotswap_or_post_breakpoint()) {
 107     return true;
 108   }
 109   if (!jvmti_can_post_on_exceptions() &&
 110       JvmtiExport::can_post_on_exceptions()) {
 111     return true;
 112   }
 113   if (!jvmti_can_pop_frame() &&
 114       JvmtiExport::can_pop_frame()) {
 115     return true;
 116   }
 117   return false;
 118 }
 119 
 120 void JVMCIEnv::init_env_mode_runtime(JavaThread* thread, JNIEnv* parent_env) {
 121   assert(thread != nullptr, "npe");
 122   _env = nullptr;
 123   _pop_frame_on_close = false;
 124   _detach_on_close = false;
 125   if (!UseJVMCINativeLibrary) {
 126     // In HotSpot mode, JNI isn't used at all.
 127     _runtime = JVMCI::java_runtime();
 128     _is_hotspot = true;
 129     return;
 130   }
 131 
 132   if (parent_env != nullptr) {
 133     // If the parent JNI environment is non-null then figure out whether it
 134     // is a HotSpot or shared library JNIEnv and set the state appropriately.
 135     _is_hotspot = thread->jni_environment() == parent_env;
 136     if (_is_hotspot) {
 137       // Select the Java runtime
 138       _runtime = JVMCI::java_runtime();
 139       return;
 140     }
 141     _runtime = thread->libjvmci_runtime();
 142     assert(_runtime != nullptr, "npe");
 143     _env = parent_env;
 144     return;
 145   }
 146 
 147   // Running in JVMCI shared library mode so ensure the shared library
 148   // is loaded and initialized and get a shared library JNIEnv
 149   _is_hotspot = false;
 150 
 151   _runtime = JVMCI::compiler_runtime(thread);
 152   _env = _runtime->init_shared_library_javavm(&_init_error, &_init_error_msg);
 153   if (_env != nullptr) {
 154     // Creating the JVMCI shared library VM also attaches the current thread
 155     _detach_on_close = true;
 156   } else if (_init_error != JNI_OK) {
 157     // Caller creating this JVMCIEnv must handle the error.
 158     JVMCI_event_1("[%s:%d] Error creating libjvmci (err: %d, %s)", _file, _line,
 159                   _init_error, _init_error_msg == nullptr ? "unknown" : _init_error_msg);
 160     return;
 161   } else {
 162     _runtime->GetEnv(thread, (void**)&parent_env, JNI_VERSION_1_2);
 163     if (parent_env != nullptr) {
 164       // Even though there's a parent JNI env, there's no guarantee
 165       // it was opened by a JVMCIEnv scope and thus may not have
 166       // pushed a local JNI frame. As such, we use a new JNI local
 167       // frame in this scope to ensure local JNI refs are collected
 168       // in a timely manner after leaving this scope.
 169       _env = parent_env;
 170     } else {
 171       ResourceMark rm; // Thread name is resource allocated
 172       JavaVMAttachArgs attach_args;
 173       attach_args.version = JNI_VERSION_1_2;
 174       attach_args.name = const_cast<char*>(thread->name());
 175       attach_args.group = nullptr;
 176       _init_error = _runtime->AttachCurrentThread(thread, (void**) &_env, &attach_args);
 177       if (_init_error == JNI_OK) {
 178         _detach_on_close = true;
 179       } else {
 180         // Caller creating this JVMCIEnv must handle the error.
 181         _env = nullptr;
 182         JVMCI_event_1("[%s:%d] Error attaching to libjvmci (err: %d)", _file, _line, _init_error);
 183         return;
 184       }
 185     }
 186   }
 187 
 188   assert(_env != nullptr, "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     JVMCI_event_1("[%s:%d] Error pushing local JNI frame (err: %d)", _file, _line, result);
 195     return;
 196   }
 197   _pop_frame_on_close = true;
 198 }
 199 
 200 JVMCIEnv::JVMCIEnv(JavaThread* thread, JVMCICompileState* compile_state, const char* file, int line):
 201     _throw_to_caller(false), _file(file), _line(line), _init_error(JNI_OK), _init_error_msg(nullptr), _compile_state(compile_state) {
 202   init_env_mode_runtime(thread, nullptr);
 203 }
 204 
 205 JVMCIEnv::JVMCIEnv(JavaThread* thread, const char* file, int line):
 206     _throw_to_caller(false), _file(file), _line(line), _init_error(JNI_OK), _init_error_msg(nullptr), _compile_state(nullptr) {
 207   init_env_mode_runtime(thread, nullptr);
 208 }
 209 
 210 JVMCIEnv::JVMCIEnv(JavaThread* thread, JNIEnv* parent_env, const char* file, int line):
 211     _throw_to_caller(true), _file(file), _line(line), _init_error(JNI_OK), _init_error_msg(nullptr), _compile_state(nullptr) {
 212   assert(parent_env != nullptr, "npe");
 213   init_env_mode_runtime(thread, parent_env);
 214   assert(_env == nullptr || parent_env == _env, "mismatched JNIEnvironment");
 215   assert(_init_error == JNI_OK, "err: %d", _init_error);
 216 }
 217 
 218 void JVMCIEnv::init(JavaThread* thread, bool is_hotspot, const char* file, int line) {
 219   _compile_state = nullptr;
 220   _throw_to_caller = false;
 221   _file = file;
 222   _line = line;
 223   _init_error = JNI_OK;
 224   _init_error_msg = nullptr;
 225   if (is_hotspot) {
 226     _env = nullptr;
 227     _pop_frame_on_close = false;
 228     _detach_on_close = false;
 229     _is_hotspot = true;
 230     _runtime = JVMCI::java_runtime();
 231   } else {
 232     init_env_mode_runtime(thread, nullptr);
 233   }
 234 }
 235 
 236 void JVMCIEnv::check_init(JVMCI_TRAPS) {
 237   guarantee(JVMCIENV != this, "must be");
 238   if (_init_error == JNI_OK) {
 239     return;
 240   }
 241   if (_init_error == JNI_ENOMEM) {
 242     JVMCI_THROW_MSG(OutOfMemoryError, "JNI_ENOMEM creating or attaching to libjvmci");
 243   }
 244   stringStream st;
 245   st.print("Error creating or attaching to libjvmci (err: %d, description: %s)",
 246            _init_error, _init_error_msg == nullptr ? "unknown" : _init_error_msg);
 247   JVMCI_THROW_MSG(InternalError, st.freeze());
 248 }
 249 
 250 void JVMCIEnv::check_init(TRAPS) {
 251   if (_init_error == JNI_OK) {
 252     return;
 253   }
 254   stringStream st;
 255   st.print("Error creating or attaching to libjvmci (err: %d, description: %s)",
 256             _init_error, _init_error_msg != nullptr ? _init_error_msg : (_init_error == JNI_ENOMEM ? "JNI_ENOMEM" : "none"));
 257   THROW_MSG(vmSymbols::java_lang_OutOfMemoryError(), st.freeze());
 258 }
 259 
 260 // Prints a pending exception (if any) and its stack trace to st.
 261 // Also partially logs the stack trace to the JVMCI event log.
 262 void JVMCIEnv::describe_pending_exception(outputStream* st) {
 263   ResourceMark rm;
 264   char* stack_trace = nullptr;
 265   if (pending_exception_as_string(nullptr, (const char**) &stack_trace)) {
 266     st->print_raw_cr(stack_trace);
 267 
 268     // Use up to half the lines of the JVMCI event log to
 269     // show the stack trace.
 270     char* cursor = stack_trace;
 271     int line = 0;
 272     const int max_lines = LogEventsBufferEntries / 2;
 273     char* last_line = nullptr;
 274     while (*cursor != '\0') {
 275       char* eol = strchr(cursor, '\n');
 276       if (eol == nullptr) {
 277         if (line == max_lines - 1) {
 278           last_line = cursor;
 279         } else if (line < max_lines) {
 280           JVMCI_event_1("%s", cursor);
 281         }
 282         cursor = cursor + strlen(cursor);
 283       } else {
 284         *eol = '\0';
 285         if (line == max_lines - 1) {
 286           last_line = cursor;
 287         } else if (line < max_lines) {
 288           JVMCI_event_1("%s", cursor);
 289         }
 290         cursor = eol + 1;
 291       }
 292       line++;
 293     }
 294     if (last_line != nullptr) {
 295       if (line > max_lines) {
 296         JVMCI_event_1("%s [elided %d more stack trace lines]", last_line, line - max_lines);
 297       } else {
 298         JVMCI_event_1("%s", last_line);
 299       }
 300     }
 301   }
 302 }
 303 
 304 bool JVMCIEnv::pending_exception_as_string(const char** to_string, const char** stack_trace) {
 305   JavaThread* THREAD = JavaThread::current(); // For exception macros.
 306   JVMCIObject to_string_obj;
 307   JVMCIObject stack_trace_obj;
 308   bool had_nested_exception = false;
 309   if (!is_hotspot()) {
 310     JNIAccessMark jni(this, THREAD);
 311     jthrowable ex = jni()->ExceptionOccurred();
 312     if (ex != nullptr) {
 313       jni()->ExceptionClear();
 314       jobjectArray pair = (jobjectArray) jni()->CallStaticObjectMethod(
 315         JNIJVMCI::HotSpotJVMCIRuntime::clazz(),
 316         JNIJVMCI::HotSpotJVMCIRuntime::exceptionToString_method(),
 317         ex, to_string != nullptr, stack_trace != nullptr);
 318       if (jni()->ExceptionCheck()) {
 319         // As last resort, dump nested exception
 320         jni()->ExceptionDescribe();
 321         had_nested_exception = true;
 322       } else {
 323         guarantee(pair != nullptr, "pair is null");
 324         int len = jni()->GetArrayLength(pair);
 325         guarantee(len == 2, "bad len is %d", len);
 326         if (to_string != nullptr) {
 327           to_string_obj = JVMCIObject::create(jni()->GetObjectArrayElement(pair, 0), false);
 328         }
 329         if (stack_trace != nullptr) {
 330           stack_trace_obj = JVMCIObject::create(jni()->GetObjectArrayElement(pair, 1), false);
 331         }
 332       }
 333     } else {
 334       return false;
 335     }
 336   } else {
 337     if (HAS_PENDING_EXCEPTION) {
 338       Handle exception(THREAD, PENDING_EXCEPTION);
 339       CLEAR_PENDING_EXCEPTION;
 340       JavaCallArguments jargs;
 341       jargs.push_oop(exception);
 342       jargs.push_int(to_string != nullptr);
 343       jargs.push_int(stack_trace != nullptr);
 344       JavaValue result(T_OBJECT);
 345       JavaCalls::call_static(&result,
 346                               HotSpotJVMCI::HotSpotJVMCIRuntime::klass(),
 347                               vmSymbols::exceptionToString_name(),
 348                               vmSymbols::exceptionToString_signature(), &jargs, THREAD);
 349       if (HAS_PENDING_EXCEPTION) {
 350         Handle nested_exception(THREAD, PENDING_EXCEPTION);
 351         CLEAR_PENDING_EXCEPTION;
 352         java_lang_Throwable::print_stack_trace(nested_exception, tty);
 353         // Clear and ignore any exceptions raised during printing
 354         CLEAR_PENDING_EXCEPTION;
 355         had_nested_exception = true;
 356       } else {
 357         oop pair = result.get_oop();
 358         guarantee(pair->is_objArray(), "must be");
 359         objArrayOop pair_arr = objArrayOop(pair);
 360         int len = pair_arr->length();
 361         guarantee(len == 2, "bad len is %d", len);
 362         if (to_string != nullptr) {
 363           to_string_obj = HotSpotJVMCI::wrap(pair_arr->obj_at(0));
 364         }
 365         if (stack_trace != nullptr) {
 366           stack_trace_obj = HotSpotJVMCI::wrap(pair_arr->obj_at(1));
 367         }
 368       }
 369     } else {
 370       return false;
 371     }
 372   }
 373   if (had_nested_exception) {
 374     if (to_string != nullptr) {
 375       *to_string = "nested exception occurred converting exception to string";
 376     }
 377     if (stack_trace != nullptr) {
 378       *stack_trace = "nested exception occurred converting exception stack to string";
 379     }
 380   } else {
 381     if (to_string_obj.is_non_null()) {
 382       *to_string = as_utf8_string(to_string_obj);
 383     }
 384     if (stack_trace_obj.is_non_null()) {
 385       *stack_trace = as_utf8_string(stack_trace_obj);
 386     }
 387   }
 388   return true;
 389 }
 390 
 391 
 392 // Shared code for translating an exception from HotSpot to libjvmci or vice versa.
 393 class ExceptionTranslation: public StackObj {
 394  protected:
 395   enum DecodeFormat {
 396     _encoded_ok        = 0, // exception was successfully encoded into buffer
 397     _buffer_alloc_fail = 1, // native memory for buffer could not be allocated
 398     _encode_oome_fail  = 2, // OutOfMemoryError thrown during encoding
 399     _encode_fail       = 3, // some other problem occured during encoding. If buffer != 0,
 400                             // buffer contains a `struct { u4 len; char[len] desc}`
 401                             // describing the problem
 402     _encode_oome_in_vm = 4  // an OutOfMemoryError thrown from within VM code on a
 403                             // thread that cannot call Java (OOME has no stack trace)
 404   };
 405 
 406   JVMCIEnv*  _from_env; // Source of translation. Can be null.
 407   JVMCIEnv*  _to_env;   // Destination of translation. Never null.
 408 
 409   ExceptionTranslation(JVMCIEnv* from_env, JVMCIEnv* to_env) : _from_env(from_env), _to_env(to_env) {}
 410 
 411   // Encodes the exception in `_from_env` into `buffer`.
 412   // Where N is the number of bytes needed for the encoding, returns N if N <= `buffer_size`
 413   // and the encoding was written to `buffer` otherwise returns -N.
 414   virtual int encode(JavaThread* THREAD, jlong buffer, int buffer_size) = 0;
 415 
 416   // Decodes the exception in `buffer` in `_to_env` and throws it.
 417   virtual void decode(JavaThread* THREAD, DecodeFormat format, jlong buffer) = 0;
 418 
 419   static bool debug_translated_exception() {
 420       const char* prop_value = Arguments::get_property("jdk.internal.vm.TranslatedException.debug");
 421       return prop_value != nullptr && strcmp("true", prop_value) == 0;
 422   }
 423 
 424  public:
 425   void doit(JavaThread* THREAD) {
 426     int buffer_size = 2048;
 427     while (true) {
 428       ResourceMark rm;
 429       jlong buffer = (jlong) NEW_RESOURCE_ARRAY_IN_THREAD_RETURN_NULL(THREAD, jbyte, buffer_size);
 430       if (buffer == 0L) {
 431         JVMCI_event_1("error translating exception: translation buffer allocation failed");
 432         decode(THREAD, _buffer_alloc_fail, 0L);
 433         return;
 434       }
 435       int res = encode(THREAD, buffer, buffer_size);
 436       if (_to_env->has_pending_exception()) {
 437         // Propagate pending exception
 438         return;
 439       }
 440       if (res < 0) {
 441         int required_buffer_size = -res;
 442         if (required_buffer_size > buffer_size) {
 443           buffer_size = required_buffer_size;
 444         }
 445       } else {
 446         decode(THREAD, _encoded_ok, buffer);
 447         if (!_to_env->has_pending_exception()) {
 448           _to_env->throw_InternalError("decodeAndThrowThrowable should have thrown an exception");
 449         }
 450         return;
 451       }
 452     }
 453   }
 454 };
 455 
 456 // Translates an exception on the HotSpot heap to an exception on the shared library heap.
 457 class HotSpotToSharedLibraryExceptionTranslation : public ExceptionTranslation {
 458  private:
 459   const Handle& _throwable;
 460 
 461   char* print_throwable_to_buffer(Handle throwable, jlong buffer, int buffer_size) {
 462     char* char_buffer = (char*) buffer + 4;
 463     stringStream st(char_buffer, (size_t) buffer_size - 4);
 464     java_lang_Throwable::print_stack_trace(throwable, &st);
 465     u4 len = (u4) st.size();
 466     *((u4*) buffer) = len;
 467     return char_buffer;
 468   }
 469 
 470   bool handle_pending_exception(JavaThread* THREAD, jlong buffer, int buffer_size) {
 471     if (HAS_PENDING_EXCEPTION) {
 472       Handle throwable = Handle(THREAD, PENDING_EXCEPTION);
 473       Symbol *ex_name = throwable->klass()->name();
 474       CLEAR_PENDING_EXCEPTION;
 475       if (ex_name == vmSymbols::java_lang_OutOfMemoryError()) {
 476         JVMCI_event_1("error translating exception: OutOfMemoryError");
 477         decode(THREAD, _encode_oome_fail, 0L);
 478       } else {
 479         char* char_buffer = print_throwable_to_buffer(throwable, buffer, buffer_size);
 480         JVMCI_event_1("error translating exception: %s", char_buffer);
 481         decode(THREAD, _encode_fail, buffer);
 482       }
 483       return true;
 484     }
 485     return false;
 486   }
 487 
 488   int encode(JavaThread* THREAD, jlong buffer, int buffer_size) {
 489     if (!THREAD->can_call_java()) {
 490       Symbol *ex_name = _throwable->klass()->name();
 491       if (ex_name == vmSymbols::java_lang_OutOfMemoryError()) {
 492         JVMCI_event_1("translating exception: OutOfMemoryError within VM code");
 493         decode(THREAD, _encode_oome_in_vm, 0L);
 494         return 0;
 495       }
 496       char* char_buffer = print_throwable_to_buffer(_throwable, buffer, buffer_size);
 497       const char* detail = log_is_enabled(Info, exceptions) ? "" : " (-Xlog:exceptions may give more detail)";
 498       JVMCI_event_1("cannot call Java to translate exception%s: %s", detail, char_buffer);
 499       decode(THREAD, _encode_fail, buffer);
 500       return 0;
 501     }
 502     Klass* vmSupport = SystemDictionary::resolve_or_fail(vmSymbols::jdk_internal_vm_VMSupport(), true, THREAD);
 503     if (handle_pending_exception(THREAD, buffer, buffer_size)) {
 504       return 0;
 505     }
 506     JavaCallArguments jargs;
 507     jargs.push_oop(_throwable);
 508     jargs.push_long(buffer);
 509     jargs.push_int(buffer_size);
 510     JavaValue result(T_INT);
 511     JavaCalls::call_static(&result,
 512                             vmSupport,
 513                             vmSymbols::encodeThrowable_name(),
 514                             vmSymbols::encodeThrowable_signature(), &jargs, THREAD);
 515     if (handle_pending_exception(THREAD, buffer, buffer_size)) {
 516       return 0;
 517     }
 518     return result.get_jint();
 519   }
 520 
 521   void decode(JavaThread* THREAD, DecodeFormat format, jlong buffer) {
 522     JVMCI_event_1("decoding exception from JVM heap (format: %d, buffer[%d]) ", format, buffer == 0L ? -1 : *((u4*) buffer));
 523     JNIAccessMark jni(_to_env, THREAD);
 524     jni()->CallStaticVoidMethod(JNIJVMCI::VMSupport::clazz(),
 525                                 JNIJVMCI::VMSupport::decodeAndThrowThrowable_method(),
 526                                 format, buffer, false, debug_translated_exception());
 527   }
 528  public:
 529   HotSpotToSharedLibraryExceptionTranslation(JVMCIEnv* hotspot_env, JVMCIEnv* jni_env, const Handle& throwable) :
 530     ExceptionTranslation(hotspot_env, jni_env), _throwable(throwable) {}
 531 };
 532 
 533 // Translates an exception on the shared library heap to an exception on the HotSpot heap.
 534 class SharedLibraryToHotSpotExceptionTranslation : public ExceptionTranslation {
 535  private:
 536   jthrowable _throwable;
 537 
 538   int encode(JavaThread* THREAD, jlong buffer, int buffer_size) {
 539     JNIAccessMark jni(_from_env, THREAD);
 540     int res = jni()->CallStaticIntMethod(JNIJVMCI::VMSupport::clazz(),
 541                                       JNIJVMCI::VMSupport::encodeThrowable_method(),
 542                                       _throwable, buffer, buffer_size);
 543     if (jni()->ExceptionCheck()) {
 544       // Cannot get name of exception thrown as that can raise another exception.
 545       jni()->ExceptionClear();
 546       JVMCI_event_1("error translating exception: unknown error");
 547       decode(THREAD, _encode_fail, 0L);
 548       return 0;
 549     }
 550     return res;
 551   }
 552 
 553   void decode(JavaThread* THREAD, DecodeFormat format, jlong buffer) {
 554     JVMCI_event_1("decoding exception to JVM heap (format: %d, buffer[%d]) ", format, buffer == 0L ? -1 : *((u4*) buffer));
 555     Klass* vmSupport = SystemDictionary::resolve_or_fail(vmSymbols::jdk_internal_vm_VMSupport(), true, CHECK);
 556     JavaCallArguments jargs;
 557     jargs.push_int(format);
 558     jargs.push_long(buffer);
 559     jargs.push_int(true);
 560     jargs.push_int(debug_translated_exception());
 561     JavaValue result(T_VOID);
 562     JavaCalls::call_static(&result,
 563                             vmSupport,
 564                             vmSymbols::decodeAndThrowThrowable_name(),
 565                             vmSymbols::decodeAndThrowThrowable_signature(), &jargs, THREAD);
 566   }
 567  public:
 568   SharedLibraryToHotSpotExceptionTranslation(JVMCIEnv* hotspot_env, JVMCIEnv* jni_env, jthrowable throwable) :
 569     ExceptionTranslation(jni_env, hotspot_env), _throwable(throwable) {}
 570 };
 571 
 572 void JVMCIEnv::translate_to_jni_exception(JavaThread* THREAD, const Handle& throwable, JVMCIEnv* hotspot_env, JVMCIEnv* jni_env) {
 573   HotSpotToSharedLibraryExceptionTranslation(hotspot_env, jni_env, throwable).doit(THREAD);
 574 }
 575 
 576 void JVMCIEnv::translate_from_jni_exception(JavaThread* THREAD, jthrowable throwable, JVMCIEnv* hotspot_env, JVMCIEnv* jni_env) {
 577   SharedLibraryToHotSpotExceptionTranslation(hotspot_env, jni_env, throwable).doit(THREAD);
 578 }
 579 
 580 jboolean JVMCIEnv::transfer_pending_exception_to_jni(JavaThread* THREAD, JVMCIEnv* hotspot_env, JVMCIEnv* jni_env) {
 581   if (HAS_PENDING_EXCEPTION) {
 582     Handle throwable = Handle(THREAD, PENDING_EXCEPTION);
 583     CLEAR_PENDING_EXCEPTION;
 584     translate_to_jni_exception(THREAD, throwable, hotspot_env, jni_env);
 585     return true;
 586   }
 587   return false;
 588 }
 589 
 590 jboolean JVMCIEnv::transfer_pending_exception(JavaThread* THREAD, JVMCIEnv* peer_env) {
 591   if (is_hotspot()) {
 592     return transfer_pending_exception_to_jni(THREAD, this, peer_env);
 593   }
 594   jthrowable ex = nullptr;
 595   {
 596     JNIAccessMark jni(this, THREAD);
 597     ex = jni()->ExceptionOccurred();
 598     if (ex != nullptr) {
 599       jni()->ExceptionClear();
 600     }
 601   }
 602   if (ex != nullptr) {
 603     translate_from_jni_exception(THREAD, ex, peer_env, this);
 604     return true;
 605   }
 606   return false;
 607 }
 608 
 609 JVMCIEnv::~JVMCIEnv() {
 610   if (_init_error_msg != nullptr) {
 611     // The memory allocated in libjvmci was not allocated with os::malloc
 612     // so must not be freed with os::free.
 613     permit_forbidden_function::free((void*)_init_error_msg);
 614   }
 615   if (_init_error != JNI_OK) {
 616     return;
 617   }
 618   if (_throw_to_caller) {
 619     if (is_hotspot()) {
 620       // Nothing to do
 621     } else {
 622       Thread* thread = Thread::current();
 623       if (thread->is_Java_thread()) {
 624         JavaThread* THREAD = JavaThread::cast(thread); // For exception macros.
 625         if (HAS_PENDING_EXCEPTION) {
 626           Handle throwable = Handle(THREAD, PENDING_EXCEPTION);
 627           CLEAR_PENDING_EXCEPTION;
 628           translate_to_jni_exception(THREAD, throwable, nullptr, this);
 629         }
 630       }
 631     }
 632   } else {
 633     if (_pop_frame_on_close) {
 634       // Pop the JNI local frame that was pushed when entering this JVMCIEnv scope.
 635       JNIAccessMark jni(this);
 636       jni()->PopLocalFrame(nullptr);
 637     }
 638 
 639     if (has_pending_exception()) {
 640       char message[256];
 641       jio_snprintf(message, 256, "Uncaught exception exiting %s JVMCIEnv scope entered at %s:%d",
 642           is_hotspot() ? "HotSpot" : "libjvmci", _file, _line);
 643       JVMCIRuntime::fatal_exception(this, message);
 644     }
 645 
 646     if (_detach_on_close) {
 647       _runtime->DetachCurrentThread(JavaThread::current());
 648     }
 649   }
 650 }
 651 
 652 jboolean JVMCIEnv::has_pending_exception() {
 653   if (is_hotspot()) {
 654     JavaThread* THREAD = JavaThread::current(); // For exception macros.
 655     return HAS_PENDING_EXCEPTION;
 656   } else {
 657     JNIAccessMark jni(this);
 658     return jni()->ExceptionCheck();
 659   }
 660 }
 661 
 662 void JVMCIEnv::clear_pending_exception() {
 663   if (is_hotspot()) {
 664     JavaThread* THREAD = JavaThread::current(); // For exception macros.
 665     CLEAR_PENDING_EXCEPTION;
 666   } else {
 667     JNIAccessMark jni(this);
 668     jni()->ExceptionClear();
 669   }
 670 }
 671 
 672 int JVMCIEnv::get_length(JVMCIArray array) {
 673   if (is_hotspot()) {
 674     return HotSpotJVMCI::resolve(array)->length();
 675   } else {
 676     JNIAccessMark jni(this);
 677     return jni()->GetArrayLength(get_jarray(array));
 678   }
 679 }
 680 
 681 JVMCIObject JVMCIEnv::get_object_at(JVMCIObjectArray array, int index) {
 682   if (is_hotspot()) {
 683     oop result = HotSpotJVMCI::resolve(array)->obj_at(index);
 684     return wrap(result);
 685   } else {
 686     JNIAccessMark jni(this);
 687     jobject result = jni()->GetObjectArrayElement(get_jobjectArray(array), index);
 688     return wrap(result);
 689   }
 690 }
 691 
 692 void JVMCIEnv::put_object_at(JVMCIObjectArray array, int index, JVMCIObject value) {
 693   if (is_hotspot()) {
 694     HotSpotJVMCI::resolve(array)->obj_at_put(index, HotSpotJVMCI::resolve(value));
 695   } else {
 696     JNIAccessMark jni(this);
 697     jni()->SetObjectArrayElement(get_jobjectArray(array), index, get_jobject(value));
 698   }
 699 }
 700 
 701 jboolean JVMCIEnv::get_bool_at(JVMCIPrimitiveArray array, int index) {
 702   if (is_hotspot()) {
 703     return HotSpotJVMCI::resolve(array)->bool_at(index);
 704   } else {
 705     JNIAccessMark jni(this);
 706     jboolean result;
 707     jni()->GetBooleanArrayRegion(array.as_jbooleanArray(), index, 1, &result);
 708     return result;
 709   }
 710 }
 711 void JVMCIEnv::put_bool_at(JVMCIPrimitiveArray array, int index, jboolean value) {
 712   if (is_hotspot()) {
 713     HotSpotJVMCI::resolve(array)->bool_at_put(index, value);
 714   } else {
 715     JNIAccessMark jni(this);
 716     jni()->SetBooleanArrayRegion(array.as_jbooleanArray(), index, 1, &value);
 717   }
 718 }
 719 
 720 jbyte JVMCIEnv::get_byte_at(JVMCIPrimitiveArray array, int index) {
 721   if (is_hotspot()) {
 722     return HotSpotJVMCI::resolve(array)->byte_at(index);
 723   } else {
 724     JNIAccessMark jni(this);
 725     jbyte result;
 726     jni()->GetByteArrayRegion(array.as_jbyteArray(), index, 1, &result);
 727     return result;
 728   }
 729 }
 730 void JVMCIEnv::put_byte_at(JVMCIPrimitiveArray array, int index, jbyte value) {
 731   if (is_hotspot()) {
 732     HotSpotJVMCI::resolve(array)->byte_at_put(index, value);
 733   } else {
 734     JNIAccessMark jni(this);
 735     jni()->SetByteArrayRegion(array.as_jbyteArray(), index, 1, &value);
 736   }
 737 }
 738 
 739 jint JVMCIEnv::get_int_at(JVMCIPrimitiveArray array, int index) {
 740   if (is_hotspot()) {
 741     return HotSpotJVMCI::resolve(array)->int_at(index);
 742   } else {
 743     JNIAccessMark jni(this);
 744     jint result;
 745     jni()->GetIntArrayRegion(array.as_jintArray(), index, 1, &result);
 746     return result;
 747   }
 748 }
 749 void JVMCIEnv::put_int_at(JVMCIPrimitiveArray array, int index, jint value) {
 750   if (is_hotspot()) {
 751     HotSpotJVMCI::resolve(array)->int_at_put(index, value);
 752   } else {
 753     JNIAccessMark jni(this);
 754     jni()->SetIntArrayRegion(array.as_jintArray(), index, 1, &value);
 755   }
 756 }
 757 
 758 jlong JVMCIEnv::get_long_at(JVMCIPrimitiveArray array, int index) {
 759   if (is_hotspot()) {
 760     return HotSpotJVMCI::resolve(array)->long_at(index);
 761   } else {
 762     JNIAccessMark jni(this);
 763     jlong result;
 764     jni()->GetLongArrayRegion(array.as_jlongArray(), index, 1, &result);
 765     return result;
 766   }
 767 }
 768 void JVMCIEnv::put_long_at(JVMCIPrimitiveArray array, int index, jlong value) {
 769   if (is_hotspot()) {
 770     HotSpotJVMCI::resolve(array)->long_at_put(index, value);
 771   } else {
 772     JNIAccessMark jni(this);
 773     jni()->SetLongArrayRegion(array.as_jlongArray(), index, 1, &value);
 774   }
 775 }
 776 
 777 void JVMCIEnv::copy_bytes_to(JVMCIPrimitiveArray src, jbyte* dest, int offset, jsize length) {
 778   if (length == 0) {
 779     return;
 780   }
 781   if (is_hotspot()) {
 782     memcpy(dest, HotSpotJVMCI::resolve(src)->byte_at_addr(offset), length);
 783   } else {
 784     JNIAccessMark jni(this);
 785     jni()->GetByteArrayRegion(src.as_jbyteArray(), offset, length, dest);
 786   }
 787 }
 788 void JVMCIEnv::copy_bytes_from(jbyte* src, JVMCIPrimitiveArray dest, int offset, jsize length) {
 789   if (length == 0) {
 790     return;
 791   }
 792   if (is_hotspot()) {
 793     memcpy(HotSpotJVMCI::resolve(dest)->byte_at_addr(offset), src, length);
 794   } else {
 795     JNIAccessMark jni(this);
 796     jni()->SetByteArrayRegion(dest.as_jbyteArray(), offset, length, src);
 797   }
 798 }
 799 
 800 void JVMCIEnv::copy_longs_from(jlong* src, JVMCIPrimitiveArray dest, int offset, jsize length) {
 801   if (length == 0) {
 802     return;
 803   }
 804   if (is_hotspot()) {
 805     memcpy(HotSpotJVMCI::resolve(dest)->long_at_addr(offset), src, length * sizeof(jlong));
 806   } else {
 807     JNIAccessMark jni(this);
 808     jni()->SetLongArrayRegion(dest.as_jlongArray(), offset, length, src);
 809   }
 810 }
 811 
 812 jboolean JVMCIEnv::is_boxing_object(BasicType type, JVMCIObject object) {
 813   if (is_hotspot()) {
 814     return java_lang_boxing_object::is_instance(HotSpotJVMCI::resolve(object), type);
 815   } else {
 816     JNIAccessMark jni(this);
 817     return jni()->IsInstanceOf(get_jobject(object), JNIJVMCI::box_class(type));
 818   }
 819 }
 820 
 821 // Get the primitive value from a Java boxing object.  It's hard error to
 822 // pass a non-primitive BasicType.
 823 jvalue JVMCIEnv::get_boxed_value(BasicType type, JVMCIObject object) {
 824   jvalue result;
 825   if (is_hotspot()) {
 826     if (java_lang_boxing_object::get_value(HotSpotJVMCI::resolve(object), &result) == T_ILLEGAL) {
 827       ShouldNotReachHere();
 828     }
 829   } else {
 830     JNIAccessMark jni(this);
 831     jfieldID field = JNIJVMCI::box_field(type);
 832     switch (type) {
 833       case T_BOOLEAN: result.z = jni()->GetBooleanField(get_jobject(object), field); break;
 834       case T_BYTE:    result.b = jni()->GetByteField(get_jobject(object), field); break;
 835       case T_SHORT:   result.s = jni()->GetShortField(get_jobject(object), field); break;
 836       case T_CHAR:    result.c = jni()->GetCharField(get_jobject(object), field); break;
 837       case T_INT:     result.i = jni()->GetIntField(get_jobject(object), field); break;
 838       case T_LONG:    result.j = jni()->GetLongField(get_jobject(object), field); break;
 839       case T_FLOAT:   result.f = jni()->GetFloatField(get_jobject(object), field); break;
 840       case T_DOUBLE:  result.d = jni()->GetDoubleField(get_jobject(object), field); break;
 841       default:
 842         ShouldNotReachHere();
 843     }
 844   }
 845   return result;
 846 }
 847 
 848 // Return the BasicType of the object if it's a boxing object, otherwise return T_ILLEGAL.
 849 BasicType JVMCIEnv::get_box_type(JVMCIObject object) {
 850   if (is_hotspot()) {
 851     return java_lang_boxing_object::basic_type(HotSpotJVMCI::resolve(object));
 852   } else {
 853     JNIAccessMark jni(this);
 854     jclass clazz = jni()->GetObjectClass(get_jobject(object));
 855     if (jni()->IsSameObject(clazz, JNIJVMCI::box_class(T_BOOLEAN))) return T_BOOLEAN;
 856     if (jni()->IsSameObject(clazz, JNIJVMCI::box_class(T_BYTE))) return T_BYTE;
 857     if (jni()->IsSameObject(clazz, JNIJVMCI::box_class(T_SHORT))) return T_SHORT;
 858     if (jni()->IsSameObject(clazz, JNIJVMCI::box_class(T_CHAR))) return T_CHAR;
 859     if (jni()->IsSameObject(clazz, JNIJVMCI::box_class(T_INT))) return T_INT;
 860     if (jni()->IsSameObject(clazz, JNIJVMCI::box_class(T_LONG))) return T_LONG;
 861     if (jni()->IsSameObject(clazz, JNIJVMCI::box_class(T_FLOAT))) return T_FLOAT;
 862     if (jni()->IsSameObject(clazz, JNIJVMCI::box_class(T_DOUBLE))) return T_DOUBLE;
 863     return T_ILLEGAL;
 864   }
 865 }
 866 
 867 // Create a boxing object of the appropriate primitive type.
 868 JVMCIObject JVMCIEnv::create_box(BasicType type, jvalue* value, JVMCI_TRAPS) {
 869   switch (type) {
 870     case T_BOOLEAN:
 871     case T_BYTE:
 872     case T_CHAR:
 873     case T_SHORT:
 874     case T_INT:
 875     case T_LONG:
 876     case T_FLOAT:
 877     case T_DOUBLE:
 878       break;
 879     default:
 880       JVMCI_THROW_MSG_(IllegalArgumentException, "Only boxes for primitive values can be created", JVMCIObject());
 881   }
 882   JavaThread* THREAD = JavaThread::current(); // For exception macros.
 883   if (is_hotspot()) {
 884     oop box = java_lang_boxing_object::create(type, value, CHECK_(JVMCIObject()));
 885     return HotSpotJVMCI::wrap(box);
 886   } else {
 887     JNIAccessMark jni(this, THREAD);
 888     jobject box = jni()->NewObjectA(JNIJVMCI::box_class(type), JNIJVMCI::box_constructor(type), value);
 889     assert(box != nullptr, "");
 890     return wrap(box);
 891   }
 892 }
 893 
 894 const char* JVMCIEnv::as_utf8_string(JVMCIObject str) {
 895   if (is_hotspot()) {
 896     return java_lang_String::as_utf8_string(HotSpotJVMCI::resolve(str));
 897   } else {
 898     JNIAccessMark jni(this);
 899     jstring jstr = str.as_jstring();
 900     int length = jni()->GetStringLength(jstr);
 901     int utf8_length = jni()->GetStringUTFLength(jstr);
 902     char* result = NEW_RESOURCE_ARRAY(char, utf8_length + 1);
 903     jni()->GetStringUTFRegion(jstr, 0, length, result);
 904     return result;
 905   }
 906 }
 907 
 908 #define DO_THROW(name)                             \
 909 void JVMCIEnv::throw_##name(const char* msg) {     \
 910   if (is_hotspot()) {                              \
 911     JavaThread* THREAD = JavaThread::current();    \
 912     THROW_MSG(HotSpotJVMCI::name::symbol(), msg);  \
 913   } else {                                         \
 914     JNIAccessMark jni(this);                       \
 915     jni()->ThrowNew(JNIJVMCI::name::clazz(), msg); \
 916   }                                                \
 917 }
 918 
 919 DO_THROW(InternalError)
 920 DO_THROW(ArrayIndexOutOfBoundsException)
 921 DO_THROW(IllegalStateException)
 922 DO_THROW(NullPointerException)
 923 DO_THROW(IllegalArgumentException)
 924 DO_THROW(InvalidInstalledCodeException)
 925 DO_THROW(UnsatisfiedLinkError)
 926 DO_THROW(UnsupportedOperationException)
 927 DO_THROW(OutOfMemoryError)
 928 DO_THROW(NoClassDefFoundError)
 929 
 930 #undef DO_THROW
 931 
 932 void JVMCIEnv::fthrow_error(const char* file, int line, const char* format, ...) {
 933   const int max_msg_size = 1024;
 934   va_list ap;
 935   va_start(ap, format);
 936   char msg[max_msg_size];
 937   os::vsnprintf(msg, max_msg_size, format, ap);
 938   va_end(ap);
 939   JavaThread* THREAD = JavaThread::current();
 940   if (is_hotspot()) {
 941     Handle h_loader;
 942     Exceptions::_throw_msg(THREAD, file, line, vmSymbols::jdk_vm_ci_common_JVMCIError(), msg, h_loader );
 943   } else {
 944     JNIAccessMark jni(this, THREAD);
 945     jni()->ThrowNew(JNIJVMCI::JVMCIError::clazz(), msg);
 946   }
 947 }
 948 
 949 jboolean JVMCIEnv::call_HotSpotJVMCIRuntime_isGCSupported (JVMCIObject runtime, jint gcIdentifier) {
 950   JavaThread* THREAD = JavaThread::current(); // For exception macros.
 951   if (is_hotspot()) {
 952     JavaCallArguments jargs;
 953     jargs.push_oop(Handle(THREAD, HotSpotJVMCI::resolve(runtime)));
 954     jargs.push_int(gcIdentifier);
 955     JavaValue result(T_BOOLEAN);
 956     JavaCalls::call_special(&result,
 957                             HotSpotJVMCI::HotSpotJVMCIRuntime::klass(),
 958                             vmSymbols::isGCSupported_name(),
 959                             vmSymbols::int_bool_signature(), &jargs, CHECK_0);
 960     return result.get_jboolean();
 961   } else {
 962     JNIAccessMark jni(this, THREAD);
 963     jboolean result = jni()->CallNonvirtualBooleanMethod(runtime.as_jobject(),
 964                                                      JNIJVMCI::HotSpotJVMCIRuntime::clazz(),
 965                                                      JNIJVMCI::HotSpotJVMCIRuntime::isGCSupported_method(),
 966                                                      gcIdentifier);
 967     if (jni()->ExceptionCheck()) {
 968       return false;
 969     }
 970     return result;
 971   }
 972 }
 973 
 974 jboolean JVMCIEnv::call_HotSpotJVMCIRuntime_isIntrinsicSupported (JVMCIObject runtime, jint intrinsicIdentifier) {
 975   JavaThread* THREAD = JavaThread::current(); // For exception macros.
 976   if (is_hotspot()) {
 977     JavaCallArguments jargs;
 978     jargs.push_oop(Handle(THREAD, HotSpotJVMCI::resolve(runtime)));
 979     jargs.push_int(intrinsicIdentifier);
 980     JavaValue result(T_BOOLEAN);
 981     JavaCalls::call_special(&result,
 982                             HotSpotJVMCI::HotSpotJVMCIRuntime::klass(),
 983                             vmSymbols::isIntrinsicSupported_name(),
 984                             vmSymbols::int_bool_signature(), &jargs, CHECK_0);
 985     return result.get_jboolean();
 986   } else {
 987     JNIAccessMark jni(this, THREAD);
 988     jboolean result = jni()->CallNonvirtualBooleanMethod(runtime.as_jobject(),
 989                                                      JNIJVMCI::HotSpotJVMCIRuntime::clazz(),
 990                                                      JNIJVMCI::HotSpotJVMCIRuntime::isIntrinsicSupported_method(),
 991                                                      intrinsicIdentifier);
 992     if (jni()->ExceptionCheck()) {
 993       return false;
 994     }
 995     return result;
 996   }
 997 }
 998 
 999 JVMCIObject JVMCIEnv::call_HotSpotJVMCIRuntime_compileMethod (JVMCIObject runtime, JVMCIObject method, int entry_bci,
1000                                                               jlong compile_state, int id) {
1001   JavaThread* THREAD = JVMCI::compilation_tick(JavaThread::current()); // For exception macros.
1002   if (is_hotspot()) {
1003     JavaCallArguments jargs;
1004     jargs.push_oop(Handle(THREAD, HotSpotJVMCI::resolve(runtime)));
1005     jargs.push_oop(Handle(THREAD, HotSpotJVMCI::resolve(method)));
1006     jargs.push_int(entry_bci);
1007     jargs.push_long(compile_state);
1008     jargs.push_int(id);
1009     JavaValue result(T_OBJECT);
1010     JavaCalls::call_special(&result,
1011                             HotSpotJVMCI::HotSpotJVMCIRuntime::klass(),
1012                             vmSymbols::compileMethod_name(),
1013                             vmSymbols::compileMethod_signature(), &jargs, CHECK_(JVMCIObject()));
1014     return wrap(result.get_oop());
1015   } else {
1016     JNIAccessMark jni(this, THREAD);
1017     jobject result = jni()->CallNonvirtualObjectMethod(runtime.as_jobject(),
1018                                                      JNIJVMCI::HotSpotJVMCIRuntime::clazz(),
1019                                                      JNIJVMCI::HotSpotJVMCIRuntime::compileMethod_method(),
1020                                                      method.as_jobject(), entry_bci, compile_state, id);
1021     if (jni()->ExceptionCheck()) {
1022       return JVMCIObject();
1023     }
1024     return wrap(result);
1025   }
1026 }
1027 
1028 void JVMCIEnv::call_HotSpotJVMCIRuntime_bootstrapFinished (JVMCIObject runtime, JVMCIEnv* JVMCIENV) {
1029   JavaThread* THREAD = JVMCI::compilation_tick(JavaThread::current()); // For exception macros.
1030   if (is_hotspot()) {
1031     JavaCallArguments jargs;
1032     jargs.push_oop(Handle(THREAD, HotSpotJVMCI::resolve(runtime)));
1033     JavaValue result(T_VOID);
1034     JavaCalls::call_special(&result, HotSpotJVMCI::HotSpotJVMCIRuntime::klass(), vmSymbols::bootstrapFinished_name(), vmSymbols::void_method_signature(), &jargs, CHECK);
1035   } else {
1036     JNIAccessMark jni(this, THREAD);
1037     jni()->CallNonvirtualVoidMethod(runtime.as_jobject(), JNIJVMCI::HotSpotJVMCIRuntime::clazz(), JNIJVMCI::HotSpotJVMCIRuntime::bootstrapFinished_method());
1038 
1039   }
1040 }
1041 
1042 void JVMCIEnv::call_HotSpotJVMCIRuntime_shutdown (JVMCIObject runtime) {
1043   JavaThread* THREAD = JavaThread::current(); // For exception macros.
1044   HandleMark hm(THREAD);
1045   if (is_hotspot()) {
1046     JavaCallArguments jargs;
1047     jargs.push_oop(Handle(THREAD, HotSpotJVMCI::resolve(runtime)));
1048     JavaValue result(T_VOID);
1049     JavaCalls::call_special(&result, HotSpotJVMCI::HotSpotJVMCIRuntime::klass(), vmSymbols::shutdown_name(), vmSymbols::void_method_signature(), &jargs, THREAD);
1050   } else {
1051     JNIAccessMark jni(this, THREAD);
1052     jni()->CallNonvirtualVoidMethod(runtime.as_jobject(), JNIJVMCI::HotSpotJVMCIRuntime::clazz(), JNIJVMCI::HotSpotJVMCIRuntime::shutdown_method());
1053   }
1054   if (has_pending_exception()) {
1055     // This should never happen as HotSpotJVMCIRuntime.shutdown() should
1056     // handle all exceptions.
1057     describe_pending_exception(tty);
1058   }
1059 }
1060 
1061 JVMCIObject JVMCIEnv::call_HotSpotJVMCIRuntime_runtime (JVMCIEnv* JVMCIENV) {
1062   JavaThread* THREAD = JVMCI::compilation_tick(JavaThread::current()); // For exception macros.
1063   if (is_hotspot()) {
1064     JavaCallArguments jargs;
1065     JavaValue result(T_OBJECT);
1066     JavaCalls::call_static(&result, HotSpotJVMCI::HotSpotJVMCIRuntime::klass(), vmSymbols::runtime_name(), vmSymbols::runtime_signature(), &jargs, CHECK_(JVMCIObject()));
1067     return wrap(result.get_oop());
1068   } else {
1069     JNIAccessMark jni(this, THREAD);
1070     jobject result = jni()->CallStaticObjectMethod(JNIJVMCI::HotSpotJVMCIRuntime::clazz(), JNIJVMCI::HotSpotJVMCIRuntime::runtime_method());
1071     if (jni()->ExceptionCheck()) {
1072       return JVMCIObject();
1073     }
1074     return wrap(result);
1075   }
1076 }
1077 
1078 JVMCIObject JVMCIEnv::call_JVMCI_getRuntime (JVMCIEnv* JVMCIENV) {
1079   JavaThread* THREAD = JVMCI::compilation_tick(JavaThread::current()); // For exception macros.
1080   if (is_hotspot()) {
1081     JavaCallArguments jargs;
1082     JavaValue result(T_OBJECT);
1083     JavaCalls::call_static(&result, HotSpotJVMCI::JVMCI::klass(), vmSymbols::getRuntime_name(), vmSymbols::getRuntime_signature(), &jargs, CHECK_(JVMCIObject()));
1084     return wrap(result.get_oop());
1085   } else {
1086     JNIAccessMark jni(this, THREAD);
1087     jobject result = jni()->CallStaticObjectMethod(JNIJVMCI::JVMCI::clazz(), JNIJVMCI::JVMCI::getRuntime_method());
1088     if (jni()->ExceptionCheck()) {
1089       return JVMCIObject();
1090     }
1091     return wrap(result);
1092   }
1093 }
1094 
1095 JVMCIObject JVMCIEnv::call_HotSpotJVMCIRuntime_getCompiler (JVMCIObject runtime, JVMCIEnv* JVMCIENV) {
1096   JavaThread* THREAD = JVMCI::compilation_tick(JavaThread::current()); // For exception macros.
1097   if (is_hotspot()) {
1098     JavaCallArguments jargs;
1099     jargs.push_oop(Handle(THREAD, HotSpotJVMCI::resolve(runtime)));
1100     JavaValue result(T_OBJECT);
1101     JavaCalls::call_virtual(&result, HotSpotJVMCI::HotSpotJVMCIRuntime::klass(), vmSymbols::getCompiler_name(), vmSymbols::getCompiler_signature(), &jargs, CHECK_(JVMCIObject()));
1102     return wrap(result.get_oop());
1103   } else {
1104     JNIAccessMark jni(this, THREAD);
1105     jobject result = jni()->CallObjectMethod(runtime.as_jobject(), JNIJVMCI::HotSpotJVMCIRuntime::getCompiler_method());
1106     if (jni()->ExceptionCheck()) {
1107       return JVMCIObject();
1108     }
1109     return wrap(result);
1110   }
1111 }
1112 
1113 void JVMCIEnv::call_HotSpotJVMCIRuntime_postTranslation(JVMCIObject object, JVMCIEnv* JVMCIENV) {
1114   JavaThread* THREAD = JVMCI::compilation_tick(JavaThread::current()); // For exception macros.
1115   if (is_hotspot()) {
1116     JavaCallArguments jargs;
1117     jargs.push_oop(Handle(THREAD, HotSpotJVMCI::resolve(object)));
1118     JavaValue result(T_VOID);
1119     JavaCalls::call_static(&result,
1120                            HotSpotJVMCI::HotSpotJVMCIRuntime::klass(),
1121                            vmSymbols::postTranslation_name(),
1122                            vmSymbols::object_void_signature(), &jargs, CHECK);
1123   } else {
1124     JNIAccessMark jni(this, THREAD);
1125     jni()->CallStaticVoidMethod(JNIJVMCI::HotSpotJVMCIRuntime::clazz(),
1126                                 JNIJVMCI::HotSpotJVMCIRuntime::postTranslation_method(),
1127                                 object.as_jobject());
1128   }
1129 }
1130 
1131 JVMCIObject JVMCIEnv::call_JavaConstant_forPrimitive(jchar type_char, jlong value, JVMCI_TRAPS) {
1132   JavaThread* THREAD = JVMCI::compilation_tick(JavaThread::current()); // For exception macros.
1133   if (is_hotspot()) {
1134     JavaCallArguments jargs;
1135     jargs.push_int(type_char);
1136     jargs.push_long(value);
1137     JavaValue result(T_OBJECT);
1138     JavaCalls::call_static(&result,
1139                            HotSpotJVMCI::JavaConstant::klass(),
1140                            vmSymbols::forPrimitive_name(),
1141                            vmSymbols::forPrimitive_signature(), &jargs, CHECK_(JVMCIObject()));
1142     return wrap(result.get_oop());
1143   } else {
1144     JNIAccessMark jni(this, THREAD);
1145     jobject result = (jstring) jni()->CallStaticObjectMethod(JNIJVMCI::JavaConstant::clazz(),
1146                                                              JNIJVMCI::JavaConstant::forPrimitive_method(),
1147                                                              type_char, value);
1148     if (jni()->ExceptionCheck()) {
1149       return JVMCIObject();
1150     }
1151     return wrap(result);
1152   }
1153 }
1154 
1155 JVMCIObject JVMCIEnv::get_jvmci_primitive_type(BasicType type) {
1156   JVMCIObjectArray primitives = get_HotSpotResolvedPrimitiveType_primitives();
1157   JVMCIObject result = get_object_at(primitives, type);
1158   return result;
1159 }
1160 
1161 JVMCIObject JVMCIEnv::new_StackTraceElement(const methodHandle& method, int bci, JVMCI_TRAPS) {
1162   JavaThread* THREAD = JavaThread::current(); // For exception macros.
1163   Symbol* file_name_sym;
1164   int line_number;
1165   java_lang_StackTraceElement::decode(method, bci, file_name_sym, line_number, CHECK_(JVMCIObject()));
1166 
1167   Symbol* method_name_sym = method->name();
1168   InstanceKlass* holder = method->method_holder();
1169   const char* declaring_class_str = holder->external_name();
1170 
1171   if (is_hotspot()) {
1172     HotSpotJVMCI::StackTraceElement::klass()->initialize(CHECK_(JVMCIObject()));
1173     oop objOop = HotSpotJVMCI::StackTraceElement::klass()->allocate_instance(CHECK_(JVMCIObject()));
1174     Handle obj = Handle(THREAD, objOop);
1175 
1176     oop declaring_class = StringTable::intern((char*) declaring_class_str, CHECK_(JVMCIObject()));
1177     HotSpotJVMCI::StackTraceElement::set_declaringClass(this, obj(), declaring_class);
1178 
1179     oop method_name = StringTable::intern(method_name_sym, CHECK_(JVMCIObject()));
1180     HotSpotJVMCI::StackTraceElement::set_methodName(this, obj(), method_name);
1181 
1182     if (file_name_sym != nullptr) {
1183       oop file_name = StringTable::intern(file_name_sym, CHECK_(JVMCIObject()));
1184       HotSpotJVMCI::StackTraceElement::set_fileName(this, obj(), file_name);
1185     }
1186     HotSpotJVMCI::StackTraceElement::set_lineNumber(this, obj(), line_number);
1187     return wrap(obj());
1188   } else {
1189     JNIAccessMark jni(this, THREAD);
1190     jobject declaring_class = jni()->NewStringUTF(declaring_class_str);
1191     if (jni()->ExceptionCheck()) {
1192       return JVMCIObject();
1193     }
1194     jobject method_name = jni()->NewStringUTF(method_name_sym->as_C_string());
1195     if (jni()->ExceptionCheck()) {
1196       return JVMCIObject();
1197     }
1198     jobject file_name = nullptr;
1199     if (file_name_sym != nullptr) {
1200       file_name = jni()->NewStringUTF(file_name_sym->as_C_string());
1201       if (jni()->ExceptionCheck()) {
1202         return JVMCIObject();
1203       }
1204     }
1205 
1206     jobject result = jni()->NewObject(JNIJVMCI::StackTraceElement::clazz(),
1207                                       JNIJVMCI::StackTraceElement::constructor(),
1208                                       declaring_class, method_name, file_name, line_number);
1209     return wrap(result);
1210   }
1211 }
1212 
1213 JVMCIObject JVMCIEnv::new_HotSpotNmethod(const methodHandle& method, const char* name, jboolean isDefault, jlong compileId, JVMCI_TRAPS) {
1214   JavaThread* THREAD = JVMCI::compilation_tick(JavaThread::current()); // For exception macros.
1215 
1216   JVMCIObject methodObject = get_jvmci_method(method, JVMCI_CHECK_(JVMCIObject()));
1217 
1218   if (is_hotspot()) {
1219     InstanceKlass* ik = InstanceKlass::cast(HotSpotJVMCI::HotSpotNmethod::klass());
1220     if (ik->should_be_initialized()) {
1221       ik->initialize(CHECK_(JVMCIObject()));
1222     }
1223     oop obj = ik->allocate_instance(CHECK_(JVMCIObject()));
1224     Handle obj_h(THREAD, obj);
1225     Handle nameStr = java_lang_String::create_from_str(name, CHECK_(JVMCIObject()));
1226 
1227     // Call constructor
1228     JavaCallArguments jargs;
1229     jargs.push_oop(obj_h);
1230     jargs.push_oop(Handle(THREAD, HotSpotJVMCI::resolve(methodObject)));
1231     jargs.push_oop(nameStr);
1232     jargs.push_int(isDefault);
1233     jargs.push_long(compileId);
1234     JavaValue result(T_VOID);
1235     JavaCalls::call_special(&result, ik,
1236                             vmSymbols::object_initializer_name(),
1237                             vmSymbols::method_string_bool_long_signature(),
1238                             &jargs, CHECK_(JVMCIObject()));
1239     return wrap(obj_h());
1240   } else {
1241     JNIAccessMark jni(this, THREAD);
1242     jobject nameStr = name == nullptr ? nullptr : jni()->NewStringUTF(name);
1243     if (jni()->ExceptionCheck()) {
1244       return JVMCIObject();
1245     }
1246 
1247     jobject result = jni()->NewObject(JNIJVMCI::HotSpotNmethod::clazz(),
1248                                       JNIJVMCI::HotSpotNmethod::constructor(),
1249                                       methodObject.as_jobject(), nameStr, isDefault);
1250     return wrap(result);
1251   }
1252 }
1253 
1254 JVMCIObject JVMCIEnv::make_local(JVMCIObject object) {
1255   if (object.is_null()) {
1256     return JVMCIObject();
1257   }
1258   if (is_hotspot()) {
1259     return wrap(JNIHandles::make_local(HotSpotJVMCI::resolve(object)));
1260   } else {
1261     JNIAccessMark jni(this);
1262     return wrap(jni()->NewLocalRef(object.as_jobject()));
1263   }
1264 }
1265 
1266 JVMCIObject JVMCIEnv::make_global(JVMCIObject object) {
1267   if (object.is_null()) {
1268     return JVMCIObject();
1269   }
1270   if (is_hotspot()) {
1271     return wrap(JNIHandles::make_global(Handle(Thread::current(), HotSpotJVMCI::resolve(object))));
1272   } else {
1273     JNIAccessMark jni(this);
1274     return wrap(jni()->NewGlobalRef(object.as_jobject()));
1275   }
1276 }
1277 
1278 void JVMCIEnv::destroy_local(JVMCIObject object) {
1279   if (is_hotspot()) {
1280     JNIHandles::destroy_local(object.as_jobject());
1281   } else {
1282     JNIAccessMark jni(this);
1283     jni()->DeleteLocalRef(object.as_jobject());
1284   }
1285 }
1286 
1287 void JVMCIEnv::destroy_global(JVMCIObject object) {
1288   if (is_hotspot()) {
1289     JNIHandles::destroy_global(object.as_jobject());
1290   } else {
1291     JNIAccessMark jni(this);
1292     jni()->DeleteGlobalRef(object.as_jobject());
1293   }
1294 }
1295 
1296 const char* JVMCIEnv::klass_name(JVMCIObject object) {
1297   if (is_hotspot()) {
1298     return HotSpotJVMCI::resolve(object)->klass()->signature_name();
1299   } else {
1300     JVMCIObject name;
1301     {
1302       JNIAccessMark jni(this);
1303       jclass jcl = jni()->GetObjectClass(object.as_jobject());
1304       jobject result = jni()->CallObjectMethod(jcl, JNIJVMCI::Class_getName_method());
1305       name = JVMCIObject::create(result, is_hotspot());
1306     }
1307     return as_utf8_string(name);
1308   }
1309 }
1310 
1311 JVMCIObject JVMCIEnv::get_jvmci_method(const methodHandle& method, JVMCI_TRAPS) {
1312   JVMCIObject method_object;
1313   if (method() == nullptr) {
1314     return method_object;
1315   }
1316   JavaThread* THREAD = JVMCI::compilation_tick(JavaThread::current()); // For exception macros.
1317   JVMCIKlassHandle holder_klass(THREAD, method->method_holder());
1318   JVMCIObject holder = get_jvmci_type(holder_klass, JVMCI_CHECK_(JVMCIObject()));
1319 
1320   CompilerOracle::tag_blackhole_if_possible(method);
1321 
1322   jmetadata handle = _runtime->allocate_handle(method);
1323   jboolean exception = false;
1324   if (is_hotspot()) {
1325     JavaValue result(T_OBJECT);
1326     JavaCallArguments args;
1327     args.push_long((jlong) handle);
1328     args.push_oop(Handle(THREAD, HotSpotJVMCI::resolve(holder)));
1329     JavaCalls::call_static(&result, HotSpotJVMCI::HotSpotResolvedJavaMethodImpl::klass(),
1330                            vmSymbols::fromMetaspace_name(),
1331                            vmSymbols::method_fromMetaspace_signature(), &args, THREAD);
1332     if (HAS_PENDING_EXCEPTION) {
1333       exception = true;
1334     } else {
1335       method_object = wrap(result.get_oop());
1336     }
1337   } else {
1338     JNIAccessMark jni(this, THREAD);
1339     method_object = JNIJVMCI::wrap(jni()->CallStaticObjectMethod(JNIJVMCI::HotSpotResolvedJavaMethodImpl::clazz(),
1340                                                                   JNIJVMCI::HotSpotResolvedJavaMethodImpl_fromMetaspace_method(),
1341                                                                  (jlong) handle, holder.as_jobject()));
1342     exception = jni()->ExceptionCheck();
1343   }
1344 
1345   if (exception) {
1346     _runtime->release_handle(handle);
1347     return JVMCIObject();
1348   }
1349 
1350   assert(asMethod(method_object) == method(), "must be");
1351   if (get_HotSpotResolvedJavaMethodImpl_methodHandle(method_object) != (jlong) handle) {
1352     _runtime->release_handle(handle);
1353   }
1354   assert(!method_object.is_null(), "must be");
1355   return method_object;
1356 }
1357 
1358 JVMCIObject JVMCIEnv::get_jvmci_type(const JVMCIKlassHandle& klass, JVMCI_TRAPS) {
1359   JVMCIObject type;
1360   if (klass.is_null()) {
1361     return type;
1362   }
1363 
1364   guarantee(klass->is_klass(), "must be valid klass");
1365   guarantee(klass->is_loader_alive(), "klass must be alive");
1366 
1367   jlong pointer = (jlong) klass();
1368   JavaThread* THREAD = JVMCI::compilation_tick(JavaThread::current()); // For exception macros.
1369   jboolean exception = false;
1370   if (is_hotspot()) {
1371     CompilerThreadCanCallJava ccj(THREAD, true);
1372     JavaValue result(T_OBJECT);
1373     JavaCallArguments args;
1374     args.push_long(pointer);
1375     JavaCalls::call_static(&result,
1376                            HotSpotJVMCI::HotSpotResolvedObjectTypeImpl::klass(),
1377                            vmSymbols::fromMetaspace_name(),
1378                            vmSymbols::klass_fromMetaspace_signature(), &args, THREAD);
1379 
1380     if (HAS_PENDING_EXCEPTION) {
1381       exception = true;
1382     } else {
1383       type = wrap(result.get_oop());
1384     }
1385   } else {
1386     JNIAccessMark jni(this, THREAD);
1387 
1388     HandleMark hm(THREAD);
1389     type = JNIJVMCI::wrap(jni()->CallStaticObjectMethod(JNIJVMCI::HotSpotResolvedObjectTypeImpl::clazz(),
1390                                                         JNIJVMCI::HotSpotResolvedObjectTypeImpl_fromMetaspace_method(),
1391                                                         pointer));
1392     exception = jni()->ExceptionCheck();
1393   }
1394   if (exception) {
1395     return JVMCIObject();
1396   }
1397 
1398   assert(type.is_non_null(), "must have result");
1399   return type;
1400 }
1401 
1402 JVMCIObject JVMCIEnv::get_jvmci_constant_pool(const constantPoolHandle& cp, JVMCI_TRAPS) {
1403   JVMCIObject cp_object;
1404   jmetadata handle = _runtime->allocate_handle(cp);
1405   jboolean exception = false;
1406   JavaThread* THREAD = JVMCI::compilation_tick(JavaThread::current()); // For exception macros.
1407   if (is_hotspot()) {
1408     JavaValue result(T_OBJECT);
1409     JavaCallArguments args;
1410     args.push_long((jlong) handle);
1411     JavaCalls::call_static(&result,
1412                            HotSpotJVMCI::HotSpotConstantPool::klass(),
1413                            vmSymbols::fromMetaspace_name(),
1414                            vmSymbols::constantPool_fromMetaspace_signature(), &args, THREAD);
1415     if (HAS_PENDING_EXCEPTION) {
1416       exception = true;
1417     } else {
1418       cp_object = wrap(result.get_oop());
1419     }
1420   } else {
1421     JNIAccessMark jni(this, THREAD);
1422     cp_object = JNIJVMCI::wrap(jni()->CallStaticObjectMethod(JNIJVMCI::HotSpotConstantPool::clazz(),
1423                                                              JNIJVMCI::HotSpotConstantPool_fromMetaspace_method(),
1424                                                              (jlong) handle));
1425     exception = jni()->ExceptionCheck();
1426   }
1427 
1428   if (exception) {
1429     _runtime->release_handle(handle);
1430     return JVMCIObject();
1431   }
1432 
1433   assert(!cp_object.is_null(), "must be");
1434   // Constant pools aren't cached so this is always a newly created object using the handle
1435   assert(get_HotSpotConstantPool_constantPoolHandle(cp_object) == (jlong) handle, "must use same handle");
1436   return cp_object;
1437 }
1438 
1439 JVMCIPrimitiveArray JVMCIEnv::new_booleanArray(int length, JVMCI_TRAPS) {
1440   JavaThread* THREAD = JavaThread::current(); // For exception macros.
1441   if (is_hotspot()) {
1442     typeArrayOop result = oopFactory::new_boolArray(length, CHECK_(JVMCIObject()));
1443     return wrap(result);
1444   } else {
1445     JNIAccessMark jni(this, THREAD);
1446     jbooleanArray result = jni()->NewBooleanArray(length);
1447     return wrap(result);
1448   }
1449 }
1450 
1451 JVMCIPrimitiveArray JVMCIEnv::new_byteArray(int length, JVMCI_TRAPS) {
1452   JavaThread* THREAD = JavaThread::current(); // For exception macros.
1453   if (is_hotspot()) {
1454     typeArrayOop result = oopFactory::new_byteArray(length, CHECK_(JVMCIObject()));
1455     return wrap(result);
1456   } else {
1457     JNIAccessMark jni(this, THREAD);
1458     jbyteArray result = jni()->NewByteArray(length);
1459     return wrap(result);
1460   }
1461 }
1462 
1463 JVMCIObjectArray JVMCIEnv::new_byte_array_array(int length, JVMCI_TRAPS) {
1464   JavaThread* THREAD = JavaThread::current(); // For exception macros.
1465   if (is_hotspot()) {
1466     Klass* byteArrayArrayKlass = TypeArrayKlass::cast(Universe::byteArrayKlass())->array_klass(CHECK_(JVMCIObject()));
1467     objArrayOop result = ObjArrayKlass::cast(byteArrayArrayKlass) ->allocate(length, CHECK_(JVMCIObject()));
1468     return wrap(result);
1469   } else {
1470     JNIAccessMark jni(this, THREAD);
1471     jobjectArray result = jni()->NewObjectArray(length, JNIJVMCI::byte_array(), nullptr);
1472     return wrap(result);
1473   }
1474 }
1475 
1476 JVMCIPrimitiveArray JVMCIEnv::new_intArray(int length, JVMCI_TRAPS) {
1477   JavaThread* THREAD = JavaThread::current(); // For exception macros.
1478   if (is_hotspot()) {
1479     typeArrayOop result = oopFactory::new_intArray(length, CHECK_(JVMCIObject()));
1480     return wrap(result);
1481   } else {
1482     JNIAccessMark jni(this, THREAD);
1483     jintArray result = jni()->NewIntArray(length);
1484     return wrap(result);
1485   }
1486 }
1487 
1488 JVMCIPrimitiveArray JVMCIEnv::new_longArray(int length, JVMCI_TRAPS) {
1489   JavaThread* THREAD = JavaThread::current(); // For exception macros.
1490   if (is_hotspot()) {
1491     typeArrayOop result = oopFactory::new_longArray(length, CHECK_(JVMCIObject()));
1492     return wrap(result);
1493   } else {
1494     JNIAccessMark jni(this, THREAD);
1495     jlongArray result = jni()->NewLongArray(length);
1496     return wrap(result);
1497   }
1498 }
1499 
1500 JVMCIObject JVMCIEnv::new_VMField(JVMCIObject name, JVMCIObject type, jlong offset, jlong address, JVMCIObject value, JVMCI_TRAPS) {
1501   JavaThread* THREAD = JavaThread::current(); // For exception macros.
1502   if (is_hotspot()) {
1503     HotSpotJVMCI::VMField::klass()->initialize(CHECK_(JVMCIObject()));
1504     oop obj = HotSpotJVMCI::VMField::klass()->allocate_instance(CHECK_(JVMCIObject()));
1505     HotSpotJVMCI::VMField::set_name(this, obj, HotSpotJVMCI::resolve(name));
1506     HotSpotJVMCI::VMField::set_type(this, obj, HotSpotJVMCI::resolve(type));
1507     HotSpotJVMCI::VMField::set_offset(this, obj, offset);
1508     HotSpotJVMCI::VMField::set_address(this, obj, address);
1509     HotSpotJVMCI::VMField::set_value(this, obj, HotSpotJVMCI::resolve(value));
1510     return wrap(obj);
1511   } else {
1512     JNIAccessMark jni(this, THREAD);
1513     jobject result = jni()->NewObject(JNIJVMCI::VMField::clazz(),
1514                                     JNIJVMCI::VMField::constructor(),
1515                                     get_jobject(name), get_jobject(type), offset, address, get_jobject(value));
1516     return wrap(result);
1517   }
1518 }
1519 
1520 JVMCIObject JVMCIEnv::new_VMFlag(JVMCIObject name, JVMCIObject type, JVMCIObject value, JVMCI_TRAPS) {
1521   JavaThread* THREAD = JavaThread::current(); // For exception macros.
1522   if (is_hotspot()) {
1523     HotSpotJVMCI::VMFlag::klass()->initialize(CHECK_(JVMCIObject()));
1524     oop obj = HotSpotJVMCI::VMFlag::klass()->allocate_instance(CHECK_(JVMCIObject()));
1525     HotSpotJVMCI::VMFlag::set_name(this, obj, HotSpotJVMCI::resolve(name));
1526     HotSpotJVMCI::VMFlag::set_type(this, obj, HotSpotJVMCI::resolve(type));
1527     HotSpotJVMCI::VMFlag::set_value(this, obj, HotSpotJVMCI::resolve(value));
1528     return wrap(obj);
1529   } else {
1530     JNIAccessMark jni(this, THREAD);
1531     jobject result = jni()->NewObject(JNIJVMCI::VMFlag::clazz(),
1532                                     JNIJVMCI::VMFlag::constructor(),
1533                                     get_jobject(name), get_jobject(type), get_jobject(value));
1534     return wrap(result);
1535   }
1536 }
1537 
1538 JVMCIObject JVMCIEnv::new_VMIntrinsicMethod(JVMCIObject declaringClass, JVMCIObject name, JVMCIObject descriptor, int id, jboolean isAvailable, jboolean c1Supported, jboolean c2Supported, JVMCI_TRAPS) {
1539   JavaThread* THREAD = JavaThread::current(); // For exception macros.
1540   if (is_hotspot()) {
1541     HotSpotJVMCI::VMIntrinsicMethod::klass()->initialize(CHECK_(JVMCIObject()));
1542     oop obj = HotSpotJVMCI::VMIntrinsicMethod::klass()->allocate_instance(CHECK_(JVMCIObject()));
1543     HotSpotJVMCI::VMIntrinsicMethod::set_declaringClass(this, obj, HotSpotJVMCI::resolve(declaringClass));
1544     HotSpotJVMCI::VMIntrinsicMethod::set_name(this, obj, HotSpotJVMCI::resolve(name));
1545     HotSpotJVMCI::VMIntrinsicMethod::set_descriptor(this, obj, HotSpotJVMCI::resolve(descriptor));
1546     HotSpotJVMCI::VMIntrinsicMethod::set_id(this, obj, id);
1547     HotSpotJVMCI::VMIntrinsicMethod::set_isAvailable(this, obj, isAvailable);
1548     HotSpotJVMCI::VMIntrinsicMethod::set_c1Supported(this, obj, c1Supported);
1549     HotSpotJVMCI::VMIntrinsicMethod::set_c2Supported(this, obj, c2Supported);
1550     return wrap(obj);
1551   } else {
1552     JNIAccessMark jni(this, THREAD);
1553     jobject result = jni()->NewObject(JNIJVMCI::VMIntrinsicMethod::clazz(),
1554                                     JNIJVMCI::VMIntrinsicMethod::constructor(),
1555                                     get_jobject(declaringClass), get_jobject(name), get_jobject(descriptor), id, isAvailable, c1Supported, c2Supported);
1556     return wrap(result);
1557   }
1558 }
1559 
1560 JVMCIObject JVMCIEnv::new_HotSpotStackFrameReference(JVMCI_TRAPS) {
1561   if (is_hotspot()) {
1562     JavaThread* THREAD = JavaThread::current(); // For exception macros.
1563     HotSpotJVMCI::HotSpotStackFrameReference::klass()->initialize(CHECK_(JVMCIObject()));
1564     oop obj = HotSpotJVMCI::HotSpotStackFrameReference::klass()->allocate_instance(CHECK_(JVMCIObject()));
1565     return wrap(obj);
1566   } else {
1567     ShouldNotReachHere();
1568     return JVMCIObject();
1569   }
1570 }
1571 JVMCIObject JVMCIEnv::new_JVMCIError(JVMCI_TRAPS) {
1572   if (is_hotspot()) {
1573     JavaThread* THREAD = JavaThread::current(); // For exception macros.
1574     HotSpotJVMCI::JVMCIError::klass()->initialize(CHECK_(JVMCIObject()));
1575     oop obj = HotSpotJVMCI::JVMCIError::klass()->allocate_instance(CHECK_(JVMCIObject()));
1576     return wrap(obj);
1577   } else {
1578     ShouldNotReachHere();
1579     return JVMCIObject();
1580   }
1581 }
1582 
1583 JVMCIObject JVMCIEnv::new_FieldInfo(FieldInfo* fieldinfo, JVMCI_TRAPS) {
1584   JavaThread* THREAD = JavaThread::current(); // For exception macros.
1585   if (is_hotspot()) {
1586     HotSpotJVMCI::FieldInfo::klass()->initialize(CHECK_(JVMCIObject()));
1587     oop obj = HotSpotJVMCI::FieldInfo::klass()->allocate_instance(CHECK_(JVMCIObject()));
1588     Handle obj_h(THREAD, obj);
1589     HotSpotJVMCI::FieldInfo::set_nameIndex(JVMCIENV, obj_h(), (jint)fieldinfo->name_index());
1590     HotSpotJVMCI::FieldInfo::set_signatureIndex(JVMCIENV, obj_h(), (jint)fieldinfo->signature_index());
1591     HotSpotJVMCI::FieldInfo::set_offset(JVMCIENV, obj_h(), (jint)fieldinfo->offset());
1592     HotSpotJVMCI::FieldInfo::set_classfileFlags(JVMCIENV, obj_h(), (jint)fieldinfo->access_flags().as_field_flags());
1593     HotSpotJVMCI::FieldInfo::set_internalFlags(JVMCIENV, obj_h(), (jint)fieldinfo->field_flags().as_uint());
1594     HotSpotJVMCI::FieldInfo::set_initializerIndex(JVMCIENV, obj_h(), (jint)fieldinfo->initializer_index());
1595     return wrap(obj_h());
1596   } else {
1597     JNIAccessMark jni(this, THREAD);
1598     jobject result = jni()->NewObject(JNIJVMCI::FieldInfo::clazz(),
1599                                       JNIJVMCI::FieldInfo::constructor(),
1600                                       (jint)fieldinfo->name_index(),
1601                                       (jint)fieldinfo->signature_index(),
1602                                       (jint)fieldinfo->offset(),
1603                                       (jint)fieldinfo->access_flags().as_field_flags(),
1604                                       (jint)fieldinfo->field_flags().as_uint(),
1605                                       (jint)fieldinfo->initializer_index());
1606 
1607     return wrap(result);
1608   }
1609 }
1610 
1611 JVMCIObject JVMCIEnv::get_object_constant(oop objOop, bool compressed, bool dont_register) {
1612   JavaThread* THREAD = JavaThread::current(); // For exception macros.
1613   Handle obj = Handle(THREAD, objOop);
1614   if (obj.is_null()) {
1615     return JVMCIObject();
1616   }
1617   if (is_hotspot()) {
1618     HotSpotJVMCI::DirectHotSpotObjectConstantImpl::klass()->initialize(CHECK_(JVMCIObject()));
1619     oop constant = HotSpotJVMCI::DirectHotSpotObjectConstantImpl::klass()->allocate_instance(CHECK_(JVMCIObject()));
1620     HotSpotJVMCI::DirectHotSpotObjectConstantImpl::set_object(this, constant, obj());
1621     HotSpotJVMCI::HotSpotObjectConstantImpl::set_compressed(this, constant, compressed);
1622     return wrap(constant);
1623   } else {
1624     jlong handle = make_oop_handle(obj);
1625     JNIAccessMark jni(this, THREAD);
1626     jobject result = jni()->NewObject(JNIJVMCI::IndirectHotSpotObjectConstantImpl::clazz(),
1627                                       JNIJVMCI::IndirectHotSpotObjectConstantImpl::constructor(),
1628                                       handle, compressed, dont_register);
1629     return wrap(result);
1630   }
1631 }
1632 
1633 
1634 Handle JVMCIEnv::asConstant(JVMCIObject constant, JVMCI_TRAPS) {
1635   if (constant.is_null()) {
1636     return Handle();
1637   }
1638   JavaThread* THREAD = JavaThread::current(); // For exception macros.
1639   if (is_hotspot()) {
1640     assert(HotSpotJVMCI::DirectHotSpotObjectConstantImpl::is_instance(this, constant), "wrong type");
1641     oop obj = HotSpotJVMCI::DirectHotSpotObjectConstantImpl::object(this, HotSpotJVMCI::resolve(constant));
1642     return Handle(THREAD, obj);
1643   } else if (isa_IndirectHotSpotObjectConstantImpl(constant)) {
1644     jlong object_handle = get_IndirectHotSpotObjectConstantImpl_objectHandle(constant);
1645     if (object_handle == 0L) {
1646       JVMCI_THROW_MSG_(NullPointerException, "Foreign object reference has been cleared", Handle());
1647     }
1648     oop result = resolve_oop_handle(object_handle);
1649     if (result == nullptr) {
1650       JVMCI_THROW_MSG_(InternalError, "Constant was unexpectedly null", Handle());
1651     }
1652     return Handle(THREAD, result);
1653   } else {
1654     JVMCI_THROW_MSG_(IllegalArgumentException, "DirectHotSpotObjectConstantImpl shouldn't reach JVMCI in SVM mode", Handle());
1655   }
1656 }
1657 
1658 JVMCIObject JVMCIEnv::wrap(jobject object) {
1659   return JVMCIObject::create(object, is_hotspot());
1660 }
1661 
1662 jlong JVMCIEnv::make_oop_handle(const Handle& obj) {
1663   assert(!obj.is_null(), "should only create handle for non-null oops");
1664   return _runtime->make_oop_handle(obj);
1665 }
1666 
1667 oop JVMCIEnv::resolve_oop_handle(jlong oopHandle) {
1668   assert(oopHandle != 0, "should be a valid handle");
1669   oop obj = NativeAccess<>::oop_load(reinterpret_cast<oop*>(oopHandle));
1670   if (obj != nullptr) {
1671     guarantee(oopDesc::is_oop_or_null(obj), "invalid oop: " INTPTR_FORMAT, p2i((oopDesc*) obj));
1672   }
1673   return obj;
1674 }
1675 
1676 JVMCIObject JVMCIEnv::create_string(const char* str, JVMCI_TRAPS) {
1677   JavaThread* THREAD = JavaThread::current(); // For exception macros.
1678   if (is_hotspot()) {
1679     Handle result = java_lang_String::create_from_str(str, CHECK_(JVMCIObject()));
1680     return HotSpotJVMCI::wrap(result());
1681   } else {
1682     jobject result;
1683     jboolean exception = false;
1684     {
1685       JNIAccessMark jni(this, THREAD);
1686       result = jni()->NewStringUTF(str);
1687       exception = jni()->ExceptionCheck();
1688     }
1689     return wrap(result);
1690   }
1691 }
1692 
1693 bool JVMCIEnv::equals(JVMCIObject a, JVMCIObject b) {
1694   if (is_hotspot()) {
1695     return HotSpotJVMCI::resolve(a) == HotSpotJVMCI::resolve(b);
1696   } else {
1697     JNIAccessMark jni(this);
1698     return jni()->IsSameObject(a.as_jobject(), b.as_jobject()) != 0;
1699   }
1700 }
1701 
1702 BasicType JVMCIEnv::typeCharToBasicType(jchar ch, JVMCI_TRAPS) {
1703   switch(ch) {
1704     case 'Z': return T_BOOLEAN;
1705     case 'B': return T_BYTE;
1706     case 'S': return T_SHORT;
1707     case 'C': return T_CHAR;
1708     case 'I': return T_INT;
1709     case 'F': return T_FLOAT;
1710     case 'J': return T_LONG;
1711     case 'D': return T_DOUBLE;
1712     case 'A': return T_OBJECT;
1713     case '-': return T_ILLEGAL;
1714     default:
1715       JVMCI_ERROR_(T_ILLEGAL, "unexpected type char: %c", ch);
1716   }
1717 }
1718 
1719 BasicType JVMCIEnv::kindToBasicType(JVMCIObject kind, JVMCI_TRAPS) {
1720   if (kind.is_null()) {
1721     JVMCI_THROW_(NullPointerException, T_ILLEGAL);
1722   }
1723   jchar ch = get_JavaKind_typeChar(kind);
1724   BasicType bt = typeCharToBasicType(ch, JVMCI_CHECK_(T_ILLEGAL));
1725   return bt;
1726 }
1727 
1728 void JVMCIEnv::initialize_installed_code(JVMCIObject installed_code, CodeBlob* cb, JVMCI_TRAPS) {
1729   // Ensure that all updates to the InstalledCode fields are consistent.
1730   if (get_InstalledCode_address(installed_code) != 0) {
1731     JVMCI_THROW_MSG(InternalError, "InstalledCode instance already in use");
1732   }
1733   if (!isa_HotSpotInstalledCode(installed_code)) {
1734     JVMCI_THROW_MSG(InternalError, "InstalledCode instance must be a subclass of HotSpotInstalledCode");
1735   }
1736 
1737   // Ignore the version which can stay at 0
1738   if (cb->is_nmethod()) {
1739     nmethod* nm = cb->as_nmethod_or_null();
1740     if (nm->is_in_use()) {
1741       set_InstalledCode_entryPoint(installed_code, (jlong) nm->verified_entry_point());
1742     }
1743   } else {
1744     set_InstalledCode_entryPoint(installed_code, (jlong) cb->code_begin());
1745   }
1746   set_InstalledCode_address(installed_code, (jlong) cb);
1747   set_HotSpotInstalledCode_size(installed_code, cb->size());
1748   set_HotSpotInstalledCode_codeStart(installed_code, (jlong) cb->code_begin());
1749   set_HotSpotInstalledCode_codeSize(installed_code, cb->code_size());
1750 }
1751 
1752 
1753 void JVMCIEnv::invalidate_nmethod_mirror(JVMCIObject mirror, bool deoptimize, JVMCI_TRAPS) {
1754   if (mirror.is_null()) {
1755     JVMCI_THROW(NullPointerException);
1756   }
1757 
1758   Thread* current = Thread::current();
1759   if (!mirror.is_hotspot() && !current->is_Java_thread()) {
1760     // Calling back into native might cause the execution to block, so only allow this when calling
1761     // from a JavaThread, which is the normal case anyway.
1762     JVMCI_THROW_MSG(IllegalArgumentException,
1763                     "Cannot invalidate HotSpotNmethod object in shared library VM heap from non-JavaThread");
1764   }
1765 
1766   JavaThread* thread = JavaThread::cast(current);
1767   JVMCINMethodHandle nmethod_handle(thread);
1768   nmethod* nm = JVMCIENV->get_nmethod(mirror, nmethod_handle);
1769   if (nm == nullptr) {
1770     // Nothing to do
1771     return;
1772   }
1773 
1774   if (!deoptimize) {
1775     // Prevent future executions of the nmethod but let current executions complete.
1776     nm->make_not_entrant("JVMCI invalidate nmethod mirror");
1777 
1778     // Do not clear the address field here as the Java code may still
1779     // want to later call this method with deoptimize == true. That requires
1780     // the address field to still be pointing at the nmethod.
1781    } else {
1782     // Deoptimize the nmethod immediately.
1783     DeoptimizationScope deopt_scope;
1784     deopt_scope.mark(nm);
1785     nm->make_not_entrant("JVMCI invalidate nmethod mirror");
1786     nm->make_deoptimized();
1787     deopt_scope.deoptimize_marked();
1788 
1789     // A HotSpotNmethod instance can only reference a single nmethod
1790     // during its lifetime so simply clear it here.
1791     set_InstalledCode_address(mirror, 0);
1792   }
1793 }
1794 
1795 Klass* JVMCIEnv::asKlass(JVMCIObject obj) {
1796   return (Klass*) get_HotSpotResolvedObjectTypeImpl_klassPointer(obj);
1797 }
1798 
1799 Method* JVMCIEnv::asMethod(JVMCIObject obj) {
1800   Method** methodHandle = (Method**) get_HotSpotResolvedJavaMethodImpl_methodHandle(obj);
1801   return *methodHandle;
1802 }
1803 
1804 ConstantPool* JVMCIEnv::asConstantPool(JVMCIObject obj) {
1805   ConstantPool** constantPoolHandle = (ConstantPool**) get_HotSpotConstantPool_constantPoolHandle(obj);
1806   return *constantPoolHandle;
1807 }
1808 
1809 MethodData* JVMCIEnv::asMethodData(JVMCIObject obj) {
1810   return (MethodData*) get_HotSpotMethodData_methodDataPointer(obj);
1811 }
1812 
1813 // Lookup an nmethod with a matching base and compile id
1814 nmethod* JVMCIEnv::lookup_nmethod(address code, jlong compile_id_snapshot) {
1815   if (code == nullptr) {
1816     return nullptr;
1817   }
1818 
1819   CodeBlob* cb = CodeCache::find_blob(code);
1820   if (cb == (CodeBlob*) code) {
1821     nmethod* nm = cb->as_nmethod_or_null();
1822     if (nm != nullptr && (compile_id_snapshot == 0 || nm->compile_id() == compile_id_snapshot)) {
1823       return nm;
1824     }
1825   }
1826   return nullptr;
1827 }
1828 
1829 
1830 CodeBlob* JVMCIEnv::get_code_blob(JVMCIObject obj) {
1831   address code = (address) get_InstalledCode_address(obj);
1832   if (code == nullptr) {
1833     return nullptr;
1834   }
1835   if (isa_HotSpotNmethod(obj)) {
1836     jlong compile_id_snapshot = get_HotSpotNmethod_compileIdSnapshot(obj);
1837     nmethod* nm = lookup_nmethod(code, compile_id_snapshot);
1838     if (nm != nullptr && compile_id_snapshot != 0L && nm->is_not_entrant()) {
1839       // Zero the entry point so that the nmethod
1840       // cannot be invoked by the mirror but can
1841       // still be deoptimized.
1842       set_InstalledCode_entryPoint(obj, 0);
1843       // Refetch the nmethod since the previous call will be a safepoint in libjvmci
1844       nm = lookup_nmethod(code, compile_id_snapshot);
1845     }
1846 
1847     if (nm == nullptr) {
1848       // The HotSpotNmethod was pointing at some nmethod but the nmethod is no longer valid, so
1849       // clear the InstalledCode fields of this HotSpotNmethod so that it no longer refers to a
1850       // nmethod in the code cache.
1851       set_InstalledCode_address(obj, 0);
1852       set_InstalledCode_entryPoint(obj, 0);
1853       set_HotSpotInstalledCode_codeStart(obj, 0);
1854     }
1855     return nm;
1856   }
1857 
1858   CodeBlob* cb = (CodeBlob*) code;
1859   assert(!cb->is_nmethod(), "unexpected nmethod");
1860   return cb;
1861 }
1862 
1863 void JVMCINMethodHandle::set_nmethod(nmethod* nm) {
1864   BarrierSetNMethod* bs_nm = BarrierSet::barrier_set()->barrier_set_nmethod();
1865   bs_nm->nmethod_entry_barrier(nm);
1866   _thread->set_live_nmethod(nm);
1867 }
1868 
1869 nmethod* JVMCIEnv::get_nmethod(JVMCIObject obj, JVMCINMethodHandle& nmethod_handle) {
1870   CodeBlob* cb = get_code_blob(obj);
1871   if (cb != nullptr) {
1872     nmethod* nm = cb->as_nmethod_or_null();
1873     if (nm != nullptr) {
1874       nmethod_handle.set_nmethod(nm);
1875       return nm;
1876     }
1877   }
1878   return nullptr;
1879 }
1880 
1881 // Generate implementations for the initialize, new, isa, get and set methods for all the types and
1882 // fields declared in the JVMCI_CLASSES_DO macro.
1883 
1884 #define START_CLASS(className, fullClassName)                                                                        \
1885   void JVMCIEnv::className##_initialize(JVMCI_TRAPS) {                                                               \
1886     if (is_hotspot()) {                                                                                              \
1887       HotSpotJVMCI::className::initialize(JVMCI_CHECK);                                                              \
1888     } else {                                                                                                         \
1889       JNIJVMCI::className::initialize(JVMCI_CHECK);                                                                  \
1890     }                                                                                                                \
1891   }                                                                                                                  \
1892   JVMCIObjectArray JVMCIEnv::new_##className##_array(int length, JVMCI_TRAPS) {                                      \
1893     if (is_hotspot()) {                                                                                              \
1894       JavaThread* THREAD = JavaThread::current(); /* For exception macros. */ \
1895       objArrayOop array = oopFactory::new_objArray(HotSpotJVMCI::className::klass(), length, CHECK_(JVMCIObject())); \
1896       return (JVMCIObjectArray) wrap(array);                                                                         \
1897     } else {                                                                                                         \
1898       JNIAccessMark jni(this);                                                                                       \
1899       jobjectArray result = jni()->NewObjectArray(length, JNIJVMCI::className::clazz(), nullptr);                    \
1900       return wrap(result);                                                                                           \
1901     }                                                                                                                \
1902   }                                                                                                                  \
1903   bool JVMCIEnv::isa_##className(JVMCIObject object) {                                                               \
1904     if (is_hotspot()) {                                                                                              \
1905       return HotSpotJVMCI::className::is_instance(this, object);                                                     \
1906     } else {                                                                                                         \
1907       return JNIJVMCI::className::is_instance(this, object);                                                         \
1908     }                                                                                                                \
1909   }
1910 
1911 #define END_CLASS
1912 
1913 #define FIELD(className, name, type, accessor, cast)                 \
1914   type JVMCIEnv::get_##className##_##name(JVMCIObject obj) {         \
1915     if (is_hotspot()) {                                              \
1916       return HotSpotJVMCI::className::get_##name(this, obj);         \
1917     } else {                                                         \
1918       return JNIJVMCI::className::get_##name(this, obj);             \
1919     }                                                                \
1920   }                                                                  \
1921   void JVMCIEnv::set_##className##_##name(JVMCIObject obj, type x) { \
1922     if (is_hotspot()) {                                              \
1923       HotSpotJVMCI::className::set_##name(this, obj, x);             \
1924     } else {                                                         \
1925       JNIJVMCI::className::set_##name(this, obj, x);                 \
1926     }                                                                \
1927   }
1928 
1929 #define EMPTY_CAST
1930 #define CHAR_FIELD(className, name)                    FIELD(className, name, jchar, Char, EMPTY_CAST)
1931 #define INT_FIELD(className, name)                     FIELD(className, name, jint, Int, EMPTY_CAST)
1932 #define BOOLEAN_FIELD(className, name)                 FIELD(className, name, jboolean, Boolean, EMPTY_CAST)
1933 #define LONG_FIELD(className, name)                    FIELD(className, name, jlong, Long, EMPTY_CAST)
1934 #define FLOAT_FIELD(className, name)                   FIELD(className, name, jfloat, Float, EMPTY_CAST)
1935 
1936 #define OBJECT_FIELD(className, name, signature)              OOPISH_FIELD(className, name, JVMCIObject, Object, EMPTY_CAST)
1937 #define OBJECTARRAY_FIELD(className, name, signature)         OOPISH_FIELD(className, name, JVMCIObjectArray, Object, (JVMCIObjectArray))
1938 #define PRIMARRAY_FIELD(className, name, signature)           OOPISH_FIELD(className, name, JVMCIPrimitiveArray, Object, (JVMCIPrimitiveArray))
1939 
1940 #define STATIC_OBJECT_FIELD(className, name, signature)       STATIC_OOPISH_FIELD(className, name, JVMCIObject, Object, (JVMCIObject))
1941 #define STATIC_OBJECTARRAY_FIELD(className, name, signature)  STATIC_OOPISH_FIELD(className, name, JVMCIObjectArray, Object, (JVMCIObjectArray))
1942 
1943 #define OOPISH_FIELD(className, name, type, accessor, cast)           \
1944   type JVMCIEnv::get_##className##_##name(JVMCIObject obj) {          \
1945     if (is_hotspot()) {                                               \
1946       return HotSpotJVMCI::className::get_##name(this, obj);          \
1947     } else {                                                          \
1948       return JNIJVMCI::className::get_##name(this, obj);              \
1949     }                                                                 \
1950   }                                                                   \
1951   void JVMCIEnv::set_##className##_##name(JVMCIObject obj, type x) {  \
1952     if (is_hotspot()) {                                               \
1953       HotSpotJVMCI::className::set_##name(this, obj, x);              \
1954     } else {                                                          \
1955       JNIJVMCI::className::set_##name(this, obj, x);                  \
1956     }                                                                 \
1957   }
1958 
1959 #define STATIC_OOPISH_FIELD(className, name, type, accessor, cast)    \
1960   type JVMCIEnv::get_##className##_##name() {                         \
1961     if (is_hotspot()) {                                               \
1962       return HotSpotJVMCI::className::get_##name(this);               \
1963     } else {                                                          \
1964       return JNIJVMCI::className::get_##name(this);                   \
1965     }                                                                 \
1966   }                                                                   \
1967   void JVMCIEnv::set_##className##_##name(type x) {                   \
1968     if (is_hotspot()) {                                               \
1969       HotSpotJVMCI::className::set_##name(this, x);                   \
1970     } else {                                                          \
1971       JNIJVMCI::className::set_##name(this, x);                       \
1972     }                                                                 \
1973   }
1974 
1975 #define STATIC_PRIMITIVE_FIELD(className, name, type, accessor, cast) \
1976   type JVMCIEnv::get_##className##_##name() {                         \
1977     if (is_hotspot()) {                                               \
1978       return HotSpotJVMCI::className::get_##name(this);               \
1979     } else {                                                          \
1980       return JNIJVMCI::className::get_##name(this);                   \
1981     }                                                                 \
1982   }                                                                   \
1983   void JVMCIEnv::set_##className##_##name(type x) {                   \
1984     if (is_hotspot()) {                                               \
1985       HotSpotJVMCI::className::set_##name(this, x);                   \
1986     } else {                                                          \
1987       JNIJVMCI::className::set_##name(this, x);                       \
1988     }                                                                 \
1989   }
1990 #define STATIC_INT_FIELD(className, name) STATIC_PRIMITIVE_FIELD(className, name, jint, Int, EMPTY_CAST)
1991 #define STATIC_BOOLEAN_FIELD(className, name) STATIC_PRIMITIVE_FIELD(className, name, jboolean, Boolean, EMPTY_CAST)
1992 #define METHOD(jniCallType, jniGetMethod, hsCallType, returnType, className, methodName, signatureSymbolName)
1993 #define CONSTRUCTOR(className, signature)
1994 
1995 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)
1996 
1997 #undef START_CLASS
1998 #undef END_CLASS
1999 #undef METHOD
2000 #undef CONSTRUCTOR
2001 #undef FIELD
2002 #undef CHAR_FIELD
2003 #undef INT_FIELD
2004 #undef BOOLEAN_FIELD
2005 #undef LONG_FIELD
2006 #undef FLOAT_FIELD
2007 #undef OBJECT_FIELD
2008 #undef PRIMARRAY_FIELD
2009 #undef OBJECTARRAY_FIELD
2010 #undef STATIC_OOPISH_FIELD
2011 #undef STATIC_OBJECT_FIELD
2012 #undef STATIC_OBJECTARRAY_FIELD
2013 #undef STATIC_INT_FIELD
2014 #undef STATIC_BOOLEAN_FIELD
2015 #undef EMPTY_CAST