8280055: JFR: Improve ObjectContext implementation

Reviewed-by: mgronlun
This commit is contained in:
Erik Gahlin 2022-01-18 17:57:12 +00:00
parent 7acc4c7dfe
commit b734dc86ee
2 changed files with 32 additions and 25 deletions

View File

@ -150,16 +150,7 @@ public class RecordedObject {
JdkJfrConsumer.setAccess(access);
}
private static final class UnsignedValue {
private final Object o;
UnsignedValue(Object o) {
this.o = o;
}
Object value() {
return o;
}
private static final record UnsignedValue(Object value) {
}
final Object[] objects;

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2019, 2022, 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
@ -26,7 +26,8 @@
package jdk.jfr.internal.consumer;
import java.time.ZoneId;
import java.util.HashMap;
import java.util.ArrayDeque;
import java.util.IdentityHashMap;
import java.util.List;
import java.util.Map;
@ -34,33 +35,48 @@ import jdk.jfr.EventType;
import jdk.jfr.ValueDescriptor;
public final class ObjectContext {
private final Map<ValueDescriptor, ObjectContext> contextLookup;
private Map<ValueDescriptor, ObjectContext> contextLookup;
private final TimeConverter timeConverter;
public final EventType eventType;
public final List<ValueDescriptor> fields;
ObjectContext(EventType eventType, List<ValueDescriptor> fields, TimeConverter timeConverter) {
this.contextLookup = new HashMap<>();
this.eventType = eventType;
this.fields = fields;
this.timeConverter = timeConverter;
}
private ObjectContext(ObjectContext parent, ValueDescriptor descriptor) {
this.eventType = parent.eventType;
this.contextLookup = parent.contextLookup;
this.timeConverter = parent.timeConverter;
this.fields = descriptor.getFields();
private ObjectContext(Map<ValueDescriptor, ObjectContext> contextLookup, EventType eventType, List<ValueDescriptor> fields, TimeConverter timeConverter) {
this.eventType = eventType;
this.contextLookup = contextLookup;
this.timeConverter = timeConverter;
this.fields = fields;
}
public ObjectContext getInstance(ValueDescriptor descriptor) {
ObjectContext context = contextLookup.get(descriptor);
if (context == null) {
context = new ObjectContext(this, descriptor);
contextLookup.put(descriptor, context);
if (contextLookup == null) {
// Lazy, only needed when accessing nested structures.
contextLookup = buildContextLookup(fields);
}
return context;
return contextLookup.get(descriptor);
}
// Create mapping from ValueDescriptor to ObjectContext for all reachable
// ValueDescriptors.
public Map<ValueDescriptor, ObjectContext> buildContextLookup(List<ValueDescriptor> fields) {
Map<ValueDescriptor, ObjectContext> lookup = new IdentityHashMap<>();
ArrayDeque<ValueDescriptor> q = new ArrayDeque<>(fields);
while (!q.isEmpty()) {
ValueDescriptor vd = q.pop();
if (!lookup.containsKey(vd)) {
List<ValueDescriptor> children = vd.getFields();
lookup.put(vd, new ObjectContext(lookup, eventType, children, timeConverter));
for (ValueDescriptor v : children) {
q.add(v);
}
}
}
return lookup;
}
public long convertTimestamp(long ticks) {