Author: Remi Meier <[email protected]>
Branch: weakref
Changeset: r409:1cf2347f286d
Date: 2013-07-18 14:45 +0200
http://bitbucket.org/pypy/stmgc/changeset/1cf2347f286d/
Log: implementing immutables and trying to fix the stealing of weakrefs
diff --git a/c4/demo_random.c b/c4/demo_random.c
--- a/c4/demo_random.c
+++ b/c4/demo_random.c
@@ -516,8 +516,8 @@
t = (nodeptr)read_barrier(ptrs[i]);
w = t->weakref;
if(w) {
+ assert(stm_get_tid((gcptr)w) == GCTID_WEAKREF);
if (w->node) {
- assert(stm_get_tid((gcptr)w) == GCTID_WEAKREF);
check((gcptr)w->node);
return (gcptr)w->node;
}
diff --git a/c4/et.c b/c4/et.c
--- a/c4/et.c
+++ b/c4/et.c
@@ -545,6 +545,7 @@
gcptr stm_WriteBarrier(gcptr P)
{
+ assert(!(P->h_tid & GCFLAG_IMMUTABLE));
if (is_private(P))
{
/* If we have GCFLAG_WRITE_BARRIER in P, then list it into
diff --git a/c4/et.h b/c4/et.h
--- a/c4/et.h
+++ b/c4/et.h
@@ -72,6 +72,8 @@
static const revision_t GCFLAG_STUB /*debug*/ = STM_FIRST_GCFLAG << 8;
static const revision_t GCFLAG_PRIVATE_FROM_PROTECTED = STM_FIRST_GCFLAG << 9;
static const revision_t GCFLAG_HAS_ID = STM_FIRST_GCFLAG << 10;
+static const revision_t GCFLAG_IMMUTABLE = STM_FIRST_GCFLAG << 11;
+
/* this value must be reflected in PREBUILT_FLAGS in stmgc.h */
#define GCFLAG_PREBUILT (GCFLAG_VISITED | \
@@ -89,6 +91,8 @@
"BACKUP_COPY", \
"STUB", \
"PRIVATE_FROM_PROTECTED", \
+ "HAS_ID", \
+ "IMMUTABLE", \
NULL }
#define IS_POINTER(v) (!((v) & 1)) /* even-valued number */
diff --git a/c4/nursery.c b/c4/nursery.c
--- a/c4/nursery.c
+++ b/c4/nursery.c
@@ -101,6 +101,13 @@
return P;
}
+gcptr stm_allocate_immutable(size_t size, unsigned long tid)
+{
+ gcptr P = stm_allocate(size, tid);
+ P->h_tid |= GCFLAG_IMMUTABLE;
+ return P;
+}
+
gcptr stmgc_duplicate(gcptr P)
{
size_t size = stmgc_size(P);
diff --git a/c4/steal.c b/c4/steal.c
--- a/c4/steal.c
+++ b/c4/steal.c
@@ -21,9 +21,47 @@
{
gcptr stub, obj = *pobj;
if (obj == NULL || (obj->h_tid & (GCFLAG_PUBLIC | GCFLAG_OLD)) ==
- (GCFLAG_PUBLIC | GCFLAG_OLD))
+ (GCFLAG_PUBLIC | GCFLAG_OLD))
return;
+ if (obj->h_tid & GCFLAG_IMMUTABLE) {
+ assert(!(obj->h_tid & GCFLAG_PRIVATE_FROM_PROTECTED));
+ /* old or young protected! mark as PUBLIC */
+ if (!(obj->h_tid & GCFLAG_PUBLIC)) {
+ if (!(obj->h_tid & GCFLAG_OLD)) {
+ gcptr O;
+
+ if (obj->h_tid & GCFLAG_HAS_ID) {
+ /* use id-copy for us */
+ O = (gcptr)obj->h_original;
+ obj->h_tid &= ~GCFLAG_HAS_ID;
+ stm_copy_to_old_id_copy(obj, O);
+ O->h_original = 0;
+ } else {
+ O = stmgc_duplicate_old(obj);
+
+ /* young and without original? */
+ if (!(obj->h_original))
+ obj->h_original = (revision_t)O;
+ }
+ obj->h_revision = (revision_t)O;
+
+ O->h_tid |= GCFLAG_PUBLIC;
+ obj->h_tid |= (GCFLAG_NURSERY_MOVED | GCFLAG_PUBLIC);
+ /* here it is fine if it stays in read caches because
+ the object is immutable anyway and there are no
+ write_barriers allowed. */
+
+ dprintf(("steal prot immutable -> public: %p | %p\n", obj, O));
+ stub = obj;
+ goto done;
+ }
+ dprintf(("prot immutable -> public: %p\n", obj));
+ obj->h_tid |= GCFLAG_PUBLIC;
+ }
+ return;
+ }
+
/* we use 'all_stubs', a dictionary, in order to try to avoid
duplicate stubs for the same object. XXX maybe it would be
better to use a fast approximative cache that stays around for
diff --git a/c4/stmgc.h b/c4/stmgc.h
--- a/c4/stmgc.h
+++ b/c4/stmgc.h
@@ -29,6 +29,9 @@
/* allocate an object out of the local nursery */
gcptr stm_allocate(size_t size, unsigned long tid);
+/* allocate an object that is be immutable. it cannot be changed with
+ a stm_write_barrier() or after the next commit */
+gcptr stm_allocate_immutable(size_t size, unsigned long tid);
/* returns a never changing hash for the object */
revision_t stm_hash(gcptr);
diff --git a/c4/weakref.c b/c4/weakref.c
--- a/c4/weakref.c
+++ b/c4/weakref.c
@@ -6,7 +6,7 @@
gcptr stm_weakref_allocate(size_t size, unsigned long tid, gcptr obj)
{
stm_push_root(obj);
- gcptr weakref = stm_allocate(size, tid);
+ gcptr weakref = stm_allocate_immutable(size, tid);
obj = stm_pop_root();
assert(!(weakref->h_tid & GCFLAG_OLD)); /* 'size' too big? */
assert(stmgc_size(weakref) == size);
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit