Skip to content

8351698: JFR: Strengthen assertion on missing IDs #24110

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2016, 2025, 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
Expand Down Expand Up @@ -308,6 +308,7 @@ private void fillConstantPools(long abortCP) throws IOException {
long thisCP = chunkHeader.getConstantPoolPosition() + chunkHeader.getAbsoluteChunkStart();
long lastCP = -1;
long delta = -1;
boolean assertionEnabled = Utils.isAssertionEnabled();
boolean logTrace = Logger.shouldLog(LogTag.JFR_SYSTEM_PARSER, LogLevel.TRACE);
while (thisCP != abortCP && delta != 0) {
CheckpointEvent cp = null;
Expand Down Expand Up @@ -364,7 +365,7 @@ private void fillConstantPools(long abortCP) throws IOException {
long position = input.position();
long key = input.readLong();
Object resolved = lookup.getPreviousResolved(key);
if (resolved == null) {
if (resolved == null || assertionEnabled) {
Object v = parser.parse(input);
logConstant(key, v, false);
lookup.getLatestPool().put(key, v);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2016, 2022, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2016, 2025, 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
Expand Down Expand Up @@ -29,12 +29,16 @@
import java.util.ArrayList;
import java.util.List;

import jdk.jfr.internal.Logger;
import jdk.jfr.EventType;
import jdk.jfr.ValueDescriptor;
import jdk.jfr.internal.LogLevel;
import jdk.jfr.internal.LogTag;
import jdk.jfr.internal.LongMap;
import jdk.jfr.internal.MetadataDescriptor;
import jdk.jfr.internal.PrivateAccess;
import jdk.jfr.internal.Type;
import jdk.jfr.internal.util.Utils;

/**
* Class that create parsers suitable for reading events and constant pools
Expand All @@ -58,7 +62,7 @@ public ParserFactory(MetadataDescriptor metadata, LongMap<ConstantLookup> consta
types.forEach(typeList::add);
for (Type t : typeList) {
if (!t.getFields().isEmpty()) { // Avoid primitives
CompositeParser cp = createCompositeParser(t, false);
CompositeParser cp = createCompositeParser(null, t);
if (t.isSimpleType()) { // Reduce to nested parser
parsers.put(t.getId(), cp.parsers[0]);
}
Expand All @@ -81,17 +85,17 @@ public LongMap<Type> getTypeMap() {
private EventParser createEventParser(EventType eventType) throws IOException {
List<Parser> parsers = new ArrayList<Parser>();
for (ValueDescriptor f : eventType.getFields()) {
parsers.add(createParser(f, true));
parsers.add(createParser(eventType, f));
}
return new EventParser(timeConverter, eventType, parsers.toArray(new Parser[0]));
}

private Parser createParser(ValueDescriptor v, boolean event) throws IOException {
private Parser createParser(EventType eventType, ValueDescriptor v) throws IOException {
boolean constantPool = PrivateAccess.getInstance().isConstantPool(v);
if (v.isArray()) {
Type valueType = PrivateAccess.getInstance().getType(v);
ValueDescriptor element = PrivateAccess.getInstance().newValueDescriptor(v.getName(), valueType, v.getAnnotationElements(), 0, constantPool, null);
return new ArrayParser(createParser(element, event));
return new ArrayParser(createParser(eventType, element));
}
long id = v.getTypeId();
Type type = types.get(id);
Expand All @@ -105,15 +109,15 @@ private Parser createParser(ValueDescriptor v, boolean event) throws IOException
lookup = new ConstantLookup(pool, type);
constantLookups.put(id, lookup);
}
if (event) {
return new EventValueConstantParser(lookup);
if (eventType != null) {
return new EventValueConstantParser(eventType, v.getName(), lookup);
}
return new ConstantValueParser(lookup);
}
Parser parser = parsers.get(id);
if (parser == null) {
if (!v.getFields().isEmpty()) {
return createCompositeParser(type, event);
return createCompositeParser(null, type);
} else {
return registerParserType(type, createPrimitiveParser(type, constantPool));
}
Expand Down Expand Up @@ -151,7 +155,7 @@ private Parser registerParserType(Type t, Parser parser) {
return parser;
}

private CompositeParser createCompositeParser(Type type, boolean event) throws IOException {
private CompositeParser createCompositeParser(EventType eventType, Type type) throws IOException {
List<ValueDescriptor> vds = type.getFields();
Parser[] parsers = new Parser[vds.size()];
CompositeParser composite = new CompositeParser(parsers);
Expand All @@ -160,7 +164,7 @@ private CompositeParser createCompositeParser(Type type, boolean event) throws I

int index = 0;
for (ValueDescriptor vd : vds) {
parsers[index++] = createParser(vd, event);
parsers[index++] = createParser(eventType, vd);
}
return composite;
}
Expand Down Expand Up @@ -316,23 +320,44 @@ public void skip(RecordingInput input) throws IOException {
}

private static final class EventValueConstantParser extends Parser {
private static final boolean ASSERTION_ENABLED = Utils.isAssertionEnabled();
private final ConstantLookup lookup;
private final EventType eventType;
private final String fieldName;

private Object lastValue = 0;
private long lastKey = -1;
private Object lastReferenceValue;
private long lastReferenceKey = -1;
EventValueConstantParser(ConstantLookup lookup) {

EventValueConstantParser(EventType eventType, String fieldName, ConstantLookup lookup) {
this.eventType = eventType;
this.fieldName = fieldName;
this.lookup = lookup;
}

@Override
public Object parse(RecordingInput input) throws IOException {
long key = input.readLong();
if (key == lastKey) {
if (key == lastKey && !ASSERTION_ENABLED) {
return lastValue;
}
lastKey = key;
lastValue = lookup.getCurrentResolved(key);
if (lastValue == null && key != 0) {
StringBuilder sb = new StringBuilder();
sb.append("Missing object ID ");
sb.append(key);
sb.append(" for ");
sb.append(eventType.getName());
sb.append(".");
sb.append(fieldName);
sb.append(" of type " + lookup.getType().getName());
sb.append(". All IDs should reference an object.");
String msg = sb.toString();
Logger.log(LogTag.JFR_SYSTEM_PARSER, LogLevel.INFO, msg);
assert false : msg;
}
return lastValue;
}

Expand Down
6 changes: 6 additions & 0 deletions src/jdk.jfr/share/classes/jdk/jfr/internal/util/Utils.java
Original file line number Diff line number Diff line change
Expand Up @@ -459,4 +459,10 @@ public static Path getPathInProperty(String prop, String subPath) {
File file = subPath == null ? new File(path) : new File(path, subPath);
return file.toPath().toAbsolutePath();
}

public static boolean isAssertionEnabled() {
boolean enabled = false;
assert enabled = true;
return enabled;
}
}
Loading