X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;ds=sidebyside;f=src%2Fruntime%2Fgc-common.c;h=a615b66936687e2b2cec13dc7e1a058f597bce44;hb=e5129834a1348cbe313d31fc2743e7f8f73848a6;hp=02b78dbc9654741ce64b752dc65f2f674fdd837f;hpb=90c2b0563695904419451b6172efcf9c7008ad8b;p=sbcl.git diff --git a/src/runtime/gc-common.c b/src/runtime/gc-common.c index 02b78db..a615b66 100644 --- a/src/runtime/gc-common.c +++ b/src/runtime/gc-common.c @@ -1523,11 +1523,17 @@ size_weak_pointer(lispobj *where) void scan_weak_pointers(void) { - struct weak_pointer *wp; - for (wp = weak_pointers; wp != NULL; wp=wp->next) { + struct weak_pointer *wp, *next_wp; + for (wp = weak_pointers, next_wp = NULL; wp != NULL; wp = next_wp) { lispobj value = wp->value; lispobj *first_pointer; gc_assert(widetag_of(wp->header)==WEAK_POINTER_WIDETAG); + + next_wp = wp->next; + wp->next = NULL; + if (next_wp == wp) /* gencgc uses a ref to self for end of list */ + next_wp = NULL; + if (!(is_lisp_pointer(value) && from_space_p(value))) continue; @@ -1679,66 +1685,14 @@ scav_hash_table_entries (struct hash_table *hash_table) /* Scavenge the key and value. */ scavenge(&kv_vector[2*i],2); - /* Rehashing of EQ based keys. */ - if ((!hash_vector) || - (hash_vector[i] == MAGIC_HASH_VECTOR_VALUE)) { -#ifndef LISP_FEATURE_GENCGC - /* For GENCGC scav_hash_table_entries only rehashes - * the entries whose keys were moved. Cheneygc always - * moves the objects so here we let the lisp side know - * that rehashing is needed for the whole table. */ - *(kv_vector - 2) = (subtype_VectorMustRehash<needing_rehash); - hash_table->needing_rehash = make_fixnum(i); - /*SHOW("P2");*/ - } else { - unsigned long prior = index_vector[old_index]; - unsigned long next = next_vector[prior]; - - /*FSHOW((stderr, "/P3a %d %d\n", prior, next));*/ - - while (next != 0) { - /*FSHOW((stderr, "/P3b %d %d\n", prior, next));*/ - if (next == i) { - /* Unlink it. */ - next_vector[prior] = next_vector[next]; - /* Link it into the needing rehash - * chain. */ - next_vector[next] = - fixnum_value(hash_table->needing_rehash); - hash_table->needing_rehash = make_fixnum(next); - /*SHOW("/P3");*/ - break; - } - prior = next; - next = next_vector[next]; - } - } + + if (old_key != new_key && new_key != empty_symbol) { + hash_table->needs_rehash_p = T; } -#endif } } } @@ -1764,7 +1718,18 @@ scav_vector (lispobj *where, lispobj object) /* Scavenge element 0, which may be a hash-table structure. */ scavenge(where+2, 1); if (!is_lisp_pointer(where[2])) { - lose("no pointer at %x in hash table\n", where[2]); + /* This'll happen when REHASH clears the header of old-kv-vector + * and fills it with zero, but some other thread simulatenously + * sets the header in %%PUTHASH. + */ + fprintf(stderr, + "Warning: no pointer at %lx in hash table: this indicates " + "non-fatal corruption caused by concurrent access to a " + "hash-table from multiple threads. Any accesses to " + "hash-tables shared between threads should be protected " + "by locks.\n", (unsigned long)&where[2]); + // We've scavenged three words. + return 3; } hash_table = (struct hash_table *)native_pointer(where[2]); /*FSHOW((stderr,"/hash_table = %x\n", hash_table));*/ @@ -1880,13 +1845,6 @@ scan_weak_hash_table (struct hash_table *hash_table) kv_vector, index_vector, next_vector, hash_vector, empty_symbol, weakness); } - { - lispobj first = fixnum_value(hash_table->needing_rehash); - scan_weak_hash_table_chain(hash_table, &first, - kv_vector, index_vector, next_vector, - hash_vector, empty_symbol, weakness); - hash_table->needing_rehash = make_fixnum(first); - } } /* Remove dead entries from weak hash tables. */