Author: Remi Meier <[email protected]>
Branch: copy-over-original
Changeset: r381:c1d5e6f19828
Date: 2013-07-10 08:59 +0200
http://bitbucket.org/pypy/stmgc/changeset/c1d5e6f19828/
Log: do a bit more
diff --git a/c4/gcpage.c b/c4/gcpage.c
--- a/c4/gcpage.c
+++ b/c4/gcpage.c
@@ -367,68 +367,70 @@
gcptr *pobj = stm_prebuilt_gcroots.items;
gcptr *pend = stm_prebuilt_gcroots.items + stm_prebuilt_gcroots.size;
gcptr obj;
+
for (; pobj != pend; pobj++) {
obj = *pobj;
assert(obj->h_tid & GCFLAG_PREBUILT_ORIGINAL);
- //assert(IS_POINTER(obj->h_revision));
+
+ if (IS_POINTER(obj->h_revision)) {
+ visit((gcptr *)&obj->h_revision);
+ gcptr next = (gcptr)obj->h_revision;
+
+ if (IS_POINTER((revision_t)next) /* needs to be an object */
+ && (next->h_revision & 1) /* needs to be a head rev */
+ && !(obj->h_tid & GCFLAG_PUBLIC_TO_PRIVATE)) {
+
+ /* XXX: WHY? */
+ assert(!(next->h_tid & GCFLAG_PUBLIC_TO_PRIVATE));
+
+ assert(next->h_tid & GCFLAG_OLD); /* not moved already */
+ assert(next->h_original == (revision_t)obj);
+ assert(next->h_tid & GCFLAG_PUBLIC);
+ assert(!(next->h_tid & GCFLAG_STUB));
+ assert(!(obj->h_tid & GCFLAG_PRIVATE_FROM_PROTECTED));
+ assert(!(next->h_tid & GCFLAG_PRIVATE_FROM_PROTECTED));
+ assert(!(obj->h_tid & GCFLAG_BACKUP_COPY));
+ assert(!(next->h_tid & GCFLAG_BACKUP_COPY));
+
+ /* copy next over obj but preserve possibly existing
+ pre-hash value and tid (prebuilt-flag) */
+ revision_t pre_hash = obj->h_original;
+ revision_t old_tid = obj->h_tid;
+ memcpy(obj, next, stmgc_size(next));
+ assert(!((obj->h_tid ^ old_tid)
+ & (GCFLAG_BACKUP_COPY | GCFLAG_STUB
+ | GCFLAG_PUBLIC | GCFLAG_HAS_ID
+ | GCFLAG_PRIVATE_FROM_PROTECTED)));
+ obj->h_original = pre_hash;
+ obj->h_tid = old_tid;
+
+ fprintf(stdout, "copy %p over prebuilt %p\n", next, obj);
+
+ /* Add this copied-over head revision to objects_to_trace
+ because it (next) was added by the preceeding visit()
+ but not at its new location (obj): */
+ gcptrlist_insert(&objects_to_trace, obj);
- gcptr next = (gcptr)obj->h_revision;
- /* XXX: do better. visit obj first and then
- copy over if possible: */
- if (!(obj->h_revision & 1)
- && (next->h_revision & 1)
- && !(next->h_tid & GCFLAG_VISITED)
- && (next->h_tid & GCFLAG_OLD)
- && !(next->h_tid & GCFLAG_PUBLIC_TO_PRIVATE) /* XXX */
- && !(obj->h_tid & GCFLAG_PUBLIC_TO_PRIVATE)) {
+ /* For those visiting later: */
+ next->h_revision = (revision_t)obj;
- assert(next->h_original == (revision_t)obj);
- assert(next->h_tid & GCFLAG_PUBLIC);
- assert(!(next->h_tid & GCFLAG_STUB));
- assert(!(obj->h_tid & GCFLAG_PRIVATE_FROM_PROTECTED));
- assert(!(next->h_tid & GCFLAG_PRIVATE_FROM_PROTECTED));
- assert(!(obj->h_tid & GCFLAG_BACKUP_COPY));
- assert(!(next->h_tid & GCFLAG_BACKUP_COPY));
+ /* mark somehow so that we can update pub_to_priv
+ for inevitable transactions and others ignore
+ it during tracing. Otherwise, inev transactions
+ will think 'next' is outdated. */
+ next->h_tid &= ~GCFLAG_OLD;
-
- revision_t pre_hash = obj->h_original;
- revision_t old_tid = obj->h_tid;
- memcpy(obj, next, stmgc_size(next));
- assert(!((obj->h_tid ^ old_tid)
- & (GCFLAG_BACKUP_COPY | GCFLAG_STUB
- | GCFLAG_PUBLIC | GCFLAG_HAS_ID
- | GCFLAG_PRIVATE_FROM_PROTECTED)));
- obj->h_original = pre_hash;
- obj->h_tid = old_tid;
+ }
+ /* obj does not need tracing if it can't
+ be reached from somewhere else*/
+ }
+ else {
+ gcptrlist_insert(&objects_to_trace, obj);
+ }
- fprintf(stdout, "copy %p over prebuilt %p\n", next, obj);
-
- /* will not be freed anyway and visit() only traces
- head revision if not visited already */
- obj->h_tid &= ~GCFLAG_VISITED;
- /* For those visiting later:
- XXX: don't: they will think that they are outdated*/
- next->h_revision = (revision_t)obj;
- //if (next->h_tid & GCFLAG_PUBLIC_TO_PRIVATE) {
- // may have already lost it
- /* mark somehow so that we can update pub_to_priv
- for inevitable transactions and others ignore
- it during tracing. Otherwise, inev transactions
- will think 'next' is outdated. */
- next->h_tid &= ~GCFLAG_OLD;
- //}
- }
- else if (IS_POINTER(obj->h_revision)) {
- visit((gcptr *)&obj->h_revision);
- }
-
- // prebuilt originals will always be traced
- // in visit_keep. And otherwise, they may
- // not lose their pub_to_priv flag
- // I think because transactions abort
- // without clearing the flags.
+ /* prebuilt objects need to lose this flag.
+ aborted transactions do not clear it themselves */
obj->h_tid &= ~GCFLAG_PUBLIC_TO_PRIVATE;
- 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
@@ -583,7 +583,9 @@
lib.stm_add_prebuilt_root(p1)
def delegate_original(p1, p2):
- assert p1.h_original == 0
+ # no h_original or it is a prebuilt with a specified hash in h_original
+ assert (p1.h_original == 0) or (p1.h_tid & GCFLAG_PREBUILT_ORIGINAL)
+ assert p1.h_tid & GCFLAG_OLD
assert p2.h_original == 0
assert p1 != p2
p2.h_original = ffi.cast("revision_t", p1)
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
@@ -309,20 +309,23 @@
check_not_free(p3) # XXX replace with p1
def test_prebuilt_version_2_copy_over_prebuilt():
- p1 = lib.pseudoprebuilt(HDR, 42 + HDR)
+ p1 = lib.pseudoprebuilt_with_hash(HDR, 42 + HDR, 99)
p2 = oalloc(HDR); make_public(p2)
p3 = oalloc(HDR); make_public(p3)
delegate(p1, p2)
delegate_original(p1, p2)
delegate(p2, p3)
delegate_original(p1, p3)
- major_collect()
- # XXX: current approach requires 2 major collections.
- # the first to compress the path
- # the second to do the copy
+ # added by delegate, remove, otherwise
+ # major_collect will not copy over prebuilt p1:
+ p1.h_tid &= ~GCFLAG_PUBLIC_TO_PRIVATE
major_collect()
check_prebuilt(p1)
+ assert lib.stm_hash(p1) == 99
check_free_old(p2)
+ check_not_free(p3)
+ # XXX: takes another major collection to free p3
+ major_collect()
check_free_old(p3)
def test_prebuilt_version_to_protected():
@@ -340,7 +343,7 @@
def test_prebuilt_version_to_protected_copy_over_prebuilt():
py.test.skip("""current copy-over-prebuilt-original approach
- does not work with public_prebuilt->protected""")
+ does not work with public_prebuilt->stub->protected""")
p1 = lib.pseudoprebuilt(HDR, 42 + HDR)
p2 = lib.stm_write_barrier(p1)
lib.stm_commit_transaction()
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit