Skip to content

Commit

Permalink
profiling.core: add sampled callgraph from incubator
Browse files Browse the repository at this point in the history
[Added] Sampling callgraph module to profiling.core

Signed-off-by: Arnaud Fiorini <fiorini.arnaud@gmail.com>
  • Loading branch information
arfio committed Mar 26, 2024
1 parent a0c8f83 commit 81c120e
Show file tree
Hide file tree
Showing 8 changed files with 517 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
/*******************************************************************************
* Copyright (c) 2017 École Polytechnique de Montréal
*
* All rights reserved. This program and the accompanying materials are
* made available under the terms of the Eclipse Public License 2.0 which
* accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*******************************************************************************/

package org.eclipse.tracecompass.analysis.profiling.core.tests.callgraph.sampled;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;

import java.util.Collection;
import java.util.Collections;
import java.util.Map;

import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.tracecompass.analysis.profiling.core.base.ICallStackElement;
import org.eclipse.tracecompass.analysis.profiling.core.callgraph.AggregatedCallSite;
import org.eclipse.tracecompass.analysis.profiling.core.callgraph.CallGraph;
import org.eclipse.tracecompass.analysis.profiling.core.callstack2.CallStackElement;
import org.eclipse.tracecompass.analysis.profiling.core.sampled.callgraph.ProfilingCallGraphAnalysisModule;
import org.eclipse.tracecompass.analysis.profiling.core.tests.CallStackTestBase2;
import org.eclipse.tracecompass.analysis.profiling.core.tree.IWeightedTreeGroupDescriptor;
import org.eclipse.tracecompass.internal.analysis.profiling.core.tree.AllGroupDescriptor;
import org.eclipse.tracecompass.tmf.core.event.ITmfEvent;
import org.eclipse.tracecompass.tmf.core.util.Pair;
import org.junit.Test;

/**
* Test profiling data where the input are stack traces from events
*
* @author Geneviève Bastien
*/
public class SampledCallGraphTest {

private static final long @NonNull [] CALLSITE_1 = { 1, 2, 3, 4 };
private static final long @NonNull [] CALLSITE_2 = { 1, 2, 3 };
private static final long @NonNull [] CALLSITE_3 = { 1, 2, 3, 4 };
private static final long @NonNull [] CALLSITE_4 = { 1, 3, 4 };
private static final long @NonNull [] CALLSITE_5 = { 1, 2, 5 };
private static final long @NonNull [] CALLSITE_6 = { 1, 2, 5, 4 };
private static final long @NonNull [] CALLSITE_7 = { 10, 11, 12 };
private static final long @NonNull [] CALLSITE_8 = { 10, 11 };
private static final long @NonNull [] CALLSITE_9 = { 1, 2, 3, 4 };
private static final long @NonNull [] CALLSITE_10 = { 1, 2, 4, 5 };

/**
* A default implementation of the profiling call graph analysis for test
* purposes
*/
private static class TestProfilingAnalysis extends ProfilingCallGraphAnalysisModule {

private final @NonNull ICallStackElement fOneElement;

public TestProfilingAnalysis() {
ICallStackElement element = new CallStackElement("test", AllGroupDescriptor.getInstance());
addRootElement(element);
fOneElement = element;
}

public @NonNull ICallStackElement getElement() {
return fOneElement;
}

@Override
public Collection<IWeightedTreeGroupDescriptor> getGroupDescriptors() {
return Collections.singleton(AllGroupDescriptor.getInstance());
}

@Override
public Map<String, Collection<Object>> getCallStack(@NonNull ITmfEvent event) {
return Collections.emptyMap();
}

@Override
protected @Nullable Pair<@NonNull ICallStackElement, @NonNull AggregatedCallSite> getProfiledStackTrace(@NonNull ITmfEvent event) {
return null;
}

}

/**
* Test a full sampling for one group
*/
@Test
public void testStackTraces() {
TestProfilingAnalysis pg = new TestProfilingAnalysis();
try {
ICallStackElement element = pg.getElement();

CallGraph cg = pg.getCallGraph();
cg.addAggregatedCallSite(element, pg.getCallSite(element, CALLSITE_1, 1));
cg.addAggregatedCallSite(element, pg.getCallSite(element, CALLSITE_2, 2));
cg.addAggregatedCallSite(element, pg.getCallSite(element, CALLSITE_3, 3));
cg.addAggregatedCallSite(element, pg.getCallSite(element, CALLSITE_4, 4));
cg.addAggregatedCallSite(element, pg.getCallSite(element, CALLSITE_5, 5));
cg.addAggregatedCallSite(element, pg.getCallSite(element, CALLSITE_6, 6));
cg.addAggregatedCallSite(element, pg.getCallSite(element, CALLSITE_7, 7));
cg.addAggregatedCallSite(element, pg.getCallSite(element, CALLSITE_8, 8));
cg.addAggregatedCallSite(element, pg.getCallSite(element, CALLSITE_9, 9));
cg.addAggregatedCallSite(element, pg.getCallSite(element, CALLSITE_10, 10));

Collection<AggregatedCallSite> aggregatedData = cg.getCallingContextTree(element);

assertNotNull(aggregatedData);
assertEquals(2, aggregatedData.size());

for (AggregatedCallSite callsite : aggregatedData) {
switch (CallStackTestBase2.getCallSiteSymbol(callsite).resolve(Collections.emptySet())) {
case "0x1": {
assertEquals(8, callsite.getWeight());
assertEquals(2, callsite.getCallees().size());
for (AggregatedCallSite childCallsite : callsite.getCallees()) {
switch (CallStackTestBase2.getCallSiteSymbol(childCallsite).resolve(Collections.emptySet())) {
case "0x2":
assertEquals(7, childCallsite.getWeight());
assertEquals(3, childCallsite.getCallees().size());
break;
case "0x3":
assertEquals(1, childCallsite.getWeight());
assertEquals(1, childCallsite.getCallees().size());
break;
default:
throw new IllegalStateException("Unknown callsite: " + CallStackTestBase2.getCallSiteSymbol(childCallsite));
}
}
}
break;
case "0xa": {
assertEquals(2, callsite.getWeight());
assertEquals(1, callsite.getCallees().size());
AggregatedCallSite childCallsite = callsite.getCallees().iterator().next();
assertEquals(2, childCallsite.getWeight());
assertEquals(1, callsite.getCallees().size());
}
break;
default:
throw new IllegalStateException("Unknown callsite: " + CallStackTestBase2.getCallSiteSymbol(callsite));
}
}
} finally {
pg.dispose();
}

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ Export-Package: org.eclipse.tracecompass.analysis.profiling.core.base;uses:="org
org.eclipse.tracecompass.analysis.profiling.core.callstack2,
org.eclipse.tracecompass.analysis.profiling.core.instrumented,
org.eclipse.tracecompass.analysis.profiling.core.model,
org.eclipse.tracecompass.analysis.profiling.core.sampled.callgraph,
org.eclipse.tracecompass.analysis.profiling.core.tree,
org.eclipse.tracecompass.internal.analysis.profiling.core;x-friends:="org.eclipse.tracecompass.analysis.profiling.core.tests,org.eclipse.tracecompass.analysis.profiling.ui",
org.eclipse.tracecompass.internal.analysis.profiling.core.callgraph;x-friends:="org.eclipse.tracecompass.analysis.profiling.core.tests,org.eclipse.tracecompass.analysis.profiling.ui",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*******************************************************************************
* Copyright (c) 2017 École Polytechnique de Montréal
*
* All rights reserved. This program and the accompanying materials are
* made available under the terms of the Eclipse Public License 2.0 which
* accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*******************************************************************************/

package org.eclipse.tracecompass.analysis.profiling.core.callstack;

import java.util.Collection;
import java.util.Map;

import org.eclipse.tracecompass.tmf.core.event.ITmfEvent;

/**
* An interface that analyses can implement if they can provide a stack of
* called function for a single event.
*
* @author Geneviève Bastien
* @since 2.5
*/
public interface IEventCallStackProvider {

/**
* Get the callstack from an event
*
* @param event
* The event for which to get the stack
* @return The callstack for the event, grouped by some domain, where the
* first element of each collection is the root.
*/
Map<String, Collection<Object>> getCallStack(ITmfEvent event);

}
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
* SPDX-License-Identifier: EPL-2.0
*******************************************************************************/

package org.eclipse.tracecompass.internal.analysis.profiling.core.instrumented;
package org.eclipse.tracecompass.analysis.profiling.core.instrumented;

import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.tracecompass.analysis.profiling.core.base.ICallStackGroupDescriptor;
Expand All @@ -18,6 +18,7 @@
* A basic group descriptor implementation.
*
* @author Geneviève Bastien
* @since 2.5
*/
public class CallStackGroupDescriptor implements ICallStackGroupDescriptor {

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*******************************************************************************
* Copyright (c) 2017 École Polytechnique de Montréal
*
* All rights reserved. This program and the accompanying materials are
* made available under the terms of the Eclipse Public License 2.0 which
* accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*******************************************************************************/

package org.eclipse.tracecompass.analysis.profiling.core.sampled.callgraph;

import org.eclipse.tracecompass.analysis.profiling.core.base.ICallStackSymbol;
import org.eclipse.tracecompass.analysis.profiling.core.callgraph.AggregatedCallSite;

/**
* A data structure aggregating data from the callstack for sampled call stack
* data. It counts the number of times each frame pointer was present in a given
* stack
*
* @author Geneviève Bastien
* @since 2.5
*/
public class AggregatedStackTraces extends AggregatedCallSite {

/**
* Constructor
*
* @param symbol
* The symbol for this frame pointer
*/
public AggregatedStackTraces(ICallStackSymbol symbol) {
super(symbol, 1);
}

private AggregatedStackTraces(AggregatedStackTraces toCopy) {
super(toCopy);
}

@Override
public AggregatedStackTraces copyOf() {
return new AggregatedStackTraces(this);
}

}
Loading

0 comments on commit 81c120e

Please sign in to comment.