Author: Remi Meier <[email protected]>
Branch: use-gcc
Changeset: r1944:a3cb98b78053
Date: 2015-08-25 16:53 +0200
http://bitbucket.org/pypy/stmgc/changeset/a3cb98b78053/
Log: change signature of stm_hashtable_list()
Storing GC references into raw memory can be problematic.
diff --git a/c8/stm/hashtable.c b/c8/stm/hashtable.c
--- a/c8/stm/hashtable.c
+++ b/c8/stm/hashtable.c
@@ -325,6 +325,9 @@
stm_allocate_preexisting(sizeof(stm_hashtable_entry_t),
(char *)&initial.header);
hashtable->additions++;
+ /* make sure .object is NULL in all segments before
+ "publishing" the entry in the hashtable: */
+ write_fence();
}
table->items[i] = entry;
write_fence(); /* make sure 'table->items' is written here */
@@ -422,7 +425,7 @@
}
long stm_hashtable_list(object_t *hobj, stm_hashtable_t *hashtable,
- stm_hashtable_entry_t **results)
+ stm_hashtable_entry_t * TLPREFIX *results)
{
/* Set the read marker. It will be left as long as we're running
the same transaction.
diff --git a/c8/stmgc.h b/c8/stmgc.h
--- a/c8/stmgc.h
+++ b/c8/stmgc.h
@@ -733,8 +733,13 @@
void stm_hashtable_write_entry(object_t *hobj, stm_hashtable_entry_t *entry,
object_t *nvalue);
long stm_hashtable_length_upper_bound(stm_hashtable_t *);
+
+/* WARNING: stm_hashtable_list does not do a stm_write() on the 'results'
+ argument. 'results' may point inside an object. So if 'results' may be
+ a part of an old obj (which may have survived a minor GC), then make
+ sure to call stm_write() on the obj before calling this function. */
long stm_hashtable_list(object_t *, stm_hashtable_t *,
- stm_hashtable_entry_t **results);
+ stm_hashtable_entry_t * TLPREFIX *results);
extern uint32_t stm_hashtable_entry_userdata;
void stm_hashtable_tracefn(struct object_s *, stm_hashtable_t *,
void (object_t **));
diff --git a/c8/test/support.py b/c8/test/support.py
--- a/c8/test/support.py
+++ b/c8/test/support.py
@@ -210,11 +210,11 @@
bool _check_hashtable_write(object_t *, stm_hashtable_t *, uintptr_t key,
object_t *nvalue, stm_thread_local_t *tl);
long stm_hashtable_length_upper_bound(stm_hashtable_t *);
-long stm_hashtable_list(object_t *, stm_hashtable_t *,
- stm_hashtable_entry_t **results);
uint32_t stm_hashtable_entry_userdata;
void stm_hashtable_tracefn(struct object_s *, stm_hashtable_t *,
void trace(object_t **));
+long _stm_hashtable_list(object_t *o, stm_hashtable_t *h,
+ object_t *entries);
void _set_hashtable(object_t *obj, stm_hashtable_t *h);
stm_hashtable_t *_get_hashtable(object_t *obj);
@@ -397,6 +397,16 @@
return entry->object;
}
+long _stm_hashtable_list(object_t *o, stm_hashtable_t *h,
+ object_t *entries)
+{
+ if (entries != NULL)
+ return stm_hashtable_list(o, h,
+ (stm_hashtable_entry_t *
TLPREFIX*)((stm_char*)entries+SIZEOF_MYOBJ));
+ return stm_hashtable_list(o, h, NULL);
+}
+
+
void _set_queue(object_t *obj, stm_queue_t *q)
{
stm_char *field_addr = ((stm_char*)obj);
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
@@ -23,15 +23,17 @@
def htitems(o):
h = get_hashtable(o)
upper_bound = lib.stm_hashtable_length_upper_bound(h)
- entries = ffi.new("stm_hashtable_entry_t *[]", upper_bound)
- count = lib.stm_hashtable_list(o, h, entries)
+ entries = stm_allocate_refs(upper_bound)
+ count = lib._stm_hashtable_list(o, h, entries)
assert count <= upper_bound
- return [(lib._get_entry_index(entries[i]),
- lib._get_entry_object(entries[i])) for i in range(count)]
+
+ return [(lib._get_entry_index(ffi.cast("stm_hashtable_entry_t *",
stm_get_ref(entries, i))),
+ lib._get_entry_object(ffi.cast("stm_hashtable_entry_t *",
stm_get_ref(entries, i))))
+ for i in range(count)]
def htlen(o):
h = get_hashtable(o)
- count = lib.stm_hashtable_list(o, h, ffi.NULL)
+ count = lib._stm_hashtable_list(o, h, ffi.NULL)
return count
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit