Skip to content

Commit 0d17fa4

Browse files
authored
feat: add support for jdk.ObjectAllocationSample (#263)
1 parent bf5f2c3 commit 0d17fa4

File tree

14 files changed

+185
-62
lines changed

14 files changed

+185
-62
lines changed

analysis/jfr/src/main/java/org/eclipse/jifa/jfr/JFRAnalyzerImpl.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -396,9 +396,10 @@ private void parseEventItem(IItem item) {
396396

397397
synchronized (this.context.getEvents()) {
398398
this.context.addEvent(event);
399-
if (event.getSettingFor() != null) {
400-
RecordedEvent.SettingFor sf = event.getSettingFor();
401-
this.context.putEventTypeId(sf.getEventType(), sf.getEventId());
399+
if (event.getActiveSetting() != null) {
400+
RecordedEvent.ActiveSetting activeSetting = event.getActiveSetting();
401+
this.context.putEventTypeId(activeSetting.eventType(), activeSetting.eventId());
402+
this.context.putActiveSetting(activeSetting, event);
402403
}
403404
}
404405
}

analysis/jfr/src/main/java/org/eclipse/jifa/jfr/common/EventConstant.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ public abstract class EventConstant {
3131
public static String NATIVE_EXECUTION_SAMPLE = "jdk.NativeMethodSample";
3232
public static String EXECUTE_VM_OPERATION = "jdk.ExecuteVMOperation";
3333

34-
public static String OBJECT_ALLOCATION_SAMPLE = "jdk.ObjectAllocationSample"; // TODO
34+
public static String OBJECT_ALLOCATION_SAMPLE = "jdk.ObjectAllocationSample";
3535
public static String OBJECT_ALLOCATION_IN_NEW_TLAB = "jdk.ObjectAllocationInNewTLAB";
3636
public static String OBJECT_ALLOCATION_OUTSIDE_TLAB = "jdk.ObjectAllocationOutsideTLAB";
3737

analysis/jfr/src/main/java/org/eclipse/jifa/jfr/extractor/AllocatedMemoryExtractor.java

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -33,35 +33,37 @@ public AllocatedMemoryExtractor(JFRAnalysisContext context) {
3333

3434
@Override
3535
void visitObjectAllocationInNewTLAB(RecordedEvent event) {
36-
RecordedStackTrace stackTrace = event.getStackTrace();
37-
if (stackTrace == null) {
36+
if (this.useObjectAllocationSample) {
3837
return;
3938
}
39+
this.visitTLABEvent(event, "tlabSize");
40+
}
4041

41-
AllocationsExtractor.AllocTaskData allocThreadData = getThreadData(event.getThread());
42-
if (allocThreadData.getSamples() == null) {
43-
allocThreadData.setSamples(new HashMap<>());
42+
@Override
43+
void visitObjectAllocationOutsideTLAB(RecordedEvent event) {
44+
if (this.useObjectAllocationSample) {
45+
return;
4446
}
45-
46-
long eventTotal = event.getLong("tlabSize");
47-
48-
allocThreadData.getSamples().compute(stackTrace, (k, temp) -> temp == null ? eventTotal : temp + eventTotal);
49-
allocThreadData.allocatedMemory += eventTotal;
47+
this.visitTLABEvent(event, "allocationSize");
5048
}
5149

5250
@Override
53-
void visitObjectAllocationOutsideTLAB(RecordedEvent event) {
51+
void visitObjectAllocationSample(RecordedEvent event) {
52+
this.visitTLABEvent(event, "weight");
53+
}
54+
55+
void visitTLABEvent(RecordedEvent event, String fieldName) {
5456
RecordedStackTrace stackTrace = event.getStackTrace();
5557
if (stackTrace == null) {
56-
return;
58+
stackTrace = StackTraceUtil.DUMMY_STACK_TRACE;
5759
}
5860

59-
AllocTaskData allocThreadData = getThreadData(event.getThread());
61+
AllocationsExtractor.AllocTaskData allocThreadData = getThreadData(event.getThread());
6062
if (allocThreadData.getSamples() == null) {
6163
allocThreadData.setSamples(new HashMap<>());
6264
}
6365

64-
long eventTotal = event.getLong("allocationSize");
66+
long eventTotal = event.getLong(fieldName);
6567

6668
allocThreadData.getSamples().compute(stackTrace, (k, temp) -> temp == null ? eventTotal : temp + eventTotal);
6769
allocThreadData.allocatedMemory += eventTotal;

analysis/jfr/src/main/java/org/eclipse/jifa/jfr/extractor/AllocationsExtractor.java

Lines changed: 31 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,16 @@
2626
import java.util.*;
2727
import java.util.stream.Collectors;
2828

29+
import static org.eclipse.jifa.jfr.common.EventConstant.OBJECT_ALLOCATION_SAMPLE;
30+
2931
public class AllocationsExtractor extends Extractor {
32+
protected boolean useObjectAllocationSample;
3033

31-
protected static final List<String> INTERESTED = Collections.unmodifiableList(new ArrayList<String>() {
34+
protected static final List<String> INTERESTED = Collections.unmodifiableList(new ArrayList<>() {
3235
{
3336
add(EventConstant.OBJECT_ALLOCATION_IN_NEW_TLAB);
3437
add(EventConstant.OBJECT_ALLOCATION_OUTSIDE_TLAB);
38+
add(OBJECT_ALLOCATION_SAMPLE);
3539
}
3640
});
3741

@@ -49,6 +53,11 @@ protected static class AllocTaskData extends TaskData {
4953

5054
public AllocationsExtractor(JFRAnalysisContext context) {
5155
super(context, INTERESTED);
56+
try {
57+
this.useObjectAllocationSample = this.context.getActiveSettingBool(OBJECT_ALLOCATION_SAMPLE, "enabled");
58+
} catch (Exception e) {
59+
this.useObjectAllocationSample = false;
60+
}
5261
}
5362

5463
AllocTaskData getThreadData(RecordedThread thread) {
@@ -57,9 +66,29 @@ AllocTaskData getThreadData(RecordedThread thread) {
5766

5867
@Override
5968
void visitObjectAllocationInNewTLAB(RecordedEvent event) {
69+
if (useObjectAllocationSample) {
70+
return;
71+
}
72+
visitEvent(event);
73+
}
74+
75+
@Override
76+
void visitObjectAllocationOutsideTLAB(RecordedEvent event) {
77+
if (useObjectAllocationSample) {
78+
return;
79+
}
80+
this.visitEvent(event);
81+
}
82+
83+
@Override
84+
void visitObjectAllocationSample(RecordedEvent event) {
85+
this.visitEvent(event);
86+
}
87+
88+
void visitEvent(RecordedEvent event) {
6089
RecordedStackTrace stackTrace = event.getStackTrace();
6190
if (stackTrace == null) {
62-
return;
91+
stackTrace = StackTraceUtil.DUMMY_STACK_TRACE;
6392
}
6493

6594
AllocTaskData allocThreadData = getThreadData(event.getThread());
@@ -71,11 +100,6 @@ void visitObjectAllocationInNewTLAB(RecordedEvent event) {
71100
allocThreadData.allocations += 1;
72101
}
73102

74-
@Override
75-
void visitObjectAllocationOutsideTLAB(RecordedEvent event) {
76-
this.visitObjectAllocationInNewTLAB(event);
77-
}
78-
79103
private List<TaskAllocations> buildThreadAllocations() {
80104
List<TaskAllocations> taskAllocations = new ArrayList<>();
81105
for (AllocTaskData data : this.data.values()) {

analysis/jfr/src/main/java/org/eclipse/jifa/jfr/extractor/CPUSampleExtractor.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ void visitExecutionSample(RecordedEvent event) {
4242

4343
@Override
4444
void visitActiveSetting(RecordedEvent event) {
45-
if (this.context.isExecutionSampleEventTypeId(event.getSettingFor().getEventId())) {
45+
if (this.context.isExecutionSampleEventTypeId(event.getActiveSetting().eventId())) {
4646
if (EventConstant.WALL.equals(event.getString("name"))) {
4747
this.isWallClockEvents = true;
4848
}

analysis/jfr/src/main/java/org/eclipse/jifa/jfr/extractor/CPUTimeExtractor.java

Lines changed: 5 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ private static class CpuTaskData extends TaskData {
7979

8080
private boolean isWallClockEvents = false;
8181

82-
private static final RecordedStackTrace DUMMY_STACK_TRACE = newDummyStackTrace("", "", "NO Frame");
82+
8383
private static final RecordedThread DUMMY_THREAD = new RecordedThread("Dummy Thread", -1L, -1L);
8484
private static final RecordedThread GC_THREAD = new RecordedThread("GC Thread", -10L, -10L);
8585

@@ -126,7 +126,7 @@ void visitGarbageCollection(RecordedEvent event) {
126126

127127
@Override
128128
void visitActiveSetting(RecordedEvent event) {
129-
if (event.getSettingFor().getEventId() == threadCPULoadEventId
129+
if (event.getActiveSetting().eventId() == threadCPULoadEventId
130130
&& EventConstant.PERIOD.equals(event.getString("name"))) {
131131
updatePeriod(event.getValue("value"));
132132
}
@@ -135,7 +135,7 @@ void visitActiveSetting(RecordedEvent event) {
135135
this.isWallClockEvents = true;
136136
}
137137

138-
if (this.context.isExecutionSampleEventTypeId(event.getSettingFor().getEventId())) {
138+
if (this.context.isExecutionSampleEventTypeId(event.getActiveSetting().eventId())) {
139139
if (EventConstant.WALL.equals(event.getString("name"))) {
140140
this.isWallClockEvents = true;
141141
} else if (EventConstant.INTERVAL.equals(event.getString("name"))) {
@@ -198,7 +198,7 @@ void visitThreadCPULoad(RecordedEvent event) {
198198
void visitExecutionSample(RecordedEvent event) {
199199
RecordedStackTrace stackTrace = event.getStackTrace();
200200
if (stackTrace == null) {
201-
stackTrace = DUMMY_STACK_TRACE;
201+
stackTrace = StackTraceUtil.DUMMY_STACK_TRACE;
202202
}
203203

204204
RecordedThread thread = event.getThread("eventThread");
@@ -269,7 +269,7 @@ private List<TaskCPUTime> buildThreadCPUTime() {
269269
gc.setTask(context.getThread(GC_THREAD));
270270
gc.setUser(gcTime);
271271
Map<StackTrace, Long> gcSamples = new HashMap<>();
272-
gcSamples.put(StackTraceUtil.build(newDummyStackTrace("", "JVM", "GC"), context.getSymbols()), 1L);
272+
gcSamples.put(StackTraceUtil.build(StackTraceUtil.newDummyStackTrace("", "JVM", "GC"), context.getSymbols()), 1L);
273273
gc.setSamples(gcSamples);
274274
threadCPUTimes.add(gc);
275275
}
@@ -299,22 +299,6 @@ public void fillResult(AnalysisResult result) {
299299
result.setCpuTime(cpuResult);
300300
}
301301

302-
private static RecordedStackTrace newDummyStackTrace(String packageName, String className, String methodName) {
303-
RecordedStackTrace st = new RecordedStackTrace();
304-
List<RecordedFrame> list = new ArrayList<>();
305-
RecordedFrame f = new RecordedFrame();
306-
RecordedMethod m = new RecordedMethod();
307-
RecordedClass c = new RecordedClass();
308-
c.setPackageName(packageName);
309-
c.setName(className);
310-
m.setType(c);
311-
f.setMethod(m);
312-
m.setName(methodName);
313-
list.add(f);
314-
st.setFrames(list);
315-
return st;
316-
}
317-
318302
private static long detectAsyncProfilerInterval() {
319303
long interval = 0;
320304
String intervalStr = System.getProperty("asyncProfilerCpuIntervalMs");

analysis/jfr/src/main/java/org/eclipse/jifa/jfr/extractor/EventVisitor.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,10 @@ void visitObjectAllocationOutsideTLAB(RecordedEvent event) {
7171
throw new UnsupportedOperationException();
7272
}
7373

74+
void visitObjectAllocationSample(RecordedEvent event) {
75+
throw new UnsupportedOperationException();
76+
}
77+
7478
void visitFileRead(RecordedEvent event) {
7579
throw new UnsupportedOperationException();
7680
}

analysis/jfr/src/main/java/org/eclipse/jifa/jfr/extractor/Extractor.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ public abstract class Extractor extends EventVisitor {
3838
put(EventConstant.EXECUTE_VM_OPERATION, EventVisitor::visitExecuteVMOperation);
3939
put(EventConstant.OBJECT_ALLOCATION_IN_NEW_TLAB, EventVisitor::visitObjectAllocationInNewTLAB);
4040
put(EventConstant.OBJECT_ALLOCATION_OUTSIDE_TLAB, EventVisitor::visitObjectAllocationOutsideTLAB);
41+
put(EventConstant.OBJECT_ALLOCATION_SAMPLE, EventVisitor::visitObjectAllocationSample);
4142

4243
put(EventConstant.FILE_FORCE, EventVisitor::visitFileForce);
4344
put(EventConstant.FILE_READ, EventVisitor::visitFileRead);

analysis/jfr/src/main/java/org/eclipse/jifa/jfr/extractor/JFRAnalysisContext.java

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,11 @@
2323

2424
import java.util.*;
2525

26+
import static org.eclipse.jifa.jfr.common.EventConstant.OBJECT_ALLOCATION_SAMPLE;
27+
2628
public class JFRAnalysisContext {
2729
private final Map<String, Long> eventTypeIds = new HashMap<>();
30+
private final Map<RecordedEvent.ActiveSetting, String> activeSettings = new HashMap<>();
2831
private final Map<Long, JavaThread> threads = new HashMap<>();
2932
private final Map<String, Long> threadNameMap = new HashMap<>();
3033
@Getter
@@ -51,13 +54,26 @@ public synchronized void putEventTypeId(String key, Long id) {
5154
}
5255
}
5356

57+
public synchronized void putActiveSetting(RecordedEvent.ActiveSetting activeSetting, RecordedEvent event) {
58+
this.activeSettings.put(activeSetting, event.getString("value"));
59+
}
60+
61+
public synchronized boolean getActiveSettingBool(String eventName, String settingName) {
62+
Long eventId = this.getEventTypeId(OBJECT_ALLOCATION_SAMPLE);
63+
RecordedEvent.ActiveSetting setting = new RecordedEvent.ActiveSetting(eventName, eventId, settingName);
64+
String v = this.activeSettings.get(setting);
65+
if (v != null) {
66+
return Boolean.parseBoolean(v);
67+
}
68+
throw new RuntimeException("should not reach here");
69+
}
70+
5471
public synchronized boolean isExecutionSampleEventTypeId(long id) {
5572
return executionSampleEventTypeIds.contains(id);
5673
}
5774

5875
public synchronized JavaThread getThread(RecordedThread thread) {
5976
return threads.computeIfAbsent(thread.getJavaThreadId(), id -> {
60-
6177
JavaThread javaThread = new JavaThread();
6278
javaThread.setId(id);
6379
javaThread.setJavaId(thread.getJavaThreadId());

analysis/jfr/src/main/java/org/eclipse/jifa/jfr/extractor/WallClockExtractor.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ void visitActiveSetting(RecordedEvent event) {
8585
this.isWallClockEvents = true;
8686
}
8787

88-
if (event.getSettingFor().getEventId() == methodSampleEventId) {
88+
if (event.getActiveSetting().eventId() == methodSampleEventId) {
8989
if (EventConstant.WALL.equals(event.getString("name"))) {
9090
this.isWallClockEvents = true;
9191
this.interval = Long.parseLong(event.getString("value")) * 1000 * 1000;

0 commit comments

Comments
 (0)