Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--docs/TCF Getting Started.html8
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/ImageCache.java1
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/profiler/ProfilerSettingsDlg.java185
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/profiler/ProfilerView.java238
4 files changed, 355 insertions, 77 deletions
diff --git a/docs/TCF Getting Started.html b/docs/TCF Getting Started.html
index 8bbc66f25..e5772aa35 100644
--- a/docs/TCF Getting Started.html
+++ b/docs/TCF Getting Started.html
@@ -43,12 +43,12 @@ below are steps to create and populate Eclipse workspace with TCF projects:</p>
<li><b>RSE (Remote System Explorer) SDK 3.3</b> or later, last tested with 3.3.1, recommended 3.3.1<br>
<a href='http://download.eclipse.org/tm/downloads/'>http://download.eclipse.org/tm/downloads/</a>
</ul>
- <li><b>Optional</b> dependencies for Target Explorer:
+ <li><b>Optional</b> dependencies for Target Explorer:
<ul>
<li><b>RXTX (Java library to access serial ports)</b><br>
- <a href='http://rxtx.qbang.org/eclipse/'>Eclipse update site at http://rxtx.qbang.org/eclipse/</a><br>
- <a href='http://rxtx.qbang.org/eclipse/downloads/'>Download location at http://rxtx.qbang.org/eclipse/downloads/</a>
- </ul>
+ <a href='http://rxtx.qbang.org/eclipse/'>Eclipse update site at http://rxtx.qbang.org/eclipse/</a><br>
+ <a href='http://rxtx.qbang.org/eclipse/downloads/'>Download location at http://rxtx.qbang.org/eclipse/downloads/</a>
+ </ul>
<li>Clone TCF Java code from <a href='http://git.eclipse.org/c/tcf/org.eclipse.tcf.git'>Eclipse GIT repository</a>, using one of the following commands:
<pre>
git clone git://git.eclipse.org/gitroot/tcf/org.eclipse.tcf.git
diff --git a/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/ImageCache.java b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/ImageCache.java
index 998a0439b..ed7924e86 100644
--- a/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/ImageCache.java
+++ b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/ImageCache.java
@@ -58,6 +58,7 @@ public class ImageCache {
IMG_SIGNALS = "icons/signals.gif",
IMG_MEMORY_MAP = "icons/memory-map.gif",
+ IMG_PROFILER = "icons/profiler.png",
IMG_ARRAY_PARTITION = "icons/full/obj16/arraypartition_obj.gif",
diff --git a/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/profiler/ProfilerSettingsDlg.java b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/profiler/ProfilerSettingsDlg.java
new file mode 100644
index 000000000..1d5c09d08
--- /dev/null
+++ b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/profiler/ProfilerSettingsDlg.java
@@ -0,0 +1,185 @@
+/*******************************************************************************
+ * Copyright (c) 2013 Xilinx, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Xilinx - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tcf.internal.debug.ui.profiler;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.MessageBox;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.tcf.internal.debug.ui.ImageCache;
+import org.eclipse.tcf.internal.debug.ui.model.TCFModel;
+import org.eclipse.tcf.services.IProfiler;
+
+class ProfilerSettingsDlg extends Dialog {
+
+ static final String PARAM_VIEW_UPDATE_PERIOD = "ViewUpdatePeriod";
+ static final String PARAM_AGGREGATE = "Aggregate";
+
+ Map<String,Object> conf;
+ Map<String,Object> data;
+
+ private Button aggregate_button;
+ private Button stack_trace_button;
+ private Text frame_cnt_text;
+ private Text view_update_text;
+
+ protected ProfilerSettingsDlg(Shell shell, Map<String,Object> conf) {
+ super(shell);
+ this.conf = conf;
+ }
+
+ @Override
+ protected void configureShell(Shell shell) {
+ super.configureShell(shell);
+ shell.setText("Profiler Configuration");
+ shell.setImage(ImageCache.getImage(ImageCache.IMG_PROFILER));
+ }
+
+ @Override
+ protected void createButtonsForButtonBar(Composite parent) {
+ createButton(parent, IDialogConstants.OK_ID, IDialogConstants.OK_LABEL, true);
+ createButton(parent, IDialogConstants.CANCEL_ID, IDialogConstants.CANCEL_LABEL, false);
+ updateButtons();
+ }
+
+ @Override
+ protected Control createDialogArea(Composite parent) {
+ Composite composite = (Composite)super.createDialogArea(parent);
+ createFields(composite);
+ setData();
+ composite.setSize(composite.computeSize(SWT.DEFAULT, SWT.DEFAULT));
+ return composite;
+ }
+
+ private void createFields(Composite parent) {
+ Font font = parent.getFont();
+ Composite composite = new Composite(parent, SWT.NONE);
+ GridLayout layout = new GridLayout(2, false);
+ composite.setFont(font);
+ composite.setLayout(layout);
+ composite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+ aggregate_button = new Button(composite, SWT.CHECK);
+ aggregate_button.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL, 0, true, false, 2, 1));
+ aggregate_button.setFont(font);
+ aggregate_button.setText("Aggregate per function");
+
+ stack_trace_button = new Button(composite, SWT.CHECK);
+ stack_trace_button.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL, 0, true, false, 2, 1));
+ stack_trace_button.setFont(font);
+ stack_trace_button.setText("Enable stack tracing");
+
+ stack_trace_button.addSelectionListener(new SelectionListener() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ updateButtons();
+ }
+ @Override
+ public void widgetDefaultSelected(SelectionEvent e) {
+ updateButtons();
+ }
+ });
+
+ Label frame_cnt_label = new Label(composite, SWT.WRAP);
+ frame_cnt_label.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING));
+ frame_cnt_label.setFont(font);
+ frame_cnt_label.setText("Max stack frames count:");
+
+ frame_cnt_text = new Text(composite, SWT.SINGLE | SWT.BORDER);
+ frame_cnt_text.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+ frame_cnt_text.setFont(font);
+
+ frame_cnt_text.addModifyListener(new ModifyListener() {
+ public void modifyText(ModifyEvent e) {
+ updateButtons();
+ }
+ });
+
+ Label view_update_label = new Label(composite, SWT.WRAP);
+ view_update_label.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING));
+ view_update_label.setFont(font);
+ view_update_label.setText("View update interval (sec):");
+
+ view_update_text = new Text(composite, SWT.SINGLE | SWT.BORDER);
+ view_update_text.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+ view_update_text.setFont(font);
+
+ view_update_text.addModifyListener(new ModifyListener() {
+ public void modifyText(ModifyEvent e) {
+ updateButtons();
+ }
+ });
+ }
+
+ private void updateButtons() {
+ Button btn = getButton(IDialogConstants.OK_ID);
+ if (btn != null) btn.setEnabled(true);
+ frame_cnt_text.setEnabled(stack_trace_button.getSelection());
+ }
+
+ private void setData() {
+ Boolean b = (Boolean)conf.get(PARAM_AGGREGATE);
+ aggregate_button.setSelection(b != null && b.booleanValue());
+ Number n = (Number)conf.get(IProfiler.PARAM_FRAME_CNT);
+ if (n == null || n.intValue() <= 1) {
+ stack_trace_button.setSelection(false);
+ frame_cnt_text.setText("5");
+ }
+ else {
+ stack_trace_button.setSelection(true);
+ frame_cnt_text.setText(conf.get(IProfiler.PARAM_FRAME_CNT).toString());
+ }
+ view_update_text.setText(conf.get(PARAM_VIEW_UPDATE_PERIOD).toString());
+ }
+
+ private void getData() {
+ data = new HashMap<String,Object>();
+ data.put(PARAM_AGGREGATE, aggregate_button.getSelection());
+ if (stack_trace_button.getSelection()) {
+ data.put(IProfiler.PARAM_FRAME_CNT, new Integer(frame_cnt_text.getText()));
+ }
+ else {
+ data.put(IProfiler.PARAM_FRAME_CNT, 1);
+ }
+ data.put(PARAM_VIEW_UPDATE_PERIOD, new Integer(view_update_text.getText()));
+ }
+
+ @Override
+ protected void okPressed() {
+ try {
+ getData();
+ }
+ catch (Throwable x) {
+ MessageBox mb = new MessageBox(getShell(), SWT.ICON_ERROR | SWT.OK);
+ mb.setText("Invalid data");
+ mb.setMessage(TCFModel.getErrorMessage(x, true));
+ mb.open();
+ return;
+ }
+ super.okPressed();
+ }
+}
diff --git a/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/profiler/ProfilerView.java b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/profiler/ProfilerView.java
index 76a972ac8..bf0b515b8 100644
--- a/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/profiler/ProfilerView.java
+++ b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/profiler/ProfilerView.java
@@ -34,6 +34,7 @@ import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.window.Window;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ControlEvent;
import org.eclipse.swt.events.ControlListener;
@@ -75,6 +76,7 @@ import org.eclipse.tcf.services.ILineNumbers;
import org.eclipse.tcf.services.IProfiler;
import org.eclipse.tcf.services.ISymbols;
import org.eclipse.tcf.util.TCFDataCache;
+import org.eclipse.tcf.util.TCFTask;
import org.eclipse.ui.IActionBars;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.part.ViewPart;
@@ -83,6 +85,8 @@ public class ProfilerView extends ViewPart {
private static final long UPDATE_DELAY = 4000;
private static final int FRAME_COUNT = 5;
+ private static final String PARAM_VIEW_UPDATE_PERIOD = ProfilerSettingsDlg.PARAM_VIEW_UPDATE_PERIOD;
+ private static final String PARAM_AGGREGATE = ProfilerSettingsDlg.PARAM_AGGREGATE;
private static class ProfileSample {
int cnt;
@@ -95,6 +99,7 @@ public class ProfilerView extends ViewPart {
private static class ProfileData {
final String ctx;
+ final Map<String,Object> params;
boolean stopped;
boolean unsupported;
@@ -110,8 +115,11 @@ public class ProfilerView extends ViewPart {
ProfileEntry[] entries;
@SuppressWarnings("unchecked")
- ProfileData(String ctx, int frame_cnt) {
+ ProfileData(String ctx, Map<String,Object> params) {
this.ctx = ctx;
+ this.params = new HashMap<String,Object>(params);
+ Number n = (Number)params.get(IProfiler.PARAM_FRAME_CNT);
+ int frame_cnt = n.intValue();
map = new Map[frame_cnt];
for (int i = 0; i < frame_cnt; i++) {
map[i] = new HashMap<BigInteger,List<ProfileSample>>();
@@ -121,6 +129,7 @@ public class ProfilerView extends ViewPart {
private static class ProfileEntry {
final BigInteger addr;
+ final Set<BigInteger> addr_list = new HashSet<BigInteger>();
String name;
String file_full;
@@ -131,6 +140,7 @@ public class ProfilerView extends ViewPart {
ProfileEntry[] up;
ProfileEntry[] dw;
+ boolean src_info_valid;
boolean mark;
ProfileEntry(BigInteger addr) {
@@ -264,12 +274,15 @@ public class ProfilerView extends ViewPart {
final int sorting;
final TCFNode selection;
final Map<BigInteger,ProfileEntry> entries = new HashMap<BigInteger,ProfileEntry>();
- final Map<BigInteger,String> funcs = new HashMap<BigInteger,String>();
+ final Map<BigInteger,BigInteger> addr_to_func_addr = new HashMap<BigInteger,BigInteger>();
+ final Map<BigInteger,String> addr_to_func_id = new HashMap<BigInteger,String>();
final TCFNodeExecContext node;
final ProfileData prof_data;
final ISymbols symbols;
final ILineNumbers line_numbers;
+ final boolean aggrerate;
final int generation;
+ TCFDataCache<?> pending;
boolean done;
Update() {
@@ -287,34 +300,71 @@ public class ProfilerView extends ViewPart {
symbols = null;
line_numbers = null;
generation = 0;
+ aggrerate = false;
}
else {
node = (TCFNodeExecContext)selection;
symbols = node.getChannel().getRemoteService(ISymbols.class);
line_numbers = node.getChannel().getRemoteService(ILineNumbers.class);
generation = p.generation_inp;
+ Boolean b = (Boolean)p.params.get(PARAM_AGGREGATE);
+ aggrerate = b != null && b.booleanValue();
}
last_update = this;
}
- private boolean getFuncName(ProfileEntry pe) {
- if (symbols == null) return true;
- String func_id = funcs.get(pe.addr);
+ private String getFuncID(BigInteger addr) {
+ if (symbols == null) return "";
+ String func_id = addr_to_func_id.get(addr);
if (func_id == null) {
func_id = "";
- TCFDataCache<TCFFunctionRef> func_cache = node.getFuncInfo(pe.addr);
+ TCFDataCache<TCFFunctionRef> func_cache = node.getFuncInfo(addr);
if (func_cache != null) {
- if (!func_cache.validate(this)) return false;
+ if (!func_cache.validate()) {
+ pending = func_cache;
+ return null;
+ }
TCFFunctionRef func_data = func_cache.getData();
if (func_data != null && func_data.symbol_id != null) {
func_id = func_data.symbol_id;
}
}
- funcs.put(pe.addr, func_id);
+ addr_to_func_id.put(addr, func_id);
+ }
+ return func_id;
+ }
+
+ private BigInteger getFuncAddress(BigInteger addr) {
+ if (!aggrerate) return addr;
+ BigInteger func_addr = addr_to_func_addr.get(addr);
+ if (func_addr != null) return func_addr;
+ String func_id = getFuncID(addr);
+ if (func_id == null) return null;
+ func_addr = addr;
+ if (func_id.length() > 0) {
+ TCFDataCache<ISymbols.Symbol> sym_cache = node.getModel().getSymbolInfoCache(func_id);
+ if (!sym_cache.validate()) {
+ pending = sym_cache;
+ return null;
+ }
+ ISymbols.Symbol sym_data = sym_cache.getData();
+ if (sym_data != null && sym_data.getAddress() != null) {
+ func_addr = JSON.toBigInteger(sym_data.getAddress());
+ }
}
+ addr_to_func_addr.put(addr, func_addr);
+ return func_addr;
+ }
+
+ private boolean getFuncName(ProfileEntry pe) {
+ String func_id = getFuncID(pe.addr);
+ if (func_id == null) return false;
if (func_id.length() > 0) {
TCFDataCache<ISymbols.Symbol> sym_cache = node.getModel().getSymbolInfoCache(func_id);
- if (!sym_cache.validate(this)) return false;
+ if (!sym_cache.validate()) {
+ pending = sym_cache;
+ return false;
+ }
ISymbols.Symbol sym_data = sym_cache.getData();
if (sym_data != null && sym_data.getName() != null) {
pe.name = sym_data.getName();
@@ -327,7 +377,10 @@ public class ProfilerView extends ViewPart {
if (line_numbers == null) return true;
TCFDataCache<TCFSourceRef> line_cache = node.getLineInfo(pe.addr);
if (line_cache == null) return true;
- if (!line_cache.validate(this)) return false;
+ if (!line_cache.validate()) {
+ pending = line_cache;
+ return false;
+ }
TCFSourceRef line_data = line_cache.getData();
if (line_data != null && line_data.area != null) {
pe.file_full = TCFSourceLookupParticipant.toFileName(line_data.area);
@@ -343,29 +396,31 @@ public class ProfilerView extends ViewPart {
return true;
}
- void linkEntry(ProfileEntry pe) {
+ private void linkEntry(ProfileEntry pe) {
Set<ProfileEntry> set_up = new HashSet<ProfileEntry>();
Set<ProfileEntry> set_dw = new HashSet<ProfileEntry>();
for (int n = 0; n < prof_data.map.length; n++) {
- List<ProfileSample> s0 = prof_data.map[n].get(pe.addr);
- if (s0 != null) {
- for (ProfileSample x : s0) {
- assert x.trace[n].equals(pe.addr);
- if (x.trace.length <= n + 1) continue;
- BigInteger addr_up = x.trace[n + 1];
- ProfileEntry pe_up = entries.get(addr_up);
- set_up.add(pe_up);
+ for (BigInteger addr : pe.addr_list) {
+ List<ProfileSample> s0 = prof_data.map[n].get(addr);
+ if (s0 != null) {
+ for (ProfileSample x : s0) {
+ assert addr.equals(x.trace[n]);
+ if (x.trace.length <= n + 1) continue;
+ BigInteger addr_up = getFuncAddress(x.trace[n + 1]);
+ ProfileEntry pe_up = entries.get(addr_up);
+ set_up.add(pe_up);
+ }
}
- }
- if (n == prof_data.map.length - 1) continue;
- List<ProfileSample> s1 = prof_data.map[n + 1].get(pe.addr);
- if (s1 != null) {
- for (ProfileSample x : s1) {
- assert x.trace.length > n + 1;
- assert x.trace[n + 1].equals(pe.addr);
- BigInteger addr_dw = x.trace[n];
- ProfileEntry pe_dw = entries.get(addr_dw);
- set_dw.add(pe_dw);
+ if (n == prof_data.map.length - 1) continue;
+ List<ProfileSample> s1 = prof_data.map[n + 1].get(addr);
+ if (s1 != null) {
+ for (ProfileSample x : s1) {
+ assert x.trace.length > n + 1;
+ assert addr.equals(x.trace[n + 1]);
+ BigInteger addr_dw = getFuncAddress(x.trace[n]);
+ ProfileEntry pe_dw = entries.get(addr_dw);
+ set_dw.add(pe_dw);
+ }
}
}
}
@@ -373,7 +428,7 @@ public class ProfilerView extends ViewPart {
if (set_dw.size() > 0) pe.dw = set_dw.toArray(new ProfileEntry[set_dw.size()]);
}
- void addUpTotal(ProfileEntry pe, float cnt) {
+ private void addUpTotal(ProfileEntry pe, float cnt) {
if (cnt <= 0.1 || pe.up == null) return;
pe.mark = true;
int n = 0;
@@ -393,6 +448,7 @@ public class ProfilerView extends ViewPart {
@Override
public void run() {
+ pending = null;
if (done) return;
if (last_update != this) return;
if (prof_data != null && generation != prof_data.generation_out) {
@@ -402,29 +458,39 @@ public class ProfilerView extends ViewPart {
else {
for (int n = 0; n < prof_data.map.length; n++) {
for (BigInteger addr : prof_data.map[n].keySet()) {
- ProfileEntry pe = entries.get(addr);
- if (pe != null) continue;
- pe = new ProfileEntry(addr);
- if (!getFuncName(pe)) return;
- if (!getLineInfo(pe)) return;
- if (n == 0) {
- List<ProfileSample> s = prof_data.map[0].get(addr);
- for (ProfileSample x : s) pe.count += x.cnt;
+ BigInteger func_addr = getFuncAddress(addr);
+ if (func_addr == null) continue;
+ ProfileEntry pe = entries.get(func_addr);
+ if (pe == null) {
+ pe = new ProfileEntry(func_addr);
+ entries.put(pe.addr, pe);
+ }
+ if (!pe.addr_list.contains(addr)) {
+ if (n == 0) {
+ List<ProfileSample> s = prof_data.map[0].get(addr);
+ for (ProfileSample x : s) pe.count += x.cnt;
+ }
+ pe.addr_list.add(addr);
+ }
+ if (!pe.src_info_valid) {
+ pe.src_info_valid = true;
+ if (!getFuncName(pe)) pe.src_info_valid = false;
+ if (!getLineInfo(pe)) pe.src_info_valid = false;
}
- entries.put(pe.addr, pe);
}
}
- for (ProfileEntry pe : entries.values()) {
- linkEntry(pe);
+ if (pending != null) {
+ pending.wait(this);
+ return;
}
+ for (ProfileEntry pe : entries.values()) linkEntry(pe);
for (List<ProfileSample> lps : prof_data.map[0].values()) {
for (ProfileSample ps : lps) {
int n = 0;
while (n < ps.trace.length) {
- ProfileEntry pe = entries.get(ps.trace[n]);
- if (n == ps.trace.length - 1) {
- addUpTotal(pe, ps.cnt);
- }
+ BigInteger func_addr = getFuncAddress(ps.trace[n]);
+ ProfileEntry pe = entries.get(func_addr);
+ if (n == ps.trace.length - 1) addUpTotal(pe, ps.cnt);
pe.total += ps.cnt;
n++;
}
@@ -435,10 +501,12 @@ public class ProfilerView extends ViewPart {
if (pe.dw != null) Arrays.sort(pe.dw, new SampleComparator(2));
}
}
- ProfileEntry[] arr = entries.values().toArray(new ProfileEntry[entries.size()]);
- Arrays.sort(arr, new SampleComparator(sorting));
prof_data.generation_out = generation;
- prof_data.entries = arr;
+ prof_data.entries = entries.values().toArray(new ProfileEntry[entries.size()]);
+ assert pending == null;
+ }
+ if (prof_data != null && prof_data.entries != null) {
+ Arrays.sort(prof_data.entries, new SampleComparator(sorting));
}
done = true;
final boolean enable_start =
@@ -454,26 +522,25 @@ public class ProfilerView extends ViewPart {
parent.getDisplay().asyncExec(new Runnable() {
@Override
public void run() {
+ if (parent.isDisposed()) return;
action_start.setEnabled(enable_start);
action_stop.setEnabled(enable_stop);
profile_node = node;
Object viewer_input = prof_data != null ? prof_data.entries : null;
- if (viewer_main.getInput() != viewer_input) {
- ISelection s = viewer_main.getSelection();
- ProfilerView.this.sample_count = sample_count;
- viewer_main.setInput(viewer_input);
- if (s instanceof IStructuredSelection) {
- IStructuredSelection ss = (IStructuredSelection)s;
- List<ProfileEntry> l = new ArrayList<ProfileEntry>();
- for (Object obj : ss.toArray()) {
- if (obj instanceof ProfileEntry) {
- ProfileEntry pe = (ProfileEntry)obj;
- pe = entries.get(pe.addr);
- if (pe != null) l.add(pe);
- }
+ ISelection s = viewer_main.getSelection();
+ ProfilerView.this.sample_count = sample_count;
+ viewer_main.setInput(viewer_input);
+ if (s instanceof IStructuredSelection) {
+ IStructuredSelection ss = (IStructuredSelection)s;
+ List<ProfileEntry> l = new ArrayList<ProfileEntry>();
+ for (Object obj : ss.toArray()) {
+ if (obj instanceof ProfileEntry) {
+ ProfileEntry pe = (ProfileEntry)obj;
+ pe = entries.get(pe.addr);
+ if (pe != null) l.add(pe);
}
- setSelection(l, false);
}
+ setSelection(l, false);
}
if (!enable_start) {
status.setText("Selected context does not support profiling");
@@ -550,13 +617,26 @@ public class ProfilerView extends ViewPart {
private final Action action_start = new Action("Start", ImageCache.getImageDescriptor(ImageCache.IMG_THREAD_RUNNNIG)) {
@Override
public void run() {
- Protocol.invokeLater(new Runnable() {
+ final TCFNode node = selection;
+ if (node == null) return;
+ Map<String,Object> conf = new TCFTask<Map<String,Object>>() {
@Override
public void run() {
- if (selection == null) return;
- start(selection);
+ done(getConfiguration(node.getID()));
}
- });
+ }.getE();
+ ProfilerSettingsDlg dlg = new ProfilerSettingsDlg(getSite().getShell(), conf);
+ if (dlg.open() == Window.OK) {
+ final Map<String,Object> params = dlg.data;
+ Protocol.invokeLater(new Runnable() {
+ @Override
+ public void run() {
+ configuration.put(node.getID(), params);
+ if (selection != node) return;
+ start(selection);
+ }
+ });
+ }
}
};
@@ -605,6 +685,9 @@ public class ProfilerView extends ViewPart {
60
};
+ private final Map<String,Map<String,Object>> configuration =
+ new HashMap<String,Map<String,Object>>();
+
@Override
public void createPartControl(Composite parent) {
this.parent = parent;
@@ -944,18 +1027,27 @@ public class ProfilerView extends ViewPart {
viewer_main.getControl().setFocus();
}
- public void start(TCFNode node) {
+ private Map<String,Object> getConfiguration(String ctx) {
+ Map<String,Object> params = configuration.get(ctx);
+ if (params == null) {
+ params = new HashMap<String,Object>();
+ params.put(IProfiler.PARAM_FRAME_CNT, FRAME_COUNT);
+ params.put(PARAM_VIEW_UPDATE_PERIOD, 4);
+ configuration.put(ctx, params);
+ }
+ return params;
+ }
+
+ private void start(TCFNode node) {
assert Protocol.isDispatchThread();
if (!launch_listener_ok) {
TCFModelManager.getModelManager().addListener(launch_listener);
launch_listener_ok = true;
}
- Map<String,Object> params = new HashMap<String,Object>();
- params.put(IProfiler.PARAM_FRAME_CNT, FRAME_COUNT);
- configure(node, params);
+ configure(node, getConfiguration(node.getID()));
}
- public void stop(TCFNode node) {
+ private void stop(TCFNode node) {
assert Protocol.isDispatchThread();
Map<String,Object> params = new HashMap<String,Object>();
configure(node, params);
@@ -975,8 +1067,7 @@ public class ProfilerView extends ViewPart {
if (d != null) d.stopped = true;
}
else {
- Number n = (Number)params.get(IProfiler.PARAM_FRAME_CNT);
- ProfileData d = new ProfileData(node.getID(), n.intValue());
+ ProfileData d = new ProfileData(node.getID(), params);
if (m == null) data.put(node.getModel(), m = new HashMap<String,ProfileData>());
m.put(d.ctx, d);
}
@@ -1044,6 +1135,7 @@ public class ProfilerView extends ViewPart {
}
private void addSample(ProfileData p, BigInteger[] trace, int len, int cnt) {
+ assert len > 0;
p.sample_count += cnt;
p.generation_inp++;
ProfileSample ps = null;

Back to the top