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