1 /* Copyright (C) 2021 Free Software Foundation, Inc.
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)
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. */
23 #include "Application.h"
24 #include "DbeSession.h"
25 #include "CallStack.h"
27 #include "DataObject.h"
28 #include "Experiment.h"
30 #include "FilterExp.h"
31 #include "FilterSet.h"
35 #include "DataSpace.h"
36 #include "MemorySpace.h"
37 #include "IOActivity.h"
38 #include "HeapActivity.h"
40 #include "MetricList.h"
43 #include "LoadObject.h"
44 #include "dbe_types.h"
45 #include "StringBuilder.h"
47 DbeView::DbeView (Application *_app, Settings *_settings, int _vindex)
51 settings = new Settings (_settings);
52 ptree = new PathTree (this);
53 dspace = new DataSpace (this);
54 memspaces = new Vector<MemorySpace*>;
55 iospace = new IOActivity (this);
56 heapspace = new HeapActivity (this);
57 filters = new Vector<FilterSet*>;
58 lo_expands = new Vector<enum LibExpand>;
59 cur_filter_str = NULL;
60 prev_filter_str = NULL;
61 cur_filter_expr = NULL;
62 filter_active = false;
64 dataViews = new Vector<Vector<DataView*>*>;
71 marks = new Vector<int>;
72 marks2dsrc = new Vector<int_pair_t>;
73 marks2dsrc_inc = new Vector<int_pair_t>;
74 marks2ddis = new Vector<int_pair_t>;
75 marks2ddis_inc = new Vector<int_pair_t>;
78 // set the view's index
81 // clear the precomputed data
97 // and clear the selections
105 // Initialize index spaces
106 int sz = settings->get_IndxTabState ()->size ();
107 indxspaces = new Vector<PathTree*>(sz);
108 indx_data = new Vector<Hist_data*>(sz);
109 sel_idxobj = new Vector<Histable*>(sz);
110 for (int i = 0; i < sz; i++)
112 PathTree *is = new PathTree (this, i);
113 indxspaces->store (i, is);
114 indx_data->store (i, NULL);
115 sel_idxobj->store (i, NULL);
119 lobjectsNoJava = NULL;
121 // set lo_expands for already existing LoadObjects
124 Vector<LoadObject*> *lobjs = dbeSession->get_text_segments ();
125 Vec_loop (LoadObject*, lobjs, idx, lo)
127 lo_expands->store (lo->seg_idx, LIBEX_SHOW);
128 set_lo_expand (lo->seg_idx, LIBEX_SHOW);
133 DbeView::DbeView (DbeView *dbev, int _vindex)
137 settings = new Settings (dbev->settings);
138 ptree = new PathTree (this);
139 dspace = new DataSpace (this);
140 iospace = new IOActivity (this);
141 heapspace = new HeapActivity (this);
142 memspaces = new Vector<MemorySpace*>;
143 filters = new Vector<FilterSet*>;
144 lo_expands = new Vector<enum LibExpand>;
145 cur_filter_str = NULL;
146 prev_filter_str = NULL;
147 cur_filter_expr = NULL;
149 dataViews = new Vector<Vector<DataView*>*>;
156 marks = new Vector<int>;
157 marks2dsrc = new Vector<int_pair_t>;
158 marks2dsrc_inc = new Vector<int_pair_t>;
159 marks2ddis = new Vector<int_pair_t>;
160 marks2ddis_inc = new Vector<int_pair_t>;
163 // set the view's index
166 // clear the precomputed data
182 // and clear the selections
190 // create the vector of IndexSpaces
191 int sz = dbev->indxspaces->size ();
192 indxspaces = new Vector<PathTree*>(sz);
193 indx_data = new Vector<Hist_data*>(sz);
194 sel_idxobj = new Vector<Histable*>(sz);
195 for (int i = 0; i < sz; i++)
197 PathTree *is = new PathTree (this, i);
198 indxspaces->store (i, is);
199 indx_data->store (i, NULL);
200 sel_idxobj->store (i, NULL);
204 // now copy the relevant information from the original view
205 for (int i = 0; i < dbeSession->nexps (); i++)
206 add_experiment (i, dbev->get_exp_enable (i));
207 update_advanced_filter ();
209 lo_expands = dbev->lo_expands->copy ();
210 lobjectsNoJava = NULL;
223 free (cur_filter_str);
224 free (prev_filter_str);
225 delete cur_filter_expr;
226 for (int exp_id = 0; exp_id < dataViews->size (); ++exp_id)
228 Vector<DataView*> *expDataViewList = dataViews->fetch (exp_id);
229 Destroy (expDataViewList);
233 metrics_lists->destroy ();
234 delete metrics_lists;
235 metrics_ref_lists->destroy ();
236 delete metrics_ref_lists;
237 delete derived_metrics;
240 delete marks2dsrc_inc;
242 delete marks2ddis_inc;
245 indxspaces->destroy ();
248 indx_data->destroy ();
251 delete lobjectsNoJava;
258 reg_metrics = new Vector<BaseMetric*>;
259 metrics_lists = new Vector<MetricList*>;
260 metrics_ref_lists = new Vector<MetricList*>;
261 for (int i = 0; i <= MET_HEAP; i++)
263 metrics_lists->append (NULL);
264 metrics_ref_lists->append (NULL);
266 derived_metrics = new DerivedMetrics;
267 derived_metrics->add_definition (GTXT ("CPI"), GTXT ("Cycles Per Instruction"), GTXT ("cycles/insts"));
268 derived_metrics->add_definition (GTXT ("IPC"), GTXT ("Instructions Per Cycle"), GTXT ("insts/cycles"));
269 derived_metrics->add_definition (GTXT ("K_CPI"), GTXT ("Kernel Cycles Per Instruction"), GTXT ("K_cycles/K_insts"));
270 derived_metrics->add_definition (GTXT ("K_IPC"), GTXT ("Kernel Instructions Per Cycle"), GTXT ("K_insts/K_cycles"));
274 DbeView::set_libexpand (char *liblist, enum LibExpand flag)
276 bool changed = settings->set_libexpand (liblist, flag, false);
277 // Show/hide performance optimization:
278 // No need to call update_lo_expand for every library because dbev->set_libexpand()
279 // is called from a loop in Dbe.cc SetLoadObjectState for every load object.
280 // It is sufficient to call update_lo_expand() just once at the end of the loop.
281 // At all other places such as er_print.cc which calls specific set_libexpand()
282 // explicitly call update_lo_expands();
287 DbeView::set_libdefaults ()
289 bool changed = settings->set_libdefaults ();
291 update_lo_expands ();
296 DbeView::update_lo_expands ()
301 // search all load objects
302 Vector<LoadObject*> *lobjs = dbeSession->get_text_segments ();
303 Vec_loop (LoadObject*, lobjs, index, lo)
305 // now search the settings list for this one
306 enum LibExpand flag = settings->get_lo_setting (lo->get_pathname ());
307 set_lo_expand (lo->seg_idx, flag);
313 DbeView::get_lo_expand (int idx)
315 if (idx < lo_expands->size ())
316 return lo_expands->get (idx);
321 DbeView::set_lo_expand (int idx, enum LibExpand flag)
323 // LIBRARY_VISIBILITY
324 if (flag == LIBEX_HIDE)
327 dbeSession->set_lib_visibility_used ();
330 if (idx < lo_expands->size () && flag == get_lo_expand (idx))
332 setShowHideChanged (); // this is necessary if called from er_print
335 lo_expands->store (idx, flag);
337 // and reset the data
349 // reset all the per-experiment arrays
351 lo_expands->reset ();
352 free (cur_filter_str);
353 cur_filter_str = NULL;
354 free (prev_filter_str);
355 prev_filter_str = NULL;
356 delete cur_filter_expr;
357 cur_filter_expr = NULL;
359 for (int exp_id = 0; exp_id < dataViews->size (); ++exp_id)
361 Vector<DataView*> *expDataViewList = dataViews->fetch (exp_id);
363 expDataViewList->destroy ();
365 dataViews->destroy ();
368 // now reset any cached data
372 showHideChanged = false;
377 DbeView::reset_data (bool all)
379 // clear the precomputed data
380 if (func_data != NULL)
385 if (line_data != NULL)
395 if (src_data != NULL)
400 if (dis_data != NULL)
405 if (fitem_data != NULL)
420 if (dobj_data != NULL)
425 if (dlay_data != NULL)
430 if (iofile_data != NULL)
435 if (iovfd_data != NULL)
440 if (iocs_data != NULL)
445 if (heapcs_data != NULL)
451 // and reset the selections
458 // Set selected object <Total> if possible
459 Function * ft = dbeSession->get_Total_Function ();
468 // loop over MemorySpaces, resetting each one
469 for (long i = 0, sz = VecSize (memspaces); i < sz; i++)
471 MemorySpace *ms = memspaces->get (i);
475 // loop over IndexSpaces, resetting cached data
476 indx_data->destroy ();
477 for (long i = 0, sz = VecSize (indxspaces); i < sz; i++)
479 indx_data->store (i, NULL);
480 sel_idxobj->store (i, NULL);
484 Vector<BaseMetric*> *
485 DbeView::get_all_reg_metrics ()
487 Vector<BaseMetric*> *mlist = dbeSession->get_all_reg_metrics ();
492 DbeView::register_metric_expr (BaseMetric::Type type, char *cmd, char *expr_spec)
494 BaseMetric *bm = dbeSession->register_metric_expr (type, cmd, expr_spec);
499 DbeView::get_compare_metric (Metric *mtr, int groupNum)
501 if (groupNum == 0 || !mtr->comparable ())
502 return new Metric (*mtr);
503 ExpGroup *gr = dbeSession->expGroups->get (groupNum - 1);
505 snprintf (buf, sizeof (buf), NTXT ("EXPGRID==%d"), gr->groupId);
506 BaseMetric *bm = register_metric_expr (mtr->get_type (), mtr->get_cmd (), buf);
507 Metric *m = new Metric (bm, mtr->get_subtype ());
508 m->set_raw_visbits (mtr->get_visbits ());
509 if (m->legend == NULL)
510 m->legend = dbe_strdup (get_basename (gr->name));
515 DbeView::get_metric_ref (MetricType mtype)
517 if (metrics_ref_lists->fetch (MET_COMMON) == NULL)
519 Vector<BaseMetric*> *base_metrics = dbeSession->get_base_reg_metrics ();
520 metrics_ref_lists->store (MET_SRCDIS, new MetricList (base_metrics, MET_SRCDIS));
521 metrics_ref_lists->store (MET_COMMON, new MetricList (base_metrics, MET_COMMON));
522 metrics_ref_lists->store (MET_NORMAL, new MetricList (base_metrics, MET_NORMAL));
523 metrics_ref_lists->store (MET_CALL, new MetricList (base_metrics, MET_CALL));
524 metrics_ref_lists->store (MET_CALL_AGR, new MetricList (base_metrics, MET_CALL_AGR));
525 metrics_ref_lists->store (MET_DATA, new MetricList (base_metrics, MET_DATA));
526 metrics_ref_lists->store (MET_INDX, new MetricList (base_metrics, MET_INDX));
527 metrics_ref_lists->store (MET_IO, new MetricList (base_metrics, MET_IO));
528 metrics_ref_lists->store (MET_HEAP, new MetricList (base_metrics, MET_HEAP));
531 return metrics_ref_lists->fetch (mtype);
534 // logically, the function list must be created first, and it
535 // will create the other two;
537 DbeView::get_metric_list (MetricType mtype)
539 if (metrics_lists->fetch (MET_COMMON) == NULL)
541 Vector<BaseMetric*> *base_metrics = dbeSession->get_base_reg_metrics ();
542 metrics_lists->store (MET_SRCDIS, new MetricList (base_metrics, MET_SRCDIS));
543 metrics_lists->store (MET_COMMON, new MetricList (base_metrics, MET_COMMON));
544 metrics_lists->store (MET_NORMAL, new MetricList (base_metrics, MET_NORMAL));
545 metrics_lists->store (MET_CALL, new MetricList (base_metrics, MET_CALL));
546 metrics_lists->store (MET_CALL_AGR, new MetricList (base_metrics, MET_CALL_AGR));
547 metrics_lists->store (MET_DATA, new MetricList (base_metrics, MET_DATA));
548 metrics_lists->store (MET_INDX, new MetricList (base_metrics, MET_INDX));
549 metrics_lists->store (MET_IO, new MetricList (base_metrics, MET_IO));
550 metrics_lists->store (MET_HEAP, new MetricList (base_metrics, MET_HEAP));
554 if (settings->str_dmetrics == NULL)
555 settings->str_dmetrics = strdup (Command::DEFAULT_METRICS);
556 char *status = setMetrics (settings->str_dmetrics, true);
559 fprintf (stderr, "XXX setMetrics(\"%s\") failed: %s\n", settings->str_dmetrics, status);
563 // set the default sort
564 setSort (settings->str_dsort, MET_NORMAL, true);
566 return metrics_lists->fetch (mtype);
570 DbeView::get_metric_list (int dsptype, int subtype)
577 case DSP_SOURCE_DISASM:
578 mlist = get_metric_list (MET_COMMON);
579 mlist = new MetricList (mlist);
582 for (long i = 0, sz = mlist->size (); i < sz; i++)
584 Metric *m = mlist->get (i);
585 if (m->comparable ())
587 Metric *m1 = get_compare_metric (m, subtype);
595 mlist = get_metric_list (MET_NORMAL);
596 mlist = new MetricList (mlist);
603 DbeView::reset_metrics ()
605 for (int i = 0, sz = metrics_lists->size (); i < sz; i++)
607 delete metrics_lists->fetch (i);
608 metrics_lists->store (i, NULL);
610 for (int i = 0, sz = metrics_ref_lists->size (); i < sz; i++)
612 delete metrics_ref_lists->fetch (i);
613 metrics_ref_lists->store (i, NULL);
618 DbeView::comparingExperiments ()
620 if (dbeSession->expGroups->size () <= 1)
622 return 0 != (settings->get_compare_mode () & (CMP_DELTA | CMP_ENABLE | CMP_RATIO));
626 DbeView::set_compare_mode (int mode)
628 if (mode == get_compare_mode ())
630 settings->set_compare_mode (mode);
631 if (comparingExperiments ())
633 Vector<BaseMetric*> *bm_list = dbeSession->get_base_reg_metrics ();
634 for (int i = 0, sz = bm_list->size (); i < sz; i++)
636 BaseMetric *m = bm_list->fetch (i);
637 if (m->get_expr_spec () || !m->comparable ())
639 for (int i1 = 0, sz1 = dbeSession->expGroups->size (); i1 < sz1; i1++)
641 ExpGroup *gr = dbeSession->expGroups->fetch (i1);
643 snprintf (buf, sizeof (buf), NTXT ("EXPGRID==%d"), gr->groupId);
644 register_metric_expr (m->get_type (), m->get_cmd (), buf);
648 MetricList *mlist = get_metric_list (MET_NORMAL);
649 MetricList *gmlist = get_metric_list (MET_CALL);
650 MetricList *dmlist = get_metric_list (MET_DATA);
651 MetricList *imlist = get_metric_list (MET_INDX);
652 if (comparingExperiments ())
654 add_compare_metrics (mlist);
655 add_compare_metrics (gmlist);
656 add_compare_metrics (dmlist);
657 add_compare_metrics (imlist);
661 remove_compare_metrics (mlist);
662 remove_compare_metrics (gmlist);
663 remove_compare_metrics (dmlist);
664 remove_compare_metrics (imlist);
669 DbeView::ifreq (FILE *outfile)
671 if (!dbeSession->is_ifreq_available ())
673 fprintf (outfile, GTXT ("No instruction frequency data available\n"));
676 for (int index = 0; index < filters->size (); index++)
678 Experiment *exp = dbeSession->get_exp (index);
679 if (exp->broken || !get_exp_enable (index) || !exp->ifreqavail)
682 // this experiment has the data; print it
684 GTXT ("Instruction frequency data from experiment %s\n\n"),
685 exp->get_expt_name ());
686 fprintf (outfile, NTXT ("%s"), pr_mesgs (exp->fetch_ifreq (), "", ""));
690 // When adding multiple sub-experiments of an experiment, it is
691 // not necessary to do the following every-time. It is sufficient to call reset_metrics()
692 // and call get_metric_ref() and get_metric_list() in the end after all the sub-experiments
695 DbeView::add_experiment_epilogue ()
697 bool flag_LIBEX_HIDE = false;
698 bool flag_ShowHideChanged = false;
699 Vector<LoadObject*> *lobjs = dbeSession->get_LoadObjects ();
700 for (long i = lo_expands->size (), sz = lobjs ? lobjs->size () : 0; i < sz; i++)
702 flag_ShowHideChanged = true;
703 LoadObject *lo = lobjs->get (i);
704 enum LibExpand flag = settings->get_lo_setting (lo->get_pathname ());
705 if (flag == LIBEX_HIDE)
706 flag_LIBEX_HIDE = true;
707 lo_expands->store (lo->seg_idx, flag);
712 dbeSession->set_lib_visibility_used ();
714 if (flag_ShowHideChanged)
716 setShowHideChanged (); // this is necessary if called from er_print
721 (void) get_metric_ref (MET_NORMAL);
722 (void) get_metric_ref (MET_CALL);
723 (void) get_metric_ref (MET_CALL_AGR);
724 (void) get_metric_ref (MET_DATA);
725 (void) get_metric_ref (MET_INDX);
726 (void) get_metric_ref (MET_IO);
727 (void) get_metric_ref (MET_HEAP);
728 (void) get_metric_list (MET_NORMAL);
729 (void) get_metric_list (MET_CALL);
730 (void) get_metric_list (MET_CALL_AGR);
731 (void) get_metric_list (MET_DATA);
732 (void) get_metric_list (MET_INDX);
733 (void) get_metric_list (MET_IO);
734 (void) get_metric_list (MET_HEAP);
737 // When adding multiple sub-experiments of an experiment, avoid invoking the steps in
738 // add_experiment_epilogue() every time and instead call it separately in the end
739 // after all sub-experiments have been added
741 DbeView::add_subexperiment (int index, bool enabled)
743 // phaseIdx doesn't change, PathTree can handle adding
744 // new experiments without reset
746 // Set up the FilterSet for the experiments
747 Experiment *exp = dbeSession->get_exp (index);
748 FilterSet *filterset = new FilterSet (this, exp);
749 filterset->set_enabled (enabled);
750 filters->store (index, filterset);
752 assert (index == dataViews->size ());
753 Vector<DataView*> *expDataViewList = new Vector<DataView*>;
754 for (int data_id = 0; data_id < DATA_LAST; ++data_id)
755 expDataViewList->append (NULL); //experiment data_id's are not known yet
756 dataViews->store (index, expDataViewList);
760 DbeView::add_experiment (int index, bool enabled)
762 // phaseIdx doesn't change, PathTree can handle adding
763 // new experiments without reset
765 // delete any cached data
768 // Set up the FilterSet for the experiments
769 Experiment *exp = dbeSession->get_exp (index);
770 FilterSet *filterset = new FilterSet (this, exp);
771 filterset->set_enabled (enabled);
772 filters->store (index, filterset);
774 assert (index == dataViews->size ());
775 Vector<DataView*> *expDataViewList = new Vector<DataView*>;
776 for (int data_id = 0; data_id < DATA_LAST; ++data_id)
777 expDataViewList->append (NULL); //experiment data_id's are not known yet
778 dataViews->store (index, expDataViewList);
781 (void) get_metric_ref (MET_NORMAL);
782 (void) get_metric_ref (MET_CALL);
783 (void) get_metric_ref (MET_CALL_AGR);
784 (void) get_metric_ref (MET_DATA);
785 (void) get_metric_ref (MET_INDX);
786 (void) get_metric_ref (MET_IO);
787 (void) get_metric_ref (MET_HEAP);
788 (void) get_metric_list (MET_NORMAL);
789 (void) get_metric_list (MET_CALL);
790 (void) get_metric_list (MET_CALL_AGR);
791 (void) get_metric_list (MET_DATA);
792 (void) get_metric_list (MET_INDX);
793 (void) get_metric_list (MET_IO);
794 (void) get_metric_list (MET_HEAP);
798 DbeView::drop_experiment (int index)
801 filters->remove (index);
803 // reset any cached data
806 Vector<DataView*> *expDataViewList = dataViews->remove (index);
809 expDataViewList->destroy ();
810 delete expDataViewList;
815 DbeView::get_exp_enable (int n)
817 return filters ? filters->fetch (n)->get_enabled () : true;
821 DbeView::set_exp_enable (int n, bool e)
823 FilterSet *fs = filters->fetch (n);
824 if (fs->get_enabled () != e)
833 DbeView::reset_metric_list (MetricList *mlist, int cmp_mode)
835 MetricType mtype = mlist->get_type ();
840 delete metrics_lists->fetch (MET_COMMON);
841 metrics_lists->store (MET_COMMON, new MetricList (mlist));
842 remove_compare_metrics (metrics_lists->fetch (MET_COMMON));
844 // ignoring the following cases (why?)
857 settings->set_compare_mode (cmp_mode);
858 if (comparingExperiments ())
859 add_compare_metrics (mlist);
865 delete metrics_lists->fetch (mtype);
866 metrics_lists->store (mtype, mlist);
867 // fall through to next case
869 metrics_lists->fetch (MET_SRCDIS)->set_metrics (mlist);
870 metrics_lists->fetch (MET_CALL)->set_metrics (mlist);
871 metrics_lists->fetch (MET_CALL_AGR)->set_metrics (mlist);
872 remove_compare_metrics (metrics_lists->fetch (MET_CALL_AGR));
873 metrics_lists->fetch (MET_DATA)->set_metrics (mlist);
874 metrics_lists->fetch (MET_INDX)->set_metrics (mlist);
875 metrics_lists->fetch (MET_IO)->set_metrics (mlist);
876 metrics_lists->fetch (MET_HEAP)->set_metrics (mlist);
879 delete metrics_lists->fetch (MET_CALL_AGR);
880 metrics_lists->store (MET_CALL_AGR, mlist);
881 remove_compare_metrics (mlist);
889 delete metrics_lists->fetch (mtype);
890 metrics_lists->store (mtype, mlist);
899 DbeView::add_compare_metrics (MetricList *mlist)
901 if (mlist == NULL || !comparingExperiments ())
903 int sort_ref_index = mlist->get_sort_ref_index ();
904 Vector<Metric*> *items = mlist->get_items ();
905 Vector<Metric*> *newItems = new Vector<Metric*>();
906 int mode = get_compare_mode ();
908 if ((mode & CMP_DELTA) != 0)
909 cmp_vbits = VAL_DELTA;
910 else if ((mode & CMP_RATIO) != 0)
911 cmp_vbits = VAL_RATIO;
912 for (long i = 0, sz = items->size (); i < sz; i++)
914 Metric *mtr = items->get (i);
915 if (sort_ref_index == i)
916 mlist->set_sort_ref_index (newItems->size ());
917 int vbits = mtr->get_visbits () & ~(VAL_DELTA | VAL_RATIO);
918 mtr->set_raw_visbits (vbits);
919 if (!mtr->comparable ())
921 newItems->append (mtr);
924 if (mtr->get_expr_spec ())
926 if (strcmp (mtr->get_expr_spec (), NTXT ("EXPGRID==1")) != 0)
928 if ((cmp_vbits & VAL_RATIO) != 0)
929 // for ratios, make sure VAL_TIMEVAL is off and VAL_VALUE is on
930 mtr->set_raw_visbits ((vbits | VAL_VALUE | cmp_vbits) & ~VAL_TIMEVAL);
933 int ind = mlist->get_listorder (mtr->get_cmd (), mtr->get_subtype (), NTXT ("EXPGRID==1"));
935 // take VAL_VALUE and VAL_TIMEVAL from base experiment
936 mtr->set_raw_visbits (cmp_vbits
937 | (vbits & ~(VAL_VALUE | VAL_TIMEVAL))
938 | (mlist->get (ind)->get_visbits ()
939 & (VAL_VALUE | VAL_TIMEVAL)));
941 mtr->set_raw_visbits (cmp_vbits | vbits);
944 newItems->append (mtr);
947 for (long i1 = 0, sz1 = dbeSession->expGroups->size (); i1 < sz1; i1++)
949 Metric *m = get_compare_metric (mtr, i1 + 1);
950 switch (m->get_vtype ())
955 m->set_raw_visbits (vbits);
959 m->set_raw_visbits (vbits);
960 else if (cmp_vbits == VAL_RATIO
961 && ((vbits & (VAL_VALUE | VAL_TIMEVAL))
962 == (VAL_VALUE | VAL_TIMEVAL)))
963 // make ratios for VAL_VALUE only
964 m->set_raw_visbits ((vbits | VAL_VALUE | cmp_vbits) & ~VAL_TIMEVAL);
966 m->set_raw_visbits (vbits | cmp_vbits);
969 newItems->append (m);
973 items->addAll (newItems);
980 DbeView::get_compare_mlist (MetricList *met_list, int grInd)
982 MetricList *mlist = new MetricList (met_list->get_type ());
983 mlist->set_sort_ref_index (met_list->get_sort_ref_index ());
984 mlist->set_sort_rev (met_list->get_sort_rev ());
986 Vector<Metric*> *items_old = met_list->get_items ();
987 for (int i = 0, sz = items_old->size (); i < sz; i++)
989 Metric *m = get_compare_metric (items_old->get (i), grInd + 1);
996 DbeView::remove_compare_metrics (MetricList *mlist)
998 Vector<Metric*> *items = mlist->get_items ();
999 Vector<Metric*> *items_old = items->copy ();
1001 int sort_index = mlist->get_sort_ref_index ();
1002 mlist->set_sort_ref_index (0);
1003 for (int i = 0, sz = items_old->size (); i < sz; i++)
1005 Metric *m = items_old->fetch (i);
1006 if (m->get_expr_spec () == NULL)
1008 // this is a 'non-compare' metric; add it
1010 if (sort_index == i)
1011 mlist->set_sort_ref_index (items->size () - 1);
1014 // is the 'non-compare' version of the metric already in the list?
1015 int ind = mlist->get_listorder (m->get_cmd (), m->get_subtype ());
1018 // not in the list; add it
1019 BaseMetric *bm = dbeSession->find_metric (m->get_type (), m->get_cmd (), NULL);
1020 Metric *new_met = new Metric (bm, m->get_subtype ());
1021 new_met->set_raw_visbits (m->get_visbits () & ~(CMP_DELTA | CMP_RATIO));
1022 items->append (new_met);
1023 if (sort_index == i)
1024 mlist->set_sort_ref_index (items->size () - 1);
1032 // setMetrics -- set the metric list according to specification
1033 // The previous sort is preserved, if possible
1034 // Otherwise, the default sort setting is used
1035 // Returns NULL if OK, or an error string if not
1036 //YXXX only MET_NORMAL appears to be used... code could be simplified
1038 DbeView::setMetrics (char *mspec, bool fromRcFile)
1041 MetricType mtype = MET_NORMAL;
1042 // note that setting the default is done here, while all else is in MetricList
1043 if (mspec == NULL) abort ();
1044 if (strcasecmp (mspec, Command::DEFAULT_CMD) == 0)
1046 mspec = settings->get_default_metrics ();
1049 MetricList *mlist = get_metric_list (mtype);
1050 mlist = new MetricList (mlist);
1051 ret = mlist->set_metrics (mspec, fromRcFile, derived_metrics);
1058 delete metrics_lists->fetch (MET_COMMON);
1059 metrics_lists->store (MET_COMMON, new MetricList (mlist));
1061 // ignoring the following cases (why?)
1071 add_compare_metrics (mlist);
1073 //YXXX looks like cut/paste code here, see reset_metric_list()
1077 delete metrics_lists->fetch (mtype);
1078 metrics_lists->store (mtype, mlist);
1079 //YXXX is lack of break intentional? If so, add comment...
1081 metrics_lists->fetch (MET_SRCDIS)->set_metrics (mlist);
1082 metrics_lists->fetch (MET_CALL)->set_metrics (mlist);
1083 metrics_lists->fetch (MET_CALL_AGR)->set_metrics (mlist);
1084 remove_compare_metrics (metrics_lists->fetch (MET_CALL_AGR));
1085 metrics_lists->fetch (MET_DATA)->set_metrics (mlist);
1086 metrics_lists->fetch (MET_INDX)->set_metrics (mlist);
1087 metrics_lists->fetch (MET_IO)->set_metrics (mlist);
1088 metrics_lists->fetch (MET_HEAP)->set_metrics (mlist);
1091 delete metrics_lists->fetch (MET_CALL_AGR);
1092 metrics_lists->store (MET_CALL_AGR, mlist);
1093 remove_compare_metrics (mlist);
1101 delete metrics_lists->fetch (mtype);
1102 metrics_lists->store (mtype, mlist);
1115 // Set Sort by name (er_print)
1117 DbeView::setSort (char * sort_list, MetricType mtype, bool fromRcFile)
1119 MetricList *mlist = NULL;
1121 // note that setting the default is done here, while all else is in MetricList
1122 if ((sort_list == NULL) || (strcmp (sort_list, Command::DEFAULT_CMD) == 0))
1124 if (settings->str_dsort == NULL)
1125 settings->str_dsort = strdup (Command::DEFAULT_METRICS);
1126 sort_list = settings->get_default_sort ();
1128 mlist = get_metric_list (mtype);
1134 char *ret = mlist->set_sort (sort_list, fromRcFile);
1138 // now resort all cached data
1143 // Set sort from the visible index (Analyzer)
1145 DbeView::setSort (int visindex, MetricType mtype, bool reverse)
1147 MetricList *mlist = get_metric_list (mtype);
1148 Vector<Metric*> *items = mlist->get_items ();
1149 if (visindex >= items->size ())
1151 mlist->set_sort (visindex, reverse);
1153 if (mtype == MET_NORMAL)
1156 MetricList *mlist_cc = get_metric_list (MET_CALL);
1157 Vector<Metric*> *items_cc = mlist_cc->get_items ();
1158 for (int i = 0; i < items_cc->size (); i++)
1160 char * name_cc = items_cc->fetch (i)->get_username ();
1161 char * name_normal = items->fetch (visindex)->get_username ();
1162 if (0 == strncmp (name_cc, name_normal, strlen (name_cc)))
1170 mlist_cc->set_sort (idx_cc, reverse);
1171 resortData (MET_CALL);
1172 // Change a sort metric for MET_CALL_AGR
1173 Metric *m = items_cc->fetch (idx_cc);
1174 MetricList *cList = get_metric_list (MET_CALL_AGR);
1175 Metric *m1 = cList->find_metric (m->get_cmd (), m->get_subtype ());
1177 cList->set_sort_metric (m1->get_cmd (), m1->get_subtype (), reverse);
1180 if (mtype == MET_CALL)
1183 MetricList *mlist_norm = get_metric_list (MET_NORMAL);
1184 Vector<Metric*> *items_norm = mlist_norm->get_items ();
1185 for (int i = 0; i < items_norm->size (); i++)
1187 char * name_norm = items_norm->fetch (i)->get_username ();
1188 char * name_cc = items->fetch (visindex)->get_username ();
1189 if (mlist_norm->get_sort_ref_index () == i
1190 && 0 == strncmp (name_norm, name_cc, strlen (name_norm)))
1198 for (int i = 0; i < items_norm->size (); i++)
1200 char * name_norm = items_norm->fetch (i)->get_username ();
1201 char * name_cc = items->fetch (visindex)->get_username ();
1202 if (0 == strncmp (name_norm, name_cc, strlen (name_norm)))
1211 mlist_norm->set_sort (idx_norm, reverse);
1212 resortData (MET_NORMAL);
1214 // Change a sort metric for MET_CALL_AGR
1215 Metric *m = items->fetch (visindex);
1216 MetricList *cList = get_metric_list (MET_CALL_AGR);
1217 Metric *m1 = cList->find_metric (m->get_cmd (), m->get_subtype ());
1219 cList->set_sort_metric (m1->get_cmd (), m1->get_subtype (), reverse);
1224 DbeView::resortData (MetricType mtype)
1229 MetricList *mlist = get_metric_list (mtype);
1233 if (func_data != NULL)
1234 func_data->resort (mlist);
1235 if (line_data != NULL)
1236 line_data->resort (mlist);
1237 if (pc_data != NULL)
1238 pc_data->resort (mlist);
1242 if (fitem_data != NULL)
1243 fitem_data->resort (mlist);
1244 if (callers != NULL)
1245 callers->resort (mlist);
1246 if (callees != NULL)
1247 callees->resort (mlist);
1250 if (dobj_data != NULL)
1251 dobj_data->resort (mlist);
1252 if (dlay_data != NULL)
1259 Vec_loop (Hist_data*, indx_data, idx, data)
1262 data->resort (mlist);
1266 if (iofile_data != NULL)
1267 iofile_data->resort (mlist);
1268 if (iovfd_data != NULL)
1269 iovfd_data->resort (mlist);
1270 if (iocs_data != NULL)
1271 iocs_data->resort (mlist);
1274 if (heapcs_data != NULL)
1275 heapcs_data->resort (mlist);
1283 // Get the sort metric name
1285 DbeView::getSort (MetricType mtype)
1287 MetricList *mlist = get_metric_list (mtype);
1288 return mlist->get_sort_name ();
1291 // Get the sort command (to use for resetting)
1293 DbeView::getSortCmd (MetricType mtype)
1295 MetricList *mlist = get_metric_list (mtype);
1296 return mlist->get_sort_cmd ();
1300 DbeView::get_sel_ind (Histable *selObj, int type, int subtype)
1328 case DSP_IOACTIVITY:
1334 case DSP_IOCALLSTACK:
1337 case DSP_HEAPCALLSTACK:
1342 data = get_indxobj_data (subtype);
1348 if (data == NULL || data->get_status () != Hist_data::SUCCESS)
1350 Vector<Hist_data::HistItem*> *hi_data = data->get_hist_items ();
1351 for (int i = 0, sz = hi_data->size (); i < sz; i++)
1353 Hist_data::HistItem *hi = hi_data->fetch (i);
1354 if (hi->obj == selObj)
1361 DbeView::get_metric_list (MetricType mtype, bool compare, int gr_num)
1366 case MET_COMMON:// comparison mode, src & disasm views
1368 {// signifies same src file (or load obj) used by all groups
1369 // show compare metrics in columns (not in separate source panels)
1370 mlist = get_metric_list (MET_NORMAL);
1373 // once source panel per group; get metrics for this group
1374 mlist = get_metric_list (mtype);
1377 mlist = get_compare_mlist (mlist, gr_num - 1);
1378 int mode = get_compare_mode ();
1379 if ((mode & (CMP_DELTA | CMP_RATIO)) != 0)
1381 for (long i = 0, sz = mlist->size (); i < sz; i++)
1383 Metric *m = mlist->get (i);
1384 char *expr_spec = m->get_expr_spec ();
1385 if (expr_spec && (strcmp (expr_spec, NTXT ("EXPGRID==1")) != 0))
1387 int vbits = m->get_visbits () & ~(VAL_DELTA | VAL_RATIO);
1388 if ((mode & CMP_RATIO) != 0)
1390 else if ((mode & CMP_DELTA) != 0)
1392 m->set_raw_visbits (vbits);
1399 mlist = get_metric_list (mtype);
1406 DbeView::get_data (MetricList *mlist, Histable *selObj, int type, int subtype)
1413 mlist = new MetricList (mlist);
1414 func_data = get_hist_data (mlist, Histable::FUNCTION, subtype, Hist_data::ALL);
1418 mlist = new MetricList (mlist);
1419 line_data = get_hist_data (mlist, Histable::LINE, subtype, Hist_data::ALL);
1423 mlist = new MetricList (mlist);
1424 pc_data = get_hist_data (mlist, Histable::INSTR, subtype, Hist_data::ALL);
1428 dobj_data = get_hist_data (mlist, Histable::DOBJECT, subtype,
1432 return get_hist_data (mlist, Histable::MEMOBJ, subtype, Hist_data::ALL);
1434 data = get_hist_data (mlist, Histable::INDEXOBJ, subtype, Hist_data::ALL);
1435 indx_data->store (subtype, data);
1440 data = get_hist_data (mlist, Histable::DOBJECT, subtype,
1442 // .. provides metric data for layout
1443 dlay_data = get_data_space ()->get_layout_data (data, marks,
1448 callers = get_hist_data (mlist, Histable::FUNCTION, subtype,
1449 Hist_data::CALLERS, selObj);
1453 callees = get_hist_data (mlist, Histable::FUNCTION, subtype,
1454 Hist_data::CALLEES, selObj);
1457 // Center Function item
1459 fitem_data = get_hist_data (mlist, Histable::FUNCTION, subtype,
1460 Hist_data::SELF, selObj);
1467 // Source or disassembly
1470 error_msg = status_str (DBEVIEW_NO_SEL_OBJ);
1473 Function *func = (Function *) selObj->convertto (Histable::FUNCTION);
1476 error_msg = dbe_strdup (GTXT ("Not a real function; no source or disassembly available."));
1479 if (func->flags & FUNC_FLAG_SIMULATED)
1481 error_msg = dbe_strdup (GTXT ("Not a real function; no source or disassembly available."));
1484 if (func->get_name () == NULL)
1486 error_msg = dbe_strdup (GTXT ("Source location not recorded in experiment"));
1489 Module *module = func->module;
1490 if (module == NULL || module->get_name () == NULL)
1492 error_msg = dbe_strdup (GTXT ("Object name not recorded in experiment"));
1496 SourceFile *srcContext = (SourceFile *) selObj->convertto (Histable::SOURCEFILE);
1499 if (func_data == NULL)
1500 func_data = get_hist_data (mlist, Histable::FUNCTION, subtype, Hist_data::ALL);
1502 // for source and disassembly the name needs to be invisible,
1503 // but that's handled in the module code
1504 if (type == DSP_SOURCE || type == DSP_SOURCE_V2)
1506 marks2dsrc->reset ();
1507 marks2dsrc_inc->reset ();
1509 data = src_data = module->get_data (this, mlist, Histable::LINE,
1510 func_data->get_totals ()->value, srcContext, func,
1511 marks, get_thresh_src (), get_src_compcom (),
1512 get_src_visible (), get_hex_visible (),
1513 false, false, marks2dsrc, marks2dsrc_inc);
1516 { /* type == DSP_DISASM */
1517 marks2ddis->reset ();
1518 marks2ddis_inc->reset ();
1520 data = dis_data = module->get_data (this, mlist, Histable::INSTR,
1521 func_data->get_totals ()->value, srcContext, func,
1522 marks, get_thresh_dis (), get_dis_compcom (),
1523 get_src_visible (), get_hex_visible (),
1524 get_func_scope (), false, marks2ddis,
1536 DbeView::get_compare_obj (Histable *obj)
1539 switch (obj->get_type ())
1541 case Histable::LINE:
1542 nm = obj->get_name ();
1545 if (dbeSession->comp_dbelines == NULL)
1546 dbeSession->comp_dbelines = new HashMap<char*, DbeLine*>;
1547 return dbeSession->comp_dbelines->get (nm, (DbeLine*) obj);
1548 case Histable::SOURCEFILE:
1549 nm = obj->get_name ();
1552 nm = get_basename (nm);
1553 if (dbeSession->comp_sources == NULL)
1554 dbeSession->comp_sources = new HashMap<char*, SourceFile*>;
1555 return dbeSession->comp_sources->get (nm, (SourceFile*) obj);
1557 return obj->get_compare_obj ();
1563 // get_hist_data() creates a new Hist_data object;
1564 // it's caller's responsibility to delete it.
1566 DbeView::get_hist_data (MetricList *mlist_orig, Histable::Type type,
1567 int subtype, Hist_data::Mode mode, Histable *obj,
1568 Histable *context, Vector<Histable*> *sel_objs,
1569 PathTree::PtreeComputeOption flag)
1571 Vector<Histable*> *objs = NULL;
1574 objs = new Vector<Histable*>();
1577 Hist_data *res = get_hist_data (mlist_orig, type, subtype, mode, objs, context, sel_objs, flag);
1583 DbeView::get_hist_data (MetricList *mlist_orig, Histable::Type type,
1584 int subtype, Hist_data::Mode mode,
1585 Vector<Histable*> *objs,
1586 Histable *context, Vector<Histable*> *sel_objs,
1587 PathTree::PtreeComputeOption flag)
1589 MetricList *mlist = new MetricList (mlist_orig);
1591 * mlist differs from mlist_orig in two ways:
1592 * - extra metrics have been added as needed to compute derived metrics
1593 * - extra metrics have been added as needed to compute time for HWC (time converted) metrics
1594 * (We don't drop those extra metrics but we don't display they to user.)
1595 * - visibility bits have been added for compare mode (e.g., VAL_DELTA or VAL_RATIO)
1596 * (We want to preserve those visbits.)
1598 // loop over mlist to add missing dependencies for derived metrics
1599 for (long i = 0, sz = mlist->get_items ()->size (); i < sz; i++)
1601 Metric *m = mlist->get_items ()->fetch (i);
1602 char *expr_spec = m->get_expr_spec ();
1603 if (expr_spec && (strcmp (expr_spec, NTXT ("EXPGRID==1")) != 0))
1605 int ind = mlist->get_listorder (m->get_cmd (), m->get_subtype (), NTXT ("EXPGRID==1"));
1608 BaseMetric *bm1 = dbeSession->find_metric (m->get_type (), m->get_cmd (), NTXT ("EXPGRID==1"));
1609 Metric *m1 = new Metric (bm1, m->get_subtype ());
1610 m1->set_dmetrics_visbits (VAL_VALUE);
1616 for (long i = 0, sz = mlist->get_items ()->size (); i < sz; i++)
1618 Metric *m = mlist->get_items ()->fetch (i);
1619 if (m->get_type () == BaseMetric::DERIVED)
1621 Definition *def = m->get_definition ();
1622 Vector<BaseMetric*> *dependencies = def->get_dependencies ();
1623 long *map = def->get_map ();
1624 for (long i1 = 0, sz1 = dependencies ? dependencies->size () : 0; i1 < sz1; i1++)
1626 BaseMetric *bm = dependencies->fetch (i1);
1627 int ind = mlist->get_listorder (bm->get_cmd (), m->get_subtype (), m->get_expr_spec ());
1630 BaseMetric *bm1 = dbeSession->find_metric (bm->get_type (), bm->get_cmd (), m->get_expr_spec ());
1631 assert (bm1 != NULL);
1632 Metric *m1 = new Metric (bm1, m->get_subtype ());
1633 m1->set_dmetrics_visbits (VAL_VALUE);
1634 ind = mlist->size ();
1640 else if (m->get_type () == BaseMetric::HWCNTR)
1642 if (m->is_tvisible () && m->get_dependent_bm ())
1644 int ii = mlist->get_listorder (m->get_dependent_bm ()->get_cmd (),
1645 m->get_subtype (), m->get_expr_spec ());
1648 BaseMetric *bm1 = dbeSession->find_metric (m->get_type (),
1649 m->get_dependent_bm ()->get_cmd (),
1650 m->get_expr_spec ());
1651 assert (bm1 != NULL);
1652 Metric *m1 = new Metric (bm1, m->get_subtype ());
1653 m1->set_dmetrics_visbits ((m->get_visbits ()
1654 & ~VAL_VALUE) | VAL_TIMEVAL);
1661 // compute Hist_data
1665 case Histable::INSTR:
1666 case Histable::LINE:
1667 data = ptree->compute_metrics (mlist, type, mode, objs, context, sel_objs);
1669 case Histable::FUNCTION:
1670 case Histable::MODULE:
1671 case Histable::LOADOBJECT:
1672 data = ptree->compute_metrics (mlist, type, mode, objs, NULL,
1675 case Histable::DOBJECT:
1676 data = dspace->compute_metrics (mlist, type, mode,
1677 objs ? objs->fetch (0) : NULL);
1679 case Histable::MEMOBJ:
1680 case Histable::INDEXOBJ:
1681 data = indxspaces->get (subtype)->compute_metrics (mlist, type, mode,
1684 case Histable::IOACTFILE:
1687 data = iofile_data = iospace->compute_metrics (mlist, type, mode,
1693 data = iospace->compute_metrics (mlist, type, mode, objs->fetch (0));
1696 case Histable::IOACTVFD:
1698 data = iovfd_data = iospace->compute_metrics (mlist, type, mode, NULL);
1700 data = iospace->compute_metrics (mlist, type, mode, objs->fetch (0));
1702 case Histable::IOCALLSTACK:
1704 data = iocs_data = iospace->compute_metrics (mlist, type, mode, NULL);
1706 data = iospace->compute_metrics (mlist, type, mode, objs->fetch (0));
1708 case Histable::HEAPCALLSTACK:
1710 data = heapcs_data = heapspace->compute_metrics (mlist, type, mode, NULL);
1712 data = heapspace->compute_metrics (mlist, type, mode, objs->fetch (0));
1718 for (long i = mlist_orig->get_items ()->size (),
1719 sz = mlist->get_items ()->size (); i < sz; i++)
1721 Metric *m = mlist->get_items ()->get (i);
1722 m->set_dmetrics_visbits (VAL_HIDE_ALL | m->get_visbits ());
1725 data->nmetrics = mlist_orig->size ();
1730 DbeView::get_mobj_name (int subtype)
1732 MemorySpace *ms = getMemorySpace (subtype);
1734 ms = addMemorySpace (subtype);
1735 return ms->getMemObjTypeName ();
1739 DbeView::getMemorySpace (int subtype)
1741 for (long i = 0, sz = VecSize (memspaces); i < sz; i++)
1743 MemorySpace *ms = memspaces->get (i);
1744 if (subtype == ms->getMemObjType ())
1751 DbeView::addMemorySpace (int subtype)
1753 MemorySpace *ms = new MemorySpace (this, subtype);
1754 memspaces->append (ms);
1759 DbeView::get_indxobj_data (int subtype)
1761 if (subtype < 0 || subtype >= indx_data->size ())
1763 return indx_data->fetch (subtype);
1767 DbeView::set_indxobj_sel (int subtype, int sel_ind)
1769 Hist_data *data = get_indxobj_data (subtype);
1772 if (sel_ind >= 0 && sel_ind < data->size ())
1774 Histable *obj = data->fetch (sel_ind)->obj;
1775 sel_idxobj->store (subtype, obj);
1780 DbeView::get_indxobj_sel (int subtype)
1782 return sel_idxobj->fetch (subtype);
1786 DbeView::addIndexSpace (int subtype)
1788 PathTree *is = new PathTree (this, subtype);
1789 indxspaces->store (subtype, is);
1790 indx_data->store (subtype, NULL);
1791 sel_idxobj->store (subtype, NULL);
1792 settings->indxobj_define (subtype, false);
1796 DbeView::get_sel_obj_io (uint64_t id, Histable::Type type)
1798 if (iospace == NULL)
1800 Histable *obj = NULL;
1801 Hist_data *data = NULL;
1804 case Histable::IOACTFILE:
1807 case Histable::IOACTVFD:
1810 case Histable::IOCALLSTACK:
1819 Vector<Hist_data::HistItem*> *hi_data = data->get_hist_items ();
1820 int size = hi_data->size ();
1821 for (int i = 0; i < size; i++)
1823 Hist_data::HistItem *hi = hi_data->fetch (i);
1824 if (hi->obj != NULL && (uint64_t) hi->obj->id == id)
1834 DbeView::get_sel_obj_heap (uint64_t id)
1836 if (heapspace == NULL || heapcs_data == NULL)
1838 Histable *obj = NULL;
1839 Hist_data *data = heapcs_data;
1840 Vector<Hist_data::HistItem*> *hi_data = data->get_hist_items ();
1841 int size = hi_data->size ();
1842 for (int i = 0; i < size; i++)
1844 Hist_data::HistItem *hi = hi_data->fetch (i);
1845 if ((hi->obj != NULL) && ((uint64_t) hi->obj->id) == id)
1855 DbeView::get_cstack_data (MetricList *mlist)
1857 return ptree->get_cstack_data (mlist);
1861 DbeView::get_stats_data (int index)
1863 DataView *packets = get_filtered_events (index, DATA_SAMPLE);
1864 if (packets == NULL)
1866 return new Stats_data (packets);
1870 DbeView::get_ovw_data (int index)
1872 DataView *packets = get_filtered_events (index, DATA_SAMPLE);
1873 Experiment* exp = dbeSession->get_exp (index);
1874 hrtime_t starttime = 0;
1876 starttime = exp->getStartTime ();
1877 if (packets == NULL)
1879 return new Ovw_data (packets, starttime);
1883 DbeView::set_filter (const char *filter_spec)
1885 if (dbe_strcmp (filter_spec, cur_filter_str) == 0) // Nothing was changed
1888 // if string is NULL, delete the filter
1889 if (filter_spec == NULL)
1893 free (cur_filter_str);
1894 cur_filter_str = NULL;
1896 if (cur_filter_expr)
1898 delete cur_filter_expr;
1899 cur_filter_expr = NULL;
1901 noParFilter = false;
1907 // process the filter
1908 Expression *expr = dbeSession->ql_parse (filter_spec);
1910 return dbe_sprintf (GTXT ("Invalid filter specification `%s'\n"), filter_spec);
1912 if (dbe_strcmp (filter_spec, "1") == 0)
1913 noParFilter = false;
1914 else if (sel_obj != NULL)
1915 if (sel_obj->get_type () == Histable::LINE)
1916 if (expr->verifyObjectInExpr (sel_obj))
1920 if (cur_filter_str != NULL)
1922 free (prev_filter_str);
1923 prev_filter_str = dbe_strdup (cur_filter_str);
1925 free (cur_filter_str);
1926 cur_filter_str = dbe_strdup (filter_spec);
1927 delete cur_filter_expr;
1928 cur_filter_expr = expr;
1935 DbeView::get_FilterExp (Experiment *exp)
1937 if (cur_filter_expr == NULL)
1939 Expression::Context *ctx = new Expression::Context (this, exp);
1940 return new FilterExp (cur_filter_expr, ctx, noParFilter);
1944 DbeView::get_filter ()
1946 return dbe_strdup (cur_filter_str);
1950 DbeView::get_filter_set (int n)
1953 if (n >= filters->size ())
1955 return ( filters->fetch (n));
1958 Vector<FilterNumeric*> *
1959 DbeView::get_all_filters (int nexp)
1961 FilterSet *fs = get_filter_set (nexp);
1962 return fs ? fs->get_all_filters () : NULL;
1966 DbeView::get_FilterNumeric (int nexp, int idx)
1968 FilterSet *fs = get_filter_set (nexp);
1969 return fs ? fs->get_filter (idx) : NULL;
1973 DbeView::backtrack_filter()
1975 if (prev_filter_str != NULL)
1976 set_filter(prev_filter_str);
1977 else set_filter("1"); // reset
1982 DbeView::update_advanced_filter ()
1984 char *s = get_advanced_filter ();
1985 if (dbe_strcmp (s, cur_filter_str))
1988 char *err_msg = set_filter (s);
1992 fprintf (stderr, NTXT ("ERROR: Advanced Filter: '%s'\n"), err_msg);
2000 DbeView::set_pattern (int n, Vector<char *> *pattern_str, bool *error)
2002 Vector<FilterNumeric*> *filts = get_all_filters (n);
2006 int imax = pattern_str->size ();
2007 if (imax > filts->size ())
2008 imax = filts->size ();
2009 for (int i = 0; i < imax; i++)
2011 FilterNumeric *f = filts->fetch (i);
2012 char *s = pattern_str->fetch (i);
2015 if (f->set_pattern (s, error))
2019 if (ret || cur_filter_expr)
2021 update_advanced_filter ();
2022 filter_active = true;
2028 append_experiments (StringBuilder *sb, int first, int last)
2032 if (sb->length () != 0)
2033 sb->append (NTXT (" || "));
2037 sb->append (NTXT ("EXPID=="));
2042 sb->append (NTXT ("EXPID>="));
2044 sb->append (NTXT (" && EXPID<="));
2051 DbeView::get_advanced_filter ()
2054 bool wasFalse = false;
2055 int first = -1, last = -1;
2056 for (int n = 0, nexps = dbeSession->nexps (); n < nexps; n++)
2058 FilterSet *fs = get_filter_set (n);
2059 char *s = fs->get_advanced_filter ();
2062 if (streq (s, NTXT ("1")))
2069 append_experiments (&sb, first, last);
2071 if (streq (s, NTXT ("0")))
2076 if (sb.length () != 0)
2077 sb.append (NTXT (" || "));
2078 sb.append (NTXT ("(EXPID=="));
2080 sb.append (NTXT (" && ("));
2083 sb.append (NTXT ("))"));
2094 append_experiments (&sb, first, last);
2097 if (sb.length () == 0)
2098 sb.append (wasFalse ? '0' : '1');
2100 append_experiments (&sb, first, last);
2101 return sb.toString ();
2105 DbeView::set_pattern (int m, char *pattern)
2109 // Store original setting in case of error
2110 int nexps = dbeSession->nexps ();
2111 int orig_phaseIdx = phaseIdx;
2112 bool *orig_enable = new bool[nexps];
2113 char **orig_pattern = new char*[nexps];
2114 for (int i = 0; i < nexps; i++)
2116 orig_pattern[i] = get_FilterNumeric (i, m)->get_pattern ();
2117 orig_enable[i] = get_exp_enable (i);
2118 set_exp_enable (i, false);
2121 // Copy the pattern so that we could safely modify it
2122 char *buf = dbe_strdup (pattern);
2123 FilterNumeric *fexp = NULL;
2126 for (bool done = false; !done; pe++)
2130 // experiment filter;
2132 fexp = new FilterNumeric (NULL, NULL, NULL);
2133 fexp->set_range (1, nexps, nexps);
2134 fexp->set_pattern (pb, &error);
2139 else if (*pe == '+' || *pe == '\0')
2146 for (int i = 0; i < nexps; i++)
2148 if (!fexp || fexp->is_selected (i + 1))
2150 FilterNumeric *f = get_FilterNumeric (i, m);
2151 f->set_pattern (pb, &error);
2154 set_exp_enable (i, true);
2167 for (int i = 0; i < nexps; i++)
2170 set_exp_enable (i, orig_enable[i]);
2171 FilterNumeric *f = get_FilterNumeric (i, m);
2172 f->set_pattern (orig_pattern[i], &err);
2173 free (orig_pattern[i]);
2175 phaseIdx = orig_phaseIdx;
2179 update_advanced_filter ();
2180 filter_active = true;
2182 delete[] orig_enable;
2183 delete[] orig_pattern;
2190 DbeView::set_view_mode (VMode newmode)
2192 if (newmode != settings->get_view_mode ())
2195 // For OpenMP, the expert mode path-tree is already present with the user mode
2196 // No need to increase the phaseIdx to trigger recomputation of path-tree
2197 // if we toggle between user and expert modes
2198 if (!(dbeSession->is_omp_available ()
2199 && ((newmode == VMODE_EXPERT
2200 && settings->get_view_mode () == VMODE_USER)
2201 || (newmode == VMODE_USER
2202 && settings->get_view_mode () == VMODE_EXPERT))))
2203 phaseIdx++; // For all other cases
2205 settings->set_view_mode (newmode);
2210 DbeView::set_view_mode (char *str, bool fromRC)
2212 VMode old = settings->get_view_mode ();
2213 Cmd_status ret = settings->set_view_mode (str, fromRC);
2214 if (old != settings->get_view_mode ())
2220 DbeView::set_en_desc (char *str, bool fromRC)
2223 Settings *s = dbeSession->get_settings ();
2224 s->set_en_desc (str, fromRC);
2226 // and tell our settings
2227 return settings->set_en_desc (str, fromRC);
2230 // Get processor stats messages
2232 DbeView::get_processor_msg (int type)
2234 if (ptree == NULL) // if no PathTree, no messages
2238 Emsg *m = (type == PSTAT_MSG) ? ptree->fetch_stats () : ptree->fetch_warnings ();
2239 for (; m != NULL; m = m->next)
2241 char* newmsg = m->get_msg ();
2246 if (type == PSTAT_MSG)
2247 ptree->delete_stats ();
2249 ptree->delete_warnings ();
2250 return (sb.length () > 0) ? sb.toString () : NULL;
2254 DbeView::dump_nodes (FILE *outfile)
2256 FILE *f = (outfile == NULL ? stderr : outfile);
2260 // Dump the clock profile events
2262 DbeView::dump_profile (FILE *out_file)
2264 for (int idx = 0; idx < dbeSession->nexps (); idx++)
2266 Experiment *exp = dbeSession->get_exp (idx);
2267 VMode view_mode = get_view_mode ();
2268 char * stateNames [/*LMS_NUM_STATES*/] = LMS_STATE_STRINGS;
2270 // Process clock profile date
2271 DataView *packets = get_filtered_events (idx, DATA_CLOCK);
2272 if (packets && packets->getSize () != 0)
2274 hrtime_t start = exp->getStartTime ();
2276 GTXT ("\nTotal Clock Profiling Packets: %d Experiment: %s\n"),
2277 (int) packets->getSize (), exp->get_expt_name ());
2278 for (long i = 0; i < packets->getSize (); i++)
2280 hrtime_t expr_ts = (hrtime_t) packets->getLongValue (PROP_TSTAMP, i);
2281 hrtime_t ts = expr_ts - start;
2283 // get the properties from the packet
2284 uint32_t thrid = (uint32_t) packets->getIntValue (PROP_THRID, i);
2285 uint32_t cpuid = (uint32_t) packets->getIntValue (PROP_CPUID, i);
2286 int mstate = (int) packets->getIntValue (PROP_MSTATE, i);
2287 int nticks = (int) packets->getIntValue (PROP_NTICK, i);
2291 if (mstate >= 0 && mstate < LMS_NUM_STATES)
2292 sname = stateNames[mstate];
2295 snprintf (buf, sizeof (buf), NTXT ("Unexpected mstate = %d"), mstate);
2299 // get the stack IGNORE HIDE
2300 Vector<Histable*> *stack = getStackPCs (view_mode, packets, i);
2301 int stack_size = stack->size ();
2303 // print the packet header with the count of stack frames
2305 GTXT ("#%6ld: %lld, %3lld.%09lld (%4lld.%09lld) t = %d, cpu = %d, frames = %d\n"),
2306 i, expr_ts, ts / NANOSEC, ts % NANOSEC,
2307 expr_ts / NANOSEC, expr_ts % NANOSEC,
2308 thrid, cpuid, stack_size);
2310 GTXT (" mstate = %d (%s), nticks = %d\n"),
2311 mstate, sname, nticks);
2313 // dump the callstack
2314 for (int j = stack_size - 1; j >= 0; j--)
2316 Histable *frame = stack->fetch (j);
2317 fprintf (out_file, GTXT (" %s [0x%016llx]\n"), frame->get_name (), (long long) frame);
2319 fprintf (out_file, "\n");
2324 GTXT ("\nNo Clock Profiling Packets in Experiment: %s\n"),
2325 exp->get_expt_name ());
2329 // Dump the sync trace events
2331 DbeView::dump_sync (FILE *out_file)
2333 for (int idx = 0; idx < dbeSession->nexps (); idx++)
2335 Experiment *exp = dbeSession->get_exp (idx);
2336 VMode view_mode = get_view_mode ();
2338 // Process heap trace date
2339 DataView *packets = get_filtered_events (idx, DATA_SYNCH);
2340 if (packets && packets->getSize () != 0)
2342 hrtime_t start = exp->getStartTime ();
2344 GTXT ("\nTotal Synctrace Packets: %d Experiment: %s\n"),
2345 (int) packets->getSize (), exp->get_expt_name ());
2347 for (long i = 0; i < packets->getSize (); i++)
2349 hrtime_t expr_ts = (hrtime_t) packets->getLongValue (PROP_TSTAMP, i);
2350 hrtime_t ts = expr_ts - start;
2352 // get the properties from the packet
2353 uint32_t thrid = (uint32_t) packets->getIntValue (PROP_THRID, i);
2354 uint32_t cpuid = (uint32_t) packets->getIntValue (PROP_CPUID, i);
2355 uint64_t syncobj = (uint64_t) packets->getLongValue (PROP_SOBJ, i);
2356 hrtime_t syncrtime = (uint64_t) packets->getLongValue (PROP_SRQST, i);
2357 hrtime_t syncdelay = expr_ts - syncrtime;
2359 // get the stack IGNORE HIDE
2360 Vector<Histable*> *stack = getStackPCs (view_mode, packets, i);
2361 int stack_size = stack->size ();
2363 // print the packet header with the count of stack frames
2365 GTXT ("#%6ld: %lld, %3lld.%09lld (%4lld.%09lld) t = %d, cpu = %d, frames = %d\n"),
2366 i, expr_ts, ts / NANOSEC, ts % NANOSEC,
2367 expr_ts / NANOSEC, expr_ts % NANOSEC, thrid,
2370 GTXT (" synchronization object @ 0x%016llx; synchronization delay %3lld.%09lld\n"),
2371 (unsigned long long) syncobj, (long long) (syncdelay / NANOSEC), (long long) (syncdelay % NANOSEC));
2373 // dump the callstack
2374 for (int j = stack_size - 1; j >= 0; j--)
2376 Histable *frame = stack->fetch (j);
2377 fprintf (out_file, GTXT (" %s [0x%016llx]\n"), frame->get_name (), (long long) frame);
2379 fprintf (out_file, "\n");
2383 fprintf (out_file, GTXT ("\nNo Synctrace Packets in Experiment: %s\n"),
2384 exp->get_expt_name ());
2388 // Dump the IO trace events
2390 DbeView::dump_iotrace (FILE *out_file)
2392 for (int idx = 0; idx < dbeSession->nexps (); idx++)
2394 Experiment *exp = dbeSession->get_exp (idx);
2395 VMode view_mode = get_view_mode ();
2397 // Process IO trace date
2398 DataView *packets = get_filtered_events (idx, DATA_IOTRACE);
2399 if (packets && packets->getSize () != 0)
2401 hrtime_t start = exp->getStartTime ();
2403 GTXT ("\nTotal IO trace Packets: %d Experiment: %s\n"),
2404 (int) packets->getSize (), exp->get_expt_name ());
2405 for (long i = 0; i < packets->getSize (); i++)
2407 hrtime_t expr_ts = (hrtime_t) packets->getLongValue (PROP_TSTAMP, i);
2408 hrtime_t ts = expr_ts - start;
2410 // get the properties from the packet
2411 uint32_t thrid = (uint32_t) packets->getIntValue (PROP_THRID, i);
2412 uint32_t cpuid = (uint32_t) packets->getIntValue (PROP_CPUID, i);
2413 IOTrace_type iotrtype = (IOTrace_type) packets->getIntValue (PROP_IOTYPE, i);
2414 uint32_t iofd = (uint32_t) packets->getIntValue (PROP_IOFD, i);
2415 uint64_t ionbyte = (uint64_t) packets->getIntValue (PROP_IONBYTE, i);
2416 hrtime_t iorqst = (hrtime_t) packets->getLongValue (PROP_IORQST, i);
2417 uint32_t ioofd = (uint32_t) packets->getIntValue (PROP_IOOFD, i);
2418 FileSystem_type iofstype = (FileSystem_type) packets->getIntValue (PROP_CPUID, i);
2419 int64_t iovfd = (int64_t) packets->getIntValue (PROP_IOVFD, i);
2422 StringBuilder *sb = (StringBuilder*) packets->getObjValue (PROP_IOFNAME, i);
2423 if (sb != NULL && sb->length () > 0)
2424 fName = sb->toString ();
2426 // get the stack IGNORE HIDE
2427 Vector<Histable*> *stack = getStackPCs (view_mode, packets, i);
2428 int stack_size = stack->size ();
2429 const char *iotrname;
2433 iotrname = "ReadTrace";
2436 iotrname = "WriteTrace";
2439 iotrname = "OpenTrace";
2442 iotrname = "CloseTrace";
2445 iotrname = "OtherIOTrace";
2447 case READ_TRACE_ERROR:
2448 iotrname = "ReadTraceError";
2450 case WRITE_TRACE_ERROR:
2451 iotrname = "WriteTraceError";
2453 case OPEN_TRACE_ERROR:
2454 iotrname = "OpenTraceError";
2456 case CLOSE_TRACE_ERROR:
2457 iotrname = "CloseTraceError";
2459 case OTHERIO_TRACE_ERROR:
2460 iotrname = "OtherIOTraceError";
2463 iotrname = "UnknownIOTraceType";
2467 // print the packet header with the count of stack frames
2469 GTXT ("#%6ld: %lld, %3lld.%09lld (%4lld.%09lld) t = %d, cpu = %d, frames = %d\n"),
2470 i, expr_ts, ts / NANOSEC, ts % NANOSEC,
2471 expr_ts / NANOSEC, expr_ts % NANOSEC,
2472 thrid, cpuid, stack_size);
2474 GTXT (" %s: fd = %d, ofd = %d, vfd = %lld, fstype = %d, rqst = %3lld.%09lld\n"),
2475 iotrname, (int) iofd, (int) ioofd, (long long) iovfd,
2476 (int) iofstype, (long long) (iorqst / NANOSEC),
2477 (long long) (iorqst % NANOSEC));
2478 fprintf (out_file, GTXT (" filename = `%s', nbytes = %d\n"),
2479 STR (fName), (int) ionbyte);
2482 // dump the callstack
2483 for (int j = stack_size - 1; j >= 0; j--)
2485 Histable *frame = stack->fetch (j);
2486 fprintf (out_file, GTXT (" %s [0x%016llx]\n"), frame->get_name (), (long long) frame);
2488 fprintf (out_file, "\n");
2492 fprintf (out_file, GTXT ("\nNo IO trace Packets in Experiment: %s\n"),
2493 exp->get_expt_name ());
2497 // Dump the HWC Profiling events
2499 DbeView::dump_hwc (FILE *out_file)
2501 for (int idx = 0; idx < dbeSession->nexps (); idx++)
2503 Experiment *exp = dbeSession->get_exp (idx);
2504 VMode view_mode = get_view_mode ();
2506 // Dump HWC profiling data
2507 DataView *packets = get_filtered_events (idx, DATA_HWC);
2508 if (packets && packets->getSize () != 0)
2510 hrtime_t start = exp->getStartTime ();
2512 GTXT ("\nTotal HW Counter Profiling Packets: %d Experiment: %s\n"),
2513 (int) packets->getSize (), exp->get_expt_name ());
2514 for (long i = 0; i < packets->getSize (); i++)
2516 const char * hwc_name;
2517 hrtime_t expr_ts = (hrtime_t) packets->getLongValue (PROP_TSTAMP, i);
2518 hrtime_t ts = expr_ts - start;
2519 uint32_t tag = (uint32_t) packets->getIntValue (PROP_HWCTAG, i);
2520 uint32_t thrid = (uint32_t) packets->getIntValue (PROP_THRID, i);
2521 uint32_t cpuid = (uint32_t) packets->getIntValue (PROP_CPUID, i);
2523 // This will work even with a different counter in every packet.
2524 if (tag < 0 || tag >= MAX_HWCOUNT
2525 || !exp->coll_params.hw_aux_name[tag])
2526 // if the packet has an invalid tag, use <invalid> as its name
2527 hwc_name = "<invalid>";
2529 hwc_name = exp->coll_params.hw_aux_name[tag];
2530 int64_t mval = packets->getLongValue (PROP_HWCINT, i);
2531 const char *err = HWCVAL_HAS_ERR (mval) ? " $$" : "";
2533 // get the stack IGNORE HIDE
2534 Vector<Histable*> *stack = getStackPCs (view_mode, packets, i);
2535 int stack_size = stack->size ();
2537 // print the packet header with the count of stack frames
2539 GTXT ("#%6ld: %lld, %3lld.%09lld (%4lld.%09lld) t = %d, cpu = %d, frames = %d\n count = %10lld (0x%016llx), tag = %d (%s)%s\n"),
2540 (long) i, (long long) expr_ts,
2541 (long long) (ts / NANOSEC), (long long) (ts % NANOSEC),
2542 (long long) (expr_ts / NANOSEC), (long long) (expr_ts % NANOSEC),
2543 (int) thrid, (int) cpuid, (int) stack_size,
2544 (long long) (HWCVAL_CLR_ERR (mval)), (long long) mval,
2545 (int) tag, hwc_name, err);
2547 // dump extended HWC packets values
2548 uint64_t va = (uint64_t) packets->getLongValue (PROP_VADDR, i);
2549 uint64_t pa = (uint64_t) packets->getLongValue (PROP_PADDR, i);
2550 fprintf (out_file, GTXT (" va = 0x%016llx, pa = 0x%016llx\n"),
2551 (unsigned long long) va, (unsigned long long) pa);
2553 // dump the callstack
2554 for (int j = stack_size - 1; j >= 0; j--)
2556 Histable *frame = stack->fetch (j);
2557 fprintf (out_file, GTXT (" %s [0x%016llx]\n"), frame->get_name (), (long long) frame);
2559 fprintf (out_file, "\n");
2564 GTXT ("\nNo HWC Profiling Packets in Experiment: %s\n"),
2565 exp->get_expt_name ());
2569 // Dump the Heap events
2571 DbeView::dump_heap (FILE *out_file)
2573 char *heapstrings[] = HEAPTYPE_STATE_USTRINGS;
2574 for (int idx = 0; idx < dbeSession->nexps (); idx++)
2576 Experiment *exp = dbeSession->get_exp (idx);
2577 VMode view_mode = get_view_mode ();
2579 // Process heap trace date
2580 DataView *packets = get_filtered_events (idx, DATA_HEAP);
2581 if (packets && packets->getSize () != 0)
2583 hrtime_t start = exp->getStartTime ();
2584 fprintf (out_file, GTXT ("\nTotal Heaptrace Packets: %d Experiment: %s\n"),
2585 (int) packets->getSize (), exp->get_expt_name ());
2586 for (long i = 0; i < packets->getSize (); i++)
2588 hrtime_t expr_ts = (hrtime_t) packets->getLongValue (PROP_TSTAMP, i);
2589 hrtime_t ts = expr_ts - start;
2591 // get the properties from the packet
2592 uint32_t thrid = (uint32_t) packets->getIntValue (PROP_THRID, i);
2593 uint32_t cpuid = (uint32_t) packets->getIntValue (PROP_CPUID, i);
2594 uint32_t heaptype = (uint32_t) packets->getIntValue (PROP_HTYPE, i);
2595 uint64_t heapsize = (uint64_t) packets->getULongValue (PROP_HSIZE, i);
2596 uint64_t heapvaddr = (uint64_t) packets->getULongValue (PROP_HVADDR, i);
2597 uint64_t heapovaddr = (uint64_t) packets->getULongValue (PROP_HOVADDR, i);
2598 if (heaptype == MUNMAP_TRACE)
2600 heapsize = (uint64_t) packets->getULongValue (PROP_HOVADDR, i);
2604 // get the stack IGNORE HIDE
2605 Vector<Histable*> *stack = getStackPCs (view_mode, packets, i);
2606 int stack_size = stack->size ();
2608 // print the packet header with the count of stack frames
2610 GTXT ("#%6ld: %lld, %3lld.%09lld (%4lld.%09lld) t = %d, cpu = %d, frames = %d\n"),
2611 i, expr_ts, ts / NANOSEC, ts % NANOSEC,
2612 expr_ts / NANOSEC, expr_ts % NANOSEC,
2613 thrid, cpuid, stack_size);
2614 char *typestr = heapstrings[heaptype];
2616 GTXT (" type = %d (%s), size = %llu (0x%llx), VADDR = 0x%016llx, OVADDR = 0x%016llx\n"),
2617 (int) heaptype, typestr, (long long unsigned int) heapsize,
2618 (long long unsigned int) heapsize,
2619 (long long unsigned int) heapvaddr,
2620 (long long unsigned int) heapovaddr);
2622 // dump the callstack
2623 for (int j = stack_size - 1; j >= 0; j--)
2625 Histable *frame = stack->fetch (j);
2626 fprintf (out_file, GTXT (" %s [0x%016llx]\n"), frame->get_name (), (long long) frame);
2628 fprintf (out_file, "\n");
2632 fprintf (out_file, GTXT ("\nNo Heaptrace Packets in Experiment: %s\n"),
2633 exp->get_expt_name ());
2637 // Dump the Java garbage collector events
2639 DbeView::dump_gc_events (FILE *out_file)
2641 for (int idx = 0; idx < dbeSession->nexps (); idx++)
2643 Experiment *exp = dbeSession->get_exp (idx);
2646 GTXT ("# No GC events in experiment %d, %s (PID %d, %s)\n"),
2647 idx, exp->get_expt_name (), exp->getPID (), exp->utargname);
2650 Vector<GCEvent*> *gce = exp->get_gcevents ();
2651 GCEvent *this_event;
2654 GTXT ("# %li events in experiment %d: %s (PID %d, %s)\n"),
2656 exp->get_expt_name (), exp->getPID (), exp->utargname);
2658 GTXT ("# exp:idx GC_start, GC_end, GC_duration\n"));
2659 Vec_loop (GCEvent*, gce, index, this_event)
2661 hrtime_t start = this_event->start - exp->getStartTime ();
2662 hrtime_t end = this_event->end - exp->getStartTime ();
2663 hrtime_t delta = this_event->end - this_event->start;
2665 "%5d:%d, %3lld.%09lld, %3lld.%09lld, %3lld.%09lld\n",
2667 (long long) (start / NANOSEC), (long long) (start % NANOSEC),
2668 (long long) (end / NANOSEC), (long long) (end % NANOSEC),
2669 (long long) (delta / NANOSEC), (long long) (delta % NANOSEC));
2676 DbeView::purge_events (int n)
2681 lst = filters->size ();
2683 lst = n > filters->size () ? filters->size () : n + 1;
2684 for (int i = n == -1 ? 0 : n; i < lst; i++)
2686 Vector<DataView*> *expDataViewList = dataViews->fetch (i);
2687 if (expDataViewList)
2689 // clear out all the data_ids, but don't change the vector size
2690 for (int data_id = 0; data_id < expDataViewList->size (); ++data_id)
2692 delete expDataViewList->fetch (data_id);
2693 expDataViewList->store (data_id, NULL);
2697 filter_active = false;
2701 // LIBRARY_VISIBILITY
2703 DbeView::resetAndConstructShowHideStacks ()
2705 for (int n = 0, nexps = dbeSession->nexps (); n < nexps; n++)
2707 Experiment *exp = dbeSession->get_exp (n);
2709 resetAndConstructShowHideStack (exp);
2713 // LIBRARY_VISIBILITY
2715 DbeView::resetAndConstructShowHideStack (Experiment *exp)
2717 exp->resetShowHideStack ();
2718 /* Vector<DataDescriptor*> *dDscrs = */ exp->getDataDescriptors ();
2721 // Construct show hide stack only for objects which have call stacks
2722 // list below similar to path tree. What about HEAP_SZ? (DBFIXME)
2723 dd = exp->get_raw_events (DATA_CLOCK);
2725 constructShowHideStack (dd, exp);
2726 dd = exp->get_raw_events (DATA_SYNCH);
2728 constructShowHideStack (dd, exp);
2729 dd = exp->get_raw_events (DATA_IOTRACE);
2731 constructShowHideStack (dd, exp);
2732 dd = exp->get_raw_events (DATA_HWC);
2734 constructShowHideStack (dd, exp);
2735 dd = exp->get_raw_events (DATA_HEAP);
2737 constructShowHideStack (dd, exp);
2738 dd = exp->get_raw_events (DATA_RACE);
2740 constructShowHideStack (dd, exp);
2741 dd = exp->get_raw_events (DATA_DLCK);
2743 constructShowHideStack (dd, exp);
2746 // LIBRARY_VISIBILITY
2748 DbeView::constructShowHideStack (DataDescriptor *dDscr, Experiment *exp)
2752 int stack_prop = PROP_NONE;
2753 VMode view_mode = get_view_mode ();
2754 if (view_mode == VMODE_MACHINE)
2755 stack_prop = PROP_MSTACK;
2756 else if (view_mode == VMODE_EXPERT)
2757 stack_prop = PROP_XSTACK;
2758 else if (view_mode == VMODE_USER)
2759 stack_prop = PROP_USTACK;
2761 for (long j = 0, sz = dDscr->getSize (); j < sz; j++)
2763 void *stackId = dDscr->getObjValue (stack_prop, j);
2764 Vector<Histable*> *stack = (Vector<Histable*>*)CallStack::getStackPCs (stackId);
2765 int stack_size = stack->size ();
2766 bool hide_on = false;
2767 LoadObject *hide_lo = NULL;
2768 Histable *last_addr = NULL;
2769 Histable *api_addr = NULL;
2772 Vector<Histable*> *hidepcs = new Vector<Histable*>;
2773 for (int i = stack_size - 1; i >= 0; i--)
2775 bool leaf = (i == 0);
2776 Histable *cur_addr = stack->fetch (i);
2777 Function *func = (Function*) cur_addr->convertto (Histable::FUNCTION);
2780 Module *mod = func->module;
2781 LoadObject *lo = mod->loadobject;
2782 int segx = lo->seg_idx;
2783 if ((get_lo_expand (segx) == LIBEX_API) && (i != (stack_size - 1)))
2786 api_addr = cur_addr;
2788 else if (get_lo_expand (segx) == LIBEX_HIDE)
2794 // Changed hidden loadobject
2795 if (last_addr != NULL)
2797 h_instr = hide_lo->get_hide_instr ((DbeInstr*) last_addr);
2798 hidepcs->append (h_instr);
2799 last_addr = cur_addr;
2808 last_addr = cur_addr;
2817 if (last_addr != NULL)
2819 h_instr = hide_lo->get_hide_instr ((DbeInstr*) last_addr);
2820 hidepcs->append (h_instr);
2825 if (last_addr != NULL && leaf) cur_addr = last_addr;
2828 h_instr = hide_lo->get_hide_instr ((DbeInstr*) cur_addr);
2829 hidepcs->append (h_instr);
2830 if (api_addr != NULL)
2831 hidepcs->append (api_addr);
2834 hidepcs->append (cur_addr);
2838 for (int i = 0, k = hidepcs->size () - 1; i < k; ++i, --k)
2839 hidepcs->swap (i, k);
2841 CallStack *cstkSH = exp->callTreeShowHide ();
2842 CallStackNode *hstack = (CallStackNode *) cstkSH->add_stack (hidepcs);
2843 dDscr->setObjValue (PROP_HSTACK, j, hstack);
2844 CallStack::setHideStack (stackId, hstack);
2851 DbeView::get_filtered_events (int idx, int data_id)
2853 if (idx < 0 || idx >= dataViews->size ())
2855 Vector<DataView*> *expDataViewList = dataViews->fetch (idx);
2856 if (!expDataViewList)
2857 return NULL; // Weird
2859 DataView *dview = expDataViewList->fetch (data_id);
2860 Experiment *exp = dbeSession->get_exp (idx);
2863 // if show-hide is on force a reconstruction of hide stacks
2864 // LIBRARY_VISIBILITY
2865 if (!showAll && (showHideChanged || newViewMode))
2867 DataDescriptor *dDscr = exp->get_raw_events (data_id);
2868 constructShowHideStack (dDscr, exp);
2873 int orig_data_id = data_id;
2874 data_id = exp->base_data_id (data_id);
2875 if (orig_data_id != data_id)
2876 // orig_data_id is a derived DataView. Get the master DataView:
2877 dview = expDataViewList->fetch (data_id);
2880 Expression *saved = cur_filter_expr;
2881 if (!adjust_filter (exp))
2884 DataDescriptor *dDscr = exp->get_raw_events (data_id);
2885 if (!showAll && (showHideChanged || newViewMode))
2886 constructShowHideStack (dDscr, exp);
2888 Emsg *m = exp->fetch_warnings ();
2890 this->warning_msg = m->get_msg ();
2894 FilterExp *filter = get_FilterExp (exp);
2895 dview = dDscr->createView ();
2896 dview->setFilter (filter);
2897 if (dview->getSize () < dDscr->getSize ())
2898 filter_active = true;
2900 expDataViewList->store (data_id, dview);
2904 delete cur_filter_expr;
2905 cur_filter_expr = saved;
2908 if (orig_data_id != data_id)
2910 // create the derived DataView:
2911 dview = exp->create_derived_data_view (orig_data_id, dview);
2912 expDataViewList->store (orig_data_id, dview);
2918 DbeView::get_filtered_events (int idx, int data_id,
2919 const int sortprops[], int sortprop_count)
2921 DataView *packets = get_filtered_events (idx, data_id);
2923 packets->sort (sortprops, sortprop_count);
2928 DbeView::adjust_filter (Experiment *exp)
2930 if (cur_filter_expr)
2932 Expression::Context ctx (this, exp);
2933 resetFilterHideMode ();
2934 Expression *fltr = cur_filter_expr->pEval (&ctx);
2935 if (fltr->complete ())
2936 { // Filter is a constant
2937 if (fltr->eval (NULL) == 0)
2942 cur_filter_expr = fltr;
2947 // Moved from Cacheable.cc:
2949 DbeView::status_str (DbeView_status status)
2953 case DBEVIEW_SUCCESS:
2955 case DBEVIEW_NO_DATA:
2956 return dbe_strdup (GTXT ("Data not available for this filter selection"));
2957 case DBEVIEW_IO_ERROR:
2958 return dbe_strdup (GTXT ("Unable to open file"));
2959 case DBEVIEW_BAD_DATA:
2960 return dbe_strdup (GTXT ("Data corrupted"));
2961 case DBEVIEW_BAD_SYMBOL_DATA:
2962 return dbe_strdup (GTXT ("Functions/Modules information corrupted"));
2963 case DBEVIEW_NO_SEL_OBJ:
2964 return dbe_strdup (GTXT ("No selected object, bring up Functions Tab"));
2970 DbeView::set_sel_obj (Histable *obj)
2974 switch (obj->get_type ())
2976 case Histable::INSTR:
2977 lastSelInstr = (DbeInstr *) obj;
2978 lastSelFunc = lastSelInstr->func;
2979 this->sel_binctx = lastSelFunc;
2981 case Histable::FUNCTION:
2982 if (lastSelInstr && lastSelInstr->func != obj)
2983 lastSelInstr = NULL;
2984 lastSelFunc = (Function *) obj;
2986 case Histable::LINE:
2988 DbeLine *dbeLine = (DbeLine *) obj;
2991 // remember previous DbeInstr and DbeFunc
2992 lastSelFunc = dbeLine->func;
2993 if (lastSelInstr && lastSelInstr->func != lastSelFunc)
2994 lastSelInstr = NULL;
2995 this->sel_binctx = lastSelFunc;
2998 this->sel_binctx = dbeLine->convertto (Histable::FUNCTION);
3001 case Histable::MODULE:
3002 case Histable::LOADOBJECT:
3003 case Histable::EADDR:
3004 case Histable::MEMOBJ:
3005 case Histable::INDEXOBJ:
3006 case Histable::PAGE:
3007 case Histable::DOBJECT:
3008 case Histable::SOURCEFILE:
3009 case Histable::IOACTFILE:
3010 case Histable::IOACTVFD:
3011 case Histable::IOCALLSTACK:
3012 case Histable::HEAPCALLSTACK:
3013 case Histable::EXPERIMENT:
3014 case Histable::OTHER:
3019 Dprintf (DEBUG_DBE, NTXT ("### set_sel_obj: DbeView.cc:%d obj %s\n"),
3020 __LINE__, obj ? obj->dump () : "NULL");
3021 Dprintf (DEBUG_DBE, NTXT ("### set_sel_obj: DbeView.cc:%d sel_obj %s\n"),
3022 __LINE__, sel_obj ? sel_obj->dump () : "NULL");
3023 Dprintf (DEBUG_DBE, NTXT ("### set_sel_obj: DbeView.cc:%d lastSelFunc %s\n"),
3024 __LINE__, lastSelFunc ? lastSelFunc->dump () : "NULL");
3025 Dprintf (DEBUG_DBE, NTXT ("### set_sel_obj: DbeView.cc:%d lastSelInstr %s\n"),
3026 __LINE__, lastSelInstr ? lastSelInstr->dump () : "NULL");
3031 DbeView::convert_line_to_instr (DbeLine *dbeLine)
3033 Dprintf (DEBUG_DBE, "### convert_line_to_instr DbeView::%d dbeLine=%s\n", __LINE__, dbeLine->dump ());
3034 Function *func = convert_line_to_func (dbeLine);
3037 Dprintf (DEBUG_DBE, "### convert_line_to_instr DbeView::%d func=%s\n", __LINE__, func->dump ());
3038 DbeInstr *dbeInstr = func->mapLineToPc (dbeLine);
3039 Dprintf (DEBUG_DBE && dbeInstr, "### convert_line_to_instr DbeView::%d dbeInstr=%s\n", __LINE__, dbeInstr->dump ());
3042 Dprintf (DEBUG_DBE && lastSelInstr, "### convert_line_to_instr DbeView::%d lastSelInstr=%s\n", __LINE__, lastSelInstr->dump ());
3043 return lastSelInstr;
3047 DbeView::convert_func_to_instr (Function *func)
3049 return (lastSelInstr && lastSelInstr->func == func) ?
3050 lastSelInstr : (DbeInstr *) func->convertto (Histable::INSTR);
3054 DbeView::convert_line_to_func (DbeLine *dbeLine)
3056 Function *func = dbeLine->func;
3059 if (lastSelFunc != NULL)
3060 // Can be mapped to the same function ?
3061 for (DbeLine *dl = dbeLine->dbeline_base; dl; dl = dl->dbeline_func_next)
3062 if (dl->func == lastSelFunc)
3065 PathTree *pathTree = NULL;
3066 Function *firstFunc = NULL;
3067 for (DbeLine *dl = dbeLine->dbeline_base; dl; dl = dl->dbeline_func_next)
3069 // Find a first function with non-zero metrics
3072 if (pathTree == NULL)
3073 pathTree = get_path_tree ();
3074 if (pathTree->get_func_nodeidx (dl->func))
3076 if (firstFunc == NULL)
3077 firstFunc = dl->func;
3080 // Take a first function
3085 DbeView::get_sel_obj (Histable::Type type)
3087 Histable *lastSelObj = sel_obj;
3088 Dprintf (DEBUG_DBE, NTXT ("### get_sel_obj: DbeView.cc:%d type=%d sel_obj %s\n"),
3089 __LINE__, type, lastSelObj ? lastSelObj->dump () : "NULL");
3090 if (lastSelObj == NULL)
3094 case Histable::INSTR:
3097 // DBFIXME LIBRARY VISIBILITY
3098 // hack to get to the hide mode object for PCs when filtering
3099 // with a PC in timeline
3100 if (lastSelObj->get_type () == Histable::INSTR)
3102 Function *func = (Function*) (lastSelObj->convertto (Histable::FUNCTION));
3103 LoadObject *lo = func->module->loadobject;
3104 if (get_lo_expand (lo->seg_idx) == LIBEX_HIDE)
3105 return lo->get_hide_function ();
3108 if (lastSelObj->get_type () == Histable::LINE)
3109 return convert_line_to_instr ((DbeLine*) lastSelObj);
3110 else if (lastSelObj->get_type () == Histable::FUNCTION)
3111 return convert_func_to_instr ((Function *) lastSelObj);
3112 return lastSelObj->convertto (type);
3113 case Histable::FUNCTION:
3114 if (lastSelObj->get_type () == Histable::LINE)
3116 Function *func = convert_line_to_func ((DbeLine*) lastSelObj);
3121 return lastSelObj->convertto (type);
3122 case Histable::LINE:
3124 return lastSelObj->convertto (type);