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