mirror of
https://github.com/autc04/Retro68.git
synced 2024-06-07 13:33:06 +00:00
555 lines
13 KiB
C++
555 lines
13 KiB
C++
/* 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);
|
|
}
|