diff --git a/coregrind/m_xarray.c b/coregrind/m_xarray.c index cdcf97861..4dc8ebdb7 100644 --- a/coregrind/m_xarray.c +++ b/coregrind/m_xarray.c @@ -44,6 +44,7 @@ struct _XArray { Int (*cmpFn) ( void*, void* ); /* cmp fn (may be NULL) */ Word elemSzB; /* element size in bytes */ void* arr; /* pointer to elements */ + Word initsizeE; /* HINT only: initial size, 0 if no hint */ Word usedsizeE; /* # used elements in arr */ Word totsizeE; /* max size of arr, in elements */ Bool sorted; /* is it sorted? */ @@ -72,6 +73,7 @@ XArray* VG_(newXA) ( void*(*alloc_fn)(HChar*,SizeT), xa->free = free_fn; xa->cmpFn = NULL; xa->elemSzB = elemSzB; + xa->initsizeE = 0; xa->usedsizeE = 0; xa->totsizeE = 0; xa->sorted = False; @@ -79,6 +81,19 @@ XArray* VG_(newXA) ( void*(*alloc_fn)(HChar*,SizeT), return xa; } +XArray* VG_(newSizedXA) ( void*(*alloc_fn)(HChar*,SizeT), + HChar* cc, + void(*free_fn)(void*), + Word elemSzB, + Word nInitialElems ) +{ + XArray* xa; + tl_assert(nInitialElems >= 0); + xa = VG_(newXA)( alloc_fn, cc, free_fn, elemSzB ); + xa->initsizeE = nInitialElems; + return xa; +} + XArray* VG_(cloneXA)( HChar* cc, XArray* xao ) { struct _XArray* xa = (struct _XArray*)xao; @@ -145,7 +160,7 @@ inline void* VG_(indexXA) ( XArray* xao, Word n ) static inline void ensureSpaceXA ( struct _XArray* xa ) { - if (xa->usedsizeE == xa->totsizeE) { + if (UNLIKELY(xa->usedsizeE == xa->totsizeE)) { void* tmp; Word newsz; if (xa->totsizeE == 0) @@ -158,7 +173,11 @@ static inline void ensureSpaceXA ( struct _XArray* xa ) Hence increase the initial array size for tiny elements in an attempt to avoid reallocations of size 2, 4, 8 if the array does start to fill up. */ - if (xa->elemSzB == 1) newsz = 8; + /* Also, if there's a hinted initial size, use that instead of + the logic in the preceding comment. */ + tl_assert(xa->initsizeE >= 0); + if (xa->initsizeE > 0) newsz = xa->initsizeE; + else if (xa->elemSzB == 1) newsz = 8; else if (xa->elemSzB == 2) newsz = 4; else newsz = 2; } else { diff --git a/include/pub_tool_xarray.h b/include/pub_tool_xarray.h index cd1b02e43..ff8dfb344 100644 --- a/include/pub_tool_xarray.h +++ b/include/pub_tool_xarray.h @@ -54,6 +54,17 @@ extern XArray* VG_(newXA) ( void*(*alloc_fn)(HChar*,SizeT), void(*free_fn)(void*), Word elemSzB ); +/* Same as VG_(newXA), except allows specification of an initial + number of elements for the array, so as to avoid a potentially + large wasted cost of repeatedly resizing the array when the caller + knows something about what the expected final size is going to + be. */ +extern XArray* VG_(newSizedXA) ( void*(*alloc_fn)(HChar*,SizeT), + HChar* cc, + void(*free_fn)(void*), + Word elemSzB, + Word nInitialElems ); + /* Free all memory associated with an XArray. */ extern void VG_(deleteXA) ( XArray* );