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#ifndef _EEXPERIMENT_H 22#define _EEXPERIMENT_H 23 24// The experiment class is responsible for managing all the data 25// for an individual experiment 26 27#include "Metric.h" 28#include "Histable.h" 29#include "Stats_data.h" 30#include "DefaultMap.h" 31#include "HeapMap.h" 32 33class Data_window; 34class DbeFile; 35class CallStack; 36class JMethod; 37class Sample; 38class SegMem; 39class LoadObject; 40class SourceFile; 41class UserLabel; 42class PRBTree; 43class Emsg; 44class Emsgqueue; 45struct JThread; 46struct GCEvent; 47class FileData; 48class Module; 49class Experiment; 50template <class ITEM> class Vector; 51 52#define JTHREAD_DEFAULT ((JThread*)0) 53#define JTHREAD_NONE ((JThread*)-1) 54 55// When we perform the pipelined optimization on resolve_frame_info() and add_stack() 56// this is the number of iterations one phase works on before passing on the work to 57// the next phase 58 59#define CSTCTX_CHUNK_SZ 10000 60#define PIPELINE_QUEUE_SZ_HI 8 61#define PIPELINE_QUEUE_SZ_LOW 2 62 63// the add_stack_ctx structure contains the intermediate state (context) after 64// CSTCTX_CHUNK_SZ number of iterations to pass on the work to another thread to 65// operate on the next stage 66typedef struct 67{ 68 Vector<DbeInstr*> *natpcs; 69 Vector<Histable*> *jpcs; 70 long idx; 71 FramePacket *frp; 72 hrtime_t tstamp; 73 uint32_t thrid; 74 bool last_ctx; 75} cstk_ctx; 76 77// To minimize threadpool overhead, the granularity of a job submitted is made larger: 78// containing a chunk of iterations (of size CSTCTX_CHUNK_SZ) 79typedef struct 80{ 81 cstk_ctx* cstCtxAr[CSTCTX_CHUNK_SZ]; 82 int last_idx; 83 long idx_begin; 84 long idx_end; 85 DataDescriptor *dDscr; 86 Experiment *exp; 87 void *cstk; 88} cstk_ctx_chunk; 89 90class Experiment : public Histable, public DbeMessages 91{ 92public: 93 94 enum Exp_status 95 { 96 SUCCESS, 97 INCOMPLETE, 98 FAILURE 99 }; 100 101 Experiment (); 102 virtual ~Experiment (); 103 104 virtual Histable_type 105 get_type () 106 { 107 return EXPERIMENT; 108 }; 109 virtual Vector<Histable*> *get_comparable_objs (); 110 111 int groupId; 112 Experiment *founder_exp; // parent of this experiment 113 Vector<Experiment*> *children_exps; // children of this experiment 114 115 // Configuration Information 116 char *hostname; // Hosthame (e.g. mymachine) 117 hrtime_t start_sec; // Starting timeval secs. 118 char *username; // name of person performing the test 119 char *architecture; // Architecture name ("sun4") 120 Platform_t platform; // Sparc,Sparcv9,Intel 121 WSize_t wsize; // word size: may be w32 or w64 122 int clock; // CPU clock frequency, Mhz 123 int varclock; // Set if CPU clock frequency can change: turbo-mode 124 int maxclock; // max. CPU clock frequency on MP machine 125 int minclock; // min. CPU clock frequency on MP machine 126 int ncpus; // count of CPUs where expt was recorded 127 int hw_cpuver; // CPU version from libcpc 128 char *machinemodel; // machine model of machine on which experiment was recorded 129 char *os_version; // Operating system name 130 int page_size; // Page size (bytes) 131 int npages; // Number of page size 132 int exp_maj_version; // major version number of current experiment 133 int exp_min_version; // minor version number of current experiment 134 int hex_field_width; // number of digits in hex form of address 135 // for current experiment, i.e. 8 for 32bit addresses 136 int broken; // If SP_JCMD_RUN line not seen 137 int obsolete; // If pointer file experiment detected 138 bool hwc_default; // True if HW counters were enabled by default 139 int hwc_bogus; // Count of bogus HWC packets 140 int hwc_lost_int; // Count of packets reflecting lost interrupt 141 int hwc_scanned; // If the HWC packets have been scanned 142 int invalid_packet; // Count of invalid packets 143 bool exec_started; // True if exec was called, and exec error not yet seen 144 bool dataspaceavail; // True if dataspace data is in the experiment 145 bool leaklistavail; // True if leaklist data is in the experiment 146 bool heapdataavail; // True if heap data is in the experiment 147 bool racelistavail; // true if there are race events in the experiment 148 bool iodataavail; // true if there are io events in the experiment 149 bool deadlocklistavail; // true if there are deadlock events in the experiment 150 bool timelineavail; // true if there are valid timestamps in the experiment 151 bool ifreqavail; // True if instruction-frequency data is in the experiment 152 bool ompavail; // true if there is OpenMP data in the experiment 153 bool has_java; 154 char *uarglist; // argv[] array, as a string 155 char *utargname; // basename of argv[0] extracted from uarglist 156 char *ucwd; // working directory 157 char *cversion; // collector version string 158 char *dversion; // driver version string (er_kernel) 159 char *jversion; // Java version string (java profiling) 160 161 // Open the named experiment record and process log file 162 Exp_status open (char *directory_name); 163 164 // Update experiment (read and process new data) 165 Exp_status update (); 166 167 // Returns collector parameters for the current sample selection 168 Collection_params * 169 get_params () 170 { 171 return &coll_params; 172 } 173 174 Exp_status 175 get_status () 176 { 177 return status; 178 } 179 180 // Returns the number of samples. For use by FilterNumeric 181 int 182 nsamples () 183 { 184 return samples->size (); 185 } 186 187 // Release any releasable memory. 188 void purge (); 189 190 void resetShowHideStack (); 191 int save_notes (char*, bool); 192 int delete_notes (bool); 193 Experiment *getBaseFounder (); // returns topmost founder or this if no descendents 194 195 hrtime_t 196 getStartTime () 197 { 198 return exp_start_time; 199 } 200 hrtime_t getRelativeStartTime (); // delta between start and founder's start 201 202 hrtime_t 203 getWallStartSec () 204 { 205 return start_sec; 206 } 207 208 hrtime_t 209 getLastEvent () 210 { 211 if (last_event != ZERO_TIME) 212 return last_event; 213 return exp_start_time; 214 } 215 216 hrtime_t 217 getGCDuration () 218 { 219 return gc_duration; 220 } 221 222 int 223 getPID () 224 { 225 return pid; 226 } 227 228 int 229 getUserExpId () 230 { 231 return userExpId; 232 } 233 234 int 235 getExpIdx () 236 { 237 return expIdx; 238 } 239 240 void 241 setExpIdx (int idx) 242 { 243 expIdx = idx; 244 } 245 246 void 247 setUserExpId (int idx) 248 { 249 userExpId = idx; 250 } 251 252 void 253 setTinyThreshold (int limit) 254 { 255 tiny_threshold = limit; 256 } 257 258 bool 259 isDiscardedTinyExperiment () 260 { 261 return discardTiny; 262 } 263 264 Exp_status open_epilogue (); 265 void read_experiment_data (bool read_ahead); 266 static int copy_file_to_archive (const char *name, const char *aname, int hide_msg); 267 static int copy_file_to_common_archive (const char *name, const char *aname, 268 int hide_msg, const char *common_archive, int relative_path = 0); 269 static int copy_file (char *name, char *aname, int hide_msg, 270 char *common_archive = NULL, int relative_path = 0); 271 272 // get_raw_events() 273 // action: get unfiltered packets, loading them if required 274 // parameters: data_id (see ProfData_type) 275 DataDescriptor *get_raw_events (int data_id); 276 Vector<DataDescriptor*> *getDataDescriptors (); 277 278 // Some DATA_* types are derived from others, e.g. DATA_HEAPSZ is derived from DATA_HEAP 279 // The following hooks support derived DataViews 280 int base_data_id (int data_id); // returns base data_id type (ProfData_type DATA_*) 281 DataView *create_derived_data_view (int data_id, DataView *dview); 282 283 Vector<BaseMetric*>* 284 get_metric_list () 285 { 286 return metrics; 287 } 288 289 char * 290 get_expt_name () 291 { 292 return expt_name; // Return the pathname to the experiment 293 }; 294 295 Vector<char*> *get_descendants_names (); 296 char *get_fndr_arch_name (); 297 char *get_arch_name (); 298 char *getNameInArchive (const char *fname, bool archiveFile = false); 299 char *checkFileInArchive (const char *fname, bool archiveFile = false); 300 DbeFile *findFileInArchive (const char *className, const char *runTimePath); 301 DbeFile *findFileInArchive (const char *fname); 302 bool create_dir (char *dname); 303 304 Vaddr 305 ret_stack_base () 306 { 307 return stack_base; 308 }; 309 310 // Map a virtual address to a PC pair 311 DbeInstr *map_Vaddr_to_PC (Vaddr addr, hrtime_t ts); 312 DbeInstr *map_jmid_to_PC (Vaddr mid, int lineno, hrtime_t ts); 313 Sample *map_event_to_Sample (hrtime_t ts); 314 GCEvent *map_event_to_GCEvent (hrtime_t ts); 315 316 DataView * 317 getOpenMPdata () 318 { 319 return openMPdata; 320 } 321 322 time_t 323 get_mtime () 324 { 325 return mtime; 326 } 327 328 Emsg *fetch_comments (void); // fetch the queue of comment messages 329 Emsg *fetch_runlogq (void); // fetch the queue of run log messages 330 Emsg *fetch_errors (void); // fetch the queue of error messages 331 Emsg *fetch_warnings (void); // fetch the queue of warning messages 332 Emsg *fetch_notes (void); // fetch the queue of notes messages 333 Emsg *fetch_ifreq (void); // fetch the queue of ifreq messages 334 Emsg *fetch_pprocq (void); // fetch the queue of post-processing messages 335 336 // message queues 337 Emsgqueue *commentq; // comments for the experiment header 338 Emsgqueue *runlogq; // used temporarily; after log file processing, 339 // messages are appended to the commentq 340 Emsgqueue *errorq; // error messages 341 Emsgqueue *warnq; // warning messages 342 Emsgqueue *notesq; // user-written notes messages 343 Emsgqueue *pprocq; // postprocessing messages 344 Emsgqueue *ifreqq; // Instruction frequency data, from count experiment 345 Map<const char*, LoadObject*> *loadObjMap; 346 Vector<LoadObject*> *loadObjs; 347 void append (LoadObject *lo); 348 LoadObject *createLoadObject (const char *path, uint64_t chksum = 0); 349 LoadObject *createLoadObject (const char *path, const char *runTimePath); 350 SourceFile *get_source (const char *path); 351 void set_clock (int clk); 352 353 CallStack * 354 callTree () 355 { 356 return cstack; 357 } 358 359 CallStack * 360 callTreeShowHide () 361 { 362 return cstackShowHide; 363 } 364 365 uint32_t mapTagValue (Prop_type, uint64_t value); 366 Histable *getTagObj (Prop_type, uint32_t idx); 367 Vector<Histable*> *getTagObjs (Prop_type); 368 369 JThread *map_pckt_to_Jthread (uint32_t tid, hrtime_t tstamp); 370 JThread *get_jthread (uint32_t tid); 371 372 Vector<JThread*> * 373 get_jthreads () 374 { 375 return jthreads; 376 } 377 378 Vector<GCEvent*> * 379 get_gcevents () 380 { 381 return gcevents; 382 } 383 384 bool need_swap_endian; 385 Collection_params coll_params; // Collection params 386 387 // Ranges for threads, lwps, cpu 388 uint64_t min_thread; 389 uint64_t max_thread; 390 uint64_t thread_cnt; 391 uint64_t min_lwp; 392 uint64_t max_lwp; 393 uint64_t lwp_cnt; 394 uint64_t min_cpu; 395 uint64_t max_cpu; 396 uint64_t cpu_cnt; 397 uint64_t dsevents; // count of dataspace events 398 uint64_t dsnoxhwcevents; /* count of ds events that could be be validated 399 * because of no branch target info */ 400 401 PacketDescriptor *newPacketDescriptor (int kind, DataDescriptor *dDscr); 402 PacketDescriptor *getPacketDescriptor (int kind); 403 404 // debugging aids -- dump_stacks, dump_map 405 void dump_stacks (FILE *); 406 void dump_map (FILE *); 407 408 // These methods are used in nightly performance regression testing 409 void DBG_memuse (Sample *); 410 void DBG_memuse (const char *sname); 411 void init_cache (); 412 413 DefaultMap<int64_t, FileData*> * 414 getFDataMap () 415 { 416 return fDataMap; 417 } 418 CallStack *cstack; 419 420protected: 421 422 Exp_status status; // Error status 423 Vector<SegMem*> *seg_items; // Master list of seg_items 424 CallStack *cstackShowHide; 425 PRBTree *maps; // All maps in (Vaddr,time) 426 427 hrtime_t gc_duration; // wall-clock hrtime of total GC intervals 428 hrtime_t exp_start_time; // wall-clock hrtime at exp start 429 hrtime_t last_event; // wall-clock hrtime of last known sample or log.xml entry 430 hrtime_t non_paused_time; // sum of periods where data collection is active (not paused) 431 hrtime_t resume_ts; // tracks log.xml start/resume times 432 void update_last_event (hrtime_t ts /*wall time (not 0-based)*/); 433 434 char *expt_name; // name of experiment 435 char *arch_name; // <experiment>/archive 436 char *fndr_arch_name; // <founder_experiment>/archive 437 //TBR? hrtime_t sample_time; // total of sample durations 438 int yyparse (); // Allow yyparse actions to access 439 Vaddr stack_base; // Stack base 440 441 // Write experiment header to comment queue 442 void write_header (); 443 void write_coll_params (); 444 445 Exp_status find_expdir (char *directory_name); 446 447 // Invoke the parser to process a file. 448 void read_data_file (const char*, const char*); 449 int read_log_file (); 450 void read_labels_file (); 451 void read_notes_file (); 452 void read_archives (); 453 int read_java_classes_file (); 454 void read_map_file (); 455 int read_overview_file (); 456 int read_dyntext_file (); 457 void read_omp_file (); 458 void read_omp_preg (); 459 void read_omp_task (); 460 void read_ifreq_file (); 461 void read_frameinfo_file (); 462 463 // Functions to process the log and loadobjects file entries 464 // They are deliberately made virtual to overload them 465 // in er_export. 466 virtual int process_arglist_cmd (char *, char *); 467 virtual int process_desc_start_cmd (char *, hrtime_t, char *, char *, int, char *); 468 virtual int process_desc_started_cmd (char *, hrtime_t, char *, char *, int, char *); 469 virtual int process_fn_load_cmd (Module *mod, char *fname, Vaddr vaddr, int fsize, hrtime_t ts); 470 virtual int process_fn_unload_cmd (char *, Vaddr, hrtime_t); 471 virtual int process_hwcounter_cmd (char *, int, char *, char *, int, int, int, char *); 472 virtual int process_hwsimctr_cmd (char *, int, char *, char *, char*, int, int, int, int, int); 473 virtual int process_jcm_load_cmd (char*, Vaddr, Vaddr, int, hrtime_t); 474 virtual int process_jcm_unload_cmd (char*, Vaddr, hrtime_t); 475 virtual int process_Linux_kernel_cmd (hrtime_t); 476 virtual int process_jthr_end_cmd (char *, uint64_t, Vaddr, Vaddr, hrtime_t); 477 virtual int process_jthr_start_cmd (char *, char *, char *, char *, uint64_t, Vaddr, Vaddr, hrtime_t); 478 virtual int process_gc_end_cmd (hrtime_t); 479 virtual int process_gc_start_cmd (hrtime_t); 480 virtual int process_sample_cmd (char *, hrtime_t, int id, char *lbl); 481 virtual int process_sample_sig_cmd (char *, int); 482 virtual int process_seg_map_cmd (char *, hrtime_t, Vaddr, int, int, int64_t, int64_t, int64_t, char *); 483 virtual int process_seg_unmap_cmd (char *, hrtime_t, Vaddr); 484 485 // creation time for experiment 486 time_t mtime; 487 hrtime_t exp_rel_start_time; // start of exp. relative to founder 488 bool exp_rel_start_time_set; 489 Vector<UserLabel*> *userLabels; // List of er_labels 490 int userExpId; // user value for EXPID 491 int expIdx; // DbeSession exp identifier 492 PRBTree *jmaps; // JAVA_CLASSES: (id,time)->Histable 493 Experiment* baseFounder; // outermost experiment (null until lazily computed) 494 495 // Represents a file in experiment 496 class ExperimentFile; 497 498 // XML handler to parse various experiment files 499 class ExperimentHandler; 500 class ExperimentLabelsHandler; 501 502 uint64_t readPacket (Data_window *dwin, Data_window::Span *span); 503 void readPacket (Data_window *dwin, char *ptr, PacketDescriptor *pDscr, 504 DataDescriptor *dDscr, int arg, uint64_t pktsz); 505 506 // read data 507 DataDescriptor *get_profile_events (); 508 DataDescriptor *get_sync_events (); 509 DataDescriptor *get_hwc_events (); 510 DataDescriptor *get_heap_events (); 511 DataDescriptor *get_heapsz_events (); 512 DataDescriptor *get_iotrace_events (); 513 DataDescriptor *get_race_events (); 514 DataDescriptor *get_deadlock_events (); 515 DataDescriptor *get_sample_events (); 516 DataDescriptor *get_gc_events (); 517 DataDescriptor *getDataDescriptor (int data_id); 518 DataDescriptor *newDataDescriptor (int data_id, int flags = 0, 519 DataDescriptor *master_dDscr = NULL); 520 521 // Frame info data structures and methods 522 struct UIDnode; 523 struct RawFramePacket; 524 525 Vector<RawFramePacket*>*frmpckts; // frame info data 526 static int frUidCmp (const void*, const void*); 527 RawFramePacket *find_frame_packet (uint64_t uid); 528 529 static const int CHUNKSZ = 16384; 530 long nnodes; 531 long nchunks; 532 UIDnode **chunks; 533 UIDnode **uidHTable; 534 Vector<UIDnode*> *uidnodes; 535 bool resolveFrameInfo; 536 bool discardTiny; 537 int tiny_threshold; /* optimize away tiny experiments which ran 538 * for less than specified time (ms): default 0 */ 539 540 static int uidNodeCmp (const void *a, const void *b); 541 UIDnode *add_uid (Data_window *dwin, uint64_t uid, int size, uint32_t *array, uint64_t link_uid); 542 UIDnode *add_uid (Data_window *dwin, uint64_t uid, int size, uint64_t *array, uint64_t link_uid); 543 UIDnode *new_uid_node (uint64_t uid, uint64_t val); 544 UIDnode *get_uid_node (uint64_t uid, uint64_t val); 545 UIDnode *get_uid_node (uint64_t uid); 546 UIDnode *find_uid_node (uint64_t uid); 547 548 ExperimentFile *logFile; 549 550 // Data descriptors 551 Vector<DataDescriptor*> *dataDscrs; 552 Vector<PacketDescriptor*> *pcktDscrs; 553 long blksz; // binary data file block size 554 555 // Processed data packets 556 DataView *openMPdata; // OMP fork events 557 558 // Map events to OpenMP parallel regions and tasks 559 Map2D<uint32_t, hrtime_t, uint64_t> *mapPRid; 560 Map2D<uint32_t, hrtime_t, void*> *mapPReg; 561 Map2D<uint32_t, hrtime_t, void*> *mapTask; 562 563 // Archive content 564 Map<const char*, DbeFile *> *archiveMap; 565 Map<const char*, SourceFile*>*sourcesMap; 566 567 void init (); 568 void fini (); 569 void post_process (); 570 void constructJavaStack (FramePacket *, UIDnode *, Map<uint64_t, uint64_t> *); 571 void resolve_frame_info (DataDescriptor*); 572 void cleanup_cstk_ctx_chunk (); 573 void register_metric (Metric::Type type); 574 void register_metric (Hwcentry *ctr, const char* aux, const char* username); 575 576 Sample *sample_last_used; 577 GCEvent *gcevent_last_used; 578 char *first_sample_label; 579 Module *get_jclass (const char *className, const char *fileName); 580 LoadObject *get_j_lo (const char *className, const char *fileName); 581 582 Vector<BaseMetric*> *metrics; 583 Vector<JThread*> *jthreads; // master list of Java threads 584 Vector<JThread*> *jthreads_idx; // index in the master list 585 Vector<GCEvent*> *gcevents; 586 Vector<UnmapChunk*> *heapUnmapEvents; 587 Vector<Sample*> *samples; // Array of Sample pointers 588 589 DefaultMap<int64_t, FileData*> *fDataMap; // list of FileData objects using the virtual File descriptor as the key 590 DefaultMap<int, int64_t> *vFdMap; // list of virtual file descrptors using the file descriptor as the key 591 592 Vector<Vector<Histable*>*> *tagObjs; // tag objects 593 bool sparse_threads; 594 595 SegMem **smemHTable; // hash table for SegMem's 596 DbeInstr **instHTable; // hash table for DbeInstr 597 Map<unsigned long long, JMethod*> *jmidHTable; // hash table for jmid 598 599 // identity of target process 600 int pid; 601 int ppid; 602 int pgrp; 603 int sid; 604 605 // Map file processing related data 606 struct MapRecord 607 { 608 609 enum 610 { 611 LOAD, UNLOAD 612 } kind; 613 Histable *obj; 614 Vaddr base; 615 Size size; 616 hrtime_t ts; 617 uint64_t foff; 618 }; 619 620 void mrec_insert (MapRecord *mrec); 621 SegMem *update_ts_in_maps (Vaddr addr, hrtime_t ts); 622 int read_warn_file (); 623 LoadObject *get_dynfunc_lo (const char *loName); 624 Function *create_dynfunc (Module *mod, char *fname, int64_t vaddr, int64_t fsize); 625 char *get_archived_name (const char *fname, bool archiveFile = false); 626 627 Vector<MapRecord*> *mrecs; 628 629private: 630 void add_evt_time_to_profile_events (DataDescriptor *dDscr); 631 DataView *create_heapsz_data_view (DataView *heap_dview); 632 void compute_heapsz_data_view (DataView *heapsz_dview); 633}; 634 635struct JThread 636{ 637 JThread *next; 638 char *name; 639 char *group_name; 640 char *parent_name; 641 uint32_t tid; // system thread id 642 Vaddr jthr; // recorded Java thread id 643 Vaddr jenv; // recorded JNIEnv id 644 uint32_t jthr_id; // internal JThread object id 645 hrtime_t start; 646 hrtime_t end; 647 648 JThread () 649 { 650 name = NULL; 651 group_name = NULL; 652 parent_name = NULL; 653 } 654 655 ~JThread () 656 { 657 free (name); 658 free (group_name); 659 free (parent_name); 660 } 661 bool is_system (); 662}; 663 664struct GCEvent 665{ 666 667 GCEvent () 668 { 669 id = -1; 670 } 671 672 ~GCEvent () { } 673 674 hrtime_t start; 675 hrtime_t end; 676 int id; 677}; 678 679class ExperimentLoadCancelException 680{ 681public: 682 683 ExperimentLoadCancelException () { }; 684 685 ~ExperimentLoadCancelException () { }; 686}; 687 688 689#endif /* _EEXPERIMENT_H */ 690