]>
git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - gprofng/src/MemorySpace.cc
1 /* Copyright (C) 2021-2024 Free Software Foundation, Inc.
4 This file is part of GNU Binutils.
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)
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.
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. */
25 #include "DbeSession.h"
26 #include "Application.h"
27 #include "Experiment.h"
28 #include "Exp_Layout.h"
29 #include "MetricList.h"
30 #include "MemObject.h"
34 #include "MemorySpace.h"
36 #include "IndexObject.h"
38 MemObjType_t::MemObjType_t ()
45 short_description
= NULL
;
46 long_description
= NULL
;
49 MemObjType_t::~MemObjType_t ()
54 free (short_description
);
55 free (long_description
);
58 MemorySpace::MemorySpace (DbeView
*_dbev
, int _mstype
)
64 // set up the MemoryObject information
65 objs
= new HashMap
<uint64_t, MemObj
*>;
69 msindex_exp_str
= NULL
;
71 // find the memory space in the table
72 MemObjType_t
*mot
= findMemSpaceByIndex (mstype
);
75 msname
= dbe_strdup (mot
->name
);
76 if (mot
->index_expr
!= NULL
)
78 msindex_exp_str
= dbe_strdup (mot
->index_expr
);
79 msindex_exp
= dbeSession
->ql_parse (msindex_exp_str
);
80 if (msindex_exp
== NULL
)
81 // this was checked when the definition was created
86 // create the Total and Unknown objects
87 mname
= dbe_strdup (NTXT ("<Total>"));
88 total_memobj
= createMemObject ((uint64_t) - 2, mname
);
89 mname
= dbe_strdup (GTXT ("<Unknown>"));
90 unk_memobj
= createMemObject ((uint64_t) - 1, mname
);
92 selected_mo_index
= (uint64_t) - 3;
96 MemorySpace::~MemorySpace ()
102 free (msindex_exp_str
);
106 MemorySpace::reset ()
108 if (hist_data_all
!= NULL
)
110 delete hist_data_all
;
111 hist_data_all
= NULL
;
113 // do not clear the selected object's index
114 // selected_mo_index = (uint64_t)-3;
116 // destroy any existing objects, but keep the vector
117 // Now that we have a hashmap, which has its own vector,
118 // safe to delete and reallocate
120 objs
= new HashMap
<uint64_t, MemObj
*>;
123 // find a memory object by its memory-object index
125 MemorySpace::findMemObject (uint64_t indx
)
128 Hist_data::HistItem
*hi
;
129 if (indx
== (uint64_t) - 3)
132 Vec_loop (Hist_data::HistItem
*, hist_data_all
->hist_items
, index
, hi
)
134 if (((uint64_t) ((MemObj
*) hi
->obj
)->id
) == indx
)
137 // object does not exist; filter change eliminated it, for example
141 // find the object referenced in the packet
143 MemorySpace::lookupMemObject (Experiment
*exp
, DataView
*packets
, long i
)
146 uint64_t va
= (uint64_t) packets
->getLongValue (PROP_VADDR
, i
);
147 if (va
== ABS_UNSUPPORTED
)
148 // return NULL, to ignore the record
150 if (va
< ABS_CODE_RANGE
)
151 // The va is not valid, rather, it's an error code
152 // return the <Unknown> object
155 Expression::Context
ctx (dbev
, exp
, packets
, i
);
156 idx
= msindex_exp
->eval (&ctx
);
157 if (idx
== (uint64_t) - 1)
160 // do a binary search for the memory object
161 MemObj
*res
= objs
->get (idx
);
164 res
= createMemObject (idx
, NULL
);
165 objs
->put (idx
, res
);
179 MemorySpace::createMemObject (uint64_t index
, char *moname
)
185 res
= new MemObj (index
, moname
);
189 // Custom memory objects
190 // The memory_page_size is defined in the machine model file such
191 // as ./machinemodels/t4.ermm.
192 // Most users prefer to look at the hexadecimal version of virtual
193 // addresses. Display only the hexadecimal version of virtual addresses
194 // for all machine model views with an exception of virtual page size.
195 if (dbe_strcmp (msname
, NTXT ("Memory_page_size")) == 0)
196 name
= dbe_sprintf (NTXT ("%s 0x%16.16llx (%llu)"), msname
,
197 (long long) index
, (unsigned long long) index
);
198 else if (dbe_strcmp (msname
, NTXT ("Memory_in_home_lgrp")) == 0)
199 name
= dbe_sprintf (NTXT ("%s: %s"), msname
,
200 index
== 1 ? GTXT ("True") : index
== 0 ? GTXT ("False")
201 : GTXT ("<Unknown>"));
202 else if (dbe_strcmp (msname
, NTXT ("Memory_lgrp")) == 0)
203 name
= dbe_sprintf (NTXT ("%s %llu"), msname
, (unsigned long long) index
);
205 name
= dbe_sprintf (NTXT ("%s 0x%16.16llx"), msname
, (long long) index
);
207 res
= new MemObj (index
, name
);
212 static Vector
<MemObjType_t
*> dyn_memobj_vec
;
213 static Vector
<MemObjType_t
*> *dyn_memobj
= &dyn_memobj_vec
;
214 static Vector
<int> *ordlist
;
216 // Static function to get a vector of custom memory object definitions
219 MemorySpace::getMemObjects ()
223 int size
= dyn_memobj
->size ();
224 Vector
<int> *indx
= new Vector
<int>(size
);
225 Vector
<char*> *name
= new Vector
<char*>(size
);
226 Vector
<char> *mnemonic
= new Vector
<char>(size
);
227 Vector
<char*> *formula
= new Vector
<char*>(size
);
228 Vector
<char*> *machmodel
= new Vector
<char*>(size
);
229 Vector
<int> *order
= new Vector
<int>(size
);
230 Vector
<char*> *sdesc
= new Vector
<char*>(size
);
231 Vector
<char*> *ldesc
= new Vector
<char*>(size
);
235 Vec_loop (MemObjType_t
*, dyn_memobj
, ii
, mot
)
237 indx
->store (ii
, mot
->type
);
238 order
->store (ii
, ii
);
239 name
->store (ii
, dbe_strdup (mot
->name
));
240 formula
->store (ii
, dbe_strdup (mot
->index_expr
));
241 mnemonic
->store (ii
, mot
->mnemonic
);
242 sdesc
->store (ii
, mot
->short_description
== NULL
? NULL
243 : dbe_strdup (mot
->short_description
));
244 ldesc
->store (ii
, mot
->long_description
== NULL
? NULL
245 : dbe_strdup (mot
->long_description
));
246 if (mot
->machmodel
== NULL
)
247 machmodel
->store (ii
, NULL
);
249 machmodel
->store (ii
, dbe_strdup (mot
->machmodel
));
252 Vector
<void*> *res
= new Vector
<void*>(8);
253 res
->store (0, indx
);
254 res
->store (1, name
);
255 res
->store (2, mnemonic
);
256 res
->store (3, formula
);
257 res
->store (4, machmodel
);
258 res
->store (5, order
);
259 res
->store (6, sdesc
);
260 res
->store (7, ldesc
);
264 // Static function to set order of memory object tabs
266 MemorySpace::set_MemTabOrder (Vector
<int> *orders
)
268 int size
= orders
->size ();
269 ordlist
= new Vector
<int>(size
);
270 for (int i
= 0; i
< size
; i
++)
271 ordlist
->store (i
, orders
->fetch (i
));
274 // Static function to define a new memory object type
276 MemorySpace::mobj_define (char *mname
, char *mindex_exp
, char *_machmodel
,
277 char *short_description
, char *long_description
)
282 return dbe_strdup (GTXT ("No memory object name has been specified."));
283 if (isalpha ((int) (mname
[0])) == 0)
284 return dbe_sprintf (GTXT ("Memory Object type name %s does not begin with an alphabetic character"),
289 if (isalnum ((int) (*p
)) == 0 && *p
!= '_')
290 return dbe_sprintf (GTXT ("Memory Object type name %s contains a non-alphanumeric character"),
295 mot
= findMemSpaceByName (mname
);
298 if (strcmp (mot
->index_expr
, mindex_exp
) == 0)
299 // It's a redefinition, but the new definition is the same
301 return dbe_sprintf (GTXT ("Memory/Index Object type name %s is already defined"),
305 // make sure the name is not in use
306 if (dbeSession
->findIndexSpaceByName (mname
) >= 0)
307 return dbe_sprintf (GTXT ("Memory/Index Object type name %s is already defined"),
310 if (mindex_exp
== NULL
|| *mindex_exp
== 0)
311 return dbe_strdup (GTXT ("No index-expr has been specified."));
313 // verify that the index expression parses correctly
314 Expression
*e
= dbeSession
->ql_parse (mindex_exp
);
316 return dbe_sprintf (GTXT ("Memory Object index expression is invalid: %s"),
320 // It's OK, create the new table entry
321 char *s
= dbeSession
->indxobj_define (mname
, NULL
, mindex_exp
,
322 short_description
, long_description
);
325 IndexObjType_t
*indObj
= dbeSession
->findIndexSpace (mname
);
327 mot
= new MemObjType_t
;
328 mot
->type
= indObj
->type
;
329 indObj
->memObj
= mot
;
330 mot
->name
= dbe_strdup (mname
);
331 mot
->index_expr
= dbe_strdup (mindex_exp
);
332 mot
->mnemonic
= MemorySpace::pickMnemonic (mname
);
333 mot
->machmodel
= dbe_strdup (_machmodel
);
334 mot
->short_description
= dbe_strdup (short_description
);
335 mot
->long_description
= dbe_strdup (long_description
);
337 // add it to the list
338 dyn_memobj
->append (mot
);
341 if (dbeSession
!= NULL
)
342 dbeSession
->mobj_define (mot
);
346 // Static function to delete a new memory object type
349 MemorySpace::mobj_delete (char *mname
)
352 return dbe_strdup (GTXT ("No memory object name has been specified.\n"));
354 // search the dynamic types
355 for (long idx
= 0, sz
= VecSize (dyn_memobj
); idx
< sz
; idx
++)
357 MemObjType_t
*mt
= dyn_memobj
->get (idx
);
358 if (strcasecmp (mt
->name
, mname
) == 0)
360 // delete it from the vector
361 mt
= dyn_memobj
->remove (idx
);
363 dbeSession
->removeIndexSpaceByName (mname
);
367 return dbe_sprintf (GTXT ("Memory object `%s' is not defined.\n"), mname
);
370 // Static function to get a list of memory object names from a machine model
373 MemorySpace::getMachineModelMemObjs (char *mname
)
375 Vector
<char *> *ret
= new Vector
<char *> ();
379 // search the memory objects
382 Vec_loop (MemObjType_t
*, dyn_memobj
, idx
, mt
)
384 if (mt
->machmodel
!= NULL
&& strcmp (mt
->machmodel
, mname
) == 0)
386 char *n
= dbe_strdup (mt
->name
);
394 MemorySpace::pickMnemonic (char *name
)
400 MemorySpace::get_filter_keywords (Vector
<void*> *res
)
402 Vector
<char*> *kwCategory
= (Vector
<char*>*) res
->fetch (0);
403 Vector
<char*> *kwCategoryI18N
= (Vector
<char*>*) res
->fetch (1);
404 Vector
<char*> *kwDataType
= (Vector
<char*>*) res
->fetch (2);
405 Vector
<char*> *kwKeyword
= (Vector
<char*>*) res
->fetch (3);
406 Vector
<char*> *kwFormula
= (Vector
<char*>*) res
->fetch (4);
407 Vector
<char*> *kwDescription
= (Vector
<char*>*) res
->fetch (5);
408 Vector
<void*> *kwEnumDescs
= (Vector
<void*>*) res
->fetch (6);
410 char *vtypeNames
[] = VTYPE_TYPE_NAMES
;
411 for (int i
= 0, sz
= dyn_memobj
? dyn_memobj
->size () : 0; i
< sz
; i
++)
413 MemObjType_t
*obj
= dyn_memobj
->fetch (i
);
414 kwCategory
->append (dbe_strdup (NTXT ("FK_MEMOBJ")));
415 kwCategoryI18N
->append (dbe_strdup (GTXT ("Memory Object Definitions")));
416 kwDataType
->append (dbe_strdup (vtypeNames
[TYPE_INT64
]));
417 kwKeyword
->append (dbe_strdup (obj
->name
));
418 kwFormula
->append (dbe_strdup (obj
->index_expr
));
419 kwDescription
->append (NULL
);
420 kwEnumDescs
->append (NULL
);
425 MemorySpace::findMemSpaceByName (const char *mname
)
430 // search the dynamic types
431 Vec_loop (MemObjType_t
*, dyn_memobj
, idx
, mt
)
433 if (strcasecmp (mt
->name
, mname
) == 0)
440 MemorySpace::findMemSpaceByIndex (int index
)
445 // search the dynamic types
446 Vec_loop (MemObjType_t
*, dyn_memobj
, idx
, mt
)
448 if (mt
->type
== index
)