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