Skip to content
1 change: 0 additions & 1 deletion src/hotspot/share/classfile/vmClassMacros.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,6 @@
do_klass(ContinuationScope_klass, jdk_internal_vm_ContinuationScope ) \
do_klass(Continuation_klass, jdk_internal_vm_Continuation ) \
do_klass(StackChunk_klass, jdk_internal_vm_StackChunk ) \
do_klass(VMSupport_klass, jdk_internal_vm_VMSupport ) \
\
do_klass(reflect_MethodAccessorImpl_klass, reflect_MethodAccessorImpl ) \
do_klass(reflect_DelegatingClassLoader_klass, reflect_DelegatingClassLoader ) \
Expand Down
4 changes: 3 additions & 1 deletion src/hotspot/share/jvmci/jvmciCompilerToVM.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2833,7 +2833,9 @@ static jbyteArray get_encoded_annotation_data(InstanceKlass* holder, AnnotationA
Handle jcp = reflect_ConstantPool::create(CHECK_NULL);
reflect_ConstantPool::set_cp(jcp(), holder->constants());

Klass* k = vmClasses::VMSupport_klass();
// load VMSupport
Symbol* klass = vmSymbols::jdk_internal_vm_VMSupport();
Klass* k = SystemDictionary::resolve_or_fail(klass, true, CHECK_NULL);

InstanceKlass* vm_support = InstanceKlass::cast(k);
if (vm_support->should_be_initialized()) {
Expand Down
35 changes: 22 additions & 13 deletions src/hotspot/share/jvmci/jvmciEnv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -382,46 +382,45 @@ class ExceptionTranslation: public StackObj {
// Encodes the exception in `_from_env` into `buffer`.
// Where N is the number of bytes needed for the encoding, returns N if N <= `buffer_size`
// and the encoding was written to `buffer` otherwise returns -N.
virtual int encode(JavaThread* THREAD, Klass* vmSupport, jlong buffer, int buffer_size) = 0;
virtual int encode(JavaThread* THREAD, jlong buffer, int buffer_size) = 0;

// Decodes the exception in `format` and `buffer` in `_to_env` and throws it.
virtual void decode(JavaThread* THREAD, Klass* vmSupport, jint format, jlong buffer) = 0;
virtual void decode(JavaThread* THREAD, jint format, jlong buffer) = 0;

public:
void doit(JavaThread* THREAD) {
Klass* vmSupport = vmClasses::VMSupport_klass();
int buffer_size = 2048;
while (true) {
ResourceMark rm;
jlong buffer = (jlong) NEW_RESOURCE_ARRAY_IN_THREAD_RETURN_NULL(THREAD, jbyte, buffer_size);
if (buffer == 0L) {
JVMCI_event_1("error translating exception: translation buffer allocation failed");
decode(THREAD, vmSupport, -1, 0L);
decode(THREAD, -1, 0L);
return;
}
int res = encode(THREAD, vmSupport, buffer, buffer_size);
int res = encode(THREAD, buffer, buffer_size);
if (_from_env != nullptr && !_from_env->is_hotspot() && _from_env->has_pending_exception()) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this check before the HAS_PENDING_EXCEPTION check? Couldn't you end up returning with a pending exception in this path?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If encode is SharedLibraryToHotSpotExceptionTranslation::encode there is no possibility of a pending HotSpot exception upon it returning. If it's HotSpotToSharedLibraryExceptionTranslation::encode then _from_env->is_hotspot() is true and so this if branch is not taken.

// Cannot get name of exception thrown by `encode` as that involves
// calling into libjvmci which in turn can raise another exception.
_from_env->clear_pending_exception();
JVMCI_event_1("error translating exception: unknown error");
decode(THREAD, vmSupport, -3, 0L);
decode(THREAD, -3, 0L);
return;
} else if (HAS_PENDING_EXCEPTION) {
Handle throwable = Handle(THREAD, PENDING_EXCEPTION);
Symbol *ex_name = throwable->klass()->name();
CLEAR_PENDING_EXCEPTION;
if (ex_name == vmSymbols::java_lang_OutOfMemoryError()) {
JVMCI_event_1("error translating exception: OutOfMemoryError");
decode(THREAD, vmSupport, -2, 0L);
decode(THREAD, -2, 0L);
} else {
char* char_buffer = (char*) buffer + 4;
stringStream st(char_buffer, (size_t) buffer_size - 4);
java_lang_Throwable::print_stack_trace(throwable, &st);
int len = st.size();
*((u4*) buffer) = len;
JVMCI_event_1("error translating exception: %s", char_buffer);
decode(THREAD, vmSupport, -3, buffer);
decode(THREAD, -3, buffer);
}
return;
} else if (res < 0) {
Expand All @@ -430,7 +429,7 @@ class ExceptionTranslation: public StackObj {
buffer_size = required_buffer_size;
}
} else {
decode(THREAD, vmSupport, 0, buffer);
decode(THREAD, 0, buffer);
if (!_to_env->has_pending_exception()) {
_to_env->throw_InternalError("decodeAndThrowThrowable should have thrown an exception");
}
Expand All @@ -445,7 +444,12 @@ class HotSpotToSharedLibraryExceptionTranslation : public ExceptionTranslation {
private:
const Handle& _throwable;

int encode(JavaThread* THREAD, Klass* vmSupport, jlong buffer, int buffer_size) {
int encode(JavaThread* THREAD, jlong buffer, int buffer_size) {
Klass* vmSupport = SystemDictionary::resolve_or_fail(vmSymbols::jdk_internal_vm_VMSupport(), true, THREAD);
if (HAS_PENDING_EXCEPTION) {
// Propagate pending exception
return 0;
}
JavaCallArguments jargs;
jargs.push_oop(_throwable);
jargs.push_long(buffer);
Expand All @@ -458,7 +462,7 @@ class HotSpotToSharedLibraryExceptionTranslation : public ExceptionTranslation {
return result.get_jint();
}

void decode(JavaThread* THREAD, Klass* vmSupport, jint format, jlong buffer) {
void decode(JavaThread* THREAD, jint format, jlong buffer) {
JNIAccessMark jni(_to_env, THREAD);
jni()->CallStaticVoidMethod(JNIJVMCI::VMSupport::clazz(),
JNIJVMCI::VMSupport::decodeAndThrowThrowable_method(),
Expand All @@ -474,14 +478,19 @@ class SharedLibraryToHotSpotExceptionTranslation : public ExceptionTranslation {
private:
jthrowable _throwable;

int encode(JavaThread* THREAD, Klass* vmSupport, jlong buffer, int buffer_size) {
int encode(JavaThread* THREAD, jlong buffer, int buffer_size) {
JNIAccessMark jni(_from_env, THREAD);
return jni()->CallStaticIntMethod(JNIJVMCI::VMSupport::clazz(),
JNIJVMCI::VMSupport::encodeThrowable_method(),
_throwable, buffer, buffer_size);
}

void decode(JavaThread* THREAD, Klass* vmSupport, jint format, jlong buffer) {
void decode(JavaThread* THREAD, jint format, jlong buffer) {
Klass* vmSupport = SystemDictionary::resolve_or_fail(vmSymbols::jdk_internal_vm_VMSupport(), true, THREAD);
if (HAS_PENDING_EXCEPTION) {
// Propagate pending exception
return;
}
JavaCallArguments jargs;
jargs.push_int(format);
jargs.push_long(buffer);
Expand Down
7 changes: 5 additions & 2 deletions src/hotspot/share/services/attachListener.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,8 @@ volatile AttachListenerState AttachListener::_state = AL_NOT_INITIALIZED;
// Invokes VMSupport.serializePropertiesToByteArray to serialize
// the system properties into a byte array.

static InstanceKlass* initialize_klass(Klass* k, TRAPS) {
static InstanceKlass* load_and_initialize_klass(Symbol* sh, TRAPS) {
Klass* k = SystemDictionary::resolve_or_fail(sh, true, CHECK_NULL);
InstanceKlass* ik = InstanceKlass::cast(k);
if (ik->should_be_initialized()) {
ik->initialize(CHECK_NULL);
Expand All @@ -67,7 +68,9 @@ static jint get_properties(AttachOperation* op, outputStream* out, Symbol* seria
JavaThread* THREAD = JavaThread::current(); // For exception macros.
HandleMark hm(THREAD);

InstanceKlass* k = initialize_klass(vmClasses::VMSupport_klass(), THREAD);
// load VMSupport
Symbol* klass = vmSymbols::jdk_internal_vm_VMSupport();
InstanceKlass* k = load_and_initialize_klass(klass, THREAD);
if (HAS_PENDING_EXCEPTION) {
java_lang_Throwable::print(PENDING_EXCEPTION, out);
CLEAR_PENDING_EXCEPTION;
Expand Down
4 changes: 3 additions & 1 deletion src/hotspot/share/services/diagnosticCommand.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -328,7 +328,9 @@ void JVMTIAgentLoadDCmd::execute(DCmdSource source, TRAPS) {
#endif // INCLUDE_SERVICES

void PrintSystemPropertiesDCmd::execute(DCmdSource source, TRAPS) {
Klass* k = vmClasses::VMSupport_klass();
// load VMSupport
Symbol* klass = vmSymbols::jdk_internal_vm_VMSupport();
Klass* k = SystemDictionary::resolve_or_fail(klass, true, CHECK);
InstanceKlass* ik = InstanceKlass::cast(k);
if (ik->should_be_initialized()) {
ik->initialize(THREAD);
Expand Down