Skip to content

Commit 7c800e6

Browse files
committedOct 29, 2024
8343026: JFR: Index into fields in the topFrame
Reviewed-by: mgronlun
1 parent d8b3685 commit 7c800e6

File tree

4 files changed

+94
-87
lines changed

4 files changed

+94
-87
lines changed
 

‎src/jdk.jfr/share/classes/jdk/jfr/internal/Type.java

+3-7
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
import jdk.jfr.Event;
3939
import jdk.jfr.SettingControl;
4040
import jdk.jfr.ValueDescriptor;
41+
import jdk.jfr.internal.util.Utils;
4142

4243
/**
4344
* Internal data structure that describes a type,
@@ -185,14 +186,9 @@ public ValueDescriptor getField(String name) {
185186
Type type = PrivateAccess.getInstance().getType(subField);
186187
return type.getField(post);
187188
}
188-
} else {
189-
for (ValueDescriptor v : getFields()) {
190-
if (name.equals(v.getName())) {
191-
return v;
192-
}
193-
}
189+
return null;
194190
}
195-
return null;
191+
return Utils.findField(getFields(), name);
196192
}
197193

198194
public List<ValueDescriptor> getFields() {

‎src/jdk.jfr/share/classes/jdk/jfr/internal/query/FieldBuilder.java

+79-78
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -49,6 +49,9 @@
4949
import jdk.jfr.consumer.RecordedEvent;
5050
import jdk.jfr.consumer.RecordedFrame;
5151
import jdk.jfr.consumer.RecordedStackTrace;
52+
import jdk.jfr.internal.PrivateAccess;
53+
import jdk.jfr.internal.Type;
54+
import jdk.jfr.internal.util.Utils;
5255

5356
/**
5457
* This is a helper class to QueryResolver. It handles the creation of fields
@@ -60,9 +63,9 @@
6063
final class FieldBuilder {
6164
private static final Set<String> KNOWN_TYPES = createKnownTypes();
6265
private final List<EventType> eventTypes;
63-
private final ValueDescriptor descriptor;
6466
private final Field field;
6567
private final String fieldName;
68+
private ValueDescriptor descriptor;
6669

6770
public FieldBuilder(List<EventType> eventTypes, FilteredType type, String fieldName) {
6871
this.eventTypes = eventTypes;
@@ -77,12 +80,15 @@ public List<Field> build() {
7780
return List.of(field);
7881
}
7982

83+
configureAliases();
8084
if (descriptor != null) {
8185
field.fixedWidth = !descriptor.getTypeName().equals("java.lang.String");
8286
field.dataType = descriptor.getTypeName();
8387
field.label = makeLabel(descriptor, hasDuration());
8488
field.alignLeft = true;
85-
field.valueGetter = valueGetter(field.name);
89+
if (field.valueGetter == null) {
90+
field.valueGetter = valueGetter(field.name);
91+
}
8692

8793
configureNumericTypes();
8894
configureTime();
@@ -113,22 +119,6 @@ private boolean hasDuration() {
113119
}
114120

115121
private boolean configureSyntheticFields() {
116-
if (fieldName.equals("stackTrace.topApplicationFrame")) {
117-
configureTopApplicationFrameField();
118-
return true;
119-
}
120-
if (fieldName.equals("stackTrace.notInit")) {
121-
configureNotInitFrameField();
122-
return true;
123-
}
124-
if (fieldName.equals("stackTrace.topFrame.class")) {
125-
configureTopFrameClassField();
126-
return true;
127-
}
128-
if (fieldName.equals("stackTrace.topFrame")) {
129-
configureTopFrameField();
130-
return true;
131-
}
132122
if (fieldName.equals("id") && field.type.getName().equals("jdk.ActiveSetting")) {
133123
configureEventTypeIdField();
134124
return true;
@@ -144,6 +134,73 @@ private boolean configureSyntheticFields() {
144134
return false;
145135
}
146136

137+
private void configureAliases() {
138+
configureFrame("topFrame", FieldBuilder::topFrame);
139+
configureFrame("topApplicationFrame", FieldBuilder::topApplicationFrame);
140+
configureFrame("topNotInitFrame", FieldBuilder::topNotInitFrame);
141+
}
142+
143+
private void configureFrame(String frameName, Function<RecordedEvent, Object> getter) {
144+
String name = "stackTrace." + frameName;
145+
if (!fieldName.startsWith(name)) {
146+
return;
147+
}
148+
ValueDescriptor stackTrace = Utils.findField(field.type.getFields(), "stackTrace");
149+
if (stackTrace == null) {
150+
return;
151+
}
152+
ValueDescriptor frames = Utils.findField(stackTrace.getFields(), "frames");
153+
if (frames == null) {
154+
return;
155+
}
156+
int length = name.length();
157+
if (fieldName.length() == length) {
158+
descriptor = frames; // Use array descriptor for now
159+
field.valueGetter = getter;
160+
return;
161+
}
162+
String subName = fieldName.substring(length + 1);
163+
Type type = PrivateAccess.getInstance().getType(frames);
164+
ValueDescriptor subField = type.getField(subName);
165+
if (subField != null) {
166+
descriptor = subField;
167+
field.valueGetter = e -> {
168+
if (getter.apply(e) instanceof RecordedFrame frame) {
169+
return frame.getValue(subName);
170+
}
171+
return null;
172+
};
173+
}
174+
}
175+
176+
private static RecordedFrame topFrame(RecordedEvent event) {
177+
return findJavaFrame(event, x -> true);
178+
}
179+
180+
private static RecordedFrame topApplicationFrame(RecordedEvent event) {
181+
return findJavaFrame(event, frame -> {
182+
RecordedClass cl = frame.getMethod().getType();
183+
RecordedClassLoader classLoader = cl.getClassLoader();
184+
return classLoader != null && !"bootstrap".equals(classLoader.getName());
185+
});
186+
}
187+
188+
private static Object topNotInitFrame(RecordedEvent event) {
189+
return findJavaFrame(event, frame -> !frame.getMethod().getName().equals("<init>"));
190+
}
191+
192+
private static RecordedFrame findJavaFrame(RecordedEvent event, Predicate<RecordedFrame> condition) {
193+
RecordedStackTrace st = event.getStackTrace();
194+
if (st != null) {
195+
for (RecordedFrame frame : st.getFrames()) {
196+
if (frame.isJavaFrame() && condition.test(frame)) {
197+
return frame;
198+
}
199+
}
200+
}
201+
return null;
202+
}
203+
147204
private void configureEventTypeIdField() {
148205
Map<Long, String> eventTypes = createEventTypeLookup();
149206
field.alignLeft = true;
@@ -166,65 +223,6 @@ private Map<Long, String> createEventTypeLookup() {
166223
return map;
167224
}
168225

169-
private void configureTopFrameField() {
170-
field.alignLeft = true;
171-
field.label = "Method";
172-
field.dataType = "jdk.types.Method";
173-
field.valueGetter = e -> {
174-
RecordedStackTrace t = e.getStackTrace();
175-
return t != null ? t.getFrames().getFirst() : null;
176-
};
177-
field.lexicalSort = true;
178-
}
179-
180-
private void configureTopFrameClassField() {
181-
field.alignLeft = true;
182-
field.label = "Class";
183-
field.dataType = "java.lang.Class";
184-
field.valueGetter = e -> {
185-
RecordedStackTrace t = e.getStackTrace();
186-
if (t == null) {
187-
return null;
188-
}
189-
return t.getFrames().getFirst().getMethod().getType();
190-
};
191-
field.lexicalSort = true;
192-
}
193-
194-
private void configureCustomFrame(Predicate<RecordedFrame> condition) {
195-
field.alignLeft = true;
196-
field.dataType = "jdk.types.Frame";
197-
field.label = "Method";
198-
field.lexicalSort = true;
199-
field.valueGetter = e -> {
200-
RecordedStackTrace t = e.getStackTrace();
201-
if (t != null) {
202-
for (RecordedFrame f : t.getFrames()) {
203-
if (f.isJavaFrame()) {
204-
if (condition.test(f)) {
205-
return f;
206-
}
207-
}
208-
}
209-
}
210-
return null;
211-
};
212-
}
213-
214-
private void configureNotInitFrameField() {
215-
configureCustomFrame(frame -> {
216-
return !frame.getMethod().getName().equals("<init>");
217-
});
218-
}
219-
220-
private void configureTopApplicationFrameField() {
221-
configureCustomFrame(frame -> {
222-
RecordedClass cl = frame.getMethod().getType();
223-
RecordedClassLoader classLoader = cl.getClassLoader();
224-
return classLoader != null && !"bootstrap".equals(classLoader.getName());
225-
});
226-
}
227-
228226
private void configureEventType(Function<RecordedEvent, Object> retriever) {
229227
field.alignLeft = true;
230228
field.dataType = String.class.getName();
@@ -234,6 +232,9 @@ private void configureEventType(Function<RecordedEvent, Object> retriever) {
234232
}
235233

236234
private static String makeLabel(ValueDescriptor v, boolean hasDuration) {
235+
if (v.getTypeName().equals("jdk.types.StackFrame")) {
236+
return "Method";
237+
}
237238
String label = v.getLabel();
238239
if (label == null) {
239240
return v.getName();

‎src/jdk.jfr/share/classes/jdk/jfr/internal/query/view.ini

+2-2
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@ table = "COLUMN 'Monitor Address', 'Class', 'Threads', 'Max Duration'
186186
label = "Deprecated Methods for Removal"
187187
table = "COLUMN 'Deprecated Method', 'Called from Class'
188188
FORMAT truncate-beginning, cell-height:10000;truncate-beginning
189-
SELECT method AS m, SET(stackTrace.topFrame.class)
189+
SELECT method AS m, SET(stackTrace.topFrame.method.type)
190190
FROM DeprecatedInvocation
191191
WHERE forRemoval = 'true'
192192
GROUP BY m
@@ -266,7 +266,7 @@ table = "COLUMN 'Message', 'Count'
266266
[application.exception-by-site]
267267
label ="Exceptions by Site"
268268
table = "COLUMN 'Method', 'Count'
269-
SELECT stackTrace.notInit AS S, COUNT(startTime) AS C
269+
SELECT stackTrace.topNotInitFrame AS S, COUNT(startTime) AS C
270270
FROM JavaErrorThrow, JavaExceptionThrow GROUP BY S ORDER BY C DESC"
271271

272272
[application.file-reads-by-path]

‎src/jdk.jfr/share/classes/jdk/jfr/internal/util/Utils.java

+10
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
import jdk.jfr.Event;
4949
import jdk.jfr.EventType;
5050
import jdk.jfr.RecordingState;
51+
import jdk.jfr.ValueDescriptor;
5152
import jdk.jfr.internal.LogLevel;
5253
import jdk.jfr.internal.LogTag;
5354
import jdk.jfr.internal.Logger;
@@ -438,4 +439,13 @@ public static long multiplyOverflow(long a, long b, long defaultValue) {
438439
return defaultValue;
439440
}
440441
}
442+
443+
public static ValueDescriptor findField(List<ValueDescriptor> fields, String name) {
444+
for (ValueDescriptor v : fields) {
445+
if (v.getName().equals(name)) {
446+
return v;
447+
}
448+
}
449+
return null;
450+
}
441451
}

0 commit comments

Comments
 (0)
Failed to load comments.