From ceaaace2e7111fc9c83f7d0ee85746fda449e76a Mon Sep 17 00:00:00 2001 From: greatim Date: Tue, 24 Mar 2015 18:25:25 +0900 Subject: [PATCH] CALLSTACK: refactoring callstack manager seperate callstack manager for "runtime" and "range" seperate profile data maker too. (runtime and range) Change-Id: I925f66bee9c955514516b98f4d8d907bab55dead Signed-off-by: greatim --- .../dynamicanalyzer/common/AnalyzerManager.java | 23 +- .../dynamicanalyzer/handlers/OpenTraceHandler.java | 2 +- .../swap/callstack/BaseCallstackManager.java | 175 +++----- .../swap/callstack/RangeCallstackManager.java | 146 +++++++ ...ckManager.java => RuntimeCallstackManager.java} | 225 +++------- .../dynamicanalyzer/swap/logparser/LogParser.java | 6 +- .../ui/info/callstack/CallStackInserter.java | 6 +- .../ui/info/callstack/CallStackUnit.java | 56 ++- .../ui/info/callstack/CallstackTable.java | 4 +- .../dynamicanalyzer/ui/range/RangeDataManager.java | 43 +- .../summary/profiling/FunctionUsageProfiler.java | 5 +- .../ui/summary/profiling/ProfileDataMaker.java | 455 +++------------------ .../summary/profiling/RangeProfileDataMaker.java | 169 ++++++++ .../summary/profiling/RuntimeProfileDataMaker.java | 250 +++++++++++ 14 files changed, 788 insertions(+), 777 deletions(-) create mode 100644 org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/swap/callstack/RangeCallstackManager.java rename org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/swap/callstack/{SWAPCallStackManager.java => RuntimeCallstackManager.java} (69%) create mode 100644 org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/ui/summary/profiling/RangeProfileDataMaker.java create mode 100644 org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/ui/summary/profiling/RuntimeProfileDataMaker.java diff --git a/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/common/AnalyzerManager.java b/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/common/AnalyzerManager.java index f2da79d..18ad634 100755 --- a/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/common/AnalyzerManager.java +++ b/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/common/AnalyzerManager.java @@ -28,15 +28,12 @@ package org.tizen.dynamicanalyzer.common; import org.tizen.dynamicanalyzer.annotation.FutureUse; import org.tizen.dynamicanalyzer.annotation.UIMethod; -import org.tizen.dynamicanalyzer.project.Project; -import org.tizen.dynamicanalyzer.swap.callstack.BaseCallstackManager; -import org.tizen.dynamicanalyzer.swap.callstack.SWAPCallStackManager; +import org.tizen.dynamicanalyzer.swap.callstack.RuntimeCallstackManager; import org.tizen.dynamicanalyzer.ui.opengl.data.type.GLSelectionData; import org.tizen.dynamicanalyzer.ui.page.BaseView; import org.tizen.dynamicanalyzer.ui.range.RangeDataManager; import org.tizen.dynamicanalyzer.ui.summary.leaks.NewLeakDetector; import org.tizen.dynamicanalyzer.ui.summary.profiling.FunctionUsageProfiler; -import org.tizen.dynamicanalyzer.ui.summary.profiling.ProfilingData; import org.tizen.dynamicanalyzer.ui.summary.warning.WarningChecker; import org.tizen.dynamicanalyzer.util.WorkbenchUtil; import org.tizen.dynamicanalyzer.widgets.da.view.DABaseComposite; @@ -55,7 +52,7 @@ public class AnalyzerManager { private static NewLeakDetector newLeakDetector = new NewLeakDetector(); private static WarningChecker warningChecker = new WarningChecker(); - private static SWAPCallStackManager swapCallstackManager = new SWAPCallStackManager(false); + private static RuntimeCallstackManager runtimeCallstackManager = new RuntimeCallstackManager(); public static boolean isPlatformSDK() { return isPlatformSDK; @@ -105,17 +102,8 @@ public class AnalyzerManager { return warningChecker; } - public static BaseCallstackManager getCallstackManager() { - Project curProject = Global.getProject(); - if (curProject != null) { - // TODO : protocol version definition - String pver = curProject.getProtocolVersion(); - if (pver.startsWith("3.")) { - return swapCallstackManager; - } - } - - return swapCallstackManager; + public static RuntimeCallstackManager getRuntimeCallstackManager() { + return runtimeCallstackManager; } public static void clear() { @@ -124,11 +112,10 @@ public class AnalyzerManager { newLeakDetector.clear(); warningChecker.clear(); - swapCallstackManager.clear(); + runtimeCallstackManager.clear(); // UserFunctionManager.getInstance().clear(); FunctionUsageProfiler.getInstance().stopNormal(); - ProfilingData.clear(); // reset internal sequence number RangeDataManager.getInstance().initRange(); } diff --git a/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/handlers/OpenTraceHandler.java b/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/handlers/OpenTraceHandler.java index 429c4dc..60a2ff4 100644 --- a/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/handlers/OpenTraceHandler.java +++ b/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/handlers/OpenTraceHandler.java @@ -146,7 +146,7 @@ public class OpenTraceHandler extends AbstractHandler { Logger.debug("failed - loadCallStackApis"); isSuccess = false; } else { - BaseCallstackManager callstackManager = AnalyzerManager.getCallstackManager(); + BaseCallstackManager callstackManager = AnalyzerManager.getRuntimeCallstackManager(); int size = callStackUnits.size(); for (int i = 0; i < size; i++) { List callStackUnit = callStackUnits.get(i); diff --git a/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/swap/callstack/BaseCallstackManager.java b/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/swap/callstack/BaseCallstackManager.java index 7e3df03..0842609 100644 --- a/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/swap/callstack/BaseCallstackManager.java +++ b/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/swap/callstack/BaseCallstackManager.java @@ -35,12 +35,10 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentSkipListMap; import org.tizen.dynamicanalyzer.common.AnalyzerConstants; -import org.tizen.dynamicanalyzer.common.AnalyzerManager; import org.tizen.dynamicanalyzer.common.Global; import org.tizen.dynamicanalyzer.common.SymbolManager; import org.tizen.dynamicanalyzer.constant.CommonConstants; import org.tizen.dynamicanalyzer.nl.InformationViewLabels; -import org.tizen.dynamicanalyzer.project.AppInfo; import org.tizen.dynamicanalyzer.project.BinaryInfo; import org.tizen.dynamicanalyzer.project.LibraryObject; import org.tizen.dynamicanalyzer.project.ProcessInformation; @@ -50,7 +48,6 @@ import org.tizen.dynamicanalyzer.swap.model.data.LogData; import org.tizen.dynamicanalyzer.swap.platform.BinarySettingData; import org.tizen.dynamicanalyzer.swap.platform.BinarySettingManager; import org.tizen.dynamicanalyzer.ui.info.callstack.CallStackData; -import org.tizen.dynamicanalyzer.ui.info.callstack.CallStackInserter; import org.tizen.dynamicanalyzer.ui.info.callstack.CallStackItem; import org.tizen.dynamicanalyzer.ui.info.callstack.CallStackUnit; import org.tizen.dynamicanalyzer.ui.summary.profiling.ProfileDataMaker; @@ -58,71 +55,16 @@ import org.tizen.dynamicanalyzer.util.Logger; import org.tizen.dynamicanalyzer.utils.AnalyzerUtil; public abstract class BaseCallstackManager { - protected static class DuplicateUserCall { - private CallStackUnit dupCallstackUnit = null; - private int dupCallcount = 0; - - public DuplicateUserCall(CallStackUnit callStackUnit) { - dupCallstackUnit = callStackUnit; - dupCallcount = 1; - } - - public CallStackUnit getDupCallstackUnit() { - return dupCallstackUnit; - } - - public int getDupCallCount() { - return dupCallcount; - } - - public void increaseDupCallCount() { - dupCallcount++; - } - - public void decreaseDupCallCount() { - dupCallcount--; - } - } - - protected ConcurrentHashMap> callstackApiAddrByPidMap = new ConcurrentHashMap>(); - protected ConcurrentSkipListMap callstackDataBySeqMap = new ConcurrentSkipListMap(); - protected String userFunctionBin = null; - protected HashMap> userCallstackByTidMap = new HashMap>(); - protected HashMap dupUserCallByTidMap = new HashMap(); - protected ConcurrentHashMap> seqTimeByTidMap = new ConcurrentHashMap>(); - - protected CallStackInserter callstackInserter = null; + protected Map> callstackApiAddrByPidMap = new ConcurrentHashMap>(); + protected NavigableMap callstackDataBySeqMap = new ConcurrentSkipListMap(); + protected Map> userCallstackByTidMap = new HashMap>(); abstract public void makeUserCallstack(LogData log, ProfileDataMaker profiler); - abstract public void makeUserCallstackforRange(LogData log, ProfileDataMaker profiler); - - abstract public void makeCallstackWithoutBacktrace(LogData inputData); - abstract public long getSeqOfUserCallstackForTime(int tid, long time); - abstract public List getCallstackAddrListFromSeq(long seq); - abstract public List> getArrayOfAddrListFromSeq(List seqs); - - public void offerCallStackUnit(CallStackUnit csu) { - if (callstackInserter != null) { - CallStackInserter.startInserterThread(); - callstackInserter.offerCallstackUnit(csu); - } - return; - } - public void offerCallStackData(CallStackData csd) { - if (callstackInserter != null) { - CallStackInserter.startInserterThread(); - callstackInserter.offerCallstackData(csd); - } - return; - } + abstract public long getSeqOfUserCallstackForTime(int tid, long time); public Map getCallStackApiAddrByPidMap(int pid) { - if (null == callstackApiAddrByPidMap) { - callstackApiAddrByPidMap = new ConcurrentHashMap>(); - } - ConcurrentHashMap callstackApiByAddrMap = callstackApiAddrByPidMap - .get(pid); + Map callstackApiByAddrMap = callstackApiAddrByPidMap.get(pid); if (null == callstackApiByAddrMap) { callstackApiByAddrMap = new ConcurrentHashMap(); callstackApiAddrByPidMap.put(pid, callstackApiByAddrMap); @@ -131,53 +73,25 @@ public abstract class BaseCallstackManager { } public NavigableMap getCallStackDataBySeqMap() { - if (null == callstackDataBySeqMap) { - callstackDataBySeqMap = new ConcurrentSkipListMap(); - } return callstackDataBySeqMap; } - public HashMap getDupUserCallByTidMap() { - if (null == dupUserCallByTidMap) { - dupUserCallByTidMap = new HashMap(); - } - return dupUserCallByTidMap; - } - - public NavigableMap getSeqTimeByTidMap(int tid) { - if (null == seqTimeByTidMap) { - seqTimeByTidMap = new ConcurrentHashMap>(); - } - ConcurrentSkipListMap seqByTimeMap = seqTimeByTidMap.get(tid); - if (null == seqByTimeMap) { - seqByTimeMap = new ConcurrentSkipListMap(); - seqTimeByTidMap.put(tid, seqByTimeMap); + public List getUserCallstack(int tid) { + List userCallstack = userCallstackByTidMap.get(tid); + if (null == userCallstack) { + userCallstack = new ArrayList(); + userCallstackByTidMap.put(tid, userCallstack); } - return seqByTimeMap; - } - - public List getTidsOfSeqTimeMap() { - ArrayList tids = new ArrayList(); - tids.addAll(seqTimeByTidMap.keySet()); - - return tids; + return userCallstack; } - public String getUserFunctionPosition() { - if (userFunctionBin == null || userFunctionBin.isEmpty()) { - if (AnalyzerManager.isOsp()) { - userFunctionBin = new String(Global.getCurrentApplication().getMainApp() - .getInfo(AppInfo.PROPERTY.EXEC.index) - + ".exe"); //$NON-NLS-1$ - } else { - userFunctionBin = new String(Global.getCurrentApplication().getMainApp() - .getInfo(AppInfo.PROPERTY.EXEC.index)); - } - } - return userFunctionBin; + public void clear() { + callstackApiAddrByPidMap.clear(); + callstackDataBySeqMap.clear(); + userCallstackByTidMap.clear(); } - public String getUserFunctionPosition(int pid, long time) { + private String getUserFunctionPosition(int pid, long time) { Project project = Global.getProject(); ProcessInformation process = project.getProcessInformation(pid); ProcessMemoryMap pmap = process.getProcessMemoryMap(time); @@ -190,28 +104,6 @@ public abstract class BaseCallstackManager { } } - public List getUserCallstack(int tid) { - if (null == userCallstackByTidMap) { - userCallstackByTidMap = new HashMap>(); - } - List userCallstack = userCallstackByTidMap.get(tid); - if (null == userCallstack) { - userCallstack = new ArrayList(); - userCallstackByTidMap.put(tid, userCallstack); - } - return userCallstack; - } - - public boolean checkUserCall(String input) { - AppInfo appInfo = Global.getProject().getApplicationInfo(); - BinaryInfo binfo = Global.getProject().getDeviceStatusInfo() - .getBinaryInfo(appInfo.getExecBinaryPath()); - if (binfo.getTargetBinaryPath().equals(input)) { - return true; - } - return false; - } - // callstack symbol format : path(functionName // ex. /usr/lib/libpthread.so(pthread_create public String getCallStackSymbol(long addr, int pid, long time) { @@ -308,5 +200,38 @@ public abstract class BaseCallstackManager { return symbol; } - abstract public void clear(); + protected boolean isAddrInBinaryRange(int pid, long time, long addr) { + ProcessMemoryMap pmap = Global.getProject().getProcessInformation(pid) + .getProcessMemoryMap(time); + if (null == pmap) { + return false; + } + // return true when addr is within memory range of main executable + // or library which is set in the binary setting + if (addr >= pmap.getMainbinary().getLowestAddress() + && addr <= pmap.getMainbinary().getHighestAddress()) { + return true; + } + + List binDataList = BinarySettingManager.getInstance() + .getBinarySettingList(); + List binPaths = new ArrayList(); + for (BinarySettingData binData : binDataList) { + binPaths.add(binData.getBinaryPath()); + } + // TODO: performance improvement + int size = binPaths.size(); + for (int i = 0; i < size; i++) { + String binPath = binPaths.get(i); + BinaryInfo bininfo = Global.getProject().getDeviceStatusInfo().getBinaryInfo(binPath); + LibraryObject libObj = pmap.getLibraryByBinaryID(bininfo.getID()); + if (null == libObj) { + continue; + } + if (addr >= libObj.getLowestAddress() && addr <= libObj.getHighestAddress()) { + return true; + } + } + return false; + } } diff --git a/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/swap/callstack/RangeCallstackManager.java b/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/swap/callstack/RangeCallstackManager.java new file mode 100644 index 0000000..dc9d140 --- /dev/null +++ b/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/swap/callstack/RangeCallstackManager.java @@ -0,0 +1,146 @@ +/* + * Dynamic Analyzer + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: + * WooJin Jung + * Jooyoul Lee + * Juyoung Kim + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Contributors: + * - S-Core Co., Ltd + * + */ + +package org.tizen.dynamicanalyzer.swap.callstack; + +import static org.tizen.dynamicanalyzer.swap.channel.data.DataChannelConstants.MSG_FUNCTION_ENTRY; +import static org.tizen.dynamicanalyzer.swap.channel.data.DataChannelConstants.MSG_FUNCTION_EXIT; + +import java.util.List; +import java.util.Map; + +import org.tizen.dynamicanalyzer.common.AnalyzerConstants; +import org.tizen.dynamicanalyzer.common.Global; +import org.tizen.dynamicanalyzer.project.BinaryInfo; +import org.tizen.dynamicanalyzer.swap.model.data.LogData; +import org.tizen.dynamicanalyzer.swap.model.data.ProfileData; +import org.tizen.dynamicanalyzer.ui.info.callstack.CallStackItem; +import org.tizen.dynamicanalyzer.ui.info.callstack.CallStackUnit; +import org.tizen.dynamicanalyzer.ui.summary.profiling.ProfileDataMaker; +import org.tizen.dynamicanalyzer.util.Logger; + +public class RangeCallstackManager extends BaseCallstackManager { + + @Override + public void makeUserCallstack(LogData log, ProfileDataMaker profiler) { + ProfileData pData = (ProfileData) log; + int pid = pData.getPid(); + long time = pData.getTime(); + + Map addrMap = getCallStackApiAddrByPidMap(pid); + + int tid = pData.getTid(); + long selfAddr = pData.getPcAddr(); + long callerAddr = pData.getCallerPcAddr(); + + CallStackUnit selfCallstackUnit = addrMap.get(selfAddr); + // TODO: use callstackunit made during trace time + if (null == selfCallstackUnit) { + String strSelfFuncName = Global.getFunctionName(pData.getApiId()); + BinaryInfo binInfo = Global.getProject().getDeviceStatusInfo() + .getBinaryInfo(pData.getBinaryId()); + String strSelfSymbol = binInfo.getTargetBinaryPath() + + AnalyzerConstants.CALLSTACK_API_TOKEN_STRING + strSelfFuncName; + selfCallstackUnit = new CallStackUnit(selfAddr, strSelfSymbol, pData.getApiId(), pData); + addrMap.put(selfAddr, selfCallstackUnit); + } + + // make ProfilingData + profiler.makeFupDataForCallTrace(selfCallstackUnit, pData); + + List userCallstack = getUserCallstack(tid); + int size = userCallstack.size(); + + CallStackUnit callerCallstackUnit = addrMap.get(callerAddr); + if (null == callerCallstackUnit) { + String strCallerSymbol = getCallStackSymbol(callerAddr, pid, time); + callerCallstackUnit = new CallStackUnit(callerAddr, strCallerSymbol, pData); + addrMap.put(callerAddr, callerCallstackUnit); + } + + int eventType = pData.getMsgID(); + if (eventType == MSG_FUNCTION_ENTRY) { + if (size == 0) { + userCallstack.add(new CallStackItem(selfCallstackUnit, time)); + } else { + if (isAddrInBinaryRange(pid, time, callerAddr)) { + // change previous top callstackunit's address to caller address of this + // callstackunit + CallStackUnit callerCsa = addrMap.get(callerAddr); + if (null == callerCsa) { + callerCsa = userCallstack.get(size - 1).getCallStackUnit(); + callerCsa.setFunctionStartAddr(callerCsa.getAddr()); + callerCsa.setAddr(callerAddr); + } else { + CallStackItem topCallstackItem = userCallstack.get(size - 1); + callerCsa.setFunctionStartAddr(topCallstackItem.getCallStackUnit() + .getAddr()); + userCallstack.set(size - 1, + new CallStackItem(callerCsa, topCallstackItem.getStartTime())); + } + } // do nothing when call is from library + // in range analysis, user callstack is only used to make callstack of sample + // and callstack of sample does not include "~~ internal library~~" + userCallstack.add(new CallStackItem(selfCallstackUnit, time)); + } + } else if (eventType == MSG_FUNCTION_EXIT) { + if (size == 0) { + return; + } + CallStackUnit removeCallStackUnit = userCallstack.get(size - 1).getCallStackUnit(); + if (selfCallstackUnit.getFunctionId() == removeCallStackUnit.getFunctionId()) { + userCallstack.remove(size - 1); + size = userCallstack.size(); + if (size > 0) { + // restore start address of previous top callstackunit + CallStackItem prevCallstackItem = userCallstack.get(size - 1); + long prevSelfAddr = prevCallstackItem.getCallStackUnit().getFunctionStartAddr(); + CallStackUnit callerCsa = addrMap.get(prevSelfAddr); + if (null == callerCsa) { + prevCallstackItem.getCallStackUnit().setAddr(prevSelfAddr); + } else { + userCallstack.set(size - 1, + new CallStackItem(callerCsa, prevCallstackItem.getStartTime())); + } + } + } else { + Logger.error("makeUserCallstack %d, %d, %s, %s", selfCallstackUnit.getFunctionId(), + removeCallStackUnit.getFunctionId(), Global.getFunctionName(selfCallstackUnit.getFunctionId()), + Global.getFunctionName(removeCallStackUnit.getFunctionId())); + // Logger.error("makeUserCallstack : EXIT self is not the same as top of user callstack"); + } + } + } + + @Override + public long getSeqOfUserCallstackForTime(int tid, long time) { + // do nothing, never been called + Logger.error("Should not be called in range callstack manager"); + return 0; + } + +} diff --git a/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/swap/callstack/SWAPCallStackManager.java b/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/swap/callstack/RuntimeCallstackManager.java similarity index 69% rename from org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/swap/callstack/SWAPCallStackManager.java rename to org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/swap/callstack/RuntimeCallstackManager.java index 40ba130..99562da 100644 --- a/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/swap/callstack/SWAPCallStackManager.java +++ b/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/swap/callstack/RuntimeCallstackManager.java @@ -36,6 +36,8 @@ import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.NavigableMap; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentSkipListMap; import org.tizen.dynamicanalyzer.common.AnalyzerConstants; import org.tizen.dynamicanalyzer.common.Global; @@ -48,8 +50,6 @@ import org.tizen.dynamicanalyzer.project.ProcessMemoryMap; import org.tizen.dynamicanalyzer.swap.model.data.LogData; import org.tizen.dynamicanalyzer.swap.model.data.ProbeCommonData; import org.tizen.dynamicanalyzer.swap.model.data.ProfileData; -import org.tizen.dynamicanalyzer.swap.platform.BinarySettingData; -import org.tizen.dynamicanalyzer.swap.platform.BinarySettingManager; import org.tizen.dynamicanalyzer.ui.info.callstack.CallStackData; import org.tizen.dynamicanalyzer.ui.info.callstack.CallStackInserter; import org.tizen.dynamicanalyzer.ui.info.callstack.CallStackItem; @@ -59,17 +59,55 @@ import org.tizen.dynamicanalyzer.ui.timeline.calltrace.FunctionEntryDBTable; import org.tizen.dynamicanalyzer.ui.timeline.calltrace.FunctionExitDBTable; import org.tizen.dynamicanalyzer.util.Logger; -public class SWAPCallStackManager extends BaseCallstackManager { +public class RuntimeCallstackManager extends BaseCallstackManager { + protected CallStackInserter callstackInserter = null; + + protected Map> seqTimeByTidMap = new ConcurrentHashMap>(); // callstackdata made in range analysis should not be saved to DB - public SWAPCallStackManager(boolean isRange) { - if (!isRange) { - callstackInserter = CallStackInserter.getInstance(); - } else { - callstackInserter = null; + public RuntimeCallstackManager() { + callstackInserter = CallStackInserter.getInstance(); + } + + public void offerCallStackUnit(CallStackUnit csu) { + if (callstackInserter != null) { + CallStackInserter.startInserterThread(); + callstackInserter.offerCallstackUnit(csu); + } + return; + } + + public void offerCallStackData(CallStackData csd) { + if (callstackInserter != null) { + CallStackInserter.startInserterThread(); + callstackInserter.offerCallstackData(csd); } + return; } + public NavigableMap getSeqTimeByTidMap(int tid) { + NavigableMap seqByTimeMap = seqTimeByTidMap.get(tid); + if (null == seqByTimeMap) { + seqByTimeMap = new ConcurrentSkipListMap(); + seqTimeByTidMap.put(tid, seqByTimeMap); + } + return seqByTimeMap; + } + + public List getTidsOfSeqTimeMap() { + ArrayList tids = new ArrayList(); + tids.addAll(seqTimeByTidMap.keySet()); + + return tids; + } + + @Override + public void clear() { + super.clear(); + seqTimeByTidMap.clear(); + } + + @Override public void makeUserCallstack(LogData input, ProfileDataMaker profiler) { ProfileData log = (ProfileData) input; int pid = log.getPid(); @@ -193,101 +231,13 @@ public class SWAPCallStackManager extends BaseCallstackManager { String apiName = Global.getFunctionName(log.getApiId()); if (apiName.equals("main")) { //$NON-NLS-1$ - ProcessInformation process = Global.getProject().getProcessInformation( - log.getPid()); + ProcessInformation process = Global.getProject() + .getProcessInformation(log.getPid()); process.setDropLog(true); } } } - public void makeUserCallstackforRange(LogData input, ProfileDataMaker profiler) { - ProfileData pData = (ProfileData) input; - int pid = pData.getPid(); - long time = pData.getTime(); - - Map addrMap = getCallStackApiAddrByPidMap(pid); - - int tid = pData.getTid(); - long selfAddr = pData.getPcAddr(); - long callerAddr = pData.getCallerPcAddr(); - - CallStackUnit selfCallstackUnit = addrMap.get(selfAddr); - // TODO: use callstackunit made during trace time - if (null == selfCallstackUnit) { - String strSelfFuncName = Global.getFunctionName(pData.getApiId()); - BinaryInfo binInfo = Global.getProject().getDeviceStatusInfo() - .getBinaryInfo(pData.getBinaryId()); - String strSelfSymbol = binInfo.getTargetBinaryPath() - + AnalyzerConstants.CALLSTACK_API_TOKEN_STRING + strSelfFuncName; - selfCallstackUnit = new CallStackUnit(selfAddr, strSelfSymbol, pData.getApiId(), pData); - addrMap.put(selfAddr, selfCallstackUnit); - } - - // make ProfilingData - profiler.makeFupDataForCallTrace(selfCallstackUnit, pData); - - List userCallstack = getUserCallstack(tid); - int size = userCallstack.size(); - - CallStackUnit callerCallstackUnit = addrMap.get(callerAddr); - if (null == callerCallstackUnit) { - String strCallerSymbol = getCallStackSymbol(callerAddr, pid, time); - callerCallstackUnit = new CallStackUnit(callerAddr, strCallerSymbol, pData); - addrMap.put(callerAddr, callerCallstackUnit); - } - - int eventType = pData.getMsgID(); - if (eventType == MSG_FUNCTION_ENTRY) { - if (size == 0) { - userCallstack.add(new CallStackItem(selfCallstackUnit, time)); - } else { - if (isAddrInBinaryRange(pid, time, callerAddr)) { - // change previous top callstackunit's address to caller address of this callstackunit - CallStackUnit callerCsa = addrMap.get(callerAddr); - if (null == callerCsa) { - callerCsa = userCallstack.get(size - 1).getCallStackUnit(); - callerCsa.setFunctionStartAddr(callerCsa.getAddr()); - callerCsa.setAddr(callerAddr); - } else { - CallStackItem topCallstackItem = userCallstack.get(size - 1); - callerCsa.setFunctionStartAddr(topCallstackItem - .getCallStackUnit().getAddr()); - userCallstack.set(size - 1, new CallStackItem(callerCsa, - topCallstackItem.getStartTime())); - } - } // do nothing when call is from library - // in range analysis, user callstack is only used to make callstack of sample - // and callstack of sample does not include "~~ internal library~~" - userCallstack.add(new CallStackItem(selfCallstackUnit, time)); - } - } else if (eventType == MSG_FUNCTION_EXIT) { - if (size == 0) { - return; - } - CallStackUnit removeCallStackUnit = userCallstack.get(size - 1) - .getCallStackUnit(); - if (selfCallstackUnit.getFunctionId() == removeCallStackUnit.getFunctionId()) { - userCallstack.remove(size - 1); - size = userCallstack.size(); - if (size > 0) { - // restore start address of previous top callstackunit - CallStackItem prevCallstackItem = userCallstack.get(size - 1); - long prevSelfAddr = prevCallstackItem.getCallStackUnit() - .getFunctionStartAddr(); - CallStackUnit callerCsa = addrMap.get(prevSelfAddr); - if (null == callerCsa) { - prevCallstackItem.getCallStackUnit().setAddr(prevSelfAddr); - } else { - userCallstack.set(size - 1, new CallStackItem(callerCsa, - prevCallstackItem.getStartTime())); - } - } - } else { - Logger.error("makeUserCallstack : EXIT self is not the same as top of user callstack"); - } - } - } - public void makeCallstackWithoutBacktrace(LogData inputData) { ProbeCommonData log = (ProbeCommonData) inputData; @@ -310,7 +260,7 @@ public class SWAPCallStackManager extends BaseCallstackManager { long userCallstackSeq = getSeqOfUserCallstackForTime(tid, time); List addrs = new ArrayList(); int size = 0; - + if (-1 != userCallstackSeq) { // seq for usercallstack is found List addrsFromUserCallStack = getCallstackAddrListFromSeq(userCallstackSeq); if (null != addrsFromUserCallStack) { // callstack data for seq is found @@ -358,6 +308,7 @@ public class SWAPCallStackManager extends BaseCallstackManager { } // to make callstack for sample, probe + @Override public long getSeqOfUserCallstackForTime(int tid, long time) { long seq = -1; String query; @@ -365,7 +316,7 @@ public class SWAPCallStackManager extends BaseCallstackManager { ResultSet rs; NavigableMap seqByTimeMap = getSeqTimeByTidMap(tid); Long callstackTime = seqByTimeMap.floorKey(time); - + if (null != callstackTime) { // found from memory seq = seqByTimeMap.get(callstackTime); } else { // select from database @@ -378,9 +329,9 @@ public class SWAPCallStackManager extends BaseCallstackManager { if (rs.next()) { entrySeq = rs.getLong(1); } - SqlConnectionManager.releaseResultSet(rs); + SqlConnectionManager.releaseResultSet(rs); } - + query = String.format(FunctionExitDBTable.USERCALLSTACK_QUERY, time); rs = SqlConnectionManager.executeQueryRS(query); if (rs == null) { @@ -391,34 +342,34 @@ public class SWAPCallStackManager extends BaseCallstackManager { } SqlConnectionManager.releaseResultSet(rs); } - + if (entrySeq < exitSeq) { // greater seq which time is less than sample/probe time seq = exitSeq; } else { seq = entrySeq; - } + } } catch (SQLException e) { Logger.exception(e); } } - + return seq; } - + public List getCallstackAddrListFromSeq(long seq) { List addrs = null; CallStackData csd = getCallStackDataBySeqMap().get(seq); - + if (null == csd) { // callstackdata is not in memory, find from DB List> callStackAddrs = CallStackInserter.getInstance() .getCallStackDataTable().getCallStackAddrsFromDB(seq); - + if (null == callStackAddrs || 0 == callStackAddrs.size() || null == callStackAddrs.get(0)) { // not found Logger.debug("CallStackData is not found for seq : " + seq); return null; } - + @SuppressWarnings("unchecked") List addressList = (List) callStackAddrs.get(0).get(0); @@ -426,17 +377,18 @@ public class SWAPCallStackManager extends BaseCallstackManager { addrs.addAll(addressList); } else { // callstackdata is in memory addrs = csd.getAddrs(); - } + } return addrs; } -//TODO: 1. execute select query once 2. change return type - > -//TODO: 3. additional discussion with leak analysis implementer if needed + + // TODO: 1. execute select query once 2. change return type - > + // TODO: 3. additional discussion with leak analysis implementer if needed public List> getArrayOfAddrListFromSeq(List seqs) { List> addrsList = null; if (null == seqs) { return null; } - + addrsList = new ArrayList>(); int size = seqs.size(); for (int i = 0; i < size; i++) { @@ -445,53 +397,8 @@ public class SWAPCallStackManager extends BaseCallstackManager { addrsList.add(addrs); } } - - return addrsList; - } - - public void clear() { - callstackApiAddrByPidMap.clear(); - callstackDataBySeqMap.clear(); - userFunctionBin = null; - userCallstackByTidMap.clear(); - dupUserCallByTidMap.clear(); - seqTimeByTidMap.clear(); - } - - public boolean isAddrInBinaryRange(int pid, long time, long addr) { - ProcessMemoryMap pmap = Global.getProject().getProcessInformation(pid) - .getProcessMemoryMap(time); - if (null == pmap) { - return false; - } - // return true when addr is within memory range of main executable - // or library which is set in the binary setting - if (addr >= pmap.getMainbinary().getLowestAddress() - && addr <= pmap.getMainbinary().getHighestAddress()) { - return true; - } - List binDataList = BinarySettingManager.getInstance() - .getBinarySettingList(); - List binPaths = new ArrayList(); - for (BinarySettingData binData : binDataList) { - binPaths.add(binData.getBinaryPath()); - } - // TODO: performance improvement - int size = binPaths.size(); - for (int i = 0; i < size; i++) { - String binPath = binPaths.get(i); - BinaryInfo bininfo = Global.getProject().getDeviceStatusInfo() - .getBinaryInfo(binPath); - LibraryObject libObj = pmap.getLibraryByBinaryID(bininfo.getID()); - if (null == libObj) { - continue; - } - if (addr >= libObj.getLowestAddress() && addr <= libObj.getHighestAddress()) { - return true; - } - } - return false; + return addrsList; } public boolean isPieBuild(int pid, long time) { diff --git a/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/swap/logparser/LogParser.java b/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/swap/logparser/LogParser.java index 6b0be95..595de7e 100755 --- a/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/swap/logparser/LogParser.java +++ b/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/swap/logparser/LogParser.java @@ -201,11 +201,11 @@ public class LogParser extends DataThread> { case MSG_PROBE_SCREENSHOT: processScreenshotData((ScreenShotData) log); packLog(log, logPack); - AnalyzerManager.getCallstackManager().makeCallstackWithoutBacktrace(log); + AnalyzerManager.getRuntimeCallstackManager().makeCallstackWithoutBacktrace(log); break; default: packLog(log, logPack); - AnalyzerManager.getCallstackManager().makeCallstackWithoutBacktrace(log); + AnalyzerManager.getRuntimeCallstackManager().makeCallstackWithoutBacktrace(log); break; } } @@ -242,7 +242,7 @@ public class LogParser extends DataThread> { } } - AnalyzerManager.getCallstackManager().makeUserCallstack(pData, + AnalyzerManager.getRuntimeCallstackManager().makeUserCallstack(pData, FunctionUsageProfiler.getInstance().getProfileDataMakerByPid(pData.getPid())); } diff --git a/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/ui/info/callstack/CallStackInserter.java b/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/ui/info/callstack/CallStackInserter.java index 69df153..78d1343 100644 --- a/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/ui/info/callstack/CallStackInserter.java +++ b/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/ui/info/callstack/CallStackInserter.java @@ -170,10 +170,10 @@ public class CallStackInserter implements Runnable { removeCallstackData(lastInsertSeq); } // clear SeqTimeMap if number of entries over > 1M - List tids = AnalyzerManager.getCallstackManager().getTidsOfSeqTimeMap(); + List tids = AnalyzerManager.getRuntimeCallstackManager().getTidsOfSeqTimeMap(); int size = tids.size(); for (int i = 0; i < size; i++) { - NavigableMap seqByTimeMap = AnalyzerManager.getCallstackManager() + NavigableMap seqByTimeMap = AnalyzerManager.getRuntimeCallstackManager() .getSeqTimeByTidMap(tids.get(i)); if (seqByTimeMap.size() > DALimit.MAX_CALLSTACK_SEQTIMEMAP_SIZE) { seqByTimeMap.clear(); @@ -194,7 +194,7 @@ public class CallStackInserter implements Runnable { } private void removeCallstackData(long seq) { - NavigableMap callstackDataMap = AnalyzerManager.getCallstackManager() + NavigableMap callstackDataMap = AnalyzerManager.getRuntimeCallstackManager() .getCallStackDataBySeqMap(); SortedMap headMap = callstackDataMap.headMap(seq); Iterator> itr = headMap.entrySet().iterator(); diff --git a/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/ui/info/callstack/CallStackUnit.java b/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/ui/info/callstack/CallStackUnit.java index 07899d4..29f290e 100644 --- a/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/ui/info/callstack/CallStackUnit.java +++ b/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/ui/info/callstack/CallStackUnit.java @@ -39,7 +39,6 @@ import org.tizen.dynamicanalyzer.util.Logger; public class CallStackUnit { private long address; private long functionStartAddress; - private String originSymbol; private String path; private String functionName; private String offset; @@ -50,55 +49,50 @@ public class CallStackUnit { // TODO: get path and function name as parameter, not symbol public CallStackUnit(long addr, String symbol, LogData log) { - address = addr; - functionStartAddress = addr; - this.originSymbol = symbol; + this.address = addr; + this.functionStartAddress = addr; this.time = log.getTime(); - this.functionId = AnalyzerConstants.INVALID_ID; - - functionName = CommonConstants.EMPTY; - offset = CommonConstants.EMPTY; - etc = CommonConstants.EMPTY; this.pid = log.getPid(); - makeCallstackData(); + this.functionId = AnalyzerConstants.INVALID_ID; + this.functionName = CommonConstants.EMPTY; + this.offset = CommonConstants.EMPTY; + this.etc = CommonConstants.EMPTY; + makeCallstackData(symbol); } public CallStackUnit(long addr, String symbol, int functionId, LogData log) { - address = addr; - functionStartAddress = addr; - this.originSymbol = symbol; + this.address = addr; + this.functionStartAddress = addr; this.time = log.getTime(); - this.functionId = functionId; - - functionName = CommonConstants.EMPTY; - offset = CommonConstants.EMPTY; - etc = CommonConstants.EMPTY; this.pid = log.getPid(); - makeCallstackData(); + this.functionId = functionId; + this.functionName = CommonConstants.EMPTY; + this.offset = CommonConstants.EMPTY; + this.etc = CommonConstants.EMPTY; + makeCallstackData(symbol); } /** using open trace **/ public CallStackUnit(long addr, int pid, int functionId, int binaryId) { - address = addr; - functionStartAddress = addr; - originSymbol = CommonConstants.EMPTY; + this.address = addr; + this.functionStartAddress = addr; this.time = -1; + this.pid = pid; this.functionId = functionId; - this.functionName = Global.getFunctionName(functionId); + BinaryInfo bInfo = Global.getProject().getDeviceStatusInfo().getBinaryInfo(binaryId); this.path = bInfo.getTargetBinaryPath(); - offset = CommonConstants.EMPTY; - etc = CommonConstants.EMPTY; - this.pid = pid; + this.offset = CommonConstants.EMPTY; + this.etc = CommonConstants.EMPTY; } - private void makeCallstackData() { + private void makeCallstackData(String symbol) { // callstack symbol format : path(functionName // ex. /usr/lib/libpthread.so(pthread_create - String[] splitPath = originSymbol.split("\\(", 2); //$NON-NLS-1$ + String[] splitPath = symbol.split("\\(", 2); //$NON-NLS-1$ path = splitPath[0]; - if (!path.startsWith("/") && !path.contains(FunctionUsageProfiler.APPLICATION) //$NON-NLS-1$ + if (!path.startsWith("/") && !path.contains(FunctionUsageProfiler.APPLICATION) && !path.contains(FunctionUsageProfiler.DEPENDENT_LIB)) { path = InformationViewLabels.CALLSTACK_TABLE_UNKNOWN_LIBRARY; } @@ -132,10 +126,6 @@ public class CallStackUnit { return functionStartAddress; } - public String getOriginSymbol() { - return originSymbol; - } - public String getSymbol() { return path + CommonConstants.OPEN_BRACKET + functionName; } diff --git a/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/ui/info/callstack/CallstackTable.java b/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/ui/info/callstack/CallstackTable.java index 9010c22..58fb6cb 100644 --- a/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/ui/info/callstack/CallstackTable.java +++ b/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/ui/info/callstack/CallstackTable.java @@ -136,13 +136,13 @@ public class CallstackTable extends DATableComposite { } Map addrMap = AnalyzerManager - .getCallstackManager().getCallStackApiAddrByPidMap(pid); + .getRuntimeCallstackManager().getCallStackApiAddrByPidMap(pid); if (null == addrMap) { return; } List addrs = null; - addrs = AnalyzerManager.getCallstackManager().getCallstackAddrListFromSeq(seqNum); + addrs = AnalyzerManager.getRuntimeCallstackManager().getCallstackAddrListFromSeq(seqNum); if (null == addrs) { return; } diff --git a/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/ui/range/RangeDataManager.java b/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/ui/range/RangeDataManager.java index d5fe54e..ab313ee 100644 --- a/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/ui/range/RangeDataManager.java +++ b/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/ui/range/RangeDataManager.java @@ -34,20 +34,21 @@ import java.util.ArrayList; import java.util.Comparator; import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.PriorityQueue; import org.eclipse.swt.SWT; import org.eclipse.swt.widgets.Display; import org.tizen.dynamicanalyzer.common.AnalyzerManager; -import org.tizen.dynamicanalyzer.communicator.DACommunicator; import org.tizen.dynamicanalyzer.database.SqlConnectionManager; import org.tizen.dynamicanalyzer.swap.callstack.BaseCallstackManager; -import org.tizen.dynamicanalyzer.swap.callstack.SWAPCallStackManager; +import org.tizen.dynamicanalyzer.swap.callstack.RangeCallstackManager; import org.tizen.dynamicanalyzer.swap.channel.data.DataChannelConstants; import org.tizen.dynamicanalyzer.swap.model.data.ProfileData; import org.tizen.dynamicanalyzer.ui.summary.SummaryDataManager; import org.tizen.dynamicanalyzer.ui.summary.profiling.FunctionSampleDBTable; import org.tizen.dynamicanalyzer.ui.summary.profiling.ProfileDataMaker; +import org.tizen.dynamicanalyzer.ui.summary.profiling.RangeProfileDataMaker; import org.tizen.dynamicanalyzer.ui.timeline.TimelinePage; import org.tizen.dynamicanalyzer.ui.timeline.calltrace.FunctionEntryDBTable; import org.tizen.dynamicanalyzer.ui.timeline.calltrace.FunctionExitDBTable; @@ -63,10 +64,8 @@ import org.tizen.dynamicanalyzer.widgets.da.view.DATabComposite; public class RangeDataManager implements Runnable { private static RangeDataManager instance = null; private Thread rangeThread = null; - // private FileDataMaker fileDataMaker = null; - private HashMap profileDataMakerMap = null; - private HashMap swapProfileDataMakerMap = null; - private BaseCallstackManager swapCallstackManager = null; + private Map profileDataMakerMap = null; + private BaseCallstackManager rangeCallstackManager = null; private long markerStartTime = 0; private long markerEndTime = 0; @@ -103,18 +102,13 @@ public class RangeDataManager implements Runnable { } private RangeDataManager() { - swapCallstackManager = new SWAPCallStackManager(true); - - // fileDataMaker = new FileDataMaker(failedChecker, leakDetector, - // warningChecker); + rangeCallstackManager = new RangeCallstackManager(); } public void clearRange() { - swapCallstackManager.clear(); + rangeCallstackManager.clear(); if (profileDataMakerMap != null) profileDataMakerMap.clear(); - if (swapProfileDataMakerMap != null) - swapProfileDataMakerMap.clear(); SummaryDataManager.getInstance().getLeakDataMaker().clearLeakDataForRange(); } @@ -185,25 +179,18 @@ public class RangeDataManager implements Runnable { return pids; } - public synchronized HashMap getProfileDataMakerMap() { - if (DACommunicator.isSWAPVersion()) { - if (null == swapProfileDataMakerMap) { - swapProfileDataMakerMap = new HashMap(); - } - return swapProfileDataMakerMap; - } else { - if (null == profileDataMakerMap) { - profileDataMakerMap = new HashMap(); - } - return profileDataMakerMap; + public synchronized Map getProfileDataMakerMap() { + if (null == profileDataMakerMap) { + profileDataMakerMap = new HashMap(); } + return profileDataMakerMap; } public ProfileDataMaker getProfileDataMakerByPid(int pid) { ProfileDataMaker profileDataMaker = getProfileDataMakerMap().get(pid); if (null == profileDataMaker) { // if (DACommunicator.isSWAPVersion()) { - profileDataMaker = new ProfileDataMaker(swapCallstackManager); + profileDataMaker = new RangeProfileDataMaker(rangeCallstackManager); // } profileDataMaker.setPid(pid); getProfileDataMakerMap().put(pid, profileDataMaker); @@ -328,7 +315,7 @@ public class RangeDataManager implements Runnable { DataChannelConstants.MSG_FUNCTION_ENTRY, rsEntry); pQueue.offer(pEntry); } - swapCallstackManager.makeUserCallstackforRange(top, profileDataMaker); + rangeCallstackManager.makeUserCallstack(top, profileDataMaker); break; case DataChannelConstants.MSG_FUNCTION_EXIT: if (rsExit.next()) { @@ -336,14 +323,14 @@ public class RangeDataManager implements Runnable { DataChannelConstants.MSG_FUNCTION_EXIT, rsExit); pQueue.offer(pExit); } - swapCallstackManager.makeUserCallstackforRange(top, profileDataMaker); + rangeCallstackManager.makeUserCallstack(top, profileDataMaker); break; case DataChannelConstants.MSG_DATA_SAMPLE: if (rsSample.next()) { ProfileData pSample = makeSampleProfileData(rsSample); pQueue.offer(pSample); } - profileDataMaker.makeFunctionUsageProfileDataforRange(top); + profileDataMaker.makeFunctionUsageProfileData(top); break; default: // never goes here Logger.error("Wrong data from selecting function profiling data inside range"); diff --git a/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/ui/summary/profiling/FunctionUsageProfiler.java b/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/ui/summary/profiling/FunctionUsageProfiler.java index b78477b..2bbf2de 100644 --- a/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/ui/summary/profiling/FunctionUsageProfiler.java +++ b/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/ui/summary/profiling/FunctionUsageProfiler.java @@ -121,7 +121,7 @@ public class FunctionUsageProfiler extends PageDataManager { public ProfileDataMaker getProfileDataMakerByPid(int pid) { ProfileDataMaker profileDataMaker = getProfileDataMakerMap().get(pid); if (null == profileDataMaker) { - profileDataMaker = new ProfileDataMaker(AnalyzerManager.getCallstackManager()); + profileDataMaker = new RuntimeProfileDataMaker(); profileDataMaker.setPid(pid); getProfileDataMakerMap().put(pid, profileDataMaker); } @@ -141,6 +141,7 @@ public class FunctionUsageProfiler extends PageDataManager { if (profileDataMakerMap != null) { profileDataMakerMap.clear(); } + ProfilingData.clear(); // reset internal sequence number } public void saveProfilingData() { @@ -261,7 +262,7 @@ public class FunctionUsageProfiler extends PageDataManager { getInstance().getProfileDataMakerByPid(sample.get(i).getPid()) .makeFunctionUsageProfileData(sampleLog); // set LastSampleSeq - NavigableMap seqByTimeMap = AnalyzerManager.getCallstackManager() + NavigableMap seqByTimeMap = AnalyzerManager.getRuntimeCallstackManager() .getSeqTimeByTidMap(sampleLog.getTid()); // find the time of callstackdata which was made // right before the current sample time diff --git a/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/ui/summary/profiling/ProfileDataMaker.java b/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/ui/summary/profiling/ProfileDataMaker.java index 24b532c..51e29e3 100644 --- a/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/ui/summary/profiling/ProfileDataMaker.java +++ b/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/ui/summary/profiling/ProfileDataMaker.java @@ -29,25 +29,23 @@ package org.tizen.dynamicanalyzer.ui.summary.profiling; import static org.tizen.dynamicanalyzer.swap.channel.data.DataChannelConstants.MSG_FUNCTION_EXIT; -import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; -import org.tizen.dynamicanalyzer.common.AnalyzerConstants; -import org.tizen.dynamicanalyzer.common.path.PathConstants; -import org.tizen.dynamicanalyzer.communicator.DACommunicator; +import org.tizen.dynamicanalyzer.common.Global; +import org.tizen.dynamicanalyzer.project.AppInfo; +import org.tizen.dynamicanalyzer.project.BinaryInfo; import org.tizen.dynamicanalyzer.swap.callstack.BaseCallstackManager; import org.tizen.dynamicanalyzer.swap.model.data.LogData; import org.tizen.dynamicanalyzer.swap.model.data.ProfileData; -import org.tizen.dynamicanalyzer.ui.info.callstack.CallStackData; import org.tizen.dynamicanalyzer.ui.info.callstack.CallStackItem; import org.tizen.dynamicanalyzer.ui.info.callstack.CallStackUnit; import org.tizen.dynamicanalyzer.util.Logger; import org.tizen.dynamicanalyzer.utils.Formatter; -public class ProfileDataMaker { +public abstract class ProfileDataMaker { static class CallstackTree { ProfilingData me; CallstackTree parent; @@ -75,22 +73,22 @@ public class ProfileDataMaker { } } - private HashMap callstackTreeByTidMap = new HashMap(); - private int totalSampleCount = 0; - private BaseCallstackManager callstackManager = null; + private Map callstackTreeByTidMap = new HashMap(); + protected int totalSampleCount = 0; + protected BaseCallstackManager callstackManager = null; private int pid = 0; - + /** - * key: ID - value : function usage profiling data hash map all function - * usage profiling data are in this hash map + * key: ID - value : function usage profiling data hash map all function usage profiling data + * are in this hash map **/ - private ConcurrentHashMap profilingDataMap = null; - private ConcurrentHashMap symbolIDHash = null; + private Map profilingDataMap = null; + private Map symbolIDHash = null; /** * key : ID - value : child ID list // all child lists are in this hash */ - private ConcurrentHashMap childListMap = null; + private Map childListMap = null; private ProfilingData appBin = null; private ProfilingData dependentLib = null; @@ -111,10 +109,6 @@ public class ProfileDataMaker { callstackTreeByTidMap.clear(); } - public BaseCallstackManager getCallstackManager() { - return callstackManager; - } - public int getPid() { return pid; } @@ -122,7 +116,7 @@ public class ProfileDataMaker { public void setPid(int pid) { this.pid = pid; } - + public String getAppBinName() { return appBinName; } @@ -183,29 +177,29 @@ public class ProfileDataMaker { public CallstackTree getCurrentCallstackTree(int tid) { CallstackTree current = callstackTreeByTidMap.get(tid); - return current; + return current; } - + public void putCurrentCallstackTree(int tid, CallstackTree current) { callstackTreeByTidMap.put(tid, current); - return; - } - + return; + } + public String getCpuRate(ProfilingData data, boolean exclusive) { int count = 0; double rate = 0.; if (exclusive) { count = data.getExCount(); - if(totalSampleCount == 0) { + if (totalSampleCount == 0) { rate = 0; - } else { + } else { rate = count / (double) totalSampleCount * 100; } } else { count = data.getInCount(); - if(totalSampleCount == 0) { + if (totalSampleCount == 0) { rate = 0; - } else { + } else { rate = count / (double) totalSampleCount * 100; } } @@ -224,12 +218,15 @@ public class ProfileDataMaker { return Long.toString(count * FunctionUsageProfiler.SAMPLE_TIME); } - private void checkUserCall(CallStackUnit csa, ProfilingData parent, - ProfilingData pp, LogData log) { - if (callstackManager.checkUserCall(csa.getPath())) { + protected void checkUserCall(CallStackUnit csa, ProfilingData parent, ProfilingData pp, + LogData log) { + AppInfo appInfo = Global.getProject().getApplicationInfo(); + BinaryInfo binfo = Global.getProject().getDeviceStatusInfo() + .getBinaryInfo(appInfo.getExecBinaryPath()); + if (binfo.getTargetBinaryPath().equals(csa.getPath())) { if (null == appBin) { - CallStackUnit appBinCsa = new CallStackUnit(-1, - FunctionUsageProfiler.APPLICATION, log); + CallStackUnit appBinCsa = new CallStackUnit(-1, FunctionUsageProfiler.APPLICATION, + log); appBin = makeNewProfilingData(appBinCsa, true); appBin.setKey(FunctionUsageProfiler.APPLICATION_KEY); appBinName = csa.getPath(); @@ -253,355 +250,12 @@ public class ProfileDataMaker { } } } - - public void makeFunctionUsageProfileData(ProfileData sampleLog) { - totalSampleCount++; - List addrs = null; - long selfAddr = sampleLog.getPcAddr(); - int pid = sampleLog.getPid(); - - if(DACommunicator.isSWAPVersion()) { - long userCallstackSeq; - int tid = sampleLog.getTid(); - long sampleTime = sampleLog.getTime(); - - CallStackData callstackData; - Map addrMap = callstackManager - .getCallStackApiAddrByPidMap(pid); - - CallStackUnit callstackUnit = addrMap.get(selfAddr); - if (null == callstackUnit) { - CallStackUnit newCallstackUnit = new CallStackUnit(selfAddr, - callstackManager.getCallStackSymbol(selfAddr, pid, sampleTime), sampleLog); - callstackManager.offerCallStackUnit(newCallstackUnit); - addrMap.put(selfAddr, newCallstackUnit); - } - - userCallstackSeq = callstackManager.getSeqOfUserCallstackForTime(tid, sampleTime); - if (-1 != userCallstackSeq) { - callstackData = callstackManager.getCallStackDataBySeqMap().get(userCallstackSeq); - if (null == callstackData) { - Logger.debug("CallStackData is not found for seq : " + userCallstackSeq); - addrs = new ArrayList(); - addrs.add(selfAddr); - } else { - addrs = new ArrayList(callstackData.getAddrs()); - for(int i = 0; i < addrs.size(); i++) { - if(addrs.get(i) == 0) { - addrs.remove(i); - } - } - addrs.add(0, selfAddr); - } - } else { -// Logger.debug("makeFunctionUsageProfileData : cannot find seq by time"); - addrs = new ArrayList(); - addrs.add(selfAddr); - } - - } else { - String callstack = sampleLog.getCallstack(); - if (null == callstack) { - return; - } - String[] splitCallstack = callstack - .split(AnalyzerConstants.DATA_PARSING_TOKEN); - - List sampleCallstack = new ArrayList(); - - for (int i = 0; i < splitCallstack.length; i++) { - sampleCallstack.add(new String(splitCallstack[i])); - } - - addrs = makeCallstackHashAndList(sampleCallstack, sampleLog); - } - - Map addrMap = callstackManager - .getCallStackApiAddrByPidMap(pid); - CallStackUnit inputData = addrMap.get(selfAddr); - if (null == inputData) { - return; - } - - // drop samples of probe library - if (inputData.getPath().startsWith(PathConstants.DA_REMOTE_PROBE_PATH)) { - return; - } - - String inputPath = inputData.getPath(); - String inputFuncName = inputData.getFunctionName(); - - ProfilingData parent = getProfilingDataByKey(inputPath); - // exclusive cpu time - if (null == parent) { - parent = makeNewProfilingData(inputData, true); - checkUserCall(inputData, parent, null, sampleLog); - if (inputFuncName.equals(FunctionUsageProfiler.UNKNOWN)) { - parent.addExCount(); - } else { - ProfilingData child = makeNewProfilingData(inputData, false); - parent.addChild(child); - child.addExCount(); - child.setParent(parent.getName()); - } - } else { - if (inputFuncName.isEmpty()) { - parent.addExCount(); - } else { - ProfilingData child = getProfilingDataByKey(inputData - .getSymbol()); - if (null == child) { - child = makeNewProfilingData(inputData, false); - parent.addChild(child); - child.setParent(parent.getName()); - } - child.addExCount(); - } - } - - // inclusive cpu time - int size = 0; - if (null != addrs) { - size = addrs.size(); - } - for (int i = 0; i < size; i++) { - CallStackUnit callstackCsa = addrMap.get(addrs.get(i)); - - if (callstackCsa.getFunctionName().equals( - FunctionUsageProfiler.UNKNOWN)) { - ProfilingData inParent = getProfilingDataByKey(callstackCsa - .getPath()); - ProfilingData pp = null; - if (null == inParent) { - inParent = makeNewProfilingData(callstackCsa, true); - checkUserCall(callstackCsa, inParent, pp, sampleLog); - } - inParent.addInCount(totalSampleCount); - - if (null != inParent.getParent()) { - String pInParentName = inParent.getParent(); - pp = getProfilingDataByKey(pInParentName); - if (null != pp) { - pp.addInCount(totalSampleCount); - } - } - } else { - ProfilingData fupData = getProfilingDataByKey(callstackCsa - .getSymbol()); - if (null == fupData) { - ProfilingData inParent = getProfilingDataByKey(callstackCsa - .getPath()); - if (null == inParent) { - inParent = makeNewProfilingData(callstackCsa, true); - checkUserCall(callstackCsa, inParent, null, sampleLog); - } - fupData = makeNewProfilingData(callstackCsa, false); - fupData.setParent(inParent.getName()); - - inParent.addChild(fupData); - inParent.addInCount(totalSampleCount); - if (null != inParent.getParent()) { - String pInParentName = inParent.getParent(); - ProfilingData pp = getProfilingDataByKey(pInParentName); - if (null != pp) { - pp.addInCount(totalSampleCount); - } - } - } else { - String pName = fupData.getParent(); - ProfilingData inParent = getProfilingDataByKey(pName); - if (inParent == null) { - Logger.error("ProfilingData: function item without library item"); - continue; - } - inParent.addInCount(totalSampleCount); - - if (null != inParent.getParent()) { - String pInParentName = inParent.getParent(); - ProfilingData ppData = getProfilingDataByKey(pInParentName); - if (null != ppData) { - ppData.addInCount(totalSampleCount); - } - } - } - fupData.addInCount(totalSampleCount); - } - } - } - // TODO: divide this method into sub-methods, redesign data process - public void makeFunctionUsageProfileDataforRange(ProfileData sampleLog) { - totalSampleCount++; - List addrs = new ArrayList(); - long selfAddr = sampleLog.getPcAddr(); - int pid = sampleLog.getPid(); - int tid = sampleLog.getTid(); - long sampleTime = sampleLog.getTime(); - - Map addrMap = callstackManager - .getCallStackApiAddrByPidMap(pid); - - CallStackUnit selfCallstackUnit = addrMap.get(selfAddr); - if (null == selfCallstackUnit) { - selfCallstackUnit = new CallStackUnit(selfAddr, - callstackManager.getCallStackSymbol(selfAddr, pid, sampleTime), sampleLog); - addrMap.put(selfAddr, selfCallstackUnit); - } - - List userCallstack = callstackManager.getUserCallstack(tid); - int callstackSize = userCallstack.size(); - - for (int i = 0; i < callstackSize; i++) { - long addr = userCallstack.get(i).getCallStackUnit().getAddr(); - addrs.add(addr); - } - addrs.add(selfAddr); - - // drop samples of probe library - if (selfCallstackUnit.getPath().startsWith(PathConstants.DA_REMOTE_PROBE_PATH)) { - return; - } - String inputPath = selfCallstackUnit.getPath(); - String inputFuncName = selfCallstackUnit.getFunctionName(); + abstract public void makeFunctionUsageProfileData(ProfileData sampleLog); - ProfilingData parent = getProfilingDataByKey(inputPath); - // exclusive cpu time - if (null == parent) { - parent = makeNewProfilingData(selfCallstackUnit, true); - checkUserCall(selfCallstackUnit, parent, null, sampleLog); - if (inputFuncName.equals(FunctionUsageProfiler.UNKNOWN)) { - parent.addExCount(); - } else { - ProfilingData child = makeNewProfilingData(selfCallstackUnit, false); - parent.addChild(child); - child.addExCount(); - child.setParent(parent.getName()); - } - } else { - if (inputFuncName.isEmpty()) { - parent.addExCount(); - } else { - ProfilingData child = getProfilingDataByKey(selfCallstackUnit - .getSymbol()); - if (null == child) { - child = makeNewProfilingData(selfCallstackUnit, false); - parent.addChild(child); - child.setParent(parent.getName()); - } - child.addExCount(); - } - } - - // inclusive cpu time - int size = 0; - if (null != addrs) { - size = addrs.size(); - } - for (int i = 0; i < size; i++) { - CallStackUnit callstackCsa = addrMap.get(addrs.get(i)); - - if (callstackCsa.getFunctionName().equals( - FunctionUsageProfiler.UNKNOWN)) { - ProfilingData inParent = getProfilingDataByKey(callstackCsa - .getPath()); - ProfilingData pp = null; - if (null == inParent) { - inParent = makeNewProfilingData(callstackCsa, true); - checkUserCall(callstackCsa, inParent, pp, sampleLog); - } - inParent.addInCount(totalSampleCount); - - if (null != inParent.getParent()) { - String pInParentName = inParent.getParent(); - pp = getProfilingDataByKey(pInParentName); - if (null != pp) { - pp.addInCount(totalSampleCount); - } - } - } else { - ProfilingData fupData = getProfilingDataByKey(callstackCsa - .getSymbol()); - if (null == fupData) { - ProfilingData inParent = getProfilingDataByKey(callstackCsa - .getPath()); - if (null == inParent) { - inParent = makeNewProfilingData(callstackCsa, true); - checkUserCall(callstackCsa, inParent, null, sampleLog); - } - fupData = makeNewProfilingData(callstackCsa, false); - fupData.setParent(inParent.getName()); - - inParent.addChild(fupData); - inParent.addInCount(totalSampleCount); - if (null != inParent.getParent()) { - String pInParentName = inParent.getParent(); - ProfilingData pp = getProfilingDataByKey(pInParentName); - if (null != pp) { - pp.addInCount(totalSampleCount); - } - } - } else { - String pName = fupData.getParent(); - ProfilingData inParent = getProfilingDataByKey(pName); - inParent.addInCount(totalSampleCount); - - if (null != inParent.getParent()) { - String pInParentName = inParent.getParent(); - ProfilingData ppData = getProfilingDataByKey(pInParentName); - if (null != ppData) { - ppData.addInCount(totalSampleCount); - } - } - } - fupData.addInCount(totalSampleCount); - } - } - } - - private List makeCallstackHashAndList(List callstackLog, - LogData log) { - int pid = log.getPid(); - Map addrMap = callstackManager - .getCallStackApiAddrByPidMap(pid); - List addrs = new ArrayList(); - int size = callstackLog.size(); - for (int i = 1; i + 1 < size; i += 2) { - if (callstackLog.get(i).equals(AnalyzerConstants.CALLSTACK_END) - || callstackLog.get(i + 1).equals( - AnalyzerConstants.CALLSTACK_END)) { - break; - } - String addrStr = callstackLog.get(i); - if (addrStr.isEmpty()) { - return null; - } - long addr = 0; - try { - addr = Long.parseLong(addrStr); - } catch (NumberFormatException e) { - Logger.exception(e); - return null; - } - addrs.add(addr); - - CallStackUnit callstackUnit = addrMap.get(addr); - if (null == callstackUnit) { - String funcName = callstackLog.get(i + 1); - CallStackUnit newCallstackUnit = new CallStackUnit(addr, - funcName, log); - callstackManager.offerCallStackUnit(newCallstackUnit); - addrMap.put(addr, newCallstackUnit); - } - } - return addrs; - } - - private ProfilingData makeNewProfilingData(CallStackUnit inputData, - boolean isParent) { - ProfilingData newProfilingData = new ProfilingData(inputData, isParent, - this); - getProfilingDataMap().put(newProfilingData.getProfilingDataID(), - newProfilingData); + protected ProfilingData makeNewProfilingData(CallStackUnit inputData, boolean isParent) { + ProfilingData newProfilingData = new ProfilingData(inputData, isParent, this); + getProfilingDataMap().put(newProfilingData.getProfilingDataID(), newProfilingData); if (isParent) { getSymbolIDHash().put(inputData.getPath(), Integer.toString(newProfilingData.getProfilingDataID())); @@ -612,8 +266,7 @@ public class ProfileDataMaker { return newProfilingData; } - public void makeFupDataForCallTrace(CallStackUnit inputCallstackApiData, - ProfileData log) { + public void makeFupDataForCallTrace(CallStackUnit inputCallstackApiData, ProfileData log) { long exeTime = 0; int type = log.getMsgID(); int tid = log.getTid(); @@ -622,29 +275,27 @@ public class ProfileDataMaker { List userCallstack = callstackManager.getUserCallstack(tid); int size = userCallstack.size(); - - if (type == MSG_FUNCTION_EXIT) { - if(size == 0 || - userCallstack.get(size - 1).getCallStackUnit() - .getFunctionId() != inputCallstackApiData.getFunctionId()) { - Logger.debug("exit without entry or EXIT self is not the same as top of user callstack :" - + inputCallstackApiData.getFunctionName()); //$NON-NLS-1$ + + if (type == MSG_FUNCTION_EXIT) { + if (size == 0 + || userCallstack.get(size - 1).getCallStackUnit().getFunctionId() != inputCallstackApiData + .getFunctionId()) { + Logger.debug("exit without entry or EXIT self is not the same as top of user callstack :" + + inputCallstackApiData.getFunctionName()); //$NON-NLS-1$ return; } startTime = userCallstack.get(size - 1).getStartTime(); - if(startTime != -1) { + if (startTime != -1) { exeTime += time - startTime; - } - } + } + } - ProfilingData parent = getProfilingDataByKey(inputCallstackApiData - .getPath()); + ProfilingData parent = getProfilingDataByKey(inputCallstackApiData.getPath()); if (null == parent) { parent = makeNewProfilingData(inputCallstackApiData, true); checkUserCall(inputCallstackApiData, parent, null, log); - ProfilingData child = makeNewProfilingData(inputCallstackApiData, - false); + ProfilingData child = makeNewProfilingData(inputCallstackApiData, false); parent.addChild(child); child.addElapsedTime(exeTime); child.setParent(parent.getName()); @@ -653,8 +304,7 @@ public class ProfileDataMaker { child.addCallCount(); } } else { // null != parent - ProfilingData child = getProfilingDataByKey(inputCallstackApiData - .getSymbol()); + ProfilingData child = getProfilingDataByKey(inputCallstackApiData.getSymbol()); if (null == child) { child = makeNewProfilingData(inputCallstackApiData, false); parent.addChild(child); @@ -666,7 +316,7 @@ public class ProfileDataMaker { } // calculate internal time - CallstackTree current = getCurrentCallstackTree(tid); + CallstackTree current = getCurrentCallstackTree(tid); if (type == MSG_FUNCTION_EXIT) { if (null == current) { // bug @@ -674,11 +324,10 @@ public class ProfileDataMaker { } else { CallstackTree parentCt = current.getParent(); if (null != parentCt) { - parentCt.addChildExeTime(current.getThis() - .getLastElapsedTime()); + parentCt.addChildExeTime(current.getThis().getLastElapsedTime()); } child.addExclusiveElapsedTime(current.getExclusiveExeTime()); - putCurrentCallstackTree(tid, current.getParent()); + putCurrentCallstackTree(tid, current.getParent()); } } else { if (null == current) { diff --git a/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/ui/summary/profiling/RangeProfileDataMaker.java b/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/ui/summary/profiling/RangeProfileDataMaker.java new file mode 100644 index 0000000..a537bae --- /dev/null +++ b/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/ui/summary/profiling/RangeProfileDataMaker.java @@ -0,0 +1,169 @@ +/* + * Dynamic Analyzer + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: + * WooJin Jung + * Jooyoul Lee + * Juyoung Kim + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Contributors: + * - S-Core Co., Ltd + * + */ +package org.tizen.dynamicanalyzer.ui.summary.profiling; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import org.tizen.dynamicanalyzer.common.path.PathConstants; +import org.tizen.dynamicanalyzer.swap.callstack.BaseCallstackManager; +import org.tizen.dynamicanalyzer.swap.model.data.ProfileData; +import org.tizen.dynamicanalyzer.ui.info.callstack.CallStackItem; +import org.tizen.dynamicanalyzer.ui.info.callstack.CallStackUnit; + +public class RangeProfileDataMaker extends ProfileDataMaker { + + public RangeProfileDataMaker(BaseCallstackManager callstackManager) { + super(callstackManager); + } + + @Override + public void makeFunctionUsageProfileData(ProfileData sampleLog) { + totalSampleCount++; + List addrs = new ArrayList(); + long selfAddr = sampleLog.getPcAddr(); + int pid = sampleLog.getPid(); + int tid = sampleLog.getTid(); + long sampleTime = sampleLog.getTime(); + + Map addrMap = callstackManager.getCallStackApiAddrByPidMap(pid); + + CallStackUnit selfCallstackUnit = addrMap.get(selfAddr); + if (null == selfCallstackUnit) { + selfCallstackUnit = new CallStackUnit(selfAddr, callstackManager.getCallStackSymbol( + selfAddr, pid, sampleTime), sampleLog); + addrMap.put(selfAddr, selfCallstackUnit); + } + + List userCallstack = callstackManager.getUserCallstack(tid); + int callstackSize = userCallstack.size(); + + for (int i = 0; i < callstackSize; i++) { + long addr = userCallstack.get(i).getCallStackUnit().getAddr(); + addrs.add(addr); + } + addrs.add(selfAddr); + + // drop samples of probe library + if (selfCallstackUnit.getPath().startsWith(PathConstants.DA_REMOTE_PROBE_PATH)) { + return; + } + + String inputPath = selfCallstackUnit.getPath(); + String inputFuncName = selfCallstackUnit.getFunctionName(); + + ProfilingData parent = getProfilingDataByKey(inputPath); + // exclusive cpu time + if (null == parent) { + parent = makeNewProfilingData(selfCallstackUnit, true); + checkUserCall(selfCallstackUnit, parent, null, sampleLog); + if (inputFuncName.equals(FunctionUsageProfiler.UNKNOWN)) { + parent.addExCount(); + } else { + ProfilingData child = makeNewProfilingData(selfCallstackUnit, false); + parent.addChild(child); + child.addExCount(); + child.setParent(parent.getName()); + } + } else { + if (inputFuncName.isEmpty()) { + parent.addExCount(); + } else { + ProfilingData child = getProfilingDataByKey(selfCallstackUnit.getSymbol()); + if (null == child) { + child = makeNewProfilingData(selfCallstackUnit, false); + parent.addChild(child); + child.setParent(parent.getName()); + } + child.addExCount(); + } + } + + // inclusive cpu time + int size = 0; + if (null != addrs) { + size = addrs.size(); + } + for (int i = 0; i < size; i++) { + CallStackUnit callstackCsa = addrMap.get(addrs.get(i)); + + if (callstackCsa.getFunctionName().equals(FunctionUsageProfiler.UNKNOWN)) { + ProfilingData inParent = getProfilingDataByKey(callstackCsa.getPath()); + ProfilingData pp = null; + if (null == inParent) { + inParent = makeNewProfilingData(callstackCsa, true); + checkUserCall(callstackCsa, inParent, pp, sampleLog); + } + inParent.addInCount(totalSampleCount); + + if (null != inParent.getParent()) { + String pInParentName = inParent.getParent(); + pp = getProfilingDataByKey(pInParentName); + if (null != pp) { + pp.addInCount(totalSampleCount); + } + } + } else { + ProfilingData fupData = getProfilingDataByKey(callstackCsa.getSymbol()); + if (null == fupData) { + ProfilingData inParent = getProfilingDataByKey(callstackCsa.getPath()); + if (null == inParent) { + inParent = makeNewProfilingData(callstackCsa, true); + checkUserCall(callstackCsa, inParent, null, sampleLog); + } + fupData = makeNewProfilingData(callstackCsa, false); + fupData.setParent(inParent.getName()); + + inParent.addChild(fupData); + inParent.addInCount(totalSampleCount); + if (null != inParent.getParent()) { + String pInParentName = inParent.getParent(); + ProfilingData pp = getProfilingDataByKey(pInParentName); + if (null != pp) { + pp.addInCount(totalSampleCount); + } + } + } else { + String pName = fupData.getParent(); + ProfilingData inParent = getProfilingDataByKey(pName); + inParent.addInCount(totalSampleCount); + + if (null != inParent.getParent()) { + String pInParentName = inParent.getParent(); + ProfilingData ppData = getProfilingDataByKey(pInParentName); + if (null != ppData) { + ppData.addInCount(totalSampleCount); + } + } + } + fupData.addInCount(totalSampleCount); + } + } + } + +} diff --git a/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/ui/summary/profiling/RuntimeProfileDataMaker.java b/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/ui/summary/profiling/RuntimeProfileDataMaker.java new file mode 100644 index 0000000..e4eb977 --- /dev/null +++ b/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/ui/summary/profiling/RuntimeProfileDataMaker.java @@ -0,0 +1,250 @@ +/* + * Dynamic Analyzer + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: + * WooJin Jung + * Jooyoul Lee + * Juyoung Kim + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Contributors: + * - S-Core Co., Ltd + * + */ +package org.tizen.dynamicanalyzer.ui.summary.profiling; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import org.tizen.dynamicanalyzer.common.AnalyzerConstants; +import org.tizen.dynamicanalyzer.common.AnalyzerManager; +import org.tizen.dynamicanalyzer.common.path.PathConstants; +import org.tizen.dynamicanalyzer.communicator.DACommunicator; +import org.tizen.dynamicanalyzer.swap.callstack.RuntimeCallstackManager; +import org.tizen.dynamicanalyzer.swap.model.data.LogData; +import org.tizen.dynamicanalyzer.swap.model.data.ProfileData; +import org.tizen.dynamicanalyzer.ui.info.callstack.CallStackData; +import org.tizen.dynamicanalyzer.ui.info.callstack.CallStackUnit; +import org.tizen.dynamicanalyzer.util.Logger; + +public class RuntimeProfileDataMaker extends ProfileDataMaker { + + public RuntimeProfileDataMaker() { + super(AnalyzerManager.getRuntimeCallstackManager()); + } + + public void makeFunctionUsageProfileData(ProfileData sampleLog) { + totalSampleCount++; + List addrs = null; + long selfAddr = sampleLog.getPcAddr(); + int pid = sampleLog.getPid(); + + if (DACommunicator.isSWAPVersion()) { + long userCallstackSeq; + int tid = sampleLog.getTid(); + long sampleTime = sampleLog.getTime(); + + CallStackData callstackData; + Map addrMap = callstackManager.getCallStackApiAddrByPidMap(pid); + + CallStackUnit callstackUnit = addrMap.get(selfAddr); + if (null == callstackUnit) { + CallStackUnit newCallstackUnit = new CallStackUnit(selfAddr, + callstackManager.getCallStackSymbol(selfAddr, pid, sampleTime), sampleLog); + ((RuntimeCallstackManager) callstackManager).offerCallStackUnit(newCallstackUnit); + addrMap.put(selfAddr, newCallstackUnit); + } + + userCallstackSeq = callstackManager.getSeqOfUserCallstackForTime(tid, sampleTime); + if (-1 != userCallstackSeq) { + callstackData = callstackManager.getCallStackDataBySeqMap().get(userCallstackSeq); + if (null == callstackData) { + Logger.debug("CallStackData is not found for seq : " + userCallstackSeq); + addrs = new ArrayList(); + addrs.add(selfAddr); + } else { + addrs = new ArrayList(callstackData.getAddrs()); + for (int i = 0; i < addrs.size(); i++) { + if (addrs.get(i) == 0) { + addrs.remove(i); + } + } + addrs.add(0, selfAddr); + } + } else { + // Logger.debug("makeFunctionUsageProfileData : cannot find seq by time"); + addrs = new ArrayList(); + addrs.add(selfAddr); + } + + } else { + String callstack = sampleLog.getCallstack(); + if (null == callstack) { + return; + } + String[] splitCallstack = callstack.split(AnalyzerConstants.DATA_PARSING_TOKEN); + + List sampleCallstack = new ArrayList(); + + for (int i = 0; i < splitCallstack.length; i++) { + sampleCallstack.add(new String(splitCallstack[i])); + } + + addrs = makeCallstackHashAndList(sampleCallstack, sampleLog); + } + + Map addrMap = callstackManager.getCallStackApiAddrByPidMap(pid); + CallStackUnit inputData = addrMap.get(selfAddr); + if (null == inputData) { + return; + } + + // drop samples of probe library + if (inputData.getPath().startsWith(PathConstants.DA_REMOTE_PROBE_PATH)) { + return; + } + + String inputPath = inputData.getPath(); + String inputFuncName = inputData.getFunctionName(); + + ProfilingData parent = getProfilingDataByKey(inputPath); + // exclusive cpu time + if (null == parent) { + parent = makeNewProfilingData(inputData, true); + checkUserCall(inputData, parent, null, sampleLog); + if (inputFuncName.equals(FunctionUsageProfiler.UNKNOWN)) { + parent.addExCount(); + } else { + ProfilingData child = makeNewProfilingData(inputData, false); + parent.addChild(child); + child.addExCount(); + child.setParent(parent.getName()); + } + } else { + if (inputFuncName.isEmpty()) { + parent.addExCount(); + } else { + ProfilingData child = getProfilingDataByKey(inputData.getSymbol()); + if (null == child) { + child = makeNewProfilingData(inputData, false); + parent.addChild(child); + child.setParent(parent.getName()); + } + child.addExCount(); + } + } + + // inclusive cpu time + int size = 0; + if (null != addrs) { + size = addrs.size(); + } + for (int i = 0; i < size; i++) { + CallStackUnit callstackCsa = addrMap.get(addrs.get(i)); + + if (callstackCsa.getFunctionName().equals(FunctionUsageProfiler.UNKNOWN)) { + ProfilingData inParent = getProfilingDataByKey(callstackCsa.getPath()); + ProfilingData pp = null; + if (null == inParent) { + inParent = makeNewProfilingData(callstackCsa, true); + checkUserCall(callstackCsa, inParent, pp, sampleLog); + } + inParent.addInCount(totalSampleCount); + + if (null != inParent.getParent()) { + String pInParentName = inParent.getParent(); + pp = getProfilingDataByKey(pInParentName); + if (null != pp) { + pp.addInCount(totalSampleCount); + } + } + } else { + ProfilingData fupData = getProfilingDataByKey(callstackCsa.getSymbol()); + if (null == fupData) { + ProfilingData inParent = getProfilingDataByKey(callstackCsa.getPath()); + if (null == inParent) { + inParent = makeNewProfilingData(callstackCsa, true); + checkUserCall(callstackCsa, inParent, null, sampleLog); + } + fupData = makeNewProfilingData(callstackCsa, false); + fupData.setParent(inParent.getName()); + + inParent.addChild(fupData); + inParent.addInCount(totalSampleCount); + if (null != inParent.getParent()) { + String pInParentName = inParent.getParent(); + ProfilingData pp = getProfilingDataByKey(pInParentName); + if (null != pp) { + pp.addInCount(totalSampleCount); + } + } + } else { + String pName = fupData.getParent(); + ProfilingData inParent = getProfilingDataByKey(pName); + if (inParent == null) { + Logger.error("ProfilingData: function item without library item"); + continue; + } + inParent.addInCount(totalSampleCount); + + if (null != inParent.getParent()) { + String pInParentName = inParent.getParent(); + ProfilingData ppData = getProfilingDataByKey(pInParentName); + if (null != ppData) { + ppData.addInCount(totalSampleCount); + } + } + } + fupData.addInCount(totalSampleCount); + } + } + } + + private List makeCallstackHashAndList(List callstackLog, LogData log) { + int pid = log.getPid(); + Map addrMap = callstackManager.getCallStackApiAddrByPidMap(pid); + List addrs = new ArrayList(); + int size = callstackLog.size(); + for (int i = 1; i + 1 < size; i += 2) { + if (callstackLog.get(i).equals(AnalyzerConstants.CALLSTACK_END) + || callstackLog.get(i + 1).equals(AnalyzerConstants.CALLSTACK_END)) { + break; + } + String addrStr = callstackLog.get(i); + if (addrStr.isEmpty()) { + return null; + } + long addr = 0; + try { + addr = Long.parseLong(addrStr); + } catch (NumberFormatException e) { + Logger.exception(e); + return null; + } + addrs.add(addr); + + CallStackUnit callstackUnit = addrMap.get(addr); + if (null == callstackUnit) { + String funcName = callstackLog.get(i + 1); + CallStackUnit newCallstackUnit = new CallStackUnit(addr, funcName, log); + ((RuntimeCallstackManager) callstackManager).offerCallStackUnit(newCallstackUnit); + addrMap.put(addr, newCallstackUnit); + } + } + return addrs; + } +} -- 2.7.4