Author: Armin Rigo <[email protected]>
Branch:
Changeset: r182:75aaf6902952
Date: 2013-06-17 20:38 +0200
http://bitbucket.org/pypy/stmgc/changeset/75aaf6902952/
Log: Next test
diff --git a/c4/gcpage.c b/c4/gcpage.c
--- a/c4/gcpage.c
+++ b/c4/gcpage.c
@@ -160,7 +160,7 @@
}
}
-static unsigned char random_char = 42;
+static unsigned char random_char = 0x55;
void stmgcpage_free(gcptr obj)
{
@@ -171,7 +171,8 @@
assert(0 < size_class && size_class < GC_SMALL_REQUESTS);
/* We simply re-add the object to the right chained list */
- assert(obj->h_tid = DEBUG_WORD(random_char++));
+ assert(obj->h_tid = DEBUG_WORD(random_char));
+ assert(random_char ^= (0xAA ^ 0x55));
obj->h_revision = (revision_t)gcp->free_loc_for_size[size_class];
gcp->free_loc_for_size[size_class] = obj;
//stm_dbgmem_not_used(obj, size_class * WORD, 0);
@@ -197,19 +198,22 @@
if (obj->h_tid & GCFLAG_VISITED)
return; /* already seen */
- if (obj->h_tid & (GCFLAG_PUBLIC_TO_PRIVATE | GCFLAG_STUB)) {
- if (obj->h_revision & 1) { // "is not a ptr", so no more recent version
- obj->h_tid &= ~GCFLAG_PUBLIC_TO_PRIVATE; // see also fix_outdated()
+ if (obj->h_revision & 1) {
+ obj->h_tid &= ~GCFLAG_PUBLIC_TO_PRIVATE; /* see also fix_outdated() */
+ }
+ else {
+ /* h_revision is a ptr: we have a more recent version */
+ assert(!(obj->h_tid & GCFLAG_STUB));
+ gcptr prev_obj = obj;
+ obj = (gcptr)obj->h_revision; /* go visit the more recent version */
+
+ if (!(obj->h_tid & GCFLAG_VISITED) && IS_POINTER(obj->h_revision)) {
+ obj = (gcptr)obj->h_revision;
+ prev_obj->h_revision = (revision_t)obj;
}
- else {
- obj = (gcptr)obj->h_revision; // go visit the more recent version
- *pobj = obj;
- goto restart;
- }
+ *pobj = obj;
+ goto restart;
}
- else
- assert(obj->h_revision & 1);
-
obj->h_tid |= GCFLAG_VISITED;
gcptrlist_insert(&objects_to_trace, obj);
}
diff --git a/c4/test/support.py b/c4/test/support.py
--- a/c4/test/support.py
+++ b/c4/test/support.py
@@ -495,10 +495,28 @@
def check_inaccessible(p):
assert not lib._stm_can_access_memory(p)
+def DEBUG_WORD(char):
+ return int(ffi.cast("revision_t", char * 0x0101010101010101))
+
+def check_free_old(p):
+ assert not lib._stm_can_access_memory(p) or p.h_tid == DEBUG_WORD(0xDD)
+
+def check_free_explicitly(p):
+ assert not lib._stm_can_access_memory(p) or p.h_tid in (
+ DEBUG_WORD(0x55), DEBUG_WORD(0xAA))
+
def check_prebuilt(p):
assert 42 < (p.h_tid & 0xFFFF) < 521
assert p.h_tid & GCFLAG_PREBUILT_ORIGINAL
+def delegate(p1, p2):
+ assert classify(p1) == "public"
+ assert classify(p2) == "public"
+ p1.h_revision = ffi.cast("revision_t", p2)
+ p1.h_tid |= GCFLAG_PUBLIC_TO_PRIVATE
+ if p1.h_tid & GCFLAG_PREBUILT_ORIGINAL:
+ lib.stmgcpage_add_prebuilt_root(p1)
+
def make_public(p1):
"""Hack at an object returned by oalloc() to force it public."""
assert classify(p1) == "protected"
diff --git a/c4/test/test_gcpage.py b/c4/test/test_gcpage.py
--- a/c4/test/test_gcpage.py
+++ b/c4/test/test_gcpage.py
@@ -182,3 +182,20 @@
check_not_free(p2)
p3 = lib.stm_write_barrier(p1)
assert p3 == p2
+
+def test_new_version():
+ p1 = oalloc(HDR); make_public(p1)
+ p2 = oalloc(HDR); make_public(p2)
+ delegate(p1, p2)
+ check_not_free(p1)
+ check_not_free(p2)
+ lib.stm_push_root(p1)
+ major_collect()
+ major_collect()
+ p1b = lib.stm_pop_root()
+ assert p1b == p2
+ check_free_old(p1)
+ check_not_free(p2)
+ p3 = lib.stm_write_barrier(p2)
+ assert p3 != p2
+ assert p3 == lib.stm_write_barrier(p2)
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit