Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/hotspot/share/jvmci/jvmciEnv.cpp
40949 views
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
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
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
76
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
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
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
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
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
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
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.
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
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
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
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
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
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
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
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
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
}
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
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
}
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
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
}
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
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
}
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
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
}
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
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
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.
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.
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.
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
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)
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
}
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
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
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
1297
JVMCIObject JVMCIEnv::wrap(jobject object) {
1298
return JVMCIObject::create(object, is_hotspot());
1299
}
1300
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
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
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
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
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
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
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
1422
Klass* JVMCIEnv::asKlass(JVMCIObject obj) {
1423
return (Klass*) get_HotSpotResolvedObjectTypeImpl_metadataPointer(obj);
1424
}
1425
1426
Method* JVMCIEnv::asMethod(JVMCIObject obj) {
1427
Method** metadataHandle = (Method**) get_HotSpotResolvedJavaMethodImpl_metadataHandle(obj);
1428
return *metadataHandle;
1429
}
1430
1431
ConstantPool* JVMCIEnv::asConstantPool(JVMCIObject obj) {
1432
ConstantPool** metadataHandle = (ConstantPool**) get_HotSpotConstantPool_metadataHandle(obj);
1433
return *metadataHandle;
1434
}
1435
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
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
1648