RFR: 7903696: JMH: Add xctrace-based perfasm profiler for macOS [v3]
Aleksey Shipilev
shade at openjdk.org
Fri Apr 19 18:03:09 UTC 2024
On Sun, 7 Apr 2024 18:22:34 GMT, Filipp Zhinkin <fzhinkin at openjdk.org> wrote:
>> Currently, the only perfasm profiler available on macOS is dtraceasm.
>> While it serves its purposes well, there are a few shortcomings: dtrace requires superuser privileges and it can only sample by timer interrupts.
>>
>> Xcode comes with a performance-analysis tool called Instruments and it has a command-line tool, called xctrace.
>> xctrace allows profiling an app using both timer interrupts and PMI, and it does not require superuser privileges.
>>
>> This PR brings JMH a profiler that uses xctrace on macOS.
>>
>> ~~There are two profilers:~~
>> ~~- XCTraceAsmProfiler, a perfasm profiler based on xctrace that works fine out of the box;~~
>> ~~- XCTraceNormProfiler, a perfnorm profiler that requires mandatory parameter, that has to be setup using Instruments UI.~~
>>
>> ~~The latter is added as a PoC and could be wiped out of this PR.~~
>>
>> Unfortunately, `xctrace` exports data in XML format, thus most of the code is responsible for XML parsing.
>
> Filipp Zhinkin has updated the pull request incrementally with three additional commits since the last revision:
>
> - 7903696: Removed an option unsupported by older xctrace version
> - 7903696: Support legacy backtrace format
> - 7903696: Detect xctrace using xcode-select
This is an impressive chunk of work, thank you!
It seems to be working on my M1 quite well. I need to try more things with it.
I have some stylistic comments.
jmh-core/src/main/java/org/openjdk/jmh/profile/XCTraceAsmProfiler.java line 86:
> 84:
> 85: private long recordStartMs = 0;
> 86: private long forkStartTimeMs = 0;
No need for `= 0` initialization here, these are default values anyway.
jmh-core/src/main/java/org/openjdk/jmh/profile/XCTraceAsmProfiler.java line 109:
> 107: .ofType(String.class)
> 108: .defaultsTo("Time Profiler");
> 109: correctOpt = parser.accepts("fixStartTime", "Fix the start time by the time it took to launch.")
Newline between these two, please.
jmh-core/src/main/java/org/openjdk/jmh/profile/XCTraceAsmProfiler.java line 157:
> 155: return super.afterTrial(br, pid, stdOut, stdErr);
> 156: } finally {
> 157: XCTraceSupport.removeDirectory(temporaryDirectory);
Do you really need `finally` here? Can we just record the result from super and then do `removeDirectory`?
jmh-core/src/main/java/org/openjdk/jmh/profile/XCTraceTableOfContentsHandler.java line 68:
> 66: } else if (schema.equals(ProfilingTableType.COUNTERS_PROFILE.tableName)) {
> 67: parseCountersProfile(attributes);
> 68: }
Optional: You can use switch over Strings here?
jmh-core/src/main/java/org/openjdk/jmh/profile/XCTraceTableProfileHandler.java line 70:
> 68: private final Consumer<XCTraceSample> callback;
> 69:
> 70: private XCTraceSample currentSample = null;
No need for `null` initialization.
jmh-core/src/main/java/org/openjdk/jmh/profile/XCTraceTableProfileHandler.java line 93:
> 91: private static long parseAddress(Attributes attributes) {
> 92: String val = attributes.getValue(XCTraceTableHandler.ADDRESS);
> 93: if (!val.startsWith("0x")) throw new IllegalStateException("Unexpected address format: " + val);
Braces and new line, please.
jmh-core/src/main/java/org/openjdk/jmh/profile/XCTraceTableProfileHandler.java line 288:
> 286:
> 287: private static abstract class TraceElement {
> 288: public final long id;
Here and later in `TraceElement` subclasses. For extra sanity, can you turn these fields `private` and expose proper (immutable) getters for them?
jmh-core/src/main/java/org/openjdk/jmh/profile/XCTraceTableProfileHandler.java line 309:
> 307:
> 308: private static final class LongHolder extends TraceElement {
> 309: public long value = 0;
Style: no need for inits.
-------------
PR Review: https://git.openjdk.org/jmh/pull/130#pullrequestreview-2010794311
PR Review Comment: https://git.openjdk.org/jmh/pull/130#discussion_r1571994451
PR Review Comment: https://git.openjdk.org/jmh/pull/130#discussion_r1571995093
PR Review Comment: https://git.openjdk.org/jmh/pull/130#discussion_r1572685549
PR Review Comment: https://git.openjdk.org/jmh/pull/130#discussion_r1572702103
PR Review Comment: https://git.openjdk.org/jmh/pull/130#discussion_r1572702919
PR Review Comment: https://git.openjdk.org/jmh/pull/130#discussion_r1572703334
PR Review Comment: https://git.openjdk.org/jmh/pull/130#discussion_r1572707098
PR Review Comment: https://git.openjdk.org/jmh/pull/130#discussion_r1572707639
More information about the jmh-dev
mailing list