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