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