From 5ccf6e682f18ba9076d9c19350ca79b3909ce5d2 Mon Sep 17 00:00:00 2001 From: Jameson Nash Date: Thu, 26 Aug 2021 11:42:14 -0400 Subject: [PATCH] fix ptrhash_remove (#42009) Same bug as 5e57c214f872083ccacafa0f753e794ec654a21a (#26833), same fix. --- src/Makefile | 4 +- src/dump.c | 5 +- src/support/htable.inc | 112 ++++++++++++++++++++++------------------- 3 files changed, 65 insertions(+), 56 deletions(-) diff --git a/src/Makefile b/src/Makefile index fe5fc81328d1aa..ed0cbaf9c8c9ae 100644 --- a/src/Makefile +++ b/src/Makefile @@ -278,10 +278,10 @@ $(addprefix $(BUILDDIR)/,threading.o threading.dbg.obj gc.o gc.dbg.obj init.c in $(addprefix $(BUILDDIR)/,APInt-C.o APInt-C.dbg.obj runtime_intrinsics.o runtime_intrinsics.dbg.obj): $(SRCDIR)/APInt-C.h # archive library file rules -$(BUILDDIR)/support/libsupport.a: $(addprefix $(SRCDIR)/support/,*.h *.c *.S) $(SRCDIR)/support/*.c +$(BUILDDIR)/support/libsupport.a: $(addprefix $(SRCDIR)/support/,*.h *.c *.S *.inc) $(SRCDIR)/support/*.c $(MAKE) -C $(SRCDIR)/support BUILDDIR='$(abspath $(BUILDDIR)/support)' -$(BUILDDIR)/support/libsupport-debug.a: $(addprefix $(SRCDIR)/support/,*.h *.c *.S) $(SRCDIR)/support/*.c +$(BUILDDIR)/support/libsupport-debug.a: $(addprefix $(SRCDIR)/support/,*.h *.c *.S *.inc) $(SRCDIR)/support/*.c $(MAKE) -C $(SRCDIR)/support debug BUILDDIR='$(abspath $(BUILDDIR)/support)' $(FLISP_EXECUTABLE_release): $(BUILDDIR)/flisp/libflisp.a diff --git a/src/dump.c b/src/dump.c index af3290a5114eb0..1cdf0787648c8c 100644 --- a/src/dump.c +++ b/src/dump.c @@ -2058,14 +2058,14 @@ static void jl_insert_backedges(jl_array_t *list, jl_array_t *targets) while (codeinst) { if (codeinst->min_world > 0) codeinst->max_world = ~(size_t)0; - ptrhash_put(&new_code_instance_validate, codeinst, HT_NOTFOUND); // mark it as handled + ptrhash_remove(&new_code_instance_validate, codeinst); // mark it as handled codeinst = jl_atomic_load_relaxed(&codeinst->next); } } else { jl_code_instance_t *codeinst = caller->cache; while (codeinst) { - ptrhash_put(&new_code_instance_validate, codeinst, HT_NOTFOUND); // should be left invalid + ptrhash_remove(&new_code_instance_validate, codeinst); // should be left invalid codeinst = jl_atomic_load_relaxed(&codeinst->next); } if (_jl_debug_method_invalidation) { @@ -2084,7 +2084,6 @@ static void validate_new_code_instances(void) for (i = 0; i < new_code_instance_validate.size; i += 2) { if (new_code_instance_validate.table[i+1] != HT_NOTFOUND) { ((jl_code_instance_t*)new_code_instance_validate.table[i])->max_world = ~(size_t)0; - new_code_instance_validate.table[i+1] = HT_NOTFOUND; } } } diff --git a/src/support/htable.inc b/src/support/htable.inc index fa59624a4998f5..7a9be2514e2f0d 100644 --- a/src/support/htable.inc +++ b/src/support/htable.inc @@ -13,67 +13,77 @@ static void **HTNAME##_lookup_bp_r(htable_t *h, void *key, void *ctx) \ { \ uint_t hv; \ - size_t i, orig, index, iter; \ + size_t i, orig, index, iter, empty_slot; \ size_t newsz, sz = hash_size(h); \ size_t maxprobe = max_probe(sz); \ void **tab = h->table; \ void **ol; \ \ hv = HFUNC((uintptr_t)key, ctx); \ - retry_bp: \ - iter = 0; \ - index = (size_t)(hv & (sz-1)) * 2; \ - sz *= 2; \ - orig = index; \ - \ - do { \ - if (tab[index+1] == HT_NOTFOUND) { \ - tab[index] = key; \ - return &tab[index+1]; \ + while (1) { \ + iter = 0; \ + index = (size_t)(hv & (sz-1)) * 2; \ + sz *= 2; \ + orig = index; \ + empty_slot = -1; \ + \ + do { \ + if (tab[index] == HT_NOTFOUND) { \ + if (empty_slot == -1) \ + empty_slot = index; \ + break; \ + } \ + if (tab[index+1] == HT_NOTFOUND) { \ + if (empty_slot == -1) \ + empty_slot = index; \ + } \ + \ + if (EQFUNC(key, tab[index], ctx)) \ + return &tab[index+1]; \ + \ + index = (index+2) & (sz-1); \ + iter++; \ + if (iter > maxprobe) \ + break; \ + } while (index != orig); \ + \ + if (empty_slot != -1) { \ + tab[empty_slot] = key; \ + return &tab[empty_slot+1]; \ } \ \ - if (EQFUNC(key, tab[index], ctx)) \ - return &tab[index+1]; \ - \ - index = (index+2) & (sz-1); \ - iter++; \ - if (iter > maxprobe) \ - break; \ - } while (index != orig); \ - \ - /* table full */ \ - /* quadruple size, rehash, retry the insert */ \ - /* it's important to grow the table really fast; otherwise we waste */ \ - /* lots of time rehashing all the keys over and over. */ \ - sz = h->size; \ - ol = h->table; \ - if (sz < HT_N_INLINE) \ - newsz = HT_N_INLINE; \ - else if (sz >= (1<<19) || (sz <= (1<<8))) \ - newsz = sz<<1; \ - else \ - newsz = sz<<2; \ - /*printf("trying to allocate %d words.\n", newsz); fflush(stdout);*/ \ - tab = (void**)LLT_ALLOC(newsz*sizeof(void*)); \ - if (tab == NULL) \ - return NULL; \ - for(i=0; i < newsz; i++) \ - tab[i] = HT_NOTFOUND; \ - h->table = tab; \ - h->size = newsz; \ - for(i=0; i < sz; i+=2) { \ - if (ol[i+1] != HT_NOTFOUND) { \ - (*HTNAME##_lookup_bp_r(h, ol[i], ctx)) = ol[i+1]; \ + /* table full */ \ + /* quadruple size, rehash, retry the insert */ \ + /* it's important to grow the table really fast; otherwise we waste */ \ + /* lots of time rehashing all the keys over and over. */ \ + sz = h->size; \ + ol = h->table; \ + if (sz < HT_N_INLINE) \ + newsz = HT_N_INLINE; \ + else if (sz >= (1<<19) || (sz <= (1<<8))) \ + newsz = sz<<1; \ + else \ + newsz = sz<<2; \ + /*printf("trying to allocate %d words.\n", newsz); fflush(stdout);*/ \ + tab = (void**)LLT_ALLOC(newsz*sizeof(void*)); \ + if (tab == NULL) \ + return NULL; \ + for (i = 0; i < newsz; i++) \ + tab[i] = HT_NOTFOUND; \ + h->table = tab; \ + h->size = newsz; \ + for (i = 0; i < sz; i += 2) { \ + if (ol[i+1] != HT_NOTFOUND) { \ + (*HTNAME##_lookup_bp_r(h, ol[i], ctx)) = ol[i+1]; \ + } \ } \ - } \ - if (ol != &h->_space[0]) \ - LLT_FREE(ol); \ + if (ol != &h->_space[0]) \ + LLT_FREE(ol); \ \ - sz = hash_size(h); \ - maxprobe = max_probe(sz); \ - tab = h->table; \ - \ - goto retry_bp; \ + sz = hash_size(h); \ + maxprobe = max_probe(sz); \ + tab = h->table; \ + } \ \ return NULL; \ } \