diff options
Diffstat (limited to 'gprofng/src/IndexObject.cc')
-rw-r--r-- | gprofng/src/IndexObject.cc | 554 |
1 files changed, 554 insertions, 0 deletions
diff --git a/gprofng/src/IndexObject.cc b/gprofng/src/IndexObject.cc new file mode 100644 index 00000000000..a7c8a376aaf --- /dev/null +++ b/gprofng/src/IndexObject.cc @@ -0,0 +1,554 @@ +/* Copyright (C) 2021 Free Software Foundation, Inc. + Contributed by Oracle. + + This file is part of GNU Binutils. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, 51 Franklin Street - Fifth Floor, Boston, + MA 02110-1301, USA. */ + +#include "config.h" +#include "util.h" +#include "DbeSession.h" +#include "DbeView.h" +#include "IndexObject.h" +#include "StringBuilder.h" + +IndexObject::IndexObject (int _indextype, uint64_t _index) +{ + indextype = _indextype; + obj = NULL; + id = _index; + name = NULL; + nameIsFinal = false; +} + +IndexObject::IndexObject (int _indextype, Histable *_obj) +{ + indextype = _indextype; + obj = _obj; + id = obj ? obj->id : (uint64_t) - 1; + name = NULL; + nameIsFinal = false; +} + +void +IndexObject::set_name (char * other_name) +{ + if (name == NULL) + { + name = other_name; + nameIsFinal = true; + } +} + +static uint64_t +extractExpgrid (uint64_t id) +{ + return (id >> IndexObject::INDXOBJ_EXPGRID_SHIFT) + & IndexObject::INDXOBJ_EXPGRID_MASK; +} + +static uint64_t +extractExpid (uint64_t id) +{ + return (id >> IndexObject::INDXOBJ_EXPID_SHIFT) + & IndexObject::INDXOBJ_EXPID_MASK; +} + +static uint64_t +extractPayload (uint64_t id) +{ + return (id >> IndexObject::INDXOBJ_PAYLOAD_SHIFT) + & IndexObject::INDXOBJ_PAYLOAD_MASK; +} + +static void +printCompareLabel (StringBuilder *sb, uint64_t grpId); + +static bool +printThread (StringBuilder *sbIn, Expression::Context * ctx, uint64_t id) +{ + uint64_t proc = extractExpid (id); + uint64_t thrid = extractPayload (id); + bool isFinal = true; + bool hasJava = false; + bool javaThread = false; + if (ctx) + { + if (ctx->dview && ctx->dview->getProp (PROP_JTHREAD)) + { + hasJava = true; + uint64_t tstamp = ctx->dview->getLongValue (PROP_TSTAMP, ctx->eventId); + JThread *jthread = ctx->exp->map_pckt_to_Jthread (thrid, tstamp); + if (jthread != JTHREAD_NONE && jthread != JTHREAD_DEFAULT) + { + sbIn->appendf (GTXT ("Process %llu, Thread %llu, JThread %llu \'%s\', Group \'%s\', Parent \'%s\'"), + (unsigned long long) proc, + (unsigned long long) thrid, + (unsigned long long) jthread->jthr_id, + get_str(jthread->name, ""), + get_str(jthread->group_name, ""), + get_str(jthread->parent_name, "")); + javaThread = true; + } + } + } + if (!javaThread) + { + sbIn->appendf (GTXT ("Process %llu, Thread %llu"), + (unsigned long long) proc, (unsigned long long) thrid); + if (hasJava) + // sometimes threads start as native and later become Java; keep checking + isFinal = false; + } + if (ctx && ctx->dbev && ctx->dbev->comparingExperiments ()) + { + Vector <Histable *> *v = ctx->exp->get_comparable_objs (); + int st = 0; + for (long i = 0, sz = VecSize (v); i < sz; i++) + { + Experiment *exp = (Experiment *) v->get (i); + if (exp) + { + if (st == 0) + { + st = 1; + continue; + } + sbIn->appendf (GTXT (" [ Group %llu Process %llu ]"), + (unsigned long long) exp->groupId - 1, + (unsigned long long) exp->getUserExpId ()); + } + } + } + return isFinal; +} + +static bool +printProcess (StringBuilder *sbIn, Expression::Context * ctx, uint64_t id) +{ + uint64_t proc = id; + if (ctx && ctx->exp) + { + int st = 0; + if (ctx->dbev && ctx->dbev->comparingExperiments ()) + { + Vector <Histable *> *v = ctx->exp->get_comparable_objs (); + for (long i = 0, sz = VecSize (v); i < sz; i++) + { + Experiment *exp = (Experiment *) v->get (i); + if (exp) + { + if (st == 0) + { + st = 1; + sbIn->appendf (GTXT ("%s, Process %3llu, PID %llu"), + get_str (exp->utargname, GTXT ("(unknown)")), + (unsigned long long) proc, + (unsigned long long) exp->getPID ()); + continue; + } + sbIn->appendf (GTXT (" [ Group %llu, Process %llu, PID %llu ]"), + (unsigned long long) exp->groupId - 1, + (unsigned long long) exp->getUserExpId (), + (unsigned long long) exp->getPID ()); + } + } + } + if (st == 0) + sbIn->appendf (GTXT ("%s, Process %3llu, PID %llu"), + get_str (ctx->exp->utargname, GTXT ("(unknown)")), + (unsigned long long) proc, + (unsigned long long) ctx->exp->getPID ()); + } + else + sbIn->appendf (GTXT ("Process %3llu"), (unsigned long long) proc); + return true; //name is final +} + +static bool +printExperiment (StringBuilder *sbIn, Expression::Context * ctx, uint64_t id) +{ + uint64_t grpId = extractExpgrid (id); + uint64_t expid = extractExpid (id); + if (ctx && ctx->dbev->comparingExperiments ()) + printCompareLabel (sbIn, grpId); + if (ctx) + { + Experiment *hasFounder = ctx->exp->founder_exp; + int pid = ctx->exp->getPID (); + uint64_t founderExpid; + if (hasFounder) + founderExpid = hasFounder->getUserExpId (); + else + founderExpid = expid; + sbIn->appendf (GTXT ("Base Experiment %llu, Process %llu, PID %llu, %s"), + (unsigned long long) founderExpid, + (unsigned long long) expid, + (unsigned long long) pid, + get_str (ctx->exp->utargname, GTXT ("(unknown)"))); + } + else + sbIn->appendf (GTXT ("Process %llu"), (unsigned long long) expid); + return true; // name is final +} + +void +IndexObject::set_name_from_context (Expression::Context * ctx) +{ + if (name != NULL) + if (nameIsFinal && strstr (name, GTXT ("(unknown)")) == NULL) + return; + if (ctx == NULL || ctx->dview == NULL || ctx->dbev == NULL) + return; + StringBuilder sb; + switch (indextype) + { + case INDEX_THREADS: + nameIsFinal = printThread (&sb, ctx, id); + break; + case INDEX_PROCESSES: + nameIsFinal = printProcess (&sb, ctx, id); + break; + case INDEX_EXPERIMENTS: + nameIsFinal = printExperiment (&sb, ctx, id); + break; + default: + name = NULL; + return; + } + if (sb.length ()) + name = sb.toString (); +} + +static void +printCompareLabel (StringBuilder *sbIn, uint64_t grpId) +{ + static const char *labels[] = {"", GTXT ("Baseline"), GTXT ("Comparison")}; + static int length; + if (!length) + { + length = strlen (labels[1]); + int length2 = strlen (labels[2]); + if (length < length2) + length = length2; + length += 5; // for open/close brace and grpId number and spaces + } + char *s = NULL; + if (grpId != 0) + { + if (grpId <= 2) + s = dbe_sprintf ("[%s]", labels[grpId]); + else + s = dbe_sprintf ("[%s-%llu]", labels[2], + (unsigned long long) (grpId - 1)); + } + sbIn->appendf ("%-*s", length, get_str (s, "")); + free (s); +} + +char * +IndexObject::get_name (NameFormat fmt) +{ + if (name == NULL) + { + StringBuilder sb; + int64_t upper; + int64_t num1; + int64_t num2; + switch (indextype) + { + case INDEX_THREADS: + printThread (&sb, NULL, id); + break; + + case INDEX_CPUS: + sb.sprintf (GTXT ("CPU %llu"), (unsigned long long) id); + break; + + case INDEX_SAMPLES: + sb.sprintf (GTXT ("Sample %llu"), (unsigned long long) id); + break; + + case INDEX_GCEVENTS: + if (id == 0) + { + sb.sprintf (GTXT ("Not in any GCEvent")); + } + else + { + sb.sprintf (GTXT ("GCEvent %llu"), (unsigned long long) id); + } + break; + + case INDEX_SECONDS: + sb.sprintf (GTXT ("Second of execution %llu"), (unsigned long long) id); + break; + + case INDEX_PROCESSES: + printProcess (&sb, NULL, id); + break; + + case INDEX_EXPERIMENTS: + printExperiment (&sb, NULL, id); + break; + case INDEX_BYTES: + upper = id; + if (id == -1) + { + break; + } + if (id % 2 == 1 && id > 1) + { + upper = id - 1; + if (upper >= 1099511627776) + { + num1 = upper / 1099511627776; + sb.sprintf (GTXT (">= %3llu TB"), (unsigned long long) num1); + } + else + { + // XXXX do nothing, this should not happen + } + } + else + { + if (upper >= 1099511627776) + { + num1 = upper / 1099511627776; + num2 = num1 / 4; + if (num2) + { + sb.sprintf (GTXT ("%3lluTB < n <= %3lluTB"), (unsigned long long) num2, (unsigned long long) num1); + } + else + { + sb.sprintf (GTXT ("256GB < n <= %3lluTB"), (unsigned long long) num1); + } + } + else if (upper >= 1073741824) + { + num1 = upper / 1073741824; + num2 = num1 / 4; + if (num2) + { + sb.sprintf (GTXT ("%3lluGB < n <= %3lluGB"), (unsigned long long) num2, (unsigned long long) num1); + } + else + { + sb.sprintf (GTXT ("256MB < n <= %3lluGB"), (unsigned long long) num1); + } + } + else if (upper >= 1048576) + { + num1 = upper / 1048576; + num2 = num1 / 4; + if (num2) + { + sb.sprintf (GTXT ("%3lluMB < n <= %3lluMB"), (unsigned long long) num2, (unsigned long long) num1); + } + else + { + sb.sprintf (GTXT ("256KB < n <= %3lluMB"), (unsigned long long) num1); + } + } + else if (upper >= 1024) + { + num1 = upper / 1024; + num2 = num1 / 4; + if (num2) + { + sb.sprintf (GTXT ("%3lluKB < n <= %3lluKB"), (unsigned long long) num2, (unsigned long long) num1); + } + else + { + sb.sprintf (GTXT (" 256 < n <= %3lluKB"), (unsigned long long) num1); + } + } + else if (upper > 0) + { + num1 = upper; + num2 = num1 / 4; + if (num1 == 1) + { + sb.sprintf (GTXT (" 1 Byte")); + } + else + { + sb.sprintf (GTXT ("%5llu < n <= %5llu Bytes"), (unsigned long long) num2, (unsigned long long) num1); + } + } + else if (upper == 0) + { + sb.sprintf (GTXT (" 0 Bytes")); + } + else + { + sb.sprintf (GTXT ("<No Data>")); + } + } + break; + case INDEX_DURATION: + if (id == -1) + { + break; + } + + if (id > 10000000000000) + { + sb.sprintf (GTXT ("n > 10000s")); + } + else if (id > 1000000000000) + { + sb.sprintf (GTXT ("1000s < n <= 10000s")); + } + else if (id > 100000000000) + { + sb.sprintf (GTXT (" 100s < n <= 1000s")); + } + else if (id > 10000000000) + { + sb.sprintf (GTXT (" 10s < n <= 100s")); + } + else if (id > 1000000000) + { + sb.sprintf (GTXT (" 1s < n <= 10s")); + } + else if (id > 100000000) + { + sb.sprintf (GTXT ("100ms < n <= 1s")); + } + else if (id > 10000000) + { + sb.sprintf (GTXT (" 10ms < n <= 100ms")); + } + else if (id > 1000000) + { + sb.sprintf (GTXT (" 1ms < n <= 10ms")); + } + else if (id > 100000) + { + sb.sprintf (GTXT ("100us < n <= 1ms")); + } + else if (id > 10000) + { + sb.sprintf (GTXT (" 10us < n <= 100us")); + } + else if (id > 1000) + { + sb.sprintf (GTXT (" 1us < n <= 10us")); + } + else if (id > 0) + { + sb.sprintf (GTXT (" 0s < n <= 1us")); + } + else if (id == 0) + { + sb.sprintf (GTXT (" 0s")); + } + else + { + sb.sprintf (GTXT ("<No Data>")); + } + break; + + // Custom index objects + default: + if (obj) + sb.sprintf (GTXT ("%s from %s"), + dbeSession->getIndexSpaceDescr (indextype), obj->get_name (fmt)); + else + { + IndexObjType_t *indexObj = dbeSession->getIndexSpace (indextype); + if (indexObj->memObj) + { + if (strcasecmp (indexObj->name, NTXT ("Memory_page_size")) == 0) + { + if (id == 0) + sb.append (GTXT ("<Unknown>")); + else + sb.sprintf (NTXT ("%s 0x%16.16llx (%llu)"), indexObj->name, + (unsigned long long) id, (unsigned long long) id); + } + else if (strcasecmp (indexObj->name, NTXT ("Memory_in_home_lgrp")) == 0) + { + if (id == 0 || id == 1) + sb.sprintf (NTXT ("%s: %s"), indexObj->name, + id == 1 ? GTXT ("True") : GTXT ("False")); + else + sb.sprintf (NTXT ("%s %s (0x%llx"), indexObj->name, + GTXT ("<Unknown>"), (unsigned long long) id); + } + else if (strcasecmp (indexObj->name, NTXT ("Memory_lgrp")) == 0) + { + if (id == 0) + sb.append (GTXT ("<Unknown>")); + else + sb.sprintf (NTXT ("%s %llu"), indexObj->name, (unsigned long long) id); + } + else + sb.sprintf (NTXT ("%s 0x%16.16llx"), indexObj->name, (unsigned long long) id); + } + else + sb.sprintf ("%s 0x%16.16llx (%llu)", indexObj->name, + (unsigned long long) id, (unsigned long long) id); + } + } + name = sb.toString (); + nameIsFinal = true; + } + return name; +} + +bool +IndexObject::requires_string_sort () +{ + if (indextype == INDEX_PROCESSES || indextype >= INDEX_LAST) + return true; + return false; +} + +Histable * +IndexObject::convertto (Histable_type type, Histable *ext) +{ + if (type == INDEXOBJ) + return this; + if (obj) + return obj->convertto (type, ext); + return NULL; +} + +IndexObjType_t::IndexObjType_t () +{ + type = 0; + name = NULL; + i18n_name = NULL; + index_expr_str = NULL; + index_expr = NULL; + mnemonic = 0; + short_description = NULL; + long_description = NULL; + memObj = NULL; +} + +IndexObjType_t::~IndexObjType_t () +{ + free (name); + free (i18n_name); + free (index_expr_str); + delete index_expr; + free (short_description); + free (long_description); +} |