Skip to content

Commit 81c120e

Browse files
committed
profiling.core: add sampled callgraph from incubator
[Added] Sampling callgraph module to profiling.core Signed-off-by: Arnaud Fiorini <fiorini.arnaud@gmail.com>
1 parent a0c8f83 commit 81c120e

8 files changed

Lines changed: 517 additions & 1 deletion

File tree

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2017 École Polytechnique de Montréal
3+
*
4+
* All rights reserved. This program and the accompanying materials are
5+
* made available under the terms of the Eclipse Public License 2.0 which
6+
* accompanies this distribution, and is available at
7+
* https://www.eclipse.org/legal/epl-2.0/
8+
*
9+
* SPDX-License-Identifier: EPL-2.0
10+
*******************************************************************************/
11+
12+
package org.eclipse.tracecompass.analysis.profiling.core.tests.callgraph.sampled;
13+
14+
import static org.junit.Assert.assertEquals;
15+
import static org.junit.Assert.assertNotNull;
16+
17+
import java.util.Collection;
18+
import java.util.Collections;
19+
import java.util.Map;
20+
21+
import org.eclipse.jdt.annotation.NonNull;
22+
import org.eclipse.jdt.annotation.Nullable;
23+
import org.eclipse.tracecompass.analysis.profiling.core.base.ICallStackElement;
24+
import org.eclipse.tracecompass.analysis.profiling.core.callgraph.AggregatedCallSite;
25+
import org.eclipse.tracecompass.analysis.profiling.core.callgraph.CallGraph;
26+
import org.eclipse.tracecompass.analysis.profiling.core.callstack2.CallStackElement;
27+
import org.eclipse.tracecompass.analysis.profiling.core.sampled.callgraph.ProfilingCallGraphAnalysisModule;
28+
import org.eclipse.tracecompass.analysis.profiling.core.tests.CallStackTestBase2;
29+
import org.eclipse.tracecompass.analysis.profiling.core.tree.IWeightedTreeGroupDescriptor;
30+
import org.eclipse.tracecompass.internal.analysis.profiling.core.tree.AllGroupDescriptor;
31+
import org.eclipse.tracecompass.tmf.core.event.ITmfEvent;
32+
import org.eclipse.tracecompass.tmf.core.util.Pair;
33+
import org.junit.Test;
34+
35+
/**
36+
* Test profiling data where the input are stack traces from events
37+
*
38+
* @author Geneviève Bastien
39+
*/
40+
public class SampledCallGraphTest {
41+
42+
private static final long @NonNull [] CALLSITE_1 = { 1, 2, 3, 4 };
43+
private static final long @NonNull [] CALLSITE_2 = { 1, 2, 3 };
44+
private static final long @NonNull [] CALLSITE_3 = { 1, 2, 3, 4 };
45+
private static final long @NonNull [] CALLSITE_4 = { 1, 3, 4 };
46+
private static final long @NonNull [] CALLSITE_5 = { 1, 2, 5 };
47+
private static final long @NonNull [] CALLSITE_6 = { 1, 2, 5, 4 };
48+
private static final long @NonNull [] CALLSITE_7 = { 10, 11, 12 };
49+
private static final long @NonNull [] CALLSITE_8 = { 10, 11 };
50+
private static final long @NonNull [] CALLSITE_9 = { 1, 2, 3, 4 };
51+
private static final long @NonNull [] CALLSITE_10 = { 1, 2, 4, 5 };
52+
53+
/**
54+
* A default implementation of the profiling call graph analysis for test
55+
* purposes
56+
*/
57+
private static class TestProfilingAnalysis extends ProfilingCallGraphAnalysisModule {
58+
59+
private final @NonNull ICallStackElement fOneElement;
60+
61+
public TestProfilingAnalysis() {
62+
ICallStackElement element = new CallStackElement("test", AllGroupDescriptor.getInstance());
63+
addRootElement(element);
64+
fOneElement = element;
65+
}
66+
67+
public @NonNull ICallStackElement getElement() {
68+
return fOneElement;
69+
}
70+
71+
@Override
72+
public Collection<IWeightedTreeGroupDescriptor> getGroupDescriptors() {
73+
return Collections.singleton(AllGroupDescriptor.getInstance());
74+
}
75+
76+
@Override
77+
public Map<String, Collection<Object>> getCallStack(@NonNull ITmfEvent event) {
78+
return Collections.emptyMap();
79+
}
80+
81+
@Override
82+
protected @Nullable Pair<@NonNull ICallStackElement, @NonNull AggregatedCallSite> getProfiledStackTrace(@NonNull ITmfEvent event) {
83+
return null;
84+
}
85+
86+
}
87+
88+
/**
89+
* Test a full sampling for one group
90+
*/
91+
@Test
92+
public void testStackTraces() {
93+
TestProfilingAnalysis pg = new TestProfilingAnalysis();
94+
try {
95+
ICallStackElement element = pg.getElement();
96+
97+
CallGraph cg = pg.getCallGraph();
98+
cg.addAggregatedCallSite(element, pg.getCallSite(element, CALLSITE_1, 1));
99+
cg.addAggregatedCallSite(element, pg.getCallSite(element, CALLSITE_2, 2));
100+
cg.addAggregatedCallSite(element, pg.getCallSite(element, CALLSITE_3, 3));
101+
cg.addAggregatedCallSite(element, pg.getCallSite(element, CALLSITE_4, 4));
102+
cg.addAggregatedCallSite(element, pg.getCallSite(element, CALLSITE_5, 5));
103+
cg.addAggregatedCallSite(element, pg.getCallSite(element, CALLSITE_6, 6));
104+
cg.addAggregatedCallSite(element, pg.getCallSite(element, CALLSITE_7, 7));
105+
cg.addAggregatedCallSite(element, pg.getCallSite(element, CALLSITE_8, 8));
106+
cg.addAggregatedCallSite(element, pg.getCallSite(element, CALLSITE_9, 9));
107+
cg.addAggregatedCallSite(element, pg.getCallSite(element, CALLSITE_10, 10));
108+
109+
Collection<AggregatedCallSite> aggregatedData = cg.getCallingContextTree(element);
110+
111+
assertNotNull(aggregatedData);
112+
assertEquals(2, aggregatedData.size());
113+
114+
for (AggregatedCallSite callsite : aggregatedData) {
115+
switch (CallStackTestBase2.getCallSiteSymbol(callsite).resolve(Collections.emptySet())) {
116+
case "0x1": {
117+
assertEquals(8, callsite.getWeight());
118+
assertEquals(2, callsite.getCallees().size());
119+
for (AggregatedCallSite childCallsite : callsite.getCallees()) {
120+
switch (CallStackTestBase2.getCallSiteSymbol(childCallsite).resolve(Collections.emptySet())) {
121+
case "0x2":
122+
assertEquals(7, childCallsite.getWeight());
123+
assertEquals(3, childCallsite.getCallees().size());
124+
break;
125+
case "0x3":
126+
assertEquals(1, childCallsite.getWeight());
127+
assertEquals(1, childCallsite.getCallees().size());
128+
break;
129+
default:
130+
throw new IllegalStateException("Unknown callsite: " + CallStackTestBase2.getCallSiteSymbol(childCallsite));
131+
}
132+
}
133+
}
134+
break;
135+
case "0xa": {
136+
assertEquals(2, callsite.getWeight());
137+
assertEquals(1, callsite.getCallees().size());
138+
AggregatedCallSite childCallsite = callsite.getCallees().iterator().next();
139+
assertEquals(2, childCallsite.getWeight());
140+
assertEquals(1, callsite.getCallees().size());
141+
}
142+
break;
143+
default:
144+
throw new IllegalStateException("Unknown callsite: " + CallStackTestBase2.getCallSiteSymbol(callsite));
145+
}
146+
}
147+
} finally {
148+
pg.dispose();
149+
}
150+
151+
}
152+
153+
}

analysis/org.eclipse.tracecompass.analysis.profiling.core/META-INF/MANIFEST.MF

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ Export-Package: org.eclipse.tracecompass.analysis.profiling.core.base;uses:="org
3636
org.eclipse.tracecompass.analysis.profiling.core.callstack2,
3737
org.eclipse.tracecompass.analysis.profiling.core.instrumented,
3838
org.eclipse.tracecompass.analysis.profiling.core.model,
39+
org.eclipse.tracecompass.analysis.profiling.core.sampled.callgraph,
3940
org.eclipse.tracecompass.analysis.profiling.core.tree,
4041
org.eclipse.tracecompass.internal.analysis.profiling.core;x-friends:="org.eclipse.tracecompass.analysis.profiling.core.tests,org.eclipse.tracecompass.analysis.profiling.ui",
4142
org.eclipse.tracecompass.internal.analysis.profiling.core.callgraph;x-friends:="org.eclipse.tracecompass.analysis.profiling.core.tests,org.eclipse.tracecompass.analysis.profiling.ui",
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2017 École Polytechnique de Montréal
3+
*
4+
* All rights reserved. This program and the accompanying materials are
5+
* made available under the terms of the Eclipse Public License 2.0 which
6+
* accompanies this distribution, and is available at
7+
* https://www.eclipse.org/legal/epl-2.0/
8+
*
9+
* SPDX-License-Identifier: EPL-2.0
10+
*******************************************************************************/
11+
12+
package org.eclipse.tracecompass.analysis.profiling.core.callstack;
13+
14+
import java.util.Collection;
15+
import java.util.Map;
16+
17+
import org.eclipse.tracecompass.tmf.core.event.ITmfEvent;
18+
19+
/**
20+
* An interface that analyses can implement if they can provide a stack of
21+
* called function for a single event.
22+
*
23+
* @author Geneviève Bastien
24+
* @since 2.5
25+
*/
26+
public interface IEventCallStackProvider {
27+
28+
/**
29+
* Get the callstack from an event
30+
*
31+
* @param event
32+
* The event for which to get the stack
33+
* @return The callstack for the event, grouped by some domain, where the
34+
* first element of each collection is the root.
35+
*/
36+
Map<String, Collection<Object>> getCallStack(ITmfEvent event);
37+
38+
}

analysis/org.eclipse.tracecompass.analysis.profiling.core/src/org/eclipse/tracecompass/internal/analysis/profiling/core/instrumented/CallStackGroupDescriptor.java renamed to analysis/org.eclipse.tracecompass.analysis.profiling.core/src/org/eclipse/tracecompass/analysis/profiling/core/instrumented/CallStackGroupDescriptor.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
* SPDX-License-Identifier: EPL-2.0
1010
*******************************************************************************/
1111

12-
package org.eclipse.tracecompass.internal.analysis.profiling.core.instrumented;
12+
package org.eclipse.tracecompass.analysis.profiling.core.instrumented;
1313

1414
import org.eclipse.jdt.annotation.Nullable;
1515
import org.eclipse.tracecompass.analysis.profiling.core.base.ICallStackGroupDescriptor;
@@ -18,6 +18,7 @@
1818
* A basic group descriptor implementation.
1919
*
2020
* @author Geneviève Bastien
21+
* @since 2.5
2122
*/
2223
public class CallStackGroupDescriptor implements ICallStackGroupDescriptor {
2324

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2017 École Polytechnique de Montréal
3+
*
4+
* All rights reserved. This program and the accompanying materials are
5+
* made available under the terms of the Eclipse Public License 2.0 which
6+
* accompanies this distribution, and is available at
7+
* https://www.eclipse.org/legal/epl-2.0/
8+
*
9+
* SPDX-License-Identifier: EPL-2.0
10+
*******************************************************************************/
11+
12+
package org.eclipse.tracecompass.analysis.profiling.core.sampled.callgraph;
13+
14+
import org.eclipse.tracecompass.analysis.profiling.core.base.ICallStackSymbol;
15+
import org.eclipse.tracecompass.analysis.profiling.core.callgraph.AggregatedCallSite;
16+
17+
/**
18+
* A data structure aggregating data from the callstack for sampled call stack
19+
* data. It counts the number of times each frame pointer was present in a given
20+
* stack
21+
*
22+
* @author Geneviève Bastien
23+
* @since 2.5
24+
*/
25+
public class AggregatedStackTraces extends AggregatedCallSite {
26+
27+
/**
28+
* Constructor
29+
*
30+
* @param symbol
31+
* The symbol for this frame pointer
32+
*/
33+
public AggregatedStackTraces(ICallStackSymbol symbol) {
34+
super(symbol, 1);
35+
}
36+
37+
private AggregatedStackTraces(AggregatedStackTraces toCopy) {
38+
super(toCopy);
39+
}
40+
41+
@Override
42+
public AggregatedStackTraces copyOf() {
43+
return new AggregatedStackTraces(this);
44+
}
45+
46+
}

0 commit comments

Comments
 (0)