src/hotspot/share/jvmci/jvmciCompilerToVM.cpp
Index
Unified diffs
Context diffs
Sdiffs
Wdiffs
Patch
New
Old
Previous File
Next File
*** old/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp Sat May 4 16:22:13 2019
--- new/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp Sat May 4 16:22:12 2019
*** 60,84 ****
--- 60,88 ----
_holder = Handle(_thread, klass->klass_holder());
}
return *this;
}
! void JNIHandleMark::push_jni_handle_block() {
JavaThread* thread = JavaThread::current();
! static void requireInHotSpot(const char* caller, JVMCI_TRAPS) {
+ if (!JVMCIENV->is_hotspot()) {
+ JVMCI_THROW_MSG(IllegalStateException, err_msg("Cannot call %s from JVMCI shared library", caller));
+ }
+ }
+
+ void JNIHandleMark::push_jni_handle_block(JavaThread* thread) {
if (thread != NULL) {
// Allocate a new block for JNI handles.
// Inlined code from jni_PushLocalFrame()
! JNIHandleBlock* java_handles = ((JavaThread*)thread)->active_handles();
JNIHandleBlock* compile_handles = JNIHandleBlock::allocate_block(thread);
assert(compile_handles != NULL && java_handles != NULL, "should not be NULL");
compile_handles->set_pop_frame_link(java_handles);
thread->set_active_handles(compile_handles);
}
}
! void JNIHandleMark::pop_jni_handle_block(JavaThread* thread) {
JavaThread* thread = JavaThread::current();
if (thread != NULL) {
// Release our JNI handle block
JNIHandleBlock* compile_handles = thread->active_handles();
JNIHandleBlock* java_handles = compile_handles->pop_frame_link();
thread->set_active_handles(java_handles);
*** 109,137 ****
--- 113,204 ----
oop arg=((objArrayOop) (_args))->obj_at(_index++);
assert(expectedType == T_OBJECT || java_lang_boxing_object::is_instance(arg, expectedType), "arg type mismatch");
return Handle(Thread::current(), arg);
}
! // Entry to native method implementation that transitions current thread to '_thread_in_vm'.
! #define C2V_VMENTRY(result_type, name, signature) \
! JNIEXPORT result_type JNICALL c2v_ ## name signature { \
! JVMCITraceMark jtm("CompilerToVM::" #name); \
! // Bring the JVMCI compiler thread into the VM state.
! #define JVMCI_VM_ENTRY_MARK \
! ThreadInVMfromNative __tiv(thread); \
! ResetNoHandleMark rnhm; \
+ HandleMarkCleaner __hm(thread); \
+ Thread* THREAD = thread; \
+ debug_only(VMNativeEntryWrapper __vew;)
+
+ // Native method block that transitions current thread to '_thread_in_vm'.
+ #define C2V_BLOCK(result_type, name, signature) \
TRACE_CALL(result_type, jvmci_ ## name signature) \
JVMCI_VM_ENTRY_MARK; \
ResourceMark rm; \
! JNI_JVMCIENV(thread, env);
+
+ static Thread* get_current_thread() {
+ return Thread::current_or_null_safe();
+ }
+
+ // Entry to native method implementation that transitions
+ // current thread to '_thread_in_vm'.
+ #define C2V_VMENTRY(result_type, name, signature) \
+ JNIEXPORT result_type JNICALL c2v_ ## name signature { \
+ Thread* base_thread = get_current_thread(); \
+ if (base_thread == NULL) { \
+ env->ThrowNew(JNIJVMCI::InternalError::clazz(), \
+ err_msg("Cannot call into HotSpot from JVMCI shared library without attaching current thread")); \
+ return; \
+ } \
+ assert(base_thread->is_Java_thread(), "just checking");\
+ JavaThread* thread = (JavaThread*) base_thread; \
+ JVMCITraceMark jtm("CompilerToVM::" #name); \
+ C2V_BLOCK(result_type, name, signature)
+
+ #define C2V_VMENTRY_(result_type, name, signature, result) \
+ JNIEXPORT result_type JNICALL c2v_ ## name signature { \
+ Thread* base_thread = get_current_thread(); \
+ if (base_thread == NULL) { \
+ env->ThrowNew(JNIJVMCI::InternalError::clazz(), \
+ err_msg("Cannot call into HotSpot from JVMCI shared library without attaching current thread")); \
+ return result; \
+ } \
+ assert(base_thread->is_Java_thread(), "just checking");\
+ JavaThread* thread = (JavaThread*) base_thread; \
+ JVMCITraceMark jtm("CompilerToVM::" #name); \
+ C2V_BLOCK(result_type, name, signature)
+
+ #define C2V_VMENTRY_NULL(result_type, name, signature) C2V_VMENTRY_(result_type, name, signature, NULL)
+ #define C2V_VMENTRY_0(result_type, name, signature) C2V_VMENTRY_(result_type, name, signature, 0)
+
+ // Entry to native method implementation that does not transition
+ // current thread to '_thread_in_vm'.
+ #define C2V_VMENTRY_PREFIX(result_type, name, signature) \
+ JNIEXPORT result_type JNICALL c2v_ ## name signature { \
+ Thread* base_thread = get_current_thread();
#define C2V_END }
+ #define JNI_THROW(caller, name, msg) do { \
+ jint __throw_res = env->ThrowNew(JNIJVMCI::name::clazz(), msg); \
+ if (__throw_res != JNI_OK) { \
+ tty->print_cr("Throwing " #name " in " caller " returned %d", __throw_res); \
+ } \
+ return; \
+ } while (0);
+
+ #define JNI_THROW_(caller, name, msg, result) do { \
+ jint __throw_res = env->ThrowNew(JNIJVMCI::name::clazz(), msg); \
+ if (__throw_res != JNI_OK) { \
+ tty->print_cr("Throwing " #name " in " caller " returned %d", __throw_res); \
+ } \
+ return result; \
+ } while (0)
+
jobjectArray readConfiguration0(JNIEnv *env, JVMCI_TRAPS);
! C2V_VMENTRY_NULL(jobjectArray, readConfiguration, (JNIEnv* env))
jobjectArray config = readConfiguration0(env, JVMCI_CHECK_NULL);
return config;
}
! C2V_VMENTRY_NULL(jobject, getFlagValue, (JNIEnv* env, jobject c2vm, jobject name_handle))
#define RETURN_BOXED_LONG(value) jvalue p; p.j = (jlong) (value); JVMCIObject box = JVMCIENV->create_box(T_LONG, &p, JVMCI_CHECK_NULL); return box.as_jobject();
#define RETURN_BOXED_DOUBLE(value) jvalue p; p.d = (jdouble) (value); JVMCIObject box = JVMCIENV->create_box(T_DOUBLE, &p, JVMCI_CHECK_NULL); return box.as_jobject();
JVMCIObject name = JVMCIENV->wrap(name_handle);
if (name.is_null()) {
JVMCI_THROW_NULL(NullPointerException);
*** 168,192 ****
--- 235,257 ----
}
#undef RETURN_BOXED_LONG
#undef RETURN_BOXED_DOUBLE
C2V_END
! C2V_VMENTRY_NULL(jobject, getObjectAtAddress, (JNIEnv* env, jobject c2vm, jlong oop_address))
if (env != JavaThread::current()->jni_environment()) {
JVMCI_THROW_MSG_NULL(InternalError, "Only supported when running in HotSpot");
}
+ requireInHotSpot("getObjectAtAddress", JVMCI_CHECK_NULL);
if (oop_address == 0) {
JVMCI_THROW_MSG_NULL(InternalError, "Handle must be non-zero");
}
oop obj = *((oopDesc**) oop_address);
if (obj != NULL) {
oopDesc::verify(obj);
}
return JNIHandles::make_local(obj);
C2V_END
! C2V_VMENTRY_NULL(jbyteArray, getBytecode, (JNIEnv* env, jobject, jobject jvmci_method))
methodHandle method = JVMCIENV->asMethod(jvmci_method);
int code_size = method->code_size();
jbyte* reconstituted_code = NEW_RESOURCE_ARRAY(jbyte, code_size);
*** 260,287 ****
--- 325,349 ----
JVMCIPrimitiveArray result = JVMCIENV->new_byteArray(code_size, JVMCI_CHECK_NULL);
JVMCIENV->copy_bytes_from(reconstituted_code, result, 0, code_size);
return JVMCIENV->get_jbyteArray(result);
C2V_END
! C2V_VMENTRY_0(jint, getExceptionTableLength, (JNIEnv* env, jobject, jobject jvmci_method))
methodHandle method = JVMCIENV->asMethod(jvmci_method);
return method->exception_table_length();
C2V_END
! C2V_VMENTRY_0(jlong, getExceptionTableStart, (JNIEnv* env, jobject, jobject jvmci_method))
methodHandle method = JVMCIENV->asMethod(jvmci_method);
if (method->exception_table_length() == 0) {
return 0L;
}
return (jlong) (address) method->exception_table_start();
C2V_END
! C2V_VMENTRY_NULL(jobject, asResolvedJavaMethod, (JNIEnv* env, jobject, jobject executable_handle))
if (env != JavaThread::current()->jni_environment()) {
JVMCI_THROW_MSG_NULL(InternalError, "Only supported when running in HotSpot");
}
+ requireInHotSpot("asResolvedJavaMethod", JVMCI_CHECK_NULL);
oop executable = JNIHandles::resolve(executable_handle);
oop mirror = NULL;
int slot = 0;
if (executable->klass() == SystemDictionary::reflect_Constructor_klass()) {
*** 296,306 ****
--- 358,368 ----
methodHandle method = InstanceKlass::cast(holder)->method_with_idnum(slot);
JVMCIObject result = JVMCIENV->get_jvmci_method(method, JVMCI_CHECK_NULL);
return JVMCIENV->get_jobject(result);
}
! C2V_VMENTRY_NULL(jobject, getResolvedJavaMethod, (JNIEnv* env, jobject, jobject base, jlong offset))
methodHandle method;
JVMCIObject base_object = JVMCIENV->wrap(base);
if (base_object.is_null()) {
method = *((Method**)(offset));
} else if (JVMCIENV->isa_HotSpotObjectConstantImpl(base_object)) {
*** 319,329 ****
--- 381,391 ----
assert (method.is_null() || method->is_method(), "invalid read");
JVMCIObject result = JVMCIENV->get_jvmci_method(method, JVMCI_CHECK_NULL);
return JVMCIENV->get_jobject(result);
}
! C2V_VMENTRY_NULL(jobject, getConstantPool, (JNIEnv* env, jobject, jobject object_handle))
constantPoolHandle cp;
JVMCIObject object = JVMCIENV->wrap(object_handle);
if (object.is_null()) {
JVMCI_THROW_NULL(NullPointerException);
}
*** 339,349 ****
--- 401,411 ----
JVMCIObject result = JVMCIENV->get_jvmci_constant_pool(cp, JVMCI_CHECK_NULL);
return JVMCIENV->get_jobject(result);
}
! C2V_VMENTRY_NULL(jobject, getResolvedJavaType0, (JNIEnv* env, jobject, jobject base, jlong offset, jboolean compressed))
JVMCIKlassHandle klass(THREAD);
JVMCIObject base_object = JVMCIENV->wrap(base);
jlong base_address = 0;
if (base_object.is_non_null() && offset == oopDesc::klass_offset_in_bytes()) {
// klass = JVMCIENV->unhandle(base_object)->klass();
*** 382,392 ****
--- 444,454 ----
assert (klass == NULL || klass->is_klass(), "invalid read");
JVMCIObject result = JVMCIENV->get_jvmci_type(klass, JVMCI_CHECK_NULL);
return JVMCIENV->get_jobject(result);
}
! C2V_VMENTRY_NULL(jobject, findUniqueConcreteMethod, (JNIEnv* env, jobject, jobject jvmci_type, jobject jvmci_method))
methodHandle method = JVMCIENV->asMethod(jvmci_method);
Klass* holder = JVMCIENV->asKlass(jvmci_type);
if (holder->is_interface()) {
JVMCI_THROW_MSG_NULL(InternalError, err_msg("Interface %s should be handled in Java code", holder->external_name()));
}
*** 398,408 ****
--- 460,470 ----
}
JVMCIObject result = JVMCIENV->get_jvmci_method(ucm, JVMCI_CHECK_NULL);
return JVMCIENV->get_jobject(result);
C2V_END
! C2V_VMENTRY_NULL(jobject, getImplementor, (JNIEnv* env, jobject, jobject jvmci_type))
Klass* klass = JVMCIENV->asKlass(jvmci_type);
if (!klass->is_interface()) {
THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(),
err_msg("Expected interface type, got %s", klass->external_name()));
}
*** 415,448 ****
--- 477,510 ----
}
JVMCIObject implementor = JVMCIENV->get_jvmci_type(handle, JVMCI_CHECK_NULL);
return JVMCIENV->get_jobject(implementor);
C2V_END
! C2V_VMENTRY_0(jboolean, methodIsIgnoredBySecurityStackWalk,(JNIEnv* env, jobject, jobject jvmci_method))
methodHandle method = JVMCIENV->asMethod(jvmci_method);
return method->is_ignored_by_security_stack_walk();
C2V_END
! C2V_VMENTRY_0(jboolean, isCompilable,(JNIEnv* env, jobject, jobject jvmci_method))
methodHandle method = JVMCIENV->asMethod(jvmci_method);
constantPoolHandle cp = method->constMethod()->constants();
assert(!cp.is_null(), "npe");
// don't inline method when constant pool contains a CONSTANT_Dynamic
return !method->is_not_compilable(CompLevel_full_optimization) && !cp->has_dynamic_constant();
C2V_END
! C2V_VMENTRY_0(jboolean, hasNeverInlineDirective,(JNIEnv* env, jobject, jobject jvmci_method))
methodHandle method = JVMCIENV->asMethod(jvmci_method);
return !Inline || CompilerOracle::should_not_inline(method) || method->dont_inline();
C2V_END
! C2V_VMENTRY_0(jboolean, shouldInlineMethod,(JNIEnv* env, jobject, jobject jvmci_method))
methodHandle method = JVMCIENV->asMethod(jvmci_method);
return CompilerOracle::should_inline(method) || method->force_inline();
C2V_END
! C2V_VMENTRY_NULL(jobject, lookupType, (JNIEnv* env, jobject, jstring jname, jclass accessing_class, jboolean resolve))
JVMCIObject name = JVMCIENV->wrap(jname);
const char* str = JVMCIENV->as_utf8_string(name);
TempNewSymbol class_name = SymbolTable::new_symbol(str, CHECK_NULL);
if (class_name->utf8_length() <= 1) {
*** 463,472 ****
--- 525,537 ----
JVMCIENV->runtime()->initialize(JVMCIENV);
}
if (resolve) {
resolved_klass = SystemDictionary::resolve_or_null(class_name, class_loader, protection_domain, CHECK_0);
+ if (resolved_klass == NULL) {
+ JVMCI_THROW_MSG_NULL(ClassNotFoundException, str);
+ }
} else {
if (class_name->char_at(0) == 'L' &&
class_name->char_at(class_name->utf8_length()-1) == ';') {
// This is a name from a signature. Strip off the trimmings.
// Call recursive to keep scope of strippedsym.
*** 481,491 ****
--- 546,555 ----
BasicType t = FieldType::get_array_info(class_name, fd, CHECK_0);
if (t == T_OBJECT) {
TempNewSymbol strippedsym = SymbolTable::new_symbol(class_name->as_utf8()+1+fd.dimension(),
class_name->utf8_length()-2-fd.dimension(),
CHECK_0);
// naked oop "k" is OK here -- we assign back into it
resolved_klass = SystemDictionary::find(strippedsym,
class_loader,
protection_domain,
CHECK_0);
if (!resolved_klass.is_null()) {
*** 500,513 ****
--- 564,575 ----
}
JVMCIObject result = JVMCIENV->get_jvmci_type(resolved_klass, JVMCI_CHECK_NULL);
return JVMCIENV->get_jobject(result);
C2V_END
! C2V_VMENTRY_NULL(jobject, lookupClass, (JNIEnv* env, jobject, jclass mirror))
if (env != JavaThread::current()->jni_environment()) {
JVMCI_THROW_MSG_NULL(InternalError, "Only supported when running in HotSpot");
}
+ requireInHotSpot("lookupClass", JVMCI_CHECK_NULL);
if (mirror == NULL) {
return NULL;
}
JVMCIKlassHandle klass(THREAD);
klass = java_lang_Class::as_Klass(JNIHandles::resolve(mirror));
*** 516,574 ****
--- 578,637 ----
}
JVMCIObject result = JVMCIENV->get_jvmci_type(klass, JVMCI_CHECK_NULL);
return JVMCIENV->get_jobject(result);
}
! C2V_VMENTRY_NULL(jobject, resolveConstantInPool, (JNIEnv* env, jobject, jobject jvmci_constant_pool, jint index))
constantPoolHandle cp = JVMCIENV->asConstantPool(jvmci_constant_pool);
oop result = cp->resolve_constant_at(index, CHECK_NULL);
return JVMCIENV->get_jobject(JVMCIENV->get_object_constant(result));
C2V_END
! C2V_VMENTRY_NULL(jobject, resolvePossiblyCachedConstantInPool, (JNIEnv* env, jobject, jobject jvmci_constant_pool, jint index))
constantPoolHandle cp = JVMCIENV->asConstantPool(jvmci_constant_pool);
oop result = cp->resolve_possibly_cached_constant_at(index, CHECK_NULL);
return JVMCIENV->get_jobject(JVMCIENV->get_object_constant(result));
C2V_END
! C2V_VMENTRY_0(jint, lookupNameAndTypeRefIndexInPool, (JNIEnv* env, jobject, jobject jvmci_constant_pool, jint index))
constantPoolHandle cp = JVMCIENV->asConstantPool(jvmci_constant_pool);
return cp->name_and_type_ref_index_at(index);
C2V_END
! C2V_VMENTRY_NULL(jobject, lookupNameInPool, (JNIEnv* env, jobject, jobject jvmci_constant_pool, jint which))
constantPoolHandle cp = JVMCIENV->asConstantPool(jvmci_constant_pool);
JVMCIObject sym = JVMCIENV->create_string(cp->name_ref_at(which), JVMCI_CHECK_NULL);
return JVMCIENV->get_jobject(sym);
C2V_END
! C2V_VMENTRY_NULL(jobject, lookupSignatureInPool, (JNIEnv* env, jobject, jobject jvmci_constant_pool, jint which))
constantPoolHandle cp = JVMCIENV->asConstantPool(jvmci_constant_pool);
JVMCIObject sym = JVMCIENV->create_string(cp->signature_ref_at(which), JVMCI_CHECK_NULL);
return JVMCIENV->get_jobject(sym);
C2V_END
! C2V_VMENTRY_0(jint, lookupKlassRefIndexInPool, (JNIEnv* env, jobject, jobject jvmci_constant_pool, jint index))
constantPoolHandle cp = JVMCIENV->asConstantPool(jvmci_constant_pool);
return cp->klass_ref_index_at(index);
C2V_END
! C2V_VMENTRY_NULL(jobject, resolveTypeInPool, (JNIEnv* env, jobject, jobject jvmci_constant_pool, jint index))
constantPoolHandle cp = JVMCIENV->asConstantPool(jvmci_constant_pool);
Klass* klass = cp->klass_at(index, CHECK_NULL);
JVMCIKlassHandle resolved_klass(THREAD, klass);
if (resolved_klass->is_instance_klass()) {
! bool linked = InstanceKlass::cast(resolved_klass())->link_class_or_fail(CHECK_NULL);
! if (!linked) {
return NULL;
! if (!InstanceKlass::cast(resolved_klass())->is_linked()) {
+ // link_class() should not return here if there is an issue.
+ JVMCI_THROW_MSG_NULL(InternalError, err_msg("Class %s must be linked", resolved_klass()->external_name()));
}
}
JVMCIObject klassObject = JVMCIENV->get_jvmci_type(resolved_klass, JVMCI_CHECK_NULL);
return JVMCIENV->get_jobject(klassObject);
C2V_END
! C2V_VMENTRY_NULL(jobject, lookupKlassInPool, (JNIEnv* env, jobject, jobject jvmci_constant_pool, jint index, jbyte opcode))
constantPoolHandle cp = JVMCIENV->asConstantPool(jvmci_constant_pool);
Klass* loading_klass = cp->pool_holder();
bool is_accessible = false;
JVMCIKlassHandle klass(THREAD, JVMCIRuntime::get_klass_by_index(cp, index, is_accessible, loading_klass));
Symbol* symbol = NULL;
*** 592,622 ****
--- 655,685 ----
result = JVMCIENV->create_string(symbol, JVMCI_CHECK_NULL);
}
return JVMCIENV->get_jobject(result);
C2V_END
! C2V_VMENTRY_NULL(jobject, lookupAppendixInPool, (JNIEnv* env, jobject, jobject jvmci_constant_pool, jint index))
constantPoolHandle cp = JVMCIENV->asConstantPool(jvmci_constant_pool);
oop appendix_oop = ConstantPool::appendix_at_if_loaded(cp, index);
return JVMCIENV->get_jobject(JVMCIENV->get_object_constant(appendix_oop));
C2V_END
! C2V_VMENTRY_NULL(jobject, lookupMethodInPool, (JNIEnv* env, jobject, jobject jvmci_constant_pool, jint index, jbyte opcode))
constantPoolHandle cp = JVMCIENV->asConstantPool(jvmci_constant_pool);
InstanceKlass* pool_holder = cp->pool_holder();
Bytecodes::Code bc = (Bytecodes::Code) (((int) opcode) & 0xFF);
methodHandle method = JVMCIRuntime::get_method_by_index(cp, index, bc, pool_holder);
JVMCIObject result = JVMCIENV->get_jvmci_method(method, JVMCI_CHECK_NULL);
return JVMCIENV->get_jobject(result);
C2V_END
! C2V_VMENTRY_0(jint, constantPoolRemapInstructionOperandFromCache, (JNIEnv* env, jobject, jobject jvmci_constant_pool, jint index))
constantPoolHandle cp = JVMCIENV->asConstantPool(jvmci_constant_pool);
return cp->remap_instruction_operand_from_cache(index);
C2V_END
! C2V_VMENTRY_NULL(jobject, resolveFieldInPool, (JNIEnv* env, jobject, jobject jvmci_constant_pool, jint index, jobject jvmci_method, jbyte opcode, jintArray info_handle))
constantPoolHandle cp = JVMCIENV->asConstantPool(jvmci_constant_pool);
Bytecodes::Code code = (Bytecodes::Code)(((int) opcode) & 0xFF);
fieldDescriptor fd;
LinkInfo link_info(cp, index, (jvmci_method != NULL) ? JVMCIENV->asMethod(jvmci_method) : NULL, CHECK_0);
LinkResolver::resolve_field(fd, link_info, Bytecodes::java_code(code), false, CHECK_0);
*** 630,640 ****
--- 693,703 ----
JVMCIKlassHandle handle(THREAD, fd.field_holder());
JVMCIObject field_holder = JVMCIENV->get_jvmci_type(handle, JVMCI_CHECK_NULL);
return JVMCIENV->get_jobject(field_holder);
C2V_END
! C2V_VMENTRY_0(jint, getVtableIndexForInterfaceMethod, (JNIEnv* env, jobject, jobject jvmci_type, jobject jvmci_method))
Klass* klass = JVMCIENV->asKlass(jvmci_type);
Method* method = JVMCIENV->asMethod(jvmci_method);
if (klass->is_interface()) {
JVMCI_THROW_MSG_0(InternalError, err_msg("Interface %s should be handled in Java code", klass->external_name()));
}
*** 648,658 ****
--- 711,721 ----
JVMCI_THROW_MSG_0(InternalError, err_msg("Class %s must be linked", klass->external_name()));
}
return LinkResolver::vtable_index_of_interface_method(klass, method);
C2V_END
! C2V_VMENTRY_NULL(jobject, resolveMethod, (JNIEnv* env, jobject, jobject receiver_jvmci_type, jobject jvmci_method, jobject caller_jvmci_type))
Klass* recv_klass = JVMCIENV->asKlass(receiver_jvmci_type);
Klass* caller_klass = JVMCIENV->asKlass(caller_jvmci_type);
methodHandle method = JVMCIENV->asMethod(jvmci_method);
Klass* resolved = method->method_holder();
*** 695,721 ****
--- 758,784 ----
JVMCIObject result = JVMCIENV->get_jvmci_method(m, JVMCI_CHECK_NULL);
return JVMCIENV->get_jobject(result);
C2V_END
! C2V_VMENTRY_0(jboolean, hasFinalizableSubclass,(JNIEnv* env, jobject, jobject jvmci_type))
Klass* klass = JVMCIENV->asKlass(jvmci_type);
assert(klass != NULL, "method must not be called for primitive types");
return Dependencies::find_finalizable_subclass(klass) != NULL;
C2V_END
! C2V_VMENTRY_NULL(jobject, getClassInitializer, (JNIEnv* env, jobject, jobject jvmci_type))
Klass* klass = JVMCIENV->asKlass(jvmci_type);
if (!klass->is_instance_klass()) {
return NULL;
}
InstanceKlass* iklass = InstanceKlass::cast(klass);
JVMCIObject result = JVMCIENV->get_jvmci_method(iklass->class_initializer(), JVMCI_CHECK_NULL);
return JVMCIENV->get_jobject(result);
C2V_END
! C2V_VMENTRY_0(jlong, getMaxCallTargetOffset, (JNIEnv* env, jobject, jlong addr))
address target_addr = (address) addr;
if (target_addr != 0x0) {
int64_t off_low = (int64_t)target_addr - ((int64_t)CodeCache::low_bound() + sizeof(int));
int64_t off_high = (int64_t)target_addr - ((int64_t)CodeCache::high_bound() + sizeof(int));
return MAX2(ABS(off_low), ABS(off_high));
*** 728,741 ****
--- 791,804 ----
method->set_not_c1_compilable();
method->set_not_c2_compilable();
method->set_dont_inline(true);
C2V_END
! C2V_VMENTRY_0(jint, installCode, (JNIEnv *env, jobject, jobject target, jobject compiled_code,
jobject installed_code, jlong failed_speculations_address, jbyteArray speculations_obj))
HandleMark hm;
! JNIHandleMark jni_hm(thread);
JVMCIObject target_handle = JVMCIENV->wrap(target);
JVMCIObject compiled_code_handle = JVMCIENV->wrap(compiled_code);
CodeBlob* cb = NULL;
JVMCIObject installed_code_handle = JVMCIENV->wrap(installed_code);
*** 789,799 ****
--- 852,862 ----
}
}
return result;
C2V_END
! C2V_VMENTRY_0(jint, getMetadata, (JNIEnv *env, jobject, jobject target, jobject compiled_code, jobject metadata))
#if INCLUDE_AOT
HandleMark hm;
assert(JVMCIENV->is_hotspot(), "AOT code is executed only in HotSpot mode");
JVMCIObject target_handle = JVMCIENV->wrap(target);
*** 870,880 ****
--- 933,943 ----
CompilerStatistics* stats = compiler->stats();
stats->_standard.reset();
stats->_osr.reset();
C2V_END
! C2V_VMENTRY_NULL(jobject, disassembleCodeBlob, (JNIEnv* env, jobject, jobject installedCode))
HandleMark hm;
if (installedCode == NULL) {
JVMCI_THROW_MSG_NULL(NullPointerException, "installedCode is null");
}
*** 907,930 ****
--- 970,991 ----
JVMCIObject result = JVMCIENV->create_string(st.as_string(), JVMCI_CHECK_NULL);
return JVMCIENV->get_jobject(result);
C2V_END
! C2V_VMENTRY_NULL(jobject, getStackTraceElement, (JNIEnv* env, jobject, jobject jvmci_method, int bci))
HandleMark hm;
methodHandle method = JVMCIENV->asMethod(jvmci_method);
JVMCIObject element = JVMCIENV->new_StackTraceElement(method, bci, JVMCI_CHECK_NULL);
return JVMCIENV->get_jobject(element);
C2V_END
! C2V_VMENTRY_NULL(jobject, executeHotSpotNmethod, (JNIEnv* env, jobject, jobject args, jobject hs_nmethod))
if (env != JavaThread::current()->jni_environment()) {
// The incoming arguments array would have to contain JavaConstants instead of regular objects
// and the return value would have to be wrapped as a JavaConstant.
! JVMCI_THROW_MSG_NULL(InternalError, "Wrapping of arguments is currently unsupported");
}
! requireInHotSpot("executeHotSpotNmethod", JVMCI_CHECK_NULL);
HandleMark hm;
JVMCIObject nmethod_mirror = JVMCIENV->wrap(hs_nmethod);
nmethod* nm = JVMCIENV->asNmethod(nmethod_mirror);
*** 966,976 ****
--- 1027,1037 ----
JVMCIObject o = JVMCIENV->create_box(jap.get_ret_type(), value, JVMCI_CHECK_NULL);
return JVMCIENV->get_jobject(o);
}
C2V_END
! C2V_VMENTRY_NULL(jlongArray, getLineNumberTable, (JNIEnv* env, jobject, jobject jvmci_method))
Method* method = JVMCIENV->asMethod(jvmci_method);
if (!method->has_linenumber_table()) {
return NULL;
}
u2 num_entries = 0;
*** 993,1011 ****
--- 1054,1072 ----
}
return (jlongArray) JVMCIENV->get_jobject(result);
C2V_END
! C2V_VMENTRY_0(jlong, getLocalVariableTableStart, (JNIEnv* env, jobject, jobject jvmci_method))
Method* method = JVMCIENV->asMethod(jvmci_method);
if (!method->has_localvariable_table()) {
return 0;
}
return (jlong) (address) method->localvariable_table_start();
C2V_END
! C2V_VMENTRY_0(jint, getLocalVariableTableLength, (JNIEnv* env, jobject, jobject jvmci_method))
Method* method = JVMCIENV->asMethod(jvmci_method);
return method->localvariable_table_length();
C2V_END
C2V_VMENTRY(void, reprofile, (JNIEnv* env, jobject, jobject jvmci_method))
*** 1035,1056 ****
--- 1096,1122 ----
C2V_VMENTRY(void, invalidateHotSpotNmethod, (JNIEnv* env, jobject, jobject hs_nmethod))
JVMCIObject nmethod_mirror = JVMCIENV->wrap(hs_nmethod);
JVMCIENV->invalidate_nmethod_mirror(nmethod_mirror, JVMCI_CHECK);
C2V_END
! C2V_VMENTRY_NULL(jobject, readUncompressedOop, (JNIEnv* env, jobject, jlong addr))
oop ret = RawAccess<>::oop_load((oop*)(address)addr);
return JVMCIENV->get_jobject(JVMCIENV->get_object_constant(ret));
C2V_END
! C2V_VMENTRY_NULL(jlongArray, collectCounters, (JNIEnv* env, jobject))
+ // Returns a zero length array if counters aren't enabled
JVMCIPrimitiveArray array = JVMCIENV->new_longArray(JVMCICounterSize, JVMCI_CHECK_NULL);
JavaThread::collect_counters(JVMCIENV, array);
+ if (JVMCICounterSize > 0) {
+ jlong* temp_array = NEW_RESOURCE_ARRAY(jlong, JVMCICounterSize);
+ JavaThread::collect_counters(temp_array, JVMCICounterSize);
+ JVMCIENV->copy_longs_from(temp_array, array, 0, JVMCICounterSize);
+ }
return (jlongArray) JVMCIENV->get_jobject(array);
C2V_END
! C2V_VMENTRY_0(int, allocateCompileId, (JNIEnv* env, jobject, jobject jvmci_method, int entry_bci))
HandleMark hm;
if (jvmci_method == NULL) {
JVMCI_THROW_0(NullPointerException);
}
Method* method = JVMCIENV->asMethod(jvmci_method);
*** 1059,1079 ****
--- 1125,1145 ----
}
return CompileBroker::assign_compile_id_unlocked(THREAD, method, entry_bci);
C2V_END
! C2V_VMENTRY_0(jboolean, isMature, (JNIEnv* env, jobject, jlong metaspace_method_data))
MethodData* mdo = JVMCIENV->asMethodData(metaspace_method_data);
return mdo != NULL && mdo->is_mature();
C2V_END
! C2V_VMENTRY_0(jboolean, hasCompiledCodeForOSR, (JNIEnv* env, jobject, jobject jvmci_method, int entry_bci, int comp_level))
Method* method = JVMCIENV->asMethod(jvmci_method);
return method->lookup_osr_nmethod_for(entry_bci, comp_level, true) != NULL;
C2V_END
! C2V_VMENTRY_NULL(jobject, getSymbol, (JNIEnv* env, jobject, jlong symbol))
JVMCIObject sym = JVMCIENV->create_string((Symbol*)(address)symbol, JVMCI_CHECK_NULL);
return JVMCIENV->get_jobject(sym);
C2V_END
bool matches(jobjectArray methods, Method* method, JVMCIEnv* JVMCIENV) {
*** 1100,1119 ****
--- 1166,1183 ----
// Invoke the method
JavaCalls::call(result, method, args, CHECK);
}
! C2V_VMENTRY_NULL(jobject, iterateFrames, (JNIEnv* env, jobject compilerToVM, jobjectArray initial_methods, jobjectArray match_methods, jint initialSkip, jobject visitor_handle))
if (!thread->has_last_Java_frame()) {
return NULL;
}
Handle visitor(THREAD, JNIHandles::resolve_non_null(visitor_handle));
if (env != JavaThread::current()->jni_environment()) {
JVMCI_THROW_MSG_NULL(InternalError, "getNextStackFrame is only supported for HotSpot stack walking");
}
+ requireInHotSpot("iterateFrames", JVMCI_CHECK_NULL);
HotSpotJVMCI::HotSpotStackFrameReference::klass()->initialize(CHECK_NULL);
Handle frame_reference = HotSpotJVMCI::HotSpotStackFrameReference::klass()->allocate_instance_handle(CHECK_NULL);
StackFrameStream fst(thread);
*** 1281,1291 ****
--- 1345,1355 ----
ConstantPoolCacheEntry* cp_cache_entry = cp->cache()->entry_at(cp->decode_cpcache_index(index));
cp_cache_entry->set_method_handle(cp, callInfo);
}
C2V_END
! C2V_VMENTRY_0(jint, isResolvedInvokeHandleInPool, (JNIEnv* env, jobject, jobject jvmci_constant_pool, jint index))
constantPoolHandle cp = JVMCIENV->asConstantPool(jvmci_constant_pool);
ConstantPoolCacheEntry* cp_cache_entry = cp->cache()->entry_at(cp->decode_cpcache_index(index));
if (cp_cache_entry->is_resolved(Bytecodes::_invokehandle)) {
// MethodHandle.invoke* --> LambdaForm?
ResourceMark rm;
*** 1322,1341 ****
--- 1386,1405 ----
}
return -1;
C2V_END
! C2V_VMENTRY_NULL(jobject, getSignaturePolymorphicHolders, (JNIEnv* env, jobject))
JVMCIObjectArray holders = JVMCIENV->new_String_array(2, JVMCI_CHECK_NULL);
JVMCIObject mh = JVMCIENV->create_string("Ljava/lang/invoke/MethodHandle;", JVMCI_CHECK_NULL);
JVMCIObject vh = JVMCIENV->create_string("Ljava/lang/invoke/VarHandle;", JVMCI_CHECK_NULL);
JVMCIENV->put_object_at(holders, 0, mh);
JVMCIENV->put_object_at(holders, 1, vh);
return JVMCIENV->get_jobject(holders);
C2V_END
! C2V_VMENTRY_0(jboolean, shouldDebugNonSafepoints, (JNIEnv* env, jobject))
//see compute_recording_non_safepoints in debugInfroRec.cpp
if (JvmtiExport::should_post_compiled_method_load() && FLAG_IS_DEFAULT(DebugNonSafepoints)) {
return true;
}
return DebugNonSafepoints;
*** 1346,1358 ****
--- 1410,1420 ----
JVMCIObject hs_frame = JVMCIENV->wrap(_hs_frame);
if (hs_frame.is_null()) {
JVMCI_THROW_MSG(NullPointerException, "stack frame is null");
}
if (env != JavaThread::current()->jni_environment()) {
JVMCI_THROW_MSG(InternalError, "getNextStackFrame is only supported for HotSpot stack walking");
}
+ requireInHotSpot("materializeVirtualObjects", JVMCI_CHECK);
JVMCIENV->HotSpotStackFrameReference_initialize(JVMCI_CHECK);
// look for the given stack frame
StackFrameStream fst(thread);
*** 1463,1502 ****
--- 1525,1624 ----
}
}
HotSpotJVMCI::HotSpotStackFrameReference::set_objectsMaterialized(JVMCIENV, hs_frame, JNI_TRUE);
C2V_END
C2V_VMENTRY(void, writeDebugOutput, (JNIEnv* env, jobject, jbyteArray bytes, jint offset, jint length))
+ // Creates a scope where the current thread is attached and detached
+ // from HotSpot if it wasn't already attached when entering the scope.
+ extern "C" void jio_printf(const char *fmt, ...);
+ class AttachDetach : public StackObj {
+ public:
+ bool _attached;
+ AttachDetach(JNIEnv* env, Thread* current_thread) {
+ if (current_thread == NULL) {
+ extern struct JavaVM_ main_vm;
+ JNIEnv* hotspotEnv;
+ jint res = main_vm.AttachCurrentThread((void**)&hotspotEnv, NULL);
+ _attached = res == JNI_OK;
+ static volatile int report_attach_error = 0;
+ if (res != JNI_OK && report_attach_error == 0 && Atomic::cmpxchg(1, &report_attach_error, 0) == 0) {
+ // Only report an attach error once
+ jio_printf("Warning: attaching current thread to VM failed with %d (future attach errors are suppressed)\n", res);
+ }
+ } else {
+ _attached = false;
+ }
+ }
+ ~AttachDetach() {
+ if (_attached && get_current_thread() != NULL) {
+ extern struct JavaVM_ main_vm;
+ jint res = main_vm.DetachCurrentThread();
+ static volatile int report_detach_error = 0;
+ if (res != JNI_OK && report_detach_error == 0 && Atomic::cmpxchg(1, &report_detach_error, 0) == 0) {
+ // Only report an attach error once
+ jio_printf("Warning: detaching current thread from VM failed with %d (future attach errors are suppressed)\n", res);
+ }
+ }
+ }
+ };
+
+ C2V_VMENTRY_PREFIX(jint, writeDebugOutput, (JNIEnv* env, jobject, jbyteArray bytes, jint offset, jint length, bool flush, bool can_throw))
+ AttachDetach ad(env, base_thread);
+ bool use_tty = true;
+ if (base_thread == NULL) {
+ if (!ad._attached) {
+ // Can only use tty if the current thread is attached
+ return 0;
+ }
+ base_thread = get_current_thread();
+ }
+ JVMCITraceMark jtm("writeDebugOutput");
+ assert(base_thread->is_Java_thread(), "just checking");
+ JavaThread* thread = (JavaThread*) base_thread;
+ C2V_BLOCK(void, writeDebugOutput, (JNIEnv* env, jobject, jbyteArray bytes, jint offset, jint length))
if (bytes == NULL) {
JVMCI_THROW(NullPointerException);
+ if (can_throw) {
+ JVMCI_THROW_0(NullPointerException);
+ }
+ return -1;
}
JVMCIPrimitiveArray array = JVMCIENV->wrap(bytes);
// Check if offset and length are non negative.
if (offset < 0 || length < 0) {
JVMCI_THROW(ArrayIndexOutOfBoundsException);
+ if (can_throw) {
+ JVMCI_THROW_0(ArrayIndexOutOfBoundsException);
+ }
+ return -2;
}
// Check if the range is valid.
int array_length = JVMCIENV->get_length(array);
if ((((unsigned int) length + (unsigned int) offset) > (unsigned int) array_length)) {
JVMCI_THROW(ArrayIndexOutOfBoundsException);
+ if (can_throw) {
+ JVMCI_THROW_0(ArrayIndexOutOfBoundsException);
+ }
+ return -2;
}
jbyte buffer[O_BUFLEN];
while (length > 0) {
int copy_len = MIN2(length, (jint)O_BUFLEN);
JVMCIENV->copy_bytes_to(array, buffer, offset, copy_len);
tty->write((char*) buffer, copy_len);
length -= O_BUFLEN;
offset += O_BUFLEN;
}
+ if (flush) {
+ tty->flush();
+ }
+ return 0;
C2V_END
C2V_VMENTRY(void, flushDebugOutput, (JNIEnv* env, jobject))
tty->flush();
C2V_END
! C2V_VMENTRY_0(int, methodDataProfileDataSize, (JNIEnv* env, jobject, jlong metaspace_method_data, jint position))
MethodData* mdo = JVMCIENV->asMethodData(metaspace_method_data);
ProfileData* profile_data = mdo->data_at(position);
if (mdo->is_valid(profile_data)) {
return profile_data->size_in_bytes();
}
*** 1510,1520 ****
--- 1632,1642 ----
}
}
JVMCI_THROW_MSG_0(IllegalArgumentException, err_msg("Invalid profile data position %d", position));
C2V_END
! C2V_VMENTRY_0(jlong, getFingerprint, (JNIEnv* env, jobject, jlong metaspace_klass))
#if INCLUDE_AOT
Klass *k = (Klass*) (address) metaspace_klass;
if (k->is_instance_klass()) {
return InstanceKlass::cast(k)->get_stored_fingerprint();
} else {
*** 1523,1541 ****
--- 1645,1663 ----
#else
JVMCI_THROW_MSG_0(InternalError, "unimplemented");
#endif
C2V_END
! C2V_VMENTRY_NULL(jobject, getHostClass, (JNIEnv* env, jobject, jobject jvmci_type))
InstanceKlass* k = InstanceKlass::cast(JVMCIENV->asKlass(jvmci_type));
InstanceKlass* host = k->unsafe_anonymous_host();
JVMCIKlassHandle handle(THREAD, host);
JVMCIObject result = JVMCIENV->get_jvmci_type(handle, JVMCI_CHECK_NULL);
return JVMCIENV->get_jobject(result);
C2V_END
! C2V_VMENTRY_NULL(jobject, getInterfaces, (JNIEnv* env, jobject, jobject jvmci_type))
if (jvmci_type == NULL) {
JVMCI_THROW_0(NullPointerException);
}
Klass* klass = JVMCIENV->asKlass(jvmci_type);
*** 1558,1568 ****
--- 1680,1690 ----
JVMCIENV->put_object_at(interfaces, index, type);
}
return JVMCIENV->get_jobject(interfaces);
C2V_END
! C2V_VMENTRY_NULL(jobject, getComponentType, (JNIEnv* env, jobject, jobject jvmci_type))
if (jvmci_type == NULL) {
JVMCI_THROW_0(NullPointerException);
}
Klass* klass = JVMCIENV->asKlass(jvmci_type);
*** 1598,1608 ****
--- 1720,1730 ----
InstanceKlass* k = InstanceKlass::cast(klass);
k->initialize(CHECK);
}
C2V_END
! C2V_VMENTRY_0(int, interpreterFrameSize, (JNIEnv* env, jobject, jobject bytecode_frame_handle))
if (bytecode_frame_handle == NULL) {
JVMCI_THROW_0(NullPointerException);
}
JVMCIObject top_bytecode_frame = JVMCIENV->wrap(bytecode_frame_handle);
*** 1646,1672 ****
--- 1768,1794 ----
JVMCI_THROW_MSG(IllegalArgumentException,
err_msg("Unexpected type: %s", lambda_form->klass()->external_name()))
}
C2V_END
! C2V_VMENTRY_0(int, getIdentityHashCode, (JNIEnv* env, jobject, jobject object))
Handle obj = JVMCIENV->asConstant(JVMCIENV->wrap(object), JVMCI_CHECK_0);
return obj->identity_hash();
C2V_END
! C2V_VMENTRY_0(jboolean, isInternedString, (JNIEnv* env, jobject, jobject object))
Handle str = JVMCIENV->asConstant(JVMCIENV->wrap(object), JVMCI_CHECK_0);
if (!java_lang_String::is_instance(str())) {
return false;
}
int len;
jchar* name = java_lang_String::as_unicode_string(str(), len, CHECK_0);
return (StringTable::lookup(name, len) != NULL);
C2V_END
! C2V_VMENTRY_NULL(jobject, unboxPrimitive, (JNIEnv* env, jobject, jobject object))
if (object == NULL) {
JVMCI_THROW_0(NullPointerException);
}
Handle box = JVMCIENV->asConstant(JVMCIENV->wrap(object), JVMCI_CHECK_NULL);
BasicType type = java_lang_boxing_object::basic_type(box());
*** 1676,1686 ****
--- 1798,1808 ----
}
JVMCIObject boxResult = JVMCIENV->create_box(type, &result, JVMCI_CHECK_NULL);
return JVMCIENV->get_jobject(boxResult);
C2V_END
! C2V_VMENTRY_NULL(jobject, boxPrimitive, (JNIEnv* env, jobject, jobject object))
if (object == NULL) {
JVMCI_THROW_0(NullPointerException);
}
JVMCIObject box = JVMCIENV->wrap(object);
BasicType type = JVMCIENV->get_box_type(box);
*** 1720,1730 ****
--- 1842,1852 ----
oop hotspot_box = (oop) box_result.get_jobject();
JVMCIObject result = JVMCIENV->get_object_constant(hotspot_box, false);
return JVMCIENV->get_jobject(result);
C2V_END
! C2V_VMENTRY_NULL(jobjectArray, getDeclaredConstructors, (JNIEnv* env, jobject, jobject holder))
if (holder == NULL) {
JVMCI_THROW_0(NullPointerException);
}
Klass* klass = JVMCIENV->asKlass(holder);
if (!klass->is_instance_klass()) {
*** 1749,1759 ****
--- 1871,1881 ----
JVMCIENV->put_object_at(methods, i, method);
}
return JVMCIENV->get_jobjectArray(methods);
C2V_END
! C2V_VMENTRY_NULL(jobjectArray, getDeclaredMethods, (JNIEnv* env, jobject, jobject holder))
if (holder == NULL) {
JVMCI_THROW_0(NullPointerException);
}
Klass* klass = JVMCIENV->asKlass(holder);
if (!klass->is_instance_klass()) {
*** 1778,1788 ****
--- 1900,1910 ----
JVMCIENV->put_object_at(methods, i, method);
}
return JVMCIENV->get_jobjectArray(methods);
C2V_END
! C2V_VMENTRY_NULL(jobject, readFieldValue, (JNIEnv* env, jobject, jobject object, jobject field, jboolean is_volatile))
if (object == NULL || field == NULL) {
JVMCI_THROW_0(NullPointerException);
}
JVMCIObject field_object = JVMCIENV->wrap(field);
JVMCIObject java_type = JVMCIENV->get_HotSpotResolvedJavaFieldImpl_type(field_object);
*** 1846,1885 ****
--- 1968,2007 ----
}
JVMCIObject result = JVMCIENV->call_PrimitiveConstant_forTypeChar(type2char(constant_type), value, JVMCI_CHECK_NULL);
return JVMCIENV->get_jobject(result);
C2V_END
! C2V_VMENTRY_0(jboolean, isInstance, (JNIEnv* env, jobject, jobject holder, jobject object))
if (object == NULL || holder == NULL) {
JVMCI_THROW_0(NullPointerException);
}
Handle obj = JVMCIENV->asConstant(JVMCIENV->wrap(object), JVMCI_CHECK_0);
Klass* klass = JVMCIENV->asKlass(JVMCIENV->wrap(holder));
return obj->is_a(klass);
C2V_END
! C2V_VMENTRY_0(jboolean, isAssignableFrom, (JNIEnv* env, jobject, jobject holder, jobject otherHolder))
if (holder == NULL || otherHolder == NULL) {
JVMCI_THROW_0(NullPointerException);
}
Klass* klass = JVMCIENV->asKlass(JVMCIENV->wrap(holder));
Klass* otherKlass = JVMCIENV->asKlass(JVMCIENV->wrap(otherHolder));
return otherKlass->is_subtype_of(klass);
C2V_END
! C2V_VMENTRY_0(jboolean, isTrustedForIntrinsics, (JNIEnv* env, jobject, jobject holder))
if (holder == NULL) {
JVMCI_THROW_0(NullPointerException);
}
InstanceKlass* ik = InstanceKlass::cast(JVMCIENV->asKlass(JVMCIENV->wrap(holder)));
if (ik->class_loader_data()->is_builtin_class_loader_data()) {
return true;
}
return false;
C2V_END
! C2V_VMENTRY_NULL(jobject, asJavaType, (JNIEnv* env, jobject, jobject object))
if (object == NULL) {
JVMCI_THROW_0(NullPointerException);
}
Handle obj = JVMCIENV->asConstant(JVMCIENV->wrap(object), JVMCI_CHECK_NULL);
if (java_lang_Class::is_instance(obj())) {
*** 1895,1923 ****
--- 2017,2045 ----
}
return NULL;
C2V_END
! C2V_VMENTRY_NULL(jobject, asString, (JNIEnv* env, jobject, jobject object))
if (object == NULL) {
JVMCI_THROW_0(NullPointerException);
}
Handle obj = JVMCIENV->asConstant(JVMCIENV->wrap(object), JVMCI_CHECK_NULL);
const char* str = java_lang_String::as_utf8_string(obj());
JVMCIObject result = JVMCIENV->create_string(str, JVMCI_CHECK_NULL);
return JVMCIENV->get_jobject(result);
C2V_END
! C2V_VMENTRY_0(jboolean, equals, (JNIEnv* env, jobject, jobject x, jlong xHandle, jobject y, jlong yHandle))
if (x == NULL || y == NULL) {
JVMCI_THROW_0(NullPointerException);
}
return JVMCIENV->resolve_handle(xHandle) == JVMCIENV->resolve_handle(yHandle);
C2V_END
! C2V_VMENTRY_NULL(jobject, getJavaMirror, (JNIEnv* env, jobject, jobject object))
if (object == NULL) {
JVMCI_THROW_0(NullPointerException);
}
JVMCIObject base_object = JVMCIENV->wrap(object);
Handle mirror;
*** 1932,1942 ****
--- 2054,2064 ----
JVMCIObject result = JVMCIENV->get_object_constant(mirror());
return JVMCIENV->get_jobject(result);
C2V_END
! C2V_VMENTRY_0(jint, getArrayLength, (JNIEnv* env, jobject, jobject x))
if (x == NULL) {
JVMCI_THROW_0(NullPointerException);
}
Handle xobj = JVMCIENV->asConstant(JVMCIENV->wrap(x), JVMCI_CHECK_0);
if (xobj->klass()->is_array_klass()) {
*** 1944,1954 ****
--- 2066,2076 ----
}
return -1;
C2V_END
! C2V_VMENTRY_NULL(jobject, readArrayElement, (JNIEnv* env, jobject, jobject x, int index))
if (x == NULL) {
JVMCI_THROW_0(NullPointerException);
}
Handle xobj = JVMCIENV->asConstant(JVMCIENV->wrap(x), JVMCI_CHECK_NULL);
if (xobj->klass()->is_array_klass()) {
*** 1984,2042 ****
--- 2106,2164 ----
}
return NULL;;
C2V_END
! C2V_VMENTRY_0(jint, arrayBaseOffset, (JNIEnv* env, jobject, jobject kind))
if (kind == NULL) {
JVMCI_THROW_0(NullPointerException);
}
BasicType type = JVMCIENV->kindToBasicType(JVMCIENV->wrap(kind), JVMCI_CHECK_0);
return arrayOopDesc::header_size(type) * HeapWordSize;
C2V_END
! C2V_VMENTRY_0(jint, arrayIndexScale, (JNIEnv* env, jobject, jobject kind))
if (kind == NULL) {
JVMCI_THROW_0(NullPointerException);
}
BasicType type = JVMCIENV->kindToBasicType(JVMCIENV->wrap(kind), JVMCI_CHECK_0);
return type2aelembytes(type);
C2V_END
! C2V_VMENTRY_0(jbyte, getByte, (JNIEnv* env, jobject, jobject x, long displacement))
if (x == NULL) {
JVMCI_THROW_0(NullPointerException);
}
Handle xobj = JVMCIENV->asConstant(JVMCIENV->wrap(x), JVMCI_CHECK_0);
return xobj->byte_field(displacement);
}
! C2V_VMENTRY_0(jshort, getShort, (JNIEnv* env, jobject, jobject x, long displacement))
if (x == NULL) {
JVMCI_THROW_0(NullPointerException);
}
Handle xobj = JVMCIENV->asConstant(JVMCIENV->wrap(x), JVMCI_CHECK_0);
return xobj->short_field(displacement);
}
! C2V_VMENTRY_0(jint, getInt, (JNIEnv* env, jobject, jobject x, long displacement))
if (x == NULL) {
JVMCI_THROW_0(NullPointerException);
}
Handle xobj = JVMCIENV->asConstant(JVMCIENV->wrap(x), JVMCI_CHECK_0);
return xobj->int_field(displacement);
}
! C2V_VMENTRY_0(jlong, getLong, (JNIEnv* env, jobject, jobject x, long displacement))
if (x == NULL) {
JVMCI_THROW_0(NullPointerException);
}
Handle xobj = JVMCIENV->asConstant(JVMCIENV->wrap(x), JVMCI_CHECK_0);
return xobj->long_field(displacement);
}
! C2V_VMENTRY_NULL(jobject, getObject, (JNIEnv* env, jobject, jobject x, long displacement))
if (x == NULL) {
JVMCI_THROW_0(NullPointerException);
}
Handle xobj = JVMCIENV->asConstant(JVMCIENV->wrap(x), JVMCI_CHECK_0);
oop res = xobj->obj_field(displacement);
*** 2050,2083 ****
--- 2172,2213 ----
assert(JVMCI::is_global_handle(handle), "Invalid delete of global JNI handle");
*((oop*)handle) = NULL; // Mark the handle as deleted, allocate will reuse it
}
}
C2V_VMENTRY(jlongArray, registerNativeMethods, (JNIEnv* env, jobject, jclass mirror))
+ static void requireJVMCINativeLibrary(JVMCI_TRAPS) {
if (!UseJVMCINativeLibrary) {
! JVMCI_THROW_MSG_0(UnsatisfiedLinkError, "JVMCI shared library is not enabled (requires -XX:+UseJVMCINativeLibrary)");
! JVMCI_THROW_MSG(UnsupportedOperationException, "JVMCI shared library is not enabled (requires -XX:+UseJVMCINativeLibrary)");
}
if (!JVMCIENV->is_hotspot()) {
JVMCI_THROW_MSG_0(UnsatisfiedLinkError, "Cannot call registerNativeMethods from JVMCI shared library");
+ }
+
+ static JavaVM* requireNativeLibraryJavaVM(const char* caller, JVMCI_TRAPS) {
+ JavaVM* javaVM = JVMCIEnv::get_shared_library_javavm();
+ if (javaVM == NULL) {
+ JVMCI_THROW_MSG_NULL(IllegalStateException, err_msg("Require JVMCI shared library to be initialized in %s", caller));
}
+ return javaVM;
+ }
+
+ C2V_VMENTRY_NULL(jlongArray, registerNativeMethods, (JNIEnv* env, jobject, jclass mirror))
+ requireJVMCINativeLibrary(JVMCI_CHECK_NULL);
+ requireInHotSpot("registerNativeMethods", JVMCI_CHECK_NULL);
void* shared_library = JVMCIEnv::get_shared_library_handle();
if (shared_library == NULL) {
// Ensure the JVMCI shared library runtime is initialized.
! JVMCIEnv __peer_jvmci_env__(thread, false, __FILE__, __LINE__);
JVMCIEnv* peerEnv = &__peer_jvmci_env__;
HandleMark hm;
JVMCIRuntime* runtime = JVMCI::compiler_runtime();
JVMCIObject receiver = runtime->get_HotSpotJVMCIRuntime(peerEnv);
if (peerEnv->has_pending_exception()) {
peerEnv->describe_pending_exception(true);
JVMCI_THROW_MSG_0(InternalError, "Error initializing JVMCI runtime");
}
shared_library = JVMCIEnv::get_shared_library_handle();
}
if (shared_library == NULL) {
! JVMCI_THROW_MSG_0(UnsatisfiedLinkError, "JVMCI shared library is unavailable");
! JVMCI_THROW_MSG_0(InternalError, "Error initializing JVMCI runtime");
+ }
}
if (mirror == NULL) {
JVMCI_THROW_0(NullPointerException);
}
*** 2111,2129 ****
--- 2241,2262 ----
char* long_name = NativeLookup::long_jni_name(method);
os::print_jni_name_prefix_on(&st, args_size);
st.print_raw(pure_name);
st.print_raw(long_name);
os::print_jni_name_suffix_on(&st, args_size);
! jni_name = st.as_string();
! entry = (address) os::dll_lookup(shared_library, jni_name);
}
! char* jni_long_name = st.as_string();
! entry = (address) os::dll_lookup(shared_library, jni_long_name);
if (entry == NULL) {
JVMCI_THROW_MSG_0(UnsatisfiedLinkError, method->name_and_sig_as_C_string());
+ JVMCI_THROW_MSG_0(UnsatisfiedLinkError, err_msg("%s [neither %s nor %s exist in %s]",
+ method->name_and_sig_as_C_string(),
+ jni_name, jni_long_name, JVMCIEnv::get_shared_library_path()));
+ }
}
+
if (method->has_native_function() && entry != method->native_function()) {
! JVMCI_THROW_MSG_0(UnsatisfiedLinkError, err_msg("Cannot overwrite existing native implementation for %s",
! method->name_and_sig_as_C_string()));
! JVMCI_THROW_MSG_0(UnsatisfiedLinkError, err_msg("%s [cannot re-link from " PTR_FORMAT " to " PTR_FORMAT "]",
! method->name_and_sig_as_C_string(), p2i(method->native_function()), p2i(entry)));
}
method->set_native_function(entry, Method::native_bind_event_is_interesting);
if (PrintJNIResolving) {
tty->print_cr("[Dynamic-linking native method %s.%s ... JNI]",
method->method_holder()->external_name(),
*** 2139,2153 ****
--- 2272,2377 ----
JVMCIENV->put_long_at(result, 2, (jlong) (address) javaVM->functions->reserved1);
JVMCIENV->put_long_at(result, 3, (jlong) (address) javaVM->functions->reserved2);
return (jlongArray) JVMCIENV->get_jobject(result);
}
! C2V_VMENTRY(jlong, translate, (JNIEnv* env, jobject, jobject obj_handle))
! C2V_VMENTRY_PREFIX(jboolean, isCurrentThreadAttached, (JNIEnv* env, jobject c2vm))
+ if (base_thread == NULL) {
+ // Called from unattached JVMCI shared library thread
+ return false;
+ }
+ JVMCITraceMark jtm("isCurrentThreadAttached");
+ assert(base_thread->is_Java_thread(), "just checking");
+ JavaThread* thread = (JavaThread*) base_thread;
+ if (thread->jni_environment() == env) {
+ C2V_BLOCK(jboolean, isCurrentThreadAttached, (JNIEnv* env, jobject))
+ requireJVMCINativeLibrary(JVMCI_CHECK_0);
+ JavaVM* javaVM = requireNativeLibraryJavaVM("isCurrentThreadAttached", JVMCI_CHECK_0);
+ JNIEnv* peerEnv;
+ return javaVM->GetEnv((void**)&peerEnv, JNI_VERSION_1_2) == JNI_OK;
+ }
+ return true;
+ C2V_END
+
+ C2V_VMENTRY_PREFIX(jboolean, attachCurrentThread, (JNIEnv* env, jobject c2vm, jboolean as_daemon))
+ if (base_thread == NULL) {
+ // Called from unattached JVMCI shared library thread
+ extern struct JavaVM_ main_vm;
+ JNIEnv* hotspotEnv;
+ jint res = as_daemon ? main_vm.AttachCurrentThreadAsDaemon((void**)&hotspotEnv, NULL) :
+ main_vm.AttachCurrentThread((void**)&hotspotEnv, NULL);
+ if (res != JNI_OK) {
+ JNI_THROW_("attachCurrentThread", InternalError, err_msg("Trying to attach thread returned %d", res), false);
+ }
+ return true;
+ }
+ JVMCITraceMark jtm("attachCurrentThread");
+ assert(base_thread->is_Java_thread(), "just checking");\
+ JavaThread* thread = (JavaThread*) base_thread;
+ if (thread->jni_environment() == env) {
+ // Called from HotSpot
+ C2V_BLOCK(jboolean, attachCurrentThread, (JNIEnv* env, jobject, jboolean))
+ requireJVMCINativeLibrary(JVMCI_CHECK_0);
+ JavaVM* javaVM = requireNativeLibraryJavaVM("attachCurrentThread", JVMCI_CHECK_0);
+ JavaVMAttachArgs attach_args;
+ attach_args.version = JNI_VERSION_1_2;
+ attach_args.name = thread->name();
+ attach_args.group = NULL;
+ JNIEnv* peerEnv;
+ if (javaVM->GetEnv((void**)&peerEnv, JNI_VERSION_1_2) == JNI_OK) {
+ return false;
+ }
+ jint res = as_daemon ? javaVM->AttachCurrentThreadAsDaemon((void**)&peerEnv, &attach_args) :
+ javaVM->AttachCurrentThread((void**)&peerEnv, &attach_args);
+ if (res == JNI_OK) {
+ guarantee(peerEnv != NULL, "must be");
+ return true;
+ }
+ JVMCI_THROW_MSG_0(InternalError, err_msg("Error %d while attaching %s", res, attach_args.name));
+ }
+ // Called from JVMCI shared library
+ return false;
+ C2V_END
+
+ C2V_VMENTRY_PREFIX(void, detachCurrentThread, (JNIEnv* env, jobject c2vm))
+ if (base_thread == NULL) {
+ // Called from unattached JVMCI shared library thread
+ JNI_THROW("detachCurrentThread", IllegalStateException, err_msg("Cannot detach non-attached thread"));
+ }
+ JVMCITraceMark jtm("detachCurrentThread");
+ assert(base_thread->is_Java_thread(), "just checking");\
+ JavaThread* thread = (JavaThread*) base_thread;
+ if (thread->jni_environment() == env) {
+ // Called from HotSpot
+ C2V_BLOCK(void, detachCurrentThread, (JNIEnv* env, jobject))
+ requireJVMCINativeLibrary(JVMCI_CHECK);
+ requireInHotSpot("detachCurrentThread", JVMCI_CHECK);
+ JavaVM* javaVM = requireNativeLibraryJavaVM("detachCurrentThread", JVMCI_CHECK);
+ JNIEnv* peerEnv;
+ if (javaVM->GetEnv((void**)&peerEnv, JNI_VERSION_1_2) != JNI_OK) {
+ JVMCI_THROW_MSG(IllegalStateException, err_msg("Cannot detach non-attached thread: %s", thread->name()));
+ }
+ jint res = javaVM->DetachCurrentThread();
+ if (res != JNI_OK) {
+ JVMCI_THROW_MSG(InternalError, err_msg("Error %d while attaching %s", res, thread->name()));
+ }
+ } else {
+ // Called from attached JVMCI shared library thread
+ extern struct JavaVM_ main_vm;
+ jint res = main_vm.DetachCurrentThread();
+ if (res != JNI_OK) {
+ JNI_THROW("detachCurrentThread", InternalError, err_msg("Cannot detach non-attached thread"));
+ }
+ }
+ C2V_END
+
+ C2V_VMENTRY_0(jlong, translate, (JNIEnv* env, jobject, jobject obj_handle))
+ requireJVMCINativeLibrary(JVMCI_CHECK_0);
if (obj_handle == NULL) {
return 0L;
}
! JVMCIEnv __peer_jvmci_env__(thread, !JVMCIENV->is_hotspot(), __FILE__, __LINE__);
JVMCIEnv* peerEnv = &__peer_jvmci_env__;
JVMCIEnv* thisEnv = JVMCIENV;
JVMCIObject obj = thisEnv->wrap(obj_handle);
JVMCIObject result;
*** 2214,2224 ****
--- 2438,2449 ----
err_msg("Cannot translate object of type: %s", thisEnv->klass_name(obj)));
}
return (jlong) peerEnv->make_global(result).as_jobject();
}
! C2V_VMENTRY_NULL(jobject, unhand, (JNIEnv* env, jobject, jlong obj_handle))
+ requireJVMCINativeLibrary(JVMCI_CHECK_NULL);
if (obj_handle == 0L) {
return NULL;
}
jobject global_handle = (jobject) obj_handle;
JVMCIObject global_handle_obj = JVMCIENV->wrap((jobject) obj_handle);
*** 2232,2242 ****
--- 2457,2467 ----
JVMCIObject code = JVMCIENV->wrap(code_handle);
// Execute this operation for the side effect of updating the InstalledCode state
JVMCIENV->asNmethod(code);
}
! C2V_VMENTRY_NULL(jbyteArray, getCode, (JNIEnv* env, jobject, jobject code_handle))
JVMCIObject code = JVMCIENV->wrap(code_handle);
CodeBlob* cb = JVMCIENV->asCodeBlob(code);
if (cb == NULL) {
return NULL;
}
*** 2244,2257 ****
--- 2469,2480 ----
JVMCIPrimitiveArray result = JVMCIENV->new_byteArray(code_size, JVMCI_CHECK_NULL);
JVMCIENV->copy_bytes_from((jbyte*) cb->code_begin(), result, 0, code_size);
return JVMCIENV->get_jbyteArray(result);
}
! C2V_VMENTRY_NULL(jobject, asReflectionExecutable, (JNIEnv* env, jobject, jobject jvmci_method))
if (env != JavaThread::current()->jni_environment()) {
JVMCI_THROW_MSG_NULL(InternalError, "Only supported when running in HotSpot");
}
+ requireInHotSpot("asReflectionExecutable", JVMCI_CHECK_NULL);
methodHandle m = JVMCIENV->asMethod(jvmci_method);
oop executable;
if (m->is_initializer()) {
if (m->is_static_initializer()) {
JVMCI_THROW_MSG_NULL(IllegalArgumentException,
*** 2262,2275 ****
--- 2485,2496 ----
executable = Reflection::new_method(m, false, CHECK_NULL);
}
return JNIHandles::make_local(THREAD, executable);
}
! C2V_VMENTRY_NULL(jobject, asReflectionField, (JNIEnv* env, jobject, jobject jvmci_type, jint index))
if (env != JavaThread::current()->jni_environment()) {
JVMCI_THROW_MSG_NULL(InternalError, "Only supported when running in HotSpot");
}
+ requireInHotSpot("asReflectionField", JVMCI_CHECK_NULL);
Klass* klass = JVMCIENV->asKlass(jvmci_type);
if (!klass->is_instance_klass()) {
JVMCI_THROW_MSG_NULL(IllegalArgumentException,
err_msg("Expected non-primitive type, got %s", klass->external_name()));
}
*** 2282,2292 ****
--- 2503,2513 ----
fieldDescriptor fd(iklass, index);
oop reflected = Reflection::new_field(&fd, CHECK_NULL);
return JNIHandles::make_local(env, reflected);
}
! C2V_VMENTRY_NULL(jobjectArray, getFailedSpeculations, (JNIEnv* env, jobject, jlong failed_speculations_address, jobjectArray current))
FailedSpeculation* head = *((FailedSpeculation**)(address) failed_speculations_address);
int result_length = 0;
for (FailedSpeculation* fs = head; fs != NULL; fs = fs->next()) {
result_length++;
}
*** 2314,2324 ****
--- 2535,2545 ----
JVMCIENV->put_object_at(result, result_index++, entry);
}
return JVMCIENV->get_jobjectArray(result);
}
! C2V_VMENTRY_0(jlong, getFailedSpeculationsAddress, (JNIEnv* env, jobject, jobject jvmci_method))
methodHandle method = JVMCIENV->asMethod(jvmci_method);
MethodData* method_data = method->method_data();
if (method_data == NULL) {
ClassLoaderData* loader_data = method->method_holder()->class_loader_data();
method_data = MethodData::allocate(loader_data, method, CHECK_0);
*** 2329,2339 ****
--- 2550,2560 ----
C2V_VMENTRY(void, releaseFailedSpeculations, (JNIEnv* env, jobject, jlong failed_speculations_address))
FailedSpeculation::free_failed_speculations((FailedSpeculation**)(address) failed_speculations_address);
}
! C2V_VMENTRY_0(bool, addFailedSpeculation, (JNIEnv* env, jobject, jlong failed_speculations_address, jbyteArray speculation_obj))
JVMCIPrimitiveArray speculation_handle = JVMCIENV->wrap(speculation_obj);
int speculation_len = JVMCIENV->get_length(speculation_handle);
char* speculation = NEW_RESOURCE_ARRAY(char, speculation_len);
JVMCIENV->copy_bytes_to(speculation_handle, (jbyte*) speculation, 0, speculation_len);
return FailedSpeculation::add_failed_speculation(NULL, (FailedSpeculation**)(address) failed_speculations_address, (address) speculation, speculation_len);
*** 2429,2439 ****
--- 2650,2660 ----
{CC "hasCompiledCodeForOSR", CC "(" HS_RESOLVED_METHOD "II)Z", FN_PTR(hasCompiledCodeForOSR)},
{CC "getSymbol", CC "(J)" STRING, FN_PTR(getSymbol)},
{CC "iterateFrames", CC "([" RESOLVED_METHOD "[" RESOLVED_METHOD "I" INSPECTED_FRAME_VISITOR ")" OBJECT, FN_PTR(iterateFrames)},
{CC "materializeVirtualObjects", CC "(" HS_STACK_FRAME_REF "Z)V", FN_PTR(materializeVirtualObjects)},
{CC "shouldDebugNonSafepoints", CC "()Z", FN_PTR(shouldDebugNonSafepoints)},
! {CC "writeDebugOutput", CC "([BII)V", FN_PTR(writeDebugOutput)},
! {CC "writeDebugOutput", CC "([BIIZZ)I", FN_PTR(writeDebugOutput)},
{CC "flushDebugOutput", CC "()V", FN_PTR(flushDebugOutput)},
{CC "methodDataProfileDataSize", CC "(JI)I", FN_PTR(methodDataProfileDataSize)},
{CC "getFingerprint", CC "(J)J", FN_PTR(getFingerprint)},
{CC "getHostClass", CC "(" HS_RESOLVED_KLASS ")" HS_RESOLVED_KLASS, FN_PTR(getHostClass)},
{CC "interpreterFrameSize", CC "(" BYTECODE_FRAME ")I", FN_PTR(interpreterFrameSize)},
*** 2467,2476 ****
--- 2688,2700 ----
{CC "getInt", CC "(" OBJECTCONSTANT "J)I", FN_PTR(getInt)},
{CC "getLong", CC "(" OBJECTCONSTANT "J)J", FN_PTR(getLong)},
{CC "getObject", CC "(" OBJECTCONSTANT "J)" OBJECTCONSTANT, FN_PTR(getObject)},
{CC "deleteGlobalHandle", CC "(J)V", FN_PTR(deleteGlobalHandle)},
{CC "registerNativeMethods", CC "(" CLASS ")[J", FN_PTR(registerNativeMethods)},
+ {CC "isCurrentThreadAttached", CC "()Z", FN_PTR(isCurrentThreadAttached)},
+ {CC "attachCurrentThread", CC "(Z)Z", FN_PTR(attachCurrentThread)},
+ {CC "detachCurrentThread", CC "()V", FN_PTR(detachCurrentThread)},
{CC "translate", CC "(" OBJECT ")J", FN_PTR(translate)},
{CC "unhand", CC "(J)" OBJECT, FN_PTR(unhand)},
{CC "updateHotSpotNmethod", CC "(" HS_NMETHOD ")V", FN_PTR(updateHotSpotNmethod)},
{CC "getCode", CC "(" HS_INSTALLED_CODE ")[B", FN_PTR(getCode)},
{CC "asReflectionExecutable", CC "(" HS_RESOLVED_METHOD ")" REFLECTION_EXECUTABLE, FN_PTR(asReflectionExecutable)},
src/hotspot/share/jvmci/jvmciCompilerToVM.cpp
Index
Unified diffs
Context diffs
Sdiffs
Wdiffs
Patch
New
Old
Previous File
Next File