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