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 ------------------------------------------------------------------------- This SF.net email is sponsored by: Microsoft Defy all challenges. Microsoft(R) Visual Studio 2008. http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/ _______________________________________________ Valgrind-developers mailing list Valgrind-developers@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/valgrind-developers