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_refArray(), "must be");
 359         refArrayOop pair_arr = refArrayOop(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, JVMCI_TRAPS) {
 682   if (is_hotspot()) {
 683     JavaThread* THREAD = JavaThread::current(); // For exception macros.
 684     oop result = HotSpotJVMCI::resolve(array)->obj_at(index, CHECK_({}));
 685     return wrap(result);
 686   } else {
 687     JNIAccessMark jni(this);
 688     jobject result = jni()->GetObjectArrayElement(get_jobjectArray(array), index);
 689     return wrap(result);
 690   }
 691 }
 692 
 693 void JVMCIEnv::put_object_at(JVMCIObjectArray array, int index, JVMCIObject value) {
 694   if (is_hotspot()) {
 695     HotSpotJVMCI::resolve(array)->obj_at_put(index, HotSpotJVMCI::resolve(value));
 696   } else {
 697     JNIAccessMark jni(this);
 698     jni()->SetObjectArrayElement(get_jobjectArray(array), index, get_jobject(value));
 699   }
 700 }
 701 
 702 jboolean JVMCIEnv::get_bool_at(JVMCIPrimitiveArray array, int index) {
 703   if (is_hotspot()) {
 704     return HotSpotJVMCI::resolve(array)->bool_at(index);
 705   } else {
 706     JNIAccessMark jni(this);
 707     jboolean result;
 708     jni()->GetBooleanArrayRegion(array.as_jbooleanArray(), index, 1, &result);
 709     return result;
 710   }
 711 }
 712 void JVMCIEnv::put_bool_at(JVMCIPrimitiveArray array, int index, jboolean value) {
 713   if (is_hotspot()) {
 714     HotSpotJVMCI::resolve(array)->bool_at_put(index, value);
 715   } else {
 716     JNIAccessMark jni(this);
 717     jni()->SetBooleanArrayRegion(array.as_jbooleanArray(), index, 1, &value);
 718   }
 719 }
 720 
 721 jbyte JVMCIEnv::get_byte_at(JVMCIPrimitiveArray array, int index) {
 722   if (is_hotspot()) {
 723     return HotSpotJVMCI::resolve(array)->byte_at(index);
 724   } else {
 725     JNIAccessMark jni(this);
 726     jbyte result;
 727     jni()->GetByteArrayRegion(array.as_jbyteArray(), index, 1, &result);
 728     return result;
 729   }
 730 }
 731 void JVMCIEnv::put_byte_at(JVMCIPrimitiveArray array, int index, jbyte value) {
 732   if (is_hotspot()) {
 733     HotSpotJVMCI::resolve(array)->byte_at_put(index, value);
 734   } else {
 735     JNIAccessMark jni(this);
 736     jni()->SetByteArrayRegion(array.as_jbyteArray(), index, 1, &value);
 737   }
 738 }
 739 
 740 jint JVMCIEnv::get_int_at(JVMCIPrimitiveArray array, int index) {
 741   if (is_hotspot()) {
 742     return HotSpotJVMCI::resolve(array)->int_at(index);
 743   } else {
 744     JNIAccessMark jni(this);
 745     jint result;
 746     jni()->GetIntArrayRegion(array.as_jintArray(), index, 1, &result);
 747     return result;
 748   }
 749 }
 750 void JVMCIEnv::put_int_at(JVMCIPrimitiveArray array, int index, jint value) {
 751   if (is_hotspot()) {
 752     HotSpotJVMCI::resolve(array)->int_at_put(index, value);
 753   } else {
 754     JNIAccessMark jni(this);
 755     jni()->SetIntArrayRegion(array.as_jintArray(), index, 1, &value);
 756   }
 757 }
 758 
 759 jlong JVMCIEnv::get_long_at(JVMCIPrimitiveArray array, int index) {
 760   if (is_hotspot()) {
 761     return HotSpotJVMCI::resolve(array)->long_at(index);
 762   } else {
 763     JNIAccessMark jni(this);
 764     jlong result;
 765     jni()->GetLongArrayRegion(array.as_jlongArray(), index, 1, &result);
 766     return result;
 767   }
 768 }
 769 void JVMCIEnv::put_long_at(JVMCIPrimitiveArray array, int index, jlong value) {
 770   if (is_hotspot()) {
 771     HotSpotJVMCI::resolve(array)->long_at_put(index, value);
 772   } else {
 773     JNIAccessMark jni(this);
 774     jni()->SetLongArrayRegion(array.as_jlongArray(), index, 1, &value);
 775   }
 776 }
 777 
 778 void JVMCIEnv::copy_bytes_to(JVMCIPrimitiveArray src, jbyte* dest, int offset, jsize length) {
 779   if (length == 0) {
 780     return;
 781   }
 782   if (is_hotspot()) {
 783     memcpy(dest, HotSpotJVMCI::resolve(src)->byte_at_addr(offset), length);
 784   } else {
 785     JNIAccessMark jni(this);
 786     jni()->GetByteArrayRegion(src.as_jbyteArray(), offset, length, dest);
 787   }
 788 }
 789 void JVMCIEnv::copy_bytes_from(jbyte* src, JVMCIPrimitiveArray dest, int offset, jsize length) {
 790   if (length == 0) {
 791     return;
 792   }
 793   if (is_hotspot()) {
 794     memcpy(HotSpotJVMCI::resolve(dest)->byte_at_addr(offset), src, length);
 795   } else {
 796     JNIAccessMark jni(this);
 797     jni()->SetByteArrayRegion(dest.as_jbyteArray(), offset, length, src);
 798   }
 799 }
 800 
 801 void JVMCIEnv::copy_longs_from(jlong* src, JVMCIPrimitiveArray dest, int offset, jsize length) {
 802   if (length == 0) {
 803     return;
 804   }
 805   if (is_hotspot()) {
 806     memcpy(HotSpotJVMCI::resolve(dest)->long_at_addr(offset), src, length * sizeof(jlong));
 807   } else {
 808     JNIAccessMark jni(this);
 809     jni()->SetLongArrayRegion(dest.as_jlongArray(), offset, length, src);
 810   }
 811 }
 812 
 813 jboolean JVMCIEnv::is_boxing_object(BasicType type, JVMCIObject object) {
 814   if (is_hotspot()) {
 815     return java_lang_boxing_object::is_instance(HotSpotJVMCI::resolve(object), type);
 816   } else {
 817     JNIAccessMark jni(this);
 818     return jni()->IsInstanceOf(get_jobject(object), JNIJVMCI::box_class(type));
 819   }
 820 }
 821 
 822 // Get the primitive value from a Java boxing object.  It's hard error to
 823 // pass a non-primitive BasicType.
 824 jvalue JVMCIEnv::get_boxed_value(BasicType type, JVMCIObject object) {
 825   jvalue result;
 826   if (is_hotspot()) {
 827     if (java_lang_boxing_object::get_value(HotSpotJVMCI::resolve(object), &result) == T_ILLEGAL) {
 828       ShouldNotReachHere();
 829     }
 830   } else {
 831     JNIAccessMark jni(this);
 832     jfieldID field = JNIJVMCI::box_field(type);
 833     switch (type) {
 834       case T_BOOLEAN: result.z = jni()->GetBooleanField(get_jobject(object), field); break;
 835       case T_BYTE:    result.b = jni()->GetByteField(get_jobject(object), field); break;
 836       case T_SHORT:   result.s = jni()->GetShortField(get_jobject(object), field); break;
 837       case T_CHAR:    result.c = jni()->GetCharField(get_jobject(object), field); break;
 838       case T_INT:     result.i = jni()->GetIntField(get_jobject(object), field); break;
 839       case T_LONG:    result.j = jni()->GetLongField(get_jobject(object), field); break;
 840       case T_FLOAT:   result.f = jni()->GetFloatField(get_jobject(object), field); break;
 841       case T_DOUBLE:  result.d = jni()->GetDoubleField(get_jobject(object), field); break;
 842       default:
 843         ShouldNotReachHere();
 844     }
 845   }
 846   return result;
 847 }
 848 
 849 // Return the BasicType of the object if it's a boxing object, otherwise return T_ILLEGAL.
 850 BasicType JVMCIEnv::get_box_type(JVMCIObject object) {
 851   if (is_hotspot()) {
 852     return java_lang_boxing_object::basic_type(HotSpotJVMCI::resolve(object));
 853   } else {
 854     JNIAccessMark jni(this);
 855     jclass clazz = jni()->GetObjectClass(get_jobject(object));
 856     if (jni()->IsSameObject(clazz, JNIJVMCI::box_class(T_BOOLEAN))) return T_BOOLEAN;
 857     if (jni()->IsSameObject(clazz, JNIJVMCI::box_class(T_BYTE))) return T_BYTE;
 858     if (jni()->IsSameObject(clazz, JNIJVMCI::box_class(T_SHORT))) return T_SHORT;
 859     if (jni()->IsSameObject(clazz, JNIJVMCI::box_class(T_CHAR))) return T_CHAR;
 860     if (jni()->IsSameObject(clazz, JNIJVMCI::box_class(T_INT))) return T_INT;
 861     if (jni()->IsSameObject(clazz, JNIJVMCI::box_class(T_LONG))) return T_LONG;
 862     if (jni()->IsSameObject(clazz, JNIJVMCI::box_class(T_FLOAT))) return T_FLOAT;
 863     if (jni()->IsSameObject(clazz, JNIJVMCI::box_class(T_DOUBLE))) return T_DOUBLE;
 864     return T_ILLEGAL;
 865   }
 866 }
 867 
 868 // Create a boxing object of the appropriate primitive type.
 869 JVMCIObject JVMCIEnv::create_box(BasicType type, jvalue* value, JVMCI_TRAPS) {
 870   switch (type) {
 871     case T_BOOLEAN:
 872     case T_BYTE:
 873     case T_CHAR:
 874     case T_SHORT:
 875     case T_INT:
 876     case T_LONG:
 877     case T_FLOAT:
 878     case T_DOUBLE:
 879       break;
 880     default:
 881       JVMCI_THROW_MSG_(IllegalArgumentException, "Only boxes for primitive values can be created", JVMCIObject());
 882   }
 883   JavaThread* THREAD = JavaThread::current(); // For exception macros.
 884   if (is_hotspot()) {
 885     oop box = java_lang_boxing_object::create(type, value, CHECK_(JVMCIObject()));
 886     return HotSpotJVMCI::wrap(box);
 887   } else {
 888     JNIAccessMark jni(this, THREAD);
 889     jobject box = jni()->NewObjectA(JNIJVMCI::box_class(type), JNIJVMCI::box_constructor(type), value);
 890     assert(box != nullptr, "");
 891     return wrap(box);
 892   }
 893 }
 894 
 895 const char* JVMCIEnv::as_utf8_string(JVMCIObject str) {
 896   if (is_hotspot()) {
 897     return java_lang_String::as_utf8_string(HotSpotJVMCI::resolve(str));
 898   } else {
 899     JNIAccessMark jni(this);
 900     jstring jstr = str.as_jstring();
 901     int length = jni()->GetStringLength(jstr);
 902     int utf8_length = jni()->GetStringUTFLength(jstr);
 903     char* result = NEW_RESOURCE_ARRAY(char, utf8_length + 1);
 904     jni()->GetStringUTFRegion(jstr, 0, length, result);
 905     return result;
 906   }
 907 }
 908 
 909 #define DO_THROW(name)                             \
 910 void JVMCIEnv::throw_##name(const char* msg) {     \
 911   if (is_hotspot()) {                              \
 912     JavaThread* THREAD = JavaThread::current();    \
 913     THROW_MSG(HotSpotJVMCI::name::symbol(), msg);  \
 914   } else {                                         \
 915     JNIAccessMark jni(this);                       \
 916     jni()->ThrowNew(JNIJVMCI::name::clazz(), msg); \
 917   }                                                \
 918 }
 919 
 920 DO_THROW(InternalError)
 921 DO_THROW(ArrayIndexOutOfBoundsException)
 922 DO_THROW(IllegalStateException)
 923 DO_THROW(NullPointerException)
 924 DO_THROW(IllegalArgumentException)
 925 DO_THROW(InvalidInstalledCodeException)
 926 DO_THROW(UnsatisfiedLinkError)
 927 DO_THROW(UnsupportedOperationException)
 928 DO_THROW(OutOfMemoryError)
 929 DO_THROW(NoClassDefFoundError)
 930 
 931 #undef DO_THROW
 932 
 933 void JVMCIEnv::fthrow_error(const char* file, int line, const char* format, ...) {
 934   const int max_msg_size = 1024;
 935   va_list ap;
 936   va_start(ap, format);
 937   char msg[max_msg_size];
 938   (void) os::vsnprintf(msg, max_msg_size, format, ap);
 939   va_end(ap);
 940   JavaThread* THREAD = JavaThread::current();
 941   if (is_hotspot()) {
 942     Handle h_loader;
 943     Exceptions::_throw_msg(THREAD, file, line, vmSymbols::jdk_vm_ci_common_JVMCIError(), msg, h_loader );
 944   } else {
 945     JNIAccessMark jni(this, THREAD);
 946     jni()->ThrowNew(JNIJVMCI::JVMCIError::clazz(), msg);
 947   }
 948 }
 949 
 950 jboolean JVMCIEnv::call_HotSpotJVMCIRuntime_isGCSupported (JVMCIObject runtime, jint gcIdentifier) {
 951   JavaThread* THREAD = JavaThread::current(); // For exception macros.
 952   if (is_hotspot()) {
 953     JavaCallArguments jargs;
 954     jargs.push_oop(Handle(THREAD, HotSpotJVMCI::resolve(runtime)));
 955     jargs.push_int(gcIdentifier);
 956     JavaValue result(T_BOOLEAN);
 957     JavaCalls::call_special(&result,
 958                             HotSpotJVMCI::HotSpotJVMCIRuntime::klass(),
 959                             vmSymbols::isGCSupported_name(),
 960                             vmSymbols::int_bool_signature(), &jargs, CHECK_0);
 961     return result.get_jboolean();
 962   } else {
 963     JNIAccessMark jni(this, THREAD);
 964     jboolean result = jni()->CallNonvirtualBooleanMethod(runtime.as_jobject(),
 965                                                      JNIJVMCI::HotSpotJVMCIRuntime::clazz(),
 966                                                      JNIJVMCI::HotSpotJVMCIRuntime::isGCSupported_method(),
 967                                                      gcIdentifier);
 968     if (jni()->ExceptionCheck()) {
 969       return false;
 970     }
 971     return result;
 972   }
 973 }
 974 
 975 jboolean JVMCIEnv::call_HotSpotJVMCIRuntime_isIntrinsicSupported (JVMCIObject runtime, jint intrinsicIdentifier) {
 976   JavaThread* THREAD = JavaThread::current(); // For exception macros.
 977   if (is_hotspot()) {
 978     JavaCallArguments jargs;
 979     jargs.push_oop(Handle(THREAD, HotSpotJVMCI::resolve(runtime)));
 980     jargs.push_int(intrinsicIdentifier);
 981     JavaValue result(T_BOOLEAN);
 982     JavaCalls::call_special(&result,
 983                             HotSpotJVMCI::HotSpotJVMCIRuntime::klass(),
 984                             vmSymbols::isIntrinsicSupported_name(),
 985                             vmSymbols::int_bool_signature(), &jargs, CHECK_0);
 986     return result.get_jboolean();
 987   } else {
 988     JNIAccessMark jni(this, THREAD);
 989     jboolean result = jni()->CallNonvirtualBooleanMethod(runtime.as_jobject(),
 990                                                      JNIJVMCI::HotSpotJVMCIRuntime::clazz(),
 991                                                      JNIJVMCI::HotSpotJVMCIRuntime::isIntrinsicSupported_method(),
 992                                                      intrinsicIdentifier);
 993     if (jni()->ExceptionCheck()) {
 994       return false;
 995     }
 996     return result;
 997   }
 998 }
 999 
1000 JVMCIObject JVMCIEnv::call_HotSpotJVMCIRuntime_compileMethod (JVMCIObject runtime, JVMCIObject method, int entry_bci,
1001                                                               jlong compile_state, int id) {
1002   JavaThread* THREAD = JVMCI::compilation_tick(JavaThread::current()); // For exception macros.
1003   if (is_hotspot()) {
1004     JavaCallArguments jargs;
1005     jargs.push_oop(Handle(THREAD, HotSpotJVMCI::resolve(runtime)));
1006     jargs.push_oop(Handle(THREAD, HotSpotJVMCI::resolve(method)));
1007     jargs.push_int(entry_bci);
1008     jargs.push_long(compile_state);
1009     jargs.push_int(id);
1010     JavaValue result(T_OBJECT);
1011     JavaCalls::call_special(&result,
1012                             HotSpotJVMCI::HotSpotJVMCIRuntime::klass(),
1013                             vmSymbols::compileMethod_name(),
1014                             vmSymbols::compileMethod_signature(), &jargs, CHECK_(JVMCIObject()));
1015     return wrap(result.get_oop());
1016   } else {
1017     JNIAccessMark jni(this, THREAD);
1018     jobject result = jni()->CallNonvirtualObjectMethod(runtime.as_jobject(),
1019                                                      JNIJVMCI::HotSpotJVMCIRuntime::clazz(),
1020                                                      JNIJVMCI::HotSpotJVMCIRuntime::compileMethod_method(),
1021                                                      method.as_jobject(), entry_bci, compile_state, id);
1022     if (jni()->ExceptionCheck()) {
1023       return JVMCIObject();
1024     }
1025     return wrap(result);
1026   }
1027 }
1028 
1029 void JVMCIEnv::call_HotSpotJVMCIRuntime_bootstrapFinished (JVMCIObject runtime, JVMCIEnv* JVMCIENV) {
1030   JavaThread* THREAD = JVMCI::compilation_tick(JavaThread::current()); // For exception macros.
1031   if (is_hotspot()) {
1032     JavaCallArguments jargs;
1033     jargs.push_oop(Handle(THREAD, HotSpotJVMCI::resolve(runtime)));
1034     JavaValue result(T_VOID);
1035     JavaCalls::call_special(&result, HotSpotJVMCI::HotSpotJVMCIRuntime::klass(), vmSymbols::bootstrapFinished_name(), vmSymbols::void_method_signature(), &jargs, CHECK);
1036   } else {
1037     JNIAccessMark jni(this, THREAD);
1038     jni()->CallNonvirtualVoidMethod(runtime.as_jobject(), JNIJVMCI::HotSpotJVMCIRuntime::clazz(), JNIJVMCI::HotSpotJVMCIRuntime::bootstrapFinished_method());
1039 
1040   }
1041 }
1042 
1043 void JVMCIEnv::call_HotSpotJVMCIRuntime_shutdown (JVMCIObject runtime) {
1044   JavaThread* THREAD = JavaThread::current(); // For exception macros.
1045   HandleMark hm(THREAD);
1046   if (is_hotspot()) {
1047     JavaCallArguments jargs;
1048     jargs.push_oop(Handle(THREAD, HotSpotJVMCI::resolve(runtime)));
1049     JavaValue result(T_VOID);
1050     JavaCalls::call_special(&result, HotSpotJVMCI::HotSpotJVMCIRuntime::klass(), vmSymbols::shutdown_name(), vmSymbols::void_method_signature(), &jargs, THREAD);
1051   } else {
1052     JNIAccessMark jni(this, THREAD);
1053     jni()->CallNonvirtualVoidMethod(runtime.as_jobject(), JNIJVMCI::HotSpotJVMCIRuntime::clazz(), JNIJVMCI::HotSpotJVMCIRuntime::shutdown_method());
1054   }
1055   if (has_pending_exception()) {
1056     // This should never happen as HotSpotJVMCIRuntime.shutdown() should
1057     // handle all exceptions.
1058     describe_pending_exception(tty);
1059   }
1060 }
1061 
1062 JVMCIObject JVMCIEnv::call_HotSpotJVMCIRuntime_runtime (JVMCIEnv* JVMCIENV) {
1063   JavaThread* THREAD = JVMCI::compilation_tick(JavaThread::current()); // For exception macros.
1064   if (is_hotspot()) {
1065     JavaCallArguments jargs;
1066     JavaValue result(T_OBJECT);
1067     JavaCalls::call_static(&result, HotSpotJVMCI::HotSpotJVMCIRuntime::klass(), vmSymbols::runtime_name(), vmSymbols::runtime_signature(), &jargs, CHECK_(JVMCIObject()));
1068     return wrap(result.get_oop());
1069   } else {
1070     JNIAccessMark jni(this, THREAD);
1071     jobject result = jni()->CallStaticObjectMethod(JNIJVMCI::HotSpotJVMCIRuntime::clazz(), JNIJVMCI::HotSpotJVMCIRuntime::runtime_method());
1072     if (jni()->ExceptionCheck()) {
1073       return JVMCIObject();
1074     }
1075     return wrap(result);
1076   }
1077 }
1078 
1079 JVMCIObject JVMCIEnv::call_JVMCI_getRuntime (JVMCIEnv* JVMCIENV) {
1080   JavaThread* THREAD = JVMCI::compilation_tick(JavaThread::current()); // For exception macros.
1081   if (is_hotspot()) {
1082     JavaCallArguments jargs;
1083     JavaValue result(T_OBJECT);
1084     JavaCalls::call_static(&result, HotSpotJVMCI::JVMCI::klass(), vmSymbols::getRuntime_name(), vmSymbols::getRuntime_signature(), &jargs, CHECK_(JVMCIObject()));
1085     return wrap(result.get_oop());
1086   } else {
1087     JNIAccessMark jni(this, THREAD);
1088     jobject result = jni()->CallStaticObjectMethod(JNIJVMCI::JVMCI::clazz(), JNIJVMCI::JVMCI::getRuntime_method());
1089     if (jni()->ExceptionCheck()) {
1090       return JVMCIObject();
1091     }
1092     return wrap(result);
1093   }
1094 }
1095 
1096 JVMCIObject JVMCIEnv::call_HotSpotJVMCIRuntime_getCompiler (JVMCIObject runtime, JVMCIEnv* JVMCIENV) {
1097   JavaThread* THREAD = JVMCI::compilation_tick(JavaThread::current()); // For exception macros.
1098   if (is_hotspot()) {
1099     JavaCallArguments jargs;
1100     jargs.push_oop(Handle(THREAD, HotSpotJVMCI::resolve(runtime)));
1101     JavaValue result(T_OBJECT);
1102     JavaCalls::call_virtual(&result, HotSpotJVMCI::HotSpotJVMCIRuntime::klass(), vmSymbols::getCompiler_name(), vmSymbols::getCompiler_signature(), &jargs, CHECK_(JVMCIObject()));
1103     return wrap(result.get_oop());
1104   } else {
1105     JNIAccessMark jni(this, THREAD);
1106     jobject result = jni()->CallObjectMethod(runtime.as_jobject(), JNIJVMCI::HotSpotJVMCIRuntime::getCompiler_method());
1107     if (jni()->ExceptionCheck()) {
1108       return JVMCIObject();
1109     }
1110     return wrap(result);
1111   }
1112 }
1113 
1114 void JVMCIEnv::call_HotSpotJVMCIRuntime_postTranslation(JVMCIObject object, JVMCIEnv* JVMCIENV) {
1115   JavaThread* THREAD = JVMCI::compilation_tick(JavaThread::current()); // For exception macros.
1116   if (is_hotspot()) {
1117     JavaCallArguments jargs;
1118     jargs.push_oop(Handle(THREAD, HotSpotJVMCI::resolve(object)));
1119     JavaValue result(T_VOID);
1120     JavaCalls::call_static(&result,
1121                            HotSpotJVMCI::HotSpotJVMCIRuntime::klass(),
1122                            vmSymbols::postTranslation_name(),
1123                            vmSymbols::object_void_signature(), &jargs, CHECK);
1124   } else {
1125     JNIAccessMark jni(this, THREAD);
1126     jni()->CallStaticVoidMethod(JNIJVMCI::HotSpotJVMCIRuntime::clazz(),
1127                                 JNIJVMCI::HotSpotJVMCIRuntime::postTranslation_method(),
1128                                 object.as_jobject());
1129   }
1130 }
1131 
1132 JVMCIObject JVMCIEnv::call_JavaConstant_forPrimitive(jchar type_char, jlong value, JVMCI_TRAPS) {
1133   JavaThread* THREAD = JVMCI::compilation_tick(JavaThread::current()); // For exception macros.
1134   if (is_hotspot()) {
1135     JavaCallArguments jargs;
1136     jargs.push_int(type_char);
1137     jargs.push_long(value);
1138     JavaValue result(T_OBJECT);
1139     JavaCalls::call_static(&result,
1140                            HotSpotJVMCI::JavaConstant::klass(),
1141                            vmSymbols::forPrimitive_name(),
1142                            vmSymbols::forPrimitive_signature(), &jargs, CHECK_(JVMCIObject()));
1143     return wrap(result.get_oop());
1144   } else {
1145     JNIAccessMark jni(this, THREAD);
1146     jobject result = (jstring) jni()->CallStaticObjectMethod(JNIJVMCI::JavaConstant::clazz(),
1147                                                              JNIJVMCI::JavaConstant::forPrimitive_method(),
1148                                                              type_char, value);
1149     if (jni()->ExceptionCheck()) {
1150       return JVMCIObject();
1151     }
1152     return wrap(result);
1153   }
1154 }
1155 
1156 JVMCIObject JVMCIEnv::get_jvmci_primitive_type(BasicType type, JVMCI_TRAPS) {
1157   JVMCIObjectArray primitives = get_HotSpotResolvedPrimitiveType_primitives();
1158   JVMCIObject result = get_object_at(primitives, type, JVMCI_CHECK_({}));
1159   return result;
1160 }
1161 
1162 JVMCIObject JVMCIEnv::new_StackTraceElement(const methodHandle& method, int bci, JVMCI_TRAPS) {
1163   JavaThread* THREAD = JavaThread::current(); // For exception macros.
1164   Symbol* file_name_sym;
1165   int line_number;
1166   java_lang_StackTraceElement::decode(method, bci, file_name_sym, line_number, CHECK_(JVMCIObject()));
1167 
1168   Symbol* method_name_sym = method->name();
1169   InstanceKlass* holder = method->method_holder();
1170   const char* declaring_class_str = holder->external_name();
1171 
1172   if (is_hotspot()) {
1173     HotSpotJVMCI::StackTraceElement::klass()->initialize(CHECK_(JVMCIObject()));
1174     oop objOop = HotSpotJVMCI::StackTraceElement::klass()->allocate_instance(CHECK_(JVMCIObject()));
1175     Handle obj = Handle(THREAD, objOop);
1176 
1177     oop declaring_class = StringTable::intern((char*) declaring_class_str, CHECK_(JVMCIObject()));
1178     HotSpotJVMCI::StackTraceElement::set_declaringClass(this, obj(), declaring_class);
1179 
1180     oop method_name = StringTable::intern(method_name_sym, CHECK_(JVMCIObject()));
1181     HotSpotJVMCI::StackTraceElement::set_methodName(this, obj(), method_name);
1182 
1183     if (file_name_sym != nullptr) {
1184       oop file_name = StringTable::intern(file_name_sym, CHECK_(JVMCIObject()));
1185       HotSpotJVMCI::StackTraceElement::set_fileName(this, obj(), file_name);
1186     }
1187     HotSpotJVMCI::StackTraceElement::set_lineNumber(this, obj(), line_number);
1188     return wrap(obj());
1189   } else {
1190     JNIAccessMark jni(this, THREAD);
1191     jobject declaring_class = jni()->NewStringUTF(declaring_class_str);
1192     if (jni()->ExceptionCheck()) {
1193       return JVMCIObject();
1194     }
1195     jobject method_name = jni()->NewStringUTF(method_name_sym->as_C_string());
1196     if (jni()->ExceptionCheck()) {
1197       return JVMCIObject();
1198     }
1199     jobject file_name = nullptr;
1200     if (file_name_sym != nullptr) {
1201       file_name = jni()->NewStringUTF(file_name_sym->as_C_string());
1202       if (jni()->ExceptionCheck()) {
1203         return JVMCIObject();
1204       }
1205     }
1206 
1207     jobject result = jni()->NewObject(JNIJVMCI::StackTraceElement::clazz(),
1208                                       JNIJVMCI::StackTraceElement::constructor(),
1209                                       declaring_class, method_name, file_name, line_number);
1210     return wrap(result);
1211   }
1212 }
1213 
1214 JVMCIObject JVMCIEnv::new_HotSpotNmethod(const methodHandle& method, const char* name, jboolean isDefault, jboolean profileDeopt, jlong compileId, JVMCI_TRAPS) {
1215   JavaThread* THREAD = JVMCI::compilation_tick(JavaThread::current()); // For exception macros.
1216 
1217   JVMCIObject methodObject = get_jvmci_method(method, JVMCI_CHECK_(JVMCIObject()));
1218 
1219   if (is_hotspot()) {
1220     InstanceKlass* ik = InstanceKlass::cast(HotSpotJVMCI::HotSpotNmethod::klass());
1221     if (ik->should_be_initialized()) {
1222       ik->initialize(CHECK_(JVMCIObject()));
1223     }
1224     oop obj = ik->allocate_instance(CHECK_(JVMCIObject()));
1225     Handle obj_h(THREAD, obj);
1226     Handle nameStr = java_lang_String::create_from_str(name, CHECK_(JVMCIObject()));
1227 
1228     // Call constructor
1229     JavaCallArguments jargs;
1230     jargs.push_oop(obj_h);
1231     jargs.push_oop(Handle(THREAD, HotSpotJVMCI::resolve(methodObject)));
1232     jargs.push_oop(nameStr);
1233     jargs.push_int(isDefault);
1234     jargs.push_int(profileDeopt);
1235     jargs.push_long(compileId);
1236     JavaValue result(T_VOID);
1237     JavaCalls::call_special(&result, ik,
1238                             vmSymbols::object_initializer_name(),
1239                             vmSymbols::method_string_bool_bool_long_signature(),
1240                             &jargs, CHECK_(JVMCIObject()));
1241     return wrap(obj_h());
1242   } else {
1243     JNIAccessMark jni(this, THREAD);
1244     jobject nameStr = name == nullptr ? nullptr : jni()->NewStringUTF(name);
1245     if (jni()->ExceptionCheck()) {
1246       return JVMCIObject();
1247     }
1248 
1249     jobject result = jni()->NewObject(JNIJVMCI::HotSpotNmethod::clazz(),
1250                                       JNIJVMCI::HotSpotNmethod::constructor(),
1251                                       methodObject.as_jobject(), nameStr, isDefault);
1252     return wrap(result);
1253   }
1254 }
1255 
1256 JVMCIObject JVMCIEnv::make_local(JVMCIObject object) {
1257   if (object.is_null()) {
1258     return JVMCIObject();
1259   }
1260   if (is_hotspot()) {
1261     return wrap(JNIHandles::make_local(HotSpotJVMCI::resolve(object)));
1262   } else {
1263     JNIAccessMark jni(this);
1264     return wrap(jni()->NewLocalRef(object.as_jobject()));
1265   }
1266 }
1267 
1268 JVMCIObject JVMCIEnv::make_global(JVMCIObject object) {
1269   if (object.is_null()) {
1270     return JVMCIObject();
1271   }
1272   if (is_hotspot()) {
1273     return wrap(JNIHandles::make_global(Handle(Thread::current(), HotSpotJVMCI::resolve(object))));
1274   } else {
1275     JNIAccessMark jni(this);
1276     return wrap(jni()->NewGlobalRef(object.as_jobject()));
1277   }
1278 }
1279 
1280 void JVMCIEnv::destroy_local(JVMCIObject object) {
1281   if (is_hotspot()) {
1282     JNIHandles::destroy_local(object.as_jobject());
1283   } else {
1284     JNIAccessMark jni(this);
1285     jni()->DeleteLocalRef(object.as_jobject());
1286   }
1287 }
1288 
1289 void JVMCIEnv::destroy_global(JVMCIObject object) {
1290   if (is_hotspot()) {
1291     JNIHandles::destroy_global(object.as_jobject());
1292   } else {
1293     JNIAccessMark jni(this);
1294     jni()->DeleteGlobalRef(object.as_jobject());
1295   }
1296 }
1297 
1298 const char* JVMCIEnv::klass_name(JVMCIObject object) {
1299   if (is_hotspot()) {
1300     return HotSpotJVMCI::resolve(object)->klass()->signature_name();
1301   } else {
1302     JVMCIObject name;
1303     {
1304       JNIAccessMark jni(this);
1305       jclass jcl = jni()->GetObjectClass(object.as_jobject());
1306       jobject result = jni()->CallObjectMethod(jcl, JNIJVMCI::Class_getName_method());
1307       name = JVMCIObject::create(result, is_hotspot());
1308     }
1309     return as_utf8_string(name);
1310   }
1311 }
1312 
1313 JVMCIObject JVMCIEnv::get_jvmci_method(const methodHandle& method, JVMCI_TRAPS) {
1314   JVMCIObject method_object;
1315   if (method() == nullptr) {
1316     return method_object;
1317   }
1318   JavaThread* THREAD = JVMCI::compilation_tick(JavaThread::current()); // For exception macros.
1319   JVMCIKlassHandle holder_klass(THREAD, method->method_holder());
1320   JVMCIObject holder = get_jvmci_type(holder_klass, JVMCI_CHECK_(JVMCIObject()));
1321 
1322   CompilerOracle::tag_blackhole_if_possible(method);
1323 
1324   jmetadata handle = _runtime->allocate_handle(method);
1325   jboolean exception = false;
1326   if (is_hotspot()) {
1327     JavaValue result(T_OBJECT);
1328     JavaCallArguments args;
1329     args.push_long((jlong) handle);
1330     args.push_oop(Handle(THREAD, HotSpotJVMCI::resolve(holder)));
1331     JavaCalls::call_static(&result, HotSpotJVMCI::HotSpotResolvedJavaMethodImpl::klass(),
1332                            vmSymbols::fromMetaspace_name(),
1333                            vmSymbols::method_fromMetaspace_signature(), &args, THREAD);
1334     if (HAS_PENDING_EXCEPTION) {
1335       exception = true;
1336     } else {
1337       method_object = wrap(result.get_oop());
1338     }
1339   } else {
1340     JNIAccessMark jni(this, THREAD);
1341     method_object = JNIJVMCI::wrap(jni()->CallStaticObjectMethod(JNIJVMCI::HotSpotResolvedJavaMethodImpl::clazz(),
1342                                                                   JNIJVMCI::HotSpotResolvedJavaMethodImpl_fromMetaspace_method(),
1343                                                                  (jlong) handle, holder.as_jobject()));
1344     exception = jni()->ExceptionCheck();
1345   }
1346 
1347   if (exception) {
1348     _runtime->release_handle(handle);
1349     return JVMCIObject();
1350   }
1351 
1352   assert(asMethod(method_object) == method(), "must be");
1353   if (get_HotSpotResolvedJavaMethodImpl_methodHandle(method_object) != (jlong) handle) {
1354     _runtime->release_handle(handle);
1355   }
1356   assert(!method_object.is_null(), "must be");
1357   return method_object;
1358 }
1359 
1360 JVMCIObject JVMCIEnv::get_jvmci_type(const JVMCIKlassHandle& klass, JVMCI_TRAPS) {
1361   JVMCIObject type;
1362   if (klass.is_null()) {
1363     return type;
1364   }
1365 
1366   guarantee(klass->is_klass(), "must be valid klass");
1367   guarantee(klass->is_loader_alive(), "klass must be alive");
1368 
1369   jlong pointer = (jlong) klass();
1370   JavaThread* THREAD = JVMCI::compilation_tick(JavaThread::current()); // For exception macros.
1371   jboolean exception = false;
1372   if (is_hotspot()) {
1373     CompilerThreadCanCallJava ccj(THREAD, true);
1374     JavaValue result(T_OBJECT);
1375     JavaCallArguments args;
1376     args.push_long(pointer);
1377     JavaCalls::call_static(&result,
1378                            HotSpotJVMCI::HotSpotResolvedObjectTypeImpl::klass(),
1379                            vmSymbols::fromMetaspace_name(),
1380                            vmSymbols::klass_fromMetaspace_signature(), &args, THREAD);
1381 
1382     if (HAS_PENDING_EXCEPTION) {
1383       exception = true;
1384     } else {
1385       type = wrap(result.get_oop());
1386     }
1387   } else {
1388     JNIAccessMark jni(this, THREAD);
1389 
1390     HandleMark hm(THREAD);
1391     type = JNIJVMCI::wrap(jni()->CallStaticObjectMethod(JNIJVMCI::HotSpotResolvedObjectTypeImpl::clazz(),
1392                                                         JNIJVMCI::HotSpotResolvedObjectTypeImpl_fromMetaspace_method(),
1393                                                         pointer));
1394     exception = jni()->ExceptionCheck();
1395   }
1396   if (exception) {
1397     return JVMCIObject();
1398   }
1399 
1400   assert(type.is_non_null(), "must have result");
1401   return type;
1402 }
1403 
1404 JVMCIObject JVMCIEnv::get_jvmci_constant_pool(const constantPoolHandle& cp, JVMCI_TRAPS) {
1405   JVMCIObject cp_object;
1406   jmetadata handle = _runtime->allocate_handle(cp);
1407   jboolean exception = false;
1408   JavaThread* THREAD = JVMCI::compilation_tick(JavaThread::current()); // For exception macros.
1409   if (is_hotspot()) {
1410     JavaValue result(T_OBJECT);
1411     JavaCallArguments args;
1412     args.push_long((jlong) handle);
1413     JavaCalls::call_static(&result,
1414                            HotSpotJVMCI::HotSpotConstantPool::klass(),
1415                            vmSymbols::fromMetaspace_name(),
1416                            vmSymbols::constantPool_fromMetaspace_signature(), &args, THREAD);
1417     if (HAS_PENDING_EXCEPTION) {
1418       exception = true;
1419     } else {
1420       cp_object = wrap(result.get_oop());
1421     }
1422   } else {
1423     JNIAccessMark jni(this, THREAD);
1424     cp_object = JNIJVMCI::wrap(jni()->CallStaticObjectMethod(JNIJVMCI::HotSpotConstantPool::clazz(),
1425                                                              JNIJVMCI::HotSpotConstantPool_fromMetaspace_method(),
1426                                                              (jlong) handle));
1427     exception = jni()->ExceptionCheck();
1428   }
1429 
1430   if (exception) {
1431     _runtime->release_handle(handle);
1432     return JVMCIObject();
1433   }
1434 
1435   assert(!cp_object.is_null(), "must be");
1436   // Constant pools aren't cached so this is always a newly created object using the handle
1437   assert(get_HotSpotConstantPool_constantPoolHandle(cp_object) == (jlong) handle, "must use same handle");
1438   return cp_object;
1439 }
1440 
1441 JVMCIPrimitiveArray JVMCIEnv::new_booleanArray(int length, JVMCI_TRAPS) {
1442   JavaThread* THREAD = JavaThread::current(); // For exception macros.
1443   if (is_hotspot()) {
1444     typeArrayOop result = oopFactory::new_boolArray(length, CHECK_(JVMCIObject()));
1445     return wrap(result);
1446   } else {
1447     JNIAccessMark jni(this, THREAD);
1448     jbooleanArray result = jni()->NewBooleanArray(length);
1449     return wrap(result);
1450   }
1451 }
1452 
1453 JVMCIPrimitiveArray JVMCIEnv::new_byteArray(int length, JVMCI_TRAPS) {
1454   JavaThread* THREAD = JavaThread::current(); // For exception macros.
1455   if (is_hotspot()) {
1456     typeArrayOop result = oopFactory::new_byteArray(length, CHECK_(JVMCIObject()));
1457     return wrap(result);
1458   } else {
1459     JNIAccessMark jni(this, THREAD);
1460     jbyteArray result = jni()->NewByteArray(length);
1461     return wrap(result);
1462   }
1463 }
1464 
1465 JVMCIObjectArray JVMCIEnv::new_byte_array_array(int length, JVMCI_TRAPS) {
1466   JavaThread* THREAD = JavaThread::current(); // For exception macros.
1467   if (is_hotspot()) {
1468     objArrayOop result = oopFactory::new_objArray(Universe::byteArrayKlass(), length, CHECK_(JVMCIObject()));
1469     return wrap(result);
1470   } else {
1471     JNIAccessMark jni(this, THREAD);
1472     jobjectArray result = jni()->NewObjectArray(length, JNIJVMCI::byte_array(), nullptr);
1473     return wrap(result);
1474   }
1475 }
1476 
1477 JVMCIPrimitiveArray JVMCIEnv::new_intArray(int length, JVMCI_TRAPS) {
1478   JavaThread* THREAD = JavaThread::current(); // For exception macros.
1479   if (is_hotspot()) {
1480     typeArrayOop result = oopFactory::new_intArray(length, CHECK_(JVMCIObject()));
1481     return wrap(result);
1482   } else {
1483     JNIAccessMark jni(this, THREAD);
1484     jintArray result = jni()->NewIntArray(length);
1485     return wrap(result);
1486   }
1487 }
1488 
1489 JVMCIPrimitiveArray JVMCIEnv::new_longArray(int length, JVMCI_TRAPS) {
1490   JavaThread* THREAD = JavaThread::current(); // For exception macros.
1491   if (is_hotspot()) {
1492     typeArrayOop result = oopFactory::new_longArray(length, CHECK_(JVMCIObject()));
1493     return wrap(result);
1494   } else {
1495     JNIAccessMark jni(this, THREAD);
1496     jlongArray result = jni()->NewLongArray(length);
1497     return wrap(result);
1498   }
1499 }
1500 
1501 JVMCIObject JVMCIEnv::new_VMField(JVMCIObject name, JVMCIObject type, jlong offset, jlong address, JVMCIObject value, JVMCI_TRAPS) {
1502   JavaThread* THREAD = JavaThread::current(); // For exception macros.
1503   if (is_hotspot()) {
1504     HotSpotJVMCI::VMField::klass()->initialize(CHECK_(JVMCIObject()));
1505     oop obj = HotSpotJVMCI::VMField::klass()->allocate_instance(CHECK_(JVMCIObject()));
1506     HotSpotJVMCI::VMField::set_name(this, obj, HotSpotJVMCI::resolve(name));
1507     HotSpotJVMCI::VMField::set_type(this, obj, HotSpotJVMCI::resolve(type));
1508     HotSpotJVMCI::VMField::set_offset(this, obj, offset);
1509     HotSpotJVMCI::VMField::set_address(this, obj, address);
1510     HotSpotJVMCI::VMField::set_value(this, obj, HotSpotJVMCI::resolve(value));
1511     return wrap(obj);
1512   } else {
1513     JNIAccessMark jni(this, THREAD);
1514     jobject result = jni()->NewObject(JNIJVMCI::VMField::clazz(),
1515                                     JNIJVMCI::VMField::constructor(),
1516                                     get_jobject(name), get_jobject(type), offset, address, get_jobject(value));
1517     return wrap(result);
1518   }
1519 }
1520 
1521 JVMCIObject JVMCIEnv::new_VMFlag(JVMCIObject name, JVMCIObject type, JVMCIObject value, JVMCI_TRAPS) {
1522   JavaThread* THREAD = JavaThread::current(); // For exception macros.
1523   if (is_hotspot()) {
1524     HotSpotJVMCI::VMFlag::klass()->initialize(CHECK_(JVMCIObject()));
1525     oop obj = HotSpotJVMCI::VMFlag::klass()->allocate_instance(CHECK_(JVMCIObject()));
1526     HotSpotJVMCI::VMFlag::set_name(this, obj, HotSpotJVMCI::resolve(name));
1527     HotSpotJVMCI::VMFlag::set_type(this, obj, HotSpotJVMCI::resolve(type));
1528     HotSpotJVMCI::VMFlag::set_value(this, obj, HotSpotJVMCI::resolve(value));
1529     return wrap(obj);
1530   } else {
1531     JNIAccessMark jni(this, THREAD);
1532     jobject result = jni()->NewObject(JNIJVMCI::VMFlag::clazz(),
1533                                     JNIJVMCI::VMFlag::constructor(),
1534                                     get_jobject(name), get_jobject(type), get_jobject(value));
1535     return wrap(result);
1536   }
1537 }
1538 
1539 JVMCIObject JVMCIEnv::new_VMIntrinsicMethod(JVMCIObject declaringClass, JVMCIObject name, JVMCIObject descriptor, int id, jboolean isAvailable, jboolean c1Supported, jboolean c2Supported, JVMCI_TRAPS) {
1540   JavaThread* THREAD = JavaThread::current(); // For exception macros.
1541   if (is_hotspot()) {
1542     HotSpotJVMCI::VMIntrinsicMethod::klass()->initialize(CHECK_(JVMCIObject()));
1543     oop obj = HotSpotJVMCI::VMIntrinsicMethod::klass()->allocate_instance(CHECK_(JVMCIObject()));
1544     HotSpotJVMCI::VMIntrinsicMethod::set_declaringClass(this, obj, HotSpotJVMCI::resolve(declaringClass));
1545     HotSpotJVMCI::VMIntrinsicMethod::set_name(this, obj, HotSpotJVMCI::resolve(name));
1546     HotSpotJVMCI::VMIntrinsicMethod::set_descriptor(this, obj, HotSpotJVMCI::resolve(descriptor));
1547     HotSpotJVMCI::VMIntrinsicMethod::set_id(this, obj, id);
1548     HotSpotJVMCI::VMIntrinsicMethod::set_isAvailable(this, obj, isAvailable);
1549     HotSpotJVMCI::VMIntrinsicMethod::set_c1Supported(this, obj, c1Supported);
1550     HotSpotJVMCI::VMIntrinsicMethod::set_c2Supported(this, obj, c2Supported);
1551     return wrap(obj);
1552   } else {
1553     JNIAccessMark jni(this, THREAD);
1554     jobject result = jni()->NewObject(JNIJVMCI::VMIntrinsicMethod::clazz(),
1555                                     JNIJVMCI::VMIntrinsicMethod::constructor(),
1556                                     get_jobject(declaringClass), get_jobject(name), get_jobject(descriptor), id, isAvailable, c1Supported, c2Supported);
1557     return wrap(result);
1558   }
1559 }
1560 
1561 JVMCIObject JVMCIEnv::new_HotSpotStackFrameReference(JVMCI_TRAPS) {
1562   if (is_hotspot()) {
1563     JavaThread* THREAD = JavaThread::current(); // For exception macros.
1564     HotSpotJVMCI::HotSpotStackFrameReference::klass()->initialize(CHECK_(JVMCIObject()));
1565     oop obj = HotSpotJVMCI::HotSpotStackFrameReference::klass()->allocate_instance(CHECK_(JVMCIObject()));
1566     return wrap(obj);
1567   } else {
1568     ShouldNotReachHere();
1569     return JVMCIObject();
1570   }
1571 }
1572 JVMCIObject JVMCIEnv::new_JVMCIError(JVMCI_TRAPS) {
1573   if (is_hotspot()) {
1574     JavaThread* THREAD = JavaThread::current(); // For exception macros.
1575     HotSpotJVMCI::JVMCIError::klass()->initialize(CHECK_(JVMCIObject()));
1576     oop obj = HotSpotJVMCI::JVMCIError::klass()->allocate_instance(CHECK_(JVMCIObject()));
1577     return wrap(obj);
1578   } else {
1579     ShouldNotReachHere();
1580     return JVMCIObject();
1581   }
1582 }
1583 
1584 JVMCIObject JVMCIEnv::new_FieldInfo(FieldInfo* fieldinfo, JVMCI_TRAPS) {
1585   JavaThread* THREAD = JavaThread::current(); // For exception macros.
1586   if (is_hotspot()) {
1587     HotSpotJVMCI::FieldInfo::klass()->initialize(CHECK_(JVMCIObject()));
1588     oop obj = HotSpotJVMCI::FieldInfo::klass()->allocate_instance(CHECK_(JVMCIObject()));
1589     Handle obj_h(THREAD, obj);
1590     HotSpotJVMCI::FieldInfo::set_nameIndex(JVMCIENV, obj_h(), (jint)fieldinfo->name_index());
1591     HotSpotJVMCI::FieldInfo::set_signatureIndex(JVMCIENV, obj_h(), (jint)fieldinfo->signature_index());
1592     HotSpotJVMCI::FieldInfo::set_offset(JVMCIENV, obj_h(), (jint)fieldinfo->offset());
1593     HotSpotJVMCI::FieldInfo::set_classfileFlags(JVMCIENV, obj_h(), (jint)fieldinfo->access_flags().as_field_flags());
1594     HotSpotJVMCI::FieldInfo::set_internalFlags(JVMCIENV, obj_h(), (jint)fieldinfo->field_flags().as_uint());
1595     HotSpotJVMCI::FieldInfo::set_initializerIndex(JVMCIENV, obj_h(), (jint)fieldinfo->initializer_index());
1596     return wrap(obj_h());
1597   } else {
1598     JNIAccessMark jni(this, THREAD);
1599     jobject result = jni()->NewObject(JNIJVMCI::FieldInfo::clazz(),
1600                                       JNIJVMCI::FieldInfo::constructor(),
1601                                       (jint)fieldinfo->name_index(),
1602                                       (jint)fieldinfo->signature_index(),
1603                                       (jint)fieldinfo->offset(),
1604                                       (jint)fieldinfo->access_flags().as_field_flags(),
1605                                       (jint)fieldinfo->field_flags().as_uint(),
1606                                       (jint)fieldinfo->initializer_index());
1607 
1608     return wrap(result);
1609   }
1610 }
1611 
1612 JVMCIObject JVMCIEnv::get_object_constant(oop objOop, bool compressed, bool dont_register) {
1613   JavaThread* THREAD = JavaThread::current(); // For exception macros.
1614   Handle obj = Handle(THREAD, objOop);
1615   if (obj.is_null()) {
1616     return JVMCIObject();
1617   }
1618   if (is_hotspot()) {
1619     HotSpotJVMCI::DirectHotSpotObjectConstantImpl::klass()->initialize(CHECK_(JVMCIObject()));
1620     oop constant = HotSpotJVMCI::DirectHotSpotObjectConstantImpl::klass()->allocate_instance(CHECK_(JVMCIObject()));
1621     HotSpotJVMCI::DirectHotSpotObjectConstantImpl::set_object(this, constant, obj());
1622     HotSpotJVMCI::HotSpotObjectConstantImpl::set_compressed(this, constant, compressed);
1623     return wrap(constant);
1624   } else {
1625     jlong handle = make_oop_handle(obj);
1626     JNIAccessMark jni(this, THREAD);
1627     jobject result = jni()->NewObject(JNIJVMCI::IndirectHotSpotObjectConstantImpl::clazz(),
1628                                       JNIJVMCI::IndirectHotSpotObjectConstantImpl::constructor(),
1629                                       handle, compressed, dont_register);
1630     return wrap(result);
1631   }
1632 }
1633 
1634 
1635 Handle JVMCIEnv::asConstant(JVMCIObject constant, JVMCI_TRAPS) {
1636   if (constant.is_null()) {
1637     return Handle();
1638   }
1639   JavaThread* THREAD = JavaThread::current(); // For exception macros.
1640   if (is_hotspot()) {
1641     assert(HotSpotJVMCI::DirectHotSpotObjectConstantImpl::is_instance(this, constant), "wrong type");
1642     oop obj = HotSpotJVMCI::DirectHotSpotObjectConstantImpl::object(this, HotSpotJVMCI::resolve(constant));
1643     return Handle(THREAD, obj);
1644   } else if (isa_IndirectHotSpotObjectConstantImpl(constant)) {
1645     jlong object_handle = get_IndirectHotSpotObjectConstantImpl_objectHandle(constant);
1646     if (object_handle == 0L) {
1647       JVMCI_THROW_MSG_(NullPointerException, "Foreign object reference has been cleared", Handle());
1648     }
1649     oop result = resolve_oop_handle(object_handle);
1650     if (result == nullptr) {
1651       JVMCI_THROW_MSG_(InternalError, "Constant was unexpectedly null", Handle());
1652     }
1653     return Handle(THREAD, result);
1654   } else {
1655     JVMCI_THROW_MSG_(IllegalArgumentException, "DirectHotSpotObjectConstantImpl shouldn't reach JVMCI in SVM mode", Handle());
1656   }
1657 }
1658 
1659 JVMCIObject JVMCIEnv::wrap(jobject object) {
1660   return JVMCIObject::create(object, is_hotspot());
1661 }
1662 
1663 jlong JVMCIEnv::make_oop_handle(const Handle& obj) {
1664   assert(!obj.is_null(), "should only create handle for non-null oops");
1665   return _runtime->make_oop_handle(obj);
1666 }
1667 
1668 oop JVMCIEnv::resolve_oop_handle(jlong oopHandle) {
1669   assert(oopHandle != 0, "should be a valid handle");
1670   oop obj = NativeAccess<>::oop_load(reinterpret_cast<oop*>(oopHandle));
1671   if (obj != nullptr) {
1672     guarantee(oopDesc::is_oop_or_null(obj), "invalid oop: " INTPTR_FORMAT, p2i((oopDesc*) obj));
1673   }
1674   return obj;
1675 }
1676 
1677 JVMCIObject JVMCIEnv::create_string(const char* str, JVMCI_TRAPS) {
1678   JavaThread* THREAD = JavaThread::current(); // For exception macros.
1679   if (is_hotspot()) {
1680     Handle result = java_lang_String::create_from_str(str, CHECK_(JVMCIObject()));
1681     return HotSpotJVMCI::wrap(result());
1682   } else {
1683     jobject result;
1684     jboolean exception = false;
1685     {
1686       JNIAccessMark jni(this, THREAD);
1687       result = jni()->NewStringUTF(str);
1688       exception = jni()->ExceptionCheck();
1689     }
1690     return wrap(result);
1691   }
1692 }
1693 
1694 bool JVMCIEnv::equals(JVMCIObject a, JVMCIObject b) {
1695   if (is_hotspot()) {
1696     return HotSpotJVMCI::resolve(a) == HotSpotJVMCI::resolve(b);
1697   } else {
1698     JNIAccessMark jni(this);
1699     return jni()->IsSameObject(a.as_jobject(), b.as_jobject()) != 0;
1700   }
1701 }
1702 
1703 BasicType JVMCIEnv::typeCharToBasicType(jchar ch, JVMCI_TRAPS) {
1704   switch(ch) {
1705     case 'Z': return T_BOOLEAN;
1706     case 'B': return T_BYTE;
1707     case 'S': return T_SHORT;
1708     case 'C': return T_CHAR;
1709     case 'I': return T_INT;
1710     case 'F': return T_FLOAT;
1711     case 'J': return T_LONG;
1712     case 'D': return T_DOUBLE;
1713     case 'A': return T_OBJECT;
1714     case '-': return T_ILLEGAL;
1715     default:
1716       JVMCI_ERROR_(T_ILLEGAL, "unexpected type char: %c", ch);
1717   }
1718 }
1719 
1720 BasicType JVMCIEnv::kindToBasicType(JVMCIObject kind, JVMCI_TRAPS) {
1721   if (kind.is_null()) {
1722     JVMCI_THROW_(NullPointerException, T_ILLEGAL);
1723   }
1724   jchar ch = get_JavaKind_typeChar(kind);
1725   BasicType bt = typeCharToBasicType(ch, JVMCI_CHECK_(T_ILLEGAL));
1726   return bt;
1727 }
1728 
1729 void JVMCIEnv::initialize_installed_code(JVMCIObject installed_code, CodeBlob* cb, JVMCI_TRAPS) {
1730   // Ensure that all updates to the InstalledCode fields are consistent.
1731   if (get_InstalledCode_address(installed_code) != 0) {
1732     JVMCI_THROW_MSG(InternalError, "InstalledCode instance already in use");
1733   }
1734   if (!isa_HotSpotInstalledCode(installed_code)) {
1735     JVMCI_THROW_MSG(InternalError, "InstalledCode instance must be a subclass of HotSpotInstalledCode");
1736   }
1737 
1738   // Ignore the version which can stay at 0
1739   if (cb->is_nmethod()) {
1740     nmethod* nm = cb->as_nmethod_or_null();
1741     if (nm->is_in_use()) {
1742       set_InstalledCode_entryPoint(installed_code, (jlong) nm->verified_entry_point());
1743     }
1744   } else {
1745     set_InstalledCode_entryPoint(installed_code, (jlong) cb->code_begin());
1746   }
1747   set_InstalledCode_address(installed_code, (jlong) cb);
1748   set_HotSpotInstalledCode_size(installed_code, cb->size());
1749   set_HotSpotInstalledCode_codeStart(installed_code, (jlong) cb->code_begin());
1750   set_HotSpotInstalledCode_codeSize(installed_code, cb->code_size());
1751 }
1752 
1753 
1754 void JVMCIEnv::invalidate_nmethod_mirror(JVMCIObject mirror, bool deoptimize, nmethod::InvalidationReason invalidation_reason, JVMCI_TRAPS) {
1755   if (mirror.is_null()) {
1756     JVMCI_THROW(NullPointerException);
1757   }
1758 
1759   Thread* current = Thread::current();
1760   if (!mirror.is_hotspot() && !current->is_Java_thread()) {
1761     // Calling back into native might cause the execution to block, so only allow this when calling
1762     // from a JavaThread, which is the normal case anyway.
1763     JVMCI_THROW_MSG(IllegalArgumentException,
1764                     "Cannot invalidate HotSpotNmethod object in shared library VM heap from non-JavaThread");
1765   }
1766 
1767   JavaThread* thread = JavaThread::cast(current);
1768   JVMCINMethodHandle nmethod_handle(thread);
1769   nmethod* nm = JVMCIENV->get_nmethod(mirror, nmethod_handle);
1770   if (nm == nullptr) {
1771     // Nothing to do
1772     return;
1773   }
1774 
1775   if (!deoptimize) {
1776     // Prevent future executions of the nmethod but let current executions complete.
1777     nm->make_not_entrant(invalidation_reason);
1778 
1779     // Do not clear the address field here as the Java code may still
1780     // want to later call this method with deoptimize == true. That requires
1781     // the address field to still be pointing at the nmethod.
1782    } else {
1783     // Deoptimize the nmethod immediately.
1784     DeoptimizationScope deopt_scope;
1785     deopt_scope.mark(nm);
1786     nm->make_not_entrant(invalidation_reason);
1787     nm->make_deoptimized();
1788     deopt_scope.deoptimize_marked();
1789 
1790     // A HotSpotNmethod instance can only reference a single nmethod
1791     // during its lifetime so simply clear it here.
1792     set_InstalledCode_address(mirror, 0);
1793   }
1794 }
1795 
1796 Klass* JVMCIEnv::asKlass(JVMCIObject obj) {
1797   return (Klass*) get_HotSpotResolvedObjectTypeImpl_klassPointer(obj);
1798 }
1799 
1800 Method* JVMCIEnv::asMethod(JVMCIObject obj) {
1801   Method** methodHandle = (Method**) get_HotSpotResolvedJavaMethodImpl_methodHandle(obj);
1802   return *methodHandle;
1803 }
1804 
1805 ConstantPool* JVMCIEnv::asConstantPool(JVMCIObject obj) {
1806   ConstantPool** constantPoolHandle = (ConstantPool**) get_HotSpotConstantPool_constantPoolHandle(obj);
1807   return *constantPoolHandle;
1808 }
1809 
1810 MethodData* JVMCIEnv::asMethodData(JVMCIObject obj) {
1811   return (MethodData*) get_HotSpotMethodData_methodDataPointer(obj);
1812 }
1813 
1814 // Lookup an nmethod with a matching base and compile id
1815 nmethod* JVMCIEnv::lookup_nmethod(address code, jlong compile_id_snapshot) {
1816   if (code == nullptr) {
1817     return nullptr;
1818   }
1819 
1820   CodeBlob* cb = CodeCache::find_blob(code);
1821   if (cb == (CodeBlob*) code) {
1822     nmethod* nm = cb->as_nmethod_or_null();
1823     if (nm != nullptr && (compile_id_snapshot == 0 || nm->compile_id() == compile_id_snapshot)) {
1824       return nm;
1825     }
1826   }
1827   return nullptr;
1828 }
1829 
1830 
1831 CodeBlob* JVMCIEnv::get_code_blob(JVMCIObject obj) {
1832   address code = (address) get_InstalledCode_address(obj);
1833   if (code == nullptr) {
1834     return nullptr;
1835   }
1836   if (isa_HotSpotNmethod(obj)) {
1837     jlong compile_id_snapshot = get_HotSpotNmethod_compileIdSnapshot(obj);
1838     nmethod* nm = lookup_nmethod(code, compile_id_snapshot);
1839     if (nm != nullptr && compile_id_snapshot != 0L && nm->is_not_entrant()) {
1840       // Zero the entry point so that the nmethod
1841       // cannot be invoked by the mirror but can
1842       // still be deoptimized.
1843       set_InstalledCode_entryPoint(obj, 0);
1844       // Refetch the nmethod since the previous call will be a safepoint in libjvmci
1845       nm = lookup_nmethod(code, compile_id_snapshot);
1846     }
1847 
1848     if (nm == nullptr) {
1849       // The HotSpotNmethod was pointing at some nmethod but the nmethod is no longer valid, so
1850       // clear the InstalledCode fields of this HotSpotNmethod so that it no longer refers to a
1851       // nmethod in the code cache.
1852       set_InstalledCode_address(obj, 0);
1853       set_InstalledCode_entryPoint(obj, 0);
1854       set_HotSpotInstalledCode_codeStart(obj, 0);
1855     }
1856     return nm;
1857   }
1858 
1859   CodeBlob* cb = (CodeBlob*) code;
1860   assert(!cb->is_nmethod(), "unexpected nmethod");
1861   return cb;
1862 }
1863 
1864 void JVMCINMethodHandle::set_nmethod(nmethod* nm) {
1865   BarrierSetNMethod* bs_nm = BarrierSet::barrier_set()->barrier_set_nmethod();
1866   bs_nm->nmethod_entry_barrier(nm);
1867   _thread->set_live_nmethod(nm);
1868 }
1869 
1870 nmethod* JVMCIEnv::get_nmethod(JVMCIObject obj, JVMCINMethodHandle& nmethod_handle) {
1871   CodeBlob* cb = get_code_blob(obj);
1872   if (cb != nullptr) {
1873     nmethod* nm = cb->as_nmethod_or_null();
1874     if (nm != nullptr) {
1875       nmethod_handle.set_nmethod(nm);
1876       return nm;
1877     }
1878   }
1879   return nullptr;
1880 }
1881 
1882 // Generate implementations for the initialize, new, isa, get and set methods for all the types and
1883 // fields declared in the JVMCI_CLASSES_DO macro.
1884 
1885 #define START_CLASS(className, fullClassName)                                                                        \
1886   void JVMCIEnv::className##_initialize(JVMCI_TRAPS) {                                                               \
1887     if (is_hotspot()) {                                                                                              \
1888       HotSpotJVMCI::className::initialize(JVMCI_CHECK);                                                              \
1889     } else {                                                                                                         \
1890       JNIJVMCI::className::initialize(JVMCI_CHECK);                                                                  \
1891     }                                                                                                                \
1892   }                                                                                                                  \
1893   JVMCIObjectArray JVMCIEnv::new_##className##_array(int length, JVMCI_TRAPS) {                                      \
1894     if (is_hotspot()) {                                                                                              \
1895       JavaThread* THREAD = JavaThread::current(); /* For exception macros. */ \
1896       objArrayOop array = oopFactory::new_objArray(HotSpotJVMCI::className::klass(), length, CHECK_(JVMCIObject())); \
1897       return (JVMCIObjectArray) wrap(array);                                                                         \
1898     } else {                                                                                                         \
1899       JNIAccessMark jni(this);                                                                                       \
1900       jobjectArray result = jni()->NewObjectArray(length, JNIJVMCI::className::clazz(), nullptr);                    \
1901       return wrap(result);                                                                                           \
1902     }                                                                                                                \
1903   }                                                                                                                  \
1904   bool JVMCIEnv::isa_##className(JVMCIObject object) {                                                               \
1905     if (is_hotspot()) {                                                                                              \
1906       return HotSpotJVMCI::className::is_instance(this, object);                                                     \
1907     } else {                                                                                                         \
1908       return JNIJVMCI::className::is_instance(this, object);                                                         \
1909     }                                                                                                                \
1910   }
1911 
1912 #define END_CLASS
1913 
1914 #define FIELD(className, name, type, accessor, cast)                 \
1915   type JVMCIEnv::get_##className##_##name(JVMCIObject obj) {         \
1916     if (is_hotspot()) {                                              \
1917       return HotSpotJVMCI::className::get_##name(this, obj);         \
1918     } else {                                                         \
1919       return JNIJVMCI::className::get_##name(this, obj);             \
1920     }                                                                \
1921   }                                                                  \
1922   void JVMCIEnv::set_##className##_##name(JVMCIObject obj, type x) { \
1923     if (is_hotspot()) {                                              \
1924       HotSpotJVMCI::className::set_##name(this, obj, x);             \
1925     } else {                                                         \
1926       JNIJVMCI::className::set_##name(this, obj, x);                 \
1927     }                                                                \
1928   }
1929 
1930 #define EMPTY_CAST
1931 #define CHAR_FIELD(className, name)                    FIELD(className, name, jchar, Char, EMPTY_CAST)
1932 #define INT_FIELD(className, name)                     FIELD(className, name, jint, Int, EMPTY_CAST)
1933 #define BOOLEAN_FIELD(className, name)                 FIELD(className, name, jboolean, Boolean, EMPTY_CAST)
1934 #define LONG_FIELD(className, name)                    FIELD(className, name, jlong, Long, EMPTY_CAST)
1935 #define FLOAT_FIELD(className, name)                   FIELD(className, name, jfloat, Float, EMPTY_CAST)
1936 
1937 #define OBJECT_FIELD(className, name, signature)              OOPISH_FIELD(className, name, JVMCIObject, Object, EMPTY_CAST)
1938 #define OBJECTARRAY_FIELD(className, name, signature)         OOPISH_FIELD(className, name, JVMCIObjectArray, Object, (JVMCIObjectArray))
1939 #define PRIMARRAY_FIELD(className, name, signature)           OOPISH_FIELD(className, name, JVMCIPrimitiveArray, Object, (JVMCIPrimitiveArray))
1940 
1941 #define STATIC_OBJECT_FIELD(className, name, signature)       STATIC_OOPISH_FIELD(className, name, JVMCIObject, Object, (JVMCIObject))
1942 #define STATIC_OBJECTARRAY_FIELD(className, name, signature)  STATIC_OOPISH_FIELD(className, name, JVMCIObjectArray, Object, (JVMCIObjectArray))
1943 
1944 #define OOPISH_FIELD(className, name, type, accessor, cast)           \
1945   type JVMCIEnv::get_##className##_##name(JVMCIObject obj) {          \
1946     if (is_hotspot()) {                                               \
1947       return HotSpotJVMCI::className::get_##name(this, obj);          \
1948     } else {                                                          \
1949       return JNIJVMCI::className::get_##name(this, obj);              \
1950     }                                                                 \
1951   }                                                                   \
1952   void JVMCIEnv::set_##className##_##name(JVMCIObject obj, type x) {  \
1953     if (is_hotspot()) {                                               \
1954       HotSpotJVMCI::className::set_##name(this, obj, x);              \
1955     } else {                                                          \
1956       JNIJVMCI::className::set_##name(this, obj, x);                  \
1957     }                                                                 \
1958   }
1959 
1960 #define STATIC_OOPISH_FIELD(className, name, type, accessor, cast)    \
1961   type JVMCIEnv::get_##className##_##name() {                         \
1962     if (is_hotspot()) {                                               \
1963       return HotSpotJVMCI::className::get_##name(this);               \
1964     } else {                                                          \
1965       return JNIJVMCI::className::get_##name(this);                   \
1966     }                                                                 \
1967   }                                                                   \
1968   void JVMCIEnv::set_##className##_##name(type x) {                   \
1969     if (is_hotspot()) {                                               \
1970       HotSpotJVMCI::className::set_##name(this, x);                   \
1971     } else {                                                          \
1972       JNIJVMCI::className::set_##name(this, x);                       \
1973     }                                                                 \
1974   }
1975 
1976 #define STATIC_PRIMITIVE_FIELD(className, name, type, accessor, cast) \
1977   type JVMCIEnv::get_##className##_##name() {                         \
1978     if (is_hotspot()) {                                               \
1979       return HotSpotJVMCI::className::get_##name(this);               \
1980     } else {                                                          \
1981       return JNIJVMCI::className::get_##name(this);                   \
1982     }                                                                 \
1983   }                                                                   \
1984   void JVMCIEnv::set_##className##_##name(type x) {                   \
1985     if (is_hotspot()) {                                               \
1986       HotSpotJVMCI::className::set_##name(this, x);                   \
1987     } else {                                                          \
1988       JNIJVMCI::className::set_##name(this, x);                       \
1989     }                                                                 \
1990   }
1991 #define STATIC_INT_FIELD(className, name) STATIC_PRIMITIVE_FIELD(className, name, jint, Int, EMPTY_CAST)
1992 #define STATIC_BOOLEAN_FIELD(className, name) STATIC_PRIMITIVE_FIELD(className, name, jboolean, Boolean, EMPTY_CAST)
1993 #define METHOD(jniCallType, jniGetMethod, hsCallType, returnType, className, methodName, signatureSymbolName)
1994 #define CONSTRUCTOR(className, signature)
1995 
1996 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)
1997 
1998 #undef START_CLASS
1999 #undef END_CLASS
2000 #undef METHOD
2001 #undef CONSTRUCTOR
2002 #undef FIELD
2003 #undef CHAR_FIELD
2004 #undef INT_FIELD
2005 #undef BOOLEAN_FIELD
2006 #undef LONG_FIELD
2007 #undef FLOAT_FIELD
2008 #undef OBJECT_FIELD
2009 #undef PRIMARRAY_FIELD
2010 #undef OBJECTARRAY_FIELD
2011 #undef STATIC_OOPISH_FIELD
2012 #undef STATIC_OBJECT_FIELD
2013 #undef STATIC_OBJECTARRAY_FIELD
2014 #undef STATIC_INT_FIELD
2015 #undef STATIC_BOOLEAN_FIELD
2016 #undef EMPTY_CAST