|
From: <sv...@va...> - 2008-09-09 23:10:24
|
Author: sewardj
Date: 2008-09-10 00:10:30 +0100 (Wed, 10 Sep 2008)
New Revision: 8595
Log:
Add a TyEntIndexCache type and mechanism, to speed up indexing
by compilation-unit offset, in type-entity arrays. For a large
test case, the cache achieves a hit rate of 82%.
Modified:
branches/YARD/coregrind/m_debuginfo/debuginfo.c
branches/YARD/coregrind/m_debuginfo/priv_tytypes.h
branches/YARD/coregrind/m_debuginfo/readdwarf3.c
branches/YARD/coregrind/m_debuginfo/storage.c
branches/YARD/coregrind/m_debuginfo/tytypes.c
branches/YARD/coregrind/m_main.c
Modified: branches/YARD/coregrind/m_debuginfo/debuginfo.c
===================================================================
--- branches/YARD/coregrind/m_debuginfo/debuginfo.c 2008-09-09 18:18:26 UTC (rev 8594)
+++ branches/YARD/coregrind/m_debuginfo/debuginfo.c 2008-09-09 23:10:30 UTC (rev 8595)
@@ -844,7 +844,7 @@
di = debugInfo_list;
while (di) {
di2 = di->next;
- VG_(printf)("XXX rm %p\n", di);
+ VG_(printf)("VG_(di_discard_ALL_debuginfo): deleting di %p\n", di);
free_DebugInfo( di );
di = di2;
}
Modified: branches/YARD/coregrind/m_debuginfo/priv_tytypes.h
===================================================================
--- branches/YARD/coregrind/m_debuginfo/priv_tytypes.h 2008-09-09 18:18:26 UTC (rev 8594)
+++ branches/YARD/coregrind/m_debuginfo/priv_tytypes.h 2008-09-09 23:10:30 UTC (rev 8595)
@@ -144,13 +144,6 @@
void ML_(pp_TyEnt_C_ishly)( XArray* /* of TyEnt */ tyents,
UWord cuOff );
-/* 'ents' is an XArray of TyEnts, sorted by their .cuOff fields. Find
- the entry which has .cuOff field as specified. Returns NULL if not
- found. Asserts if more than one entry has the specified .cuOff
- value. */
-TyEnt* ML_(TyEnts__index_by_cuOff) ( XArray* /* of TyEnt */ ents,
- UWord cuOff_to_find );
-
/* Generates a total ordering on TyEnts based only on their .cuOff
fields. */
Word ML_(TyEnt__cmp_by_cuOff_only) ( TyEnt* te1, TyEnt* te2 );
@@ -179,6 +172,40 @@
UWord ty_cuOff,
OffT offset );
+
+/* A fast-lookup cache for ML_(TyEnts__index_by_cuOff). Nothing
+ particularly surprising here; it's 2 way set associative, with some
+ number of ways, doesn't particularly have to be a power of 2. In
+ order to have a way to indicate an invalid entry, we set the second
+ value of the pair to NULL, and keep checking for it, since
+ unfortunately there's no obvious cuOff number that we could put in
+ the first word of the pair that could indicate an invalid entry.
+
+ 4096 arrived at as the best value for an E6600 loading Qt-4.4.1
+ Designer and all associated libraries, compiled by gcc-4.3.1,
+ -g -O, 64-bit, which is at least a moderately good stress test,
+ with the largest library being about 150MB.*/
+
+#define N_TYENT_INDEX_CACHE 4096
+
+typedef
+ struct {
+ struct { UWord cuOff0; TyEnt* ent0;
+ UWord cuOff1; TyEnt* ent1; }
+ ce[N_TYENT_INDEX_CACHE];
+ }
+ TyEntIndexCache;
+
+void ML_(TyEntIndexCache__invalidate) ( TyEntIndexCache* cache );
+
+/* 'ents' is an XArray of TyEnts, sorted by their .cuOff fields. Find
+ the entry which has .cuOff field as specified. Returns NULL if not
+ found. Asserts if more than one entry has the specified .cuOff
+ value. */
+TyEnt* ML_(TyEnts__index_by_cuOff) ( XArray* /* of TyEnt */ ents,
+ TyEntIndexCache* cache,
+ UWord cuOff_to_find );
+
#endif /* ndef __PRIV_TYTYPES_H */
/*--------------------------------------------------------------------*/
Modified: branches/YARD/coregrind/m_debuginfo/readdwarf3.c
===================================================================
--- branches/YARD/coregrind/m_debuginfo/readdwarf3.c 2008-09-09 18:18:26 UTC (rev 8594)
+++ branches/YARD/coregrind/m_debuginfo/readdwarf3.c 2008-09-09 23:10:30 UTC (rev 8595)
@@ -2222,7 +2222,7 @@
typeE.cuOff = posn;
typeE.tag = Te_TyEnum;
typeE.Te.TyEnum.atomRs
- = VG_(newXA)( ML_(dinfo_zalloc), "di.readdwarf3.ptD.1",
+ = VG_(newXA)( ML_(dinfo_zalloc), "di.readdwarf3.ptD.enum_type.1",
ML_(dinfo_free),
sizeof(UWord) );
while (True) {
@@ -2233,7 +2233,7 @@
cc, c_die, False/*td3*/, form );
if (attr == DW_AT_name && ctsMemSzB > 0) {
typeE.Te.TyEnum.name
- = ML_(dinfo_strdup)( "di.readdwarf3.enum_type.1",
+ = ML_(dinfo_strdup)( "di.readdwarf3.pTD.enum_type.2",
(UChar*)(UWord)cts );
}
if (attr == DW_AT_byte_size && ctsSzB > 0) {
@@ -2262,7 +2262,7 @@
cc, c_die, False/*td3*/, form );
if (attr == DW_AT_name && ctsMemSzB > 0) {
atomE.Te.Atom.name
- = ML_(dinfo_strdup)( "di.readdwarf3.enumerator.1",
+ = ML_(dinfo_strdup)( "di.readdwarf3.pTD.enumerator.1",
(UChar*)(UWord)cts );
}
if (attr == DW_AT_const_value && ctsSzB > 0) {
@@ -2301,12 +2301,12 @@
typeE.tag = Te_TyStOrUn;
typeE.Te.TyStOrUn.name = NULL;
typeE.Te.TyStOrUn.fieldRs
- = VG_(newXA)( ML_(dinfo_zalloc), "di.readdwarf3.struct_type.1",
+ = VG_(newXA)( ML_(dinfo_zalloc), "di.readdwarf3.pTD.struct_type.1",
ML_(dinfo_free),
sizeof(UWord) );
typeE.Te.TyStOrUn.complete = True;
typeE.Te.TyStOrUn.isStruct = dtag == DW_TAG_structure_type
- || dtag == DW_TAG_class_type;
+ || dtag == DW_TAG_class_type;
while (True) {
DW_AT attr = (DW_AT) get_ULEB128( c_abbv );
DW_FORM form = (DW_FORM)get_ULEB128( c_abbv );
@@ -2431,7 +2431,7 @@
typeE.tag = Te_TyArray;
typeE.Te.TyArray.typeR = D3_INVALID_CUOFF;
typeE.Te.TyArray.boundRs
- = VG_(newXA)( ML_(dinfo_zalloc), "di.readdwarf3.ptD.3",
+ = VG_(newXA)( ML_(dinfo_zalloc), "di.readdwarf3.ptD.array_type.1",
ML_(dinfo_free),
sizeof(UWord) );
while (True) {
@@ -2672,10 +2672,11 @@
static UWord chase_cuOff ( Bool* changed,
XArray* /* of TyEnt */ ents,
+ TyEntIndexCache* ents_cache,
UWord cuOff )
{
TyEnt* ent;
- ent = ML_(TyEnts__index_by_cuOff)( ents, cuOff );
+ ent = ML_(TyEnts__index_by_cuOff)( ents, ents_cache, cuOff );
if (!ent) {
VG_(printf)("chase_cuOff: no entry for 0x%05lx\n", cuOff);
@@ -2697,6 +2698,7 @@
static
void chase_cuOffs_in_XArray ( Bool* changed,
XArray* /* of TyEnt */ ents,
+ TyEntIndexCache* ents_cache,
/*MOD*/XArray* /* of UWord */ cuOffs )
{
Bool b2 = False;
@@ -2704,7 +2706,7 @@
for (i = 0; i < n; i++) {
Bool b = False;
UWord* p = VG_(indexXA)( cuOffs, i );
- *p = chase_cuOff( &b, ents, *p );
+ *p = chase_cuOff( &b, ents, ents_cache, *p );
if (b)
b2 = True;
}
@@ -2712,6 +2714,7 @@
}
static Bool TyEnt__subst_R_fields ( XArray* /* of TyEnt */ ents,
+ TyEntIndexCache* ents_cache,
/*MOD*/TyEnt* te )
{
Bool b, changed = False;
@@ -2719,7 +2722,8 @@
case Te_EMPTY:
break;
case Te_INDIR:
- te->Te.INDIR.indR = chase_cuOff( &b, ents, te->Te.INDIR.indR );
+ te->Te.INDIR.indR
+ = chase_cuOff( &b, ents, ents_cache, te->Te.INDIR.indR );
if (b) changed = True;
break;
case Te_UNKNOWN:
@@ -2727,7 +2731,8 @@
case Te_Atom:
break;
case Te_Field:
- te->Te.Field.typeR = chase_cuOff( &b, ents, te->Te.Field.typeR );
+ te->Te.Field.typeR
+ = chase_cuOff( &b, ents, ents_cache, te->Te.Field.typeR );
if (b) changed = True;
break;
case Te_Bound:
@@ -2735,31 +2740,35 @@
case Te_TyBase:
break;
case Te_TyPorR:
- te->Te.TyPorR.typeR = chase_cuOff( &b, ents, te->Te.TyPorR.typeR );
+ te->Te.TyPorR.typeR
+ = chase_cuOff( &b, ents, ents_cache, te->Te.TyPorR.typeR );
if (b) changed = True;
break;
case Te_TyTyDef:
- te->Te.TyTyDef.typeR = chase_cuOff( &b, ents, te->Te.TyTyDef.typeR );
+ te->Te.TyTyDef.typeR
+ = chase_cuOff( &b, ents, ents_cache, te->Te.TyTyDef.typeR );
if (b) changed = True;
break;
case Te_TyStOrUn:
- chase_cuOffs_in_XArray( &b, ents, te->Te.TyStOrUn.fieldRs );
+ chase_cuOffs_in_XArray( &b, ents, ents_cache, te->Te.TyStOrUn.fieldRs );
if (b) changed = True;
break;
case Te_TyEnum:
- chase_cuOffs_in_XArray( &b, ents, te->Te.TyEnum.atomRs );
+ chase_cuOffs_in_XArray( &b, ents, ents_cache, te->Te.TyEnum.atomRs );
if (b) changed = True;
break;
case Te_TyArray:
- te->Te.TyArray.typeR = chase_cuOff( &b, ents, te->Te.TyArray.typeR );
+ te->Te.TyArray.typeR
+ = chase_cuOff( &b, ents, ents_cache, te->Te.TyArray.typeR );
if (b) changed = True;
- chase_cuOffs_in_XArray( &b, ents, te->Te.TyArray.boundRs );
+ chase_cuOffs_in_XArray( &b, ents, ents_cache, te->Te.TyArray.boundRs );
if (b) changed = True;
break;
case Te_TyFn:
break;
case Te_TyQual:
- te->Te.TyQual.typeR = chase_cuOff( &b, ents, te->Te.TyQual.typeR );
+ te->Te.TyQual.typeR
+ = chase_cuOff( &b, ents, ents_cache, te->Te.TyQual.typeR );
if (b) changed = True;
break;
case Te_TyVoid:
@@ -2777,7 +2786,8 @@
(which should not itself be an indirection). In summary, this
routine shorts out all references to indirection nodes. */
static
-Word dedup_types_substitution_pass ( /*MOD*/XArray* /* of TyEnt */ ents )
+Word dedup_types_substitution_pass ( /*MOD*/XArray* /* of TyEnt */ ents,
+ TyEntIndexCache* ents_cache )
{
Word i, n, nChanged = 0;
Bool b;
@@ -2787,7 +2797,7 @@
vg_assert(ent->tag != Te_EMPTY);
/* We have to substitute everything, even indirections, so as to
ensure that chains of indirections don't build up. */
- b = TyEnt__subst_R_fields( ents, ent );
+ b = TyEnt__subst_R_fields( ents, ents_cache, ent );
if (b)
nChanged++;
}
@@ -2861,9 +2871,12 @@
static
-void dedup_types ( Bool td3, /*MOD*/XArray* /* of TyEnt */ ents )
+void dedup_types ( Bool td3,
+ /*MOD*/XArray* /* of TyEnt */ ents,
+ TyEntIndexCache* ents_cache )
{
Word m, n, i, nDel, nSubst, nThresh;
+ if (0) td3 = True;
n = VG_(sizeXA)( ents );
@@ -2884,7 +2897,7 @@
the array, until there are no more changes. */
do {
nDel = dedup_types_commoning_pass ( ents );
- nSubst = dedup_types_substitution_pass ( ents );
+ nSubst = dedup_types_substitution_pass ( ents, ents_cache );
vg_assert(nDel >= 0 && nSubst >= 0);
TRACE_D3(" %ld deletions, %ld substitutions\n", nDel, nSubst);
} while (nDel > nThresh || nSubst > nThresh);
@@ -2900,7 +2913,8 @@
ent = VG_(indexXA)( ents, i );
if (ent->tag != Te_INDIR) continue;
m++;
- ind = ML_(TyEnts__index_by_cuOff)( ents, ent->Te.INDIR.indR );
+ ind = ML_(TyEnts__index_by_cuOff)( ents, ents_cache,
+ ent->Te.INDIR.indR );
vg_assert(ind);
vg_assert(ind->tag != Te_INDIR);
}
@@ -2925,7 +2939,8 @@
__attribute__((noinline))
static void resolve_variable_types (
void (*barf)( HChar* ) __attribute__((noreturn)),
- /*R-O*/XArray* /* of TyEnt */ tyents,
+ /*R-O*/XArray* /* of TyEnt */ ents,
+ /*MOD*/TyEntIndexCache* ents_cache,
/*MOD*/XArray* /* of TempVar* */ vars
)
{
@@ -2935,9 +2950,11 @@
TempVar* var = *(TempVar**)VG_(indexXA)( vars, i );
/* This is the stated type of the variable. But it might be
an indirection, so be careful. */
- TyEnt* ent = ML_(TyEnts__index_by_cuOff)( tyents, var->typeR );
+ TyEnt* ent = ML_(TyEnts__index_by_cuOff)( ents, ents_cache,
+ var->typeR );
if (ent && ent->tag == Te_INDIR) {
- ent = ML_(TyEnts__index_by_cuOff)( tyents, ent->Te.INDIR.indR );
+ ent = ML_(TyEnts__index_by_cuOff)( ents, ents_cache,
+ ent->Te.INDIR.indR );
vg_assert(ent);
vg_assert(ent->tag != Te_INDIR);
}
@@ -3109,6 +3126,8 @@
XArray* /* of GExpr* */ gexprs;
XArray* /* of TempVar* */ tempvars;
WordFM* /* of (XArray* of AddrRange, void) */ rangestree;
+ TyEntIndexCache* tyents_cache = NULL;
+ TyEntIndexCache* tyents_to_keep_cache = NULL;
TempVar *varp, *varp2;
GExpr* gexpr;
Cursor abbv; /* for showing .debug_abbrev */
@@ -3292,7 +3311,7 @@
delete this tree, and the XArrays attached to it, at the end of
this function. */
rangestree = VG_(newFM)( ML_(dinfo_zalloc),
- "di.readdwarf3.ndrw.1b (rangestree)",
+ "di.readdwarf3.ndrw.2 (rangestree)",
ML_(dinfo_free),
(Word(*)(UWord,UWord))cmp__XArrays_of_AddrRange );
@@ -3300,13 +3319,13 @@
DebugInfo; instead their contents are handed to ML_(addVar) and
the list elements are then deleted. */
tempvars = VG_(newXA)( ML_(dinfo_zalloc),
- "di.readdwarf3.ndrw.2 (TempVar*s array)",
+ "di.readdwarf3.ndrw.3 (TempVar*s array)",
ML_(dinfo_free),
sizeof(TempVar*) );
/* List of GExprs we're accumulating. These wind up in the
DebugInfo. */
- gexprs = VG_(newXA)( ML_(dinfo_zalloc), "di.readdwarf3.ndrw.3",
+ gexprs = VG_(newXA)( ML_(dinfo_zalloc), "di.readdwarf3.ndrw.4",
ML_(dinfo_free), sizeof(GExpr*) );
/* We need a D3TypeParser to keep track of partially constructed
@@ -3394,7 +3413,7 @@
etc. */
vg_assert(!varparser.filenameTable );
varparser.filenameTable
- = VG_(newXA)( ML_(dinfo_zalloc), "di.readdwarf3.ndrw.4",
+ = VG_(newXA)( ML_(dinfo_zalloc), "di.readdwarf3.ndrw.5",
ML_(dinfo_free),
sizeof(UChar*) );
vg_assert(varparser.filenameTable);
@@ -3441,7 +3460,10 @@
TRACE_D3("------ Compressing type entries ------\n");
}
- dedup_types( td3, tyents );
+ tyents_cache = ML_(dinfo_zalloc)( "di.readdwarf3.ndrw.6",
+ sizeof(TyEntIndexCache) );
+ ML_(TyEntIndexCache__invalidate)( tyents_cache );
+ dedup_types( td3, tyents, tyents_cache );
if (td3) {
TRACE_D3("\n");
ML_(pp_TyEnts)(tyents, "After type entity (TyEnt) compression");
@@ -3449,7 +3471,7 @@
TRACE_D3("\n");
TRACE_D3("------ Resolving the types of variables ------\n" );
- resolve_variable_types( barf, tyents, tempvars );
+ resolve_variable_types( barf, tyents, tyents_cache, tempvars );
/* Copy all the non-INDIR tyents into a new table. For large
.so's, about 90% of the tyents will by now have been resolved to
@@ -3457,7 +3479,7 @@
them. */
tyents_to_keep
= VG_(newXA)( ML_(dinfo_zalloc),
- "di.readdwarf3.ndrw.6 (TyEnt to-keep array)",
+ "di.readdwarf3.ndrw.7 (TyEnt to-keep array)",
ML_(dinfo_free), sizeof(TyEnt) );
n = VG_(sizeXA)( tyents );
for (i = 0; i < n; i++) {
@@ -3468,6 +3490,8 @@
VG_(deleteXA)( tyents );
tyents = NULL;
+ ML_(dinfo_free)( tyents_cache );
+ tyents_cache = NULL;
/* Sort tyents_to_keep so we can lookup in it. A complete (if
minor) waste of time, since tyents itself is sorted, but
@@ -3479,6 +3503,12 @@
);
VG_(sortXA)( tyents_to_keep );
+ /* Enable cacheing on tyents_to_keep */
+ tyents_to_keep_cache
+ = ML_(dinfo_zalloc)( "di.readdwarf3.ndrw.8",
+ sizeof(TyEntIndexCache) );
+ ML_(TyEntIndexCache__invalidate)( tyents_to_keep_cache );
+
/* And record the tyents in the DebugInfo. We do this before
starting to hand variables to ML_(addVar), since if ML_(addVar)
wants to do debug printing (of the types of said vars) then it
@@ -3510,7 +3540,7 @@
ascending order, there is no need to sort the array after
construction. The ascendingness is however asserted for. */
dioff_lookup_tab
- = VG_(newXA)( ML_(dinfo_zalloc), "di.readdwarf3.ndrw.5",
+ = VG_(newXA)( ML_(dinfo_zalloc), "di.readdwarf3.ndrw.9",
ML_(dinfo_free),
sizeof(TempVar*) );
vg_assert(dioff_lookup_tab);
@@ -3623,7 +3653,9 @@
the type didn't get resolved. Really, in that case
something's broken earlier on, and should be fixed, rather
than just skipping the variable. */
- ent = ML_(TyEnts__index_by_cuOff)( tyents_to_keep, varp->typeR );
+ ent = ML_(TyEnts__index_by_cuOff)( tyents_to_keep,
+ tyents_to_keep_cache,
+ varp->typeR );
/* The next two assertions should be guaranteed by
our previous call to resolve_variable_types. */
vg_assert(ent);
@@ -3746,6 +3778,15 @@
key-finalizer. */
VG_(deleteFM)( rangestree, (void(*)(UWord))VG_(deleteXA), NULL );
+ /* and the tyents_to_keep cache */
+ ML_(dinfo_free)( tyents_to_keep_cache );
+ tyents_to_keep_cache = NULL;
+
+ /* and the file name table (just the array, not the entries
+ themselves). */
+ vg_assert(varparser.filenameTable);
+ VG_(deleteXA)( varparser.filenameTable );
+
/* record the GExprs in di so they can be freed later */
vg_assert(!di->admin_gexprs);
di->admin_gexprs = gexprs;
Modified: branches/YARD/coregrind/m_debuginfo/storage.c
===================================================================
--- branches/YARD/coregrind/m_debuginfo/storage.c 2008-09-09 18:18:26 UTC (rev 8594)
+++ branches/YARD/coregrind/m_debuginfo/storage.c 2008-09-09 23:10:30 UTC (rev 8595)
@@ -751,7 +751,7 @@
vg_assert(name);
vg_assert(gexpr);
- ent = ML_(TyEnts__index_by_cuOff)( di->admin_tyents, typeR);
+ ent = ML_(TyEnts__index_by_cuOff)( di->admin_tyents, NULL, typeR );
tl_assert(ent);
vg_assert(ML_(TyEnt__is_type)(ent));
Modified: branches/YARD/coregrind/m_debuginfo/tytypes.c
===================================================================
--- branches/YARD/coregrind/m_debuginfo/tytypes.c 2008-09-09 18:18:26 UTC (rev 8594)
+++ branches/YARD/coregrind/m_debuginfo/tytypes.c 2008-09-09 23:10:30 UTC (rev 8595)
@@ -198,7 +198,7 @@
static void pp_TyBound_C_ishly ( XArray* tyents, UWord cuOff )
{
- TyEnt* ent = ML_(TyEnts__index_by_cuOff)( tyents, cuOff );
+ TyEnt* ent = ML_(TyEnts__index_by_cuOff)( tyents, NULL, cuOff );
if (!ent) {
VG_(printf)("**bounds-have-invalid-cuOff**");
return;
@@ -220,7 +220,7 @@
void ML_(pp_TyEnt_C_ishly)( XArray* /* of TyEnt */ tyents,
UWord cuOff )
{
- TyEnt* ent = ML_(TyEnts__index_by_cuOff)( tyents, cuOff );
+ TyEnt* ent = ML_(TyEnts__index_by_cuOff)( tyents, NULL, cuOff );
if (!ent) {
VG_(printf)("**type-has-invalid-cuOff**");
return;
@@ -292,12 +292,60 @@
found. Asserts if more than one entry has the specified .cuOff
value. */
+void ML_(TyEntIndexCache__invalidate) ( TyEntIndexCache* cache )
+{
+ Word i;
+ for (i = 0; i < N_TYENT_INDEX_CACHE; i++) {
+ cache->ce[i].cuOff0 = 0; /* not actually necessary */
+ cache->ce[i].ent0 = NULL; /* "invalid entry" */
+ cache->ce[i].cuOff1 = 0; /* not actually necessary */
+ cache->ce[i].ent1 = NULL; /* "invalid entry" */
+ }
+}
+
TyEnt* ML_(TyEnts__index_by_cuOff) ( XArray* /* of TyEnt */ ents,
+ TyEntIndexCache* cache,
UWord cuOff_to_find )
{
Bool found;
Word first, last;
- TyEnt key;
+ TyEnt key, *res;
+
+ /* crude stats, aggregated over all caches */
+ static UWord cacheQs = 0 - 1;
+ static UWord cacheHits = 0;
+
+ if (0 && 0 == (cacheQs & 0xFFFF))
+ VG_(printf)("cache: %'lu queries, %'lu misses\n",
+ cacheQs, cacheQs - cacheHits);
+
+ if (LIKELY(cache != NULL)) {
+ UWord h = cuOff_to_find % (UWord)N_TYENT_INDEX_CACHE;
+ cacheQs++;
+ // dude, like, way 0, dude.
+ if (cache->ce[h].cuOff0 == cuOff_to_find && cache->ce[h].ent0 != NULL) {
+ // dude, way 0 is a total hit!
+ cacheHits++;
+ return cache->ce[h].ent0;
+ }
+ // dude, check out way 1, dude.
+ if (cache->ce[h].cuOff1 == cuOff_to_find && cache->ce[h].ent1 != NULL) {
+ // way 1 hit
+ UWord tc;
+ TyEnt* te;
+ cacheHits++;
+ // dude, way 1 is the new way 0. move with the times, dude.
+ tc = cache->ce[h].cuOff0;
+ te = cache->ce[h].ent0;
+ cache->ce[h].cuOff0 = cache->ce[h].cuOff1;
+ cache->ce[h].ent0 = cache->ce[h].ent1;
+ cache->ce[h].cuOff1 = tc;
+ cache->ce[h].ent1 = te;
+ return cache->ce[h].ent0;
+ }
+ }
+
+ /* We'll have to do it the hard way */
key.cuOff = cuOff_to_find;
key.tag = Te_EMPTY;
found = VG_(lookupXA)( ents, &key, &first, &last );
@@ -308,7 +356,21 @@
/* If this fails, the array is invalid in the sense that there is
more than one entry with .cuOff == cuOff_to_find. */
vg_assert(first == last);
- return (TyEnt*)VG_(indexXA)( ents, first );
+ res = (TyEnt*)VG_(indexXA)( ents, first );
+
+ if (LIKELY(cache != NULL) && LIKELY(res != NULL)) {
+ /* this is a bit stupid, computing this twice. Oh well.
+ Perhaps some magic gcc transformation will common them up.
+ re "res != NULL", since .ent of NULL denotes 'invalid entry',
+ we can't cache the result when res == NULL. */
+ UWord h = cuOff_to_find % (UWord)N_TYENT_INDEX_CACHE;
+ cache->ce[h].cuOff1 = cache->ce[h].cuOff0;
+ cache->ce[h].ent1 = cache->ce[h].ent0;
+ cache->ce[h].cuOff0 = cuOff_to_find;
+ cache->ce[h].ent0 = res;
+ }
+
+ return res;
}
@@ -566,7 +628,7 @@
{
Word i;
MaybeUWord eszB;
- TyEnt* ent = ML_(TyEnts__index_by_cuOff)(tyents, cuOff);
+ TyEnt* ent = ML_(TyEnts__index_by_cuOff)(tyents, NULL, cuOff);
TyEnt* ent2;
vg_assert(ent);
vg_assert(ML_(TyEnt__is_type)(ent));
@@ -577,7 +639,8 @@
case Te_TyQual:
return ML_(sizeOfType)( tyents, ent->Te.TyQual.typeR );
case Te_TyTyDef:
- ent2 = ML_(TyEnts__index_by_cuOff)(tyents, ent->Te.TyTyDef.typeR);
+ ent2 = ML_(TyEnts__index_by_cuOff)(tyents, NULL,
+ ent->Te.TyTyDef.typeR);
vg_assert(ent2);
if (ent2->tag == Te_UNKNOWN)
return mk_MaybeUWord_Nothing(); /*UNKNOWN*/
@@ -592,7 +655,8 @@
case Te_TyEnum:
return mk_MaybeUWord_Just( ent->Te.TyEnum.szB );
case Te_TyArray:
- ent2 = ML_(TyEnts__index_by_cuOff)(tyents, ent->Te.TyArray.typeR);
+ ent2 = ML_(TyEnts__index_by_cuOff)(tyents, NULL,
+ ent->Te.TyArray.typeR);
vg_assert(ent2);
if (ent2->tag == Te_UNKNOWN)
return mk_MaybeUWord_Nothing(); /*UNKNOWN*/
@@ -601,7 +665,7 @@
UWord bo_cuOff
= *(UWord*)VG_(indexXA)(ent->Te.TyArray.boundRs, i);
TyEnt* bo
- = ML_(TyEnts__index_by_cuOff)( tyents, bo_cuOff );
+ = ML_(TyEnts__index_by_cuOff)( tyents, NULL, bo_cuOff );
vg_assert(bo);
vg_assert(bo->tag == Te_Bound);
if (!(bo->Te.Bound.knownL && bo->Te.Bound.knownU))
@@ -643,7 +707,7 @@
sizeof(UChar) );
vg_assert(xa);
- ty = ML_(TyEnts__index_by_cuOff)(tyents, ty_cuOff);
+ ty = ML_(TyEnts__index_by_cuOff)(tyents, NULL, ty_cuOff);
while (True) {
vg_assert(ty);
@@ -673,7 +737,7 @@
if ((!fieldRs) || VG_(sizeXA)(fieldRs) == 0) goto done;
for (i = 0; i < VG_(sizeXA)( fieldRs ); i++ ) {
fieldR = *(UWord*)VG_(indexXA)( fieldRs, i );
- field = ML_(TyEnts__index_by_cuOff)(tyents, fieldR);
+ field = ML_(TyEnts__index_by_cuOff)(tyents, NULL, fieldR);
vg_assert(field);
vg_assert(field->tag == Te_Field);
vg_assert(field->Te.Field.loc);
@@ -719,7 +783,8 @@
VG_(addBytesToXA)( xa, field->Te.Field.name,
VG_(strlen)(field->Te.Field.name) );
offset -= offMin;
- ty = ML_(TyEnts__index_by_cuOff)(tyents, field->Te.Field.typeR );
+ ty = ML_(TyEnts__index_by_cuOff)(tyents, NULL,
+ field->Te.Field.typeR );
tl_assert(ty);
if (ty->tag == Te_UNKNOWN) goto done;
/* keep going; look inside the field. */
@@ -734,7 +799,8 @@
TyEnt* bound;
/* Just deal with the simple, common C-case: 1-D array,
zero based, known size. */
- elemTy = ML_(TyEnts__index_by_cuOff)(tyents, ty->Te.TyArray.typeR);
+ elemTy = ML_(TyEnts__index_by_cuOff)(tyents, NULL,
+ ty->Te.TyArray.typeR);
vg_assert(elemTy);
if (elemTy->tag == Te_UNKNOWN) goto done;
vg_assert(ML_(TyEnt__is_type)(elemTy));
@@ -742,7 +808,7 @@
goto done;
if (VG_(sizeXA)( ty->Te.TyArray.boundRs ) != 1) goto done;
boundR = *(UWord*)VG_(indexXA)( ty->Te.TyArray.boundRs, 0 );
- bound = ML_(TyEnts__index_by_cuOff)(tyents, boundR);
+ bound = ML_(TyEnts__index_by_cuOff)(tyents, NULL, boundR);
vg_assert(bound);
vg_assert(bound->tag == Te_Bound);
if (!(bound->Te.Bound.knownL && bound->Te.Bound.knownU
@@ -767,14 +833,16 @@
}
case Te_TyQual: {
- ty = ML_(TyEnts__index_by_cuOff)(tyents, ty->Te.TyQual.typeR);
+ ty = ML_(TyEnts__index_by_cuOff)(tyents, NULL,
+ ty->Te.TyQual.typeR);
tl_assert(ty);
if (ty->tag == Te_UNKNOWN) goto done;
break;
}
case Te_TyTyDef: {
- ty = ML_(TyEnts__index_by_cuOff)(tyents, ty->Te.TyTyDef.typeR);
+ ty = ML_(TyEnts__index_by_cuOff)(tyents, NULL,
+ ty->Te.TyTyDef.typeR);
tl_assert(ty);
if (ty->tag == Te_UNKNOWN) goto done;
break;
Modified: branches/YARD/coregrind/m_main.c
===================================================================
--- branches/YARD/coregrind/m_main.c 2008-09-09 18:18:26 UTC (rev 8594)
+++ branches/YARD/coregrind/m_main.c 2008-09-09 23:10:30 UTC (rev 8595)
@@ -2081,7 +2081,7 @@
/* Show a profile of the heap(s) at shutdown. Optionally, first
throw away all the debug info, as that makes it easy to spot
- leaks in the debuginfo reader. */
+ leaks in the debuginfo reader (for debugging only!) */
if (VG_(clo_profile_heap)) {
if (0) VG_(di_discard_ALL_debuginfo)();
VG_(print_arena_cc_analysis)();
|