[pypy-commit] stmgc use-gcc: fix for segfault during rehashing of hashtable
Raemi
noreply at buildbot.pypy.org
Tue Sep 8 13:13:44 CEST 2015
Author: Remi Meier <remi.meier at inf.ethz.ch>
Branch: use-gcc
Changeset: r1953:d434158d1537
Date: 2015-09-08 11:38 +0200
http://bitbucket.org/pypy/stmgc/changeset/d434158d1537/
Log: fix for segfault during rehashing of hashtable
After just looking up an entry (and allocate preexisting it), the
entry may not be accessible in the segment doing a major-gc. Handle
this case by looking in segment 0. (however, test is still failing)
diff --git a/c8/stm/hashtable.c b/c8/stm/hashtable.c
--- a/c8/stm/hashtable.c
+++ b/c8/stm/hashtable.c
@@ -150,8 +150,9 @@
static void _stm_rehash_hashtable(stm_hashtable_t *hashtable,
uintptr_t biggercount,
- char *segment_base)
+ long segnum) /* segnum=-1 if no major GC */
{
+ char *segment_base = segnum == -1 ? NULL : get_segment_base(segnum);
dprintf(("rehash %p to size %ld, segment_base=%p\n",
hashtable, biggercount, segment_base));
@@ -175,22 +176,26 @@
stm_hashtable_entry_t *entry = table->items[j];
if (entry == NULL)
continue;
- if (segment_base != NULL) {
+
+ char *to_read_from = segment_base;
+ if (segnum != -1) {
/* -> compaction during major GC */
+ to_read_from = get_page_status_in(segnum, (uintptr_t)entry / 4096UL) == PAGE_NO_ACCESS
+ ? stm_object_pages : to_read_from;
if (((struct stm_hashtable_entry_s *)
- REAL_ADDRESS(segment_base, entry))->object == NULL &&
- !_stm_was_read_by_anybody((object_t *)entry)) {
- dprintf((" removing dead %p\n", entry));
+ REAL_ADDRESS(to_read_from, entry))->object == NULL &&
+ !_stm_was_read_by_anybody((object_t *)entry)) {
+ dprintf((" removing dead %p at %ld\n", entry, j));
continue;
}
}
uintptr_t eindex;
- if (segment_base == NULL)
+ if (segnum == -1)
eindex = entry->index; /* read from STM_SEGMENT */
else
eindex = ((struct stm_hashtable_entry_s *)
- REAL_ADDRESS(segment_base, entry))->index;
+ REAL_ADDRESS(to_read_from, entry))->index;
dprintf((" insert_clean %p at index=%ld\n",
entry, eindex));
@@ -340,7 +345,7 @@
biggercount *= 4;
else
biggercount *= 2;
- _stm_rehash_hashtable(hashtable, biggercount, /*segment_base=*/NULL);
+ _stm_rehash_hashtable(hashtable, biggercount, /*segnum=*/-1);
goto restart;
}
}
@@ -501,7 +506,7 @@
assert(count <= table->mask + 1);
dprintf(("compact with %ld items:\n", num_entries_times_6 / 6));
- _stm_rehash_hashtable(hashtable, count, get_segment_base(segnum));
+ _stm_rehash_hashtable(hashtable, count, segnum);
}
table = hashtable->table;
diff --git a/c8/test/support.py b/c8/test/support.py
--- a/c8/test/support.py
+++ b/c8/test/support.py
@@ -225,6 +225,7 @@
stm_hashtable_t *_get_hashtable(object_t *obj);
uintptr_t _get_entry_index(stm_hashtable_entry_t *entry);
object_t *_get_entry_object(stm_hashtable_entry_t *entry);
+void *_get_hashtable_table(stm_hashtable_t *h);
typedef struct stm_queue_s stm_queue_t;
stm_queue_t *stm_queue_create(void);
@@ -403,6 +404,11 @@
return entry->object;
}
+
+void *_get_hashtable_table(stm_hashtable_t *h) {
+ return *((void**)h);
+}
+
long _stm_hashtable_list(object_t *o, stm_hashtable_t *h,
object_t *entries)
{
diff --git a/c8/test/test_hashtable.py b/c8/test/test_hashtable.py
--- a/c8/test/test_hashtable.py
+++ b/c8/test/test_hashtable.py
@@ -395,6 +395,35 @@
stm_major_collect()
self.commit_transaction()
+ def test_dont_lose_entry(self):
+ self.start_transaction()
+ h = self.allocate_hashtable()
+ self.push_root(h)
+ stm_minor_collect()
+ h = self.pop_root()
+ self.push_root(h)
+ # produce entries:
+ K = 300
+ for i in range(K):
+ hashtable_lookup(h, get_hashtable(h), i)
+
+ table = lib._get_hashtable_table(get_hashtable(h))
+ entry = hashtable_lookup(h, get_hashtable(h), K)
+ self.push_root(entry)
+ stm_major_collect()
+ entry2 = hashtable_lookup(h, get_hashtable(h), K)
+ entry = self.pop_root()
+ assert table != lib._get_hashtable_table(get_hashtable(h)) # compacted
+ assert entry == entry2
+
+ # get rid of ht:
+ self.pop_root()
+ self.commit_transaction()
+ self.start_transaction()
+ stm_major_collect()
+ self.commit_transaction()
+
+
More information about the pypy-commit
mailing list