From: Julian Seward Date: Tue, 26 Dec 2006 03:01:53 +0000 (+0000) Subject: Merge r6341 (ExeContext hashing fix) X-Git-Tag: svn/VALGRIND_3_2_2~56 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=3116cf3709c044e6f7f904b172ef0586fec91d52;p=thirdparty%2Fvalgrind.git Merge r6341 (ExeContext hashing fix) git-svn-id: svn://svn.valgrind.org/valgrind/branches/VALGRIND_3_2_BRANCH@6424 --- diff --git a/coregrind/m_execontext.c b/coregrind/m_execontext.c index 1c87d192aa..636a1f1a6c 100644 --- a/coregrind/m_execontext.c +++ b/coregrind/m_execontext.c @@ -185,6 +185,13 @@ Bool VG_(eq_ExeContext) ( VgRes res, ExeContext* e1, ExeContext* e2 ) on the returned ExeContext* values themselves. Inspired by Hugs's Text type. */ +static inline UWord ROLW ( UWord w, Int n ) +{ + Int bpw = 8 * sizeof(UWord); + w = (w << n) | (w >> (bpw-n)); + return w; +} + ExeContext* VG_(record_ExeContext) ( ThreadId tid ) { Int i; @@ -194,6 +201,12 @@ ExeContext* VG_(record_ExeContext) ( ThreadId tid ) ExeContext* new_ec; ExeContext* list; UInt n_ips; + ExeContext *prev2, *prev; + + static UInt ctr = 0; + + vg_assert(sizeof(void*) == sizeof(UWord)); + vg_assert(sizeof(void*) == sizeof(Addr)); init_ExeContext_storage(); vg_assert(VG_(clo_backtrace_size) >= 1 && @@ -208,15 +221,19 @@ ExeContext* VG_(record_ExeContext) ( ThreadId tid ) hash = 0; for (i = 0; i < n_ips; i++) { hash ^= ips[i]; - hash = (hash << 29) | (hash >> 3); + hash = ROLW(hash, 19); } + if (0) VG_(printf)("hash 0x%lx ", hash); hash = hash % N_EC_LISTS; + if (0) VG_(printf)("%lu\n", hash); /* And (the expensive bit) look a matching entry in the list. */ ec_searchreqs++; - list = ec_list[hash]; + prev2 = NULL; + prev = NULL; + list = ec_list[hash]; while (True) { if (list == NULL) break; @@ -229,11 +246,22 @@ ExeContext* VG_(record_ExeContext) ( ThreadId tid ) } } if (same) break; - list = list->next; + prev2 = prev; + prev = list; + list = list->next; } if (list != NULL) { - /* Yay! We found it. */ + /* Yay! We found it. Once every 8 searches, move it one step + closer to the start of the list to make future searches + cheaper. */ + if (prev2 && prev && 0 == ((ctr++) & 7)) { + vg_assert(prev2->next == prev); + vg_assert(prev->next == list); + prev2->next = list; + prev->next = list->next; + list->next = prev; + } return list; }