|
1 /* |
|
2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of the License "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: |
|
15 * |
|
16 */ |
|
17 |
|
18 package com.nokia.carbide.cpp.pi.memory; |
|
19 |
|
20 import java.io.File; |
|
21 import java.util.ArrayList; |
|
22 import java.util.Hashtable; |
|
23 |
|
24 import org.eclipse.jface.action.Action; |
|
25 import org.eclipse.jface.action.MenuManager; |
|
26 import org.eclipse.jface.action.Separator; |
|
27 import org.eclipse.jface.resource.ImageDescriptor; |
|
28 import org.eclipse.swt.widgets.Display; |
|
29 import org.eclipse.swt.widgets.Event; |
|
30 import org.osgi.framework.BundleContext; |
|
31 import org.osgi.framework.Version; |
|
32 |
|
33 import com.nokia.carbide.cpp.internal.pi.analyser.NpiInstanceRepository; |
|
34 import com.nokia.carbide.cpp.internal.pi.analyser.ProfileVisualiser; |
|
35 import com.nokia.carbide.cpp.internal.pi.memory.actions.MemoryStatisticsDialog; |
|
36 import com.nokia.carbide.cpp.internal.pi.model.GenericTrace; |
|
37 import com.nokia.carbide.cpp.internal.pi.model.ParsedTraceData; |
|
38 import com.nokia.carbide.cpp.internal.pi.plugin.model.AbstractPiPlugin; |
|
39 import com.nokia.carbide.cpp.internal.pi.plugin.model.IClassReplacer; |
|
40 import com.nokia.carbide.cpp.internal.pi.plugin.model.IEventListener; |
|
41 import com.nokia.carbide.cpp.internal.pi.plugin.model.IReportable; |
|
42 import com.nokia.carbide.cpp.internal.pi.plugin.model.ITrace; |
|
43 import com.nokia.carbide.cpp.internal.pi.plugin.model.IViewMenu; |
|
44 import com.nokia.carbide.cpp.internal.pi.plugin.model.IVisualizable; |
|
45 import com.nokia.carbide.cpp.internal.pi.visual.GenericTraceGraph; |
|
46 import com.nokia.carbide.cpp.internal.pi.visual.GraphDrawRequest; |
|
47 import com.nokia.carbide.cpp.internal.pi.visual.PIEvent; |
|
48 import com.nokia.carbide.cpp.pi.editors.PIPageEditor; |
|
49 |
|
50 |
|
51 /** |
|
52 * The main plugin class to be used in the desktop. |
|
53 */ |
|
54 public class MemoryPlugin extends AbstractPiPlugin |
|
55 implements IViewMenu, ITrace, IClassReplacer, IVisualizable, IEventListener, IReportable |
|
56 { |
|
57 private static final String HELP_CONTEXT_ID = PIPageEditor.PI_ID + ".memory"; //$NON-NLS-1$ |
|
58 |
|
59 // There will be 1 graph for editor page 0 |
|
60 // This code may assume that page 0 has the threads graph |
|
61 private final static int GRAPH_COUNT = 3; |
|
62 |
|
63 //The shared instance. |
|
64 private static MemoryPlugin plugin; |
|
65 |
|
66 // version number of profiler |
|
67 private String profilerVersion = ""; |
|
68 |
|
69 private static void setPlugin(MemoryPlugin newPlugin) |
|
70 { |
|
71 plugin = newPlugin; |
|
72 } |
|
73 |
|
74 /** |
|
75 * The constructor. |
|
76 */ |
|
77 public MemoryPlugin() { |
|
78 super(); |
|
79 setPlugin(this); |
|
80 } |
|
81 |
|
82 /** |
|
83 * This method is called upon plug-in activation |
|
84 */ |
|
85 public void start(BundleContext context) throws Exception { |
|
86 super.start(context); |
|
87 } |
|
88 |
|
89 /** |
|
90 * This method is called when the plug-in is stopped |
|
91 */ |
|
92 public void stop(BundleContext context) throws Exception { |
|
93 super.stop(context); |
|
94 setPlugin(null); |
|
95 } |
|
96 |
|
97 /** |
|
98 * Returns the shared instance. |
|
99 */ |
|
100 public static MemoryPlugin getDefault() { |
|
101 return plugin; |
|
102 } |
|
103 |
|
104 /** |
|
105 * Returns an image descriptor for the image file at the given |
|
106 * plug-in relative path. |
|
107 * |
|
108 * @param path the path |
|
109 * @return the image descriptor |
|
110 */ |
|
111 public static ImageDescriptor getImageDescriptor(String path) { |
|
112 return AbstractPiPlugin.imageDescriptorFromPlugin("com.nokia.carbide.cpp.pi.memory", path); //$NON-NLS-1$ |
|
113 } |
|
114 |
|
115 public Class getTraceClass() |
|
116 { |
|
117 return MemTrace.class; |
|
118 } |
|
119 |
|
120 public Class getReplacedClass(String className) |
|
121 { |
|
122 if ( className.indexOf("com.nokia.carbide.cpp.pi.memory.MemTrace") != -1 //$NON-NLS-1$ |
|
123 || className.indexOf("com.nokia.carbide.pi.memory.MemTrace") != -1 //$NON-NLS-1$ |
|
124 || className.indexOf("fi.vtt.bappea.model.MemTrace") != -1 //$NON-NLS-1$ |
|
125 || className.indexOf("fi.vtt.bappea.memTracePlugin.MemTrace") != -1) //$NON-NLS-1$ |
|
126 { |
|
127 return MemTrace.class; |
|
128 } |
|
129 else if ( className.indexOf("com.nokia.carbide.cpp.pi.memory.MemSample") != -1 //$NON-NLS-1$ |
|
130 || className.indexOf("com.nokia.carbide.pi.memory.MemSample") != -1 //$NON-NLS-1$ |
|
131 || className.indexOf("fi.vtt.bappea.model.MemSample") != -1 //$NON-NLS-1$ |
|
132 || className.indexOf("fi.vtt.bappea.memTracePlugin.MemSample") != -1) //$NON-NLS-1$ |
|
133 { |
|
134 return MemSample.class; |
|
135 } |
|
136 else if ( className.indexOf("[Lcom.nokia.carbide.cpp.pi.memory.MemThread") != -1 //$NON-NLS-1$ |
|
137 || className.indexOf("[Lcom.nokia.carbide.pi.memory.MemThread") != -1 //$NON-NLS-1$ |
|
138 || className.indexOf("[Lfi.vtt.bappea.model.MemThread;") != -1 //$NON-NLS-1$ |
|
139 || className.indexOf("[Lfi.vtt.bappea.memTracePlugin.MemThread") != -1) //$NON-NLS-1$ |
|
140 { |
|
141 return MemThread[].class; |
|
142 } |
|
143 else if ( className.indexOf("com.nokia.carbide.cpp.pi.memory.MemThread") != -1 //$NON-NLS-1$ |
|
144 || className.indexOf("com.nokia.carbide.pi.memory.MemThread") != -1 //$NON-NLS-1$ |
|
145 || className.indexOf("fi.vtt.bappea.model.MemThread") != -1 //$NON-NLS-1$ |
|
146 || className.indexOf("fi.vtt.bappea.memTracePlugin.MemThread") != -1) //$NON-NLS-1$ |
|
147 { |
|
148 return MemThread.class; |
|
149 } |
|
150 else |
|
151 return null; |
|
152 } |
|
153 |
|
154 public void initialiseTrace(GenericTrace trace) |
|
155 { |
|
156 if (!(trace instanceof MemTrace)) |
|
157 return; |
|
158 |
|
159 MemTrace memTrace = (MemTrace)trace; |
|
160 |
|
161 /*if(!profilerVersion.equalsIgnoreCase("")) { |
|
162 // set version, needed by mem trace graph to support event based trace data |
|
163 // convert version number from string to double |
|
164 int versionNumber = convertVersionStringToInt(profilerVersion); |
|
165 memTrace.setVersion(versionNumber); |
|
166 } */ |
|
167 |
|
168 NpiInstanceRepository.getInstance().activeUidAddTrace("com.nokia.carbide.cpp.pi.memory", trace); //$NON-NLS-1$ |
|
169 |
|
170 memTrace.gatherDrawData(); |
|
171 |
|
172 System.out.println(Messages.getString("MemoryPlugin.traceProcessed")); //$NON-NLS-1$ |
|
173 } |
|
174 |
|
175 public String getTraceName() { |
|
176 return "Memory"; //$NON-NLS-1$ |
|
177 } |
|
178 |
|
179 public int getTraceId() { |
|
180 return 4; |
|
181 } |
|
182 |
|
183 public ParsedTraceData parseTraceFile(File file) throws Exception |
|
184 { |
|
185 ParsedTraceData traceData = null; |
|
186 try |
|
187 { |
|
188 MemTraceParser memParser = new MemTraceParser(); |
|
189 traceData = memParser.parse(file); |
|
190 |
|
191 //the profiler version data is stored in mem trace parser |
|
192 //profilerVersion = memParser.getProfilerVersion(); |
|
193 |
|
194 return traceData; |
|
195 } catch (Exception e) |
|
196 { |
|
197 e.printStackTrace(); |
|
198 throw e; |
|
199 } |
|
200 } |
|
201 |
|
202 public MenuManager getViewOptionManager() { |
|
203 if (NpiInstanceRepository.getInstance().activeUidGetTrace("com.nokia.carbide.cpp.pi.memory") == null) //$NON-NLS-1$ |
|
204 return null; // no trace, so no MenuManager |
|
205 |
|
206 boolean showChunk = true; |
|
207 boolean showHeapStack = true; |
|
208 |
|
209 // if there is a showChunk value associated with the current Analyser tab, then use it |
|
210 Object obj; |
|
211 obj = NpiInstanceRepository.getInstance().activeUidGetPersistState("com.nokia.carbide.cpp.pi.memory.showChunk"); //$NON-NLS-1$ |
|
212 if ((obj != null) && (obj instanceof Boolean)) |
|
213 // retrieve the current value |
|
214 showChunk = (Boolean)obj; |
|
215 else |
|
216 // set the initial value |
|
217 NpiInstanceRepository.getInstance().activeUidSetPersistState("com.nokia.carbide.cpp.pi.memory.showChunk", showChunk); //$NON-NLS-1$ |
|
218 |
|
219 // if there is a showHeapStack value associated with the current Analyser tab, then use it |
|
220 obj = NpiInstanceRepository.getInstance().activeUidGetPersistState("com.nokia.carbide.cpp.pi.memory.showHeapStack"); //$NON-NLS-1$ |
|
221 if ((obj != null) && (obj instanceof Boolean)) |
|
222 // retrieve the current value |
|
223 showHeapStack = (Boolean)obj; |
|
224 else |
|
225 // set the initial value |
|
226 NpiInstanceRepository.getInstance().activeUidSetPersistState("com.nokia.carbide.cpp.pi.memory.showHeapStack", showHeapStack); //$NON-NLS-1$ |
|
227 |
|
228 Action action; |
|
229 |
|
230 MenuManager manager = new MenuManager(Messages.getString("MemoryPlugin.memoryGraph")); //$NON-NLS-1$ |
|
231 |
|
232 action = new Action(Messages.getString("MemoryPlugin.memoryStats"), Action.AS_PUSH_BUTTON) { //$NON-NLS-1$ |
|
233 public void run() { |
|
234 new MemoryStatisticsDialog(Display.getCurrent()); |
|
235 } |
|
236 }; |
|
237 |
|
238 action.setToolTipText(Messages.getString("MemoryPlugin.memoryStatsTooltip")); //$NON-NLS-1$ |
|
239 manager.add(action); |
|
240 |
|
241 manager.add(new Separator()); |
|
242 |
|
243 action = new Action(Messages.getString("MemoryPlugin.showChunks"), Action.AS_RADIO_BUTTON) { //$NON-NLS-1$ |
|
244 public void run() { |
|
245 if (this.isChecked()) |
|
246 receiveSelectionEvent("chunk_on"); //$NON-NLS-1$ |
|
247 } |
|
248 }; |
|
249 action.setChecked(showChunk && !showHeapStack); |
|
250 action.setToolTipText(Messages.getString("MemoryPlugin.showChunksTooltip")); //$NON-NLS-1$ |
|
251 manager.add(action); |
|
252 |
|
253 action = new Action(Messages.getString("MemoryPlugin.showHeapStack"), Action.AS_RADIO_BUTTON) { //$NON-NLS-1$ |
|
254 public void run() { |
|
255 if (this.isChecked()) |
|
256 receiveSelectionEvent("heapstack_on"); //$NON-NLS-1$ |
|
257 } |
|
258 }; |
|
259 action.setChecked(showHeapStack && !showChunk); |
|
260 action.setToolTipText(Messages.getString("MemoryPlugin.showHeapStackTooltip")); //$NON-NLS-1$ |
|
261 manager.add(action); |
|
262 |
|
263 action = new Action(Messages.getString("MemoryPlugin.showAll"), Action.AS_RADIO_BUTTON) { //$NON-NLS-1$ |
|
264 public void run() { |
|
265 if (this.isChecked()) |
|
266 receiveSelectionEvent("chunk_heapstack_on"); //$NON-NLS-1$ |
|
267 } |
|
268 }; |
|
269 action.setChecked(showChunk && showHeapStack); |
|
270 action.setToolTipText(Messages.getString("MemoryPlugin.showAllTooltip")); //$NON-NLS-1$ |
|
271 manager.add(action); |
|
272 |
|
273 manager.add(new Separator()); |
|
274 |
|
275 boolean rescale = false; |
|
276 |
|
277 // if there is a rescale value associated with the current Analyser tab, then use it |
|
278 obj = NpiInstanceRepository.getInstance().activeUidGetPersistState("com.nokia.carbide.cpp.pi.memory.rescale"); //$NON-NLS-1$ |
|
279 if ((obj != null) && (obj instanceof Boolean)) |
|
280 // retrieve the current value |
|
281 rescale = (Boolean)obj; |
|
282 else |
|
283 // set the initial value |
|
284 NpiInstanceRepository.getInstance().activeUidSetPersistState("com.nokia.carbide.cpp.pi.memory.rescale", rescale); //$NON-NLS-1$ |
|
285 |
|
286 action = new Action(Messages.getString("MemoryPlugin.dynamicRescale"), Action.AS_CHECK_BOX) { //$NON-NLS-1$ |
|
287 public void run() { |
|
288 if (this.isChecked()) |
|
289 receiveSelectionEvent("rescale_on"); //$NON-NLS-1$ |
|
290 else |
|
291 receiveSelectionEvent("rescale_off"); //$NON-NLS-1$ |
|
292 } |
|
293 }; |
|
294 action.setChecked(rescale); |
|
295 action.setToolTipText(Messages.getString("MemoryPlugin.dynamicRescaleTooltip")); //$NON-NLS-1$ |
|
296 manager.add(action); |
|
297 |
|
298 return manager; |
|
299 } |
|
300 |
|
301 public void receiveEvent(String actionString, Event event) { |
|
302 MemTrace trace = (MemTrace)NpiInstanceRepository.getInstance().activeUidGetTrace("com.nokia.carbide.cpp.pi.memory"); //$NON-NLS-1$ |
|
303 |
|
304 if (trace == null) |
|
305 return; |
|
306 |
|
307 if ( actionString.equals("chunk_on") //$NON-NLS-1$ |
|
308 || actionString.equals("heapstack_on") //$NON-NLS-1$ |
|
309 || actionString.equals("chunk_heapstack_on") //$NON-NLS-1$ |
|
310 || actionString.equals("rescale_on") //$NON-NLS-1$ |
|
311 || actionString.equals("rescale_off")) //$NON-NLS-1$ |
|
312 { |
|
313 ((MemTraceGraph)trace.getTraceGraph(PIPageEditor.THREADS_PAGE)).action(actionString); |
|
314 ((MemTraceGraph)trace.getTraceGraph(PIPageEditor.BINARIES_PAGE)).action(actionString); |
|
315 ((MemTraceGraph)trace.getTraceGraph(PIPageEditor.FUNCTIONS_PAGE)).action(actionString); |
|
316 } else if (actionString.equals("scroll")) //$NON-NLS-1$ |
|
317 { |
|
318 if ( !(event.data instanceof String) |
|
319 || !((String)event.data).equals("FigureCanvas")) //$NON-NLS-1$ |
|
320 return; |
|
321 |
|
322 PIEvent be = new PIEvent(event, PIEvent.SCROLLED); |
|
323 |
|
324 ((MemTraceGraph)trace.getTraceGraph(PIPageEditor.THREADS_PAGE)).piEventReceived(be); |
|
325 ((MemTraceGraph)trace.getTraceGraph(PIPageEditor.BINARIES_PAGE)).piEventReceived(be); |
|
326 ((MemTraceGraph)trace.getTraceGraph(PIPageEditor.FUNCTIONS_PAGE)).piEventReceived(be); |
|
327 } |
|
328 } |
|
329 |
|
330 public void receiveSelectionEvent(String actionString) |
|
331 { |
|
332 if (actionString == null) |
|
333 return; |
|
334 |
|
335 if (actionString.equals("chunk_on")) { //$NON-NLS-1$ |
|
336 NpiInstanceRepository.getInstance().activeUidSetPersistState("com.nokia.carbide.cpp.pi.memory.showChunk", true); //$NON-NLS-1$ |
|
337 NpiInstanceRepository.getInstance().activeUidSetPersistState("com.nokia.carbide.cpp.pi.memory.showHeapStack", false); //$NON-NLS-1$ |
|
338 } else if (actionString.equals("heapstack_on")) { //$NON-NLS-1$ |
|
339 NpiInstanceRepository.getInstance().activeUidSetPersistState("com.nokia.carbide.cpp.pi.memory.showChunk", false); //$NON-NLS-1$ |
|
340 NpiInstanceRepository.getInstance().activeUidSetPersistState("com.nokia.carbide.cpp.pi.memory.showHeapStack", true); //$NON-NLS-1$ |
|
341 } else if (actionString.equals("chunk_heapstack_on")) { //$NON-NLS-1$ |
|
342 NpiInstanceRepository.getInstance().activeUidSetPersistState("com.nokia.carbide.cpp.pi.memory.showChunk", true); //$NON-NLS-1$ |
|
343 NpiInstanceRepository.getInstance().activeUidSetPersistState("com.nokia.carbide.cpp.pi.memory.showHeapStack", true); //$NON-NLS-1$ |
|
344 } else if (actionString.equals("rescale_on")) { //$NON-NLS-1$ |
|
345 NpiInstanceRepository.getInstance().activeUidSetPersistState("com.nokia.carbide.cpp.pi.memory.rescale", true); //$NON-NLS-1$ |
|
346 } else if (actionString.equals("rescale_off")) { //$NON-NLS-1$ |
|
347 NpiInstanceRepository.getInstance().activeUidSetPersistState("com.nokia.carbide.cpp.pi.memory.rescale", false); //$NON-NLS-1$ |
|
348 } else { |
|
349 return; |
|
350 } |
|
351 |
|
352 ((MemTraceGraph)this.getTraceGraph(PIPageEditor.THREADS_PAGE)).action(actionString); |
|
353 ((MemTraceGraph)this.getTraceGraph(PIPageEditor.BINARIES_PAGE)).action(actionString); |
|
354 ((MemTraceGraph)this.getTraceGraph(PIPageEditor.FUNCTIONS_PAGE)).action(actionString); |
|
355 } |
|
356 |
|
357 // public GenericTraceGraph getTraceGraph() { |
|
358 // MemTrace trace = (MemTrace) PIPageEditor.currentTab().getData("com.nokia.carbide.cpp.pi.memory.trace"); //$NON-NLS-1$ |
|
359 // |
|
360 // if (trace != null) |
|
361 // return trace.getTraceGraph(); |
|
362 // else |
|
363 // return null; |
|
364 // } |
|
365 |
|
366 public GenericTraceGraph getTraceGraph(int graphIndex) { |
|
367 MemTrace trace = (MemTrace)NpiInstanceRepository.getInstance().activeUidGetTrace("com.nokia.carbide.cpp.pi.memory"); //$NON-NLS-1$ |
|
368 |
|
369 if (trace != null) |
|
370 return trace.getTraceGraph(graphIndex); |
|
371 else |
|
372 return null; |
|
373 } |
|
374 |
|
375 public Integer getLastSample(int graphIndex) { |
|
376 MemTrace trace = (MemTrace)NpiInstanceRepository.getInstance().activeUidGetTrace("com.nokia.carbide.cpp.pi.memory"); //$NON-NLS-1$ |
|
377 |
|
378 if (trace != null) |
|
379 return new Integer(trace.getLastSampleNumber()); |
|
380 else |
|
381 return null; |
|
382 } |
|
383 |
|
384 public Hashtable<Integer,Object> getSummaryTable(double start, double end) |
|
385 { |
|
386 // MemTrace trace = (MemTrace)NpiInstanceRepository.getInstance().activeUidGetTrace("com.nokia.carbide.cpp.pi.memory"); //$NON-NLS-1$ |
|
387 // return ((MemTraceGraph)trace.getTraceGraph(PIPageEditor.currentPageIndex(),PIPageEditor.currentTab())).getTableData(); |
|
388 return null; |
|
389 } |
|
390 |
|
391 public String getGeneralInfo() { |
|
392 return null; |
|
393 } |
|
394 |
|
395 public ArrayList<String> getColumnNames() |
|
396 { |
|
397 ArrayList<String> names = new ArrayList<String>(); |
|
398 names.add(Messages.getString("MemoryPlugin.namesThread")); //$NON-NLS-1$ |
|
399 names.add(Messages.getString("MemoryPlugin.namesAvgChunk")); //$NON-NLS-1$ |
|
400 names.add(Messages.getString("MemoryPlugin.namesAvgStack")); //$NON-NLS-1$ |
|
401 names.add(Messages.getString("MemoryPlugin.namesTotal")); //$NON-NLS-1$ |
|
402 return names; |
|
403 } |
|
404 |
|
405 public ArrayList<Boolean> getColumnSortTypes() |
|
406 { |
|
407 ArrayList<Boolean> sortTypes = new ArrayList<Boolean>(); |
|
408 sortTypes.add(SORT_BY_NAME); |
|
409 sortTypes.add(SORT_BY_NUMBER); |
|
410 sortTypes.add(SORT_BY_NUMBER); |
|
411 sortTypes.add(SORT_BY_NUMBER); |
|
412 return sortTypes; |
|
413 } |
|
414 |
|
415 public String getActiveInfo(Object arg0, double startTime, double endTime) { |
|
416 return null; |
|
417 } |
|
418 |
|
419 public MenuManager getReportGeneratorManager() { |
|
420 return null; |
|
421 } |
|
422 |
|
423 public GraphDrawRequest getDrawRequest(int graphIndex) { |
|
424 return null; |
|
425 } |
|
426 |
|
427 public int getGraphCount() { |
|
428 return GRAPH_COUNT; |
|
429 } |
|
430 |
|
431 public int getPageNumber(int graphIndex) { |
|
432 // Assumes page 0 has the threads graph, 1 has the binaries, and 2 has the functions |
|
433 if (graphIndex == 0) |
|
434 return PIPageEditor.THREADS_PAGE; |
|
435 else if (graphIndex == 1) |
|
436 return PIPageEditor.BINARIES_PAGE; |
|
437 else if (graphIndex == 2) |
|
438 return PIPageEditor.FUNCTIONS_PAGE; |
|
439 |
|
440 return PIPageEditor.NEXT_AVAILABLE_PAGE; |
|
441 } |
|
442 |
|
443 // return whether this plugin's editor pages have been created |
|
444 public boolean arePagesCreated() { |
|
445 return false; |
|
446 } |
|
447 |
|
448 public void setPagesCreated(boolean pagesCreated) { |
|
449 return; |
|
450 } |
|
451 |
|
452 public int getCreatePageCount() { |
|
453 return 0; |
|
454 } |
|
455 |
|
456 public int getCreatePageIndex(int index) { |
|
457 return 0; |
|
458 } |
|
459 |
|
460 public ProfileVisualiser createPage(int index) { |
|
461 return null; |
|
462 } |
|
463 |
|
464 public void setPageIndex(int index, int pageIndex) { |
|
465 return; |
|
466 } |
|
467 |
|
468 |
|
469 /* (non-Javadoc) |
|
470 * @see com.nokia.carbide.cpp.internal.pi.plugin.model.IVisualizable#getGraphTitle(int) |
|
471 */ |
|
472 public String getGraphTitle(int graphIndex) { |
|
473 return Messages.getString("MemoryPlugin.pluginTitle"); //$NON-NLS-1$ |
|
474 } |
|
475 } |