]> Git Repo - binutils.git/blob - gprofng/src/IndexObject.cc
Automatic date update in version.in
[binutils.git] / gprofng / src / IndexObject.cc
1 /* Copyright (C) 2021 Free Software Foundation, Inc.
2    Contributed by Oracle.
3
4    This file is part of GNU Binutils.
5
6    This program is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 3, or (at your option)
9    any later version.
10
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15
16    You should have received a copy of the GNU General Public License
17    along with this program; if not, write to the Free Software
18    Foundation, 51 Franklin Street - Fifth Floor, Boston,
19    MA 02110-1301, USA.  */
20
21 #include "config.h"
22 #include "util.h"
23 #include "DbeSession.h"
24 #include "DbeView.h"
25 #include "IndexObject.h"
26 #include "StringBuilder.h"
27
28 IndexObject::IndexObject (int _indextype, uint64_t _index)
29 {
30   indextype = _indextype;
31   obj = NULL;
32   id = _index;
33   name = NULL;
34   nameIsFinal = false;
35 }
36
37 IndexObject::IndexObject (int _indextype, Histable *_obj)
38 {
39   indextype = _indextype;
40   obj = _obj;
41   id = obj ? obj->id : (uint64_t) - 1;
42   name = NULL;
43   nameIsFinal = false;
44 }
45
46 void
47 IndexObject::set_name (char * other_name)
48 {
49   if (name == NULL)
50     {
51       name = other_name;
52       nameIsFinal = true;
53     }
54 }
55
56 static uint64_t
57 extractExpgrid (uint64_t id)
58 {
59   return (id >> IndexObject::INDXOBJ_EXPGRID_SHIFT)
60           & IndexObject::INDXOBJ_EXPGRID_MASK;
61 }
62
63 static uint64_t
64 extractExpid (uint64_t id)
65 {
66   return (id >> IndexObject::INDXOBJ_EXPID_SHIFT)
67           & IndexObject::INDXOBJ_EXPID_MASK;
68 }
69
70 static uint64_t
71 extractPayload (uint64_t id)
72 {
73   return (id >> IndexObject::INDXOBJ_PAYLOAD_SHIFT)
74           & IndexObject::INDXOBJ_PAYLOAD_MASK;
75 }
76
77 static void
78 printCompareLabel (StringBuilder *sb, uint64_t grpId);
79
80 static bool
81 printThread (StringBuilder *sbIn, Expression::Context * ctx, uint64_t id)
82 {
83   uint64_t proc = extractExpid (id);
84   uint64_t thrid = extractPayload (id);
85   bool isFinal = true;
86   bool hasJava = false;
87   bool javaThread = false;
88   if (ctx)
89     {
90       if (ctx->dview && ctx->dview->getProp (PROP_JTHREAD))
91         {
92           hasJava = true;
93           uint64_t tstamp = ctx->dview->getLongValue (PROP_TSTAMP, ctx->eventId);
94           JThread *jthread = ctx->exp->map_pckt_to_Jthread (thrid, tstamp);
95           if (jthread != JTHREAD_NONE && jthread != JTHREAD_DEFAULT)
96             {
97               sbIn->appendf (GTXT ("Process %llu, Thread %llu, JThread %llu \'%s\', Group \'%s\', Parent \'%s\'"),
98                              (unsigned long long) proc,
99                              (unsigned long long) thrid,
100                              (unsigned long long) jthread->jthr_id,
101                              get_str(jthread->name, ""),
102                              get_str(jthread->group_name, ""),
103                              get_str(jthread->parent_name, ""));
104               javaThread = true;
105             }
106         }
107     }
108   if (!javaThread)
109     {
110       sbIn->appendf (GTXT ("Process %llu, Thread %llu"),
111                      (unsigned long long) proc, (unsigned long long) thrid);
112       if (hasJava)
113         // sometimes threads start as native and later become Java; keep checking
114         isFinal = false;
115     }
116   if (ctx && ctx->dbev && ctx->dbev->comparingExperiments ())
117     {
118       Vector <Histable *> *v = ctx->exp->get_comparable_objs ();
119       int st = 0;
120       for (long i = 0, sz = VecSize (v); i < sz; i++)
121         {
122           Experiment *exp = (Experiment *) v->get (i);
123           if (exp)
124             {
125               if (st == 0)
126                 {
127                   st = 1;
128                   continue;
129                 }
130               sbIn->appendf (GTXT (" [ Group %llu  Process %llu ]"),
131                              (unsigned long long) exp->groupId - 1,
132                              (unsigned long long) exp->getUserExpId ());
133             }
134         }
135     }
136   return isFinal;
137 }
138
139 static bool
140 printProcess (StringBuilder *sbIn, Expression::Context * ctx, uint64_t id)
141 {
142   uint64_t proc = id;
143   if (ctx && ctx->exp)
144     {
145       int st = 0;
146       if (ctx->dbev && ctx->dbev->comparingExperiments ())
147         {
148           Vector <Histable *> *v = ctx->exp->get_comparable_objs ();
149           for (long i = 0, sz = VecSize (v); i < sz; i++)
150             {
151               Experiment *exp = (Experiment *) v->get (i);
152               if (exp)
153                 {
154                   if (st == 0)
155                     {
156                       st = 1;
157                       sbIn->appendf (GTXT ("%s, Process %3llu, PID %llu"),
158                                  get_str (exp->utargname, GTXT ("(unknown)")),
159                                      (unsigned long long) proc,
160                                      (unsigned long long) exp->getPID ());
161                       continue;
162                     }
163                   sbIn->appendf (GTXT (" [ Group %llu,  Process %llu, PID %llu ]"),
164                                  (unsigned long long) exp->groupId - 1,
165                                  (unsigned long long) exp->getUserExpId (),
166                                  (unsigned long long) exp->getPID ());
167                 }
168             }
169         }
170       if (st == 0)
171         sbIn->appendf (GTXT ("%s, Process %3llu, PID %llu"),
172                        get_str (ctx->exp->utargname, GTXT ("(unknown)")),
173                        (unsigned long long) proc,
174                        (unsigned long long) ctx->exp->getPID ());
175     }
176   else
177     sbIn->appendf (GTXT ("Process %3llu"), (unsigned long long) proc);
178   return true; //name is final
179 }
180
181 static bool
182 printExperiment (StringBuilder *sbIn, Expression::Context * ctx, uint64_t id)
183 {
184   uint64_t grpId = extractExpgrid (id);
185   uint64_t expid = extractExpid (id);
186   if (ctx && ctx->dbev->comparingExperiments ())
187     printCompareLabel (sbIn, grpId);
188   if (ctx)
189     {
190       Experiment *hasFounder = ctx->exp->founder_exp;
191       int pid = ctx->exp->getPID ();
192       uint64_t founderExpid;
193       if (hasFounder)
194         founderExpid = hasFounder->getUserExpId ();
195       else
196         founderExpid = expid;
197       sbIn->appendf (GTXT ("Base Experiment %llu, Process %llu, PID %llu, %s"),
198                      (unsigned long long) founderExpid,
199                      (unsigned long long) expid,
200                      (unsigned long long) pid,
201                      get_str (ctx->exp->utargname, GTXT ("(unknown)")));
202     }
203   else
204     sbIn->appendf (GTXT ("Process %llu"), (unsigned long long) expid);
205   return true; // name is final
206 }
207
208 void
209 IndexObject::set_name_from_context (Expression::Context * ctx)
210 {
211   if (name != NULL)
212     if (nameIsFinal && strstr (name, GTXT ("(unknown)")) == NULL)
213       return;
214   if (ctx == NULL || ctx->dview == NULL || ctx->dbev == NULL)
215     return;
216   StringBuilder sb;
217   switch (indextype)
218     {
219     case INDEX_THREADS:
220       nameIsFinal = printThread (&sb, ctx, id);
221       break;
222     case INDEX_PROCESSES:
223       nameIsFinal = printProcess (&sb, ctx, id);
224       break;
225     case INDEX_EXPERIMENTS:
226       nameIsFinal = printExperiment (&sb, ctx, id);
227       break;
228     default:
229       name = NULL;
230       return;
231     }
232   if (sb.length ())
233     name = sb.toString ();
234 }
235
236 static void
237 printCompareLabel (StringBuilder *sbIn, uint64_t grpId)
238 {
239   static const char *labels[] = {"", GTXT ("Baseline"), GTXT ("Comparison")};
240   static int length;
241   if (!length)
242     {
243       length = strlen (labels[1]);
244       int length2 = strlen (labels[2]);
245       if (length < length2)
246         length = length2;
247       length += 5; // for open/close brace and grpId number and spaces
248     }
249   char *s = NULL;
250   if (grpId != 0)
251     {
252       if (grpId <= 2)
253         s = dbe_sprintf ("[%s]", labels[grpId]);
254       else
255         s = dbe_sprintf ("[%s-%llu]", labels[2],
256                          (unsigned long long) (grpId - 1));
257     }
258   sbIn->appendf ("%-*s", length, get_str (s, ""));
259   free (s);
260 }
261
262 char *
263 IndexObject::get_name (NameFormat fmt)
264 {
265   if (name == NULL)
266     {
267       StringBuilder sb;
268       int64_t upper;
269       int64_t num1;
270       int64_t num2;
271       switch (indextype)
272         {
273         case INDEX_THREADS:
274           printThread (&sb, NULL, id);
275           break;
276
277         case INDEX_CPUS:
278           sb.sprintf (GTXT ("CPU %llu"), (unsigned long long) id);
279           break;
280
281         case INDEX_SAMPLES:
282           sb.sprintf (GTXT ("Sample %llu"), (unsigned long long) id);
283           break;
284
285         case INDEX_GCEVENTS:
286           if (id == 0)
287             {
288               sb.sprintf (GTXT ("Not in any GCEvent"));
289             }
290           else
291             {
292               sb.sprintf (GTXT ("GCEvent %llu"), (unsigned long long) id);
293             }
294           break;
295
296         case INDEX_SECONDS:
297           sb.sprintf (GTXT ("Second of execution %llu"), (unsigned long long) id);
298           break;
299
300         case INDEX_PROCESSES:
301           printProcess (&sb, NULL, id);
302           break;
303
304         case INDEX_EXPERIMENTS:
305           printExperiment (&sb, NULL, id);
306           break;
307         case INDEX_BYTES:
308           upper = id;
309           if (id == -1)
310             {
311               break;
312             }
313           if (id % 2 == 1 && id > 1)
314             {
315               upper = id - 1;
316               if (upper >= 1099511627776)
317                 {
318                   num1 = upper / 1099511627776;
319                   sb.sprintf (GTXT (">= %3llu TB"), (unsigned long long) num1);
320                 }
321               else
322                 {
323                   // XXXX do nothing, this should not happen
324                 }
325             }
326           else
327             {
328               if (upper >= 1099511627776)
329                 {
330                   num1 = upper / 1099511627776;
331                   num2 = num1 / 4;
332                   if (num2)
333                     {
334                       sb.sprintf (GTXT ("%3lluTB < n <= %3lluTB"), (unsigned long long) num2, (unsigned long long) num1);
335                     }
336                   else
337                     {
338                       sb.sprintf (GTXT ("256GB < n <= %3lluTB"), (unsigned long long) num1);
339                     }
340                 }
341               else if (upper >= 1073741824)
342                 {
343                   num1 = upper / 1073741824;
344                   num2 = num1 / 4;
345                   if (num2)
346                     {
347                       sb.sprintf (GTXT ("%3lluGB < n <= %3lluGB"), (unsigned long long) num2, (unsigned long long) num1);
348                     }
349                   else
350                     {
351                       sb.sprintf (GTXT ("256MB < n <= %3lluGB"), (unsigned long long) num1);
352                     }
353                 }
354               else if (upper >= 1048576)
355                 {
356                   num1 = upper / 1048576;
357                   num2 = num1 / 4;
358                   if (num2)
359                     {
360                       sb.sprintf (GTXT ("%3lluMB < n <= %3lluMB"), (unsigned long long) num2, (unsigned long long) num1);
361                     }
362                   else
363                     {
364                       sb.sprintf (GTXT ("256KB < n <= %3lluMB"), (unsigned long long) num1);
365                     }
366                 }
367               else if (upper >= 1024)
368                 {
369                   num1 = upper / 1024;
370                   num2 = num1 / 4;
371                   if (num2)
372                     {
373                       sb.sprintf (GTXT ("%3lluKB < n <= %3lluKB"), (unsigned long long) num2, (unsigned long long) num1);
374                     }
375                   else
376                     {
377                       sb.sprintf (GTXT ("  256 < n <= %3lluKB"), (unsigned long long) num1);
378                     }
379                 }
380               else if (upper > 0)
381                 {
382                   num1 = upper;
383                   num2 = num1 / 4;
384                   if (num1 == 1)
385                     {
386                       sb.sprintf (GTXT ("    1 Byte"));
387                     }
388                   else
389                     {
390                       sb.sprintf (GTXT ("%5llu < n <= %5llu Bytes"), (unsigned long long) num2, (unsigned long long) num1);
391                     }
392                 }
393               else if (upper == 0)
394                 {
395                   sb.sprintf (GTXT ("    0 Bytes"));
396                 }
397               else
398                 {
399                   sb.sprintf (GTXT ("<No Data>"));
400                 }
401             }
402           break;
403         case INDEX_DURATION:
404           if (id == -1)
405             {
406               break;
407             }
408
409           if (id > 10000000000000)
410             {
411               sb.sprintf (GTXT ("n > 10000s"));
412             }
413           else if (id > 1000000000000)
414             {
415               sb.sprintf (GTXT ("1000s < n <= 10000s"));
416             }
417           else if (id > 100000000000)
418             {
419               sb.sprintf (GTXT (" 100s < n <= 1000s"));
420             }
421           else if (id > 10000000000)
422             {
423               sb.sprintf (GTXT ("  10s < n <=  100s"));
424             }
425           else if (id > 1000000000)
426             {
427               sb.sprintf (GTXT ("   1s < n <=   10s"));
428             }
429           else if (id > 100000000)
430             {
431               sb.sprintf (GTXT ("100ms < n <=    1s"));
432             }
433           else if (id > 10000000)
434             {
435               sb.sprintf (GTXT (" 10ms < n <= 100ms"));
436             }
437           else if (id > 1000000)
438             {
439               sb.sprintf (GTXT ("  1ms < n <=  10ms"));
440             }
441           else if (id > 100000)
442             {
443               sb.sprintf (GTXT ("100us < n <=   1ms"));
444             }
445           else if (id > 10000)
446             {
447               sb.sprintf (GTXT (" 10us < n <= 100us"));
448             }
449           else if (id > 1000)
450             {
451               sb.sprintf (GTXT ("  1us < n <=  10us"));
452             }
453           else if (id > 0)
454             {
455               sb.sprintf (GTXT ("   0s < n <=   1us"));
456             }
457           else if (id == 0)
458             {
459               sb.sprintf (GTXT ("   0s"));
460             }
461           else
462             {
463               sb.sprintf (GTXT ("<No Data>"));
464             }
465           break;
466
467           // Custom index objects
468         default:
469           if (obj)
470               sb.sprintf (GTXT ("%s from %s"),
471                           dbeSession->getIndexSpaceDescr (indextype), obj->get_name (fmt));
472           else
473             {
474               IndexObjType_t *indexObj = dbeSession->getIndexSpace (indextype);
475               if (indexObj->memObj)
476                 {
477                   if (strcasecmp (indexObj->name, NTXT ("Memory_page_size")) == 0)
478                     {
479                       if (id == 0)
480                           sb.append (GTXT ("<Unknown>"));
481                       else
482                           sb.sprintf (NTXT ("%s 0x%16.16llx (%llu)"), indexObj->name,
483                                       (unsigned long long) id, (unsigned long long) id);
484                     }
485                   else if (strcasecmp (indexObj->name, NTXT ("Memory_in_home_lgrp")) == 0)
486                     {
487                       if (id == 0 || id == 1)
488                           sb.sprintf (NTXT ("%s: %s"), indexObj->name,
489                                       id == 1 ? GTXT ("True") : GTXT ("False"));
490                       else
491                           sb.sprintf (NTXT ("%s %s (0x%llx"), indexObj->name,
492                                       GTXT ("<Unknown>"), (unsigned long long) id);
493                     }
494                   else if (strcasecmp (indexObj->name, NTXT ("Memory_lgrp")) == 0)
495                     {
496                       if (id == 0)
497                           sb.append (GTXT ("<Unknown>"));
498                       else
499                           sb.sprintf (NTXT ("%s %llu"), indexObj->name, (unsigned long long) id);
500                     }
501                   else
502                       sb.sprintf (NTXT ("%s 0x%16.16llx"), indexObj->name, (unsigned long long) id);
503                 }
504               else
505                   sb.sprintf ("%s 0x%16.16llx (%llu)", indexObj->name,
506                               (unsigned long long) id, (unsigned long long) id);
507             }
508         }
509       name = sb.toString ();
510       nameIsFinal = true;
511     }
512   return name;
513 }
514
515 bool
516 IndexObject::requires_string_sort ()
517 {
518   if (indextype == INDEX_PROCESSES || indextype >= INDEX_LAST)
519     return true;
520   return false;
521 }
522
523 Histable *
524 IndexObject::convertto (Histable_type type, Histable *ext)
525 {
526   if (type == INDEXOBJ)
527     return this;
528   if (obj)
529     return obj->convertto (type, ext);
530   return NULL;
531 }
532
533 IndexObjType_t::IndexObjType_t ()
534 {
535   type = 0;
536   name = NULL;
537   i18n_name = NULL;
538   index_expr_str = NULL;
539   index_expr = NULL;
540   mnemonic = 0;
541   short_description = NULL;
542   long_description = NULL;
543   memObj = NULL;
544 }
545
546 IndexObjType_t::~IndexObjType_t ()
547 {
548   free (name);
549   free (i18n_name);
550   free (index_expr_str);
551   delete index_expr;
552   free (short_description);
553   free (long_description);
554 }
This page took 0.055577 seconds and 4 git commands to generate.