]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gprofng/src/Dbe.cc
Update year range in gprofng copyright notices
[thirdparty/binutils-gdb.git] / gprofng / src / Dbe.cc
CommitLineData
76bdc726 1/* Copyright (C) 2021-2023 Free Software Foundation, Inc.
bb368aad
VM
2 Contributed by Oracle.
3
4 This file is part of GNU Binutils.
5
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.
10
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.
15
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. */
20
21#include "config.h"
22#include <errno.h>
23#include <sys/types.h> // open, chmod
24#include <signal.h>
25#include <fcntl.h> // open
26#include <strings.h>
27#include <unistd.h>
28
29#include "util.h"
30#include "Histable.h"
31#include "DbeSession.h"
32#include "DbeView.h"
33#include "BaseMetric.h"
34#include "CallStack.h"
35#include "collctrl.h"
36#include "Command.h"
37#include "Dbe.h"
38#include "DbeApplication.h"
39#include "DefaultMap.h"
40#include "LoadObject.h"
41#include "Experiment.h"
42#include "IndexObject.h"
43#include "IOActivity.h"
44#include "PreviewExp.h"
45#include "Function.h"
46#include "Hist_data.h"
47#include "MetricList.h"
48#include "Module.h"
49#include "DataSpace.h"
50#include "MemorySpace.h"
51#include "DataObject.h"
52#include "MemObject.h"
53#include "Filter.h"
54#include "FilterSet.h"
55#include "FilterExp.h"
56#include "Sample.h"
57#include "Print.h"
58#include "StringBuilder.h"
59#include "dbe_types.h"
60#include "ExpGroup.h"
61#include "vec.h"
62#include "UserLabel.h"
63#include "DbeFile.h"
64#include "PathTree.h"
65
66// Data structures for managing the collector control info for Collection GUI
67static Coll_Ctrl *col_ctr = NULL;
68
69template<> VecType Vector<int>::type ()
70{
71 return VEC_INTEGER;
72}
73
74template<> VecType Vector<unsigned>::type ()
75{
76 return VEC_INTEGER;
77}
78
79template<> VecType Vector<char>::type ()
80{
81 return VEC_CHAR;
82}
83
84template<> VecType Vector<bool>::type ()
85{
86 return VEC_BOOL;
87}
88
89template<> VecType Vector<double>::type ()
90{
91 return VEC_DOUBLE;
92}
93
94template<> VecType Vector<long long>::type ()
95{
96 return VEC_LLONG;
97}
98
99template<> VecType Vector<uint64_t>::type ()
100{
101 return VEC_LLONG;
102}
103
104template<> VecType Vector<void*>::type ()
105{
106 return VEC_VOIDARR;
107}
108
109template<> VecType Vector<char*>::type ()
110{
111 return VEC_STRING;
112}
113
114template<> VecType Vector<Vector<int>*>::type ()
115{
116 return VEC_INTARR;
117}
118
119template<> VecType Vector<Vector<char*>*>::type ()
120{
121 return VEC_STRINGARR;
122}
123
124template<> VecType Vector<Vector<long long>*>::type ()
125{
126 return VEC_LLONGARR;
127}
128
129// gcc won't instantiate Vector<unsigned>::type() without it
130Vector<unsigned> __dummy_unsigned_vector;
131
132#define CASE_S(x) case x: return #x
133static const char *
134dsp_type_to_string (int t)
135{
136 switch (t)
137 {
138 CASE_S (DSP_FUNCTION);
139 CASE_S (DSP_LINE);
140 CASE_S (DSP_PC);
141 CASE_S (DSP_SOURCE);
142 CASE_S (DSP_DISASM);
143 CASE_S (DSP_SELF);
144 CASE_S (DSP_CALLER);
145 CASE_S (DSP_CALLEE);
146 CASE_S (DSP_CALLTREE);
147 CASE_S (DSP_TIMELINE);
148 CASE_S (DSP_STATIS);
149 CASE_S (DSP_EXP);
150 CASE_S (DSP_LEAKLIST);
151 CASE_S (DSP_MEMOBJ);
152 CASE_S (DSP_DATAOBJ);
153 CASE_S (DSP_DLAYOUT);
154 CASE_S (DSP_SRC_FILE);
155 CASE_S (DSP_IFREQ);
156 CASE_S (DSP_RACES);
157 CASE_S (DSP_INDXOBJ);
158 CASE_S (DSP_DUALSOURCE);
159 CASE_S (DSP_SOURCE_DISASM);
160 CASE_S (DSP_DEADLOCKS);
161 CASE_S (DSP_SOURCE_V2);
162 CASE_S (DSP_DISASM_V2);
163 CASE_S (DSP_IOACTIVITY);
164 CASE_S (DSP_OVERVIEW);
165 CASE_S (DSP_IOCALLSTACK);
166 CASE_S (DSP_HEAPCALLSTACK);
167 CASE_S (DSP_SAMPLE);
168 default:
169 break;
170 }
171 return NTXT ("ERROR");
172}
173
174enum
175{
176 COMPARE_BIT = 1 << 8,
177 MTYPE_MASK = (1 << 8) - 1,
178 GROUP_ID_SHIFT = 16
179};
180
181static DbeView *
182getDbeView (int dbevindex)
183{
184 DbeView *dbev = dbeSession->getView (dbevindex);
185 if (dbev == NULL)
186 abort ();
187 return dbev;
188}
189
190
191Vector<char*> *
192dbeGetInitMessages ()
193{
194 // If any comments from the .rc files, send them to the GUI
195 Emsg *msg = theDbeApplication->fetch_comments ();
196 int size = 0;
197 while (msg != NULL)
198 {
199 size++;
200 msg = msg->next;
201 }
202
203 // Initialize Java String array
204 Vector<char*> *list = new Vector<char*>(size);
205 msg = theDbeApplication->fetch_comments ();
206 size = 0;
207 int i = 0;
208 while (msg != NULL)
209 {
210 char *str = msg->get_msg ();
211 list->store (i, dbe_strdup (str));
212 i++;
213 msg = msg->next;
214 }
215
216 // now delete the comments
217 theDbeApplication->delete_comments ();
218 return list;
219}
220
221Vector<char*> *
222dbeGetExpPreview (int /*dbevindex*/, char *exp_name)
223{
224 PreviewExp *preview = new PreviewExp ();
225 preview->experiment_open (exp_name);
226 preview->open_epilogue ();
227
228 // Initialize Java String array
229 Vector<char*> *info = preview->preview_info ();
230 int size = info->size ();
231 Vector<char*> *list = new Vector<char*>(size);
232
233 // Get experiment names
234 for (int i = 0; i < size; i++)
235 {
236 char *str = info->fetch (i);
237 if (str == NULL)
238 str = GTXT ("N/A");
239 list->store (i, dbe_strdup (str));
240 }
241 delete info;
242 delete preview;
243 return list;
244}
245
246char *
247dbeGetExpParams (int /*dbevindex*/, char *exp_name)
248{
249 PreviewExp *preview = new PreviewExp ();
250 preview->experiment_open (exp_name);
251
252 // Initialize Java String array
253 char *arg_list = dbe_strdup (preview->getArgList ());
254 delete preview;
255 return arg_list;
256}
257
258/**
259 * Gets File Attributes according to the specified format
260 * Supported formats:
261 * "/bin/ls -dl " - see 'man ls' for details
262 * @param filename
263 * @param format
264 * @return char * attributes
265 */
266char *
267dbeGetFileAttributes (const char *filename, const char *format)
268{
269 if (format != NULL)
270 {
271 if (!strcmp (format, NTXT ("/bin/ls -dl ")))
272 {
273 // A kind of "/bin/ls -dl " simulation
274 struct stat64 sbuf;
275 sbuf.st_mode = 0;
276 dbe_stat (filename, &sbuf);
277 if (S_IREAD & sbuf.st_mode)
278 { // Readable
279 if (S_ISDIR (sbuf.st_mode) != 0)
280 return dbe_sprintf (NTXT ("%s %s\n"), NTXT ("drwxrwxr-x"), filename);
281 else if (S_ISREG (sbuf.st_mode) != 0)
282 return dbe_sprintf (NTXT ("%s %s\n"), NTXT ("-rwxrwxr-x"), filename);
283 }
284 }
285 }
286 return dbe_strdup (NTXT (""));
287}
288
289/**
290 * Gets list of files for specified directory according to the specified format
291 * Supported formats:
292 * "/bin/ls -a" - see 'man ls' for details
293 * "/bin/ls -aF" - see 'man ls' for details
294 * @param dirname
295 * @param format
296 * @return char * files
297 */
298char *
299dbeGetFiles (const char *dirname, const char *format)
300{
301 if (format != NULL)
302 return dbe_read_dir (dirname, format);
303 return dbe_strdup (NTXT (""));
304}
305
306/**
307 * Creates the directory named by this full path name, including any
308 * necessary but nonexistent parent directories.
309 * @param dirname
310 * @return result
311 */
312char *
313dbeCreateDirectories (const char *dirname)
314{
315 if (dirname != NULL)
316 {
317 char *res = dbe_create_directories (dirname);
318 if (res != NULL)
319 return res;
320 }
321 return dbe_strdup (NTXT (""));
322}
323
324/**
325 * Deletes the file or the directory named by the specified path name.
326 * If this pathname denotes a directory, then the directory must be empty in order to be deleted.
327 * @param const char *pathname
328 * @return int result
329 */
330char *
331dbeDeleteFile (const char *pathname)
332{
333 // return unlink(pathname);
334 if (pathname != NULL)
335 {
336 char *res = dbe_delete_file (pathname);
337 if (res != NULL)
338 return res;
339 }
340 return dbe_strdup (NTXT (""));
341}
342
343/**
344 * Reads the file named by the specified path name.
345 * Temporary limitation: file should be "text only" and its size should be less than the 1 MB limit.
346 * If the operation was successful, the contents is in the first element, and second element is NULL.
347 * If the operation failed, then first element is NULL, and second element contains the error message.
348 * @param const char *pathname
349 * @return Vector<char*> *result
350 */
351Vector<char*> *
352dbeReadFile (const char *pathname)
353{
354 Vector<char*> *result = new Vector<char*>(2);
355 int limit = 1024 * 1024; // Temporary limit: 1 MB
356 char * contents = (char *) malloc (limit);
357 StringBuilder sb;
358 if (NULL == contents)
359 {
360 sb.sprintf (NTXT ("\nError: Cannot allocate %d bytes\n"), limit);
361 result->store (0, NULL);
362 result->store (1, sb.toString ()); // failure
363 return result;
364 }
365 int fd = open (pathname, O_RDONLY);
366 if (fd >= 0)
367 {
368 int64_t bytes = read_from_file (fd, contents, limit);
369 close (fd);
370 if (bytes >= limit)
371 {
372 sb.sprintf (NTXT ("\nError: file size is greater than the limit (%d bytes)\n"), limit);
373 result->store (0, NULL);
374 result->store (1, sb.toString ()); // failure
375 }
376 else
377 {
378 contents[bytes] = '\0'; // add string terminator
379 result->store (0, contents);
380 result->store (1, NULL); // success
381 }
382 }
383 else
384 {
385 sb.sprintf (NTXT ("\nError: Cannot open file %s\n"), pathname);
386 result->store (0, NULL);
387 result->store (1, sb.toString ()); // failure
388 free (contents);
389 }
390 return result;
391}
392
393/**
394 * Writes the file named by the specified path name.
395 * Temporary limitation: file should be "text only" and its size should be less than the 1 MB limit.
396 * If the operation failed, then -1 is returned.
397 * @param const char *pathname
398 * @return int result (written bytes)
399 */
400int
401dbeWriteFile (const char *pathname, const char *contents)
402{
403 int result = -1; // error
404 size_t len = 0;
405 if (NULL != contents)
406 len = strlen (contents);
407 size_t limit = 1024 * 1024; // Temporary limit: 1 MB
408 if (len > limit) return result;
409 unlink (pathname);
410 mode_t mode = S_IRUSR | S_IWUSR;
411 int fd = open (pathname, O_WRONLY | O_CREAT | O_TRUNC, mode);
412 if (fd >= 0)
413 { // replace file contents
414 chmod (pathname, /*S_IRUSR || S_IWUSR*/ 0600); // rw for owner only
415 ssize_t bytes = 0;
416 if (len > 0)
417 bytes = write (fd, contents, len);
418 close (fd);
419 result = (int) bytes;
420 }
421 return result;
422}
423
424/**
425 * Gets list of running processes according to the specified format
426 * Supported formats:
427 * "/bin/ps -ef" - see 'man ps' for details
428 * @param format
429 * @return char * processes
430 */
431char *
432dbeGetRunningProcesses (const char *format)
433{
434 if (format != NULL)
435 return dbe_get_processes (format);
436 return dbe_strdup (NTXT (""));
437}
438
439//
440// Open experiment
441//
442char *
443dbeOpenExperimentList (int /* dbevindex */, Vector<Vector<char*>*> *groups,
444 bool sessionRestart)
445{
446 if (sessionRestart)
447 dbeSession->reset ();
448 char *errstr;
449 // Open experiments
450 try
451 {
452 errstr = dbeSession->setExperimentsGroups (groups);
453 }
454 catch (ExperimentLoadCancelException *)
455 {
456 errstr = dbe_strdup (NTXT ("Experiment Load Cancelled"));
457 }
458 return errstr;
459}
460
461//
462// Drop experiments
463//
464char *
465dbeDropExperiment (int /* dbevindex */, Vector<int> *drop_index)
466{
467 for (int i = drop_index->size () - 1; i >= 0; i--)
468 {
469 char *ret = dbeSession->drop_experiment (drop_index->fetch (i));
470 if (ret != NULL)
471 return ret;
472 }
473 return NULL;
474}
475
476/**
477 * Read .er.rc file from the specified location
478 * @param path
479 * @return
480 */
481char *
482dbeReadRCFile (int dbevindex, char* path)
483{
484 DbeView *dbev = getDbeView (dbevindex);
485 char *err_msg = dbev->get_settings ()->read_rc (path);
486 return err_msg;
487}
488
489char *
490dbeSetExperimentsGroups (Vector<Vector<char*>*> *groups)
491{
492 int cmp_mode = dbeSession->get_settings ()->get_compare_mode ();
493 if (groups->size () < 2)
494 cmp_mode = CMP_DISABLE;
495 else if (cmp_mode == CMP_DISABLE)
496 cmp_mode = CMP_ENABLE;
497 for (int i = 0;; i++)
498 {
499 DbeView *dbev = dbeSession->getView (i);
500 if (dbev == NULL)
501 break;
502 dbev->get_settings ()->set_compare_mode (cmp_mode);
503 }
504 char *err_msg = dbeSession->setExperimentsGroups (groups);
505
506 // automatically load machine model if applicable
507 dbeDetectLoadMachineModel (0);
508 return err_msg;
509}
510
511Vector<Vector<char*>*> *
512dbeGetExperimensGroups ()
513{
514 Vector<Vector<char*>*> *grops = dbeSession->getExperimensGroups ();
515 return grops;
516}
517
518Vector<int> *
519dbeGetFounderExpId (Vector<int> *expIds)
520{
521 Vector<int> *ret = new Vector<int>(expIds->size ());
522 for (int i = 0; i < expIds->size (); i++)
523 {
524 int expId = expIds->fetch (i);
525 Experiment *exp = dbeSession->get_exp (expId);
526 if (exp != NULL)
527 {
528 int founderExpId = exp->getBaseFounder ()->getExpIdx ();
529 ret->store (i, founderExpId);
530 }
531 else
532 ret->store (i, -1);
533 }
534 return ret;
535}
536
537Vector<int> *
538dbeGetUserExpId (Vector<int> *expIds)
539{
540 // returns "User Visible" ids used for EXPID filters and timeline processes
541 Vector<int> *ret = new Vector<int>(expIds->size ());
542 for (int i = 0; i < expIds->size (); i++)
543 {
544 int expId = expIds->fetch (i);
545 Experiment *exp = dbeSession->get_exp (expId);
546 if (exp != NULL)
547 {
548 int userExpId = exp->getUserExpId ();
549 ret->store (i, userExpId);
550 }
551 else
552 ret->store (i, -1);
553 }
554 return ret;
555}
556
557//
558// Get experiment groupid
559//
560Vector<int> *
561dbeGetExpGroupId (Vector<int> *expIds)
562{
563 Vector<int> *ret = new Vector<int>(expIds->size ());
564 for (int i = 0; i < expIds->size (); i++)
565 {
566 int expId = expIds->fetch (i);
567 Experiment *exp = dbeSession->get_exp (expId);
568 if (exp != NULL)
569 {
570 int gId = exp->groupId;
571 ret->store (i, gId);
572 }
573 else
574 ret->store (i, -1);
575 }
576 return ret;
577}
578
579Vector<char*> *
580dbeGetExpsProperty (const char *prop_name)
581{
582 long nexps = dbeSession->nexps ();
583 if (prop_name == NULL || nexps == 0)
584 return NULL;
585 Vector<char*> *list = new Vector<char*>(nexps);
586 StringBuilder sb;
587 int empty = 1;
588 int prop = 99;
589 if (strcasecmp (prop_name, NTXT ("ERRORS")) == 0)
590 prop = 1;
591 else if (strcasecmp (prop_name, NTXT ("WARNINGS")) == 0)
592 prop = 2;
593 if (prop < 3)
594 {
595 for (long i = 0; i < nexps; i++)
596 {
597 Experiment *exp = dbeSession->get_exp (i);
598 char *nm = exp->get_expt_name ();
599 sb.setLength (0);
600 for (Emsg *emsg = (prop == 1) ? exp->fetch_errors () : exp->fetch_warnings ();
601 emsg; emsg = emsg->next)
602 sb.appendf (NTXT ("%s: %s\n"), STR (nm), STR (emsg->get_msg ()));
603 char *s = NULL;
604 if (sb.length () > 0)
605 {
606 s = sb.toString ();
607 empty = 0;
608 }
609 list->append (s);
610 }
611 }
612 if (empty)
613 {
614 delete list;
615 list = NULL;
616 }
617 return list;
618}
619
620//
621// Get experiment names
622//
623Vector<char*> *
624dbeGetExpName (int /*dbevindex*/)
625{
626 int size = dbeSession->nexps ();
627 if (size == 0)
628 return NULL;
629 // Initialize Java String array
630 Vector<char*> *list = new Vector<char*>(size);
631
632 // Get experiment names
633 for (int i = 0; i < size; i++)
634 {
635 Experiment *texp = dbeSession->get_exp (i);
636 char *buf = dbe_sprintf (NTXT ("%s [%s]"), texp->get_expt_name (),
637 texp->utargname != NULL ? texp->utargname : GTXT ("(unknown)"));
638 list->store (i, buf);
639 }
640 return list;
641}
642
643//
644// Get experiment state
645//
646Vector<int> *
647dbeGetExpState (int /* dbevindex */)
648{
649 int size = dbeSession->nexps ();
650 if (size == 0)
651 return NULL;
652 // Initialize Java array
653 Vector<int> *state = new Vector<int>(size);
654
655 // Get experiment state
656 for (int i = 0; i < size; i++)
657 {
658 Experiment *exp = dbeSession->get_exp (i);
659 int set = EXP_SUCCESS;
660 if (exp->get_status () == Experiment::FAILURE)
661 set |= EXP_FAILURE;
662 if (exp->get_status () == Experiment::INCOMPLETE)
663 set |= EXP_INCOMPLETE;
664 if (exp->broken)
665 set |= EXP_BROKEN;
666 if (exp->obsolete)
667 set |= EXP_OBSOLETE;
668 state->store (i, set);
669 }
670 return state;
671}
672
673//
674// Get enabled experiment indices
675//
676Vector<bool> *
677dbeGetExpEnable (int dbevindex)
678{
679 DbeView *dbev = getDbeView (dbevindex);
680 int size = dbeSession->nexps ();
681 if (dbev == NULL || size == 0)
682 return NULL;
683
684 // Get enabled experiment
685 Vector<bool> *enable = new Vector<bool>(size);
686 for (int i = 0; i < size; i++)
687 {
688 bool val = dbev->get_exp_enable (i) && !dbeSession->get_exp (i)->broken;
689 enable->store (i, val);
690 }
691 return enable;
692}
693
694//
695// Get enabled experiment indices
696//
697bool
698dbeSetExpEnable (int dbevindex, Vector<bool> *enable)
699{
700 DbeView *dbev = getDbeView (dbevindex);
701 bool ret = false;
702 int size = dbeSession->nexps ();
703 if (dbev == NULL || size == 0)
704 return false;
705
706 // set enable, as per input vector
707 for (int i = 0; i < size; i++)
708 if (!dbeSession->get_exp (i)->broken
709 && dbev->get_exp_enable (i) != enable->fetch (i))
710 {
711 dbev->set_exp_enable (i, enable->fetch (i));
712 ret = true;
713 }
714 return ret;
715}
716
717//
718// Get experiment info
719//
720Vector<char*> *
721dbeGetExpInfo (int dbevindex)
722{
723 DbeView *dbev = dbeSession->getView (dbevindex);
724 if (dbev == NULL)
725 abort ();
726 int size = dbeSession->nexps ();
727 if (size == 0)
728 return NULL;
729
730 // Initialize Java String array
731 Vector<char*> *list = new Vector<char*>(size * 2 + 1);
732
733 // Get experiment names
734 Vector<LoadObject*> *text_segments = dbeSession->get_text_segments ();
735 char *msg = pr_load_objects (text_segments, NTXT (""));
736 delete text_segments;
737 list->store (0, msg);
738 int k = 1;
739 for (int i = 0; i < size; i++)
740 {
741 Experiment *exp = dbeSession->get_exp (i);
742 char *msg0 = pr_mesgs (exp->fetch_notes (), NTXT (""), NTXT (""));
743 char *msg1 = pr_mesgs (exp->fetch_errors (), GTXT ("No errors\n"), NTXT (""));
744 char *msg2 = pr_mesgs (exp->fetch_warnings (), GTXT ("No warnings\n"), NTXT (""));
745 char *msg3 = pr_mesgs (exp->fetch_comments (), NTXT (""), NTXT (""));
746 char *msg4 = pr_mesgs (exp->fetch_pprocq (), NTXT (""), NTXT (""));
747 msg = dbe_sprintf (NTXT ("%s%s%s%s"), msg1, msg2, msg3, msg4);
748 list->store (k++, msg0);
749 list->store (k++, msg);
750 free (msg1);
751 free (msg2);
752 free (msg3);
753 free (msg4);
754 }
755 return list;
756}
757
758bool
759dbeGetViewModeEnable ()
760{
761 return dbeSession->has_ompavail () || dbeSession->has_java ();
762}
763
764bool
765dbeGetJavaEnable ()
766{
767 return dbeSession->has_java ();
768}
769
770int
771dbeUpdateNotes (int dbevindex, int exp_id, int type, char* text, bool handle_file)
772{
773 DbeView *dbev = dbeSession->getView (dbevindex);
774 if (dbev == NULL)
775 abort ();
776 int size = dbeSession->nexps ();
777 if (size == 0)
778 return -1;
779 Experiment *exp = dbeSession->get_exp (exp_id);
780 return (type == 0) ? exp->save_notes (text, handle_file) : exp->delete_notes (handle_file);
781}
782
783//
784// Get load object names
785//
786Vector<char*> *
787dbeGetLoadObjectName (int /* dbevindex */)
788{
789 Vector<LoadObject*> *lobjs = dbeSession->get_text_segments ();
790 int size = lobjs->size ();
791
792 // Initialize Java String array
793 Vector<char*> *list = new Vector<char*>(size);
794
795 // Get load object names
796 LoadObject *lo;
797 int index;
798 Vec_loop (LoadObject*, lobjs, index, lo)
799 {
800 list->store (index, dbe_strdup (lo->get_name ()));
801 }
802 delete lobjs;
803 return list;
804}
805
806// XXX Will use later when order has to be passed too,
807// Get complete List of tabs
808//
809Vector<void*> *
810dbeGetTabList (int /* dbevindex */)
811{
812 //DbeView *dbev = getDbeView (dbevindex);
813 //Vector<void*> *tabs = dbeSession->get_TabList();
814 //return tabs;
815 return NULL;
816}
817
818//
819// Returns list of available tabs
820//
821Vector<void*> *
822dbeGetTabListInfo (int dbevindex)
823{
824 int index;
825 DispTab *dsptab;
826 DbeView *dbev = getDbeView (dbevindex);
827
828 // make sure the tabs are initialized properly
829 dbev->get_settings ()->proc_tabs (theDbeApplication->rdtMode);
830 Vector<DispTab*> *tabs = dbev->get_TabList ();
831
832 // Get number of available tabs
833 int size = 0;
834 Vec_loop (DispTab*, tabs, index, dsptab)
835 {
836 if (!dsptab->available)
837 continue;
838 size++;
839 }
840 Vector<void*> *data = new Vector<void*>(2);
841 Vector<int> *typelist = new Vector<int>(size);
842 Vector<char*> *cmdlist = new Vector<char*>(size);
843 Vector<int> *ordlist = new Vector<int>(size);
844
845 // Build list of avaliable tabs
846 int i = 0;
847
848 Vec_loop (DispTab*, tabs, index, dsptab)
849 {
850 if (!dsptab->available)
851 continue;
852 typelist->store (i, dsptab->type);
853 cmdlist->store (i, dbe_strdup (Command::get_cmd_str (dsptab->cmdtoken)));
854 ordlist->store (i, dsptab->order);
855 i++;
856 }
857 data->store (0, typelist);
858 data->store (1, cmdlist);
859 data->store (2, ordlist);
860 return data;
861}
862
863// Return visibility state for all available tabs
864//
865Vector<bool> *
866dbeGetTabSelectionState (int dbevindex)
867{
868 int index;
869 DispTab *dsptab;
870 DbeView *dbev = getDbeView (dbevindex);
871 Vector<DispTab*> *tabs = dbev->get_TabList ();
872
873 // Get number of available tabs
874 int size = 0;
875 Vec_loop (DispTab*, tabs, index, dsptab)
876 {
877 if (!dsptab->available)
878 continue;
879 size++;
880 }
881 Vector<bool> *states = new Vector<bool>(size);
882
883 // Get visibility bit for all available tabs
884 int i = 0;
885 Vec_loop (DispTab*, tabs, index, dsptab)
886 {
887 if (!dsptab->available)
888 continue;
889 states->store (i++, dsptab->visible);
890 }
891 return states;
892}
893
894// Set visibility bit for a tab
895void
896dbeSetTabSelectionState (int dbevindex, Vector<bool> *selected)
897{
898 int index;
899 DispTab *dsptab;
900 DbeView *dbev = getDbeView (dbevindex);
901 Vector<DispTab*> *tabs = dbev->get_TabList ();
902 int i = 0;
903 Vec_loop (DispTab*, tabs, index, dsptab)
904 {
905 if (!dsptab->available)
906 continue;
907 dsptab->visible = selected->fetch (i++);
908 }
909}
910
911// Return visibility state for all available MemObj tabs
912Vector<bool> *
913dbeGetMemTabSelectionState (int dbevindex)
914{
915 int index;
916 bool dsptab;
917 DbeView *dbev = getDbeView (dbevindex);
918 Vector<bool> *memtabs = dbev->get_MemTabState ();
919
920 // set the output vector
921 int size = memtabs->size ();
922 Vector<bool> *states = new Vector<bool>(size);
923
924 // Get visibility bit for all available tabs
925 int i = 0;
926 Vec_loop (bool, memtabs, index, dsptab)
927 {
928 states->store (i++, dsptab);
929 }
930 return states;
931}
932
933// Set visibility bit for a memory tab
934//
935void
936dbeSetMemTabSelectionState (int dbevindex, Vector<bool> *selected)
937{
938 DbeView *dbev = dbeSession->getView (dbevindex);
939 if (dbev == NULL)
940 abort ();
941 dbev->set_MemTabState (selected);
942}
943
944// Return visibility state for all available index tabs
945Vector<bool> *
946dbeGetIndxTabSelectionState (int dbevindex)
947{
948 int index;
949 bool dsptab;
950 DbeView *dbev = dbeSession->getView (dbevindex);
951 if (dbev == NULL)
952 abort ();
953 Vector<bool> *indxtabs = dbev->get_IndxTabState ();
954
955 // set the output vector
956 int size = indxtabs->size ();
957 Vector<bool> *states = new Vector<bool>(size);
958
959 // Get visibility bit for all available tabs
960 int i = 0;
961 Vec_loop (bool, indxtabs, index, dsptab)
962 {
963 states->store (i++, dsptab);
964 }
965 return states;
966}
967
968// Set visibility bit for a index tab
969void
970dbeSetIndxTabSelectionState (int dbevindex, Vector<bool> *selected)
971{
972 DbeView *dbev = dbeSession->getView (dbevindex);
973 if (dbev == NULL)
974 abort ();
975 dbev->set_IndxTabState (selected);
976}
977
978//
979// Get search path
980//
981Vector<char*> *
982dbeGetSearchPath (int /*dbevindex*/)
983{
984 Vector<char*> *path = dbeSession->get_search_path ();
985 int size = path->size ();
986 Vector<char*> *list = new Vector<char*>(size);
987 int index;
988 char *name;
989 Vec_loop (char*, path, index, name)
990 {
991 list->store (index, dbe_strdup (name));
992 }
993 return list;
994}
995
996//
997// Set search path
998//
999void
1000dbeSetSearchPath (int /*dbevindex*/, Vector<char*> *path)
1001{
1002 dbeSession->set_search_path (path, true);
1003 return;
1004}
1005
1006//
1007// Get pathmaps
1008//
1009Vector<void*> *
1010dbeGetPathmaps (int /*dbevindex*/)
1011{
1012 int index;
1013 pathmap_t *pthmap;
1014 Vector<pathmap_t*> *path = dbeSession->get_pathmaps ();
1015 int size = path->size ();
1016 Vector<void*> *data = new Vector<void*>(2);
1017 Vector<char*> *oldlist = new Vector<char*>(size);
1018 Vector<char*> *newlist = new Vector<char*>(size);
1019
1020 int i = 0;
1021 Vec_loop (pathmap_t*, path, index, pthmap)
1022 {
1023 oldlist->store (i, dbe_strdup (pthmap->old_prefix));
1024 newlist->store (i, dbe_strdup (pthmap->new_prefix));
1025 i++;
1026 }
1027 data->store (0, oldlist);
1028 data->store (1, newlist);
1029 return data;
1030} // dbeGetPathmaps
1031
1032char *
1033dbeSetPathmaps (Vector<char*> *from, Vector<char*> *to)
1034{
1035 if (from == NULL || to == NULL || from->size () != to->size ())
1036 return dbe_strdup ("dbeSetPathmaps: size of 'from' does not match for size of 'to'\n");
1037 Vector<pathmap_t*> *newPath = new Vector<pathmap_t*>(from->size ());
1038 for (int i = 0, sz = from->size (); i < sz; i++)
1039 {
1040 char *err = Settings::add_pathmap (newPath, from->get (i), to->get (i));
1041 if (err)
1042 {
1043 newPath->destroy ();
1044 delete newPath;
1045 return err;
1046 }
1047 }
1048 dbeSession->set_pathmaps (newPath);
1049 return NULL;
1050}
1051
1052//
1053// Add pathmap
1054char *
1055dbeAddPathmap (int /* dbevindex */, char *from, char *to)
1056{
1057 Vector<pathmap_t*> *pmp = dbeSession->get_pathmaps ();
1058 char *err = Settings::add_pathmap (pmp, from, to);
1059 return err;
1060}
1061
1062//
1063// Get error/warning string of data
1064char *
1065dbeGetMsg (int dbevindex, int type)
1066{
1067 DbeView *dbev = dbeSession->getView (dbevindex);
1068 if (dbev == NULL)
1069 abort ();
1070 char *msgstr = NULL;
1071 if (type == ERROR_MSG)
1072 msgstr = dbev->get_error_msg ();
1073 else if (type == WARNING_MSG)
1074 msgstr = dbev->get_warning_msg ();
1075 else if (type == PSTAT_MSG)
1076 msgstr = dbev->get_processor_msg (PSTAT_MSG);
1077 else if (type == PWARN_MSG)
1078 msgstr = dbev->get_processor_msg (PWARN_MSG);
1079 return msgstr ? dbe_strdup (msgstr) : NULL;
1080}
1081
1082// Create a DbeView, given new index, and index of view to clone
1083int
1084dbeInitView (int id, int cloneid)
1085{
1086 return dbeSession->createView (id, cloneid);
1087}
1088
1089
1090// Delete a DbeView
1091void
1092dbeDeleteView (int dbevindex)
1093{
1094 dbeSession->dropView (dbevindex);
1095 return;
1096} // dbeDeleteView
1097
1098MetricList *
1099dbeGetMetricListV2 (int dbevindex, MetricType mtype,
1100 Vector<int> *type, Vector<int> *subtype, Vector<bool> *sort,
1101 Vector<int> *vis, Vector<char*> *cmd,
1102 Vector<char*> *expr_spec, Vector<char*> *legends)
1103{
1104 DbeView *dbev = dbeSession->getView (dbevindex);
1105 MetricList *mlist = new MetricList (mtype);
1106 for (int i = 0, msize = type->size (); i < msize; i++)
1107 {
1108 BaseMetric *bm = dbev->register_metric_expr ((BaseMetric::Type) type->fetch (i),
1109 cmd->fetch (i),
1110 expr_spec->fetch (i));
1111 Metric *m = new Metric (bm, (Metric::SubType) subtype->fetch (i));
1112 m->set_raw_visbits (vis->fetch (i));
1113 if (m->legend == NULL)
1114 m->legend = dbe_strdup (legends->fetch (i));
1115 mlist->append (m);
1116 if (sort->fetch (i))
1117 {
1118 mlist->set_sort_ref_index (i);
1119 }
1120 }
1121 return mlist;
1122}
1123
1124static Vector<void*> *
1125dbeGetMetricList (MetricList *mlist)
1126{
1127 int clock_val = dbeSession->get_clock (-1);
1128 Vector<Metric*> *items = mlist->get_items ();
1129 int size = items->size ();
1130
1131 Vector<int> *type = new Vector<int>(size);
1132 Vector<int> *subtype = new Vector<int>(size);
1133 Vector<int> *clock = new Vector<int>(size);
1134 Vector<int> *flavors = new Vector<int>(size);
1135 Vector<int> *vis = new Vector<int>(size);
1136 Vector<bool> *sorted = new Vector<bool>(size);
1137 Vector<int> *value_styles = new Vector<int>(size);
1138 Vector<char*> *aux = new Vector<char*>(size);
1139 Vector<char*> *name = new Vector<char*>(size);
1140 Vector<char*> *abbr = new Vector<char*>(size);
1141 Vector<char*> *comd = new Vector<char*>(size);
1142 Vector<char*> *unit = new Vector<char*>(size);
1143 Vector<char*> *user_name = new Vector<char*>(size);
1144 Vector<char*> *expr_spec = new Vector<char*>(size);
1145 Vector<char*> *legend = new Vector<char*>(size);
1146 Vector<int> *valtype = new Vector<int>(size);
1147 Vector<char*> *data_type_name = new Vector<char*>(size);
1148 Vector<char*> *data_type_uname = new Vector<char*>(size);
1149 Vector<char*> *short_desc = new Vector<char*>(size);
1150
1151 int sort_index = mlist->get_sort_ref_index ();
1152 // Fill metric elements
1153 for (int i = 0; i < size; i++)
1154 {
1155 Metric *m = items->fetch (i);
1156 type->append (m->get_type ());
1157 subtype->append (m->get_subtype ());
1158 flavors->append (m->get_flavors ());
1159 abbr->append (dbe_strdup (m->get_abbr ()));
1160 char *s = m->get_abbr_unit ();
1161 if ((m->get_visbits () & VAL_RATIO) != 0)
1162 s = NULL;
1163 unit->append (dbe_strdup (s ? s : NTXT ("")));
1164 value_styles->append (m->get_value_styles ());
1165 vis->append (m->get_visbits ());
1166 sorted->append (i == sort_index);
1167 clock->append (m->get_type () == Metric::HWCNTR ? clock_val
1168 : m->get_clock_unit ());
1169 aux->append (dbe_strdup (m->get_aux ()));
1170 name->append (dbe_strdup (m->get_name ()));
1171 comd->append (dbe_strdup (m->get_cmd ()));
1172 user_name->append (dbe_strdup (m->get_username ()));
1173 expr_spec->append (dbe_strdup (m->get_expr_spec ()));
1174 legend->append (dbe_strdup (m->legend));
1175 valtype->append (m->get_vtype2 ());
1176
1177 char* _data_type_name = NULL;
1178 char* _data_type_uname = NULL;
1179 int data_type = m->get_packet_type ();
1180 if (data_type >= 0 && data_type < DATA_LAST)
1181 {
1182 _data_type_name = dbe_strdup (get_prof_data_type_name (data_type));
1183 _data_type_uname = dbe_strdup (get_prof_data_type_uname (data_type));
1184 }
1185 data_type_name->append (_data_type_name);
1186 data_type_uname->append (_data_type_uname);
1187
1188 char* _short_desc = NULL;
1189 if (m->get_type () == Metric::HWCNTR)
1190 {
1191 Hwcentry * hwctr = m->get_hw_ctr ();
1192 if (hwctr)
1193 _short_desc = dbe_strdup (hwctr->short_desc);
1194 }
1195 short_desc->append (_short_desc);
1196 }
1197
1198 // Set Java array
1199 Vector<void*> *data = new Vector<void*>(16);
1200 data->append (type);
1201 data->append (subtype);
1202 data->append (clock);
1203 data->append (flavors);
1204 data->append (value_styles);
1205 data->append (user_name);
1206 data->append (expr_spec);
1207 data->append (aux);
1208 data->append (name);
1209 data->append (abbr);
1210 data->append (comd);
1211 data->append (unit);
1212 data->append (vis);
1213 data->append (sorted);
1214 data->append (legend);
1215 data->append (valtype);
1216 data->append (data_type_name);
1217 data->append (data_type_uname);
1218 data->append (short_desc);
1219 return data;
1220}
1221
1222Vector<void*> *
1223dbeGetRefMetricsV2 ()
1224{
1225 MetricList *mlist = new MetricList (MET_NORMAL);
1226 Vector<BaseMetric*> *base_metrics = dbeSession->get_base_reg_metrics ();
1227 for (long i = 0, sz = base_metrics->size (); i < sz; i++)
1228 {
1229 BaseMetric *bm = base_metrics->fetch (i);
1230 Metric *m;
1231 if (bm->get_flavors () & Metric::EXCLUSIVE)
1232 {
1233 m = new Metric (bm, Metric::EXCLUSIVE);
1234 m->enable_all_visbits ();
1235 mlist->append (m);
1236 }
1237 else if (bm->get_flavors () & BaseMetric::STATIC)
1238 {
1239 m = new Metric (bm, BaseMetric::STATIC);
1240 m->enable_all_visbits ();
1241 mlist->append (m);
1242 }
1243 }
1244 Vector<void*> *data = dbeGetMetricList (mlist);
1245 delete mlist;
1246 return data;
1247}
1248
1249Vector<void*> *
1250dbeGetCurMetricsV2 (int dbevindex, MetricType mtype)
1251{
1252 DbeView *dbev = dbeSession->getView (dbevindex);
1253 MetricList *mlist = dbev->get_metric_list (mtype);
1254 Vector<void*> *data = dbeGetMetricList (mlist);
1255 return data;
1256}
1257
1258// YXXX we should refactor Metrics/BaseMetrics so that it no longer uses VAL_VALUE to enable time.
1259static int
1260convert_visbits_to_gui_checkbox_bits (BaseMetric *bm, const int visbits)
1261{
1262 // The purpose of this function is to handle the following case:
1263 // When bm->get_value_styles() supports VAL_TIMEVAL but not VAL_VALUE
1264 // Metric and BaseMetric use (visbits&VAL_VALUE) to enable time.
1265 // However, the Overview expects the VAL_TIMEVAL bit to enable time.
1266 // Inputs: visbits as returned by BaseMetric->get_default_visbits();
1267 // Returns: valuebits, as used for checks in GUI checkboxes
1268 int valuebits = visbits;
1269 const int value_styles = bm->get_value_styles ();
1270 if ((value_styles & VAL_TIMEVAL) && // supports time
1271 !(value_styles & VAL_VALUE))
1272 { // but not value
1273 unsigned mask = ~(VAL_VALUE | VAL_TIMEVAL);
1274 valuebits = (unsigned) valuebits & mask; // clear bits
1275 if (visbits & VAL_VALUE)
1276 valuebits |= VAL_TIMEVAL; // set VAL_TIMEVAL
1277 if (visbits & VAL_TIMEVAL)
1278 valuebits |= VAL_TIMEVAL; // weird, this should never happen.
1279 }
1280 return valuebits;
1281}
1282
1283static Vector<void*> *
1284dbeGetMetricTreeNode (BaseMetricTreeNode* curr, MetricList *mlist,
1285 bool include_unregistered, bool has_clock_profiling_data)
1286{
1287 Vector<void*> *data = new Vector<void*>(2);
1288
1289 // ----- fields
1290 Vector<void*> *fields = new Vector<void*>();
1291 Vector<char*> *name = new Vector<char*>(1);
1292 Vector<char*> *username = new Vector<char*>(1);
1293 Vector<char*> *description = new Vector<char*>(1);
1294 Vector<int> * flavors = new Vector<int>(1);
1295 Vector<int> * vtype = new Vector<int>(1);
1296 Vector<int> * vstyles_capable = new Vector<int>(1);
1297
1298 // Specifies which default styles should be enabled when a metric is enabled.
1299 // Also, specifies if metric should start enabled
1300 Vector<int> *vstyles_e_defaults = new Vector<int>(1);
1301 Vector<int> *vstyles_i_defaults = new Vector<int>(1);
1302 Vector<bool> *registered = new Vector<bool>(1);
1303 Vector<bool> *aggregation = new Vector<bool>(1);
1304 Vector<bool> *has_value = new Vector<bool>(1);
1305 Vector<char*> *unit = new Vector<char*>(1);
1306 Vector<char*> *unit_uname = new Vector<char*>(1);
1307
1308 char *_name = NULL;
1309 char *_username = NULL;
1310 char *_description = dbe_strdup (curr->get_description ());
1311
1312 // BaseMetric fields
1313 int _flavors = 0; // SubType bitmask: (e.g. EXCLUSIVE)
1314 int _vtype = 0; // ValueTag: e.g. VT_INT, VT_FLOAT, ...
1315 int _vstyles_capable = 0; // ValueType bitmask, e.g. VAL_TIMEVAL
1316 int _vstyles_e_default_values = 0; // default visibility settings, exclusive/static
1317 int _vstyles_i_derault_values = 0; // default visibility settings, inclusive
1318 bool _registered = curr->is_registered ()
1319 || curr->get_num_registered_descendents () > 0;
1320 bool _aggregation = curr->is_composite_metric ()
1321 && curr->get_num_registered_descendents () > 0;
1322 bool _has_value = false; //not used yet; for nodes that don't have metrics
1323 char *_unit = NULL;
1324 char *_unit_uname = NULL;
1325
1326 BaseMetric *bm = curr->get_BaseMetric ();
1327 if (bm)
1328 {
1329 _name = dbe_strdup (bm->get_cmd ());
1330 _username = dbe_strdup (bm->get_username ());
1331 if (!include_unregistered && !curr->is_registered ())
1332 abort ();
1333 _flavors = bm->get_flavors ();
1334 _vtype = bm->get_vtype ();
1335 _vstyles_capable = bm->get_value_styles ();
1336 int e_visbits = bm->get_default_visbits (BaseMetric::EXCLUSIVE);
1337 int i_visbits = bm->get_default_visbits (BaseMetric::INCLUSIVE);
1338 _vstyles_e_default_values = convert_visbits_to_gui_checkbox_bits (bm, e_visbits);
1339 _vstyles_i_derault_values = convert_visbits_to_gui_checkbox_bits (bm, i_visbits);
1340 // not all metrics shown in er_print cmd line should be selected in the GUI at startup:
1341 if (has_clock_profiling_data && bm->get_hw_ctr ())
1342 {
1343 bool hide = true; // by default, hide HWCs
1344 if (dbe_strcmp (bm->get_hw_ctr ()->name, NTXT ("c_stalls")) == 0 ||
1345 dbe_strcmp (bm->get_hw_ctr ()->name, NTXT ("K_c_stalls")) == 0)
1346 {
1347 bool is_time = (bm->get_value_styles () & VAL_TIMEVAL) != 0;
1348 if (is_time)
1349 // By default, show time variant of c_stalls
1350 hide = false;
1351 }
1352 if (hide)
1353 {
1354 _vstyles_e_default_values |= VAL_HIDE_ALL;
1355 _vstyles_i_derault_values |= VAL_HIDE_ALL;
1356 }
1357 }
1358 }
1359 else
1360 {
1361 // not a base metric
1362 _name = dbe_strdup (curr->get_name ());
1363 _username = dbe_strdup (curr->get_user_name ());
1364 if (curr->get_unit ())
1365 { // represents a value
1366 _has_value = true;
1367 _unit = dbe_strdup (curr->get_unit ());
1368 _unit_uname = dbe_strdup (curr->get_unit_uname ());
1369 }
1370 }
1371 name->append (_name); // unique id string (dmetrics cmd)
1372 username->append (_username); // user-visible name
1373 description->append (_description);
1374 flavors->append (_flavors); // SubType bitmask: (e.g. EXCLUSIVE)
1375 vtype->append (_vtype); // ValueTag: e.g. VT_INT, VT_FLOAT, ...
1376 vstyles_capable->append (_vstyles_capable); // ValueType bitmask, e.g. VAL_TIMEVAL
1377 vstyles_e_defaults->append (_vstyles_e_default_values);
1378 vstyles_i_defaults->append (_vstyles_i_derault_values);
1379 registered->append (_registered); // is a "live" metric
1380 aggregation->append (_aggregation); // value derived from children nodes
1381 has_value->append (_has_value); // value generated from other source
1382 unit->append (_unit); // See BaseMetric.h, e.g. UNIT_SECONDS
1383 unit_uname->append (_unit_uname); //See BaseMetric.h,
1384
1385 fields->append (name);
1386 fields->append (username);
1387 fields->append (description);
1388 fields->append (flavors);
1389 fields->append (vtype);
1390 fields->append (vstyles_capable);
1391 fields->append (vstyles_e_defaults);
1392 fields->append (vstyles_i_defaults);
1393 fields->append (registered);
1394 fields->append (aggregation);
1395 fields->append (has_value);
1396 fields->append (unit);
1397 fields->append (unit_uname);
1398 data->append (fields);
1399
1400 // ----- children
1401 Vector<BaseMetricTreeNode*> *children = curr->get_children ();
1402 int num_children = children->size ();
1403 Vector<void*> *children_list = new Vector<void*>(num_children);
1404 BaseMetricTreeNode *child_node;
1405 int index;
1406
1407 Vec_loop (BaseMetricTreeNode*, children, index, child_node)
1408 {
1409 if (include_unregistered /* fetch everything */
1410 || child_node->is_registered ()
1411 || child_node->get_num_registered_descendents () > 0)
1412 {
1413 //Special case for metrics that aren't registered
1414 // but have registered children
1415 // Linux example: Total Time is unregistered, CPU Time is registered
1416 if (!include_unregistered && /* not fetching everything */
1417 !child_node->is_registered () &&
1418 (child_node->get_BaseMetric () != NULL ||
1419 child_node->is_composite_metric ()))
1420 {
1421 Vector<BaseMetricTreeNode*> *registered_descendents =
1422 new Vector<BaseMetricTreeNode*>();
1423 child_node->get_nearest_registered_descendents (registered_descendents);
1424 int idx2;
1425 BaseMetricTreeNode*desc_node;
1426 Vec_loop (BaseMetricTreeNode*, registered_descendents, idx2, desc_node)
1427 {
1428 Vector<void*> *desc_data;
1429 desc_data = dbeGetMetricTreeNode (desc_node, mlist,
1430 include_unregistered, has_clock_profiling_data);
1431 children_list->append (desc_data);
1432 }
1433 delete registered_descendents;
1434 continue;
1435 }
1436 Vector<void*> *child_data;
1437 child_data = dbeGetMetricTreeNode (child_node, mlist,
1438 include_unregistered, has_clock_profiling_data);
1439 children_list->append (child_data);
1440 }
1441 }
1442 data->append (children_list);
1443 return data;
1444}
1445
1446Vector<void*> *
1447dbeGetRefMetricTree (int dbevindex, bool include_unregistered)
1448{
1449 DbeView *dbev = dbeSession->getView (dbevindex);
1450 MetricList *mlist = dbev->get_metric_list (MET_NORMAL);
1451 bool has_clock_profiling_data = false;
1452 for (long i = 0, sz = mlist->get_items ()->size (); i < sz; i++)
1453 {
1454 Metric *m = mlist->get_items ()->fetch (i);
1455 if (m->get_packet_type () == DATA_CLOCK)
1456 {
1457 has_clock_profiling_data = true;
1458 break;
1459 }
1460 }
1461 BaseMetricTreeNode *curr = dbeSession->get_reg_metrics_tree ();
1462 return dbeGetMetricTreeNode (curr, mlist, include_unregistered, has_clock_profiling_data);
1463}
1464
1465static Vector<void*> *
1466dbeGetTableDataV2Data (DbeView *dbev, Hist_data *data);
1467
1468static Vector<void*> *dbeGetTableDataOneColumn (Hist_data *data, int met_ind);
1469static Vector<void*> *
1470dbeGetTableDataOneColumn (DbeView *dbev, Vector<Hist_data::HistItem*> *data,
1471 ValueTag vtype, int metricColumnNumber);
1472
1473static hrtime_t
1474dbeCalcGroupDuration (int grInd)
1475{
1476 int thisGroupSize = 1;
1477 hrtime_t max_time = 0;
1478 Experiment *exp;
1479 if (dbeSession->expGroups->size () > 0)
1480 {
1481 ExpGroup *grp = dbeSession->expGroups->fetch (grInd);
1482 thisGroupSize = grp->exps->size ();
1483 for (int ii = 0; ii < thisGroupSize; ii++)
1484 {
1485 exp = grp->exps->fetch (ii);
1486 Vector<DataDescriptor*> *ddscr = exp->getDataDescriptors ();
1487 delete ddscr;// getDataDescriptors() forces reading of experiment data
1488 if (exp != NULL)
1489 {
1490 hrtime_t tot_time = exp->getLastEvent () - exp->getStartTime ()
1491 + exp->getRelativeStartTime ();
1492 if (max_time < tot_time)
1493 max_time = tot_time;
1494 }
1495 }
1496 }
1497 else
1498 {
1499 exp = dbeSession->get_exp (0);
1500 if (exp != NULL)
1501 max_time = exp->getLastEvent () - exp->getStartTime ();
1502 }
1503 return max_time; //nanoseconds
1504}
1505
1506static hrtime_t
1507dbeCalcGroupGCDuration (int grInd)
1508{
1509 int thisGroupSize = 1;
1510 hrtime_t tot_time = 0;
1511 Experiment *exp;
1512 if (dbeSession->expGroups->size () > 0)
1513 {
1514 ExpGroup *grp = dbeSession->expGroups->fetch (grInd);
1515 thisGroupSize = grp->exps->size ();
1516 for (int ii = 0; ii < thisGroupSize; ii++)
1517 {
1518 exp = grp->exps->fetch (ii);
1519 Vector<DataDescriptor*> *ddscr = exp->getDataDescriptors ();
1520 delete ddscr; // getDataDescriptors() forces reading of experiment data
1521 if (exp != NULL)
1522 tot_time += exp->getGCDuration ();
1523 }
1524 }
1525 else
1526 {
1527 exp = dbeSession->get_exp (0);
1528 if (exp != NULL)
1529 tot_time = exp->getGCDuration ();
1530 }
1531 return tot_time; //nanoseconds
1532}
1533
1534Vector<void*> *
1535dbeGetRefMetricTreeValues (int dbevindex, Vector<char *> *metric_cmds,
1536 Vector<char *> *non_metric_cmds)
1537{
1538 DbeView *dbev = dbeSession->getView (dbevindex);
1539 // valueTable will have N "columns" of values, where N is the number of
1540 // requested metrics and non-metrics.
1541 // Each column will be a vector with M "rows", where M is the number of
1542 // compare groups.
1543 // highlightTable mirrors the structure of valueTable. Each cell indicates
1544 // if the corresponding valueTable cell is "hot" (interesting)
1545 int numMetrics = metric_cmds->size ();
1546 int numNonMetrics = non_metric_cmds->size ();
1547 int totalColumns = numMetrics + numNonMetrics; // Columns
1548 Vector<void*> *valueTable = new Vector<void*>(totalColumns);
1549 Vector<void*> *highlightTable = new Vector<void*>(totalColumns);
1550
1551 // the return value consists of the two tables discussed above.
1552 Vector<void*> *rc = new Vector<void*>(2);
1553 rc->append (valueTable);
1554 rc->append (highlightTable);
1555 if (dbeSession->nexps () == 0)
1556 { // no experiments are loaded
1557 for (int jj = 0; jj < totalColumns; jj++)
1558 {
1559 Vector<void *> *columnData = new Vector<void *>();
1560 valueTable->append (columnData);
1561 highlightTable->append (columnData);
1562 }
1563 return rc;
1564 }
1565
1566 int ngroups = dbeSession->expGroups->size (); // Rows (one per compare group)
1567 if (ngroups == 0 || !dbev->comparingExperiments ())
1568 ngroups = 1;
1569
1570 Vector<double> *groupTotalTime = new Vector<double>(ngroups);
1571 Vector<double> *groupCpuTime = new Vector<double>(ngroups);
1572 // initialize highlight table
1573 for (int ii = 0; ii < totalColumns; ii++)
1574 { // metrics
1575 Vector<bool> *columnData = new Vector<bool>(ngroups);
1576 highlightTable->append (columnData);
1577 for (int grInd = 0; grInd < ngroups; grInd++)
1578 columnData->store (grInd, false); // non-highlight
1579 }
1580
1581 if (numMetrics > 0)
1582 {
1583 MetricList *bmlist;
1584 // set bmlist to list of requested base metrics
1585 BaseMetricTreeNode *root = dbeSession->get_reg_metrics_tree ();
1586 int index;
1587 char *mcmd;
1588 Vector<BaseMetric*> *base_metrics = new Vector<BaseMetric*>();
1589 Vec_loop (char *, metric_cmds, index, mcmd)
1590 {
1591 BaseMetricTreeNode *bmt_node = root->find (mcmd);
1592 if (!bmt_node)
1593 abort (); //YXXX weird
1594 BaseMetric * baseNetric = bmt_node->get_BaseMetric ();
1595 if (!baseNetric)
1596 abort ();
1597 base_metrics->append (baseNetric);
1598 }
1599
1600 // MET_INDX will create MetricList of Exclusive metrics
1601 bmlist = new MetricList (base_metrics, MET_SRCDIS);
1602
1603 // Use the Function List to fetch <Total> values
1604 // A temporary table, v_totals, stores <total> by group
1605 Vector<Hist_data::HistItem *> *v_totals = new Vector<Hist_data::HistItem *>(ngroups);
1606 for (int grInd = 0; grInd < ngroups; grInd++)
1607 {
1608 MetricList *mlist;
1609 if (ngroups > 1)
1610 mlist = dbev->get_compare_mlist (bmlist, grInd);
1611 else
1612 mlist = bmlist;
1613 if (mlist->size () != numMetrics)
1614 abort ();
1615
1616 Hist_data *data;
1617 data = dbev->get_hist_data (mlist, Histable::FUNCTION, 0,
1618 Hist_data::ALL);
1619 Hist_data::HistItem * totals = data->get_totals ();
1620 v_totals->append (totals);
1621 }
1622
1623 // store the Hist_data totals in valueTable
1624 {
1625 Metric *mitem;
1626 int index;
1627 Vec_loop (Metric*, bmlist->get_items (), index, mitem)
1628 {
1629 Vector<void*> * columnData = dbeGetTableDataOneColumn (dbev,
1630 v_totals, mitem->get_vtype (), index);
1631 valueTable->append (columnData);
1632 }
1633 }
1634
1635 // 7207285: hack for hwc profiling cycles conversion:
1636 {
1637 Metric *mitem;
1638 int index;
1639 Vec_loop (Metric*, bmlist->get_items (), index, mitem)
1640 {
1641 if (mitem->is_time_val ()
1642 && mitem->get_vtype () == VT_ULLONG)
1643 {
1644 Vector<long long> *cycleValues = (Vector<long long> *)valueTable->fetch (index);
1645 Vector<double> *timeValues = new Vector<double>(ngroups);
1646 assert (cycleValues->size () == ngroups);
1647 for (int grInd = 0; grInd < ngroups; grInd++)
1648 {
1649 long long cycles = cycleValues->fetch (grInd);
1650 int expId;
1651 if (dbeSession->expGroups->size () > 0)
1652 {
1653 ExpGroup *gr = dbeSession->expGroups->fetch (grInd);
1654 Experiment *exp = gr->exps->fetch (0);
1655 expId = exp->getExpIdx ();
1656 }
1657 else
1658 expId = -1;
1659 int clock = dbeSession->get_clock (expId);
1660 double time;
1661 if (clock)
1662 time = cycles / (1.e+6 * clock);
1663 else
1664 time = cycles; //weird
1665 timeValues->store (grInd, time);
1666 }
1667 delete cycleValues;
1668 valueTable->store (index, timeValues);
1669 }
1670 }
1671 }
1672
1673 // Scan metrics for best measure of CPU time
1674 int bestCpuTimeIndx = -1;
1675 {
1676 Metric *mitem;
1677 int index;
1678 Vec_loop (Metric*, bmlist->get_items (), index, mitem)
1679 {
1680 BaseMetric::Type type = mitem->get_type ();
1681 if (type == BaseMetric::CP_KERNEL_CPU)
1682 {
1683 bestCpuTimeIndx = index;
1684 break; // CP_KERNEL_CPU trumps other measures
1685 }
1686 if (type == BaseMetric::CP_TOTAL_CPU)
1687 {
1688 // clock profiling CPU time
1689 bestCpuTimeIndx = index;
1690 // keep looking in case CP_KERNEL_CPU also exists
1691 continue;
1692 }
1693
1694 bool isTime = ((mitem->get_value_styles () & VAL_TIMEVAL) != 0);
1695 bool isHwcCycles = (type == BaseMetric::HWCNTR
1696 && (dbe_strcmp (mitem->get_aux (), "cycles") == 0)
1697 && isTime);
1698 if (isHwcCycles)
1699 if (bestCpuTimeIndx < 0)
1700 bestCpuTimeIndx = index;
1701 }
1702 if (bestCpuTimeIndx >= 0)
1703 {
1704 Vector<double> *timeValues = (Vector<double> *)valueTable->fetch (bestCpuTimeIndx);
1705 if (timeValues->type () == VEC_DOUBLE)
1706 for (int grInd = 0; grInd < ngroups; grInd++)
1707 {
1708 double time = timeValues->fetch (grInd);
1709 groupCpuTime->append (time);
1710 }
1711 }
1712 }
1713
1714 // Scan metrics for Total Thread time
1715 {
1716 Metric *mitem;
1717 int index;
1718 Vec_loop (Metric*, bmlist->get_items (), index, mitem)
1719 {
1720 BaseMetric::Type type = mitem->get_type ();
1721 if (type == BaseMetric::CP_TOTAL)
1722 {
1723 Vector<double> *timeValues = (Vector<double> *)valueTable->fetch (index);
1724 if (timeValues->type () != VEC_DOUBLE)
1725 continue; // weird
1726 for (int grInd = 0; grInd < ngroups; grInd++)
1727 {
1728 double time = timeValues->fetch (grInd);
1729 groupTotalTime->append (time);
1730 }
1731 break;
1732 }
1733 }
1734 }
1735
1736 // highlight metrics based on cpu time
1737#define CPUSEC_PERCENT_THRESHOLD 10.0
1738#define HWC_OVERFLOWS_PER_CPUSEC_THRESHOLD 15
1739 {
1740 Metric *mitem;
1741 int index;
1742 Vec_loop (Metric*, bmlist->get_items (), index, mitem)
1743 {
1744 BaseMetric::Type type = mitem->get_type ();
1745 Vector<bool> * columnHilites = (Vector<bool> *)highlightTable->fetch (index);
1746
1747 // always highlight the following
1748 if (index == bestCpuTimeIndx)
1749 {
1750 for (int grInd = 0; grInd < ngroups; grInd++)
1751 columnHilites->store (grInd, true);
1752 continue;
1753 }
1754
1755 // skip certain types
1756 bool typeIsCycles = (type == BaseMetric::HWCNTR
1757 && dbe_strcmp (mitem->get_aux (), NTXT ("cycles")) == 0);
1758 bool typeIsInsts = (type == BaseMetric::HWCNTR
1759 && dbe_strcmp (mitem->get_aux (), NTXT ("insts")) == 0);
1760 if (type == BaseMetric::CP_TOTAL
1761 || type == BaseMetric::CP_TOTAL_CPU
1762 || type == BaseMetric::CP_LMS_USER
1763 || type == BaseMetric::CP_LMS_SYSTEM
1764 || type == BaseMetric::CP_LMS_TRAP
1765 || type == BaseMetric::CP_LMS_USER_LOCK
1766 || type == BaseMetric::CP_LMS_SLEEP
1767 || type == BaseMetric::CP_KERNEL_CPU
1768 || type == BaseMetric::OMP_WORK
1769 || typeIsCycles
1770 || typeIsInsts
1771 // || type == BaseMetric::CP_TOTAL_WAIT
1772 )
1773 continue; // types we never highlight
1774
1775 // for time values, compare against CPUSEC_PERCENT_THRESHOLD
1776 bool isTime = ((mitem->get_value_styles () & VAL_TIMEVAL) != 0);
1777 if (isTime)
1778 {
1779 if (groupCpuTime->size () == 0)
1780 continue; // no time to use as reference
1781 Vector<double> *timeValues = (Vector<double> *)valueTable->fetch (index);
1782 if (timeValues->type () != VEC_DOUBLE)
1783 continue; // weird
1784 for (int grInd = 0; grInd < ngroups; grInd++)
1785 {
1786 double thistime = timeValues->fetch (grInd);
1787 double usertime = groupCpuTime->fetch (grInd);
1788 if (thistime / (CPUSEC_PERCENT_THRESHOLD / 100) > usertime)
1789 columnHilites->store (grInd, true);
1790 }
1791 continue;
1792 }
1793
1794 // for HWC event counts, look at rate of events
1795 if (type == BaseMetric::HWCNTR)
1796 {
1797 Hwcentry *hwctr = mitem->get_hw_ctr ();
1798 if (!hwctr)
1799 continue; // weird
1800 if (!hwctr->metric)
1801 continue; // raw counter
1802 if (groupCpuTime->size () == 0)
1803 continue; // no time to use as reference
1804 if (mitem->get_base_metric ()->get_dependent_bm ())
1805 continue; // has a derived time metric, only flag time version
1806 Vector<long long> *llValues = (Vector<long long> *)valueTable->fetch (index);
1807 if (llValues->type () != VEC_LLONG)
1808 continue; // weird
1809 int overflowVal = hwctr->val; //overflow count
1810 if (!overflowVal)
1811 continue; // weird
1812 if (overflowVal > (4000000))
1813 // cut off events that are very frequent like loads/stores
1814 // 4Ghz * (0.01 seconds/event) / (4000000 events/overflow) = 10 cycles
1815 continue;
1816 // for HWCs we could base it on the overflow rate
1817 for (int grInd = 0; grInd < ngroups; grInd++)
1818 {
1819 double thisVal = llValues->fetch (grInd);
1820 thisVal /= overflowVal;
1821 double usertime = groupCpuTime->fetch (grInd);
1822 if (thisVal > usertime * HWC_OVERFLOWS_PER_CPUSEC_THRESHOLD)
1823 columnHilites->store (grInd, true);
1824 }
1825 continue;
1826 }
1827
1828 // check for non-zero counts of the following
1829 if (type == BaseMetric::DEADLOCKS ||
1830 type == BaseMetric::RACCESS ||
1831 type == BaseMetric::HEAP_ALLOC_BYTES ||
1832 type == BaseMetric::HEAP_LEAK_BYTES)
1833 {
1834 Vector<long long> *llValues = (Vector<long long> *)valueTable->fetch (index);
1835 if (llValues->type () != VEC_LLONG)
1836 continue; // weird
1837 for (int grInd = 0; grInd < ngroups; grInd++)
1838 {
1839 long long thisVal = llValues->fetch (grInd);
1840 if (thisVal)
1841 columnHilites->store (grInd, true);
1842 }
1843 continue;
1844 }
1845 // continue adding cases as needed
1846 }
1847 }
1848 }
1849
1850 if (numNonMetrics > 0)
1851 {
1852 int index;
1853 char *mcmd;
1854 Vec_loop (char *, non_metric_cmds, index, mcmd)
1855 {
1856 if (dbe_strcmp (mcmd, NTXT ("YXXX_TOTAL_TIME_PLUS_THREADS")) == 0
1857 && groupCpuTime->size () == ngroups)
1858 {
1859 Vector<char *> *columnData = new Vector<char *>(ngroups);
1860 for (int grInd = 0; grInd < ngroups; grInd++)
1861 {
1862 double totaltime = groupTotalTime->fetch (grInd);
1863 columnData->append (dbe_sprintf (NTXT ("%0.3f %s"), totaltime, GTXT ("Seconds")));
1864 }
1865 valueTable->append (columnData);
1866 }
1867 else if (dbe_strcmp (mcmd, L1_DURATION) == 0)
1868 {
1869 Vector<double> *columnData = new Vector<double>(ngroups);
1870 for (int grInd = 0; grInd < ngroups; grInd++)
1871 {
1872 hrtime_t duration = dbeCalcGroupDuration (grInd);
1873 double seconds = duration * 1.e-9;
1874 columnData->append (seconds);
1875 }
1876 valueTable->append (columnData);
1877 }
1878 else if (dbe_strcmp (mcmd, L1_GCDURATION) == 0)
1879 {
1880 Vector<double> *columnData = new Vector<double>(ngroups);
1881 for (int grInd = 0; grInd < ngroups; grInd++)
1882 {
1883 hrtime_t duration = dbeCalcGroupGCDuration (grInd);
1884 double seconds = duration * 1.e-9;
1885 columnData->append (seconds);
1886 }
1887 valueTable->append (columnData);
1888 }
1889 else
1890 {
1891 Vector<char *> *columnData = new Vector<char *>(ngroups);
1892 char * valueString = NTXT ("<unknown>");
1893 for (int grInd = 0; grInd < ngroups; grInd++)
1894 columnData->append (dbe_strdup (valueString));
1895 valueTable->append (columnData);
1896 }
1897 }
1898 }
1899 return rc;
1900}
1901
1902Vector<char*> *
1903dbeGetOverviewText (int dbevindex)
1904{
1905 DbeView *dbev = dbeSession->getView (dbevindex);
1906 Vector<char*> *info = new Vector<char*>;
1907 char *field;
1908 int ngroups = dbeSession->expGroups->size (); // Rows (one per compare group)
1909 if (ngroups == 0 || !dbev->comparingExperiments ())
1910 ngroups = 1;
1911 for (int grInd = 0; grInd < ngroups; grInd++)
1912 {
1913 int thisGroupSize = 1;
1914 Experiment *exp;
1915 if (dbeSession->expGroups->size () > 0)
1916 {
1917 ExpGroup *gr = dbeSession->expGroups->fetch (grInd);
1918 exp = gr->exps->fetch (0);
1919 thisGroupSize = gr->exps->size ();
1920 }
1921 else
1922 {
1923 if (dbeSession->nexps () == 0)
1924 return info;
1925 exp = dbeSession->get_exp (0);
1926 }
1927 char * expHeader;
1928 if (ngroups == 1)
1929 expHeader = dbe_strdup (GTXT ("Experiment :"));
1930 else if (grInd == 0)
1931 expHeader = dbe_strdup (GTXT ("Base Group : "));
1932 else if (ngroups == 2)
1933 expHeader = dbe_strdup (GTXT ("Compare Group : "));
1934 else
1935 expHeader = dbe_sprintf (GTXT ("Compare Group %d : "), grInd);
1936 if (thisGroupSize == 1)
1937 info->append (dbe_sprintf ("%s%s", expHeader, exp->get_expt_name ()));
1938 else
1939 info->append (dbe_sprintf ("%s%s (plus %d more)",
1940 expHeader, exp->get_expt_name (), thisGroupSize - 1));
1941 free (expHeader);
1942 field = exp->uarglist;
1943 if (field && field[0])
1944 info->append (dbe_sprintf (GTXT (" Target : '%s'"), field));
1945 field = exp->hostname;
1946 if (field && field[0])
6094a48e 1947 info->append (dbe_sprintf (GTXT (" Host : %s (%s, %s)"),
bb368aad
VM
1948 field,
1949 exp->architecture ? exp->architecture
1950 : GTXT ("<CPU architecture not recorded>"),
1951 exp->os_version ? exp->os_version
1952 : GTXT ("<OS version not recorded>")));
6094a48e
VM
1953 time_t start_sec = (time_t) exp->start_sec;
1954 char *p = ctime (&start_sec);
bb368aad
VM
1955 hrtime_t tot_time = dbeCalcGroupDuration (grInd);
1956 double seconds = tot_time * 1.e-9;
6094a48e
VM
1957 info->append (dbe_sprintf (
1958 GTXT (" Start Time : %s Duration : %0.3f Seconds"),
1959 p, seconds));
bb368aad
VM
1960 // Number of descendants/processes would be nice
1961 info->append (dbe_strdup (NTXT ("")));
1962 }
1963 return info;
1964}
1965
1966//--------------------------------------------------------------------------
1967// Set Sort by index
1968//
1969void
1970dbeSetSort (int dbevindex, int sort_index, MetricType mtype, bool reverse)
1971{
1972 DbeView *dbev;
1973
1974 dbev = dbeSession->getView (dbevindex);
1975 if (dbev == NULL)
1976 abort ();
1977 dbev->setSort (sort_index, mtype, reverse);
1978 return;
1979}
1980
1981//
1982// Get annotation setting
1983//
1984Vector<int> *
1985dbeGetAnoValue (int dbevindex)
1986{
1987 DbeView *dbev = dbeSession->getView (dbevindex);
1988 if (dbev == NULL)
1989 abort ();
1990 Vector<int> *set = new Vector<int>(9);
1991 set->store (0, dbev->get_src_compcom ());
1992 set->store (1, dbev->get_dis_compcom ());
1993 set->store (2, dbev->get_thresh_src ());
1994 set->store (3, dbev->get_thresh_src ());
1995 set->store (4, dbev->get_src_visible ());
1996 set->store (5, (int) dbev->get_srcmetric_visible ());
1997 set->store (6, (int) dbev->get_hex_visible ());
1998 set->store (7, (int) dbev->get_cmpline_visible ());
1999 set->store (8, (int) dbev->get_func_scope ());
2000 return set;
2001}
2002
2003//
2004// Set annotation setting
2005//
2006void
2007dbeSetAnoValue (int dbevindex, Vector<int> *set)
2008{
2009 DbeView *dbev;
2010 dbev = dbeSession->getView (dbevindex);
2011 if (dbev == NULL)
2012 abort ();
2013 if (set->size () != 10)
2014 return;
2015 dbev->set_src_compcom (set->fetch (0));
2016 dbev->set_dis_compcom (set->fetch (1));
2017 dbev->set_thresh_src (set->fetch (2));
2018 dbev->set_thresh_dis (set->fetch (3));
2019 dbev->set_src_visible (set->fetch (4));
2020 dbev->set_srcmetric_visible ((bool)set->fetch (5));
2021 dbev->set_hex_visible ((bool)set->fetch (6));
2022 dbev->set_cmpline_visible ((bool)set->fetch (7));
2023 dbev->set_func_scope (set->fetch (8));
2024 dbev->set_funcline_visible ((bool)set->fetch (9));
2025 return;
2026}
2027
2028//
2029// Get name formats
2030//
2031int
2032dbeGetNameFormat (int dbevindex)
2033{
2034 DbeView *dbev;
2035 dbev = dbeSession->getView (dbevindex);
2036 if (dbev == NULL)
2037 abort ();
2038 Histable::NameFormat fmt = dbev->get_name_format ();
2039 return Histable::fname_fmt (fmt);
2040}
2041
2042bool
2043dbeGetSoName (int dbevindex)
2044{
2045 DbeView *dbev;
2046 dbev = dbeSession->getView (dbevindex);
2047 if (dbev == NULL)
2048 abort ();
2049 Histable::NameFormat fmt = dbev->get_name_format ();
2050 return Histable::soname_fmt (fmt);
2051}
2052
2053//
2054// Set name formats
2055//
2056void
2057dbeSetNameFormat (int dbevindex, int nformat, bool soname)
2058{
2059 DbeView *dbev;
2060 dbev = dbeSession->getView (dbevindex);
2061 if (dbev == NULL)
2062 abort ();
2063 dbev->set_name_format (nformat, soname);
2064}
2065
2066//
2067// Get View mode
2068//
2069int
2070dbeGetViewMode (int dbevindex)
2071{
2072 DbeView *dbev;
2073 dbev = dbeSession->getView (dbevindex);
2074 if (dbev == NULL)
2075 abort ();
2076 return (int) dbev->get_view_mode ();
2077}
2078
2079// Set View mode
2080void
2081dbeSetViewMode (int dbevindex, int nmode)
2082{
2083 DbeView *dbev;
2084 dbev = dbeSession->getView (dbevindex);
2085 if (dbev == NULL)
2086 abort ();
2087 dbev->set_view_mode ((VMode) nmode);
2088 return;
2089}
2090
2091// Get timeline setting
2092//
2093Vector<void*> *
2094dbeGetTLValue (int dbevindex)
2095{
2096 DbeView *dbev;
2097 dbev = dbeSession->getView (dbevindex);
2098 if (dbev == NULL)
2099 abort ();
2100 Vector<char *> *strings = new Vector<char *>();
2101 char *tldata_cmd = dbev->get_tldata ();
2102 strings->store (0, tldata_cmd);
2103
2104 Vector<int> *ints = new Vector<int>(3);
2105 int val;
2106 val = dbev->get_tlmode ();
2107 ints->store (0, val);
2108 val = dbev->get_stack_align ();
2109 ints->store (1, val);
2110 val = dbev->get_stack_depth ();
2111 ints->store (2, val);
2112
2113 Vector<void*> *objs = new Vector<void*>(2);
2114 objs->store (0, strings);
2115 objs->store (1, ints);
2116 return objs;
2117}
2118
2119//
2120// Set timeline setting
2121//
2122void
2123dbeSetTLValue (int dbevindex, const char *tldata_cmd,
2124 int entitiy_prop_id, int stackalign, int stackdepth)
2125{
2126 DbeView *dbev;
2127 dbev = dbeSession->getView (dbevindex);
2128 if (dbev == NULL)
2129 abort ();
2130 dbev->set_tldata (tldata_cmd);
2131 dbev->set_tlmode (entitiy_prop_id);
2132 dbev->set_stack_align (stackalign);
2133 dbev->set_stack_depth (stackdepth);
2134 return;
2135}
2136
2137//
2138// Get founder experiments and their descendants
2139//
2140Vector<void*> *
2141dbeGetExpFounderDescendants ()
2142{
2143 int size = dbeSession->nexps ();
2144 if (size == 0)
2145 return NULL;
2146 Vector<void*> *table = new Vector<void*>(2);
2147 Vector<int> *founderExpIds = new Vector<int>();
2148 Vector<Vector<int> *> *subExpIds = new Vector<Vector<int>*>();
2149 for (int index = 0; index < size; index++)
2150 {
2151 Experiment *exp = dbeSession->get_exp (index);
2152 if (exp->founder_exp == NULL)
2153 {
2154 founderExpIds->append (exp->getExpIdx ());
2155 Vector<int> *subExps = new Vector<int>();
2156 for (int i = 0; i < exp->children_exps->size (); i++)
2157 {
2158 Experiment * subExp = exp->children_exps->fetch (i);
2159 subExps->append (subExp->getExpIdx ());
2160 }
2161 subExpIds->append (subExps);
2162 }
2163 }
2164 table->store (0, founderExpIds);
2165 table->store (1, subExpIds);
2166 return table;
2167}
2168
2169//
2170// Get experiment selection
2171//
2172Vector<void*> *
2173dbeGetExpSelection (int dbevindex)
2174{
2175 DbeView *dbev = dbeSession->getView (dbevindex);
2176 if (dbev == NULL)
2177 abort ();
2178 int size = dbeSession->nexps ();
2179 if (size == 0)
2180 return NULL;
2181 Vector<void*> *table = new Vector<void*>(3);
2182 Vector<char*> *names = new Vector<char*>(size);
2183 Vector<bool> *enable = new Vector<bool>(size);
2184 Vector<int> *userExpIds = new Vector<int>(size);
2185
2186 // Get experiment names
2187 for (int index = 0; index < size; index++)
2188 {
2189 Experiment *exp = dbeSession->get_exp (index);
2190 char *buf = dbeGetName (dbevindex, index);
2191 names->store (index, buf);
2192 bool val;
2193 val = dbev->get_exp_enable (index);
2194 enable->store (index, val);
2195 userExpIds->store (index, exp->getUserExpId ());
2196 }
2197 table->store (0, names);
2198 table->store (1, enable);
2199 table->store (2, userExpIds);
2200 return table;
2201}
2202
2203int
2204dbeValidateFilterExpression (char *str_expr)
2205{
2206 if (str_expr == NULL)
2207 return 0;
2208 Expression *expr = dbeSession->ql_parse (str_expr);
2209 if (expr == NULL)
2210 return 0;
2211 delete expr;
2212 return 1;
2213}
2214
2215Vector<void*> *
2216dbeGetFilterKeywords (int /* dbevindex */)
2217{
2218 Vector <char*> *kwCategory = new Vector<char *>();
2219 Vector <char*> *kwCategoryI18N = new Vector<char *>();
2220 Vector <char*> *kwDataType = new Vector<char *>();
2221 Vector <char*> *kwKeyword = new Vector<char *>();
2222 Vector <char*> *kwFormula = new Vector<char *>();
2223 Vector <char*> *kwDescription = new Vector<char *>();
2224 Vector <void*> *kwEnumDescs = new Vector<void *>();
2225
2226 Vector<void*> *res = new Vector<void*>(7);
2227 res->append (kwCategory);
2228 res->append (kwCategoryI18N);
2229 res->append (kwDataType);
2230 res->append (kwKeyword);
2231 res->append (kwFormula);
2232 res->append (kwDescription);
2233 res->append (kwEnumDescs);
2234
2235 char *vtypeNames[] = VTYPE_TYPE_NAMES;
2236 // section header for global definitions
2237 kwCategory->append (dbe_strdup (NTXT ("FK_SECTION")));
2238 kwCategoryI18N->append (dbe_strdup (GTXT ("Global Definitions")));
2239 kwDataType->append (NULL);
2240 kwKeyword->append (NULL);
2241 kwFormula->append (NULL);
2242 kwDescription->append (NULL);
2243 kwEnumDescs->append (NULL);
2244 dbeSession->get_filter_keywords (res);
2245 MemorySpace::get_filter_keywords (res);
2246
2247 // loop thru all founder experiments
2248 int nexp = dbeSession->nexps ();
2249 for (int ii = 0; ii < nexp; ++ii)
2250 {
2251 Experiment* fexp = dbeSession->get_exp (ii);
2252 if (fexp->founder_exp != NULL)
2253 continue; // is a child; should be covered when we get to founder
2254
2255 // section header for each founder
2256 // section header for founder experiment
2257 kwCategory->append (dbe_strdup (NTXT ("FK_SECTION")));
2258 kwCategoryI18N->append (dbe_sprintf (NTXT ("%s [EXPGRID==%d]"),
2259 fexp->get_expt_name (),
2260 fexp->groupId));
2261 kwDataType->append (NULL);
2262 kwKeyword->append (NULL);
2263 kwFormula->append (NULL);
2264 kwDescription->append (NULL);
2265 kwEnumDescs->append (NULL);
2266
2267 int nchildren = fexp->children_exps->size ();
2268 Experiment *exp;
2269 // category header: Experiments
2270 {
2271 char *propUName = dbeSession->getPropUName (PROP_EXPID);
2272
2273 // store list of subexperiments in kwEnumDescs
2274 Vector <char*> *enumDescs = new Vector<char *>();
2275 int jj = 0;
2276 exp = fexp;
2277 while (1)
2278 {
2279 char * expBasename = get_basename (exp->get_expt_name ());
2280 char * targetName = exp->utargname ? exp->utargname
2281 : (char *) GTXT ("(unknown)");
2282 enumDescs->append (dbe_sprintf (NTXT ("(%d) -> %s [%s, PID %d]"),
2283 exp->getUserExpId (), expBasename,
2284 targetName, exp->getPID ()));
2285 if (jj >= nchildren)
2286 break;
2287 exp = fexp->children_exps->fetch (jj);
2288 jj++;
2289 }
2290 kwCategory->append (dbe_strdup (NTXT ("FK_EXPLIST")));
2291 kwCategoryI18N->append (dbe_strdup (GTXT ("Experiments")));
2292 kwDataType->append (dbe_strdup (vtypeNames[TYPE_INT32]));
2293 kwKeyword->append (dbe_strdup (NTXT ("EXPID")));
2294 kwFormula->append (NULL);
2295 kwDescription->append (propUName);
2296 kwEnumDescs->append (enumDescs);
2297 }
2298
2299 // select representative experiment
2300 if (nchildren == 0)
2301 exp = fexp; // founder
2302 else
2303 exp = fexp->children_exps->fetch (0); // first child
2304 int expIdx = exp->getExpIdx ();
2305 Vector<void*> *data = dbeGetDataDescriptorsV2 (expIdx);
2306 if (data == NULL)
2307 continue;
2308 Vector<int> *dataId = (Vector<int>*)data->fetch (0);
2309 Vector<char*> *dataName = (Vector<char*>*)data->fetch (1);
2310 Vector<char*> *dataUName = (Vector<char*>*)data->fetch (2);
2311 if (dataId == NULL || dataName == NULL)
2312 {
2313 destroy (data);
2314 continue;
2315 }
2316 // loop thru data descriptors
2317 int ndata = dataId->size ();
2318 for (int j = 0; j < ndata; ++j)
2319 {
2320 // category: data name (e.g. Clock Profiling)
2321 char * catName = dataName->fetch (j);
2322 char * dUname = dataUName ? dataUName->fetch (j) : catName;
2323 char * catUname = dUname ? dUname : catName;
2324
2325 Vector<void*> *props = dbeGetDataPropertiesV2 (expIdx, dataId->fetch (j));
2326 if (props == NULL)
2327 continue;
2328 Vector<char*> *propUName = (Vector<char*>*)props->fetch (1);
2329 Vector<int> *propTypeId = (Vector<int> *)props->fetch (2);
2330 Vector<char*> *propType = (Vector<char*>*)props->fetch (3);
2331 Vector<char*> *propName = (Vector<char*>*)props->fetch (5);
2332 Vector<Vector<char*>*> *propStateNames =
2333 (Vector<Vector<char*>*> *)props->fetch (6);
2334 Vector<Vector<char*>*> *propStateUNames =
2335 (Vector<Vector<char*>*> *)props->fetch (7);
2336 if (propName == NULL || propUName == NULL || propType == NULL
2337 || propName->size () <= 0)
2338 {
2339 destroy (props);
2340 continue;
2341 }
2342 int nprop = propName->size ();
2343 for (int k = 0; k < nprop; ++k)
2344 {
2345 if (propTypeId->fetch (k) == TYPE_OBJ)
2346 continue;
2347 if (dbe_strcmp (propName->fetch (k), NTXT ("FRINFO")) == 0)
2348 continue;
2349
2350 // store list of states in kwEnumDescs
2351 Vector<char*> *enumDescs = new Vector<char *>();
2352 Vector<char*>* stateNames = propStateNames->fetch (k);
2353 Vector<char*>* stateUNames = propStateUNames->fetch (k);
2354 int nStates = stateNames ? stateNames->size () : 0;
2355 for (int kk = 0; kk < nStates; ++kk)
2356 {
2357 const char *stateName = stateNames->fetch (kk);
2358 if (stateName == NULL || strlen (stateName) == 0)
2359 continue;
2360 const char *stateUName = stateUNames->fetch (kk);
2361 if (stateUName == NULL || strlen (stateUName) == 0)
2362 stateUName = stateName;
2363 enumDescs->append (dbe_sprintf (NTXT ("(%d) -> %s"), kk, stateUName));
2364 }
2365 kwCategory->append (dbe_strdup (catName));
2366 kwCategoryI18N->append (dbe_strdup (catUname));
2367 kwDataType->append (dbe_strdup (propType->fetch (k)));
2368 kwKeyword->append (dbe_strdup (propName->fetch (k)));
2369 kwFormula->append (NULL);
2370 kwDescription->append (dbe_strdup (propUName->fetch (k)));
2371 kwEnumDescs->append (enumDescs);
2372 }
2373 destroy (props);
2374 }
2375 destroy (data);
2376 }
2377 return (res);
2378}
2379
2380// GetFilters -- returns the list of filters for the indexed experiment
2381// returns false if there's a problem; true otherwise
2382//
2383Vector<void*> *
2384dbeGetFilters (int dbevindex, int nexp)
2385{
2386 FilterNumeric *filt;
2387 int index;
2388 DbeView *dbev = dbeSession->getView (dbevindex);
2389 if (dbev == NULL)
2390 abort ();
2391 Vector<FilterNumeric *>*filters = dbev->get_all_filters (nexp);
2392 if (filters == NULL)
2393 return NULL;
2394
2395 // return an array of filter data for that experiment
2396 Vector <int> *findex = new Vector<int>(); // index of the filters
2397 Vector <char*> *shortname = new Vector<char *>();
2398 // short name of filter
2399 Vector <char*> *i18n_name = new Vector<char *>();
2400 // External I18N'd name of filter
2401 Vector <char*> *pattern = new Vector<char *>();
2402 // current setting string
2403 Vector <char*> *status = new Vector<char *>();
2404 // current status of filter (%, range, etc.)
2405
2406 Vec_loop (FilterNumeric *, filters, index, filt)
2407 {
2408 findex->append (index);
2409 shortname->append (dbe_strdup (filt->get_cmd ()));
2410 i18n_name->append (dbe_strdup (filt->get_name ()));
2411 pattern->append (dbe_strdup (filt->get_pattern ()));
2412 status->append (dbe_strdup (filt->get_status ()));
2413 }
2414 Vector<void*> *res = new Vector<void*>(5);
2415 res->store (0, findex);
2416 res->store (1, shortname);
2417 res->store (2, i18n_name);
2418 res->store (3, pattern);
2419 res->store (4, status);
2420 return (res);
2421}
2422
2423// Set a filter string for a view
2424// Returns NULL if OK, error message if not
2425
2426char *
2427dbeSetFilterStr (int dbevindex, char *filter_str)
2428{
2429 DbeView *dbev = dbeSession->getView (dbevindex);
2430 if (dbev == NULL)
2431 abort ();
2432 dbev->clear_error_msg ();
2433 dbev->clear_warning_msg ();
2434 char *ret = dbev->set_filter (filter_str);
2435 return ret;
2436}
2437
2438// Get the current filter setting for the view
2439char *
2440dbeGetFilterStr (int dbevindex)
2441{
2442 DbeView *dbev = dbeSession->getView (dbevindex);
2443 if (dbev == NULL)
2444 abort ();
2445 char *ret = dbev->get_filter ();
2446 return ret;
2447}
2448
2449// Update a filters for a single experiment
2450// Returns true if any filter->set_pattern() returns true,
2451// implying rereading the data is needed (i.e., a filter changed)
2452//
2453bool
2454dbeUpdateFilters (int dbevindex, Vector<bool> *selected, Vector<char *> *pattern_str)
2455{
2456 DbeView *dbev = dbeSession->getView (dbevindex);
2457 if (dbev == NULL)
2458 abort ();
2459 dbev->clear_error_msg ();
2460 dbev->clear_warning_msg ();
2461
2462 // Get index of first selected experiment
2463 int size = selected->size ();
2464 int nselexp = -1;
2465 for (int index = 0; index < size; index++)
2466 {
2467 if (selected->fetch (index) == true)
2468 {
2469 nselexp = index;
2470 break;
2471 }
2472 }
2473 if (nselexp == -1) // No experiment selected
2474 return false;
2475
2476 bool ret = false;
2477 for (int j = 0; j < size; j++)
2478 {
2479 if (selected->fetch (j) == false)
2480 continue;
2481 bool error;
2482 if (dbev->set_pattern (j, pattern_str, &error))
2483 ret = true;
2484 }
2485 dbev->update_advanced_filter ();
2486 return ret;
2487}
2488
2489char *
2490dbeComposeFilterClause (int dbevindex, int type, int subtype, Vector<int> *selections)
2491{
2492 DbeView *dbev = dbeSession->getView (dbevindex);
2493 if (dbev == NULL)
2494 abort ();
2495 // ask the cached data to generate the string
2496 Hist_data *data;
2497 switch (type)
2498 {
2499 case DSP_FUNCTION:
2500 data = dbev->func_data;
2501 break;
2502 case DSP_DLAYOUT:
2503 data = dbev->dlay_data;
2504 break;
2505 case DSP_DATAOBJ:
2506 data = dbev->dobj_data;
2507 break;
2508 case DSP_MEMOBJ:
2509 case DSP_INDXOBJ:
2510 data = dbev->get_indxobj_data (subtype);
2511 break;
2512 case DSP_LINE:
2513 data = dbev->line_data;
2514 break;
2515 case DSP_PC:
2516 data = dbev->pc_data;
2517 break;
2518 case DSP_SOURCE:
2519 data = dbev->src_data;
2520 break;
2521 case DSP_DISASM:
2522 data = dbev->dis_data;
2523 break;
2524 case DSP_IOACTIVITY:
2525 data = dbev->iofile_data;
2526 break;
2527 case DSP_IOVFD:
2528 data = dbev->iovfd_data;
2529 break;
2530 case DSP_IOCALLSTACK:
2531 data = dbev->iocs_data;
2532 break;
2533 case DSP_HEAPCALLSTACK:
2534 data = dbev->heapcs_data;
2535 break;
2536 default:
2537 return NULL;
2538 }
2539 if (data == NULL)
2540 return NULL;
2541
2542 // Get array of object indices, and compose filter string
2543 Vector<uint64_t> *obj_ids = data->get_object_indices (selections);
2544 if (obj_ids == NULL || obj_ids->size () == 0)
2545 return NULL;
2546
2547 uint64_t sel;
2548 int index;
2549 int found = 0;
2550 char buf[128];
2551 StringBuilder sb;
2552 sb.append ('(');
2553 switch (type)
2554 {
2555 case DSP_LINE:
2556 case DSP_PC:
2557 case DSP_SOURCE:
2558 case DSP_DISASM:
2559 case DSP_FUNCTION:
2560 sb.append (NTXT ("LEAF IN "));
2561 break;
2562 case DSP_MEMOBJ:
2563 case DSP_INDXOBJ:
2564 sb.append (dbeSession->getIndexSpaceName (subtype));
2565 sb.append (NTXT (" IN "));
2566 break;
2567 }
2568 Vec_loop (uint64_t, obj_ids, index, sel)
2569 {
2570 if (found == 0)
2571 {
2572 found = 1;
2573 sb.append ('(');
2574 }
2575 else
2576 sb.append (NTXT (", "));
2577 snprintf (buf, sizeof (buf), NTXT ("%llu"), (long long) sel);
2578 sb.append (buf);
2579 }
2580 if (found == 1)
2581 sb.append (')');
2582
2583 switch (type)
2584 {
2585 case DSP_DLAYOUT:
2586 case DSP_DATAOBJ:
2587 sb.append (NTXT (" SOME IN DOBJ"));
2588 break;
2589 }
2590 sb.append (')');
2591 return sb.toString ();
2592}
2593
2594//
2595// Get load object states
2596//
2597Vector<void *> *
2598dbeGetLoadObjectList (int dbevindex)
2599{
2600 DbeView *dbev = dbeSession->getView (dbevindex);
2601 if (dbev == NULL)
2602 abort ();
2603 Vector<LoadObject*> *lobjs = dbeSession->get_text_segments ();
2604 int size = lobjs->size ();
2605
2606 // Initialize Java boolean array
2607 Vector<char *> *names = new Vector<char *>(size);
2608 Vector<int> *states = new Vector<int>(size);
2609 Vector<int> *indices = new Vector<int>(size);
2610 Vector<char *> *paths = new Vector<char *>(size);
2611 Vector<int> *isJava = new Vector<int>(size);
2612
2613 // Get load object states
2614 int index;
2615 LoadObject *lo;
2616 char *lo_name;
2617
2618 // lobjectsNoJava is a trimmed list of indices provided to front-end skipping the Java
2619 // classes. lobjectsNoJava preserves the mapping of the index into the complete lobjs
2620 // vector. What front-end sees as lobj[i] is really lobj[lobjectsNoJava[i]];
2621
2622 // This list is constructed every time GetLoadObjectList() or GetLoadObjectState() is
2623 // called. Possibility of further optimization by making it more persistent.
2624 // Only consumer of this list is dbeSetLoadObjectState
2625 int new_index = 0;
2626 if (dbev->lobjectsNoJava == NULL)
2627 dbev->lobjectsNoJava = new Vector<int>(1);
2628 else
2629 dbev->lobjectsNoJava->reset ();
2630
2631 Vec_loop (LoadObject*, lobjs, index, lo)
2632 {
2633 // Set 0, 1, or 2 for show/hide/api
2634 enum LibExpand expand = dbev->get_lo_expand (lo->seg_idx);
2635
2636 lo_name = lo->get_name ();
2637 if (lo_name != NULL)
2638 {
2639 size_t len = strlen (lo_name);
2640 if (len > 7 && streq (lo_name + len - 7, NTXT (".class>")))
2641 isJava->store (new_index, 1);
2642 else
2643 isJava->store (new_index, 0);
2644 }
2645 else
2646 isJava->store (new_index, 0);
2647 dbev->lobjectsNoJava->append (index);
2648
2649 names->store (new_index, dbe_sprintf (NTXT ("%s"), lo_name));
2650 states->store (new_index, (int) expand);
2651 indices->store (new_index, (int) lo->seg_idx);
2652 paths->store (new_index, dbe_sprintf (NTXT ("%s"), lo->get_pathname ()));
2653 new_index++;
2654 }
2655 Vector<void*> *res = new Vector<void*>(5);
2656 res->store (0, names);
2657 res->store (1, states);
2658 res->store (2, indices);
2659 res->store (3, paths);
2660 res->store (4, isJava);
2661 delete lobjs;
2662 return res;
2663}
2664
2665Vector<int> *
2666dbeGetLoadObjectState (int dbevindex)
2667{
2668 DbeView *dbev = dbeSession->getView (dbevindex);
2669 if (dbev == NULL)
2670 abort ();
2671 Vector<LoadObject*> *lobjs = dbeSession->get_text_segments ();
2672 int size = lobjs->size ();
2673
2674 // Initialize Java boolean array
2675 Vector<int> *states = new Vector<int>(size);
2676 char *lo_name;
2677
2678 // lobjectsNoJava is a trimmed list of indices provided to front-end skipping the Java
2679 // classes. lobjectsNoJava preserves the mapping of the index into the complete lobjs
2680 // vector. What front-end sees as lobj[i] is really lobj[lobjectsNoJava[i]];
2681
2682 // This list is constructed every time GetLoadObjectList() or GetLoadObjectState() is
2683 // called. Possibility of further optimization by making it more persistent.
2684 // Only consumer of this list is dbeSetLoadObjectState
2685 int new_index = 0;
2686 if (dbev->lobjectsNoJava == NULL)
2687 dbev->lobjectsNoJava = new Vector<int>(1);
2688 else
2689 dbev->lobjectsNoJava->reset ();
2690
2691 // Get load object states
2692 int index;
2693 LoadObject *lo;
2694
2695 Vec_loop (LoadObject*, lobjs, index, lo)
2696 {
2697 // Set 0, 1, or 2 for show/hide/api
2698 lo_name = lo->get_name ();
2699 if (lo_name != NULL)
2700 {
2701 size_t len = strlen (lo_name);
2702 if (len > 7 && streq (lo_name + len - 7, NTXT (".class>")))
2703 continue;
2704 }
2705 else
2706 dbev->lobjectsNoJava->append (index);
2707
2708 enum LibExpand expand = dbev->get_lo_expand (lo->seg_idx);
2709 states->store (new_index, (int) expand);
2710 new_index++;
2711 }
2712 delete lobjs;
2713 return states;
2714}
2715
2716// Set load object states
2717void
2718dbeSetLoadObjectState (int dbevindex, Vector<int> *selected)
2719{
2720 DbeView *dbev = dbeSession->getView (dbevindex);
2721 if (dbev == NULL)
2722 abort ();
2723 Vector<LoadObject*> *lobjs = dbeSession->get_text_segments ();
2724
2725 int index;
2726 bool changed = false;
2727
2728 LoadObject *lo;
2729 int new_index = 0;
2730 dbev->setShowAll ();
2731 Vec_loop (LoadObject*, lobjs, index, lo)
2732 {
2733 if (dbev->lobjectsNoJava != NULL)
2734 {
2735 // This loadobject is a java class and was skipped
2736 if (dbev->lobjectsNoJava->fetch (new_index) != index)
2737 continue;
2738 }
2739 // Get array of settings
2740 enum LibExpand expand = (enum LibExpand) selected->fetch (new_index);
2741 if (expand == LIBEX_HIDE)
2742 {
2743 dbev->resetShowAll ();
2744 dbeSession->set_lib_visibility_used ();
2745 }
2746 changed = changed | dbev->set_libexpand (lo->get_pathname (), expand);
2747 new_index++;
2748 }
2749 delete lobjs;
2750 if (changed == true)
2751 {
2752 dbev->setShowHideChanged ();
2753 dbev->update_lo_expands ();
2754 }
2755
2756 return;
2757}
2758
2759// Reset load object states
2760void
2761dbeSetLoadObjectDefaults (int dbevindex)
2762{
2763 DbeView *dbev = dbeSession->getView (dbevindex);
2764 if (dbev == NULL)
2765 abort ();
2766 dbev->set_libdefaults ();
2767}
2768
2769// Get Machine model
2770Vector<char*>*
2771dbeGetCPUVerMachineModel (int dbevindex)
2772{
2773 Vector<char*>* table = new Vector<char*>();
2774 DbeView *dbev = dbeSession->getView (dbevindex);
2775 char * mach_model = dbev->get_settings ()->get_machinemodel ();
2776 if (mach_model != NULL)
2777 {
2778 table->append (mach_model);
2779 return table;
2780 }
2781 int grsize = dbeSession->expGroups->size ();
2782 for (int j = 0; j < grsize; j++)
2783 {
2784 ExpGroup *gr = dbeSession->expGroups->fetch (j);
2785 Vector<Experiment*> *exps = gr->exps;
2786 for (int i = 0, sz = exps->size (); i < sz; i++)
2787 {
2788 Experiment *exp = exps->fetch (i);
2789 char *model = exp->machinemodel;
2790 if (model != NULL)
2791 table->append (dbe_strdup (model));
2792 }
2793 }
2794 return table;
2795}
2796
2797// automatically load machine model if applicable
2798void
2799dbeDetectLoadMachineModel (int dbevindex)
2800{
2801 if (dbeSession->is_datamode_available ())
2802 {
2803 char *model = dbeGetMachineModel ();
2804 if (model == NULL)
2805 {
2806 Vector<char*>* models = dbeGetCPUVerMachineModel (dbevindex);
2807 char * machineModel = NTXT ("generic");
2808 if (models->size () > 0)
2809 {
2810 machineModel = models->get (0);
2811 for (int i = 1; i < models->size (); i++)
2812 {
2813 if (strncmp (models->get (i), machineModel, strlen (machineModel)) == 0)
2814 {
2815 machineModel = NTXT ("generic");
2816 break;
2817 }
2818 }
2819 dbeLoadMachineModel (machineModel);
2820 }
2821 delete models;
2822 }
2823 }
2824}
2825
2826// Managing Memory Objects
2827char *
2828dbeDefineMemObj (char *name, char *index_expr, char *machinemodel,
2829 char *sdesc, char *ldesc)
2830{
2831 return MemorySpace::mobj_define (name, index_expr, machinemodel, sdesc, ldesc);
2832}
2833
2834char *
2835dbeDeleteMemObj (char *name)
2836{
2837 return MemorySpace::mobj_delete (name);
2838}
2839
2840Vector<void*> *
2841dbeGetMemObjects (int /*dbevindex*/)
2842{
2843 Vector<void*> *res = MemorySpace::getMemObjects ();
2844 return res;
2845}
2846
2847// Managing machine model
2848char *
2849dbeLoadMachineModel (char *name)
2850{
2851 return dbeSession->load_mach_model (name);
2852}
2853
2854char *
2855dbeGetMachineModel ()
2856{
2857 return dbeSession->get_mach_model ();
2858}
2859
2860Vector <char *> *
2861dbeListMachineModels ()
2862{
2863 return dbeSession->list_mach_models ();
2864}
2865
2866// Managing Index Objects
2867char *
2868dbeDefineIndxObj (char *name, char *index_expr, char *sdesc, char *ldesc)
2869{
2870 return dbeSession->indxobj_define (name, NULL, index_expr, sdesc, ldesc);
2871}
2872
2873Vector<void*> *
2874dbeGetIndxObjDescriptions (int /*dbevindex*/)
2875{
2876 Vector<void*> *res = dbeSession->getIndxObjDescriptions ();
2877 return res;
2878}
2879
2880Vector<void*> *
2881dbeGetCustomIndxObjects (int /*dbevindex*/)
2882{
2883 Vector<void*> *res = dbeSession->getCustomIndxObjects ();
2884 return res;
2885}
2886
2887void
2888dbeSetSelObj (int dbevindex, Obj sel_obj_or_ind, int type, int subtype)
2889{
2890 DbeView *dbev = dbeSession->getView (dbevindex);
2891 if (dbev == NULL)
2892 abort ();
2893 Histable *sel_obj;
2894 Hist_data *data;
2895 int sel_ind = (int) sel_obj_or_ind;
2896
2897 switch (type)
2898 {
2899 case DSP_FUNCTION:
2900 data = dbev->func_data;
2901 break;
2902 case DSP_LINE:
2903 data = dbev->line_data;
2904 break;
2905 case DSP_PC:
2906 data = dbev->pc_data;
2907 break;
2908 case DSP_CALLER:
2909 data = dbev->callers;
2910 break;
2911 case DSP_CALLEE:
2912 data = dbev->callees;
2913 break;
2914 case DSP_SOURCE:
2915 data = dbev->src_data;
2916 break;
2917 case DSP_DISASM:
2918 data = dbev->dis_data;
2919 break;
2920 case DSP_DLAYOUT:
2921 data = dbev->dlay_data;
2922 if (data == NULL)
2923 {
2924 dbev->sel_binctx = NULL;
2925 return;
2926 }
2927 if (sel_ind >= 0 && sel_ind < dbev->dlay_data->size ())
2928 dbev->sel_dobj = dbev->dlay_data->fetch (sel_ind)->obj;
2929 return;
2930 case DSP_DATAOBJ:
2931 data = dbev->dobj_data;
2932 if (data == NULL)
2933 {
2934 dbev->sel_binctx = NULL;
2935 return;
2936 }
2937 if (sel_ind >= 0 && sel_ind < dbev->dobj_data->size ())
2938 dbev->sel_dobj = dbev->dobj_data->fetch (sel_ind)->obj;
2939 return;
2940 case DSP_MEMOBJ:
2941 case DSP_INDXOBJ:
2942 dbev->set_indxobj_sel (subtype, sel_ind);
2943 sel_obj = dbev->get_indxobj_sel (subtype);
2944 if (sel_obj && sel_obj->get_type () == Histable::INDEXOBJ)
2945 dbev->set_sel_obj (((IndexObject*) sel_obj)->get_obj ());
2946 return;
2947 case DSP_SOURCE_V2:
2948 case DSP_DISASM_V2:
2949 case DSP_TIMELINE:
2950 case DSP_LEAKLIST:
2951 case DSP_RACES:
2952 case DSP_DEADLOCKS:
2953 case DSP_DUALSOURCE:
2954 case DSP_SOURCE_DISASM:
2955 case DSP_IOACTIVITY:
2956 case DSP_IOVFD:
2957 case DSP_IOCALLSTACK:
2958 case DSP_HEAPCALLSTACK:
2959 case DSP_MINICALLER:
2960 dbev->set_sel_obj ((Histable *) sel_obj_or_ind);
2961 return;
2962 default:
2963 // abort();
2964 return;
2965 }
2966 if (type != DSP_SOURCE && type != DSP_DISASM && type != DSP_SOURCE_V2
2967 && type != DSP_DISASM_V2)
2968 dbev->sel_binctx = NULL;
2969
2970 if (data == NULL || data->get_status () != Hist_data::SUCCESS
2971 || sel_ind >= data->size ())
2972 return;
2973
2974 if (sel_ind >= 0 && sel_ind < data->size ())
2975 dbev->set_sel_obj (data->fetch (sel_ind)->obj);
2976}
2977
2978void
2979dbeSetSelObjV2 (int dbevindex, uint64_t id)
2980{
2981 DbeView *dbev = dbeSession->getView (dbevindex);
2982 if (dbev == NULL)
2983 abort ();
2984 dbev->set_sel_obj (dbeSession->findObjectById (id));
2985}
2986
2987Obj
2988dbeGetSelObj (int dbevindex, int type, int subtype)
2989{
2990 DbeView *dbev = dbeSession->getView (dbevindex);
2991 Histable *sel_obj = NULL;
2992 switch (type)
2993 {
2994 case DSP_FUNCTION:
2995 sel_obj = dbev->get_sel_obj (Histable::FUNCTION);
2996 break;
2997 case DSP_LINE:
2998 case DSP_SOURCE:
2999 case DSP_SOURCE_V2:
3000 sel_obj = dbev->get_sel_obj (Histable::LINE);
3001 break;
3002 case DSP_PC:
3003 case DSP_DISASM:
3004 case DSP_DISASM_V2:
3005 sel_obj = dbev->get_sel_obj (Histable::INSTR);
3006 break;
3007 case DSP_SRC_FILE:
3008 sel_obj = dbev->get_sel_obj (Histable::SOURCEFILE);
3009 break;
3010 case DSP_DATAOBJ:
3011 case DSP_DLAYOUT:
3012 if (dbev->sel_dobj)
3013 sel_obj = dbev->sel_dobj->convertto (Histable::DOBJECT);
3014 break;
3015 case DSP_MEMOBJ:
3016 case DSP_INDXOBJ:
3017 sel_obj = dbev->get_indxobj_sel (subtype);
3018 break;
3019 default:
3020 abort ();
3021 }
3022 Dprintf (DEBUG_DBE, NTXT ("### dbeGetSelObj: Dbe.cc:%d %s (%d) returns %s\n"),
3023 __LINE__, dsp_type_to_string (type), type, sel_obj ? sel_obj->dump () : "NULL");
3024 return (Obj) sel_obj;
3025}
3026
3027Obj
3028dbeConvertSelObj (Obj obj, int type)
3029{
3030 Histable *sel_obj = (Histable *) obj;
3031 Dprintf (DEBUG_DBE, NTXT ("### dbeConvertSelObj: Dbe.cc:%d %s (%d) sel_obj=%s\n"),
3032 __LINE__, dsp_type_to_string (type), type, sel_obj ? sel_obj->dump ()
3033 : "NULL");
3034 if (sel_obj == NULL)
3035 return (Obj) NULL;
3036 switch (type)
3037 {
3038 case DSP_FUNCTION:
3039 return (Obj) sel_obj->convertto (Histable::FUNCTION);
3040 case DSP_LINE:
3041 return (Obj) sel_obj->convertto (Histable::LINE);
3042 case DSP_SOURCE:
3043 case DSP_SOURCE_V2:
3044 {
3045 SourceFile* srcCtx = NULL;
3046 if (sel_obj->get_type () == Histable::INSTR)
3047 {
3048 DbeInstr* dbei = (DbeInstr *) sel_obj;
3049 srcCtx = (SourceFile*) dbei->convertto (Histable::SOURCEFILE);
3050 }
3051 else if (sel_obj->get_type () == Histable::LINE)
3052 {
3053 DbeLine * dbel = (DbeLine *) sel_obj;
3054 srcCtx = dbel->sourceFile;
3055 }
3056 sel_obj = sel_obj->convertto (Histable::LINE, srcCtx);
3057 Dprintf (DEBUG_DBE, NTXT ("### dbeConvertSelObj: Dbe.cc:%d %s (%d) returns %s\n"),
3058 __LINE__, dsp_type_to_string (type), type, sel_obj ? sel_obj->dump () : "NULL");
3059 if (sel_obj && sel_obj->get_type () == Histable::LINE)
3060 {
3061 DbeLine * dbel = (DbeLine *) sel_obj;
3062 return (Obj) dbel->dbeline_base;
3063 }
3064 return (Obj) sel_obj->convertto (Histable::LINE, srcCtx);
3065 }
3066 case DSP_PC:
3067 case DSP_DISASM:
3068 case DSP_DISASM_V2:
3069 return (Obj) sel_obj->convertto (Histable::INSTR);
3070 case DSP_SRC_FILE:
3071 return (Obj) sel_obj->convertto (Histable::SOURCEFILE);
3072 default:
3073 abort ();
3074 }
3075 return (Obj) NULL;
3076}
3077
3078uint64_t
3079dbeGetSelObjV2 (int dbevindex, char *typeStr)
3080{
3081 DbeView *dbev = dbeSession->getView (dbevindex);
3082 if (dbev == NULL)
3083 abort ();
3084 Histable *obj = NULL;
3085 if (typeStr != NULL)
3086 {
3087 if (streq (typeStr, NTXT ("FUNCTION")))
3088 obj = dbev->get_sel_obj (Histable::FUNCTION);
3089 else if (streq (typeStr, NTXT ("INSTRUCTION")))
3090 obj = dbev->get_sel_obj (Histable::INSTR);
3091 else if (streq (typeStr, NTXT ("SOURCELINE")))
3092 obj = dbev->get_sel_obj (Histable::LINE);
3093 else if (streq (typeStr, NTXT ("SOURCEFILE")))
3094 obj = dbev->get_sel_obj (Histable::SOURCEFILE);
3095 }
3096 Dprintf (DEBUG_DBE, NTXT ("### dbeGetSelObjV2: Dbe.cc:%d %s returns %s\n"),
3097 __LINE__, STR (typeStr), obj ? obj->dump () : "NULL");
3098 return obj != NULL ? obj->id : (uint64_t) - 1;
3099}
3100
3101Vector<uint64_t> *
3102dbeGetSelObjsIO (int dbevindex, Vector<uint64_t> *ids, int type)
3103{
3104 DbeView *dbev = dbeSession->getView (dbevindex);
3105 if (dbev == NULL)
3106 abort ();
3107 Vector<uint64_t> *res = NULL;
3108 Vector<uint64_t> *result = new Vector<uint64_t>();
3109 for (int i = 0; i < ids->size (); i++)
3110 {
3111 res = dbeGetSelObjIO (dbevindex, ids->fetch (i), type);
3112 if (res != NULL)
3113 {
3114 result->addAll (res);
3115 delete res;
3116 }
3117 }
3118 return result;
3119}
3120
3121Vector<uint64_t> *
3122dbeGetSelObjIO (int dbevindex, uint64_t id, int type)
3123{
3124 DbeView *dbev = dbeSession->getView (dbevindex);
3125 if (dbev == NULL)
3126 abort ();
3127 Histable *obj = NULL;
3128 Vector<uint64_t> *res = NULL;
3129 int size = 0;
3130 switch (type)
3131 {
3132 case DSP_IOACTIVITY:
3133 obj = dbev->get_sel_obj_io (id, Histable::IOACTFILE);
3134 size = obj != NULL ? ((FileData*) obj)->getVirtualFds ()->size () : 0;
3135 if (size)
3136 {
3137 res = new Vector<uint64_t>();
3138 Vector<int64_t> *vfds = ((FileData*) obj)->getVirtualFds ();
3139 for (int i = 0; i < size; i++)
3140 res->append (vfds->fetch (i));
3141 }
3142 break;
3143 case DSP_IOVFD:
3144 obj = dbev->get_sel_obj_io (id, Histable::IOACTVFD);
3145 if (obj)
3146 {
3147 res = new Vector<uint64_t>();
3148 res->append (obj->id);
3149 }
3150 break;
3151 case DSP_IOCALLSTACK:
3152 obj = dbev->get_sel_obj_io (id, Histable::IOCALLSTACK);
3153 if (obj)
3154 {
3155 Vector<Obj> *instrs = dbeGetStackPCs (dbevindex, obj->id);
3156 if (instrs == NULL)
3157 return NULL;
3158 int stsize = instrs->size ();
3159 res = new Vector<uint64_t>(stsize);
3160 for (int i = 0; i < stsize; i++)
3161 {
3162 Histable *objFunc = (DbeInstr*) (instrs->fetch (i));
3163 if (objFunc->get_type () != Histable::LINE)
3164 {
3165 objFunc = objFunc->convertto (Histable::FUNCTION);
3166 res->insert (0, objFunc->id);
3167 }
3168 }
3169 delete instrs;
3170 }
3171 break;
3172 default:
3173 break;
3174 }
3175 return res;
3176}
3177
3178uint64_t
3179dbeGetSelObjHeapTimestamp (int dbevindex, uint64_t id)
3180{
3181 DbeView *dbev = dbeSession->getView (dbevindex);
3182 if (dbev == NULL)
3183 abort ();
3184 Histable *obj = NULL;
3185 uint64_t res = 0;
3186 Vector<uint64_t> *peakStackIds;
3187 Vector<hrtime_t> *peakTimestamps;
3188
3189 // Find and return the timestamp for the peak
3190 bool foundPeakId = false;
3191 if (id > 0)
3192 {
3193 obj = dbev->get_sel_obj_heap (0);
3194 if (obj != NULL)
3195 {
3196 peakStackIds = ((HeapData*) obj)->getPeakStackIds ();
3197 peakTimestamps = ((HeapData*) obj)->getPeakTimestamps ();
3198 for (int i = 0; i < peakStackIds->size (); i++)
3199 {
3200 if (id == peakStackIds->fetch (i))
3201 {
3202 res = peakTimestamps->fetch (i);
3203 foundPeakId = true;
3204 break;
3205 }
3206 }
3207 }
3208 }
3209
3210 // Return the first timestamp for the peak
3211 // if the callstack id is zero or it
3212 // doesn't match with the peak stack id
3213 if (id == 0 || !foundPeakId)
3214 {
3215 obj = dbev->get_sel_obj_heap (0);
3216 res = obj != NULL ? ((HeapData*) obj)->getPeakTimestamps ()->fetch (0) : 0;
3217 }
3218 return res;
3219}
3220
3221int
3222dbeGetSelObjHeapUserExpId (int dbevindex, uint64_t id)
3223{
3224 DbeView *dbev = dbeSession->getView (dbevindex);
3225 if (dbev == NULL)
3226 abort ();
3227 Histable *obj = NULL;
3228 int res = 0;
3229 obj = dbev->get_sel_obj_heap (id);
3230 res = obj != NULL ? ((HeapData*) obj)->getUserExpId () : 0;
3231 return res;
3232}
3233
3234//
3235// Get index of selected function/object
3236//
3237int
3238dbeGetSelIndex (int dbevindex, Obj sel_obj, int type, int subtype)
3239{
3240 Hist_data *data;
3241 DbeView *dbev = dbeSession->getView (dbevindex);
3242 if (dbev == NULL)
3243 abort ();
3244 switch (type)
3245 {
3246 case DSP_FUNCTION:
3247 data = dbev->func_data;
3248 break;
3249 case DSP_LINE:
3250 data = dbev->line_data;
3251 break;
3252 case DSP_PC:
3253 data = dbev->pc_data;
3254 break;
3255 case DSP_SOURCE:
3256 case DSP_SOURCE_V2:
3257 data = dbev->src_data;
3258 break;
3259 case DSP_DISASM:
3260 case DSP_DISASM_V2:
3261 data = dbev->dis_data;
3262 break;
3263 case DSP_DLAYOUT:
3264 data = dbev->dlay_data;
3265 break;
3266 case DSP_DATAOBJ:
3267 data = dbev->dobj_data;
3268 break;
3269 case DSP_MEMOBJ:
3270 case DSP_INDXOBJ:
3271 data = dbev->get_indxobj_data (subtype);
3272 break;
3273 default:
3274 data = NULL;
3275 break;
3276 }
3277 if (data == NULL || data->get_status () != Hist_data::SUCCESS)
3278 return -1;
3279
3280 Histable *chk_obj = (Histable *) sel_obj;
3281 Vector<Hist_data::HistItem*> *histItems = data->get_hist_items ();
3282 if (histItems == NULL || chk_obj == NULL)
3283 return -1;
3284 for (int i = 0, sz = histItems->size (); i < sz; i++)
3285 {
3286 if (histItems->get (i)->obj == chk_obj)
3287 return i;
3288 if (histItems->get (i)->obj == NULL)
3289 continue;
3290 if (histItems->get (i)->obj->get_type () == Histable::LINE
3291 && chk_obj->get_type () == Histable::LINE)
3292 {
3293 if (((DbeLine*) histItems->get (i)->obj)->convertto (Histable::FUNCTION)
3294 == ((DbeLine*) chk_obj)->convertto (Histable::FUNCTION)
3295 && ((DbeLine*) histItems->get (i)->obj)->lineno
3296 == ((DbeLine*) chk_obj)->lineno)
3297 return i;
3298 }
3299 else if (histItems->get (i)->obj->get_type () == Histable::INSTR
3300 && chk_obj->get_type () == Histable::INSTR)
3301 if (((DbeInstr*) histItems->get (i)->obj)->convertto (Histable::FUNCTION)
3302 == ((DbeInstr*) chk_obj)->convertto (Histable::FUNCTION)
3303 && ((DbeInstr*) histItems->get (i)->obj)->addr
3304 == ((DbeInstr*) chk_obj)->addr)
3305 return i;
3306 }
3307
3308 Histable *chk_obj1 = NULL;
3309 switch (type)
3310 {
3311 case DSP_FUNCTION:
3312 chk_obj1 = chk_obj->convertto (Histable::FUNCTION);
3313 break;
3314 case DSP_LINE:
3315 case DSP_SOURCE:
3316 case DSP_SOURCE_V2:
3317 chk_obj1 = chk_obj->convertto (Histable::LINE);
3318 break;
3319 case DSP_PC:
3320 case DSP_DISASM:
3321 case DSP_DISASM_V2:
3322 chk_obj1 = chk_obj->convertto (Histable::INSTR);
3323 break;
3324 }
3325 if (chk_obj1 && chk_obj != chk_obj1)
3326 for (int i = 0, sz = histItems->size (); i < sz; i++)
3327 if (histItems->get (i)->obj == chk_obj1)
3328 return i;
3329
3330 if (type == DSP_LINE)
3331 {
3332 for (int i = 0, sz = histItems->size (); i < sz; i++)
3333 if (histItems->get (i)->obj != NULL
3334 && chk_obj->convertto (Histable::FUNCTION)
3335 == histItems->get (i)->obj->convertto (Histable::FUNCTION))
3336 return i;
3337 }
3338 else if (type == DSP_PC)
3339 {
3340 for (int i = 0, sz = histItems->size (); i < sz; i++)
3341 if (histItems->get (i)->obj != NULL
3342 && (histItems->get (i)->obj)->convertto (Histable::FUNCTION)
3343 == (chk_obj)->convertto (Histable::FUNCTION)
3344 && ((DbeLine*) histItems->get (i)->obj->convertto (Histable::LINE))->lineno
3345 == ((DbeLine*) chk_obj->convertto (Histable::LINE))->lineno)
3346 return i;
3347 for (int i = 0, sz = histItems->size (); i < sz; i++)
3348 if (histItems->get (i)->obj != NULL
3349 && (histItems->get (i)->obj)->convertto (Histable::FUNCTION)
3350 == (chk_obj)->convertto (Histable::FUNCTION))
3351 return i;
3352 }
3353
3354 // If we clicked on an mfunction line in the called-by call mini in user mode for omp
3355 // we might not find that function in func data
3356 if (dbev->isOmpDisMode () && type == DSP_FUNCTION)
3357 {
3358 int p = dbeGetSelIndex (dbevindex, sel_obj, DSP_DISASM, subtype);
3359 if (p != -1)
3360 return p;
3361 }
3362 return -1;
3363}
3364
3365// Print data
3366//
3367char *
3368dbePrintData (int dbevindex, int type, int subtype, char *printer,
3369 char *fname, FILE *outfile)
3370{
3371 Histable *current_obj;
3372 Function *func;
3373 Module *module;
3374 MetricList *mlist_orig;
3375 bool header;
3376 Print_params params;
3377 DbeView *dbev = dbeSession->getView (dbevindex);
3378 if (dbev == NULL)
3379 abort ();
3380
3381 // Set print parameters
3382 if (printer != NULL)
3383 {
3384 params.dest = DEST_PRINTER;
3385 params.name = printer;
3386 }
3387 else if (outfile != NULL)
3388 {
3389 params.dest = DEST_OPEN_FILE;
3390 params.openfile = outfile;
3391 params.name = NULL;
3392 }
3393 else
3394 {
3395 params.dest = DEST_FILE;
3396 params.name = fname;
3397 if (*(params.name) == '\0')
3398 {
3399 free (params.name);
3400 return dbe_strdup (GTXT ("Please enter the name of the file to which to print"));
3401 }
3402 }
3403 params.ncopies = 1;
3404 if (outfile != NULL)
3405 header = false;
3406 else
3407 header = !(type == DSP_SOURCE || type == DSP_SOURCE_V2 || type == DSP_DISASM_V2);
3408
3409 params.header = header;
3410
3411 // figure out what kind of metrics to use
3412 if (type == DSP_SELF || type == DSP_CALLER || type == DSP_CALLEE
3413 || type == DSP_CALLTREE)
3414 mlist_orig = dbev->get_metric_list (MET_CALL);
3415 else if (type == DSP_DATAOBJ || type == DSP_DLAYOUT || type == DSP_MEMOBJ)
3416 mlist_orig = dbev->get_metric_list (MET_DATA);
3417 else if (type == DSP_INDXOBJ)
3418 mlist_orig = dbev->get_metric_list (MET_INDX);
3419 else if (type == DSP_IOACTIVITY || type == DSP_IOVFD
3420 || type == DSP_IOCALLSTACK)
3421 mlist_orig = dbev->get_metric_list (MET_IO);
3422 else if (type == DSP_HEAPCALLSTACK)
3423 mlist_orig = dbev->get_metric_list (MET_HEAP);
3424 else
3425 mlist_orig = dbev->get_metric_list (MET_NORMAL);
3426
3427 // make a compacted version of the input list
3428 // the list will either be moved to the generated data,
3429 // or freed below if it wasn't needed
3430 MetricList *mlist = new MetricList (mlist_orig);
3431 Hist_data *data = NULL;
3432 er_print_common_display *cd = NULL;
3433 int ix;
3434 // Set data
3435 switch (type)
3436 {
3437 case DSP_FUNCTION:
3438 case DSP_LINE:
3439 case DSP_PC:
3440 case DSP_MEMOBJ:
3441 case DSP_INDXOBJ:
3442 case DSP_DATAOBJ:
3443 data = dbev->get_hist_data (mlist,
3444 ((type == DSP_FUNCTION) ? Histable::FUNCTION :
3445 (type == DSP_LINE) ? Histable::LINE :
3446 (type == DSP_PC) ? Histable::INSTR :
3447 (type == DSP_INDXOBJ) ? Histable::INDEXOBJ :
3448 (type == DSP_MEMOBJ) ? Histable::MEMOBJ
3449 : Histable::DOBJECT),
3450 subtype, Hist_data::ALL);
3451 if (data->get_status () != Hist_data::SUCCESS)
3452 return DbeView::status_str (DbeView::DBEVIEW_NO_DATA); // no strdup()
3453
3454 cd = new er_print_histogram (dbev, data, mlist, MODE_LIST,
3455 dbev->get_limit (),
3456 mlist->get_sort_name (), NULL, true, true);
3457 break;
3458 case DSP_DLAYOUT:
3459 {
3460 data = dbev->get_hist_data (mlist, Histable::DOBJECT, 0, Hist_data::LAYOUT);
3461 if (data->get_status () != Hist_data::SUCCESS)
3462 return DbeView::status_str (DbeView::DBEVIEW_NO_DATA); // no strdup()
3463 cd = new er_print_histogram (dbev, data, mlist, MODE_ANNOTATED,
3464 dbev->get_thresh_dis (),
3465 mlist->get_sort_name (), NULL, true, true);
3466 break;
3467 }
3468
3469 // source and disassembly
3470 case DSP_SOURCE:
3471 case DSP_DISASM:
3472 case DSP_SOURCE_V2:
3473 case DSP_DISASM_V2:
3474 if (dbev->sel_obj == NULL)
3475 return NULL;
3476 current_obj = dbev->sel_obj->convertto (Histable::FUNCTION);
3477 if (current_obj->get_type () != Histable::FUNCTION)
3478 return dbe_strdup (GTXT ("Not a real function; no source or disassembly available."));
3479 func = (Function*) current_obj->convertto (Histable::FUNCTION);
3480 if (func->flags & FUNC_FLAG_SIMULATED)
3481 return dbe_strdup (GTXT ("Not a real function; no source or disassembly available."));
3482 if (func->get_name () == NULL)
3483 return dbe_strdup (GTXT ("Source location not recorded in experiment"));
3484 module = func->module;
3485 if (module == NULL || module->get_name () == NULL)
3486 return dbe_strdup (GTXT ("Object name not recorded in experiment"));
3487 ix = module->loadobject->seg_idx;
3488 if (dbev->get_lo_expand (ix) == LIBEX_HIDE)
3489 return dbe_strdup (GTXT ("No source or disassembly available for hidden object"));
3490 cd = new er_print_histogram (dbev, dbev->func_data, mlist, MODE_ANNOTATED,
3491 type == DSP_DISASM || type == DSP_DISASM_V2,
3492 mlist->get_sort_name (),
3493 func, false, false);
3494 break;
3495
3496 // callers-callees
3497 case DSP_SELF:
3498 case DSP_CALLER:
3499 case DSP_CALLEE:
3500 if (dbev->sel_obj == NULL)
3501 return NULL;
3502 current_obj = dbev->sel_obj->convertto (Histable::FUNCTION);
3503 cd = new er_print_histogram (dbev, dbev->func_data, mlist, MODE_GPROF, 1,
3504 mlist->get_sort_name (), current_obj,
3505 false, false);
3506 break;
3507
3508 // statistics; this won't use the metric list copied above, so delete it
3509 case DSP_STATIS:
3510 cd = new er_print_experiment (dbev, 0, dbeSession->nexps () - 1,
3511 true, true, true, true, false);
3512 delete mlist;
3513 break;
3514 case DSP_EXP:
3515 cd = new er_print_experiment (dbev, 0, dbeSession->nexps () - 1,
3516 true, true, false, false, false);
3517 delete mlist;
3518 break;
3519 case DSP_LEAKLIST:
3520 cd = new er_print_leaklist (dbev, true, true, dbev->get_limit ());
3521 delete mlist;
3522 break;
3523 case DSP_HEAPCALLSTACK:
3524 cd = new er_print_heapactivity (dbev, Histable::HEAPCALLSTACK, false,
3525 dbev->get_limit ());
3526 delete mlist;
3527 break;
3528 case DSP_IOACTIVITY:
3529 cd = new er_print_ioactivity (dbev, Histable::IOACTFILE, false,
3530 dbev->get_limit ());
3531 delete mlist;
3532 break;
3533 case DSP_IOVFD:
3534 cd = new er_print_ioactivity (dbev, Histable::IOACTVFD, false,
3535 dbev->get_limit ());
3536 delete mlist;
3537 break;
3538
3539 // the io call stack
3540 case DSP_IOCALLSTACK:
3541 cd = new er_print_ioactivity (dbev, Histable::IOCALLSTACK, false,
3542 dbev->get_limit ());
3543 delete mlist;
3544 break;
3545
3546 // some unknown panel -- return an error string
3547 default:
3548 delete mlist;
3549 return dbe_strdup (GTXT ("Print not available"));
3550 }
3551
3552 // Start printing
3553 char *buf = NULL;
3554
3555 // first open the file/device/whatever
3556 if (cd->open (&params) == 0)
3557 {
3558 // now call the actual print routine
3559 cd->data_dump ();
3560 if (params.dest == DEST_PRINTER)
3561 {
3562 if (streq ((char *) params.name, NTXT ("-")))
3563 {
3564 // Special case - return report to the GUI
3565 int maxbytes = 2 * 1024 * 1024; // IPC large buffer limit
3566 char *report = cd->get_output (maxbytes);
3567 delete data;
3568 delete cd;
3569 return report; // TEMPORARY
3570 }
3571 }
3572 if (cd->print_output () == false)
3573 buf = dbe_sprintf (NTXT ("%s: %s"),
3574 GTXT ("Unable to submit print request to"),
3575 params.name);
3576 }
3577 else
3578 // if unable to set up the print, return an error
3579 buf = dbe_sprintf (NTXT ("%s: %s"),
3580 GTXT ("Unable to open file"),
3581 params.name);
3582
3583 // dbe_free((void *) params.name); XXX when should this happen?
3584 if (data)
3585 if (data->isViewOwned () == false)
3586 delete data;
3587 delete cd;
3588 return buf;
3589}
3590
3591// Set limit for print data
3592//
3593char *
3594dbeSetPrintLimit (int dbevindex, int limit)
3595{
3596 DbeView *dbev = dbeSession->getView (dbevindex);
3597 if (dbev == NULL)
3598 abort ();
3599 return (dbev->set_limit (limit));
3600}
3601
3602// get limit for print data
3603int
3604dbeGetPrintLimit (int dbevindex)
3605{
3606 DbeView *dbev = dbeSession->getView (dbevindex);
3607 if (dbev == NULL)
3608 abort ();
3609 int limit = dbev->get_limit ();
3610 return limit;
3611}
3612
3613// set printmode for data
3614char *
3615dbeSetPrintMode (int dbevindex, char * pmode)
3616{
3617 DbeView *dbev = dbeSession->getView (dbevindex);
3618 if (dbev == NULL)
3619 abort ();
3620 char *r = dbev->set_printmode (pmode);
3621 return r;
3622}
3623
3624// get printmode for data
3625int
3626dbeGetPrintMode (int dbevindex)
3627{
3628 DbeView *dbev = dbeSession->getView (dbevindex);
3629 if (dbev == NULL)
3630 abort ();
3631 return (dbev->get_printmode ());
3632}
3633
3634// get printmode for data
3635char *
3636dbeGetPrintModeString (int dbevindex)
3637{
3638 DbeView *dbev = dbeSession->getView (dbevindex);
3639 if (dbev == NULL)
3640 abort ();
3641 return ( dbev->get_printmode_str ());
3642}
3643
3644// get print delimiter for csv data
3645char
3646dbeGetPrintDelim (int dbevindex)
3647{
3648 DbeView *dbev = dbeSession->getView (dbevindex);
3649 if (dbev == NULL)
3650 abort ();
3651 return (dbev->get_printdelimiter ());
3652}
3653
3654// Set Source/Object/Load-Object file names
3655static void
3656set_file_names (Function *func, char *names[3])
3657{
3658 Module *module = func->module;
3659 LoadObject *loadobject = module->loadobject;
3660 if (loadobject == NULL)
3661 loadobject = dbeSession->get_Unknown_LoadObject ();
3662 free (names[0]);
3663 free (names[1]);
3664 free (names[2]);
3665 SourceFile *sf = func->getDefSrc ();
3666 char *src_name = sf->dbeFile->get_location_info ();
3667 DbeFile *df = module->dbeFile;
3668 if (df == NULL || (df->filetype & DbeFile::F_JAVACLASS) == 0)
3669 df = module->loadobject->dbeFile;
3670 char *lo_name = df->get_location_info ();
3671 char *dot_o_name = lo_name;
3672 if (module->dot_o_file)
3673 dot_o_name = module->dot_o_file->dbeFile->get_location_info ();
3674 names[0] = dbe_sprintf (NTXT ("%s: %s"), GTXT ("Source File"), src_name);
3675 names[1] = dbe_sprintf (NTXT ("%s: %s"), GTXT ("Object File"), dot_o_name);
3676 names[2] = dbe_sprintf (NTXT ("%s: %s"), GTXT ("Load Object"), lo_name);
3677}
3678
3679// dbeSetFuncData
3680// Master function to generate all Tab data for the analyzer
3681// Returns the index of the selected item in the specified list
3682//
3683// After calling it to set up, the Analyzer calls dbeGetFuncList
3684// to format the generated data and return the table
3685// Most of the data is destined for a JTable
3686//
3687int
3688dbeSetFuncData (int dbevindex, Obj sel_obj, int type, int subtype)
3689{
3690 MetricList *_mlist;
3691 Histable *org_obj;
3692 Hist_data *data = NULL;
3693 int index, sel_index;
3694 Function *func;
3695 char *name;
3696 int ix;
3697
3698 DbeView *dbev = dbeSession->getView (dbevindex);
3699 sel_index = -1;
3700 dbev->resetOmpDisMode ();
3701 dbev->error_msg = dbev->warning_msg = NULL;
3702
3703 // get metric list, make a compact duplicate
3704 _mlist = dbev->get_metric_list (MET_NORMAL);
3705 MetricList *mlist = new MetricList (_mlist);
3706
3707 // Remove old function/obj list data & Get new function/obj list data
3708 org_obj = (Histable *) sel_obj;
3709
3710 // Figure out which "function" data is being asked for, i.e.,
3711 // which of the analyzer displays is asking for data
3712 switch (type)
3713 {
3714 // the various tables: functions, lines, PCs, DataObjects, IndexObjects
3715 case DSP_FUNCTION:
3716 case DSP_LINE:
3717 case DSP_PC:
3718 case DSP_DATAOBJ:
3719 case DSP_MEMOBJ:
3720 case DSP_INDXOBJ:
3721 switch (type)
3722 {
3723 case DSP_FUNCTION:
3724 if (dbev->func_data)
3725 delete dbev->func_data;
3726 dbev->func_data = data = dbev->get_hist_data (mlist,
3727 Histable::FUNCTION, subtype, Hist_data::ALL);
3728 break;
3729 case DSP_LINE:
3730 if (dbev->line_data)
3731 delete dbev->line_data;
3732 dbev->line_data = data = dbev->get_hist_data (mlist,
3733 Histable::LINE, subtype, Hist_data::ALL);
3734 break;
3735 case DSP_PC:
3736 if (dbev->pc_data)
3737 delete dbev->pc_data;
3738 dbev->pc_data = data = dbev->get_hist_data (mlist,
3739 Histable::INSTR, subtype, Hist_data::ALL);
3740 break;
3741 case DSP_DATAOBJ:
3742 if (dbev->dobj_data)
3743 delete dbev->dobj_data;
3744 mlist = dbev->get_metric_list (MET_DATA);
3745 dbev->dobj_data = data = dbev->get_hist_data (mlist,
3746 Histable::DOBJECT, subtype, Hist_data::ALL);
3747 break;
3748 case DSP_MEMOBJ:
3749 mlist = dbev->get_metric_list (MET_DATA);
3750 data = dbev->get_hist_data (mlist, Histable::MEMOBJ, subtype,
3751 Hist_data::ALL);
3752 dbev->indx_data->store (subtype, data);
3753 break;
3754 case DSP_INDXOBJ:
3755 mlist = dbev->get_metric_list (MET_INDX);
3756 data = dbev->get_hist_data (mlist, Histable::INDEXOBJ, subtype,
3757 Hist_data::ALL);
3758 dbev->indx_data->store (subtype, data);
3759 break;
3760 default:
3761 break;
3762 }
3763
3764 // Set the selection of row item
3765 if (data->get_status () == Hist_data::SUCCESS)
3766 {
3767 // otherwise, look for it
3768 sel_index = -1;
3769 if (org_obj)
3770 {
3771 Hist_data::HistItem *hi;
3772 Vec_loop (Hist_data::HistItem*, data->get_hist_items (), index, hi)
3773 {
3774 if (hi->obj == org_obj)
3775 {
3776 sel_index = index;
3777 break;
3778 }
3779 }
3780 if (sel_index == -1 && (type == DSP_LINE || type == DSP_PC))
3781 {
3782 Vec_loop (Hist_data::HistItem*, data->get_hist_items (), index, hi)
3783 {
3784 name = hi->obj->get_name ();
3785 if (strcmp (name, NTXT ("<Total>")) &&
3786 strcmp (name, GTXT ("<Unknown>")))
3787 {
3788 int done = 0;
3789 switch (type)
3790 {
3791 case DSP_LINE:
3792 if (org_obj->convertto (Histable::FUNCTION)
3793 == hi->obj->convertto (Histable::FUNCTION))
3794 {
3795 sel_index = index;
3796 done = 1;
3797 }
3798 break;
3799 case DSP_PC:
3800 if (hi->obj->convertto (Histable::FUNCTION)
3801 == org_obj->convertto (Histable::FUNCTION)
3802 && ((DbeLine*) hi->obj->convertto (Histable::LINE))->lineno
3803 == ((DbeLine*) org_obj->convertto (Histable::LINE))->lineno)
3804 {
3805 sel_index = index;
3806 done = 1;
3807 }
3808 break;
3809 }
3810 if (done)
3811 break;
3812 }
3813 }
3814 }
3815 if (sel_index == -1 && type == DSP_PC)
3816 {
3817 Vec_loop (Hist_data::HistItem*, data->get_hist_items (), index, hi)
3818 {
3819 name = hi->obj->get_name ();
3820 if (strcmp (name, NTXT ("<Total>")) &&
3821 strcmp (name, GTXT ("<Unknown>")))
3822 {
3823 int done = 0;
3824 if (hi->obj->convertto (Histable::FUNCTION) ==
3825 org_obj->convertto (Histable::FUNCTION))
3826 {
3827 sel_index = index;
3828 done = 1;
3829 }
3830 if (done)
3831 break;
3832 }
3833 }
3834 }
3835 }
3836 if (sel_index == -1)
3837 {
3838 Hist_data::HistItem *hi;
3839 Vec_loop (Hist_data::HistItem*, data->get_hist_items (), index, hi)
3840 {
3841 name = hi->obj->get_name ();
3842 if (strcmp (name, NTXT ("<Total>")) &&
3843 strcmp (name, GTXT ("<Unknown>")))
3844 {
3845 sel_index = index;
3846 break;
3847 }
3848 }
3849 }
3850 }
3851 else
3852 dbev->error_msg = DbeView::status_str (DbeView::DBEVIEW_NO_DATA);
3853 return sel_index;
3854 // the end of the code for the regular tables
3855
3856 // Data Layout
3857 case DSP_DLAYOUT:
3858 if (dbev->dlay_data)
3859 delete dbev->dlay_data;
3860 dbev->marks->reset ();
3861 mlist = dbev->get_metric_list (MET_DATA);
3862
3863 // initial dobj list ...
3864 data = dbev->get_hist_data (mlist, Histable::DOBJECT, subtype,
3865 Hist_data::LAYOUT);
3866 // .. provides metric data for layout
3867 dbev->dlay_data = data = dbev->get_data_space ()->get_layout_data (data,
3868 dbev->marks, dbev->get_thresh_dis ());
3869 if (data->get_status () != Hist_data::SUCCESS)
3870 dbev->error_msg = DbeView::status_str (DbeView::DBEVIEW_NO_DATA);
3871 return sel_index;
3872
3873 // Source or disassembly
3874 case DSP_SOURCE_V2:
3875 case DSP_DISASM_V2:
3876 case DSP_SOURCE:
3877 case DSP_DISASM:
3878 {
3879 if (org_obj == NULL)
3880 {
3881 dbev->error_msg = DbeView::status_str (DbeView::DBEVIEW_NO_SEL_OBJ);
3882 return sel_index;
3883 }
3884 if (org_obj->get_type () != Histable::FUNCTION)
3885 {
3886 dbev->error_msg = dbe_strdup (
3887 GTXT ("Not a real function; no source or disassembly available."));
3888 return sel_index;
3889 }
3890 func = (Function *) org_obj;
3891 if (func->flags & FUNC_FLAG_SIMULATED)
3892 {
3893 dbev->error_msg = dbe_strdup (
3894 GTXT ("Not a real function; no source or disassembly available."));
3895 return sel_index;
3896 }
3897 if (func->get_name () == NULL)
3898 {
3899 dbev->error_msg = dbe_strdup (
3900 GTXT ("Source location not recorded in experiment"));
3901 return sel_index;
3902 }
3903 Module *module = func->module;
3904 if ((module == NULL) || (module->get_name () == NULL))
3905 {
3906 dbev->error_msg = dbe_strdup (
3907 GTXT ("Object name not recorded in experiment"));
3908 return sel_index;
3909 }
3910 ix = module->loadobject->seg_idx;
3911 if (dbev->get_lo_expand (ix) == LIBEX_HIDE)
3912 {
3913 dbev->error_msg = dbe_strdup (
3914 GTXT ("No source or disassembly available for hidden object"));
3915 return sel_index;
3916 }
3917
3918 if ((type == DSP_DISASM || type == DSP_DISASM_V2)
3919 && dbev->get_view_mode () == VMODE_USER
3920 && dbeSession->is_omp_available ())
3921 dbev->setOmpDisMode ();
3922
3923 dbev->marks->reset ();
3924 SourceFile *srcContext = NULL;
3925 switch (dbev->sel_obj->get_type ())
3926 {
3927 case Histable::FUNCTION:
3928 {
3929 Function *f = (Function *) dbev->sel_obj;
3930 srcContext = f->getDefSrc ();
3931 dbev->sel_binctx = f->module;
3932 break;
3933 }
3934 case Histable::LINE:
3935 {
3936 DbeLine *dl = (DbeLine *) dbev->sel_obj;
3937 srcContext = dl->sourceFile;
3938 Function *f = dl->func;
3939 if (f)
3940 dbev->sel_binctx = f;
3941 break;
3942 }
3943 case Histable::INSTR:
3944 {
3945 Function *f = (Function *) dbev->sel_obj->convertto (Histable::FUNCTION);
3946 if (f)
3947 {
3948 dbev->sel_binctx = f;
3949 srcContext = f->getDefSrc ();
3950 }
3951 break;
3952 }
3953 default:
3954 break;
3955 }
3956 mlist = dbev->get_metric_list (MET_SRCDIS);
3957
3958 // for source and disassembly the name needs to be invisible,
3959 // but that's handled in the module code
3960 if (type == DSP_SOURCE)
3961 {
3962 if (dbev->src_data)
3963 delete dbev->src_data;
3964
3965 // func_data computation needed for get_totals
3966 if (dbev->func_data == NULL)
3967 dbev->func_data = data = dbev->get_hist_data (mlist,
3968 Histable::FUNCTION, subtype, Hist_data::ALL);
3969 dbev->marks2dsrc->reset ();
3970 dbev->marks2dsrc_inc->reset ();
3971 data = dbev->src_data = module->get_data (dbev, mlist,
3972 Histable::LINE, dbev->func_data->get_totals ()->value,
3973 srcContext, func, dbev->marks,
3974 dbev->get_thresh_src (), dbev->get_src_compcom (),
3975 dbev->get_src_visible (), dbev->get_hex_visible (),
3976 false, false, dbev->marks2dsrc, dbev->marks2dsrc_inc);
3977 set_file_names (func, dbev->names_src);
3978 if (srcContext)
3979 {
3980 free (dbev->names_src[0]);
3981 dbev->names_src[0] = dbe_sprintf (GTXT ("Source File: %s"),
3982 srcContext->dbeFile->get_location_info ());
3983 }
3984 Obj obj = (Obj) func->convertto (Histable::LINE, srcContext);
3985 sel_index = dbeGetSelIndex (dbevindex, obj, type, subtype);
3986 }
3987 else
3988 { /* type == DSP_DISASM */
3989 if (dbev->dis_data)
3990 delete dbev->dis_data;
3991
3992 // func_data computation needed for get_totals
3993 if (dbev->func_data == NULL)
3994 dbev->func_data = data = dbev->get_hist_data (mlist,
3995 Histable::FUNCTION, subtype, Hist_data::ALL);
3996 dbev->marks2ddis->reset ();
3997 dbev->marks2ddis_inc->reset ();
3998 data = dbev->dis_data = module->get_data (dbev, mlist,
3999 Histable::INSTR, dbev->func_data->get_totals ()->value,
4000 srcContext, func, dbev->marks, dbev->get_thresh_dis (),
4001 dbev->get_dis_compcom (), dbev->get_src_visible (),
4002 dbev->get_hex_visible (), dbev->get_func_scope (),
4003 false, dbev->marks2ddis, dbev->marks2ddis_inc);
4004 set_file_names (func, dbev->names_dis);
4005 if (srcContext)
4006 {
4007 free (dbev->names_dis[0]);
4008 dbev->names_dis[0] = dbe_sprintf (GTXT ("Source File: %s"),
4009 srcContext->dbeFile->get_location_info ());
4010 }
4011 Obj obj = (Obj) func->convertto (Histable::INSTR);
4012 sel_index = dbeGetSelIndex (dbevindex, obj, type, subtype);
4013 }
4014 return sel_index;
4015 }
4016
4017 // the three cases for caller-callee
4018 case DSP_SELF:
4019 case DSP_CALLER:
4020 case DSP_CALLEE:
4021 if (org_obj == NULL)
4022 {
4023 dbev->error_msg = DbeView::status_str (DbeView::DBEVIEW_NO_SEL_OBJ);
4024 return sel_index;
4025 }
4026
4027 // Caller data
4028 if (dbev->callers)
4029 delete dbev->callers;
4030 mlist = dbev->get_metric_list (MET_CALL);
4031 dbev->callers = dbev->get_hist_data (mlist, Histable::FUNCTION, subtype,
4032 Hist_data::CALLERS, org_obj);
4033 if (dbev->callers->get_status () != Hist_data::SUCCESS)
4034 {
4035 dbev->error_msg = DbeView::status_str (DbeView::DBEVIEW_NO_DATA);
4036 return sel_index;
4037 }
4038
4039 // Callee data
4040 if (dbev->callees)
4041 delete dbev->callees;
4042 dbev->callees = dbev->get_hist_data (mlist, Histable::FUNCTION, subtype,
4043 Hist_data::CALLEES, org_obj);
4044 if (dbev->callees->get_status () != Hist_data::SUCCESS)
4045 {
4046 dbev->error_msg = DbeView::status_str (DbeView::DBEVIEW_NO_DATA);
4047 return sel_index;
4048 }
4049
4050 // Center Function item
4051 if (dbev->fitem_data)
4052 delete dbev->fitem_data;
4053 dbev->fitem_data = dbev->get_hist_data (mlist, Histable::FUNCTION, subtype,
4054 Hist_data::SELF, org_obj);
4055 if (dbev->fitem_data->get_status () != Hist_data::SUCCESS)
4056 {
4057 dbev->error_msg = DbeView::status_str (DbeView::DBEVIEW_NO_DATA);
4058 return sel_index;
4059 }
4060 return sel_index;
4061 default:
4062 abort ();
4063 }
4064 return sel_index;
4065}
4066
4067Vector<void*>*
4068dbeGetTotals (int dbevindex, int dsptype, int subtype)
4069{
4070 DbeView *dbev = dbeSession->getView (dbevindex);
4071 MetricList *mlist = dbev->get_metric_list (dsptype, subtype);
4072 Hist_data *data = dbev->get_hist_data (mlist, Histable::FUNCTION, 0,
4073 Hist_data::ALL);
4074 Hist_data::HistItem *totals = data->get_totals ();
4075 Vector<void*> *tbl = new Vector<void*>(mlist->size ());
4076 for (long i = 0, sz = mlist->size (); i < sz; i++)
4077 {
4078 Metric *m = mlist->get (i);
4079 switch (m->get_vtype ())
4080 {
4081 case VT_DOUBLE:
4082 {
4083 Vector<double> *lst = new Vector<double>(1);
4084 lst->append (totals->value[i].d);
4085 tbl->append (lst);
4086 break;
4087 }
4088 case VT_INT:
4089 {
4090 Vector<int> *lst = new Vector<int>(1);
4091 lst->append (totals->value[i].i);
4092 tbl->append (lst);
4093 break;
4094 }
4095 case VT_LLONG:
4096 case VT_ULLONG:
4097 case VT_ADDRESS:
4098 {
4099 Vector<long long> *lst = new Vector<long long>(1);
4100 lst->append (totals->value[i].ll);
4101 tbl->append (lst);
4102 break;
4103 }
4104 case VT_LABEL:
4105 {
4106 Vector<char *> *lst = new Vector<char *>(1);
4107 Histable::NameFormat nfmt = dbev->get_name_format ();
4108 lst->append (dbe_strdup (totals->obj->get_name (nfmt)));
4109 tbl->append (lst);
4110 break;
4111 }
4112 default:
4113 abort ();
4114 }
4115 }
4116 Vector<void*> *res = new Vector<void*>(2);
4117 res->append (dbeGetMetricList (mlist));
4118 res->append (tbl);
4119 return res;
4120}
4121
4122Vector<void*>*
4123dbeGetHotMarks (int dbevindex, int type)
4124{
4125 Vector<void*>* table = new Vector<void*>(2);
4126 Vector<int>* table0 = new Vector<int> ();
4127 Vector<int>* table1 = new Vector<int> ();
4128 DbeView *dbev = dbeSession->getView (dbevindex);
4129 if (dbev == NULL)
4130 return NULL;
4131
4132 switch (type)
4133 {
4134 case DSP_SOURCE:
4135 case DSP_SOURCE_V2:
4136 for (int i = 0; i < dbev->marks2dsrc->size (); i++)
4137 {
4138 table0->append (dbev->marks2dsrc->fetch (i).index1);
4139 table1->append (dbev->marks2dsrc->fetch (i).index2);
4140 }
4141 break;
4142 case DSP_DISASM:
4143 case DSP_DISASM_V2:
4144 for (int i = 0; i < dbev->marks2ddis->size (); i++)
4145 {
4146 table0->append (dbev->marks2ddis->fetch (i).index1);
4147 table1->append (dbev->marks2ddis->fetch (i).index2);
4148 }
4149 break;
4150 default:
4151 break;
4152 }
4153 table->store (0, table0);
4154 table->store (1, table1);
4155 return table;
4156}
4157
4158Vector<void*>*
4159dbeGetHotMarksInc (int dbevindex, int type)
4160{
4161 Vector<void*>* table = new Vector<void*>(2);
4162 Vector<int>* table0 = new Vector<int> ();
4163 Vector<int>* table1 = new Vector<int> ();
4164 DbeView *dbev = dbeSession->getView (dbevindex);
4165 if (dbev == NULL)
4166 return NULL;
4167
4168 switch (type)
4169 {
4170 case DSP_SOURCE:
4171 case DSP_SOURCE_V2:
4172 for (int i = 0; i < dbev->marks2dsrc_inc->size (); i++)
4173 {
4174 table0->append (dbev->marks2dsrc_inc->fetch (i).index1);
4175 table1->append (dbev->marks2dsrc_inc->fetch (i).index2);
4176 }
4177 break;
4178 case DSP_DISASM:
4179 case DSP_DISASM_V2:
4180 for (int i = 0; i < dbev->marks2ddis_inc->size (); i++)
4181 {
4182 table0->append (dbev->marks2ddis_inc->fetch (i).index1);
4183 table1->append (dbev->marks2ddis_inc->fetch (i).index2);
4184 }
4185 break;
4186 default:
4187 break;
4188 }
4189 table->store (0, table0);
4190 table->store (1, table1);
4191 return table;
4192}
4193
4194Vector<void*>*
4195dbeGetSummaryHotMarks (int dbevindex, Vector<Obj> *sel_objs, int type)
4196{
4197 Vector<void*>* table = new Vector<void*>(2);
4198 Vector<int>* table0 = new Vector<int> ();
4199 Vector<int>* table1 = new Vector<int> ();
4200 DbeView *dbev = dbeSession->getView (dbevindex);
4201 if (dbev == NULL)
4202 return NULL;
4203 if (sel_objs == NULL || sel_objs->size () == 0)
4204 return NULL;
4205
4206 Hist_data *data;
4207 Vector<int_pair_t> *marks2d;
4208 Vector<int_pair_t>* marks2d_inc;
4209 switch (type)
4210 {
4211 case DSP_SOURCE:
4212 case DSP_SOURCE_V2:
4213 data = dbev->src_data;
4214 marks2d = dbev->marks2dsrc;
4215 marks2d_inc = dbev->marks2dsrc_inc;
4216 break;
4217 case DSP_DISASM:
4218 case DSP_DISASM_V2:
4219 data = dbev->dis_data;
4220 marks2d = dbev->marks2ddis;
4221 marks2d_inc = dbev->marks2ddis_inc;
4222 break;
4223 default:
4224 data = NULL;
4225 marks2d = NULL;
4226 marks2d_inc = NULL;
4227 break;
4228 }
4229 if (data == NULL || data->get_status () != Hist_data::SUCCESS
4230 || marks2d_inc == NULL || marks2d == NULL)
4231 return NULL;
4232
4233 MetricList *orig_mlist = data->get_metric_list ();
4234 MetricList *prop_mlist = new MetricList (dbev->get_metric_ref (MET_NORMAL));
4235 if (prop_mlist && dbev->comparingExperiments ())
4236 prop_mlist = dbev->get_compare_mlist (prop_mlist, 0);
4237 Metric *mitem;
4238 int index, index2;
4239 index2 = 0;
4240 Vec_loop (Metric*, prop_mlist->get_items (), index, mitem)
4241 {
4242 if (mitem->get_subtype () == Metric::STATIC)
4243 continue;
4244
4245 for (int i = 0; i < marks2d_inc->size (); i++)
4246 {
4247 int found = 0;
4248 for (int j = 0; j < sel_objs->size (); j++)
4249 {
4250 int sel_index = (int) sel_objs->fetch (j);
4251 int marked_index = marks2d_inc->fetch (i).index1;
4252 if (sel_index == marked_index)
4253 {
4254 found = 1;
4255 break;
4256 }
4257 }
4258 if (!found)
4259 continue;
4260 int mindex = marks2d_inc->fetch (i).index2;
4261 Metric *orig_metric = orig_mlist->get_items ()->fetch (mindex);
4262 if (orig_metric->get_id () == mitem->get_id ()
4263 && mitem->get_subtype () == Metric::INCLUSIVE)
4264 {
4265 table0->append (index2);
4266 table1->append (1);
4267 }
4268 }
4269
4270 for (int i = 0; i < marks2d->size (); i++)
4271 {
4272 int found = 0;
4273 for (int j = 0; j < sel_objs->size (); j++)
4274 {
4275 int sel_index = (int) sel_objs->fetch (j);
4276 int marked_index = marks2d->fetch (i).index1;
4277 if (sel_index == marked_index)
4278 {
4279 found = 1;
4280 break;
4281 }
4282 }
4283 if (!found)
4284 continue;
4285 int mindex = marks2d->fetch (i).index2;
4286 Metric *orig_metric = orig_mlist->get_items ()->fetch (mindex);
4287 if (orig_metric->get_id () == mitem->get_id ()
4288 && mitem->get_subtype () == Metric::EXCLUSIVE)
4289 {
4290 table0->append (index2);
4291 table1->append (0);
4292 }
4293 }
4294 if (!(mitem->get_subtype () == Metric::EXCLUSIVE
4295 || mitem->get_subtype () == Metric::DATASPACE))
4296 index2++;
4297 }
4298 table->store (0, table0);
4299 table->store (1, table1);
4300 return table;
4301}
4302
4303// Get a vector of function ids of data(begin, begin + length - 1)
4304// Currently only support source/disassembly view
4305Vector<uint64_t>*
4306dbeGetFuncId (int dbevindex, int type, int begin, int length)
4307{
4308 Vector<uint64_t>* table = new Vector<uint64_t > ();
4309 DbeView *dbev = dbeSession->getView (dbevindex);
4310 if (dbev == NULL)
4311 abort ();
4312
4313 Hist_data *data;
4314 Function* given_func = NULL;
4315 switch (type)
4316 {
4317 case DSP_SOURCE:
4318 case DSP_SOURCE_V2:
4319 data = dbev->src_data;
4320 break;
4321 case DSP_DISASM:
4322 case DSP_DISASM_V2:
4323 data = dbev->dis_data;
4324 break;
4325 default:
4326 data = NULL;
4327 abort ();
4328 }
4329
4330 if (data == NULL || data->get_status () != Hist_data::SUCCESS)
4331 return NULL;
4332
4333 if (begin < 0 || begin + length > data->size ())
4334 return NULL;
4335
4336 switch (type)
4337 {
4338 case DSP_SOURCE:
4339 case DSP_SOURCE_V2:
4340 case DSP_DISASM:
4341 case DSP_DISASM_V2:
4342 {
4343 for (int i = begin; i < begin + length; i++)
4344 {
4345 given_func = NULL;
4346 Histable * sel_obj = data->fetch (i)->obj;
4347 if (sel_obj != NULL)
4348 given_func = (Function*) (sel_obj)->convertto (Histable::FUNCTION, (Histable*) dbev);
4349 if (given_func == NULL)
4350 table->append (0);
4351 else
4352 table->append (given_func->id);
4353 }
4354 }
4355 break;
4356 default:
4357 abort ();
4358 }
4359 return table;
4360}
4361
4362Vector<void*>*
4363dbeGetFuncCallerInfo (int dbevindex, int type, Vector<int>* idxs, int groupId)
4364{
4365 Vector<void*>* data = new Vector<void*>();
4366 if (type == DSP_SOURCE_V2 || type == DSP_DISASM_V2)
4367 {
4368 Obj sel_func = dbeGetSelObj (dbevindex, DSP_FUNCTION, 0);
4369 if (sel_func == 0)
4370 return data;
4371 Vector<Obj> * cmpObjs = dbeGetComparableObjsV2 (dbevindex, sel_func, type);
4372 if (cmpObjs == NULL)
4373 return data;
4374 DbeView *dbev = dbeSession->getView (dbevindex);
4375 int mtype = MET_COMMON | COMPARE_BIT | ((groupId + 1) << GROUP_ID_SHIFT);
4376 MetricList *mlist = dbev->get_metric_list ((MetricType) (mtype & MTYPE_MASK),
4377 (mtype & COMPARE_BIT) != 0,
4378 mtype >> GROUP_ID_SHIFT);
4379 Histable *selObj = (Histable *) cmpObjs->fetch (groupId);
4380 int subtype = 0;
4381 Hist_data *hist_data = dbev->get_data (mlist, selObj, type, subtype);
4382 if (hist_data == NULL)
4383 return data;
4384 }
4385 for (int i = 0; i < idxs->size (); i++)
4386 data->append (dbeGetFuncCallerInfoById (dbevindex, type, idxs->fetch (i)));
4387 return data;
4388}
4389
4390//
4391// Get Table of Caller info:
4392// param: idx -- selected AT_FUNC row
4393// return: callsite_id, callsite_name (function: file: line)
4394Vector<void*>*
4395dbeGetFuncCallerInfoById (int dbevindex, int type, int idx)
4396{
4397 Vector<void*>* table = new Vector<void*>(3);
4398 Vector<uint64_t>* table0 = new Vector<uint64_t> ();
4399 Vector<int>* table1 = new Vector<int> ();
4400 Vector<char*>* table2 = new Vector<char*>();
4401
4402 DbeView *dbev = dbeSession->getView (dbevindex);
4403 if (dbev == NULL)
4404 abort ();
4405 Hist_data *data;
4406 Function* given_func = NULL;
4407 Vector<Histable*> *instr_info = NULL;
4408 switch (type)
4409 {
4410 case DSP_SOURCE:
4411 case DSP_SOURCE_V2:
4412 data = dbev->src_data;
4413 break;
4414 case DSP_DISASM:
4415 case DSP_DISASM_V2:
4416 data = dbev->dis_data;
4417 break;
4418 default:
4419 data = NULL;
4420 abort ();
4421 }
4422 if (data == NULL || data->get_status () != Hist_data::SUCCESS)
4423 return NULL;
4424
4425 if (idx < 0 || idx >= data->size ())
4426 return NULL;
4427 switch (type)
4428 {
4429 case DSP_SOURCE:
4430 case DSP_SOURCE_V2:
4431 case DSP_DISASM:
4432 case DSP_DISASM_V2:
4433 {
4434 Histable * sel_obj = data->fetch (idx)->obj;
4435 if (sel_obj == NULL)
4436 return NULL;
4437 given_func = (Function*) (sel_obj)->convertto (Histable::FUNCTION, (Histable*) dbev);
4438 if (given_func == NULL)
4439 return NULL;
4440 PathTree * ptree = dbev->get_path_tree ();
4441 if (ptree == NULL)
4442 return NULL;
4443 instr_info = ptree->get_clr_instr (given_func);
4444 DefaultMap<uint64_t, int> * line_seen = new DefaultMap<uint64_t, int>();
4445 for (int j = 0; j < ((Vector<Histable*>*)instr_info)->size (); j++)
4446 {
4447 Histable *instr = ((Vector<Histable*>*)instr_info)->fetch (j);
4448 Function *cur_func = NULL;
4449 if (instr->get_type () == Histable::INSTR)
4450 cur_func = ((DbeInstr*) instr)->func;
4451 else if (instr->get_type () == Histable::LINE)
4452 cur_func = ((DbeLine*) instr)->func;
4453 if (cur_func == NULL || (cur_func->flags & FUNC_FLAG_SIMULATED))
4454 continue; // skip functions like <Total>
4455 Histable* line;
4456 switch (type)
4457 {
4458 case DSP_SOURCE:
4459 case DSP_SOURCE_V2:
4460 if (cur_func != NULL)
4461 {
4462 SourceFile *sourceFile = cur_func->getDefSrc ();
4463 if (sourceFile == NULL ||
4464 (sourceFile->flags & SOURCE_FLAG_UNKNOWN) != 0)
4465 continue; // skip functions like <Function: %s, instructions without line numbers>
4466 }
4467 line = instr->convertto (Histable::LINE, NULL);
4468 break;
4469 case DSP_DISASM:
4470 case DSP_DISASM_V2:
4471 line = instr->convertto (Histable::INSTR, NULL);
4472 break;
4473 default:
4474 abort ();
4475 }
4476 uint64_t func_id = cur_func->id;
4477 uint64_t line_id = instr->id;
4478 int is_null = 0;
4479 int line_no = -1;
4480 switch (type)
4481 {
4482 case DSP_SOURCE:
4483 case DSP_SOURCE_V2:
4484 is_null = (((DbeLine*) line)->func == NULL) ? 1 : 0;
4485 if (is_null)
4486 ((DbeLine*) line)->func = cur_func;
4487 line_no = ((DbeLine*) line)->lineno;
4488 if (line_seen->get (line_id) == 0)
4489 {
4490 line_seen->put (line_id, 1);
4491 table0->append (func_id);
4492 table1->append (line_no);
4493 Histable::NameFormat nfmt = dbev->get_name_format ();
4494 table2->append (dbe_strdup (line->get_name (nfmt)));
4495 }
4496 if (is_null)
4497 ((DbeLine*) line)->func = NULL;
4498 break;
4499 case DSP_DISASM:
4500 case DSP_DISASM_V2:
4501 is_null = (((DbeInstr*) line)->func == NULL) ? 1 : 0;
4502 if (is_null)
4503 ((DbeInstr*) line)->func = cur_func;
4504 line_no = ((DbeInstr*) line)->addr;
4505 if (line_seen->get (line_id) == 0)
4506 {
4507 line_seen->put (line_id, 1);
4508 table0->append (func_id);
4509 table1->append (line_no);
4510 Histable::NameFormat nfmt = dbev->get_name_format ();
4511 table2->append (dbe_strdup (line->get_name (nfmt)));
4512 }
4513 if (is_null)
4514 ((DbeInstr*) line)->func = NULL;
4515 break;
4516 default:
4517 abort ();
4518 }
4519 }
4520 delete line_seen;
4521 delete instr_info;
4522 }
4523 break;
4524 default:
4525 abort ();
4526 }
4527 table->store (0, table0);
4528 table->store (1, table1);
4529 table->store (2, table2);
4530 return table;
4531}
4532
4533Vector<void*>*
4534dbeGetFuncCalleeInfo (int dbevindex, int type, Vector<int>* idxs, int groupId)
4535{
4536 Vector<void*>* data = new Vector<void*>();
4537 if (type == DSP_SOURCE_V2 || type == DSP_DISASM_V2)
4538 {
4539 Obj sel_func = dbeGetSelObj (dbevindex, DSP_FUNCTION, 0);
4540 if (sel_func == 0)
4541 return data;
4542 Vector<Obj> * cmpObjs = dbeGetComparableObjsV2 (dbevindex, sel_func, type);
4543 if (cmpObjs == NULL)
4544 return data;
4545 DbeView *dbev = dbeSession->getView (dbevindex);
4546 int mtype = MET_COMMON | COMPARE_BIT | ((groupId + 1) << GROUP_ID_SHIFT);
4547 MetricList *mlist = dbev->get_metric_list ((MetricType) (mtype & MTYPE_MASK),
4548 (mtype & COMPARE_BIT) != 0,
4549 mtype >> GROUP_ID_SHIFT);
4550 Histable *selObj = (Histable *) cmpObjs->fetch (groupId);
4551 int subtype = 0;
4552 Hist_data *hist_data = dbev->get_data (mlist, selObj, type, subtype);
4553 if (hist_data == NULL)
4554 return data;
4555 }
4556
4557 for (int i = 0; i < idxs->size (); i++)
4558 data->append (dbeGetFuncCalleeInfoById (dbevindex, type, idxs->fetch (i)));
4559 return data;
4560}
4561
4562//
4563// Get Table of Callee info:
4564// param: idx -- selected AT_FUNC row
4565// return: callsite_row, callee_id, callee_name
4566//
4567Vector<void*>*
4568dbeGetFuncCalleeInfoById (int dbevindex, int type, int idx)
4569{
4570 Vector<void*>* table = new Vector<void*>(3);
4571 Vector<int>* table0 = new Vector<int>();
4572 Vector<uint64_t>* table1 = new Vector<uint64_t > ();
4573 Vector<char*>* table2 = new Vector<char*>();
4574 DbeView *dbev = dbeSession->getView (dbevindex);
4575 if (dbev == NULL)
4576 abort ();
4577 Hist_data *data;
4578 Function* given_func = NULL;
4579 Vector<Histable*> *instr_info = NULL;
4580 Vector<void*> *func_info = NULL;
4581
4582 switch (type)
4583 {
4584 case DSP_SOURCE:
4585 case DSP_SOURCE_V2:
4586 data = dbev->src_data;
4587 break;
4588 case DSP_DISASM:
4589 case DSP_DISASM_V2:
4590 data = dbev->dis_data;
4591 break;
4592 default:
4593 data = NULL;
4594 abort ();
4595 }
4596 if (data == NULL || data->get_status () != Hist_data::SUCCESS)
4597 return NULL;
4598 if (idx < 0 || idx >= data->size ())
4599 return NULL;
4600 switch (type)
4601 {
4602 case DSP_SOURCE:
4603 case DSP_SOURCE_V2:
4604 case DSP_DISASM:
4605 case DSP_DISASM_V2:
4606 {
4607 Histable * sel_obj = data->fetch (idx)->obj;
4608 if (sel_obj == NULL)
4609 return NULL;
4610 given_func = (Function*) (sel_obj)->convertto (Histable::FUNCTION, (Histable*) dbev);
4611 if (given_func == NULL)
4612 return NULL;
4613 PathTree * ptree = dbev->get_path_tree ();
4614 if (ptree == NULL)
4615 return NULL;
4616 Vector<Histable*> *instrs = NULL;
4617 Vector<void*> *callee_instrs = ptree->get_cle_instr (given_func, instrs);
4618 func_info = new Vector<void*>();
4619 instr_info = new Vector<Histable*>();
4620 for (long a = 0, sz_a = callee_instrs ? callee_instrs->size () : 0; a < sz_a; a++)
4621 {
4622 Vector<Histable*> *temp = ((Vector<Vector<Histable*>*>*)callee_instrs)->get (a);
4623 DefaultMap<Function*, int> * func_seen = new DefaultMap<Function*, int>();
4624 Histable* instr0 = (Histable*) instrs->fetch (a);
4625 for (long b = 0, sz_b = temp ? temp->size () : 0; b < sz_b; b++)
4626 {
4627 Histable *instr = temp->get (b);
4628 if (instr->get_type () == Histable::INSTR)
4629 {
4630 Function* func1 = ((DbeInstr *) instr)->func;
4631 func_seen->put (func1, 1);
4632 }
4633 else if (instr->get_type () == Histable::LINE)
4634 {
4635 Function* func1 = ((DbeLine *) instr)->func;
4636 func_seen->put (func1, 1);
4637 }
4638 }
4639 Vector<Function*> *funcs = func_seen->keySet ();
4640 delete func_seen;
4641 if (funcs->size () > 0)
4642 {
4643 instr_info->append (instr0);
4644 func_info->append (funcs);
4645 }
4646 }
4647 delete instrs;
4648 destroy (callee_instrs);
4649
4650 DefaultMap<uint64_t, Vector<int>* > * instr_idxs = new DefaultMap<uint64_t, Vector<int>* >();
4651 DefaultMap<uint64_t, int> * func_idxs = new DefaultMap<uint64_t, int>();
4652 for (long j = 0, sz_j = instr_info ? instr_info->size () : 0; j < sz_j; j++)
4653 {
4654 Histable *instr = instr_info->get (j);
4655 Function *cur_func = NULL;
4656 if (instr->get_type () == Histable::INSTR)
4657 cur_func = ((DbeInstr*) instr)->func;
4658 else if (instr->get_type () == Histable::LINE)
4659 cur_func = ((DbeLine*) instr)->func;
4660 if (cur_func != NULL && (cur_func->flags & FUNC_FLAG_SIMULATED))
4661 continue; // skip functions like <Total>
4662 Histable* line;
4663 switch (type)
4664 {
4665 case DSP_SOURCE:
4666 case DSP_SOURCE_V2:
4667 if (cur_func != NULL)
4668 {
4669 SourceFile *sourceFile = cur_func->getDefSrc ();
4670 if (sourceFile == NULL ||
4671 (sourceFile->flags & SOURCE_FLAG_UNKNOWN) != 0)
4672 // skip functions like <Function: %s, instructions without line numbers>
4673 continue;
4674 }
4675 line = instr->convertto (Histable::LINE, NULL);
4676 if (type == DSP_SOURCE_V2)
4677 line = dbev->get_compare_obj (line);
4678 break;
4679 case DSP_DISASM:
4680 case DSP_DISASM_V2:
4681 line = instr;
4682 if (type == DSP_DISASM_V2)
4683 line = dbev->get_compare_obj (line);
4684 break;
4685 default:
4686 abort ();
4687 }
4688 if (func_idxs->get (line->id) == 0)
4689 {
4690 func_idxs->put (line->id, 1);
4691 Vector<int> *temp_idx = new Vector<int>();
4692 temp_idx->append (j);
4693 instr_idxs->put (line->id, temp_idx);
4694 }
4695 else
4696 {
4697 Vector<int> *temp_idx = instr_idxs->get (line->id);
4698 temp_idx->append (j);
4699 }
4700 }
4701 for (long i = 0; i < data->size (); i++)
4702 {
4703 Histable* line = data->fetch (i)->obj;
4704 if (line == NULL)
4705 continue;
4706 Vector<int> * instr_idx = instr_idxs->get (line->id);
4707 if (instr_idx == NULL)
4708 continue;
4709 for (long j = 0; j < instr_idx->size (); j++)
4710 {
4711 Vector<void*>* callee_funcs_vec = (Vector<void*>*)func_info;
4712 if (callee_funcs_vec->size () == 0)
4713 continue;
4714 Vector<Function*>* callee_funcs_value = (Vector<Function*>*)callee_funcs_vec->fetch (instr_idx->fetch (j));
4715 for (int k = 0; callee_funcs_value != NULL && k < callee_funcs_value->size (); k++)
4716 {
4717 uint64_t funcobj_id = ((Function*) callee_funcs_value->fetch (k))->id;
4718 int old_size = table0->size ();
4719 if (old_size > 0 && i == table0->fetch (old_size - 1)
4720 && funcobj_id == table1->fetch (old_size - 1))
4721 continue;
4722 table0->append (i);
4723 table1->append (funcobj_id);
4724 table2->append (dbe_strdup (((Function*) callee_funcs_value->fetch (k))->get_name ()));
4725 }
4726 }
4727 }
4728 delete instr_idxs;
4729 delete func_idxs;
4730 destroy (func_info);
4731 delete instr_info;
4732 }
4733 break;
4734 default:
4735 abort ();
4736 }
4737 table->store (0, table0);
4738 table->store (1, table1);
4739 table->store (2, table2);
4740 return table;
4741}
4742
4743//
4744// Get Table of Function List data with only total values
4745//
4746Vector<void*> *
4747dbeGetFuncListMini (int dbevindex, int type, int /*subtype*/)
4748{
4749 Hist_data *data;
4750 DbeView *dbev = dbeSession->getView (dbevindex);
4751 switch (type)
4752 {
4753 case DSP_FUNCTION:
4754 data = dbev->func_data;
4755 break;
4756 default:
4757 data = NULL;
4758 break;
4759 }
4760 if (data == NULL || data->get_status () != Hist_data::SUCCESS)
4761 return NULL;
4762
4763 MetricList *mlist = data->get_metric_list ();
4764
4765 // Get table size: count visible metrics
4766 int nvisible = 0;
4767 for (long i = 0, sz = mlist->size (); i < sz; i++)
4768 {
4769 Metric *m = mlist->get (i);
4770 if (m->is_visible () || m->is_tvisible () || m->is_pvisible ())
4771 nvisible++;
4772 }
4773 Vector<void*> *table = new Vector<void*>(nvisible + 1);
4774
4775 // Fill function list elements
4776 Hist_data::HistItem *totals = data->get_totals ();
4777 for (long i = 0, sz = mlist->size (); i < sz; i++)
4778 {
4779 Metric *m = mlist->get (i);
4780 if (!m->is_visible () && !m->is_tvisible () && !m->is_pvisible ())
4781 continue;
4782 TValue res;
4783 TValue *v = data->get_value (&res, i, totals);
4784 if ((m->get_visbits () & VAL_RATIO) != 0)
4785 {
4786 Vector<double> *col = new Vector<double>(1);
4787 double d = (v->tag != VT_LABEL) ? v->to_double () : 100.; // NaN
4788 col->append (d);
4789 table->append (col);
4790 continue;
4791 }
4792 switch (m->get_vtype ())
4793 {
4794 case VT_INT:
4795 {
4796 Vector<int> *col = new Vector<int>(1);
4797 col->append (v->i);
4798 table->append (col);
4799 break;
4800 }
4801 case VT_ADDRESS:
4802 case VT_ULLONG:
4803 case VT_LLONG:
4804 {
4805 Vector<long long> *col = new Vector<long long>(1);
4806 col->append (v->ll);
4807 table->append (col);
4808 break;
4809 }
4810 case VT_LABEL:
4811 {
4812 Vector<char *> *col = new Vector<char *>(1);
4813 col->append (dbe_strdup (v->l));
4814 table->append (col);
4815 break;
4816 }
4817 case VT_DOUBLE:
4818 default:
4819 {
4820 Vector<double> *col = new Vector<double>(1);
4821 col->append (v->d);
4822 table->append (col);
4823 break;
4824 }
4825 }
4826 }
4827 table->append (NULL);
4828 return table;
4829}
4830
4831// Get Table of Function List data
4832Vector<void*> *
4833dbeGetFuncList (int dbevindex, int type, int subtype)
4834{
4835 MetricList *mlist;
4836 Metric *mitem;
4837 int nitems, nvisible;
4838 int index, index2, nv;
4839 char *cell;
4840 Vector<int> *ji_list;
4841 Hist_data *data;
4842 Hist_data::HistItem *item;
4843
4844 DbeView *dbev = dbeSession->getView (dbevindex);
4845 if (dbev == NULL)
4846 abort ();
4847
4848 // fprintf(stderr, NTXT("XXX dbeGetFuncList, FuncListDisp_type = %d\n"), type);
4849 switch (type)
4850 {
4851 case DSP_FUNCTION:
4852 data = dbev->func_data;
4853 break;
4854 case DSP_LINE:
4855 data = dbev->line_data;
4856 break;
4857 case DSP_PC:
4858 data = dbev->pc_data;
4859 break;
4860 case DSP_SOURCE:
4861 case DSP_SOURCE_V2:
4862 data = dbev->src_data;
4863 break;
4864 case DSP_DISASM:
4865 case DSP_DISASM_V2:
4866 data = dbev->dis_data;
4867 break;
4868 case DSP_SELF:
4869 data = dbev->fitem_data;
4870 break;
4871 case DSP_CALLER:
4872 data = dbev->callers;
4873 break;
4874 case DSP_CALLEE:
4875 data = dbev->callees;
4876 break;
4877 case DSP_DLAYOUT:
4878 data = dbev->dlay_data;
4879 break;
4880 case DSP_DATAOBJ:
4881 data = dbev->dobj_data;
4882 break;
4883 case DSP_MEMOBJ:
4884 case DSP_INDXOBJ:
4885 data = dbev->get_indxobj_data (subtype);
4886 break;
4887 default:
4888 data = NULL;
4889 break;
4890 }
4891 if (data == NULL || data->get_status () != Hist_data::SUCCESS)
4892 return NULL;
4893 mlist = data->get_metric_list ();
4894
4895 // Get table size: count visible metrics
4896 nitems = data->size ();
4897 nvisible = 0;
4898 Vec_loop (Metric*, mlist->get_items (), index, mitem)
4899 {
4900 if (mitem->is_visible () || mitem->is_tvisible () || mitem->is_pvisible ())
4901 nvisible++;
4902 }
4903
4904 // Initialize Java String array
4905 Vector<void*> *table = new Vector<void*>(nvisible + 1);
4906
4907 // Mark Hi-value metric items for annotated src/dis/layout
4908 if (type == DSP_SOURCE || type == DSP_DISASM || type == DSP_DLAYOUT
4909 || type == DSP_SOURCE_V2 || type == DSP_DISASM_V2)
4910 {
4911 ji_list = new Vector<int>(nitems);
4912
4913 if (dbev->marks->size () > 0)
4914 index = dbev->marks->fetch (0);
4915 else
4916 index = -1;
4917 int mindex = 0;
4918 for (index2 = 0; index2 < nitems; index2++)
4919 {
4920 item = data->fetch (index2);
4921 if (index2 == index)
4922 {
4923 ji_list->store (index2, -item->type);
4924 if (++mindex < dbev->marks->size ())
4925 index = dbev->marks->fetch (mindex);
4926 else
4927 index = -1;
4928 }
4929 else
4930 ji_list->store (index2, item->type);
4931 }
4932 table->store (nvisible, ji_list);
4933 }
4934 else
4935 table->store (nvisible, NULL);
4936
4937 // Fill function list elements
4938 nv = 0;
4939
4940 Vec_loop (Metric*, mlist->get_items (), index, mitem)
4941 {
4942 if (!mitem->is_visible () && !mitem->is_tvisible () &&
4943 !mitem->is_pvisible ())
4944 continue;
4945
4946 // Fill values
4947 switch (mitem->get_vtype ())
4948 {
4949 case VT_LABEL:
4950 {
4951 Vector<char*> *jobjects = new Vector<char*>(nitems);
4952 char *buf = NULL;
4953 size_t bufsz = 0;
4954 int lspace = 0;
4955 if (type == DSP_SOURCE || type == DSP_DISASM || type == DSP_SOURCE_V2
4956 || type == DSP_DISASM_V2)
4957 {
4958 // if this is source or disassembly, where we'll insert
4959 // a preface into the output line, figure out how wide
4960 // it needs to be
4961 // first, scan all the lines, to get the maximum line number
4962 bufsz = 1024;
4963 buf = (char *) malloc (bufsz);
4964 int max_lineno = 0;
4965 int hidx;
4966 Hist_data::HistItem *hitem;
4967 Vec_loop (Hist_data::HistItem*, data, hidx, hitem)
4968 {
4969 if (!hitem->obj)
4970 continue;
4971 if (hitem->obj->get_type () == Histable::LINE &&
4972 ((DbeLine*) hitem->obj)->lineno > max_lineno)
4973 max_lineno = ((DbeLine*) hitem->obj)->lineno;
4974 else if (hitem->obj->get_type () == Histable::INSTR
4975 && ((DbeInstr*) hitem->obj)->lineno > max_lineno)
4976 max_lineno = ((DbeInstr*) hitem->obj)->lineno;
4977 }
4978
4979 // we have the maximum integer over all linenumbers in the file
4980 // figure out how many digits are needed
4981 lspace = snprintf (buf, bufsz, NTXT ("%d"), max_lineno);
4982 }
4983 for (index2 = 0; index2 < nitems; index2++)
4984 {
4985 item = data->fetch (index2);
4986 if (type == DSP_DLAYOUT)
4987 cell = dbe_strdup (((DataObject*) (item->obj))->get_offset_name ());
4988 else if (type == DSP_SOURCE || type == DSP_DISASM || type == DSP_SOURCE_V2 || type == DSP_DISASM_V2)
4989 {
4990 // This code is duplicated in output.cc, yet it's
4991 // intended for presentation purpose and thus is
4992 // potentially different for er_print and analyzer.
4993 switch (item->type)
4994 {
4995 case Module::AT_SRC_ONLY:
4996 case Module::AT_SRC:
4997 if (item->obj == NULL)
4998 snprintf (buf, bufsz, NTXT (" %*c. "), lspace, ' ');
4999 else
5000 snprintf (buf, bufsz, NTXT (" %*d. "), lspace, ((DbeLine*) item->obj)->lineno);
5001 break;
5002 case Module::AT_FUNC:
5003 case Module::AT_QUOTE:
5004 snprintf (buf, bufsz, NTXT ("%*c"), lspace + 3, ' ');
5005 break;
5006 case Module::AT_DIS:
5007 case Module::AT_DIS_ONLY:
5008 if (item->obj == NULL || ((DbeInstr*) item->obj)->lineno == -1)
5009 snprintf (buf, bufsz, NTXT ("%*c[%*s] "), lspace + 3, ' ', lspace, NTXT ("?"));
5010 else
5011 snprintf (buf, bufsz, NTXT ("%*c[%*d] "), lspace + 3, ' ', lspace,
5012 ((DbeInstr*) item->obj)->lineno);
5013 break;
5014 case Module::AT_COM:
5015 case Module::AT_EMPTY:
5016 *buf = (char) 0;
5017 break;
5018 }
5019 // get the line's text
5020 char *s = item->value[index].l;
5021 if (s != NULL)
5022 {
5023 // copy the string expanding all tabulations
5024 // (JTable doesn't render them)
5025 char *d = buf + strlen (buf);
5026 char c;
5027 size_t column = 0;
5028 do
5029 {
5030 c = *s++;
5031 if (c == '\t')
5032 {
5033 do
5034 {
5035 *d++ = ' ';
5036 column++;
5037 }
5038 while (column & 07);
5039 }
5040 else
5041 {
5042 *d++ = c;
5043 column++;
5044 }
5045 if (column + 32 > bufsz)
5046 {
5047 // Reallocate the buffer
5048 size_t curlen = d - buf;
5049 bufsz += 1024;
5050 char *buf_new = (char *) malloc (bufsz);
5051 strncpy (buf_new, buf, curlen);
5052 buf_new[curlen] = '\0';
5053 free (buf);
5054 buf = buf_new;
5055 d = buf + curlen;
5056 }
5057 }
5058 while (c != (char) 0);
5059 }
5060 cell = dbe_strdup (buf);
5061 free (item->value[index].l);
5062 item->value[index].l = NULL; //YXXX missing from dbeGetFuncListV2
5063 }
5064 else
5065 {
5066 // omazur: why don't we have it as metric value
5067 Histable::NameFormat nfmt = dbev->get_name_format ();
5068 cell = dbe_strdup (item->obj->get_name (nfmt));
5069 }
5070 jobjects->store (index2, cell);
5071 }
5072 if (type == DSP_SOURCE || type == DSP_DISASM || type == DSP_SOURCE_V2
5073 || type == DSP_DISASM_V2)
5074 free (buf);
5075 table->store (nv++, jobjects);
5076 break;
5077 }
5078 default:
5079 table->store (nv++, dbeGetTableDataOneColumn (data, index));
5080 break;
5081 }
5082 }
5083 return table;
5084}
5085
5086Vector<Obj> *
5087dbeGetComparableObjsV2 (int /* dbevindex */, Obj sel_obj, int type)
5088{
5089 long grsize = dbeSession->expGroups->size ();
5090 Vector<Obj> *res = new Vector<Obj> (grsize + 1);
5091 for (long j = 0; j < grsize; j++)
5092 res->append ((Obj) NULL);
5093 res->append (sel_obj);
5094 Histable *obj = (Histable *) sel_obj;
5095 if (obj == NULL)
5096 return res;
5097 Function *func = (Function *) obj->convertto (Histable::FUNCTION);
5098 if (func == NULL)
5099 return res;
5100 Vector<Histable *> *cmpObjs = func->get_comparable_objs ();
5101 if (cmpObjs == NULL || cmpObjs->size () != grsize)
5102 return res;
5103
5104 Histable::Type conv_type = (type == DSP_SOURCE || type == DSP_SOURCE_V2) ?
5105 Histable::LINE : Histable::INSTR;
5106 switch (obj->get_type ())
5107 {
5108 case Histable::FUNCTION:
5109 for (long j = 0; j < grsize; j++)
5110 res->store (j, (Obj) cmpObjs->get (j));
5111 return res;
5112 case Histable::INSTR:
5113 case Histable::LINE:
5114 {
5115 SourceFile *srcContext = (SourceFile *) obj->convertto (Histable::SOURCEFILE);
5116 char *bname = get_basename (srcContext->get_name ());
5117 for (long j = 0; j < grsize; j++)
5118 {
5119 Function *func1 = (Function *) cmpObjs->get (j);
5120 if (func == func1)
5121 {
5122 if (conv_type == Histable::LINE)
5123 res->store (j, (Obj) obj);
5124 else
5125 res->store (j, (Obj) obj->convertto (conv_type, srcContext));
5126 continue;
5127 }
5128 if (func1 == NULL)
5129 continue;
5130 Vector<SourceFile*> *sources = func1->get_sources ();
5131 SourceFile *sf = NULL;
5132 for (long j1 = 0, sz1 = sources ? sources->size () : 0; j1 < sz1; j1++)
5133 {
5134 SourceFile *sf1 = sources->get (j1);
5135 if (sf1 == srcContext)
5136 { // the same file
5137 sf = srcContext;
5138 break;
5139 }
5140 else if (sf == NULL)
5141 {
5142 char *bname1 = get_basename (sf1->get_name ());
5143 if (dbe_strcmp (bname, bname1) == 0)
5144 sf = sf1;
5145 }
5146 }
5147 res->store (j, (Obj) func1->convertto (conv_type, srcContext));
5148 }
5149 break;
5150 }
5151 default:
5152 break;
5153 }
5154 return res;
5155}
5156
5157// Get Table of Function List data
5158Vector<void *> *
5159dbeGetFuncListV2 (int dbevindex, int mtype, Obj sel_obj, int type, int subtype)
5160{
5161 Metric *mitem;
5162 int nitems, nvisible;
5163 int index, index2, nv;
5164 char *cell;
5165 Hist_data::HistItem *item;
5166 DbeView *dbev = dbeSession->getView (dbevindex);
5167 dbev->error_msg = dbev->warning_msg = NULL;
5168 MetricList *mlist = dbev->get_metric_list ((MetricType) (mtype & MTYPE_MASK),
5169 (mtype & COMPARE_BIT) != 0,
5170 mtype >> GROUP_ID_SHIFT);
5171 Histable *selObj = (Histable *) sel_obj;
5172 int old_compare_mode = dbev->get_compare_mode ();
5173 if ((mtype & COMPARE_BIT) != 0)
5174 dbev->reset_compare_mode (CMP_DISABLE);
5175 Hist_data *data = dbev->get_data (mlist, selObj, type, subtype);
5176 dbev->reset_compare_mode (old_compare_mode);
5177 if (data == NULL || data->get_status () != Hist_data::SUCCESS)
5178 return NULL;
5179 nitems = data->size ();
5180 nvisible = mlist->get_items ()->size ();
5181
5182 // Initialize Java String array
5183 Vector<void*> *table = new Vector<void*>(nvisible + 3);
5184 // Mark Hi-value metric items for annotated src/dis/layout
5185 if (type == DSP_SOURCE || type == DSP_DISASM || type == DSP_DLAYOUT
5186 || type == DSP_SOURCE_V2 || type == DSP_DISASM_V2)
5187 {
5188 Vector<int> *types = new Vector<int>(nitems);
5189 Vector<Obj> *ids = new Vector<Obj > (nitems);
5190 if (dbev->marks->size () > 0)
5191 index = dbev->marks->fetch (0);
5192 else
5193 index = -1;
5194 int mindex = 0;
5195 for (int i = 0; i < nitems; i++)
5196 {
5197 item = data->fetch (i);
5198 ids->store (i, (Obj) item->obj);
5199 if (i == index)
5200 {
5201 types->store (i, -item->type);
5202 if (++mindex < dbev->marks->size ())
5203 index = dbev->marks->fetch (mindex);
5204 else
5205 index = -1;
5206 }
5207 else
5208 types->store (i, item->type);
5209 }
5210 table->store (nvisible, types);
5211 table->store (nvisible + 1, ids);
5212 }
5213 else
5214 {
5215 table->store (nvisible, NULL);
5216 table->store (nvisible + 1, NULL);
5217 }
5218
5219 // Fill function list elements
5220 nv = 0;
5221 Vec_loop (Metric*, mlist->get_items (), index, mitem)
5222 {
5223 if (!mitem->is_visible () && !mitem->is_tvisible () &&
5224 !mitem->is_pvisible ())
5225 continue;
5226
5227 // Fill values
5228 switch (mitem->get_vtype ())
5229 {
5230 default:
5231 table->store (nv++, dbeGetTableDataOneColumn (data, index));
5232 break;
5233 case VT_LABEL:
5234 Vector<char*> *jobjects = new Vector<char*>(nitems);
5235 char *buf = NULL;
5236 size_t bufsz = 0;
5237 int lspace = 0;
5238 if (type == DSP_SOURCE || type == DSP_DISASM || type == DSP_SOURCE_V2
5239 || type == DSP_DISASM_V2)
5240 {
5241 // if this is source or disassembly, where we'll insert
5242 // a preface into the output line, figure out how wide
5243 // it needs to be
5244 // first, scan all the lines, to get the maximum line number
5245 bufsz = 1024;
5246 buf = (char *) malloc (bufsz);
5247 int max_lineno = 0;
5248 int hidx;
5249 Hist_data::HistItem *hitem;
5250 Vec_loop (Hist_data::HistItem*, data, hidx, hitem)
5251 {
5252 if (!hitem->obj)
5253 continue;
5254 if (hitem->obj->get_type () == Histable::LINE &&
5255 ((DbeLine*) hitem->obj)->lineno > max_lineno)
5256 max_lineno = ((DbeLine*) hitem->obj)->lineno;
5257 else if (hitem->obj->get_type () == Histable::INSTR
5258 && ((DbeInstr*) hitem->obj)->lineno > max_lineno)
5259 max_lineno = ((DbeInstr*) hitem->obj)->lineno;
5260 }
5261
5262 // we have the maximum integer over all linenumbers in the file
5263 // figure out how many digits are needed
5264 lspace = snprintf (buf, bufsz, NTXT ("%d"), max_lineno);
5265 }
5266
5267 for (index2 = 0; index2 < nitems; index2++)
5268 {
5269 item = data->fetch (index2);
5270 if (type == DSP_DLAYOUT)
5271 cell = dbe_strdup (((DataObject*) (item->obj))->get_offset_name ());
5272 else if (type == DSP_SOURCE || type == DSP_DISASM || type == DSP_SOURCE_V2 || type == DSP_DISASM_V2)
5273 {
5274 // This code is duplicated in output.cc, yet it's
5275 // intended for presentation purpose and thus is
5276 // potentially different for er_print and analyzer.
5277 switch (item->type)
5278 {
5279 case Module::AT_SRC_ONLY:
5280 case Module::AT_SRC:
5281 if (item->obj == NULL)
5282 snprintf (buf, bufsz, NTXT (" %*c. "), lspace, ' ');
5283 else
5284 snprintf (buf, bufsz, NTXT (" %*d. "), lspace,
5285 ((DbeLine*) item->obj)->lineno);
5286 break;
5287 case Module::AT_FUNC:
5288 case Module::AT_QUOTE:
5289 snprintf (buf, bufsz, NTXT ("%*c"), lspace + 3, ' ');
5290 break;
5291 case Module::AT_DIS:
5292 case Module::AT_DIS_ONLY:
5293 if (item->obj == NULL || ((DbeInstr*) item->obj)->lineno == -1)
5294 snprintf (buf, bufsz, NTXT ("%*c[%*s] "), lspace + 3, ' ',
5295 lspace, NTXT ("?"));
5296 else
5297 snprintf (buf, bufsz, NTXT ("%*c[%*d] "), lspace + 3, ' ',
5298 lspace,
5299 ((DbeInstr*) item->obj)->lineno);
5300 break;
5301 case Module::AT_COM:
5302 case Module::AT_EMPTY:
5303 *buf = (char) 0;
5304 break;
5305 }
5306 // get the line's text
5307 char *s = item->value[index].l;
5308 if (s != NULL)
5309 {
5310 // copy the string expanding all tabulations
5311 // (JTable doesn't render them)
5312 char *d = buf + strlen (buf);
5313 char c;
5314 size_t column = 0;
5315 do
5316 {
5317 c = *s++;
5318 if (c == '\t')
5319 {
5320 do
5321 {
5322 *d++ = ' ';
5323 column++;
5324 }
5325 while (column & 07);
5326 }
5327 else
5328 {
5329 *d++ = c;
5330 column++;
5331 }
5332 if (column + 32 > bufsz)
5333 {
5334 // Reallocate the buffer
5335 size_t curlen = d - buf;
5336 bufsz += 1024;
5337 char *buf_new = (char *) malloc (bufsz);
5338 strncpy (buf_new, buf, curlen);
5339 buf_new[curlen] = '\0';
5340 free (buf);
5341 buf = buf_new;
5342 d = buf + curlen;
5343 }
5344 }
5345 while (c != (char) 0);
5346 }
5347 cell = dbe_strdup (buf);
5348 }
5349 else
5350 {
5351 Histable::NameFormat nfmt = dbev->get_name_format ();
5352 cell = dbe_strdup (item->obj->get_name (nfmt));
5353 }
5354 jobjects->store (index2, cell);
5355 }
5356
5357 if (type == DSP_SOURCE || type == DSP_DISASM || type == DSP_SOURCE_V2
5358 || type == DSP_DISASM_V2)
5359 free (buf);
5360 table->store (nv++, jobjects);
5361 break;
5362 }
5363 }
5364 table->append (dbeGetMetricList (mlist));
5365 return table;
5366} // dbeGetFuncListV2
5367
5368//
5369// Get Table DataV2
5370//
5371Vector<void*> *
5372dbeGetTableDataV2 (int dbevindex, char *mlistStr, char *modeStr, char *typeStr,
5373 char *subtypeStr, Vector<uint64_t> *ids)
5374{
5375 DbeView *dbev = dbeSession->getView (dbevindex);
5376 if (dbev == NULL)
5377 abort ();
5378
5379 // Process metric list specification
5380 if (mlistStr == NULL)
5381 return NULL;
5382 bool met_call = false;
5383 MetricList *mlist = NULL;
5384 if (streq (mlistStr, NTXT ("MET_NORMAL")))
5385 mlist = dbev->get_metric_list (MET_NORMAL);
5386 else if (streq (mlistStr, NTXT ("MET_CALL")))
5387 {
5388 met_call = true;
5389 mlist = dbev->get_metric_list (MET_CALL);
5390 }
5391 else if (streq (mlistStr, NTXT ("MET_CALL_AGR")))
5392 mlist = dbev->get_metric_list (MET_CALL_AGR);
5393 else if (streq (mlistStr, NTXT ("MET_DATA")))
5394 mlist = dbev->get_metric_list (MET_DATA);
5395 else if (streq (mlistStr, NTXT ("MET_INDX")))
5396 mlist = dbev->get_metric_list (MET_INDX);
5397 else if (streq (mlistStr, NTXT ("MET_IO")))
5398 mlist = dbev->get_metric_list (MET_IO);
5399 else if (streq (mlistStr, NTXT ("MET_HEAP")))
5400 mlist = dbev->get_metric_list (MET_HEAP);
5401 else
5402 return NULL;
5403
5404 // Process mode specification
5405 if (modeStr == NULL)
5406 return NULL;
5407 Hist_data::Mode mode = (Hist_data::Mode)0;
5408 if (streq (modeStr, NTXT ("CALLERS")))
5409 mode = Hist_data::CALLERS;
5410 else if (streq (modeStr, NTXT ("CALLEES")))
5411 mode = Hist_data::CALLEES;
5412 else if (streq (modeStr, NTXT ("SELF")))
5413 mode = Hist_data::SELF;
5414 else if (streq (modeStr, NTXT ("ALL")))
5415 mode = Hist_data::ALL;
5416 else
5417 return NULL;
5418
5419 // Process type specification
5420 if (typeStr == NULL)
5421 return NULL;
5422 Histable::Type type = Histable::OTHER;
5423 if (streq (typeStr, NTXT ("FUNCTION")))
5424 type = Histable::FUNCTION;
5425 else if (streq (typeStr, NTXT ("INDEXOBJ")))
5426 type = Histable::INDEXOBJ;
5427 else if (streq (typeStr, NTXT ("IOACTFILE")))
5428 type = Histable::IOACTFILE;
5429 else if (streq (typeStr, NTXT ("IOACTVFD")))
5430 type = Histable::IOACTVFD;
5431 else if (streq (typeStr, NTXT ("IOCALLSTACK")))
5432 type = Histable::IOCALLSTACK;
5433 else if (streq (typeStr, NTXT ("HEAPCALLSTACK")))
5434 type = Histable::HEAPCALLSTACK;
5435 else if (streq (typeStr, NTXT ("LINE")))
5436 type = Histable::LINE;
5437 else if (streq (typeStr, NTXT ("INSTR")))
5438 type = Histable::INSTR;
5439 else
5440 // XXX Accepting objects other than above may require a different
5441 // implementation of the id -> Histable mapping below
5442 return NULL;
5443
5444 // Process subtype specification
5445 int subtype = 0;
5446 if (subtypeStr != NULL)
5447 subtype = atoi (subtypeStr);
5448 Vector<Histable*> *hobjs = NULL;
5449 if (ids != NULL)
5450 {
5451 hobjs = new Vector<Histable*>();
5452 for (int i = 0; i < ids->size (); ++i)
5453 {
5454 Histable::Type obj_type = type;
5455 if ((obj_type == Histable::LINE || obj_type == Histable::INSTR)
5456 && subtype == 0)
5457 obj_type = Histable::FUNCTION;
5458 Histable *hobj = dbeSession->findObjectById (obj_type, subtype, ids->fetch (i));
5459 if ((obj_type == Histable::LINE || obj_type == Histable::INSTR)
5460 && subtype == 0 && hobj == NULL)
5461 return NULL;
5462 hobjs->append (hobj);
5463 }
5464 }
5465
5466 PathTree::PtreeComputeOption flag = PathTree::COMPUTEOPT_NONE;
5467 if (dbev->isOmpDisMode () && type == Histable::FUNCTION
5468 && mode == Hist_data::CALLEES && met_call)
5469 flag = PathTree::COMPUTEOPT_OMP_CALLEE;
5470
5471 Hist_data *data = dbev->get_hist_data (mlist, type, subtype, mode, hobjs, NULL, NULL, flag);
5472 return dbeGetTableDataV2Data (dbev, data);
5473}
5474
5475static Vector<void*> *
5476dbeGetTableDataV2Data (DbeView * /*dbev*/, Hist_data *data)
5477{
5478 if (data == NULL || data->get_status () != Hist_data::SUCCESS)
5479 return NULL;
5480 MetricList *mlist;
5481 mlist = data->get_metric_list ();
5482 int nitems = data->size ();
5483
5484 // Initialize Java String array
5485 Vector<void*> *table = new Vector<void*>(mlist->size () + 1);
5486
5487 // Fill function list elements
5488 for (long i = 0, sz = mlist->size (); i < sz; i++)
5489 {
5490 Metric *mitem = mlist->get (i);
5491 if (!mitem->is_visible () && !mitem->is_tvisible () &&
5492 !mitem->is_pvisible ())
5493 continue;
5494 table->append (dbeGetTableDataOneColumn (data, i));
5495 }
5496
5497 // Add an array of Histable IDs
5498 Vector<uint64_t> *idList = new Vector<uint64_t>(nitems);
5499 for (int i = 0; i < nitems; ++i)
5500 {
5501 Hist_data::HistItem *item = data->fetch (i);
5502 if (item->obj->get_type () == Histable::LINE
5503 || item->obj->get_type () == Histable::INSTR)
5504 idList->store (i, (uint64_t) (item->obj));
5505 else
5506 idList->store (i, item->obj->id);
5507 }
5508 table->append (idList);
5509 return table;
5510} // dbeGetTableData
5511
5512//YXXX try to use the following to consolidate similar cut/paste code
5513
5514static Vector<void*> *
5515dbeGetTableDataOneColumn (Hist_data *data, int met_ind)
5516{
5517 // Allocates a vector and fills it with metric values for one column
5518 TValue res;
5519 Metric *m = data->get_metric_list ()->get (met_ind);
5520 if ((m->get_visbits () & VAL_RATIO) != 0)
5521 {
5522 Vector<double> *col = new Vector<double>(data->size ());
5523 for (long row = 0, sz_row = data->size (); row < sz_row; row++)
5524 {
5525 TValue *v = data->get_value (&res, met_ind, row);
5526 double d = (v->tag != VT_LABEL) ? v->to_double () : 100.; // NaN
5527 col->append (d);
5528 }
5529 return (Vector<void*> *) col;
5530 }
5531
5532 switch (m->get_vtype ())
5533 {
5534 case VT_DOUBLE:
5535 {
5536 Vector<double> *col = new Vector<double>(data->size ());
5537 for (long row = 0, sz_row = data->size (); row < sz_row; row++)
5538 {
5539 TValue *v = data->get_value (&res, met_ind, row);
5540 col->append (v->d);
5541 }
5542 return (Vector<void*> *) col;
5543 }
5544 case VT_INT:
5545 {
5546 Vector<int> *col = new Vector<int>(data->size ());
5547 for (long row = 0, sz_row = data->size (); row < sz_row; row++)
5548 {
5549 TValue *v = data->get_value (&res, met_ind, row);
5550 col->append (v->i);
5551 }
5552 return (Vector<void*> *) col;
5553 }
5554 case VT_ULLONG:
5555 case VT_LLONG:
5556 {
5557 Vector<long long> *col = new Vector<long long>(data->size ());
5558 for (long row = 0, sz_row = data->size (); row < sz_row; row++)
5559 {
5560 TValue *v = data->get_value (&res, met_ind, row);
5561 col->append (v->ll);
5562 }
5563 return (Vector<void*> *) col;
5564 }
5565 case VT_ADDRESS:
5566 {
5567 Vector<long long> *col = new Vector<long long>(data->size ());
5568 for (long row = 0, sz_row = data->size (); row < sz_row; row++)
5569 {
5570 TValue *v = data->get_value (&res, met_ind, row);
5571 // set the highest bit to mark this jlong as
5572 // a VT_ADDRESS (rather than a regular VT_LLONG)
5573 col->append (v->ll | 0x8000000000000000ULL);
5574 }
5575 return (Vector<void*> *) col;
5576 }
5577 case VT_LABEL:
5578 {
5579 Vector<char *> *col = new Vector<char *>(data->size ());
5580 for (long row = 0, sz_row = data->size (); row < sz_row; row++)
5581 {
5582 TValue *v = data->get_value (&res, met_ind, row);
5583 col->append (dbe_strdup (v->l));
5584 }
5585 return (Vector<void*> *) col;
5586 }
5587 default:
5588 return NULL;
5589 }
5590}
5591
5592static Vector<void*> *
5593dbeGetTableDataOneColumn (DbeView *dbev, Vector<Hist_data::HistItem*> *data,
5594 ValueTag vtype, int metricColumnNumber)
5595// Allocates a vector and fills it with metric values for one column
5596{
5597 Vector<void*> *column_data = NULL;
5598 int nitems = data->size (); // number of rows
5599 int index = metricColumnNumber;
5600 switch (vtype)
5601 {
5602 case VT_DOUBLE:
5603 {
5604 Vector<double> *jd_list = new Vector<double>(nitems);
5605 for (int index2 = 0; index2 < nitems; index2++)
5606 {
5607 Hist_data::HistItem *item = data->fetch (index2);
5608 jd_list->store (index2, item->value[index].d);
5609 }
5610 column_data = (Vector<void*> *)jd_list;
5611 break;
5612 }
5613 case VT_INT:
5614 {
5615 Vector<int> *ji_list = new Vector<int>(nitems);
5616 for (int index2 = 0; index2 < nitems; index2++)
5617 {
5618 Hist_data::HistItem *item = data->fetch (index2);
5619 ji_list->store (index2, item->value[index].i);
5620 }
5621 column_data = (Vector<void*> *)ji_list;
5622 break;
5623 }
5624 case VT_ULLONG:
5625 case VT_LLONG:
5626 {
5627 Vector<long long> *jl_list = new Vector<long long>(nitems);
5628 for (int index2 = 0; index2 < nitems; index2++)
5629 {
5630 Hist_data::HistItem *item = data->fetch (index2);
5631 jl_list->store (index2, item->value[index].ll);
5632 }
5633 column_data = (Vector<void*> *)jl_list;
5634 break;
5635 }
5636 case VT_ADDRESS:
5637 {
5638 Vector<long long> *jl_list = new Vector<long long>(nitems);
5639 for (int index2 = 0; index2 < nitems; index2++)
5640 {
5641 Hist_data::HistItem *item = data->fetch (index2);
5642
5643 // set the highest bit to mark this jlong as
5644 // a VT_ADDRESS (rather than a regular VT_LLONG)
5645 uint64_t addr = item->value[index].ll;
5646 addr |= 0x8000000000000000ULL;
5647 jl_list->store (index2, addr);
5648 }
5649 column_data = (Vector<void*> *)jl_list;
5650 break;
5651 }
5652 case VT_LABEL:
5653 {
5654 Vector<char*> *jobjects = new Vector<char*>(nitems);
5655 for (int index2 = 0; index2 < nitems; index2++)
5656 {
5657 Hist_data::HistItem *item = data->fetch (index2);
5658
5659 // omazur: why don't we have it as metric value
5660 Histable::NameFormat nfmt = dbev->get_name_format ();
5661 char *str = dbe_strdup (item->obj->get_name (nfmt));
5662 jobjects->store (index2, str);
5663 }
5664 column_data = (Vector<void*> *)jobjects;
5665 break;
5666 }
5667 default:
5668 abort ();
5669 }
5670 return column_data;
5671}
5672
5673int
5674dbeGetCallTreeNumLevels (int dbevindex)
5675{
5676 DbeView *dbev = dbeSession->getView (dbevindex);
5677 if (dbev == NULL)
5678 abort ();
5679 PathTree * ptree = dbev->get_path_tree ();
5680 if (ptree == NULL)
5681 return 0;
5682 return ptree->get_ftree_depth ();
5683}
5684
5685Vector<void*>*
5686dbeGetCallTreeLevel (int dbevindex, char *mcmd, int level)
5687{
5688 DbeView *dbev = dbeSession->getView (dbevindex);
5689 if (dbev == NULL)
5690 abort ();
5691 PathTree * ptree = dbev->get_path_tree ();
5692 if (ptree == NULL)
5693 return NULL;
5694 if (mcmd == NULL)
5695 return NULL;
5696 BaseMetric *bm = dbeSession->find_base_reg_metric (mcmd);
5697 if (bm == NULL)
5698 return NULL;
5699 return ptree->get_ftree_level (bm, level);
5700}
5701
5702Vector<void*>*
5703dbeGetCallTreeLevels (int dbevindex, char *mcmd)
5704{
5705 DbeView *dbev = dbeSession->getView (dbevindex);
5706 if (dbev == NULL)
5707 abort ();
5708 PathTree * ptree = dbev->get_path_tree ();
5709 if (ptree == NULL)
5710 return NULL;
5711 if (mcmd == NULL)
5712 return NULL;
5713 BaseMetric *bm = dbeSession->find_base_reg_metric (mcmd);
5714 if (bm == NULL)
5715 return NULL;
5716
5717 int depth = ptree->get_ftree_depth ();
5718 Vector<void*> *results = new Vector<void*>(depth);
5719 for (int ii = 0; ii < depth; ii++)
5720 results->append (ptree->get_ftree_level (bm, ii));
5721 return results;
5722}
5723
5724Vector<void*>*
5725dbeGetCallTreeLevelFuncs (int dbevindex, int start_level, int end_level)
5726{ // (0,-1) -> all levels
5727 DbeView *dbev = dbeSession->getView (dbevindex);
5728 if (dbev == NULL)
5729 abort ();
5730 PathTree * ptree = dbev->get_path_tree ();
5731 if (ptree == NULL)
5732 return NULL;
5733
5734 int depth = ptree->get_ftree_depth ();
5735 if (start_level < 0)
5736 start_level = 0;
5737 if (end_level < 0 || end_level >= depth)
5738 end_level = depth - 1;
5739
5740 Histable::NameFormat nfmt = dbev->get_name_format (); //YXXX or fixed format?
5741 Vector<char*> *funcNames = new Vector<char*>();
5742 Vector<long long> *funcIds = new Vector<long long>();
5743 Vector<Obj> *funcObjs = new Vector<Obj>();
5744
5745 if (start_level == 0 && end_level == depth - 1)
5746 return dbeGetCallTreeFuncs (dbevindex);
5747 else
5748 {
5749 for (int ii = start_level; ii <= end_level; ii++)
5750 {
5751 Vector<void*> *info = ptree->get_ftree_level (NULL, ii); /*no metric*/
5752 if (!info)
5753 continue;
5754 Vector<long long> *fids = (Vector<long long> *)info->get (2);
5755 if (!fids)
5756 continue;
5757 int index;
5758 long long fid;
5759 Vec_loop (long long, fids, index, fid)
5760 {
5761 funcIds->append (fid);
5762 Histable *obj = dbeSession->findObjectById (fid);
5763 char * fname = obj ? dbe_strdup (obj->get_name (nfmt)) : NULL;
5764 funcNames->append (fname);
5765 funcObjs->append ((unsigned long) obj); // avoiding sign extension
5766 }
5767 destroy (info);
5768 }
5769 }
5770 Vector<void*> *results = new Vector<void*>(3);
5771 results->append (funcIds);
5772 results->append (funcNames);
5773 results->append (funcObjs);
5774 return results;
5775}
5776
5777Vector<void*> *
5778dbeGetCallTreeFuncs (int dbevindex)
5779{ // does not require ptree->get_ftree_level() to be computed
5780 DbeView *dbev = dbeSession->getView (dbevindex);
5781 if (dbev == NULL)
5782 abort ();
5783 PathTree * ptree = dbev->get_path_tree ();
5784 if (ptree == NULL)
5785 return 0;
5786 Vector<Function*>* funcs = ptree->get_funcs (); // Unique functions in tree
5787 if (funcs == NULL)
5788 return NULL;
5789
5790 long sz = funcs->size ();
5791 Vector<void*> *results = new Vector<void*>(3);
5792 Vector<long long> *funcIds = new Vector<long long>(sz);
5793 Vector<char*> *funcNames = new Vector<char*>(sz);
5794 Vector<Obj> *funcObjs = new Vector<Obj>(sz);
5795
5796 int index;
5797 Function * func;
5798 Histable::NameFormat nfmt = dbev->get_name_format (); //YXXX or fixed format?
5799 Vec_loop (Function *, funcs, index, func)
5800 {
5801 funcIds->append (func->id); // do we need IDs?
5802 char *fname = dbe_strdup (func->get_name (nfmt));
5803 funcNames->append (fname);
5804 funcObjs->append ((unsigned long) func); // avoiding sign extension
5805 }
5806 results->put (0, funcIds);
5807 results->put (1, funcNames);
5808 results->put (2, funcObjs);
5809 destroy (funcs);
5810 return results;
5811}
5812
5813Vector<void*>*
5814dbeGetCallTreeChildren (int dbevindex, char *mcmd, Vector<int /*NodeIdx*/>*node_idxs)
5815{
5816 DbeView *dbev = dbeSession->getView (dbevindex);
5817 if (dbev == NULL)
5818 abort ();
5819 if (node_idxs == NULL || node_idxs->size () == 0)
5820 return NULL;
5821 long sz = node_idxs->size ();
5822 PathTree * ptree = dbev->get_path_tree ();
5823 if (ptree == NULL)
5824 return NULL;
5825 if (mcmd == NULL)
5826 return NULL;
5827 BaseMetric *bm = dbeSession->find_base_reg_metric (mcmd);
5828 if (bm == NULL)
5829 return NULL;
5830
5831 Vector<void*> *results = new Vector<void*>(sz);
5832 for (long ii = 0; ii < sz; ii++)
5833 {
5834 PathTree::NodeIdx nodeIdx = node_idxs->get (ii); // upcasted from int
5835 results->append (ptree->get_ftree_node_children (bm, nodeIdx));
5836 }
5837 return results;
5838}
5839
5840Vector<int> *
5841dbeGetGroupIds (int /*dbevindex*/)
5842{
5843 Vector<ExpGroup*> *groups = dbeSession->expGroups;
5844 int sz = groups->size ();
5845 Vector<int> *grIds = new Vector<int>(sz);
5846 for (int i = 0; i < sz; i++)
5847 grIds->store (i, groups->fetch (i)->groupId);
5848 return grIds;
5849}
5850
5851//
5852// Get label for name column
5853//
5854Vector<char*> *
5855dbeGetNames (int dbevindex, int type, Obj sel_obj)
5856{
5857 char *s0, *s1, *s2;
5858 bool need_strdup = true;
5859 switch (type)
5860 {
5861 case DSP_SOURCE_V2:
5862 case DSP_DISASM_V2:
5863 case DSP_SOURCE:
5864 case DSP_DISASM:
5865 {
5866 if (sel_obj)
5867 {
5868 Histable *selObj = (Histable*) sel_obj;
5869 Function *func = (Function *) selObj->convertto (Histable::FUNCTION);
5870 if (func)
5871 {
5872 char *names[3] = {NULL, NULL, NULL};
5873 set_file_names (func, names);
5874 s0 = names[0];
5875 s1 = names[1];
5876 s2 = names[2];
5877 need_strdup = false;
5878 break;
5879 }
5880 }
5881 DbeView *dbev = dbeSession->getView (dbevindex);
5882 char **names = type == DSP_SOURCE || type == DSP_SOURCE_V2 ? dbev->names_src : dbev->names_dis;
5883 s0 = names[0];
5884 s1 = names[1];
5885 s2 = names[2];
5886 break;
5887 }
5888 case DSP_LINE:
5889 s0 = GTXT ("Lines");
5890 s1 = GTXT ("Function, line # in \"sourcefile\"");
5891 s2 = NTXT ("");
5892 break;
5893 case DSP_PC:
5894 s0 = GTXT ("PCs");
5895 s1 = GTXT ("Function + offset");
5896 s2 = NTXT ("");
5897 break;
5898 case DSP_DLAYOUT:
5899 s0 = GTXT ("Name");
5900 s1 = GTXT ("* +offset .element");
5901 s2 = NTXT ("");
5902 break;
5903 default:
5904 s0 = GTXT ("Name");
5905 s1 = s2 = NTXT ("");
5906 break;
5907 }
5908 if (need_strdup)
5909 {
5910 s0 = dbe_strdup (s0);
5911 s1 = dbe_strdup (s1);
5912 s2 = dbe_strdup (s2);
5913 }
5914 Vector<char*> *table = new Vector<char*>(3);
5915 table->store (0, s0);
5916 table->store (1, s1);
5917 table->store (2, s2);
5918 return table;
5919}
5920
5921//
5922// Get Total/Maximum element of Function List
5923//
5924Vector<void*> *
5925dbeGetTotalMax (int dbevindex, int type, int subtype)
5926{
5927 Hist_data *data;
5928 int index;
5929 Hist_data::HistItem *total_item, *maximum_item;
5930 DbeView *dbev = dbeSession->getView (dbevindex);
5931 if (dbev == NULL)
5932 abort ();
5933
5934 switch (type)
5935 {
5936 case DSP_LINE:
5937 data = dbev->line_data;
5938 break;
5939 case DSP_PC:
5940 data = dbev->pc_data;
5941 break;
5942 case DSP_CALLER:
5943 data = dbev->callers;
5944 break;
5945 case DSP_SELF:
5946 case DSP_CALLEE:
5947 data = dbev->callees;
5948 break;
5949 case DSP_DLAYOUT:
5950 data = dbev->dlay_data;
5951 break;
5952 case DSP_DATAOBJ:
5953 data = dbev->dobj_data;
5954 break;
5955 case DSP_MEMOBJ:
5956 data = dbev->get_indxobj_data (subtype);
5957 break;
5958 case DSP_INDXOBJ:
5959 data = dbev->get_indxobj_data (subtype);
5960 break;
5961 case DSP_FUNCTION: // annotated src/dis use func total/max
5962 case DSP_SOURCE:
5963 case DSP_DISASM:
5964 case DSP_SOURCE_V2:
5965 case DSP_DISASM_V2:
5966 data = dbev->func_data;
5967 break;
5968 default:
5969 abort ();
5970 }
5971 if (data == NULL || data->get_status () != Hist_data::SUCCESS)
5972 return NULL;
5973
5974 // Get list size
5975 // XXX -- the original list has all items, visible or not;
5976 // XXX -- the one from Hist_data has only visible items,
5977 // XXX -- and should be the only ones computed
5978 // XXX -- Analyzer got confused (yesterday), when we used the shorter list
5979 // XXX -- Why can we fetch total/max for metrics never
5980 // XXX -- computed without core dumping?
5981 MetricList *mlist2 = data->get_metric_list ();
5982 int size = mlist2->get_items ()->size ();
5983
5984 // Initialize Java array
5985 Vector<void*> *total_max = new Vector<void*>(2);
5986 Vector<double> *total = new Vector<double>(size);
5987 Vector<double> *maximum = new Vector<double>(size);
5988
5989 // Fill total/maximum element
5990 total_item = data->get_totals ();
5991 maximum_item = data->get_maximums ();
5992
5993 for (index = 0; index < size; index++)
5994 {
5995 total->store (index, total_item->value[index].to_double ());
5996 maximum->store (index, maximum_item->value[index].to_double ());
5997 }
5998 total_max->store (0, total);
5999 total_max->store (1, maximum);
6000 return total_max;
6001}
6002
6003//
6004// Get Table of Overview List
6005Vector<void*> *
6006dbeGetStatisOverviewList (int dbevindex)
6007{
6008 int size;
6009 Ovw_data **data;
6010 Ovw_data::Ovw_item labels, *totals;
6011 int nitems;
6012 int index, index2;
6013
6014 DbeView *dbev = dbeSession->getView (dbevindex);
6015 if (dbev == NULL)
6016 abort ();
6017 dbev->error_msg = dbev->warning_msg = NULL;
6018
6019 size = dbeSession->nexps ();
6020 totals = new Ovw_data::Ovw_item[size + 1];
6021 data = new Ovw_data*[size + 1];
6022 data[0] = new Ovw_data ();
6023
6024 for (index = 1; index <= size; index++)
6025 {
6026 data[index] = dbev->get_ovw_data (index - 1);
6027 if (data[index] == NULL)
6028 {
6029 Ovw_data::reset_item (&totals[index]); // set contents to zeros
6030 continue;
6031 }
6032 data[0]->sum (data[index]);
6033 totals[index] = data[index]->get_totals (); //shallow copy!
6034 }
6035 totals[0] = data[0]->get_totals ();
6036
6037 // Get table size
6038 labels = data[0]->get_labels ();
6039 nitems = labels.size + 4;
6040
6041 // Initialize Java String array
6042 Vector<void*> *table = new Vector<void*>(size + 4);
6043 Vector<char*> *jobjects = new Vector<char*>(nitems);
6044
6045 // Set the label
6046 jobjects->store (0, dbe_strdup (GTXT ("Start Time (sec.)")));
6047 jobjects->store (1, dbe_strdup (GTXT ("End Time (sec.)")));
6048 jobjects->store (2, dbe_strdup (GTXT ("Duration (sec.)")));
6049 jobjects->store (3, dbe_strdup (GTXT ("Total Thread Time (sec.)")));
6050 jobjects->store (4, dbe_strdup (GTXT ("Average number of Threads")));
6051
6052 for (index2 = 5; index2 < nitems; index2++)
6053 jobjects->store (index2, dbe_strdup (labels.values[index2 - 4].l));
6054 table->store (0, jobjects);
6055
6056 // Set the data
6057 for (index = 0; index <= size; index++)
6058 {
6059 Vector<double> *jd_list = new Vector<double>(nitems);
6060 jd_list->store (0, tstodouble (totals[index].start));
6061 jd_list->store (1, tstodouble (totals[index].end));
6062 jd_list->store (2, tstodouble (totals[index].duration));
6063 jd_list->store (3, tstodouble (totals[index].tlwp));
6064 jd_list->store (4, totals[index].nlwp);
6065 for (index2 = 5; index2 < nitems; index2++)
6066 jd_list->store (index2, tstodouble (totals[index].values[index2 - 4].t));
6067 table->store (index + 1, jd_list);
6068 }
6069 for (index = 0; index <= size; index++)
6070 delete data[index];
6071 delete[] data;
6072 delete[] totals;
6073 return table;
6074}
6075
6076// Get Table of Statistics List
6077Vector<void*> *
6078dbeGetStatisList (int dbevindex)
6079{
6080 int size;
6081 Stats_data **data;
6082 int nitems;
6083 int index, index2;
6084 DbeView *dbev = dbeSession->getView (dbevindex);
6085 if (dbev == NULL)
6086 abort ();
6087 dbev->error_msg = dbev->warning_msg = NULL;
6088 if ((size = dbeSession->nexps ()) == 0)
6089 return NULL;
6090
6091 // Get statistics data
6092 data = (Stats_data **) malloc ((size + 1) * sizeof (Stats_data *));
6093 data[0] = new Stats_data ();
6094 for (index = 1; index <= size; index++)
6095 {
6096 data[index] = dbev->get_stats_data (index - 1);
6097 if (data[index] == NULL)
6098 continue;
6099 data[0]->sum (data[index]);
6100 }
6101
6102 // Get table size
6103 nitems = data[0]->size ();
6104
6105 // Initialize Java String array
6106 Vector<void*> *table = new Vector<void*>(size + 2);
6107 Vector<char*> *jobjects = new Vector<char*>(nitems);
6108
6109 // Set the label
6110 for (index2 = 0; index2 < nitems; index2++)
6111 jobjects->store (index2, dbe_strdup (data[0]->fetch (index2).label));
6112 table->store (0, jobjects);
6113
6114 // Set the data
6115 for (index = 0; index <= size; index++)
6116 {
6117 Vector<double> *jd_list = new Vector<double>(nitems);
6118 for (index2 = 0; index2 < nitems; index2++)
6119 {
6120 double val = 0;
6121 if (data[index])
6122 val = data[index]->fetch (index2).value.to_double ();
6123 jd_list->store (index2, val);
6124 }
6125 table->store (index + 1, jd_list);
6126 }
6127 if (data)
6128 {
6129 for (index = 0; index <= size; index++)
6130 delete data[index];
6131 free (data);
6132 }
6133 return table;
6134}
6135
6136
6137//
6138// Set summary list
6139//
6140static void
6141setSummary (Vector<Histable*> *objs, Vector<int> *saligns,
6142 Vector<char> *mnemonic, Vector<char*> *jlabels, Vector<char*> *jvalues)
6143{
6144 char *sname = NULL, *oname = NULL, *lname = NULL, *alias = NULL,
6145 *mangle = NULL, *address = NULL, *size = NULL,
6146 *name_0 = NULL, *sname_0 = NULL, *oname_0 = NULL, *lname_0 = NULL,
6147 *alias_0 = NULL, *mangle_0 = NULL;
6148 Function *func, *last_func = NULL;
6149 int one_func = 1;
6150
6151 // Get the source/object/load-object files & aliases
6152 long long ll_size = 0;
6153 for (long i = 0; i < objs->size (); i++)
6154 {
6155 Histable *current_obj = objs->fetch (i);
6156 Histable::Type htype = current_obj->get_type ();
6157 if (htype == Histable::LOADOBJECT)
6158 lname = ((LoadObject *) current_obj)->dbeFile->get_location_info ();
6159 else if ((func = (Function*) current_obj->convertto (Histable::FUNCTION)) != NULL)
6160 {
6161 if (one_func && last_func != NULL && last_func != func)
6162 one_func = 0;
6163 last_func = func;
6164 sname = NULL;
6165 DbeLine *dbeline = (DbeLine*) current_obj->convertto (Histable::LINE);
6166 if (dbeline)
6167 {
6168 SourceFile *sf;
6169 if (dbeline->lineno == 0 && dbeline->include != NULL)
6170 sf = dbeline->include;
6171 else if (dbeline->sourceFile != NULL)
6172 sf = dbeline->sourceFile;
6173 else
6174 sf = func->getDefSrc ();
6175 if (sf)
6176 sname = sf->dbeFile->get_location_info ();
6177 }
6178 char *func_name = func->get_name ();
6179 mangle = func->get_mangled_name ();
6180 if (mangle && streq (func_name, mangle))
6181 mangle = NULL;
6182 Module *module = func->module;
6183 if (module != NULL)
6184 {
6185 module->read_stabs ();
6186 if (sname == NULL || strlen (sname) == 0)
6187 {
6188 SourceFile *sf = module->getMainSrc ();
6189 sname = sf->dbeFile->get_location_info ();
6190 }
6191 DbeFile *df = module->dbeFile;
6192 if (df == NULL || (df->filetype & DbeFile::F_JAVACLASS) == 0)
6193 df = module->loadobject->dbeFile;
6194 lname = df->get_location_info ();
6195 oname = lname;
6196 if (module->dot_o_file)
6197 oname = module->dot_o_file->dbeFile->get_location_info ();
6198 }
6199
6200 if (htype == Histable::INSTR && dbeSession->is_datamode_available ())
6201 alias = ((DbeInstr*) current_obj)->get_descriptor ();
6202 }
6203
6204 char *name = current_obj->get_name ();
6205 if (i == 0)
6206 {
6207 name_0 = name;
6208 lname_0 = lname;
6209 sname_0 = sname;
6210 oname_0 = oname;
6211 mangle_0 = mangle;
6212 alias_0 = alias;
6213 if (objs->size () == 1)
6214 {
6215 uint64_t addr = current_obj->get_addr ();
6216 address = dbe_sprintf (NTXT ("%lld:0x%08llX"),
6217 (long long) ADDRESS_SEG (addr),
6218 (long long) ADDRESS_OFF (addr));
6219 }
6220 }
6221 else
6222 {
6223 if (name_0 != name)
6224 name_0 = NULL;
6225 if (lname_0 != lname)
6226 lname_0 = NULL;
6227 if (sname_0 != sname)
6228 sname_0 = NULL;
6229 if (oname_0 != oname)
6230 oname_0 = NULL;
6231 if (mangle_0 != mangle)
6232 mangle_0 = NULL;
6233 if (alias_0 != alias)
6234 alias_0 = NULL;
6235 }
6236 if (current_obj->get_size () == -1)
6237 {
6238 if (size == NULL)
6239 size = dbe_strdup (GTXT ("(Unknown)"));
6240 }
6241 else
6242 ll_size += current_obj->get_size ();
6243 }
6244 if (size == NULL)
6245 size = dbe_sprintf (NTXT ("%lld"), ll_size);
6246 if (name_0 == NULL)
6247 {
6248 if (objs->size () > 1)
6249 {
6250 char *func_name = last_func == NULL ? NULL :
6251 (one_func == 0 ? NULL : last_func->get_name ());
6252 name_0 = dbe_sprintf (NTXT ("%s%s%s (%lld %s)"),
6253 func_name == NULL ? "" : func_name,
6254 func_name == NULL ? "" : ": ",
6255 GTXT ("Multiple Selection"),
6256 (long long) objs->size (),
6257 GTXT ("objects"));
6258 }
6259 }
6260 else
6261 name_0 = dbe_strdup (name_0);
6262
6263 // Set the name area
6264 saligns->store (0, TEXT_LEFT);
6265 mnemonic->store (0, 'N');
6266 jlabels->store (0, dbe_strdup (GTXT ("Name")));
6267 jvalues->store (0, name_0);
6268
6269 saligns->store (1, TEXT_LEFT);
6270 mnemonic->store (1, 'P');
6271 jlabels->store (1, dbe_strdup (GTXT ("PC Address")));
6272 jvalues->store (1, address);
6273
6274 saligns->store (2, TEXT_LEFT);
6275 mnemonic->store (2, 'z');
6276 jlabels->store (2, dbe_strdup (GTXT ("Size")));
6277 jvalues->store (2, size);
6278
6279 saligns->store (3, TEXT_RIGHT);
6280 mnemonic->store (3, 'r');
6281 jlabels->store (3, dbe_strdup (GTXT ("Source File")));
6282 jvalues->store (3, dbe_strdup (sname_0));
6283
6284 saligns->store (4, TEXT_RIGHT);
6285 mnemonic->store (4, 'b');
6286 jlabels->store (4, dbe_strdup (GTXT ("Object File")));
6287 jvalues->store (4, dbe_strdup (oname_0));
6288
6289 saligns->store (5, TEXT_LEFT);
6290 mnemonic->store (5, 'j');
6291 jlabels->store (5, dbe_strdup (GTXT ("Load Object")));
6292 jvalues->store (5, dbe_strdup (lname_0));
6293
6294 saligns->store (6, TEXT_LEFT);
6295 mnemonic->store (6, 'm');
6296 jlabels->store (6, dbe_strdup (GTXT ("Mangled Name")));
6297 jvalues->store (6, dbe_strdup (mangle_0));
6298
6299 saligns->store (7, TEXT_LEFT);
6300 mnemonic->store (7, 'A');
6301 jlabels->store (7, dbe_strdup (GTXT ("Aliases")));
6302 jvalues->store (7, dbe_strdup (alias_0));
6303}
6304
6305// Set memory-object summary list
6306//
6307static void
6308setMemSummary (Vector<Histable*> *objs, Vector<int> *saligns,
6309 Vector<char> *mnemonic, Vector<char*> *jlabels,
6310 Vector<char*> *jvalues)
6311{
6312 saligns->store (0, TEXT_LEFT);
6313 mnemonic->store (0, 'M');
6314 jlabels->store (0, dbe_strdup (GTXT ("Memory Object")));
6315 if (objs->size () == 1)
6316 {
6317 Histable *current_obj = objs->fetch (0);
6318 jvalues->store (0, dbe_strdup (current_obj->get_name ()));
6319 }
6320 else
6321 {
6322 char *name = dbe_sprintf (NTXT ("%s (%lld %s)"),
6323 GTXT ("Multiple Selection"),
6324 (long long) objs->size (), GTXT ("objects"));
6325 jvalues->store (0, name);
6326 }
6327}
6328
6329// Set index-object summary list
6330//
6331static void
6332setIndxSummary (Vector<Histable*> *objs, Vector<int> *saligns,
6333 Vector<char> *mnemonic, Vector<char*> *jlabels,
6334 Vector<char*> *jvalues)
6335{
6336 saligns->store (0, TEXT_LEFT);
6337 mnemonic->store (0, 'I');
6338 jlabels->store (0, dbe_strdup (GTXT ("Index Object")));
6339
6340 if (objs->size () == 1)
6341 {
6342 Histable *current_obj = objs->fetch (0);
6343 jvalues->store (0, dbe_strdup (current_obj->get_name ()));
6344 }
6345 else
6346 {
6347 char *name = dbe_sprintf (NTXT ("%s (%lld %s)"), GTXT ("Multiple Selection"),
6348 (long long) objs->size (), GTXT ("objects"));
6349 jvalues->store (0, name);
6350 }
6351}
6352
6353// Set I/O activity summary list
6354//
6355static void
6356setIOActivitySummary (Vector<Histable*> *objs, Vector<int> *saligns,
6357 Vector<char> *mnemonic, Vector<char*> *jlabels,
6358 Vector<char*> *jvalues)
6359{
6360 saligns->store (0, TEXT_LEFT);
6361 mnemonic->store (0, 'O');
6362 jlabels->store (0, dbe_strdup (GTXT ("I/O Activity")));
6363 if (objs->size () == 1)
6364 {
6365 Histable *current_obj = objs->fetch (0);
6366 jvalues->store (0, dbe_strdup (current_obj->get_name ()));
6367 }
6368 else
6369 {
6370 char *name = dbe_sprintf (NTXT ("%s (%lld %s)"), GTXT ("Multiple Selection"),
6371 (long long) objs->size (), GTXT ("objects"));
6372 jvalues->store (0, name);
6373 }
6374}
6375
6376// Set heap activity summary list
6377//
6378static void
6379setHeapActivitySummary (Vector<Histable*> *objs, Vector<int> *saligns,
6380 Vector<char> *mnemonic, Vector<char*> *jlabels,
6381 Vector<char*> *jvalues)
6382{
6383 saligns->store (0, TEXT_LEFT);
6384 mnemonic->store (0, 'O');
6385 jlabels->store (0, dbe_strdup (GTXT ("Heap Activity")));
6386
6387 if (objs->size () == 1)
6388 {
6389 Histable *current_obj = objs->fetch (0);
6390 jvalues->store (0, dbe_strdup (current_obj->get_name ()));
6391 }
6392 else
6393 {
6394 char *name = dbe_sprintf (NTXT ("%s (%lld %s)"), GTXT ("Multiple Selection"),
6395 (long long) objs->size (), GTXT ("objects"));
6396 jvalues->store (0, name);
6397 }
6398}
6399
6400//
6401// Set data-object summary list
6402//
6403static void
6404setDataSummary (Vector<Histable*> *objs, Vector<int> *saligns,
6405 Vector<char> *mnemonic, Vector<char*> *jlabels,
6406 Vector<char*> *jvalues)
6407{
6408 char *name, *type, *member, *elist;
6409 DataObject *dobj;
6410 Vector<DataObject *> *delem;
6411 Histable *scope;
6412 int index;
6413 char *size, *offset, *elements, *scopename;
6414
6415 // Get the data object elements
6416 member = elist = type = size = offset = elements = scopename = NULL;
6417
6418 if (objs->size () == 1)
6419 {
6420 Histable *current_obj = objs->fetch (0);
6421 name = dbe_strdup (current_obj->get_name ());
6422 dobj = (DataObject *) current_obj;
6423 type = dobj->get_typename ();
6424 scope = dobj->get_scope ();
6425 delem = dbeSession->get_dobj_elements (dobj);
6426 if (type == NULL)
6427 type = GTXT ("(Synthetic)");
6428 if (!scope)
6429 scopename = dbe_strdup (GTXT ("(Global)"));
6430 else
6431 {
6432 switch (scope->get_type ())
6433 {
6434 case Histable::FUNCTION:
6435 scopename = dbe_sprintf (NTXT ("%s(%s)"),
6436 ((Function*) scope)->module->get_name (),
6437 scope->get_name ());
6438 break;
6439 case Histable::LOADOBJECT:
6440 case Histable::MODULE:
6441 default:
6442 scopename = dbe_strdup (scope->get_name ());
6443 break;
6444 }
6445 }
6446
6447 if (dobj->get_offset () != -1)
6448 {
6449 if (dobj->get_parent ())
6450 member = dbe_strdup (dobj->get_parent ()->get_name ());
6451 offset = dbe_sprintf (NTXT ("%lld"), (long long) dobj->get_offset ());
6452 }
6453 size = dbe_sprintf ("%lld", (long long) dobj->get_size ());
6454
6455 if (delem->size () > 0)
6456 {
6457 elements = dbe_sprintf (NTXT ("%lld"), (long long) delem->size ());
6458 StringBuilder sb_tmp, sb;
6459 sb.append (GTXT ("Offset Size Name\n"));
6460 for (index = 0; index < delem->size (); index++)
6461 {
6462 DataObject *ditem = delem->fetch (index);
6463 sb_tmp.sprintf (NTXT ("%6lld %5lld %s\n"),
6464 (long long) ditem->get_offset (),
6465 (long long) ditem->get_size (), ditem->get_name ());
6466 sb.append (&sb_tmp);
6467 }
6468 if (sb.charAt (sb.length () - 1) == '\n')
6469 sb.setLength (sb.length () - 1);
6470 elist = sb.toString ();
6471 }
6472 }
6473 else
6474 name = dbe_sprintf (NTXT ("%s (%lld %s)"), GTXT ("Multiple Selection"),
6475 (long long) objs->size (), GTXT ("objects"));
6476
6477 saligns->store (0, TEXT_LEFT);
6478 mnemonic->store (0, 'D');
6479 jlabels->store (0, dbe_strdup (GTXT ("Data Object")));
6480 jvalues->store (0, name);
6481
6482 saligns->store (1, TEXT_LEFT);
6483 mnemonic->store (1, 'S');
6484 jlabels->store (1, dbe_strdup (GTXT ("Scope")));
6485 jvalues->store (1, scopename);
6486
6487 saligns->store (2, TEXT_LEFT);
6488 mnemonic->store (2, 'T');
6489 jlabels->store (2, dbe_strdup (GTXT ("Type")));
6490 jvalues->store (2, dbe_strdup (type));
6491
6492 saligns->store (3, TEXT_LEFT);
6493 mnemonic->store (3, 'M');
6494 jlabels->store (3, dbe_strdup (GTXT ("Member of")));
6495 jvalues->store (3, member);
6496
6497 saligns->store (4, TEXT_LEFT);
6498 mnemonic->store (4, 'O');
6499 jlabels->store (4, dbe_strdup (GTXT ("Offset")));
6500 jvalues->store (4, offset);
6501
6502 saligns->store (5, TEXT_LEFT);
6503 mnemonic->store (5, 'z');
6504 jlabels->store (5, dbe_strdup (GTXT ("Size")));
6505 jvalues->store (5, size);
6506
6507 saligns->store (6, TEXT_LEFT);
6508 mnemonic->store (6, 'E');
6509 jlabels->store (6, dbe_strdup (GTXT ("Elements")));
6510 jvalues->store (6, elements);
6511
6512 saligns->store (7, TEXT_LEFT);
6513 mnemonic->store (7, 'L');
6514 jlabels->store (7, dbe_strdup (GTXT ("List")));
6515 jvalues->store (7, elist);
6516}
6517
6518#define SUMMARY_NAME 8
6519#define DSUMMARY_NAME 8
6520#define LSUMMARY_NAME 7
6521#define IMSUMMARY_NAME 1
6522
6523Vector<void*> *
6524dbeGetSummaryV2 (int dbevindex, Vector<Obj> *sel_objs, int type, int subtype)
6525{
6526 if (sel_objs == NULL || sel_objs->size () == 0)
6527 return NULL;
6528 DbeView *dbev = dbeSession->getView (dbevindex);
6529 Vector<Histable*>*objs = new Vector<Histable*>(sel_objs->size ());
6530 for (int i = 0; i < sel_objs->size (); i++)
6531 {
6532 Histable *obj = (Histable *) sel_objs->fetch (i);
6533 if (obj == NULL)
6534 continue;
6535 char *nm = obj->get_name ();
6536 if (streq (nm, NTXT ("<Total>")))
6537 {
6538 // Special case for 'Total'.
6539 // Multi selection which includes 'Total' is only 'Total'
6540 objs->reset ();
6541 objs->append (obj);
6542 break;
6543 }
6544 objs->append (obj);
6545 }
6546 if (objs->size () == 0)
6547 return NULL;
6548
6549 // Set name area
6550 int nname = SUMMARY_NAME;
6551 Vector<int> *saligns = new Vector<int>(nname);
6552 Vector<char>*mnemonic = new Vector<char>(nname);
6553 Vector<char*> *jlabels = new Vector<char*>(nname);
6554 Vector<char*> *jvalues = new Vector<char*>(nname);
6555 Vector<void*> *name_objs = new Vector<void*>(4);
6556 name_objs->store (0, saligns);
6557 name_objs->store (1, mnemonic);
6558 name_objs->store (2, jlabels);
6559 name_objs->store (3, jvalues);
6560 setSummary (objs, saligns, mnemonic, jlabels, jvalues);
6561
6562 MetricList *prop_mlist = new MetricList (dbev->get_metric_ref (MET_NORMAL));
6563 if (prop_mlist && dbev->comparingExperiments ())
6564 prop_mlist = dbev->get_compare_mlist (prop_mlist, 0);
6565
6566 int nitems = prop_mlist->get_items ()->size ();
6567
6568 // Set the metrics area
6569 jlabels = new Vector<char*>(nitems);
6570 Vector<double> *clock_list = new Vector<double>(nitems);
6571 Vector<double> *excl_list = new Vector<double>(nitems);
6572 Vector<double> *ep_list = new Vector<double>(nitems);
6573 Vector<double> *incl_list = new Vector<double>(nitems);
6574 Vector<double> *ip_list = new Vector<double>(nitems);
6575 Vector<int> *vtype = new Vector<int>(nitems);
6576
6577 // Initialize Java String array
6578 Vector<void*> *metric_objs = new Vector<void*>(8);
6579 metric_objs->store (0, jlabels);
6580 metric_objs->store (1, clock_list);
6581 metric_objs->store (2, excl_list);
6582 metric_objs->store (3, ep_list);
6583 metric_objs->store (4, incl_list);
6584 metric_objs->store (5, ip_list);
6585 metric_objs->store (6, vtype);
6586
6587 int last_init = -1;
6588 for (int i = 0; i < objs->size (); i++)
6589 {
6590 Histable *obj = objs->fetch (i);
6591 // Get the data to be displayed
6592 Hist_data *data = dbev->get_hist_data (prop_mlist, obj->get_type (), subtype,
6593 Hist_data::SELF, obj, dbev->sel_binctx, objs);
6594
6595 if (data->get_status () != Hist_data::SUCCESS)
6596 {
6597 if (type != DSP_DLAYOUT)
6598 { // For data_layout, rows with zero metrics are OK
6599 delete data;
6600 continue;
6601 }
6602 }
6603 TValue *values = NULL;
6604 if (data->get_status () == Hist_data::SUCCESS)
6605 {
6606 Hist_data::HistItem *hi = data->fetch (0);
6607 if (hi)
6608 values = hi->value;
6609 }
6610 Hist_data::HistItem *total = data->get_totals ();
6611 int index2 = 0;
6612 char *tstr = GTXT (" Time");
6613 char *estr = GTXT ("Exclusive ");
6614 size_t len = strlen (estr);
6615
6616 // get the metric list from the data
6617 MetricList *mlist = data->get_metric_list ();
6618 int index;
6619 Metric *mitem;
6620 double clock;
6621 Vec_loop (Metric*, mlist->get_items (), index, mitem)
6622 {
6623 if (mitem->get_subtype () == Metric::STATIC)
6624 continue;
6625 if (last_init < index2)
6626 {
6627 last_init = index2;
6628 jlabels->store (index2, NULL);
6629 clock_list->store (index2, 0.0);
6630 excl_list->store (index2, 0.0);
6631 ep_list->store (index2, 0.0);
6632 incl_list->store (index2, 0.0);
6633 ip_list->store (index2, 0.0);
6634 vtype->store (index2, 0);
6635 }
6636 double dvalue = (values != NULL) ? values[index].to_double () : 0.0;
6637 double dtotal = total->value[index].to_double ();
6638 if (mitem->is_time_val ())
6639 clock = 1.e+6 * dbeSession->get_clock (-1);
6640 else
6641 clock = 0.0;
6642
6643 clock_list->store (index2, clock);
6644 if ((mitem->get_subtype () == Metric::EXCLUSIVE) ||
6645 (mitem->get_subtype () == Metric::DATASPACE))
6646 {
6647 if (i == 0)
6648 {
6649 char *sstr = mitem->get_name ();
6650 if (!strncmp (sstr, estr, len))
6651 sstr += len;
6652 char *buf, *lstr = strstr (sstr, tstr);
6653 if (lstr)
6654 buf = dbe_strndup (sstr, lstr - sstr);
6655 else
6656 buf = dbe_strdup (sstr);
6657 jlabels->store (index2, buf);
6658 vtype->store (index2, mitem->get_vtype ());
6659 }
6660 dvalue += excl_list->fetch (index2);
6661 double percent = dtotal == 0.0 ? dtotal : (dvalue / dtotal) * 100;
6662 excl_list->store (index2, dvalue);
6663 ep_list->store (index2, percent);
6664 }
6665 else
6666 {
6667 dvalue += incl_list->fetch (index2);
6668 if (dvalue > dtotal)
6669 dvalue = dtotal; // temporary correction
6670 double percent = dtotal == 0.0 ? dtotal : (dvalue / dtotal) * 100;
6671 incl_list->store (index2, dvalue);
6672 ip_list->store (index2, percent);
6673 index2++;
6674 }
6675 }
6676 delete data;
6677 }
6678 delete prop_mlist;
6679 Vector<void*> *summary = new Vector<void*>(2);
6680 summary->store (0, name_objs);
6681 summary->store (1, metric_objs);
6682 return summary;
6683}
6684
6685// Get Summary List
6686Vector<void*> *
6687dbeGetSummary (int dbevindex, Vector<Obj> *sel_objs, int type, int subtype)
6688{
6689 bool is_data, is_mem, is_indx, is_iodata, is_heapdata;
6690 Hist_data::HistItem *total;
6691 MetricList *prop_mlist; // as passed to get_hist_data
6692 MetricList *mlist; // as stored in the data
6693 Metric *mitem;
6694 int i, nname, nitems, index, index2;
6695 TValue *values;
6696 double dvalue, clock;
6697 Hist_data *data;
6698 Vector<double> *percent_scale;
6699
6700 DbeView *dbev = dbeSession->getView (dbevindex);
6701 if (dbev == NULL)
6702 abort ();
6703 if (sel_objs == NULL || sel_objs->size () == 0)
6704 return NULL;
6705
6706 is_mem = false;
6707 is_data = false;
6708 is_indx = false;
6709 is_iodata = false;
6710 is_heapdata = false;
6711 nname = SUMMARY_NAME;
6712 Vector<Histable*>*objs = new Vector<Histable*>(sel_objs->size ());
6713 if (type == DSP_TIMELINE)
6714 objs->append ((Histable *) sel_objs->fetch (0));
6715 else
6716 {
6717 switch (type)
6718 {
6719 case DSP_FUNCTION:
6720 data = dbev->func_data;
6721 break;
6722 case DSP_LINE:
6723 data = dbev->line_data;
6724 break;
6725 case DSP_PC:
6726 data = dbev->pc_data;
6727 break;
6728 case DSP_SELF:
6729 data = dbev->fitem_data;
6730 break;
6731 case DSP_SOURCE:
6732 case DSP_SOURCE_V2:
6733 data = dbev->src_data;
6734 break;
6735 case DSP_DISASM:
6736 case DSP_DISASM_V2:
6737 data = dbev->dis_data;
6738 break;
6739 case DSP_DLAYOUT:
6740 is_data = true;
6741 nname = LSUMMARY_NAME;
6742 data = dbev->dlay_data;
6743 break;
6744 case DSP_DATAOBJ:
6745 is_data = true;
6746 nname = DSUMMARY_NAME;
6747 data = dbev->dobj_data;
6748 break;
6749 case DSP_MEMOBJ:
6750 is_data = true;
6751 is_mem = true;
6752 nname = IMSUMMARY_NAME;
6753 data = dbev->get_indxobj_data (subtype);
6754 break;
6755 case DSP_INDXOBJ:
6756 is_indx = true;
6757 nname = IMSUMMARY_NAME;
6758 data = dbev->get_indxobj_data (subtype);
6759 break;
6760 case DSP_IOACTIVITY:
6761 is_iodata = true;
6762 nname = IMSUMMARY_NAME;
6763 data = dbev->iofile_data;
6764 break;
6765 case DSP_IOVFD:
6766 is_iodata = true;
6767 nname = IMSUMMARY_NAME;
6768 data = dbev->iovfd_data;
6769 break;
6770 case DSP_IOCALLSTACK:
6771 is_iodata = true;
6772 nname = IMSUMMARY_NAME;
6773 data = dbev->iocs_data;
6774 break;
6775 case DSP_HEAPCALLSTACK:
6776 is_heapdata = true;
6777 nname = IMSUMMARY_NAME;
6778 data = dbev->heapcs_data;
6779 break;
6780 default:
6781 data = NULL;
6782 break;
6783 }
6784 if (data == NULL || data->get_status () != Hist_data::SUCCESS)
6785 return NULL;
6786
6787 Hist_data::HistItem *current_item;
6788 for (i = 0; i < sel_objs->size (); i++)
6789 {
6790 int sel_index = (int) sel_objs->fetch (i);
6791 if (type != DSP_IOACTIVITY && type != DSP_IOVFD &&
6792 type != DSP_IOCALLSTACK && type != DSP_HEAPCALLSTACK)
6793 {
6794 if (sel_index < 0 || sel_index >= data->size ())
6795 continue;
6796 current_item = data->fetch (sel_index);
6797 if (current_item->obj == NULL)
6798 continue;
6799 }
6800 else
6801 {
6802 if (sel_index < 0)
6803 continue;
6804 bool found = false;
6805 for (int j = 0; j < data->size (); j++)
6806 {
6807 current_item = data->fetch (j);
6808 if ((current_item->obj != NULL) && (current_item->obj->id == sel_index))
6809 {
6810 found = true;
6811 break;
6812 }
6813 }
6814 if (!found)
6815 continue;
6816 }
6817 char *nm = current_item->obj->get_name ();
6818 if (streq (nm, NTXT ("<Total>")))
6819 {
6820 // Special case for 'Total'.
6821 // Multi selection which includes 'Total' is only 'Total'
6822 objs->reset ();
6823 objs->append (current_item->obj);
6824 break;
6825 }
6826 objs->append (current_item->obj);
6827 }
6828 }
6829 if (objs->size () == 0)
6830 return NULL;
6831
6832 // Set name area
6833 Vector<int> *saligns = new Vector<int>(nname);
6834 Vector<char>*mnemonic = new Vector<char>(nname);
6835 Vector<char*> *jlabels = new Vector<char*>(nname);
6836 Vector<char*> *jvalues = new Vector<char*>(nname);
6837 Vector<void*> *name_objs = new Vector<void*>(4);
6838 name_objs->store (0, saligns);
6839 name_objs->store (1, mnemonic);
6840 name_objs->store (2, jlabels);
6841 name_objs->store (3, jvalues);
6842 if (is_mem)
6843 setMemSummary (objs, saligns, mnemonic, jlabels, jvalues);
6844 else if (is_indx)
6845 setIndxSummary (objs, saligns, mnemonic, jlabels, jvalues);
6846 else if (is_data)
6847 setDataSummary (objs, saligns, mnemonic, jlabels, jvalues);
6848 else if (is_iodata)
6849 setIOActivitySummary (objs, saligns, mnemonic, jlabels, jvalues);
6850 else if (is_heapdata)
6851 setHeapActivitySummary (objs, saligns, mnemonic, jlabels, jvalues);
6852 else
6853 setSummary (objs, saligns, mnemonic, jlabels, jvalues);
6854
6855 // Get the reference metrics
6856 if (is_data)
6857 prop_mlist = new MetricList (dbev->get_metric_ref (MET_DATA));
6858 else if (is_indx)
6859 prop_mlist = new MetricList (dbev->get_metric_ref (MET_INDX));
6860 else if (is_iodata)
6861 prop_mlist = new MetricList (dbev->get_metric_ref (MET_IO));
6862 else if (is_heapdata)
6863 prop_mlist = new MetricList (dbev->get_metric_ref (MET_HEAP));
6864 else
6865 prop_mlist = new MetricList (dbev->get_metric_ref (MET_NORMAL));
6866
6867 // XXXX a workaround to avoid aggregated data for compare mode, only show base experiment data
6868 if (prop_mlist && dbev->comparingExperiments ())
6869 prop_mlist = dbev->get_compare_mlist (prop_mlist, 0);
6870 nitems = prop_mlist->get_items ()->size ();
6871
6872 // Set the metrics area
6873 jlabels = new Vector<char*>(nitems);
6874 Vector<double> *clock_list = new Vector<double>(nitems);
6875 Vector<double> *excl_list = new Vector<double>(nitems);
6876 Vector<double> *ep_list = new Vector<double>(nitems);
6877 Vector<double> *incl_list = new Vector<double>(nitems);
6878 Vector<double> *ip_list = new Vector<double>(nitems);
6879 Vector<int> *vtype = new Vector<int>(nitems);
6880
6881 // Initialize Java String array
6882 Vector<void*> *metric_objs = new Vector<void*>(8);
6883 metric_objs->store (0, jlabels);
6884 metric_objs->store (1, clock_list);
6885 metric_objs->store (2, excl_list);
6886 metric_objs->store (3, ep_list);
6887 metric_objs->store (4, incl_list);
6888 metric_objs->store (5, ip_list);
6889 metric_objs->store (6, vtype);
6890 percent_scale = new Vector<double>();
6891 int last_init = -1;
6892 for (i = 0; i < objs->size (); i++)
6893 {
6894 Histable *current_obj = objs->fetch (i);
6895 // Get the data to be displayed
6896 data = dbev->get_hist_data (prop_mlist, current_obj->get_type (), subtype,
6897 Hist_data::SELF, current_obj, dbev->sel_binctx, objs);
6898 if (data->get_status () != Hist_data::SUCCESS)
6899 {
6900 if (type != DSP_DLAYOUT)
6901 { // For data_layout, rows with zero metrics are OK
6902 delete data;
6903 continue;
6904 }
6905 }
6906 Hist_data::HistItem *hi = data->fetch (0);
6907 values = hi ? hi->value : NULL;
6908 total = data->get_totals ();
6909 index2 = 0;
6910
6911 // get the metric list from the data
6912 mlist = data->get_metric_list ();
6913
6914 // We loop over the metrics in mlist.
6915 // We construct index2, which tells us
6916 // the corresponding entry in the metric_objs lists.
6917 // We need this mapping multiple times.
6918 // So, if you change the looping in any way here,
6919 // do so as well in other similar loops.
6920 // All such loops are marked so:
6921 // See discussion on "mlist-to-index2 mapping".
6922
6923 Vec_loop (Metric*, mlist->get_items (), index, mitem)
6924 {
6925 if (mitem->get_subtype () == Metric::STATIC)
6926 continue;
6927 if (last_init < index2)
6928 {
6929 last_init = index2;
6930 jlabels->store (index2, NULL);
6931 clock_list->store (index2, 0.0);
6932 excl_list->store (index2, 0.0);
6933 ep_list->store (index2, 0.0);
6934 incl_list->store (index2, 0.0);
6935 ip_list->store (index2, 0.0);
6936 vtype->store (index2, 0);
6937 }
6938 dvalue = (values != NULL) ? values[index].to_double () : 0.0;
6939 double dtotal = total->value[index].to_double ();
6940 percent_scale->store (index, dtotal == 0. ? 0. : 100. / dtotal);
6941 if (mitem->is_time_val ())
6942 clock = 1.e+6 * dbeSession->get_clock (-1);
6943 else
6944 clock = 0.0;
6945
6946 clock_list->store (index2, clock);
6947 if (mitem->get_subtype () == Metric::EXCLUSIVE ||
6948 mitem->get_subtype () == Metric::DATASPACE)
6949 {
6950 if (i == 0)
6951 {
6952 char *sstr = mitem->get_username ();
6953 char *buf = dbe_strdup (sstr);
6954 jlabels->store (index2, buf);
6955 vtype->store (index2, mitem->get_vtype ());
6956 }
6957 dvalue += excl_list->fetch (index2);
6958 double percent = dvalue * percent_scale->fetch (index);
6959 excl_list->store (index2, dvalue);
6960 ep_list->store (index2, percent);
6961 if (is_data || is_indx || is_iodata || is_heapdata)
6962 // move to next row, except if there's inclusive data, too
6963 index2++;
6964 }
6965 else
6966 {
6967 dvalue += incl_list->fetch (index2);
6968 if (dvalue > dtotal && mitem->get_type () != BaseMetric::DERIVED)
6969 dvalue = dtotal; // temporary correction
6970 double percent = dvalue * percent_scale->fetch (index);
6971 incl_list->store (index2, dvalue);
6972 ip_list->store (index2, percent);
6973 index2++;
6974 }
6975 }
6976 delete data;
6977 }
6978
6979 // for multi-selection, we have to recompute the derived metrics
6980 if (objs->size () > 1 &&
6981 dbev->get_derived_metrics () != NULL &&
6982 dbev->get_derived_metrics ()->get_items () != NULL &&
6983 dbev->get_derived_metrics ()->get_items ()->size () > 0)
6984 {
6985 // See discussion on "mlist-to-index2 mapping".
6986 Vector<Metric*> *mvec = new Vector<Metric*>(nitems);
6987 index2 = 0;
6988 Vec_loop (Metric*, prop_mlist->get_items (), index, mitem)
6989 {
6990 if (mitem->get_subtype () == Metric::STATIC)
6991 continue;
6992 if (mitem->get_subtype () == Metric::EXCLUSIVE ||
6993 mitem->get_subtype () == Metric::DATASPACE)
6994 {
6995 mvec->store (index2, mitem);
6996 if (is_data || is_indx || is_iodata || is_heapdata)
6997 index2++;
6998 }
6999 else
7000 {
7001 assert (strcmp (mvec->fetch (index2)->get_cmd (), mitem->get_cmd ()) == 0);
7002 index2++;
7003 }
7004 }
7005 int *map = dbev->get_derived_metrics ()->construct_map (mvec, BaseMetric::EXCLUSIVE, mvec->fetch (0)->get_expr_spec ());
7006 if (map != NULL)
7007 {
7008 int nmetrics = mvec->size ();
7009 double *evalues = (double *) malloc (nmetrics * sizeof (double));
7010 double *ivalues = (double *) malloc (nmetrics * sizeof (double));
7011 for (index2 = 0; index2 < nmetrics; index2++)
7012 {
7013 evalues[index2] = excl_list->fetch (index2);
7014 ivalues[index2] = incl_list->fetch (index2);
7015 }
7016
7017 // evaluate derived metrics
7018 dbev->get_derived_metrics ()->eval (map, evalues);
7019 dbev->get_derived_metrics ()->eval (map, ivalues);
7020 for (index2 = 0; index2 < nmetrics; index2++)
7021 {
7022 excl_list->store (index2, evalues[index2]);
7023 incl_list->store (index2, ivalues[index2]);
7024 }
7025
7026 // recompute percentages for derived metrics EUGENE maybe all percentage computations should be moved here
7027 // See discussion on "mlist-to-index2 mapping".
7028 index2 = 0;
7029 Vec_loop (Metric*, prop_mlist->get_items (), index, mitem)
7030 {
7031 if (mitem->get_subtype () == Metric::STATIC)
7032 continue;
7033 if (mitem->get_subtype () == Metric::EXCLUSIVE ||
7034 mitem->get_subtype () == Metric::DATASPACE)
7035 {
7036 if (mitem->get_type () == BaseMetric::DERIVED)
7037 ep_list->store (index2, excl_list->fetch (index2) * percent_scale->fetch (index));
7038 if (is_data || is_indx || is_iodata || is_heapdata)
7039 index2++;
7040 }
7041 else
7042 {
7043 if (mitem->get_type () == BaseMetric::DERIVED)
7044 ip_list->store (index2, incl_list->fetch (index2) * percent_scale->fetch (index));
7045 index2++;
7046 }
7047 }
7048 free (evalues);
7049 free (ivalues);
7050 free (map);
7051 }
7052 delete mvec;
7053 }
7054 delete prop_mlist;
7055 Vector<void*> *summary = new Vector<void*>(2);
7056 summary->store (0, name_objs);
7057 summary->store (1, metric_objs);
7058 delete objs;
7059 delete percent_scale;
7060 return summary;
7061}
7062
7063char *
7064dbeGetExpName (int /*dbevindex*/, char *dir_name)
7065{
7066 char *ret;
7067 char *warn;
7068 if (col_ctr == NULL)
7069 col_ctr = new Coll_Ctrl (1); // Potential race condition?
7070 if (dir_name != NULL)
7071 {
7072 ret = col_ctr->set_directory (dir_name, &warn);
7073 // note that the warning and error msgs are written to stderr, not returned to caller
7074 if (warn != NULL)
7075 fprintf (stderr, NTXT ("%s"), warn);
7076 if (ret != NULL)
7077 fprintf (stderr, NTXT ("%s"), ret);
7078 }
7079 return dbe_strdup (col_ctr->get_expt ());
7080}
7081
7082// === CollectDialog HWC info ===
7083
7084Vector<Vector<char*>*> *
7085dbeGetHwcSets (int /*dbevindex*/, bool forKernel)
7086{
7087 Vector<Vector<char*>*> *list = new Vector<Vector<char*>*>(2);
7088 char * defctrs = hwc_get_default_cntrs2 (forKernel, 1);
7089 Vector<char*> *i18n = new Vector<char*>(1); // User name
7090 Vector<char*> *name = new Vector<char*>(1); // Internal name
7091 if (NULL != defctrs)
7092 {
7093 i18n->store (0, strdup (defctrs));
7094 name->store (0, strdup (NTXT ("default")));
7095 }
7096 list->store (0, i18n);
7097 list->store (1, name);
7098 return list;
7099}
7100
7101static Vector<void*> *
7102dbeGetHwcs (Hwcentry **hwcs)
7103{
7104 int sz;
7105 for (sz = 0; hwcs && hwcs[sz]; sz++)
7106 ;
7107 Vector<void*> *list = new Vector<void*>(9);
7108 Vector<char*> *i18n = new Vector<char*>(sz);
7109 Vector<char*> *name = new Vector<char*>(sz);
7110 Vector<char*> *int_name = new Vector<char*>(sz);
7111 Vector<char*> *metric = new Vector<char*>(sz);
7112 Vector<long long> *val = new Vector<long long>(sz);
7113 Vector<int> *timecvt = new Vector<int>(sz);
7114 Vector<int> *memop = new Vector<int>(sz);
7115 Vector<char*> *short_desc = new Vector<char*>(sz);
7116 Vector<Vector<int>*> *reglist_v = new Vector<Vector<int>*>(sz);
7117 Vector<bool> *supportsAttrs = new Vector<bool>(sz);
7118 Vector<bool> *supportsMemspace = new Vector<bool>(sz);
7119
7120 for (int i = 0; i < sz; i++)
7121 {
7122 Hwcentry *ctr = hwcs[i];
7123 Vector<int> *registers = new Vector<int>(MAX_PICS);
7124 regno_t *reglist = ctr->reg_list;
7125 for (int k = 0; !REG_LIST_EOL (reglist[k]) && k < MAX_PICS; k++)
7126 registers->store (k, reglist[k]);
7127
7128 i18n->store (i, dbe_strdup (hwc_i18n_metric (ctr)));
7129 name->store (i, dbe_strdup (ctr->name));
7130 int_name->store (i, dbe_strdup (ctr->int_name));
7131 metric->store (i, dbe_strdup (ctr->metric));
7132 val->store (i, ctr->val); // signed promotion from int
7133 timecvt->store (i, ctr->timecvt);
7134 memop->store (i, ctr->memop);
7135 reglist_v->store (i, registers);
7136 short_desc->store (i, dbe_strdup (ctr->short_desc));
7137 supportsAttrs->store (i, true);
7138 supportsMemspace->store (i, ABST_MEMSPACE_ENABLED (ctr->memop));
7139 }
7140 list->store (0, i18n);
7141 list->store (1, name);
7142 list->store (2, int_name);
7143 list->store (3, metric);
7144 list->store (4, val);
7145 list->store (5, timecvt);
7146 list->store (6, memop);
7147 list->store (7, short_desc);
7148 list->store (8, reglist_v);
7149 list->store (9, supportsAttrs);
7150 list->store (10, supportsMemspace);
7151 return list;
7152}
7153
7154Vector<void *> *
7155dbeGetHwcsAll (int /*dbevindex*/, bool forKernel)
7156{
7157 Vector<void*> *list = new Vector<void*>(2);
7158 list->store (0, dbeGetHwcs (hwc_get_std_ctrs (forKernel)));
7159 list->store (1, dbeGetHwcs (hwc_get_raw_ctrs (forKernel)));
7160 return list;
7161}
7162
7163Vector<char*> *
7164dbeGetHwcHelp (int /*dbevindex*/, bool forKernel)
7165{
7166 Vector<char*> *strings = new Vector<char*>(32);
7167 FILE *f = tmpfile ();
7168 hwc_usage_f (forKernel, f, "", 0, 0, 1); // writes to f
7169 fflush (f);
7170 fseek (f, 0, SEEK_SET);
7171#define MAX_LINE_LEN 2048
7172 char buff[MAX_LINE_LEN];
7173 int ii = 0;
7174 while (fgets (buff, MAX_LINE_LEN, f))
7175 strings->store (ii++, dbe_strdup (buff));
7176 fclose (f);
7177 return strings;
7178}
7179
7180Vector<char*> *
7181dbeGetHwcAttrList (int /*dbevindex*/, bool forKernel)
7182{
7183 char ** attr_list = hwc_get_attrs (forKernel); // Get Attribute list
7184 int size;
7185 for (size = 0; attr_list && attr_list[size]; size++)
7186 ;
7187
7188 Vector<char*> *name = new Vector<char*>(size);
7189 for (int i = 0; i < size; i++)
7190 name->store (i, dbe_strdup (attr_list[i]));
7191 return name;
7192}
7193
7194//Get maximum number of simultaneous counters
7195int
7196dbeGetHwcMaxConcurrent (int /*dbevindex*/, bool forKernel)
7197{
7198 return hwc_get_max_concurrent (forKernel);
7199}
7200
7201// === End CollectDialog HWC info ===
7202
7203
7204// Instruction-frequency data
7205Vector<char*> *
7206dbeGetIfreqData (int dbevindex)
7207{
7208 DbeView *dbev = dbeSession->getView (dbevindex);
7209 if (dbev == NULL)
7210 abort ();
7211 if (!dbeSession->is_ifreq_available ())
7212 return NULL;
7213 int size = dbeSession->nexps ();
7214 if (size == 0)
7215 return NULL;
7216
7217 // Initialize Java String array
7218 Vector<char*> *list = new Vector<char*>();
7219 for (int i = 0; i < size; i++)
7220 {
7221 Experiment *exp = dbeSession->get_exp (i);
7222 if (exp->broken || !dbev->get_exp_enable (i) || !exp->ifreqavail)
7223 continue;
7224 // write a header for the experiment
7225 list->append (dbe_sprintf (GTXT ("Instruction frequency data from experiment %s\n\n"),
7226 exp->get_expt_name ()));
7227 // add its instruction frequency messages
7228 char *ifreq = pr_mesgs (exp->fetch_ifreq (), NTXT (""), NTXT (""));
7229 list->append (ifreq);
7230 }
7231 return list;
7232}
7233
7234// LeakList related methods
7235//
7236Vector<void*> *
7237dbeGetLeakListInfo (int dbevindex, bool leakflag)
7238{
7239 DbeView *dbev = dbeSession->getView (dbevindex);
7240 if (dbev == NULL)
7241 abort ();
7242 MetricList *origmlist = dbev->get_metric_list (MET_NORMAL);
7243 MetricList *nmlist = new MetricList (origmlist);
7244 if (leakflag)
7245 nmlist->set_metrics (NTXT ("e.heapleakbytes:e.heapleakcnt:name"), true,
7246 dbev->get_derived_metrics ());
7247 else
7248 nmlist->set_metrics (NTXT ("e.heapallocbytes:e.heapalloccnt:name"), true,
7249 dbev->get_derived_metrics ());
7250 MetricList *mlist = new MetricList (nmlist);
7251 delete nmlist;
7252
7253 CStack_data *lam = dbev->get_cstack_data (mlist);
7254 if (lam == NULL || lam->size () == 0)
7255 {
7256 delete lam;
7257 delete mlist;
7258 return NULL;
7259 }
7260 Vector<Vector<Obj>*> *evalue = new Vector<Vector<Obj>*>(lam->size ());
7261 Vector<Vector<Obj>*> *pcstack = new Vector<Vector<Obj>*>(lam->size ());
7262 Vector<Vector<Obj>*> *offstack = new Vector<Vector<Obj>*>(lam->size ());
7263 Vector<Vector<Obj>*> *fpcstack = new Vector<Vector<Obj>*>(lam->size ());
7264 Vector<Vector<Obj>*> *sumval = new Vector<Vector<Obj>*>(lam->size ());
7265
7266 int index;
7267 CStack_data::CStack_item *lae;
7268 Vec_loop (CStack_data::CStack_item*, lam->cstack_items, index, lae)
7269 {
7270 Vector<Obj> *jivals = NULL;
7271 if (lae != NULL)
7272 {
7273 jivals = new Vector<Obj>(4);
7274 jivals->store (0, (Obj) (index + 1));
7275 jivals->store (1, (Obj) lae->value[1].ll);
7276 jivals->store (2, (Obj) lae->value[0].ll);
7277 jivals->store (3, (Obj) (leakflag ? 1 : 2));
7278 }
7279 evalue->store (index, jivals);
7280 int snum = lae->stack->size ();
7281 Vector<Obj> *jivals1 = new Vector<Obj>(snum);
7282 Vector<Obj> *jivals2 = new Vector<Obj>(snum);
7283 Vector<Obj> *jivals3 = new Vector<Obj>(snum);
7284 if (lae->stack != NULL)
7285 {
7286 for (int i = lae->stack->size () - 1; i >= 0; i--)
7287 {
7288 DbeInstr *instr = lae->stack->fetch (i);
7289 jivals1->store (i, (Obj) instr);
7290 jivals2->store (i, (Obj) instr->func);
7291 jivals3->store (i, (Obj) instr->addr);
7292 }
7293 }
7294 fpcstack->store (index, jivals1);
7295 pcstack->store (index, jivals2);
7296 offstack->store (index, jivals3);
7297 lae++;
7298 }
7299 Vector<Obj> *jivals4 = new Vector<Obj>(3);
7300 jivals4->store (0, (Obj) lam->size ());
7301 jivals4->store (1, (Obj) lam->total->value[1].ll);
7302 jivals4->store (2, (Obj) lam->total->value[0].ll);
7303 sumval->store (0, jivals4);
7304 delete lam;
7305 delete mlist;
7306 Vector<void*> *earray = new Vector<void*>(5);
7307 earray->store (0, evalue);
7308 earray->store (1, pcstack);
7309 earray->store (2, offstack);
7310 earray->store (3, fpcstack);
7311 earray->store (4, sumval);
7312 return earray;
7313}
7314
7315// Map timeline address to function instr
7316//
7317Obj
7318dbeGetObject (int dbevindex, Obj sel_func, Obj sel_pc)
7319{
7320 DbeView *dbev = dbeSession->getView (dbevindex);
7321 if (dbev == NULL)
7322 abort ();
7323 if (sel_pc)
7324 return sel_pc;
7325 return sel_func;
7326}
7327
7328char *
7329dbeGetName (int /*dbevindex*/, int exp_id)
7330// This function's name is not descriptive enough - it returns a string
7331// containing the full experiment name with path, process name, and PID.
7332// There are various dbe functions that provide experiment name and experiment
7333// details, and they should probably be consolidated/refactored. (TBR)
7334// For another example of similar output formatting, see dbeGetExpName().
7335{
7336 int id = (exp_id < 0) ? 0 : exp_id;
7337 Experiment *exp = dbeSession->get_exp (id);
7338 if (exp == NULL)
7339 return NULL;
7340 char *buf =
7341 dbe_sprintf (NTXT ("%s [%s, PID %d]"),
7342 exp->get_expt_name (),
7343 exp->utargname != NULL ? exp->utargname : GTXT ("(unknown)"),
7344 exp->getPID ());
7345 return buf;
7346}
7347
7348Vector<char*> *
7349dbeGetExpVerboseName (Vector<int> *exp_ids)
7350{
7351 int len = exp_ids->size ();
7352 Vector<char*> *list = new Vector<char*>(len);
7353 for (int i = 0; i < len; i++)
7354 {
7355 char * verboseName = dbeGetName (0, exp_ids->fetch (i)); // no strdup()
7356 list->store (i, verboseName);
7357 }
7358 return list;
7359}
7360
7361long long
7362dbeGetStartTime (int /*dbevindex*/, int exp_id)
7363{
7364 int id = (exp_id < 0) ? 0 : exp_id;
7365 Experiment *exp = dbeSession->get_exp (id);
7366 return exp ? exp->getStartTime () : (long long) 0;
7367}
7368
7369long long
7370dbeGetRelativeStartTime (int /*dbevindex*/, int exp_id)
7371{
7372 int id = (exp_id < 0) ? 0 : exp_id;
7373 Experiment *exp = dbeSession->get_exp (id);
7374 return exp ? exp->getRelativeStartTime () : (long long) 0;
7375}
7376
7377long long
7378dbeGetEndTime (int /*dbevindex*/, int exp_id)
7379{
7380 int id = (exp_id < 0) ? 0 : exp_id;
7381 Experiment *exp = dbeSession->get_exp (id);
7382
7383 // Experiment::getEndTime was initially implemented as
7384 // returning exp->last_event. To preserve the semantics
7385 // new Experiment::getLastEvent() is used here.
7386 return exp ? exp->getLastEvent () : (long long) 0;
7387}
7388
7389int
7390dbeGetClock (int /*dbevindex*/, int exp_id)
7391{
7392 return dbeSession->get_clock (exp_id);
7393}
7394
7395long long
7396dbeGetWallStartSec (int /*dbevindex*/, int exp_id)
7397{
7398 int id = (exp_id < 0) ? 0 : exp_id;
7399 Experiment *exp = dbeSession->get_exp (id);
7400 return exp ? exp->getWallStartSec () : 0ll;
7401}
7402
7403char *
7404dbeGetHostname (int /*dbevindex*/, int exp_id)
7405{
7406 int id = (exp_id < 0) ? 0 : exp_id;
7407 Experiment *exp = dbeSession->get_exp (id);
7408 return exp ? dbe_strdup (exp->hostname) : NULL;
7409}
7410
7411static DataView *
7412getTimelinePackets (int dbevindex, int exp_id, int data_id, int entity_prop_id)
7413{
7414 DbeView *dbev = dbeSession->getView (dbevindex);
7415 if (dbev == NULL)
7416 abort ();
7417 const int sortprop_count = 3;
7418 const int sortprops[sortprop_count] = {
7419 PROP_HWCTAG, // aux
7420 entity_prop_id,
7421 PROP_TSTAMP
7422 };
7423 DataView *packets = dbev->get_filtered_events (exp_id, data_id,
7424 sortprops, sortprop_count);
7425 return packets;
7426}
7427
7428static long
7429getIdxByVals (DataView * packets, int aux, int entity_prop_val,
7430 uint64_t time, DataView::Relation rel)
7431{
7432 const int sortprop_count = 3;
7433 Datum tval[sortprop_count];
7434 tval[0].setUINT32 (aux);
7435 tval[1].setUINT32 (entity_prop_val); //CPUID, LWPID, THRID are downsized to 32
7436 tval[2].setUINT64 (time);
7437 long idx = packets->getIdxByVals (tval, rel);
7438 return idx;
7439}
7440
7441static bool
7442isValidIdx (DataView * packets, int entity_prop_id,
7443 int aux, int entity_prop_val, long idx)
7444{
7445 if (idx < 0 || idx >= packets->getSize ())
7446 return false;
7447 int pkt_aux = packets->getIntValue (PROP_HWCTAG, idx);
7448 if (pkt_aux != aux)
7449 return false;
7450 if (entity_prop_id == PROP_EXPID)
7451 return true; // not a packet property; we know the packet is in this experiment
7452 if (entity_prop_id == PROP_NONE)
7453 return true; // not a packet property; we know the packet is in this experiment
7454 int pkt_ent = packets->getIntValue (entity_prop_id, idx);
7455 if (pkt_ent != entity_prop_val)
7456 return false;
7457 return true;
7458}
7459
7460static bool
7461hasInvisbleTLEvents (Experiment *exp, VMode view_mode)
7462{
7463 if (exp->has_java && view_mode == VMODE_USER)
7464 return true;
7465 return false;
7466}
7467
7468static bool
7469isVisibleTLEvent (Experiment *exp, VMode view_mode, DataView* packets, long idx)
7470{
7471 if (hasInvisbleTLEvents (exp, view_mode))
7472 {
7473 JThread *jthread = (JThread*) packets->getObjValue (PROP_JTHREAD, idx);
7474 if (jthread == JTHREAD_NONE || (jthread != NULL && jthread->is_system ()))
7475 return false;
7476 }
7477 return true;
7478}
7479
7480static long
7481getTLVisibleIdxByStepping (Experiment *exp, VMode view_mode, int entity_prop_id,
7482 DataView * packets, int aux, int entity_prop_val,
7483 long idx, long move_count, int direction)
7484{
7485 assert (move_count >= 0);
7486 assert (direction == 1 || direction == -1 || direction == 0);
7487 if (direction == 0 /* precise hit required */)
7488 move_count = 0;
7489 do
7490 {
7491 if (!isValidIdx (packets, entity_prop_id, aux, entity_prop_val, idx))
7492 return -1;
7493 if (isVisibleTLEvent (exp, view_mode, packets, idx))
7494 {
7495 if (move_count <= 0)
7496 break;
7497 move_count--;
7498 }
7499 if (direction == 0)
7500 return -1;
7501 idx += direction;
7502 }
7503 while (1);
7504 return idx;
7505}
7506
7507static long
7508getTLVisibleIdxByVals (Experiment *exp, VMode view_mode, int entity_prop_id,
7509 DataView * packets,
7510 int aux, int entity_prop_val, uint64_t time, DataView::Relation rel)
7511{
7512 long idx = getIdxByVals (packets, aux, entity_prop_val, time, rel);
7513 if (!hasInvisbleTLEvents (exp, view_mode))
7514 return idx;
7515 if (idx < 0)
7516 return idx;
7517 if (rel == DataView::REL_EQ)
7518 return -1; // would require bi-directional search... not supported for now
7519 int direction = (rel == DataView::REL_LT || rel == DataView::REL_LTEQ) ? -1 : 1;
7520 idx = getTLVisibleIdxByStepping (exp, view_mode, entity_prop_id, packets,
7521 aux, entity_prop_val,
7522 idx, 0 /* first match */, direction);
7523 return idx;
7524}
7525
7526// In thread mode, the entity name for non Java thread should be the 1st func
7527// from the current thread's stack. See #4961315
7528static char*
7529getThreadRootFuncName (int, int, int, int, VMode)
7530{
7531 return NULL; // until we figure out what we want to show... YXXX
7532}
7533
7534Vector<void*> *
7535dbeGetEntityProps (int dbevindex) //YXXX TBD, should this be exp-specific?
7536{
7537 DbeView *dbev = dbeSession->getView (dbevindex);
7538 if (dbev == NULL)
7539 abort ();
7540 Vector<int> *prop_id = new Vector<int>();
7541 Vector<char*> *prop_name = new Vector<char*>();
7542 Vector<char*> *prop_uname = new Vector<char*>();
7543 Vector<char*> *prop_cname = new Vector<char*>(); //must match TLModeCmd vals!
7544
7545 prop_id->append (PROP_NONE);
7546 prop_name->append (dbe_strdup (GTXT ("NONE")));
7547 prop_uname->append (dbe_strdup (GTXT ("Unknown")));
7548 prop_cname->append (dbe_strdup (NTXT ("unknown")));
7549
7550 prop_id->append (PROP_LWPID);
7551 prop_name->append (dbe_strdup (GTXT ("LWPID")));
7552 prop_uname->append (dbe_strdup (GTXT ("LWP")));
7553 prop_cname->append (dbe_strdup (NTXT ("lwp")));
7554
7555 prop_id->append (PROP_THRID);
7556 prop_name->append (dbe_strdup (GTXT ("THRID")));
7557 prop_uname->append (dbe_strdup (GTXT ("Thread")));
7558 prop_cname->append (dbe_strdup (NTXT ("thread")));
7559
7560 prop_id->append (PROP_CPUID);
7561 prop_name->append (dbe_strdup (GTXT ("CPUID")));
7562 prop_uname->append (dbe_strdup (GTXT ("CPU")));
7563 prop_cname->append (dbe_strdup (NTXT ("cpu")));
7564
7565 prop_id->append (PROP_EXPID);
7566 prop_name->append (dbe_strdup (GTXT ("EXPID")));
7567 prop_uname->append (dbe_strdup (GTXT ("Process"))); // placeholder...
7568 // ...until we finalize how to expose user-level Experiments, descendents
7569 prop_cname->append (dbe_strdup (NTXT ("experiment")));
7570 Vector<void*> *darray = new Vector<void*>();
7571 darray->store (0, prop_id);
7572 darray->store (1, prop_name);
7573 darray->store (2, prop_uname);
7574 darray->store (3, prop_cname);
7575 return darray;
7576}
7577
7578Vector<void*> *
7579dbeGetEntities (int dbevindex, int exp_id, int entity_prop_id)
7580{
7581 DbeView *dbev = dbeSession->getView (dbevindex);
7582 if (dbev == NULL)
7583 abort ();
7584 Experiment *exp = dbeSession->get_exp (exp_id);
7585 if (exp == NULL)
7586 return NULL;
7587
7588 // Recognize and skip faketime experiments
7589 if (exp->timelineavail == false)
7590 return NULL;
7591 Vector<Histable*> *tagObjs = exp->getTagObjs ((Prop_type) entity_prop_id);
7592 int total_nelem;
7593 if (tagObjs)
7594 total_nelem = (int) tagObjs->size ();
7595 else
7596 total_nelem = 0;
7597 const VMode view_mode = dbev->get_view_mode ();
7598 bool show_java_threadnames = (entity_prop_id == PROP_THRID &&
7599 view_mode != VMODE_MACHINE);
7600 // allocate the structures for the return
7601 Vector<int> *entity_prop_vals = new Vector<int>();
7602 Vector<char*> *jthr_names = new Vector<char*>();
7603 Vector<char*> *jthr_g_names = new Vector<char*>();
7604 Vector<char*> *jthr_p_names = new Vector<char*>();
7605
7606 // now walk the tagObjs from the experiment, and check for filtering
7607 for (int tagObjsIdx = 0; tagObjsIdx < total_nelem; tagObjsIdx++)
7608 {
7609 int entity_prop_val = (int) ((Other *) tagObjs->fetch (tagObjsIdx))->tag;
7610 entity_prop_vals->append (entity_prop_val);
7611 char *jname, *jgname, *jpname;
7612 JThread *jthread = NULL;
7613 bool has_java_threadnames = false;
7614 if (show_java_threadnames)
7615 {
7616 jthread = exp->get_jthread (entity_prop_val);
7617 has_java_threadnames = (jthread != JTHREAD_DEFAULT
7618 && jthread != JTHREAD_NONE);
7619 }
7620 if (!has_java_threadnames)
7621 {
7622 jname = jgname = jpname = NULL;
7623 if (entity_prop_id == PROP_THRID || entity_prop_id == PROP_LWPID)
7624 // if non Java thread, set thread name to the 1st func
7625 // from the current thread's stack. see #4961315
7626 jname = getThreadRootFuncName (dbevindex, exp_id, entity_prop_id,
7627 entity_prop_val, view_mode);
7628 }
7629 else
7630 {
7631 jname = dbe_strdup (jthread->name);
7632 jgname = dbe_strdup (jthread->group_name);
7633 jpname = dbe_strdup (jthread->parent_name);
7634 }
7635 jthr_names->append (jname);
7636 jthr_g_names->append (jgname);
7637 jthr_p_names->append (jpname);
7638 }
7639 Vector<char*> *entity_prop_name_v = new Vector<char*>();
7640 char* entity_prop_name = dbeSession->getPropName (entity_prop_id);
7641 entity_prop_name_v->append (entity_prop_name);
7642 Vector<void*> *darray = new Vector<void*>(5);
7643 darray->store (0, entity_prop_vals);
7644 darray->store (1, jthr_names);
7645 darray->store (2, jthr_g_names);
7646 darray->store (3, jthr_p_names);
7647 darray->store (4, entity_prop_name_v); // vector only has 1 element
7648 return darray;
7649}
7650
7651// TBR: dbeGetEntities() can be set to private now that we have dbeGetEntitiesV2()
7652Vector<void*> *
7653dbeGetEntitiesV2 (int dbevindex, Vector<int> *exp_ids, int entity_prop_id)
7654{
7655 int sz = exp_ids->size ();
7656 Vector<void*> *res = new Vector<void*>(sz);
7657 for (int ii = 0; ii < sz; ii++)
7658 {
7659 int expIdx = exp_ids->fetch (ii);
7660 Vector<void*>* ents = dbeGetEntities (dbevindex, expIdx, entity_prop_id);
7661 res->store (ii, ents);
7662 }
7663 return res;
7664}
7665
7666//YXXX old-tl packets still used for details
7667static Vector<void*> *
7668getTLDetailValues (int dbevindex, Experiment * exp, int data_id,
7669 VMode view_mode, DataView *packets, long idx)
7670{
7671 Vector<long long> *value = new Vector<long long>(15);
7672 long i = idx;
7673 if (data_id == DATA_SAMPLE || data_id == DATA_GCEVENT)
7674 {
7675 //YXXX DATA_SAMPLE not handled but could be.
7676 }
7677 Obj stack = (unsigned long) getStack (view_mode, packets, i);
7678 Vector<Obj> *funcs = stack ? dbeGetStackFunctions (dbevindex, stack) : NULL;
7679 Function *func = (Function*)
7680 getStackPC (0, view_mode, packets, i)->convertto (Histable::FUNCTION);
7681 // Fill common data
7682 value->store (0, packets->getIntValue (PROP_LWPID, i));
7683 value->store (1, packets->getIntValue (PROP_THRID, i));
7684 value->store (2, packets->getIntValue (PROP_CPUID, i));
7685 value->store (3, packets->getLongValue (PROP_TSTAMP, i));
7686 value->store (4, (unsigned long) stack);
7687 value->store (5, (unsigned long) func);
7688
7689 // Fill specific data
7690 switch (data_id)
7691 {
7692 case DATA_CLOCK:
7693 value->store (6, packets->getIntValue (PROP_MSTATE, i));
7694 {
7695 hrtime_t interval = exp->get_params ()->ptimer_usec * 1000LL // nanoseconds
7696 * packets->getLongValue (PROP_NTICK, i);
7697 value->store (7, interval);
7698 }
7699 value->store (8, packets->getIntValue (PROP_OMPSTATE, i));
7700 value->store (9, packets->getLongValue (PROP_EVT_TIME, i)); // visual duration
7701 break;
7702 case DATA_SYNCH:
7703 value->store (6, packets->getLongValue (PROP_EVT_TIME, i));
7704 value->store (7, packets->getLongValue (PROP_SOBJ, i));
7705 break;
7706 case DATA_HWC:
7707 value->store (6, packets->getLongValue (PROP_HWCINT, i));
7708 value->store (7, packets->getLongValue (PROP_VADDR, i)); // data vaddr
7709 value->store (8, packets->getLongValue (PROP_PADDR, i)); // data paddr
7710 value->store (9, packets->getLongValue (PROP_VIRTPC, i)); // pc paddr
7711 value->store (10, packets->getLongValue (PROP_PHYSPC, i)); // pc vaddr
7712 break;
7713 case DATA_RACE:
7714 value->store (6, packets->getIntValue (PROP_RTYPE, i));
7715 value->store (7, packets->getIntValue (PROP_RID, i));
7716 value->store (8, packets->getLongValue (PROP_RVADDR, i));
7717 break;
7718 case DATA_DLCK:
7719 value->store (6, packets->getIntValue (PROP_DTYPE, i));
7720 value->store (7, packets->getIntValue (PROP_DLTYPE, i));
7721 value->store (8, packets->getIntValue (PROP_DID, i));
7722 value->store (9, packets->getLongValue (PROP_DVADDR, i));
7723 break;
7724 case DATA_HEAP:
7725 case DATA_HEAPSZ:
7726 value->store (6, packets->getIntValue (PROP_HTYPE, i));
7727 value->store (7, packets->getLongValue (PROP_HSIZE, i));
7728 value->store (8, packets->getLongValue (PROP_HVADDR, i));
7729 value->store (9, packets->getLongValue (PROP_HOVADDR, i));
7730 value->store (10, packets->getLongValue (PROP_HLEAKED, i));
7731 value->store (11, packets->getLongValue (PROP_HFREED, i));
7732 value->store (12, packets->getLongValue (PROP_HCUR_ALLOCS, i)); // signed int64_t
7733 value->store (13, packets->getLongValue (PROP_HCUR_LEAKS, i));
7734 break;
7735 case DATA_IOTRACE:
7736 value->store (6, packets->getIntValue (PROP_IOTYPE, i));
7737 value->store (7, packets->getIntValue (PROP_IOFD, i));
7738 value->store (8, packets->getLongValue (PROP_IONBYTE, i));
7739 value->store (9, packets->getLongValue (PROP_EVT_TIME, i));
7740 value->store (10, packets->getIntValue (PROP_IOVFD, i));
7741 break;
7742 }
7743 Vector<void*> *result = new Vector<void*>(5);
7744 result->store (0, value);
7745 result->store (1, funcs); // Histable::Function*
7746 result->store (2, funcs ? dbeGetFuncNames (dbevindex, funcs) : 0); // formatted func names
7747 result->store (3, stack ? dbeGetStackPCs (dbevindex, stack) : 0); // Histable::DbeInstr*
7748 result->store (4, stack ? dbeGetStackNames (dbevindex, stack) : 0); // formatted pc names
7749 return result;
7750}
7751
7752Vector<void*> *
7753dbeGetTLDetails (int dbevindex, int exp_id, int data_id,
7754 int entity_prop_id, Obj event_id)
7755{
7756 DbeView *dbev = dbeSession->getView (dbevindex);
7757 if (dbev == NULL)
7758 abort ();
7759 Experiment *exp = dbeSession->get_exp (exp_id < 0 ? 0 : exp_id);
7760 if (exp == NULL)
7761 return NULL;
7762 DataView *packets =
7763 getTimelinePackets (dbevindex, exp_id, data_id, entity_prop_id);
7764 if (!packets)
7765 return NULL;
7766
7767 VMode view_mode = dbev->get_view_mode ();
7768 long idx = (long) event_id;
7769 Vector<void*> *values = getTLDetailValues (dbevindex, exp, data_id, view_mode, packets, idx);
7770 return values;
7771}
7772
7773Vector<Obj> *
7774dbeGetStackFunctions (int dbevindex, Obj stack)
7775{
7776 Vector<Obj> *instrs = dbeGetStackPCs (dbevindex, stack);
7777 if (instrs == NULL)
7778 return NULL;
7779 int stsize = instrs->size ();
7780 Vector<Obj> *jivals = new Vector<Obj>(stsize);
7781 for (int i = 0; i < stsize; i++)
7782 {
7783 Histable *obj = (Histable*) instrs->fetch (i);
7784 // if ( obj->get_type() != Histable::LINE ) {//YXXX what is this?
7785 // Remove the above check: why not do this conversion for lines -
7786 // otherwise filtering in timeline by function stack in omp user mode is broken
7787 obj = obj->convertto (Histable::FUNCTION);
7788 jivals->store (i, (Obj) obj);
7789 }
7790 delete instrs;
7791 return jivals;
7792}
7793
7794Vector<void*> *
7795dbeGetStacksFunctions (int dbevindex, Vector<Obj> *stacks)
7796{
7797 long sz = stacks->size ();
7798 Vector<void*> *res = new Vector<void*>(sz);
7799 for (int ii = 0; ii < sz; ii++)
7800 {
7801 Obj stack = stacks->fetch (ii);
7802 Vector<Obj> *jivals = dbeGetStackFunctions (dbevindex, stack);
7803 res->store (ii, jivals);
7804 }
7805 return res;
7806}
7807
7808Vector<Obj> *
7809dbeGetStackPCs (int dbevindex, Obj stack)
7810{
7811 DbeView *dbev = dbeSession->getView (dbevindex);
7812 if (dbev == NULL)
7813 abort ();
7814 if (stack == 0)
7815 return NULL;
7816
7817 bool show_all = dbev->isShowAll ();
7818 Vector<Histable*> *instrs = CallStack::getStackPCs ((void *) stack, !show_all);
7819 int stsize = instrs->size ();
7820 int istart = 0;
7821 bool showAll = dbev->isShowAll ();
7822 for (int i = 0; i < stsize - 1; i++)
7823 {
7824 Function *func = (Function*) instrs->fetch (i)->convertto (Histable::FUNCTION);
7825 int ix = func->module->loadobject->seg_idx;
7826 if (showAll && dbev->get_lo_expand (ix) == LIBEX_API)
7827 // truncate stack here: LIBRARY_VISIBILITY if we are using API only but no hide
7828 istart = i;
7829 }
7830 stsize = stsize - istart;
7831 Vector<Obj> *jlvals = new Vector<Obj>(stsize);
7832 for (int i = 0; i < stsize; i++)
7833 {
7834 Histable *instr = instrs->fetch (i + istart);
7835 jlvals->store (i, (Obj) instr);
7836 }
7837 delete instrs;
7838 return jlvals;
7839}
7840
7841Vector<char*> *
7842dbeGetStackNames (int dbevindex, Obj stack)
7843{
7844 DbeView *dbev = dbeSession->getView (dbevindex);
7845 Vector<Obj> *instrs = dbeGetStackPCs (dbevindex, stack);
7846 if (instrs == NULL)
7847 return NULL;
7848 int stsize = instrs->size ();
7849 Vector<char*> *list = new Vector<char*>(stsize);
7850 bool showAll = dbev->isShowAll ();
7851 for (int i = 0; i < stsize; i++)
7852 {
7853 Histable* instr = (Histable*) instrs->fetch (i);
7854 if (!showAll)
7855 {
7856 // LIBRARY_VISIBILITY
7857 Function *func = (Function*) instr->convertto (Histable::FUNCTION);
7858 LoadObject *lo = ((Function*) func)->module->loadobject;
7859 if (dbev->get_lo_expand (lo->seg_idx) == LIBEX_HIDE)
7860 {
7861 list->store (i, dbe_strdup (lo->get_name ()));
7862 continue;
7863 }
7864 }
7865 list->store (i, dbe_strdup (instr->get_name (dbev->get_name_format ())));
7866 }
7867 delete instrs;
7868 return list;
7869}
7870
7871Vector<void*> *
7872dbeGetSamples (int dbevindex, int exp_id, int64_t lo_idx, int64_t hi_idx)
7873{
7874 DataView * packets =
7875 getTimelinePackets (dbevindex, exp_id, DATA_SAMPLE, PROP_EXPID);
7876 if (packets == NULL || packets->getSize () == 0)
7877 return NULL;
7878 long lo;
7879 if (lo_idx < 0)
7880 lo = 0;
7881 else
7882 lo = (long) lo_idx;
7883
7884 long long max = packets->getSize () - 1;
7885 long hi;
7886 if (hi_idx < 0 || hi_idx > max)
7887 hi = (long) max;
7888 else
7889 hi = (long) hi_idx;
7890
7891 Vector<Vector<long long>*> *sarray = new Vector<Vector<long long>*>;
7892 Vector<long long>* starts = new Vector<long long>;
7893 Vector<long long>* ends = new Vector<long long>;
7894 Vector<long long>* rtimes = new Vector<long long>;
7895 Vector<char*> *startNames = new Vector<char*>;
7896 Vector<char*> *endNames = new Vector<char*>;
7897 Vector<int> *sampId = new Vector<int>;
7898
7899 for (long index = lo; index <= hi; index++)
7900 {
7901 Sample *sample = (Sample*) packets->getObjValue (PROP_SMPLOBJ, index);
7902 PrUsage *prusage = sample->get_usage ();
7903 if (prusage == NULL)
7904 prusage = new PrUsage;
7905 Vector<long long> *states = prusage->getMstateValues ();
7906 sarray->append (states);
7907 starts->append (sample->get_start_time ());
7908 ends->append (sample->get_end_time ());
7909 rtimes->append (prusage->pr_rtime);
7910 startNames->append (dbe_strdup (sample->get_start_label ()));
7911 endNames->append (dbe_strdup (sample->get_end_label ()));
7912 sampId->append (sample->get_number ());
7913 }
7914 Vector<void *> *res = new Vector<void*>(6);
7915 res->store (0, sarray);
7916 res->store (1, starts);
7917 res->store (2, ends);
7918 res->store (3, rtimes);
7919 res->store (4, startNames);
7920 res->store (5, endNames);
7921 res->store (6, sampId);
7922 return res;
7923}
7924
7925Vector<void*> *
7926dbeGetGCEvents (int dbevindex, int exp_id, int64_t lo_idx, int64_t hi_idx)
7927{
7928 DataView *packets =
7929 getTimelinePackets (dbevindex, exp_id, DATA_GCEVENT, PROP_EXPID);
7930 if (packets == NULL || packets->getSize () == 0)
7931 return NULL;
7932
7933 long lo;
7934 if (lo_idx < 0)
7935 lo = 0;
7936 else
7937 lo = (long) lo_idx;
7938 long long max = packets->getSize () - 1;
7939 long hi;
7940 if (hi_idx < 0 || hi_idx > max)
7941 hi = (long) max;
7942 else
7943 hi = (long) hi_idx;
7944
7945 Vector<long long>* starts = new Vector<long long>;
7946 Vector<long long>* ends = new Vector<long long>;
7947 Vector<int> *eventId = new Vector<int>;
7948 for (long index = lo; index <= hi; index++)
7949 {
7950 GCEvent *gcevent = (GCEvent*) packets->getObjValue (PROP_GCEVENTOBJ, index);
7951 if (gcevent)
7952 {
7953 starts->append (gcevent->start);
7954 ends->append (gcevent->end);
7955 eventId->append (gcevent->id);
7956 }
7957 }
7958 Vector<void *> *res = new Vector<void*>(3);
7959 res->store (0, starts);
7960 res->store (1, ends);
7961 res->store (2, eventId);
7962 return res;
7963}
7964
7965Vector<Vector<char*>*>*
7966dbeGetIOStatistics (int dbevindex)
7967{
7968 DbeView *dbev = dbeSession->getView (dbevindex);
7969 Hist_data *hist_data;
7970 Hist_data::HistItem *hi;
7971 FileData *fDataTotal;
7972
7973 hist_data = dbev->iofile_data;
7974 if (hist_data == NULL)
7975 return NULL;
7976 hi = hist_data->fetch (0);
7977 fDataTotal = (FileData*) hi->obj;
7978
7979 Vector<char*> *writeStat = new Vector<char*>;
7980 Vector<char*> *readStat = new Vector<char*>;
7981 Vector<char*> *otherStat = new Vector<char*>;
7982 Vector<char*> *errorStat = new Vector<char*>;
7983
7984 writeStat->append (dbe_strdup (GTXT ("Write Statistics")));
7985 readStat->append (dbe_strdup (GTXT ("Read Statistics")));
7986 otherStat->append (dbe_strdup (GTXT ("Other I/O Statistics")));
7987 errorStat->append (dbe_strdup (GTXT ("I/O Error Statistics")));
7988
7989 StringBuilder sb;
7990 if (fDataTotal->getWriteCnt () > 0)
7991 {
7992 if (fDataTotal->getW0KB1KBCnt () > 0)
7993 {
7994 sb.sprintf (GTXT ("0KB - 1KB"));
7995 writeStat->append (sb.toString ());
7996 sb.sprintf (NTXT ("%d"), fDataTotal->getW0KB1KBCnt ());
7997 writeStat->append (sb.toString ());
7998 }
7999 if (fDataTotal->getW1KB8KBCnt () > 0)
8000 {
8001 sb.sprintf (GTXT ("1KB - 8KB"));
8002 writeStat->append (sb.toString ());
8003 sb.sprintf (NTXT ("%d"), fDataTotal->getW1KB8KBCnt ());
8004 writeStat->append (sb.toString ());
8005 }
8006 if (fDataTotal->getW8KB32KBCnt () > 0)
8007 {
8008 sb.sprintf (GTXT ("8KB - 32KB"));
8009 writeStat->append (sb.toString ());
8010 sb.sprintf (NTXT ("%d"), fDataTotal->getW8KB32KBCnt ());
8011 writeStat->append (sb.toString ());
8012 }
8013 if (fDataTotal->getW32KB128KBCnt () > 0)
8014 {
8015 sb.sprintf (GTXT ("32KB - 128KB"));
8016 writeStat->append (sb.toString ());
8017 sb.sprintf (NTXT ("%d"), fDataTotal->getW32KB128KBCnt ());
8018 writeStat->append (sb.toString ());
8019 }
8020 if (fDataTotal->getW128KB256KBCnt () > 0)
8021 {
8022 sb.sprintf (GTXT ("128KB - 256KB"));
8023 writeStat->append (sb.toString ());
8024 sb.sprintf (NTXT ("%d"), fDataTotal->getW128KB256KBCnt ());
8025 writeStat->append (sb.toString ());
8026 }
8027 if (fDataTotal->getW256KB512KBCnt () > 0)
8028 {
8029 sb.sprintf (GTXT ("256KB - 512KB"));
8030 writeStat->append (sb.toString ());
8031 sb.sprintf (NTXT ("%d"), fDataTotal->getW256KB512KBCnt ());
8032 writeStat->append (sb.toString ());
8033 }
8034 if (fDataTotal->getW512KB1000KBCnt () > 0)
8035 {
8036 sb.sprintf (GTXT ("512KB - 1000KB"));
8037 writeStat->append (sb.toString ());
8038 sb.sprintf (NTXT ("%d"), fDataTotal->getW512KB1000KBCnt ());
8039 writeStat->append (sb.toString ());
8040 }
8041 if (fDataTotal->getW1000KB10MBCnt () > 0)
8042 {
8043 sb.sprintf (GTXT ("1000KB - 10MB"));
8044 writeStat->append (sb.toString ());
8045 sb.sprintf (NTXT ("%d"), fDataTotal->getW1000KB10MBCnt ());
8046 writeStat->append (sb.toString ());
8047 }
8048 if (fDataTotal->getW10MB100MBCnt () > 0)
8049 {
8050 sb.sprintf (GTXT ("10MB - 100MB"));
8051 writeStat->append (sb.toString ());
8052 sb.sprintf (NTXT ("%d"), fDataTotal->getW10MB100MBCnt ());
8053 writeStat->append (sb.toString ());
8054 }
8055 if (fDataTotal->getW100MB1GBCnt () > 0)
8056 {
8057 sb.sprintf (GTXT ("100MB - 1GB"));
8058 writeStat->append (sb.toString ());
8059 sb.sprintf (NTXT ("%d"), fDataTotal->getW100MB1GBCnt ());
8060 writeStat->append (sb.toString ());
8061 }
8062 if (fDataTotal->getW1GB10GBCnt () > 0)
8063 {
8064 sb.sprintf (GTXT ("1GB - 10GB"));
8065 writeStat->append (sb.toString ());
8066 sb.sprintf (NTXT ("%d"), fDataTotal->getW1GB10GBCnt ());
8067 writeStat->append (sb.toString ());
8068 }
8069 if (fDataTotal->getW10GB100GBCnt () > 0)
8070 {
8071 sb.sprintf (GTXT ("10GB - 100GB"));
8072 writeStat->append (sb.toString ());
8073 sb.sprintf (NTXT ("%d"), fDataTotal->getW10GB100GBCnt ());
8074 writeStat->append (sb.toString ());
8075 }
8076 if (fDataTotal->getW100GB1TBCnt () > 0)
8077 {
8078 sb.sprintf (GTXT ("100GB - 1TB"));
8079 writeStat->append (sb.toString ());
8080 sb.sprintf (NTXT ("%d"), fDataTotal->getW100GB1TBCnt ());
8081 writeStat->append (sb.toString ());
8082 }
8083 if (fDataTotal->getW1TB10TBCnt () > 0)
8084 {
8085 sb.sprintf (GTXT ("1TB - 10TB"));
8086 writeStat->append (sb.toString ());
8087 sb.sprintf (NTXT ("%d"), fDataTotal->getW1TB10TBCnt ());
8088 writeStat->append (sb.toString ());
8089 }
8090
8091 sb.sprintf (GTXT ("Longest write"));
8092 writeStat->append (sb.toString ());
8093 sb.sprintf (NTXT ("%.6f (secs.)"),
8094 (double) (fDataTotal->getWSlowestBytes () / (double) NANOSEC));
8095 writeStat->append (sb.toString ());
8096
8097 sb.sprintf (GTXT ("Smallest write bytes"));
8098 writeStat->append (sb.toString ());
8099 sb.sprintf (NTXT ("%d"), (int) (fDataTotal->getWSmallestBytes ()));
8100 writeStat->append (sb.toString ());
8101
8102 sb.sprintf (GTXT ("Largest write bytes"));
8103 writeStat->append (sb.toString ());
8104 sb.sprintf (NTXT ("%d"), (int) (fDataTotal->getWLargestBytes ()));
8105 writeStat->append (sb.toString ());
8106
8107 sb.sprintf (GTXT ("Total time"));
8108 writeStat->append (sb.toString ());
8109 sb.sprintf (NTXT ("%.6f (secs.)"),
8110 (double) (fDataTotal->getWriteTime () / (double) NANOSEC));
8111 writeStat->append (sb.toString ());
8112
8113 sb.sprintf (GTXT ("Total calls"));
8114 writeStat->append (sb.toString ());
8115 sb.sprintf (NTXT ("%d"), (int) (fDataTotal->getWriteCnt ()));
8116 writeStat->append (sb.toString ());
8117
8118 sb.sprintf (GTXT ("Total bytes"));
8119 writeStat->append (sb.toString ());
8120 sb.sprintf (NTXT ("%lld"), (long long) (fDataTotal->getWriteBytes ()));
8121 writeStat->append (sb.toString ());
8122 }
8123
8124 if (fDataTotal->getReadCnt () > 0)
8125 {
8126 if (fDataTotal->getR0KB1KBCnt () > 0)
8127 {
8128 sb.sprintf (GTXT ("0KB - 1KB"));
8129 readStat->append (sb.toString ());
8130 sb.sprintf (NTXT ("%d"), fDataTotal->getR0KB1KBCnt ());
8131 readStat->append (sb.toString ());
8132 }
8133 if (fDataTotal->getR1KB8KBCnt () > 0)
8134 {
8135 sb.sprintf (GTXT ("1KB - 8KB"));
8136 readStat->append (sb.toString ());
8137 sb.sprintf (NTXT ("%d"), fDataTotal->getR1KB8KBCnt ());
8138 readStat->append (sb.toString ());
8139 }
8140 if (fDataTotal->getR8KB32KBCnt () > 0)
8141 {
8142 sb.sprintf (GTXT ("8KB - 32KB"));
8143 readStat->append (sb.toString ());
8144 sb.sprintf (NTXT ("%d"), fDataTotal->getR8KB32KBCnt ());
8145 readStat->append (sb.toString ());
8146 }
8147 if (fDataTotal->getR32KB128KBCnt () > 0)
8148 {
8149 sb.sprintf (GTXT ("32KB - 128KB"));
8150 readStat->append (sb.toString ());
8151 sb.sprintf (NTXT ("%d"), fDataTotal->getR32KB128KBCnt ());
8152 readStat->append (sb.toString ());
8153 }
8154 if (fDataTotal->getR128KB256KBCnt () > 0)
8155 {
8156 sb.sprintf (GTXT ("128KB - 256KB"));
8157 readStat->append (sb.toString ());
8158 sb.sprintf (NTXT ("%d"), fDataTotal->getR128KB256KBCnt ());
8159 readStat->append (sb.toString ());
8160 }
8161 if (fDataTotal->getR256KB512KBCnt () > 0)
8162 {
8163 sb.sprintf (GTXT ("256KB - 512KB"));
8164 readStat->append (sb.toString ());
8165 sb.sprintf (NTXT ("%d"), fDataTotal->getR256KB512KBCnt ());
8166 readStat->append (sb.toString ());
8167 }
8168 if (fDataTotal->getR512KB1000KBCnt () > 0)
8169 {
8170 sb.sprintf (GTXT ("512KB - 1000KB"));
8171 readStat->append (sb.toString ());
8172 sb.sprintf (NTXT ("%d"), fDataTotal->getR512KB1000KBCnt ());
8173 readStat->append (sb.toString ());
8174 }
8175 if (fDataTotal->getR1000KB10MBCnt () > 0)
8176 {
8177 sb.sprintf (GTXT ("1000KB - 10MB"));
8178 readStat->append (sb.toString ());
8179 sb.sprintf (NTXT ("%d"), fDataTotal->getR1000KB10MBCnt ());
8180 readStat->append (sb.toString ());
8181 }
8182 if (fDataTotal->getR10MB100MBCnt () > 0)
8183 {
8184 sb.sprintf (GTXT ("10MB - 100MB"));
8185 readStat->append (sb.toString ());
8186 sb.sprintf (NTXT ("%d"), fDataTotal->getR10MB100MBCnt ());
8187 readStat->append (sb.toString ());
8188 }
8189 if (fDataTotal->getR100MB1GBCnt () > 0)
8190 {
8191 sb.sprintf (GTXT ("100MB - 1GB"));
8192 readStat->append (sb.toString ());
8193 sb.sprintf (NTXT ("%d"), fDataTotal->getR100MB1GBCnt ());
8194 readStat->append (sb.toString ());
8195 }
8196 if (fDataTotal->getR1GB10GBCnt () > 0)
8197 {
8198 sb.sprintf (GTXT ("1GB - 10GB"));
8199 readStat->append (sb.toString ());
8200 sb.sprintf (NTXT ("%d"), fDataTotal->getR1GB10GBCnt ());
8201 readStat->append (sb.toString ());
8202 }
8203 if (fDataTotal->getR10GB100GBCnt () > 0)
8204 {
8205 sb.sprintf (GTXT ("10GB - 100GB"));
8206 readStat->append (sb.toString ());
8207 sb.sprintf (NTXT ("%d"), fDataTotal->getR10GB100GBCnt ());
8208 readStat->append (sb.toString ());
8209 }
8210 if (fDataTotal->getR100GB1TBCnt () > 0)
8211 {
8212 sb.sprintf (GTXT ("100GB - 1TB"));
8213 readStat->append (sb.toString ());
8214 sb.sprintf (NTXT ("%d"), fDataTotal->getR100GB1TBCnt ());
8215 readStat->append (sb.toString ());
8216 }
8217 if (fDataTotal->getR1TB10TBCnt () > 0)
8218 {
8219 sb.sprintf (GTXT ("1TB - 10TB"));
8220 readStat->append (sb.toString ());
8221 sb.sprintf (NTXT ("%d"), fDataTotal->getR1TB10TBCnt ());
8222 readStat->append (sb.toString ());
8223 }
8224
8225 sb.sprintf (GTXT ("Longest read"));
8226 readStat->append (sb.toString ());
8227 sb.sprintf (NTXT ("%.6f (secs.)"),
8228 (double) (fDataTotal->getRSlowestBytes () / (double) NANOSEC));
8229 readStat->append (sb.toString ());
8230
8231 sb.sprintf (GTXT ("Smallest read bytes"));
8232 readStat->append (sb.toString ());
8233 sb.sprintf (NTXT ("%d"), (int) (fDataTotal->getRSmallestBytes ()));
8234 readStat->append (sb.toString ());
8235
8236 sb.sprintf (GTXT ("Largest read bytes"));
8237 readStat->append (sb.toString ());
8238 sb.sprintf (NTXT ("%d"), (int) (fDataTotal->getRLargestBytes ()));
8239 readStat->append (sb.toString ());
8240
8241 sb.sprintf (GTXT ("Total time"));
8242 readStat->append (sb.toString ());
8243 sb.sprintf (NTXT ("%.6f (secs.)"),
8244 (double) (fDataTotal->getReadTime () / (double) NANOSEC));
8245 readStat->append (sb.toString ());
8246
8247 sb.sprintf (GTXT ("Total calls"));
8248 readStat->append (sb.toString ());
8249 sb.sprintf (NTXT ("%d"), (int) (fDataTotal->getReadCnt ()));
8250 readStat->append (sb.toString ());
8251
8252 sb.sprintf (GTXT ("Total bytes"));
8253 readStat->append (sb.toString ());
8254 sb.sprintf (NTXT ("%lld"), (long long) (fDataTotal->getReadBytes ()));
8255 readStat->append (sb.toString ());
8256 }
8257
8258 if (fDataTotal->getOtherCnt () > 0)
8259 {
8260 sb.sprintf (GTXT ("Total time"));
8261 otherStat->append (sb.toString ());
8262 sb.sprintf (NTXT ("%.6f (secs.)"),
8263 (double) (fDataTotal->getOtherTime () / (double) NANOSEC));
8264 otherStat->append (sb.toString ());
8265
8266 sb.sprintf (GTXT ("Total calls"));
8267 otherStat->append (sb.toString ());
8268 sb.sprintf (NTXT ("%d"), (int) (fDataTotal->getOtherCnt ()));
8269 otherStat->append (sb.toString ());
8270 }
8271
8272 if (fDataTotal->getErrorCnt () > 0)
8273 {
8274 sb.sprintf (GTXT ("Total time"));
8275 errorStat->append (sb.toString ());
8276 sb.sprintf (NTXT ("%.6f (secs.)"),
8277 (double) (fDataTotal->getErrorTime () / (double) NANOSEC));
8278 errorStat->append (sb.toString ());
8279
8280 sb.sprintf (GTXT ("Total calls"));
8281 errorStat->append (sb.toString ());
8282 sb.sprintf (NTXT ("%d"), (int) (fDataTotal->getErrorCnt ()));
8283 errorStat->append (sb.toString ());
8284 }
8285 Vector<Vector<char*>*>* statisticsData = new Vector<Vector<char*>*>(4);
8286 statisticsData->store (0, writeStat);
8287 statisticsData->store (1, readStat);
8288 statisticsData->store (2, otherStat);
8289 statisticsData->store (3, errorStat);
8290 return statisticsData;
8291}
8292
8293Vector<Vector<char*>*>*
8294dbeGetHeapStatistics (int dbevindex)
8295{
8296 DbeView *dbev = dbeSession->getView (dbevindex);
8297 Hist_data *hist_data;
8298 Hist_data::HistItem *hi;
8299 HeapData *hDataTotal;
8300 hist_data = dbev->heapcs_data;
8301 if (hist_data == NULL)
8302 return NULL;
8303
8304 hi = hist_data->fetch (0);
8305 hDataTotal = (HeapData*) hi->obj;
8306 Vector<char*> *memoryUsage = new Vector<char*>;
8307 Vector<char*> *allocStat = new Vector<char*>;
8308 Vector<char*> *leakStat = new Vector<char*>;
8309
8310 memoryUsage->append (dbe_strdup (GTXT ("Process With Highest Peak Memory Usage")));
8311 allocStat->append (dbe_strdup (GTXT ("Memory Allocations Statistics")));
8312 leakStat->append (dbe_strdup (GTXT ("Memory Leaks Statistics")));
8313 StringBuilder sb;
8314 if (hDataTotal->getPeakMemUsage () > 0)
8315 {
8316 sb.sprintf (GTXT ("Heap size bytes"));
8317 memoryUsage->append (sb.toString ());
8318 sb.sprintf (NTXT ("%lld"), (long long) (hDataTotal->getPeakMemUsage ()));
8319 memoryUsage->append (sb.toString ());
8320
8321 sb.sprintf (GTXT ("Experiment Id"));
8322 memoryUsage->append (sb.toString ());
8323 sb.sprintf (NTXT ("%d"), (int) (hDataTotal->getUserExpId ()));
8324 memoryUsage->append (sb.toString ());
8325
8326 sb.sprintf (GTXT ("Process Id"));
8327 memoryUsage->append (sb.toString ());
8328 sb.sprintf (NTXT ("%d"), (int) (hDataTotal->getPid ()));
8329 memoryUsage->append (sb.toString ());
8330
8331 Vector<hrtime_t> *pTimestamps;
8332 pTimestamps = hDataTotal->getPeakTimestamps ();
8333 if (pTimestamps != NULL)
8334 {
8335 for (int i = 0; i < pTimestamps->size (); i++)
8336 {
8337 sb.sprintf (GTXT ("Time of peak"));
8338 memoryUsage->append (sb.toString ());
8339 sb.sprintf (NTXT ("%.3f (secs.)"), (double) (pTimestamps->fetch (i) / (double) NANOSEC));
8340 memoryUsage->append (sb.toString ());
8341 }
8342 }
8343 }
8344
8345 if (hDataTotal->getAllocCnt () > 0)
8346 {
8347 if (hDataTotal->getA0KB1KBCnt () > 0)
8348 {
8349 sb.sprintf (GTXT ("0KB - 1KB"));
8350 allocStat->append (sb.toString ());
8351 sb.sprintf (NTXT ("%d"), hDataTotal->getA0KB1KBCnt ());
8352 allocStat->append (sb.toString ());
8353 }
8354 if (hDataTotal->getA1KB8KBCnt () > 0)
8355 {
8356 sb.sprintf (GTXT ("1KB - 8KB"));
8357 allocStat->append (sb.toString ());
8358 sb.sprintf (NTXT ("%d"), hDataTotal->getA1KB8KBCnt ());
8359 allocStat->append (sb.toString ());
8360 }
8361 if (hDataTotal->getA8KB32KBCnt () > 0)
8362 {
8363 sb.sprintf (GTXT ("8KB - 32KB"));
8364 allocStat->append (sb.toString ());
8365 sb.sprintf (NTXT ("%d"), hDataTotal->getA8KB32KBCnt ());
8366 allocStat->append (sb.toString ());
8367 }
8368 if (hDataTotal->getA32KB128KBCnt () > 0)
8369 {
8370 sb.sprintf (GTXT ("32KB - 128KB"));
8371 allocStat->append (sb.toString ());
8372 sb.sprintf (NTXT ("%d"), hDataTotal->getA32KB128KBCnt ());
8373 allocStat->append (sb.toString ());
8374 }
8375 if (hDataTotal->getA128KB256KBCnt () > 0)
8376 {
8377 sb.sprintf (GTXT ("128KB - 256KB"));
8378 allocStat->append (sb.toString ());
8379 sb.sprintf (NTXT ("%d"), hDataTotal->getA128KB256KBCnt ());
8380 allocStat->append (sb.toString ());
8381 }
8382 if (hDataTotal->getA256KB512KBCnt () > 0)
8383 {
8384 sb.sprintf (GTXT ("256KB - 512KB"));
8385 allocStat->append (sb.toString ());
8386 sb.sprintf (NTXT ("%d"), hDataTotal->getA256KB512KBCnt ());
8387 allocStat->append (sb.toString ());
8388 }
8389 if (hDataTotal->getA512KB1000KBCnt () > 0)
8390 {
8391 sb.sprintf (GTXT ("512KB - 1000KB"));
8392 allocStat->append (sb.toString ());
8393 sb.sprintf (NTXT ("%d"), hDataTotal->getA512KB1000KBCnt ());
8394 allocStat->append (sb.toString ());
8395 }
8396 if (hDataTotal->getA1000KB10MBCnt () > 0)
8397 {
8398 sb.sprintf (GTXT ("1000KB - 10MB"));
8399 allocStat->append (sb.toString ());
8400 sb.sprintf (NTXT ("%d"), hDataTotal->getA1000KB10MBCnt ());
8401 allocStat->append (sb.toString ());
8402 }
8403 if (hDataTotal->getA10MB100MBCnt () > 0)
8404 {
8405 sb.sprintf (GTXT ("10MB - 100MB"));
8406 allocStat->append (sb.toString ());
8407 sb.sprintf (NTXT ("%d"), hDataTotal->getA10MB100MBCnt ());
8408 allocStat->append (sb.toString ());
8409 }
8410 if (hDataTotal->getA100MB1GBCnt () > 0)
8411 {
8412 sb.sprintf (GTXT ("100MB - 1GB"));
8413 allocStat->append (sb.toString ());
8414 sb.sprintf (NTXT ("%d"), hDataTotal->getA100MB1GBCnt ());
8415 allocStat->append (sb.toString ());
8416 }
8417 if (hDataTotal->getA1GB10GBCnt () > 0)
8418 {
8419 sb.sprintf (GTXT ("1GB - 10GB"));
8420 allocStat->append (sb.toString ());
8421 sb.sprintf (NTXT ("%d"), hDataTotal->getA1GB10GBCnt ());
8422 allocStat->append (sb.toString ());
8423 }
8424 if (hDataTotal->getA10GB100GBCnt () > 0)
8425 {
8426 sb.sprintf (GTXT ("10GB - 100GB"));
8427 allocStat->append (sb.toString ());
8428 sb.sprintf (NTXT ("%d"), hDataTotal->getA10GB100GBCnt ());
8429 allocStat->append (sb.toString ());
8430 }
8431 if (hDataTotal->getA100GB1TBCnt () > 0)
8432 {
8433 sb.sprintf (GTXT ("100GB - 1TB"));
8434 allocStat->append (sb.toString ());
8435 sb.sprintf (NTXT ("%d"), hDataTotal->getA100GB1TBCnt ());
8436 allocStat->append (sb.toString ());
8437 }
8438 if (hDataTotal->getA1TB10TBCnt () > 0)
8439 {
8440 sb.sprintf (GTXT ("1TB - 10TB"));
8441 allocStat->append (sb.toString ());
8442 sb.sprintf (NTXT ("%d"), hDataTotal->getA1TB10TBCnt ());
8443 allocStat->append (sb.toString ());
8444 }
8445
8446 sb.sprintf (GTXT ("Smallest allocation bytes"));
8447 allocStat->append (sb.toString ());
8448 sb.sprintf (NTXT ("%d"), (int) (hDataTotal->getASmallestBytes ()));
8449 allocStat->append (sb.toString ());
8450
8451 sb.sprintf (GTXT ("Largest allocation bytes"));
8452 allocStat->append (sb.toString ());
8453 sb.sprintf (NTXT ("%d"), (int) (hDataTotal->getALargestBytes ()));
8454 allocStat->append (sb.toString ());
8455
8456 sb.sprintf (GTXT ("Total allocations"));
8457 allocStat->append (sb.toString ());
8458 sb.sprintf (NTXT ("%d"), (int) (hDataTotal->getAllocCnt ()));
8459 allocStat->append (sb.toString ());
8460
8461 sb.sprintf (GTXT ("Total bytes"));
8462 allocStat->append (sb.toString ());
8463 sb.sprintf (NTXT ("%lld"), (long long) (hDataTotal->getAllocBytes ()));
8464 allocStat->append (sb.toString ());
8465 }
8466
8467 if (hDataTotal->getLeakCnt () > 0)
8468 {
8469 if (hDataTotal->getL0KB1KBCnt () > 0)
8470 {
8471 sb.sprintf (GTXT ("0KB - 1KB"));
8472 leakStat->append (sb.toString ());
8473 sb.sprintf (NTXT ("%d"), hDataTotal->getL0KB1KBCnt ());
8474 leakStat->append (sb.toString ());
8475 }
8476 if (hDataTotal->getL1KB8KBCnt () > 0)
8477 {
8478 sb.sprintf (GTXT ("1KB - 8KB"));
8479 leakStat->append (sb.toString ());
8480 sb.sprintf (NTXT ("%d"), hDataTotal->getL1KB8KBCnt ());
8481 leakStat->append (sb.toString ());
8482 }
8483 if (hDataTotal->getL8KB32KBCnt () > 0)
8484 {
8485 sb.sprintf (GTXT ("8KB - 32KB"));
8486 leakStat->append (sb.toString ());
8487 sb.sprintf (NTXT ("%d"), hDataTotal->getL8KB32KBCnt ());
8488 leakStat->append (sb.toString ());
8489 }
8490 if (hDataTotal->getL32KB128KBCnt () > 0)
8491 {
8492 sb.sprintf (GTXT ("32KB - 128KB"));
8493 leakStat->append (sb.toString ());
8494 sb.sprintf (NTXT ("%d"), hDataTotal->getL32KB128KBCnt ());
8495 leakStat->append (sb.toString ());
8496 }
8497 if (hDataTotal->getL128KB256KBCnt () > 0)
8498 {
8499 sb.sprintf (GTXT ("128KB - 256KB"));
8500 leakStat->append (sb.toString ());
8501 sb.sprintf (NTXT ("%d"), hDataTotal->getL128KB256KBCnt ());
8502 leakStat->append (sb.toString ());
8503 }
8504 if (hDataTotal->getL256KB512KBCnt () > 0)
8505 {
8506 sb.sprintf (GTXT ("256KB - 512KB"));
8507 leakStat->append (sb.toString ());
8508 sb.sprintf (NTXT ("%d"), hDataTotal->getL256KB512KBCnt ());
8509 leakStat->append (sb.toString ());
8510 }
8511 if (hDataTotal->getL512KB1000KBCnt () > 0)
8512 {
8513 sb.sprintf (GTXT ("512KB - 1000KB"));
8514 leakStat->append (sb.toString ());
8515 sb.sprintf (NTXT ("%d"), hDataTotal->getL512KB1000KBCnt ());
8516 leakStat->append (sb.toString ());
8517 }
8518 if (hDataTotal->getL1000KB10MBCnt () > 0)
8519 {
8520 sb.sprintf (GTXT ("1000KB - 10MB"));
8521 leakStat->append (sb.toString ());
8522 sb.sprintf (NTXT ("%d"), hDataTotal->getL1000KB10MBCnt ());
8523 leakStat->append (sb.toString ());
8524 }
8525 if (hDataTotal->getL10MB100MBCnt () > 0)
8526 {
8527 sb.sprintf (GTXT ("10MB - 100MB"));
8528 leakStat->append (sb.toString ());
8529 sb.sprintf (NTXT ("%d"), hDataTotal->getL10MB100MBCnt ());
8530 leakStat->append (sb.toString ());
8531 }
8532 if (hDataTotal->getL100MB1GBCnt () > 0)
8533 {
8534 sb.sprintf (GTXT ("100MB - 1GB"));
8535 leakStat->append (sb.toString ());
8536 sb.sprintf (NTXT ("%d"), hDataTotal->getL100MB1GBCnt ());
8537 leakStat->append (sb.toString ());
8538 }
8539 if (hDataTotal->getL1GB10GBCnt () > 0)
8540 {
8541 sb.sprintf (GTXT ("1GB - 10GB"));
8542 leakStat->append (sb.toString ());
8543 sb.sprintf (NTXT ("%d"), hDataTotal->getL1GB10GBCnt ());
8544 leakStat->append (sb.toString ());
8545 }
8546 if (hDataTotal->getL10GB100GBCnt () > 0)
8547 {
8548 sb.sprintf (GTXT ("10GB - 100GB"));
8549 leakStat->append (sb.toString ());
8550 sb.sprintf (NTXT ("%d"), hDataTotal->getL10GB100GBCnt ());
8551 leakStat->append (sb.toString ());
8552 }
8553 if (hDataTotal->getL100GB1TBCnt () > 0)
8554 {
8555 sb.sprintf (GTXT ("100GB - 1TB"));
8556 leakStat->append (sb.toString ());
8557 sb.sprintf (NTXT ("%d"), hDataTotal->getL100GB1TBCnt ());
8558 leakStat->append (sb.toString ());
8559 }
8560 if (hDataTotal->getL1TB10TBCnt () > 0)
8561 {
8562 sb.sprintf (GTXT ("1TB - 10TB"));
8563 leakStat->append (sb.toString ());
8564 sb.sprintf (NTXT ("%d"), hDataTotal->getL1TB10TBCnt ());
8565 leakStat->append (sb.toString ());
8566 }
8567
8568 sb.sprintf (GTXT ("Smallest leaked bytes"));
8569 leakStat->append (sb.toString ());
8570 sb.sprintf (NTXT ("%d"), (int) (hDataTotal->getLSmallestBytes ()));
8571 leakStat->append (sb.toString ());
8572
8573 sb.sprintf (GTXT ("Largest leaked bytes"));
8574 leakStat->append (sb.toString ());
8575 sb.sprintf (NTXT ("%d"), (int) (hDataTotal->getLLargestBytes ()));
8576 leakStat->append (sb.toString ());
8577
8578 sb.sprintf (GTXT ("Total leaked"));
8579 leakStat->append (sb.toString ());
8580 sb.sprintf (NTXT ("%d"), (int) (hDataTotal->getLeakCnt ()));
8581 leakStat->append (sb.toString ());
8582
8583 sb.sprintf (GTXT ("Total bytes"));
8584 leakStat->append (sb.toString ());
8585 sb.sprintf (NTXT ("%lld"), (long long) (hDataTotal->getLeakBytes ()));
8586 leakStat->append (sb.toString ());
8587 }
8588 Vector<Vector<char*>*>* statisticsData = new Vector<Vector<char*>*>(3);
8589 statisticsData->store (0, memoryUsage);
8590 statisticsData->store (1, allocStat);
8591 statisticsData->store (2, leakStat);
8592 return statisticsData;
8593}
8594
8595Vector<char*> *
8596dbeGetFuncNames (int dbevindex, Vector<Obj> *funcs)
8597{
8598 int len = funcs->size ();
8599 Vector<char*> *list = new Vector<char*>(len);
8600 for (int i = 0; i < len; i++)
8601 list->store (i, dbeGetFuncName (dbevindex, funcs->fetch (i))); // no strdup()
8602 return list;
8603}
8604
8605Vector<char*> *
8606dbeGetObjNamesV2 (int dbevindex, Vector<uint64_t> *ids)
8607{
8608 int len = ids->size ();
8609 Vector<char*> *list = new Vector<char*>(len);
8610 for (int i = 0; i < len; i++)
8611 list->store (i, dbeGetObjNameV2 (dbevindex, ids->fetch (i))); // no strdup()
8612 return list;
8613}
8614
8615char *
8616dbeGetFuncName (int dbevindex, Obj func)
8617{
8618 DbeView *dbev = dbeSession->getView (dbevindex);
8619 if (dbev == NULL)
8620 abort ();
8621 if (func == 0)
8622 return NULL;
8623 char *fname;
8624 fname = ((Histable *) func)->get_name (dbev->get_name_format ());
8625 return fname ? dbe_strdup (fname) : NULL;
8626}
8627
8628Vector<uint64_t> *
8629dbeGetFuncIds (int dbevindex, Vector<Obj> *funcs)
8630{
8631 int len = funcs->size ();
8632 Vector<uint64_t> *list = new Vector<uint64_t>(len);
8633 for (int i = 0; i < len; i++)
8634 list->store (i, dbeGetFuncId (dbevindex, funcs->fetch (i)));
8635 return list;
8636}
8637
8638uint64_t
8639dbeGetFuncId (int dbevindex, Obj func)
8640{
8641 DbeView *dbev = dbeSession->getView (dbevindex);
8642 if (dbev == NULL)
8643 abort ();
8644 if (func == 0)
8645 return 0;
8646 uint64_t id = ((Histable *) func)->id;
8647 return id;
8648}
8649
8650char *
8651dbeGetObjNameV2 (int dbevindex, uint64_t id)
8652{
8653 DbeView *dbev = dbeSession->getView (dbevindex);
8654 if (dbev == NULL)
8655 abort ();
8656 Histable *obj = dbeSession->findObjectById (id);
8657 if (obj == NULL)
8658 return NULL;
8659 char *fname = obj->get_name (dbev->get_name_format ());
8660 return fname ? dbe_strdup (fname) : NULL;
8661}
8662
8663char *
8664dbeGetDataspaceTypeDesc (int /*dbevindex*/, Obj stack)
8665{
8666 if (stack == 0)
8667 return NULL;
8668 Histable *hist = CallStack::getStackPC ((void *) stack, 0);
8669 DbeInstr *instr;
8670 Histable::Type type = hist->get_type ();
8671 if (type != Histable::INSTR)
8672 return NULL;
8673 else
8674 instr = (DbeInstr *) hist;
8675 char *descriptor = instr->get_descriptor ();
8676 return descriptor ? dbe_strdup (descriptor) : NULL;
8677}
8678
8679Vector<void*> *
8680dbeGetDataDescriptorsV2 (int exp_id)
8681{
8682 Experiment *exp = dbeSession->get_exp (exp_id);
8683 if (exp == NULL)
8684 return NULL;
8685 Vector<int> *dataId = new Vector<int>;
8686 Vector<char*> *dataName = new Vector<char*>;
8687 Vector<char*> *dataUName = new Vector<char*>;
8688 Vector<int> *auxProp = new Vector<int>;
8689 Vector<DataDescriptor*> *ddscr = exp->getDataDescriptors ();
8690 for (int i = 0; i < ddscr->size (); i++)
8691 {
8692 DataDescriptor *dataDscr = ddscr->fetch (i);
8693 if (dataDscr->getFlags () & DDFLAG_NOSHOW)
8694 continue;
8695 int data_id = dataDscr->getId ();
8696 int aux_prop_id = (data_id == DATA_HWC) ? PROP_HWCTAG : PROP_NONE;
8697 dataId->append (data_id);
8698 dataName->append (strdup (dataDscr->getName ()));
8699 dataUName->append (strdup (dataDscr->getUName ()));
8700 auxProp->append (aux_prop_id);
8701 }
8702 delete ddscr;
8703 Vector<void*> *res = new Vector<void*>(3);
8704 res->store (0, dataId);
8705 res->store (1, dataName);
8706 res->store (2, dataUName);
8707 res->store (3, auxProp);
8708 return res;
8709}
8710
8711Vector<void*> *
8712dbeGetDataPropertiesV2 (int exp_id, int data_id)
8713{
8714 Experiment *exp = dbeSession->get_exp (exp_id);
8715 if (exp == NULL)
8716 return NULL;
8717 DataDescriptor *dataDscr = exp->get_raw_events (data_id);
8718 if (dataDscr == NULL)
8719 return NULL;
8720 Vector<PropDescr*> *props = dataDscr->getProps ();
8721 Vector<int> *propId = new Vector<int>(props->size ());
8722 Vector<char*> *propUName = new Vector<char*>(props->size ());
8723 Vector<int> *propTypeId = new Vector<int>(props->size ());
8724 Vector<char*> *propTypeName = new Vector<char*>(props->size ());
8725 Vector<int> *propFlags = new Vector<int>(props->size ());
8726 Vector<char*> *propName = new Vector<char*>(props->size ());
8727 Vector<void*> *propStateNames = new Vector<void*>(props->size ());
8728 Vector<void*> *propStateUNames = new Vector<void*>(props->size ());
8729
8730 for (int i = 0; i < props->size (); i++)
8731 {
8732 PropDescr *prop = props->fetch (i);
8733 char *pname = prop->name;
8734 if (pname == NULL)
8735 pname = NTXT ("");
8736 char *uname = prop->uname;
8737 if (uname == NULL)
8738 uname = pname;
8739 int vtypeNum = prop->vtype;
8740 if (vtypeNum < 0 || vtypeNum >= TYPE_LAST)
8741 vtypeNum = TYPE_NONE;
8742 const char * vtypeNames[] = VTYPE_TYPE_NAMES;
8743 const char *vtype = vtypeNames[prop->vtype];
8744 Vector<char*> *stateNames = NULL;
8745 Vector<char*> *stateUNames = NULL;
8746 int nStates = prop->getMaxState ();
8747 if (nStates > 0)
8748 {
8749 stateNames = new Vector<char*>(nStates);
8750 stateUNames = new Vector<char*>(nStates);
8751 for (int kk = 0; kk < nStates; kk++)
8752 {
8753 const char * stateName = prop->getStateName (kk);
8754 stateNames->store (kk, dbe_strdup (stateName));
8755 const char * Uname = prop->getStateUName (kk);
8756 stateUNames->store (kk, dbe_strdup (Uname));
8757 }
8758 }
8759 propId->store (i, prop->propID);
8760 propUName->store (i, dbe_strdup (uname));
8761 propTypeId->store (i, prop->vtype);
8762 propTypeName->store (i, dbe_strdup (vtype));
8763 propFlags->store (i, prop->flags);
8764 propName->store (i, dbe_strdup (pname));
8765 propStateNames->store (i, stateNames);
8766 propStateUNames->store (i, stateUNames);
8767 }
8768 Vector<void*> *res = new Vector<void*>(7);
8769 res->store (0, propId);
8770 res->store (1, propUName);
8771 res->store (2, propTypeId);
8772 res->store (3, propTypeName);
8773 res->store (4, propFlags);
8774 res->store (5, propName);
8775 res->store (6, propStateNames);
8776 res->store (7, propStateUNames);
8777 return res;
8778}
8779
8780Vector<void *> *
8781dbeGetExperimentTimeInfo (Vector<int> *exp_ids)
8782{
8783 int sz = exp_ids->size ();
8784 Vector<long long> *offset_time = new Vector<long long> (sz);
8785 Vector<long long> *start_time = new Vector<long long> (sz);
8786 Vector<long long> *end_time = new Vector<long long> (sz);
8787 Vector<long long> *start_wall_sec = new Vector<long long> (sz);
8788 Vector<char* > *hostname = new Vector<char*> (sz);
8789 Vector<int> *cpu_freq = new Vector<int> (sz);
8790 for (int ii = 0; ii < sz; ii++)
8791 {
8792 int expIdx = exp_ids->fetch (ii);
8793 { // update end_time by forcing fetch of experiment data
8794 // workaround until dbeGetEndTime() is more robust
8795 int id = (expIdx < 0) ? 0 : expIdx;
8796 Experiment *exp = dbeSession->get_exp (id);
8797 if (exp)
8798 {
8799 Vector<DataDescriptor*> *ddscr = exp->getDataDescriptors ();
8800 delete ddscr;
8801 }
8802 }
8803 offset_time->store (ii, dbeGetRelativeStartTime (0, expIdx));
8804 start_time->store (ii, dbeGetStartTime (0, expIdx));
8805 end_time->store (ii, dbeGetEndTime (0, expIdx));
8806 start_wall_sec->store (ii, dbeGetWallStartSec (0, expIdx));
8807 hostname->store (ii, dbeGetHostname (0, expIdx));
8808 cpu_freq->store (ii, dbeGetClock (0, expIdx));
8809 }
8810 Vector<void*> *res = new Vector<void*>(4);
8811 res->store (0, offset_time);
8812 res->store (1, start_time);
8813 res->store (2, end_time);
8814 res->store (3, start_wall_sec);
8815 res->store (4, hostname);
8816 res->store (5, cpu_freq);
8817 return res;
8818}
8819
8820Vector<void *> *
8821dbeGetExperimentDataDescriptors (Vector<int> *exp_ids)
8822{
8823 int sz = exp_ids->size ();
8824 Vector<void*> *exp_dscr_info = new Vector<void*> (sz);
8825 Vector<void*> *exp_dscr_props = new Vector<void*> (sz);
8826
8827 for (int ii = 0; ii < sz; ii++)
8828 {
8829 int expIdx = exp_ids->fetch (ii);
8830 Vector<void*> *ddscrInfo = dbeGetDataDescriptorsV2 (expIdx);
8831 Vector<void*> *ddscrProps = new Vector<void*> (); // one entry per ddscrInfo
8832 if (ddscrInfo)
8833 {
8834 Vector<int> *dataId = (Vector<int>*)ddscrInfo->fetch (0);
8835 if (dataId)
8836 {
8837 // loop thru data descriptors
8838 int ndata = dataId->size ();
8839 for (int j = 0; j < ndata; ++j)
8840 {
8841 Vector<void*> *props = dbeGetDataPropertiesV2 (expIdx, dataId->fetch (j));
8842 ddscrProps->store (j, props);
8843 }
8844 }
8845 }
8846 exp_dscr_info->store (ii, ddscrInfo);
8847 exp_dscr_props->store (ii, ddscrProps);
8848 }
8849 Vector<void*> *res = new Vector<void*>(2);
8850 res->store (0, exp_dscr_info);
8851 res->store (1, exp_dscr_props);
8852 return res;
8853}
8854
8855static Vector<void *> *
8856dbeGetTLDataRepVals (VMode view_mode, hrtime_t start_ts, hrtime_t delta,
8857 int numDeltas, DataView*packets,
8858 Vector<long> *representativeEvents, bool showDuration);
8859
8860static bool
8861dbeHasTLData (int dbevindex, int exp_id, int data_id, int entity_prop_id,
8862 int entity_prop_value, int aux)
8863{
8864 DataView *packets =
8865 getTimelinePackets (dbevindex, exp_id, data_id, entity_prop_id);
8866 if (!packets || packets->getSize () == 0)
8867 return false;
8868 long start_ind = getIdxByVals (packets, aux, entity_prop_value,
8869 0, DataView::REL_GTEQ); // time >= 0
8870 if (start_ind < 0)
8871 return false;
8872
8873 DbeView *dbev = dbeSession->getView (dbevindex);
8874 VMode view_mode = dbev->get_view_mode ();
8875 Experiment *exp = dbeSession->get_exp (exp_id);
8876 if (!hasInvisbleTLEvents (exp, view_mode))
8877 return true; // all events are visible, no further checking required
8878 long end_ind = getIdxByVals (packets, aux, entity_prop_value,
8879 MAX_TIME, DataView::REL_LTEQ);
8880 for (long ii = start_ind; ii <= end_ind; ii++)
8881 {
8882 if (!isVisibleTLEvent (exp, view_mode, packets, ii))
8883 continue;
8884 return true; // first visible packet => has data
8885 }
8886 return false;
8887}
8888
8889Vector<bool> *
8890dbeHasTLData (int dbev_index, Vector<int> *exp_ids, Vector<int> *data_ids,
8891 Vector<int> *entity_prop_ids, // LWP,CPU,THR, etc
8892 Vector<int> *entity_prop_values, Vector<int> *auxs)
8893{
8894 DbeView *dbev = dbeSession->getView (dbev_index);
8895 if (!dbev->isShowAll () && (dbev->isShowHideChanged ()
8896 || dbev->isNewViewMode ()))
8897 {
8898 // LIBRARY_VISIBILITY
8899 dbev->resetAndConstructShowHideStacks ();
8900 if (dbev->isNewViewMode ())
8901 dbev->resetNewViewMode ();
8902 if (dbev->isShowHideChanged ())
8903 dbev->resetShowHideChanged ();
8904 }
8905
8906 int sz = exp_ids->size ();
8907 Vector<bool> *hasVec = new Vector<bool>(sz);
8908 for (int ii = 0; ii < sz; ii++)
8909 {
8910 bool hasData = dbeHasTLData (dbev_index, exp_ids->fetch (ii),
8911 data_ids->fetch (ii),
8912 entity_prop_ids->fetch (ii),
8913 entity_prop_values->fetch (ii),
8914 auxs->fetch (ii));
8915 hasVec->store (ii, hasData);
8916 }
8917 return hasVec;
8918}
8919
8920/*
8921 * dbeGetTLData implements:
8922 * FROM data_id
8923 * DURATION >= delta AND ( start_ts <= TSTAMP < start_ts+num*delta OR
8924 * start_ts <= TSTAMP-DURATION < start_ts+num*delta )
8925 * OR
8926 * FAIR( DURATION < delta AND ( start_ts <= TSTAMP < start_ts+num*delta ) )
8927 * WHERE lfilter
8928 */
8929
8930Vector<void *> *
8931dbeGetTLData (
8932 int dbevindex,
8933 int exp_id,
8934 int data_id, // DATA_*
8935 int entity_prop_id, // Show PROP_LWPID, PROP_CPUID, PROP_THRID, PROP_EXPID, or N/A
8936 int entity_prop_value, // which LWPID, CPUID, THRID, EXPID for this request
8937 int aux,
8938 hrtime_t param_start_ts,
8939 hrtime_t param_delta,
8940 int param_numDeltas,
8941 bool getRepresentatives, // fetch TL representatives
8942 Vector<char *> *chartProps) // calculate sums for these property vals
8943{
8944 const hrtime_t start_ts = param_start_ts;
8945 const hrtime_t delta = param_delta;
8946 const int numDeltas = param_numDeltas;
8947 DbeView *dbev = dbeSession->getView (dbevindex);
8948 if (dbev == NULL)
8949 abort ();
8950 Experiment *exp = dbeSession->get_exp (exp_id);
8951 if (exp == NULL)
8952 return NULL;
8953 if (getRepresentatives == false && chartProps == NULL)
8954 return NULL;
8955 if (delta <= 0)
8956 return NULL;
8957
8958 hrtime_t tmp_ts = start_ts + delta * numDeltas;
8959 if (tmp_ts < start_ts)
8960 tmp_ts = MAX_TIME;
8961 const hrtime_t end_ts = tmp_ts;
8962 if (exp->get_status () == Experiment::INCOMPLETE &&
8963 exp->getLastEvent () < end_ts)
8964 exp->update ();
8965 DataView *packets =
8966 getTimelinePackets (dbevindex, exp_id, data_id, entity_prop_id);
8967 if (packets == NULL)
8968 return NULL; // strange, no data view?
8969
8970 VMode view_mode = dbev->get_view_mode (); // user, expert, machine //YXXX yuck
8971
8972 // storage for calculating timeline representative events
8973 Vector<long> *representativeEvents = NULL;
8974 // list of representative events to be displayed on TL
8975 Vector<int> *binRepIdx = NULL;
8976 // for each bin, index of current "best" representativeEvent
8977 Vector<void*> *representativeVals = NULL;
8978 // TL representative packets' values
8979
8980 // storage for calculating charts
8981 Vector<int> *propIds = NULL; // [propIdx], which prop to measure
8982 Vector<void*> *propVals = NULL; // [propIdx][bin], prop vals
8983 Vector<int> *propNumStates = NULL; // [propIdx], how many states for prop?
8984 Vector<bool> *propCumulativeChart = NULL; // [propIdx], data represents cumulative totals
8985 Vector<long long> *propCumulativeRecentBinLastVal = NULL; // [propIdx], most recent value
8986 Vector<long long> *propCumulativeRecentBinHighVal = NULL; // [propIdx], highest value for propCumulativeRecentBin
8987 Vector<int> *propCumulativeRecentBin = NULL; // [propIdx], most recent bin
8988
8989 // determine when to show duration of events
8990 bool tmp_repsShowDuration = false;
8991 bool tmp_statesUseDuration = false;
8992 bool tmp_extendMicrostates = false;
8993 const hrtime_t ptimerTickDuration = exp->get_params ()->ptimer_usec * 1000LL; // nanoseconds per tick
8994 const bool hasDuration = packets->getProp (PROP_EVT_TIME) ? true : false;
8995 if (hasDuration)
8996 {
8997 switch (entity_prop_id)
8998 {
8999 case PROP_CPUID:
9000 tmp_repsShowDuration = false;
9001 tmp_statesUseDuration = false;
9002 break;
9003 case PROP_THRID:
9004 case PROP_LWPID:
9005 tmp_repsShowDuration = true;
9006 tmp_statesUseDuration = true;
9007 tmp_extendMicrostates = (DATA_CLOCK == data_id) && (ptimerTickDuration < param_delta);
9008 break;
9009 case PROP_EXPID:
9010 case PROP_NONE: // experiment summary row uses this
9011 default:
9012 if (DATA_SAMPLE == data_id)
9013 {
9014 tmp_repsShowDuration = true;
9015 tmp_statesUseDuration = true;
9016 }
9017 else if (DATA_GCEVENT == data_id)
9018 {
9019 tmp_repsShowDuration = true;
9020 tmp_statesUseDuration = true;
9021 }
9022 else if (DATA_CLOCK == data_id)
9023 {
9024 tmp_repsShowDuration = false;
9025 tmp_statesUseDuration = true;
9026 tmp_extendMicrostates = true;
9027 }
9028 else
9029 {
9030 tmp_repsShowDuration = false;
9031 tmp_statesUseDuration = true;
9032 }
9033 break;
9034 }
9035 }
9036 const bool repsShowDuration = tmp_repsShowDuration; // show stretched callstacks
9037 const bool statesUseDuration = tmp_statesUseDuration; // use duration to calculate state charts
9038 const bool extendMicrostates = tmp_extendMicrostates; // we show discrete profiling microstates with
9039 // width=(tick-1), but for computing
9040 // zoomed-out graphs we need to extend to
9041 // account for all ticks, width=(ntick)
9042 const bool reverseScan = repsShowDuration || extendMicrostates; // scan packets in reverse
9043
9044 // determine range of packet indices (lo_pkt_idx, hi_pkt_idx)
9045 long lo_pkt_idx, hi_pkt_idx;
9046 if (extendMicrostates && !(entity_prop_id == PROP_THRID || entity_prop_id == PROP_LWPID))
9047 {
9048 // merging data from multiple threads, need to scan all packets with timestamp [start_ts, exp end]
9049 hrtime_t exp_end_time = exp->getLastEvent () + 1;
9050 hi_pkt_idx = getIdxByVals (packets, aux, entity_prop_value,
9051 exp_end_time, DataView::REL_LT); // last item
9052 }
9053 else
9054 hi_pkt_idx = getIdxByVals (packets, aux, entity_prop_value,
9055 end_ts, DataView::REL_LT);
9056 if (repsShowDuration)
9057 {
9058 // There are two issues to deal with
9059 // 1. events that end "off screen" to the right
9060 // 2. overlapping events
9061
9062 // 1. events that end "off screen" to the right
9063 // For now, we only consistently handle the case where events don't overlap.
9064 // Note that packet timestamps mark end of duration, not start.
9065 // This means that the rightmost event won't be within hi_pkt_idx.
9066 // Solution: Check if end+1 packet _started_ in-range
9067 // Caveat: because we only look ahead by one packet, if there are
9068 // overlapping duration events (e.g. EXPID aggregation)), zoom level
9069 // and panning combo may cause events with TSTAMP>end_ts
9070 // to appear/disappear. A complete solution would involve
9071 // a solution to 2.
9072
9073 // 2. overlapping events
9074 // For now, we have a simplistic solution that makes "wide" events win. However,
9075 // a future solution for deterministically dealing with overlap might look like this:
9076 // - find all packets that touch the visible time range
9077 // - possibly use two DataViews: one with TSTAMP_HI sort and one with TSTAMP_LO
9078 // sort to allow efficient determination of packets with HI and LO endpoints in-range
9079 // - create buckets to capture "winning" event for each bin (each pixel, that is)
9080 // - sort the new list of packets by TSTAMP_HI (for example)
9081 // - looping thru the packets that are in-range, update every bin it touches with it's id
9082 // - if there is overlap, earlier packets will be kicked out of bins
9083 // - On the GUI side, paint one event at a time, as normal.
9084 // - However, for selections, recognize that duration of event may span many bins
9085 //
9086 long idx;
9087 if (hi_pkt_idx >= 0)
9088 // a packet was found to the left of the end time
9089 idx = hi_pkt_idx + 1; // attempt to go one packet right
9090 else
9091 idx = getIdxByVals (packets, aux, entity_prop_value,
9092 end_ts, DataView::REL_GTEQ);
9093 if (isValidIdx (packets, entity_prop_id, aux, entity_prop_value, idx))
9094 {
9095 int64_t pkt_ts = packets->getLongValue (PROP_TSTAMP, idx);
9096 int64_t duration = packets->getLongValue (PROP_EVT_TIME, idx);
9097 pkt_ts -= duration;
9098 if (pkt_ts < end_ts)
9099 hi_pkt_idx = idx;
9100 }
9101 }
9102 lo_pkt_idx = getIdxByVals (packets, aux, entity_prop_value,
9103 start_ts, DataView::REL_GTEQ);
9104
9105 // allocate structs that return chart data
9106 bool hasCumulativeCharts = false;
9107 if (chartProps && chartProps->size () > 0)
9108 {
9109 int nprops = chartProps->size ();
9110 // pre-allocate storage
9111 propIds = new Vector<int> (nprops);
9112 propVals = new Vector<void*>(nprops);
9113 propNumStates = new Vector<int> (nprops);
9114 propCumulativeChart = new Vector<bool>(nprops);
9115 propCumulativeRecentBinLastVal = new Vector<long long>(nprops);
9116 propCumulativeRecentBinHighVal = new Vector<long long>(nprops);
9117 propCumulativeRecentBin = new Vector<int>(nprops);
9118 for (int propNum = 0; propNum < nprops; propNum++)
9119 {
9120 const char* propStr = chartProps->fetch (propNum);
9121 int items_per_prop = 0;
9122 int prop_id = PROP_NONE;
9123 if (!strcmp (propStr, "EVT_COUNT"))
9124 items_per_prop = 1; // use PROP_NONE for counting packets
9125 else
9126 {
9127 int lookup_prop_id = dbeSession->getPropIdByName (propStr);
9128 PropDescr *propDscr = packets->getProp (lookup_prop_id);
9129 if (propDscr != NULL)
9130 {
9131 switch (propDscr->vtype)
9132 {
9133 case TYPE_INT32:
9134 case TYPE_UINT32:
9135 case TYPE_INT64:
9136 case TYPE_UINT64:
9137 items_per_prop = propDscr->getMaxState () + 1;
9138 // add extra slot to store values with out-of-range idx
9139 prop_id = lookup_prop_id;
9140 break;
9141 case TYPE_DOUBLE:
9142 break; // not implemented yet
9143 case TYPE_STRING:
9144 case TYPE_OBJ:
9145 case TYPE_DATE:
9146 default:
9147 break;
9148 }
9149 }
9150 }
9151 void *vals;
9152 if (!items_per_prop)
9153 vals = NULL;
9154 else if (items_per_prop == 1)
9155 {
9156 Vector<long long> *longVals = new Vector<long long> ();
9157 longVals->store (numDeltas - 1, 0); // initialize all elements
9158 vals = longVals;
9159 }
9160 else
9161 {
9162 Vector<Vector<long long>*> *stateVals =
9163 new Vector<Vector<long long>*> ();
9164 vals = stateVals;
9165 // initialize only on-demand, some may not be needed
9166 }
9167
9168 bool isCumulativeChart;
9169#define YXXX_HEAP_VS_TIME 1 // YXXX add data meaning to properties?
9170#if YXXX_HEAP_VS_TIME
9171 isCumulativeChart = (prop_id == PROP_HCUR_LEAKS || prop_id == PROP_HCUR_ALLOCS);
9172#endif
9173 if (isCumulativeChart)
9174 hasCumulativeCharts = true;
9175 propIds->store (propNum, prop_id);
9176 propVals->store (propNum, vals);
9177 propNumStates->store (propNum, items_per_prop);
9178 propCumulativeRecentBinLastVal->store (propNum, 0);
9179 propCumulativeRecentBinHighVal->store (propNum, 0);
9180 propCumulativeRecentBin->store (propNum, 0);
9181 propCumulativeChart->store (propNum, isCumulativeChart);
9182 }
9183 }
9184
9185 // Adjust idx range for calculating 'cumulative charts' e.g. heap size
9186 if (hasCumulativeCharts)
9187 {
9188 // set initial values if earlier packet exists
9189 long lo_idx;
9190 if (lo_pkt_idx >= 0)
9191 // packet was found to the right of start
9192 lo_idx = lo_pkt_idx - 1; // attempt to go left by one event
9193 else
9194 // no packet was to the right of start, look left of start
9195 lo_idx = getIdxByVals (packets, aux, entity_prop_value,
9196 start_ts, DataView::REL_LT);
9197 if (isValidIdx (packets, entity_prop_id, aux, entity_prop_value, lo_idx))
9198 {
9199 // preceding packet found
9200 // update initial values
9201 int nprops = propCumulativeChart->size ();
9202 for (int propNum = 0; propNum < nprops; propNum++)
9203 {
9204 if (!propCumulativeChart->fetch (propNum))
9205 continue;
9206 int propId = propIds->fetch (propNum);
9207 long long value = packets->getLongValue (propId, lo_idx);
9208 propCumulativeRecentBinLastVal->store (propNum, value);
9209 propCumulativeRecentBinHighVal->store (propNum, value);
9210 }
9211 // update indices used for iterating
9212 lo_pkt_idx = lo_idx;
9213 if (hi_pkt_idx < lo_pkt_idx)
9214 hi_pkt_idx = lo_pkt_idx;
9215 }
9216 }
9217 if (lo_pkt_idx < 0 || hi_pkt_idx < 0)
9218 goto dbeGetTLData_done; // no data; return empty vectors, not null
9219
9220 // representative events (subset of callstacks to represent on TL)
9221 if (getRepresentatives)
9222 {
9223 representativeEvents = new Vector<long>(numDeltas);
9224 // per-bin, longest event's index
9225 binRepIdx = new Vector<int>(numDeltas);
9226 for (int ii = 0; ii < numDeltas; ++ii)
9227 binRepIdx->append (-1);
9228 }
9229 // While packets are sorted by _end_ timestamp (TSTAMP),
9230 // after calculating start times for non-zero durations,
9231 // start times are not guaranteed be monotonically increasing.
9232 // For packets with duration, we'll scan them in reverse order to
9233 // take advantage of the monotonically decreasing _end_ timestamps.
9234 long start_idx, idx_inc;
9235 if (!reverseScan)
9236 {
9237 start_idx = lo_pkt_idx;
9238 idx_inc = 1;
9239 }
9240 else
9241 {
9242 start_idx = hi_pkt_idx;
9243 idx_inc = -1;
9244 }
9245 for (long ii = start_idx; ii >= lo_pkt_idx && ii <= hi_pkt_idx; ii += idx_inc)
9246 {
9247 if (!isVisibleTLEvent (exp, view_mode, packets, ii) && !hasCumulativeCharts)
9248 continue;
9249
9250 // determine packet time duration and start bin
9251 int tmp_start_bin; // packet start bin
9252 int tmp_end_bin; // packet end bin (inclusive)
9253 const hrtime_t pkt_end_ts = packets->getLongValue (PROP_TSTAMP, ii);
9254 const hrtime_t pkt_dur = packets->getLongValue (PROP_EVT_TIME, ii);
9255 const hrtime_t pkt_start_ts = pkt_end_ts - pkt_dur;
9256 if (pkt_end_ts < start_ts && !hasCumulativeCharts)
9257 continue; // weird, should not happen
9258 if (pkt_start_ts >= end_ts)
9259 continue; // could happen
9260 hrtime_t bin_end_ts = pkt_end_ts;
9261 if (bin_end_ts >= end_ts)
9262 bin_end_ts = end_ts - 1;
9263 tmp_end_bin = (int) ((bin_end_ts - start_ts) / delta);
9264 hrtime_t bin_start_ts = pkt_start_ts;
9265 if (bin_start_ts < start_ts)
9266 bin_start_ts = start_ts; // event truncated to left.
9267 tmp_start_bin = (int) ((bin_start_ts - start_ts) / delta);
9268 // By definition
9269 // (end_ts - start_ts) == delta * numDeltas
9270 // and we know
9271 // pkt_start < end_ts
9272 // therefore
9273 // (pkt_start - start_ts) < delta * numDeltas
9274 // (pkt_start - start_ts) / delta < numDeltas
9275 // bin < numDeltas
9276 assert (tmp_end_bin < numDeltas);
9277 assert (tmp_start_bin < numDeltas);
9278 const bool is_offscreen = tmp_end_bin < 0 ? true : false;
9279 if (tmp_end_bin < 0)
9280 tmp_end_bin = 0;
9281 const int pkt_end_bin = tmp_end_bin; // packet end bin (inclusive)
9282 const int pkt_start_bin = tmp_start_bin;
9283 if (getRepresentatives && !is_offscreen)
9284 { // find best representative
9285 // Note: for events with duration, we're scanning packets in order
9286 // of decreasing end-timestamp. This means that the first packet
9287 // that hits a particular _start_ bin will have the longest duration
9288 // of any later packet that might hit that start bin. The
9289 // the first packet will be the best (longest) packet.
9290 const int bin = reverseScan ? pkt_start_bin : pkt_end_bin;
9291 int eventIdx = binRepIdx->fetch (bin);
9292 if (eventIdx == -1)
9293 {
9294 eventIdx = representativeEvents->size (); // append to end
9295 representativeEvents->append (ii);
9296 binRepIdx->store (bin, eventIdx);
9297 }
9298 }
9299 if (propIds)
9300 { // per-bin chart: sum across filtered packets
9301 for (int propNum = 0; propNum < propIds->size (); propNum++)
9302 {
9303 void *thisProp = propVals->fetch (propNum);
9304 if (thisProp == NULL)
9305 continue; // no valid data
9306 if (is_offscreen && !propCumulativeChart->fetch (propNum))
9307 continue; // offscreen events are only processed for cumulative charts
9308 int propId = propIds->fetch (propNum);
9309 long long val;
9310 if (propId == PROP_NONE)
9311 val = 1; // count
9312 else
9313 val = packets->getLongValue (propId, ii);
9314 long nitems = propNumStates->fetch (propNum);
9315 if (nitems < 1)
9316 continue;
9317 else if (nitems == 1)
9318 {
9319 // chart is not based on not multiple states
9320 Vector<long long>* thisPropVals =
9321 (Vector<long long>*)thisProp;
9322 if (thisPropVals->size () == 0)
9323 thisPropVals->store (numDeltas - 1, 0);
9324 const int bin = statesUseDuration ? pkt_start_bin : pkt_end_bin;
9325 if (!propCumulativeChart->fetch (propNum))
9326 {
9327 val += thisPropVals->fetch (bin);
9328 thisPropVals->store (bin, val);
9329 }
9330 else
9331 {
9332 // propCumulativeChart
9333 long long high_value = propCumulativeRecentBinHighVal->fetch (propNum);
9334 int last_bin = propCumulativeRecentBin->fetch (propNum);
9335 if (last_bin < bin)
9336 {
9337 // backfill from previous event
9338 // last_bin: store largest value (in case of multiple events)
9339 thisPropVals->store (last_bin, high_value);
9340 // propagate forward the bin's last value
9341 long long last_value = propCumulativeRecentBinLastVal->fetch (propNum);
9342 for (int kk = last_bin + 1; kk < bin; kk++)
9343 thisPropVals->store (kk, last_value);
9344 // prepare new bin for current event
9345 high_value = 0; // high value of next bin is 0.
9346 propCumulativeRecentBinHighVal->store (propNum, high_value);
9347 propCumulativeRecentBin->store (propNum, bin);
9348 }
9349 long long this_value = packets->getLongValue (propId, ii);
9350 propCumulativeRecentBinLastVal->store (propNum, this_value);
9351 if (high_value < this_value)
9352 {
9353 // record the max
9354 high_value = this_value;
9355 propCumulativeRecentBinHighVal->store (propNum, high_value);
9356 }
9357 if (ii == hi_pkt_idx)
9358 {
9359 // bin: show largest value (in case of multiple events
9360 thisPropVals->store (bin, high_value);
9361 //forward fill remaining bins
9362 for (int kk = bin + 1; kk < numDeltas; kk++)
9363 thisPropVals->store (kk, this_value);
9364 }
9365 }
9366 }
9367 else
9368 {
9369 // means val is actually a state #
9370 Vector<Vector<long long>*>* thisPropStateVals =
9371 (Vector<Vector<long long>*>*)thisProp;
9372 if (thisPropStateVals->size () == 0)
9373 thisPropStateVals->store (numDeltas - 1, 0);
9374 long stateNum;
9375 if (val >= 0 && val < nitems)
9376 stateNum = (long) val;
9377 else
9378 stateNum = nitems - 1; // out of range, use last slot
9379 hrtime_t graph_pkt_dur = pkt_dur;
9380 hrtime_t graph_pkt_start_ts = pkt_start_ts;
9381 int tmp2_start_bin = pkt_start_bin;
9382 if (propId == PROP_MSTATE)
9383 {
9384 if (statesUseDuration && extendMicrostates)
9385 {
9386 // microstate stacks are shown and filtered with width=NTICK-1
9387 // but for microstate graph calcs use width=NTICK.
9388 graph_pkt_dur += ptimerTickDuration;
9389 graph_pkt_start_ts -= ptimerTickDuration;
9390 hrtime_t bin_start_ts = graph_pkt_start_ts;
9391 if (bin_start_ts < start_ts)
9392 bin_start_ts = start_ts; // event truncated to left.
9393 tmp2_start_bin = (int) ((bin_start_ts - start_ts) / delta);
9394 }
9395 }
9396 const int graph_pkt_start_bin = statesUseDuration ? tmp2_start_bin : pkt_end_bin;
9397
9398 // We will distribute the state's presence evenly over duration of the event.
9399 // When only a 'partial bin' is touched by an event, adjust accordingly.
9400 long long value_per_bin; // weight to be applied to each bin
9401 {
9402 long long weight;
9403 if (propId == PROP_MSTATE) // ticks to nanoseconds
9404 weight = packets->getLongValue (PROP_NTICK, ii) * ptimerTickDuration;
9405 else if (graph_pkt_dur)
9406 weight = graph_pkt_dur; // nanoseconds
9407 else
9408 weight = 1; // no duration; indicate presence
9409 if (graph_pkt_start_bin != pkt_end_bin)
9410 {
9411 // spans multiple bins
9412 double nbins = (double) graph_pkt_dur / delta;
9413 value_per_bin = weight / nbins;
9414 }
9415 else
9416 value_per_bin = weight;
9417 }
9418 for (int evtbin = graph_pkt_start_bin; evtbin <= pkt_end_bin; evtbin++)
9419 {
9420 Vector<long long>* stateValues =
9421 (Vector<long long>*) thisPropStateVals->fetch (evtbin);
9422 if (stateValues == NULL)
9423 {
9424 // on-demand storage
9425 stateValues = new Vector<long long>(nitems);
9426 stateValues->store (nitems - 1, 0); // force memset of full vector
9427 thisPropStateVals->store (evtbin, stateValues);
9428 }
9429 long long new_val = stateValues->fetch (stateNum);
9430 if (graph_pkt_start_bin == pkt_end_bin ||
9431 (evtbin > graph_pkt_start_bin && evtbin < pkt_end_bin))
9432 {
9433 new_val += value_per_bin;
9434 }
9435 else
9436 {
9437 // partial bin
9438 const hrtime_t bin_start = start_ts + evtbin * delta;
9439 const hrtime_t bin_end = start_ts + (evtbin + 1) * delta - 1;
9440 if (evtbin == graph_pkt_start_bin)
9441 {
9442 // leftmost bin
9443 if (graph_pkt_start_ts < bin_start)
9444 new_val += value_per_bin;
9445 else
9446 {
9447 double percent = (double) (bin_end - graph_pkt_start_ts) / delta;
9448 new_val += value_per_bin*percent;
9449 }
9450 }
9451 else
9452 {
9453 // rightmost bin
9454 if (pkt_end_ts > bin_end)
9455 new_val += value_per_bin;
9456 else
9457 {
9458 double percent = (double) (pkt_end_ts - bin_start) / delta;
9459 new_val += value_per_bin*percent;
9460 }
9461 }
9462 }
9463 stateValues->store (stateNum, new_val);
9464 }
9465 }
9466 }
9467 }
9468 }
9469 delete binRepIdx;
9470 delete propIds;
9471 delete propCumulativeChart;
9472 delete propCumulativeRecentBinLastVal;
9473 delete propCumulativeRecentBinHighVal;
9474 delete propCumulativeRecentBin;
9475 if (representativeEvents != NULL && reverseScan)
9476 {
9477 if (repsShowDuration)
9478 {
9479 //YXXX for now prune here, but in the future, let gui decide what to show
9480 // Prune events that are completely obscured long duration events.
9481 // Note: representativeEvents is sorted by decreasing _end_ timestamps.
9482 Vector<long> *prunedEvents = new Vector<long>(numDeltas);
9483 hrtime_t prev_start_ts = MAX_TIME;
9484 long repCnt = representativeEvents->size ();
9485 for (long kk = 0; kk < repCnt; kk++)
9486 {
9487 long ii = representativeEvents->fetch (kk);
9488 hrtime_t tmp_end_ts = packets->getLongValue (PROP_TSTAMP, ii);
9489 hrtime_t tmp_dur = packets->getLongValue (PROP_EVT_TIME, ii);
9490 hrtime_t tmp_start_ts = tmp_end_ts - tmp_dur;
9491 if (tmp_start_ts >= prev_start_ts)
9492 // this event would be completely hidden
9493 // (because of sorting, we know tmp_end_ts <= prev_end_ts)
9494 continue;
9495 prev_start_ts = tmp_start_ts;
9496 prunedEvents->append (ii);
9497 }
9498 // invert order to to get increasing _end_ timestamps
9499 representativeEvents->reset ();
9500 for (long kk = prunedEvents->size () - 1; kk >= 0; kk--)
9501 {
9502 long packet_idx = prunedEvents->fetch (kk);
9503 representativeEvents->append (packet_idx);
9504 }
9505 delete prunedEvents;
9506 }
9507 else
9508 { // !repsShowDuration
9509 // Note: representativeEvents is sorted by decreasing _end_ timestamps.
9510 // Reverse the order:
9511 long hi_idx = representativeEvents->size () - 1;
9512 long lo_idx = 0;
9513 while (hi_idx > lo_idx)
9514 {
9515 // swap
9516 long lo = representativeEvents->fetch (lo_idx);
9517 long hi = representativeEvents->fetch (hi_idx);
9518 representativeEvents->store (lo_idx, hi);
9519 representativeEvents->store (hi_idx, lo);
9520 hi_idx--;
9521 lo_idx++;
9522 }
9523 }
9524 }
9525
9526dbeGetTLData_done:
9527 if (getRepresentatives)
9528 {
9529 representativeVals = dbeGetTLDataRepVals (view_mode, start_ts, delta,
9530 numDeltas, packets, representativeEvents, repsShowDuration);
9531 delete representativeEvents;
9532 }
9533 Vector<void*> *results = new Vector<void*> (2);
9534 results->store (0, representativeVals);
9535 results->store (1, propVals);
9536 return results;
9537}
9538
9539// add representative events to return buffer
9540
9541static Vector<void *> *
9542dbeGetTLDataRepVals (VMode view_mode, hrtime_t start_ts, hrtime_t delta,
9543 int numDeltas, DataView*packets,
9544 Vector<long> *representativeEvents, bool showDuration)
9545{
9546 int numrecs = representativeEvents ? representativeEvents->size () : 0;
9547 // allocate storage for results
9548 Vector<int> *startBins = new Vector<int>(numrecs);
9549 Vector<int> *numBins = new Vector<int>(numrecs);
9550 Vector<Obj> *eventIdxs = new Vector<Obj>(numrecs);
9551 Vector<Obj> *stackIds = NULL;
9552 if (packets->getProp (PROP_FRINFO))
9553 stackIds = new Vector<Obj>(numrecs);
9554 Vector<int> *mstates = NULL;
9555 if (packets->getProp (PROP_MSTATE))
9556 mstates = new Vector<int>(numrecs);
9557 Vector<Vector<long long>*> *sampleVals = NULL;
9558 if (packets->getProp (PROP_SMPLOBJ))
9559 sampleVals = new Vector<Vector<long long>*>(numrecs);
9560 Vector<long long> *timeStart = new Vector<long long>(numrecs);
9561 Vector<long long> *timeEnd = new Vector<long long>(numrecs);
9562 int prevEndBin = -1; // make sure we don't overlap bins
9563 for (int eventIdx = 0; eventIdx < numrecs; eventIdx++)
9564 {
9565 long packetIdx = representativeEvents->fetch (eventIdx);
9566 // long eventId = packets->getIdByIdx( packetIdx );
9567 const hrtime_t pkt_tstamp = packets->getLongValue (PROP_TSTAMP, packetIdx);
9568 const hrtime_t pkt_dur = showDuration ? packets->getLongValue (PROP_EVT_TIME, packetIdx) : 0;
9569 timeStart->store (eventIdx, pkt_tstamp - pkt_dur);
9570 timeEnd->store (eventIdx, pkt_tstamp);
9571
9572 // calc startBin
9573 int startBin = (int) ((pkt_tstamp - pkt_dur - start_ts) / delta);
9574 if (startBin <= prevEndBin)
9575 startBin = prevEndBin + 1;
9576 // calc binCnt
9577 int endBin = (int) ((pkt_tstamp - start_ts) / delta);
9578 if (endBin >= numDeltas)
9579 endBin = numDeltas - 1;
9580 int binCnt = endBin - startBin + 1;
9581 prevEndBin = endBin;
9582 startBins->store (eventIdx, startBin);
9583 numBins->store (eventIdx, binCnt);
9584 eventIdxs->store (eventIdx, packetIdx); // store packet's idx
9585 if (stackIds != NULL)
9586 {
9587 void* stackId = getStack (view_mode, packets, packetIdx);
9588 stackIds->store (eventIdx, (Obj) (unsigned long) stackId);
9589 }
9590 if (mstates != NULL)
9591 {
9592 int mstate = packets->getIntValue (PROP_MSTATE, packetIdx);
9593 mstates->store (eventIdx, mstate);
9594 }
9595 if (sampleVals != NULL)
9596 {
9597 Sample* sample = (Sample*) packets->getObjValue (PROP_SMPLOBJ, packetIdx);
9598 if (!sample || !sample->get_usage ())
9599 sample = sample;
9600 else
9601 {
9602 PrUsage* prusage = sample->get_usage ();
9603 Vector<long long> *mstateVals = prusage->getMstateValues ();
9604 sampleVals->store (eventIdx, mstateVals);
9605 }
9606 }
9607 }
9608 // caller responsible for: delete representativeEvents;
9609 Vector<void*> *results = new Vector<void*> (8);
9610 results->store (0, startBins);
9611 results->store (1, numBins);
9612 results->store (2, eventIdxs);
9613 results->store (3, stackIds);
9614 results->store (4, mstates);
9615 results->store (5, sampleVals);
9616 results->store (6, timeStart);
9617 results->store (7, timeEnd);
9618 return results;
9619}
9620
9621// starting from <event_id> packet idx, step <move_count> visible events
9622// return the resulting idx and that packet's center time, or null if no event.
9623Vector<long long> *
9624dbeGetTLEventCenterTime (int dbevindex, int exp_id, int data_id,
9625 int entity_prop_id, int entity_prop_val, int aux,
9626 long long event_id, long long move_count)
9627{
9628 DataView *packets = getTimelinePackets (dbevindex, exp_id, data_id,
9629 entity_prop_id);
9630 if (packets == NULL)
9631 return NULL;
9632 long idx = (long) event_id;
9633
9634 DbeView *dbev = dbeSession->getView (dbevindex);
9635 VMode view_mode = dbev->get_view_mode ();
9636 Experiment *exp = dbeSession->get_exp (exp_id);
9637 int direction;
9638 if (move_count == 0)
9639 direction = 0;
9640 else if (move_count < 0)
9641 {
9642 move_count = -move_count;
9643 direction = -1;
9644 }
9645 else
9646 direction = 1;
9647 idx = getTLVisibleIdxByStepping (exp, view_mode, entity_prop_id, packets, aux,
9648 entity_prop_val, idx, move_count, direction);
9649 if (idx >= 0)
9650 {
9651 long long ts = packets->getLongValue (PROP_TSTAMP, idx);
9652 long long dur = packets->getLongValue (PROP_EVT_TIME, idx);
9653 long long center = ts - dur / 2;
9654 Vector<long long> *results = new Vector<long long> (2);
9655 results->store (0, idx); // result idx
9656 results->store (1, center); // result timestamp
9657 return results;
9658 }
9659 return NULL;
9660}
9661
9662long long
9663dbeGetTLEventIdxNearTime (int dbevindex, int exp_id, int data_id,
9664 int entity_prop_id, int entity_prop_val, int aux,
9665 int searchDirection, long long tstamp)
9666{
9667 DataView *packets = getTimelinePackets (dbevindex, exp_id, data_id,
9668 entity_prop_id);
9669 if (packets == NULL)
9670 return -1;
9671 DbeView *dbev = dbeSession->getView (dbevindex);
9672 VMode view_mode = dbev->get_view_mode ();
9673 Experiment *exp = dbeSession->get_exp (exp_id);
9674 if (searchDirection < 0)
9675 {
9676 int idx = getTLVisibleIdxByVals (exp, view_mode, entity_prop_id,
9677 packets, aux, entity_prop_val, tstamp,
9678 DataView::REL_LTEQ);
9679 if (idx != -1)
9680 return idx;
9681 searchDirection = 1; // couldn't find to left, try to right
9682 }
9683 if (searchDirection > 0)
9684 {
9685 int idx = getTLVisibleIdxByVals (exp, view_mode, entity_prop_id,
9686 packets, aux, entity_prop_val, tstamp,
9687 DataView::REL_GTEQ);
9688 if (idx != -1)
9689 return idx;
9690 // couldn't find to right, fall through to generic
9691 }
9692 // search left and right of timestamp
9693 long idx1, idx2;
9694 idx1 = getTLVisibleIdxByVals (exp, view_mode, entity_prop_id,
9695 packets, aux, entity_prop_val, tstamp,
9696 DataView::REL_LT);
9697 idx2 = getTLVisibleIdxByVals (exp, view_mode, entity_prop_id,
9698 packets, aux, entity_prop_val, tstamp,
9699 DataView::REL_GTEQ);
9700 if (idx1 == -1)
9701 return idx2;
9702 else if (idx2 == -1)
9703 return idx1;
9704
9705 // both valid, so need to compare to see which is closer
9706 long long t1 = packets->getLongValue (PROP_TSTAMP, idx1);
9707 long long t2 = packets->getLongValue (PROP_TSTAMP, idx2);
9708 long long t2dur = packets->getLongValue (PROP_EVT_TIME, idx2);
9709 long long delta1 = tstamp - t1; // should always be positive
9710 long long delta2 = (t2 - t2dur) - tstamp; // if negative, overlaps idx1
9711 if (delta1 > delta2)
9712 return idx2;
9713 else
9714 return idx1;
9715}
9716
9717enum Aggr_type
9718{
9719 AGGR_NONE,
9720 AGGR_FAIR,
9721 AGGR_MAX,
9722 AGGR_MIN,
9723 AGGR_CNT,
9724 AGGR_SUM,
9725 AGGR_AVG
9726};
9727
9728static Aggr_type
9729getAggrFunc (char *aname)
9730{
9731 Aggr_type agrfn = AGGR_NONE;
9732 if (aname == NULL)
9733 return agrfn;
9734 if (strcmp (aname, NTXT ("FAIR")) == 0)
9735 agrfn = AGGR_FAIR;
9736 else if (strcmp (aname, NTXT ("MAX")) == 0)
9737 agrfn = AGGR_MAX;
9738 else if (strcmp (aname, NTXT ("MIN")) == 0)
9739 agrfn = AGGR_MIN;
9740 else if (strcmp (aname, NTXT ("CNT")) == 0)
9741 agrfn = AGGR_CNT;
9742 else if (strcmp (aname, NTXT ("SUM")) == 0)
9743 agrfn = AGGR_SUM;
9744 else if (strcmp (aname, NTXT ("AVG")) == 0)
9745 agrfn = AGGR_AVG;
9746 return agrfn;
9747}
9748
9749static long long
9750computeAggrVal (DefaultMap<long long, long long> *fval_map, Aggr_type agrfn)
9751{
9752 long long aval = 0;
9753 long cnt = 0;
9754 Vector<long long> *fvals = fval_map->values ();
9755 long nvals = fvals->size ();
9756 for (int i = 0; i < nvals; ++i)
9757 {
9758 long long val = fvals->fetch (i);
9759 switch (agrfn)
9760 {
9761 case AGGR_FAIR:
9762 aval = val;
9763 break;
9764 case AGGR_MAX:
9765 if (aval < val || cnt == 0)
9766 aval = val;
9767 break;
9768 case AGGR_MIN:
9769 if (aval > val || cnt == 0)
9770 aval = val;
9771 break;
9772 case AGGR_CNT:
9773 aval = cnt + 1;
9774 break;
9775 case AGGR_SUM:
9776 case AGGR_AVG:
9777 aval += val;
9778 break;
9779 case AGGR_NONE:
9780 break;
9781 }
9782 if (agrfn == AGGR_FAIR)
9783 break;
9784 cnt += 1;
9785 }
9786
9787 // Finalize aggregation
9788 if (agrfn == AGGR_AVG)
9789 if (cnt > 0)
9790 aval = (aval + cnt / 2) / cnt;
9791 delete fvals;
9792 return aval;
9793}
9794
9795Vector<long long> *
9796dbeGetAggregatedValue (int data_id, // data table id
9797 char *lfilter, // local filter
9798 char *fexpr, // function expression
9799 char *pname_ts, // property name for timestamp
9800 hrtime_t start_ts, // start of the first time interval
9801 hrtime_t delta, // time interval length
9802 int num, // number of time intervals
9803 char *pname_key, // property name for aggregation key
9804 char *aggr_func) // aggregation function
9805{
9806 Vector<long long> *res = new Vector<long long>;
9807 Experiment *exp = dbeSession->get_exp (0);
9808 if (exp == NULL)
9809 return res;
9810 hrtime_t end_ts = start_ts + delta * num;
9811 if (end_ts < start_ts) // check overflow
9812 end_ts = MAX_TIME;
9813
9814 if (exp->get_status () == Experiment::INCOMPLETE
9815 && exp->getLastEvent () < end_ts)
9816 exp->update ();
9817
9818 DataDescriptor *dataDscr = exp->get_raw_events (data_id);
9819 if (dataDscr == NULL)
9820 return res;
9821
9822 // Process timestamp argument
9823 int prop_ts = dbeSession->getPropIdByName (pname_ts);
9824 if (prop_ts == PROP_NONE)
9825 return res;
9826 assert (prop_ts == -1);
9827
9828 // Parse all expressions
9829 Expression *flt_expr = NULL;
9830 if (lfilter != NULL)
9831 flt_expr = dbeSession->ql_parse (lfilter);
9832 Expression *func_expr = NULL;
9833 if (fexpr != NULL)
9834 func_expr = dbeSession->ql_parse (fexpr);
9835 if (func_expr == NULL) // Not specified or malformed
9836 return res;
9837
9838 // Process aggregation key argument
9839 int prop_key = PROP_NONE;
9840 Data *data_key = NULL;
9841 if (pname_key != NULL)
9842 {
9843 prop_key = dbeSession->getPropIdByName (pname_key);
9844 data_key = dataDscr->getData (prop_key);
9845 if (data_key == NULL) // Specified but not found
9846 return res;
9847 }
9848
9849 // Process aggregation function argument
9850 Aggr_type agrfn = AGGR_FAIR;
9851 if (aggr_func != NULL)
9852 {
9853 agrfn = getAggrFunc (aggr_func);
9854 if (agrfn == AGGR_NONE) // Specified but not recognized
9855 return res;
9856 }
9857 DefaultMap<long long, long long> *
9858 fval_map = new DefaultMap<long long, long long>; // key_val -> func_val
9859 Vector<long long> *key_set = NULL;
9860 assert (key_set != NULL);
9861 if (key_set == NULL)
9862 {
9863 key_set = new Vector<long long>;
9864 key_set->append (0L);
9865 }
9866 DefaultMap<long long, int> *key_seen = new DefaultMap<long long, int>;
9867 long idx_prev = -1;
9868 for (int tidx = 0; tidx < num; ++tidx)
9869 {
9870 long idx_cur = -1;
9871 assert (idx_cur != -1);
9872 int left = key_set->size ();
9873 key_seen->clear ();
9874 for (long idx = idx_cur; idx > idx_prev; --idx)
9875 {
9876 long id = 0;
9877 assert (id != 0);
9878
9879 // Pre-create expression context
9880 Expression::Context ctx (dbeSession->getView (0), exp, NULL, id);
9881 // First use the filter
9882 if (flt_expr != NULL)
9883 if (flt_expr->eval (&ctx) == 0)
9884 continue;
9885
9886 // Calculate the key
9887 // keys are limited to integral values
9888 long long key = 0;
9889 if (data_key != NULL)
9890 key = data_key->fetchLong (id);
9891
9892 // Check if already seen
9893 if (key_seen->get (key) == 1)
9894 continue;
9895 key_seen->put (key, 1);
9896 left -= 1;
9897
9898 // Calculate function value
9899 // function values are limited to integral values
9900 long long fval = func_expr->eval (&ctx);
9901 fval_map->put (key, fval);
9902 if (left == 0)
9903 break;
9904 }
9905 idx_prev = idx_cur;
9906 long long aval = computeAggrVal (fval_map, agrfn);
9907 res->store (tidx, aval);
9908 }
9909 delete key_seen;
9910 delete fval_map;
9911 delete flt_expr;
9912 delete func_expr;
9913 return res;
9914}
9915
9916Vector<char*> *
9917dbeGetLineInfo (Obj pc)
9918{
9919 DbeInstr *instr = (DbeInstr*) pc;
9920 if (instr == NULL || instr->get_type () != Histable::INSTR)
9921 return NULL;
9922 DbeLine *dbeline = (DbeLine*) instr->convertto (Histable::LINE);
9923 const char *fname = dbeline ? dbeline->sourceFile->get_name () : NTXT ("");
9924 char lineno[16];
9925 *lineno = '\0';
9926 if (dbeline != NULL)
9927 snprintf (lineno, sizeof (lineno), NTXT ("%d"), dbeline->lineno);
9928 Vector<char*> *res = new Vector<char*>(2);
9929 res->store (0, strdup (fname));
9930 res->store (1, strdup (lineno));
9931 return res;
9932}
9933
9934int
9935dbeSetAlias (char *name, char *uname, char *expr)
9936{
9937 char *res = dbeSession->indxobj_define (name, uname, expr, NULL, NULL);
9938 return res == NULL ? 0 : 1;
9939}
9940
9941Vector<char*> *
9942dbeGetAlias (char *name)
9943{
9944 Vector<char*> *res = new Vector<char*>;
9945 int idx = dbeSession->findIndexSpaceByName (name);
9946 if (idx >= 0)
9947 {
9948 char *str = dbeSession->getIndexSpaceDescr (idx);
9949 res->append (dbe_strdup (str));
9950 str = dbeSession->getIndexSpaceExprStr (idx);
9951 res->append (dbe_strdup (str));
9952 }
9953 return res;
9954}
9955
9956static int
9957key_cmp (const void *p1, const void *p2)
9958{
9959 long long ll1 = *(long long*) p1;
9960 long long ll2 = *(long long*) p2;
9961 return ll1 < ll2 ? -1 : ll1 > ll2 ? 1 : 0;
9962}
9963
9964Vector<Vector<long long>*> *
9965dbeGetXYPlotData (
9966 int data_id, // data table id
9967 char *lfilter, // local filter expression
9968 char *arg, // name for the argument
9969 char *func1, // expression for the first axis (x)
9970 char *aggr1, // aggregation function for func1: "SUM","CNT",...
9971 char *func2, // expression for the second axis (y)
9972 char *aggr2, // aggregation function for func2
9973 char *func3, // expression for the third axis (color)
9974 char *aggr3) // aggregation function for func3
9975{
9976 Vector<Vector<long long>*> *res = new Vector<Vector<long long>*>;
9977 Experiment *exp = dbeSession->get_exp (0);
9978 if (exp == NULL)
9979 return res;
9980 if (exp->get_status () == Experiment::INCOMPLETE)
9981 exp->update ();
9982
9983 DataDescriptor *dataDscr = exp->get_raw_events (data_id);
9984 if (dataDscr == NULL)
9985 return res;
9986
9987 // Parse all expressions
9988 Vector<Expression*> *funcs = new Vector<Expression*>;
9989 Vector<Aggr_type> *aggrs = new Vector<Aggr_type>;
9990 Vector<DefaultMap<long long, long long>*> *fval_maps =
9991 new Vector<DefaultMap<long long, long long>*>;
9992 Vector<DefaultMap<long long, long>*> *cnt_maps =
9993 new Vector<DefaultMap<long long, long>*>;
9994 if (func1 != NULL)
9995 {
9996 Expression *expr = dbeSession->ql_parse (func1);
9997 funcs->append (expr);
9998 aggrs->append (getAggrFunc (aggr1));
9999 fval_maps->append (new DefaultMap<long long, long long>);
10000 cnt_maps->append (new DefaultMap<long long, long>);
10001 res->append (new Vector<long long>);
10002 if (func2 != NULL)
10003 {
10004 expr = dbeSession->ql_parse (func2);
10005 funcs->append (expr);
10006 aggrs->append (getAggrFunc (aggr2));
10007 fval_maps->append (new DefaultMap<long long, long long>);
10008 cnt_maps->append (new DefaultMap<long long, long>);
10009 res->append (new Vector<long long>);
10010 if (func3 != NULL)
10011 {
10012 expr = dbeSession->ql_parse (func3);
10013 funcs->append (expr);
10014 aggrs->append (getAggrFunc (aggr3));
10015 fval_maps->append (new DefaultMap<long long, long long>);
10016 cnt_maps->append (new DefaultMap<long long, long>);
10017 res->append (new Vector<long long>);
10018 }
10019 }
10020 }
10021 if (funcs->size () == 0)
10022 {
10023 funcs->destroy ();
10024 delete funcs;
10025 fval_maps->destroy ();
10026 delete fval_maps;
10027 cnt_maps->destroy ();
10028 delete cnt_maps;
10029 delete aggrs;
10030 return res;
10031 }
10032 Expression *arg_expr = NULL;
10033 if (arg != NULL)
10034 arg_expr = dbeSession->ql_parse (arg);
10035 if (arg_expr == NULL)
10036 {
10037 funcs->destroy ();
10038 delete funcs;
10039 fval_maps->destroy ();
10040 delete fval_maps;
10041 cnt_maps->destroy ();
10042 delete cnt_maps;
10043 delete aggrs;
10044 return res;
10045 }
10046 Expression *flt_expr = NULL;
10047 if (lfilter != NULL)
10048 flt_expr = dbeSession->ql_parse (lfilter);
10049 Vector<long long> *kidx_map = new Vector<long long>(); // key_idx -> key_val
10050 for (long i = 0; i < dataDscr->getSize (); i++)
10051 {
10052 Expression::Context ctx (dbeSession->getView (0), exp, NULL, i);
10053 // First use the filter
10054 if (flt_expr != NULL)
10055 if (flt_expr->eval (&ctx) == 0)
10056 continue;
10057
10058 // Compute the argument
10059 long long key = arg_expr->eval (&ctx);
10060 if (kidx_map->find (key) == -1)
10061 kidx_map->append (key);
10062 for (long j = 0; j < funcs->size (); ++j)
10063 {
10064 Expression *func = funcs->fetch (j);
10065 Aggr_type aggr = aggrs->fetch (j);
10066 DefaultMap<long long, long long> *fval_map = fval_maps->fetch (j);
10067 DefaultMap<long long, long> *cnt_map = cnt_maps->fetch (j);
10068 long long fval = func->eval (&ctx);
10069 long long aval = fval_map->get (key);
10070 long cnt = cnt_map->get (key);
10071 switch (aggr)
10072 {
10073 case AGGR_NONE:
10074 case AGGR_FAIR:
10075 if (cnt == 0)
10076 aval = fval;
10077 break;
10078 case AGGR_MAX:
10079 if (aval < fval || cnt == 0)
10080 aval = fval;
10081 break;
10082 case AGGR_MIN:
10083 if (aval > fval || cnt == 0)
10084 aval = fval;
10085 break;
10086 case AGGR_CNT:
10087 aval = cnt + 1;
10088 break;
10089 case AGGR_SUM:
10090 case AGGR_AVG:
10091 aval += fval;
10092 break;
10093 }
10094 cnt_map->put (key, cnt + 1);
10095 fval_map->put (key, aval);
10096 }
10097 }
10098 kidx_map->sort (key_cmp);
10099
10100 // Finalize aggregation, prepare result
10101 for (long j = 0; j < funcs->size (); ++j)
10102 {
10103 Aggr_type aggr = aggrs->fetch (j);
10104 Vector<long long> *resj = res->fetch (j);
10105 DefaultMap<long long, long long> *
10106 fval_map = fval_maps->fetch (j);
10107 DefaultMap<long long, long> *
10108 cnt_map = cnt_maps->fetch (j);
10109 for (int kidx = 0; kidx < kidx_map->size (); ++kidx)
10110 {
10111 long long key = kidx_map->fetch (kidx);
10112 long long aval = fval_map->get (key);
10113 if (aggr == AGGR_AVG)
10114 {
10115 long cnt = cnt_map->get (key);
10116 if (cnt > 0)
10117 aval = (aval + cnt / 2) / cnt;
10118 }
10119 resj->append (aval);
10120 }
10121 }
10122 delete flt_expr;
10123 funcs->destroy ();
10124 delete funcs;
10125 delete aggrs;
10126 delete arg_expr;
10127 delete kidx_map;
10128 fval_maps->destroy ();
10129 delete fval_maps;
10130 cnt_maps->destroy ();
10131 delete cnt_maps;
10132 return res;
10133}
10134
10135/* ********************************************************************* */
10136/* Routines for use by Collector GUI */
10137/**
10138 * Returns signal value for provided name. Example of name: "SIGUSR1"
10139 * @param signal
10140 * @return value
10141 */
10142int
10143dbeGetSignalValue (char *signal)
10144{
10145 int ret = -1;
10146 if (signal == NULL)
10147 return ret;
10148 if (strcmp (signal, "SIGUSR1") == 0)
10149 return (SIGUSR1);
10150 if (strcmp (signal, "SIGUSR2") == 0)
10151 return (SIGUSR2);
10152 if (strcmp (signal, "SIGPROF") == 0)
10153 return (SIGPROF);
10154 return ret;
10155}
10156
10157char *
10158dbeSendSignal (pid_t p, int signum)
10159{
10160 int ret = kill (p, signum);
10161 if (p == 0 || p == -1)
10162 return (dbe_sprintf (GTXT ("kill of process %d not supported\n"), p));
10163 if (ret == 0)
10164 return NULL;
10165 char *msg = dbe_sprintf (GTXT ("kill(%d, %d) failed: %s\n"), p, signum,
10166 strerror (errno));
10167 return msg;
10168}
10169
10170char *
10171dbeGetCollectorControlValue (char *control)
10172{
10173 if (control == NULL)
10174 return NULL;
10175 if (col_ctr == NULL)
10176 col_ctr = new Coll_Ctrl (1);
10177 char *msg = col_ctr->get (control);
10178 return msg;
10179}
10180
10181char *
10182dbeSetCollectorControlValue (char *control, char * value)
10183{
10184 if (control == NULL)
10185 return NULL;
10186 if (col_ctr == NULL)
10187 col_ctr = new Coll_Ctrl (1);
10188 char *msg = col_ctr->set (control, value);
10189 return msg;
10190}
10191
10192char *
10193dbeUnsetCollectorControlValue (char *control)
10194{
10195 if (control == NULL)
10196 return NULL;
10197 if (col_ctr == NULL)
10198 col_ctr = new Coll_Ctrl (1);
10199 char *msg = col_ctr->unset (control);
10200 return msg;
10201}
10202
10203void
10204dbeSetLocation (const char *fname, const char *location)
10205{
10206 Vector<SourceFile*> *sources = dbeSession->get_sources ();
10207 for (long i = 0, sz = sources ? sources->size () : 0; i < sz; i++)
10208 {
10209 SourceFile *src = sources->get (i);
10210 DbeFile *df = src->dbeFile;
10211 if (df && (strcmp (fname, df->get_name ()) == 0))
10212 {
10213 df->find_file ((char *) location);
10214 break;
10215 }
10216 }
10217}
10218
10219void
10220dbeSetLocations (Vector<const char *> *fnames, Vector<const char *> *locations)
10221{
10222 if (fnames == NULL || locations == NULL
10223 || fnames->size () != locations->size ())
10224 return;
10225 for (long i = 0, sz = fnames->size (); i < sz; i++)
10226 dbeSetLocation (fnames->get (i), locations->get (i));
10227}
10228
10229Vector<void*> *
10230dbeResolvedWith_setpath (const char *path)
10231{
10232 Vector<char*> *names = new Vector<char*>();
10233 Vector<char*> *pathes = new Vector<char*>();
10234 Vector<long long> *ids = new Vector<long long>();
10235 Vector<SourceFile*> *sources = dbeSession->get_sources ();
10236 for (long i = 0, sz = sources ? sources->size () : 0; i < sz; i++)
10237 {
10238 SourceFile *src = sources->get (i);
10239 DbeFile *df = src->dbeFile;
10240 if (df == NULL || (df->filetype & DbeFile::F_FICTION) != 0)
10241 continue;
10242 char *fnm = df->get_name ();
10243 if ((df->filetype & (DbeFile::F_JAVACLASS | DbeFile::F_JAVA_SOURCE)) != 0)
10244 {
10245 char *jnm = dbe_sprintf (NTXT ("%s/%s"), path, fnm);
10246 if (df->check_access (jnm) == DbeFile::F_FILE)
10247 {
10248 names->append (dbe_strdup (fnm));
10249 pathes->append (jnm);
10250 ids->append (src->id);
10251 continue;
10252 }
10253 free (jnm);
10254 }
10255 char *nm = dbe_sprintf (NTXT ("%s/%s"), path, get_basename (fnm));
10256 if (df->check_access (nm) == DbeFile::F_FILE)
10257 {
10258 names->append (dbe_strdup (fnm));
10259 pathes->append (nm);
10260 ids->append (src->id);
10261 continue;
10262 }
10263 free (nm);
10264 }
10265 if (names->size () != 0)
10266 {
10267 Vector<void*> *data = new Vector<void*>(3);
10268 data->append (names);
10269 data->append (pathes);
10270 data->append (ids);
10271 return data;
10272 }
10273 return NULL;
10274}
10275
10276Vector<void*> *
10277dbeResolvedWith_pathmap (const char *old_prefix, const char *new_prefix)
10278{
10279 size_t len = strlen (old_prefix);
10280 Vector<char*> *names = new Vector<char*>();
10281 Vector<char*> *pathes = new Vector<char*>();
10282 Vector<long long> *ids = new Vector<long long>();
10283 Vector<SourceFile*> *sources = dbeSession->get_sources ();
10284 for (long i = 0, sz = sources ? sources->size () : 0; i < sz; i++)
10285 {
10286 SourceFile *src = sources->get (i);
10287 DbeFile *df = src->dbeFile;
10288 if (df == NULL || (df->filetype & DbeFile::F_FICTION) != 0)
10289 continue;
10290 char *fnm = df->get_name ();
10291 if (strncmp (old_prefix, fnm, len) == 0
10292 && (fnm[len] == '/' || fnm[len] == '\0'))
10293 {
10294 char *nm = dbe_sprintf (NTXT ("%s/%s"), new_prefix, fnm + len);
10295 if (df->check_access (nm) == DbeFile::F_FILE)
10296 {
10297 names->append (dbe_strdup (fnm));
10298 pathes->append (nm);
10299 ids->append (src->id);
10300 continue;
10301 }
10302 if ((df->filetype & DbeFile::F_JAVA_SOURCE) != 0)
10303 {
10304 free (nm);
10305 nm = dbe_sprintf (NTXT ("%s/%s"), new_prefix, fnm);
10306 if (df->check_access (nm) == DbeFile::F_FILE)
10307 {
10308 names->append (dbe_strdup (fnm));
10309 pathes->append (nm);
10310 ids->append (src->id);
10311 continue;
10312 }
10313 }
10314 free (nm);
10315 }
10316 }
10317 if (names->size () != 0)
10318 {
10319 Vector<void*> *data = new Vector<void*>(3);
10320 data->append (names);
10321 data->append (pathes);
10322 data->append (ids);
10323 return data;
10324 }
10325 return NULL;
10326}
10327
10328void
10329dbe_archive (Vector<long long> *ids, Vector<const char *> *locations)
10330{
10331 if (ids == NULL || locations == NULL || ids->size () != locations->size ())
10332 return;
10333 Experiment *exp = dbeSession->get_exp (0);
10334 if (exp == NULL)
10335 return;
10336 Vector<SourceFile*> *sources = dbeSession->get_sources ();
10337 for (long i1 = 0, sz1 = ids->size (); i1 < sz1; i1++)
10338 {
10339 long long id = ids->get (i1);
10340 for (long i = 0, sz = sources ? sources->size () : 0; i < sz; i++)
10341 {
10342 SourceFile *src = sources->get (i);
10343 if (src->id == id)
10344 {
10345 DbeFile *df = src->dbeFile;
10346 if (df)
10347 {
10348 char *fnm = df->find_file ((char *) locations->get (i1));
10349 if (fnm)
10350 {
10351 char *nm = df->get_name ();
10352 char *anm = exp->getNameInArchive (nm, false);
10353 exp->copy_file (fnm, anm, true);
10354 free (anm);
10355 }
10356 }
10357 }
10358 }
10359 }
10360}
10361
10362/* ************************************************************************ */
10363
10364/* Routines to check connection between Remote Analyzer Client and er_print */
10365char *
10366dbeCheckConnection (char *str)
10367{
10368 return dbe_strdup (str);
10369}