8238197: JFR: Rework setting and getting EventHandler

Reviewed-by: egahlin, jbachorik
This commit is contained in:
Markus Grönlund 2021-06-10 10:26:49 +00:00
parent f770f771f8
commit a187fcc3ec
2 changed files with 48 additions and 68 deletions

View File

@ -759,72 +759,58 @@ bool JfrJavaSupport::is_excluded(jobject thread) {
return native_thread != NULL ? native_thread->jfr_thread_local()->is_excluded() : is_thread_excluded(thread);
}
static const Klass* get_handler_field_descriptor(const Handle& h_mirror, fieldDescriptor* descriptor, TRAPS) {
assert(h_mirror.not_null(), "invariant");
assert(descriptor != NULL, "invariant");
Klass* const k = java_lang_Class::as_Klass(h_mirror());
assert(k->is_instance_klass(), "invariant");
InstanceKlass* const ik = InstanceKlass::cast(k);
if (ik->is_not_initialized()) {
ik->initialize(CHECK_NULL);
}
assert(ik->is_being_initialized() || ik->is_initialized(), "invariant");
const Klass* const typed_field_holder = ik->find_field(vmSymbols::eventHandler_name(),
vmSymbols::jdk_jfr_internal_handlers_EventHandler_signature(),
true,
descriptor);
return typed_field_holder != NULL ? typed_field_holder : ik->find_field(vmSymbols::eventHandler_name(),
vmSymbols::object_signature(), // untyped
true,
descriptor);
}
jobject JfrJavaSupport::get_handler(jobject clazz, TRAPS) {
DEBUG_ONLY(JfrJavaSupport::check_java_thread_in_vm(THREAD));
const oop klass_oop = JNIHandles::resolve(clazz);
assert(klass_oop != NULL, "invariant");
Klass* klass = java_lang_Class::as_Klass(klass_oop);
HandleMark hm(THREAD);
Handle h_klass_oop(Handle(THREAD, klass->java_mirror()));
InstanceKlass* const instance_klass = static_cast<InstanceKlass*>(klass);
klass->initialize(CHECK_NULL);
fieldDescriptor event_handler_field;
Klass* f = instance_klass->find_field(
vmSymbols::eventHandler_name(),
vmSymbols::jdk_jfr_internal_handlers_EventHandler_signature(),
true, &event_handler_field);
if (f != NULL) {
oop ret = h_klass_oop->obj_field(event_handler_field.offset());
return ret != NULL ? JfrJavaSupport::local_jni_handle(ret, THREAD) : NULL;
const Handle h_mirror(Handle(THREAD, JNIHandles::resolve(clazz)));
assert(h_mirror.not_null(), "invariant");
fieldDescriptor handler_field_descriptor;
const Klass* const field_holder = get_handler_field_descriptor(h_mirror, &handler_field_descriptor, THREAD);
if (field_holder == NULL) {
// The only reason should be that klass initialization failed.
return NULL;
}
fieldDescriptor object_field;
Klass* g = instance_klass->find_field(
vmSymbols::eventHandler_name(),
vmSymbols::object_signature(),
true, &object_field);
if (g != NULL) {
oop ret = h_klass_oop->obj_field(object_field.offset());
return ret != NULL ? JfrJavaSupport::local_jni_handle(ret, THREAD) : NULL;
}
assert(f == NULL && g == NULL, "no handler field for class");
return NULL;
assert(java_lang_Class::as_Klass(h_mirror()) == field_holder, "invariant");
oop handler_oop = h_mirror->obj_field(handler_field_descriptor.offset());
return handler_oop != NULL ? JfrJavaSupport::local_jni_handle(handler_oop, THREAD) : NULL;
}
bool JfrJavaSupport::set_handler(jobject clazz, jobject handler, TRAPS) {
DEBUG_ONLY(JfrJavaSupport::check_java_thread_in_vm(THREAD));
const oop klass_oop = JNIHandles::resolve(clazz);
assert(klass_oop != NULL, "invariant");
HandleMark hm(THREAD);
const Handle h_mirror(Handle(THREAD, JNIHandles::resolve(clazz)));
assert(h_mirror.not_null(), "invariant");
fieldDescriptor handler_field_descriptor;
const Klass* const field_holder = get_handler_field_descriptor(h_mirror, &handler_field_descriptor, THREAD);
if (field_holder == NULL) {
// The only reason should be that klass initialization failed.
return false;
}
assert(java_lang_Class::as_Klass(h_mirror()) == field_holder, "invariant");
const oop handler_oop = JNIHandles::resolve(handler);
assert(handler_oop != NULL, "invariant");
Klass* klass = java_lang_Class::as_Klass(klass_oop);
HandleMark hm(THREAD);
Handle h_klass_oop(Handle(THREAD, klass->java_mirror()));
InstanceKlass* const instance_klass = static_cast<InstanceKlass*>(klass);
klass->initialize(CHECK_false);
fieldDescriptor event_handler_field;
Klass* f = instance_klass->find_field(
vmSymbols::eventHandler_name(),
vmSymbols::jdk_jfr_internal_handlers_EventHandler_signature(),
true, &event_handler_field);
if (f != NULL) {
h_klass_oop->obj_field_put(event_handler_field.offset(), handler_oop);
return true;
}
fieldDescriptor object_handler_field;
Klass* g = instance_klass->find_field(
vmSymbols::eventHandler_name(),
vmSymbols::object_signature(),
true, &object_handler_field);
if (g != NULL) {
h_klass_oop->obj_field_put(object_handler_field.offset(), handler_oop);
return true;
}
assert(f == NULL && g == NULL, "no handler field for class");
return false;
h_mirror->obj_field_put(handler_field_descriptor.offset(), handler_oop);
return true;
}
void JfrJavaSupport::on_thread_start(Thread* t) {

View File

@ -445,23 +445,17 @@ public final class Utils {
public static synchronized EventHandler getHandler(Class<? extends jdk.internal.event.Event> eventClass) {
Utils.ensureValidEventSubclass(eventClass);
try {
Field f = eventClass.getDeclaredField(EventInstrumentation.FIELD_EVENT_HANDLER);
SecuritySupport.setAccessible(f);
return (EventHandler) f.get(null);
} catch (NoSuchFieldException | IllegalArgumentException | IllegalAccessException e) {
throw new InternalError("Could not access event handler");
Object handler = JVM.getJVM().getHandler(eventClass);
if (handler == null || handler instanceof EventHandler) {
return (EventHandler) handler;
}
throw new InternalError("Could not access event handler");
}
static synchronized void setHandler(Class<? extends jdk.internal.event.Event> eventClass, EventHandler handler) {
Utils.ensureValidEventSubclass(eventClass);
try {
Field field = eventClass.getDeclaredField(EventInstrumentation.FIELD_EVENT_HANDLER);
SecuritySupport.setAccessible(field);
field.set(null, handler);
} catch (NoSuchFieldException | IllegalArgumentException | IllegalAccessException e) {
throw new InternalError("Could not access event handler");
if (!JVM.getJVM().setHandler(eventClass, handler)) {
throw new InternalError("Could not set event handler");
}
}