From fdf2d9bb7a8afdc5805bedf953c124266b6aa376 Mon Sep 17 00:00:00 2001 From: Matthew Khouzam Date: Fri, 12 Aug 2016 15:05:49 -0400 Subject: [PATCH] flamegraph: add min and max duration support to flamegraph statistics. Change-Id: I85ca00e702c943d954a54e01b273ebdcd7a7782f Signed-off-by: Matthew Khouzam Signed-off-by: Sonia Farrah Reviewed-on: https://git.eclipse.org/r/78993 Reviewed-by: Hudson CI Reviewed-by: Jean-Christian Kouame Tested-by: Jean-Christian Kouame Reviewed-by: Bernd Hufmann Tested-by: Bernd Hufmann --- .../callgraph/AggregatedCalledFunction.java | 49 ++++++++++++------- .../AggregatedCalledFunctionStatistics.java | 43 +++++++++++++--- .../core/callgraph/CallGraphAnalysis.java | 8 +-- .../core/callgraph/CalledFunctionFactory.java | 4 +- .../FlameGraphPresentationProvider.java | 33 +++---------- 5 files changed, 82 insertions(+), 55 deletions(-) diff --git a/analysis/org.eclipse.tracecompass.analysis.timing.core/src/org/eclipse/tracecompass/internal/analysis/timing/core/callgraph/AggregatedCalledFunction.java b/analysis/org.eclipse.tracecompass.analysis.timing.core/src/org/eclipse/tracecompass/internal/analysis/timing/core/callgraph/AggregatedCalledFunction.java index 5610407cf6..719f7e45fa 100644 --- a/analysis/org.eclipse.tracecompass.analysis.timing.core/src/org/eclipse/tracecompass/internal/analysis/timing/core/callgraph/AggregatedCalledFunction.java +++ b/analysis/org.eclipse.tracecompass.analysis.timing.core/src/org/eclipse/tracecompass/internal/analysis/timing/core/callgraph/AggregatedCalledFunction.java @@ -47,27 +47,40 @@ public class AggregatedCalledFunction { private long fSelfTime; /** - * Constructor + * Constructor, parent is not null * - * @param symbol - * The function's name or address - * @param duration - * The function's duration - * @param depth - * The function's depth - * @param maxDepth - * The aggregation tree's maximum depth + * @param calledFunction + * called function * @param parent - * The function's caller + * the parent entry + * */ - public AggregatedCalledFunction(Object symbol, long duration, int depth, int maxDepth, @Nullable AggregatedCalledFunction parent) { - fSymbol = symbol; - fDuration = duration; - fSelfTime = duration; - fDepth = depth; - fMaxDepth = maxDepth; + public AggregatedCalledFunction(AbstractCalledFunction calledFunction, AggregatedCalledFunction parent) { + fSymbol = calledFunction.getSymbol(); + fDuration = calledFunction.getLength(); + fSelfTime = calledFunction.getLength(); + fDepth = calledFunction.getDepth(); + fMaxDepth = parent.getMaxDepth(); fParent = parent; - fStatistics = new AggregatedCalledFunctionStatistics(duration, duration); + fStatistics = new AggregatedCalledFunctionStatistics(calledFunction, calledFunction); + } + + /** + * Root constructor, parent is null + * + * @param calledFunction + * the called function + * @param maxDepth + * the maximum depth + */ + public AggregatedCalledFunction(AbstractCalledFunction calledFunction, int maxDepth) { + fSymbol = calledFunction.getSymbol(); + fDuration = calledFunction.getLength(); + fSelfTime = calledFunction.getLength(); + fDepth = calledFunction.getDepth(); + fMaxDepth = maxDepth; + fParent = null; + fStatistics = new AggregatedCalledFunctionStatistics(calledFunction, calledFunction); } /** @@ -163,7 +176,7 @@ public class AggregatedCalledFunction { long sourceSelfTime = source.getSelfTime(); destination.addToDuration(sourceDuration); destination.addToSelfTime(sourceSelfTime); - destination.fStatistics.update(sourceDuration, sourceSelfTime); + destination.fStatistics.update(source.fStatistics.getMaxSegment(), source.fStatistics.getMinSegment(), sourceDuration, sourceSelfTime); // merge the children callees. mergeChildren(destination, source); } diff --git a/analysis/org.eclipse.tracecompass.analysis.timing.core/src/org/eclipse/tracecompass/internal/analysis/timing/core/callgraph/AggregatedCalledFunctionStatistics.java b/analysis/org.eclipse.tracecompass.analysis.timing.core/src/org/eclipse/tracecompass/internal/analysis/timing/core/callgraph/AggregatedCalledFunctionStatistics.java index d15071eed3..293fd71256 100644 --- a/analysis/org.eclipse.tracecompass.analysis.timing.core/src/org/eclipse/tracecompass/internal/analysis/timing/core/callgraph/AggregatedCalledFunctionStatistics.java +++ b/analysis/org.eclipse.tracecompass.analysis.timing.core/src/org/eclipse/tracecompass/internal/analysis/timing/core/callgraph/AggregatedCalledFunctionStatistics.java @@ -11,6 +11,7 @@ package org.eclipse.tracecompass.internal.analysis.timing.core.callgraph; import org.eclipse.tracecompass.analysis.timing.core.segmentstore.statistics.SegmentStoreStatistics; import org.eclipse.tracecompass.segmentstore.core.BasicSegment; +import org.eclipse.tracecompass.segmentstore.core.ISegment; /** * Class to calculate statistics for an aggregated function. @@ -35,6 +36,14 @@ public class AggregatedCalledFunctionStatistics extends SegmentStoreStatistics { * The variance of the self time */ private double fVariance; + /** + * The segment with the longest duration + */ + private ISegment fMaxSegment; + /** + * The segment with the shortest duration + */ + private ISegment fMinSegment; /** * Constructor @@ -44,25 +53,37 @@ public class AggregatedCalledFunctionStatistics extends SegmentStoreStatistics { * @param selfTime * The function's self time */ - public AggregatedCalledFunctionStatistics(long duration, long selfTime) { - fMaxSelfTime = selfTime; - fMinSelfTime = selfTime; - fSelfTimeAverage = selfTime; + public AggregatedCalledFunctionStatistics(ISegment duration, ISegment selfTime) { + fMaxSelfTime = selfTime.getLength(); + fMinSelfTime = selfTime.getLength(); + fSelfTimeAverage = selfTime.getLength(); fVariance = 0.0; - update(new BasicSegment(0, duration)); + fMinSegment = duration; + fMaxSegment = duration; + update(duration); } /** * Update the statistics, this is used while merging nodes for the * aggregation tree. * + * @param maxSegment + * The longest segment of the function to be merged + * @param minSegment + * The shortest segment of the function to be merged * @param duration * The function to be merged duration * @param selfTime * The function to be merged self time */ - public void update(long duration, long selfTime) { + public void update(ISegment maxSegment, ISegment minSegment, long duration, long selfTime) { update(new BasicSegment(0, duration)); + if (maxSegment.getLength() > fMaxSegment.getLength()) { + fMaxSegment = maxSegment; + } + if (minSegment.getLength() < fMinSegment.getLength()) { + fMinSegment = minSegment; + } if (fMaxSelfTime < selfTime) { fMaxSelfTime = selfTime; } @@ -122,4 +143,14 @@ public class AggregatedCalledFunctionStatistics extends SegmentStoreStatistics { fMinSelfTime = selfTime; fSelfTimeAverage = selfTime; } + + @Override + public ISegment getMaxSegment() { + return fMaxSegment; + } + + @Override + public ISegment getMinSegment() { + return fMinSegment; + } } diff --git a/analysis/org.eclipse.tracecompass.analysis.timing.core/src/org/eclipse/tracecompass/internal/analysis/timing/core/callgraph/CallGraphAnalysis.java b/analysis/org.eclipse.tracecompass.analysis.timing.core/src/org/eclipse/tracecompass/internal/analysis/timing/core/callgraph/CallGraphAnalysis.java index b75e11eba6..8b87520a1a 100644 --- a/analysis/org.eclipse.tracecompass.analysis.timing.core/src/org/eclipse/tracecompass/internal/analysis/timing/core/callgraph/CallGraphAnalysis.java +++ b/analysis/org.eclipse.tracecompass.analysis.timing.core/src/org/eclipse/tracecompass/internal/analysis/timing/core/callgraph/CallGraphAnalysis.java @@ -205,10 +205,12 @@ public abstract class CallGraphAnalysis extends TmfAbstractAnalysisModule implem */ private boolean iterateOverQuark(ITmfStateSystem stateSystem, int quark, String[] subAttributePath, IProgressMonitor monitor) { String threadName = stateSystem.getAttributeName(quark); - AggregatedCalledFunction init = new AggregatedCalledFunction(threadName, 0L, 0, 0, null); + AggregatedCalledFunction init = null; try { long curTime = stateSystem.getStartTime(); long limit = stateSystem.getCurrentEndTime(); + AbstractCalledFunction initSegment = CalledFunctionFactory.create(0, 0, 0, threadName, null); + init = new AggregatedCalledFunction(initSegment, 0); while (curTime < limit) { if (monitor.isCanceled()) { return false; @@ -229,7 +231,7 @@ public abstract class CallGraphAnalysis extends TmfAbstractAnalysisModule implem // Create the segment for the first call event. AbstractCalledFunction segment = CalledFunctionFactory.create(intervalStart, intervalEnd + 1, depth, stateValue, null); fRootFunctions.add(segment); - AggregatedCalledFunction firstNode = new AggregatedCalledFunction(stateValue, intervalEnd - intervalStart + 1, segment.getDepth(), fCurrentQuarks.size(), null); + AggregatedCalledFunction firstNode = new AggregatedCalledFunction(segment, fCurrentQuarks.size()); if (!findChildren(segment, depth, stateSystem, fCurrentQuarks.size() + fCurrentQuarks.get(depth), firstNode, monitor)) { return false; } @@ -293,7 +295,7 @@ public abstract class CallGraphAnalysis extends TmfAbstractAnalysisModule implem return true; } AbstractCalledFunction segment = CalledFunctionFactory.create(intervalStart, intervalEnd + 1, node.getDepth() + 1, stateValue, node); - AggregatedCalledFunction childNode = new AggregatedCalledFunction(stateValue, segment.getLength(), segment.getDepth(), aggregatedCalledFunction.getMaxDepth(), aggregatedCalledFunction); + AggregatedCalledFunction childNode = new AggregatedCalledFunction(segment, aggregatedCalledFunction); // Search for the children with the next quark. findChildren(segment, depth + 1, ss, maxQuark, childNode, monitor); aggregatedCalledFunction.addChild(childNode); diff --git a/analysis/org.eclipse.tracecompass.analysis.timing.core/src/org/eclipse/tracecompass/internal/analysis/timing/core/callgraph/CalledFunctionFactory.java b/analysis/org.eclipse.tracecompass.analysis.timing.core/src/org/eclipse/tracecompass/internal/analysis/timing/core/callgraph/CalledFunctionFactory.java index 0709c0db5e..26e93958bf 100644 --- a/analysis/org.eclipse.tracecompass.analysis.timing.core/src/org/eclipse/tracecompass/internal/analysis/timing/core/callgraph/CalledFunctionFactory.java +++ b/analysis/org.eclipse.tracecompass.analysis.timing.core/src/org/eclipse/tracecompass/internal/analysis/timing/core/callgraph/CalledFunctionFactory.java @@ -97,9 +97,9 @@ public class CalledFunctionFactory { * the symbol * @param parent * the parent node - * @return an ICalledFunction with the specified propertiess + * @return an ICalledFunction with the specified properties */ - private static CalledStringFunction create(long start, long end, int depth, String value, @Nullable ICalledFunction parent) { + public static CalledStringFunction create(long start, long end, int depth, String value, @Nullable ICalledFunction parent) { if (start > end) { throw new IllegalArgumentException(Messages.TimeError + '[' + start + ',' + end + ']'); } diff --git a/analysis/org.eclipse.tracecompass.analysis.timing.ui/src/org/eclipse/tracecompass/internal/analysis/timing/ui/flamegraph/FlameGraphPresentationProvider.java b/analysis/org.eclipse.tracecompass.analysis.timing.ui/src/org/eclipse/tracecompass/internal/analysis/timing/ui/flamegraph/FlameGraphPresentationProvider.java index d452295b9b..70330e0888 100644 --- a/analysis/org.eclipse.tracecompass.analysis.timing.ui/src/org/eclipse/tracecompass/internal/analysis/timing/ui/flamegraph/FlameGraphPresentationProvider.java +++ b/analysis/org.eclipse.tracecompass.analysis.timing.ui/src/org/eclipse/tracecompass/internal/analysis/timing/ui/flamegraph/FlameGraphPresentationProvider.java @@ -18,8 +18,6 @@ import org.eclipse.swt.graphics.RGB; import org.eclipse.swt.graphics.Rectangle; import org.eclipse.tracecompass.analysis.timing.ui.views.segmentstore.SubSecondTimeWithUnitFormat; import org.eclipse.tracecompass.internal.analysis.timing.core.callgraph.AggregatedCalledFunctionStatistics; -import org.eclipse.tracecompass.statesystem.core.statevalue.ITmfStateValue; -import org.eclipse.tracecompass.statesystem.core.statevalue.TmfStateValue; import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; import org.eclipse.tracecompass.tmf.core.trace.TmfTraceManager; import org.eclipse.tracecompass.tmf.ui.symbols.ISymbolProvider; @@ -130,31 +128,14 @@ public class FlameGraphPresentationProvider extends TimeGraphPresentationProvide */ private static String getFuntionSymbol(FlamegraphEvent event, ISymbolProvider symbolProvider) { String funcSymbol = ""; //$NON-NLS-1$ - if (event.getSymbol() instanceof TmfStateValue) { - ITmfStateValue symbol = (ITmfStateValue) event.getSymbol(); - switch (symbol.getType()) { - case LONG: - Long longAddress = symbol.unboxLong(); - funcSymbol = symbolProvider.getSymbolText(longAddress); - if (funcSymbol == null) { - return "0x" + Long.toHexString(longAddress); //$NON-NLS-1$ - } - return funcSymbol; - case STRING: - return symbol.unboxStr(); - case INTEGER: - Integer intAddress = symbol.unboxInt(); - funcSymbol = symbolProvider.getSymbolText(intAddress); - if (funcSymbol == null) { - return "0x" + Integer.toHexString(intAddress); //$NON-NLS-1$ - } - return funcSymbol; - case CUSTOM: - case DOUBLE: - case NULL: - default: - break; + if (event.getSymbol() instanceof Long || event.getSymbol() instanceof Integer) { + long longAddress = ((Long) event.getSymbol()).longValue(); + funcSymbol = symbolProvider.getSymbolText(longAddress); + if (funcSymbol == null) { + return "0x" + Long.toHexString(longAddress); //$NON-NLS-1$ } + } else { + return event.getSymbol().toString(); } return funcSymbol; } -- 2.34.1