Automatic date update in version.in
[binutils-gdb.git] / gprofng / src / DbeSession.cc
blob203290911677869d4ddd9f859cdc6623106fedc4
1 /* Copyright (C) 2021-2024 Free Software Foundation, Inc.
2 Contributed by Oracle.
4 This file is part of GNU Binutils.
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3, or (at your option)
9 any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, 51 Franklin Street - Fifth Floor, Boston,
19 MA 02110-1301, USA. */
21 #include "config.h"
22 #include <ctype.h>
23 #include <stdio.h>
24 #include <dirent.h>
25 #include <unistd.h>
26 #include <sys/types.h>
27 #include <errno.h>
28 #include <sys/param.h>
30 #include "util.h"
31 #include "Application.h"
32 #include "Experiment.h"
33 #include "ExpGroup.h"
34 #include "Expression.h"
35 #include "DataObject.h"
36 #include "Elf.h"
37 #include "Function.h"
38 #include "DbeSession.h"
39 #include "LoadObject.h"
40 #include "DbeSyncMap.h"
41 #include "DbeThread.h"
42 #include "ClassFile.h"
43 #include "IndexObject.h"
44 #include "PathTree.h"
45 #include "Print.h"
47 // Bison 3.0 doesn't define YY_NULLPTR. I copied this from QLParser.tab.cc.
48 // Why this is not in QLParser.tab.hh ? YY_NULLPTR is used in QLParser.tab.hh
49 # ifndef YY_NULLPTR
50 # if defined __cplusplus && 201103L <= __cplusplus
51 # define YY_NULLPTR nullptr
52 # else
53 # define YY_NULLPTR 0
54 # endif
55 # endif
56 #include "QLParser.tab.hh"
57 #include "DbeView.h"
58 #include "MemorySpace.h"
59 #include "Module.h"
60 #include "SourceFile.h"
61 #include "StringBuilder.h"
62 #include "BaseMetric.h"
63 #include "BaseMetricTreeNode.h"
64 #include "Command.h"
65 #include "UserLabel.h"
66 #include "StringMap.h"
67 #include "DbeFile.h"
68 #include "DbeJarFile.h"
69 #include "IOActivity.h"
70 #include "HeapActivity.h"
72 // This is a universal List structure to organize objects
73 // of various types, even if different.
74 struct List
76 List *next;
77 void *val;
80 struct Countable
82 Countable (void *_item)
84 item = _item;
85 ref_count = 0;
88 void *item;
89 int ref_count;
92 Platform_t DbeSession::platform =
93 #if ARCH(SPARC)
94 Sparc;
95 #elif ARCH(Aarch64)
96 Aarch64;
97 #else // ARCH(Intel)
98 Intel;
99 #endif
101 // This constant determines the size of the data object name hash table.
102 static const int HTableSize = 8192;
103 static int DEFAULT_TINY_THRESHOLD = -1;
105 unsigned int mpmt_debug_opt = 0;
106 DbeSession *dbeSession = NULL;
108 DbeSession::DbeSession (Settings *_settings, bool _ipc_mode, bool _rdt_mode)
110 dbeSession = this;
111 ipc_mode = _ipc_mode;
112 rdt_mode = _rdt_mode;
113 settings = new Settings (_settings);
114 views = new Vector<DbeView*>;
115 exps = new Vector<Experiment*>;
116 lobjs = new Vector<LoadObject*>;
117 objs = new Vector<Histable*>;
118 dobjs = new Vector<DataObject*>;
119 metrics = new Vector<Countable*>;
120 reg_metrics = new Vector<BaseMetric*>;
121 hwcentries = NULL;
122 reg_metrics_tree = NULL; // BaseMetric() requires DbeSession::ql_parse
123 idxobjs = new Vector<HashMap<uint64_t, Histable*>*>;
124 tmp_files = new Vector<char*>;
125 search_path = new Vector<char*>;
126 classpath = new Vector<char*>;
127 classpath_df = NULL;
128 expGroups = new Vector<ExpGroup*>;
129 sourcesMap = new HashMap<char*, SourceFile*>;
130 sources = new Vector<SourceFile*>;
131 comp_lobjs = new HashMap<char*, LoadObject*>;
132 comp_dbelines = new HashMap<char*, DbeLine*>;
133 comp_sources = new HashMap<char*, SourceFile*>;
134 loadObjMap = new DbeSyncMap<LoadObject>;
135 f_special = new Vector<Function*>(LastSpecialFunction);
136 omp_functions = new Vector<Function*>(OMP_LAST_STATE);
137 interactive = false;
138 lib_visibility_used = false;
140 // Define all known property names
141 propNames = new Vector<PropDescr*>;
142 propNames_name_store (PROP_NONE, NTXT (""));
143 propNames_name_store (PROP_ATSTAMP, NTXT ("ATSTAMP"));
144 propNames_name_store (PROP_ETSTAMP, NTXT ("ETSTAMP"));
145 propNames_name_store (PROP_TSTAMP, NTXT ("TSTAMP"));
146 propNames_name_store (PROP_THRID, NTXT ("THRID"));
147 propNames_name_store (PROP_LWPID, NTXT ("LWPID"));
148 propNames_name_store (PROP_CPUID, NTXT ("CPUID"));
149 propNames_name_store (PROP_FRINFO, NTXT ("FRINFO"));
150 propNames_name_store (PROP_EVT_TIME, NTXT ("EVT_TIME"));
152 // Samples
153 propNames_name_store (PROP_SMPLOBJ, NTXT ("SMPLOBJ"));
154 propNames_name_store (PROP_SAMPLE, NTXT ("SAMPLE"));
156 // GCEvents
157 propNames_name_store (PROP_GCEVENTOBJ, NTXT ("GCEVENTOBJ"));
158 propNames_name_store (PROP_GCEVENT, NTXT ("GCEVENT"));
160 // Metadata used by some packet types
161 propNames_name_store (PROP_VOIDP_OBJ, NTXT ("VOIDP_OBJ"),
162 NULL, TYPE_UINT64, DDFLAG_NOSHOW);
164 // Clock profiling properties
165 propNames_name_store (PROP_UCPU, NTXT ("UCPU"));
166 propNames_name_store (PROP_SCPU, NTXT ("SCPU"));
167 propNames_name_store (PROP_TRAP, NTXT ("TRAP"));
168 propNames_name_store (PROP_TFLT, NTXT ("TFLT"));
169 propNames_name_store (PROP_DFLT, NTXT ("DFLT"));
170 propNames_name_store (PROP_KFLT, NTXT ("KFLT"));
171 propNames_name_store (PROP_ULCK, NTXT ("ULCK"));
172 propNames_name_store (PROP_TSLP, NTXT ("TSLP"));
173 propNames_name_store (PROP_WCPU, NTXT ("WCPU"));
174 propNames_name_store (PROP_TSTP, NTXT ("TSTP"));
176 propNames_name_store (PROP_MSTATE, NTXT ("MSTATE"));
177 propNames_name_store (PROP_NTICK, NTXT ("NTICK"));
178 propNames_name_store (PROP_OMPSTATE, NTXT ("OMPSTATE"));
180 // Synchronization tracing properties
181 propNames_name_store (PROP_SRQST, NTXT ("SRQST"));
182 propNames_name_store (PROP_SOBJ, NTXT ("SOBJ"));
184 // Hardware counter profiling properties
185 propNames_name_store (PROP_HWCTAG, NTXT ("HWCTAG"));
186 propNames_name_store (PROP_HWCINT, NTXT ("HWCINT"));
187 propNames_name_store (PROP_VADDR, NTXT ("VADDR"));
188 propNames_name_store (PROP_PADDR, NTXT ("PADDR"));
189 propNames_name_store (PROP_VIRTPC, NTXT ("VIRTPC"));
190 propNames_name_store (PROP_PHYSPC, NTXT ("PHYSPC"));
191 propNames_name_store (PROP_LWP_LGRP_HOME, NTXT ("LWP_LGRP_HOME"));
192 propNames_name_store (PROP_PS_LGRP_HOME, NTXT ("PS_LGRP_HOME"));
193 propNames_name_store (PROP_EA_PAGESIZE, NTXT ("EA_PAGESIZE"));
194 propNames_name_store (PROP_EA_LGRP, NTXT ("EA_LGRP"));
195 propNames_name_store (PROP_PC_PAGESIZE, NTXT ("PC_PAGESIZE"));
196 propNames_name_store (PROP_PC_LGRP, NTXT ("PC_LGRP"));
197 propNames_name_store (PROP_HWCDOBJ, NTXT ("HWCDOBJ"));
198 propNames_name_store (PROP_MEM_LAT, NTXT ("MEM_LAT"));
199 propNames_name_store (PROP_MEM_SRC, NTXT ("MEM_SRC"));
201 // Heap tracing properties
202 propNames_name_store (PROP_HTYPE, NTXT ("HTYPE"));
203 propNames_name_store (PROP_HSIZE, NTXT ("HSIZE"));
204 propNames_name_store (PROP_HVADDR, NTXT ("HVADDR"));
205 propNames_name_store (PROP_HOVADDR, NTXT ("HOVADDR"));
206 propNames_name_store (PROP_HLEAKED, NTXT ("HLEAKED"),
207 GTXT ("Leaked bytes"), TYPE_UINT64, 0);
208 propNames_name_store (PROP_HMEM_USAGE, NTXT ("HMEM_USAGE"));
209 propNames_name_store (PROP_HFREED, NTXT ("HFREED"),
210 GTXT ("Freed bytes"), TYPE_UINT64, 0);
211 propNames_name_store (PROP_HCUR_ALLOCS, NTXT ("HCUR_ALLOCS"),
212 GTXT ("Current allocations"), TYPE_INT64, 0);
213 propNames_name_store (PROP_HCUR_NET_ALLOC, NTXT ("HCUR_NET_ALLOC"),
214 NULL, TYPE_INT64, DDFLAG_NOSHOW);
215 propNames_name_store (PROP_HCUR_LEAKS, NTXT ("HCUR_LEAKS"),
216 GTXT ("Current leaks"), TYPE_UINT64, 0);
217 propNames_name_store (PROP_DDSCR_LNK, NTXT ("DDSCR_LNK"),
218 NULL, TYPE_UINT64, DDFLAG_NOSHOW);
220 // IO tracing properties
221 propNames_name_store (PROP_IOTYPE, NTXT ("IOTYPE"));
222 propNames_name_store (PROP_IOFD, NTXT ("IOFD"));
223 propNames_name_store (PROP_IONBYTE, NTXT ("IONBYTE"));
224 propNames_name_store (PROP_IORQST, NTXT ("IORQST"));
225 propNames_name_store (PROP_IOOFD, NTXT ("IOOFD"));
226 propNames_name_store (PROP_IOFNAME, NTXT ("IOFNAME"));
227 propNames_name_store (PROP_IOVFD, NTXT ("IOVFD"));
228 propNames_name_store (PROP_IOFSTYPE, NTXT ("IOFSTYPE"));
230 // omptrace raw properties
231 propNames_name_store (PROP_CPRID, NTXT ("CPRID"));
232 propNames_name_store (PROP_PPRID, NTXT ("PPRID"));
233 propNames_name_store (PROP_TSKID, NTXT ("TSKID"));
234 propNames_name_store (PROP_PTSKID, NTXT ("PTSKID"));
235 propNames_name_store (PROP_PRPC, NTXT ("PRPC"));
237 // Data race detection properties
238 propNames_name_store (PROP_RID, NTXT ("RID"));
239 propNames_name_store (PROP_RTYPE, NTXT ("RTYPE"));
240 propNames_name_store (PROP_LEAFPC, NTXT ("LEAFPC"));
241 propNames_name_store (PROP_RVADDR, NTXT ("RVADDR"));
242 propNames_name_store (PROP_RCNT, NTXT ("RCNT"));
244 // Deadlock detection properties
245 propNames_name_store (PROP_DID, NTXT ("DID"));
246 propNames_name_store (PROP_DLTYPE, NTXT ("DLTYPE"));
247 propNames_name_store (PROP_DTYPE, NTXT ("DTYPE"));
248 propNames_name_store (PROP_DVADDR, NTXT ("DVADDR"));
250 // Synthetic properties (queries only)
251 propNames_name_store (PROP_STACK, NTXT ("STACK"));
252 propNames_name_store (PROP_MSTACK, NTXT ("MSTACK"));
253 propNames_name_store (PROP_USTACK, NTXT ("USTACK"));
254 propNames_name_store (PROP_XSTACK, NTXT ("XSTACK"));
255 propNames_name_store (PROP_HSTACK, NTXT ("HSTACK"));
256 propNames_name_store (PROP_STACKID, NTXT ("STACKID"));
257 //propNames_name_store( PROP_CPRID, NTXT("CPRID") );
258 //propNames_name_store( PROP_TSKID, NTXT("TSKID") );
259 propNames_name_store (PROP_JTHREAD, NTXT ("JTHREAD"),
260 GTXT ("Java thread number"), TYPE_UINT64, 0);
262 propNames_name_store (PROP_LEAF, NTXT ("LEAF"));
263 propNames_name_store (PROP_DOBJ, NTXT ("DOBJ"));
264 propNames_name_store (PROP_SAMPLE_MAP, NTXT ("SAMPLE_MAP"));
265 propNames_name_store (PROP_GCEVENT_MAP, NTXT ("GCEVENT_MAP"));
266 propNames_name_store (PROP_PID, NTXT ("PID"),
267 GTXT ("Process id"), TYPE_UINT64, 0);
268 propNames_name_store (PROP_EXPID, NTXT ("EXPID"),
269 GTXT ("Experiment id"), TYPE_UINT64, DDFLAG_NOSHOW);
270 propNames_name_store (PROP_EXPID_CMP, NTXT ("EXPID_CMP"),
271 GTXT ("Comparable Experiment Id"), TYPE_UINT64,
272 DDFLAG_NOSHOW); //YXXX find better description
273 propNames_name_store (PROP_EXPGRID, NTXT ("EXPGRID"),
274 GTXT ("Comparison Group id"), TYPE_UINT64, 0);
275 propNames_name_store (PROP_PARREG, NTXT ("PARREG"));
276 propNames_name_store (PROP_TSTAMP_LO, NTXT ("TSTAMP_LO"),
277 GTXT ("Start Timestamp (nanoseconds)"), TYPE_UINT64, 0);
278 propNames_name_store (PROP_TSTAMP_HI, NTXT ("TSTAMP_HI"),
279 GTXT ("End Timestamp (nanoseconds)"), TYPE_UINT64, 0);
280 propNames_name_store (PROP_TSTAMP2, NTXT ("TSTAMP2"),
281 GTXT ("End Timestamp (nanoseconds)"), TYPE_UINT64,
282 DDFLAG_NOSHOW);
283 propNames_name_store (PROP_FREQ_MHZ, NTXT ("FREQ_MHZ"),
284 GTXT ("CPU Frequency, MHz"), TYPE_UINT32, 0);
285 propNames_name_store (PROP_NTICK_USEC, NTXT ("NTICK_USEC"),
286 GTXT ("Clock Profiling Interval, Microseconds"),
287 TYPE_UINT64, 0);
289 propNames_name_store (PROP_IOHEAPBYTES, NTXT ("IOHEAPBYTES"));
291 propNames_name_store (PROP_STACKL, NTXT ("STACKL"));
292 propNames_name_store (PROP_MSTACKL, NTXT ("MSTACKL"));
293 propNames_name_store (PROP_USTACKL, NTXT ("USTACKL"));
294 propNames_name_store (PROP_XSTACKL, NTXT ("XSTACKL"));
296 propNames_name_store (PROP_STACKI, NTXT ("STACKI"));
297 propNames_name_store (PROP_MSTACKI, NTXT ("MSTACKI"));
298 propNames_name_store (PROP_USTACKI, NTXT ("USTACKI"));
299 propNames_name_store (PROP_XSTACKI, NTXT ("XSTACKI"));
301 // Make sure predefined names are not used for dynamic properties
302 propNames_name_store (PROP_LAST, NTXT (""));
304 localized_SP_UNKNOWN_NAME = GTXT ("(unknown)");
306 // define Index objects
307 dyn_indxobj = new Vector<IndexObjType_t*>();
308 dyn_indxobj_indx = 0;
309 char *s = dbe_sprintf (NTXT ("((EXPID_CMP<<%llu) | THRID)"),
310 (unsigned long long) IndexObject::INDXOBJ_EXPID_SHIFT);
311 indxobj_define (NTXT ("Threads"), GTXT ("Threads"), s, NULL, NULL);
312 free (s);
313 indxobj_define (NTXT ("CPUs"), GTXT ("CPUs"), NTXT ("(CPUID)"), NULL, NULL);
314 indxobj_define (NTXT ("Samples"), GTXT ("Samples"), NTXT ("(SAMPLE_MAP)"),
315 NULL, NULL);
316 indxobj_define (NTXT ("GCEvents"), GTXT ("GCEvents"), NTXT ("(GCEVENT_MAP)"),
317 NULL, NULL);
318 indxobj_define (NTXT ("Seconds"), GTXT ("Seconds"),
319 NTXT ("(TSTAMP/1000000000)"), NULL, NULL);
320 indxobj_define (NTXT ("Processes"), GTXT ("Processes"), NTXT ("(EXPID_CMP)"),
321 NULL, NULL);
322 s = dbe_sprintf (NTXT ("((EXPGRID<<%llu) | (EXPID<<%llu))"),
323 (unsigned long long) IndexObject::INDXOBJ_EXPGRID_SHIFT,
324 (unsigned long long) IndexObject::INDXOBJ_EXPID_SHIFT);
325 indxobj_define (NTXT ("Experiment_IDs"), GTXT ("Experiment_IDs"), s, NULL, NULL);
326 free (s);
327 indxobj_define (NTXT ("Datasize"), GTXT ("Datasize"),
328 "(IOHEAPBYTES==0?0:"
329 "((IOHEAPBYTES<=(1<<0)?(1<<0):"
330 "((IOHEAPBYTES<=(1<<2)?(1<<2):"
331 "((IOHEAPBYTES<=(1<<4)?(1<<4):"
332 "((IOHEAPBYTES<=(1<<6)?(1<<6):"
333 "((IOHEAPBYTES<=(1<<8)?(1<<8):"
334 "((IOHEAPBYTES<=(1<<10)?(1<<10):"
335 "((IOHEAPBYTES<=(1<<12)?(1<<12):"
336 "((IOHEAPBYTES<=(1<<14)?(1<<14):"
337 "((IOHEAPBYTES<=(1<<16)?(1<<16):"
338 "((IOHEAPBYTES<=(1<<18)?(1<<18):"
339 "((IOHEAPBYTES<=(1<<20)?(1<<20):"
340 "((IOHEAPBYTES<=(1<<22)?(1<<22):"
341 "((IOHEAPBYTES<=(1<<24)?(1<<24):"
342 "((IOHEAPBYTES<=(1<<26)?(1<<26):"
343 "((IOHEAPBYTES<=(1<<28)?(1<<28):"
344 "((IOHEAPBYTES<=(1<<30)?(1<<30):"
345 "((IOHEAPBYTES<=(1<<32)?(1<<32):"
346 "((IOHEAPBYTES<=(1<<34)?(1<<34):"
347 "((IOHEAPBYTES<=(1<<36)?(1<<36):"
348 "((IOHEAPBYTES<=(1<<38)?(1<<38):"
349 "((IOHEAPBYTES<=(1<<40)?(1<<40):"
350 "((IOHEAPBYTES<=(1<<42)?(1<<42):"
351 "((IOHEAPBYTES<=(1<<44)?(1<<44):"
352 "((IOHEAPBYTES<=(1<<46)?(1<<46):"
353 "((IOHEAPBYTES<=(1<<48)?(1<<48):"
354 "((IOHEAPBYTES<=(1<<50)?(1<<50):"
355 "(IOHEAPBYTES==-1?-1:(1<<50|1)"
356 "))))))))))))))))))))))))))))))))))))))))))))))))))))))",
357 NULL, NULL);
358 indxobj_define (NTXT ("Duration"), GTXT ("Duration"),
359 "((TSTAMP_HI-TSTAMP_LO)==0?0:"
360 "(((TSTAMP_HI-TSTAMP_LO)<=1000?1000:"
361 "(((TSTAMP_HI-TSTAMP_LO)<=10000?10000:"
362 "(((TSTAMP_HI-TSTAMP_LO)<=100000?100000:"
363 "(((TSTAMP_HI-TSTAMP_LO)<=1000000?1000000:"
364 "(((TSTAMP_HI-TSTAMP_LO)<=10000000?10000000:"
365 "(((TSTAMP_HI-TSTAMP_LO)<=100000000?100000000:"
366 "(((TSTAMP_HI-TSTAMP_LO)<=1000000000?1000000000:"
367 "(((TSTAMP_HI-TSTAMP_LO)<=10000000000?10000000000:"
368 "(((TSTAMP_HI-TSTAMP_LO)<=100000000000?100000000000:"
369 "(((TSTAMP_HI-TSTAMP_LO)<=1000000000000?1000000000000:"
370 "(((TSTAMP_HI-TSTAMP_LO)<=10000000000000?10000000000000:"
371 "(10000000000001))))))))))))))))))))))))", NULL, NULL);
372 dyn_indxobj_indx_fixed = dyn_indxobj_indx;
373 Elf::elf_init ();
374 defExpName = NULL;
375 mach_model_loaded = NULL;
376 tmp_dir_name = NULL;
377 settings->read_rc (ipc_mode || rdt_mode);
379 init ();
382 DbeSession::~DbeSession ()
384 Destroy (views);
385 Destroy (exps);
386 Destroy (dobjs);
387 Destroy (metrics);
388 Destroy (search_path);
389 Destroy (classpath);
390 Destroy (propNames);
391 Destroy (expGroups);
392 Destroy (userLabels);
393 if (hwcentries)
395 for (long i = 0, sz = hwcentries->size (); i < sz; i++)
397 Hwcentry *h = hwcentries->get (i);
398 free (h->int_name);
399 free (h->name);
400 delete h;
402 delete hwcentries;
405 if (idxobjs)
407 for (int i = 0; i < idxobjs->size (); ++i)
409 HashMap<uint64_t, Histable*> *hMap = idxobjs->get (i);
410 if (hMap)
412 hMap->values ()->destroy ();
413 delete hMap;
416 delete idxobjs;
419 for (int i = 0; i < HTableSize; i++)
421 List *list = dnameHTable[i];
422 while (list)
424 List *tmp = list;
425 list = list->next;
426 delete tmp;
429 delete[] dnameHTable;
430 delete classpath_df;
431 Destroy (objs);
432 Destroy (reg_metrics);
433 Destroy (dyn_indxobj);
434 delete lobjs;
435 delete f_special;
436 destroy_map (DbeFile *, dbeFiles);
437 destroy_map (DbeJarFile *, dbeJarFiles);
438 delete loadObjMap;
439 delete omp_functions;
440 delete sourcesMap;
441 delete sources;
442 delete comp_lobjs;
443 delete comp_dbelines;
444 delete comp_sources;
445 delete reg_metrics_tree;
446 delete settings;
447 free (mach_model_loaded);
449 if (defExpName != NULL)
451 StringBuilder *sb = new StringBuilder ();
452 sb->append (NTXT ("/bin/rm -rf "));
453 sb->append (defExpName);
454 char *cmd = sb->toString ();
455 system (cmd);
456 free (cmd);
457 delete sb;
458 free (defExpName);
460 unlink_tmp_files ();
461 delete tmp_files;
462 dbeSession = NULL;
465 void
466 DbeSession::unlink_tmp_files ()
468 if (tmp_files)
470 for (int i = 0, sz = tmp_files->size (); i < sz; i++)
471 unlink (tmp_files->fetch (i));
472 tmp_files->destroy ();
473 delete tmp_files;
474 tmp_files = NULL;
476 if (tmp_dir_name)
478 char *cmd = dbe_sprintf (NTXT ("/bin/rm -rf %s"), tmp_dir_name);
479 system (cmd);
480 free (cmd);
481 free (tmp_dir_name);
482 tmp_dir_name = NULL;
486 char *
487 DbeSession::get_tmp_file_name (const char *nm, bool for_java)
489 if (tmp_dir_name == NULL)
491 tmp_dir_name = dbe_sprintf (NTXT ("/tmp/analyzer.%llu.%lld"),
492 (unsigned long long) getuid (), (long long) getpid ());
493 mkdir (tmp_dir_name, S_IRWXU);
495 char *fnm = dbe_sprintf (NTXT ("%s/%s"), tmp_dir_name, nm);
496 if (for_java)
497 for (char *s = fnm + strlen (tmp_dir_name) + 1; *s; s++)
498 if (*s == '/')
499 *s = '.';
500 return fnm;
503 void
504 DbeSession::init ()
506 user_exp_id_counter = 0;
507 status_ompavail = 0;
508 archive_mode = 0;
510 #if DEBUG
511 char *s = getenv (NTXT ("MPMT_DEBUG"));
512 if (s)
513 mpmt_debug_opt = atoi (s);
514 #endif /* DEBUG */
515 dbeFiles = new StringMap<DbeFile*>();
516 dbeJarFiles = new StringMap<DbeJarFile*>(128, 128);
518 // set up the initial (after .rc file reading) search path
519 set_search_path (settings->str_search_path, true);
520 userLabels = NULL;
522 // Preset all objects as they may reuse each other
523 lo_unknown = NULL;
524 f_unknown = NULL;
525 j_unknown = NULL;
526 lo_total = NULL;
527 sf_unknown = NULL;
528 f_total = NULL;
529 f_jvm = NULL;
530 d_total = NULL;
531 d_scalars = NULL;
532 d_unknown = NULL;
533 expGroups->destroy ();
534 f_special->reset ();
535 for (int i = 0; i < LastSpecialFunction; i++)
536 f_special->append (NULL);
538 lo_omp = NULL;
539 omp_functions->reset ();
540 for (int i = 0; i < OMP_LAST_STATE; i++)
541 omp_functions->append (NULL);
543 // make sure the metric list is initialized
544 register_metric (Metric::SIZES);
545 register_metric (Metric::ADDRESS);
546 register_metric (Metric::ONAME);
548 // This is needed only to maintain loadobject id's
549 // for <Total> and <Unknown> in tests
550 (void) get_Unknown_LoadObject ();
551 (void) get_Total_LoadObject ();
553 // Create the data object name hash table.
554 dnameHTable = new List*[HTableSize];
555 for (int i = 0; i < HTableSize; i++)
556 dnameHTable[i] = NULL;
558 d_total = createDataObject ();
559 d_total->set_name (NTXT ("<Total>"));
561 // XXXX <Scalars> only appropriate for Program/Data-oriented analyses
562 d_scalars = createDataObject ();
563 d_scalars->set_name (GTXT ("<Scalars>"));
565 d_unknown = createDataObject ();
566 d_unknown->set_name (GTXT ("<Unknown>"));
568 // assign d_unknown's children so data_olayout has consistent sorting
569 for (unsigned pp_code = 1; pp_code < NUM_ABS_PP_CODES + 2; pp_code++)
571 char *errcode;
572 DataObject* dobj = createDataObject ();
573 switch (pp_code)
575 case NUM_ABS_PP_CODES + 1:
576 errcode = PTXT (DOBJ_UNDETERMINED);
577 break;
578 case NUM_ABS_PP_CODES:
579 errcode = PTXT (DOBJ_UNSPECIFIED);
580 break;
581 case NUM_ABS_PP_CODES - 1:
582 errcode = PTXT (DOBJ_UNIDENTIFIED);
583 break;
584 default:
585 errcode = PTXT (ABS_PP_CODES[pp_code]);
587 dobj->parent = d_unknown;
588 dobj->set_dobjname (errcode, NULL); // dobj->parent must already be set
591 for (unsigned rt_code = 1; rt_code < NUM_ABS_RT_CODES - 1; rt_code++)
593 DataObject* dobj = createDataObject ();
594 dobj->parent = d_unknown;
595 dobj->set_dobjname (PTXT (ABS_RT_CODES[rt_code]), NULL); // dobj->parent must already be set
599 void
600 DbeSession::reset_data ()
602 for (long i = 0, sz = VecSize (idxobjs); i < sz; ++i)
603 if (idxobjs->get (i))
604 idxobjs->get (i)->reset ();
607 void
608 DbeSession::reset ()
610 loadObjMap->reset ();
611 DbeView *dbev;
612 int index;
614 Vec_loop (DbeView*, views, index, dbev)
616 dbev->reset ();
619 destroy_map (DbeFile *, dbeFiles);
620 destroy_map (DbeJarFile *, dbeJarFiles);
621 exps->destroy ();
622 lobjs->reset (); // all LoadObjects belong to objs
623 dobjs->destroy (); // deletes d_unknown and d_total as well
624 objs->destroy ();
625 comp_lobjs->clear ();
626 comp_dbelines->clear ();
627 comp_sources->clear ();
628 sourcesMap->clear ();
629 sources->reset ();
631 // Delete the data object name hash table.
632 for (int i = 0; i < HTableSize; i++)
634 List *list = dnameHTable[i];
635 while (list)
637 List *tmp = list;
638 list = list->next;
639 delete tmp;
642 delete[] dnameHTable;
644 // IndexObect definitions remain, objects themselves may go
645 for (int i = 0; i < idxobjs->size (); ++i)
647 HashMap<uint64_t, Histable*> *v = idxobjs->fetch (i);
648 if (v != NULL)
650 v->values ()->destroy ();
651 v->clear ();
654 init ();
657 Vector<SourceFile*> *
658 DbeSession::get_sources ()
660 return sources;
663 DbeFile *
664 DbeSession::getDbeFile (char *filename, int filetype)
666 Dprintf (DEBUG_DBE_FILE, NTXT ("DbeSession::getDbeFile filetype=0x%x %s\n"), filetype, filename);
667 if (strncmp (filename, NTXT ("./"), 2) == 0)
668 filename += 2;
669 DbeFile *dbeFile = dbeFiles->get (filename);
670 if (dbeFile == NULL)
672 dbeFile = new DbeFile (filename);
673 dbeFiles->put (filename, dbeFile);
675 dbeFile->filetype |= filetype;
676 return dbeFile;
679 LoadObject *
680 DbeSession::get_Total_LoadObject ()
682 if (lo_total == NULL)
684 lo_total = createLoadObject (NTXT ("<Total>"));
685 lo_total->dbeFile->filetype |= DbeFile::F_FICTION;
687 return lo_total;
690 Function *
691 DbeSession::get_Total_Function ()
693 if (f_total == NULL)
695 f_total = createFunction ();
696 f_total->flags |= FUNC_FLAG_SIMULATED | FUNC_FLAG_NO_OFFSET;
697 f_total->set_name (NTXT ("<Total>"));
698 Module *mod = get_Total_LoadObject ()->noname;
699 f_total->module = mod;
700 mod->functions->append (f_total);
702 return f_total;
705 LoadObject *
706 DbeSession::get_Unknown_LoadObject ()
708 if (lo_unknown == NULL)
710 lo_unknown = createLoadObject (GTXT ("<Unknown>"));
711 lo_unknown->type = LoadObject::SEG_TEXT; // makes it expandable
712 lo_unknown->dbeFile->filetype |= DbeFile::F_FICTION;
714 // force creation of the <Unknown> function
715 (void) get_Unknown_Function ();
717 return lo_unknown;
720 SourceFile *
721 DbeSession::get_Unknown_Source ()
723 if (sf_unknown == NULL)
725 sf_unknown = createSourceFile (localized_SP_UNKNOWN_NAME);
726 sf_unknown->dbeFile->filetype |= DbeFile::F_FICTION;
727 sf_unknown->flags |= SOURCE_FLAG_UNKNOWN;
729 return sf_unknown;
732 Function *
733 DbeSession::get_Unknown_Function ()
735 if (f_unknown == NULL)
737 f_unknown = createFunction ();
738 f_unknown->flags |= FUNC_FLAG_SIMULATED;
739 f_unknown->set_name (GTXT ("<Unknown>"));
740 Module *mod = get_Unknown_LoadObject ()->noname;
741 f_unknown->module = mod;
742 mod->functions->append (f_unknown);
744 return f_unknown;
747 // LIBRARY_VISIBILITY
749 Function *
750 DbeSession::create_hide_function (LoadObject *lo)
752 Function *h_function = createFunction ();
753 h_function->set_name (lo->get_name ());
754 h_function->module = lo->noname;
755 h_function->isHideFunc = true;
756 lo->noname->functions->append (h_function);
757 return h_function;
760 Function *
761 DbeSession::get_JUnknown_Function ()
763 if (j_unknown == NULL)
765 j_unknown = createFunction ();
766 j_unknown->flags |= FUNC_FLAG_SIMULATED;
767 j_unknown->set_name (GTXT ("<no Java callstack recorded>"));
768 Module *mod = get_Unknown_LoadObject ()->noname;
769 j_unknown->module = mod;
770 mod->functions->append (j_unknown);
772 return j_unknown;
775 Function *
776 DbeSession::get_jvm_Function ()
778 if (f_jvm == NULL)
780 f_jvm = createFunction ();
781 f_jvm->flags |= FUNC_FLAG_SIMULATED | FUNC_FLAG_NO_OFFSET;
782 f_jvm->set_name (GTXT ("<JVM-System>"));
784 // Find the JVM LoadObject
785 LoadObject *jvm = get_Unknown_LoadObject ();
786 for (int i = 0; i < lobjs->size (); ++i)
788 LoadObject *lo = lobjs->fetch (i);
789 if (lo->flags & SEG_FLAG_JVM)
791 jvm = lo;
792 break;
795 Module *mod = jvm->noname;
796 f_jvm->module = mod;
797 mod->functions->append (f_jvm);
798 // XXXX is it required? no consistency among all special functions
799 // jvm->functions->append( f_jvm );
801 return f_jvm;
804 Function *
805 DbeSession::getSpecialFunction (SpecialFunction kind)
807 if (kind < 0 || kind >= LastSpecialFunction)
808 return NULL;
810 Function *func = f_special->fetch (kind);
811 if (func == NULL)
813 char *fname;
814 switch (kind)
816 case TruncatedStackFunc:
817 fname = GTXT ("<Truncated-stack>");
818 break;
819 case FailedUnwindFunc:
820 fname = GTXT ("<Stack-unwind-failed>");
821 break;
822 default:
823 return NULL;
825 func = createFunction ();
826 func->flags |= FUNC_FLAG_SIMULATED | FUNC_FLAG_NO_OFFSET;
827 Module *mod = get_Total_LoadObject ()->noname;
828 func->module = mod;
829 mod->functions->append (func);
830 func->set_name (fname);
831 f_special->store (kind, func);
833 return func;
836 LoadObject *
837 DbeSession::get_OMP_LoadObject ()
839 if (lo_omp == NULL)
841 for (int i = 0, sz = lobjs->size (); i < sz; i++)
843 LoadObject *lo = lobjs->fetch (i);
844 if (lo->flags & SEG_FLAG_OMP)
846 lo_omp = lo;
847 return lo_omp;
850 lo_omp = createLoadObject (GTXT ("<OMP>"));
851 lo_omp->type = LoadObject::SEG_TEXT;
852 lo_omp->dbeFile->filetype |= DbeFile::F_FICTION;
854 return lo_omp;
857 Function *
858 DbeSession::get_OMP_Function (int n)
860 if (n < 0 || n >= OMP_LAST_STATE)
861 return NULL;
863 Function *func = omp_functions->fetch (n);
864 if (func == NULL)
866 char *fname;
867 switch (n)
869 case OMP_OVHD_STATE:
870 fname = GTXT ("<OMP-overhead>");
871 break;
872 case OMP_IDLE_STATE:
873 fname = GTXT ("<OMP-idle>");
874 break;
875 case OMP_RDUC_STATE:
876 fname = GTXT ("<OMP-reduction>");
877 break;
878 case OMP_IBAR_STATE:
879 fname = GTXT ("<OMP-implicit_barrier>");
880 break;
881 case OMP_EBAR_STATE:
882 fname = GTXT ("<OMP-explicit_barrier>");
883 break;
884 case OMP_LKWT_STATE:
885 fname = GTXT ("<OMP-lock_wait>");
886 break;
887 case OMP_CTWT_STATE:
888 fname = GTXT ("<OMP-critical_section_wait>");
889 break;
890 case OMP_ODWT_STATE:
891 fname = GTXT ("<OMP-ordered_section_wait>");
892 break;
893 case OMP_ATWT_STATE:
894 fname = GTXT ("<OMP-atomic_wait>");
895 break;
896 default:
897 return NULL;
899 func = createFunction ();
900 func->flags |= FUNC_FLAG_SIMULATED | FUNC_FLAG_NO_OFFSET;
901 func->set_name (fname);
903 LoadObject *omp = get_OMP_LoadObject ();
904 func->module = omp->noname;
905 omp->noname->functions->append (func);
906 omp->functions->append (func);
907 omp_functions->store (n, func);
909 return func;
912 // Divide the original createExperiment() into two steps
913 // In part1, we just create the data structure, in part2, if
914 // we decide to keep the experiment around, add it to various
915 // lists in DbeSession
916 Experiment *
917 DbeSession::createExperimentPart1 ()
919 Experiment *exp = new Experiment ();
920 return exp;
923 void
924 DbeSession::createExperimentPart2 (Experiment *exp)
926 int ind = expGroups->size ();
927 if (ind > 0)
929 ExpGroup *gr = expGroups->fetch (ind - 1);
930 exp->groupId = gr->groupId;
931 gr->append (exp);
933 exp->setExpIdx (exps->size ());
934 exp->setUserExpId (++user_exp_id_counter);
935 exps->append (exp);
938 Experiment *
939 DbeSession::createExperiment ()
941 Experiment *exp = new Experiment ();
942 append (exp);
943 return exp;
946 void
947 DbeSession::append (Experiment *exp)
949 exp->setExpIdx (exps->size ());
950 exp->setUserExpId (++user_exp_id_counter);
951 exps->append (exp);
952 if (exp->founder_exp)
954 if (exp->founder_exp->children_exps == NULL)
955 exp->founder_exp->children_exps = new Vector<Experiment *>;
956 exp->founder_exp->children_exps->append (exp);
957 if (exp->founder_exp->groupId > 0)
959 exp->groupId = exp->founder_exp->groupId;
960 expGroups->get (exp->groupId - 1)->append (exp);
963 if (exp->groupId == 0)
965 long ind = VecSize (expGroups);
966 if (ind > 0)
968 ExpGroup *gr = expGroups->get (ind - 1);
969 exp->groupId = gr->groupId;
970 gr->append (exp);
975 void
976 DbeSession::append (Hwcentry *h)
978 if (hwcentries == NULL)
979 hwcentries = new Vector<Hwcentry*>;
980 hwcentries->append (h);
984 DbeSession::ngoodexps ()
986 return exps->size ();
990 DbeSession::createView (int index, int cloneindex)
992 // ensure that there is no view with that index
993 DbeView *dbev = getView (index);
994 if (dbev != NULL)
995 abort ();
997 // find the view to be cloned
998 dbev = getView (cloneindex);
999 DbeView *newview;
1000 if (dbev == NULL)
1001 newview = new DbeView (theApplication, settings, index);
1002 else
1003 newview = new DbeView (dbev, index);
1004 views->append (newview);
1005 return index;
1008 DbeView *
1009 DbeSession::getView (int index)
1011 int i;
1012 DbeView *dbev;
1013 Vec_loop (DbeView*, views, i, dbev)
1015 if (dbev->vindex == index)
1016 return dbev;
1018 return NULL;
1021 void
1022 DbeSession::dropView (int index)
1024 int i;
1025 DbeView *dbev;
1027 Vec_loop (DbeView*, views, i, dbev)
1029 if (dbev->vindex == index)
1031 views->remove (i);
1032 delete dbev;
1033 return;
1036 // view not found; ignore for now
1039 Vector<char*> *
1040 DbeSession::get_group_or_expt (char *path)
1042 Vector<char*> *exp_list = new Vector<char*>;
1043 FILE *fptr;
1044 char *new_path, buf[MAXPATHLEN], name[MAXPATHLEN];
1046 fptr = fopen (path, NTXT ("r"));
1047 if (!fptr || !fgets (buf, (int) sizeof (buf), fptr)
1048 || strncmp (buf, SP_GROUP_HEADER, strlen (SP_GROUP_HEADER)))
1050 // it's not an experiment group
1051 new_path = dbe_strdup (path);
1052 new_path = canonical_path (new_path);
1053 exp_list->append (new_path);
1055 else
1057 // it is an experiment group, read the list to get them all
1058 while (fgets (buf, (int) sizeof (buf), fptr))
1060 if ((*buf != '#') && (sscanf (buf, NTXT ("%s"), name) == 1))
1062 new_path = dbe_strdup (name);
1063 new_path = canonical_path (new_path);
1064 exp_list->append (new_path);
1068 if (fptr)
1069 fclose (fptr);
1070 return exp_list;
1073 #define GET_INT_VAL(v, s, len) \
1074 for (v = len = 0; isdigit(*s); s++, len++) { v = v * 10 + (*s -'0'); }
1076 static int
1077 dir_name_cmp (const void *a, const void *b)
1079 char *s1 = *((char **) a);
1080 char *s2 = *((char **) b);
1081 while (*s1)
1083 if (isdigit (*s1) && isdigit (*s2))
1085 int v1, v2, len1, len2;
1086 GET_INT_VAL (v1, s1, len1);
1087 GET_INT_VAL (v2, s2, len2);
1088 if (v1 != v2)
1089 return v1 - v2;
1090 if (len1 != len2)
1091 return len2 - len1;
1092 continue;
1094 if (*s1 != *s2)
1095 break;
1096 s1++;
1097 s2++;
1099 return *s1 - *s2;
1102 static int
1103 read_experiment_data_in_parallel (void *arg)
1105 exp_ctx *ctx = (exp_ctx *) arg;
1106 Experiment *dexp = ctx->exp;
1107 bool read_ahead = ctx->read_ahead;
1108 dexp->read_experiment_data (read_ahead);
1109 free (ctx);
1110 return 0;
1113 void
1114 DbeSession::open_experiment (Experiment *exp, char *path)
1116 exp->open (path);
1117 if (exp->get_status () != Experiment::FAILURE)
1118 exp->read_experiment_data (false);
1119 exp->open_epilogue ();
1121 // Update all DbeViews
1122 for (int i = 0, sz = views->size (); i < sz; i++)
1124 DbeView *dbev = views->fetch (i);
1125 dbev->add_experiment (exp->getExpIdx (), true);
1128 if (exp->get_status () == Experiment::FAILURE)
1130 check_tab_avail ();
1131 return;
1134 char *discard_tiny = getenv (NTXT ("SP_ANALYZER_DISCARD_TINY_EXPERIMENTS"));
1135 int user_specified_tiny_threshold = DEFAULT_TINY_THRESHOLD; // in milliseconds
1136 if (discard_tiny != NULL)
1138 user_specified_tiny_threshold = (atoi (discard_tiny));
1139 if (user_specified_tiny_threshold < 0)
1140 user_specified_tiny_threshold = DEFAULT_TINY_THRESHOLD;
1143 // Open descendant experiments
1144 DIR *exp_dir = opendir (path);
1145 if (exp_dir == NULL)
1147 check_tab_avail ();
1148 return;
1151 Vector<char*> *exp_names = new Vector<char*>();
1152 struct dirent *entry = NULL;
1153 while ((entry = readdir (exp_dir)) != NULL)
1155 if (entry->d_name[0] != '_')
1156 continue;
1157 size_t len = strlen (entry->d_name);
1158 if (len < 3 || strcmp (entry->d_name + len - 3, NTXT (".er")) != 0)
1159 continue;
1160 exp_names->append (dbe_strdup (entry->d_name));
1162 closedir (exp_dir);
1163 exp_names->sort (dir_name_cmp);
1164 Experiment **t_exp_list = new Experiment *[exp_names->size ()];
1165 int nsubexps = 0;
1167 for (int j = 0, jsz = exp_names->size (); j < jsz; j++)
1169 t_exp_list[j] = NULL;
1171 char *lineage_name = exp_names->fetch (j);
1172 dbe_stat_t sbuf;
1173 char *dpath = dbe_sprintf (NTXT ("%s/%s"), path, lineage_name);
1175 // look for experiments with no profile collected
1176 if (user_specified_tiny_threshold == DEFAULT_TINY_THRESHOLD)
1178 char *frinfoname = dbe_sprintf (NTXT ("%s/%s"), dpath, "data." SP_FRINFO_FILE);
1179 int st = dbe_stat (frinfoname, &sbuf);
1180 free (frinfoname);
1181 if (st == 0)
1183 // if no profile/trace data do not process this experiment any further
1184 if (sbuf.st_size == 0)
1186 free (dpath);
1187 continue;
1191 else
1192 { // check if dpath is a directory
1193 if (dbe_stat (dpath, &sbuf) != 0)
1195 free (dpath);
1196 continue;
1198 else if (!S_ISDIR (sbuf.st_mode))
1200 free (dpath);
1201 continue;
1204 size_t lineage_name_len = strlen (lineage_name);
1205 lineage_name[lineage_name_len - 3] = 0; /* remove .er */
1206 Experiment *dexp = new Experiment ();
1207 dexp->founder_exp = exp;
1208 if (user_specified_tiny_threshold > DEFAULT_TINY_THRESHOLD)
1210 dexp->setTinyThreshold (user_specified_tiny_threshold);
1211 dexp->open (dpath);
1212 if (dexp->isDiscardedTinyExperiment ())
1214 delete dexp;
1215 free (dpath);
1216 continue;
1219 else
1220 dexp->open (dpath);
1221 append (dexp);
1222 t_exp_list[j] = dexp;
1223 nsubexps++;
1224 dexp->set_clock (exp->clock);
1226 // DbeView add_experiment() is split into two parts
1227 // add_subexperiment() is called repeeatedly for
1228 // all sub_experiments, later add_experiment_epilogue() finishes up the task
1229 for (int i = 0, sz = views->size (); i < sz; i++)
1231 DbeView *dbev = views->fetch (i);
1232 bool enabled = settings->check_en_desc (lineage_name, dexp->utargname);
1233 dbev->add_subexperiment (dexp->getExpIdx (), enabled);
1235 free (dpath);
1238 for (int i = 0, sz = views->size (); i < sz; i++)
1240 DbeView *dbev = views->fetch (i);
1241 dbev->add_experiment_epilogue ();
1244 DbeThreadPool * threadPool = new DbeThreadPool (-1);
1245 for (int j = 0, jsz = exp_names->size (); j < jsz; j++)
1247 if (t_exp_list[j] == NULL) continue;
1248 Experiment *dexp = t_exp_list[j];
1249 exp_ctx *new_ctx = (exp_ctx*) malloc (sizeof (exp_ctx));
1250 new_ctx->path = NULL;
1251 new_ctx->exp = dexp;
1252 new_ctx->ds = this;
1253 new_ctx->read_ahead = true;
1254 DbeQueue *q = new DbeQueue (read_experiment_data_in_parallel, new_ctx);
1255 threadPool->put_queue (q);
1257 threadPool->wait_queues ();
1258 delete threadPool;
1260 for (long j = 0, jsz = exp_names->size (); j < jsz; j++)
1262 if (t_exp_list[j] == NULL) continue;
1263 Experiment *dexp = t_exp_list[j];
1264 dexp->open_epilogue ();
1266 exp_names->destroy ();
1267 delete[] t_exp_list;
1268 delete exp_names;
1270 // update setting for leaklist and dataspace
1271 check_tab_avail ();
1274 void
1275 DbeSession::append_mesgs (StringBuilder *sb, char *path, Experiment *exp)
1277 if (exp->fetch_errors () != NULL)
1279 // yes, there were errors
1280 char *ststr = pr_mesgs (exp->fetch_errors (), NTXT (""), NTXT (""));
1281 sb->append (path);
1282 sb->append (NTXT (": "));
1283 sb->append (ststr);
1284 free (ststr);
1287 Emsg *m = exp->fetch_warnings ();
1288 if (m != NULL)
1290 sb->append (path);
1291 sb->append (NTXT (": "));
1292 if (!is_interactive ())
1293 sb->append (GTXT ("Experiment has warnings, see header for details\n"));
1294 else
1295 sb->append (GTXT ("Experiment has warnings, see experiment panel for details\n"));
1298 // Check for descendant experiments that are not loaded
1299 int num_desc = VecSize (exp->children_exps);
1300 if ((num_desc > 0) && !settings->check_en_desc (NULL, NULL))
1302 char *s;
1303 if (!is_interactive ())
1304 s = dbe_sprintf (GTXT ("Has %d descendant(s), use commands controlling selection to load descendant data\n"), num_desc);
1305 else
1306 s = dbe_sprintf (GTXT ("Has %d descendant(s), use filter panel to load descendant data\n"), num_desc);
1307 sb->append (path);
1308 sb->append (NTXT (": "));
1309 sb->append (s);
1310 free (s);
1314 Experiment *
1315 DbeSession::get_exp (int exp_ind)
1317 if (exp_ind < 0 || exp_ind >= exps->size ())
1318 return NULL;
1319 Experiment *exp = exps->fetch (exp_ind);
1320 exp->setExpIdx (exp_ind);
1321 return exp;
1324 Vector<Vector<char*>*> *
1325 DbeSession::getExperimensGroups ()
1327 if (dbeSession->expGroups == NULL || dbeSession->expGroups->size () == 0)
1328 return NULL;
1329 bool compare_mode = expGroups->size () > 1;
1330 Vector<Vector<char*>*> *groups = new Vector<Vector<char*>*> (
1331 compare_mode ? expGroups->size () : 1);
1332 for (int i = 0; i < expGroups->size (); i++)
1334 ExpGroup *grp = expGroups->fetch (i);
1335 Vector<Experiment*> *founders = grp->get_founders ();
1336 if (founders && founders->size () != 0)
1338 Vector<char *> *names = new Vector<char*> (founders->size ());
1339 for (int j = 0; j < founders->size (); j++)
1341 Experiment *exp = founders->fetch (j);
1342 names->append (dbe_strdup (exp->get_expt_name ()));
1344 if (compare_mode || groups->size () == 0)
1345 groups->append (names);
1346 else
1347 groups->fetch (0)->addAll (names);
1349 delete founders;
1351 return groups;
1354 char *
1355 DbeSession::setExperimentsGroups (Vector<Vector<char*>*> *groups)
1357 StringBuilder sb;
1358 for (int i = 0; i < groups->size (); i++)
1360 Vector<char *> *names = groups->fetch (i);
1361 ExpGroup *grp;
1362 if (names->size () == 1)
1363 grp = new ExpGroup (names->fetch (0));
1364 else
1366 char *nm = dbe_sprintf (GTXT ("Group %d"), i + 1);
1367 grp = new ExpGroup (nm);
1368 free (nm);
1370 expGroups->append (grp);
1371 grp->groupId = expGroups->size ();
1373 for (int j = 0; j < names->size (); j++)
1375 char *path = names->fetch (j);
1376 size_t len = strlen (path);
1377 if ((len > 4) && !strcmp (path + len - 4, NTXT (".erg")))
1379 Vector<char*> *lst = get_group_or_expt (path);
1380 for (int j1 = 0; j1 < lst->size (); j1++)
1382 Experiment *exp = new Experiment ();
1383 append (exp);
1384 open_experiment (exp, lst->get (j1));
1385 if (exp->get_status () == Experiment::FAILURE)
1386 append_mesgs (&sb, path, exp);
1388 lst->destroy ();
1389 delete lst;
1391 else
1393 Experiment *exp = new Experiment ();
1394 append (exp);
1395 open_experiment (exp, path);
1396 if (exp->get_status () == Experiment::FAILURE)
1397 append_mesgs (&sb, path, exp);
1402 for (int i = 0, sz = views->size (); i < sz; i++)
1404 DbeView *dbev = views->fetch (i);
1405 dbev->update_advanced_filter ();
1406 int cmp = dbev->get_settings ()->get_compare_mode ();
1407 dbev->set_compare_mode (CMP_DISABLE);
1408 dbev->set_compare_mode (cmp);
1410 return sb.length () == 0 ? NULL : sb.toString ();
1413 char *
1414 DbeSession::drop_experiment (int exp_ind)
1416 DbeView *dbev;
1417 int index;
1418 Experiment *exp2;
1420 status_ompavail = -1;
1421 Experiment *exp = exps->fetch (exp_ind);
1423 // If this is a sub experiment, don't do it
1424 if (exp->founder_exp != NULL) // this is a sub experiment; don't do it
1425 return (dbe_strdup (GTXT ("Can not drop subexperiments")));
1427 if (VecSize (exp->children_exps) > 0)
1428 for (;;)
1430 // search the list of experiments to find all that have this one as founder
1431 bool found = false;
1432 Vec_loop (Experiment*, exps, index, exp2)
1434 if (exp2->founder_exp == exp)
1436 exp2->founder_exp = NULL;
1437 drop_experiment (index);
1438 found = true;
1439 break;
1442 if (found == false)
1443 break;
1446 // then proceed to finish the drop
1447 Vec_loop (DbeView*, views, index, dbev)
1449 dbev->drop_experiment (exp_ind);
1452 int old_cnt = expGroups->size ();
1453 for (int i = 0; i < old_cnt; i++)
1455 ExpGroup *gr = expGroups->fetch (i);
1456 if (gr->groupId == exp->groupId)
1458 gr->drop_experiment (exp);
1459 if ((gr->founder == NULL) && (gr->exps->size () == 0))
1461 delete gr;
1462 expGroups->remove (i);
1464 break;
1467 delete exps->remove (exp_ind);
1468 if (old_cnt != expGroups->size ())
1470 for (int i = 0, sz = expGroups->size (); i < sz; i++)
1472 ExpGroup *gr = expGroups->fetch (i);
1473 gr->groupId = i + 1;
1474 Vector<Experiment*> *expList = gr->exps;
1475 for (int i1 = 0, sz1 = expList->size (); i1 < sz1; i1++)
1476 expList->fetch (i1)->groupId = gr->groupId;
1478 for (int i = 0, sz = views->size (); i < sz; i++)
1480 dbev = views->fetch (i);
1481 int cmp = dbev->get_compare_mode ();
1482 dbev->set_compare_mode (CMP_DISABLE);
1483 dbev->set_compare_mode (cmp);
1486 check_tab_avail (); // update tab availability
1487 return NULL;
1491 DbeSession::find_experiment (char *path)
1493 Experiment *exp;
1494 int index;
1495 Vec_loop (Experiment*, exps, index, exp)
1497 if (strcmp (exp->get_expt_name (), path) == 0)
1498 return exp->getExpIdx ();
1500 return -1;
1503 LoadObject *
1504 DbeSession::createLoadObject (const char *nm, int64_t cksum)
1506 return loadObjMap->sync_create_item (nm, cksum);
1509 LoadObject *
1510 DbeSession::createLoadObject (const char *nm, const char *runTimePath, DbeFile *df)
1512 return loadObjMap->sync_create_item (nm, runTimePath, df);
1515 void
1516 DbeSession::append (LoadObject *lobj)
1518 Histable *obj = lobj; // workaround for a C++ problem
1519 objs->append (obj);
1520 lobj->id = objs->size () - 1;
1521 lobjs->append (lobj);
1522 lobj->seg_idx = lobjs->size () - 1;
1523 char *loname = lobj->get_pathname ();
1524 dbeFiles->put (loname, lobj->dbeFile);
1527 DbeJarFile *
1528 DbeSession::get_JarFile (const char *name)
1530 DbeJarFile *jf = dbeJarFiles->get (name);
1531 if (jf == NULL)
1533 jf = new DbeJarFile (name);
1534 dbeJarFiles->put (name, jf);
1536 return jf;
1539 Module *
1540 DbeSession::createModule (LoadObject *lo, const char *nm)
1542 Module *mod = new Module ();
1543 Histable *obj = mod; // workaround for a C++ problem
1544 objs->append (obj);
1545 mod->id = objs->size () - 1;
1546 mod->loadobject = lo;
1547 mod->set_name (dbe_strdup (nm ? nm : localized_SP_UNKNOWN_NAME));
1548 lo->seg_modules->append (mod);
1549 return mod;
1552 Module *
1553 DbeSession::createUnknownModule (LoadObject *lo)
1555 Module *mod = createModule (lo, localized_SP_UNKNOWN_NAME);
1556 mod->flags |= MOD_FLAG_UNKNOWN;
1557 mod->set_file_name (dbe_strdup (localized_SP_UNKNOWN_NAME));
1558 return mod;
1561 SourceFile *
1562 DbeSession::createSourceFile (const char *_path)
1564 char *path = (char *) _path;
1565 if (strncmp (path, NTXT ("./"), 2) == 0)
1566 path += 2;
1567 SourceFile *source = sourcesMap->get (path);
1568 if (source == NULL)
1570 source = new SourceFile (path);
1571 (void) sourcesMap->put (path, source);
1572 append (source);
1574 return source;
1577 Function *
1578 DbeSession::createFunction ()
1580 Function *func = new Function (objs->size ());
1581 Histable *obj = func; // workaround for a C++ problem
1582 objs->append (obj);
1583 return func;
1586 JMethod *
1587 DbeSession::createJMethod ()
1589 JMethod *jmthd = new JMethod (objs->size ());
1590 Histable *obj = jmthd; // workaround for a C++ problem
1591 objs->append (obj);
1592 return jmthd;
1595 Module *
1596 DbeSession::createClassFile (char *className)
1598 ClassFile *cls = new ClassFile ();
1599 cls->set_name (className);
1600 char *clpath = cls->get_java_file_name (className, true);
1601 cls->dbeFile = getDbeFile (clpath, DbeFile::F_JAVACLASS);
1602 free (clpath);
1603 Histable *obj = cls; // workaround for a C++ problem
1604 objs->append (obj);
1605 cls->id = objs->size () - 1;
1606 return cls;
1609 Histable *
1610 DbeSession::createHistObject (Histable::Type type)
1612 switch (type)
1614 case Histable::DOBJECT:
1616 DataObject *dataobj = new DataObject ();
1617 dobjs->append (dataobj);
1618 dataobj->id = dobjs->size () - 1;
1619 return dataobj;
1621 default:
1622 assert (0);
1624 return NULL;
1627 DataObject *
1628 DbeSession::createDataObject ()
1630 DataObject *dataobj = new DataObject ();
1631 dobjs->append (dataobj);
1632 dataobj->id = dobjs->size () - 1;
1633 return dataobj;
1636 DataObject *
1637 DbeSession::createDataObject (DataObject *dobj, DataObject *parent)
1639 DataObject *dataobj = new DataObject ();
1640 dataobj->size = dobj->size;
1641 dataobj->offset = dobj->offset;
1642 dataobj->parent = parent;
1643 dataobj->set_dobjname (dobj->get_typename (), dobj->get_instname ());
1644 dobjs->append (dataobj);
1645 dataobj->id = dobjs->size () - 1;
1646 return dataobj;
1649 DataObject *
1650 DbeSession::createMasterDataObject (DataObject *dobj)
1652 DataObject *parent = NULL;
1653 if (dobj->parent)
1654 { // define master parent first
1655 parent = find_dobj_master (dobj->parent);
1656 if (!parent)
1657 { // clone master from this dataobject parent
1658 parent = createDataObject (dobj->parent);
1659 parent->scope = NULL; // master is scope-less
1660 Dprintf (DEBUG_DATAOBJ,
1661 "Master DataObject(%llu) cloned from (%llu) %s\n",
1662 (ull_t) parent->id, (ull_t) dobj->parent->id,
1663 dobj->parent->get_name ());
1664 // clone master DataObject elements
1665 Vector<DataObject*> *delem = get_dobj_elements (dobj->parent);
1666 int element_index = 0;
1667 DataObject *element = NULL;
1668 Vec_loop (DataObject*, delem, element_index, element)
1670 DataObject *master_element = createDataObject (element, parent);
1671 master_element->scope = NULL; // master is scope-less
1672 Dprintf (DEBUG_DATAOBJ,
1673 "Member DataObject(%llu) cloned from (%llu) %s\n",
1674 (ull_t) master_element->id, (ull_t) element->id,
1675 element->get_name ());
1678 else
1679 Dprintf (DEBUG_DATAOBJ, "Master DataObject(%llu) clone found (%llu) %s\n",
1680 (ull_t) parent->id, (ull_t) dobj->parent->id,
1681 dobj->parent->get_name ());
1684 DataObject *master = find_dobj_master (dobj);
1685 if (!master)
1686 { // clone master from this dataobject
1687 master = createDataObject (dobj, parent);
1688 master->scope = NULL; // master is scope-less
1689 Dprintf (DEBUG_DATAOBJ, "Master DataObject(%llu) cloned from (%llu) %s\n",
1690 (ull_t) master->id, (ull_t) dobj->id, dobj->get_name ());
1692 else
1693 Dprintf (DEBUG_DATAOBJ, "Master DataObject(%llu) clone found (%llu) %s\n",
1694 (ull_t) master->id, (ull_t) dobj->id, dobj->get_name ());
1695 return master;
1698 void
1699 DbeSession::insert_metric (BaseMetric *mtr, Vector<BaseMetric*> *mlist)
1701 if ((mtr->get_flavors () & Metric::STATIC) == 0)
1703 // insert in front of the first STATIC
1704 for (int i = 0, mlist_sz = mlist->size (); i < mlist_sz; i++)
1706 BaseMetric *m = mlist->fetch (i);
1707 if (m->get_flavors () & Metric::STATIC)
1709 mlist->insert (i, mtr);
1710 return;
1714 mlist->append (mtr);
1717 BaseMetricTreeNode*
1718 DbeSession::get_reg_metrics_tree ()
1720 if (reg_metrics_tree == NULL)
1721 // Can't init earlier because BaseMetric() requires DbeSession::ql_parse
1722 reg_metrics_tree = new BaseMetricTreeNode ();
1723 return reg_metrics_tree;
1726 void
1727 DbeSession::update_metric_tree (BaseMetric *m)
1729 get_reg_metrics_tree ()->register_metric (m);
1732 BaseMetric *
1733 DbeSession::register_metric_expr (BaseMetric::Type type, char *cmd, char *expr_spec)
1735 BaseMetric *m = find_metric (type, cmd, expr_spec);
1736 if (m)
1737 return m;
1738 BaseMetric *bm = find_metric (type, cmd, NULL); // clone this version
1739 m = new BaseMetric (*bm);
1740 m->set_expr_spec (expr_spec);
1741 insert_metric (m, reg_metrics);
1742 return m;
1745 BaseMetric *
1746 DbeSession::register_metric (BaseMetric::Type type)
1748 BaseMetric *m = find_metric (type, NULL, NULL);
1749 if (m)
1750 return m;
1751 m = new BaseMetric (type);
1752 insert_metric (m, reg_metrics);
1753 update_metric_tree (m);
1754 return m;
1757 BaseMetric *
1758 DbeSession::register_metric (Hwcentry *ctr, const char* aux, const char* username)
1760 BaseMetric *m = find_metric (BaseMetric::HWCNTR, aux, NULL);
1761 if (m)
1762 // That may be a problem when metrics aren't an exact match.
1763 // For example, memoryspace is disabled in one experiment and not in another.
1764 return m;
1765 if (ctr->timecvt)
1767 char *time_cmd = dbe_sprintf (NTXT ("t%s"), aux);
1768 char *time_username = dbe_sprintf (GTXT ("%s Time"),
1769 ctr->metric ? ctr->metric :
1770 (ctr->name ? ctr->name : ctr->int_name));
1771 BaseMetric *m1;
1772 if (ipc_mode)
1774 // Two visible metrics are presented in GUI
1775 m1 = new BaseMetric (ctr, aux, time_cmd, time_username, VAL_TIMEVAL);
1776 insert_metric (m1, reg_metrics);
1777 update_metric_tree (m1);
1778 m = new BaseMetric (ctr, aux, username, VAL_VALUE, m1);
1780 else
1782 // Only one visible metric is presented in er_print
1783 m1 = new BaseMetric (ctr, aux, time_cmd, time_username, VAL_TIMEVAL | VAL_INTERNAL);
1784 insert_metric (m1, reg_metrics);
1785 m = new BaseMetric (ctr, aux, username, VAL_TIMEVAL | VAL_VALUE, m1);
1787 free (time_cmd);
1788 free (time_username);
1790 else
1791 m = new BaseMetric (ctr, aux, username, VAL_VALUE);
1792 insert_metric (m, reg_metrics);
1793 update_metric_tree (m);
1794 return m;
1797 BaseMetric *
1798 DbeSession::register_metric (char *name, char *username, char *_def)
1800 BaseMetric *m = find_metric (BaseMetric::DERIVED, name, NULL);
1801 if (m)
1802 return m;
1803 Definition *p = Definition::add_definition (_def);
1804 if (p == NULL)
1805 return NULL;
1806 m = new BaseMetric (name, username, p);
1807 insert_metric (m, reg_metrics);
1808 update_metric_tree (m);
1809 return m;
1812 void
1813 DbeSession::drop_metric (BaseMetric *mtr)
1815 Countable *cnt;
1816 int index;
1818 Vec_loop (Countable*, metrics, index, cnt)
1820 if (mtr == (BaseMetric *) cnt->item)
1822 cnt->ref_count--;
1823 if (cnt->ref_count == 0)
1825 // Remove this metric from all views
1826 DbeView *dbev;
1827 int index2;
1828 Vec_loop (DbeView*, views, index2, dbev)
1830 dbev->reset_metrics ();
1832 delete metrics->remove (index);
1833 delete mtr;
1834 return;
1840 BaseMetric *
1841 DbeSession::find_metric (BaseMetric::Type type, const char *cmd, const char *expr_spec)
1843 for (int i = 0, sz = reg_metrics->size (); i < sz; i++)
1845 BaseMetric *bm = reg_metrics->fetch (i);
1846 if (bm->get_type () == type && dbe_strcmp (bm->get_expr_spec (), expr_spec) == 0)
1848 if ((type == BaseMetric::DERIVED || type == BaseMetric::HWCNTR)
1849 && dbe_strcmp (bm->get_cmd (), cmd) != 0)
1850 continue;
1851 return bm;
1854 return NULL;
1857 BaseMetric *
1858 DbeSession::find_base_reg_metric (char * mcmd)
1860 for (int i = 0, sz = reg_metrics->size (); i < sz; i++)
1862 BaseMetric *bm = reg_metrics->fetch (i);
1863 if (bm->get_expr_spec () != NULL)
1864 continue; // skip compare metrics
1865 if (dbe_strcmp (bm->get_cmd (), mcmd) == 0)
1866 return bm;
1868 return NULL;
1871 Vector<BaseMetric*> *
1872 DbeSession::get_base_reg_metrics ()
1874 Vector<BaseMetric*> *mlist = new Vector<BaseMetric*>;
1875 Vector<BaseMetric*> *ml = get_all_reg_metrics ();
1876 for (int i = 0, sz = ml->size (); i < sz; i++)
1878 BaseMetric *m = ml->fetch (i);
1879 if (m->get_expr_spec () == NULL)
1880 mlist->append (m);
1882 return mlist;
1885 void
1886 DbeSession::check_tab_avail ()
1888 DbeView *dbev;
1889 int index;
1890 // tell the views to update their tab lists
1891 Vec_loop (DbeView*, views, index, dbev)
1893 dbev->get_settings ()->updateTabAvailability ();
1897 bool
1898 DbeSession::is_datamode_available ()
1900 Experiment *exp;
1901 int index;
1902 Vec_loop (Experiment*, exps, index, exp)
1904 if (exp->dataspaceavail)
1905 return true;
1907 return false;
1910 bool
1911 DbeSession::is_leaklist_available ()
1913 Experiment *exp;
1914 int index;
1915 Vec_loop (Experiment*, exps, index, exp)
1917 if (exp->leaklistavail)
1918 return true;
1920 return false;
1923 bool
1924 DbeSession::is_heapdata_available ()
1926 Experiment *exp;
1927 int index;
1928 Vec_loop (Experiment*, exps, index, exp)
1930 if (exp->heapdataavail)
1931 return true;
1933 return false;
1936 bool
1937 DbeSession::is_iodata_available ()
1939 Experiment *exp;
1940 int index;
1941 Vec_loop (Experiment*, exps, index, exp)
1943 if (exp->iodataavail)
1944 return true;
1946 return false;
1949 bool
1950 DbeSession::is_racelist_available ()
1952 Experiment *exp;
1953 int index;
1954 Vec_loop (Experiment*, exps, index, exp)
1956 if (exp->racelistavail)
1957 return true;
1959 return false;
1962 bool
1963 DbeSession::is_deadlocklist_available ()
1965 Experiment *exp;
1966 int index;
1967 Vec_loop (Experiment*, exps, index, exp)
1969 if (exp->deadlocklistavail)
1970 return true;
1972 return false;
1975 bool
1976 DbeSession::is_timeline_available ()
1978 Experiment *exp;
1979 int index;
1980 Vec_loop (Experiment*, exps, index, exp)
1982 if (exp->timelineavail)
1983 return true;
1985 return false;
1988 bool
1989 DbeSession::is_ifreq_available ()
1991 Experiment *exp;
1992 int index;
1993 Vec_loop (Experiment*, exps, index, exp)
1995 if (exp->ifreqavail)
1996 return true;
1998 return false;
2001 bool
2002 DbeSession::is_omp_available ()
2004 if (status_ompavail == -1)
2006 status_ompavail = 0;
2007 for (int i = 0, sz = exps ? exps->size () : 0; i < sz; i++)
2009 Experiment *exp = exps->fetch (i);
2010 if (exp->ompavail)
2012 status_ompavail = 1;
2013 break;
2017 return status_ompavail == 1;
2020 bool
2021 DbeSession::has_java ()
2023 int status_has_java = 0;
2024 for (int i = 0, sz = exps ? exps->size () : 0; i < sz; i++)
2026 Experiment *exp = exps->fetch (i);
2027 if (exp->has_java)
2029 status_has_java = 1;
2030 break;
2033 return status_has_java == 1;
2036 bool
2037 DbeSession::has_ompavail ()
2039 int status_has_ompavail = 0;
2040 for (int i = 0, sz = exps ? exps->size () : 0; i < sz; i++)
2042 Experiment *exp = exps->fetch (i);
2043 if (exp->ompavail)
2045 status_has_ompavail = 1;
2046 break;
2049 return status_has_ompavail == 1;
2053 DbeSession::get_clock (int whichexp)
2055 // XXXX clock frequency should be an attribute of each CPU,
2056 // XXX and not a property of the session
2057 // if whichexp is -1, pick the first exp that has a clock
2058 // otherwise return the clock from the numbered experiment
2059 Experiment *exp;
2060 if (whichexp != -1)
2062 exp = get_exp (whichexp);
2063 if (exp != NULL)
2064 return exp->clock;
2065 return 0;
2067 int n = nexps ();
2068 for (int i = 0; i < n; i++)
2070 exp = get_exp (i);
2071 if (exp != NULL && exp->clock != 0)
2072 return exp->clock;
2074 return 0;
2077 LoadObject *
2078 DbeSession::find_lobj_by_name (const char *lobj_name, int64_t cksum)
2080 return loadObjMap->get (lobj_name, cksum);
2083 static unsigned
2084 hash (char *s)
2086 unsigned res = 0;
2087 for (int i = 0; i < 64 && *s; i++)
2088 res = res * 13 + *s++;
2089 return res;
2092 // This method is introduced to fix performance
2093 // problems with the data space profiling in the
2094 // current release. A better design is desired.
2095 void
2096 DbeSession::dobj_updateHT (DataObject *dobj)
2098 unsigned index = hash (dobj->get_unannotated_name ()) % HTableSize;
2099 List *list = new List;
2100 list->val = (void*) dobj;
2101 list->next = dnameHTable[index];
2102 dnameHTable[index] = list;
2105 DataObject *
2106 DbeSession::find_dobj_by_name (char *dobj_name)
2108 unsigned index = hash (dobj_name) % HTableSize;
2109 List *list = dnameHTable[index];
2110 for (; list; list = list->next)
2112 DataObject *d = (DataObject*) list->val;
2113 if (strcmp (d->get_unannotated_name (), dobj_name) == 0)
2114 return d;
2116 return (DataObject *) NULL;
2119 DataObject *
2120 DbeSession::find_dobj_match (DataObject *dobj)
2122 char *dobj_name = dobj->get_unannotated_name ();
2123 unsigned index = hash (dobj_name) % HTableSize;
2124 List *list = dnameHTable[index];
2125 for (; list; list = list->next)
2127 DataObject *d = (DataObject*) list->val;
2128 if (strcmp (d->get_unannotated_name (), dobj_name) == 0
2129 && d->size == dobj->size && d->offset == dobj->offset
2130 && d->scope == dobj->scope)
2131 return d;
2133 return (DataObject *) NULL;
2136 DataObject *
2137 DbeSession::find_dobj_master (DataObject *dobj)
2139 char *dobj_name = dobj->get_unannotated_name ();
2140 unsigned index = hash (dobj_name) % HTableSize;
2141 List *list = dnameHTable[index];
2142 for (; list; list = list->next)
2144 DataObject *d = (DataObject*) list->val;
2145 // XXXX should parent also match?
2146 if (strcmp (d->get_unannotated_name (), dobj_name) == 0
2147 && d->size == dobj->size && d->offset == dobj->offset
2148 && d->master == NULL && d->scope == NULL)
2149 return d;
2151 return (DataObject *) NULL;
2154 Vector<DataObject*>*
2155 DbeSession::get_dobj_elements (DataObject *dobj)
2157 DataObject *d;
2158 int index;
2159 Vector<DataObject*> *elements = new Vector<DataObject*>;
2160 if (dobj == d_total)
2161 return elements;
2162 Vec_loop (DataObject*, dobjs, index, d)
2164 if (d->get_parent () && d->get_parent () == dobj)
2165 elements->append (d);
2167 return elements;
2170 Vector<LoadObject*>*
2171 DbeSession::get_text_segments ()
2173 LoadObject *lo;
2174 int index;
2175 Vector<LoadObject*> *tlobjs = new Vector<LoadObject*>;
2176 Vec_loop (LoadObject*, lobjs, index, lo)
2178 if (lo->type == LoadObject::SEG_TEXT)
2179 tlobjs->append (lo);
2181 return tlobjs;
2184 static long long
2185 getNumber (const char *s, char * &last)
2187 long long val;
2188 char *sp;
2189 errno = 0;
2190 val = strtoll (s, &sp, 0);
2191 if (errno == EINVAL)
2192 last = NULL;
2193 else
2195 while (isspace (*sp))
2196 sp++;
2197 last = sp;
2199 return (val);
2202 bool
2203 DbeSession::find_obj (FILE *dis_file, FILE *inp_file, Histable *&obj,
2204 char *name, const char *sel, Histable::Type type, bool xdefault)
2206 Vector<Histable*> *obj_lst;
2207 int which = -1;
2208 char *last = NULL;
2209 if (type != Histable::FUNCTION && sel)
2211 // check that a number has been provided
2212 which = (int) getNumber (sel, last);
2213 if (last == NULL || *last != '\0')
2215 fprintf (stderr, GTXT ("Error: Invalid number entered: %s\n"), sel);
2216 sel = NULL;
2217 which = 0;
2219 which--;
2221 obj_lst = new Vector<Histable*>;
2222 switch (type)
2224 case Histable::FUNCTION:
2225 obj = map_NametoFunction (name, obj_lst, sel);
2226 break;
2227 case Histable::MODULE:
2228 obj = map_NametoModule (name, obj_lst, which);
2229 break;
2230 case Histable::LOADOBJECT:
2231 obj = map_NametoLoadObject (name, obj_lst, which);
2232 break;
2233 case Histable::DOBJECT:
2234 obj = map_NametoDataObject (name, obj_lst, which);
2235 break;
2236 default:
2237 abort (); // unexpected Histable!
2240 if ((obj == NULL) && (obj_lst->size () > 0))
2242 if (obj_lst->size () == 1)
2243 which = 0;
2244 else
2246 if (sel && (which < 0 || which >= obj_lst->size ()))
2247 fprintf (stderr, GTXT ("Error: Invalid number entered: %s\n"), sel);
2248 if (xdefault)
2250 fprintf (stderr, GTXT ("Default selection \"1\" made\n"));
2251 which = 0;
2253 else
2255 which = ask_which (dis_file, inp_file, obj_lst, name);
2256 if (which == -1)
2258 delete obj_lst;
2259 return false;
2263 obj = obj_lst->fetch (which);
2265 delete obj_lst;
2266 return true;
2270 DbeSession::ask_which (FILE *dis_file, FILE *inp_file,
2271 Vector<Histable*> *list, char *name)
2273 Histable *hitem;
2274 Function *func;
2275 Module *module;
2276 int which, index, index1;
2277 char *item_name, *lo_name, *fname, *last;
2278 char buf[BUFSIZ];
2279 for (;;)
2281 fprintf (dis_file, GTXT ("Available name list:\n"));
2282 fprintf (dis_file, GTXT ("%8d) Cancel\n"), 0);
2283 Vec_loop (Histable*, list, index, hitem)
2285 index1 = index + 1;
2286 item_name = hitem->get_name ();
2287 switch (hitem->get_type ())
2289 case Histable::FUNCTION:
2290 func = (Function *) hitem;
2291 module = func->module;
2293 // id == -1 indicates er_src invocation
2294 if (module == NULL || (module->lang_code == Sp_lang_java
2295 && module->loadobject->id == -1))
2296 fprintf (dis_file, NTXT ("%8d) %s\n"), index1, item_name);
2297 else
2299 lo_name = module->loadobject->get_pathname ();
2300 fname = (module->file_name && *module->file_name) ?
2301 module->file_name : module->get_name ();
2302 if (fname && *fname)
2303 fprintf (dis_file, NTXT ("%8d) %s %s:0x%llx (%s)\n"), index1,
2304 item_name, lo_name, (ull_t) func->img_offset, fname);
2305 else
2306 fprintf (dis_file, NTXT ("%8d) %s %s:0x%llx\n"), index1,
2307 item_name, lo_name, (ull_t) func->img_offset);
2309 break;
2310 case Histable::MODULE:
2311 module = (Module *) hitem;
2312 lo_name = module->loadobject->get_pathname ();
2313 if (name[strlen (name) - 1] ==
2314 module->file_name[strlen (module->file_name) - 1])
2315 fprintf (dis_file, NTXT ("%8d) %s(%s)\n"), index1,
2316 module->file_name, lo_name);
2317 else
2318 fprintf (dis_file, NTXT ("%8d) %s(%s)\n"), index1, item_name,
2319 lo_name);
2320 break;
2321 default:
2322 fprintf (dis_file, NTXT ("%8d) %s\n"), index1, item_name);
2323 break;
2326 if (inp_file != stdin)
2327 return -1;
2328 fprintf (dis_file, GTXT ("Enter selection: "));
2329 if (fgets (buf, (int) sizeof (buf), inp_file) == NULL)
2331 fprintf (stderr, GTXT ("Error: Invalid number entered:\n"));
2332 return -1;
2334 which = (int) getNumber (buf, last);
2335 if (last && *last == '\0')
2336 if (which >= 0 && which <= list->size ())
2337 return which - 1;
2338 fprintf (stderr, GTXT ("Error: Invalid number entered: %s\n"), buf);
2342 static bool
2343 match_basename (char *name, char *full_name, int len = -1)
2345 if (full_name == NULL)
2346 return false;
2347 if (!strchr (name, '/'))
2348 full_name = get_basename (full_name);
2349 if (len == -1)
2350 return streq (name, full_name);
2351 return strncmp (name, full_name, len) == 0;
2354 LoadObject *
2355 DbeSession::map_NametoLoadObject (char *name, Vector<Histable*> *list, int which)
2357 // Search the tree to find the first module whose module name
2358 // matches "name" or whose source file name matches "name"
2359 // Issues: is the name a pathname, or a base name?
2360 // Should we look at suffix to disambiguate?
2361 LoadObject *loitem;
2362 int index;
2363 Vec_loop (LoadObject*, lobjs, index, loitem)
2365 // try pathname first
2366 // if failed, try object name next
2367 if (match_basename (name, loitem->get_pathname ()) ||
2368 match_basename (name, loitem->get_name ()))
2370 if (which == list->size ())
2371 return loitem;
2372 list->append (loitem);
2375 return (LoadObject *) NULL;
2378 Module *
2379 DbeSession::map_NametoModule (char *name, Vector<Histable*> *list, int which)
2381 // Search the tree to find the first loadobject whose loadobject name
2382 // matches "name".
2384 // Issues: is the name a pathname, or a base name?
2385 // Should we look at suffix to disambiguate?
2386 LoadObject *loitem;
2387 Module *mitem;
2388 int index1, index2;
2389 Vec_loop (LoadObject*, lobjs, index1, loitem)
2391 Vec_loop (Module*, loitem->seg_modules, index2, mitem)
2393 // try source name first
2394 // if failed, try object name next
2395 if (match_basename (name, mitem->file_name) ||
2396 match_basename (name, mitem->get_name ()))
2398 if (which == list->size ())
2399 return mitem;
2400 list->append (mitem);
2404 return (Module *) NULL;
2407 Function *
2408 DbeSession::map_NametoFunction (char *name, Vector<Histable*> *list,
2409 const char *sel)
2411 // Search the tree to find the first function whose
2412 // name matches "name".
2413 // Issues: is the name a full name, or a short name?
2414 // Is it a demangled name? If so, what about spaces
2415 // within the name?
2416 // Is there a way to return all names that match?
2417 // How can the user specify a particular function of that name?
2418 LoadObject *loitem;
2419 Function *fitem, *main_func = NULL;
2420 Module *mitem, *main_mod = NULL;
2421 int index1, index2, index3, which = -1;
2422 if (sel)
2424 char *last = NULL;
2425 if (*sel == '@')
2426 { // 'sel' is "@seg_num:address"
2427 which = (int) getNumber (sel + 1, last);
2428 if (last == NULL || *last != ':' || (which < 0) || (which >= lobjs->size ()))
2430 fprintf (stderr, GTXT ("Error: Invalid number entered: %s\n"), sel);
2431 return NULL;
2433 uint64_t address = getNumber (last + 1, last);
2434 if (last == NULL || *last != '\0')
2436 fprintf (stderr, GTXT ("Error: Invalid number entered: %s\n"), sel);
2437 return NULL;
2439 loitem = lobjs->fetch (which);
2440 Vec_loop (Module*, loitem->seg_modules, index2, mitem)
2442 Vec_loop (Function*, mitem->functions, index3, fitem)
2444 if (address == fitem->img_offset && match_FName (name, fitem))
2445 return fitem;
2448 return NULL;
2451 which = (int) getNumber (sel, last);
2452 if (last == NULL || *last != '\0')
2454 fprintf (stderr, GTXT ("Error: Invalid number entered: %s\n"), sel);
2455 return NULL;
2457 which--;
2460 int len_path = 0;
2461 char *with_path = name;
2462 name = StrRchr (name, '`');
2463 if (name != with_path)
2464 len_path = (int) (name - with_path);
2465 else
2466 with_path = NULL;
2468 Vec_loop (LoadObject*, lobjs, index1, loitem)
2470 Vec_loop (Module*, loitem->seg_modules, index2, mitem)
2472 if (with_path)
2473 { // with file name
2474 // try source name first
2475 // if failed, try object name next
2476 if (!match_basename (with_path, mitem->file_name, len_path) &&
2477 !match_basename (with_path, mitem->get_name (), len_path))
2478 continue;
2480 Vec_loop (Function*, mitem->functions, index3, fitem)
2482 if (match_FName (name, fitem))
2484 if (which == list->size ())
2485 return fitem;
2486 list->append (fitem);
2487 continue;
2489 if (streq (fitem->get_name (), NTXT ("MAIN_")) && mitem->is_fortran ())
2491 main_func = fitem;
2492 main_mod = mitem;
2498 if (main_mod && main_func)
2500 main_mod->read_stabs ();
2501 if (streq (main_func->get_match_name (), name) && which <= 1)
2502 return main_func;
2504 return (Function *) NULL;
2507 DataObject *
2508 DbeSession::map_NametoDataObject (char *name, Vector<Histable*> *list,
2509 int which)
2511 // Search master list to find dataobjects whose names match "name"
2512 // selecting only the entry corresponding to "which" if it is not -1.
2513 // Issues: is the name fully qualified or only partially?
2514 DataObject *ditem = NULL;
2515 int index;
2516 char *full_name;
2517 Vec_loop (DataObject*, dobjs, index, ditem)
2519 if (ditem->scope) continue; // skip non-master dataobjects
2521 // try fully-qualified dataobject name first
2522 if ((full_name = ditem->get_name ()) != NULL)
2524 if (streq (name, full_name))
2526 if (which == list->size ())
2527 return ditem;
2528 list->append (ditem);
2532 if (list->size () > 0)
2533 return ditem; // return fully-qualified match
2535 // if fully-qualified name doesn't match anything, try a partial match
2536 Vec_loop (DataObject*, dobjs, index, ditem)
2538 if (ditem->scope) continue; // skip non-master dataobjects
2540 // try fully-qualified dataobject name first
2541 if ((full_name = ditem->get_name ()) != NULL)
2543 if (strstr (full_name, name))
2545 if (which == list->size ())
2546 return ditem;
2547 list->append (ditem);
2551 return (DataObject *) NULL;
2554 bool
2555 DbeSession::match_FName (char *name, Function *func)
2557 size_t len;
2558 char buf[MAXDBUF];
2559 char *full_name;
2560 if (streq (func->get_name (), name)) // try full name comparison
2561 return true;
2562 if (streq (func->get_mangled_name (), name)) // try mangled name
2563 return true;
2564 if (streq (func->get_match_name (), name)) // try match name
2565 return true;
2567 Module *md = func->module; // try FORTRAN name
2568 if (md && md->is_fortran ())
2570 char *mangled_name = func->get_mangled_name ();
2571 len = strlen (name);
2572 if (((len + 1) == strlen (mangled_name)) &&
2573 (strncmp (name, mangled_name, len) == 0))
2574 return true;
2576 snprintf (buf, sizeof (buf), NTXT ("%s"), func->get_name ());
2577 full_name = buf;
2578 char *arg = NULL; // find modifier and C++ class name
2579 int i = get_paren (buf);
2580 if (i >= 0)
2582 arg = buf + i;
2583 *arg = '\0';
2586 char *mod = strchr (full_name, ' ');
2587 char *cls = strchr (full_name, ':');
2589 if (mod)
2591 len = mod - full_name + 1;
2592 if (!strncmp (full_name, name, len))
2593 name += len;
2594 full_name += len;
2595 if (streq (full_name, name)) // try without modifier
2596 return true;
2599 size_t len_cmp = strlen (name);
2600 if (arg)
2602 *arg = '(';
2603 len = arg - full_name; // try without 'args'
2604 if (len_cmp == len && !strncmp (full_name, name, len))
2605 return true;
2606 if (cls)
2608 len = arg - cls - 2; // and without 'class name'
2609 if ((len_cmp == len) && !strncmp (cls + 2, name, len))
2610 return true;
2614 if (cls)
2616 len = cls - full_name; // try C++ class name only
2617 if (len_cmp == len && !strncmp (full_name, name, len))
2618 return true;
2619 if (streq (cls + 2, name)) // try without 'class name'
2620 return true;
2622 return false;
2625 bool
2626 DbeSession::add_path (char *path)
2628 return add_path (path, get_search_path ());
2631 bool
2632 DbeSession::add_classpath (char *path)
2634 return add_path (path, classpath);
2637 Vector<DbeFile*> *
2638 DbeSession::get_classpath ()
2640 if (classpath_df == NULL)
2641 classpath_df = new Vector<DbeFile*>;
2642 for (int i = classpath_df->size (), sz = classpath->size (); i < sz; i++)
2643 classpath_df->store (i, getDbeFile (classpath->fetch (i),
2644 DbeFile::F_DIR_OR_JAR));
2645 return classpath_df;
2648 bool
2649 DbeSession::add_path (char *path, Vector<char*> *pathes)
2651 bool result = false;
2652 Vector <char *> *tokens = split_str (path, ':');
2653 for (long j = 0, jsz = VecSize (tokens); j < jsz; j++)
2655 char *spath = tokens->get (j);
2656 // Don't append path if it's already there
2657 bool got = false;
2658 for (int i = 0, sz = pathes->size (); i < sz; i++)
2660 char *nm = pathes->get (i);
2661 if (streq (nm, spath))
2663 got = true;
2664 break;
2667 if (!got)
2669 pathes->append (spath);
2670 result = true;
2672 else
2673 free (spath);
2675 delete tokens;
2676 return result;
2679 void
2680 DbeSession::set_need_refind ()
2682 Vector<DbeFile*> *f_list = dbeFiles->values ();
2683 for (long i = 0, sz = f_list == NULL ? 0 : f_list->size (); i < sz; i++)
2685 DbeFile *f = f_list->get (i);
2686 f->set_need_refind (true);
2688 delete f_list;
2689 for (long i = 0, sz = sources == NULL ? 0 : sources->size (); i < sz; i++)
2691 SourceFile *f = sources->get (i);
2692 if (f && f->dbeFile)
2693 f->dbeFile->set_need_refind (true);
2697 void
2698 DbeSession::set_search_path (Vector<char*> *path, bool reset)
2700 if (reset)
2701 search_path->destroy ();
2702 for (int i = 0, sz = path == NULL ? 0 : path->size (); i < sz; i++)
2704 char *name = path->fetch (i);
2705 if (add_path (name))
2706 reset = true;
2708 if (reset)
2710 set_need_refind ();
2712 // now reset the string setting for it
2713 StringBuilder sb;
2714 for (int i = 0, sz = search_path == NULL ? 0 : search_path->size (); i < sz; i++)
2716 char *name = search_path->fetch (i);
2717 if (sb.length () != 0)
2718 sb.append (':');
2719 sb.append (name);
2721 free (settings->str_search_path);
2722 settings->str_search_path = sb.toString ();
2726 void
2727 DbeSession::set_search_path (char *_lpath, bool reset)
2729 Vector<char *> *path = new Vector<char*>;
2730 char *lpath = dbe_strdup (_lpath);
2731 for (char *s = lpath; s;)
2733 path->append (s);
2734 s = strchr (s, ':');
2735 if (s)
2737 *s = 0;
2738 s++;
2741 set_search_path (path, reset);
2742 delete path;
2743 free (lpath);
2746 void
2747 DbeSession::set_pathmaps (Vector<pathmap_t*> *newPathMap)
2749 set_need_refind ();
2750 settings->set_pathmaps (newPathMap);
2753 Vector<pathmap_t*> *
2754 DbeSession::get_pathmaps ()
2756 return settings->pathmaps;
2759 void
2760 DbeSession::mobj_define (MemObjType_t *mobj)
2762 settings->mobj_define (mobj, false);
2763 DbeView *dbev;
2764 int index;
2765 Vec_loop (DbeView*, views, index, dbev)
2767 dbev->get_settings ()->mobj_define (mobj, false);
2771 void
2772 DbeSession::dump_segments (FILE *out)
2774 int index;
2775 LoadObject *loitem;
2776 Vec_loop (LoadObject*, lobjs, index, loitem)
2778 fprintf (out, NTXT ("Segment %d -- %s -- %s\n\n"),
2779 index, loitem->get_name (), loitem->get_pathname ());
2780 loitem->dump_functions (out);
2781 fprintf (out, NTXT ("\n End Segment %d -- %s -- %s\n\n"),
2782 index, loitem->get_name (), loitem->get_pathname ());
2786 void
2787 DbeSession::dump_dataobjects (FILE *out)
2789 DataObject *ditem;
2790 int index;
2792 fprintf (out, NTXT ("\nMaster list of DataObjects:\n"));
2793 Vec_loop (DataObject*, dobjs, index, ditem)
2795 Histable* scope = ditem->get_scope ();
2796 DataObject* parent = ditem->get_parent ();
2797 DataObject* master = ditem->get_master ();
2798 if (parent != NULL)
2799 fprintf (out, "id %6lld: [%4lld] parent = %6lld, offset = %+4lld %s\n",
2800 (ll_t) ditem->id, (ll_t) ditem->get_size (),
2801 (ll_t) parent->id, (ll_t) ditem->get_offset (),
2802 ditem->get_name ());
2803 else
2805 // parent is NULL
2806 fprintf (out, NTXT ("id %6lld: [%4lld] %s "),
2807 (ll_t) ditem->id, (ll_t) ditem->get_size (),
2808 ditem->get_name ());
2809 if (master != NULL)
2810 fprintf (out, NTXT (" master=%lld "), (ll_t) master->id);
2811 else if (scope != NULL)
2812 fprintf (out, NTXT (" master=?? "));
2813 else
2814 fprintf (out, NTXT (" MASTER "));
2815 #if DEBUG
2816 if (scope != NULL)
2818 switch (scope->get_type ())
2820 case Histable::LOADOBJECT:
2821 case Histable::FUNCTION:
2822 fprintf (out, NTXT ("%s"), scope->get_name ());
2823 break;
2824 case Histable::MODULE:
2826 char *filename = get_basename (scope->get_name ());
2827 fprintf (out, NTXT ("%s"), filename);
2828 break;
2830 default:
2831 fprintf (out, NTXT (" Unexpected scope %d:%s"),
2832 scope->get_type (), scope->get_name ());
2835 #endif
2836 fprintf (out, NTXT ("\n"));
2841 void
2842 DbeSession::dump_map (FILE *out)
2844 Experiment *exp;
2845 int index;
2846 Vec_loop (Experiment*, exps, index, exp)
2848 exp->dump_map (out);
2852 void
2853 DbeSession::dump_stacks (FILE *outfile)
2855 Experiment *exp;
2856 int n = nexps ();
2857 FILE *f = (outfile == NULL ? stderr : outfile);
2858 for (int i = 0; i < n; i++)
2860 exp = get_exp (i);
2861 fprintf (f, GTXT ("Experiment %d -- %s\n"), i, exp->get_expt_name ());
2862 exp->dump_stacks (f);
2866 void
2867 DbeSession::propNames_name_store (int propId, const char *propName)
2869 PropDescr *prop = new PropDescr (propId, propName);
2870 prop->flags = PRFLAG_NOSHOW; // do not show descriptions
2871 propNames->store (propId, prop);
2874 void
2875 DbeSession::propNames_name_store (int propId, const char* propName,
2876 const char* propUname, VType_type dataType,
2877 int flags)
2879 PropDescr *prop = new PropDescr (propId, propName);
2880 prop->vtype = dataType;
2881 prop->uname = dbe_strdup (propUname);
2882 prop->flags = flags;
2883 propNames->store (propId, prop);
2886 char *
2887 DbeSession::propNames_name_fetch (int i)
2889 PropDescr *prop = propNames->fetch (i);
2890 if (prop)
2891 return prop->name;
2892 return NULL;
2896 DbeSession::registerPropertyName (const char *name)
2898 if (name == NULL)
2899 return PROP_NONE;
2900 for (int i = 0; i < propNames->size (); i++)
2902 char *pname = propNames_name_fetch (i);
2903 if (pname && strcasecmp (pname, name) == 0)
2904 return i;
2906 int propId = propNames->size ();
2907 propNames_name_store (propId, name);
2908 return propId;
2912 DbeSession::getPropIdByName (const char *name)
2914 if (name == NULL)
2915 return PROP_NONE;
2916 for (int i = 0; i < propNames->size (); i++)
2918 char *pname = propNames_name_fetch (i);
2919 if (pname && strcasecmp (pname, name) == 0)
2920 return i;
2922 return PROP_NONE;
2925 char *
2926 DbeSession::getPropName (int propId)
2928 if (!propNames)
2929 return NULL;
2930 if (propId < 0 || propId >= propNames->size ())
2931 return NULL;
2932 return dbe_strdup (propNames_name_fetch (propId));
2935 char *
2936 DbeSession::getPropUName (int propId)
2938 if (!propNames)
2939 return NULL;
2940 if (propId < 0 || propId >= propNames->size ())
2941 return NULL;
2942 PropDescr *prop = propNames->fetch (propId);
2943 if (prop)
2944 return dbe_strdup (prop->uname);
2945 return NULL;
2948 void
2949 DbeSession::append (UserLabel *lbl)
2951 if (lbl->expr)
2953 if (userLabels == NULL)
2954 userLabels = new Vector<UserLabel*> ();
2955 userLabels->append (lbl);
2959 void
2960 DbeSession::append (SourceFile *sf)
2962 sources->append (sf);
2963 objs->append (sf);
2966 UserLabel *
2967 DbeSession::findUserLabel (const char *name)
2969 for (int i = 0, sz = userLabels ? userLabels->size () : 0; i < sz; i++)
2971 UserLabel *lbl = userLabels->fetch (i);
2972 if (strcasecmp (lbl->name, name) == 0)
2973 return lbl;
2975 return NULL;
2978 Expression *
2979 DbeSession::findObjDefByName (const char *name)
2981 Expression *expr = NULL;
2983 MemObjType_t *mot = MemorySpace::findMemSpaceByName (name);
2984 if (mot != NULL)
2986 char *index_expr_str = mot->index_expr;
2987 expr = ql_parse (index_expr_str);
2990 if (expr == NULL)
2992 int indxtype = findIndexSpaceByName (name);
2993 expr = getIndexSpaceExpr (indxtype);
2995 if (expr == NULL)
2997 UserLabel *ulbl = findUserLabel (name);
2998 if (ulbl)
2999 expr = ulbl->expr;
3001 return expr;
3004 Expression *
3005 DbeSession::ql_parse (const char *expr_spec)
3007 if (expr_spec == NULL)
3008 expr_spec = "";
3009 QL::Result result (expr_spec);
3010 QL::Parser qlparser (result);
3011 if (qlparser.parse () != 0)
3012 return NULL;
3013 return result ();
3016 Vector<void*> *
3017 DbeSession::getIndxObjDescriptions ()
3019 int size = dyn_indxobj_indx;
3020 if (size == 0)
3021 return NULL;
3022 Vector<int> *type = new Vector<int>(dyn_indxobj_indx);
3023 Vector<char*> *desc = new Vector<char*>(dyn_indxobj_indx);
3024 Vector<char*> *i18ndesc = new Vector<char*>(dyn_indxobj_indx);
3025 Vector<char> *mnemonic = new Vector<char>(dyn_indxobj_indx);
3026 Vector<int> *orderList = new Vector<int>(dyn_indxobj_indx);
3027 Vector<char*> *exprList = new Vector<char*>(dyn_indxobj_indx);
3028 Vector<char*> *sdesc = new Vector<char*>(dyn_indxobj_indx);
3029 Vector<char*> *ldesc = new Vector<char*>(dyn_indxobj_indx);
3031 for (long i = 0, sz = VecSize (dyn_indxobj); i < sz; i++)
3033 IndexObjType_t *tot = dyn_indxobj->get (i);
3034 if (tot->memObj == NULL)
3036 type->append ((int) tot->type);
3037 desc->append (dbe_strdup (tot->name));
3038 i18ndesc->append (dbe_strdup (tot->i18n_name));
3039 sdesc->append (dbe_strdup (tot->short_description));
3040 ldesc->append (dbe_strdup (tot->long_description));
3041 mnemonic->append (tot->mnemonic);
3042 orderList->append (settings->indx_tab_order->fetch (i));
3043 exprList->append (dbe_strdup (tot->index_expr_str));
3046 Vector<void*> *res = new Vector<void*>(8);
3047 res->store (0, type);
3048 res->store (1, desc);
3049 res->store (2, mnemonic);
3050 res->store (3, i18ndesc);
3051 res->store (4, orderList);
3052 res->store (5, exprList);
3053 res->store (6, sdesc);
3054 res->store (7, ldesc);
3055 return (res);
3058 // Static function to get a vector of custom index object definitions
3059 Vector<void*> *
3060 DbeSession::getCustomIndxObjects ()
3062 Vector<char*> *name = new Vector<char*>;
3063 Vector<char*> *formula = new Vector<char*>;
3064 for (long i = dyn_indxobj_indx_fixed, sz = VecSize (dyn_indxobj); i < sz; i++)
3066 IndexObjType_t *tot = dyn_indxobj->get (i);
3067 if (tot->memObj == NULL)
3069 name->append (dbe_strdup (tot->name));
3070 formula->append (dbe_strdup (tot->index_expr_str));
3073 Vector<void*> *res = new Vector<void*>(2);
3074 res->store (0, name);
3075 res->store (1, formula);
3076 return (res);
3079 // Static function to define a new index object type
3080 char *
3081 DbeSession::indxobj_define (const char *mname, char *i18nname, const char *index_expr_str, char *short_description, char *long_description)
3083 if (mname == NULL)
3084 return dbe_strdup (GTXT ("No index object type name has been specified."));
3085 if (isalpha ((int) (mname[0])) == 0)
3086 return dbe_sprintf (GTXT ("Index Object type name %s does not begin with an alphabetic character"),
3087 mname);
3088 const char *p = mname;
3089 while (*p != 0)
3091 if ((isalnum ((int) (*p)) == 0) && (*p != '_'))
3092 return dbe_sprintf (GTXT ("Index Object type name %s contains a non-alphanumeric character"),
3093 mname);
3094 p++;
3097 // make sure the name is not in use
3098 if (MemorySpace::findMemSpaceByName (mname) != NULL)
3099 return dbe_sprintf (GTXT ("Memory/Index Object type name %s is already defined"),
3100 mname);
3102 int idxx = findIndexSpaceByName (mname);
3103 if (idxx >= 0)
3105 IndexObjType_t *mt = dyn_indxobj->fetch (idxx);
3106 if (strcmp (mt->index_expr_str, index_expr_str) == 0)
3107 // It's a redefinition, but the new definition is the same
3108 return NULL;
3109 return dbe_sprintf (GTXT ("Memory/Index Object type name %s is already defined"),
3110 mname);
3112 if (index_expr_str == NULL)
3113 return dbe_strdup (GTXT ("No index-expr has been specified."));
3114 if (strlen (index_expr_str) == 0)
3115 return dbe_sprintf (GTXT ("Index Object index expression is invalid: %s"),
3116 index_expr_str);
3118 // verify that the index expression parses correctly
3119 char *expr_str = dbe_strdup (index_expr_str);
3120 Expression *expr = ql_parse (expr_str);
3121 if (expr == NULL)
3122 return dbe_sprintf (GTXT ("Index Object index expression is invalid: %s"),
3123 expr_str);
3125 // It's OK, create the new table entry
3126 IndexObjType_t *tot = new IndexObjType_t;
3127 tot->type = dyn_indxobj_indx++;
3128 tot->name = dbe_strdup (mname);
3129 tot->i18n_name = dbe_strdup (i18nname);
3130 tot->short_description = dbe_strdup (short_description);
3131 tot->long_description = dbe_strdup (long_description);
3132 tot->index_expr_str = expr_str;
3133 tot->index_expr = expr;
3134 tot->mnemonic = mname[0];
3136 // add it to the list
3137 dyn_indxobj->append (tot);
3138 idxobjs->append (new HashMap<uint64_t, Histable*>);
3140 // tell the session
3141 settings->indxobj_define (tot->type, false);
3143 DbeView *dbev;
3144 int index;
3145 Vec_loop (DbeView*, views, index, dbev)
3147 dbev->addIndexSpace (tot->type);
3149 return NULL;
3152 char *
3153 DbeSession::getIndexSpaceName (int index)
3155 if (index < 0 || index >= dyn_indxobj->size ())
3156 return NULL;
3157 return dyn_indxobj->fetch (index)->name;
3160 char *
3161 DbeSession::getIndexSpaceDescr (int index)
3163 if (index < 0 || index >= dyn_indxobj->size ())
3164 return NULL;
3165 return dyn_indxobj->fetch (index)->i18n_name;
3168 Expression *
3169 DbeSession::getIndexSpaceExpr (int index)
3171 if (index < 0 || index >= dyn_indxobj->size ())
3172 return NULL;
3173 return dyn_indxobj->fetch (index)->index_expr;
3176 char *
3177 DbeSession::getIndexSpaceExprStr (int index)
3179 if (index < 0 || index >= dyn_indxobj->size ())
3180 return NULL;
3181 return dyn_indxobj->fetch (index)->index_expr_str;
3185 DbeSession::findIndexSpaceByName (const char *mname)
3187 int idx;
3188 IndexObjType_t *mt;
3189 Vec_loop (IndexObjType_t*, dyn_indxobj, idx, mt)
3191 if (strcasecmp (mt->name, mname) == 0)
3192 return idx;
3194 return -1;
3197 void
3198 DbeSession::removeIndexSpaceByName (const char *mname)
3200 IndexObjType_t *indObj = findIndexSpace (mname);
3201 if (indObj)
3202 indObj->name[0] = 0;
3205 IndexObjType_t *
3206 DbeSession::getIndexSpace (int index)
3208 return ((index < 0) || (index >= VecSize (dyn_indxobj))) ? NULL : dyn_indxobj->get (index);
3211 IndexObjType_t *
3212 DbeSession::findIndexSpace (const char *mname)
3214 return getIndexSpace (findIndexSpaceByName (mname));
3217 void
3218 DbeSession::get_filter_keywords (Vector<void*> *res)
3220 Vector <char*> *kwCategory = (Vector<char*>*) res->fetch (0);
3221 Vector <char*> *kwCategoryI18N = (Vector<char*>*) res->fetch (1);
3222 Vector <char*> *kwDataType = (Vector<char*>*) res->fetch (2);
3223 Vector <char*> *kwKeyword = (Vector<char*>*) res->fetch (3);
3224 Vector <char*> *kwFormula = (Vector<char*>*) res->fetch (4);
3225 Vector <char*> *kwDescription = (Vector<char*>*) res->fetch (5);
3226 Vector <void*> *kwEnumDescs = (Vector<void*>*) res->fetch (6);
3228 char *vtypeNames[] = VTYPE_TYPE_NAMES;
3229 for (long i = 0, sz = userLabels ? userLabels->size () : 0; i < sz; i++)
3231 UserLabel *lbl = userLabels->fetch (i);
3232 kwCategory->append (dbe_strdup (NTXT ("FK_LABEL")));
3233 kwCategoryI18N->append (dbe_strdup (GTXT ("Labels")));
3234 kwDataType->append (dbe_strdup (vtypeNames[TYPE_BOOL]));
3235 kwKeyword->append (dbe_strdup (lbl->name));
3236 kwFormula->append (dbe_strdup (lbl->str_expr));
3237 kwDescription->append (dbe_strdup (lbl->comment));
3238 kwEnumDescs->append (NULL);
3241 for (long i = 0, sz = propNames ? propNames->size () : 0; i < sz; i++)
3243 PropDescr *prop = propNames->fetch (i);
3244 char *pname = prop ? prop->name : NULL;
3245 if (pname == NULL || *pname == 0 || prop->flags & PRFLAG_NOSHOW)
3246 continue;
3247 int vtypeNum = prop->vtype;
3248 if (vtypeNum < 0 || vtypeNum >= TYPE_LAST)
3249 vtypeNum = TYPE_NONE;
3250 kwCategory->append (dbe_strdup (NTXT ("FK_EVTPROP"))); //Event Property
3251 kwCategoryI18N->append (dbe_strdup (GTXT ("Misc. Definitions")));
3252 kwDataType->append (dbe_strdup (vtypeNames[vtypeNum]));
3253 kwKeyword->append (dbe_strdup (pname));
3254 kwFormula->append (NULL);
3255 kwDescription->append (dbe_strdup (prop->uname));
3256 kwEnumDescs->append (NULL);
3259 for (long i = 0, sz = dyn_indxobj ? dyn_indxobj->size () : 0; i < sz; i++)
3261 IndexObjType_t *obj = dyn_indxobj->get (i);
3262 if (obj->memObj)
3263 continue;
3264 kwCategory->append (dbe_strdup (NTXT ("FK_IDXOBJ")));
3265 kwCategoryI18N->append (dbe_strdup (GTXT ("Index Object Definitions")));
3266 kwDataType->append (dbe_strdup (vtypeNames[TYPE_INT64]));
3267 kwKeyword->append (dbe_strdup (obj->name));
3268 kwFormula->append (dbe_strdup (obj->index_expr_str));
3269 kwDescription->append (dbe_strdup (obj->i18n_name));
3270 kwEnumDescs->append (NULL);
3274 Histable *
3275 DbeSession::findIndexObject (int idxtype, uint64_t idx)
3277 HashMap<uint64_t, Histable*> *iobjs = idxobjs->fetch (idxtype);
3278 return iobjs->get (idx);
3281 Histable *
3282 DbeSession::createIndexObject (int idxtype, int64_t idx)
3284 HashMap<uint64_t, Histable*> *iobjs = idxobjs->fetch (idxtype);
3286 Histable *idxobj = iobjs->get (idx);
3287 if (idxobj == NULL)
3289 idxobj = new IndexObject (idxtype, idx);
3290 if (idx == -1)
3291 idxobj->set_name (dbe_strdup (GTXT ("<Unknown>")));
3292 iobjs->put (idx, idxobj);
3295 return idxobj;
3298 Histable *
3299 DbeSession::createIndexObject (int idxtype, Histable *hobj)
3301 HashMap<uint64_t, Histable*> *iobjs = idxobjs->fetch (idxtype);
3302 int64_t idx = hobj ? hobj->id : -1;
3303 Histable *idxobj = iobjs->get (idx);
3304 if (idxobj == NULL)
3306 idxobj = new IndexObject (idxtype, hobj);
3307 if (idx == -1)
3308 idxobj->set_name (dbe_strdup (GTXT ("<Unknown>")));
3309 iobjs->put (idx, idxobj);
3312 return idxobj;
3315 Histable *
3316 DbeSession::findObjectById (Histable::Type type, int subtype, uint64_t id)
3318 switch (type)
3320 case Histable::FUNCTION:
3321 case Histable::MODULE:
3322 case Histable::LOADOBJECT:
3323 return ( id < (uint64_t) objs->size ()) ? objs->fetch ((int) id) : NULL;
3324 case Histable::INDEXOBJ:
3325 return findIndexObject (subtype, id);
3326 // ignoring the following cases
3327 case Histable::INSTR:
3328 case Histable::LINE:
3329 case Histable::EADDR:
3330 case Histable::MEMOBJ:
3331 case Histable::PAGE:
3332 case Histable::DOBJECT:
3333 case Histable::SOURCEFILE:
3334 case Histable::IOACTFILE:
3335 case Histable::IOACTVFD:
3336 case Histable::IOCALLSTACK:
3337 case Histable::HEAPCALLSTACK:
3338 case Histable::OTHER:
3339 case Histable::EXPERIMENT:
3340 break;
3342 return NULL;
3345 // return a vector of Functions that match the regular expression input string
3346 Vector<JThread *> *
3347 DbeSession::match_java_threads (char *ustr, int matchParent,
3348 Vector<uint64_t> * &grids,
3349 Vector<uint64_t> * &expids)
3351 if (ustr == NULL)
3352 return NULL;
3354 char *str = dbe_sprintf (NTXT ("^%s$"), ustr);
3355 regex_t regex_desc;
3356 int rc = regcomp (&regex_desc, str, REG_EXTENDED | REG_NOSUB | REG_NEWLINE);
3357 free (str);
3358 if (rc) // syntax error in parsing string
3359 return NULL;
3361 // allocate the new vector
3362 Vector<JThread *> *ret = new Vector<JThread*>;
3363 grids = new Vector<uint64_t>;
3364 expids = new Vector<uint64_t>;
3366 int index;
3367 JThread *jthread;
3368 int expid;
3369 Experiment* exp;
3370 Vec_loop (Experiment*, exps, expid, exp)
3373 Vec_loop (JThread*, exp->get_jthreads (), index, jthread)
3375 const char * name;
3376 if (matchParent)
3377 name = jthread->parent_name;
3378 else
3379 name = jthread->group_name;
3380 if (name == NULL)
3381 name = "";
3382 if (!regexec (&regex_desc, name, 0, NULL, 0))
3384 // this one matches
3385 ret->append (jthread);
3386 grids->append (exp->groupId);
3387 expids->append (exp->getUserExpId ());
3392 regfree (&regex_desc);
3393 return ret;
3396 // return a vector of Functions that match the regular expression input string
3397 Vector<Function *> *
3398 DbeSession::match_func_names (const char *ustr, Histable::NameFormat nfmt)
3400 if (ustr == NULL)
3401 return NULL;
3402 char *str = dbe_sprintf (NTXT ("^%s$"), ustr);
3403 regex_t regex_desc;
3404 int rc = regcomp (&regex_desc, str, REG_EXTENDED | REG_NOSUB | REG_NEWLINE);
3405 free (str);
3406 if (rc) // syntax error in parsing string
3407 return NULL;
3409 // allocate the new vector
3410 Vector<Function *> *ret = new Vector<Function*>;
3412 int index;
3413 Histable *obj;
3414 Vec_loop (Histable*, objs, index, obj)
3416 if (obj->get_type () == Histable::FUNCTION)
3418 Function *func = (Function*) obj;
3419 if (!regexec (&regex_desc, func->get_name (nfmt), 0, NULL, 0))
3420 // this one matches
3421 ret->append (func);
3424 regfree (&regex_desc);
3425 return ret;
3428 // return a vector of Functions that match the regular expression input string
3429 Vector<FileData *> *
3430 DbeSession::match_file_names (char *ustr, Histable::NameFormat nfmt)
3432 if (ustr == NULL)
3433 return NULL;
3434 char *str = dbe_sprintf (NTXT ("^%s$"), ustr);
3435 regex_t regex_desc;
3436 int rc = regcomp (&regex_desc, str, REG_EXTENDED | REG_NOSUB | REG_NEWLINE);
3437 free (str);
3438 if (rc) // syntax error in parsing string
3439 return NULL;
3441 // allocate the new vector
3442 Vector<FileData *> *ret = new Vector<FileData*>;
3443 int numExps = nexps ();
3444 DefaultMap<int64_t, FileData*>* fDataMap;
3445 Vector<FileData *> *fDataObjs;
3446 FileData *fData;
3447 int size;
3448 for (int i = 0; i < numExps; i++)
3450 Experiment *exp = get_exp (i);
3451 fDataMap = exp->getFDataMap ();
3452 fDataObjs = fDataMap->values ();
3453 size = fDataObjs->size ();
3454 for (int j = 0; j < size; j++)
3456 fData = fDataObjs->fetch (j);
3457 if (fData
3458 && !regexec (&regex_desc, fData->get_raw_name (nfmt), 0, NULL, 0))
3459 // this one matches
3460 ret->append (fData);
3463 regfree (&regex_desc);
3464 return ret;
3467 // return a vector of DataObjects that match the regular expression input string
3468 Vector<DataObject *> *
3469 DbeSession::match_dobj_names (char *ustr)
3471 if (ustr == NULL)
3472 return NULL;
3473 char *str = dbe_sprintf (NTXT ("^%s$"), ustr);
3474 regex_t regex_desc;
3475 int rc = regcomp (&regex_desc, str, REG_EXTENDED | REG_NOSUB | REG_NEWLINE);
3476 free (str);
3477 if (rc) // syntax error in parsing string
3478 return NULL;
3480 // allocate the new vector
3481 Vector<DataObject *> *ret = new Vector<DataObject*>;
3482 int index;
3483 DataObject *ditem;
3484 Vec_loop (DataObject*, dobjs, index, ditem)
3486 // does this one match
3487 if (!regexec (&regex_desc, ditem->get_name (), 0, NULL, 0))
3488 // this one matches
3489 ret->append (ditem);
3491 regfree (&regex_desc);
3492 return ret;
3495 void
3496 DbeSession::dump (char *msg, Vector<BaseMetric*> *mlist)
3498 if (msg)
3499 fprintf (stderr, "%s\n", msg);
3500 int sz = mlist ? mlist->size () : -1;
3501 for (int i = 0; i < sz; i++)
3503 BaseMetric *m = mlist->fetch (i);
3504 char *s = m->dump ();
3505 fprintf (stderr, "%2d %s\n", i, s);
3506 free (s);
3508 fprintf (stderr, "======END of mlist[%d] =========\n", sz);
3511 void
3512 DbeSession::dump (char *msg, Vector<Metric*> *mlist)
3514 if (msg)
3515 fprintf (stderr, "%s\n", msg);
3516 int sz = mlist ? mlist->size () : -1;
3517 for (int i = 0; i < sz; i++)
3519 Metric *m = mlist->fetch (i);
3520 char *s = m->dump ();
3521 fprintf (stderr, "%2d %s\n", i, s);
3522 free (s);
3524 fprintf (stderr, "======END of mlist[%d] =========\n", sz);