diff --git a/coregrind/m_transtab.c b/coregrind/m_transtab.c index 0f6807eb9..a5f6f26fa 100644 --- a/coregrind/m_transtab.c +++ b/coregrind/m_transtab.c @@ -569,6 +569,7 @@ void InEdgeArr__add ( InEdgeArr* iea, InEdge* ie ) XArray *var = VG_(newXA)(ttaux_malloc, "transtab.IEA__add", ttaux_free, sizeof(InEdge)); + VG_(hintSizeXA) (var, iea->n_fixed + 1); UWord i; for (i = 0; i < iea->n_fixed; i++) { VG_(addToXA)(var, &iea->edges.fixed[i]); @@ -649,6 +650,7 @@ void OutEdgeArr__add ( OutEdgeArr* oea, OutEdge* oe ) XArray *var = VG_(newXA)(ttaux_malloc, "transtab.OEA__add", ttaux_free, sizeof(OutEdge)); + VG_(hintSizeXA) (var, oea->n_fixed+1); UWord i; for (i = 0; i < oea->n_fixed; i++) { VG_(addToXA)(var, &oea->edges.fixed[i]); diff --git a/coregrind/m_xarray.c b/coregrind/m_xarray.c index 18e3f6cb9..6a306f820 100644 --- a/coregrind/m_xarray.c +++ b/coregrind/m_xarray.c @@ -133,6 +133,24 @@ inline void* VG_(indexXA) ( const XArray* xa, Word n ) return ((char*)xa->arr) + n * xa->elemSzB; } +void VG_(hintSizeXA) ( XArray* xa, Word n) +{ + /* Currently, we support giving a size hint only just after the + call to VG_(newXA). So, we could instead have done + a function VG_(newXA_with_SizeHint). The separate VG_(hintSizeXA) + function is however chosen as we might one day accept to + give a size hint after having added elements. That could be useful + for reducing the size of an xarray to just the size currently needed + or to give a size hint when it is known that a lot more elements + are needed or when the final nr of elements is known. */ + vg_assert(xa); + vg_assert(xa->usedsizeE == 0); + vg_assert(xa->totsizeE == 0); + vg_assert(!xa->arr); + xa->arr = xa->alloc_fn(xa->cc, n * xa->elemSzB); + xa->totsizeE = n; +} + static inline void ensureSpaceXA ( XArray* xa ) { if (xa->usedsizeE == xa->totsizeE) { diff --git a/include/pub_tool_xarray.h b/include/pub_tool_xarray.h index 2f429e4c6..e3bc84e9c 100644 --- a/include/pub_tool_xarray.h +++ b/include/pub_tool_xarray.h @@ -104,6 +104,13 @@ extern Bool VG_(lookupXA_UNSAFE) ( const XArray* xao, const void* key, /* How elements are there in this XArray now? */ extern Word VG_(sizeXA) ( const XArray* ); +/* If you know how many elements an XArray will have, you can + optimise memory usage and number of reallocation needed + to insert these elements. The call to VG_(hintSizeXA) must be + done just after the call to VG_(newXA), before any element + has been inserted. */ +extern void VG_(hintSizeXA) ( XArray*, Word); + /* Index into the XArray. Checks bounds and bombs if the index is invalid. What this returns is the address of the specified element in the array, not (of course) the element itself. Note that the diff --git a/memcheck/mc_translate.c b/memcheck/mc_translate.c index 64d1fd4f5..892b43b3b 100644 --- a/memcheck/mc_translate.c +++ b/memcheck/mc_translate.c @@ -6303,6 +6303,7 @@ IRSB* MC_(instrument) ( VgCallbackClosure* closure, mce.tmpMap = VG_(newXA)( VG_(malloc), "mc.MC_(instrument).1", VG_(free), sizeof(TempMapEnt)); + VG_(hintSizeXA) (mce.tmpMap, sb_in->tyenv->types_used); for (i = 0; i < sb_in->tyenv->types_used; i++) { TempMapEnt ent; ent.kind = Orig;