Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/jdk17u
Path: blob/master/src/hotspot/share/jvmci/jvmciEnv.cpp
64440 views
1
/*
2
* Copyright (c) 1999, 2022, 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
// Shared code for translating an exception from HotSpot to libjvmci or vice versa.
282
class ExceptionTranslation: public StackObj {
283
protected:
284
JVMCIEnv* _from_env; // Source of translation. Can be nullptr.
285
JVMCIEnv* _to_env; // Destination of translation. Never nullptr.
286
287
ExceptionTranslation(JVMCIEnv* from_env, JVMCIEnv* to_env) : _from_env(from_env), _to_env(to_env) {}
288
289
// Encodes the exception in `_from_env` into `buffer`.
290
// Where N is the number of bytes needed for the encoding, returns N if N <= `buffer_size`
291
// and the encoding was written to `buffer` otherwise returns -N.
292
virtual int encode(JavaThread* THREAD, Klass* runtimeKlass, jlong buffer, int buffer_size) = 0;
293
294
// Decodes the exception in `buffer` in `_to_env` and throws it.
295
virtual void decode(JavaThread* THREAD, Klass* runtimeKlass, jlong buffer) = 0;
296
297
public:
298
void doit(JavaThread* THREAD) {
299
// Resolve HotSpotJVMCIRuntime class explicitly as HotSpotJVMCI::compute_offsets
300
// may not have been called.
301
Klass* runtimeKlass = SystemDictionary::resolve_or_fail(vmSymbols::jdk_vm_ci_hotspot_HotSpotJVMCIRuntime(), true, CHECK);
302
303
int buffer_size = 2048;
304
while (true) {
305
ResourceMark rm;
306
jlong buffer = (jlong) NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, jbyte, buffer_size);
307
int res = encode(THREAD, runtimeKlass, buffer, buffer_size);
308
if ((_from_env != nullptr && _from_env->has_pending_exception()) || HAS_PENDING_EXCEPTION) {
309
JVMCIRuntime::fatal_exception(_from_env, "HotSpotJVMCIRuntime.encodeThrowable should not throw an exception");
310
}
311
if (res < 0) {
312
int required_buffer_size = -res;
313
if (required_buffer_size > buffer_size) {
314
buffer_size = required_buffer_size;
315
}
316
} else {
317
decode(THREAD, runtimeKlass, buffer);
318
if (!_to_env->has_pending_exception()) {
319
JVMCIRuntime::fatal_exception(_to_env, "HotSpotJVMCIRuntime.decodeAndThrowThrowable should throw an exception");
320
}
321
return;
322
}
323
}
324
}
325
};
326
327
// Translates an exception on the HotSpot heap to an exception on the shared library heap.
328
class HotSpotToSharedLibraryExceptionTranslation : public ExceptionTranslation {
329
private:
330
const Handle& _throwable;
331
332
int encode(JavaThread* THREAD, Klass* runtimeKlass, jlong buffer, int buffer_size) {
333
JavaCallArguments jargs;
334
jargs.push_oop(_throwable);
335
jargs.push_long(buffer);
336
jargs.push_int(buffer_size);
337
JavaValue result(T_INT);
338
JavaCalls::call_static(&result,
339
runtimeKlass,
340
vmSymbols::encodeThrowable_name(),
341
vmSymbols::encodeThrowable_signature(), &jargs, THREAD);
342
return result.get_jint();
343
}
344
345
void decode(JavaThread* THREAD, Klass* runtimeKlass, jlong buffer) {
346
JNIAccessMark jni(_to_env, THREAD);
347
jni()->CallStaticVoidMethod(JNIJVMCI::HotSpotJVMCIRuntime::clazz(),
348
JNIJVMCI::HotSpotJVMCIRuntime::decodeAndThrowThrowable_method(),
349
buffer);
350
}
351
public:
352
HotSpotToSharedLibraryExceptionTranslation(JVMCIEnv* hotspot_env, JVMCIEnv* jni_env, const Handle& throwable) :
353
ExceptionTranslation(hotspot_env, jni_env), _throwable(throwable) {}
354
};
355
356
// Translates an exception on the shared library heap to an exception on the HotSpot heap.
357
class SharedLibraryToHotSpotExceptionTranslation : public ExceptionTranslation {
358
private:
359
jthrowable _throwable;
360
361
int encode(JavaThread* THREAD, Klass* runtimeKlass, jlong buffer, int buffer_size) {
362
JNIAccessMark jni(_from_env, THREAD);
363
return jni()->CallStaticIntMethod(JNIJVMCI::HotSpotJVMCIRuntime::clazz(),
364
JNIJVMCI::HotSpotJVMCIRuntime::encodeThrowable_method(),
365
_throwable, buffer, buffer_size);
366
}
367
368
void decode(JavaThread* THREAD, Klass* runtimeKlass, jlong buffer) {
369
JavaCallArguments jargs;
370
jargs.push_long(buffer);
371
JavaValue result(T_VOID);
372
JavaCalls::call_static(&result,
373
runtimeKlass,
374
vmSymbols::decodeAndThrowThrowable_name(),
375
vmSymbols::long_void_signature(), &jargs, THREAD);
376
}
377
public:
378
SharedLibraryToHotSpotExceptionTranslation(JVMCIEnv* hotspot_env, JVMCIEnv* jni_env, jthrowable throwable) :
379
ExceptionTranslation(jni_env, hotspot_env), _throwable(throwable) {}
380
};
381
382
void JVMCIEnv::translate_to_jni_exception(JavaThread* THREAD, const Handle& throwable, JVMCIEnv* hotspot_env, JVMCIEnv* jni_env) {
383
HotSpotToSharedLibraryExceptionTranslation(hotspot_env, jni_env, throwable).doit(THREAD);
384
}
385
386
void JVMCIEnv::translate_from_jni_exception(JavaThread* THREAD, jthrowable throwable, JVMCIEnv* hotspot_env, JVMCIEnv* jni_env) {
387
SharedLibraryToHotSpotExceptionTranslation(hotspot_env, jni_env, throwable).doit(THREAD);
388
}
389
390
jboolean JVMCIEnv::transfer_pending_exception(JavaThread* THREAD, JVMCIEnv* peer_env) {
391
if (is_hotspot()) {
392
if (HAS_PENDING_EXCEPTION) {
393
Handle throwable = Handle(THREAD, PENDING_EXCEPTION);
394
CLEAR_PENDING_EXCEPTION;
395
translate_to_jni_exception(THREAD, throwable, this, peer_env);
396
return true;
397
}
398
} else {
399
jthrowable ex = nullptr;
400
{
401
JNIAccessMark jni(this, THREAD);
402
ex = jni()->ExceptionOccurred();
403
if (ex != nullptr) {
404
jni()->ExceptionClear();
405
}
406
}
407
if (ex != nullptr) {
408
translate_from_jni_exception(THREAD, ex, peer_env, this);
409
return true;
410
}
411
}
412
return false;
413
}
414
415
416
JVMCIEnv::~JVMCIEnv() {
417
if (_throw_to_caller) {
418
if (is_hotspot()) {
419
// Nothing to do
420
} else {
421
Thread* thread = Thread::current();
422
if (thread->is_Java_thread()) {
423
JavaThread* THREAD = thread->as_Java_thread(); // For exception macros.
424
if (HAS_PENDING_EXCEPTION) {
425
Handle throwable = Handle(THREAD, PENDING_EXCEPTION);
426
CLEAR_PENDING_EXCEPTION;
427
translate_to_jni_exception(THREAD, throwable, nullptr, this);
428
}
429
}
430
}
431
} else {
432
if (_pop_frame_on_close) {
433
// Pop the JNI local frame that was pushed when entering this JVMCIEnv scope.
434
JNIAccessMark jni(this);
435
jni()->PopLocalFrame(NULL);
436
}
437
438
if (has_pending_exception()) {
439
char message[256];
440
jio_snprintf(message, 256, "Uncaught exception exiting JVMCIEnv scope entered at %s:%d", _file, _line);
441
JVMCIRuntime::fatal_exception(this, message);
442
}
443
444
if (_detach_on_close) {
445
_runtime->DetachCurrentThread(JavaThread::current());
446
}
447
}
448
}
449
450
jboolean JVMCIEnv::has_pending_exception() {
451
if (is_hotspot()) {
452
JavaThread* THREAD = JavaThread::current(); // For exception macros.
453
return HAS_PENDING_EXCEPTION;
454
} else {
455
JNIAccessMark jni(this);
456
return jni()->ExceptionCheck();
457
}
458
}
459
460
void JVMCIEnv::clear_pending_exception() {
461
if (is_hotspot()) {
462
JavaThread* THREAD = JavaThread::current(); // For exception macros.
463
CLEAR_PENDING_EXCEPTION;
464
} else {
465
JNIAccessMark jni(this);
466
jni()->ExceptionClear();
467
}
468
}
469
470
int JVMCIEnv::get_length(JVMCIArray array) {
471
if (is_hotspot()) {
472
return HotSpotJVMCI::resolve(array)->length();
473
} else {
474
JNIAccessMark jni(this);
475
return jni()->GetArrayLength(get_jarray(array));
476
}
477
}
478
479
JVMCIObject JVMCIEnv::get_object_at(JVMCIObjectArray array, int index) {
480
if (is_hotspot()) {
481
oop result = HotSpotJVMCI::resolve(array)->obj_at(index);
482
return wrap(result);
483
} else {
484
JNIAccessMark jni(this);
485
jobject result = jni()->GetObjectArrayElement(get_jobjectArray(array), index);
486
return wrap(result);
487
}
488
}
489
490
void JVMCIEnv::put_object_at(JVMCIObjectArray array, int index, JVMCIObject value) {
491
if (is_hotspot()) {
492
HotSpotJVMCI::resolve(array)->obj_at_put(index, HotSpotJVMCI::resolve(value));
493
} else {
494
JNIAccessMark jni(this);
495
jni()->SetObjectArrayElement(get_jobjectArray(array), index, get_jobject(value));
496
}
497
}
498
499
jboolean JVMCIEnv::get_bool_at(JVMCIPrimitiveArray array, int index) {
500
if (is_hotspot()) {
501
return HotSpotJVMCI::resolve(array)->bool_at(index);
502
} else {
503
JNIAccessMark jni(this);
504
jboolean result;
505
jni()->GetBooleanArrayRegion(array.as_jbooleanArray(), index, 1, &result);
506
return result;
507
}
508
}
509
void JVMCIEnv::put_bool_at(JVMCIPrimitiveArray array, int index, jboolean value) {
510
if (is_hotspot()) {
511
HotSpotJVMCI::resolve(array)->bool_at_put(index, value);
512
} else {
513
JNIAccessMark jni(this);
514
jni()->SetBooleanArrayRegion(array.as_jbooleanArray(), index, 1, &value);
515
}
516
}
517
518
jbyte JVMCIEnv::get_byte_at(JVMCIPrimitiveArray array, int index) {
519
if (is_hotspot()) {
520
return HotSpotJVMCI::resolve(array)->byte_at(index);
521
} else {
522
JNIAccessMark jni(this);
523
jbyte result;
524
jni()->GetByteArrayRegion(array.as_jbyteArray(), index, 1, &result);
525
return result;
526
}
527
}
528
void JVMCIEnv::put_byte_at(JVMCIPrimitiveArray array, int index, jbyte value) {
529
if (is_hotspot()) {
530
HotSpotJVMCI::resolve(array)->byte_at_put(index, value);
531
} else {
532
JNIAccessMark jni(this);
533
jni()->SetByteArrayRegion(array.as_jbyteArray(), index, 1, &value);
534
}
535
}
536
537
jint JVMCIEnv::get_int_at(JVMCIPrimitiveArray array, int index) {
538
if (is_hotspot()) {
539
return HotSpotJVMCI::resolve(array)->int_at(index);
540
} else {
541
JNIAccessMark jni(this);
542
jint result;
543
jni()->GetIntArrayRegion(array.as_jintArray(), index, 1, &result);
544
return result;
545
}
546
}
547
void JVMCIEnv::put_int_at(JVMCIPrimitiveArray array, int index, jint value) {
548
if (is_hotspot()) {
549
HotSpotJVMCI::resolve(array)->int_at_put(index, value);
550
} else {
551
JNIAccessMark jni(this);
552
jni()->SetIntArrayRegion(array.as_jintArray(), index, 1, &value);
553
}
554
}
555
556
long JVMCIEnv::get_long_at(JVMCIPrimitiveArray array, int index) {
557
if (is_hotspot()) {
558
return HotSpotJVMCI::resolve(array)->long_at(index);
559
} else {
560
JNIAccessMark jni(this);
561
jlong result;
562
jni()->GetLongArrayRegion(array.as_jlongArray(), index, 1, &result);
563
return result;
564
}
565
}
566
void JVMCIEnv::put_long_at(JVMCIPrimitiveArray array, int index, jlong value) {
567
if (is_hotspot()) {
568
HotSpotJVMCI::resolve(array)->long_at_put(index, value);
569
} else {
570
JNIAccessMark jni(this);
571
jni()->SetLongArrayRegion(array.as_jlongArray(), index, 1, &value);
572
}
573
}
574
575
void JVMCIEnv::copy_bytes_to(JVMCIPrimitiveArray src, jbyte* dest, int offset, jsize length) {
576
if (length == 0) {
577
return;
578
}
579
if (is_hotspot()) {
580
memcpy(dest, HotSpotJVMCI::resolve(src)->byte_at_addr(offset), length);
581
} else {
582
JNIAccessMark jni(this);
583
jni()->GetByteArrayRegion(src.as_jbyteArray(), offset, length, dest);
584
}
585
}
586
void JVMCIEnv::copy_bytes_from(jbyte* src, JVMCIPrimitiveArray dest, int offset, jsize length) {
587
if (length == 0) {
588
return;
589
}
590
if (is_hotspot()) {
591
memcpy(HotSpotJVMCI::resolve(dest)->byte_at_addr(offset), src, length);
592
} else {
593
JNIAccessMark jni(this);
594
jni()->SetByteArrayRegion(dest.as_jbyteArray(), offset, length, src);
595
}
596
}
597
598
void JVMCIEnv::copy_longs_from(jlong* src, JVMCIPrimitiveArray dest, int offset, jsize length) {
599
if (length == 0) {
600
return;
601
}
602
if (is_hotspot()) {
603
memcpy(HotSpotJVMCI::resolve(dest)->long_at_addr(offset), src, length * sizeof(jlong));
604
} else {
605
JNIAccessMark jni(this);
606
jni()->SetLongArrayRegion(dest.as_jlongArray(), offset, length, src);
607
}
608
}
609
610
jboolean JVMCIEnv::is_boxing_object(BasicType type, JVMCIObject object) {
611
if (is_hotspot()) {
612
return java_lang_boxing_object::is_instance(HotSpotJVMCI::resolve(object), type);
613
} else {
614
JNIAccessMark jni(this);
615
return jni()->IsInstanceOf(get_jobject(object), JNIJVMCI::box_class(type));
616
}
617
}
618
619
// Get the primitive value from a Java boxing object. It's hard error to
620
// pass a non-primitive BasicType.
621
jvalue JVMCIEnv::get_boxed_value(BasicType type, JVMCIObject object) {
622
jvalue result;
623
if (is_hotspot()) {
624
if (java_lang_boxing_object::get_value(HotSpotJVMCI::resolve(object), &result) == T_ILLEGAL) {
625
ShouldNotReachHere();
626
}
627
} else {
628
JNIAccessMark jni(this);
629
jfieldID field = JNIJVMCI::box_field(type);
630
switch (type) {
631
case T_BOOLEAN: result.z = jni()->GetBooleanField(get_jobject(object), field); break;
632
case T_BYTE: result.b = jni()->GetByteField(get_jobject(object), field); break;
633
case T_SHORT: result.s = jni()->GetShortField(get_jobject(object), field); break;
634
case T_CHAR: result.c = jni()->GetCharField(get_jobject(object), field); break;
635
case T_INT: result.i = jni()->GetIntField(get_jobject(object), field); break;
636
case T_LONG: result.j = jni()->GetLongField(get_jobject(object), field); break;
637
case T_FLOAT: result.f = jni()->GetFloatField(get_jobject(object), field); break;
638
case T_DOUBLE: result.d = jni()->GetDoubleField(get_jobject(object), field); break;
639
default:
640
ShouldNotReachHere();
641
}
642
}
643
return result;
644
}
645
646
// Return the BasicType of the object if it's a boxing object, otherwise return T_ILLEGAL.
647
BasicType JVMCIEnv::get_box_type(JVMCIObject object) {
648
if (is_hotspot()) {
649
return java_lang_boxing_object::basic_type(HotSpotJVMCI::resolve(object));
650
} else {
651
JNIAccessMark jni(this);
652
jclass clazz = jni()->GetObjectClass(get_jobject(object));
653
if (jni()->IsSameObject(clazz, JNIJVMCI::box_class(T_BOOLEAN))) return T_BOOLEAN;
654
if (jni()->IsSameObject(clazz, JNIJVMCI::box_class(T_BYTE))) return T_BYTE;
655
if (jni()->IsSameObject(clazz, JNIJVMCI::box_class(T_SHORT))) return T_SHORT;
656
if (jni()->IsSameObject(clazz, JNIJVMCI::box_class(T_CHAR))) return T_CHAR;
657
if (jni()->IsSameObject(clazz, JNIJVMCI::box_class(T_INT))) return T_INT;
658
if (jni()->IsSameObject(clazz, JNIJVMCI::box_class(T_LONG))) return T_LONG;
659
if (jni()->IsSameObject(clazz, JNIJVMCI::box_class(T_FLOAT))) return T_FLOAT;
660
if (jni()->IsSameObject(clazz, JNIJVMCI::box_class(T_DOUBLE))) return T_DOUBLE;
661
return T_ILLEGAL;
662
}
663
}
664
665
// Create a boxing object of the appropriate primitive type.
666
JVMCIObject JVMCIEnv::create_box(BasicType type, jvalue* value, JVMCI_TRAPS) {
667
switch (type) {
668
case T_BOOLEAN:
669
case T_BYTE:
670
case T_CHAR:
671
case T_SHORT:
672
case T_INT:
673
case T_LONG:
674
case T_FLOAT:
675
case T_DOUBLE:
676
break;
677
default:
678
JVMCI_THROW_MSG_(IllegalArgumentException, "Only boxes for primitive values can be created", JVMCIObject());
679
}
680
JavaThread* THREAD = JavaThread::current(); // For exception macros.
681
if (is_hotspot()) {
682
oop box = java_lang_boxing_object::create(type, value, CHECK_(JVMCIObject()));
683
return HotSpotJVMCI::wrap(box);
684
} else {
685
JNIAccessMark jni(this, THREAD);
686
jobject box = jni()->NewObjectA(JNIJVMCI::box_class(type), JNIJVMCI::box_constructor(type), value);
687
assert(box != NULL, "");
688
return wrap(box);
689
}
690
}
691
692
const char* JVMCIEnv::as_utf8_string(JVMCIObject str) {
693
if (is_hotspot()) {
694
return java_lang_String::as_utf8_string(HotSpotJVMCI::resolve(str));
695
} else {
696
JNIAccessMark jni(this);
697
int length = jni()->GetStringLength(str.as_jstring());
698
int utf8_length = jni()->GetStringUTFLength(str.as_jstring());
699
char* result = NEW_RESOURCE_ARRAY(char, utf8_length + 1);
700
jni()->GetStringUTFRegion(str.as_jstring(), 0, length, result);
701
return result;
702
}
703
}
704
705
#define DO_THROW(name) \
706
void JVMCIEnv::throw_##name(const char* msg) { \
707
if (is_hotspot()) { \
708
JavaThread* THREAD = JavaThread::current(); \
709
THROW_MSG(HotSpotJVMCI::name::symbol(), msg); \
710
} else { \
711
JNIAccessMark jni(this); \
712
jni()->ThrowNew(JNIJVMCI::name::clazz(), msg); \
713
} \
714
}
715
716
DO_THROW(InternalError)
717
DO_THROW(ArrayIndexOutOfBoundsException)
718
DO_THROW(IllegalStateException)
719
DO_THROW(NullPointerException)
720
DO_THROW(IllegalArgumentException)
721
DO_THROW(InvalidInstalledCodeException)
722
DO_THROW(UnsatisfiedLinkError)
723
DO_THROW(UnsupportedOperationException)
724
DO_THROW(ClassNotFoundException)
725
726
#undef DO_THROW
727
728
void JVMCIEnv::fthrow_error(const char* file, int line, const char* format, ...) {
729
const int max_msg_size = 1024;
730
va_list ap;
731
va_start(ap, format);
732
char msg[max_msg_size];
733
vsnprintf(msg, max_msg_size, format, ap);
734
msg[max_msg_size-1] = '\0';
735
va_end(ap);
736
JavaThread* THREAD = JavaThread::current();
737
if (is_hotspot()) {
738
Handle h_loader = Handle();
739
Handle h_protection_domain = Handle();
740
Exceptions::_throw_msg(THREAD, file, line, vmSymbols::jdk_vm_ci_common_JVMCIError(), msg, h_loader, h_protection_domain);
741
} else {
742
JNIAccessMark jni(this, THREAD);
743
jni()->ThrowNew(JNIJVMCI::JVMCIError::clazz(), msg);
744
}
745
}
746
747
jboolean JVMCIEnv::call_HotSpotJVMCIRuntime_isGCSupported (JVMCIObject runtime, jint gcIdentifier) {
748
JavaThread* THREAD = JavaThread::current(); // For exception macros.
749
if (is_hotspot()) {
750
JavaCallArguments jargs;
751
jargs.push_oop(Handle(THREAD, HotSpotJVMCI::resolve(runtime)));
752
jargs.push_int(gcIdentifier);
753
JavaValue result(T_BOOLEAN);
754
JavaCalls::call_special(&result,
755
HotSpotJVMCI::HotSpotJVMCIRuntime::klass(),
756
vmSymbols::isGCSupported_name(),
757
vmSymbols::int_bool_signature(), &jargs, CHECK_0);
758
return result.get_jboolean();
759
} else {
760
JNIAccessMark jni(this, THREAD);
761
jboolean result = jni()->CallNonvirtualBooleanMethod(runtime.as_jobject(),
762
JNIJVMCI::HotSpotJVMCIRuntime::clazz(),
763
JNIJVMCI::HotSpotJVMCIRuntime::isGCSupported_method(),
764
gcIdentifier);
765
if (jni()->ExceptionCheck()) {
766
return false;
767
}
768
return result;
769
}
770
}
771
772
JVMCIObject JVMCIEnv::call_HotSpotJVMCIRuntime_compileMethod (JVMCIObject runtime, JVMCIObject method, int entry_bci,
773
jlong compile_state, int id) {
774
JavaThread* THREAD = JVMCI::compilation_tick(JavaThread::current()); // For exception macros.
775
if (is_hotspot()) {
776
JavaCallArguments jargs;
777
jargs.push_oop(Handle(THREAD, HotSpotJVMCI::resolve(runtime)));
778
jargs.push_oop(Handle(THREAD, HotSpotJVMCI::resolve(method)));
779
jargs.push_int(entry_bci);
780
jargs.push_long(compile_state);
781
jargs.push_int(id);
782
JavaValue result(T_OBJECT);
783
JavaCalls::call_special(&result,
784
HotSpotJVMCI::HotSpotJVMCIRuntime::klass(),
785
vmSymbols::compileMethod_name(),
786
vmSymbols::compileMethod_signature(), &jargs, CHECK_(JVMCIObject()));
787
return wrap(result.get_oop());
788
} else {
789
JNIAccessMark jni(this, THREAD);
790
jobject result = jni()->CallNonvirtualObjectMethod(runtime.as_jobject(),
791
JNIJVMCI::HotSpotJVMCIRuntime::clazz(),
792
JNIJVMCI::HotSpotJVMCIRuntime::compileMethod_method(),
793
method.as_jobject(), entry_bci, compile_state, id);
794
if (jni()->ExceptionCheck()) {
795
return JVMCIObject();
796
}
797
return wrap(result);
798
}
799
}
800
801
void JVMCIEnv::call_HotSpotJVMCIRuntime_bootstrapFinished (JVMCIObject runtime, JVMCIEnv* JVMCIENV) {
802
JavaThread* THREAD = JVMCI::compilation_tick(JavaThread::current()); // For exception macros.
803
if (is_hotspot()) {
804
JavaCallArguments jargs;
805
jargs.push_oop(Handle(THREAD, HotSpotJVMCI::resolve(runtime)));
806
JavaValue result(T_VOID);
807
JavaCalls::call_special(&result, HotSpotJVMCI::HotSpotJVMCIRuntime::klass(), vmSymbols::bootstrapFinished_name(), vmSymbols::void_method_signature(), &jargs, CHECK);
808
} else {
809
JNIAccessMark jni(this, THREAD);
810
jni()->CallNonvirtualVoidMethod(runtime.as_jobject(), JNIJVMCI::HotSpotJVMCIRuntime::clazz(), JNIJVMCI::HotSpotJVMCIRuntime::bootstrapFinished_method());
811
812
}
813
}
814
815
void JVMCIEnv::call_HotSpotJVMCIRuntime_shutdown (JVMCIObject runtime) {
816
JavaThread* THREAD = JavaThread::current(); // For exception macros.
817
HandleMark hm(THREAD);
818
if (is_hotspot()) {
819
JavaCallArguments jargs;
820
jargs.push_oop(Handle(THREAD, HotSpotJVMCI::resolve(runtime)));
821
JavaValue result(T_VOID);
822
JavaCalls::call_special(&result, HotSpotJVMCI::HotSpotJVMCIRuntime::klass(), vmSymbols::shutdown_name(), vmSymbols::void_method_signature(), &jargs, THREAD);
823
} else {
824
JNIAccessMark jni(this, THREAD);
825
jni()->CallNonvirtualVoidMethod(runtime.as_jobject(), JNIJVMCI::HotSpotJVMCIRuntime::clazz(), JNIJVMCI::HotSpotJVMCIRuntime::shutdown_method());
826
}
827
if (has_pending_exception()) {
828
// This should never happen as HotSpotJVMCIRuntime.shutdown() should
829
// handle all exceptions.
830
describe_pending_exception(true);
831
}
832
}
833
834
JVMCIObject JVMCIEnv::call_HotSpotJVMCIRuntime_runtime (JVMCIEnv* JVMCIENV) {
835
JavaThread* THREAD = JVMCI::compilation_tick(JavaThread::current()); // For exception macros.
836
if (is_hotspot()) {
837
JavaCallArguments jargs;
838
JavaValue result(T_OBJECT);
839
JavaCalls::call_static(&result, HotSpotJVMCI::HotSpotJVMCIRuntime::klass(), vmSymbols::runtime_name(), vmSymbols::runtime_signature(), &jargs, CHECK_(JVMCIObject()));
840
return wrap(result.get_oop());
841
} else {
842
JNIAccessMark jni(this, THREAD);
843
jobject result = jni()->CallStaticObjectMethod(JNIJVMCI::HotSpotJVMCIRuntime::clazz(), JNIJVMCI::HotSpotJVMCIRuntime::runtime_method());
844
if (jni()->ExceptionCheck()) {
845
return JVMCIObject();
846
}
847
return wrap(result);
848
}
849
}
850
851
JVMCIObject JVMCIEnv::call_JVMCI_getRuntime (JVMCIEnv* JVMCIENV) {
852
JavaThread* THREAD = JVMCI::compilation_tick(JavaThread::current()); // For exception macros.
853
if (is_hotspot()) {
854
JavaCallArguments jargs;
855
JavaValue result(T_OBJECT);
856
JavaCalls::call_static(&result, HotSpotJVMCI::JVMCI::klass(), vmSymbols::getRuntime_name(), vmSymbols::getRuntime_signature(), &jargs, CHECK_(JVMCIObject()));
857
return wrap(result.get_oop());
858
} else {
859
JNIAccessMark jni(this, THREAD);
860
jobject result = jni()->CallStaticObjectMethod(JNIJVMCI::JVMCI::clazz(), JNIJVMCI::JVMCI::getRuntime_method());
861
if (jni()->ExceptionCheck()) {
862
return JVMCIObject();
863
}
864
return wrap(result);
865
}
866
}
867
868
JVMCIObject JVMCIEnv::call_HotSpotJVMCIRuntime_getCompiler (JVMCIObject runtime, JVMCIEnv* JVMCIENV) {
869
JavaThread* THREAD = JVMCI::compilation_tick(JavaThread::current()); // For exception macros.
870
if (is_hotspot()) {
871
JavaCallArguments jargs;
872
jargs.push_oop(Handle(THREAD, HotSpotJVMCI::resolve(runtime)));
873
JavaValue result(T_OBJECT);
874
JavaCalls::call_virtual(&result, HotSpotJVMCI::HotSpotJVMCIRuntime::klass(), vmSymbols::getCompiler_name(), vmSymbols::getCompiler_signature(), &jargs, CHECK_(JVMCIObject()));
875
return wrap(result.get_oop());
876
} else {
877
JNIAccessMark jni(this, THREAD);
878
jobject result = jni()->CallObjectMethod(runtime.as_jobject(), JNIJVMCI::HotSpotJVMCIRuntime::getCompiler_method());
879
if (jni()->ExceptionCheck()) {
880
return JVMCIObject();
881
}
882
return wrap(result);
883
}
884
}
885
886
887
JVMCIObject JVMCIEnv::call_HotSpotJVMCIRuntime_callToString(JVMCIObject object, JVMCIEnv* JVMCIENV) {
888
JavaThread* THREAD = JVMCI::compilation_tick(JavaThread::current()); // For exception macros.
889
if (is_hotspot()) {
890
JavaCallArguments jargs;
891
jargs.push_oop(Handle(THREAD, HotSpotJVMCI::resolve(object)));
892
JavaValue result(T_OBJECT);
893
JavaCalls::call_static(&result,
894
HotSpotJVMCI::HotSpotJVMCIRuntime::klass(),
895
vmSymbols::callToString_name(),
896
vmSymbols::callToString_signature(), &jargs, CHECK_(JVMCIObject()));
897
return wrap(result.get_oop());
898
} else {
899
JNIAccessMark jni(this, THREAD);
900
jobject result = (jstring) jni()->CallStaticObjectMethod(JNIJVMCI::HotSpotJVMCIRuntime::clazz(),
901
JNIJVMCI::HotSpotJVMCIRuntime::callToString_method(),
902
object.as_jobject());
903
if (jni()->ExceptionCheck()) {
904
return JVMCIObject();
905
}
906
return wrap(result);
907
}
908
}
909
910
void JVMCIEnv::call_HotSpotJVMCIRuntime_postTranslation(JVMCIObject object, JVMCIEnv* JVMCIENV) {
911
JavaThread* THREAD = JVMCI::compilation_tick(JavaThread::current()); // For exception macros.
912
if (is_hotspot()) {
913
JavaCallArguments jargs;
914
jargs.push_oop(Handle(THREAD, HotSpotJVMCI::resolve(object)));
915
JavaValue result(T_VOID);
916
JavaCalls::call_static(&result,
917
HotSpotJVMCI::HotSpotJVMCIRuntime::klass(),
918
vmSymbols::postTranslation_name(),
919
vmSymbols::object_void_signature(), &jargs, CHECK);
920
} else {
921
JNIAccessMark jni(this, THREAD);
922
jni()->CallStaticVoidMethod(JNIJVMCI::HotSpotJVMCIRuntime::clazz(),
923
JNIJVMCI::HotSpotJVMCIRuntime::postTranslation_method(),
924
object.as_jobject());
925
}
926
}
927
928
JVMCIObject JVMCIEnv::call_JavaConstant_forPrimitive(JVMCIObject kind, jlong value, JVMCI_TRAPS) {
929
JavaThread* THREAD = JVMCI::compilation_tick(JavaThread::current()); // For exception macros.
930
if (is_hotspot()) {
931
JavaCallArguments jargs;
932
jargs.push_oop(Handle(THREAD, HotSpotJVMCI::resolve(kind)));
933
jargs.push_long(value);
934
JavaValue result(T_OBJECT);
935
JavaCalls::call_static(&result,
936
HotSpotJVMCI::JavaConstant::klass(),
937
vmSymbols::forPrimitive_name(),
938
vmSymbols::forPrimitive_signature(), &jargs, CHECK_(JVMCIObject()));
939
return wrap(result.get_oop());
940
} else {
941
JNIAccessMark jni(this, THREAD);
942
jobject result = (jstring) jni()->CallStaticObjectMethod(JNIJVMCI::JavaConstant::clazz(),
943
JNIJVMCI::JavaConstant::forPrimitive_method(),
944
kind.as_jobject(), value);
945
if (jni()->ExceptionCheck()) {
946
return JVMCIObject();
947
}
948
return wrap(result);
949
}
950
}
951
952
JVMCIObject JVMCIEnv::get_jvmci_primitive_type(BasicType type) {
953
JVMCIObjectArray primitives = get_HotSpotResolvedPrimitiveType_primitives();
954
JVMCIObject result = get_object_at(primitives, type);
955
return result;
956
}
957
958
JVMCIObject JVMCIEnv::new_StackTraceElement(const methodHandle& method, int bci, JVMCI_TRAPS) {
959
JavaThread* THREAD = JavaThread::current(); // For exception macros.
960
Symbol* file_name_sym;
961
int line_number;
962
java_lang_StackTraceElement::decode(method, bci, file_name_sym, line_number, CHECK_(JVMCIObject()));
963
964
Symbol* method_name_sym = method->name();
965
InstanceKlass* holder = method->method_holder();
966
const char* declaring_class_str = holder->external_name();
967
968
if (is_hotspot()) {
969
HotSpotJVMCI::StackTraceElement::klass()->initialize(CHECK_(JVMCIObject()));
970
oop objOop = HotSpotJVMCI::StackTraceElement::klass()->allocate_instance(CHECK_(JVMCIObject()));
971
Handle obj = Handle(THREAD, objOop);
972
973
oop declaring_class = StringTable::intern((char*) declaring_class_str, CHECK_(JVMCIObject()));
974
HotSpotJVMCI::StackTraceElement::set_declaringClass(this, obj(), declaring_class);
975
976
oop method_name = StringTable::intern(method_name_sym, CHECK_(JVMCIObject()));
977
HotSpotJVMCI::StackTraceElement::set_methodName(this, obj(), method_name);
978
979
if (file_name_sym != NULL) {
980
oop file_name = StringTable::intern(file_name_sym, CHECK_(JVMCIObject()));
981
HotSpotJVMCI::StackTraceElement::set_fileName(this, obj(), file_name);
982
}
983
HotSpotJVMCI::StackTraceElement::set_lineNumber(this, obj(), line_number);
984
return wrap(obj());
985
} else {
986
JNIAccessMark jni(this, THREAD);
987
jobject declaring_class = jni()->NewStringUTF(declaring_class_str);
988
if (jni()->ExceptionCheck()) {
989
return JVMCIObject();
990
}
991
jobject method_name = jni()->NewStringUTF(method_name_sym->as_C_string());
992
if (jni()->ExceptionCheck()) {
993
return JVMCIObject();
994
}
995
jobject file_name = NULL;
996
if (file_name_sym != NULL) {
997
file_name = jni()->NewStringUTF(file_name_sym->as_C_string());
998
if (jni()->ExceptionCheck()) {
999
return JVMCIObject();
1000
}
1001
}
1002
1003
jobject result = jni()->NewObject(JNIJVMCI::StackTraceElement::clazz(),
1004
JNIJVMCI::StackTraceElement::constructor(),
1005
declaring_class, method_name, file_name, line_number);
1006
return wrap(result);
1007
}
1008
}
1009
1010
JVMCIObject JVMCIEnv::new_HotSpotNmethod(const methodHandle& method, const char* name, jboolean isDefault, jlong compileId, JVMCI_TRAPS) {
1011
JavaThread* THREAD = JVMCI::compilation_tick(JavaThread::current()); // For exception macros.
1012
1013
JVMCIObject methodObject = get_jvmci_method(method, JVMCI_CHECK_(JVMCIObject()));
1014
1015
if (is_hotspot()) {
1016
InstanceKlass* ik = InstanceKlass::cast(HotSpotJVMCI::HotSpotNmethod::klass());
1017
if (ik->should_be_initialized()) {
1018
ik->initialize(CHECK_(JVMCIObject()));
1019
}
1020
oop obj = ik->allocate_instance(CHECK_(JVMCIObject()));
1021
Handle obj_h(THREAD, obj);
1022
Handle nameStr = java_lang_String::create_from_str(name, CHECK_(JVMCIObject()));
1023
1024
// Call constructor
1025
JavaCallArguments jargs;
1026
jargs.push_oop(obj_h);
1027
jargs.push_oop(Handle(THREAD, HotSpotJVMCI::resolve(methodObject)));
1028
jargs.push_oop(nameStr);
1029
jargs.push_int(isDefault);
1030
jargs.push_long(compileId);
1031
JavaValue result(T_VOID);
1032
JavaCalls::call_special(&result, ik,
1033
vmSymbols::object_initializer_name(),
1034
vmSymbols::method_string_bool_long_signature(),
1035
&jargs, CHECK_(JVMCIObject()));
1036
return wrap(obj_h());
1037
} else {
1038
JNIAccessMark jni(this, THREAD);
1039
jobject nameStr = name == NULL ? NULL : jni()->NewStringUTF(name);
1040
if (jni()->ExceptionCheck()) {
1041
return JVMCIObject();
1042
}
1043
1044
jobject result = jni()->NewObject(JNIJVMCI::HotSpotNmethod::clazz(),
1045
JNIJVMCI::HotSpotNmethod::constructor(),
1046
methodObject.as_jobject(), nameStr, isDefault);
1047
return wrap(result);
1048
}
1049
}
1050
1051
JVMCIObject JVMCIEnv::make_local(JVMCIObject object) {
1052
if (object.is_null()) {
1053
return JVMCIObject();
1054
}
1055
if (is_hotspot()) {
1056
return wrap(JNIHandles::make_local(HotSpotJVMCI::resolve(object)));
1057
} else {
1058
JNIAccessMark jni(this);
1059
return wrap(jni()->NewLocalRef(object.as_jobject()));
1060
}
1061
}
1062
1063
JVMCIObject JVMCIEnv::make_global(JVMCIObject object) {
1064
if (object.is_null()) {
1065
return JVMCIObject();
1066
}
1067
if (is_hotspot()) {
1068
return wrap(JNIHandles::make_global(Handle(Thread::current(), HotSpotJVMCI::resolve(object))));
1069
} else {
1070
JNIAccessMark jni(this);
1071
return wrap(jni()->NewGlobalRef(object.as_jobject()));
1072
}
1073
}
1074
1075
void JVMCIEnv::destroy_local(JVMCIObject object) {
1076
if (is_hotspot()) {
1077
JNIHandles::destroy_local(object.as_jobject());
1078
} else {
1079
JNIAccessMark jni(this);
1080
jni()->DeleteLocalRef(object.as_jobject());
1081
}
1082
}
1083
1084
void JVMCIEnv::destroy_global(JVMCIObject object) {
1085
if (is_hotspot()) {
1086
JNIHandles::destroy_global(object.as_jobject());
1087
} else {
1088
JNIAccessMark jni(this);
1089
jni()->DeleteGlobalRef(object.as_jobject());
1090
}
1091
}
1092
1093
const char* JVMCIEnv::klass_name(JVMCIObject object) {
1094
if (is_hotspot()) {
1095
return HotSpotJVMCI::resolve(object)->klass()->signature_name();
1096
} else {
1097
JVMCIObject name;
1098
{
1099
JNIAccessMark jni(this);
1100
jclass jcl = jni()->GetObjectClass(object.as_jobject());
1101
jobject result = jni()->CallObjectMethod(jcl, JNIJVMCI::Class_getName_method());
1102
name = JVMCIObject::create(result, is_hotspot());
1103
}
1104
return as_utf8_string(name);
1105
}
1106
}
1107
1108
JVMCIObject JVMCIEnv::get_jvmci_method(const methodHandle& method, JVMCI_TRAPS) {
1109
JVMCIObject method_object;
1110
if (method() == NULL) {
1111
return method_object;
1112
}
1113
1114
CompilerOracle::tag_blackhole_if_possible(method);
1115
1116
JavaThread* THREAD = JVMCI::compilation_tick(JavaThread::current()); // For exception macros.
1117
jmetadata handle = _runtime->allocate_handle(method);
1118
jboolean exception = false;
1119
if (is_hotspot()) {
1120
JavaValue result(T_OBJECT);
1121
JavaCallArguments args;
1122
args.push_long((jlong) handle);
1123
JavaCalls::call_static(&result, HotSpotJVMCI::HotSpotResolvedJavaMethodImpl::klass(),
1124
vmSymbols::fromMetaspace_name(),
1125
vmSymbols::method_fromMetaspace_signature(), &args, THREAD);
1126
if (HAS_PENDING_EXCEPTION) {
1127
exception = true;
1128
} else {
1129
method_object = wrap(result.get_oop());
1130
}
1131
} else {
1132
JNIAccessMark jni(this, THREAD);
1133
method_object = JNIJVMCI::wrap(jni()->CallStaticObjectMethod(JNIJVMCI::HotSpotResolvedJavaMethodImpl::clazz(),
1134
JNIJVMCI::HotSpotResolvedJavaMethodImpl_fromMetaspace_method(),
1135
(jlong) handle));
1136
exception = jni()->ExceptionCheck();
1137
}
1138
1139
if (exception) {
1140
_runtime->release_handle(handle);
1141
return JVMCIObject();
1142
}
1143
1144
assert(asMethod(method_object) == method(), "must be");
1145
if (get_HotSpotResolvedJavaMethodImpl_metadataHandle(method_object) != (jlong) handle) {
1146
_runtime->release_handle(handle);
1147
}
1148
assert(!method_object.is_null(), "must be");
1149
return method_object;
1150
}
1151
1152
JVMCIObject JVMCIEnv::get_jvmci_type(const JVMCIKlassHandle& klass, JVMCI_TRAPS) {
1153
JVMCIObject type;
1154
if (klass.is_null()) {
1155
return type;
1156
}
1157
1158
jlong pointer = (jlong) klass();
1159
JavaThread* THREAD = JVMCI::compilation_tick(JavaThread::current()); // For exception macros.
1160
JVMCIObject signature = create_string(klass->signature_name(), JVMCI_CHECK_(JVMCIObject()));
1161
jboolean exception = false;
1162
if (is_hotspot()) {
1163
JavaValue result(T_OBJECT);
1164
JavaCallArguments args;
1165
args.push_long(pointer);
1166
args.push_oop(Handle(THREAD, HotSpotJVMCI::resolve(signature)));
1167
JavaCalls::call_static(&result,
1168
HotSpotJVMCI::HotSpotResolvedObjectTypeImpl::klass(),
1169
vmSymbols::fromMetaspace_name(),
1170
vmSymbols::klass_fromMetaspace_signature(), &args, THREAD);
1171
1172
if (HAS_PENDING_EXCEPTION) {
1173
exception = true;
1174
} else {
1175
type = wrap(result.get_oop());
1176
}
1177
} else {
1178
JNIAccessMark jni(this, THREAD);
1179
1180
HandleMark hm(THREAD);
1181
type = JNIJVMCI::wrap(jni()->CallStaticObjectMethod(JNIJVMCI::HotSpotResolvedObjectTypeImpl::clazz(),
1182
JNIJVMCI::HotSpotResolvedObjectTypeImpl_fromMetaspace_method(),
1183
pointer, signature.as_jstring()));
1184
exception = jni()->ExceptionCheck();
1185
}
1186
if (exception) {
1187
return JVMCIObject();
1188
}
1189
1190
assert(type.is_non_null(), "must have result");
1191
return type;
1192
}
1193
1194
JVMCIObject JVMCIEnv::get_jvmci_constant_pool(const constantPoolHandle& cp, JVMCI_TRAPS) {
1195
JVMCIObject cp_object;
1196
jmetadata handle = _runtime->allocate_handle(cp);
1197
jboolean exception = false;
1198
JavaThread* THREAD = JVMCI::compilation_tick(JavaThread::current()); // For exception macros.
1199
if (is_hotspot()) {
1200
JavaValue result(T_OBJECT);
1201
JavaCallArguments args;
1202
args.push_long((jlong) handle);
1203
JavaCalls::call_static(&result,
1204
HotSpotJVMCI::HotSpotConstantPool::klass(),
1205
vmSymbols::fromMetaspace_name(),
1206
vmSymbols::constantPool_fromMetaspace_signature(), &args, THREAD);
1207
if (HAS_PENDING_EXCEPTION) {
1208
exception = true;
1209
} else {
1210
cp_object = wrap(result.get_oop());
1211
}
1212
} else {
1213
JNIAccessMark jni(this, THREAD);
1214
cp_object = JNIJVMCI::wrap(jni()->CallStaticObjectMethod(JNIJVMCI::HotSpotConstantPool::clazz(),
1215
JNIJVMCI::HotSpotConstantPool_fromMetaspace_method(),
1216
(jlong) handle));
1217
exception = jni()->ExceptionCheck();
1218
}
1219
1220
if (exception) {
1221
_runtime->release_handle(handle);
1222
return JVMCIObject();
1223
}
1224
1225
assert(!cp_object.is_null(), "must be");
1226
// Constant pools aren't cached so this is always a newly created object using the handle
1227
assert(get_HotSpotConstantPool_metadataHandle(cp_object) == (jlong) handle, "must use same handle");
1228
return cp_object;
1229
}
1230
1231
JVMCIPrimitiveArray JVMCIEnv::new_booleanArray(int length, JVMCI_TRAPS) {
1232
JavaThread* THREAD = JavaThread::current(); // For exception macros.
1233
if (is_hotspot()) {
1234
typeArrayOop result = oopFactory::new_boolArray(length, CHECK_(JVMCIObject()));
1235
return wrap(result);
1236
} else {
1237
JNIAccessMark jni(this, THREAD);
1238
jbooleanArray result = jni()->NewBooleanArray(length);
1239
return wrap(result);
1240
}
1241
}
1242
1243
JVMCIPrimitiveArray JVMCIEnv::new_byteArray(int length, JVMCI_TRAPS) {
1244
JavaThread* THREAD = JavaThread::current(); // For exception macros.
1245
if (is_hotspot()) {
1246
typeArrayOop result = oopFactory::new_byteArray(length, CHECK_(JVMCIObject()));
1247
return wrap(result);
1248
} else {
1249
JNIAccessMark jni(this, THREAD);
1250
jbyteArray result = jni()->NewByteArray(length);
1251
return wrap(result);
1252
}
1253
}
1254
1255
JVMCIObjectArray JVMCIEnv::new_byte_array_array(int length, JVMCI_TRAPS) {
1256
JavaThread* THREAD = JavaThread::current(); // For exception macros.
1257
if (is_hotspot()) {
1258
Klass* byteArrayArrayKlass = TypeArrayKlass::cast(Universe::byteArrayKlassObj ())->array_klass(CHECK_(JVMCIObject()));
1259
objArrayOop result = ObjArrayKlass::cast(byteArrayArrayKlass) ->allocate(length, CHECK_(JVMCIObject()));
1260
return wrap(result);
1261
} else {
1262
JNIAccessMark jni(this, THREAD);
1263
jobjectArray result = jni()->NewObjectArray(length, JNIJVMCI::byte_array(), NULL);
1264
return wrap(result);
1265
}
1266
}
1267
1268
JVMCIPrimitiveArray JVMCIEnv::new_intArray(int length, JVMCI_TRAPS) {
1269
JavaThread* THREAD = JavaThread::current(); // For exception macros.
1270
if (is_hotspot()) {
1271
typeArrayOop result = oopFactory::new_intArray(length, CHECK_(JVMCIObject()));
1272
return wrap(result);
1273
} else {
1274
JNIAccessMark jni(this, THREAD);
1275
jintArray result = jni()->NewIntArray(length);
1276
return wrap(result);
1277
}
1278
}
1279
1280
JVMCIPrimitiveArray JVMCIEnv::new_longArray(int length, JVMCI_TRAPS) {
1281
JavaThread* THREAD = JavaThread::current(); // For exception macros.
1282
if (is_hotspot()) {
1283
typeArrayOop result = oopFactory::new_longArray(length, CHECK_(JVMCIObject()));
1284
return wrap(result);
1285
} else {
1286
JNIAccessMark jni(this, THREAD);
1287
jlongArray result = jni()->NewLongArray(length);
1288
return wrap(result);
1289
}
1290
}
1291
1292
JVMCIObject JVMCIEnv::new_VMField(JVMCIObject name, JVMCIObject type, jlong offset, jlong address, JVMCIObject value, JVMCI_TRAPS) {
1293
JavaThread* THREAD = JavaThread::current(); // For exception macros.
1294
if (is_hotspot()) {
1295
HotSpotJVMCI::VMField::klass()->initialize(CHECK_(JVMCIObject()));
1296
oop obj = HotSpotJVMCI::VMField::klass()->allocate_instance(CHECK_(JVMCIObject()));
1297
HotSpotJVMCI::VMField::set_name(this, obj, HotSpotJVMCI::resolve(name));
1298
HotSpotJVMCI::VMField::set_type(this, obj, HotSpotJVMCI::resolve(type));
1299
HotSpotJVMCI::VMField::set_offset(this, obj, offset);
1300
HotSpotJVMCI::VMField::set_address(this, obj, address);
1301
HotSpotJVMCI::VMField::set_value(this, obj, HotSpotJVMCI::resolve(value));
1302
return wrap(obj);
1303
} else {
1304
JNIAccessMark jni(this, THREAD);
1305
jobject result = jni()->NewObject(JNIJVMCI::VMField::clazz(),
1306
JNIJVMCI::VMField::constructor(),
1307
get_jobject(name), get_jobject(type), offset, address, get_jobject(value));
1308
return wrap(result);
1309
}
1310
}
1311
1312
JVMCIObject JVMCIEnv::new_VMFlag(JVMCIObject name, JVMCIObject type, JVMCIObject value, JVMCI_TRAPS) {
1313
JavaThread* THREAD = JavaThread::current(); // For exception macros.
1314
if (is_hotspot()) {
1315
HotSpotJVMCI::VMFlag::klass()->initialize(CHECK_(JVMCIObject()));
1316
oop obj = HotSpotJVMCI::VMFlag::klass()->allocate_instance(CHECK_(JVMCIObject()));
1317
HotSpotJVMCI::VMFlag::set_name(this, obj, HotSpotJVMCI::resolve(name));
1318
HotSpotJVMCI::VMFlag::set_type(this, obj, HotSpotJVMCI::resolve(type));
1319
HotSpotJVMCI::VMFlag::set_value(this, obj, HotSpotJVMCI::resolve(value));
1320
return wrap(obj);
1321
} else {
1322
JNIAccessMark jni(this, THREAD);
1323
jobject result = jni()->NewObject(JNIJVMCI::VMFlag::clazz(),
1324
JNIJVMCI::VMFlag::constructor(),
1325
get_jobject(name), get_jobject(type), get_jobject(value));
1326
return wrap(result);
1327
}
1328
}
1329
1330
JVMCIObject JVMCIEnv::new_VMIntrinsicMethod(JVMCIObject declaringClass, JVMCIObject name, JVMCIObject descriptor, int id, JVMCI_TRAPS) {
1331
JavaThread* THREAD = JavaThread::current(); // For exception macros.
1332
if (is_hotspot()) {
1333
HotSpotJVMCI::VMIntrinsicMethod::klass()->initialize(CHECK_(JVMCIObject()));
1334
oop obj = HotSpotJVMCI::VMIntrinsicMethod::klass()->allocate_instance(CHECK_(JVMCIObject()));
1335
HotSpotJVMCI::VMIntrinsicMethod::set_declaringClass(this, obj, HotSpotJVMCI::resolve(declaringClass));
1336
HotSpotJVMCI::VMIntrinsicMethod::set_name(this, obj, HotSpotJVMCI::resolve(name));
1337
HotSpotJVMCI::VMIntrinsicMethod::set_descriptor(this, obj, HotSpotJVMCI::resolve(descriptor));
1338
HotSpotJVMCI::VMIntrinsicMethod::set_id(this, obj, id);
1339
return wrap(obj);
1340
} else {
1341
JNIAccessMark jni(this, THREAD);
1342
jobject result = jni()->NewObject(JNIJVMCI::VMIntrinsicMethod::clazz(),
1343
JNIJVMCI::VMIntrinsicMethod::constructor(),
1344
get_jobject(declaringClass), get_jobject(name), get_jobject(descriptor), id);
1345
return wrap(result);
1346
}
1347
}
1348
1349
JVMCIObject JVMCIEnv::new_HotSpotStackFrameReference(JVMCI_TRAPS) {
1350
if (is_hotspot()) {
1351
JavaThread* THREAD = JavaThread::current(); // For exception macros.
1352
HotSpotJVMCI::HotSpotStackFrameReference::klass()->initialize(CHECK_(JVMCIObject()));
1353
oop obj = HotSpotJVMCI::HotSpotStackFrameReference::klass()->allocate_instance(CHECK_(JVMCIObject()));
1354
return wrap(obj);
1355
} else {
1356
ShouldNotReachHere();
1357
return JVMCIObject();
1358
}
1359
}
1360
JVMCIObject JVMCIEnv::new_JVMCIError(JVMCI_TRAPS) {
1361
if (is_hotspot()) {
1362
JavaThread* THREAD = JavaThread::current(); // For exception macros.
1363
HotSpotJVMCI::JVMCIError::klass()->initialize(CHECK_(JVMCIObject()));
1364
oop obj = HotSpotJVMCI::JVMCIError::klass()->allocate_instance(CHECK_(JVMCIObject()));
1365
return wrap(obj);
1366
} else {
1367
ShouldNotReachHere();
1368
return JVMCIObject();
1369
}
1370
}
1371
1372
1373
JVMCIObject JVMCIEnv::get_object_constant(oop objOop, bool compressed, bool dont_register) {
1374
JavaThread* THREAD = JavaThread::current(); // For exception macros.
1375
Handle obj = Handle(THREAD, objOop);
1376
if (obj.is_null()) {
1377
return JVMCIObject();
1378
}
1379
if (is_hotspot()) {
1380
HotSpotJVMCI::DirectHotSpotObjectConstantImpl::klass()->initialize(CHECK_(JVMCIObject()));
1381
oop constant = HotSpotJVMCI::DirectHotSpotObjectConstantImpl::klass()->allocate_instance(CHECK_(JVMCIObject()));
1382
HotSpotJVMCI::DirectHotSpotObjectConstantImpl::set_object(this, constant, obj());
1383
HotSpotJVMCI::HotSpotObjectConstantImpl::set_compressed(this, constant, compressed);
1384
return wrap(constant);
1385
} else {
1386
jlong handle = make_handle(obj);
1387
JNIAccessMark jni(this, THREAD);
1388
jobject result = jni()->NewObject(JNIJVMCI::IndirectHotSpotObjectConstantImpl::clazz(),
1389
JNIJVMCI::IndirectHotSpotObjectConstantImpl::constructor(),
1390
handle, compressed, dont_register);
1391
return wrap(result);
1392
}
1393
}
1394
1395
1396
Handle JVMCIEnv::asConstant(JVMCIObject constant, JVMCI_TRAPS) {
1397
if (constant.is_null()) {
1398
return Handle();
1399
}
1400
JavaThread* THREAD = JavaThread::current(); // For exception macros.
1401
if (is_hotspot()) {
1402
assert(HotSpotJVMCI::DirectHotSpotObjectConstantImpl::is_instance(this, constant), "wrong type");
1403
oop obj = HotSpotJVMCI::DirectHotSpotObjectConstantImpl::object(this, HotSpotJVMCI::resolve(constant));
1404
return Handle(THREAD, obj);
1405
} else if (isa_IndirectHotSpotObjectConstantImpl(constant)) {
1406
jlong object_handle = get_IndirectHotSpotObjectConstantImpl_objectHandle(constant);
1407
if (object_handle == 0L) {
1408
JVMCI_THROW_MSG_(NullPointerException, "Foreign object reference has been cleared", Handle());
1409
}
1410
oop result = resolve_handle(object_handle);
1411
if (result == NULL) {
1412
JVMCI_THROW_MSG_(InternalError, "Constant was unexpectedly NULL", Handle());
1413
}
1414
return Handle(THREAD, result);
1415
} else {
1416
JVMCI_THROW_MSG_(IllegalArgumentException, "DirectHotSpotObjectConstantImpl shouldn't reach JVMCI in SVM mode", Handle());
1417
}
1418
}
1419
1420
JVMCIObject JVMCIEnv::wrap(jobject object) {
1421
return JVMCIObject::create(object, is_hotspot());
1422
}
1423
1424
jlong JVMCIEnv::make_handle(const Handle& obj) {
1425
assert(!obj.is_null(), "should only create handle for non-NULL oops");
1426
jobject handle = _runtime->make_global(obj);
1427
return (jlong) handle;
1428
}
1429
1430
oop JVMCIEnv::resolve_handle(jlong objectHandle) {
1431
assert(objectHandle != 0, "should be a valid handle");
1432
oop obj = *((oopDesc**)objectHandle);
1433
if (obj != NULL) {
1434
oopDesc::verify(obj);
1435
}
1436
return obj;
1437
}
1438
1439
JVMCIObject JVMCIEnv::create_string(const char* str, JVMCI_TRAPS) {
1440
JavaThread* THREAD = JavaThread::current(); // For exception macros.
1441
if (is_hotspot()) {
1442
Handle result = java_lang_String::create_from_str(str, CHECK_(JVMCIObject()));
1443
return HotSpotJVMCI::wrap(result());
1444
} else {
1445
jobject result;
1446
jboolean exception = false;
1447
{
1448
JNIAccessMark jni(this, THREAD);
1449
result = jni()->NewStringUTF(str);
1450
exception = jni()->ExceptionCheck();
1451
}
1452
return wrap(result);
1453
}
1454
}
1455
1456
bool JVMCIEnv::equals(JVMCIObject a, JVMCIObject b) {
1457
if (is_hotspot()) {
1458
return HotSpotJVMCI::resolve(a) == HotSpotJVMCI::resolve(b);
1459
} else {
1460
JNIAccessMark jni(this);
1461
return jni()->IsSameObject(a.as_jobject(), b.as_jobject()) != 0;
1462
}
1463
}
1464
1465
BasicType JVMCIEnv::kindToBasicType(JVMCIObject kind, JVMCI_TRAPS) {
1466
if (kind.is_null()) {
1467
JVMCI_THROW_(NullPointerException, T_ILLEGAL);
1468
}
1469
jchar ch = get_JavaKind_typeChar(kind);
1470
switch(ch) {
1471
case 'Z': return T_BOOLEAN;
1472
case 'B': return T_BYTE;
1473
case 'S': return T_SHORT;
1474
case 'C': return T_CHAR;
1475
case 'I': return T_INT;
1476
case 'F': return T_FLOAT;
1477
case 'J': return T_LONG;
1478
case 'D': return T_DOUBLE;
1479
case 'A': return T_OBJECT;
1480
case '-': return T_ILLEGAL;
1481
default:
1482
JVMCI_ERROR_(T_ILLEGAL, "unexpected Kind: %c", ch);
1483
}
1484
}
1485
1486
void JVMCIEnv::initialize_installed_code(JVMCIObject installed_code, CodeBlob* cb, JVMCI_TRAPS) {
1487
// Ensure that all updates to the InstalledCode fields are consistent.
1488
if (get_InstalledCode_address(installed_code) != 0) {
1489
JVMCI_THROW_MSG(InternalError, "InstalledCode instance already in use");
1490
}
1491
if (!isa_HotSpotInstalledCode(installed_code)) {
1492
JVMCI_THROW_MSG(InternalError, "InstalledCode instance must be a subclass of HotSpotInstalledCode");
1493
}
1494
1495
// Ignore the version which can stay at 0
1496
if (cb->is_nmethod()) {
1497
nmethod* nm = cb->as_nmethod_or_null();
1498
if (!nm->is_alive()) {
1499
JVMCI_THROW_MSG(InternalError, "nmethod has been reclaimed");
1500
}
1501
if (nm->is_in_use()) {
1502
set_InstalledCode_entryPoint(installed_code, (jlong) nm->verified_entry_point());
1503
}
1504
} else {
1505
set_InstalledCode_entryPoint(installed_code, (jlong) cb->code_begin());
1506
}
1507
set_InstalledCode_address(installed_code, (jlong) cb);
1508
set_HotSpotInstalledCode_size(installed_code, cb->size());
1509
set_HotSpotInstalledCode_codeStart(installed_code, (jlong) cb->code_begin());
1510
set_HotSpotInstalledCode_codeSize(installed_code, cb->code_size());
1511
}
1512
1513
1514
void JVMCIEnv::invalidate_nmethod_mirror(JVMCIObject mirror, JVMCI_TRAPS) {
1515
if (mirror.is_null()) {
1516
JVMCI_THROW(NullPointerException);
1517
}
1518
1519
nmethodLocker locker;
1520
nmethod* nm = JVMCIENV->get_nmethod(mirror, locker);
1521
if (nm == NULL) {
1522
// Nothing to do
1523
return;
1524
}
1525
1526
Thread* current = Thread::current();
1527
if (!mirror.is_hotspot() && !current->is_Java_thread()) {
1528
// Calling back into native might cause the execution to block, so only allow this when calling
1529
// from a JavaThread, which is the normal case anyway.
1530
JVMCI_THROW_MSG(IllegalArgumentException,
1531
"Cannot invalidate HotSpotNmethod object in shared library VM heap from non-JavaThread");
1532
}
1533
1534
nmethodLocker nml(nm);
1535
if (nm->is_alive()) {
1536
// Invalidating the HotSpotNmethod means we want the nmethod to be deoptimized.
1537
Deoptimization::deoptimize_all_marked(nm);
1538
}
1539
1540
// A HotSpotNmethod instance can only reference a single nmethod
1541
// during its lifetime so simply clear it here.
1542
set_InstalledCode_address(mirror, 0);
1543
}
1544
1545
Klass* JVMCIEnv::asKlass(JVMCIObject obj) {
1546
return (Klass*) get_HotSpotResolvedObjectTypeImpl_metadataPointer(obj);
1547
}
1548
1549
Method* JVMCIEnv::asMethod(JVMCIObject obj) {
1550
Method** metadataHandle = (Method**) get_HotSpotResolvedJavaMethodImpl_metadataHandle(obj);
1551
return *metadataHandle;
1552
}
1553
1554
ConstantPool* JVMCIEnv::asConstantPool(JVMCIObject obj) {
1555
ConstantPool** metadataHandle = (ConstantPool**) get_HotSpotConstantPool_metadataHandle(obj);
1556
return *metadataHandle;
1557
}
1558
1559
CodeBlob* JVMCIEnv::get_code_blob(JVMCIObject obj, nmethodLocker& locker) {
1560
address code = (address) get_InstalledCode_address(obj);
1561
if (code == NULL) {
1562
return NULL;
1563
}
1564
if (isa_HotSpotNmethod(obj)) {
1565
nmethod* nm = NULL;
1566
{
1567
// Lookup the CodeBlob while holding the CodeCache_lock to ensure the nmethod can't be freed
1568
// by nmethod::flush while we're interrogating it.
1569
MutexLocker cm_lock(CodeCache_lock, Mutex::_no_safepoint_check_flag);
1570
CodeBlob* cb = CodeCache::find_blob_unsafe(code);
1571
if (cb == (CodeBlob*) code) {
1572
nmethod* the_nm = cb->as_nmethod_or_null();
1573
if (the_nm != NULL && the_nm->is_alive()) {
1574
// Lock the nmethod to stop any further transitions by the sweeper. It's still possible
1575
// for this code to execute in the middle of the sweeping of the nmethod but that will be
1576
// handled below.
1577
locker.set_code(nm, true);
1578
nm = the_nm;
1579
}
1580
}
1581
}
1582
1583
if (nm != NULL) {
1584
// We found the nmethod but it could be in the process of being freed. Check the state of the
1585
// nmethod while holding the CompiledMethod_lock. This ensures that any transitions by other
1586
// threads have seen the is_locked_by_vm() update above.
1587
MutexLocker cm_lock(CompiledMethod_lock, Mutex::_no_safepoint_check_flag);
1588
if (!nm->is_alive()) {
1589
// It was alive when we looked it up but it's no longer alive so release it.
1590
locker.set_code(NULL);
1591
nm = NULL;
1592
}
1593
}
1594
1595
jlong compile_id_snapshot = get_HotSpotNmethod_compileIdSnapshot(obj);
1596
if (compile_id_snapshot != 0L) {
1597
// Found a live nmethod with the same address, make sure it's the same nmethod
1598
if (nm == (nmethod*) code && nm->compile_id() == compile_id_snapshot && nm->is_alive()) {
1599
if (nm->is_not_entrant()) {
1600
// Zero the entry point so that the nmethod
1601
// cannot be invoked by the mirror but can
1602
// still be deoptimized.
1603
set_InstalledCode_entryPoint(obj, 0);
1604
}
1605
return nm;
1606
}
1607
// The HotSpotNmethod no longer refers to a valid nmethod so clear the state
1608
locker.set_code(NULL);
1609
nm = NULL;
1610
}
1611
1612
if (nm == NULL) {
1613
// The HotSpotNmethod was pointing at some nmethod but the nmethod is no longer valid, so
1614
// clear the InstalledCode fields of this HotSpotNmethod so that it no longer refers to a
1615
// nmethod in the code cache.
1616
set_InstalledCode_address(obj, 0);
1617
set_InstalledCode_entryPoint(obj, 0);
1618
}
1619
return nm;
1620
}
1621
1622
CodeBlob* cb = (CodeBlob*) code;
1623
assert(!cb->is_nmethod(), "unexpected nmethod");
1624
return cb;
1625
}
1626
1627
nmethod* JVMCIEnv::get_nmethod(JVMCIObject obj, nmethodLocker& locker) {
1628
CodeBlob* cb = get_code_blob(obj, locker);
1629
if (cb != NULL) {
1630
return cb->as_nmethod_or_null();
1631
}
1632
return NULL;
1633
}
1634
1635
// Generate implementations for the initialize, new, isa, get and set methods for all the types and
1636
// fields declared in the JVMCI_CLASSES_DO macro.
1637
1638
#define START_CLASS(className, fullClassName) \
1639
void JVMCIEnv::className##_initialize(JVMCI_TRAPS) { \
1640
if (is_hotspot()) { \
1641
HotSpotJVMCI::className::initialize(JVMCI_CHECK); \
1642
} else { \
1643
JNIJVMCI::className::initialize(JVMCI_CHECK); \
1644
} \
1645
} \
1646
JVMCIObjectArray JVMCIEnv::new_##className##_array(int length, JVMCI_TRAPS) { \
1647
if (is_hotspot()) { \
1648
JavaThread* THREAD = JavaThread::current(); /* For exception macros. */ \
1649
objArrayOop array = oopFactory::new_objArray(HotSpotJVMCI::className::klass(), length, CHECK_(JVMCIObject())); \
1650
return (JVMCIObjectArray) wrap(array); \
1651
} else { \
1652
JNIAccessMark jni(this); \
1653
jobjectArray result = jni()->NewObjectArray(length, JNIJVMCI::className::clazz(), NULL); \
1654
return wrap(result); \
1655
} \
1656
} \
1657
bool JVMCIEnv::isa_##className(JVMCIObject object) { \
1658
if (is_hotspot()) { \
1659
return HotSpotJVMCI::className::is_instance(this, object); \
1660
} else { \
1661
return JNIJVMCI::className::is_instance(this, object); \
1662
} \
1663
}
1664
1665
#define END_CLASS
1666
1667
#define FIELD(className, name, type, accessor, cast) \
1668
type JVMCIEnv::get_##className##_##name(JVMCIObject obj) { \
1669
if (is_hotspot()) { \
1670
return HotSpotJVMCI::className::get_##name(this, obj); \
1671
} else { \
1672
return JNIJVMCI::className::get_##name(this, obj); \
1673
} \
1674
} \
1675
void JVMCIEnv::set_##className##_##name(JVMCIObject obj, type x) { \
1676
if (is_hotspot()) { \
1677
HotSpotJVMCI::className::set_##name(this, obj, x); \
1678
} else { \
1679
JNIJVMCI::className::set_##name(this, obj, x); \
1680
} \
1681
}
1682
1683
#define EMPTY_CAST
1684
#define CHAR_FIELD(className, name) FIELD(className, name, jchar, Char, EMPTY_CAST)
1685
#define INT_FIELD(className, name) FIELD(className, name, jint, Int, EMPTY_CAST)
1686
#define BOOLEAN_FIELD(className, name) FIELD(className, name, jboolean, Boolean, EMPTY_CAST)
1687
#define LONG_FIELD(className, name) FIELD(className, name, jlong, Long, EMPTY_CAST)
1688
#define FLOAT_FIELD(className, name) FIELD(className, name, jfloat, Float, EMPTY_CAST)
1689
1690
#define OBJECT_FIELD(className, name, signature) OOPISH_FIELD(className, name, JVMCIObject, Object, EMPTY_CAST)
1691
#define OBJECTARRAY_FIELD(className, name, signature) OOPISH_FIELD(className, name, JVMCIObjectArray, Object, (JVMCIObjectArray))
1692
#define PRIMARRAY_FIELD(className, name, signature) OOPISH_FIELD(className, name, JVMCIPrimitiveArray, Object, (JVMCIPrimitiveArray))
1693
1694
#define STATIC_OBJECT_FIELD(className, name, signature) STATIC_OOPISH_FIELD(className, name, JVMCIObject, Object, (JVMCIObject))
1695
#define STATIC_OBJECTARRAY_FIELD(className, name, signature) STATIC_OOPISH_FIELD(className, name, JVMCIObjectArray, Object, (JVMCIObjectArray))
1696
1697
#define OOPISH_FIELD(className, name, type, accessor, cast) \
1698
type JVMCIEnv::get_##className##_##name(JVMCIObject obj) { \
1699
if (is_hotspot()) { \
1700
return HotSpotJVMCI::className::get_##name(this, obj); \
1701
} else { \
1702
return JNIJVMCI::className::get_##name(this, obj); \
1703
} \
1704
} \
1705
void JVMCIEnv::set_##className##_##name(JVMCIObject obj, type x) { \
1706
if (is_hotspot()) { \
1707
HotSpotJVMCI::className::set_##name(this, obj, x); \
1708
} else { \
1709
JNIJVMCI::className::set_##name(this, obj, x); \
1710
} \
1711
}
1712
1713
#define STATIC_OOPISH_FIELD(className, name, type, accessor, cast) \
1714
type JVMCIEnv::get_##className##_##name() { \
1715
if (is_hotspot()) { \
1716
return HotSpotJVMCI::className::get_##name(this); \
1717
} else { \
1718
return JNIJVMCI::className::get_##name(this); \
1719
} \
1720
} \
1721
void JVMCIEnv::set_##className##_##name(type x) { \
1722
if (is_hotspot()) { \
1723
HotSpotJVMCI::className::set_##name(this, x); \
1724
} else { \
1725
JNIJVMCI::className::set_##name(this, x); \
1726
} \
1727
}
1728
1729
#define STATIC_PRIMITIVE_FIELD(className, name, type, accessor, cast) \
1730
type JVMCIEnv::get_##className##_##name() { \
1731
if (is_hotspot()) { \
1732
return HotSpotJVMCI::className::get_##name(this); \
1733
} else { \
1734
return JNIJVMCI::className::get_##name(this); \
1735
} \
1736
} \
1737
void JVMCIEnv::set_##className##_##name(type x) { \
1738
if (is_hotspot()) { \
1739
HotSpotJVMCI::className::set_##name(this, x); \
1740
} else { \
1741
JNIJVMCI::className::set_##name(this, x); \
1742
} \
1743
}
1744
#define STATIC_INT_FIELD(className, name) STATIC_PRIMITIVE_FIELD(className, name, jint, Int, EMPTY_CAST)
1745
#define STATIC_BOOLEAN_FIELD(className, name) STATIC_PRIMITIVE_FIELD(className, name, jboolean, Boolean, EMPTY_CAST)
1746
#define METHOD(jniCallType, jniGetMethod, hsCallType, returnType, className, methodName, signatureSymbolName, args)
1747
#define CONSTRUCTOR(className, signature)
1748
1749
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)
1750
1751
#undef START_CLASS
1752
#undef END_CLASS
1753
#undef METHOD
1754
#undef CONSTRUCTOR
1755
#undef FIELD
1756
#undef CHAR_FIELD
1757
#undef INT_FIELD
1758
#undef BOOLEAN_FIELD
1759
#undef LONG_FIELD
1760
#undef FLOAT_FIELD
1761
#undef OBJECT_FIELD
1762
#undef PRIMARRAY_FIELD
1763
#undef OBJECTARRAY_FIELD
1764
#undef STATIC_OOPISH_FIELD
1765
#undef STATIC_OBJECT_FIELD
1766
#undef STATIC_OBJECTARRAY_FIELD
1767
#undef STATIC_INT_FIELD
1768
#undef STATIC_BOOLEAN_FIELD
1769
#undef EMPTY_CAST
1770
1771