From 831ebadbeeaaa05fb475d4bd5548efdc74bebe31 Mon Sep 17 00:00:00 2001 From: "p.privalov" Date: Wed, 7 Sep 2016 11:45:24 +0300 Subject: [PATCH] SRADA-886 Implemented callstack data loading from saved trace. Also: CallStackData.getAddrs() now returns unmodifiable copy of list of addreses. To add address to this list introduced method CallStackData.addAddr(..). Change-Id: I7627abb2c6d4e02a671abafa5667f2821cb51b4b --- .../tizen/dynamicanalyzer/database/DBTable.java | 10 ++++++ .../project/callstack/RuntimeCallstackManager.java | 34 ++++++++++++++---- .../ui/info/callstack/CallStackData.java | 42 +++++++++++++++++++--- .../ui/info/callstack/CallStackDataDBTable.java | 21 +++++++++++ .../ui/memory/table/MemoryCallStackTable.java | 6 ++++ .../summary/profiling/RuntimeProfileDataMaker.java | 6 ++-- 6 files changed, 105 insertions(+), 14 deletions(-) diff --git a/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/database/DBTable.java b/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/database/DBTable.java index 214f94c..1b444a1 100644 --- a/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/database/DBTable.java +++ b/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/database/DBTable.java @@ -236,6 +236,16 @@ public abstract class DBTable implements IPreparedStatement, IResultSet { } // default implementation of IResultSet + /** + * Transform {@link ResultSet} to row data. Used to transfer data from + * database to runtime data. This method should be reimplemented for each + * database table + * + * @param rs row data from data base + * @return items of {@code rs} transformed to java data types. May return + * null if data is corrupted, or if data extraction does not supported + * for one database table + */ public List extractDataFromResultSet(ResultSet rs) { return null; } diff --git a/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/project/callstack/RuntimeCallstackManager.java b/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/project/callstack/RuntimeCallstackManager.java index 206951f..eb62029 100644 --- a/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/project/callstack/RuntimeCallstackManager.java +++ b/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/project/callstack/RuntimeCallstackManager.java @@ -47,6 +47,7 @@ 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.ui.info.callstack.CallStackData; +import org.tizen.dynamicanalyzer.ui.info.callstack.CallStackDataDBTable; import org.tizen.dynamicanalyzer.ui.info.callstack.CallStackInserter; import org.tizen.dynamicanalyzer.ui.info.callstack.CallStackItem; import org.tizen.dynamicanalyzer.ui.info.callstack.CallStackUnit; @@ -175,7 +176,8 @@ public class RuntimeCallstackManager extends BaseCallstackManager { } size = userCallstack.size(); for (int i = size - 1; i >= 0; i--) { - callstackData.getAddrs().add(userCallstack.get(i).getCallStackUnit().getAddr()); + callstackData.addAddr(userCallstack.get(i).getCallStackUnit() + .getAddr()); } offerCallStackData(callstackData); getCallStackDataBySeqMap().put(seq, callstackData); @@ -210,7 +212,8 @@ public class RuntimeCallstackManager extends BaseCallstackManager { } } for (int i = size - 1; i >= 0; i--) { - callstackData.getAddrs().add(userCallstack.get(i).getCallStackUnit().getAddr()); + callstackData.addAddr(userCallstack.get(i) + .getCallStackUnit().getAddr()); } offerCallStackData(callstackData); getCallStackDataBySeqMap().put(seq, callstackData); @@ -296,7 +299,7 @@ public class RuntimeCallstackManager extends BaseCallstackManager { size = addrs.size(); for (int i = 0; i < size; i++) { - callstackData.getAddrs().add(addrs.get(i)); + callstackData.addAddr(addrs.get(i)); } offerCallStackData(callstackData); getCallStackDataBySeqMap().put(seq, callstackData); @@ -317,7 +320,7 @@ public class RuntimeCallstackManager extends BaseCallstackManager { } public List getCallstackAddrListFromSeq(long seq) { - List addrs = null; + List addrs = new ArrayList(); CallStackData csd = getCallStackDataBySeqMap().get(seq); if (null == csd) { // callstackdata is not in memory, find from DB @@ -333,10 +336,9 @@ public class RuntimeCallstackManager extends BaseCallstackManager { @SuppressWarnings("unchecked") List addressList = (List) callStackAddrs.get(0).get(0); - addrs = new ArrayList(); addrs.addAll(addressList); } else { // callstackdata is in memory - addrs = csd.getAddrs(); + addrs.addAll(csd.getAddrs()); } return addrs; } @@ -379,6 +381,9 @@ public class RuntimeCallstackManager extends BaseCallstackManager { } } + /** + * Prepare callstack data to be saved into {@link CallStackUnitDBTable}. + */ public void save() { // save callstack unit List> insertData = new ArrayList>(); @@ -401,6 +406,10 @@ public class RuntimeCallstackManager extends BaseCallstackManager { } } + /** + * Restore callstack data maps from {@link CallStackDataDBTable} and + * {@link CallStackUnitDBTable}. + */ public void open() { // open callstack unit List> callStackUnits = CallStackInserter.getInstance().getCallStackUnitTable() @@ -416,5 +425,18 @@ public class RuntimeCallstackManager extends BaseCallstackManager { CallStackUnit csa = new CallStackUnit(addr, pid, functionId, binaryId); getCallStackApiAddrByPidMap(pid).put(addr, csa); } + + // open callstack data + List> callStackData = CallStackInserter.getInstance() + .getCallStackDataTable().selectAllColumnData(null); + for (int i = 0; i < callStackData.size(); i++) { + List csdata = callStackData.get(i); + long seq = (Long) csdata + .get(CallStackDataDBTable.COLUMN.SEQUENCE_NUMBER.index); + List addrs = (List) csdata + .get(CallStackDataDBTable.COLUMN.ADDRESS_ARRAY.index); + CallStackData csd = new CallStackData(seq, addrs); + getCallStackDataBySeqMap().put(seq, csd); + } } } diff --git a/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/ui/info/callstack/CallStackData.java b/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/ui/info/callstack/CallStackData.java index dbccd85..04264c1 100644 --- a/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/ui/info/callstack/CallStackData.java +++ b/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/ui/info/callstack/CallStackData.java @@ -28,24 +28,58 @@ package org.tizen.dynamicanalyzer.ui.info.callstack; import java.util.ArrayList; +import java.util.Collections; import java.util.List; +/** + * Class containing data about callstack state at the moment of receiving + * message with specified sequence number. + */ public class CallStackData { protected long seq; protected List addrs; + /** + * Public constructor for empty callstack data. + * + * @param seqNum sequence number of entry or exit message + */ public CallStackData(long seqNum) { seq = seqNum; + addrs = new ArrayList(); + } + + /** + * Public constructor for non empty callstack data. + * + * @param seqNum sequence number of entry or exit message + * @param addrs List with addresses of called functions + */ + public CallStackData(long seqNum, List addrs) { + seq = seqNum; + this.addrs = addrs; } + /** + * Return sequence number. + */ public long getSeq() { return seq; } + /** + * Return unmodifiable copy of list with addresses of called functions. + */ public List getAddrs() { - if (null == addrs) { - addrs = new ArrayList(); - } - return addrs; + return Collections.unmodifiableList(addrs); + } + + /** + * Add specified address to call stack data. + * + * @param addr specified address + */ + public void addAddr(long addr) { + this.addrs.add(addr); } } diff --git a/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/ui/info/callstack/CallStackDataDBTable.java b/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/ui/info/callstack/CallStackDataDBTable.java index 293687c..6cdfb74 100644 --- a/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/ui/info/callstack/CallStackDataDBTable.java +++ b/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/ui/info/callstack/CallStackDataDBTable.java @@ -102,4 +102,25 @@ public class CallStackDataDBTable extends DBTable { return isPrepared; } + + @Override + public List extractDataFromResultSet(ResultSet rs) { + List row = new ArrayList(); + try { + row.add(Long.valueOf(rs.getLong(COLUMN.SEQUENCE_NUMBER.index + 1))); //because counting starts from 1 in db. + //add array + List addrs = new ArrayList(); + Object[] buf = (Object[]) rs.getArray( + COLUMN.ADDRESS_ARRAY.index + 1).getArray(); + for (Object b : buf) { + addrs.add((Long) b); + } + row.add(addrs); + } catch (SQLException e) { + Logger.exception(e); + return null; + } + + return row; + } } diff --git a/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/ui/memory/table/MemoryCallStackTable.java b/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/ui/memory/table/MemoryCallStackTable.java index bea7850..c409798 100644 --- a/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/ui/memory/table/MemoryCallStackTable.java +++ b/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/ui/memory/table/MemoryCallStackTable.java @@ -203,6 +203,12 @@ public class MemoryCallStackTable extends DATableComposite { // analyze performance and must be removed. } + /** + * Find current callstack for the moment, when allocation was performed. + * + * @param seqNum sequence number of the allocation + * @return unmodifiable list of addresses + */ private List getAddrs(long seqNum) { RuntimeCallstackManager callstackManager = Global.getRuntimeCallstackManager(); if (callstackManager.getCallStackDataBySeqMap().floorEntry(seqNum) == null) 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 index 5122729..a392dd5 100644 --- 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 @@ -45,7 +45,7 @@ public class RuntimeProfileDataMaker extends ProfileDataMaker { public void makeFunctionUsageProfileData(ProfileData sampleLog) { totalSampleCount++; - List addrs = null; + List addrs = new ArrayList(); long selfAddr = sampleLog.getPcAddr(); int pid = sampleLog.getPid(); int tid = sampleLog.getTid(); @@ -66,10 +66,9 @@ public class RuntimeProfileDataMaker extends ProfileDataMaker { 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()); + addrs.addAll(callstackData.getAddrs()); for (int i = 0; i < addrs.size(); i++) { if (addrs.get(i) == 0) { addrs.remove(i); @@ -79,7 +78,6 @@ public class RuntimeProfileDataMaker extends ProfileDataMaker { } } else { // Logger.debug("makeFunctionUsageProfileData : cannot find seq by time"); - addrs = new ArrayList(); addrs.add(selfAddr); } -- 2.7.4