diff --git a/src/hotspot/share/prims/jvmtiExport.cpp b/src/hotspot/share/prims/jvmtiExport.cpp index 02f39460ff6..219bd26f926 100644 --- a/src/hotspot/share/prims/jvmtiExport.cpp +++ b/src/hotspot/share/prims/jvmtiExport.cpp @@ -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; } diff --git a/src/hotspot/share/prims/jvmtiImpl.cpp b/src/hotspot/share/prims/jvmtiImpl.cpp index c0a4ca949c9..a082c37e10c 100644 --- a/src/hotspot/share/prims/jvmtiImpl.cpp +++ b/src/hotspot/share/prims/jvmtiImpl.cpp @@ -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(); } diff --git a/src/hotspot/share/prims/jvmtiImpl.hpp b/src/hotspot/share/prims/jvmtiImpl.hpp index 0fd63556a78..614d0b1bb89 100644 --- a/src/hotspot/share/prims/jvmtiImpl.hpp +++ b/src/hotspot/share/prims/jvmtiImpl.hpp @@ -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;