|
From: <sv...@va...> - 2008-02-14 12:09:03
|
Author: sewardj
Date: 2008-02-14 12:09:04 +0000 (Thu, 14 Feb 2008)
New Revision: 7407
Log:
Improve storage management: put all names and D3Expr blocks from
Dwarf3 .debug_info reading, into the DebugInfo's string table. This
avoids bazillions of tiny allocations, and makes it easy to free all
those strings at munmap time.
Modified:
branches/DATASYMS/coregrind/m_debuginfo/debuginfo.c
branches/DATASYMS/coregrind/m_debuginfo/misc.c
branches/DATASYMS/coregrind/m_debuginfo/priv_misc.h
branches/DATASYMS/coregrind/m_debuginfo/priv_storage.h
branches/DATASYMS/coregrind/m_debuginfo/priv_tytypes.h
branches/DATASYMS/coregrind/m_debuginfo/readdwarf3.c
branches/DATASYMS/coregrind/m_debuginfo/storage.c
branches/DATASYMS/coregrind/m_debuginfo/tytypes.c
Modified: branches/DATASYMS/coregrind/m_debuginfo/debuginfo.c
===================================================================
--- branches/DATASYMS/coregrind/m_debuginfo/debuginfo.c 2008-02-14 00:44:17 UTC (rev 7406)
+++ branches/DATASYMS/coregrind/m_debuginfo/debuginfo.c 2008-02-14 12:09:04 UTC (rev 7407)
@@ -192,6 +192,7 @@
/* Free a DebugInfo, and also all the stuff hanging off it. */
static void free_DebugInfo ( DebugInfo* di )
{
+ Word i, j;
struct strchunk *chunk, *next;
vg_assert(di != NULL);
if (di->filename) ML_(dinfo_free)(di->filename);
@@ -206,19 +207,17 @@
}
{ TyAdmin *admin1, *admin2;
+ GExpr *gexpr1, *gexpr2;
for (admin1 = di->tyadmins; admin1; admin1 = admin2) {
admin2 = admin1->next;
- //ML_(dinfo_free)(admin1);
ML_(delete_TyAdmin_and_payload)(admin1);
}
- GExpr *gexpr1, *gexpr2;
for (gexpr1 = di->gexprs; gexpr1; gexpr1 = gexpr2) {
gexpr2 = gexpr1->next;
ML_(dinfo_free)(gexpr1);
}
}
- Word i, j;
if (di->varinfo) {
for (i = 0; i < VG_(sizeXA)(di->varinfo); i++) {
OSet* scope = *(OSet**)VG_(indexXA)(di->varinfo, i);
@@ -233,13 +232,11 @@
for (j = 0; j < VG_(sizeXA)( arange->vars ); j++) {
DiVariable* var = (DiVariable*)VG_(indexXA)(arange->vars,j);
vg_assert(var);
- /////////////////////////////
- //if (var->name && 0xDD != *(var->name))
- // ML_(dinfo_free)(var->name);
- // var->name gets used more than once .. can't free it
- /////////////////////////////
+ /* Nothing to free in var: all the pointer fields refer
+ to stuff either on an admin list, or in .strchunks */
}
- ML_(dinfo_free)(arange->vars);
+ VG_(deleteXA)(arange->vars);
+ /* Don't free arange itself, as OSetGen_Destroy does that */
}
VG_(OSetGen_Destroy)(scope);
}
@@ -1021,7 +1018,7 @@
Bool show = False;
vg_assert(var->name);
vg_assert(var->type);
- vg_assert(var->gexprV);
+ vg_assert(var->gexpr);
var_szB = ML_(sizeOfType)(var->type);
if (show) {
@@ -1030,7 +1027,7 @@
VG_(printf)("\n");
}
- res = ML_(evaluate_GX)( var->gexprV, var->fbGXv, regs );
+ res = ML_(evaluate_GX)( var->gexpr, var->fbGX, regs );
if (show) VG_(printf)("VVVV: -> 0x%lx %s\n", res.res,
res.failure ? res.failure : "(success)");
Modified: branches/DATASYMS/coregrind/m_debuginfo/misc.c
===================================================================
--- branches/DATASYMS/coregrind/m_debuginfo/misc.c 2008-02-14 00:44:17 UTC (rev 7406)
+++ branches/DATASYMS/coregrind/m_debuginfo/misc.c 2008-02-14 12:09:04 UTC (rev 7407)
@@ -59,14 +59,7 @@
return VG_(arena_strdup)( VG_AR_DINFO, str );
}
-UChar* ML_(dinfo_memdup)( UChar* mem, UWord nbytes ) {
- UChar* r = VG_(arena_malloc)( VG_AR_DINFO, nbytes );
- if (nbytes > 0)
- VG_(memcpy)( r, mem, nbytes );
- return r;
-}
-
void ML_(copy_bytes_into_XA) ( XArray* /* of UChar */ xa,
void* bytes, Word nbytes ) {
Word i;
Modified: branches/DATASYMS/coregrind/m_debuginfo/priv_misc.h
===================================================================
--- branches/DATASYMS/coregrind/m_debuginfo/priv_misc.h 2008-02-14 00:44:17 UTC (rev 7406)
+++ branches/DATASYMS/coregrind/m_debuginfo/priv_misc.h 2008-02-14 12:09:04 UTC (rev 7407)
@@ -50,7 +50,6 @@
void* ML_(dinfo_zalloc)( SizeT szB );
void ML_(dinfo_free)( void* v );
UChar* ML_(dinfo_strdup)( const UChar* str );
-UChar* ML_(dinfo_memdup)( UChar* mem, UWord nbytes );
/* Copy bytes into an XArray of what are assumed to be, well,
bytes. */
Modified: branches/DATASYMS/coregrind/m_debuginfo/priv_storage.h
===================================================================
--- branches/DATASYMS/coregrind/m_debuginfo/priv_storage.h 2008-02-14 00:44:17 UTC (rev 7406)
+++ branches/DATASYMS/coregrind/m_debuginfo/priv_storage.h 2008-02-14 12:09:04 UTC (rev 7407)
@@ -220,11 +220,12 @@
typedef
struct {
- UChar* name; /* freestanding, in AR_DINFO */
- Type* type;
- void* gexprV; /* FIXME: make this GExpr* */
- void* fbGXv; /* FIXME: make this GExpr*. SHARED. */
- UChar* fileName; /* where declared; may be NULL. */
+ UChar* name; /* in DebugInfo.strchunks */
+ Type* type; /* on DebugInfo.admin list */
+ GExpr* gexpr; /* on DebugInfo.gexprs list */
+ GExpr* fbGX; /* SHARED. */
+ UChar* fileName; /* where declared; may be NULL. in
+ DebugInfo.strchunks */
Int lineNo; /* where declared; may be zero. */
}
DiVariable;
@@ -416,8 +417,8 @@
Addr aMax,
UChar* name,
Type* type,
- void* gexpr, /* actually GExpr* */
- void* fbGXv, /* actually GExpr*. SHARED. */
+ GExpr* gexpr,
+ GExpr* fbGX, /* SHARED. */
UChar* fileName, /* where decl'd - may be NULL */
Int lineNo, /* where decl'd - may be zero */
Bool show );
Modified: branches/DATASYMS/coregrind/m_debuginfo/priv_tytypes.h
===================================================================
--- branches/DATASYMS/coregrind/m_debuginfo/priv_tytypes.h 2008-02-14 00:44:17 UTC (rev 7406)
+++ branches/DATASYMS/coregrind/m_debuginfo/priv_tytypes.h 2008-02-14 12:09:04 UTC (rev 7407)
@@ -58,12 +58,12 @@
/* an enumeration value */
struct _TyAtom {
- UChar* name; /* AR_DINFO, unshared */
+ UChar* name; /* in DebugInfo.strchunks */
Long value;
};
struct _TyField {
- UChar* name; /* AR_DINFO, unshared */
+ UChar* name; /* in DebugInfo.strchunks */
Type* typeR;
D3Expr* loc;
Bool isStruct;
@@ -78,7 +78,7 @@
};
struct _D3Expr {
- UChar* bytes; /* AR_DINFO, unshared */
+ UChar* bytes; /* in DebugInfo.strchunks */
UWord nbytes;
};
@@ -87,7 +87,7 @@
Ty_Enum, Ty_Array, Ty_Fn, Ty_Qual, Ty_Void } tag;
union {
struct {
- UChar* name; /* AR_DINFO, unshared */
+ UChar* name; /* in DebugInfo.strchunks */
Int szB;
UChar enc; /* S:signed U:unsigned F:floating */
} Base;
@@ -97,18 +97,18 @@
Bool isPtr;
} PorR;
struct {
- UChar* name; /* AR_DINFO, unshared */
+ UChar* name; /* in DebugInfo.strchunks */
Type* typeR; /* MAY BE NULL, denoting unknown */
} TyDef;
struct {
- UChar* name; /* AR_DINFO, unshared */
+ UChar* name; /* in DebugInfo.strchunks */
UWord szB;
XArray* /* of TyField* */ fields;
Bool complete;
Bool isStruct;
} StOrUn;
struct {
- UChar* name; /* AR_DINFO, unshared */
+ UChar* name; /* in DebugInfo.strchunks */
Int szB;
XArray* /* of TyAtom* */ atomRs;
} Enum;
Modified: branches/DATASYMS/coregrind/m_debuginfo/readdwarf3.c
===================================================================
--- branches/DATASYMS/coregrind/m_debuginfo/readdwarf3.c 2008-02-14 00:44:17 UTC (rev 7406)
+++ branches/DATASYMS/coregrind/m_debuginfo/readdwarf3.c 2008-02-14 12:09:04 UTC (rev 7407)
@@ -55,7 +55,7 @@
#include "pub_core_libcprint.h"
#include "pub_core_options.h"
#include "pub_core_xarray.h"
-#include "priv_misc.h" /* dinfo_zalloc/free/strdup */
+#include "priv_misc.h" /* dinfo_zalloc/free */
#include "priv_tytypes.h"
#include "priv_d3basics.h"
#include "priv_storage.h"
@@ -224,10 +224,10 @@
/* Assume 'c' points to the start of a string. Return the absolute
address of whatever it points at, and advance it past the
- terminating zero. This makes it safe for the caller to then strdup
- the returned value, since (w.r.t. image overruns) the process of
- advancing past the terminating zero will already have "vetted" the
- string. */
+ terminating zero. This makes it safe for the caller to then copy
+ the string with ML_(addStr), since (w.r.t. image overruns) the
+ process of advancing past the terminating zero will already have
+ "vetted" the string. */
static UChar* get_AsciiZ ( Cursor* c ) {
UChar uc;
UChar* res = get_address_of_Cursor(c);
@@ -299,6 +299,8 @@
/* Where is .debug_line? */
UChar* debug_line_img;
UWord debug_line_sz;
+ /* --- Needed so we can add stuff to the string table. --- */
+ struct _DebugInfo* di;
/* --- a cache for set_abbv_Cursor --- */
/* abbv_code == (ULong)-1 for an unused entry. */
struct { ULong abbv_code; UWord posn; } saC_cache[N_ABBV_CACHE];
@@ -1143,13 +1145,13 @@
vg_assert( VG_(sizeXA)( parser->filenameTable ) == 0 );
/* Add a dummy index-zero entry. DWARF3 numbers its files
from 1, for some reason. */
- str = ML_(dinfo_strdup)( "<unknown>" );;
+ str = ML_(addStr)( cc->di, "<unknown>", -1 );
VG_(addToXA)( parser->filenameTable, &str );
while (peek_UChar(&c) != 0) {
str = get_AsciiZ(&c);
TRACE_D3(" read_filename_table: %ld %s\n",
VG_(sizeXA)(parser->filenameTable), str);
- str = ML_(dinfo_strdup)( str );
+ str = ML_(addStr)( cc->di, str, -1 );
VG_(addToXA)( parser->filenameTable, &str );
(void)get_ULEB128( &c ); /* skip directory index # */
(void)get_ULEB128( &c ); /* skip last mod time */
@@ -1357,7 +1359,7 @@
cc, c_die, False/*td3*/, form );
n_attrs++;
if (attr == DW_AT_name && ctsMemSzB > 0) {
- name = ML_(dinfo_strdup)( (UChar*)(UWord)cts );
+ name = ML_(addStr)( cc->di, (UChar*)(UWord)cts, -1 );
}
if (attr == DW_AT_location
&& ((ctsMemSzB > 0 && ctsSzB == 0)
@@ -1408,9 +1410,10 @@
vg_assert(parser->sp >= 0);
if (!name)
- name = ML_(dinfo_strdup)(
- dtag == DW_TAG_variable ? "<anon_variable>"
- : "<anon_formal>" );
+ name = ML_(addStr)(
+ cc->di, dtag == DW_TAG_variable
+ ? "<anon_variable>"
+ : "<anon_formal>", -1 );
/* If this is a local variable (non-external), try to find
the GExpr for the DW_AT_frame_base of the containing
@@ -1775,7 +1778,7 @@
cc, c_die, False/*td3*/, form );
if (attr == DW_AT_name && ctsMemSzB > 0) {
type->Ty.Base.name
- = ML_(dinfo_strdup)( (UChar*)(UWord)cts );
+ = ML_(addStr)( cc->di, (UChar*)(UWord)cts, -1 );
}
if (attr == DW_AT_byte_size && ctsSzB > 0) {
type->Ty.Base.szB = cts;
@@ -1850,7 +1853,7 @@
cc, c_die, False/*td3*/, form );
if (attr == DW_AT_name && ctsMemSzB > 0) {
type->Ty.Enum.name
- = ML_(dinfo_strdup)( (UChar*)(UWord)cts );
+ = ML_(addStr)( cc->di, (UChar*)(UWord)cts, -1 );
}
if (attr == DW_AT_byte_size && ctsSzB > 0) {
type->Ty.Enum.szB = cts;
@@ -1875,7 +1878,7 @@
get_Form_contents( &cts, &ctsSzB, &ctsMemSzB,
cc, c_die, False/*td3*/, form );
if (attr == DW_AT_name && ctsMemSzB > 0) {
- atom->name = ML_(dinfo_strdup)( (UChar*)(UWord)cts );
+ atom->name = ML_(addStr)( cc->di, (UChar*)(UWord)cts, -1 );
}
if (attr == DW_AT_const_value && ctsSzB > 0) {
atom->value = cts;
@@ -1918,7 +1921,7 @@
cc, c_die, False/*td3*/, form );
if (attr == DW_AT_name && ctsMemSzB > 0) {
type->Ty.StOrUn.name
- = ML_(dinfo_strdup)( (UChar*)(UWord)cts );
+ = ML_(addStr)( cc->di, (UChar*)(UWord)cts, -1 );
}
if (attr == DW_AT_byte_size && ctsSzB >= 0) {
type->Ty.StOrUn.szB = cts;
@@ -1971,14 +1974,14 @@
get_Form_contents( &cts, &ctsSzB, &ctsMemSzB,
cc, c_die, False/*td3*/, form );
if (attr == DW_AT_name && ctsMemSzB > 0) {
- field->name = ML_(dinfo_strdup)( (UChar*)(UWord)cts );
+ field->name = ML_(addStr)( cc->di, (UChar*)(UWord)cts, -1 );
}
if (attr == DW_AT_type && ctsSzB > 0) {
field->typeR = (Type*)(UWord)cts;
}
if (attr == DW_AT_data_member_location && ctsMemSzB > 0) {
- UChar* copy = ML_(dinfo_memdup)( (UChar*)(UWord)cts,
- (UWord)ctsMemSzB );
+ UChar* copy = ML_(addStr)( cc->di, (UChar*)(UWord)cts,
+ (Int)ctsMemSzB );
expr = ML_(new_D3Expr)( copy, (UWord)ctsMemSzB );
}
}
@@ -1993,7 +1996,7 @@
parent_is_struct
= parser->qparent[parser->sp]->Ty.StOrUn.isStruct;
if (!field->name)
- field->name = ML_(dinfo_strdup)("<anon_field>");
+ field->name = ML_(addStr)(cc->di, "<anon_field>", -1);
if ((!field->name) || (field->typeR == D3_INVALID_CUOFF))
goto bad_DIE;
if (parent_is_struct && (!expr))
@@ -2119,7 +2122,7 @@
cc, c_die, False/*td3*/, form );
if (attr == DW_AT_name && ctsMemSzB > 0) {
type->Ty.TyDef.name
- = ML_(dinfo_strdup)( (UChar*)(UWord)cts );
+ = ML_(addStr)( cc->di, (UChar*)(UWord)cts, -1 );
}
if (attr == DW_AT_type && ctsSzB > 0) {
type->Ty.TyDef.typeR = (Type*)(UWord)cts;
@@ -2810,6 +2813,7 @@
cc.debug_line_img = debug_line_img;
cc.debug_line_sz = debug_line_sz;
cc.cu_start_offset = cu_start_offset;
+ cc.di = di;
/* The CU's svma can be deduced by looking at the AT_low_pc
value in the top level TAG_compile_unit, which is the topmost
DIE. We'll leave it for the 'varparser' to acquire that info
Modified: branches/DATASYMS/coregrind/m_debuginfo/storage.c
===================================================================
--- branches/DATASYMS/coregrind/m_debuginfo/storage.c 2008-02-14 00:44:17 UTC (rev 7406)
+++ branches/DATASYMS/coregrind/m_debuginfo/storage.c 2008-02-14 12:09:04 UTC (rev 7407)
@@ -170,8 +170,11 @@
Int space_needed;
UChar* p;
- if (len == -1)
+ if (len == -1) {
len = VG_(strlen)(str);
+ } else {
+ vg_assert(len >= 0);
+ }
space_needed = 1 + len;
@@ -571,8 +574,8 @@
Addr aMax,
UChar* name,
Type* type,
- void* gexprV, /* actually GExpr* */
- void* fbGXv, /* actually GExpr*. SHARED. */
+ GExpr* gexpr,
+ GExpr* fbGX,
UChar* fileName, /* where decl'd - may be NULL */
Int lineNo, /* where decl'd - may be zero */
Bool show )
@@ -586,11 +589,11 @@
level, aMin, aMax, name );
ML_(pp_Type_C_ishly)( type );
VG_(printf)("\n Var=");
- ML_(pp_GX)(gexprV);
+ ML_(pp_GX)(gexpr);
VG_(printf)("\n");
- if (fbGXv) {
+ if (fbGX) {
VG_(printf)(" FrB=");
- ML_(pp_GX)( fbGXv );
+ ML_(pp_GX)( fbGX );
VG_(printf)("\n");
} else {
VG_(printf)(" FrB=none\n");
@@ -602,7 +605,7 @@
vg_assert(aMin <= aMax);
vg_assert(name);
vg_assert(type);
- vg_assert(gexprV);
+ vg_assert(gexpr);
if (!di->varinfo) {
di->varinfo = VG_(newXA)( ML_(dinfo_zalloc), ML_(dinfo_free),
@@ -630,8 +633,8 @@
/* DiVariable var; */
var.name = name;
var.type = type;
- var.gexprV = gexprV;
- var.fbGXv = fbGXv;
+ var.gexpr = gexpr;
+ var.fbGX = fbGX;
var.fileName = fileName;
var.lineNo = lineNo;
vg_assert(range);
Modified: branches/DATASYMS/coregrind/m_debuginfo/tytypes.c
===================================================================
--- branches/DATASYMS/coregrind/m_debuginfo/tytypes.c 2008-02-14 00:44:17 UTC (rev 7406)
+++ branches/DATASYMS/coregrind/m_debuginfo/tytypes.c 2008-02-14 12:09:04 UTC (rev 7407)
@@ -81,13 +81,11 @@
}
void ML_(delete_TyAtom)( TyAtom* atom ) {
- if (atom->name)
- ML_(dinfo_free)(atom->name);
+ /* .name is in DebugInfo.strchunks */
ML_(dinfo_free)(atom);
}
void ML_(delete_TyField)( TyField* field ) {
- if (field->name)
- ML_(dinfo_free)(field->name);
+ /* .name is in DebugInfo.strchunks */
/* typeR and loc will be on the admin list; no need to free */
ML_(dinfo_free)(field);
}
@@ -95,35 +93,31 @@
ML_(dinfo_free)(bounds);
}
void ML_(delete_D3Expr)( D3Expr* expr ) {
- if (expr->bytes)
- ML_(dinfo_free)(expr->bytes);
+ /* .bytes is in DebugInfo.strchunks */
ML_(dinfo_free)(expr);
}
+__attribute__((noinline))
void ML_(delete_Type)( Type* ty ) {
switch (ty->tag) {
case Ty_Base:
- if (ty->Ty.Base.name)
- ML_(dinfo_free)(ty->Ty.Base.name);
+ /* .name is in DebugInfo.strchunks */
break;
case Ty_PorR:
/* typeR will be on the admin list */
break;
case Ty_TyDef:
- if (ty->Ty.TyDef.name)
- ML_(dinfo_free)(ty->Ty.TyDef.name);
+ /* .name is in DebugInfo.strchunks */
/* typeR will be on the admin list */
break;
case Ty_StOrUn:
- if (ty->Ty.StOrUn.name)
- ML_(dinfo_free)(ty->Ty.StOrUn.name);
+ /* .name is in DebugInfo.strchunks */
/* Just dump the containing XArray. The fields themselves
will be on the admin list. */
if (ty->Ty.StOrUn.fields)
VG_(deleteXA)(ty->Ty.StOrUn.fields);
break;
case Ty_Enum:
- if (ty->Ty.Enum.name)
- ML_(dinfo_free)(ty->Ty.Enum.name);
+ /* .name is in DebugInfo.strchunks */
if (ty->Ty.Enum.atomRs)
VG_(deleteXA)( ty->Ty.Enum.atomRs);
/* Just dump the containing XArray. The atoms themselves
|