Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
callstack: Bring incubated CallGraph, internal 1st
Bring CallGraph from Incubator for an eventual ICallGraphProvider as next step. Make this CallGraph internal (non-API) only for now, or until proven as API once/if that becomes the case. Bring these other classes/interfaces as minimally required dependencies. Except for .tree which is trivial enough, wait before introducing sub-packages as Incubator's, to not prematurely create some that could be misnamed or contain too few classes/interfaces. CallGraph and its dependencies added herein are tested through upstream classes in Incubator. Thus postpone their test coverage until the latter can be ported in turn. Change-Id: I614575fac6464158f85f0d1a578131f3a4a8014c Signed-off-by: Marco Miller <marco.miller@ericsson.com> Reviewed-on: https://git.eclipse.org/r/c/tracecompass/org.eclipse.tracecompass/+/197758 Tested-by: Trace Compass Bot <tracecompass-bot@eclipse.org> Tested-by: Bernd Hufmann <bernd.hufmann@ericsson.com> Reviewed-by: Bernd Hufmann <bernd.hufmann@ericsson.com>
- Loading branch information
1 parent
9a6d5a0
commit 72a48a5
Showing
17 changed files
with
1,631 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
97 changes: 97 additions & 0 deletions
97
...ore/src/org/eclipse/tracecompass/internal/analysis/callstack/core/AggregatedCallSite.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
/******************************************************************************* | ||
* Copyright (c) 2017-2019 É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.internal.analysis.callstack.core; | ||
|
||
import java.util.ArrayList; | ||
import java.util.Collection; | ||
import java.util.List; | ||
import java.util.Map; | ||
|
||
import org.eclipse.tracecompass.analysis.timing.core.statistics.IStatistics; | ||
import org.eclipse.tracecompass.internal.analysis.callstack.core.tree.WeightedTree; | ||
|
||
import com.google.common.annotations.VisibleForTesting; | ||
import com.google.common.collect.ImmutableMap; | ||
|
||
/** | ||
* Base class for aggregating call site data from either sampled or instrumented | ||
* call stacks. | ||
* | ||
* @author Geneviève Bastien | ||
*/ | ||
public class AggregatedCallSite extends WeightedTree<ICallStackSymbol> { | ||
|
||
/** | ||
* Constructor | ||
* | ||
* @param symbol | ||
* The symbol of the call site. It can eventually be resolved to | ||
* a string using the symbol providers | ||
* @param initialLength | ||
* The initial length of this object | ||
*/ | ||
public AggregatedCallSite(ICallStackSymbol symbol, long initialLength) { | ||
super(symbol, initialLength); | ||
} | ||
|
||
/** | ||
* Copy constructor | ||
* | ||
* @param copy | ||
* The call site to copy | ||
*/ | ||
protected AggregatedCallSite(AggregatedCallSite copy) { | ||
super(copy); | ||
} | ||
|
||
/** | ||
* Return the children as a collection of aggregatedCallSite | ||
* | ||
* @return The children as callees | ||
*/ | ||
@VisibleForTesting | ||
public Collection<AggregatedCallSite> getCallees() { | ||
List<AggregatedCallSite> list = new ArrayList<>(); | ||
for (WeightedTree<ICallStackSymbol> child : getChildren()) { | ||
if (child instanceof AggregatedCallSite) { | ||
list.add((AggregatedCallSite) child); | ||
} | ||
} | ||
return list; | ||
} | ||
|
||
/** | ||
* Make a copy of this callsite, with its statistics. Implementing classes | ||
* should make sure they copy all fields of the callsite, including the | ||
* statistics. | ||
* | ||
* @return A copy of this aggregated call site | ||
*/ | ||
@Override | ||
public AggregatedCallSite copyOf() { | ||
return new AggregatedCallSite(this); | ||
} | ||
|
||
/** | ||
* Get additional statistics for this call site | ||
* | ||
* @return A map of statistics title with statistics | ||
*/ | ||
public Map<String, IStatistics<?>> getStatistics() { | ||
return ImmutableMap.of(); | ||
} | ||
|
||
@Override | ||
public String toString() { | ||
return "CallSite: " + getObject(); //$NON-NLS-1$ | ||
} | ||
} |
110 changes: 110 additions & 0 deletions
110
...llstack.core/src/org/eclipse/tracecompass/internal/analysis/callstack/core/CallGraph.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
/******************************************************************************* | ||
* 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.internal.analysis.callstack.core; | ||
|
||
import java.util.Collection; | ||
import java.util.Collections; | ||
import java.util.HashSet; | ||
import java.util.Set; | ||
|
||
import org.eclipse.tracecompass.internal.analysis.callstack.core.tree.IWeightedTreeSet; | ||
|
||
import com.google.common.collect.HashMultimap; | ||
import com.google.common.collect.ImmutableSet; | ||
import com.google.common.collect.Multimap; | ||
|
||
/** | ||
* Represents a callgraph, ie the aggregation of callsites per elements. | ||
* | ||
* TODO: Have an interface and keep the add* method internal | ||
* | ||
* @author Geneviève Bastien | ||
*/ | ||
public class CallGraph implements IWeightedTreeSet<ICallStackSymbol, ICallStackElement, AggregatedCallSite> { | ||
|
||
/** | ||
* An empty graph that can be returned when there is no other call graph | ||
* available | ||
*/ | ||
public static final CallGraph EMPTY_GRAPH = new CallGraph(); | ||
|
||
private Set<ICallStackElement> fRootElements = new HashSet<>(); | ||
private final Multimap<ICallStackElement, AggregatedCallSite> fCcts = HashMultimap.create(); | ||
|
||
/** | ||
* Constructor | ||
*/ | ||
public CallGraph() { | ||
// Empty | ||
} | ||
|
||
/** | ||
* Gets the calling context tree for an element. | ||
* | ||
* The calling context tree is the callgraph data aggregated by keeping the | ||
* context of each call. | ||
* | ||
* @param element | ||
* The element for which to get the calling context tree | ||
* @return The aggregated data for the first level of the callgraph | ||
*/ | ||
@SuppressWarnings("null") | ||
public Collection<AggregatedCallSite> getCallingContextTree(ICallStackElement element) { | ||
return fCcts.get(element); | ||
} | ||
|
||
/** | ||
* Add an aggregated callsite to a callstack element. | ||
* | ||
* @param dstGroup | ||
* the destination group | ||
* @param callsite | ||
* the callsite to add | ||
*/ | ||
public void addAggregatedCallSite(ICallStackElement dstGroup, AggregatedCallSite callsite) { | ||
// Make sure the root element is present | ||
ICallStackElement root = dstGroup; | ||
ICallStackElement parent = dstGroup.getParentElement(); | ||
while (parent != null) { | ||
root = parent; | ||
parent = parent.getParentElement(); | ||
} | ||
fRootElements.add(root); | ||
// Add the callsite to the appropriate group | ||
Collection<AggregatedCallSite> callsites = fCcts.get(dstGroup); | ||
for (AggregatedCallSite site : callsites) { | ||
if (site.getObject().equals(callsite.getObject())) { | ||
site.merge(callsite); | ||
return; | ||
} | ||
} | ||
fCcts.put(dstGroup, callsite); | ||
} | ||
|
||
/** | ||
* Get the root elements containing the call graph data. | ||
* | ||
* @return The root elements of the call graph | ||
*/ | ||
@Override | ||
public Collection<ICallStackElement> getElements() { | ||
return ImmutableSet.copyOf(fRootElements); | ||
} | ||
|
||
@Override | ||
public Collection<AggregatedCallSite> getTreesFor(Object element) { | ||
if (element instanceof ICallStackElement) { | ||
return getCallingContextTree((ICallStackElement) element); | ||
} | ||
return Collections.emptyList(); | ||
} | ||
} |
102 changes: 102 additions & 0 deletions
102
...core/src/org/eclipse/tracecompass/internal/analysis/callstack/core/ICallStackElement.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
/******************************************************************************* | ||
* 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.internal.analysis.callstack.core; | ||
|
||
import java.util.Collection; | ||
|
||
import org.eclipse.jdt.annotation.Nullable; | ||
import org.eclipse.tracecompass.internal.analysis.callstack.core.tree.ITree; | ||
import org.eclipse.tracecompass.internal.analysis.callstack.core.tree.IWeightedTreeGroupDescriptor; | ||
|
||
/** | ||
* Interface that classes representing a single element in the callstack | ||
* hierarchy must implement. Typically, a {@link ICallStackElement} will be | ||
* associated with a {@link ICallStackGroupDescriptor}. It will have children | ||
* that will correspond to the next group in the hierarchy. | ||
* | ||
* The actual data of the various available analyses containing those elements | ||
* will be available only at the leaf elements. | ||
* | ||
* @author Geneviève Bastien | ||
*/ | ||
public interface ICallStackElement extends ITree { | ||
|
||
/** | ||
* Get the elements at the next level of the callstack hierarchy from this | ||
* element | ||
* | ||
* FIXME: Can this method be completely replaced by | ||
* {@link ITree#getChildren()}? | ||
* | ||
* @return The list of children elements in the hierarchy | ||
*/ | ||
Collection<ICallStackElement> getChildrenElements(); | ||
|
||
/** | ||
* Get the corresponding group descriptor | ||
* | ||
* @return The group descriptor of this element | ||
*/ | ||
IWeightedTreeGroupDescriptor getGroup(); | ||
|
||
/** | ||
* Get the next group descriptor | ||
* | ||
* @return The next group descriptor, or <code>null</code> if this is a leaf | ||
* element | ||
*/ | ||
@Nullable IWeightedTreeGroupDescriptor getNextGroup(); | ||
|
||
/** | ||
* Get the key for symbol resolution at a given time | ||
* | ||
* @param time | ||
* The time at which to get the symbol key | ||
* @return The symbol key at time | ||
*/ | ||
int getSymbolKeyAt(long time); | ||
|
||
/** | ||
* Set the symbol key element to use for this hierarchy | ||
* | ||
* @param element | ||
* The symbol key element | ||
*/ | ||
void setSymbolKeyElement(ICallStackElement element); | ||
|
||
/** | ||
* Return whether this element is the symbol key element | ||
* | ||
* @return Whether the element is the symbol key | ||
*/ | ||
boolean isSymbolKeyElement(); | ||
|
||
/** | ||
* Get the parent element, or <code>null</code> if this element corresponds | ||
* to the first group of the hierarchy | ||
* | ||
* FIXME: Can this method be completely replaced by | ||
* {@link ITree#getParent()}? | ||
* | ||
* @return The parent element | ||
*/ | ||
@Nullable ICallStackElement getParentElement(); | ||
|
||
/** | ||
* Get whether this element is a leaf element in the callstack hierarchy. | ||
* Leaf elements are expected to contain the proper analysis data. | ||
* | ||
* @return Whether this element is a leaf, i.e. contains analysis data or | ||
* not | ||
*/ | ||
boolean isLeaf(); | ||
} |
76 changes: 76 additions & 0 deletions
76
.../org/eclipse/tracecompass/internal/analysis/callstack/core/ICallStackGroupDescriptor.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
/******************************************************************************* | ||
* Copyright (c) 2016 É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.internal.analysis.callstack.core; | ||
|
||
import org.eclipse.jdt.annotation.Nullable; | ||
import org.eclipse.tracecompass.internal.analysis.callstack.core.tree.IWeightedTreeGroupDescriptor; | ||
|
||
/** | ||
* This interface describes a group in the callstack. A group can either be a | ||
* source group under which other groups are, or a leaf group, under which is | ||
* the actual stack. | ||
* | ||
* Example: Let's take a trace that registers function entry and exit for | ||
* threads and where events also provide information on some other stackable | ||
* application component: | ||
* | ||
* A possible group hierarchy would be the following: | ||
* | ||
* <pre> | ||
* Per PID: | ||
* [pid] | ||
* [tid] | ||
* data | ||
* </pre> | ||
* | ||
* or | ||
* | ||
* <pre> | ||
* With additional component information: | ||
* [pid] | ||
* [application component] | ||
* [tid] | ||
* data | ||
* </pre> | ||
* | ||
* In the first case, there would be 2 groups, and in the second 3 groups. It is | ||
* the analysis's responsibility to implement how to retrieve which group a | ||
* trace event belongs to and add the data to the proper leaf group. These | ||
* groups are indication for the various analyses on how to divide the data and | ||
* some analyses may do some aggregation based on those groups. | ||
* | ||
* To each group will correspond a number of {@link ICallStackElement} that | ||
* represent single elements of this group. In the example above, to the [pid] | ||
* group will correspond each individual process being analyses, eg. process 45, | ||
* 10001, etc. | ||
* | ||
* If the function names happen to be addresses in an executable and the PID is | ||
* the key to map those symbols to actual function names, then the first group | ||
* "[pid]" would be the symbol key group, used to resolve the symbols. | ||
* | ||
* @author Geneviève Bastien | ||
*/ | ||
public interface ICallStackGroupDescriptor extends IWeightedTreeGroupDescriptor { | ||
|
||
@Override | ||
@Nullable ICallStackGroupDescriptor getNextGroup(); | ||
|
||
/** | ||
* Get whether the value of this group should be used as the key for the | ||
* symbol provider. For instance, for some callstack, the group | ||
* corresponding to the process ID would be the symbol key group. | ||
* | ||
* @return <code>true</code> if the values of this group are used as the | ||
* symbol mapping key. | ||
*/ | ||
boolean isSymbolKeyGroup(); | ||
} |
Oops, something went wrong.