1
1
/*
2
- * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
2
+ * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved.
3
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
4
*
5
5
* This code is free software; you can redistribute it and/or modify it
50
50
public class ProfilerCLITest {
51
51
52
52
public static final String SAMPLING_HISTOGRAM_REGEX = "Sampling Histogram. Recorded [0-9]* samples with period [0-9]*ms. Missed [0-9]* samples." ;
53
+ public static final String SAMPLING_CALLTREE_REGEX = "Sampling Call Tree. Recorded [0-9]* samples with period [0-9]*ms. Missed [0-9]* samples." ;
53
54
public static final int EXEC_COUNT = 10 ;
54
- public static final String NAME_REGEX = " [a-z]* +" ;
55
+ public static final int LOOP_COUNT = 10 ;
56
+ public static final String NAME_REGEX = " +[a-z]* +" ;
55
57
public static final String SEPARATOR_REGEX = "\\ |" ;
56
58
public static final String TIME_REGEX = " *[0-9]*ms +[0-9]*\\ .[0-9]\\ % " ;
57
59
public static final String PERCENT_REGEX = " *[0-9]*\\ .[0-9]\\ % " ;
@@ -66,6 +68,58 @@ protected Source makeSource(String s) {
66
68
return Source .newBuilder (InstrumentationTestLanguage .ID , s , "test" ).buildLiteral ();
67
69
}
68
70
71
+ @ Test
72
+ public void testCallTreeWithTiers () {
73
+ Assume .assumeFalse (checkRuntime ());
74
+ HashMap <String , String > options = new HashMap <>();
75
+ options .put ("cpusampler" , "true" );
76
+ options .put ("cpusampler.Output" , "calltree" );
77
+ options .put ("cpusampler.ShowTiers" , "true" );
78
+ options .put ("engine.FirstTierCompilationThreshold" , Integer .toString (5 * LOOP_COUNT ));
79
+ options .put ("engine.LastTierCompilationThreshold" , Integer .toString (7 * LOOP_COUNT ));
80
+ options .put ("engine.BackgroundCompilation" , "false" );
81
+ String [] output = runSampler (options );
82
+ // @formatter:off
83
+ // OUTPUT IS:
84
+ // ----------------------------------------------------------------------------------------------------------------------------------------------------
85
+ // Sampling Call Tree. Recorded 120 samples with period 10ms. Missed 6 samples.
86
+ Assert .assertTrue (output [1 ].matches (SAMPLING_CALLTREE_REGEX ));
87
+ // Self Time: Time spent on the top of the stack.
88
+ Assert .assertEquals (SELF_TIME , output [2 ]);
89
+ // Total Time: Time spent somewhere on the stack.
90
+ Assert .assertEquals (TOTAL_TIME , output [3 ]);
91
+ // T0: Percent of time spent in interpreter.
92
+ Assert .assertEquals (INTERPRETER , output [4 ]);
93
+ // T1: Percent of time spent in code compiled by tier 1 compiler.
94
+ Assert .assertEquals (T1 , output [5 ]);
95
+ // T2: Percent of time spent in code compiled by tier 2 compiler.
96
+ Assert .assertEquals (T2 , output [6 ]);
97
+ // ----------------------------------------------------------------------------------------------------------------------------------------------------
98
+ // Name || Total Time | T0 | T1 | T2 || Self Time | T0 | T1 | T2 || Location
99
+ // ----------------------------------------------------------------------------------------------------------------------------------------------------
100
+ Assert .assertEquals (" Name || Total Time | T0 | T1 | T2 || Self Time | T0 | T1 | T2 || Location " , output [8 ]);
101
+ // || 1200ms 100.0% | 100.0% | 0.0% | 0.0% || 0ms 0.0% | 0.0% | 0.0% | 0.0% || test~1:0-161
102
+ // baz || 1080ms 90.0% | 72.2% | 27.8% | 0.0% || 0ms 0.0% | 0.0% | 0.0% | 0.0% || test~1:98-139
103
+ String lineRegex = NAME_REGEX +
104
+ SEPARATOR_REGEX + SEPARATOR_REGEX +
105
+ TIME_REGEX + SEPARATOR_REGEX + PERCENT_REGEX + SEPARATOR_REGEX + PERCENT_REGEX + SEPARATOR_REGEX + PERCENT_REGEX +
106
+ SEPARATOR_REGEX + SEPARATOR_REGEX +
107
+ TIME_REGEX + SEPARATOR_REGEX + PERCENT_REGEX + SEPARATOR_REGEX + PERCENT_REGEX + SEPARATOR_REGEX + PERCENT_REGEX +
108
+ SEPARATOR_REGEX + SEPARATOR_REGEX +
109
+ LOCATION_REGEX ;
110
+ Assert .assertTrue (output [10 ].matches (lineRegex ));
111
+ Assert .assertTrue (output [11 ].matches (lineRegex ));
112
+ // bar || 1080ms 90.0% | 13.0% | 50.9% | 36.1% || 0ms 0.0% | 0.0% | 0.0% | 0.0% || test~1:43-84
113
+ Assert .assertTrue (output [12 ].matches (lineRegex ));
114
+ // foo || 1080ms 90.0% | 3.7% | 58.3% | 38.0% || 1080ms 90.0% | 3.7% | 58.3% | 38.0% || test~1:16-29
115
+ Assert .assertTrue (output [13 ].matches (lineRegex ));
116
+ // bar || 120ms 10.0% | 8.3% | 58.3% | 33.3% || 0ms 0.0% | 0.0% | 0.0% | 0.0% || test~1:43-84
117
+ Assert .assertTrue (output [14 ].matches (lineRegex ));
118
+ // foo || 120ms 10.0% | 0.0% | 58.3% | 41.7% || 120ms 10.0% | 0.0% | 58.3% | 41.7% || test~1:16-29
119
+ Assert .assertTrue (output [15 ].matches (lineRegex ));
120
+ // @formatter:on
121
+ }
122
+
69
123
@ Test
70
124
public void testDefaultSampleHistogram () {
71
125
Assume .assumeTrue (checkRuntime ());
@@ -196,8 +250,8 @@ private String[] runSamplerMultithreaded(Map<String, String> options) {
196
250
try (Context context = Context .newBuilder ().in (System .in ).out (out ).err (err ).options (options ).build ()) {
197
251
context .eval (makeSource ("ROOT(" +
198
252
"DEFINE(foo,ROOT(SLEEP(1)))," +
199
- "DEFINE(bar,ROOT(BLOCK(STATEMENT,LOOP(10 , CALL(foo)))))," +
200
- "DEFINE(baz,ROOT(BLOCK(STATEMENT,LOOP(10 , CALL(bar)))))," +
253
+ "DEFINE(bar,ROOT(BLOCK(STATEMENT,LOOP(" + LOOP_COUNT + " , CALL(foo)))))," +
254
+ "DEFINE(baz,ROOT(BLOCK(STATEMENT,LOOP(" + LOOP_COUNT + " , CALL(bar)))))," +
201
255
")" ));
202
256
Runnable evalSource1 = new Runnable () {
203
257
@ Override
@@ -241,8 +295,8 @@ private String[] runSampler(Map<String, String> options) {
241
295
try (Context context = Context .newBuilder ().in (System .in ).out (out ).err (err ).options (options ).build ()) {
242
296
Source source = makeSource ("ROOT(" +
243
297
"DEFINE(foo,ROOT(SLEEP(1)))," +
244
- "DEFINE(bar,ROOT(BLOCK(STATEMENT,LOOP(10 , CALL(foo)))))," +
245
- "DEFINE(baz,ROOT(BLOCK(STATEMENT,LOOP(10 , CALL(bar)))))," +
298
+ "DEFINE(bar,ROOT(BLOCK(STATEMENT,LOOP(" + LOOP_COUNT + " , CALL(foo)))))," +
299
+ "DEFINE(baz,ROOT(BLOCK(STATEMENT,LOOP(" + LOOP_COUNT + " , CALL(bar)))))," +
246
300
"CALL(baz),CALL(bar)" +
247
301
")" );
248
302
for (int i = 0 ; i < EXEC_COUNT ; i ++) {
@@ -350,8 +404,8 @@ public void testSamplerJson() {
350
404
Context context = Context .newBuilder ().in (System .in ).out (out ).err (err ).option ("cpusampler" , "true" ).option ("cpusampler.Output" , "json" ).build ();
351
405
Source defaultSourceForSampling = makeSource ("ROOT(" +
352
406
"DEFINE(foo,ROOT(SLEEP(1)))," +
353
- "DEFINE(bar,ROOT(BLOCK(STATEMENT,LOOP(10 , CALL(foo)))))," +
354
- "DEFINE(baz,ROOT(BLOCK(STATEMENT,LOOP(10 , CALL(bar)))))," +
407
+ "DEFINE(bar,ROOT(BLOCK(STATEMENT,LOOP(" + LOOP_COUNT + " , CALL(foo)))))," +
408
+ "DEFINE(baz,ROOT(BLOCK(STATEMENT,LOOP(" + LOOP_COUNT + " , CALL(bar)))))," +
355
409
"CALL(baz),CALL(bar)" +
356
410
")" );
357
411
for (int i = 0 ; i < 10 ; i ++) {
0 commit comments