8214294: Post ResourceExhausted events generated by CompilerThread on the ServiceThread

This commit is contained in:
Leonid Mesnik 2026-01-24 00:21:10 -08:00
parent 44b74e165e
commit bd25de028b
3 changed files with 42 additions and 10 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 2026, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -1803,12 +1803,10 @@ void JvmtiExport::post_resource_exhausted(jint resource_exhausted_flags, const c
log_error(jvmti)("Posting Resource Exhausted event: %s",
description != nullptr ? description : "unknown");
// JDK-8213834: handlers of ResourceExhausted may attempt some analysis
// which often requires running java.
// This will cause problems on threads not able to run java, e.g. compiler
// threads. To forestall these problems, we therefore suppress sending this
// event from threads which are not able to run java.
if (!thread->can_call_java()) {
JvmtiDeferredEvent event = JvmtiDeferredEvent::resource_exhausted_event(
resource_exhausted_flags, nullptr, description);
ServiceThread::enqueue_deferred_event(&event);
return;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 2026, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -797,6 +797,19 @@ JvmtiDeferredEvent JvmtiDeferredEvent::class_unload_event(const char* name) {
return event;
}
JvmtiDeferredEvent JvmtiDeferredEvent::resource_exhausted_event(
const jint flags, const void* reserved, const char* description) {
JvmtiDeferredEvent event = JvmtiDeferredEvent(TYPE_RESOURCE_EXHAUSTED);
// Need to make a copy of the description since we don't know how long
// the event poster will keep it around after we enqueue the
// deferred event and return. strdup() failure is handled in
// the post() routine below.
event._event_data.resource_exhausted.flags = flags;
event._event_data.resource_exhausted.reserved = reserved;
event._event_data.resource_exhausted.description = os::strdup(description);
return event;
}
void JvmtiDeferredEvent::post() {
assert(Thread::current()->is_service_thread(),
"Service thread must post enqueued events");
@ -836,6 +849,19 @@ void JvmtiDeferredEvent::post() {
}
break;
}
case TYPE_RESOURCE_EXHAUSTED: {
JvmtiExport::post_resource_exhausted(
_event_data.resource_exhausted.flags,
// if strdup failed give the event a default name
(_event_data.resource_exhausted.description == nullptr)
? "no description" : _event_data.resource_exhausted.description
);
if (_event_data.resource_exhausted.description != nullptr) {
// release our copy
os::free((void *)_event_data.resource_exhausted.description);
}
break;
}
default:
ShouldNotReachHere();
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1999, 2026, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -297,7 +297,8 @@ class JvmtiDeferredEvent {
TYPE_COMPILED_METHOD_LOAD,
TYPE_COMPILED_METHOD_UNLOAD,
TYPE_DYNAMIC_CODE_GENERATED,
TYPE_CLASS_UNLOAD
TYPE_CLASS_UNLOAD,
TYPE_RESOURCE_EXHAUSTED
} Type;
Type _type;
@ -315,6 +316,11 @@ class JvmtiDeferredEvent {
struct {
const char* name;
} class_unload;
struct {
jint flags;
const void* reserved;
const char* description;
} resource_exhausted;
} _event_data;
JvmtiDeferredEvent(Type t) : _type(t) {}
@ -333,7 +339,9 @@ class JvmtiDeferredEvent {
NOT_JVMTI_RETURN_(JvmtiDeferredEvent());
static JvmtiDeferredEvent class_unload_event(
const char* name) NOT_JVMTI_RETURN_(JvmtiDeferredEvent());
static JvmtiDeferredEvent resource_exhausted_event(
const jint flags, const void* reserved, const char* description)
NOT_JVMTI_RETURN_(JvmtiDeferredEvent());
// Actually posts the event.
void post() NOT_JVMTI_RETURN;
void post_compiled_method_load_event(JvmtiEnv* env) NOT_JVMTI_RETURN;