Update year range in copyright notice of binutils files
[binutils-gdb.git] / gprofng / src / Dbe.cc
blob91a5aa5ef05ac8ac77ab7054803a6cd6edd9cfec
1 /* Copyright (C) 2021-2024 Free Software Foundation, Inc.
2 Contributed by Oracle.
4 This file is part of GNU Binutils.
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3, or (at your option)
9 any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, 51 Franklin Street - Fifth Floor, Boston,
19 MA 02110-1301, USA. */
21 #include "config.h"
22 #include <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>
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"
66 // Data structures for managing the collector control info for Collection GUI
67 static Coll_Ctrl *col_ctr = NULL;
69 template<> VecType Vector<int>::type ()
71 return VEC_INTEGER;
74 template<> VecType Vector<unsigned>::type ()
76 return VEC_INTEGER;
79 template<> VecType Vector<char>::type ()
81 return VEC_CHAR;
84 template<> VecType Vector<bool>::type ()
86 return VEC_BOOL;
89 template<> VecType Vector<double>::type ()
91 return VEC_DOUBLE;
94 template<> VecType Vector<long long>::type ()
96 return VEC_LLONG;
99 template<> VecType Vector<uint64_t>::type ()
101 return VEC_LLONG;
104 template<> VecType Vector<void*>::type ()
106 return VEC_VOIDARR;
109 template<> VecType Vector<char*>::type ()
111 return VEC_STRING;
114 template<> VecType Vector<Vector<int>*>::type ()
116 return VEC_INTARR;
119 template<> VecType Vector<Vector<char*>*>::type ()
121 return VEC_STRINGARR;
124 template<> VecType Vector<Vector<long long>*>::type ()
126 return VEC_LLONGARR;
129 // gcc won't instantiate Vector<unsigned>::type() without it
130 Vector<unsigned> __dummy_unsigned_vector;
132 #define CASE_S(x) case x: return #x
133 static const char *
134 dsp_type_to_string (int t)
136 switch (t)
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;
171 return NTXT ("ERROR");
174 enum
176 COMPARE_BIT = 1 << 8,
177 MTYPE_MASK = (1 << 8) - 1,
178 GROUP_ID_SHIFT = 16
181 static DbeView *
182 getDbeView (int dbevindex)
184 DbeView *dbev = dbeSession->getView (dbevindex);
185 if (dbev == NULL)
186 abort ();
187 return dbev;
191 Vector<char*> *
192 dbeGetInitMessages ()
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)
199 size++;
200 msg = msg->next;
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)
210 char *str = msg->get_msg ();
211 list->store (i, dbe_strdup (str));
212 i++;
213 msg = msg->next;
216 // now delete the comments
217 theDbeApplication->delete_comments ();
218 return list;
221 Vector<char*> *
222 dbeGetExpPreview (int /*dbevindex*/, char *exp_name)
224 PreviewExp *preview = new PreviewExp ();
225 preview->experiment_open (exp_name);
226 preview->open_epilogue ();
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);
233 // Get experiment names
234 for (int i = 0; i < size; i++)
236 char *str = info->fetch (i);
237 if (str == NULL)
238 str = GTXT ("N/A");
239 list->store (i, dbe_strdup (str));
241 delete info;
242 delete preview;
243 return list;
246 char *
247 dbeGetExpParams (int /*dbevindex*/, char *exp_name)
249 PreviewExp *preview = new PreviewExp ();
250 preview->experiment_open (exp_name);
252 // Initialize Java String array
253 char *arg_list = dbe_strdup (preview->getArgList ());
254 delete preview;
255 return arg_list;
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
266 char *
267 dbeGetFileAttributes (const char *filename, const char *format)
269 if (format != NULL)
271 if (!strcmp (format, NTXT ("/bin/ls -dl ")))
273 // A kind of "/bin/ls -dl " simulation
274 dbe_stat_t 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);
286 return dbe_strdup (NTXT (""));
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
298 char *
299 dbeGetFiles (const char *dirname, const char *format)
301 if (format != NULL)
302 return dbe_read_dir (dirname, format);
303 return dbe_strdup (NTXT (""));
307 * Creates the directory named by this full path name, including any
308 * necessary but nonexistent parent directories.
309 * @param dirname
310 * @return result
312 char *
313 dbeCreateDirectories (const char *dirname)
315 if (dirname != NULL)
317 char *res = dbe_create_directories (dirname);
318 if (res != NULL)
319 return res;
321 return dbe_strdup (NTXT (""));
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
330 char *
331 dbeDeleteFile (const char *pathname)
333 // return unlink(pathname);
334 if (pathname != NULL)
336 char *res = dbe_delete_file (pathname);
337 if (res != NULL)
338 return res;
340 return dbe_strdup (NTXT (""));
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
351 Vector<char*> *
352 dbeReadFile (const char *pathname)
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)
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;
365 int fd = open (pathname, O_RDONLY);
366 if (fd >= 0)
368 int64_t bytes = read_from_file (fd, contents, limit);
369 close (fd);
370 if (bytes >= limit)
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
376 else
378 contents[bytes] = '\0'; // add string terminator
379 result->store (0, contents);
380 result->store (1, NULL); // success
383 else
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);
390 return result;
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)
401 dbeWriteFile (const char *pathname, const char *contents)
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;
421 return result;
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
431 char *
432 dbeGetRunningProcesses (const char *format)
434 if (format != NULL)
435 return dbe_get_processes (format);
436 return dbe_strdup (NTXT (""));
440 // Open experiment
442 char *
443 dbeOpenExperimentList (int /* dbevindex */, Vector<Vector<char*>*> *groups,
444 bool sessionRestart)
446 if (sessionRestart)
447 dbeSession->reset ();
448 char *errstr;
449 // Open experiments
452 errstr = dbeSession->setExperimentsGroups (groups);
454 catch (ExperimentLoadCancelException *)
456 errstr = dbe_strdup (NTXT ("Experiment Load Cancelled"));
458 return errstr;
462 // Drop experiments
464 char *
465 dbeDropExperiment (int /* dbevindex */, Vector<int> *drop_index)
467 for (int i = drop_index->size () - 1; i >= 0; i--)
469 char *ret = dbeSession->drop_experiment (drop_index->fetch (i));
470 if (ret != NULL)
471 return ret;
473 return NULL;
477 * Read .er.rc file from the specified location
478 * @param path
479 * @return
481 char *
482 dbeReadRCFile (int dbevindex, char* path)
484 DbeView *dbev = getDbeView (dbevindex);
485 char *err_msg = dbev->get_settings ()->read_rc (path);
486 return err_msg;
489 char *
490 dbeSetExperimentsGroups (Vector<Vector<char*>*> *groups)
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++)
499 DbeView *dbev = dbeSession->getView (i);
500 if (dbev == NULL)
501 break;
502 dbev->get_settings ()->set_compare_mode (cmp_mode);
504 char *err_msg = dbeSession->setExperimentsGroups (groups);
506 // automatically load machine model if applicable
507 dbeDetectLoadMachineModel (0);
508 return err_msg;
511 Vector<Vector<char*>*> *
512 dbeGetExperimensGroups ()
514 Vector<Vector<char*>*> *grops = dbeSession->getExperimensGroups ();
515 return grops;
518 Vector<int> *
519 dbeGetFounderExpId (Vector<int> *expIds)
521 Vector<int> *ret = new Vector<int>(expIds->size ());
522 for (int i = 0; i < expIds->size (); i++)
524 int expId = expIds->fetch (i);
525 Experiment *exp = dbeSession->get_exp (expId);
526 if (exp != NULL)
528 int founderExpId = exp->getBaseFounder ()->getExpIdx ();
529 ret->store (i, founderExpId);
531 else
532 ret->store (i, -1);
534 return ret;
537 Vector<int> *
538 dbeGetUserExpId (Vector<int> *expIds)
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++)
544 int expId = expIds->fetch (i);
545 Experiment *exp = dbeSession->get_exp (expId);
546 if (exp != NULL)
548 int userExpId = exp->getUserExpId ();
549 ret->store (i, userExpId);
551 else
552 ret->store (i, -1);
554 return ret;
558 // Get experiment groupid
560 Vector<int> *
561 dbeGetExpGroupId (Vector<int> *expIds)
563 Vector<int> *ret = new Vector<int>(expIds->size ());
564 for (int i = 0; i < expIds->size (); i++)
566 int expId = expIds->fetch (i);
567 Experiment *exp = dbeSession->get_exp (expId);
568 if (exp != NULL)
570 int gId = exp->groupId;
571 ret->store (i, gId);
573 else
574 ret->store (i, -1);
576 return ret;
579 Vector<char*> *
580 dbeGetExpsProperty (const char *prop_name)
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)
595 for (long i = 0; i < nexps; i++)
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)
606 s = sb.toString ();
607 empty = 0;
609 list->append (s);
612 if (empty)
614 delete list;
615 list = NULL;
617 return list;
621 // Get experiment names
623 Vector<char*> *
624 dbeGetExpName (int /*dbevindex*/)
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);
632 // Get experiment names
633 for (int i = 0; i < size; i++)
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);
640 return list;
644 // Get experiment state
646 Vector<int> *
647 dbeGetExpState (int /* dbevindex */)
649 int size = dbeSession->nexps ();
650 if (size == 0)
651 return NULL;
652 // Initialize Java array
653 Vector<int> *state = new Vector<int>(size);
655 // Get experiment state
656 for (int i = 0; i < size; i++)
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);
670 return state;
674 // Get enabled experiment indices
676 Vector<bool> *
677 dbeGetExpEnable (int dbevindex)
679 DbeView *dbev = getDbeView (dbevindex);
680 int size = dbeSession->nexps ();
681 if (dbev == NULL || size == 0)
682 return NULL;
684 // Get enabled experiment
685 Vector<bool> *enable = new Vector<bool>(size);
686 for (int i = 0; i < size; i++)
688 bool val = dbev->get_exp_enable (i) && !dbeSession->get_exp (i)->broken;
689 enable->store (i, val);
691 return enable;
695 // Get enabled experiment indices
697 bool
698 dbeSetExpEnable (int dbevindex, Vector<bool> *enable)
700 DbeView *dbev = getDbeView (dbevindex);
701 bool ret = false;
702 int size = dbeSession->nexps ();
703 if (dbev == NULL || size == 0)
704 return false;
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))
711 dbev->set_exp_enable (i, enable->fetch (i));
712 ret = true;
714 return ret;
718 // Get experiment info
720 Vector<char*> *
721 dbeGetExpInfo (int dbevindex)
723 DbeView *dbev = dbeSession->getView (dbevindex);
724 if (dbev == NULL)
725 abort ();
726 int size = dbeSession->nexps ();
727 if (size == 0)
728 return NULL;
730 // Initialize Java String array
731 Vector<char*> *list = new Vector<char*>(size * 2 + 1);
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++)
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);
755 return list;
758 bool
759 dbeGetViewModeEnable ()
761 return dbeSession->has_ompavail () || dbeSession->has_java ();
764 bool
765 dbeGetJavaEnable ()
767 return dbeSession->has_java ();
771 dbeUpdateNotes (int dbevindex, int exp_id, int type, char* text, bool handle_file)
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);
784 // Get load object names
786 Vector<char*> *
787 dbeGetLoadObjectName (int /* dbevindex */)
789 Vector<LoadObject*> *lobjs = dbeSession->get_text_segments ();
790 int size = lobjs->size ();
792 // Initialize Java String array
793 Vector<char*> *list = new Vector<char*>(size);
795 // Get load object names
796 LoadObject *lo;
797 int index;
798 Vec_loop (LoadObject*, lobjs, index, lo)
800 list->store (index, dbe_strdup (lo->get_name ()));
802 delete lobjs;
803 return list;
806 // XXX Will use later when order has to be passed too,
807 // Get complete List of tabs
809 Vector<void*> *
810 dbeGetTabList (int /* dbevindex */)
812 //DbeView *dbev = getDbeView (dbevindex);
813 //Vector<void*> *tabs = dbeSession->get_TabList();
814 //return tabs;
815 return NULL;
819 // Returns list of available tabs
821 Vector<void*> *
822 dbeGetTabListInfo (int dbevindex)
824 int index;
825 DispTab *dsptab;
826 DbeView *dbev = getDbeView (dbevindex);
828 // make sure the tabs are initialized properly
829 dbev->get_settings ()->proc_tabs (theDbeApplication->rdtMode);
830 Vector<DispTab*> *tabs = dbev->get_TabList ();
832 // Get number of available tabs
833 int size = 0;
834 Vec_loop (DispTab*, tabs, index, dsptab)
836 if (!dsptab->available)
837 continue;
838 size++;
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);
845 // Build list of avaliable tabs
846 int i = 0;
848 Vec_loop (DispTab*, tabs, index, dsptab)
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++;
857 data->store (0, typelist);
858 data->store (1, cmdlist);
859 data->store (2, ordlist);
860 return data;
863 // Return visibility state for all available tabs
865 Vector<bool> *
866 dbeGetTabSelectionState (int dbevindex)
868 int index;
869 DispTab *dsptab;
870 DbeView *dbev = getDbeView (dbevindex);
871 Vector<DispTab*> *tabs = dbev->get_TabList ();
873 // Get number of available tabs
874 int size = 0;
875 Vec_loop (DispTab*, tabs, index, dsptab)
877 if (!dsptab->available)
878 continue;
879 size++;
881 Vector<bool> *states = new Vector<bool>(size);
883 // Get visibility bit for all available tabs
884 int i = 0;
885 Vec_loop (DispTab*, tabs, index, dsptab)
887 if (!dsptab->available)
888 continue;
889 states->store (i++, dsptab->visible);
891 return states;
894 // Set visibility bit for a tab
895 void
896 dbeSetTabSelectionState (int dbevindex, Vector<bool> *selected)
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)
905 if (!dsptab->available)
906 continue;
907 dsptab->visible = selected->fetch (i++);
911 // Return visibility state for all available MemObj tabs
912 Vector<bool> *
913 dbeGetMemTabSelectionState (int dbevindex)
915 int index;
916 bool dsptab;
917 DbeView *dbev = getDbeView (dbevindex);
918 Vector<bool> *memtabs = dbev->get_MemTabState ();
920 // set the output vector
921 int size = memtabs->size ();
922 Vector<bool> *states = new Vector<bool>(size);
924 // Get visibility bit for all available tabs
925 int i = 0;
926 Vec_loop (bool, memtabs, index, dsptab)
928 states->store (i++, dsptab);
930 return states;
933 // Set visibility bit for a memory tab
935 void
936 dbeSetMemTabSelectionState (int dbevindex, Vector<bool> *selected)
938 DbeView *dbev = dbeSession->getView (dbevindex);
939 if (dbev == NULL)
940 abort ();
941 dbev->set_MemTabState (selected);
944 // Return visibility state for all available index tabs
945 Vector<bool> *
946 dbeGetIndxTabSelectionState (int dbevindex)
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 ();
955 // set the output vector
956 int size = indxtabs->size ();
957 Vector<bool> *states = new Vector<bool>(size);
959 // Get visibility bit for all available tabs
960 int i = 0;
961 Vec_loop (bool, indxtabs, index, dsptab)
963 states->store (i++, dsptab);
965 return states;
968 // Set visibility bit for a index tab
969 void
970 dbeSetIndxTabSelectionState (int dbevindex, Vector<bool> *selected)
972 DbeView *dbev = dbeSession->getView (dbevindex);
973 if (dbev == NULL)
974 abort ();
975 dbev->set_IndxTabState (selected);
979 // Get search path
981 Vector<char*> *
982 dbeGetSearchPath (int /*dbevindex*/)
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)
991 list->store (index, dbe_strdup (name));
993 return list;
997 // Set search path
999 void
1000 dbeSetSearchPath (int /*dbevindex*/, Vector<char*> *path)
1002 dbeSession->set_search_path (path, true);
1003 return;
1007 // Get pathmaps
1009 Vector<void*> *
1010 dbeGetPathmaps (int /*dbevindex*/)
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);
1020 int i = 0;
1021 Vec_loop (pathmap_t*, path, index, pthmap)
1023 oldlist->store (i, dbe_strdup (pthmap->old_prefix));
1024 newlist->store (i, dbe_strdup (pthmap->new_prefix));
1025 i++;
1027 data->store (0, oldlist);
1028 data->store (1, newlist);
1029 return data;
1030 } // dbeGetPathmaps
1032 char *
1033 dbeSetPathmaps (Vector<char*> *from, Vector<char*> *to)
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++)
1040 char *err = Settings::add_pathmap (newPath, from->get (i), to->get (i));
1041 if (err)
1043 newPath->destroy ();
1044 delete newPath;
1045 return err;
1048 dbeSession->set_pathmaps (newPath);
1049 return NULL;
1053 // Add pathmap
1054 char *
1055 dbeAddPathmap (int /* dbevindex */, char *from, char *to)
1057 Vector<pathmap_t*> *pmp = dbeSession->get_pathmaps ();
1058 char *err = Settings::add_pathmap (pmp, from, to);
1059 return err;
1063 // Get error/warning string of data
1064 char *
1065 dbeGetMsg (int dbevindex, int type)
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;
1082 // Create a DbeView, given new index, and index of view to clone
1084 dbeInitView (int id, int cloneid)
1086 return dbeSession->createView (id, cloneid);
1090 // Delete a DbeView
1091 void
1092 dbeDeleteView (int dbevindex)
1094 dbeSession->dropView (dbevindex);
1095 return;
1096 } // dbeDeleteView
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)
1104 DbeView *dbev = dbeSession->getView (dbevindex);
1105 MetricList *mlist = new MetricList (mtype);
1106 for (int i = 0, msize = type->size (); i < msize; i++)
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))
1118 mlist->set_sort_ref_index (i);
1121 return mlist;
1124 static Vector<void*> *
1125 dbeGetMetricList (MetricList *mlist)
1127 int clock_val = dbeSession->get_clock (-1);
1128 Vector<Metric*> *items = mlist->get_items ();
1129 int size = items->size ();
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);
1151 int sort_index = mlist->get_sort_ref_index ();
1152 // Fill metric elements
1153 for (int i = 0; i < size; i++)
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 ());
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)
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));
1185 data_type_name->append (_data_type_name);
1186 data_type_uname->append (_data_type_uname);
1188 char* _short_desc = NULL;
1189 if (m->get_type () == Metric::HWCNTR)
1191 Hwcentry * hwctr = m->get_hw_ctr ();
1192 if (hwctr)
1193 _short_desc = dbe_strdup (hwctr->short_desc);
1195 short_desc->append (_short_desc);
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;
1222 Vector<void*> *
1223 dbeGetRefMetricsV2 ()
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++)
1229 BaseMetric *bm = base_metrics->fetch (i);
1230 Metric *m;
1231 if (bm->get_flavors () & Metric::EXCLUSIVE)
1233 m = new Metric (bm, Metric::EXCLUSIVE);
1234 m->enable_all_visbits ();
1235 mlist->append (m);
1237 else if (bm->get_flavors () & BaseMetric::STATIC)
1239 m = new Metric (bm, BaseMetric::STATIC);
1240 m->enable_all_visbits ();
1241 mlist->append (m);
1244 Vector<void*> *data = dbeGetMetricList (mlist);
1245 delete mlist;
1246 return data;
1249 Vector<void*> *
1250 dbeGetCurMetricsV2 (int dbevindex, MetricType mtype)
1252 DbeView *dbev = dbeSession->getView (dbevindex);
1253 MetricList *mlist = dbev->get_metric_list (mtype);
1254 Vector<void*> *data = dbeGetMetricList (mlist);
1255 return data;
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)
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.
1280 return valuebits;
1283 static Vector<void*> *
1284 dbeGetMetricTreeNode (BaseMetricTreeNode* curr, MetricList *mlist,
1285 bool include_unregistered, bool has_clock_profiling_data)
1287 Vector<void*> *data = new Vector<void*>(2);
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);
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);
1308 char *_name = NULL;
1309 char *_username = NULL;
1310 char *_description = dbe_strdup (curr->get_description ());
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;
1326 BaseMetric *bm = curr->get_BaseMetric ();
1327 if (bm)
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 ())
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)
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;
1352 if (hide)
1354 _vstyles_e_default_values |= VAL_HIDE_ALL;
1355 _vstyles_i_derault_values |= VAL_HIDE_ALL;
1359 else
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 ());
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,
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);
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;
1407 Vec_loop (BaseMetricTreeNode*, children, index, child_node)
1409 if (include_unregistered /* fetch everything */
1410 || child_node->is_registered ()
1411 || child_node->get_num_registered_descendents () > 0)
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 ()))
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)
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);
1433 delete registered_descendents;
1434 continue;
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);
1442 data->append (children_list);
1443 return data;
1446 Vector<void*> *
1447 dbeGetRefMetricTree (int dbevindex, bool include_unregistered)
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++)
1454 Metric *m = mlist->get_items ()->fetch (i);
1455 if (m->get_packet_type () == DATA_CLOCK)
1457 has_clock_profiling_data = true;
1458 break;
1461 BaseMetricTreeNode *curr = dbeSession->get_reg_metrics_tree ();
1462 return dbeGetMetricTreeNode (curr, mlist, include_unregistered, has_clock_profiling_data);
1465 static Vector<void*> *
1466 dbeGetTableDataV2Data (DbeView *dbev, Hist_data *data);
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);
1473 static hrtime_t
1474 dbeCalcGroupDuration (int grInd)
1476 int thisGroupSize = 1;
1477 hrtime_t max_time = 0;
1478 Experiment *exp;
1479 if (dbeSession->expGroups->size () > 0)
1481 ExpGroup *grp = dbeSession->expGroups->fetch (grInd);
1482 thisGroupSize = grp->exps->size ();
1483 for (int ii = 0; ii < thisGroupSize; ii++)
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)
1490 hrtime_t tot_time = exp->getLastEvent () - exp->getStartTime ()
1491 + exp->getRelativeStartTime ();
1492 if (max_time < tot_time)
1493 max_time = tot_time;
1497 else
1499 exp = dbeSession->get_exp (0);
1500 if (exp != NULL)
1501 max_time = exp->getLastEvent () - exp->getStartTime ();
1503 return max_time; //nanoseconds
1506 static hrtime_t
1507 dbeCalcGroupGCDuration (int grInd)
1509 int thisGroupSize = 1;
1510 hrtime_t tot_time = 0;
1511 Experiment *exp;
1512 if (dbeSession->expGroups->size () > 0)
1514 ExpGroup *grp = dbeSession->expGroups->fetch (grInd);
1515 thisGroupSize = grp->exps->size ();
1516 for (int ii = 0; ii < thisGroupSize; ii++)
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 ();
1525 else
1527 exp = dbeSession->get_exp (0);
1528 if (exp != NULL)
1529 tot_time = exp->getGCDuration ();
1531 return tot_time; //nanoseconds
1534 Vector<void*> *
1535 dbeGetRefMetricTreeValues (int dbevindex, Vector<char *> *metric_cmds,
1536 Vector<char *> *non_metric_cmds)
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);
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++)
1559 Vector<void *> *columnData = new Vector<void *>();
1560 valueTable->append (columnData);
1561 highlightTable->append (columnData);
1563 return rc;
1566 int ngroups = dbeSession->expGroups->size (); // Rows (one per compare group)
1567 if (ngroups == 0 || !dbev->comparingExperiments ())
1568 ngroups = 1;
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
1581 if (numMetrics > 0)
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)
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);
1600 // MET_INDX will create MetricList of Exclusive metrics
1601 bmlist = new MetricList (base_metrics, MET_SRCDIS);
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++)
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 ();
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);
1623 // store the Hist_data totals in valueTable
1625 Metric *mitem;
1626 int index;
1627 Vec_loop (Metric*, bmlist->get_items (), index, mitem)
1629 Vector<void*> * columnData = dbeGetTableDataOneColumn (dbev,
1630 v_totals, mitem->get_vtype (), index);
1631 valueTable->append (columnData);
1635 // 7207285: hack for hwc profiling cycles conversion:
1637 Metric *mitem;
1638 int index;
1639 Vec_loop (Metric*, bmlist->get_items (), index, mitem)
1641 if (mitem->is_time_val ()
1642 && mitem->get_vtype () == VT_ULLONG)
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++)
1649 long long cycles = cycleValues->fetch (grInd);
1650 int expId;
1651 if (dbeSession->expGroups->size () > 0)
1653 ExpGroup *gr = dbeSession->expGroups->fetch (grInd);
1654 Experiment *exp = gr->exps->fetch (0);
1655 expId = exp->getExpIdx ();
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);
1667 delete cycleValues;
1668 valueTable->store (index, timeValues);
1673 // Scan metrics for best measure of CPU time
1674 int bestCpuTimeIndx = -1;
1676 Metric *mitem;
1677 int index;
1678 Vec_loop (Metric*, bmlist->get_items (), index, mitem)
1680 BaseMetric::Type type = mitem->get_type ();
1681 if (type == BaseMetric::CP_KERNEL_CPU)
1683 bestCpuTimeIndx = index;
1684 break; // CP_KERNEL_CPU trumps other measures
1686 if (type == BaseMetric::CP_TOTAL_CPU)
1688 // clock profiling CPU time
1689 bestCpuTimeIndx = index;
1690 // keep looking in case CP_KERNEL_CPU also exists
1691 continue;
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;
1702 if (bestCpuTimeIndx >= 0)
1704 Vector<double> *timeValues = (Vector<double> *)valueTable->fetch (bestCpuTimeIndx);
1705 if (timeValues->type () == VEC_DOUBLE)
1706 for (int grInd = 0; grInd < ngroups; grInd++)
1708 double time = timeValues->fetch (grInd);
1709 groupCpuTime->append (time);
1714 // Scan metrics for Total Thread time
1716 Metric *mitem;
1717 int index;
1718 Vec_loop (Metric*, bmlist->get_items (), index, mitem)
1720 BaseMetric::Type type = mitem->get_type ();
1721 if (type == BaseMetric::CP_TOTAL)
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++)
1728 double time = timeValues->fetch (grInd);
1729 groupTotalTime->append (time);
1731 break;
1736 // highlight metrics based on cpu time
1737 #define CPUSEC_PERCENT_THRESHOLD 10.0
1738 #define HWC_OVERFLOWS_PER_CPUSEC_THRESHOLD 15
1740 Metric *mitem;
1741 int index;
1742 Vec_loop (Metric*, bmlist->get_items (), index, mitem)
1744 BaseMetric::Type type = mitem->get_type ();
1745 Vector<bool> * columnHilites = (Vector<bool> *)highlightTable->fetch (index);
1747 // always highlight the following
1748 if (index == bestCpuTimeIndx)
1750 for (int grInd = 0; grInd < ngroups; grInd++)
1751 columnHilites->store (grInd, true);
1752 continue;
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
1773 continue; // types we never highlight
1775 // for time values, compare against CPUSEC_PERCENT_THRESHOLD
1776 bool isTime = ((mitem->get_value_styles () & VAL_TIMEVAL) != 0);
1777 if (isTime)
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++)
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);
1791 continue;
1794 // for HWC event counts, look at rate of events
1795 if (type == BaseMetric::HWCNTR)
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++)
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);
1825 continue;
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)
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++)
1839 long long thisVal = llValues->fetch (grInd);
1840 if (thisVal)
1841 columnHilites->store (grInd, true);
1843 continue;
1845 // continue adding cases as needed
1850 if (numNonMetrics > 0)
1852 int index;
1853 char *mcmd;
1854 Vec_loop (char *, non_metric_cmds, index, mcmd)
1856 if (dbe_strcmp (mcmd, NTXT ("YXXX_TOTAL_TIME_PLUS_THREADS")) == 0
1857 && groupCpuTime->size () == ngroups)
1859 Vector<char *> *columnData = new Vector<char *>(ngroups);
1860 for (int grInd = 0; grInd < ngroups; grInd++)
1862 double totaltime = groupTotalTime->fetch (grInd);
1863 columnData->append (dbe_sprintf (NTXT ("%0.3f %s"), totaltime, GTXT ("Seconds")));
1865 valueTable->append (columnData);
1867 else if (dbe_strcmp (mcmd, L1_DURATION) == 0)
1869 Vector<double> *columnData = new Vector<double>(ngroups);
1870 for (int grInd = 0; grInd < ngroups; grInd++)
1872 hrtime_t duration = dbeCalcGroupDuration (grInd);
1873 double seconds = duration * 1.e-9;
1874 columnData->append (seconds);
1876 valueTable->append (columnData);
1878 else if (dbe_strcmp (mcmd, L1_GCDURATION) == 0)
1880 Vector<double> *columnData = new Vector<double>(ngroups);
1881 for (int grInd = 0; grInd < ngroups; grInd++)
1883 hrtime_t duration = dbeCalcGroupGCDuration (grInd);
1884 double seconds = duration * 1.e-9;
1885 columnData->append (seconds);
1887 valueTable->append (columnData);
1889 else
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);
1899 return rc;
1902 Vector<char*> *
1903 dbeGetOverviewText (int dbevindex)
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++)
1913 int thisGroupSize = 1;
1914 Experiment *exp;
1915 if (dbeSession->expGroups->size () > 0)
1917 ExpGroup *gr = dbeSession->expGroups->fetch (grInd);
1918 exp = gr->exps->fetch (0);
1919 thisGroupSize = gr->exps->size ();
1921 else
1923 if (dbeSession->nexps () == 0)
1924 return info;
1925 exp = dbeSession->get_exp (0);
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 (GTXT (" Host : %s (%s, %s)"),
1948 field,
1949 exp->architecture ? exp->architecture
1950 : GTXT ("<CPU architecture not recorded>"),
1951 exp->os_version ? exp->os_version
1952 : GTXT ("<OS version not recorded>")));
1953 time_t start_sec = (time_t) exp->start_sec;
1954 char *p = ctime (&start_sec);
1955 hrtime_t tot_time = dbeCalcGroupDuration (grInd);
1956 double seconds = tot_time * 1.e-9;
1957 info->append (dbe_sprintf (
1958 GTXT (" Start Time : %s Duration : %0.3f Seconds"),
1959 p, seconds));
1960 // Number of descendants/processes would be nice
1961 info->append (dbe_strdup (NTXT ("")));
1963 return info;
1966 //--------------------------------------------------------------------------
1967 // Set Sort by index
1969 void
1970 dbeSetSort (int dbevindex, int sort_index, MetricType mtype, bool reverse)
1972 DbeView *dbev;
1974 dbev = dbeSession->getView (dbevindex);
1975 if (dbev == NULL)
1976 abort ();
1977 dbev->setSort (sort_index, mtype, reverse);
1978 return;
1982 // Get annotation setting
1984 Vector<int> *
1985 dbeGetAnoValue (int dbevindex)
1987 DbeView *dbev = dbeSession->getView (dbevindex);
1988 if (dbev == NULL)
1989 abort ();
1990 Vector<int> *set = new Vector<int>(9);
1991 set->store (0, dbev->get_src_compcom ());
1992 set->store (1, dbev->get_dis_compcom ());
1993 set->store (2, dbev->get_thresh_src ());
1994 set->store (3, dbev->get_thresh_src ());
1995 set->store (4, dbev->get_src_visible ());
1996 set->store (5, (int) dbev->get_srcmetric_visible ());
1997 set->store (6, (int) dbev->get_hex_visible ());
1998 set->store (7, (int) dbev->get_cmpline_visible ());
1999 set->store (8, (int) dbev->get_func_scope ());
2000 return set;
2004 // Set annotation setting
2006 void
2007 dbeSetAnoValue (int dbevindex, Vector<int> *set)
2009 DbeView *dbev;
2010 dbev = dbeSession->getView (dbevindex);
2011 if (dbev == NULL)
2012 abort ();
2013 if (set->size () != 10)
2014 return;
2015 dbev->set_src_compcom (set->fetch (0));
2016 dbev->set_dis_compcom (set->fetch (1));
2017 dbev->set_thresh_src (set->fetch (2));
2018 dbev->set_thresh_dis (set->fetch (3));
2019 dbev->set_src_visible (set->fetch (4));
2020 dbev->set_srcmetric_visible ((bool)set->fetch (5));
2021 dbev->set_hex_visible ((bool)set->fetch (6));
2022 dbev->set_cmpline_visible ((bool)set->fetch (7));
2023 dbev->set_func_scope (set->fetch (8));
2024 dbev->set_funcline_visible ((bool)set->fetch (9));
2025 return;
2029 // Get name formats
2032 dbeGetNameFormat (int dbevindex)
2034 DbeView *dbev;
2035 dbev = dbeSession->getView (dbevindex);
2036 if (dbev == NULL)
2037 abort ();
2038 Histable::NameFormat fmt = dbev->get_name_format ();
2039 return Histable::fname_fmt (fmt);
2042 bool
2043 dbeGetSoName (int dbevindex)
2045 DbeView *dbev;
2046 dbev = dbeSession->getView (dbevindex);
2047 if (dbev == NULL)
2048 abort ();
2049 Histable::NameFormat fmt = dbev->get_name_format ();
2050 return Histable::soname_fmt (fmt);
2054 // Set name formats
2056 void
2057 dbeSetNameFormat (int dbevindex, int nformat, bool soname)
2059 DbeView *dbev;
2060 dbev = dbeSession->getView (dbevindex);
2061 if (dbev == NULL)
2062 abort ();
2063 dbev->set_name_format (nformat, soname);
2067 // Get View mode
2070 dbeGetViewMode (int dbevindex)
2072 DbeView *dbev;
2073 dbev = dbeSession->getView (dbevindex);
2074 if (dbev == NULL)
2075 abort ();
2076 return (int) dbev->get_view_mode ();
2079 // Set View mode
2080 void
2081 dbeSetViewMode (int dbevindex, int nmode)
2083 DbeView *dbev;
2084 dbev = dbeSession->getView (dbevindex);
2085 if (dbev == NULL)
2086 abort ();
2087 dbev->set_view_mode ((VMode) nmode);
2088 return;
2091 // Get timeline setting
2093 Vector<void*> *
2094 dbeGetTLValue (int dbevindex)
2096 DbeView *dbev;
2097 dbev = dbeSession->getView (dbevindex);
2098 if (dbev == NULL)
2099 abort ();
2100 Vector<char *> *strings = new Vector<char *>();
2101 char *tldata_cmd = dbev->get_tldata ();
2102 strings->store (0, tldata_cmd);
2104 Vector<int> *ints = new Vector<int>(3);
2105 int val;
2106 val = dbev->get_tlmode ();
2107 ints->store (0, val);
2108 val = dbev->get_stack_align ();
2109 ints->store (1, val);
2110 val = dbev->get_stack_depth ();
2111 ints->store (2, val);
2113 Vector<void*> *objs = new Vector<void*>(2);
2114 objs->store (0, strings);
2115 objs->store (1, ints);
2116 return objs;
2120 // Set timeline setting
2122 void
2123 dbeSetTLValue (int dbevindex, const char *tldata_cmd,
2124 int entitiy_prop_id, int stackalign, int stackdepth)
2126 DbeView *dbev;
2127 dbev = dbeSession->getView (dbevindex);
2128 if (dbev == NULL)
2129 abort ();
2130 dbev->set_tldata (tldata_cmd);
2131 dbev->set_tlmode (entitiy_prop_id);
2132 dbev->set_stack_align (stackalign);
2133 dbev->set_stack_depth (stackdepth);
2134 return;
2138 // Get founder experiments and their descendants
2140 Vector<void*> *
2141 dbeGetExpFounderDescendants ()
2143 int size = dbeSession->nexps ();
2144 if (size == 0)
2145 return NULL;
2146 Vector<void*> *table = new Vector<void*>(2);
2147 Vector<int> *founderExpIds = new Vector<int>();
2148 Vector<Vector<int> *> *subExpIds = new Vector<Vector<int>*>();
2149 for (int index = 0; index < size; index++)
2151 Experiment *exp = dbeSession->get_exp (index);
2152 if (exp->founder_exp == NULL)
2154 founderExpIds->append (exp->getExpIdx ());
2155 Vector<int> *subExps = new Vector<int>();
2156 for (int i = 0; i < exp->children_exps->size (); i++)
2158 Experiment * subExp = exp->children_exps->fetch (i);
2159 subExps->append (subExp->getExpIdx ());
2161 subExpIds->append (subExps);
2164 table->store (0, founderExpIds);
2165 table->store (1, subExpIds);
2166 return table;
2170 // Get experiment selection
2172 Vector<void*> *
2173 dbeGetExpSelection (int dbevindex)
2175 DbeView *dbev = dbeSession->getView (dbevindex);
2176 if (dbev == NULL)
2177 abort ();
2178 int size = dbeSession->nexps ();
2179 if (size == 0)
2180 return NULL;
2181 Vector<void*> *table = new Vector<void*>(3);
2182 Vector<char*> *names = new Vector<char*>(size);
2183 Vector<bool> *enable = new Vector<bool>(size);
2184 Vector<int> *userExpIds = new Vector<int>(size);
2186 // Get experiment names
2187 for (int index = 0; index < size; index++)
2189 Experiment *exp = dbeSession->get_exp (index);
2190 char *buf = dbeGetName (dbevindex, index);
2191 names->store (index, buf);
2192 bool val;
2193 val = dbev->get_exp_enable (index);
2194 enable->store (index, val);
2195 userExpIds->store (index, exp->getUserExpId ());
2197 table->store (0, names);
2198 table->store (1, enable);
2199 table->store (2, userExpIds);
2200 return table;
2204 dbeValidateFilterExpression (char *str_expr)
2206 if (str_expr == NULL)
2207 return 0;
2208 Expression *expr = dbeSession->ql_parse (str_expr);
2209 if (expr == NULL)
2210 return 0;
2211 delete expr;
2212 return 1;
2215 Vector<void*> *
2216 dbeGetFilterKeywords (int /* dbevindex */)
2218 Vector <char*> *kwCategory = new Vector<char *>();
2219 Vector <char*> *kwCategoryI18N = new Vector<char *>();
2220 Vector <char*> *kwDataType = new Vector<char *>();
2221 Vector <char*> *kwKeyword = new Vector<char *>();
2222 Vector <char*> *kwFormula = new Vector<char *>();
2223 Vector <char*> *kwDescription = new Vector<char *>();
2224 Vector <void*> *kwEnumDescs = new Vector<void *>();
2226 Vector<void*> *res = new Vector<void*>(7);
2227 res->append (kwCategory);
2228 res->append (kwCategoryI18N);
2229 res->append (kwDataType);
2230 res->append (kwKeyword);
2231 res->append (kwFormula);
2232 res->append (kwDescription);
2233 res->append (kwEnumDescs);
2235 char *vtypeNames[] = VTYPE_TYPE_NAMES;
2236 // section header for global definitions
2237 kwCategory->append (dbe_strdup (NTXT ("FK_SECTION")));
2238 kwCategoryI18N->append (dbe_strdup (GTXT ("Global Definitions")));
2239 kwDataType->append (NULL);
2240 kwKeyword->append (NULL);
2241 kwFormula->append (NULL);
2242 kwDescription->append (NULL);
2243 kwEnumDescs->append (NULL);
2244 dbeSession->get_filter_keywords (res);
2245 MemorySpace::get_filter_keywords (res);
2247 // loop thru all founder experiments
2248 int nexp = dbeSession->nexps ();
2249 for (int ii = 0; ii < nexp; ++ii)
2251 Experiment* fexp = dbeSession->get_exp (ii);
2252 if (fexp->founder_exp != NULL)
2253 continue; // is a child; should be covered when we get to founder
2255 // section header for each founder
2256 // section header for founder experiment
2257 kwCategory->append (dbe_strdup (NTXT ("FK_SECTION")));
2258 kwCategoryI18N->append (dbe_sprintf (NTXT ("%s [EXPGRID==%d]"),
2259 fexp->get_expt_name (),
2260 fexp->groupId));
2261 kwDataType->append (NULL);
2262 kwKeyword->append (NULL);
2263 kwFormula->append (NULL);
2264 kwDescription->append (NULL);
2265 kwEnumDescs->append (NULL);
2267 int nchildren = fexp->children_exps->size ();
2268 Experiment *exp;
2269 // category header: Experiments
2271 char *propUName = dbeSession->getPropUName (PROP_EXPID);
2273 // store list of subexperiments in kwEnumDescs
2274 Vector <char*> *enumDescs = new Vector<char *>();
2275 int jj = 0;
2276 exp = fexp;
2277 while (1)
2279 char * expBasename = get_basename (exp->get_expt_name ());
2280 char * targetName = exp->utargname ? exp->utargname
2281 : (char *) GTXT ("(unknown)");
2282 enumDescs->append (dbe_sprintf (NTXT ("(%d) -> %s [%s, PID %d]"),
2283 exp->getUserExpId (), expBasename,
2284 targetName, exp->getPID ()));
2285 if (jj >= nchildren)
2286 break;
2287 exp = fexp->children_exps->fetch (jj);
2288 jj++;
2290 kwCategory->append (dbe_strdup (NTXT ("FK_EXPLIST")));
2291 kwCategoryI18N->append (dbe_strdup (GTXT ("Experiments")));
2292 kwDataType->append (dbe_strdup (vtypeNames[TYPE_INT32]));
2293 kwKeyword->append (dbe_strdup (NTXT ("EXPID")));
2294 kwFormula->append (NULL);
2295 kwDescription->append (propUName);
2296 kwEnumDescs->append (enumDescs);
2299 // select representative experiment
2300 if (nchildren == 0)
2301 exp = fexp; // founder
2302 else
2303 exp = fexp->children_exps->fetch (0); // first child
2304 int expIdx = exp->getExpIdx ();
2305 Vector<void*> *data = dbeGetDataDescriptorsV2 (expIdx);
2306 if (data == NULL)
2307 continue;
2308 Vector<int> *dataId = (Vector<int>*)data->fetch (0);
2309 Vector<char*> *dataName = (Vector<char*>*)data->fetch (1);
2310 Vector<char*> *dataUName = (Vector<char*>*)data->fetch (2);
2311 if (dataId == NULL || dataName == NULL)
2313 destroy (data);
2314 continue;
2316 // loop thru data descriptors
2317 int ndata = dataId->size ();
2318 for (int j = 0; j < ndata; ++j)
2320 // category: data name (e.g. Clock Profiling)
2321 char * catName = dataName->fetch (j);
2322 char * dUname = dataUName ? dataUName->fetch (j) : catName;
2323 char * catUname = dUname ? dUname : catName;
2325 Vector<void*> *props = dbeGetDataPropertiesV2 (expIdx, dataId->fetch (j));
2326 if (props == NULL)
2327 continue;
2328 Vector<char*> *propUName = (Vector<char*>*)props->fetch (1);
2329 Vector<int> *propTypeId = (Vector<int> *)props->fetch (2);
2330 Vector<char*> *propType = (Vector<char*>*)props->fetch (3);
2331 Vector<char*> *propName = (Vector<char*>*)props->fetch (5);
2332 Vector<Vector<char*>*> *propStateNames =
2333 (Vector<Vector<char*>*> *)props->fetch (6);
2334 Vector<Vector<char*>*> *propStateUNames =
2335 (Vector<Vector<char*>*> *)props->fetch (7);
2336 if (propName == NULL || propUName == NULL || propType == NULL
2337 || propName->size () <= 0)
2339 destroy (props);
2340 continue;
2342 int nprop = propName->size ();
2343 for (int k = 0; k < nprop; ++k)
2345 if (propTypeId->fetch (k) == TYPE_OBJ)
2346 continue;
2347 if (dbe_strcmp (propName->fetch (k), NTXT ("FRINFO")) == 0)
2348 continue;
2350 // store list of states in kwEnumDescs
2351 Vector<char*> *enumDescs = new Vector<char *>();
2352 Vector<char*>* stateNames = propStateNames->fetch (k);
2353 Vector<char*>* stateUNames = propStateUNames->fetch (k);
2354 int nStates = stateNames ? stateNames->size () : 0;
2355 for (int kk = 0; kk < nStates; ++kk)
2357 const char *stateName = stateNames->fetch (kk);
2358 if (stateName == NULL || strlen (stateName) == 0)
2359 continue;
2360 const char *stateUName = stateUNames->fetch (kk);
2361 if (stateUName == NULL || strlen (stateUName) == 0)
2362 stateUName = stateName;
2363 enumDescs->append (dbe_sprintf (NTXT ("(%d) -> %s"), kk, stateUName));
2365 kwCategory->append (dbe_strdup (catName));
2366 kwCategoryI18N->append (dbe_strdup (catUname));
2367 kwDataType->append (dbe_strdup (propType->fetch (k)));
2368 kwKeyword->append (dbe_strdup (propName->fetch (k)));
2369 kwFormula->append (NULL);
2370 kwDescription->append (dbe_strdup (propUName->fetch (k)));
2371 kwEnumDescs->append (enumDescs);
2373 destroy (props);
2375 destroy (data);
2377 return (res);
2380 // GetFilters -- returns the list of filters for the indexed experiment
2381 // returns false if there's a problem; true otherwise
2383 Vector<void*> *
2384 dbeGetFilters (int dbevindex, int nexp)
2386 FilterNumeric *filt;
2387 int index;
2388 DbeView *dbev = dbeSession->getView (dbevindex);
2389 if (dbev == NULL)
2390 abort ();
2391 Vector<FilterNumeric *>*filters = dbev->get_all_filters (nexp);
2392 if (filters == NULL)
2393 return NULL;
2395 // return an array of filter data for that experiment
2396 Vector <int> *findex = new Vector<int>(); // index of the filters
2397 Vector <char*> *shortname = new Vector<char *>();
2398 // short name of filter
2399 Vector <char*> *i18n_name = new Vector<char *>();
2400 // External I18N'd name of filter
2401 Vector <char*> *pattern = new Vector<char *>();
2402 // current setting string
2403 Vector <char*> *status = new Vector<char *>();
2404 // current status of filter (%, range, etc.)
2406 Vec_loop (FilterNumeric *, filters, index, filt)
2408 findex->append (index);
2409 shortname->append (dbe_strdup (filt->get_cmd ()));
2410 i18n_name->append (dbe_strdup (filt->get_name ()));
2411 pattern->append (dbe_strdup (filt->get_pattern ()));
2412 status->append (dbe_strdup (filt->get_status ()));
2414 Vector<void*> *res = new Vector<void*>(5);
2415 res->store (0, findex);
2416 res->store (1, shortname);
2417 res->store (2, i18n_name);
2418 res->store (3, pattern);
2419 res->store (4, status);
2420 return (res);
2423 // Set a filter string for a view
2424 // Returns NULL if OK, error message if not
2426 char *
2427 dbeSetFilterStr (int dbevindex, char *filter_str)
2429 DbeView *dbev = dbeSession->getView (dbevindex);
2430 if (dbev == NULL)
2431 abort ();
2432 dbev->clear_error_msg ();
2433 dbev->clear_warning_msg ();
2434 char *ret = dbev->set_filter (filter_str);
2435 return ret;
2438 // Get the current filter setting for the view
2439 char *
2440 dbeGetFilterStr (int dbevindex)
2442 DbeView *dbev = dbeSession->getView (dbevindex);
2443 if (dbev == NULL)
2444 abort ();
2445 char *ret = dbev->get_filter ();
2446 return ret;
2449 // Update a filters for a single experiment
2450 // Returns true if any filter->set_pattern() returns true,
2451 // implying rereading the data is needed (i.e., a filter changed)
2453 bool
2454 dbeUpdateFilters (int dbevindex, Vector<bool> *selected, Vector<char *> *pattern_str)
2456 DbeView *dbev = dbeSession->getView (dbevindex);
2457 if (dbev == NULL)
2458 abort ();
2459 dbev->clear_error_msg ();
2460 dbev->clear_warning_msg ();
2462 // Get index of first selected experiment
2463 int size = selected->size ();
2464 int nselexp = -1;
2465 for (int index = 0; index < size; index++)
2467 if (selected->fetch (index) == true)
2469 nselexp = index;
2470 break;
2473 if (nselexp == -1) // No experiment selected
2474 return false;
2476 bool ret = false;
2477 for (int j = 0; j < size; j++)
2479 if (selected->fetch (j) == false)
2480 continue;
2481 bool error;
2482 if (dbev->set_pattern (j, pattern_str, &error))
2483 ret = true;
2485 dbev->update_advanced_filter ();
2486 return ret;
2489 char *
2490 dbeComposeFilterClause (int dbevindex, int type, int subtype, Vector<int> *selections)
2492 DbeView *dbev = dbeSession->getView (dbevindex);
2493 if (dbev == NULL)
2494 abort ();
2495 // ask the cached data to generate the string
2496 Hist_data *data;
2497 switch (type)
2499 case DSP_FUNCTION:
2500 data = dbev->func_data;
2501 break;
2502 case DSP_DLAYOUT:
2503 data = dbev->dlay_data;
2504 break;
2505 case DSP_DATAOBJ:
2506 data = dbev->dobj_data;
2507 break;
2508 case DSP_MEMOBJ:
2509 case DSP_INDXOBJ:
2510 data = dbev->get_indxobj_data (subtype);
2511 break;
2512 case DSP_LINE:
2513 data = dbev->line_data;
2514 break;
2515 case DSP_PC:
2516 data = dbev->pc_data;
2517 break;
2518 case DSP_SOURCE:
2519 data = dbev->src_data;
2520 break;
2521 case DSP_DISASM:
2522 data = dbev->dis_data;
2523 break;
2524 case DSP_IOACTIVITY:
2525 data = dbev->iofile_data;
2526 break;
2527 case DSP_IOVFD:
2528 data = dbev->iovfd_data;
2529 break;
2530 case DSP_IOCALLSTACK:
2531 data = dbev->iocs_data;
2532 break;
2533 case DSP_HEAPCALLSTACK:
2534 data = dbev->heapcs_data;
2535 break;
2536 default:
2537 return NULL;
2539 if (data == NULL)
2540 return NULL;
2542 // Get array of object indices, and compose filter string
2543 Vector<uint64_t> *obj_ids = data->get_object_indices (selections);
2544 if (obj_ids == NULL || obj_ids->size () == 0)
2545 return NULL;
2547 uint64_t sel;
2548 int index;
2549 int found = 0;
2550 char buf[128];
2551 StringBuilder sb;
2552 sb.append ('(');
2553 switch (type)
2555 case DSP_LINE:
2556 case DSP_PC:
2557 case DSP_SOURCE:
2558 case DSP_DISASM:
2559 case DSP_FUNCTION:
2560 sb.append (NTXT ("LEAF IN "));
2561 break;
2562 case DSP_MEMOBJ:
2563 case DSP_INDXOBJ:
2564 sb.append (dbeSession->getIndexSpaceName (subtype));
2565 sb.append (NTXT (" IN "));
2566 break;
2568 Vec_loop (uint64_t, obj_ids, index, sel)
2570 if (found == 0)
2572 found = 1;
2573 sb.append ('(');
2575 else
2576 sb.append (NTXT (", "));
2577 snprintf (buf, sizeof (buf), NTXT ("%llu"), (long long) sel);
2578 sb.append (buf);
2580 if (found == 1)
2581 sb.append (')');
2583 switch (type)
2585 case DSP_DLAYOUT:
2586 case DSP_DATAOBJ:
2587 sb.append (NTXT (" SOME IN DOBJ"));
2588 break;
2590 sb.append (')');
2591 return sb.toString ();
2595 // Get load object states
2597 Vector<void *> *
2598 dbeGetLoadObjectList (int dbevindex)
2600 DbeView *dbev = dbeSession->getView (dbevindex);
2601 if (dbev == NULL)
2602 abort ();
2603 Vector<LoadObject*> *lobjs = dbeSession->get_text_segments ();
2604 int size = lobjs->size ();
2606 // Initialize Java boolean array
2607 Vector<char *> *names = new Vector<char *>(size);
2608 Vector<int> *states = new Vector<int>(size);
2609 Vector<int> *indices = new Vector<int>(size);
2610 Vector<char *> *paths = new Vector<char *>(size);
2611 Vector<int> *isJava = new Vector<int>(size);
2613 // Get load object states
2614 int index;
2615 LoadObject *lo;
2616 char *lo_name;
2618 // lobjectsNoJava is a trimmed list of indices provided to front-end skipping the Java
2619 // classes. lobjectsNoJava preserves the mapping of the index into the complete lobjs
2620 // vector. What front-end sees as lobj[i] is really lobj[lobjectsNoJava[i]];
2622 // This list is constructed every time GetLoadObjectList() or GetLoadObjectState() is
2623 // called. Possibility of further optimization by making it more persistent.
2624 // Only consumer of this list is dbeSetLoadObjectState
2625 int new_index = 0;
2626 if (dbev->lobjectsNoJava == NULL)
2627 dbev->lobjectsNoJava = new Vector<int>(1);
2628 else
2629 dbev->lobjectsNoJava->reset ();
2631 Vec_loop (LoadObject*, lobjs, index, lo)
2633 // Set 0, 1, or 2 for show/hide/api
2634 enum LibExpand expand = dbev->get_lo_expand (lo->seg_idx);
2636 lo_name = lo->get_name ();
2637 if (lo_name != NULL)
2639 size_t len = strlen (lo_name);
2640 if (len > 7 && streq (lo_name + len - 7, NTXT (".class>")))
2641 isJava->store (new_index, 1);
2642 else
2643 isJava->store (new_index, 0);
2645 else
2646 isJava->store (new_index, 0);
2647 dbev->lobjectsNoJava->append (index);
2649 names->store (new_index, dbe_sprintf (NTXT ("%s"), lo_name));
2650 states->store (new_index, (int) expand);
2651 indices->store (new_index, (int) lo->seg_idx);
2652 paths->store (new_index, dbe_sprintf (NTXT ("%s"), lo->get_pathname ()));
2653 new_index++;
2655 Vector<void*> *res = new Vector<void*>(5);
2656 res->store (0, names);
2657 res->store (1, states);
2658 res->store (2, indices);
2659 res->store (3, paths);
2660 res->store (4, isJava);
2661 delete lobjs;
2662 return res;
2665 Vector<int> *
2666 dbeGetLoadObjectState (int dbevindex)
2668 DbeView *dbev = dbeSession->getView (dbevindex);
2669 if (dbev == NULL)
2670 abort ();
2671 Vector<LoadObject*> *lobjs = dbeSession->get_text_segments ();
2672 int size = lobjs->size ();
2674 // Initialize Java boolean array
2675 Vector<int> *states = new Vector<int>(size);
2676 char *lo_name;
2678 // lobjectsNoJava is a trimmed list of indices provided to front-end skipping the Java
2679 // classes. lobjectsNoJava preserves the mapping of the index into the complete lobjs
2680 // vector. What front-end sees as lobj[i] is really lobj[lobjectsNoJava[i]];
2682 // This list is constructed every time GetLoadObjectList() or GetLoadObjectState() is
2683 // called. Possibility of further optimization by making it more persistent.
2684 // Only consumer of this list is dbeSetLoadObjectState
2685 int new_index = 0;
2686 if (dbev->lobjectsNoJava == NULL)
2687 dbev->lobjectsNoJava = new Vector<int>(1);
2688 else
2689 dbev->lobjectsNoJava->reset ();
2691 // Get load object states
2692 int index;
2693 LoadObject *lo;
2695 Vec_loop (LoadObject*, lobjs, index, lo)
2697 // Set 0, 1, or 2 for show/hide/api
2698 lo_name = lo->get_name ();
2699 if (lo_name != NULL)
2701 size_t len = strlen (lo_name);
2702 if (len > 7 && streq (lo_name + len - 7, NTXT (".class>")))
2703 continue;
2705 else
2706 dbev->lobjectsNoJava->append (index);
2708 enum LibExpand expand = dbev->get_lo_expand (lo->seg_idx);
2709 states->store (new_index, (int) expand);
2710 new_index++;
2712 delete lobjs;
2713 return states;
2716 // Set load object states
2717 void
2718 dbeSetLoadObjectState (int dbevindex, Vector<int> *selected)
2720 DbeView *dbev = dbeSession->getView (dbevindex);
2721 if (dbev == NULL)
2722 abort ();
2723 Vector<LoadObject*> *lobjs = dbeSession->get_text_segments ();
2725 int index;
2726 bool changed = false;
2728 LoadObject *lo;
2729 int new_index = 0;
2730 dbev->setShowAll ();
2731 Vec_loop (LoadObject*, lobjs, index, lo)
2733 if (dbev->lobjectsNoJava != NULL)
2735 // This loadobject is a java class and was skipped
2736 if (dbev->lobjectsNoJava->fetch (new_index) != index)
2737 continue;
2739 // Get array of settings
2740 enum LibExpand expand = (enum LibExpand) selected->fetch (new_index);
2741 if (expand == LIBEX_HIDE)
2743 dbev->resetShowAll ();
2744 dbeSession->set_lib_visibility_used ();
2746 changed = changed | dbev->set_libexpand (lo->get_pathname (), expand);
2747 new_index++;
2749 delete lobjs;
2750 if (changed == true)
2752 dbev->setShowHideChanged ();
2753 dbev->update_lo_expands ();
2756 return;
2759 // Reset load object states
2760 void
2761 dbeSetLoadObjectDefaults (int dbevindex)
2763 DbeView *dbev = dbeSession->getView (dbevindex);
2764 if (dbev == NULL)
2765 abort ();
2766 dbev->set_libdefaults ();
2769 // Get Machine model
2770 Vector<char*>*
2771 dbeGetCPUVerMachineModel (int dbevindex)
2773 Vector<char*>* table = new Vector<char*>();
2774 DbeView *dbev = dbeSession->getView (dbevindex);
2775 char * mach_model = dbev->get_settings ()->get_machinemodel ();
2776 if (mach_model != NULL)
2778 table->append (mach_model);
2779 return table;
2781 int grsize = dbeSession->expGroups->size ();
2782 for (int j = 0; j < grsize; j++)
2784 ExpGroup *gr = dbeSession->expGroups->fetch (j);
2785 Vector<Experiment*> *exps = gr->exps;
2786 for (int i = 0, sz = exps->size (); i < sz; i++)
2788 Experiment *exp = exps->fetch (i);
2789 char *model = exp->machinemodel;
2790 if (model != NULL)
2791 table->append (dbe_strdup (model));
2794 return table;
2797 // automatically load machine model if applicable
2798 void
2799 dbeDetectLoadMachineModel (int dbevindex)
2801 if (dbeSession->is_datamode_available ())
2803 char *model = dbeGetMachineModel ();
2804 if (model == NULL)
2806 Vector<char*>* models = dbeGetCPUVerMachineModel (dbevindex);
2807 char * machineModel = NTXT ("generic");
2808 if (models->size () > 0)
2810 machineModel = models->get (0);
2811 for (int i = 1; i < models->size (); i++)
2813 if (strncmp (models->get (i), machineModel, strlen (machineModel)) == 0)
2815 machineModel = NTXT ("generic");
2816 break;
2819 dbeLoadMachineModel (machineModel);
2821 delete models;
2826 // Managing Memory Objects
2827 char *
2828 dbeDefineMemObj (char *name, char *index_expr, char *machinemodel,
2829 char *sdesc, char *ldesc)
2831 return MemorySpace::mobj_define (name, index_expr, machinemodel, sdesc, ldesc);
2834 char *
2835 dbeDeleteMemObj (char *name)
2837 return MemorySpace::mobj_delete (name);
2840 Vector<void*> *
2841 dbeGetMemObjects (int /*dbevindex*/)
2843 Vector<void*> *res = MemorySpace::getMemObjects ();
2844 return res;
2847 // Managing machine model
2848 char *
2849 dbeLoadMachineModel (char *name)
2851 return dbeSession->load_mach_model (name);
2854 char *
2855 dbeGetMachineModel ()
2857 return dbeSession->get_mach_model ();
2860 Vector <char *> *
2861 dbeListMachineModels ()
2863 return dbeSession->list_mach_models ();
2866 // Managing Index Objects
2867 char *
2868 dbeDefineIndxObj (char *name, char *index_expr, char *sdesc, char *ldesc)
2870 return dbeSession->indxobj_define (name, NULL, index_expr, sdesc, ldesc);
2873 Vector<void*> *
2874 dbeGetIndxObjDescriptions (int /*dbevindex*/)
2876 Vector<void*> *res = dbeSession->getIndxObjDescriptions ();
2877 return res;
2880 Vector<void*> *
2881 dbeGetCustomIndxObjects (int /*dbevindex*/)
2883 Vector<void*> *res = dbeSession->getCustomIndxObjects ();
2884 return res;
2887 void
2888 dbeSetSelObj (int dbevindex, Obj sel_obj_or_ind, int type, int subtype)
2890 DbeView *dbev = dbeSession->getView (dbevindex);
2891 if (dbev == NULL)
2892 abort ();
2893 Histable *sel_obj;
2894 Hist_data *data;
2895 int sel_ind = (int) sel_obj_or_ind;
2897 switch (type)
2899 case DSP_FUNCTION:
2900 data = dbev->func_data;
2901 break;
2902 case DSP_LINE:
2903 data = dbev->line_data;
2904 break;
2905 case DSP_PC:
2906 data = dbev->pc_data;
2907 break;
2908 case DSP_CALLER:
2909 data = dbev->callers;
2910 break;
2911 case DSP_CALLEE:
2912 data = dbev->callees;
2913 break;
2914 case DSP_SOURCE:
2915 data = dbev->src_data;
2916 break;
2917 case DSP_DISASM:
2918 data = dbev->dis_data;
2919 break;
2920 case DSP_DLAYOUT:
2921 data = dbev->dlay_data;
2922 if (data == NULL)
2924 dbev->sel_binctx = NULL;
2925 return;
2927 if (sel_ind >= 0 && sel_ind < dbev->dlay_data->size ())
2928 dbev->sel_dobj = dbev->dlay_data->fetch (sel_ind)->obj;
2929 return;
2930 case DSP_DATAOBJ:
2931 data = dbev->dobj_data;
2932 if (data == NULL)
2934 dbev->sel_binctx = NULL;
2935 return;
2937 if (sel_ind >= 0 && sel_ind < dbev->dobj_data->size ())
2938 dbev->sel_dobj = dbev->dobj_data->fetch (sel_ind)->obj;
2939 return;
2940 case DSP_MEMOBJ:
2941 case DSP_INDXOBJ:
2942 dbev->set_indxobj_sel (subtype, sel_ind);
2943 sel_obj = dbev->get_indxobj_sel (subtype);
2944 if (sel_obj && sel_obj->get_type () == Histable::INDEXOBJ)
2945 dbev->set_sel_obj (((IndexObject*) sel_obj)->get_obj ());
2946 return;
2947 case DSP_SOURCE_V2:
2948 case DSP_DISASM_V2:
2949 case DSP_TIMELINE:
2950 case DSP_LEAKLIST:
2951 case DSP_RACES:
2952 case DSP_DEADLOCKS:
2953 case DSP_DUALSOURCE:
2954 case DSP_SOURCE_DISASM:
2955 case DSP_IOACTIVITY:
2956 case DSP_IOVFD:
2957 case DSP_IOCALLSTACK:
2958 case DSP_HEAPCALLSTACK:
2959 case DSP_MINICALLER:
2960 dbev->set_sel_obj ((Histable *) sel_obj_or_ind);
2961 return;
2962 default:
2963 // abort();
2964 return;
2966 if (type != DSP_SOURCE && type != DSP_DISASM && type != DSP_SOURCE_V2
2967 && type != DSP_DISASM_V2)
2968 dbev->sel_binctx = NULL;
2970 if (data == NULL || data->get_status () != Hist_data::SUCCESS
2971 || sel_ind >= data->size ())
2972 return;
2974 if (sel_ind >= 0 && sel_ind < data->size ())
2975 dbev->set_sel_obj (data->fetch (sel_ind)->obj);
2978 void
2979 dbeSetSelObjV2 (int dbevindex, uint64_t id)
2981 DbeView *dbev = dbeSession->getView (dbevindex);
2982 if (dbev == NULL)
2983 abort ();
2984 dbev->set_sel_obj (dbeSession->findObjectById (id));
2988 dbeGetSelObj (int dbevindex, int type, int subtype)
2990 DbeView *dbev = dbeSession->getView (dbevindex);
2991 Histable *sel_obj = NULL;
2992 switch (type)
2994 case DSP_FUNCTION:
2995 sel_obj = dbev->get_sel_obj (Histable::FUNCTION);
2996 break;
2997 case DSP_LINE:
2998 case DSP_SOURCE:
2999 case DSP_SOURCE_V2:
3000 sel_obj = dbev->get_sel_obj (Histable::LINE);
3001 break;
3002 case DSP_PC:
3003 case DSP_DISASM:
3004 case DSP_DISASM_V2:
3005 sel_obj = dbev->get_sel_obj (Histable::INSTR);
3006 break;
3007 case DSP_SRC_FILE:
3008 sel_obj = dbev->get_sel_obj (Histable::SOURCEFILE);
3009 break;
3010 case DSP_DATAOBJ:
3011 case DSP_DLAYOUT:
3012 if (dbev->sel_dobj)
3013 sel_obj = dbev->sel_dobj->convertto (Histable::DOBJECT);
3014 break;
3015 case DSP_MEMOBJ:
3016 case DSP_INDXOBJ:
3017 sel_obj = dbev->get_indxobj_sel (subtype);
3018 break;
3019 default:
3020 abort ();
3022 Dprintf (DEBUG_DBE, NTXT ("### dbeGetSelObj: Dbe.cc:%d %s (%d) returns %s\n"),
3023 __LINE__, dsp_type_to_string (type), type, sel_obj ? sel_obj->dump () : "NULL");
3024 return (Obj) sel_obj;
3028 dbeConvertSelObj (Obj obj, int type)
3030 Histable *sel_obj = (Histable *) obj;
3031 Dprintf (DEBUG_DBE, NTXT ("### dbeConvertSelObj: Dbe.cc:%d %s (%d) sel_obj=%s\n"),
3032 __LINE__, dsp_type_to_string (type), type, sel_obj ? sel_obj->dump ()
3033 : "NULL");
3034 if (sel_obj == NULL)
3035 return (Obj) NULL;
3036 switch (type)
3038 case DSP_FUNCTION:
3039 return (Obj) sel_obj->convertto (Histable::FUNCTION);
3040 case DSP_LINE:
3041 return (Obj) sel_obj->convertto (Histable::LINE);
3042 case DSP_SOURCE:
3043 case DSP_SOURCE_V2:
3045 SourceFile* srcCtx = NULL;
3046 if (sel_obj->get_type () == Histable::INSTR)
3048 DbeInstr* dbei = (DbeInstr *) sel_obj;
3049 srcCtx = (SourceFile*) dbei->convertto (Histable::SOURCEFILE);
3051 else if (sel_obj->get_type () == Histable::LINE)
3053 DbeLine * dbel = (DbeLine *) sel_obj;
3054 srcCtx = dbel->sourceFile;
3056 sel_obj = sel_obj->convertto (Histable::LINE, srcCtx);
3057 Dprintf (DEBUG_DBE, NTXT ("### dbeConvertSelObj: Dbe.cc:%d %s (%d) returns %s\n"),
3058 __LINE__, dsp_type_to_string (type), type, sel_obj ? sel_obj->dump () : "NULL");
3059 if (sel_obj && sel_obj->get_type () == Histable::LINE)
3061 DbeLine * dbel = (DbeLine *) sel_obj;
3062 return (Obj) dbel->dbeline_base;
3064 return (Obj) sel_obj->convertto (Histable::LINE, srcCtx);
3066 case DSP_PC:
3067 case DSP_DISASM:
3068 case DSP_DISASM_V2:
3069 return (Obj) sel_obj->convertto (Histable::INSTR);
3070 case DSP_SRC_FILE:
3071 return (Obj) sel_obj->convertto (Histable::SOURCEFILE);
3072 default:
3073 abort ();
3075 return (Obj) NULL;
3078 uint64_t
3079 dbeGetSelObjV2 (int dbevindex, char *typeStr)
3081 DbeView *dbev = dbeSession->getView (dbevindex);
3082 if (dbev == NULL)
3083 abort ();
3084 Histable *obj = NULL;
3085 if (typeStr != NULL)
3087 if (streq (typeStr, NTXT ("FUNCTION")))
3088 obj = dbev->get_sel_obj (Histable::FUNCTION);
3089 else if (streq (typeStr, NTXT ("INSTRUCTION")))
3090 obj = dbev->get_sel_obj (Histable::INSTR);
3091 else if (streq (typeStr, NTXT ("SOURCELINE")))
3092 obj = dbev->get_sel_obj (Histable::LINE);
3093 else if (streq (typeStr, NTXT ("SOURCEFILE")))
3094 obj = dbev->get_sel_obj (Histable::SOURCEFILE);
3096 Dprintf (DEBUG_DBE, NTXT ("### dbeGetSelObjV2: Dbe.cc:%d %s returns %s\n"),
3097 __LINE__, STR (typeStr), obj ? obj->dump () : "NULL");
3098 return obj != NULL ? obj->id : (uint64_t) - 1;
3101 Vector<uint64_t> *
3102 dbeGetSelObjsIO (int dbevindex, Vector<uint64_t> *ids, int type)
3104 DbeView *dbev = dbeSession->getView (dbevindex);
3105 if (dbev == NULL)
3106 abort ();
3107 Vector<uint64_t> *res = NULL;
3108 Vector<uint64_t> *result = new Vector<uint64_t>();
3109 for (int i = 0; i < ids->size (); i++)
3111 res = dbeGetSelObjIO (dbevindex, ids->fetch (i), type);
3112 if (res != NULL)
3114 result->addAll (res);
3115 delete res;
3118 return result;
3121 Vector<uint64_t> *
3122 dbeGetSelObjIO (int dbevindex, uint64_t id, int type)
3124 DbeView *dbev = dbeSession->getView (dbevindex);
3125 if (dbev == NULL)
3126 abort ();
3127 Histable *obj = NULL;
3128 Vector<uint64_t> *res = NULL;
3129 int size = 0;
3130 switch (type)
3132 case DSP_IOACTIVITY:
3133 obj = dbev->get_sel_obj_io (id, Histable::IOACTFILE);
3134 size = obj != NULL ? ((FileData*) obj)->getVirtualFds ()->size () : 0;
3135 if (size)
3137 res = new Vector<uint64_t>();
3138 Vector<int64_t> *vfds = ((FileData*) obj)->getVirtualFds ();
3139 for (int i = 0; i < size; i++)
3140 res->append (vfds->fetch (i));
3142 break;
3143 case DSP_IOVFD:
3144 obj = dbev->get_sel_obj_io (id, Histable::IOACTVFD);
3145 if (obj)
3147 res = new Vector<uint64_t>();
3148 res->append (obj->id);
3150 break;
3151 case DSP_IOCALLSTACK:
3152 obj = dbev->get_sel_obj_io (id, Histable::IOCALLSTACK);
3153 if (obj)
3155 Vector<Obj> *instrs = dbeGetStackPCs (dbevindex, obj->id);
3156 if (instrs == NULL)
3157 return NULL;
3158 int stsize = instrs->size ();
3159 res = new Vector<uint64_t>(stsize);
3160 for (int i = 0; i < stsize; i++)
3162 Histable *objFunc = (DbeInstr*) (instrs->fetch (i));
3163 if (objFunc->get_type () != Histable::LINE)
3165 objFunc = objFunc->convertto (Histable::FUNCTION);
3166 res->insert (0, objFunc->id);
3169 delete instrs;
3171 break;
3172 default:
3173 break;
3175 return res;
3178 uint64_t
3179 dbeGetSelObjHeapTimestamp (int dbevindex, uint64_t id)
3181 DbeView *dbev = dbeSession->getView (dbevindex);
3182 if (dbev == NULL)
3183 abort ();
3184 Histable *obj = NULL;
3185 uint64_t res = 0;
3186 Vector<uint64_t> *peakStackIds;
3187 Vector<hrtime_t> *peakTimestamps;
3189 // Find and return the timestamp for the peak
3190 bool foundPeakId = false;
3191 if (id > 0)
3193 obj = dbev->get_sel_obj_heap (0);
3194 if (obj != NULL)
3196 peakStackIds = ((HeapData*) obj)->getPeakStackIds ();
3197 peakTimestamps = ((HeapData*) obj)->getPeakTimestamps ();
3198 for (int i = 0; i < peakStackIds->size (); i++)
3200 if (id == peakStackIds->fetch (i))
3202 res = peakTimestamps->fetch (i);
3203 foundPeakId = true;
3204 break;
3210 // Return the first timestamp for the peak
3211 // if the callstack id is zero or it
3212 // doesn't match with the peak stack id
3213 if (id == 0 || !foundPeakId)
3215 obj = dbev->get_sel_obj_heap (0);
3216 res = obj != NULL ? ((HeapData*) obj)->getPeakTimestamps ()->fetch (0) : 0;
3218 return res;
3222 dbeGetSelObjHeapUserExpId (int dbevindex, uint64_t id)
3224 DbeView *dbev = dbeSession->getView (dbevindex);
3225 if (dbev == NULL)
3226 abort ();
3227 Histable *obj = NULL;
3228 int res = 0;
3229 obj = dbev->get_sel_obj_heap (id);
3230 res = obj != NULL ? ((HeapData*) obj)->getUserExpId () : 0;
3231 return res;
3235 // Get index of selected function/object
3238 dbeGetSelIndex (int dbevindex, Obj sel_obj, int type, int subtype)
3240 Hist_data *data;
3241 DbeView *dbev = dbeSession->getView (dbevindex);
3242 if (dbev == NULL)
3243 abort ();
3244 switch (type)
3246 case DSP_FUNCTION:
3247 data = dbev->func_data;
3248 break;
3249 case DSP_LINE:
3250 data = dbev->line_data;
3251 break;
3252 case DSP_PC:
3253 data = dbev->pc_data;
3254 break;
3255 case DSP_SOURCE:
3256 case DSP_SOURCE_V2:
3257 data = dbev->src_data;
3258 break;
3259 case DSP_DISASM:
3260 case DSP_DISASM_V2:
3261 data = dbev->dis_data;
3262 break;
3263 case DSP_DLAYOUT:
3264 data = dbev->dlay_data;
3265 break;
3266 case DSP_DATAOBJ:
3267 data = dbev->dobj_data;
3268 break;
3269 case DSP_MEMOBJ:
3270 case DSP_INDXOBJ:
3271 data = dbev->get_indxobj_data (subtype);
3272 break;
3273 default:
3274 data = NULL;
3275 break;
3277 if (data == NULL || data->get_status () != Hist_data::SUCCESS)
3278 return -1;
3280 Histable *chk_obj = (Histable *) sel_obj;
3281 Vector<Hist_data::HistItem*> *histItems = data->get_hist_items ();
3282 if (histItems == NULL || chk_obj == NULL)
3283 return -1;
3284 for (int i = 0, sz = histItems->size (); i < sz; i++)
3286 if (histItems->get (i)->obj == chk_obj)
3287 return i;
3288 if (histItems->get (i)->obj == NULL)
3289 continue;
3290 if (histItems->get (i)->obj->get_type () == Histable::LINE
3291 && chk_obj->get_type () == Histable::LINE)
3293 if (((DbeLine*) histItems->get (i)->obj)->convertto (Histable::FUNCTION)
3294 == ((DbeLine*) chk_obj)->convertto (Histable::FUNCTION)
3295 && ((DbeLine*) histItems->get (i)->obj)->lineno
3296 == ((DbeLine*) chk_obj)->lineno)
3297 return i;
3299 else if (histItems->get (i)->obj->get_type () == Histable::INSTR
3300 && chk_obj->get_type () == Histable::INSTR)
3301 if (((DbeInstr*) histItems->get (i)->obj)->convertto (Histable::FUNCTION)
3302 == ((DbeInstr*) chk_obj)->convertto (Histable::FUNCTION)
3303 && ((DbeInstr*) histItems->get (i)->obj)->addr
3304 == ((DbeInstr*) chk_obj)->addr)
3305 return i;
3308 Histable *chk_obj1 = NULL;
3309 switch (type)
3311 case DSP_FUNCTION:
3312 chk_obj1 = chk_obj->convertto (Histable::FUNCTION);
3313 break;
3314 case DSP_LINE:
3315 case DSP_SOURCE:
3316 case DSP_SOURCE_V2:
3317 chk_obj1 = chk_obj->convertto (Histable::LINE);
3318 break;
3319 case DSP_PC:
3320 case DSP_DISASM:
3321 case DSP_DISASM_V2:
3322 chk_obj1 = chk_obj->convertto (Histable::INSTR);
3323 break;
3325 if (chk_obj1 && chk_obj != chk_obj1)
3326 for (int i = 0, sz = histItems->size (); i < sz; i++)
3327 if (histItems->get (i)->obj == chk_obj1)
3328 return i;
3330 if (type == DSP_LINE)
3332 for (int i = 0, sz = histItems->size (); i < sz; i++)
3333 if (histItems->get (i)->obj != NULL
3334 && chk_obj->convertto (Histable::FUNCTION)
3335 == histItems->get (i)->obj->convertto (Histable::FUNCTION))
3336 return i;
3338 else if (type == DSP_PC)
3340 for (int i = 0, sz = histItems->size (); i < sz; i++)
3341 if (histItems->get (i)->obj != NULL
3342 && (histItems->get (i)->obj)->convertto (Histable::FUNCTION)
3343 == (chk_obj)->convertto (Histable::FUNCTION)
3344 && ((DbeLine*) histItems->get (i)->obj->convertto (Histable::LINE))->lineno
3345 == ((DbeLine*) chk_obj->convertto (Histable::LINE))->lineno)
3346 return i;
3347 for (int i = 0, sz = histItems->size (); i < sz; i++)
3348 if (histItems->get (i)->obj != NULL
3349 && (histItems->get (i)->obj)->convertto (Histable::FUNCTION)
3350 == (chk_obj)->convertto (Histable::FUNCTION))
3351 return i;
3354 // If we clicked on an mfunction line in the called-by call mini in user mode for omp
3355 // we might not find that function in func data
3356 if (dbev->isOmpDisMode () && type == DSP_FUNCTION)
3358 int p = dbeGetSelIndex (dbevindex, sel_obj, DSP_DISASM, subtype);
3359 if (p != -1)
3360 return p;
3362 return -1;
3365 // Print data
3367 char *
3368 dbePrintData (int dbevindex, int type, int subtype, char *printer,
3369 char *fname, FILE *outfile)
3371 Histable *current_obj;
3372 Function *func;
3373 Module *module;
3374 MetricList *mlist_orig;
3375 bool header;
3376 Print_params params;
3377 DbeView *dbev = dbeSession->getView (dbevindex);
3378 if (dbev == NULL)
3379 abort ();
3381 // Set print parameters
3382 if (printer != NULL)
3384 params.dest = DEST_PRINTER;
3385 params.name = printer;
3387 else if (outfile != NULL)
3389 params.dest = DEST_OPEN_FILE;
3390 params.openfile = outfile;
3391 params.name = NULL;
3393 else
3395 params.dest = DEST_FILE;
3396 params.name = fname;
3397 if (*(params.name) == '\0')
3399 free (params.name);
3400 return dbe_strdup (GTXT ("Please enter the name of the file to which to print"));
3403 params.ncopies = 1;
3404 if (outfile != NULL)
3405 header = false;
3406 else
3407 header = !(type == DSP_SOURCE || type == DSP_SOURCE_V2 || type == DSP_DISASM_V2);
3409 params.header = header;
3411 // figure out what kind of metrics to use
3412 if (type == DSP_SELF || type == DSP_CALLER || type == DSP_CALLEE
3413 || type == DSP_CALLTREE)
3414 mlist_orig = dbev->get_metric_list (MET_CALL);
3415 else if (type == DSP_DATAOBJ || type == DSP_DLAYOUT || type == DSP_MEMOBJ)
3416 mlist_orig = dbev->get_metric_list (MET_DATA);
3417 else if (type == DSP_INDXOBJ)
3418 mlist_orig = dbev->get_metric_list (MET_INDX);
3419 else if (type == DSP_IOACTIVITY || type == DSP_IOVFD
3420 || type == DSP_IOCALLSTACK)
3421 mlist_orig = dbev->get_metric_list (MET_IO);
3422 else if (type == DSP_HEAPCALLSTACK)
3423 mlist_orig = dbev->get_metric_list (MET_HEAP);
3424 else
3425 mlist_orig = dbev->get_metric_list (MET_NORMAL);
3427 // make a compacted version of the input list
3428 // the list will either be moved to the generated data,
3429 // or freed below if it wasn't needed
3430 MetricList *mlist = new MetricList (mlist_orig);
3431 Hist_data *data = NULL;
3432 er_print_common_display *cd = NULL;
3433 int ix;
3434 // Set data
3435 switch (type)
3437 case DSP_FUNCTION:
3438 case DSP_LINE:
3439 case DSP_PC:
3440 case DSP_MEMOBJ:
3441 case DSP_INDXOBJ:
3442 case DSP_DATAOBJ:
3443 data = dbev->get_hist_data (mlist,
3444 ((type == DSP_FUNCTION) ? Histable::FUNCTION :
3445 (type == DSP_LINE) ? Histable::LINE :
3446 (type == DSP_PC) ? Histable::INSTR :
3447 (type == DSP_INDXOBJ) ? Histable::INDEXOBJ :
3448 (type == DSP_MEMOBJ) ? Histable::MEMOBJ
3449 : Histable::DOBJECT),
3450 subtype, Hist_data::ALL);
3451 if (data->get_status () != Hist_data::SUCCESS)
3452 return DbeView::status_str (DbeView::DBEVIEW_NO_DATA); // no strdup()
3454 cd = new er_print_histogram (dbev, data, mlist, MODE_LIST,
3455 dbev->get_limit (),
3456 mlist->get_sort_name (), NULL, true, true);
3457 break;
3458 case DSP_DLAYOUT:
3460 data = dbev->get_hist_data (mlist, Histable::DOBJECT, 0, Hist_data::LAYOUT);
3461 if (data->get_status () != Hist_data::SUCCESS)
3462 return DbeView::status_str (DbeView::DBEVIEW_NO_DATA); // no strdup()
3463 cd = new er_print_histogram (dbev, data, mlist, MODE_ANNOTATED,
3464 dbev->get_thresh_dis (),
3465 mlist->get_sort_name (), NULL, true, true);
3466 break;
3469 // source and disassembly
3470 case DSP_SOURCE:
3471 case DSP_DISASM:
3472 case DSP_SOURCE_V2:
3473 case DSP_DISASM_V2:
3474 if (dbev->sel_obj == NULL)
3475 return NULL;
3476 current_obj = dbev->sel_obj->convertto (Histable::FUNCTION);
3477 if (current_obj->get_type () != Histable::FUNCTION)
3478 return dbe_strdup (GTXT ("Not a real function; no source or disassembly available."));
3479 func = (Function*) current_obj->convertto (Histable::FUNCTION);
3480 if (func->flags & FUNC_FLAG_SIMULATED)
3481 return dbe_strdup (GTXT ("Not a real function; no source or disassembly available."));
3482 if (func->get_name () == NULL)
3483 return dbe_strdup (GTXT ("Source location not recorded in experiment"));
3484 module = func->module;
3485 if (module == NULL || module->get_name () == NULL)
3486 return dbe_strdup (GTXT ("Object name not recorded in experiment"));
3487 ix = module->loadobject->seg_idx;
3488 if (dbev->get_lo_expand (ix) == LIBEX_HIDE)
3489 return dbe_strdup (GTXT ("No source or disassembly available for hidden object"));
3490 cd = new er_print_histogram (dbev, dbev->func_data, mlist, MODE_ANNOTATED,
3491 type == DSP_DISASM || type == DSP_DISASM_V2,
3492 mlist->get_sort_name (),
3493 func, false, false);
3494 break;
3496 // callers-callees
3497 case DSP_SELF:
3498 case DSP_CALLER:
3499 case DSP_CALLEE:
3500 if (dbev->sel_obj == NULL)
3501 return NULL;
3502 current_obj = dbev->sel_obj->convertto (Histable::FUNCTION);
3503 cd = new er_print_histogram (dbev, dbev->func_data, mlist, MODE_GPROF, 1,
3504 mlist->get_sort_name (), current_obj,
3505 false, false);
3506 break;
3508 // statistics; this won't use the metric list copied above, so delete it
3509 case DSP_STATIS:
3510 cd = new er_print_experiment (dbev, 0, dbeSession->nexps () - 1,
3511 true, true, true, true, false);
3512 delete mlist;
3513 break;
3514 case DSP_EXP:
3515 cd = new er_print_experiment (dbev, 0, dbeSession->nexps () - 1,
3516 true, true, false, false, false);
3517 delete mlist;
3518 break;
3519 case DSP_LEAKLIST:
3520 cd = new er_print_leaklist (dbev, true, true, dbev->get_limit ());
3521 delete mlist;
3522 break;
3523 case DSP_HEAPCALLSTACK:
3524 cd = new er_print_heapactivity (dbev, Histable::HEAPCALLSTACK, false,
3525 dbev->get_limit ());
3526 delete mlist;
3527 break;
3528 case DSP_IOACTIVITY:
3529 cd = new er_print_ioactivity (dbev, Histable::IOACTFILE, false,
3530 dbev->get_limit ());
3531 delete mlist;
3532 break;
3533 case DSP_IOVFD:
3534 cd = new er_print_ioactivity (dbev, Histable::IOACTVFD, false,
3535 dbev->get_limit ());
3536 delete mlist;
3537 break;
3539 // the io call stack
3540 case DSP_IOCALLSTACK:
3541 cd = new er_print_ioactivity (dbev, Histable::IOCALLSTACK, false,
3542 dbev->get_limit ());
3543 delete mlist;
3544 break;
3546 // some unknown panel -- return an error string
3547 default:
3548 delete mlist;
3549 return dbe_strdup (GTXT ("Print not available"));
3552 // Start printing
3553 char *buf = NULL;
3555 // first open the file/device/whatever
3556 if (cd->open (&params) == 0)
3558 // now call the actual print routine
3559 cd->data_dump ();
3560 if (params.dest == DEST_PRINTER)
3562 if (streq ((char *) params.name, NTXT ("-")))
3564 // Special case - return report to the GUI
3565 int maxbytes = 2 * 1024 * 1024; // IPC large buffer limit
3566 char *report = cd->get_output (maxbytes);
3567 delete data;
3568 delete cd;
3569 return report; // TEMPORARY
3572 if (cd->print_output () == false)
3573 buf = dbe_sprintf (NTXT ("%s: %s"),
3574 GTXT ("Unable to submit print request to"),
3575 params.name);
3577 else
3578 // if unable to set up the print, return an error
3579 buf = dbe_sprintf (NTXT ("%s: %s"),
3580 GTXT ("Unable to open file"),
3581 params.name);
3583 // dbe_free((void *) params.name); XXX when should this happen?
3584 if (data)
3585 if (data->isViewOwned () == false)
3586 delete data;
3587 delete cd;
3588 return buf;
3591 // Set limit for print data
3593 char *
3594 dbeSetPrintLimit (int dbevindex, int limit)
3596 DbeView *dbev = dbeSession->getView (dbevindex);
3597 if (dbev == NULL)
3598 abort ();
3599 return (dbev->set_limit (limit));
3602 // get limit for print data
3604 dbeGetPrintLimit (int dbevindex)
3606 DbeView *dbev = dbeSession->getView (dbevindex);
3607 if (dbev == NULL)
3608 abort ();
3609 int limit = dbev->get_limit ();
3610 return limit;
3613 // set printmode for data
3614 char *
3615 dbeSetPrintMode (int dbevindex, char * pmode)
3617 DbeView *dbev = dbeSession->getView (dbevindex);
3618 if (dbev == NULL)
3619 abort ();
3620 char *r = dbev->set_printmode (pmode);
3621 return r;
3624 // get printmode for data
3626 dbeGetPrintMode (int dbevindex)
3628 DbeView *dbev = dbeSession->getView (dbevindex);
3629 if (dbev == NULL)
3630 abort ();
3631 return (dbev->get_printmode ());
3634 // get printmode for data
3635 char *
3636 dbeGetPrintModeString (int dbevindex)
3638 DbeView *dbev = dbeSession->getView (dbevindex);
3639 if (dbev == NULL)
3640 abort ();
3641 return ( dbev->get_printmode_str ());
3644 // get print delimiter for csv data
3645 char
3646 dbeGetPrintDelim (int dbevindex)
3648 DbeView *dbev = dbeSession->getView (dbevindex);
3649 if (dbev == NULL)
3650 abort ();
3651 return (dbev->get_printdelimiter ());
3654 // Set Source/Object/Load-Object file names
3655 static void
3656 set_file_names (Function *func, char *names[3])
3658 Module *module = func->module;
3659 LoadObject *loadobject = module->loadobject;
3660 if (loadobject == NULL)
3661 loadobject = dbeSession->get_Unknown_LoadObject ();
3662 free (names[0]);
3663 free (names[1]);
3664 free (names[2]);
3665 SourceFile *sf = func->getDefSrc ();
3666 char *src_name = sf->dbeFile->get_location_info ();
3667 DbeFile *df = module->dbeFile;
3668 if (df == NULL || (df->filetype & DbeFile::F_JAVACLASS) == 0)
3669 df = module->loadobject->dbeFile;
3670 char *lo_name = df->get_location_info ();
3671 char *dot_o_name = lo_name;
3672 if (module->dot_o_file)
3673 dot_o_name = module->dot_o_file->dbeFile->get_location_info ();
3674 names[0] = dbe_sprintf (NTXT ("%s: %s"), GTXT ("Source File"), src_name);
3675 names[1] = dbe_sprintf (NTXT ("%s: %s"), GTXT ("Object File"), dot_o_name);
3676 names[2] = dbe_sprintf (NTXT ("%s: %s"), GTXT ("Load Object"), lo_name);
3679 // dbeSetFuncData
3680 // Master function to generate all Tab data for the analyzer
3681 // Returns the index of the selected item in the specified list
3683 // After calling it to set up, the Analyzer calls dbeGetFuncList
3684 // to format the generated data and return the table
3685 // Most of the data is destined for a JTable
3688 dbeSetFuncData (int dbevindex, Obj sel_obj, int type, int subtype)
3690 MetricList *_mlist;
3691 Histable *org_obj;
3692 Hist_data *data = NULL;
3693 int index, sel_index;
3694 Function *func;
3695 char *name;
3696 int ix;
3698 DbeView *dbev = dbeSession->getView (dbevindex);
3699 sel_index = -1;
3700 dbev->resetOmpDisMode ();
3701 dbev->error_msg = dbev->warning_msg = NULL;
3703 // get metric list, make a compact duplicate
3704 _mlist = dbev->get_metric_list (MET_NORMAL);
3705 MetricList *mlist = new MetricList (_mlist);
3707 // Remove old function/obj list data & Get new function/obj list data
3708 org_obj = (Histable *) sel_obj;
3710 // Figure out which "function" data is being asked for, i.e.,
3711 // which of the analyzer displays is asking for data
3712 switch (type)
3714 // the various tables: functions, lines, PCs, DataObjects, IndexObjects
3715 case DSP_FUNCTION:
3716 case DSP_LINE:
3717 case DSP_PC:
3718 case DSP_DATAOBJ:
3719 case DSP_MEMOBJ:
3720 case DSP_INDXOBJ:
3721 switch (type)
3723 case DSP_FUNCTION:
3724 if (dbev->func_data)
3725 delete dbev->func_data;
3726 dbev->func_data = data = dbev->get_hist_data (mlist,
3727 Histable::FUNCTION, subtype, Hist_data::ALL);
3728 break;
3729 case DSP_LINE:
3730 if (dbev->line_data)
3731 delete dbev->line_data;
3732 dbev->line_data = data = dbev->get_hist_data (mlist,
3733 Histable::LINE, subtype, Hist_data::ALL);
3734 break;
3735 case DSP_PC:
3736 if (dbev->pc_data)
3737 delete dbev->pc_data;
3738 dbev->pc_data = data = dbev->get_hist_data (mlist,
3739 Histable::INSTR, subtype, Hist_data::ALL);
3740 break;
3741 case DSP_DATAOBJ:
3742 if (dbev->dobj_data)
3743 delete dbev->dobj_data;
3744 mlist = dbev->get_metric_list (MET_DATA);
3745 dbev->dobj_data = data = dbev->get_hist_data (mlist,
3746 Histable::DOBJECT, subtype, Hist_data::ALL);
3747 break;
3748 case DSP_MEMOBJ:
3749 mlist = dbev->get_metric_list (MET_DATA);
3750 data = dbev->get_hist_data (mlist, Histable::MEMOBJ, subtype,
3751 Hist_data::ALL);
3752 dbev->indx_data->store (subtype, data);
3753 break;
3754 case DSP_INDXOBJ:
3755 mlist = dbev->get_metric_list (MET_INDX);
3756 data = dbev->get_hist_data (mlist, Histable::INDEXOBJ, subtype,
3757 Hist_data::ALL);
3758 dbev->indx_data->store (subtype, data);
3759 break;
3760 default:
3761 break;
3764 // Set the selection of row item
3765 if (data->get_status () == Hist_data::SUCCESS)
3767 // otherwise, look for it
3768 sel_index = -1;
3769 if (org_obj)
3771 Hist_data::HistItem *hi;
3772 Vec_loop (Hist_data::HistItem*, data->get_hist_items (), index, hi)
3774 if (hi->obj == org_obj)
3776 sel_index = index;
3777 break;
3780 if (sel_index == -1 && (type == DSP_LINE || type == DSP_PC))
3782 Vec_loop (Hist_data::HistItem*, data->get_hist_items (), index, hi)
3784 name = hi->obj->get_name ();
3785 if (strcmp (name, NTXT ("<Total>")) &&
3786 strcmp (name, GTXT ("<Unknown>")))
3788 int done = 0;
3789 switch (type)
3791 case DSP_LINE:
3792 if (org_obj->convertto (Histable::FUNCTION)
3793 == hi->obj->convertto (Histable::FUNCTION))
3795 sel_index = index;
3796 done = 1;
3798 break;
3799 case DSP_PC:
3800 if (hi->obj->convertto (Histable::FUNCTION)
3801 == org_obj->convertto (Histable::FUNCTION)
3802 && ((DbeLine*) hi->obj->convertto (Histable::LINE))->lineno
3803 == ((DbeLine*) org_obj->convertto (Histable::LINE))->lineno)
3805 sel_index = index;
3806 done = 1;
3808 break;
3810 if (done)
3811 break;
3815 if (sel_index == -1 && type == DSP_PC)
3817 Vec_loop (Hist_data::HistItem*, data->get_hist_items (), index, hi)
3819 name = hi->obj->get_name ();
3820 if (strcmp (name, NTXT ("<Total>")) &&
3821 strcmp (name, GTXT ("<Unknown>")))
3823 int done = 0;
3824 if (hi->obj->convertto (Histable::FUNCTION) ==
3825 org_obj->convertto (Histable::FUNCTION))
3827 sel_index = index;
3828 done = 1;
3830 if (done)
3831 break;
3836 if (sel_index == -1)
3838 Hist_data::HistItem *hi;
3839 Vec_loop (Hist_data::HistItem*, data->get_hist_items (), index, hi)
3841 name = hi->obj->get_name ();
3842 if (strcmp (name, NTXT ("<Total>")) &&
3843 strcmp (name, GTXT ("<Unknown>")))
3845 sel_index = index;
3846 break;
3851 else
3852 dbev->error_msg = DbeView::status_str (DbeView::DBEVIEW_NO_DATA);
3853 return sel_index;
3854 // the end of the code for the regular tables
3856 // Data Layout
3857 case DSP_DLAYOUT:
3858 if (dbev->dlay_data)
3859 delete dbev->dlay_data;
3860 dbev->marks->reset ();
3861 mlist = dbev->get_metric_list (MET_DATA);
3863 // initial dobj list ...
3864 data = dbev->get_hist_data (mlist, Histable::DOBJECT, subtype,
3865 Hist_data::LAYOUT);
3866 // .. provides metric data for layout
3867 dbev->dlay_data = data = dbev->get_data_space ()->get_layout_data (data,
3868 dbev->marks, dbev->get_thresh_dis ());
3869 if (data->get_status () != Hist_data::SUCCESS)
3870 dbev->error_msg = DbeView::status_str (DbeView::DBEVIEW_NO_DATA);
3871 return sel_index;
3873 // Source or disassembly
3874 case DSP_SOURCE_V2:
3875 case DSP_DISASM_V2:
3876 case DSP_SOURCE:
3877 case DSP_DISASM:
3879 if (org_obj == NULL)
3881 dbev->error_msg = DbeView::status_str (DbeView::DBEVIEW_NO_SEL_OBJ);
3882 return sel_index;
3884 if (org_obj->get_type () != Histable::FUNCTION)
3886 dbev->error_msg = dbe_strdup (
3887 GTXT ("Not a real function; no source or disassembly available."));
3888 return sel_index;
3890 func = (Function *) org_obj;
3891 if (func->flags & FUNC_FLAG_SIMULATED)
3893 dbev->error_msg = dbe_strdup (
3894 GTXT ("Not a real function; no source or disassembly available."));
3895 return sel_index;
3897 if (func->get_name () == NULL)
3899 dbev->error_msg = dbe_strdup (
3900 GTXT ("Source location not recorded in experiment"));
3901 return sel_index;
3903 Module *module = func->module;
3904 if ((module == NULL) || (module->get_name () == NULL))
3906 dbev->error_msg = dbe_strdup (
3907 GTXT ("Object name not recorded in experiment"));
3908 return sel_index;
3910 ix = module->loadobject->seg_idx;
3911 if (dbev->get_lo_expand (ix) == LIBEX_HIDE)
3913 dbev->error_msg = dbe_strdup (
3914 GTXT ("No source or disassembly available for hidden object"));
3915 return sel_index;
3918 if ((type == DSP_DISASM || type == DSP_DISASM_V2)
3919 && dbev->get_view_mode () == VMODE_USER
3920 && dbeSession->is_omp_available ())
3921 dbev->setOmpDisMode ();
3923 dbev->marks->reset ();
3924 SourceFile *srcContext = NULL;
3925 switch (dbev->sel_obj->get_type ())
3927 case Histable::FUNCTION:
3929 Function *f = (Function *) dbev->sel_obj;
3930 srcContext = f->getDefSrc ();
3931 dbev->sel_binctx = f->module;
3932 break;
3934 case Histable::LINE:
3936 DbeLine *dl = (DbeLine *) dbev->sel_obj;
3937 srcContext = dl->sourceFile;
3938 Function *f = dl->func;
3939 if (f)
3940 dbev->sel_binctx = f;
3941 break;
3943 case Histable::INSTR:
3945 Function *f = (Function *) dbev->sel_obj->convertto (Histable::FUNCTION);
3946 if (f)
3948 dbev->sel_binctx = f;
3949 srcContext = f->getDefSrc ();
3951 break;
3953 default:
3954 break;
3956 mlist = dbev->get_metric_list (MET_SRCDIS);
3958 // for source and disassembly the name needs to be invisible,
3959 // but that's handled in the module code
3960 if (type == DSP_SOURCE)
3962 if (dbev->src_data)
3963 delete dbev->src_data;
3965 // func_data computation needed for get_totals
3966 if (dbev->func_data == NULL)
3967 dbev->func_data = data = dbev->get_hist_data (mlist,
3968 Histable::FUNCTION, subtype, Hist_data::ALL);
3969 dbev->marks2dsrc->reset ();
3970 dbev->marks2dsrc_inc->reset ();
3971 data = dbev->src_data = module->get_data (dbev, mlist,
3972 Histable::LINE, dbev->func_data->get_totals ()->value,
3973 srcContext, func, dbev->marks,
3974 dbev->get_thresh_src (), dbev->get_src_compcom (),
3975 dbev->get_src_visible (), dbev->get_hex_visible (),
3976 false, false, dbev->marks2dsrc, dbev->marks2dsrc_inc);
3977 set_file_names (func, dbev->names_src);
3978 if (srcContext)
3980 free (dbev->names_src[0]);
3981 dbev->names_src[0] = dbe_sprintf (GTXT ("Source File: %s"),
3982 srcContext->dbeFile->get_location_info ());
3984 Obj obj = (Obj) func->convertto (Histable::LINE, srcContext);
3985 sel_index = dbeGetSelIndex (dbevindex, obj, type, subtype);
3987 else
3988 { /* type == DSP_DISASM */
3989 if (dbev->dis_data)
3990 delete dbev->dis_data;
3992 // func_data computation needed for get_totals
3993 if (dbev->func_data == NULL)
3994 dbev->func_data = data = dbev->get_hist_data (mlist,
3995 Histable::FUNCTION, subtype, Hist_data::ALL);
3996 dbev->marks2ddis->reset ();
3997 dbev->marks2ddis_inc->reset ();
3998 data = dbev->dis_data = module->get_data (dbev, mlist,
3999 Histable::INSTR, dbev->func_data->get_totals ()->value,
4000 srcContext, func, dbev->marks, dbev->get_thresh_dis (),
4001 dbev->get_dis_compcom (), dbev->get_src_visible (),
4002 dbev->get_hex_visible (), dbev->get_func_scope (),
4003 false, dbev->marks2ddis, dbev->marks2ddis_inc);
4004 set_file_names (func, dbev->names_dis);
4005 if (srcContext)
4007 free (dbev->names_dis[0]);
4008 dbev->names_dis[0] = dbe_sprintf (GTXT ("Source File: %s"),
4009 srcContext->dbeFile->get_location_info ());
4011 Obj obj = (Obj) func->convertto (Histable::INSTR);
4012 sel_index = dbeGetSelIndex (dbevindex, obj, type, subtype);
4014 return sel_index;
4017 // the three cases for caller-callee
4018 case DSP_SELF:
4019 case DSP_CALLER:
4020 case DSP_CALLEE:
4021 if (org_obj == NULL)
4023 dbev->error_msg = DbeView::status_str (DbeView::DBEVIEW_NO_SEL_OBJ);
4024 return sel_index;
4027 // Caller data
4028 if (dbev->callers)
4029 delete dbev->callers;
4030 mlist = dbev->get_metric_list (MET_CALL);
4031 dbev->callers = dbev->get_hist_data (mlist, Histable::FUNCTION, subtype,
4032 Hist_data::CALLERS, org_obj);
4033 if (dbev->callers->get_status () != Hist_data::SUCCESS)
4035 dbev->error_msg = DbeView::status_str (DbeView::DBEVIEW_NO_DATA);
4036 return sel_index;
4039 // Callee data
4040 if (dbev->callees)
4041 delete dbev->callees;
4042 dbev->callees = dbev->get_hist_data (mlist, Histable::FUNCTION, subtype,
4043 Hist_data::CALLEES, org_obj);
4044 if (dbev->callees->get_status () != Hist_data::SUCCESS)
4046 dbev->error_msg = DbeView::status_str (DbeView::DBEVIEW_NO_DATA);
4047 return sel_index;
4050 // Center Function item
4051 if (dbev->fitem_data)
4052 delete dbev->fitem_data;
4053 dbev->fitem_data = dbev->get_hist_data (mlist, Histable::FUNCTION, subtype,
4054 Hist_data::SELF, org_obj);
4055 if (dbev->fitem_data->get_status () != Hist_data::SUCCESS)
4057 dbev->error_msg = DbeView::status_str (DbeView::DBEVIEW_NO_DATA);
4058 return sel_index;
4060 return sel_index;
4061 default:
4062 abort ();
4064 return sel_index;
4067 Vector<void*>*
4068 dbeGetTotals (int dbevindex, int dsptype, int subtype)
4070 DbeView *dbev = dbeSession->getView (dbevindex);
4071 MetricList *mlist = dbev->get_metric_list (dsptype, subtype);
4072 Hist_data *data = dbev->get_hist_data (mlist, Histable::FUNCTION, 0,
4073 Hist_data::ALL);
4074 Hist_data::HistItem *totals = data->get_totals ();
4075 Vector<void*> *tbl = new Vector<void*>(mlist->size ());
4076 for (long i = 0, sz = mlist->size (); i < sz; i++)
4078 Metric *m = mlist->get (i);
4079 switch (m->get_vtype ())
4081 case VT_DOUBLE:
4083 Vector<double> *lst = new Vector<double>(1);
4084 lst->append (totals->value[i].d);
4085 tbl->append (lst);
4086 break;
4088 case VT_INT:
4090 Vector<int> *lst = new Vector<int>(1);
4091 lst->append (totals->value[i].i);
4092 tbl->append (lst);
4093 break;
4095 case VT_LLONG:
4096 case VT_ULLONG:
4097 case VT_ADDRESS:
4099 Vector<long long> *lst = new Vector<long long>(1);
4100 lst->append (totals->value[i].ll);
4101 tbl->append (lst);
4102 break;
4104 case VT_LABEL:
4106 Vector<char *> *lst = new Vector<char *>(1);
4107 Histable::NameFormat nfmt = dbev->get_name_format ();
4108 lst->append (dbe_strdup (totals->obj->get_name (nfmt)));
4109 tbl->append (lst);
4110 break;
4112 default:
4113 abort ();
4116 Vector<void*> *res = new Vector<void*>(2);
4117 res->append (dbeGetMetricList (mlist));
4118 res->append (tbl);
4119 return res;
4122 Vector<void*>*
4123 dbeGetHotMarks (int dbevindex, int type)
4125 Vector<void*>* table = new Vector<void*>(2);
4126 Vector<int>* table0 = new Vector<int> ();
4127 Vector<int>* table1 = new Vector<int> ();
4128 DbeView *dbev = dbeSession->getView (dbevindex);
4129 if (dbev == NULL)
4130 return NULL;
4132 switch (type)
4134 case DSP_SOURCE:
4135 case DSP_SOURCE_V2:
4136 for (int i = 0; i < dbev->marks2dsrc->size (); i++)
4138 table0->append (dbev->marks2dsrc->fetch (i).index1);
4139 table1->append (dbev->marks2dsrc->fetch (i).index2);
4141 break;
4142 case DSP_DISASM:
4143 case DSP_DISASM_V2:
4144 for (int i = 0; i < dbev->marks2ddis->size (); i++)
4146 table0->append (dbev->marks2ddis->fetch (i).index1);
4147 table1->append (dbev->marks2ddis->fetch (i).index2);
4149 break;
4150 default:
4151 break;
4153 table->store (0, table0);
4154 table->store (1, table1);
4155 return table;
4158 Vector<void*>*
4159 dbeGetHotMarksInc (int dbevindex, int type)
4161 Vector<void*>* table = new Vector<void*>(2);
4162 Vector<int>* table0 = new Vector<int> ();
4163 Vector<int>* table1 = new Vector<int> ();
4164 DbeView *dbev = dbeSession->getView (dbevindex);
4165 if (dbev == NULL)
4166 return NULL;
4168 switch (type)
4170 case DSP_SOURCE:
4171 case DSP_SOURCE_V2:
4172 for (int i = 0; i < dbev->marks2dsrc_inc->size (); i++)
4174 table0->append (dbev->marks2dsrc_inc->fetch (i).index1);
4175 table1->append (dbev->marks2dsrc_inc->fetch (i).index2);
4177 break;
4178 case DSP_DISASM:
4179 case DSP_DISASM_V2:
4180 for (int i = 0; i < dbev->marks2ddis_inc->size (); i++)
4182 table0->append (dbev->marks2ddis_inc->fetch (i).index1);
4183 table1->append (dbev->marks2ddis_inc->fetch (i).index2);
4185 break;
4186 default:
4187 break;
4189 table->store (0, table0);
4190 table->store (1, table1);
4191 return table;
4194 Vector<void*>*
4195 dbeGetSummaryHotMarks (int dbevindex, Vector<Obj> *sel_objs, int type)
4197 Vector<void*>* table = new Vector<void*>(2);
4198 Vector<int>* table0 = new Vector<int> ();
4199 Vector<int>* table1 = new Vector<int> ();
4200 DbeView *dbev = dbeSession->getView (dbevindex);
4201 if (dbev == NULL)
4202 return NULL;
4203 if (sel_objs == NULL || sel_objs->size () == 0)
4204 return NULL;
4206 Hist_data *data;
4207 Vector<int_pair_t> *marks2d;
4208 Vector<int_pair_t>* marks2d_inc;
4209 switch (type)
4211 case DSP_SOURCE:
4212 case DSP_SOURCE_V2:
4213 data = dbev->src_data;
4214 marks2d = dbev->marks2dsrc;
4215 marks2d_inc = dbev->marks2dsrc_inc;
4216 break;
4217 case DSP_DISASM:
4218 case DSP_DISASM_V2:
4219 data = dbev->dis_data;
4220 marks2d = dbev->marks2ddis;
4221 marks2d_inc = dbev->marks2ddis_inc;
4222 break;
4223 default:
4224 data = NULL;
4225 marks2d = NULL;
4226 marks2d_inc = NULL;
4227 break;
4229 if (data == NULL || data->get_status () != Hist_data::SUCCESS
4230 || marks2d_inc == NULL || marks2d == NULL)
4231 return NULL;
4233 MetricList *orig_mlist = data->get_metric_list ();
4234 MetricList *prop_mlist = new MetricList (dbev->get_metric_ref (MET_NORMAL));
4235 if (prop_mlist && dbev->comparingExperiments ())
4236 prop_mlist = dbev->get_compare_mlist (prop_mlist, 0);
4237 Metric *mitem;
4238 int index, index2;
4239 index2 = 0;
4240 Vec_loop (Metric*, prop_mlist->get_items (), index, mitem)
4242 if (mitem->get_subtype () == Metric::STATIC)
4243 continue;
4245 for (int i = 0; i < marks2d_inc->size (); i++)
4247 int found = 0;
4248 for (int j = 0; j < sel_objs->size (); j++)
4250 int sel_index = (int) sel_objs->fetch (j);
4251 int marked_index = marks2d_inc->fetch (i).index1;
4252 if (sel_index == marked_index)
4254 found = 1;
4255 break;
4258 if (!found)
4259 continue;
4260 int mindex = marks2d_inc->fetch (i).index2;
4261 Metric *orig_metric = orig_mlist->get_items ()->fetch (mindex);
4262 if (orig_metric->get_id () == mitem->get_id ()
4263 && mitem->get_subtype () == Metric::INCLUSIVE)
4265 table0->append (index2);
4266 table1->append (1);
4270 for (int i = 0; i < marks2d->size (); i++)
4272 int found = 0;
4273 for (int j = 0; j < sel_objs->size (); j++)
4275 int sel_index = (int) sel_objs->fetch (j);
4276 int marked_index = marks2d->fetch (i).index1;
4277 if (sel_index == marked_index)
4279 found = 1;
4280 break;
4283 if (!found)
4284 continue;
4285 int mindex = marks2d->fetch (i).index2;
4286 Metric *orig_metric = orig_mlist->get_items ()->fetch (mindex);
4287 if (orig_metric->get_id () == mitem->get_id ()
4288 && mitem->get_subtype () == Metric::EXCLUSIVE)
4290 table0->append (index2);
4291 table1->append (0);
4294 if (!(mitem->get_subtype () == Metric::EXCLUSIVE
4295 || mitem->get_subtype () == Metric::DATASPACE))
4296 index2++;
4298 table->store (0, table0);
4299 table->store (1, table1);
4300 return table;
4303 // Get a vector of function ids of data(begin, begin + length - 1)
4304 // Currently only support source/disassembly view
4305 Vector<uint64_t>*
4306 dbeGetFuncId (int dbevindex, int type, int begin, int length)
4308 Vector<uint64_t>* table = new Vector<uint64_t > ();
4309 DbeView *dbev = dbeSession->getView (dbevindex);
4310 if (dbev == NULL)
4311 abort ();
4313 Hist_data *data;
4314 Function* given_func = NULL;
4315 switch (type)
4317 case DSP_SOURCE:
4318 case DSP_SOURCE_V2:
4319 data = dbev->src_data;
4320 break;
4321 case DSP_DISASM:
4322 case DSP_DISASM_V2:
4323 data = dbev->dis_data;
4324 break;
4325 default:
4326 data = NULL;
4327 abort ();
4330 if (data == NULL || data->get_status () != Hist_data::SUCCESS)
4331 return NULL;
4333 if (begin < 0 || begin + length > data->size ())
4334 return NULL;
4336 switch (type)
4338 case DSP_SOURCE:
4339 case DSP_SOURCE_V2:
4340 case DSP_DISASM:
4341 case DSP_DISASM_V2:
4343 for (int i = begin; i < begin + length; i++)
4345 given_func = NULL;
4346 Histable * sel_obj = data->fetch (i)->obj;
4347 if (sel_obj != NULL)
4348 given_func = (Function*) (sel_obj)->convertto (Histable::FUNCTION, (Histable*) dbev);
4349 if (given_func == NULL)
4350 table->append (0);
4351 else
4352 table->append (given_func->id);
4355 break;
4356 default:
4357 abort ();
4359 return table;
4362 Vector<void*>*
4363 dbeGetFuncCallerInfo (int dbevindex, int type, Vector<int>* idxs, int groupId)
4365 Vector<void*>* data = new Vector<void*>();
4366 if (type == DSP_SOURCE_V2 || type == DSP_DISASM_V2)
4368 Obj sel_func = dbeGetSelObj (dbevindex, DSP_FUNCTION, 0);
4369 if (sel_func == 0)
4370 return data;
4371 Vector<Obj> * cmpObjs = dbeGetComparableObjsV2 (dbevindex, sel_func, type);
4372 if (cmpObjs == NULL)
4373 return data;
4374 DbeView *dbev = dbeSession->getView (dbevindex);
4375 int mtype = MET_COMMON | COMPARE_BIT | ((groupId + 1) << GROUP_ID_SHIFT);
4376 MetricList *mlist = dbev->get_metric_list ((MetricType) (mtype & MTYPE_MASK),
4377 (mtype & COMPARE_BIT) != 0,
4378 mtype >> GROUP_ID_SHIFT);
4379 Histable *selObj = (Histable *) cmpObjs->fetch (groupId);
4380 int subtype = 0;
4381 Hist_data *hist_data = dbev->get_data (mlist, selObj, type, subtype);
4382 if (hist_data == NULL)
4383 return data;
4385 for (int i = 0; i < idxs->size (); i++)
4386 data->append (dbeGetFuncCallerInfoById (dbevindex, type, idxs->fetch (i)));
4387 return data;
4391 // Get Table of Caller info:
4392 // param: idx -- selected AT_FUNC row
4393 // return: callsite_id, callsite_name (function: file: line)
4394 Vector<void*>*
4395 dbeGetFuncCallerInfoById (int dbevindex, int type, int idx)
4397 Vector<void*>* table = new Vector<void*>(3);
4398 Vector<uint64_t>* table0 = new Vector<uint64_t> ();
4399 Vector<int>* table1 = new Vector<int> ();
4400 Vector<char*>* table2 = new Vector<char*>();
4402 DbeView *dbev = dbeSession->getView (dbevindex);
4403 if (dbev == NULL)
4404 abort ();
4405 Hist_data *data;
4406 Function* given_func = NULL;
4407 Vector<Histable*> *instr_info = NULL;
4408 switch (type)
4410 case DSP_SOURCE:
4411 case DSP_SOURCE_V2:
4412 data = dbev->src_data;
4413 break;
4414 case DSP_DISASM:
4415 case DSP_DISASM_V2:
4416 data = dbev->dis_data;
4417 break;
4418 default:
4419 data = NULL;
4420 abort ();
4422 if (data == NULL || data->get_status () != Hist_data::SUCCESS)
4423 return NULL;
4425 if (idx < 0 || idx >= data->size ())
4426 return NULL;
4427 switch (type)
4429 case DSP_SOURCE:
4430 case DSP_SOURCE_V2:
4431 case DSP_DISASM:
4432 case DSP_DISASM_V2:
4434 Histable * sel_obj = data->fetch (idx)->obj;
4435 if (sel_obj == NULL)
4436 return NULL;
4437 given_func = (Function*) (sel_obj)->convertto (Histable::FUNCTION, (Histable*) dbev);
4438 if (given_func == NULL)
4439 return NULL;
4440 PathTree * ptree = dbev->get_path_tree ();
4441 if (ptree == NULL)
4442 return NULL;
4443 instr_info = ptree->get_clr_instr (given_func);
4444 DefaultMap<uint64_t, int> * line_seen = new DefaultMap<uint64_t, int>();
4445 for (int j = 0; j < ((Vector<Histable*>*)instr_info)->size (); j++)
4447 Histable *instr = ((Vector<Histable*>*)instr_info)->fetch (j);
4448 Function *cur_func = NULL;
4449 if (instr->get_type () == Histable::INSTR)
4450 cur_func = ((DbeInstr*) instr)->func;
4451 else if (instr->get_type () == Histable::LINE)
4452 cur_func = ((DbeLine*) instr)->func;
4453 if (cur_func == NULL || (cur_func->flags & FUNC_FLAG_SIMULATED))
4454 continue; // skip functions like <Total>
4455 Histable* line;
4456 switch (type)
4458 case DSP_SOURCE:
4459 case DSP_SOURCE_V2:
4460 if (cur_func != NULL)
4462 SourceFile *sourceFile = cur_func->getDefSrc ();
4463 if (sourceFile == NULL ||
4464 (sourceFile->flags & SOURCE_FLAG_UNKNOWN) != 0)
4465 continue; // skip functions like <Function: %s, instructions without line numbers>
4467 line = instr->convertto (Histable::LINE, NULL);
4468 break;
4469 case DSP_DISASM:
4470 case DSP_DISASM_V2:
4471 line = instr->convertto (Histable::INSTR, NULL);
4472 break;
4473 default:
4474 abort ();
4476 uint64_t func_id = cur_func->id;
4477 uint64_t line_id = instr->id;
4478 int is_null = 0;
4479 int line_no = -1;
4480 switch (type)
4482 case DSP_SOURCE:
4483 case DSP_SOURCE_V2:
4484 is_null = (((DbeLine*) line)->func == NULL) ? 1 : 0;
4485 if (is_null)
4486 ((DbeLine*) line)->func = cur_func;
4487 line_no = ((DbeLine*) line)->lineno;
4488 if (line_seen->get (line_id) == 0)
4490 line_seen->put (line_id, 1);
4491 table0->append (func_id);
4492 table1->append (line_no);
4493 Histable::NameFormat nfmt = dbev->get_name_format ();
4494 table2->append (dbe_strdup (line->get_name (nfmt)));
4496 if (is_null)
4497 ((DbeLine*) line)->func = NULL;
4498 break;
4499 case DSP_DISASM:
4500 case DSP_DISASM_V2:
4501 is_null = (((DbeInstr*) line)->func == NULL) ? 1 : 0;
4502 if (is_null)
4503 ((DbeInstr*) line)->func = cur_func;
4504 line_no = ((DbeInstr*) line)->addr;
4505 if (line_seen->get (line_id) == 0)
4507 line_seen->put (line_id, 1);
4508 table0->append (func_id);
4509 table1->append (line_no);
4510 Histable::NameFormat nfmt = dbev->get_name_format ();
4511 table2->append (dbe_strdup (line->get_name (nfmt)));
4513 if (is_null)
4514 ((DbeInstr*) line)->func = NULL;
4515 break;
4516 default:
4517 abort ();
4520 delete line_seen;
4521 delete instr_info;
4523 break;
4524 default:
4525 abort ();
4527 table->store (0, table0);
4528 table->store (1, table1);
4529 table->store (2, table2);
4530 return table;
4533 Vector<void*>*
4534 dbeGetFuncCalleeInfo (int dbevindex, int type, Vector<int>* idxs, int groupId)
4536 Vector<void*>* data = new Vector<void*>();
4537 if (type == DSP_SOURCE_V2 || type == DSP_DISASM_V2)
4539 Obj sel_func = dbeGetSelObj (dbevindex, DSP_FUNCTION, 0);
4540 if (sel_func == 0)
4541 return data;
4542 Vector<Obj> * cmpObjs = dbeGetComparableObjsV2 (dbevindex, sel_func, type);
4543 if (cmpObjs == NULL)
4544 return data;
4545 DbeView *dbev = dbeSession->getView (dbevindex);
4546 int mtype = MET_COMMON | COMPARE_BIT | ((groupId + 1) << GROUP_ID_SHIFT);
4547 MetricList *mlist = dbev->get_metric_list ((MetricType) (mtype & MTYPE_MASK),
4548 (mtype & COMPARE_BIT) != 0,
4549 mtype >> GROUP_ID_SHIFT);
4550 Histable *selObj = (Histable *) cmpObjs->fetch (groupId);
4551 int subtype = 0;
4552 Hist_data *hist_data = dbev->get_data (mlist, selObj, type, subtype);
4553 if (hist_data == NULL)
4554 return data;
4557 for (int i = 0; i < idxs->size (); i++)
4558 data->append (dbeGetFuncCalleeInfoById (dbevindex, type, idxs->fetch (i)));
4559 return data;
4563 // Get Table of Callee info:
4564 // param: idx -- selected AT_FUNC row
4565 // return: callsite_row, callee_id, callee_name
4567 Vector<void*>*
4568 dbeGetFuncCalleeInfoById (int dbevindex, int type, int idx)
4570 Vector<void*>* table = new Vector<void*>(3);
4571 Vector<int>* table0 = new Vector<int>();
4572 Vector<uint64_t>* table1 = new Vector<uint64_t > ();
4573 Vector<char*>* table2 = new Vector<char*>();
4574 DbeView *dbev = dbeSession->getView (dbevindex);
4575 if (dbev == NULL)
4576 abort ();
4577 Hist_data *data;
4578 Function* given_func = NULL;
4579 Vector<Histable*> *instr_info = NULL;
4580 Vector<void*> *func_info = NULL;
4582 switch (type)
4584 case DSP_SOURCE:
4585 case DSP_SOURCE_V2:
4586 data = dbev->src_data;
4587 break;
4588 case DSP_DISASM:
4589 case DSP_DISASM_V2:
4590 data = dbev->dis_data;
4591 break;
4592 default:
4593 data = NULL;
4594 abort ();
4596 if (data == NULL || data->get_status () != Hist_data::SUCCESS)
4597 return NULL;
4598 if (idx < 0 || idx >= data->size ())
4599 return NULL;
4600 switch (type)
4602 case DSP_SOURCE:
4603 case DSP_SOURCE_V2:
4604 case DSP_DISASM:
4605 case DSP_DISASM_V2:
4607 Histable * sel_obj = data->fetch (idx)->obj;
4608 if (sel_obj == NULL)
4609 return NULL;
4610 given_func = (Function*) (sel_obj)->convertto (Histable::FUNCTION, (Histable*) dbev);
4611 if (given_func == NULL)
4612 return NULL;
4613 PathTree * ptree = dbev->get_path_tree ();
4614 if (ptree == NULL)
4615 return NULL;
4616 Vector<Histable*> *instrs = NULL;
4617 Vector<void*> *callee_instrs = ptree->get_cle_instr (given_func, instrs);
4618 func_info = new Vector<void*>();
4619 instr_info = new Vector<Histable*>();
4620 for (long a = 0, sz_a = callee_instrs ? callee_instrs->size () : 0; a < sz_a; a++)
4622 Vector<Histable*> *temp = ((Vector<Vector<Histable*>*>*)callee_instrs)->get (a);
4623 DefaultMap<Function*, int> * func_seen = new DefaultMap<Function*, int>();
4624 Histable* instr0 = (Histable*) instrs->fetch (a);
4625 for (long b = 0, sz_b = temp ? temp->size () : 0; b < sz_b; b++)
4627 Histable *instr = temp->get (b);
4628 if (instr->get_type () == Histable::INSTR)
4630 Function* func1 = ((DbeInstr *) instr)->func;
4631 func_seen->put (func1, 1);
4633 else if (instr->get_type () == Histable::LINE)
4635 Function* func1 = ((DbeLine *) instr)->func;
4636 func_seen->put (func1, 1);
4639 Vector<Function*> *funcs = func_seen->keySet ();
4640 delete func_seen;
4641 if (funcs->size () > 0)
4643 instr_info->append (instr0);
4644 func_info->append (funcs);
4647 delete instrs;
4648 destroy (callee_instrs);
4650 DefaultMap<uint64_t, Vector<int>* > * instr_idxs = new DefaultMap<uint64_t, Vector<int>* >();
4651 DefaultMap<uint64_t, int> * func_idxs = new DefaultMap<uint64_t, int>();
4652 for (long j = 0, sz_j = instr_info ? instr_info->size () : 0; j < sz_j; j++)
4654 Histable *instr = instr_info->get (j);
4655 Function *cur_func = NULL;
4656 if (instr->get_type () == Histable::INSTR)
4657 cur_func = ((DbeInstr*) instr)->func;
4658 else if (instr->get_type () == Histable::LINE)
4659 cur_func = ((DbeLine*) instr)->func;
4660 if (cur_func != NULL && (cur_func->flags & FUNC_FLAG_SIMULATED))
4661 continue; // skip functions like <Total>
4662 Histable* line;
4663 switch (type)
4665 case DSP_SOURCE:
4666 case DSP_SOURCE_V2:
4667 if (cur_func != NULL)
4669 SourceFile *sourceFile = cur_func->getDefSrc ();
4670 if (sourceFile == NULL ||
4671 (sourceFile->flags & SOURCE_FLAG_UNKNOWN) != 0)
4672 // skip functions like <Function: %s, instructions without line numbers>
4673 continue;
4675 line = instr->convertto (Histable::LINE, NULL);
4676 if (type == DSP_SOURCE_V2)
4677 line = dbev->get_compare_obj (line);
4678 break;
4679 case DSP_DISASM:
4680 case DSP_DISASM_V2:
4681 line = instr;
4682 if (type == DSP_DISASM_V2)
4683 line = dbev->get_compare_obj (line);
4684 break;
4685 default:
4686 abort ();
4688 if (func_idxs->get (line->id) == 0)
4690 func_idxs->put (line->id, 1);
4691 Vector<int> *temp_idx = new Vector<int>();
4692 temp_idx->append (j);
4693 instr_idxs->put (line->id, temp_idx);
4695 else
4697 Vector<int> *temp_idx = instr_idxs->get (line->id);
4698 temp_idx->append (j);
4701 for (long i = 0; i < data->size (); i++)
4703 Histable* line = data->fetch (i)->obj;
4704 if (line == NULL)
4705 continue;
4706 Vector<int> * instr_idx = instr_idxs->get (line->id);
4707 if (instr_idx == NULL)
4708 continue;
4709 for (long j = 0; j < instr_idx->size (); j++)
4711 Vector<void*>* callee_funcs_vec = (Vector<void*>*)func_info;
4712 if (callee_funcs_vec->size () == 0)
4713 continue;
4714 Vector<Function*>* callee_funcs_value = (Vector<Function*>*)callee_funcs_vec->fetch (instr_idx->fetch (j));
4715 for (int k = 0; callee_funcs_value != NULL && k < callee_funcs_value->size (); k++)
4717 uint64_t funcobj_id = ((Function*) callee_funcs_value->fetch (k))->id;
4718 int old_size = table0->size ();
4719 if (old_size > 0 && i == table0->fetch (old_size - 1)
4720 && funcobj_id == table1->fetch (old_size - 1))
4721 continue;
4722 table0->append (i);
4723 table1->append (funcobj_id);
4724 table2->append (dbe_strdup (((Function*) callee_funcs_value->fetch (k))->get_name ()));
4728 delete instr_idxs;
4729 delete func_idxs;
4730 destroy (func_info);
4731 delete instr_info;
4733 break;
4734 default:
4735 abort ();
4737 table->store (0, table0);
4738 table->store (1, table1);
4739 table->store (2, table2);
4740 return table;
4744 // Get Table of Function List data with only total values
4746 Vector<void*> *
4747 dbeGetFuncListMini (int dbevindex, int type, int /*subtype*/)
4749 Hist_data *data;
4750 DbeView *dbev = dbeSession->getView (dbevindex);
4751 switch (type)
4753 case DSP_FUNCTION:
4754 data = dbev->func_data;
4755 break;
4756 default:
4757 data = NULL;
4758 break;
4760 if (data == NULL || data->get_status () != Hist_data::SUCCESS)
4761 return NULL;
4763 MetricList *mlist = data->get_metric_list ();
4765 // Get table size: count visible metrics
4766 int nvisible = 0;
4767 for (long i = 0, sz = mlist->size (); i < sz; i++)
4769 Metric *m = mlist->get (i);
4770 if (m->is_visible () || m->is_tvisible () || m->is_pvisible ())
4771 nvisible++;
4773 Vector<void*> *table = new Vector<void*>(nvisible + 1);
4775 // Fill function list elements
4776 Hist_data::HistItem *totals = data->get_totals ();
4777 for (long i = 0, sz = mlist->size (); i < sz; i++)
4779 Metric *m = mlist->get (i);
4780 if (!m->is_visible () && !m->is_tvisible () && !m->is_pvisible ())
4781 continue;
4782 TValue res;
4783 TValue *v = data->get_value (&res, i, totals);
4784 if ((m->get_visbits () & VAL_RATIO) != 0)
4786 Vector<double> *col = new Vector<double>(1);
4787 double d = (v->tag != VT_LABEL) ? v->to_double () : 100.; // NaN
4788 col->append (d);
4789 table->append (col);
4790 continue;
4792 switch (m->get_vtype ())
4794 case VT_INT:
4796 Vector<int> *col = new Vector<int>(1);
4797 col->append (v->i);
4798 table->append (col);
4799 break;
4801 case VT_ADDRESS:
4802 case VT_ULLONG:
4803 case VT_LLONG:
4805 Vector<long long> *col = new Vector<long long>(1);
4806 col->append (v->ll);
4807 table->append (col);
4808 break;
4810 case VT_LABEL:
4812 Vector<char *> *col = new Vector<char *>(1);
4813 col->append (dbe_strdup (v->l));
4814 table->append (col);
4815 break;
4817 case VT_DOUBLE:
4818 default:
4820 Vector<double> *col = new Vector<double>(1);
4821 col->append (v->d);
4822 table->append (col);
4823 break;
4827 table->append (NULL);
4828 return table;
4831 // Get Table of Function List data
4832 Vector<void*> *
4833 dbeGetFuncList (int dbevindex, int type, int subtype)
4835 MetricList *mlist;
4836 Metric *mitem;
4837 int nitems, nvisible;
4838 int index, index2, nv;
4839 char *cell;
4840 Vector<int> *ji_list;
4841 Hist_data *data;
4842 Hist_data::HistItem *item;
4844 DbeView *dbev = dbeSession->getView (dbevindex);
4845 if (dbev == NULL)
4846 abort ();
4848 // fprintf(stderr, NTXT("XXX dbeGetFuncList, FuncListDisp_type = %d\n"), type);
4849 switch (type)
4851 case DSP_FUNCTION:
4852 data = dbev->func_data;
4853 break;
4854 case DSP_LINE:
4855 data = dbev->line_data;
4856 break;
4857 case DSP_PC:
4858 data = dbev->pc_data;
4859 break;
4860 case DSP_SOURCE:
4861 case DSP_SOURCE_V2:
4862 data = dbev->src_data;
4863 break;
4864 case DSP_DISASM:
4865 case DSP_DISASM_V2:
4866 data = dbev->dis_data;
4867 break;
4868 case DSP_SELF:
4869 data = dbev->fitem_data;
4870 break;
4871 case DSP_CALLER:
4872 data = dbev->callers;
4873 break;
4874 case DSP_CALLEE:
4875 data = dbev->callees;
4876 break;
4877 case DSP_DLAYOUT:
4878 data = dbev->dlay_data;
4879 break;
4880 case DSP_DATAOBJ:
4881 data = dbev->dobj_data;
4882 break;
4883 case DSP_MEMOBJ:
4884 case DSP_INDXOBJ:
4885 data = dbev->get_indxobj_data (subtype);
4886 break;
4887 default:
4888 data = NULL;
4889 break;
4891 if (data == NULL || data->get_status () != Hist_data::SUCCESS)
4892 return NULL;
4893 mlist = data->get_metric_list ();
4895 // Get table size: count visible metrics
4896 nitems = data->size ();
4897 nvisible = 0;
4898 Vec_loop (Metric*, mlist->get_items (), index, mitem)
4900 if (mitem->is_visible () || mitem->is_tvisible () || mitem->is_pvisible ())
4901 nvisible++;
4904 // Initialize Java String array
4905 Vector<void*> *table = new Vector<void*>(nvisible + 1);
4907 // Mark Hi-value metric items for annotated src/dis/layout
4908 if (type == DSP_SOURCE || type == DSP_DISASM || type == DSP_DLAYOUT
4909 || type == DSP_SOURCE_V2 || type == DSP_DISASM_V2)
4911 ji_list = new Vector<int>(nitems);
4913 if (dbev->marks->size () > 0)
4914 index = dbev->marks->fetch (0);
4915 else
4916 index = -1;
4917 int mindex = 0;
4918 for (index2 = 0; index2 < nitems; index2++)
4920 item = data->fetch (index2);
4921 if (index2 == index)
4923 ji_list->store (index2, -item->type);
4924 if (++mindex < dbev->marks->size ())
4925 index = dbev->marks->fetch (mindex);
4926 else
4927 index = -1;
4929 else
4930 ji_list->store (index2, item->type);
4932 table->store (nvisible, ji_list);
4934 else
4935 table->store (nvisible, NULL);
4937 // Fill function list elements
4938 nv = 0;
4940 Vec_loop (Metric*, mlist->get_items (), index, mitem)
4942 if (!mitem->is_visible () && !mitem->is_tvisible () &&
4943 !mitem->is_pvisible ())
4944 continue;
4946 // Fill values
4947 switch (mitem->get_vtype ())
4949 case VT_LABEL:
4951 Vector<char*> *jobjects = new Vector<char*>(nitems);
4952 char *buf = NULL;
4953 size_t bufsz = 0;
4954 int lspace = 0;
4955 if (type == DSP_SOURCE || type == DSP_DISASM || type == DSP_SOURCE_V2
4956 || type == DSP_DISASM_V2)
4958 // if this is source or disassembly, where we'll insert
4959 // a preface into the output line, figure out how wide
4960 // it needs to be
4961 // first, scan all the lines, to get the maximum line number
4962 bufsz = 1024;
4963 buf = (char *) malloc (bufsz);
4964 int max_lineno = 0;
4965 int hidx;
4966 Hist_data::HistItem *hitem;
4967 Vec_loop (Hist_data::HistItem*, data, hidx, hitem)
4969 if (!hitem->obj)
4970 continue;
4971 if (hitem->obj->get_type () == Histable::LINE &&
4972 ((DbeLine*) hitem->obj)->lineno > max_lineno)
4973 max_lineno = ((DbeLine*) hitem->obj)->lineno;
4974 else if (hitem->obj->get_type () == Histable::INSTR
4975 && ((DbeInstr*) hitem->obj)->lineno > max_lineno)
4976 max_lineno = ((DbeInstr*) hitem->obj)->lineno;
4979 // we have the maximum integer over all linenumbers in the file
4980 // figure out how many digits are needed
4981 lspace = snprintf (buf, bufsz, NTXT ("%d"), max_lineno);
4983 for (index2 = 0; index2 < nitems; index2++)
4985 item = data->fetch (index2);
4986 if (type == DSP_DLAYOUT)
4987 cell = dbe_strdup (((DataObject*) (item->obj))->get_offset_name ());
4988 else if (type == DSP_SOURCE || type == DSP_DISASM || type == DSP_SOURCE_V2 || type == DSP_DISASM_V2)
4990 // This code is duplicated in output.cc, yet it's
4991 // intended for presentation purpose and thus is
4992 // potentially different for er_print and analyzer.
4993 switch (item->type)
4995 case Module::AT_SRC_ONLY:
4996 case Module::AT_SRC:
4997 if (item->obj == NULL)
4998 snprintf (buf, bufsz, NTXT (" %*c. "), lspace, ' ');
4999 else
5000 snprintf (buf, bufsz, NTXT (" %*d. "), lspace, ((DbeLine*) item->obj)->lineno);
5001 break;
5002 case Module::AT_FUNC:
5003 case Module::AT_QUOTE:
5004 snprintf (buf, bufsz, NTXT ("%*c"), lspace + 3, ' ');
5005 break;
5006 case Module::AT_DIS:
5007 case Module::AT_DIS_ONLY:
5008 if (item->obj == NULL || ((DbeInstr*) item->obj)->lineno == -1)
5009 snprintf (buf, bufsz, NTXT ("%*c[%*s] "), lspace + 3, ' ', lspace, NTXT ("?"));
5010 else
5011 snprintf (buf, bufsz, NTXT ("%*c[%*d] "), lspace + 3, ' ', lspace,
5012 ((DbeInstr*) item->obj)->lineno);
5013 break;
5014 case Module::AT_COM:
5015 case Module::AT_EMPTY:
5016 *buf = (char) 0;
5017 break;
5019 // get the line's text
5020 char *s = item->value[index].l;
5021 if (s != NULL)
5023 // copy the string expanding all tabulations
5024 // (JTable doesn't render them)
5025 char *d = buf + strlen (buf);
5026 char c;
5027 size_t column = 0;
5030 c = *s++;
5031 if (c == '\t')
5035 *d++ = ' ';
5036 column++;
5038 while (column & 07);
5040 else
5042 *d++ = c;
5043 column++;
5045 if (column + 32 > bufsz)
5047 // Reallocate the buffer
5048 size_t curlen = d - buf;
5049 bufsz += 1024;
5050 char *buf_new = (char *) malloc (bufsz);
5051 strncpy (buf_new, buf, curlen);
5052 buf_new[curlen] = '\0';
5053 free (buf);
5054 buf = buf_new;
5055 d = buf + curlen;
5058 while (c != (char) 0);
5060 cell = dbe_strdup (buf);
5061 free (item->value[index].l);
5062 item->value[index].l = NULL; //YXXX missing from dbeGetFuncListV2
5064 else
5066 // omazur: why don't we have it as metric value
5067 Histable::NameFormat nfmt = dbev->get_name_format ();
5068 cell = dbe_strdup (item->obj->get_name (nfmt));
5070 jobjects->store (index2, cell);
5072 if (type == DSP_SOURCE || type == DSP_DISASM || type == DSP_SOURCE_V2
5073 || type == DSP_DISASM_V2)
5074 free (buf);
5075 table->store (nv++, jobjects);
5076 break;
5078 default:
5079 table->store (nv++, dbeGetTableDataOneColumn (data, index));
5080 break;
5083 return table;
5086 Vector<Obj> *
5087 dbeGetComparableObjsV2 (int /* dbevindex */, Obj sel_obj, int type)
5089 long grsize = dbeSession->expGroups->size ();
5090 Vector<Obj> *res = new Vector<Obj> (grsize + 1);
5091 for (long j = 0; j < grsize; j++)
5092 res->append ((Obj) NULL);
5093 res->append (sel_obj);
5094 Histable *obj = (Histable *) sel_obj;
5095 if (obj == NULL)
5096 return res;
5097 Function *func = (Function *) obj->convertto (Histable::FUNCTION);
5098 if (func == NULL)
5099 return res;
5100 Vector<Histable *> *cmpObjs = func->get_comparable_objs ();
5101 if (cmpObjs == NULL || cmpObjs->size () != grsize)
5102 return res;
5104 Histable::Type conv_type = (type == DSP_SOURCE || type == DSP_SOURCE_V2) ?
5105 Histable::LINE : Histable::INSTR;
5106 switch (obj->get_type ())
5108 case Histable::FUNCTION:
5109 for (long j = 0; j < grsize; j++)
5110 res->store (j, (Obj) cmpObjs->get (j));
5111 return res;
5112 case Histable::INSTR:
5113 case Histable::LINE:
5115 SourceFile *srcContext = (SourceFile *) obj->convertto (Histable::SOURCEFILE);
5116 char *bname = get_basename (srcContext->get_name ());
5117 for (long j = 0; j < grsize; j++)
5119 Function *func1 = (Function *) cmpObjs->get (j);
5120 if (func == func1)
5122 if (conv_type == Histable::LINE)
5123 res->store (j, (Obj) obj);
5124 else
5125 res->store (j, (Obj) obj->convertto (conv_type, srcContext));
5126 continue;
5128 if (func1 == NULL)
5129 continue;
5130 Vector<SourceFile*> *sources = func1->get_sources ();
5131 SourceFile *sf = NULL;
5132 for (long j1 = 0, sz1 = sources ? sources->size () : 0; j1 < sz1; j1++)
5134 SourceFile *sf1 = sources->get (j1);
5135 if (sf1 == srcContext)
5136 { // the same file
5137 sf = srcContext;
5138 break;
5140 else if (sf == NULL)
5142 char *bname1 = get_basename (sf1->get_name ());
5143 if (dbe_strcmp (bname, bname1) == 0)
5144 sf = sf1;
5147 res->store (j, (Obj) func1->convertto (conv_type, srcContext));
5149 break;
5151 default:
5152 break;
5154 return res;
5157 // Get Table of Function List data
5158 Vector<void *> *
5159 dbeGetFuncListV2 (int dbevindex, int mtype, Obj sel_obj, int type, int subtype)
5161 Metric *mitem;
5162 int nitems, nvisible;
5163 int index, index2, nv;
5164 char *cell;
5165 Hist_data::HistItem *item;
5166 DbeView *dbev = dbeSession->getView (dbevindex);
5167 dbev->error_msg = dbev->warning_msg = NULL;
5168 MetricList *mlist = dbev->get_metric_list ((MetricType) (mtype & MTYPE_MASK),
5169 (mtype & COMPARE_BIT) != 0,
5170 mtype >> GROUP_ID_SHIFT);
5171 Histable *selObj = (Histable *) sel_obj;
5172 int old_compare_mode = dbev->get_compare_mode ();
5173 if ((mtype & COMPARE_BIT) != 0)
5174 dbev->reset_compare_mode (CMP_DISABLE);
5175 Hist_data *data = dbev->get_data (mlist, selObj, type, subtype);
5176 dbev->reset_compare_mode (old_compare_mode);
5177 if (data == NULL || data->get_status () != Hist_data::SUCCESS)
5178 return NULL;
5179 nitems = data->size ();
5180 nvisible = mlist->get_items ()->size ();
5182 // Initialize Java String array
5183 Vector<void*> *table = new Vector<void*>(nvisible + 3);
5184 // Mark Hi-value metric items for annotated src/dis/layout
5185 if (type == DSP_SOURCE || type == DSP_DISASM || type == DSP_DLAYOUT
5186 || type == DSP_SOURCE_V2 || type == DSP_DISASM_V2)
5188 Vector<int> *types = new Vector<int>(nitems);
5189 Vector<Obj> *ids = new Vector<Obj > (nitems);
5190 if (dbev->marks->size () > 0)
5191 index = dbev->marks->fetch (0);
5192 else
5193 index = -1;
5194 int mindex = 0;
5195 for (int i = 0; i < nitems; i++)
5197 item = data->fetch (i);
5198 ids->store (i, (Obj) item->obj);
5199 if (i == index)
5201 types->store (i, -item->type);
5202 if (++mindex < dbev->marks->size ())
5203 index = dbev->marks->fetch (mindex);
5204 else
5205 index = -1;
5207 else
5208 types->store (i, item->type);
5210 table->store (nvisible, types);
5211 table->store (nvisible + 1, ids);
5213 else
5215 table->store (nvisible, NULL);
5216 table->store (nvisible + 1, NULL);
5219 // Fill function list elements
5220 nv = 0;
5221 Vec_loop (Metric*, mlist->get_items (), index, mitem)
5223 if (!mitem->is_visible () && !mitem->is_tvisible () &&
5224 !mitem->is_pvisible ())
5225 continue;
5227 // Fill values
5228 switch (mitem->get_vtype ())
5230 default:
5231 table->store (nv++, dbeGetTableDataOneColumn (data, index));
5232 break;
5233 case VT_LABEL:
5234 Vector<char*> *jobjects = new Vector<char*>(nitems);
5235 char *buf = NULL;
5236 size_t bufsz = 0;
5237 int lspace = 0;
5238 if (type == DSP_SOURCE || type == DSP_DISASM || type == DSP_SOURCE_V2
5239 || type == DSP_DISASM_V2)
5241 // if this is source or disassembly, where we'll insert
5242 // a preface into the output line, figure out how wide
5243 // it needs to be
5244 // first, scan all the lines, to get the maximum line number
5245 bufsz = 1024;
5246 buf = (char *) malloc (bufsz);
5247 int max_lineno = 0;
5248 int hidx;
5249 Hist_data::HistItem *hitem;
5250 Vec_loop (Hist_data::HistItem*, data, hidx, hitem)
5252 if (!hitem->obj)
5253 continue;
5254 if (hitem->obj->get_type () == Histable::LINE &&
5255 ((DbeLine*) hitem->obj)->lineno > max_lineno)
5256 max_lineno = ((DbeLine*) hitem->obj)->lineno;
5257 else if (hitem->obj->get_type () == Histable::INSTR
5258 && ((DbeInstr*) hitem->obj)->lineno > max_lineno)
5259 max_lineno = ((DbeInstr*) hitem->obj)->lineno;
5262 // we have the maximum integer over all linenumbers in the file
5263 // figure out how many digits are needed
5264 lspace = snprintf (buf, bufsz, NTXT ("%d"), max_lineno);
5267 for (index2 = 0; index2 < nitems; index2++)
5269 item = data->fetch (index2);
5270 if (type == DSP_DLAYOUT)
5271 cell = dbe_strdup (((DataObject*) (item->obj))->get_offset_name ());
5272 else if (type == DSP_SOURCE || type == DSP_DISASM || type == DSP_SOURCE_V2 || type == DSP_DISASM_V2)
5274 // This code is duplicated in output.cc, yet it's
5275 // intended for presentation purpose and thus is
5276 // potentially different for er_print and analyzer.
5277 switch (item->type)
5279 case Module::AT_SRC_ONLY:
5280 case Module::AT_SRC:
5281 if (item->obj == NULL)
5282 snprintf (buf, bufsz, NTXT (" %*c. "), lspace, ' ');
5283 else
5284 snprintf (buf, bufsz, NTXT (" %*d. "), lspace,
5285 ((DbeLine*) item->obj)->lineno);
5286 break;
5287 case Module::AT_FUNC:
5288 case Module::AT_QUOTE:
5289 snprintf (buf, bufsz, NTXT ("%*c"), lspace + 3, ' ');
5290 break;
5291 case Module::AT_DIS:
5292 case Module::AT_DIS_ONLY:
5293 if (item->obj == NULL || ((DbeInstr*) item->obj)->lineno == -1)
5294 snprintf (buf, bufsz, NTXT ("%*c[%*s] "), lspace + 3, ' ',
5295 lspace, NTXT ("?"));
5296 else
5297 snprintf (buf, bufsz, NTXT ("%*c[%*d] "), lspace + 3, ' ',
5298 lspace,
5299 ((DbeInstr*) item->obj)->lineno);
5300 break;
5301 case Module::AT_COM:
5302 case Module::AT_EMPTY:
5303 *buf = (char) 0;
5304 break;
5306 // get the line's text
5307 char *s = item->value[index].l;
5308 if (s != NULL)
5310 // copy the string expanding all tabulations
5311 // (JTable doesn't render them)
5312 char *d = buf + strlen (buf);
5313 char c;
5314 size_t column = 0;
5317 c = *s++;
5318 if (c == '\t')
5322 *d++ = ' ';
5323 column++;
5325 while (column & 07);
5327 else
5329 *d++ = c;
5330 column++;
5332 if (column + 32 > bufsz)
5334 // Reallocate the buffer
5335 size_t curlen = d - buf;
5336 bufsz += 1024;
5337 char *buf_new = (char *) malloc (bufsz);
5338 strncpy (buf_new, buf, curlen);
5339 buf_new[curlen] = '\0';
5340 free (buf);
5341 buf = buf_new;
5342 d = buf + curlen;
5345 while (c != (char) 0);
5347 cell = dbe_strdup (buf);
5349 else
5351 Histable::NameFormat nfmt = dbev->get_name_format ();
5352 cell = dbe_strdup (item->obj->get_name (nfmt));
5354 jobjects->store (index2, cell);
5357 if (type == DSP_SOURCE || type == DSP_DISASM || type == DSP_SOURCE_V2
5358 || type == DSP_DISASM_V2)
5359 free (buf);
5360 table->store (nv++, jobjects);
5361 break;
5364 table->append (dbeGetMetricList (mlist));
5365 return table;
5366 } // dbeGetFuncListV2
5369 // Get Table DataV2
5371 Vector<void*> *
5372 dbeGetTableDataV2 (int dbevindex, char *mlistStr, char *modeStr, char *typeStr,
5373 char *subtypeStr, Vector<uint64_t> *ids)
5375 DbeView *dbev = dbeSession->getView (dbevindex);
5376 if (dbev == NULL)
5377 abort ();
5379 // Process metric list specification
5380 if (mlistStr == NULL)
5381 return NULL;
5382 bool met_call = false;
5383 MetricList *mlist = NULL;
5384 if (streq (mlistStr, NTXT ("MET_NORMAL")))
5385 mlist = dbev->get_metric_list (MET_NORMAL);
5386 else if (streq (mlistStr, NTXT ("MET_CALL")))
5388 met_call = true;
5389 mlist = dbev->get_metric_list (MET_CALL);
5391 else if (streq (mlistStr, NTXT ("MET_CALL_AGR")))
5392 mlist = dbev->get_metric_list (MET_CALL_AGR);
5393 else if (streq (mlistStr, NTXT ("MET_DATA")))
5394 mlist = dbev->get_metric_list (MET_DATA);
5395 else if (streq (mlistStr, NTXT ("MET_INDX")))
5396 mlist = dbev->get_metric_list (MET_INDX);
5397 else if (streq (mlistStr, NTXT ("MET_IO")))
5398 mlist = dbev->get_metric_list (MET_IO);
5399 else if (streq (mlistStr, NTXT ("MET_HEAP")))
5400 mlist = dbev->get_metric_list (MET_HEAP);
5401 else
5402 return NULL;
5404 // Process mode specification
5405 if (modeStr == NULL)
5406 return NULL;
5407 Hist_data::Mode mode = (Hist_data::Mode)0;
5408 if (streq (modeStr, NTXT ("CALLERS")))
5409 mode = Hist_data::CALLERS;
5410 else if (streq (modeStr, NTXT ("CALLEES")))
5411 mode = Hist_data::CALLEES;
5412 else if (streq (modeStr, NTXT ("SELF")))
5413 mode = Hist_data::SELF;
5414 else if (streq (modeStr, NTXT ("ALL")))
5415 mode = Hist_data::ALL;
5416 else
5417 return NULL;
5419 // Process type specification
5420 if (typeStr == NULL)
5421 return NULL;
5422 Histable::Type type = Histable::OTHER;
5423 if (streq (typeStr, NTXT ("FUNCTION")))
5424 type = Histable::FUNCTION;
5425 else if (streq (typeStr, NTXT ("INDEXOBJ")))
5426 type = Histable::INDEXOBJ;
5427 else if (streq (typeStr, NTXT ("IOACTFILE")))
5428 type = Histable::IOACTFILE;
5429 else if (streq (typeStr, NTXT ("IOACTVFD")))
5430 type = Histable::IOACTVFD;
5431 else if (streq (typeStr, NTXT ("IOCALLSTACK")))
5432 type = Histable::IOCALLSTACK;
5433 else if (streq (typeStr, NTXT ("HEAPCALLSTACK")))
5434 type = Histable::HEAPCALLSTACK;
5435 else if (streq (typeStr, NTXT ("LINE")))
5436 type = Histable::LINE;
5437 else if (streq (typeStr, NTXT ("INSTR")))
5438 type = Histable::INSTR;
5439 else
5440 // XXX Accepting objects other than above may require a different
5441 // implementation of the id -> Histable mapping below
5442 return NULL;
5444 // Process subtype specification
5445 int subtype = 0;
5446 if (subtypeStr != NULL)
5447 subtype = atoi (subtypeStr);
5448 Vector<Histable*> *hobjs = NULL;
5449 if (ids != NULL)
5451 hobjs = new Vector<Histable*>();
5452 for (int i = 0; i < ids->size (); ++i)
5454 Histable::Type obj_type = type;
5455 if ((obj_type == Histable::LINE || obj_type == Histable::INSTR)
5456 && subtype == 0)
5457 obj_type = Histable::FUNCTION;
5458 Histable *hobj = dbeSession->findObjectById (obj_type, subtype, ids->fetch (i));
5459 if ((obj_type == Histable::LINE || obj_type == Histable::INSTR)
5460 && subtype == 0 && hobj == NULL)
5461 return NULL;
5462 hobjs->append (hobj);
5466 PathTree::PtreeComputeOption flag = PathTree::COMPUTEOPT_NONE;
5467 if (dbev->isOmpDisMode () && type == Histable::FUNCTION
5468 && mode == Hist_data::CALLEES && met_call)
5469 flag = PathTree::COMPUTEOPT_OMP_CALLEE;
5471 Hist_data *data = dbev->get_hist_data (mlist, type, subtype, mode, hobjs, NULL, NULL, flag);
5472 return dbeGetTableDataV2Data (dbev, data);
5475 static Vector<void*> *
5476 dbeGetTableDataV2Data (DbeView * /*dbev*/, Hist_data *data)
5478 if (data == NULL || data->get_status () != Hist_data::SUCCESS)
5479 return NULL;
5480 MetricList *mlist;
5481 mlist = data->get_metric_list ();
5482 int nitems = data->size ();
5484 // Initialize Java String array
5485 Vector<void*> *table = new Vector<void*>(mlist->size () + 1);
5487 // Fill function list elements
5488 for (long i = 0, sz = mlist->size (); i < sz; i++)
5490 Metric *mitem = mlist->get (i);
5491 if (!mitem->is_visible () && !mitem->is_tvisible () &&
5492 !mitem->is_pvisible ())
5493 continue;
5494 table->append (dbeGetTableDataOneColumn (data, i));
5497 // Add an array of Histable IDs
5498 Vector<uint64_t> *idList = new Vector<uint64_t>(nitems);
5499 for (int i = 0; i < nitems; ++i)
5501 Hist_data::HistItem *item = data->fetch (i);
5502 if (item->obj->get_type () == Histable::LINE
5503 || item->obj->get_type () == Histable::INSTR)
5504 idList->store (i, (uint64_t) (item->obj));
5505 else
5506 idList->store (i, item->obj->id);
5508 table->append (idList);
5509 return table;
5510 } // dbeGetTableData
5512 //YXXX try to use the following to consolidate similar cut/paste code
5514 static Vector<void*> *
5515 dbeGetTableDataOneColumn (Hist_data *data, int met_ind)
5517 // Allocates a vector and fills it with metric values for one column
5518 TValue res;
5519 Metric *m = data->get_metric_list ()->get (met_ind);
5520 if ((m->get_visbits () & VAL_RATIO) != 0)
5522 Vector<double> *col = new Vector<double>(data->size ());
5523 for (long row = 0, sz_row = data->size (); row < sz_row; row++)
5525 TValue *v = data->get_value (&res, met_ind, row);
5526 double d = (v->tag != VT_LABEL) ? v->to_double () : 100.; // NaN
5527 col->append (d);
5529 return (Vector<void*> *) col;
5532 switch (m->get_vtype ())
5534 case VT_DOUBLE:
5536 Vector<double> *col = new Vector<double>(data->size ());
5537 for (long row = 0, sz_row = data->size (); row < sz_row; row++)
5539 TValue *v = data->get_value (&res, met_ind, row);
5540 col->append (v->d);
5542 return (Vector<void*> *) col;
5544 case VT_INT:
5546 Vector<int> *col = new Vector<int>(data->size ());
5547 for (long row = 0, sz_row = data->size (); row < sz_row; row++)
5549 TValue *v = data->get_value (&res, met_ind, row);
5550 col->append (v->i);
5552 return (Vector<void*> *) col;
5554 case VT_ULLONG:
5555 case VT_LLONG:
5557 Vector<long long> *col = new Vector<long long>(data->size ());
5558 for (long row = 0, sz_row = data->size (); row < sz_row; row++)
5560 TValue *v = data->get_value (&res, met_ind, row);
5561 col->append (v->ll);
5563 return (Vector<void*> *) col;
5565 case VT_ADDRESS:
5567 Vector<long long> *col = new Vector<long long>(data->size ());
5568 for (long row = 0, sz_row = data->size (); row < sz_row; row++)
5570 TValue *v = data->get_value (&res, met_ind, row);
5571 // set the highest bit to mark this jlong as
5572 // a VT_ADDRESS (rather than a regular VT_LLONG)
5573 col->append (v->ll | 0x8000000000000000ULL);
5575 return (Vector<void*> *) col;
5577 case VT_LABEL:
5579 Vector<char *> *col = new Vector<char *>(data->size ());
5580 for (long row = 0, sz_row = data->size (); row < sz_row; row++)
5582 TValue *v = data->get_value (&res, met_ind, row);
5583 col->append (dbe_strdup (v->l));
5585 return (Vector<void*> *) col;
5587 default:
5588 return NULL;
5592 static Vector<void*> *
5593 dbeGetTableDataOneColumn (DbeView *dbev, Vector<Hist_data::HistItem*> *data,
5594 ValueTag vtype, int metricColumnNumber)
5595 // Allocates a vector and fills it with metric values for one column
5597 Vector<void*> *column_data = NULL;
5598 int nitems = data->size (); // number of rows
5599 int index = metricColumnNumber;
5600 switch (vtype)
5602 case VT_DOUBLE:
5604 Vector<double> *jd_list = new Vector<double>(nitems);
5605 for (int index2 = 0; index2 < nitems; index2++)
5607 Hist_data::HistItem *item = data->fetch (index2);
5608 jd_list->store (index2, item->value[index].d);
5610 column_data = (Vector<void*> *)jd_list;
5611 break;
5613 case VT_INT:
5615 Vector<int> *ji_list = new Vector<int>(nitems);
5616 for (int index2 = 0; index2 < nitems; index2++)
5618 Hist_data::HistItem *item = data->fetch (index2);
5619 ji_list->store (index2, item->value[index].i);
5621 column_data = (Vector<void*> *)ji_list;
5622 break;
5624 case VT_ULLONG:
5625 case VT_LLONG:
5627 Vector<long long> *jl_list = new Vector<long long>(nitems);
5628 for (int index2 = 0; index2 < nitems; index2++)
5630 Hist_data::HistItem *item = data->fetch (index2);
5631 jl_list->store (index2, item->value[index].ll);
5633 column_data = (Vector<void*> *)jl_list;
5634 break;
5636 case VT_ADDRESS:
5638 Vector<long long> *jl_list = new Vector<long long>(nitems);
5639 for (int index2 = 0; index2 < nitems; index2++)
5641 Hist_data::HistItem *item = data->fetch (index2);
5643 // set the highest bit to mark this jlong as
5644 // a VT_ADDRESS (rather than a regular VT_LLONG)
5645 uint64_t addr = item->value[index].ll;
5646 addr |= 0x8000000000000000ULL;
5647 jl_list->store (index2, addr);
5649 column_data = (Vector<void*> *)jl_list;
5650 break;
5652 case VT_LABEL:
5654 Vector<char*> *jobjects = new Vector<char*>(nitems);
5655 for (int index2 = 0; index2 < nitems; index2++)
5657 Hist_data::HistItem *item = data->fetch (index2);
5659 // omazur: why don't we have it as metric value
5660 Histable::NameFormat nfmt = dbev->get_name_format ();
5661 char *str = dbe_strdup (item->obj->get_name (nfmt));
5662 jobjects->store (index2, str);
5664 column_data = (Vector<void*> *)jobjects;
5665 break;
5667 default:
5668 abort ();
5670 return column_data;
5674 dbeGetCallTreeNumLevels (int dbevindex)
5676 DbeView *dbev = dbeSession->getView (dbevindex);
5677 if (dbev == NULL)
5678 abort ();
5679 PathTree * ptree = dbev->get_path_tree ();
5680 if (ptree == NULL)
5681 return 0;
5682 return ptree->get_ftree_depth ();
5685 Vector<void*>*
5686 dbeGetCallTreeLevel (int dbevindex, char *mcmd, int level)
5688 DbeView *dbev = dbeSession->getView (dbevindex);
5689 if (dbev == NULL)
5690 abort ();
5691 PathTree * ptree = dbev->get_path_tree ();
5692 if (ptree == NULL)
5693 return NULL;
5694 if (mcmd == NULL)
5695 return NULL;
5696 BaseMetric *bm = dbeSession->find_base_reg_metric (mcmd);
5697 if (bm == NULL)
5698 return NULL;
5699 return ptree->get_ftree_level (bm, level);
5702 Vector<void*>*
5703 dbeGetCallTreeLevels (int dbevindex, char *mcmd)
5705 DbeView *dbev = dbeSession->getView (dbevindex);
5706 if (dbev == NULL)
5707 abort ();
5708 PathTree * ptree = dbev->get_path_tree ();
5709 if (ptree == NULL)
5710 return NULL;
5711 if (mcmd == NULL)
5712 return NULL;
5713 BaseMetric *bm = dbeSession->find_base_reg_metric (mcmd);
5714 if (bm == NULL)
5715 return NULL;
5717 int depth = ptree->get_ftree_depth ();
5718 Vector<void*> *results = new Vector<void*>(depth);
5719 for (int ii = 0; ii < depth; ii++)
5720 results->append (ptree->get_ftree_level (bm, ii));
5721 return results;
5724 Vector<void*>*
5725 dbeGetCallTreeLevelFuncs (int dbevindex, int start_level, int end_level)
5726 { // (0,-1) -> all levels
5727 DbeView *dbev = dbeSession->getView (dbevindex);
5728 if (dbev == NULL)
5729 abort ();
5730 PathTree * ptree = dbev->get_path_tree ();
5731 if (ptree == NULL)
5732 return NULL;
5734 int depth = ptree->get_ftree_depth ();
5735 if (start_level < 0)
5736 start_level = 0;
5737 if (end_level < 0 || end_level >= depth)
5738 end_level = depth - 1;
5740 Histable::NameFormat nfmt = dbev->get_name_format (); //YXXX or fixed format?
5741 Vector<char*> *funcNames = new Vector<char*>();
5742 Vector<long long> *funcIds = new Vector<long long>();
5743 Vector<Obj> *funcObjs = new Vector<Obj>();
5745 if (start_level == 0 && end_level == depth - 1)
5746 return dbeGetCallTreeFuncs (dbevindex);
5747 else
5749 for (int ii = start_level; ii <= end_level; ii++)
5751 Vector<void*> *info = ptree->get_ftree_level (NULL, ii); /*no metric*/
5752 if (!info)
5753 continue;
5754 Vector<long long> *fids = (Vector<long long> *)info->get (2);
5755 if (!fids)
5756 continue;
5757 int index;
5758 long long fid;
5759 Vec_loop (long long, fids, index, fid)
5761 funcIds->append (fid);
5762 Histable *obj = dbeSession->findObjectById (fid);
5763 char * fname = obj ? dbe_strdup (obj->get_name (nfmt)) : NULL;
5764 funcNames->append (fname);
5765 funcObjs->append ((unsigned long) obj); // avoiding sign extension
5767 destroy (info);
5770 Vector<void*> *results = new Vector<void*>(3);
5771 results->append (funcIds);
5772 results->append (funcNames);
5773 results->append (funcObjs);
5774 return results;
5777 Vector<void*> *
5778 dbeGetCallTreeFuncs (int dbevindex)
5779 { // does not require ptree->get_ftree_level() to be computed
5780 DbeView *dbev = dbeSession->getView (dbevindex);
5781 if (dbev == NULL)
5782 abort ();
5783 PathTree * ptree = dbev->get_path_tree ();
5784 if (ptree == NULL)
5785 return 0;
5786 Vector<Function*>* funcs = ptree->get_funcs (); // Unique functions in tree
5787 if (funcs == NULL)
5788 return NULL;
5790 long sz = funcs->size ();
5791 Vector<void*> *results = new Vector<void*>(3);
5792 Vector<long long> *funcIds = new Vector<long long>(sz);
5793 Vector<char*> *funcNames = new Vector<char*>(sz);
5794 Vector<Obj> *funcObjs = new Vector<Obj>(sz);
5796 int index;
5797 Function * func;
5798 Histable::NameFormat nfmt = dbev->get_name_format (); //YXXX or fixed format?
5799 Vec_loop (Function *, funcs, index, func)
5801 funcIds->append (func->id); // do we need IDs?
5802 char *fname = dbe_strdup (func->get_name (nfmt));
5803 funcNames->append (fname);
5804 funcObjs->append ((unsigned long) func); // avoiding sign extension
5806 results->put (0, funcIds);
5807 results->put (1, funcNames);
5808 results->put (2, funcObjs);
5809 destroy (funcs);
5810 return results;
5813 Vector<void*>*
5814 dbeGetCallTreeChildren (int dbevindex, char *mcmd, Vector<int /*NodeIdx*/>*node_idxs)
5816 DbeView *dbev = dbeSession->getView (dbevindex);
5817 if (dbev == NULL)
5818 abort ();
5819 if (node_idxs == NULL || node_idxs->size () == 0)
5820 return NULL;
5821 long sz = node_idxs->size ();
5822 PathTree * ptree = dbev->get_path_tree ();
5823 if (ptree == NULL)
5824 return NULL;
5825 if (mcmd == NULL)
5826 return NULL;
5827 BaseMetric *bm = dbeSession->find_base_reg_metric (mcmd);
5828 if (bm == NULL)
5829 return NULL;
5831 Vector<void*> *results = new Vector<void*>(sz);
5832 for (long ii = 0; ii < sz; ii++)
5834 PathTree::NodeIdx nodeIdx = node_idxs->get (ii); // upcasted from int
5835 results->append (ptree->get_ftree_node_children (bm, nodeIdx));
5837 return results;
5840 Vector<int> *
5841 dbeGetGroupIds (int /*dbevindex*/)
5843 Vector<ExpGroup*> *groups = dbeSession->expGroups;
5844 int sz = groups->size ();
5845 Vector<int> *grIds = new Vector<int>(sz);
5846 for (int i = 0; i < sz; i++)
5847 grIds->store (i, groups->fetch (i)->groupId);
5848 return grIds;
5852 // Get label for name column
5854 Vector<char*> *
5855 dbeGetNames (int dbevindex, int type, Obj sel_obj)
5857 char *s0, *s1, *s2;
5858 bool need_strdup = true;
5859 switch (type)
5861 case DSP_SOURCE_V2:
5862 case DSP_DISASM_V2:
5863 case DSP_SOURCE:
5864 case DSP_DISASM:
5866 if (sel_obj)
5868 Histable *selObj = (Histable*) sel_obj;
5869 Function *func = (Function *) selObj->convertto (Histable::FUNCTION);
5870 if (func)
5872 char *names[3] = {NULL, NULL, NULL};
5873 set_file_names (func, names);
5874 s0 = names[0];
5875 s1 = names[1];
5876 s2 = names[2];
5877 need_strdup = false;
5878 break;
5881 DbeView *dbev = dbeSession->getView (dbevindex);
5882 char **names = type == DSP_SOURCE || type == DSP_SOURCE_V2 ? dbev->names_src : dbev->names_dis;
5883 s0 = names[0];
5884 s1 = names[1];
5885 s2 = names[2];
5886 break;
5888 case DSP_LINE:
5889 s0 = GTXT ("Lines");
5890 s1 = GTXT ("Function, line # in \"sourcefile\"");
5891 s2 = NTXT ("");
5892 break;
5893 case DSP_PC:
5894 s0 = GTXT ("PCs");
5895 s1 = GTXT ("Function + offset");
5896 s2 = NTXT ("");
5897 break;
5898 case DSP_DLAYOUT:
5899 s0 = GTXT ("Name");
5900 s1 = GTXT ("* +offset .element");
5901 s2 = NTXT ("");
5902 break;
5903 default:
5904 s0 = GTXT ("Name");
5905 s1 = s2 = NTXT ("");
5906 break;
5908 if (need_strdup)
5910 s0 = dbe_strdup (s0);
5911 s1 = dbe_strdup (s1);
5912 s2 = dbe_strdup (s2);
5914 Vector<char*> *table = new Vector<char*>(3);
5915 table->store (0, s0);
5916 table->store (1, s1);
5917 table->store (2, s2);
5918 return table;
5922 // Get Total/Maximum element of Function List
5924 Vector<void*> *
5925 dbeGetTotalMax (int dbevindex, int type, int subtype)
5927 Hist_data *data;
5928 int index;
5929 Hist_data::HistItem *total_item, *maximum_item;
5930 DbeView *dbev = dbeSession->getView (dbevindex);
5931 if (dbev == NULL)
5932 abort ();
5934 switch (type)
5936 case DSP_LINE:
5937 data = dbev->line_data;
5938 break;
5939 case DSP_PC:
5940 data = dbev->pc_data;
5941 break;
5942 case DSP_CALLER:
5943 data = dbev->callers;
5944 break;
5945 case DSP_SELF:
5946 case DSP_CALLEE:
5947 data = dbev->callees;
5948 break;
5949 case DSP_DLAYOUT:
5950 data = dbev->dlay_data;
5951 break;
5952 case DSP_DATAOBJ:
5953 data = dbev->dobj_data;
5954 break;
5955 case DSP_MEMOBJ:
5956 data = dbev->get_indxobj_data (subtype);
5957 break;
5958 case DSP_INDXOBJ:
5959 data = dbev->get_indxobj_data (subtype);
5960 break;
5961 case DSP_FUNCTION: // annotated src/dis use func total/max
5962 case DSP_SOURCE:
5963 case DSP_DISASM:
5964 case DSP_SOURCE_V2:
5965 case DSP_DISASM_V2:
5966 data = dbev->func_data;
5967 break;
5968 default:
5969 abort ();
5971 if (data == NULL || data->get_status () != Hist_data::SUCCESS)
5972 return NULL;
5974 // Get list size
5975 // XXX -- the original list has all items, visible or not;
5976 // XXX -- the one from Hist_data has only visible items,
5977 // XXX -- and should be the only ones computed
5978 // XXX -- Analyzer got confused (yesterday), when we used the shorter list
5979 // XXX -- Why can we fetch total/max for metrics never
5980 // XXX -- computed without core dumping?
5981 MetricList *mlist2 = data->get_metric_list ();
5982 int size = mlist2->get_items ()->size ();
5984 // Initialize Java array
5985 Vector<void*> *total_max = new Vector<void*>(2);
5986 Vector<double> *total = new Vector<double>(size);
5987 Vector<double> *maximum = new Vector<double>(size);
5989 // Fill total/maximum element
5990 total_item = data->get_totals ();
5991 maximum_item = data->get_maximums ();
5993 for (index = 0; index < size; index++)
5995 total->store (index, total_item->value[index].to_double ());
5996 maximum->store (index, maximum_item->value[index].to_double ());
5998 total_max->store (0, total);
5999 total_max->store (1, maximum);
6000 return total_max;
6004 // Get Table of Overview List
6005 Vector<void*> *
6006 dbeGetStatisOverviewList (int dbevindex)
6008 int size;
6009 Ovw_data **data;
6010 Ovw_data::Ovw_item labels, *totals;
6011 int nitems;
6012 int index, index2;
6014 DbeView *dbev = dbeSession->getView (dbevindex);
6015 if (dbev == NULL)
6016 abort ();
6017 dbev->error_msg = dbev->warning_msg = NULL;
6019 size = dbeSession->nexps ();
6020 totals = new Ovw_data::Ovw_item[size + 1];
6021 data = new Ovw_data*[size + 1];
6022 data[0] = new Ovw_data ();
6024 for (index = 1; index <= size; index++)
6026 data[index] = dbev->get_ovw_data (index - 1);
6027 if (data[index] == NULL)
6029 Ovw_data::reset_item (&totals[index]); // set contents to zeros
6030 continue;
6032 data[0]->sum (data[index]);
6033 totals[index] = data[index]->get_totals (); //shallow copy!
6035 totals[0] = data[0]->get_totals ();
6037 // Get table size
6038 labels = data[0]->get_labels ();
6039 nitems = labels.size + 4;
6041 // Initialize Java String array
6042 Vector<void*> *table = new Vector<void*>(size + 4);
6043 Vector<char*> *jobjects = new Vector<char*>(nitems);
6045 // Set the label
6046 jobjects->store (0, dbe_strdup (GTXT ("Start Time (sec.)")));
6047 jobjects->store (1, dbe_strdup (GTXT ("End Time (sec.)")));
6048 jobjects->store (2, dbe_strdup (GTXT ("Duration (sec.)")));
6049 jobjects->store (3, dbe_strdup (GTXT ("Total Thread Time (sec.)")));
6050 jobjects->store (4, dbe_strdup (GTXT ("Average number of Threads")));
6052 for (index2 = 5; index2 < nitems; index2++)
6053 jobjects->store (index2, dbe_strdup (labels.values[index2 - 4].l));
6054 table->store (0, jobjects);
6056 // Set the data
6057 for (index = 0; index <= size; index++)
6059 Vector<double> *jd_list = new Vector<double>(nitems);
6060 jd_list->store (0, tstodouble (totals[index].start));
6061 jd_list->store (1, tstodouble (totals[index].end));
6062 jd_list->store (2, tstodouble (totals[index].duration));
6063 jd_list->store (3, tstodouble (totals[index].tlwp));
6064 jd_list->store (4, totals[index].nlwp);
6065 for (index2 = 5; index2 < nitems; index2++)
6066 jd_list->store (index2, tstodouble (totals[index].values[index2 - 4].t));
6067 table->store (index + 1, jd_list);
6069 for (index = 0; index <= size; index++)
6070 delete data[index];
6071 delete[] data;
6072 delete[] totals;
6073 return table;
6076 // Get Table of Statistics List
6077 Vector<void*> *
6078 dbeGetStatisList (int dbevindex)
6080 int size;
6081 Stats_data **data;
6082 int nitems;
6083 int index, index2;
6084 DbeView *dbev = dbeSession->getView (dbevindex);
6085 if (dbev == NULL)
6086 abort ();
6087 dbev->error_msg = dbev->warning_msg = NULL;
6088 if ((size = dbeSession->nexps ()) == 0)
6089 return NULL;
6091 // Get statistics data
6092 data = (Stats_data **) malloc ((size + 1) * sizeof (Stats_data *));
6093 data[0] = new Stats_data ();
6094 for (index = 1; index <= size; index++)
6096 data[index] = dbev->get_stats_data (index - 1);
6097 if (data[index] == NULL)
6098 continue;
6099 data[0]->sum (data[index]);
6102 // Get table size
6103 nitems = data[0]->size ();
6105 // Initialize Java String array
6106 Vector<void*> *table = new Vector<void*>(size + 2);
6107 Vector<char*> *jobjects = new Vector<char*>(nitems);
6109 // Set the label
6110 for (index2 = 0; index2 < nitems; index2++)
6111 jobjects->store (index2, dbe_strdup (data[0]->fetch (index2).label));
6112 table->store (0, jobjects);
6114 // Set the data
6115 for (index = 0; index <= size; index++)
6117 Vector<double> *jd_list = new Vector<double>(nitems);
6118 for (index2 = 0; index2 < nitems; index2++)
6120 double val = 0;
6121 if (data[index])
6122 val = data[index]->fetch (index2).value.to_double ();
6123 jd_list->store (index2, val);
6125 table->store (index + 1, jd_list);
6127 if (data)
6129 for (index = 0; index <= size; index++)
6130 delete data[index];
6131 free (data);
6133 return table;
6138 // Set summary list
6140 static void
6141 setSummary (Vector<Histable*> *objs, Vector<int> *saligns,
6142 Vector<char> *mnemonic, Vector<char*> *jlabels, Vector<char*> *jvalues)
6144 char *sname = NULL, *oname = NULL, *lname = NULL, *alias = NULL,
6145 *mangle = NULL, *address = NULL, *size = NULL,
6146 *name_0 = NULL, *sname_0 = NULL, *oname_0 = NULL, *lname_0 = NULL,
6147 *alias_0 = NULL, *mangle_0 = NULL;
6148 Function *func, *last_func = NULL;
6149 int one_func = 1;
6151 // Get the source/object/load-object files & aliases
6152 long long ll_size = 0;
6153 for (long i = 0; i < objs->size (); i++)
6155 Histable *current_obj = objs->fetch (i);
6156 Histable::Type htype = current_obj->get_type ();
6157 if (htype == Histable::LOADOBJECT)
6158 lname = ((LoadObject *) current_obj)->dbeFile->get_location_info ();
6159 else if ((func = (Function*) current_obj->convertto (Histable::FUNCTION)) != NULL)
6161 if (one_func && last_func != NULL && last_func != func)
6162 one_func = 0;
6163 last_func = func;
6164 sname = NULL;
6165 DbeLine *dbeline = (DbeLine*) current_obj->convertto (Histable::LINE);
6166 if (dbeline)
6168 SourceFile *sf;
6169 if (dbeline->lineno == 0 && dbeline->include != NULL)
6170 sf = dbeline->include;
6171 else if (dbeline->sourceFile != NULL)
6172 sf = dbeline->sourceFile;
6173 else
6174 sf = func->getDefSrc ();
6175 if (sf)
6176 sname = sf->dbeFile->get_location_info ();
6178 char *func_name = func->get_name ();
6179 mangle = func->get_mangled_name ();
6180 if (mangle && streq (func_name, mangle))
6181 mangle = NULL;
6182 Module *module = func->module;
6183 if (module != NULL)
6185 module->read_stabs ();
6186 if (sname == NULL || strlen (sname) == 0)
6188 SourceFile *sf = module->getMainSrc ();
6189 sname = sf->dbeFile->get_location_info ();
6191 DbeFile *df = module->dbeFile;
6192 if (df == NULL || (df->filetype & DbeFile::F_JAVACLASS) == 0)
6193 df = module->loadobject->dbeFile;
6194 lname = df->get_location_info ();
6195 oname = lname;
6196 if (module->dot_o_file)
6197 oname = module->dot_o_file->dbeFile->get_location_info ();
6200 if (htype == Histable::INSTR && dbeSession->is_datamode_available ())
6201 alias = ((DbeInstr*) current_obj)->get_descriptor ();
6204 char *name = current_obj->get_name ();
6205 if (i == 0)
6207 name_0 = name;
6208 lname_0 = lname;
6209 sname_0 = sname;
6210 oname_0 = oname;
6211 mangle_0 = mangle;
6212 alias_0 = alias;
6213 if (objs->size () == 1)
6215 uint64_t addr = current_obj->get_addr ();
6216 address = dbe_sprintf (NTXT ("%lld:0x%08llX"),
6217 (long long) ADDRESS_SEG (addr),
6218 (long long) ADDRESS_OFF (addr));
6221 else
6223 if (name_0 != name)
6224 name_0 = NULL;
6225 if (lname_0 != lname)
6226 lname_0 = NULL;
6227 if (sname_0 != sname)
6228 sname_0 = NULL;
6229 if (oname_0 != oname)
6230 oname_0 = NULL;
6231 if (mangle_0 != mangle)
6232 mangle_0 = NULL;
6233 if (alias_0 != alias)
6234 alias_0 = NULL;
6236 if (current_obj->get_size () == -1)
6238 if (size == NULL)
6239 size = dbe_strdup (GTXT ("(Unknown)"));
6241 else
6242 ll_size += current_obj->get_size ();
6244 if (size == NULL)
6245 size = dbe_sprintf (NTXT ("%lld"), ll_size);
6246 if (name_0 == NULL)
6248 if (objs->size () > 1)
6250 char *func_name = last_func == NULL ? NULL :
6251 (one_func == 0 ? NULL : last_func->get_name ());
6252 name_0 = dbe_sprintf (NTXT ("%s%s%s (%lld %s)"),
6253 func_name == NULL ? "" : func_name,
6254 func_name == NULL ? "" : ": ",
6255 GTXT ("Multiple Selection"),
6256 (long long) objs->size (),
6257 GTXT ("objects"));
6260 else
6261 name_0 = dbe_strdup (name_0);
6263 // Set the name area
6264 saligns->store (0, TEXT_LEFT);
6265 mnemonic->store (0, 'N');
6266 jlabels->store (0, dbe_strdup (GTXT ("Name")));
6267 jvalues->store (0, name_0);
6269 saligns->store (1, TEXT_LEFT);
6270 mnemonic->store (1, 'P');
6271 jlabels->store (1, dbe_strdup (GTXT ("PC Address")));
6272 jvalues->store (1, address);
6274 saligns->store (2, TEXT_LEFT);
6275 mnemonic->store (2, 'z');
6276 jlabels->store (2, dbe_strdup (GTXT ("Size")));
6277 jvalues->store (2, size);
6279 saligns->store (3, TEXT_RIGHT);
6280 mnemonic->store (3, 'r');
6281 jlabels->store (3, dbe_strdup (GTXT ("Source File")));
6282 jvalues->store (3, dbe_strdup (sname_0));
6284 saligns->store (4, TEXT_RIGHT);
6285 mnemonic->store (4, 'b');
6286 jlabels->store (4, dbe_strdup (GTXT ("Object File")));
6287 jvalues->store (4, dbe_strdup (oname_0));
6289 saligns->store (5, TEXT_LEFT);
6290 mnemonic->store (5, 'j');
6291 jlabels->store (5, dbe_strdup (GTXT ("Load Object")));
6292 jvalues->store (5, dbe_strdup (lname_0));
6294 saligns->store (6, TEXT_LEFT);
6295 mnemonic->store (6, 'm');
6296 jlabels->store (6, dbe_strdup (GTXT ("Mangled Name")));
6297 jvalues->store (6, dbe_strdup (mangle_0));
6299 saligns->store (7, TEXT_LEFT);
6300 mnemonic->store (7, 'A');
6301 jlabels->store (7, dbe_strdup (GTXT ("Aliases")));
6302 jvalues->store (7, dbe_strdup (alias_0));
6305 // Set memory-object summary list
6307 static void
6308 setMemSummary (Vector<Histable*> *objs, Vector<int> *saligns,
6309 Vector<char> *mnemonic, Vector<char*> *jlabels,
6310 Vector<char*> *jvalues)
6312 saligns->store (0, TEXT_LEFT);
6313 mnemonic->store (0, 'M');
6314 jlabels->store (0, dbe_strdup (GTXT ("Memory Object")));
6315 if (objs->size () == 1)
6317 Histable *current_obj = objs->fetch (0);
6318 jvalues->store (0, dbe_strdup (current_obj->get_name ()));
6320 else
6322 char *name = dbe_sprintf (NTXT ("%s (%lld %s)"),
6323 GTXT ("Multiple Selection"),
6324 (long long) objs->size (), GTXT ("objects"));
6325 jvalues->store (0, name);
6329 // Set index-object summary list
6331 static void
6332 setIndxSummary (Vector<Histable*> *objs, Vector<int> *saligns,
6333 Vector<char> *mnemonic, Vector<char*> *jlabels,
6334 Vector<char*> *jvalues)
6336 saligns->store (0, TEXT_LEFT);
6337 mnemonic->store (0, 'I');
6338 jlabels->store (0, dbe_strdup (GTXT ("Index Object")));
6340 if (objs->size () == 1)
6342 Histable *current_obj = objs->fetch (0);
6343 jvalues->store (0, dbe_strdup (current_obj->get_name ()));
6345 else
6347 char *name = dbe_sprintf (NTXT ("%s (%lld %s)"), GTXT ("Multiple Selection"),
6348 (long long) objs->size (), GTXT ("objects"));
6349 jvalues->store (0, name);
6353 // Set I/O activity summary list
6355 static void
6356 setIOActivitySummary (Vector<Histable*> *objs, Vector<int> *saligns,
6357 Vector<char> *mnemonic, Vector<char*> *jlabels,
6358 Vector<char*> *jvalues)
6360 saligns->store (0, TEXT_LEFT);
6361 mnemonic->store (0, 'O');
6362 jlabels->store (0, dbe_strdup (GTXT ("I/O Activity")));
6363 if (objs->size () == 1)
6365 Histable *current_obj = objs->fetch (0);
6366 jvalues->store (0, dbe_strdup (current_obj->get_name ()));
6368 else
6370 char *name = dbe_sprintf (NTXT ("%s (%lld %s)"), GTXT ("Multiple Selection"),
6371 (long long) objs->size (), GTXT ("objects"));
6372 jvalues->store (0, name);
6376 // Set heap activity summary list
6378 static void
6379 setHeapActivitySummary (Vector<Histable*> *objs, Vector<int> *saligns,
6380 Vector<char> *mnemonic, Vector<char*> *jlabels,
6381 Vector<char*> *jvalues)
6383 saligns->store (0, TEXT_LEFT);
6384 mnemonic->store (0, 'O');
6385 jlabels->store (0, dbe_strdup (GTXT ("Heap Activity")));
6387 if (objs->size () == 1)
6389 Histable *current_obj = objs->fetch (0);
6390 jvalues->store (0, dbe_strdup (current_obj->get_name ()));
6392 else
6394 char *name = dbe_sprintf (NTXT ("%s (%lld %s)"), GTXT ("Multiple Selection"),
6395 (long long) objs->size (), GTXT ("objects"));
6396 jvalues->store (0, name);
6401 // Set data-object summary list
6403 static void
6404 setDataSummary (Vector<Histable*> *objs, Vector<int> *saligns,
6405 Vector<char> *mnemonic, Vector<char*> *jlabels,
6406 Vector<char*> *jvalues)
6408 char *name, *type, *member, *elist;
6409 DataObject *dobj;
6410 Vector<DataObject *> *delem;
6411 Histable *scope;
6412 int index;
6413 char *size, *offset, *elements, *scopename;
6415 // Get the data object elements
6416 member = elist = type = size = offset = elements = scopename = NULL;
6418 if (objs->size () == 1)
6420 Histable *current_obj = objs->fetch (0);
6421 name = dbe_strdup (current_obj->get_name ());
6422 dobj = (DataObject *) current_obj;
6423 type = dobj->get_typename ();
6424 scope = dobj->get_scope ();
6425 delem = dbeSession->get_dobj_elements (dobj);
6426 if (type == NULL)
6427 type = GTXT ("(Synthetic)");
6428 if (!scope)
6429 scopename = dbe_strdup (GTXT ("(Global)"));
6430 else
6432 switch (scope->get_type ())
6434 case Histable::FUNCTION:
6435 scopename = dbe_sprintf (NTXT ("%s(%s)"),
6436 ((Function*) scope)->module->get_name (),
6437 scope->get_name ());
6438 break;
6439 case Histable::LOADOBJECT:
6440 case Histable::MODULE:
6441 default:
6442 scopename = dbe_strdup (scope->get_name ());
6443 break;
6447 if (dobj->get_offset () != -1)
6449 if (dobj->get_parent ())
6450 member = dbe_strdup (dobj->get_parent ()->get_name ());
6451 offset = dbe_sprintf (NTXT ("%lld"), (long long) dobj->get_offset ());
6453 size = dbe_sprintf ("%lld", (long long) dobj->get_size ());
6455 if (delem->size () > 0)
6457 elements = dbe_sprintf (NTXT ("%lld"), (long long) delem->size ());
6458 StringBuilder sb_tmp, sb;
6459 sb.append (GTXT ("Offset Size Name\n"));
6460 for (index = 0; index < delem->size (); index++)
6462 DataObject *ditem = delem->fetch (index);
6463 sb_tmp.sprintf (NTXT ("%6lld %5lld %s\n"),
6464 (long long) ditem->get_offset (),
6465 (long long) ditem->get_size (), ditem->get_name ());
6466 sb.append (&sb_tmp);
6468 if (sb.charAt (sb.length () - 1) == '\n')
6469 sb.setLength (sb.length () - 1);
6470 elist = sb.toString ();
6473 else
6474 name = dbe_sprintf (NTXT ("%s (%lld %s)"), GTXT ("Multiple Selection"),
6475 (long long) objs->size (), GTXT ("objects"));
6477 saligns->store (0, TEXT_LEFT);
6478 mnemonic->store (0, 'D');
6479 jlabels->store (0, dbe_strdup (GTXT ("Data Object")));
6480 jvalues->store (0, name);
6482 saligns->store (1, TEXT_LEFT);
6483 mnemonic->store (1, 'S');
6484 jlabels->store (1, dbe_strdup (GTXT ("Scope")));
6485 jvalues->store (1, scopename);
6487 saligns->store (2, TEXT_LEFT);
6488 mnemonic->store (2, 'T');
6489 jlabels->store (2, dbe_strdup (GTXT ("Type")));
6490 jvalues->store (2, dbe_strdup (type));
6492 saligns->store (3, TEXT_LEFT);
6493 mnemonic->store (3, 'M');
6494 jlabels->store (3, dbe_strdup (GTXT ("Member of")));
6495 jvalues->store (3, member);
6497 saligns->store (4, TEXT_LEFT);
6498 mnemonic->store (4, 'O');
6499 jlabels->store (4, dbe_strdup (GTXT ("Offset")));
6500 jvalues->store (4, offset);
6502 saligns->store (5, TEXT_LEFT);
6503 mnemonic->store (5, 'z');
6504 jlabels->store (5, dbe_strdup (GTXT ("Size")));
6505 jvalues->store (5, size);
6507 saligns->store (6, TEXT_LEFT);
6508 mnemonic->store (6, 'E');
6509 jlabels->store (6, dbe_strdup (GTXT ("Elements")));
6510 jvalues->store (6, elements);
6512 saligns->store (7, TEXT_LEFT);
6513 mnemonic->store (7, 'L');
6514 jlabels->store (7, dbe_strdup (GTXT ("List")));
6515 jvalues->store (7, elist);
6518 #define SUMMARY_NAME 8
6519 #define DSUMMARY_NAME 8
6520 #define LSUMMARY_NAME 7
6521 #define IMSUMMARY_NAME 1
6523 Vector<void*> *
6524 dbeGetSummaryV2 (int dbevindex, Vector<Obj> *sel_objs, int type, int subtype)
6526 if (sel_objs == NULL || sel_objs->size () == 0)
6527 return NULL;
6528 DbeView *dbev = dbeSession->getView (dbevindex);
6529 Vector<Histable*>*objs = new Vector<Histable*>(sel_objs->size ());
6530 for (int i = 0; i < sel_objs->size (); i++)
6532 Histable *obj = (Histable *) sel_objs->fetch (i);
6533 if (obj == NULL)
6534 continue;
6535 char *nm = obj->get_name ();
6536 if (streq (nm, NTXT ("<Total>")))
6538 // Special case for 'Total'.
6539 // Multi selection which includes 'Total' is only 'Total'
6540 objs->reset ();
6541 objs->append (obj);
6542 break;
6544 objs->append (obj);
6546 if (objs->size () == 0)
6547 return NULL;
6549 // Set name area
6550 int nname = SUMMARY_NAME;
6551 Vector<int> *saligns = new Vector<int>(nname);
6552 Vector<char>*mnemonic = new Vector<char>(nname);
6553 Vector<char*> *jlabels = new Vector<char*>(nname);
6554 Vector<char*> *jvalues = new Vector<char*>(nname);
6555 Vector<void*> *name_objs = new Vector<void*>(4);
6556 name_objs->store (0, saligns);
6557 name_objs->store (1, mnemonic);
6558 name_objs->store (2, jlabels);
6559 name_objs->store (3, jvalues);
6560 setSummary (objs, saligns, mnemonic, jlabels, jvalues);
6562 MetricList *prop_mlist = new MetricList (dbev->get_metric_ref (MET_NORMAL));
6563 if (prop_mlist && dbev->comparingExperiments ())
6564 prop_mlist = dbev->get_compare_mlist (prop_mlist, 0);
6566 int nitems = prop_mlist->get_items ()->size ();
6568 // Set the metrics area
6569 jlabels = new Vector<char*>(nitems);
6570 Vector<double> *clock_list = new Vector<double>(nitems);
6571 Vector<double> *excl_list = new Vector<double>(nitems);
6572 Vector<double> *ep_list = new Vector<double>(nitems);
6573 Vector<double> *incl_list = new Vector<double>(nitems);
6574 Vector<double> *ip_list = new Vector<double>(nitems);
6575 Vector<int> *vtype = new Vector<int>(nitems);
6577 // Initialize Java String array
6578 Vector<void*> *metric_objs = new Vector<void*>(8);
6579 metric_objs->store (0, jlabels);
6580 metric_objs->store (1, clock_list);
6581 metric_objs->store (2, excl_list);
6582 metric_objs->store (3, ep_list);
6583 metric_objs->store (4, incl_list);
6584 metric_objs->store (5, ip_list);
6585 metric_objs->store (6, vtype);
6587 int last_init = -1;
6588 for (int i = 0; i < objs->size (); i++)
6590 Histable *obj = objs->fetch (i);
6591 // Get the data to be displayed
6592 Hist_data *data = dbev->get_hist_data (prop_mlist, obj->get_type (), subtype,
6593 Hist_data::SELF, obj, dbev->sel_binctx, objs);
6595 if (data->get_status () != Hist_data::SUCCESS)
6597 if (type != DSP_DLAYOUT)
6598 { // For data_layout, rows with zero metrics are OK
6599 delete data;
6600 continue;
6603 TValue *values = NULL;
6604 if (data->get_status () == Hist_data::SUCCESS)
6606 Hist_data::HistItem *hi = data->fetch (0);
6607 if (hi)
6608 values = hi->value;
6610 Hist_data::HistItem *total = data->get_totals ();
6611 int index2 = 0;
6612 char *tstr = GTXT (" Time");
6613 char *estr = GTXT ("Exclusive ");
6614 size_t len = strlen (estr);
6616 // get the metric list from the data
6617 MetricList *mlist = data->get_metric_list ();
6618 int index;
6619 Metric *mitem;
6620 double clock;
6621 Vec_loop (Metric*, mlist->get_items (), index, mitem)
6623 if (mitem->get_subtype () == Metric::STATIC)
6624 continue;
6625 if (last_init < index2)
6627 last_init = index2;
6628 jlabels->store (index2, NULL);
6629 clock_list->store (index2, 0.0);
6630 excl_list->store (index2, 0.0);
6631 ep_list->store (index2, 0.0);
6632 incl_list->store (index2, 0.0);
6633 ip_list->store (index2, 0.0);
6634 vtype->store (index2, 0);
6636 double dvalue = (values != NULL) ? values[index].to_double () : 0.0;
6637 double dtotal = total->value[index].to_double ();
6638 if (mitem->is_time_val ())
6639 clock = 1.e+6 * dbeSession->get_clock (-1);
6640 else
6641 clock = 0.0;
6643 clock_list->store (index2, clock);
6644 if ((mitem->get_subtype () == Metric::EXCLUSIVE) ||
6645 (mitem->get_subtype () == Metric::DATASPACE))
6647 if (i == 0)
6649 char *sstr = mitem->get_name ();
6650 if (!strncmp (sstr, estr, len))
6651 sstr += len;
6652 char *buf, *lstr = strstr (sstr, tstr);
6653 if (lstr)
6654 buf = dbe_strndup (sstr, lstr - sstr);
6655 else
6656 buf = dbe_strdup (sstr);
6657 jlabels->store (index2, buf);
6658 vtype->store (index2, mitem->get_vtype ());
6660 dvalue += excl_list->fetch (index2);
6661 double percent = dtotal == 0.0 ? dtotal : (dvalue / dtotal) * 100;
6662 excl_list->store (index2, dvalue);
6663 ep_list->store (index2, percent);
6665 else
6667 dvalue += incl_list->fetch (index2);
6668 if (dvalue > dtotal)
6669 dvalue = dtotal; // temporary correction
6670 double percent = dtotal == 0.0 ? dtotal : (dvalue / dtotal) * 100;
6671 incl_list->store (index2, dvalue);
6672 ip_list->store (index2, percent);
6673 index2++;
6676 delete data;
6678 delete prop_mlist;
6679 Vector<void*> *summary = new Vector<void*>(2);
6680 summary->store (0, name_objs);
6681 summary->store (1, metric_objs);
6682 return summary;
6685 // Get Summary List
6686 Vector<void*> *
6687 dbeGetSummary (int dbevindex, Vector<Obj> *sel_objs, int type, int subtype)
6689 bool is_data, is_mem, is_indx, is_iodata, is_heapdata;
6690 Hist_data::HistItem *total;
6691 MetricList *prop_mlist; // as passed to get_hist_data
6692 MetricList *mlist; // as stored in the data
6693 Metric *mitem;
6694 int i, nname, nitems, index, index2;
6695 TValue *values;
6696 double dvalue, clock;
6697 Hist_data *data;
6698 Vector<double> *percent_scale;
6700 DbeView *dbev = dbeSession->getView (dbevindex);
6701 if (dbev == NULL)
6702 abort ();
6703 if (sel_objs == NULL || sel_objs->size () == 0)
6704 return NULL;
6706 is_mem = false;
6707 is_data = false;
6708 is_indx = false;
6709 is_iodata = false;
6710 is_heapdata = false;
6711 nname = SUMMARY_NAME;
6712 Vector<Histable*>*objs = new Vector<Histable*>(sel_objs->size ());
6713 if (type == DSP_TIMELINE)
6714 objs->append ((Histable *) sel_objs->fetch (0));
6715 else
6717 switch (type)
6719 case DSP_FUNCTION:
6720 data = dbev->func_data;
6721 break;
6722 case DSP_LINE:
6723 data = dbev->line_data;
6724 break;
6725 case DSP_PC:
6726 data = dbev->pc_data;
6727 break;
6728 case DSP_SELF:
6729 data = dbev->fitem_data;
6730 break;
6731 case DSP_SOURCE:
6732 case DSP_SOURCE_V2:
6733 data = dbev->src_data;
6734 break;
6735 case DSP_DISASM:
6736 case DSP_DISASM_V2:
6737 data = dbev->dis_data;
6738 break;
6739 case DSP_DLAYOUT:
6740 is_data = true;
6741 nname = LSUMMARY_NAME;
6742 data = dbev->dlay_data;
6743 break;
6744 case DSP_DATAOBJ:
6745 is_data = true;
6746 nname = DSUMMARY_NAME;
6747 data = dbev->dobj_data;
6748 break;
6749 case DSP_MEMOBJ:
6750 is_data = true;
6751 is_mem = true;
6752 nname = IMSUMMARY_NAME;
6753 data = dbev->get_indxobj_data (subtype);
6754 break;
6755 case DSP_INDXOBJ:
6756 is_indx = true;
6757 nname = IMSUMMARY_NAME;
6758 data = dbev->get_indxobj_data (subtype);
6759 break;
6760 case DSP_IOACTIVITY:
6761 is_iodata = true;
6762 nname = IMSUMMARY_NAME;
6763 data = dbev->iofile_data;
6764 break;
6765 case DSP_IOVFD:
6766 is_iodata = true;
6767 nname = IMSUMMARY_NAME;
6768 data = dbev->iovfd_data;
6769 break;
6770 case DSP_IOCALLSTACK:
6771 is_iodata = true;
6772 nname = IMSUMMARY_NAME;
6773 data = dbev->iocs_data;
6774 break;
6775 case DSP_HEAPCALLSTACK:
6776 is_heapdata = true;
6777 nname = IMSUMMARY_NAME;
6778 data = dbev->heapcs_data;
6779 break;
6780 default:
6781 data = NULL;
6782 break;
6784 if (data == NULL || data->get_status () != Hist_data::SUCCESS)
6785 return NULL;
6787 Hist_data::HistItem *current_item;
6788 for (i = 0; i < sel_objs->size (); i++)
6790 int sel_index = (int) sel_objs->fetch (i);
6791 if (type != DSP_IOACTIVITY && type != DSP_IOVFD &&
6792 type != DSP_IOCALLSTACK && type != DSP_HEAPCALLSTACK)
6794 if (sel_index < 0 || sel_index >= data->size ())
6795 continue;
6796 current_item = data->fetch (sel_index);
6797 if (current_item->obj == NULL)
6798 continue;
6800 else
6802 if (sel_index < 0)
6803 continue;
6804 bool found = false;
6805 for (int j = 0; j < data->size (); j++)
6807 current_item = data->fetch (j);
6808 if ((current_item->obj != NULL) && (current_item->obj->id == sel_index))
6810 found = true;
6811 break;
6814 if (!found)
6815 continue;
6817 char *nm = current_item->obj->get_name ();
6818 if (streq (nm, NTXT ("<Total>")))
6820 // Special case for 'Total'.
6821 // Multi selection which includes 'Total' is only 'Total'
6822 objs->reset ();
6823 objs->append (current_item->obj);
6824 break;
6826 objs->append (current_item->obj);
6829 if (objs->size () == 0)
6830 return NULL;
6832 // Set name area
6833 Vector<int> *saligns = new Vector<int>(nname);
6834 Vector<char>*mnemonic = new Vector<char>(nname);
6835 Vector<char*> *jlabels = new Vector<char*>(nname);
6836 Vector<char*> *jvalues = new Vector<char*>(nname);
6837 Vector<void*> *name_objs = new Vector<void*>(4);
6838 name_objs->store (0, saligns);
6839 name_objs->store (1, mnemonic);
6840 name_objs->store (2, jlabels);
6841 name_objs->store (3, jvalues);
6842 if (is_mem)
6843 setMemSummary (objs, saligns, mnemonic, jlabels, jvalues);
6844 else if (is_indx)
6845 setIndxSummary (objs, saligns, mnemonic, jlabels, jvalues);
6846 else if (is_data)
6847 setDataSummary (objs, saligns, mnemonic, jlabels, jvalues);
6848 else if (is_iodata)
6849 setIOActivitySummary (objs, saligns, mnemonic, jlabels, jvalues);
6850 else if (is_heapdata)
6851 setHeapActivitySummary (objs, saligns, mnemonic, jlabels, jvalues);
6852 else
6853 setSummary (objs, saligns, mnemonic, jlabels, jvalues);
6855 // Get the reference metrics
6856 if (is_data)
6857 prop_mlist = new MetricList (dbev->get_metric_ref (MET_DATA));
6858 else if (is_indx)
6859 prop_mlist = new MetricList (dbev->get_metric_ref (MET_INDX));
6860 else if (is_iodata)
6861 prop_mlist = new MetricList (dbev->get_metric_ref (MET_IO));
6862 else if (is_heapdata)
6863 prop_mlist = new MetricList (dbev->get_metric_ref (MET_HEAP));
6864 else
6865 prop_mlist = new MetricList (dbev->get_metric_ref (MET_NORMAL));
6867 // XXXX a workaround to avoid aggregated data for compare mode, only show base experiment data
6868 if (prop_mlist && dbev->comparingExperiments ())
6869 prop_mlist = dbev->get_compare_mlist (prop_mlist, 0);
6870 nitems = prop_mlist->get_items ()->size ();
6872 // Set the metrics area
6873 jlabels = new Vector<char*>(nitems);
6874 Vector<double> *clock_list = new Vector<double>(nitems);
6875 Vector<double> *excl_list = new Vector<double>(nitems);
6876 Vector<double> *ep_list = new Vector<double>(nitems);
6877 Vector<double> *incl_list = new Vector<double>(nitems);
6878 Vector<double> *ip_list = new Vector<double>(nitems);
6879 Vector<int> *vtype = new Vector<int>(nitems);
6881 // Initialize Java String array
6882 Vector<void*> *metric_objs = new Vector<void*>(8);
6883 metric_objs->store (0, jlabels);
6884 metric_objs->store (1, clock_list);
6885 metric_objs->store (2, excl_list);
6886 metric_objs->store (3, ep_list);
6887 metric_objs->store (4, incl_list);
6888 metric_objs->store (5, ip_list);
6889 metric_objs->store (6, vtype);
6890 percent_scale = new Vector<double>();
6891 int last_init = -1;
6892 for (i = 0; i < objs->size (); i++)
6894 Histable *current_obj = objs->fetch (i);
6895 // Get the data to be displayed
6896 data = dbev->get_hist_data (prop_mlist, current_obj->get_type (), subtype,
6897 Hist_data::SELF, current_obj, dbev->sel_binctx, objs);
6898 if (data->get_status () != Hist_data::SUCCESS)
6900 if (type != DSP_DLAYOUT)
6901 { // For data_layout, rows with zero metrics are OK
6902 delete data;
6903 continue;
6906 Hist_data::HistItem *hi = data->fetch (0);
6907 values = hi ? hi->value : NULL;
6908 total = data->get_totals ();
6909 index2 = 0;
6911 // get the metric list from the data
6912 mlist = data->get_metric_list ();
6914 // We loop over the metrics in mlist.
6915 // We construct index2, which tells us
6916 // the corresponding entry in the metric_objs lists.
6917 // We need this mapping multiple times.
6918 // So, if you change the looping in any way here,
6919 // do so as well in other similar loops.
6920 // All such loops are marked so:
6921 // See discussion on "mlist-to-index2 mapping".
6923 Vec_loop (Metric*, mlist->get_items (), index, mitem)
6925 if (mitem->get_subtype () == Metric::STATIC)
6926 continue;
6927 if (last_init < index2)
6929 last_init = index2;
6930 jlabels->store (index2, NULL);
6931 clock_list->store (index2, 0.0);
6932 excl_list->store (index2, 0.0);
6933 ep_list->store (index2, 0.0);
6934 incl_list->store (index2, 0.0);
6935 ip_list->store (index2, 0.0);
6936 vtype->store (index2, 0);
6938 dvalue = (values != NULL) ? values[index].to_double () : 0.0;
6939 double dtotal = total->value[index].to_double ();
6940 percent_scale->store (index, dtotal == 0. ? 0. : 100. / dtotal);
6941 if (mitem->is_time_val ())
6942 clock = 1.e+6 * dbeSession->get_clock (-1);
6943 else
6944 clock = 0.0;
6946 clock_list->store (index2, clock);
6947 if (mitem->get_subtype () == Metric::EXCLUSIVE ||
6948 mitem->get_subtype () == Metric::DATASPACE)
6950 if (i == 0)
6952 char *sstr = mitem->get_username ();
6953 char *buf = dbe_strdup (sstr);
6954 jlabels->store (index2, buf);
6955 vtype->store (index2, mitem->get_vtype ());
6957 dvalue += excl_list->fetch (index2);
6958 double percent = dvalue * percent_scale->fetch (index);
6959 excl_list->store (index2, dvalue);
6960 ep_list->store (index2, percent);
6961 if (is_data || is_indx || is_iodata || is_heapdata)
6962 // move to next row, except if there's inclusive data, too
6963 index2++;
6965 else
6967 dvalue += incl_list->fetch (index2);
6968 if (dvalue > dtotal && mitem->get_type () != BaseMetric::DERIVED)
6969 dvalue = dtotal; // temporary correction
6970 double percent = dvalue * percent_scale->fetch (index);
6971 incl_list->store (index2, dvalue);
6972 ip_list->store (index2, percent);
6973 index2++;
6976 delete data;
6979 // for multi-selection, we have to recompute the derived metrics
6980 if (objs->size () > 1 &&
6981 dbev->get_derived_metrics () != NULL &&
6982 dbev->get_derived_metrics ()->get_items () != NULL &&
6983 dbev->get_derived_metrics ()->get_items ()->size () > 0)
6985 // See discussion on "mlist-to-index2 mapping".
6986 Vector<Metric*> *mvec = new Vector<Metric*>(nitems);
6987 index2 = 0;
6988 Vec_loop (Metric*, prop_mlist->get_items (), index, mitem)
6990 if (mitem->get_subtype () == Metric::STATIC)
6991 continue;
6992 if (mitem->get_subtype () == Metric::EXCLUSIVE ||
6993 mitem->get_subtype () == Metric::DATASPACE)
6995 mvec->store (index2, mitem);
6996 if (is_data || is_indx || is_iodata || is_heapdata)
6997 index2++;
6999 else
7001 assert (strcmp (mvec->fetch (index2)->get_cmd (), mitem->get_cmd ()) == 0);
7002 index2++;
7005 int *map = dbev->get_derived_metrics ()->construct_map (mvec, BaseMetric::EXCLUSIVE, mvec->fetch (0)->get_expr_spec ());
7006 if (map != NULL)
7008 int nmetrics = mvec->size ();
7009 double *evalues = (double *) malloc (nmetrics * sizeof (double));
7010 double *ivalues = (double *) malloc (nmetrics * sizeof (double));
7011 for (index2 = 0; index2 < nmetrics; index2++)
7013 evalues[index2] = excl_list->fetch (index2);
7014 ivalues[index2] = incl_list->fetch (index2);
7017 // evaluate derived metrics
7018 dbev->get_derived_metrics ()->eval (map, evalues);
7019 dbev->get_derived_metrics ()->eval (map, ivalues);
7020 for (index2 = 0; index2 < nmetrics; index2++)
7022 excl_list->store (index2, evalues[index2]);
7023 incl_list->store (index2, ivalues[index2]);
7026 // recompute percentages for derived metrics EUGENE maybe all percentage computations should be moved here
7027 // See discussion on "mlist-to-index2 mapping".
7028 index2 = 0;
7029 Vec_loop (Metric*, prop_mlist->get_items (), index, mitem)
7031 if (mitem->get_subtype () == Metric::STATIC)
7032 continue;
7033 if (mitem->get_subtype () == Metric::EXCLUSIVE ||
7034 mitem->get_subtype () == Metric::DATASPACE)
7036 if (mitem->get_type () == BaseMetric::DERIVED)
7037 ep_list->store (index2, excl_list->fetch (index2) * percent_scale->fetch (index));
7038 if (is_data || is_indx || is_iodata || is_heapdata)
7039 index2++;
7041 else
7043 if (mitem->get_type () == BaseMetric::DERIVED)
7044 ip_list->store (index2, incl_list->fetch (index2) * percent_scale->fetch (index));
7045 index2++;
7048 free (evalues);
7049 free (ivalues);
7050 free (map);
7052 delete mvec;
7054 delete prop_mlist;
7055 Vector<void*> *summary = new Vector<void*>(2);
7056 summary->store (0, name_objs);
7057 summary->store (1, metric_objs);
7058 delete objs;
7059 delete percent_scale;
7060 return summary;
7063 char *
7064 dbeGetExpName (int /*dbevindex*/, char *dir_name)
7066 char *ret;
7067 char *warn;
7068 if (col_ctr == NULL)
7069 col_ctr = new Coll_Ctrl (1); // Potential race condition?
7070 if (dir_name != NULL)
7072 ret = col_ctr->set_directory (dir_name, &warn);
7073 // note that the warning and error msgs are written to stderr, not returned to caller
7074 if (warn != NULL)
7075 fprintf (stderr, NTXT ("%s"), warn);
7076 if (ret != NULL)
7077 fprintf (stderr, NTXT ("%s"), ret);
7079 return dbe_strdup (col_ctr->get_expt ());
7082 // === CollectDialog HWC info ===
7084 Vector<Vector<char*>*> *
7085 dbeGetHwcSets (int /*dbevindex*/, bool forKernel)
7087 Vector<Vector<char*>*> *list = new Vector<Vector<char*>*>(2);
7088 char * defctrs = hwc_get_default_cntrs2 (forKernel, 1);
7089 Vector<char*> *i18n = new Vector<char*>(1); // User name
7090 Vector<char*> *name = new Vector<char*>(1); // Internal name
7091 if (NULL != defctrs)
7093 i18n->store (0, strdup (defctrs));
7094 name->store (0, strdup (NTXT ("default")));
7096 list->store (0, i18n);
7097 list->store (1, name);
7098 return list;
7101 static Vector<void*> *
7102 dbeGetHwcs (Hwcentry **hwcs)
7104 int sz;
7105 for (sz = 0; hwcs && hwcs[sz]; sz++)
7107 Vector<void*> *list = new Vector<void*>(9);
7108 Vector<char*> *i18n = new Vector<char*>(sz);
7109 Vector<char*> *name = new Vector<char*>(sz);
7110 Vector<char*> *int_name = new Vector<char*>(sz);
7111 Vector<char*> *metric = new Vector<char*>(sz);
7112 Vector<long long> *val = new Vector<long long>(sz);
7113 Vector<int> *timecvt = new Vector<int>(sz);
7114 Vector<int> *memop = new Vector<int>(sz);
7115 Vector<char*> *short_desc = new Vector<char*>(sz);
7116 Vector<Vector<int>*> *reglist_v = new Vector<Vector<int>*>(sz);
7117 Vector<bool> *supportsAttrs = new Vector<bool>(sz);
7118 Vector<bool> *supportsMemspace = new Vector<bool>(sz);
7120 for (int i = 0; i < sz; i++)
7122 Hwcentry *ctr = hwcs[i];
7123 Vector<int> *registers = new Vector<int>(MAX_PICS);
7124 regno_t *reglist = ctr->reg_list;
7125 for (int k = 0; !REG_LIST_EOL (reglist[k]) && k < MAX_PICS; k++)
7126 registers->store (k, reglist[k]);
7128 i18n->store (i, dbe_strdup (hwc_i18n_metric (ctr)));
7129 name->store (i, dbe_strdup (ctr->name));
7130 int_name->store (i, dbe_strdup (ctr->int_name));
7131 metric->store (i, dbe_strdup (ctr->metric));
7132 val->store (i, ctr->val); // signed promotion from int
7133 timecvt->store (i, ctr->timecvt);
7134 memop->store (i, ctr->memop);
7135 reglist_v->store (i, registers);
7136 short_desc->store (i, dbe_strdup (ctr->short_desc));
7137 supportsAttrs->store (i, true);
7138 supportsMemspace->store (i, ABST_MEMSPACE_ENABLED (ctr->memop));
7140 list->store (0, i18n);
7141 list->store (1, name);
7142 list->store (2, int_name);
7143 list->store (3, metric);
7144 list->store (4, val);
7145 list->store (5, timecvt);
7146 list->store (6, memop);
7147 list->store (7, short_desc);
7148 list->store (8, reglist_v);
7149 list->store (9, supportsAttrs);
7150 list->store (10, supportsMemspace);
7151 return list;
7154 Vector<void *> *
7155 dbeGetHwcsAll (int /*dbevindex*/, bool forKernel)
7157 Vector<void*> *list = new Vector<void*>(2);
7158 list->store (0, dbeGetHwcs (hwc_get_std_ctrs (forKernel)));
7159 list->store (1, dbeGetHwcs (hwc_get_raw_ctrs (forKernel)));
7160 return list;
7163 Vector<char*> *
7164 dbeGetHwcHelp (int /*dbevindex*/, bool forKernel)
7166 Vector<char*> *strings = new Vector<char*>(32);
7167 FILE *f = tmpfile ();
7168 hwc_usage_f (forKernel, f, "", 0, 0, 1); // writes to f
7169 fflush (f);
7170 fseek (f, 0, SEEK_SET);
7171 #define MAX_LINE_LEN 2048
7172 char buff[MAX_LINE_LEN];
7173 int ii = 0;
7174 while (fgets (buff, MAX_LINE_LEN, f))
7175 strings->store (ii++, dbe_strdup (buff));
7176 fclose (f);
7177 return strings;
7180 Vector<char*> *
7181 dbeGetHwcAttrList (int /*dbevindex*/, bool forKernel)
7183 char ** attr_list = hwc_get_attrs (forKernel); // Get Attribute list
7184 int size;
7185 for (size = 0; attr_list && attr_list[size]; size++)
7188 Vector<char*> *name = new Vector<char*>(size);
7189 for (int i = 0; i < size; i++)
7190 name->store (i, dbe_strdup (attr_list[i]));
7191 return name;
7194 //Get maximum number of simultaneous counters
7196 dbeGetHwcMaxConcurrent (int /*dbevindex*/, bool forKernel)
7198 return hwc_get_max_concurrent (forKernel);
7201 // === End CollectDialog HWC info ===
7204 // Instruction-frequency data
7205 Vector<char*> *
7206 dbeGetIfreqData (int dbevindex)
7208 DbeView *dbev = dbeSession->getView (dbevindex);
7209 if (dbev == NULL)
7210 abort ();
7211 if (!dbeSession->is_ifreq_available ())
7212 return NULL;
7213 int size = dbeSession->nexps ();
7214 if (size == 0)
7215 return NULL;
7217 // Initialize Java String array
7218 Vector<char*> *list = new Vector<char*>();
7219 for (int i = 0; i < size; i++)
7221 Experiment *exp = dbeSession->get_exp (i);
7222 if (exp->broken || !dbev->get_exp_enable (i) || !exp->ifreqavail)
7223 continue;
7224 // write a header for the experiment
7225 list->append (dbe_sprintf (GTXT ("Instruction frequency data from experiment %s\n\n"),
7226 exp->get_expt_name ()));
7227 // add its instruction frequency messages
7228 char *ifreq = pr_mesgs (exp->fetch_ifreq (), NTXT (""), NTXT (""));
7229 list->append (ifreq);
7231 return list;
7234 // LeakList related methods
7236 Vector<void*> *
7237 dbeGetLeakListInfo (int dbevindex, bool leakflag)
7239 DbeView *dbev = dbeSession->getView (dbevindex);
7240 if (dbev == NULL)
7241 abort ();
7242 MetricList *origmlist = dbev->get_metric_list (MET_NORMAL);
7243 MetricList *nmlist = new MetricList (origmlist);
7244 if (leakflag)
7245 nmlist->set_metrics (NTXT ("e.heapleakbytes:e.heapleakcnt:name"), true,
7246 dbev->get_derived_metrics ());
7247 else
7248 nmlist->set_metrics (NTXT ("e.heapallocbytes:e.heapalloccnt:name"), true,
7249 dbev->get_derived_metrics ());
7250 MetricList *mlist = new MetricList (nmlist);
7251 delete nmlist;
7253 CStack_data *lam = dbev->get_cstack_data (mlist);
7254 if (lam == NULL || lam->size () == 0)
7256 delete lam;
7257 delete mlist;
7258 return NULL;
7260 Vector<Vector<Obj>*> *evalue = new Vector<Vector<Obj>*>(lam->size ());
7261 Vector<Vector<Obj>*> *pcstack = new Vector<Vector<Obj>*>(lam->size ());
7262 Vector<Vector<Obj>*> *offstack = new Vector<Vector<Obj>*>(lam->size ());
7263 Vector<Vector<Obj>*> *fpcstack = new Vector<Vector<Obj>*>(lam->size ());
7264 Vector<Vector<Obj>*> *sumval = new Vector<Vector<Obj>*>(lam->size ());
7266 int index;
7267 CStack_data::CStack_item *lae;
7268 Vec_loop (CStack_data::CStack_item*, lam->cstack_items, index, lae)
7270 Vector<Obj> *jivals = NULL;
7271 if (lae != NULL)
7273 jivals = new Vector<Obj>(4);
7274 jivals->store (0, (Obj) (index + 1));
7275 jivals->store (1, (Obj) lae->value[1].ll);
7276 jivals->store (2, (Obj) lae->value[0].ll);
7277 jivals->store (3, (Obj) (leakflag ? 1 : 2));
7279 evalue->store (index, jivals);
7280 int snum = lae->stack->size ();
7281 Vector<Obj> *jivals1 = new Vector<Obj>(snum);
7282 Vector<Obj> *jivals2 = new Vector<Obj>(snum);
7283 Vector<Obj> *jivals3 = new Vector<Obj>(snum);
7284 if (lae->stack != NULL)
7286 for (int i = lae->stack->size () - 1; i >= 0; i--)
7288 DbeInstr *instr = lae->stack->fetch (i);
7289 jivals1->store (i, (Obj) instr);
7290 jivals2->store (i, (Obj) instr->func);
7291 jivals3->store (i, (Obj) instr->addr);
7294 fpcstack->store (index, jivals1);
7295 pcstack->store (index, jivals2);
7296 offstack->store (index, jivals3);
7297 lae++;
7299 Vector<Obj> *jivals4 = new Vector<Obj>(3);
7300 jivals4->store (0, (Obj) lam->size ());
7301 jivals4->store (1, (Obj) lam->total->value[1].ll);
7302 jivals4->store (2, (Obj) lam->total->value[0].ll);
7303 sumval->store (0, jivals4);
7304 delete lam;
7305 delete mlist;
7306 Vector<void*> *earray = new Vector<void*>(5);
7307 earray->store (0, evalue);
7308 earray->store (1, pcstack);
7309 earray->store (2, offstack);
7310 earray->store (3, fpcstack);
7311 earray->store (4, sumval);
7312 return earray;
7315 // Map timeline address to function instr
7318 dbeGetObject (int dbevindex, Obj sel_func, Obj sel_pc)
7320 DbeView *dbev = dbeSession->getView (dbevindex);
7321 if (dbev == NULL)
7322 abort ();
7323 if (sel_pc)
7324 return sel_pc;
7325 return sel_func;
7328 char *
7329 dbeGetName (int /*dbevindex*/, int exp_id)
7330 // This function's name is not descriptive enough - it returns a string
7331 // containing the full experiment name with path, process name, and PID.
7332 // There are various dbe functions that provide experiment name and experiment
7333 // details, and they should probably be consolidated/refactored. (TBR)
7334 // For another example of similar output formatting, see dbeGetExpName().
7336 int id = (exp_id < 0) ? 0 : exp_id;
7337 Experiment *exp = dbeSession->get_exp (id);
7338 if (exp == NULL)
7339 return NULL;
7340 char *buf =
7341 dbe_sprintf (NTXT ("%s [%s, PID %d]"),
7342 exp->get_expt_name (),
7343 exp->utargname != NULL ? exp->utargname : GTXT ("(unknown)"),
7344 exp->getPID ());
7345 return buf;
7348 Vector<char*> *
7349 dbeGetExpVerboseName (Vector<int> *exp_ids)
7351 int len = exp_ids->size ();
7352 Vector<char*> *list = new Vector<char*>(len);
7353 for (int i = 0; i < len; i++)
7355 char * verboseName = dbeGetName (0, exp_ids->fetch (i)); // no strdup()
7356 list->store (i, verboseName);
7358 return list;
7361 long long
7362 dbeGetStartTime (int /*dbevindex*/, int exp_id)
7364 int id = (exp_id < 0) ? 0 : exp_id;
7365 Experiment *exp = dbeSession->get_exp (id);
7366 return exp ? exp->getStartTime () : (long long) 0;
7369 long long
7370 dbeGetRelativeStartTime (int /*dbevindex*/, int exp_id)
7372 int id = (exp_id < 0) ? 0 : exp_id;
7373 Experiment *exp = dbeSession->get_exp (id);
7374 return exp ? exp->getRelativeStartTime () : (long long) 0;
7377 long long
7378 dbeGetEndTime (int /*dbevindex*/, int exp_id)
7380 int id = (exp_id < 0) ? 0 : exp_id;
7381 Experiment *exp = dbeSession->get_exp (id);
7383 // Experiment::getEndTime was initially implemented as
7384 // returning exp->last_event. To preserve the semantics
7385 // new Experiment::getLastEvent() is used here.
7386 return exp ? exp->getLastEvent () : (long long) 0;
7390 dbeGetClock (int /*dbevindex*/, int exp_id)
7392 return dbeSession->get_clock (exp_id);
7395 long long
7396 dbeGetWallStartSec (int /*dbevindex*/, int exp_id)
7398 int id = (exp_id < 0) ? 0 : exp_id;
7399 Experiment *exp = dbeSession->get_exp (id);
7400 return exp ? exp->getWallStartSec () : 0ll;
7403 char *
7404 dbeGetHostname (int /*dbevindex*/, int exp_id)
7406 int id = (exp_id < 0) ? 0 : exp_id;
7407 Experiment *exp = dbeSession->get_exp (id);
7408 return exp ? dbe_strdup (exp->hostname) : NULL;
7411 static DataView *
7412 getTimelinePackets (int dbevindex, int exp_id, int data_id, int entity_prop_id)
7414 DbeView *dbev = dbeSession->getView (dbevindex);
7415 if (dbev == NULL)
7416 abort ();
7417 const int sortprop_count = 3;
7418 const int sortprops[sortprop_count] = {
7419 PROP_HWCTAG, // aux
7420 entity_prop_id,
7421 PROP_TSTAMP
7423 DataView *packets = dbev->get_filtered_events (exp_id, data_id,
7424 sortprops, sortprop_count);
7425 return packets;
7428 static long
7429 getIdxByVals (DataView * packets, int aux, int entity_prop_val,
7430 uint64_t time, DataView::Relation rel)
7432 const int sortprop_count = 3;
7433 Datum tval[sortprop_count];
7434 tval[0].setUINT32 (aux);
7435 tval[1].setUINT32 (entity_prop_val); //CPUID, LWPID, THRID are downsized to 32
7436 tval[2].setUINT64 (time);
7437 long idx = packets->getIdxByVals (tval, rel);
7438 return idx;
7441 static bool
7442 isValidIdx (DataView * packets, int entity_prop_id,
7443 int aux, int entity_prop_val, long idx)
7445 if (idx < 0 || idx >= packets->getSize ())
7446 return false;
7447 int pkt_aux = packets->getIntValue (PROP_HWCTAG, idx);
7448 if (pkt_aux != aux)
7449 return false;
7450 if (entity_prop_id == PROP_EXPID)
7451 return true; // not a packet property; we know the packet is in this experiment
7452 if (entity_prop_id == PROP_NONE)
7453 return true; // not a packet property; we know the packet is in this experiment
7454 int pkt_ent = packets->getIntValue (entity_prop_id, idx);
7455 if (pkt_ent != entity_prop_val)
7456 return false;
7457 return true;
7460 static bool
7461 hasInvisbleTLEvents (Experiment *exp, VMode view_mode)
7463 if (exp->has_java && view_mode == VMODE_USER)
7464 return true;
7465 return false;
7468 static bool
7469 isVisibleTLEvent (Experiment *exp, VMode view_mode, DataView* packets, long idx)
7471 if (hasInvisbleTLEvents (exp, view_mode))
7473 JThread *jthread = (JThread*) packets->getObjValue (PROP_JTHREAD, idx);
7474 if (jthread == JTHREAD_NONE || (jthread != NULL && jthread->is_system ()))
7475 return false;
7477 return true;
7480 static long
7481 getTLVisibleIdxByStepping (Experiment *exp, VMode view_mode, int entity_prop_id,
7482 DataView * packets, int aux, int entity_prop_val,
7483 long idx, long move_count, int direction)
7485 assert (move_count >= 0);
7486 assert (direction == 1 || direction == -1 || direction == 0);
7487 if (direction == 0 /* precise hit required */)
7488 move_count = 0;
7491 if (!isValidIdx (packets, entity_prop_id, aux, entity_prop_val, idx))
7492 return -1;
7493 if (isVisibleTLEvent (exp, view_mode, packets, idx))
7495 if (move_count <= 0)
7496 break;
7497 move_count--;
7499 if (direction == 0)
7500 return -1;
7501 idx += direction;
7503 while (1);
7504 return idx;
7507 static long
7508 getTLVisibleIdxByVals (Experiment *exp, VMode view_mode, int entity_prop_id,
7509 DataView * packets,
7510 int aux, int entity_prop_val, uint64_t time, DataView::Relation rel)
7512 long idx = getIdxByVals (packets, aux, entity_prop_val, time, rel);
7513 if (!hasInvisbleTLEvents (exp, view_mode))
7514 return idx;
7515 if (idx < 0)
7516 return idx;
7517 if (rel == DataView::REL_EQ)
7518 return -1; // would require bi-directional search... not supported for now
7519 int direction = (rel == DataView::REL_LT || rel == DataView::REL_LTEQ) ? -1 : 1;
7520 idx = getTLVisibleIdxByStepping (exp, view_mode, entity_prop_id, packets,
7521 aux, entity_prop_val,
7522 idx, 0 /* first match */, direction);
7523 return idx;
7526 // In thread mode, the entity name for non Java thread should be the 1st func
7527 // from the current thread's stack. See #4961315
7528 static char*
7529 getThreadRootFuncName (int, int, int, int, VMode)
7531 return NULL; // until we figure out what we want to show... YXXX
7534 Vector<void*> *
7535 dbeGetEntityProps (int dbevindex) //YXXX TBD, should this be exp-specific?
7537 DbeView *dbev = dbeSession->getView (dbevindex);
7538 if (dbev == NULL)
7539 abort ();
7540 Vector<int> *prop_id = new Vector<int>();
7541 Vector<char*> *prop_name = new Vector<char*>();
7542 Vector<char*> *prop_uname = new Vector<char*>();
7543 Vector<char*> *prop_cname = new Vector<char*>(); //must match TLModeCmd vals!
7545 prop_id->append (PROP_NONE);
7546 prop_name->append (dbe_strdup (GTXT ("NONE")));
7547 prop_uname->append (dbe_strdup (GTXT ("Unknown")));
7548 prop_cname->append (dbe_strdup (NTXT ("unknown")));
7550 prop_id->append (PROP_LWPID);
7551 prop_name->append (dbe_strdup (GTXT ("LWPID")));
7552 prop_uname->append (dbe_strdup (GTXT ("LWP")));
7553 prop_cname->append (dbe_strdup (NTXT ("lwp")));
7555 prop_id->append (PROP_THRID);
7556 prop_name->append (dbe_strdup (GTXT ("THRID")));
7557 prop_uname->append (dbe_strdup (GTXT ("Thread")));
7558 prop_cname->append (dbe_strdup (NTXT ("thread")));
7560 prop_id->append (PROP_CPUID);
7561 prop_name->append (dbe_strdup (GTXT ("CPUID")));
7562 prop_uname->append (dbe_strdup (GTXT ("CPU")));
7563 prop_cname->append (dbe_strdup (NTXT ("cpu")));
7565 prop_id->append (PROP_EXPID);
7566 prop_name->append (dbe_strdup (GTXT ("EXPID")));
7567 prop_uname->append (dbe_strdup (GTXT ("Process"))); // placeholder...
7568 // ...until we finalize how to expose user-level Experiments, descendents
7569 prop_cname->append (dbe_strdup (NTXT ("experiment")));
7570 Vector<void*> *darray = new Vector<void*>();
7571 darray->store (0, prop_id);
7572 darray->store (1, prop_name);
7573 darray->store (2, prop_uname);
7574 darray->store (3, prop_cname);
7575 return darray;
7578 Vector<void*> *
7579 dbeGetEntities (int dbevindex, int exp_id, int entity_prop_id)
7581 DbeView *dbev = dbeSession->getView (dbevindex);
7582 if (dbev == NULL)
7583 abort ();
7584 Experiment *exp = dbeSession->get_exp (exp_id);
7585 if (exp == NULL)
7586 return NULL;
7588 // Recognize and skip faketime experiments
7589 if (exp->timelineavail == false)
7590 return NULL;
7591 Vector<Histable*> *tagObjs = exp->getTagObjs ((Prop_type) entity_prop_id);
7592 int total_nelem;
7593 if (tagObjs)
7594 total_nelem = (int) tagObjs->size ();
7595 else
7596 total_nelem = 0;
7597 const VMode view_mode = dbev->get_view_mode ();
7598 bool show_java_threadnames = (entity_prop_id == PROP_THRID &&
7599 view_mode != VMODE_MACHINE);
7600 // allocate the structures for the return
7601 Vector<int> *entity_prop_vals = new Vector<int>();
7602 Vector<char*> *jthr_names = new Vector<char*>();
7603 Vector<char*> *jthr_g_names = new Vector<char*>();
7604 Vector<char*> *jthr_p_names = new Vector<char*>();
7606 // now walk the tagObjs from the experiment, and check for filtering
7607 for (int tagObjsIdx = 0; tagObjsIdx < total_nelem; tagObjsIdx++)
7609 int entity_prop_val = (int) ((Other *) tagObjs->fetch (tagObjsIdx))->tag;
7610 entity_prop_vals->append (entity_prop_val);
7611 char *jname, *jgname, *jpname;
7612 JThread *jthread = NULL;
7613 bool has_java_threadnames = false;
7614 if (show_java_threadnames)
7616 jthread = exp->get_jthread (entity_prop_val);
7617 has_java_threadnames = (jthread != JTHREAD_DEFAULT
7618 && jthread != JTHREAD_NONE);
7620 if (!has_java_threadnames)
7622 jname = jgname = jpname = NULL;
7623 if (entity_prop_id == PROP_THRID || entity_prop_id == PROP_LWPID)
7624 // if non Java thread, set thread name to the 1st func
7625 // from the current thread's stack. see #4961315
7626 jname = getThreadRootFuncName (dbevindex, exp_id, entity_prop_id,
7627 entity_prop_val, view_mode);
7629 else
7631 jname = dbe_strdup (jthread->name);
7632 jgname = dbe_strdup (jthread->group_name);
7633 jpname = dbe_strdup (jthread->parent_name);
7635 jthr_names->append (jname);
7636 jthr_g_names->append (jgname);
7637 jthr_p_names->append (jpname);
7639 Vector<char*> *entity_prop_name_v = new Vector<char*>();
7640 char* entity_prop_name = dbeSession->getPropName (entity_prop_id);
7641 entity_prop_name_v->append (entity_prop_name);
7642 Vector<void*> *darray = new Vector<void*>(5);
7643 darray->store (0, entity_prop_vals);
7644 darray->store (1, jthr_names);
7645 darray->store (2, jthr_g_names);
7646 darray->store (3, jthr_p_names);
7647 darray->store (4, entity_prop_name_v); // vector only has 1 element
7648 return darray;
7651 // TBR: dbeGetEntities() can be set to private now that we have dbeGetEntitiesV2()
7652 Vector<void*> *
7653 dbeGetEntitiesV2 (int dbevindex, Vector<int> *exp_ids, int entity_prop_id)
7655 int sz = exp_ids->size ();
7656 Vector<void*> *res = new Vector<void*>(sz);
7657 for (int ii = 0; ii < sz; ii++)
7659 int expIdx = exp_ids->fetch (ii);
7660 Vector<void*>* ents = dbeGetEntities (dbevindex, expIdx, entity_prop_id);
7661 res->store (ii, ents);
7663 return res;
7666 //YXXX old-tl packets still used for details
7667 static Vector<void*> *
7668 getTLDetailValues (int dbevindex, Experiment * exp, int data_id,
7669 VMode view_mode, DataView *packets, long idx)
7671 Vector<long long> *value = new Vector<long long>(15);
7672 long i = idx;
7673 if (data_id == DATA_SAMPLE || data_id == DATA_GCEVENT)
7675 //YXXX DATA_SAMPLE not handled but could be.
7677 Obj stack = (unsigned long) getStack (view_mode, packets, i);
7678 Vector<Obj> *funcs = stack ? dbeGetStackFunctions (dbevindex, stack) : NULL;
7679 Function *func = (Function*)
7680 getStackPC (0, view_mode, packets, i)->convertto (Histable::FUNCTION);
7681 // Fill common data
7682 value->store (0, packets->getIntValue (PROP_LWPID, i));
7683 value->store (1, packets->getIntValue (PROP_THRID, i));
7684 value->store (2, packets->getIntValue (PROP_CPUID, i));
7685 value->store (3, packets->getLongValue (PROP_TSTAMP, i));
7686 value->store (4, (unsigned long) stack);
7687 value->store (5, (unsigned long) func);
7689 // Fill specific data
7690 switch (data_id)
7692 case DATA_CLOCK:
7693 value->store (6, packets->getIntValue (PROP_MSTATE, i));
7695 hrtime_t interval = exp->get_params ()->ptimer_usec * 1000LL // nanoseconds
7696 * packets->getLongValue (PROP_NTICK, i);
7697 value->store (7, interval);
7699 value->store (8, packets->getIntValue (PROP_OMPSTATE, i));
7700 value->store (9, packets->getLongValue (PROP_EVT_TIME, i)); // visual duration
7701 break;
7702 case DATA_SYNCH:
7703 value->store (6, packets->getLongValue (PROP_EVT_TIME, i));
7704 value->store (7, packets->getLongValue (PROP_SOBJ, i));
7705 break;
7706 case DATA_HWC:
7707 value->store (6, packets->getLongValue (PROP_HWCINT, i));
7708 value->store (7, packets->getLongValue (PROP_VADDR, i)); // data vaddr
7709 value->store (8, packets->getLongValue (PROP_PADDR, i)); // data paddr
7710 value->store (9, packets->getLongValue (PROP_VIRTPC, i)); // pc paddr
7711 value->store (10, packets->getLongValue (PROP_PHYSPC, i)); // pc vaddr
7712 break;
7713 case DATA_RACE:
7714 value->store (6, packets->getIntValue (PROP_RTYPE, i));
7715 value->store (7, packets->getIntValue (PROP_RID, i));
7716 value->store (8, packets->getLongValue (PROP_RVADDR, i));
7717 break;
7718 case DATA_DLCK:
7719 value->store (6, packets->getIntValue (PROP_DTYPE, i));
7720 value->store (7, packets->getIntValue (PROP_DLTYPE, i));
7721 value->store (8, packets->getIntValue (PROP_DID, i));
7722 value->store (9, packets->getLongValue (PROP_DVADDR, i));
7723 break;
7724 case DATA_HEAP:
7725 case DATA_HEAPSZ:
7726 value->store (6, packets->getIntValue (PROP_HTYPE, i));
7727 value->store (7, packets->getLongValue (PROP_HSIZE, i));
7728 value->store (8, packets->getLongValue (PROP_HVADDR, i));
7729 value->store (9, packets->getLongValue (PROP_HOVADDR, i));
7730 value->store (10, packets->getLongValue (PROP_HLEAKED, i));
7731 value->store (11, packets->getLongValue (PROP_HFREED, i));
7732 value->store (12, packets->getLongValue (PROP_HCUR_ALLOCS, i)); // signed int64_t
7733 value->store (13, packets->getLongValue (PROP_HCUR_LEAKS, i));
7734 break;
7735 case DATA_IOTRACE:
7736 value->store (6, packets->getIntValue (PROP_IOTYPE, i));
7737 value->store (7, packets->getIntValue (PROP_IOFD, i));
7738 value->store (8, packets->getLongValue (PROP_IONBYTE, i));
7739 value->store (9, packets->getLongValue (PROP_EVT_TIME, i));
7740 value->store (10, packets->getIntValue (PROP_IOVFD, i));
7741 break;
7743 Vector<void*> *result = new Vector<void*>(5);
7744 result->store (0, value);
7745 result->store (1, funcs); // Histable::Function*
7746 result->store (2, funcs ? dbeGetFuncNames (dbevindex, funcs) : 0); // formatted func names
7747 result->store (3, stack ? dbeGetStackPCs (dbevindex, stack) : 0); // Histable::DbeInstr*
7748 result->store (4, stack ? dbeGetStackNames (dbevindex, stack) : 0); // formatted pc names
7749 return result;
7752 Vector<void*> *
7753 dbeGetTLDetails (int dbevindex, int exp_id, int data_id,
7754 int entity_prop_id, Obj event_id)
7756 DbeView *dbev = dbeSession->getView (dbevindex);
7757 if (dbev == NULL)
7758 abort ();
7759 Experiment *exp = dbeSession->get_exp (exp_id < 0 ? 0 : exp_id);
7760 if (exp == NULL)
7761 return NULL;
7762 DataView *packets =
7763 getTimelinePackets (dbevindex, exp_id, data_id, entity_prop_id);
7764 if (!packets)
7765 return NULL;
7767 VMode view_mode = dbev->get_view_mode ();
7768 long idx = (long) event_id;
7769 Vector<void*> *values = getTLDetailValues (dbevindex, exp, data_id, view_mode, packets, idx);
7770 return values;
7773 Vector<Obj> *
7774 dbeGetStackFunctions (int dbevindex, Obj stack)
7776 Vector<Obj> *instrs = dbeGetStackPCs (dbevindex, stack);
7777 if (instrs == NULL)
7778 return NULL;
7779 int stsize = instrs->size ();
7780 Vector<Obj> *jivals = new Vector<Obj>(stsize);
7781 for (int i = 0; i < stsize; i++)
7783 Histable *obj = (Histable*) instrs->fetch (i);
7784 // if ( obj->get_type() != Histable::LINE ) {//YXXX what is this?
7785 // Remove the above check: why not do this conversion for lines -
7786 // otherwise filtering in timeline by function stack in omp user mode is broken
7787 obj = obj->convertto (Histable::FUNCTION);
7788 jivals->store (i, (Obj) obj);
7790 delete instrs;
7791 return jivals;
7794 Vector<void*> *
7795 dbeGetStacksFunctions (int dbevindex, Vector<Obj> *stacks)
7797 long sz = stacks->size ();
7798 Vector<void*> *res = new Vector<void*>(sz);
7799 for (int ii = 0; ii < sz; ii++)
7801 Obj stack = stacks->fetch (ii);
7802 Vector<Obj> *jivals = dbeGetStackFunctions (dbevindex, stack);
7803 res->store (ii, jivals);
7805 return res;
7808 Vector<Obj> *
7809 dbeGetStackPCs (int dbevindex, Obj stack)
7811 DbeView *dbev = dbeSession->getView (dbevindex);
7812 if (dbev == NULL)
7813 abort ();
7814 if (stack == 0)
7815 return NULL;
7817 bool show_all = dbev->isShowAll ();
7818 Vector<Histable*> *instrs = CallStack::getStackPCs ((void *) stack, !show_all);
7819 int stsize = instrs->size ();
7820 int istart = 0;
7821 bool showAll = dbev->isShowAll ();
7822 for (int i = 0; i < stsize - 1; i++)
7824 Function *func = (Function*) instrs->fetch (i)->convertto (Histable::FUNCTION);
7825 int ix = func->module->loadobject->seg_idx;
7826 if (showAll && dbev->get_lo_expand (ix) == LIBEX_API)
7827 // truncate stack here: LIBRARY_VISIBILITY if we are using API only but no hide
7828 istart = i;
7830 stsize = stsize - istart;
7831 Vector<Obj> *jlvals = new Vector<Obj>(stsize);
7832 for (int i = 0; i < stsize; i++)
7834 Histable *instr = instrs->fetch (i + istart);
7835 jlvals->store (i, (Obj) instr);
7837 delete instrs;
7838 return jlvals;
7841 Vector<char*> *
7842 dbeGetStackNames (int dbevindex, Obj stack)
7844 DbeView *dbev = dbeSession->getView (dbevindex);
7845 Vector<Obj> *instrs = dbeGetStackPCs (dbevindex, stack);
7846 if (instrs == NULL)
7847 return NULL;
7848 int stsize = instrs->size ();
7849 Vector<char*> *list = new Vector<char*>(stsize);
7850 bool showAll = dbev->isShowAll ();
7851 for (int i = 0; i < stsize; i++)
7853 Histable* instr = (Histable*) instrs->fetch (i);
7854 if (!showAll)
7856 // LIBRARY_VISIBILITY
7857 Function *func = (Function*) instr->convertto (Histable::FUNCTION);
7858 LoadObject *lo = ((Function*) func)->module->loadobject;
7859 if (dbev->get_lo_expand (lo->seg_idx) == LIBEX_HIDE)
7861 list->store (i, dbe_strdup (lo->get_name ()));
7862 continue;
7865 list->store (i, dbe_strdup (instr->get_name (dbev->get_name_format ())));
7867 delete instrs;
7868 return list;
7871 Vector<void*> *
7872 dbeGetSamples (int dbevindex, int exp_id, int64_t lo_idx, int64_t hi_idx)
7874 DataView * packets =
7875 getTimelinePackets (dbevindex, exp_id, DATA_SAMPLE, PROP_EXPID);
7876 if (packets == NULL || packets->getSize () == 0)
7877 return NULL;
7878 long lo;
7879 if (lo_idx < 0)
7880 lo = 0;
7881 else
7882 lo = (long) lo_idx;
7884 long long max = packets->getSize () - 1;
7885 long hi;
7886 if (hi_idx < 0 || hi_idx > max)
7887 hi = (long) max;
7888 else
7889 hi = (long) hi_idx;
7891 Vector<Vector<long long>*> *sarray = new Vector<Vector<long long>*>;
7892 Vector<long long>* starts = new Vector<long long>;
7893 Vector<long long>* ends = new Vector<long long>;
7894 Vector<long long>* rtimes = new Vector<long long>;
7895 Vector<char*> *startNames = new Vector<char*>;
7896 Vector<char*> *endNames = new Vector<char*>;
7897 Vector<int> *sampId = new Vector<int>;
7899 for (long index = lo; index <= hi; index++)
7901 Sample *sample = (Sample*) packets->getObjValue (PROP_SMPLOBJ, index);
7902 PrUsage *prusage = sample->get_usage ();
7903 if (prusage == NULL)
7904 prusage = new PrUsage;
7905 Vector<long long> *states = prusage->getMstateValues ();
7906 sarray->append (states);
7907 starts->append (sample->get_start_time ());
7908 ends->append (sample->get_end_time ());
7909 rtimes->append (prusage->pr_rtime);
7910 startNames->append (dbe_strdup (sample->get_start_label ()));
7911 endNames->append (dbe_strdup (sample->get_end_label ()));
7912 sampId->append (sample->get_number ());
7914 Vector<void *> *res = new Vector<void*>(6);
7915 res->store (0, sarray);
7916 res->store (1, starts);
7917 res->store (2, ends);
7918 res->store (3, rtimes);
7919 res->store (4, startNames);
7920 res->store (5, endNames);
7921 res->store (6, sampId);
7922 return res;
7925 Vector<void*> *
7926 dbeGetGCEvents (int dbevindex, int exp_id, int64_t lo_idx, int64_t hi_idx)
7928 DataView *packets =
7929 getTimelinePackets (dbevindex, exp_id, DATA_GCEVENT, PROP_EXPID);
7930 if (packets == NULL || packets->getSize () == 0)
7931 return NULL;
7933 long lo;
7934 if (lo_idx < 0)
7935 lo = 0;
7936 else
7937 lo = (long) lo_idx;
7938 long long max = packets->getSize () - 1;
7939 long hi;
7940 if (hi_idx < 0 || hi_idx > max)
7941 hi = (long) max;
7942 else
7943 hi = (long) hi_idx;
7945 Vector<long long>* starts = new Vector<long long>;
7946 Vector<long long>* ends = new Vector<long long>;
7947 Vector<int> *eventId = new Vector<int>;
7948 for (long index = lo; index <= hi; index++)
7950 GCEvent *gcevent = (GCEvent*) packets->getObjValue (PROP_GCEVENTOBJ, index);
7951 if (gcevent)
7953 starts->append (gcevent->start);
7954 ends->append (gcevent->end);
7955 eventId->append (gcevent->id);
7958 Vector<void *> *res = new Vector<void*>(3);
7959 res->store (0, starts);
7960 res->store (1, ends);
7961 res->store (2, eventId);
7962 return res;
7965 Vector<Vector<char*>*>*
7966 dbeGetIOStatistics (int dbevindex)
7968 DbeView *dbev = dbeSession->getView (dbevindex);
7969 Hist_data *hist_data;
7970 Hist_data::HistItem *hi;
7971 FileData *fDataTotal;
7973 hist_data = dbev->iofile_data;
7974 if (hist_data == NULL)
7975 return NULL;
7976 hi = hist_data->fetch (0);
7977 fDataTotal = (FileData*) hi->obj;
7979 Vector<char*> *writeStat = new Vector<char*>;
7980 Vector<char*> *readStat = new Vector<char*>;
7981 Vector<char*> *otherStat = new Vector<char*>;
7982 Vector<char*> *errorStat = new Vector<char*>;
7984 writeStat->append (dbe_strdup (GTXT ("Write Statistics")));
7985 readStat->append (dbe_strdup (GTXT ("Read Statistics")));
7986 otherStat->append (dbe_strdup (GTXT ("Other I/O Statistics")));
7987 errorStat->append (dbe_strdup (GTXT ("I/O Error Statistics")));
7989 StringBuilder sb;
7990 if (fDataTotal->getWriteCnt () > 0)
7992 if (fDataTotal->getW0KB1KBCnt () > 0)
7994 sb.sprintf (GTXT ("0KB - 1KB"));
7995 writeStat->append (sb.toString ());
7996 sb.sprintf (NTXT ("%d"), fDataTotal->getW0KB1KBCnt ());
7997 writeStat->append (sb.toString ());
7999 if (fDataTotal->getW1KB8KBCnt () > 0)
8001 sb.sprintf (GTXT ("1KB - 8KB"));
8002 writeStat->append (sb.toString ());
8003 sb.sprintf (NTXT ("%d"), fDataTotal->getW1KB8KBCnt ());
8004 writeStat->append (sb.toString ());
8006 if (fDataTotal->getW8KB32KBCnt () > 0)
8008 sb.sprintf (GTXT ("8KB - 32KB"));
8009 writeStat->append (sb.toString ());
8010 sb.sprintf (NTXT ("%d"), fDataTotal->getW8KB32KBCnt ());
8011 writeStat->append (sb.toString ());
8013 if (fDataTotal->getW32KB128KBCnt () > 0)
8015 sb.sprintf (GTXT ("32KB - 128KB"));
8016 writeStat->append (sb.toString ());
8017 sb.sprintf (NTXT ("%d"), fDataTotal->getW32KB128KBCnt ());
8018 writeStat->append (sb.toString ());
8020 if (fDataTotal->getW128KB256KBCnt () > 0)
8022 sb.sprintf (GTXT ("128KB - 256KB"));
8023 writeStat->append (sb.toString ());
8024 sb.sprintf (NTXT ("%d"), fDataTotal->getW128KB256KBCnt ());
8025 writeStat->append (sb.toString ());
8027 if (fDataTotal->getW256KB512KBCnt () > 0)
8029 sb.sprintf (GTXT ("256KB - 512KB"));
8030 writeStat->append (sb.toString ());
8031 sb.sprintf (NTXT ("%d"), fDataTotal->getW256KB512KBCnt ());
8032 writeStat->append (sb.toString ());
8034 if (fDataTotal->getW512KB1000KBCnt () > 0)
8036 sb.sprintf (GTXT ("512KB - 1000KB"));
8037 writeStat->append (sb.toString ());
8038 sb.sprintf (NTXT ("%d"), fDataTotal->getW512KB1000KBCnt ());
8039 writeStat->append (sb.toString ());
8041 if (fDataTotal->getW1000KB10MBCnt () > 0)
8043 sb.sprintf (GTXT ("1000KB - 10MB"));
8044 writeStat->append (sb.toString ());
8045 sb.sprintf (NTXT ("%d"), fDataTotal->getW1000KB10MBCnt ());
8046 writeStat->append (sb.toString ());
8048 if (fDataTotal->getW10MB100MBCnt () > 0)
8050 sb.sprintf (GTXT ("10MB - 100MB"));
8051 writeStat->append (sb.toString ());
8052 sb.sprintf (NTXT ("%d"), fDataTotal->getW10MB100MBCnt ());
8053 writeStat->append (sb.toString ());
8055 if (fDataTotal->getW100MB1GBCnt () > 0)
8057 sb.sprintf (GTXT ("100MB - 1GB"));
8058 writeStat->append (sb.toString ());
8059 sb.sprintf (NTXT ("%d"), fDataTotal->getW100MB1GBCnt ());
8060 writeStat->append (sb.toString ());
8062 if (fDataTotal->getW1GB10GBCnt () > 0)
8064 sb.sprintf (GTXT ("1GB - 10GB"));
8065 writeStat->append (sb.toString ());
8066 sb.sprintf (NTXT ("%d"), fDataTotal->getW1GB10GBCnt ());
8067 writeStat->append (sb.toString ());
8069 if (fDataTotal->getW10GB100GBCnt () > 0)
8071 sb.sprintf (GTXT ("10GB - 100GB"));
8072 writeStat->append (sb.toString ());
8073 sb.sprintf (NTXT ("%d"), fDataTotal->getW10GB100GBCnt ());
8074 writeStat->append (sb.toString ());
8076 if (fDataTotal->getW100GB1TBCnt () > 0)
8078 sb.sprintf (GTXT ("100GB - 1TB"));
8079 writeStat->append (sb.toString ());
8080 sb.sprintf (NTXT ("%d"), fDataTotal->getW100GB1TBCnt ());
8081 writeStat->append (sb.toString ());
8083 if (fDataTotal->getW1TB10TBCnt () > 0)
8085 sb.sprintf (GTXT ("1TB - 10TB"));
8086 writeStat->append (sb.toString ());
8087 sb.sprintf (NTXT ("%d"), fDataTotal->getW1TB10TBCnt ());
8088 writeStat->append (sb.toString ());
8091 sb.sprintf (GTXT ("Longest write"));
8092 writeStat->append (sb.toString ());
8093 sb.sprintf (NTXT ("%.6f (secs.)"),
8094 (double) (fDataTotal->getWSlowestBytes () / (double) NANOSEC));
8095 writeStat->append (sb.toString ());
8097 sb.sprintf (GTXT ("Smallest write bytes"));
8098 writeStat->append (sb.toString ());
8099 sb.sprintf (NTXT ("%d"), (int) (fDataTotal->getWSmallestBytes ()));
8100 writeStat->append (sb.toString ());
8102 sb.sprintf (GTXT ("Largest write bytes"));
8103 writeStat->append (sb.toString ());
8104 sb.sprintf (NTXT ("%d"), (int) (fDataTotal->getWLargestBytes ()));
8105 writeStat->append (sb.toString ());
8107 sb.sprintf (GTXT ("Total time"));
8108 writeStat->append (sb.toString ());
8109 sb.sprintf (NTXT ("%.6f (secs.)"),
8110 (double) (fDataTotal->getWriteTime () / (double) NANOSEC));
8111 writeStat->append (sb.toString ());
8113 sb.sprintf (GTXT ("Total calls"));
8114 writeStat->append (sb.toString ());
8115 sb.sprintf (NTXT ("%d"), (int) (fDataTotal->getWriteCnt ()));
8116 writeStat->append (sb.toString ());
8118 sb.sprintf (GTXT ("Total bytes"));
8119 writeStat->append (sb.toString ());
8120 sb.sprintf (NTXT ("%lld"), (long long) (fDataTotal->getWriteBytes ()));
8121 writeStat->append (sb.toString ());
8124 if (fDataTotal->getReadCnt () > 0)
8126 if (fDataTotal->getR0KB1KBCnt () > 0)
8128 sb.sprintf (GTXT ("0KB - 1KB"));
8129 readStat->append (sb.toString ());
8130 sb.sprintf (NTXT ("%d"), fDataTotal->getR0KB1KBCnt ());
8131 readStat->append (sb.toString ());
8133 if (fDataTotal->getR1KB8KBCnt () > 0)
8135 sb.sprintf (GTXT ("1KB - 8KB"));
8136 readStat->append (sb.toString ());
8137 sb.sprintf (NTXT ("%d"), fDataTotal->getR1KB8KBCnt ());
8138 readStat->append (sb.toString ());
8140 if (fDataTotal->getR8KB32KBCnt () > 0)
8142 sb.sprintf (GTXT ("8KB - 32KB"));
8143 readStat->append (sb.toString ());
8144 sb.sprintf (NTXT ("%d"), fDataTotal->getR8KB32KBCnt ());
8145 readStat->append (sb.toString ());
8147 if (fDataTotal->getR32KB128KBCnt () > 0)
8149 sb.sprintf (GTXT ("32KB - 128KB"));
8150 readStat->append (sb.toString ());
8151 sb.sprintf (NTXT ("%d"), fDataTotal->getR32KB128KBCnt ());
8152 readStat->append (sb.toString ());
8154 if (fDataTotal->getR128KB256KBCnt () > 0)
8156 sb.sprintf (GTXT ("128KB - 256KB"));
8157 readStat->append (sb.toString ());
8158 sb.sprintf (NTXT ("%d"), fDataTotal->getR128KB256KBCnt ());
8159 readStat->append (sb.toString ());
8161 if (fDataTotal->getR256KB512KBCnt () > 0)
8163 sb.sprintf (GTXT ("256KB - 512KB"));
8164 readStat->append (sb.toString ());
8165 sb.sprintf (NTXT ("%d"), fDataTotal->getR256KB512KBCnt ());
8166 readStat->append (sb.toString ());
8168 if (fDataTotal->getR512KB1000KBCnt () > 0)
8170 sb.sprintf (GTXT ("512KB - 1000KB"));
8171 readStat->append (sb.toString ());
8172 sb.sprintf (NTXT ("%d"), fDataTotal->getR512KB1000KBCnt ());
8173 readStat->append (sb.toString ());
8175 if (fDataTotal->getR1000KB10MBCnt () > 0)
8177 sb.sprintf (GTXT ("1000KB - 10MB"));
8178 readStat->append (sb.toString ());
8179 sb.sprintf (NTXT ("%d"), fDataTotal->getR1000KB10MBCnt ());
8180 readStat->append (sb.toString ());
8182 if (fDataTotal->getR10MB100MBCnt () > 0)
8184 sb.sprintf (GTXT ("10MB - 100MB"));
8185 readStat->append (sb.toString ());
8186 sb.sprintf (NTXT ("%d"), fDataTotal->getR10MB100MBCnt ());
8187 readStat->append (sb.toString ());
8189 if (fDataTotal->getR100MB1GBCnt () > 0)
8191 sb.sprintf (GTXT ("100MB - 1GB"));
8192 readStat->append (sb.toString ());
8193 sb.sprintf (NTXT ("%d"), fDataTotal->getR100MB1GBCnt ());
8194 readStat->append (sb.toString ());
8196 if (fDataTotal->getR1GB10GBCnt () > 0)
8198 sb.sprintf (GTXT ("1GB - 10GB"));
8199 readStat->append (sb.toString ());
8200 sb.sprintf (NTXT ("%d"), fDataTotal->getR1GB10GBCnt ());
8201 readStat->append (sb.toString ());
8203 if (fDataTotal->getR10GB100GBCnt () > 0)
8205 sb.sprintf (GTXT ("10GB - 100GB"));
8206 readStat->append (sb.toString ());
8207 sb.sprintf (NTXT ("%d"), fDataTotal->getR10GB100GBCnt ());
8208 readStat->append (sb.toString ());
8210 if (fDataTotal->getR100GB1TBCnt () > 0)
8212 sb.sprintf (GTXT ("100GB - 1TB"));
8213 readStat->append (sb.toString ());
8214 sb.sprintf (NTXT ("%d"), fDataTotal->getR100GB1TBCnt ());
8215 readStat->append (sb.toString ());
8217 if (fDataTotal->getR1TB10TBCnt () > 0)
8219 sb.sprintf (GTXT ("1TB - 10TB"));
8220 readStat->append (sb.toString ());
8221 sb.sprintf (NTXT ("%d"), fDataTotal->getR1TB10TBCnt ());
8222 readStat->append (sb.toString ());
8225 sb.sprintf (GTXT ("Longest read"));
8226 readStat->append (sb.toString ());
8227 sb.sprintf (NTXT ("%.6f (secs.)"),
8228 (double) (fDataTotal->getRSlowestBytes () / (double) NANOSEC));
8229 readStat->append (sb.toString ());
8231 sb.sprintf (GTXT ("Smallest read bytes"));
8232 readStat->append (sb.toString ());
8233 sb.sprintf (NTXT ("%d"), (int) (fDataTotal->getRSmallestBytes ()));
8234 readStat->append (sb.toString ());
8236 sb.sprintf (GTXT ("Largest read bytes"));
8237 readStat->append (sb.toString ());
8238 sb.sprintf (NTXT ("%d"), (int) (fDataTotal->getRLargestBytes ()));
8239 readStat->append (sb.toString ());
8241 sb.sprintf (GTXT ("Total time"));
8242 readStat->append (sb.toString ());
8243 sb.sprintf (NTXT ("%.6f (secs.)"),
8244 (double) (fDataTotal->getReadTime () / (double) NANOSEC));
8245 readStat->append (sb.toString ());
8247 sb.sprintf (GTXT ("Total calls"));
8248 readStat->append (sb.toString ());
8249 sb.sprintf (NTXT ("%d"), (int) (fDataTotal->getReadCnt ()));
8250 readStat->append (sb.toString ());
8252 sb.sprintf (GTXT ("Total bytes"));
8253 readStat->append (sb.toString ());
8254 sb.sprintf (NTXT ("%lld"), (long long) (fDataTotal->getReadBytes ()));
8255 readStat->append (sb.toString ());
8258 if (fDataTotal->getOtherCnt () > 0)
8260 sb.sprintf (GTXT ("Total time"));
8261 otherStat->append (sb.toString ());
8262 sb.sprintf (NTXT ("%.6f (secs.)"),
8263 (double) (fDataTotal->getOtherTime () / (double) NANOSEC));
8264 otherStat->append (sb.toString ());
8266 sb.sprintf (GTXT ("Total calls"));
8267 otherStat->append (sb.toString ());
8268 sb.sprintf (NTXT ("%d"), (int) (fDataTotal->getOtherCnt ()));
8269 otherStat->append (sb.toString ());
8272 if (fDataTotal->getErrorCnt () > 0)
8274 sb.sprintf (GTXT ("Total time"));
8275 errorStat->append (sb.toString ());
8276 sb.sprintf (NTXT ("%.6f (secs.)"),
8277 (double) (fDataTotal->getErrorTime () / (double) NANOSEC));
8278 errorStat->append (sb.toString ());
8280 sb.sprintf (GTXT ("Total calls"));
8281 errorStat->append (sb.toString ());
8282 sb.sprintf (NTXT ("%d"), (int) (fDataTotal->getErrorCnt ()));
8283 errorStat->append (sb.toString ());
8285 Vector<Vector<char*>*>* statisticsData = new Vector<Vector<char*>*>(4);
8286 statisticsData->store (0, writeStat);
8287 statisticsData->store (1, readStat);
8288 statisticsData->store (2, otherStat);
8289 statisticsData->store (3, errorStat);
8290 return statisticsData;
8293 Vector<Vector<char*>*>*
8294 dbeGetHeapStatistics (int dbevindex)
8296 DbeView *dbev = dbeSession->getView (dbevindex);
8297 Hist_data *hist_data;
8298 Hist_data::HistItem *hi;
8299 HeapData *hDataTotal;
8300 hist_data = dbev->heapcs_data;
8301 if (hist_data == NULL)
8302 return NULL;
8304 hi = hist_data->fetch (0);
8305 hDataTotal = (HeapData*) hi->obj;
8306 Vector<char*> *memoryUsage = new Vector<char*>;
8307 Vector<char*> *allocStat = new Vector<char*>;
8308 Vector<char*> *leakStat = new Vector<char*>;
8310 memoryUsage->append (dbe_strdup (GTXT ("Process With Highest Peak Memory Usage")));
8311 allocStat->append (dbe_strdup (GTXT ("Memory Allocations Statistics")));
8312 leakStat->append (dbe_strdup (GTXT ("Memory Leaks Statistics")));
8313 StringBuilder sb;
8314 if (hDataTotal->getPeakMemUsage () > 0)
8316 sb.sprintf (GTXT ("Heap size bytes"));
8317 memoryUsage->append (sb.toString ());
8318 sb.sprintf (NTXT ("%lld"), (long long) (hDataTotal->getPeakMemUsage ()));
8319 memoryUsage->append (sb.toString ());
8321 sb.sprintf (GTXT ("Experiment Id"));
8322 memoryUsage->append (sb.toString ());
8323 sb.sprintf (NTXT ("%d"), (int) (hDataTotal->getUserExpId ()));
8324 memoryUsage->append (sb.toString ());
8326 sb.sprintf (GTXT ("Process Id"));
8327 memoryUsage->append (sb.toString ());
8328 sb.sprintf (NTXT ("%d"), (int) (hDataTotal->getPid ()));
8329 memoryUsage->append (sb.toString ());
8331 Vector<hrtime_t> *pTimestamps;
8332 pTimestamps = hDataTotal->getPeakTimestamps ();
8333 if (pTimestamps != NULL)
8335 for (int i = 0; i < pTimestamps->size (); i++)
8337 sb.sprintf (GTXT ("Time of peak"));
8338 memoryUsage->append (sb.toString ());
8339 sb.sprintf (NTXT ("%.3f (secs.)"), (double) (pTimestamps->fetch (i) / (double) NANOSEC));
8340 memoryUsage->append (sb.toString ());
8345 if (hDataTotal->getAllocCnt () > 0)
8347 if (hDataTotal->getA0KB1KBCnt () > 0)
8349 sb.sprintf (GTXT ("0KB - 1KB"));
8350 allocStat->append (sb.toString ());
8351 sb.sprintf (NTXT ("%d"), hDataTotal->getA0KB1KBCnt ());
8352 allocStat->append (sb.toString ());
8354 if (hDataTotal->getA1KB8KBCnt () > 0)
8356 sb.sprintf (GTXT ("1KB - 8KB"));
8357 allocStat->append (sb.toString ());
8358 sb.sprintf (NTXT ("%d"), hDataTotal->getA1KB8KBCnt ());
8359 allocStat->append (sb.toString ());
8361 if (hDataTotal->getA8KB32KBCnt () > 0)
8363 sb.sprintf (GTXT ("8KB - 32KB"));
8364 allocStat->append (sb.toString ());
8365 sb.sprintf (NTXT ("%d"), hDataTotal->getA8KB32KBCnt ());
8366 allocStat->append (sb.toString ());
8368 if (hDataTotal->getA32KB128KBCnt () > 0)
8370 sb.sprintf (GTXT ("32KB - 128KB"));
8371 allocStat->append (sb.toString ());
8372 sb.sprintf (NTXT ("%d"), hDataTotal->getA32KB128KBCnt ());
8373 allocStat->append (sb.toString ());
8375 if (hDataTotal->getA128KB256KBCnt () > 0)
8377 sb.sprintf (GTXT ("128KB - 256KB"));
8378 allocStat->append (sb.toString ());
8379 sb.sprintf (NTXT ("%d"), hDataTotal->getA128KB256KBCnt ());
8380 allocStat->append (sb.toString ());
8382 if (hDataTotal->getA256KB512KBCnt () > 0)
8384 sb.sprintf (GTXT ("256KB - 512KB"));
8385 allocStat->append (sb.toString ());
8386 sb.sprintf (NTXT ("%d"), hDataTotal->getA256KB512KBCnt ());
8387 allocStat->append (sb.toString ());
8389 if (hDataTotal->getA512KB1000KBCnt () > 0)
8391 sb.sprintf (GTXT ("512KB - 1000KB"));
8392 allocStat->append (sb.toString ());
8393 sb.sprintf (NTXT ("%d"), hDataTotal->getA512KB1000KBCnt ());
8394 allocStat->append (sb.toString ());
8396 if (hDataTotal->getA1000KB10MBCnt () > 0)
8398 sb.sprintf (GTXT ("1000KB - 10MB"));
8399 allocStat->append (sb.toString ());
8400 sb.sprintf (NTXT ("%d"), hDataTotal->getA1000KB10MBCnt ());
8401 allocStat->append (sb.toString ());
8403 if (hDataTotal->getA10MB100MBCnt () > 0)
8405 sb.sprintf (GTXT ("10MB - 100MB"));
8406 allocStat->append (sb.toString ());
8407 sb.sprintf (NTXT ("%d"), hDataTotal->getA10MB100MBCnt ());
8408 allocStat->append (sb.toString ());
8410 if (hDataTotal->getA100MB1GBCnt () > 0)
8412 sb.sprintf (GTXT ("100MB - 1GB"));
8413 allocStat->append (sb.toString ());
8414 sb.sprintf (NTXT ("%d"), hDataTotal->getA100MB1GBCnt ());
8415 allocStat->append (sb.toString ());
8417 if (hDataTotal->getA1GB10GBCnt () > 0)
8419 sb.sprintf (GTXT ("1GB - 10GB"));
8420 allocStat->append (sb.toString ());
8421 sb.sprintf (NTXT ("%d"), hDataTotal->getA1GB10GBCnt ());
8422 allocStat->append (sb.toString ());
8424 if (hDataTotal->getA10GB100GBCnt () > 0)
8426 sb.sprintf (GTXT ("10GB - 100GB"));
8427 allocStat->append (sb.toString ());
8428 sb.sprintf (NTXT ("%d"), hDataTotal->getA10GB100GBCnt ());
8429 allocStat->append (sb.toString ());
8431 if (hDataTotal->getA100GB1TBCnt () > 0)
8433 sb.sprintf (GTXT ("100GB - 1TB"));
8434 allocStat->append (sb.toString ());
8435 sb.sprintf (NTXT ("%d"), hDataTotal->getA100GB1TBCnt ());
8436 allocStat->append (sb.toString ());
8438 if (hDataTotal->getA1TB10TBCnt () > 0)
8440 sb.sprintf (GTXT ("1TB - 10TB"));
8441 allocStat->append (sb.toString ());
8442 sb.sprintf (NTXT ("%d"), hDataTotal->getA1TB10TBCnt ());
8443 allocStat->append (sb.toString ());
8446 sb.sprintf (GTXT ("Smallest allocation bytes"));
8447 allocStat->append (sb.toString ());
8448 sb.sprintf (NTXT ("%d"), (int) (hDataTotal->getASmallestBytes ()));
8449 allocStat->append (sb.toString ());
8451 sb.sprintf (GTXT ("Largest allocation bytes"));
8452 allocStat->append (sb.toString ());
8453 sb.sprintf (NTXT ("%d"), (int) (hDataTotal->getALargestBytes ()));
8454 allocStat->append (sb.toString ());
8456 sb.sprintf (GTXT ("Total allocations"));
8457 allocStat->append (sb.toString ());
8458 sb.sprintf (NTXT ("%d"), (int) (hDataTotal->getAllocCnt ()));
8459 allocStat->append (sb.toString ());
8461 sb.sprintf (GTXT ("Total bytes"));
8462 allocStat->append (sb.toString ());
8463 sb.sprintf (NTXT ("%lld"), (long long) (hDataTotal->getAllocBytes ()));
8464 allocStat->append (sb.toString ());
8467 if (hDataTotal->getLeakCnt () > 0)
8469 if (hDataTotal->getL0KB1KBCnt () > 0)
8471 sb.sprintf (GTXT ("0KB - 1KB"));
8472 leakStat->append (sb.toString ());
8473 sb.sprintf (NTXT ("%d"), hDataTotal->getL0KB1KBCnt ());
8474 leakStat->append (sb.toString ());
8476 if (hDataTotal->getL1KB8KBCnt () > 0)
8478 sb.sprintf (GTXT ("1KB - 8KB"));
8479 leakStat->append (sb.toString ());
8480 sb.sprintf (NTXT ("%d"), hDataTotal->getL1KB8KBCnt ());
8481 leakStat->append (sb.toString ());
8483 if (hDataTotal->getL8KB32KBCnt () > 0)
8485 sb.sprintf (GTXT ("8KB - 32KB"));
8486 leakStat->append (sb.toString ());
8487 sb.sprintf (NTXT ("%d"), hDataTotal->getL8KB32KBCnt ());
8488 leakStat->append (sb.toString ());
8490 if (hDataTotal->getL32KB128KBCnt () > 0)
8492 sb.sprintf (GTXT ("32KB - 128KB"));
8493 leakStat->append (sb.toString ());
8494 sb.sprintf (NTXT ("%d"), hDataTotal->getL32KB128KBCnt ());
8495 leakStat->append (sb.toString ());
8497 if (hDataTotal->getL128KB256KBCnt () > 0)
8499 sb.sprintf (GTXT ("128KB - 256KB"));
8500 leakStat->append (sb.toString ());
8501 sb.sprintf (NTXT ("%d"), hDataTotal->getL128KB256KBCnt ());
8502 leakStat->append (sb.toString ());
8504 if (hDataTotal->getL256KB512KBCnt () > 0)
8506 sb.sprintf (GTXT ("256KB - 512KB"));
8507 leakStat->append (sb.toString ());
8508 sb.sprintf (NTXT ("%d"), hDataTotal->getL256KB512KBCnt ());
8509 leakStat->append (sb.toString ());
8511 if (hDataTotal->getL512KB1000KBCnt () > 0)
8513 sb.sprintf (GTXT ("512KB - 1000KB"));
8514 leakStat->append (sb.toString ());
8515 sb.sprintf (NTXT ("%d"), hDataTotal->getL512KB1000KBCnt ());
8516 leakStat->append (sb.toString ());
8518 if (hDataTotal->getL1000KB10MBCnt () > 0)
8520 sb.sprintf (GTXT ("1000KB - 10MB"));
8521 leakStat->append (sb.toString ());
8522 sb.sprintf (NTXT ("%d"), hDataTotal->getL1000KB10MBCnt ());
8523 leakStat->append (sb.toString ());
8525 if (hDataTotal->getL10MB100MBCnt () > 0)
8527 sb.sprintf (GTXT ("10MB - 100MB"));
8528 leakStat->append (sb.toString ());
8529 sb.sprintf (NTXT ("%d"), hDataTotal->getL10MB100MBCnt ());
8530 leakStat->append (sb.toString ());
8532 if (hDataTotal->getL100MB1GBCnt () > 0)
8534 sb.sprintf (GTXT ("100MB - 1GB"));
8535 leakStat->append (sb.toString ());
8536 sb.sprintf (NTXT ("%d"), hDataTotal->getL100MB1GBCnt ());
8537 leakStat->append (sb.toString ());
8539 if (hDataTotal->getL1GB10GBCnt () > 0)
8541 sb.sprintf (GTXT ("1GB - 10GB"));
8542 leakStat->append (sb.toString ());
8543 sb.sprintf (NTXT ("%d"), hDataTotal->getL1GB10GBCnt ());
8544 leakStat->append (sb.toString ());
8546 if (hDataTotal->getL10GB100GBCnt () > 0)
8548 sb.sprintf (GTXT ("10GB - 100GB"));
8549 leakStat->append (sb.toString ());
8550 sb.sprintf (NTXT ("%d"), hDataTotal->getL10GB100GBCnt ());
8551 leakStat->append (sb.toString ());
8553 if (hDataTotal->getL100GB1TBCnt () > 0)
8555 sb.sprintf (GTXT ("100GB - 1TB"));
8556 leakStat->append (sb.toString ());
8557 sb.sprintf (NTXT ("%d"), hDataTotal->getL100GB1TBCnt ());
8558 leakStat->append (sb.toString ());
8560 if (hDataTotal->getL1TB10TBCnt () > 0)
8562 sb.sprintf (GTXT ("1TB - 10TB"));
8563 leakStat->append (sb.toString ());
8564 sb.sprintf (NTXT ("%d"), hDataTotal->getL1TB10TBCnt ());
8565 leakStat->append (sb.toString ());
8568 sb.sprintf (GTXT ("Smallest leaked bytes"));
8569 leakStat->append (sb.toString ());
8570 sb.sprintf (NTXT ("%d"), (int) (hDataTotal->getLSmallestBytes ()));
8571 leakStat->append (sb.toString ());
8573 sb.sprintf (GTXT ("Largest leaked bytes"));
8574 leakStat->append (sb.toString ());
8575 sb.sprintf (NTXT ("%d"), (int) (hDataTotal->getLLargestBytes ()));
8576 leakStat->append (sb.toString ());
8578 sb.sprintf (GTXT ("Total leaked"));
8579 leakStat->append (sb.toString ());
8580 sb.sprintf (NTXT ("%d"), (int) (hDataTotal->getLeakCnt ()));
8581 leakStat->append (sb.toString ());
8583 sb.sprintf (GTXT ("Total bytes"));
8584 leakStat->append (sb.toString ());
8585 sb.sprintf (NTXT ("%lld"), (long long) (hDataTotal->getLeakBytes ()));
8586 leakStat->append (sb.toString ());
8588 Vector<Vector<char*>*>* statisticsData = new Vector<Vector<char*>*>(3);
8589 statisticsData->store (0, memoryUsage);
8590 statisticsData->store (1, allocStat);
8591 statisticsData->store (2, leakStat);
8592 return statisticsData;
8595 Vector<char*> *
8596 dbeGetFuncNames (int dbevindex, Vector<Obj> *funcs)
8598 int len = funcs->size ();
8599 Vector<char*> *list = new Vector<char*>(len);
8600 for (int i = 0; i < len; i++)
8601 list->store (i, dbeGetFuncName (dbevindex, funcs->fetch (i))); // no strdup()
8602 return list;
8605 Vector<char*> *
8606 dbeGetObjNamesV2 (int dbevindex, Vector<uint64_t> *ids)
8608 int len = ids->size ();
8609 Vector<char*> *list = new Vector<char*>(len);
8610 for (int i = 0; i < len; i++)
8611 list->store (i, dbeGetObjNameV2 (dbevindex, ids->fetch (i))); // no strdup()
8612 return list;
8615 char *
8616 dbeGetFuncName (int dbevindex, Obj func)
8618 DbeView *dbev = dbeSession->getView (dbevindex);
8619 if (dbev == NULL)
8620 abort ();
8621 if (func == 0)
8622 return NULL;
8623 char *fname;
8624 fname = ((Histable *) func)->get_name (dbev->get_name_format ());
8625 return fname ? dbe_strdup (fname) : NULL;
8628 Vector<uint64_t> *
8629 dbeGetFuncIds (int dbevindex, Vector<Obj> *funcs)
8631 int len = funcs->size ();
8632 Vector<uint64_t> *list = new Vector<uint64_t>(len);
8633 for (int i = 0; i < len; i++)
8634 list->store (i, dbeGetFuncId (dbevindex, funcs->fetch (i)));
8635 return list;
8638 uint64_t
8639 dbeGetFuncId (int dbevindex, Obj func)
8641 DbeView *dbev = dbeSession->getView (dbevindex);
8642 if (dbev == NULL)
8643 abort ();
8644 if (func == 0)
8645 return 0;
8646 uint64_t id = ((Histable *) func)->id;
8647 return id;
8650 char *
8651 dbeGetObjNameV2 (int dbevindex, uint64_t id)
8653 DbeView *dbev = dbeSession->getView (dbevindex);
8654 if (dbev == NULL)
8655 abort ();
8656 Histable *obj = dbeSession->findObjectById (id);
8657 if (obj == NULL)
8658 return NULL;
8659 char *fname = obj->get_name (dbev->get_name_format ());
8660 return fname ? dbe_strdup (fname) : NULL;
8663 char *
8664 dbeGetDataspaceTypeDesc (int /*dbevindex*/, Obj stack)
8666 if (stack == 0)
8667 return NULL;
8668 Histable *hist = CallStack::getStackPC ((void *) stack, 0);
8669 DbeInstr *instr;
8670 Histable::Type type = hist->get_type ();
8671 if (type != Histable::INSTR)
8672 return NULL;
8673 else
8674 instr = (DbeInstr *) hist;
8675 char *descriptor = instr->get_descriptor ();
8676 return descriptor ? dbe_strdup (descriptor) : NULL;
8679 Vector<void*> *
8680 dbeGetDataDescriptorsV2 (int exp_id)
8682 Experiment *exp = dbeSession->get_exp (exp_id);
8683 if (exp == NULL)
8684 return NULL;
8685 Vector<int> *dataId = new Vector<int>;
8686 Vector<char*> *dataName = new Vector<char*>;
8687 Vector<char*> *dataUName = new Vector<char*>;
8688 Vector<int> *auxProp = new Vector<int>;
8689 Vector<DataDescriptor*> *ddscr = exp->getDataDescriptors ();
8690 for (int i = 0; i < ddscr->size (); i++)
8692 DataDescriptor *dataDscr = ddscr->fetch (i);
8693 if (dataDscr->getFlags () & DDFLAG_NOSHOW)
8694 continue;
8695 int data_id = dataDscr->getId ();
8696 int aux_prop_id = (data_id == DATA_HWC) ? PROP_HWCTAG : PROP_NONE;
8697 dataId->append (data_id);
8698 dataName->append (strdup (dataDscr->getName ()));
8699 dataUName->append (strdup (dataDscr->getUName ()));
8700 auxProp->append (aux_prop_id);
8702 delete ddscr;
8703 Vector<void*> *res = new Vector<void*>(3);
8704 res->store (0, dataId);
8705 res->store (1, dataName);
8706 res->store (2, dataUName);
8707 res->store (3, auxProp);
8708 return res;
8711 Vector<void*> *
8712 dbeGetDataPropertiesV2 (int exp_id, int data_id)
8714 Experiment *exp = dbeSession->get_exp (exp_id);
8715 if (exp == NULL)
8716 return NULL;
8717 DataDescriptor *dataDscr = exp->get_raw_events (data_id);
8718 if (dataDscr == NULL)
8719 return NULL;
8720 Vector<PropDescr*> *props = dataDscr->getProps ();
8721 Vector<int> *propId = new Vector<int>(props->size ());
8722 Vector<char*> *propUName = new Vector<char*>(props->size ());
8723 Vector<int> *propTypeId = new Vector<int>(props->size ());
8724 Vector<char*> *propTypeName = new Vector<char*>(props->size ());
8725 Vector<int> *propFlags = new Vector<int>(props->size ());
8726 Vector<char*> *propName = new Vector<char*>(props->size ());
8727 Vector<void*> *propStateNames = new Vector<void*>(props->size ());
8728 Vector<void*> *propStateUNames = new Vector<void*>(props->size ());
8730 for (int i = 0; i < props->size (); i++)
8732 PropDescr *prop = props->fetch (i);
8733 char *pname = prop->name;
8734 if (pname == NULL)
8735 pname = NTXT ("");
8736 char *uname = prop->uname;
8737 if (uname == NULL)
8738 uname = pname;
8739 int vtypeNum = prop->vtype;
8740 if (vtypeNum < 0 || vtypeNum >= TYPE_LAST)
8741 vtypeNum = TYPE_NONE;
8742 const char * vtypeNames[] = VTYPE_TYPE_NAMES;
8743 const char *vtype = vtypeNames[prop->vtype];
8744 Vector<char*> *stateNames = NULL;
8745 Vector<char*> *stateUNames = NULL;
8746 int nStates = prop->getMaxState ();
8747 if (nStates > 0)
8749 stateNames = new Vector<char*>(nStates);
8750 stateUNames = new Vector<char*>(nStates);
8751 for (int kk = 0; kk < nStates; kk++)
8753 const char * stateName = prop->getStateName (kk);
8754 stateNames->store (kk, dbe_strdup (stateName));
8755 const char * Uname = prop->getStateUName (kk);
8756 stateUNames->store (kk, dbe_strdup (Uname));
8759 propId->store (i, prop->propID);
8760 propUName->store (i, dbe_strdup (uname));
8761 propTypeId->store (i, prop->vtype);
8762 propTypeName->store (i, dbe_strdup (vtype));
8763 propFlags->store (i, prop->flags);
8764 propName->store (i, dbe_strdup (pname));
8765 propStateNames->store (i, stateNames);
8766 propStateUNames->store (i, stateUNames);
8768 Vector<void*> *res = new Vector<void*>(7);
8769 res->store (0, propId);
8770 res->store (1, propUName);
8771 res->store (2, propTypeId);
8772 res->store (3, propTypeName);
8773 res->store (4, propFlags);
8774 res->store (5, propName);
8775 res->store (6, propStateNames);
8776 res->store (7, propStateUNames);
8777 return res;
8780 Vector<void *> *
8781 dbeGetExperimentTimeInfo (Vector<int> *exp_ids)
8783 int sz = exp_ids->size ();
8784 Vector<long long> *offset_time = new Vector<long long> (sz);
8785 Vector<long long> *start_time = new Vector<long long> (sz);
8786 Vector<long long> *end_time = new Vector<long long> (sz);
8787 Vector<long long> *start_wall_sec = new Vector<long long> (sz);
8788 Vector<char* > *hostname = new Vector<char*> (sz);
8789 Vector<int> *cpu_freq = new Vector<int> (sz);
8790 for (int ii = 0; ii < sz; ii++)
8792 int expIdx = exp_ids->fetch (ii);
8793 { // update end_time by forcing fetch of experiment data
8794 // workaround until dbeGetEndTime() is more robust
8795 int id = (expIdx < 0) ? 0 : expIdx;
8796 Experiment *exp = dbeSession->get_exp (id);
8797 if (exp)
8799 Vector<DataDescriptor*> *ddscr = exp->getDataDescriptors ();
8800 delete ddscr;
8803 offset_time->store (ii, dbeGetRelativeStartTime (0, expIdx));
8804 start_time->store (ii, dbeGetStartTime (0, expIdx));
8805 end_time->store (ii, dbeGetEndTime (0, expIdx));
8806 start_wall_sec->store (ii, dbeGetWallStartSec (0, expIdx));
8807 hostname->store (ii, dbeGetHostname (0, expIdx));
8808 cpu_freq->store (ii, dbeGetClock (0, expIdx));
8810 Vector<void*> *res = new Vector<void*>(4);
8811 res->store (0, offset_time);
8812 res->store (1, start_time);
8813 res->store (2, end_time);
8814 res->store (3, start_wall_sec);
8815 res->store (4, hostname);
8816 res->store (5, cpu_freq);
8817 return res;
8820 Vector<void *> *
8821 dbeGetExperimentDataDescriptors (Vector<int> *exp_ids)
8823 int sz = exp_ids->size ();
8824 Vector<void*> *exp_dscr_info = new Vector<void*> (sz);
8825 Vector<void*> *exp_dscr_props = new Vector<void*> (sz);
8827 for (int ii = 0; ii < sz; ii++)
8829 int expIdx = exp_ids->fetch (ii);
8830 Vector<void*> *ddscrInfo = dbeGetDataDescriptorsV2 (expIdx);
8831 Vector<void*> *ddscrProps = new Vector<void*> (); // one entry per ddscrInfo
8832 if (ddscrInfo)
8834 Vector<int> *dataId = (Vector<int>*)ddscrInfo->fetch (0);
8835 if (dataId)
8837 // loop thru data descriptors
8838 int ndata = dataId->size ();
8839 for (int j = 0; j < ndata; ++j)
8841 Vector<void*> *props = dbeGetDataPropertiesV2 (expIdx, dataId->fetch (j));
8842 ddscrProps->store (j, props);
8846 exp_dscr_info->store (ii, ddscrInfo);
8847 exp_dscr_props->store (ii, ddscrProps);
8849 Vector<void*> *res = new Vector<void*>(2);
8850 res->store (0, exp_dscr_info);
8851 res->store (1, exp_dscr_props);
8852 return res;
8855 static Vector<void *> *
8856 dbeGetTLDataRepVals (VMode view_mode, hrtime_t start_ts, hrtime_t delta,
8857 int numDeltas, DataView*packets,
8858 Vector<long> *representativeEvents, bool showDuration);
8860 static bool
8861 dbeHasTLData (int dbevindex, int exp_id, int data_id, int entity_prop_id,
8862 int entity_prop_value, int aux)
8864 DataView *packets =
8865 getTimelinePackets (dbevindex, exp_id, data_id, entity_prop_id);
8866 if (!packets || packets->getSize () == 0)
8867 return false;
8868 long start_ind = getIdxByVals (packets, aux, entity_prop_value,
8869 0, DataView::REL_GTEQ); // time >= 0
8870 if (start_ind < 0)
8871 return false;
8873 DbeView *dbev = dbeSession->getView (dbevindex);
8874 VMode view_mode = dbev->get_view_mode ();
8875 Experiment *exp = dbeSession->get_exp (exp_id);
8876 if (!hasInvisbleTLEvents (exp, view_mode))
8877 return true; // all events are visible, no further checking required
8878 long end_ind = getIdxByVals (packets, aux, entity_prop_value,
8879 MAX_TIME, DataView::REL_LTEQ);
8880 for (long ii = start_ind; ii <= end_ind; ii++)
8882 if (!isVisibleTLEvent (exp, view_mode, packets, ii))
8883 continue;
8884 return true; // first visible packet => has data
8886 return false;
8889 Vector<bool> *
8890 dbeHasTLData (int dbev_index, Vector<int> *exp_ids, Vector<int> *data_ids,
8891 Vector<int> *entity_prop_ids, // LWP,CPU,THR, etc
8892 Vector<int> *entity_prop_values, Vector<int> *auxs)
8894 DbeView *dbev = dbeSession->getView (dbev_index);
8895 if (!dbev->isShowAll () && (dbev->isShowHideChanged ()
8896 || dbev->isNewViewMode ()))
8898 // LIBRARY_VISIBILITY
8899 dbev->resetAndConstructShowHideStacks ();
8900 if (dbev->isNewViewMode ())
8901 dbev->resetNewViewMode ();
8902 if (dbev->isShowHideChanged ())
8903 dbev->resetShowHideChanged ();
8906 int sz = exp_ids->size ();
8907 Vector<bool> *hasVec = new Vector<bool>(sz);
8908 for (int ii = 0; ii < sz; ii++)
8910 bool hasData = dbeHasTLData (dbev_index, exp_ids->fetch (ii),
8911 data_ids->fetch (ii),
8912 entity_prop_ids->fetch (ii),
8913 entity_prop_values->fetch (ii),
8914 auxs->fetch (ii));
8915 hasVec->store (ii, hasData);
8917 return hasVec;
8921 * dbeGetTLData implements:
8922 * FROM data_id
8923 * DURATION >= delta AND ( start_ts <= TSTAMP < start_ts+num*delta OR
8924 * start_ts <= TSTAMP-DURATION < start_ts+num*delta )
8925 * OR
8926 * FAIR( DURATION < delta AND ( start_ts <= TSTAMP < start_ts+num*delta ) )
8927 * WHERE lfilter
8930 Vector<void *> *
8931 dbeGetTLData (
8932 int dbevindex,
8933 int exp_id,
8934 int data_id, // DATA_*
8935 int entity_prop_id, // Show PROP_LWPID, PROP_CPUID, PROP_THRID, PROP_EXPID, or N/A
8936 int entity_prop_value, // which LWPID, CPUID, THRID, EXPID for this request
8937 int aux,
8938 hrtime_t param_start_ts,
8939 hrtime_t param_delta,
8940 int param_numDeltas,
8941 bool getRepresentatives, // fetch TL representatives
8942 Vector<char *> *chartProps) // calculate sums for these property vals
8944 const hrtime_t start_ts = param_start_ts;
8945 const hrtime_t delta = param_delta;
8946 const int numDeltas = param_numDeltas;
8947 DbeView *dbev = dbeSession->getView (dbevindex);
8948 if (dbev == NULL)
8949 abort ();
8950 Experiment *exp = dbeSession->get_exp (exp_id);
8951 if (exp == NULL)
8952 return NULL;
8953 if (getRepresentatives == false && chartProps == NULL)
8954 return NULL;
8955 if (delta <= 0)
8956 return NULL;
8958 hrtime_t tmp_ts = start_ts + delta * numDeltas;
8959 if (tmp_ts < start_ts)
8960 tmp_ts = MAX_TIME;
8961 const hrtime_t end_ts = tmp_ts;
8962 if (exp->get_status () == Experiment::INCOMPLETE &&
8963 exp->getLastEvent () < end_ts)
8964 exp->update ();
8965 DataView *packets =
8966 getTimelinePackets (dbevindex, exp_id, data_id, entity_prop_id);
8967 if (packets == NULL)
8968 return NULL; // strange, no data view?
8970 VMode view_mode = dbev->get_view_mode (); // user, expert, machine //YXXX yuck
8972 // storage for calculating timeline representative events
8973 Vector<long> *representativeEvents = NULL;
8974 // list of representative events to be displayed on TL
8975 Vector<int> *binRepIdx = NULL;
8976 // for each bin, index of current "best" representativeEvent
8977 Vector<void*> *representativeVals = NULL;
8978 // TL representative packets' values
8980 // storage for calculating charts
8981 Vector<int> *propIds = NULL; // [propIdx], which prop to measure
8982 Vector<void*> *propVals = NULL; // [propIdx][bin], prop vals
8983 Vector<int> *propNumStates = NULL; // [propIdx], how many states for prop?
8984 Vector<bool> *propCumulativeChart = NULL; // [propIdx], data represents cumulative totals
8985 Vector<long long> *propCumulativeRecentBinLastVal = NULL; // [propIdx], most recent value
8986 Vector<long long> *propCumulativeRecentBinHighVal = NULL; // [propIdx], highest value for propCumulativeRecentBin
8987 Vector<int> *propCumulativeRecentBin = NULL; // [propIdx], most recent bin
8989 // determine when to show duration of events
8990 bool tmp_repsShowDuration = false;
8991 bool tmp_statesUseDuration = false;
8992 bool tmp_extendMicrostates = false;
8993 const hrtime_t ptimerTickDuration = exp->get_params ()->ptimer_usec * 1000LL; // nanoseconds per tick
8994 const bool hasDuration = packets->getProp (PROP_EVT_TIME) ? true : false;
8995 if (hasDuration)
8997 switch (entity_prop_id)
8999 case PROP_CPUID:
9000 tmp_repsShowDuration = false;
9001 tmp_statesUseDuration = false;
9002 break;
9003 case PROP_THRID:
9004 case PROP_LWPID:
9005 tmp_repsShowDuration = true;
9006 tmp_statesUseDuration = true;
9007 tmp_extendMicrostates = (DATA_CLOCK == data_id) && (ptimerTickDuration < param_delta);
9008 break;
9009 case PROP_EXPID:
9010 case PROP_NONE: // experiment summary row uses this
9011 default:
9012 if (DATA_SAMPLE == data_id)
9014 tmp_repsShowDuration = true;
9015 tmp_statesUseDuration = true;
9017 else if (DATA_GCEVENT == data_id)
9019 tmp_repsShowDuration = true;
9020 tmp_statesUseDuration = true;
9022 else if (DATA_CLOCK == data_id)
9024 tmp_repsShowDuration = false;
9025 tmp_statesUseDuration = true;
9026 tmp_extendMicrostates = true;
9028 else
9030 tmp_repsShowDuration = false;
9031 tmp_statesUseDuration = true;
9033 break;
9036 const bool repsShowDuration = tmp_repsShowDuration; // show stretched callstacks
9037 const bool statesUseDuration = tmp_statesUseDuration; // use duration to calculate state charts
9038 const bool extendMicrostates = tmp_extendMicrostates; // we show discrete profiling microstates with
9039 // width=(tick-1), but for computing
9040 // zoomed-out graphs we need to extend to
9041 // account for all ticks, width=(ntick)
9042 const bool reverseScan = repsShowDuration || extendMicrostates; // scan packets in reverse
9044 // determine range of packet indices (lo_pkt_idx, hi_pkt_idx)
9045 long lo_pkt_idx, hi_pkt_idx;
9046 if (extendMicrostates && !(entity_prop_id == PROP_THRID || entity_prop_id == PROP_LWPID))
9048 // merging data from multiple threads, need to scan all packets with timestamp [start_ts, exp end]
9049 hrtime_t exp_end_time = exp->getLastEvent () + 1;
9050 hi_pkt_idx = getIdxByVals (packets, aux, entity_prop_value,
9051 exp_end_time, DataView::REL_LT); // last item
9053 else
9054 hi_pkt_idx = getIdxByVals (packets, aux, entity_prop_value,
9055 end_ts, DataView::REL_LT);
9056 if (repsShowDuration)
9058 // There are two issues to deal with
9059 // 1. events that end "off screen" to the right
9060 // 2. overlapping events
9062 // 1. events that end "off screen" to the right
9063 // For now, we only consistently handle the case where events don't overlap.
9064 // Note that packet timestamps mark end of duration, not start.
9065 // This means that the rightmost event won't be within hi_pkt_idx.
9066 // Solution: Check if end+1 packet _started_ in-range
9067 // Caveat: because we only look ahead by one packet, if there are
9068 // overlapping duration events (e.g. EXPID aggregation)), zoom level
9069 // and panning combo may cause events with TSTAMP>end_ts
9070 // to appear/disappear. A complete solution would involve
9071 // a solution to 2.
9073 // 2. overlapping events
9074 // For now, we have a simplistic solution that makes "wide" events win. However,
9075 // a future solution for deterministically dealing with overlap might look like this:
9076 // - find all packets that touch the visible time range
9077 // - possibly use two DataViews: one with TSTAMP_HI sort and one with TSTAMP_LO
9078 // sort to allow efficient determination of packets with HI and LO endpoints in-range
9079 // - create buckets to capture "winning" event for each bin (each pixel, that is)
9080 // - sort the new list of packets by TSTAMP_HI (for example)
9081 // - looping thru the packets that are in-range, update every bin it touches with it's id
9082 // - if there is overlap, earlier packets will be kicked out of bins
9083 // - On the GUI side, paint one event at a time, as normal.
9084 // - However, for selections, recognize that duration of event may span many bins
9086 long idx;
9087 if (hi_pkt_idx >= 0)
9088 // a packet was found to the left of the end time
9089 idx = hi_pkt_idx + 1; // attempt to go one packet right
9090 else
9091 idx = getIdxByVals (packets, aux, entity_prop_value,
9092 end_ts, DataView::REL_GTEQ);
9093 if (isValidIdx (packets, entity_prop_id, aux, entity_prop_value, idx))
9095 int64_t pkt_ts = packets->getLongValue (PROP_TSTAMP, idx);
9096 int64_t duration = packets->getLongValue (PROP_EVT_TIME, idx);
9097 pkt_ts -= duration;
9098 if (pkt_ts < end_ts)
9099 hi_pkt_idx = idx;
9102 lo_pkt_idx = getIdxByVals (packets, aux, entity_prop_value,
9103 start_ts, DataView::REL_GTEQ);
9105 // allocate structs that return chart data
9106 bool hasCumulativeCharts = false;
9107 if (chartProps && chartProps->size () > 0)
9109 int nprops = chartProps->size ();
9110 // pre-allocate storage
9111 propIds = new Vector<int> (nprops);
9112 propVals = new Vector<void*>(nprops);
9113 propNumStates = new Vector<int> (nprops);
9114 propCumulativeChart = new Vector<bool>(nprops);
9115 propCumulativeRecentBinLastVal = new Vector<long long>(nprops);
9116 propCumulativeRecentBinHighVal = new Vector<long long>(nprops);
9117 propCumulativeRecentBin = new Vector<int>(nprops);
9118 for (int propNum = 0; propNum < nprops; propNum++)
9120 const char* propStr = chartProps->fetch (propNum);
9121 int items_per_prop = 0;
9122 int prop_id = PROP_NONE;
9123 if (!strcmp (propStr, "EVT_COUNT"))
9124 items_per_prop = 1; // use PROP_NONE for counting packets
9125 else
9127 int lookup_prop_id = dbeSession->getPropIdByName (propStr);
9128 PropDescr *propDscr = packets->getProp (lookup_prop_id);
9129 if (propDscr != NULL)
9131 switch (propDscr->vtype)
9133 case TYPE_INT32:
9134 case TYPE_UINT32:
9135 case TYPE_INT64:
9136 case TYPE_UINT64:
9137 items_per_prop = propDscr->getMaxState () + 1;
9138 // add extra slot to store values with out-of-range idx
9139 prop_id = lookup_prop_id;
9140 break;
9141 case TYPE_DOUBLE:
9142 break; // not implemented yet
9143 case TYPE_STRING:
9144 case TYPE_OBJ:
9145 case TYPE_DATE:
9146 default:
9147 break;
9151 void *vals;
9152 if (!items_per_prop)
9153 vals = NULL;
9154 else if (items_per_prop == 1)
9156 Vector<long long> *longVals = new Vector<long long> ();
9157 longVals->store (numDeltas - 1, 0); // initialize all elements
9158 vals = longVals;
9160 else
9162 Vector<Vector<long long>*> *stateVals =
9163 new Vector<Vector<long long>*> ();
9164 vals = stateVals;
9165 // initialize only on-demand, some may not be needed
9168 bool isCumulativeChart;
9169 #define YXXX_HEAP_VS_TIME 1 // YXXX add data meaning to properties?
9170 #if YXXX_HEAP_VS_TIME
9171 isCumulativeChart = (prop_id == PROP_HCUR_LEAKS || prop_id == PROP_HCUR_ALLOCS);
9172 #endif
9173 if (isCumulativeChart)
9174 hasCumulativeCharts = true;
9175 propIds->store (propNum, prop_id);
9176 propVals->store (propNum, vals);
9177 propNumStates->store (propNum, items_per_prop);
9178 propCumulativeRecentBinLastVal->store (propNum, 0);
9179 propCumulativeRecentBinHighVal->store (propNum, 0);
9180 propCumulativeRecentBin->store (propNum, 0);
9181 propCumulativeChart->store (propNum, isCumulativeChart);
9185 // Adjust idx range for calculating 'cumulative charts' e.g. heap size
9186 if (hasCumulativeCharts)
9188 // set initial values if earlier packet exists
9189 long lo_idx;
9190 if (lo_pkt_idx >= 0)
9191 // packet was found to the right of start
9192 lo_idx = lo_pkt_idx - 1; // attempt to go left by one event
9193 else
9194 // no packet was to the right of start, look left of start
9195 lo_idx = getIdxByVals (packets, aux, entity_prop_value,
9196 start_ts, DataView::REL_LT);
9197 if (isValidIdx (packets, entity_prop_id, aux, entity_prop_value, lo_idx))
9199 // preceding packet found
9200 // update initial values
9201 int nprops = propCumulativeChart->size ();
9202 for (int propNum = 0; propNum < nprops; propNum++)
9204 if (!propCumulativeChart->fetch (propNum))
9205 continue;
9206 int propId = propIds->fetch (propNum);
9207 long long value = packets->getLongValue (propId, lo_idx);
9208 propCumulativeRecentBinLastVal->store (propNum, value);
9209 propCumulativeRecentBinHighVal->store (propNum, value);
9211 // update indices used for iterating
9212 lo_pkt_idx = lo_idx;
9213 if (hi_pkt_idx < lo_pkt_idx)
9214 hi_pkt_idx = lo_pkt_idx;
9217 if (lo_pkt_idx < 0 || hi_pkt_idx < 0)
9218 goto dbeGetTLData_done; // no data; return empty vectors, not null
9220 // representative events (subset of callstacks to represent on TL)
9221 if (getRepresentatives)
9223 representativeEvents = new Vector<long>(numDeltas);
9224 // per-bin, longest event's index
9225 binRepIdx = new Vector<int>(numDeltas);
9226 for (int ii = 0; ii < numDeltas; ++ii)
9227 binRepIdx->append (-1);
9229 // While packets are sorted by _end_ timestamp (TSTAMP),
9230 // after calculating start times for non-zero durations,
9231 // start times are not guaranteed be monotonically increasing.
9232 // For packets with duration, we'll scan them in reverse order to
9233 // take advantage of the monotonically decreasing _end_ timestamps.
9234 long start_idx, idx_inc;
9235 if (!reverseScan)
9237 start_idx = lo_pkt_idx;
9238 idx_inc = 1;
9240 else
9242 start_idx = hi_pkt_idx;
9243 idx_inc = -1;
9245 for (long ii = start_idx; ii >= lo_pkt_idx && ii <= hi_pkt_idx; ii += idx_inc)
9247 if (!isVisibleTLEvent (exp, view_mode, packets, ii) && !hasCumulativeCharts)
9248 continue;
9250 // determine packet time duration and start bin
9251 int tmp_start_bin; // packet start bin
9252 int tmp_end_bin; // packet end bin (inclusive)
9253 const hrtime_t pkt_end_ts = packets->getLongValue (PROP_TSTAMP, ii);
9254 const hrtime_t pkt_dur = packets->getLongValue (PROP_EVT_TIME, ii);
9255 const hrtime_t pkt_start_ts = pkt_end_ts - pkt_dur;
9256 if (pkt_end_ts < start_ts && !hasCumulativeCharts)
9257 continue; // weird, should not happen
9258 if (pkt_start_ts >= end_ts)
9259 continue; // could happen
9260 hrtime_t bin_end_ts = pkt_end_ts;
9261 if (bin_end_ts >= end_ts)
9262 bin_end_ts = end_ts - 1;
9263 tmp_end_bin = (int) ((bin_end_ts - start_ts) / delta);
9264 hrtime_t bin_start_ts = pkt_start_ts;
9265 if (bin_start_ts < start_ts)
9266 bin_start_ts = start_ts; // event truncated to left.
9267 tmp_start_bin = (int) ((bin_start_ts - start_ts) / delta);
9268 // By definition
9269 // (end_ts - start_ts) == delta * numDeltas
9270 // and we know
9271 // pkt_start < end_ts
9272 // therefore
9273 // (pkt_start - start_ts) < delta * numDeltas
9274 // (pkt_start - start_ts) / delta < numDeltas
9275 // bin < numDeltas
9276 assert (tmp_end_bin < numDeltas);
9277 assert (tmp_start_bin < numDeltas);
9278 const bool is_offscreen = tmp_end_bin < 0 ? true : false;
9279 if (tmp_end_bin < 0)
9280 tmp_end_bin = 0;
9281 const int pkt_end_bin = tmp_end_bin; // packet end bin (inclusive)
9282 const int pkt_start_bin = tmp_start_bin;
9283 if (getRepresentatives && !is_offscreen)
9284 { // find best representative
9285 // Note: for events with duration, we're scanning packets in order
9286 // of decreasing end-timestamp. This means that the first packet
9287 // that hits a particular _start_ bin will have the longest duration
9288 // of any later packet that might hit that start bin. The
9289 // the first packet will be the best (longest) packet.
9290 const int bin = reverseScan ? pkt_start_bin : pkt_end_bin;
9291 int eventIdx = binRepIdx->fetch (bin);
9292 if (eventIdx == -1)
9294 eventIdx = representativeEvents->size (); // append to end
9295 representativeEvents->append (ii);
9296 binRepIdx->store (bin, eventIdx);
9299 if (propIds)
9300 { // per-bin chart: sum across filtered packets
9301 for (int propNum = 0; propNum < propIds->size (); propNum++)
9303 void *thisProp = propVals->fetch (propNum);
9304 if (thisProp == NULL)
9305 continue; // no valid data
9306 if (is_offscreen && !propCumulativeChart->fetch (propNum))
9307 continue; // offscreen events are only processed for cumulative charts
9308 int propId = propIds->fetch (propNum);
9309 long long val;
9310 if (propId == PROP_NONE)
9311 val = 1; // count
9312 else
9313 val = packets->getLongValue (propId, ii);
9314 long nitems = propNumStates->fetch (propNum);
9315 if (nitems < 1)
9316 continue;
9317 else if (nitems == 1)
9319 // chart is not based on not multiple states
9320 Vector<long long>* thisPropVals =
9321 (Vector<long long>*)thisProp;
9322 if (thisPropVals->size () == 0)
9323 thisPropVals->store (numDeltas - 1, 0);
9324 const int bin = statesUseDuration ? pkt_start_bin : pkt_end_bin;
9325 if (!propCumulativeChart->fetch (propNum))
9327 val += thisPropVals->fetch (bin);
9328 thisPropVals->store (bin, val);
9330 else
9332 // propCumulativeChart
9333 long long high_value = propCumulativeRecentBinHighVal->fetch (propNum);
9334 int last_bin = propCumulativeRecentBin->fetch (propNum);
9335 if (last_bin < bin)
9337 // backfill from previous event
9338 // last_bin: store largest value (in case of multiple events)
9339 thisPropVals->store (last_bin, high_value);
9340 // propagate forward the bin's last value
9341 long long last_value = propCumulativeRecentBinLastVal->fetch (propNum);
9342 for (int kk = last_bin + 1; kk < bin; kk++)
9343 thisPropVals->store (kk, last_value);
9344 // prepare new bin for current event
9345 high_value = 0; // high value of next bin is 0.
9346 propCumulativeRecentBinHighVal->store (propNum, high_value);
9347 propCumulativeRecentBin->store (propNum, bin);
9349 long long this_value = packets->getLongValue (propId, ii);
9350 propCumulativeRecentBinLastVal->store (propNum, this_value);
9351 if (high_value < this_value)
9353 // record the max
9354 high_value = this_value;
9355 propCumulativeRecentBinHighVal->store (propNum, high_value);
9357 if (ii == hi_pkt_idx)
9359 // bin: show largest value (in case of multiple events
9360 thisPropVals->store (bin, high_value);
9361 //forward fill remaining bins
9362 for (int kk = bin + 1; kk < numDeltas; kk++)
9363 thisPropVals->store (kk, this_value);
9367 else
9369 // means val is actually a state #
9370 Vector<Vector<long long>*>* thisPropStateVals =
9371 (Vector<Vector<long long>*>*)thisProp;
9372 if (thisPropStateVals->size () == 0)
9373 thisPropStateVals->store (numDeltas - 1, 0);
9374 long stateNum;
9375 if (val >= 0 && val < nitems)
9376 stateNum = (long) val;
9377 else
9378 stateNum = nitems - 1; // out of range, use last slot
9379 hrtime_t graph_pkt_dur = pkt_dur;
9380 hrtime_t graph_pkt_start_ts = pkt_start_ts;
9381 int tmp2_start_bin = pkt_start_bin;
9382 if (propId == PROP_MSTATE)
9384 if (statesUseDuration && extendMicrostates)
9386 // microstate stacks are shown and filtered with width=NTICK-1
9387 // but for microstate graph calcs use width=NTICK.
9388 graph_pkt_dur += ptimerTickDuration;
9389 graph_pkt_start_ts -= ptimerTickDuration;
9390 hrtime_t bin_start_ts = graph_pkt_start_ts;
9391 if (bin_start_ts < start_ts)
9392 bin_start_ts = start_ts; // event truncated to left.
9393 tmp2_start_bin = (int) ((bin_start_ts - start_ts) / delta);
9396 const int graph_pkt_start_bin = statesUseDuration ? tmp2_start_bin : pkt_end_bin;
9398 // We will distribute the state's presence evenly over duration of the event.
9399 // When only a 'partial bin' is touched by an event, adjust accordingly.
9400 long long value_per_bin; // weight to be applied to each bin
9402 long long weight;
9403 if (propId == PROP_MSTATE) // ticks to nanoseconds
9404 weight = packets->getLongValue (PROP_NTICK, ii) * ptimerTickDuration;
9405 else if (graph_pkt_dur)
9406 weight = graph_pkt_dur; // nanoseconds
9407 else
9408 weight = 1; // no duration; indicate presence
9409 if (graph_pkt_start_bin != pkt_end_bin)
9411 // spans multiple bins
9412 double nbins = (double) graph_pkt_dur / delta;
9413 value_per_bin = weight / nbins;
9415 else
9416 value_per_bin = weight;
9418 for (int evtbin = graph_pkt_start_bin; evtbin <= pkt_end_bin; evtbin++)
9420 Vector<long long>* stateValues =
9421 (Vector<long long>*) thisPropStateVals->fetch (evtbin);
9422 if (stateValues == NULL)
9424 // on-demand storage
9425 stateValues = new Vector<long long>(nitems);
9426 stateValues->store (nitems - 1, 0); // force memset of full vector
9427 thisPropStateVals->store (evtbin, stateValues);
9429 long long new_val = stateValues->fetch (stateNum);
9430 if (graph_pkt_start_bin == pkt_end_bin ||
9431 (evtbin > graph_pkt_start_bin && evtbin < pkt_end_bin))
9433 new_val += value_per_bin;
9435 else
9437 // partial bin
9438 const hrtime_t bin_start = start_ts + evtbin * delta;
9439 const hrtime_t bin_end = start_ts + (evtbin + 1) * delta - 1;
9440 if (evtbin == graph_pkt_start_bin)
9442 // leftmost bin
9443 if (graph_pkt_start_ts < bin_start)
9444 new_val += value_per_bin;
9445 else
9447 double percent = (double) (bin_end - graph_pkt_start_ts) / delta;
9448 new_val += value_per_bin*percent;
9451 else
9453 // rightmost bin
9454 if (pkt_end_ts > bin_end)
9455 new_val += value_per_bin;
9456 else
9458 double percent = (double) (pkt_end_ts - bin_start) / delta;
9459 new_val += value_per_bin*percent;
9463 stateValues->store (stateNum, new_val);
9469 delete binRepIdx;
9470 delete propIds;
9471 delete propCumulativeChart;
9472 delete propCumulativeRecentBinLastVal;
9473 delete propCumulativeRecentBinHighVal;
9474 delete propCumulativeRecentBin;
9475 if (representativeEvents != NULL && reverseScan)
9477 if (repsShowDuration)
9479 //YXXX for now prune here, but in the future, let gui decide what to show
9480 // Prune events that are completely obscured long duration events.
9481 // Note: representativeEvents is sorted by decreasing _end_ timestamps.
9482 Vector<long> *prunedEvents = new Vector<long>(numDeltas);
9483 hrtime_t prev_start_ts = MAX_TIME;
9484 long repCnt = representativeEvents->size ();
9485 for (long kk = 0; kk < repCnt; kk++)
9487 long ii = representativeEvents->fetch (kk);
9488 hrtime_t tmp_end_ts = packets->getLongValue (PROP_TSTAMP, ii);
9489 hrtime_t tmp_dur = packets->getLongValue (PROP_EVT_TIME, ii);
9490 hrtime_t tmp_start_ts = tmp_end_ts - tmp_dur;
9491 if (tmp_start_ts >= prev_start_ts)
9492 // this event would be completely hidden
9493 // (because of sorting, we know tmp_end_ts <= prev_end_ts)
9494 continue;
9495 prev_start_ts = tmp_start_ts;
9496 prunedEvents->append (ii);
9498 // invert order to to get increasing _end_ timestamps
9499 representativeEvents->reset ();
9500 for (long kk = prunedEvents->size () - 1; kk >= 0; kk--)
9502 long packet_idx = prunedEvents->fetch (kk);
9503 representativeEvents->append (packet_idx);
9505 delete prunedEvents;
9507 else
9508 { // !repsShowDuration
9509 // Note: representativeEvents is sorted by decreasing _end_ timestamps.
9510 // Reverse the order:
9511 long hi_idx = representativeEvents->size () - 1;
9512 long lo_idx = 0;
9513 while (hi_idx > lo_idx)
9515 // swap
9516 long lo = representativeEvents->fetch (lo_idx);
9517 long hi = representativeEvents->fetch (hi_idx);
9518 representativeEvents->store (lo_idx, hi);
9519 representativeEvents->store (hi_idx, lo);
9520 hi_idx--;
9521 lo_idx++;
9526 dbeGetTLData_done:
9527 if (getRepresentatives)
9529 representativeVals = dbeGetTLDataRepVals (view_mode, start_ts, delta,
9530 numDeltas, packets, representativeEvents, repsShowDuration);
9531 delete representativeEvents;
9533 Vector<void*> *results = new Vector<void*> (2);
9534 results->store (0, representativeVals);
9535 results->store (1, propVals);
9536 return results;
9539 // add representative events to return buffer
9541 static Vector<void *> *
9542 dbeGetTLDataRepVals (VMode view_mode, hrtime_t start_ts, hrtime_t delta,
9543 int numDeltas, DataView*packets,
9544 Vector<long> *representativeEvents, bool showDuration)
9546 int numrecs = representativeEvents ? representativeEvents->size () : 0;
9547 // allocate storage for results
9548 Vector<int> *startBins = new Vector<int>(numrecs);
9549 Vector<int> *numBins = new Vector<int>(numrecs);
9550 Vector<Obj> *eventIdxs = new Vector<Obj>(numrecs);
9551 Vector<Obj> *stackIds = NULL;
9552 if (packets->getProp (PROP_FRINFO))
9553 stackIds = new Vector<Obj>(numrecs);
9554 Vector<int> *mstates = NULL;
9555 if (packets->getProp (PROP_MSTATE))
9556 mstates = new Vector<int>(numrecs);
9557 Vector<Vector<long long>*> *sampleVals = NULL;
9558 if (packets->getProp (PROP_SMPLOBJ))
9559 sampleVals = new Vector<Vector<long long>*>(numrecs);
9560 Vector<long long> *timeStart = new Vector<long long>(numrecs);
9561 Vector<long long> *timeEnd = new Vector<long long>(numrecs);
9562 int prevEndBin = -1; // make sure we don't overlap bins
9563 for (int eventIdx = 0; eventIdx < numrecs; eventIdx++)
9565 long packetIdx = representativeEvents->fetch (eventIdx);
9566 // long eventId = packets->getIdByIdx( packetIdx );
9567 const hrtime_t pkt_tstamp = packets->getLongValue (PROP_TSTAMP, packetIdx);
9568 const hrtime_t pkt_dur = showDuration ? packets->getLongValue (PROP_EVT_TIME, packetIdx) : 0;
9569 timeStart->store (eventIdx, pkt_tstamp - pkt_dur);
9570 timeEnd->store (eventIdx, pkt_tstamp);
9572 // calc startBin
9573 int startBin = (int) ((pkt_tstamp - pkt_dur - start_ts) / delta);
9574 if (startBin <= prevEndBin)
9575 startBin = prevEndBin + 1;
9576 // calc binCnt
9577 int endBin = (int) ((pkt_tstamp - start_ts) / delta);
9578 if (endBin >= numDeltas)
9579 endBin = numDeltas - 1;
9580 int binCnt = endBin - startBin + 1;
9581 prevEndBin = endBin;
9582 startBins->store (eventIdx, startBin);
9583 numBins->store (eventIdx, binCnt);
9584 eventIdxs->store (eventIdx, packetIdx); // store packet's idx
9585 if (stackIds != NULL)
9587 void* stackId = getStack (view_mode, packets, packetIdx);
9588 stackIds->store (eventIdx, (Obj) (unsigned long) stackId);
9590 if (mstates != NULL)
9592 int mstate = packets->getIntValue (PROP_MSTATE, packetIdx);
9593 mstates->store (eventIdx, mstate);
9595 if (sampleVals != NULL)
9597 Sample* sample = (Sample*) packets->getObjValue (PROP_SMPLOBJ, packetIdx);
9598 if (!sample || !sample->get_usage ())
9599 sample = sample;
9600 else
9602 PrUsage* prusage = sample->get_usage ();
9603 Vector<long long> *mstateVals = prusage->getMstateValues ();
9604 sampleVals->store (eventIdx, mstateVals);
9608 // caller responsible for: delete representativeEvents;
9609 Vector<void*> *results = new Vector<void*> (8);
9610 results->store (0, startBins);
9611 results->store (1, numBins);
9612 results->store (2, eventIdxs);
9613 results->store (3, stackIds);
9614 results->store (4, mstates);
9615 results->store (5, sampleVals);
9616 results->store (6, timeStart);
9617 results->store (7, timeEnd);
9618 return results;
9621 // starting from <event_id> packet idx, step <move_count> visible events
9622 // return the resulting idx and that packet's center time, or null if no event.
9623 Vector<long long> *
9624 dbeGetTLEventCenterTime (int dbevindex, int exp_id, int data_id,
9625 int entity_prop_id, int entity_prop_val, int aux,
9626 long long event_id, long long move_count)
9628 DataView *packets = getTimelinePackets (dbevindex, exp_id, data_id,
9629 entity_prop_id);
9630 if (packets == NULL)
9631 return NULL;
9632 long idx = (long) event_id;
9634 DbeView *dbev = dbeSession->getView (dbevindex);
9635 VMode view_mode = dbev->get_view_mode ();
9636 Experiment *exp = dbeSession->get_exp (exp_id);
9637 int direction;
9638 if (move_count == 0)
9639 direction = 0;
9640 else if (move_count < 0)
9642 move_count = -move_count;
9643 direction = -1;
9645 else
9646 direction = 1;
9647 idx = getTLVisibleIdxByStepping (exp, view_mode, entity_prop_id, packets, aux,
9648 entity_prop_val, idx, move_count, direction);
9649 if (idx >= 0)
9651 long long ts = packets->getLongValue (PROP_TSTAMP, idx);
9652 long long dur = packets->getLongValue (PROP_EVT_TIME, idx);
9653 long long center = ts - dur / 2;
9654 Vector<long long> *results = new Vector<long long> (2);
9655 results->store (0, idx); // result idx
9656 results->store (1, center); // result timestamp
9657 return results;
9659 return NULL;
9662 long long
9663 dbeGetTLEventIdxNearTime (int dbevindex, int exp_id, int data_id,
9664 int entity_prop_id, int entity_prop_val, int aux,
9665 int searchDirection, long long tstamp)
9667 DataView *packets = getTimelinePackets (dbevindex, exp_id, data_id,
9668 entity_prop_id);
9669 if (packets == NULL)
9670 return -1;
9671 DbeView *dbev = dbeSession->getView (dbevindex);
9672 VMode view_mode = dbev->get_view_mode ();
9673 Experiment *exp = dbeSession->get_exp (exp_id);
9674 if (searchDirection < 0)
9676 int idx = getTLVisibleIdxByVals (exp, view_mode, entity_prop_id,
9677 packets, aux, entity_prop_val, tstamp,
9678 DataView::REL_LTEQ);
9679 if (idx != -1)
9680 return idx;
9681 searchDirection = 1; // couldn't find to left, try to right
9683 if (searchDirection > 0)
9685 int idx = getTLVisibleIdxByVals (exp, view_mode, entity_prop_id,
9686 packets, aux, entity_prop_val, tstamp,
9687 DataView::REL_GTEQ);
9688 if (idx != -1)
9689 return idx;
9690 // couldn't find to right, fall through to generic
9692 // search left and right of timestamp
9693 long idx1, idx2;
9694 idx1 = getTLVisibleIdxByVals (exp, view_mode, entity_prop_id,
9695 packets, aux, entity_prop_val, tstamp,
9696 DataView::REL_LT);
9697 idx2 = getTLVisibleIdxByVals (exp, view_mode, entity_prop_id,
9698 packets, aux, entity_prop_val, tstamp,
9699 DataView::REL_GTEQ);
9700 if (idx1 == -1)
9701 return idx2;
9702 else if (idx2 == -1)
9703 return idx1;
9705 // both valid, so need to compare to see which is closer
9706 long long t1 = packets->getLongValue (PROP_TSTAMP, idx1);
9707 long long t2 = packets->getLongValue (PROP_TSTAMP, idx2);
9708 long long t2dur = packets->getLongValue (PROP_EVT_TIME, idx2);
9709 long long delta1 = tstamp - t1; // should always be positive
9710 long long delta2 = (t2 - t2dur) - tstamp; // if negative, overlaps idx1
9711 if (delta1 > delta2)
9712 return idx2;
9713 else
9714 return idx1;
9717 enum Aggr_type
9719 AGGR_NONE,
9720 AGGR_FAIR,
9721 AGGR_MAX,
9722 AGGR_MIN,
9723 AGGR_CNT,
9724 AGGR_SUM,
9725 AGGR_AVG
9728 static Aggr_type
9729 getAggrFunc (char *aname)
9731 Aggr_type agrfn = AGGR_NONE;
9732 if (aname == NULL)
9733 return agrfn;
9734 if (strcmp (aname, NTXT ("FAIR")) == 0)
9735 agrfn = AGGR_FAIR;
9736 else if (strcmp (aname, NTXT ("MAX")) == 0)
9737 agrfn = AGGR_MAX;
9738 else if (strcmp (aname, NTXT ("MIN")) == 0)
9739 agrfn = AGGR_MIN;
9740 else if (strcmp (aname, NTXT ("CNT")) == 0)
9741 agrfn = AGGR_CNT;
9742 else if (strcmp (aname, NTXT ("SUM")) == 0)
9743 agrfn = AGGR_SUM;
9744 else if (strcmp (aname, NTXT ("AVG")) == 0)
9745 agrfn = AGGR_AVG;
9746 return agrfn;
9749 static long long
9750 computeAggrVal (DefaultMap<long long, long long> *fval_map, Aggr_type agrfn)
9752 long long aval = 0;
9753 long cnt = 0;
9754 Vector<long long> *fvals = fval_map->values ();
9755 long nvals = fvals->size ();
9756 for (int i = 0; i < nvals; ++i)
9758 long long val = fvals->fetch (i);
9759 switch (agrfn)
9761 case AGGR_FAIR:
9762 aval = val;
9763 break;
9764 case AGGR_MAX:
9765 if (aval < val || cnt == 0)
9766 aval = val;
9767 break;
9768 case AGGR_MIN:
9769 if (aval > val || cnt == 0)
9770 aval = val;
9771 break;
9772 case AGGR_CNT:
9773 aval = cnt + 1;
9774 break;
9775 case AGGR_SUM:
9776 case AGGR_AVG:
9777 aval += val;
9778 break;
9779 case AGGR_NONE:
9780 break;
9782 if (agrfn == AGGR_FAIR)
9783 break;
9784 cnt += 1;
9787 // Finalize aggregation
9788 if (agrfn == AGGR_AVG)
9789 if (cnt > 0)
9790 aval = (aval + cnt / 2) / cnt;
9791 delete fvals;
9792 return aval;
9795 Vector<long long> *
9796 dbeGetAggregatedValue (int data_id, // data table id
9797 char *lfilter, // local filter
9798 char *fexpr, // function expression
9799 char *pname_ts, // property name for timestamp
9800 hrtime_t start_ts, // start of the first time interval
9801 hrtime_t delta, // time interval length
9802 int num, // number of time intervals
9803 char *pname_key, // property name for aggregation key
9804 char *aggr_func) // aggregation function
9806 Vector<long long> *res = new Vector<long long>;
9807 Experiment *exp = dbeSession->get_exp (0);
9808 if (exp == NULL)
9809 return res;
9810 hrtime_t end_ts = start_ts + delta * num;
9811 if (end_ts < start_ts) // check overflow
9812 end_ts = MAX_TIME;
9814 if (exp->get_status () == Experiment::INCOMPLETE
9815 && exp->getLastEvent () < end_ts)
9816 exp->update ();
9818 DataDescriptor *dataDscr = exp->get_raw_events (data_id);
9819 if (dataDscr == NULL)
9820 return res;
9822 // Process timestamp argument
9823 int prop_ts = dbeSession->getPropIdByName (pname_ts);
9824 if (prop_ts == PROP_NONE)
9825 return res;
9826 assert (prop_ts == -1);
9828 // Parse all expressions
9829 Expression *flt_expr = NULL;
9830 if (lfilter != NULL)
9831 flt_expr = dbeSession->ql_parse (lfilter);
9832 Expression *func_expr = NULL;
9833 if (fexpr != NULL)
9834 func_expr = dbeSession->ql_parse (fexpr);
9835 if (func_expr == NULL) // Not specified or malformed
9836 return res;
9838 // Process aggregation key argument
9839 int prop_key = PROP_NONE;
9840 Data *data_key = NULL;
9841 if (pname_key != NULL)
9843 prop_key = dbeSession->getPropIdByName (pname_key);
9844 data_key = dataDscr->getData (prop_key);
9845 if (data_key == NULL) // Specified but not found
9846 return res;
9849 // Process aggregation function argument
9850 Aggr_type agrfn = AGGR_FAIR;
9851 if (aggr_func != NULL)
9853 agrfn = getAggrFunc (aggr_func);
9854 if (agrfn == AGGR_NONE) // Specified but not recognized
9855 return res;
9857 DefaultMap<long long, long long> *
9858 fval_map = new DefaultMap<long long, long long>; // key_val -> func_val
9859 Vector<long long> *key_set = NULL;
9860 assert (key_set != NULL);
9861 if (key_set == NULL)
9863 key_set = new Vector<long long>;
9864 key_set->append (0L);
9866 DefaultMap<long long, int> *key_seen = new DefaultMap<long long, int>;
9867 long idx_prev = -1;
9868 for (int tidx = 0; tidx < num; ++tidx)
9870 long idx_cur = -1;
9871 assert (idx_cur != -1);
9872 int left = key_set->size ();
9873 key_seen->clear ();
9874 for (long idx = idx_cur; idx > idx_prev; --idx)
9876 long id = 0;
9877 assert (id != 0);
9879 // Pre-create expression context
9880 Expression::Context ctx (dbeSession->getView (0), exp, NULL, id);
9881 // First use the filter
9882 if (flt_expr != NULL)
9883 if (flt_expr->eval (&ctx) == 0)
9884 continue;
9886 // Calculate the key
9887 // keys are limited to integral values
9888 long long key = 0;
9889 if (data_key != NULL)
9890 key = data_key->fetchLong (id);
9892 // Check if already seen
9893 if (key_seen->get (key) == 1)
9894 continue;
9895 key_seen->put (key, 1);
9896 left -= 1;
9898 // Calculate function value
9899 // function values are limited to integral values
9900 long long fval = func_expr->eval (&ctx);
9901 fval_map->put (key, fval);
9902 if (left == 0)
9903 break;
9905 idx_prev = idx_cur;
9906 long long aval = computeAggrVal (fval_map, agrfn);
9907 res->store (tidx, aval);
9909 delete key_seen;
9910 delete fval_map;
9911 delete flt_expr;
9912 delete func_expr;
9913 return res;
9916 Vector<char*> *
9917 dbeGetLineInfo (Obj pc)
9919 DbeInstr *instr = (DbeInstr*) pc;
9920 if (instr == NULL || instr->get_type () != Histable::INSTR)
9921 return NULL;
9922 DbeLine *dbeline = (DbeLine*) instr->convertto (Histable::LINE);
9923 const char *fname = dbeline ? dbeline->sourceFile->get_name () : NTXT ("");
9924 char lineno[16];
9925 *lineno = '\0';
9926 if (dbeline != NULL)
9927 snprintf (lineno, sizeof (lineno), NTXT ("%d"), dbeline->lineno);
9928 Vector<char*> *res = new Vector<char*>(2);
9929 res->store (0, strdup (fname));
9930 res->store (1, strdup (lineno));
9931 return res;
9935 dbeSetAlias (char *name, char *uname, char *expr)
9937 char *res = dbeSession->indxobj_define (name, uname, expr, NULL, NULL);
9938 return res == NULL ? 0 : 1;
9941 Vector<char*> *
9942 dbeGetAlias (char *name)
9944 Vector<char*> *res = new Vector<char*>;
9945 int idx = dbeSession->findIndexSpaceByName (name);
9946 if (idx >= 0)
9948 char *str = dbeSession->getIndexSpaceDescr (idx);
9949 res->append (dbe_strdup (str));
9950 str = dbeSession->getIndexSpaceExprStr (idx);
9951 res->append (dbe_strdup (str));
9953 return res;
9956 static int
9957 key_cmp (const void *p1, const void *p2)
9959 long long ll1 = *(long long*) p1;
9960 long long ll2 = *(long long*) p2;
9961 return ll1 < ll2 ? -1 : ll1 > ll2 ? 1 : 0;
9964 Vector<Vector<long long>*> *
9965 dbeGetXYPlotData (
9966 int data_id, // data table id
9967 char *lfilter, // local filter expression
9968 char *arg, // name for the argument
9969 char *func1, // expression for the first axis (x)
9970 char *aggr1, // aggregation function for func1: "SUM","CNT",...
9971 char *func2, // expression for the second axis (y)
9972 char *aggr2, // aggregation function for func2
9973 char *func3, // expression for the third axis (color)
9974 char *aggr3) // aggregation function for func3
9976 Vector<Vector<long long>*> *res = new Vector<Vector<long long>*>;
9977 Experiment *exp = dbeSession->get_exp (0);
9978 if (exp == NULL)
9979 return res;
9980 if (exp->get_status () == Experiment::INCOMPLETE)
9981 exp->update ();
9983 DataDescriptor *dataDscr = exp->get_raw_events (data_id);
9984 if (dataDscr == NULL)
9985 return res;
9987 // Parse all expressions
9988 Vector<Expression*> *funcs = new Vector<Expression*>;
9989 Vector<Aggr_type> *aggrs = new Vector<Aggr_type>;
9990 Vector<DefaultMap<long long, long long>*> *fval_maps =
9991 new Vector<DefaultMap<long long, long long>*>;
9992 Vector<DefaultMap<long long, long>*> *cnt_maps =
9993 new Vector<DefaultMap<long long, long>*>;
9994 if (func1 != NULL)
9996 Expression *expr = dbeSession->ql_parse (func1);
9997 funcs->append (expr);
9998 aggrs->append (getAggrFunc (aggr1));
9999 fval_maps->append (new DefaultMap<long long, long long>);
10000 cnt_maps->append (new DefaultMap<long long, long>);
10001 res->append (new Vector<long long>);
10002 if (func2 != NULL)
10004 expr = dbeSession->ql_parse (func2);
10005 funcs->append (expr);
10006 aggrs->append (getAggrFunc (aggr2));
10007 fval_maps->append (new DefaultMap<long long, long long>);
10008 cnt_maps->append (new DefaultMap<long long, long>);
10009 res->append (new Vector<long long>);
10010 if (func3 != NULL)
10012 expr = dbeSession->ql_parse (func3);
10013 funcs->append (expr);
10014 aggrs->append (getAggrFunc (aggr3));
10015 fval_maps->append (new DefaultMap<long long, long long>);
10016 cnt_maps->append (new DefaultMap<long long, long>);
10017 res->append (new Vector<long long>);
10021 if (funcs->size () == 0)
10023 funcs->destroy ();
10024 delete funcs;
10025 fval_maps->destroy ();
10026 delete fval_maps;
10027 cnt_maps->destroy ();
10028 delete cnt_maps;
10029 delete aggrs;
10030 return res;
10032 Expression *arg_expr = NULL;
10033 if (arg != NULL)
10034 arg_expr = dbeSession->ql_parse (arg);
10035 if (arg_expr == NULL)
10037 funcs->destroy ();
10038 delete funcs;
10039 fval_maps->destroy ();
10040 delete fval_maps;
10041 cnt_maps->destroy ();
10042 delete cnt_maps;
10043 delete aggrs;
10044 return res;
10046 Expression *flt_expr = NULL;
10047 if (lfilter != NULL)
10048 flt_expr = dbeSession->ql_parse (lfilter);
10049 Vector<long long> *kidx_map = new Vector<long long>(); // key_idx -> key_val
10050 for (long i = 0; i < dataDscr->getSize (); i++)
10052 Expression::Context ctx (dbeSession->getView (0), exp, NULL, i);
10053 // First use the filter
10054 if (flt_expr != NULL)
10055 if (flt_expr->eval (&ctx) == 0)
10056 continue;
10058 // Compute the argument
10059 long long key = arg_expr->eval (&ctx);
10060 if (kidx_map->find (key) == -1)
10061 kidx_map->append (key);
10062 for (long j = 0; j < funcs->size (); ++j)
10064 Expression *func = funcs->fetch (j);
10065 Aggr_type aggr = aggrs->fetch (j);
10066 DefaultMap<long long, long long> *fval_map = fval_maps->fetch (j);
10067 DefaultMap<long long, long> *cnt_map = cnt_maps->fetch (j);
10068 long long fval = func->eval (&ctx);
10069 long long aval = fval_map->get (key);
10070 long cnt = cnt_map->get (key);
10071 switch (aggr)
10073 case AGGR_NONE:
10074 case AGGR_FAIR:
10075 if (cnt == 0)
10076 aval = fval;
10077 break;
10078 case AGGR_MAX:
10079 if (aval < fval || cnt == 0)
10080 aval = fval;
10081 break;
10082 case AGGR_MIN:
10083 if (aval > fval || cnt == 0)
10084 aval = fval;
10085 break;
10086 case AGGR_CNT:
10087 aval = cnt + 1;
10088 break;
10089 case AGGR_SUM:
10090 case AGGR_AVG:
10091 aval += fval;
10092 break;
10094 cnt_map->put (key, cnt + 1);
10095 fval_map->put (key, aval);
10098 kidx_map->sort (key_cmp);
10100 // Finalize aggregation, prepare result
10101 for (long j = 0; j < funcs->size (); ++j)
10103 Aggr_type aggr = aggrs->fetch (j);
10104 Vector<long long> *resj = res->fetch (j);
10105 DefaultMap<long long, long long> *
10106 fval_map = fval_maps->fetch (j);
10107 DefaultMap<long long, long> *
10108 cnt_map = cnt_maps->fetch (j);
10109 for (int kidx = 0; kidx < kidx_map->size (); ++kidx)
10111 long long key = kidx_map->fetch (kidx);
10112 long long aval = fval_map->get (key);
10113 if (aggr == AGGR_AVG)
10115 long cnt = cnt_map->get (key);
10116 if (cnt > 0)
10117 aval = (aval + cnt / 2) / cnt;
10119 resj->append (aval);
10122 delete flt_expr;
10123 funcs->destroy ();
10124 delete funcs;
10125 delete aggrs;
10126 delete arg_expr;
10127 delete kidx_map;
10128 fval_maps->destroy ();
10129 delete fval_maps;
10130 cnt_maps->destroy ();
10131 delete cnt_maps;
10132 return res;
10135 /* ********************************************************************* */
10136 /* Routines for use by Collector GUI */
10138 * Returns signal value for provided name. Example of name: "SIGUSR1"
10139 * @param signal
10140 * @return value
10143 dbeGetSignalValue (char *signal)
10145 int ret = -1;
10146 if (signal == NULL)
10147 return ret;
10148 if (strcmp (signal, "SIGUSR1") == 0)
10149 return (SIGUSR1);
10150 if (strcmp (signal, "SIGUSR2") == 0)
10151 return (SIGUSR2);
10152 if (strcmp (signal, "SIGPROF") == 0)
10153 return (SIGPROF);
10154 return ret;
10157 char *
10158 dbeSendSignal (pid_t p, int signum)
10160 int ret = kill (p, signum);
10161 if (p == 0 || p == -1)
10162 return (dbe_sprintf (GTXT ("kill of process %d not supported\n"), p));
10163 if (ret == 0)
10164 return NULL;
10165 char *msg = dbe_sprintf (GTXT ("kill(%d, %d) failed: %s\n"), p, signum,
10166 strerror (errno));
10167 return msg;
10170 char *
10171 dbeGetCollectorControlValue (char *control)
10173 if (control == NULL)
10174 return NULL;
10175 if (col_ctr == NULL)
10176 col_ctr = new Coll_Ctrl (1);
10177 char *msg = col_ctr->get (control);
10178 return msg;
10181 char *
10182 dbeSetCollectorControlValue (char *control, char * value)
10184 if (control == NULL)
10185 return NULL;
10186 if (col_ctr == NULL)
10187 col_ctr = new Coll_Ctrl (1);
10188 char *msg = col_ctr->set (control, value);
10189 return msg;
10192 char *
10193 dbeUnsetCollectorControlValue (char *control)
10195 if (control == NULL)
10196 return NULL;
10197 if (col_ctr == NULL)
10198 col_ctr = new Coll_Ctrl (1);
10199 char *msg = col_ctr->unset (control);
10200 return msg;
10203 void
10204 dbeSetLocation (const char *fname, const char *location)
10206 Vector<SourceFile*> *sources = dbeSession->get_sources ();
10207 for (long i = 0, sz = sources ? sources->size () : 0; i < sz; i++)
10209 SourceFile *src = sources->get (i);
10210 DbeFile *df = src->dbeFile;
10211 if (df && (strcmp (fname, df->get_name ()) == 0))
10213 df->find_file ((char *) location);
10214 break;
10219 void
10220 dbeSetLocations (Vector<const char *> *fnames, Vector<const char *> *locations)
10222 if (fnames == NULL || locations == NULL
10223 || fnames->size () != locations->size ())
10224 return;
10225 for (long i = 0, sz = fnames->size (); i < sz; i++)
10226 dbeSetLocation (fnames->get (i), locations->get (i));
10229 Vector<void*> *
10230 dbeResolvedWith_setpath (const char *path)
10232 Vector<char*> *names = new Vector<char*>();
10233 Vector<char*> *pathes = new Vector<char*>();
10234 Vector<long long> *ids = new Vector<long long>();
10235 Vector<SourceFile*> *sources = dbeSession->get_sources ();
10236 for (long i = 0, sz = sources ? sources->size () : 0; i < sz; i++)
10238 SourceFile *src = sources->get (i);
10239 DbeFile *df = src->dbeFile;
10240 if (df == NULL || (df->filetype & DbeFile::F_FICTION) != 0)
10241 continue;
10242 char *fnm = df->get_name ();
10243 if ((df->filetype & (DbeFile::F_JAVACLASS | DbeFile::F_JAVA_SOURCE)) != 0)
10245 char *jnm = dbe_sprintf (NTXT ("%s/%s"), path, fnm);
10246 if (df->check_access (jnm) == DbeFile::F_FILE)
10248 names->append (dbe_strdup (fnm));
10249 pathes->append (jnm);
10250 ids->append (src->id);
10251 continue;
10253 free (jnm);
10255 char *nm = dbe_sprintf (NTXT ("%s/%s"), path, get_basename (fnm));
10256 if (df->check_access (nm) == DbeFile::F_FILE)
10258 names->append (dbe_strdup (fnm));
10259 pathes->append (nm);
10260 ids->append (src->id);
10261 continue;
10263 free (nm);
10265 if (names->size () != 0)
10267 Vector<void*> *data = new Vector<void*>(3);
10268 data->append (names);
10269 data->append (pathes);
10270 data->append (ids);
10271 return data;
10273 return NULL;
10276 Vector<void*> *
10277 dbeResolvedWith_pathmap (const char *old_prefix, const char *new_prefix)
10279 size_t len = strlen (old_prefix);
10280 Vector<char*> *names = new Vector<char*>();
10281 Vector<char*> *pathes = new Vector<char*>();
10282 Vector<long long> *ids = new Vector<long long>();
10283 Vector<SourceFile*> *sources = dbeSession->get_sources ();
10284 for (long i = 0, sz = sources ? sources->size () : 0; i < sz; i++)
10286 SourceFile *src = sources->get (i);
10287 DbeFile *df = src->dbeFile;
10288 if (df == NULL || (df->filetype & DbeFile::F_FICTION) != 0)
10289 continue;
10290 char *fnm = df->get_name ();
10291 if (strncmp (old_prefix, fnm, len) == 0
10292 && (fnm[len] == '/' || fnm[len] == '\0'))
10294 char *nm = dbe_sprintf (NTXT ("%s/%s"), new_prefix, fnm + len);
10295 if (df->check_access (nm) == DbeFile::F_FILE)
10297 names->append (dbe_strdup (fnm));
10298 pathes->append (nm);
10299 ids->append (src->id);
10300 continue;
10302 if ((df->filetype & DbeFile::F_JAVA_SOURCE) != 0)
10304 free (nm);
10305 nm = dbe_sprintf (NTXT ("%s/%s"), new_prefix, fnm);
10306 if (df->check_access (nm) == DbeFile::F_FILE)
10308 names->append (dbe_strdup (fnm));
10309 pathes->append (nm);
10310 ids->append (src->id);
10311 continue;
10314 free (nm);
10317 if (names->size () != 0)
10319 Vector<void*> *data = new Vector<void*>(3);
10320 data->append (names);
10321 data->append (pathes);
10322 data->append (ids);
10323 return data;
10325 return NULL;
10328 void
10329 dbe_archive (Vector<long long> *ids, Vector<const char *> *locations)
10331 if (ids == NULL || locations == NULL || ids->size () != locations->size ())
10332 return;
10333 Experiment *exp = dbeSession->get_exp (0);
10334 if (exp == NULL)
10335 return;
10336 Vector<SourceFile*> *sources = dbeSession->get_sources ();
10337 for (long i1 = 0, sz1 = ids->size (); i1 < sz1; i1++)
10339 long long id = ids->get (i1);
10340 for (long i = 0, sz = sources ? sources->size () : 0; i < sz; i++)
10342 SourceFile *src = sources->get (i);
10343 if (src->id == id)
10345 DbeFile *df = src->dbeFile;
10346 if (df)
10348 char *fnm = df->find_file ((char *) locations->get (i1));
10349 if (fnm)
10351 char *nm = df->get_name ();
10352 char *anm = exp->getNameInArchive (nm, false);
10353 exp->copy_file (fnm, anm, true);
10354 free (anm);
10362 /* ************************************************************************ */
10364 /* Routines to check connection between Remote Analyzer Client and er_print */
10365 char *
10366 dbeCheckConnection (char *str)
10368 return dbe_strdup (str);