Skip to content

Commit

Permalink
7439: Introduced IConstantPoolExtension for Constant Pools
Browse files Browse the repository at this point in the history
Reviewed-by: hirt
  • Loading branch information
Jean-Philippe Bempel committed Dec 1, 2021
1 parent ca20442 commit d4449ce
Show file tree
Hide file tree
Showing 13 changed files with 455 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.function.Consumer;
import java.util.function.Predicate;
Expand All @@ -55,6 +56,7 @@
import org.openjdk.jmc.flightrecorder.internal.EventArray;
import org.openjdk.jmc.flightrecorder.internal.EventArrays;
import org.openjdk.jmc.flightrecorder.internal.parser.ParserStats;
import org.openjdk.jmc.flightrecorder.parser.IConstantPoolExtension;

/**
* Implementation of {@link IItemCollection} using {@link IItemIterable} iterators.
Expand Down Expand Up @@ -272,4 +274,9 @@ public IItemCollection getConstantPools() {
public IItemCollection getConstants() {
return parserStats.getConstants();
}

@Override
public Map<String, IConstantPoolExtension> getConstantPoolExtensions() {
return parserStats.getConstantPoolExtensions();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,12 @@
*/
package org.openjdk.jmc.flightrecorder;

import java.util.Collections;
import java.util.Map;
import java.util.function.Consumer;

import org.openjdk.jmc.common.item.IItemCollection;
import org.openjdk.jmc.flightrecorder.parser.IConstantPoolExtension;

public interface IParserStats {

Expand Down Expand Up @@ -64,4 +67,8 @@ public interface IEventStats {
IItemCollection getConstantPools();

IItemCollection getConstants();

default Map<String, IConstantPoolExtension> getConstantPoolExtensions() {
return Collections.emptyMap();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,14 @@
*/
package org.openjdk.jmc.flightrecorder.internal;

import java.util.Map;
import java.util.Set;

import org.openjdk.jmc.common.item.IItemCollection;
import org.openjdk.jmc.common.unit.IQuantity;
import org.openjdk.jmc.common.unit.IRange;
import org.openjdk.jmc.flightrecorder.internal.parser.ParserStats;
import org.openjdk.jmc.flightrecorder.parser.IConstantPoolExtension;

public class EventArrays {

Expand Down Expand Up @@ -70,4 +72,8 @@ public IItemCollection getConstantPools() {
public IItemCollection getConstants() {
return parserStats.getConstants();
}

public Map<String, IConstantPoolExtension> getConstantPoolExtensions() {
return parserStats.getConstantPoolExtensions();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,10 @@
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;

import org.openjdk.jmc.common.collection.FastAccessNumberMap;
import org.openjdk.jmc.common.item.IAttribute;
Expand All @@ -51,6 +53,7 @@
import org.openjdk.jmc.flightrecorder.internal.EventArrays;
import org.openjdk.jmc.flightrecorder.internal.parser.RepositoryBuilder.EventTypeEntry;
import org.openjdk.jmc.flightrecorder.internal.util.CanonicalConstantMap;
import org.openjdk.jmc.flightrecorder.parser.IConstantPoolExtension;
import org.openjdk.jmc.flightrecorder.parser.IEventSinkFactory;
import org.openjdk.jmc.flightrecorder.parser.IParserExtension;

Expand All @@ -64,6 +67,7 @@ public class LoaderContext {
private final ConcurrentHashMap<Object, CanonicalConstantMap<Object>> constantsByType = new ConcurrentHashMap<>();
private final boolean hideExperimentals;
private final List<? extends IParserExtension> extensions;
private final List<IConstantPoolExtension> constPoolExtensions = new CopyOnWriteArrayList<>();
private final Set<IRange<IQuantity>> chunkRanges;
private final ParserStats parserStats = new ParserStats();

Expand All @@ -75,6 +79,12 @@ public LoaderContext(List<? extends IParserExtension> extensions, boolean hideEx
for (int i = extensions.size() - 1; i >= 0; i--) {
sinkFactory = extensions.get(i).getEventSinkFactory(sinkFactory);
}
for (IParserExtension extension : extensions) {
IConstantPoolExtension constantPoolExtension = extension.createConstantPoolExtension();
if (constantPoolExtension != null) {
constPoolExtensions.add(constantPoolExtension);
}
}
this.sinkFactory = sinkFactory;
this.chunkRanges = new HashSet<>();
}
Expand All @@ -99,6 +109,36 @@ public String getValueInterpretation(String eventTypeId, String fieldId) {
return null;
}

public Object constantRead(long constantIndex, Object constant, String eventTypeId) {
Object newConstant = constant;
for (IConstantPoolExtension m : constPoolExtensions) {
newConstant = m.constantRead(constantIndex, newConstant, eventTypeId);
}
return newConstant;
}

public Object constantReferenced(Object constant, String poolName, String eventTypeId) {
Object newConstant = constant;
for (IConstantPoolExtension m : constPoolExtensions) {
newConstant = m.constantReferenced(newConstant, poolName, eventTypeId);
}
return newConstant;
}

public Object constantResolved(Object constant, String poolName, String eventTypeId) {
Object newConstant = constant;
for (IConstantPoolExtension m : constPoolExtensions) {
newConstant = m.constantResolved(newConstant, poolName, eventTypeId);
}
return newConstant;
}

public void allConstantPoolsResolved(Map<String, FastAccessNumberMap<Object>> constantPools) {
for (IConstantPoolExtension m : constPoolExtensions) {
m.allConstantPoolsResolved(constantPools);
}
}

public IEventSinkFactory getSinkFactory() {
return sinkFactory;
}
Expand Down Expand Up @@ -166,4 +206,11 @@ public void setSkippedEventCount(long skippedEventCount) {
public void addEntryPoolSize(String typeIdentifier, long size) {
parserStats.addEntryPoolSize(typeIdentifier, size);
}

public void addConstantPoolExtensions() {
for (IConstantPoolExtension ext : constPoolExtensions) {
ext.eventsLoaded();
parserStats.addConstantPoolExtension(ext);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@
import org.openjdk.jmc.common.unit.UnitLookup;
import org.openjdk.jmc.common.util.MemberAccessorToolkit;
import org.openjdk.jmc.flightrecorder.IParserStats.IEventStats;
import org.openjdk.jmc.flightrecorder.parser.IConstantPoolExtension;
import org.openjdk.jmc.flightrecorder.stacktrace.FrameSeparator;
import org.openjdk.jmc.flightrecorder.stacktrace.FrameSeparator.FrameCategorization;
import org.openjdk.jmc.flightrecorder.stacktrace.StacktraceFormatToolkit;
Expand All @@ -71,10 +72,11 @@ public class ParserStats {
private final AtomicInteger chunkCount = new AtomicInteger();
private final AtomicLong skippedEventCount = new AtomicLong();
private final ConcurrentHashMap<String, EventTypeStats> statsByType = new ConcurrentHashMap<>();
private final ConcurrentLinkedDeque<ConstantPoolInfo> constantPoolInfoList = new ConcurrentLinkedDeque<ConstantPoolInfo>();
private final ConcurrentLinkedDeque<ConstantPoolInfo> constantPoolInfoList = new ConcurrentLinkedDeque<>();
private final ConcurrentHashMap<String, Long> entryPoolSizeByType = new ConcurrentHashMap<>();
private IItemCollection poolStats;
private IItemCollection constants;
private Map<String, IConstantPoolExtension> constantPoolExtensions = new ConcurrentHashMap<>();

public void setVersion(short majorVersion, short minorVersion) {
this.majorVersion = majorVersion;
Expand Down Expand Up @@ -112,6 +114,10 @@ public void addEntryPoolSize(String typeIdentifier, long size) {
});
}

public void addConstantPoolExtension(IConstantPoolExtension extension) {
constantPoolExtensions.put(extension.getId(), extension);
}

public void forEachEventType(Consumer<IEventStats> consumer) {
for (EventTypeStats eventStats : statsByType.values()) {
consumer.accept(eventStats);
Expand Down Expand Up @@ -175,6 +181,10 @@ public IItemCollection getConstants() {
return constants;
}

public Map<String, IConstantPoolExtension> getConstantPoolExtensions() {
return constantPoolExtensions;
}

static class ConstPoolItem implements IItem, IType<IItem> {
private final String name;
private long count;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ public byte[] call() throws Exception {
index += size;
}
context.setSkippedEventCount(manager.getSkippedEventCount());
context.addConstantPoolExtensions();
return data;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ public IValueReader getReader() throws InvalidJfrFileException {
throw new InvalidJfrFileException(
element.typeIdentifier + " is a simple type referring to itself"); //$NON-NLS-1$
} else {
reader = createFieldReader(element.fields.get(0), null);
reader = createFieldReader(element.fields.get(0), null, context, element.typeIdentifier);
}
} else if (fieldCount == 0 && element.superType == null) {
if (StringReader.STRING.equals(element.typeIdentifier)) {
Expand All @@ -187,7 +187,7 @@ public IValueReader getReader() throws InvalidJfrFileException {
reader = typeReader;
for (int i = 0; i < fieldCount; i++) {
FieldElement fe = element.fields.get(i);
IValueReader reader = createFieldReader(fe, null);
IValueReader reader = createFieldReader(fe, null, context, element.typeIdentifier);
String labelOrId = (fe.label == null) ? fe.fieldIdentifier : fe.label;
typeReader.addField(fe.fieldIdentifier, labelOrId, fe.description, reader);
}
Expand Down Expand Up @@ -292,6 +292,7 @@ void readConstant(IDataInput input) throws InvalidJfrFileException, IOException
Object value = constants.get(constantIndex);
if (value == null) {
value = getReader().read(input, true);
value = context.constantRead(constantIndex, value, element.typeIdentifier);
constants.put(constantIndex, value);
} else {
getReader().skip(input);
Expand Down Expand Up @@ -339,7 +340,7 @@ void init(LoaderContext context) throws InvalidJfrFileException, IOException {
for (int i = 0; i < element.getFieldCount(); i++) {
FieldElement fe = element.fields.get(i);
String valueType = context.getValueInterpretation(element.typeIdentifier, fe.fieldIdentifier);
IValueReader reader = createFieldReader(fe, valueType);
IValueReader reader = createFieldReader(fe, valueType, context, element.typeIdentifier);
String fieldLabel = buildLabel(fe.fieldIdentifier, fe);
if (context.hideExperimentals() && fe.experimental) {
valueReaders.add(reader);
Expand All @@ -351,7 +352,8 @@ void init(LoaderContext context) throws InvalidJfrFileException, IOException {
FieldElement nestedField = fieldType.fields.get(j);
String nestedId = fe.fieldIdentifier + ":" + nestedField.fieldIdentifier; //$NON-NLS-1$
String nestedValueType = context.getValueInterpretation(element.typeIdentifier, nestedId);
IValueReader nestedReader = createFieldReader(nestedField, nestedValueType);
IValueReader nestedReader = createFieldReader(nestedField, nestedValueType, context,
element.typeIdentifier);
valueReaders.add(nestedReader);
String nestedLabel = fieldLabel + " : " //$NON-NLS-1$
+ (nestedField.label == null ? nestedField.fieldIdentifier : nestedField.label);
Expand Down Expand Up @@ -384,11 +386,13 @@ void updateEventStats(long size) {
private final Map<Long, StructContentType<Object[]>> structTypes = new HashMap<>();
private final FastAccessNumberMap<TypeEntry> otherTypes = new FastAccessNumberMap<>();
private final FastAccessNumberMap<EventTypeEntry> eventTypes = new FastAccessNumberMap<>();
private final LoaderContext context;
private final ChunkStructure header;
private long skippedEventCount;

TypeManager(List<ClassElement> classList, LoaderContext context, ChunkStructure header)
throws InvalidJfrFileException, IOException {
this.context = context;
this.header = header;
for (ClassElement ce : classList) {
if (ce.isEventType()) {
Expand Down Expand Up @@ -430,9 +434,12 @@ void readConstants(long typeId, IDataInput input, int constantCount) throws Inva
}

void resolveConstants() throws InvalidJfrFileException {
Map<String, FastAccessNumberMap<Object>> pools = new HashMap<>();
for (TypeEntry classEntry : otherTypes) {
classEntry.resolveConstants();
pools.put(classEntry.element.typeIdentifier, classEntry.constants);
}
context.allConstantPoolsResolved(pools);
}

long getSkippedEventCount() {
Expand All @@ -456,7 +463,8 @@ private void resolveAnnotations(AnnotatedElement ae) throws InvalidJfrFileExcept
}
}

private IValueReader createFieldReader(FieldElement f, String valueType) throws InvalidJfrFileException {
private IValueReader createFieldReader(FieldElement f, String valueType, LoaderContext context, String eventTypeId)
throws InvalidJfrFileException {
TypeEntry fieldType = getTypeEntry(f.classId);
String typeIdentifier = fieldType.element.typeIdentifier;
boolean isNumeric = PrimitiveReader.isNumeric(typeIdentifier);
Expand Down Expand Up @@ -487,7 +495,7 @@ private IValueReader createFieldReader(FieldElement f, String valueType) throws
if (isNumeric) {
throw new InvalidJfrFileException("Numerics should not be put in constant pools"); //$NON-NLS-1$
}
reader = new PoolReader(fieldType.constants, reader.getContentType());
reader = new PoolReader(fieldType.constants, reader.getContentType(), context, typeIdentifier, eventTypeId);
}
return f.isArray() ? new ArrayReader(reader, header) : reader;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018, 2021, Oracle and/or its affiliates. All rights reserved.
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
Expand Down Expand Up @@ -48,6 +48,7 @@
import org.openjdk.jmc.common.unit.UnitLookup;
import org.openjdk.jmc.common.util.MemberAccessorToolkit;
import org.openjdk.jmc.flightrecorder.internal.InvalidJfrFileException;
import org.openjdk.jmc.flightrecorder.internal.parser.LoaderContext;

class ValueReaders {
interface IValueReader {
Expand Down Expand Up @@ -81,17 +82,25 @@ public boolean equals(Object obj) {
static class PoolReader implements IValueReader {
private final FastAccessNumberMap<Object> constantPool;
private final ContentType<?> contentType;
private final LoaderContext context;
private final String poolName;
private final String eventTypeId;

PoolReader(FastAccessNumberMap<Object> pool, ContentType<?> contentType) {
PoolReader(FastAccessNumberMap<Object> pool, ContentType<?> contentType, LoaderContext context, String poolName,
String eventTypeId) {
this.constantPool = pool;
this.contentType = contentType;
this.context = context;
this.poolName = poolName;
this.eventTypeId = eventTypeId;
}

@Override
public Object read(IDataInput in, boolean allowUnresolvedReference)
throws IOException, InvalidJfrFileException {
long constantIndex = in.readLong();
Object constant = constantPool.get(constantIndex);
constant = context.constantReferenced(constant, poolName, eventTypeId);
return (allowUnresolvedReference && (constant == null)) ? new ConstantReference(constantIndex) : constant;
}

Expand All @@ -103,7 +112,9 @@ public void skip(IDataInput in) throws IOException, InvalidJfrFileException {
@Override
public Object resolve(Object value) throws InvalidJfrFileException {
if (value instanceof ConstantReference) {
return constantPool.get(((ConstantReference) value).key);
Object newValue = constantPool.get(((ConstantReference) value).key);
newValue = context.constantResolved(newValue, poolName, eventTypeId);
return newValue;
}
return value;
}
Expand Down
Loading

0 comments on commit d4449ce

Please sign in to comment.