Author: Armin Rigo <[email protected]>
Branch: finalizer
Changeset: r1471:f191db4c021a
Date: 2014-10-16 06:57 +0200
http://bitbucket.org/pypy/stmgc/changeset/f191db4c021a/
Log: Progress
diff --git a/c7/stm/finalizer.c b/c7/stm/finalizer.c
--- a/c7/stm/finalizer.c
+++ b/c7/stm/finalizer.c
@@ -8,6 +8,7 @@
static void init_finalizers(struct finalizers_s *f)
{
f->objects_with_finalizers = list_create();
+ f->count_non_young = 0;
f->run_finalizers = NULL;
f->running_next = NULL;
}
@@ -83,6 +84,8 @@
object_t *stm_allocate_with_finalizer(ssize_t size_rounded_up)
{
+ object_t *obj = _stm_allocate_external(size_rounded_up);
+
if (STM_PSEGMENT->finalizers == NULL) {
struct finalizers_s *f = malloc(sizeof(struct finalizers_s));
if (f == NULL)
@@ -90,8 +93,6 @@
init_finalizers(f);
STM_PSEGMENT->finalizers = f;
}
-
- object_t *obj = _allocate_old(size_rounded_up);
LIST_APPEND(STM_PSEGMENT->finalizers->objects_with_finalizers, obj);
return obj;
}
@@ -201,16 +202,17 @@
LIST_APPEND(_finalizer_tmpstack, obj);
}
-static inline struct list_s *finalizer_trace(object_t *obj, struct list_s *lst)
+static inline struct list_s *finalizer_trace(char *base, object_t *obj,
+ struct list_s *lst)
{
- struct object_s *realobj =
- (struct object_s *)REAL_ADDRESS(stm_object_pages, obj);
+ struct object_s *realobj = (struct object_s *)REAL_ADDRESS(base, obj);
_finalizer_tmpstack = lst;
stmcb_trace(realobj, &_append_to_finalizer_tmpstack);
return _finalizer_tmpstack;
}
-static void _recursively_bump_finalization_state(object_t *obj, int to_state)
+static void _recursively_bump_finalization_state(char *base, object_t *obj,
+ int to_state)
{
struct list_s *tmpstack = _finalizer_emptystack;
assert(list_is_empty(tmpstack));
@@ -221,7 +223,7 @@
write_locks[mark_loc(obj)]++;
/* trace */
- tmpstack = finalizer_trace(obj, tmpstack);
+ tmpstack = finalizer_trace(base, obj, tmpstack);
}
if (list_is_empty(tmpstack))
@@ -232,7 +234,7 @@
_finalizer_emptystack = tmpstack;
}
-static struct list_s *mark_finalize_step1(struct finalizers_s *f)
+static struct list_s *mark_finalize_step1(char *base, struct finalizers_s *f)
{
if (f == NULL)
return NULL;
@@ -259,20 +261,21 @@
int state = _finalization_state(y);
if (state <= 0) {
_bump_finalization_state_from_0_to_1(y);
- pending = finalizer_trace(y, pending);
+ pending = finalizer_trace(base, y, pending);
}
else if (state == 2) {
- _recursively_bump_finalization_state(y, 3);
+ _recursively_bump_finalization_state(base, y, 3);
}
}
_finalizer_pending = pending;
assert(_finalization_state(x) == 1);
- _recursively_bump_finalization_state(x, 2);
+ _recursively_bump_finalization_state(base, x, 2);
}
return marked;
}
-static void mark_finalize_step2(struct finalizers_s *f, struct list_s *marked)
+static void mark_finalize_step2(char *base, struct finalizers_s *f,
+ struct list_s *marked)
{
if (f == NULL)
return;
@@ -289,7 +292,7 @@
if (run_finalizers == NULL)
run_finalizers = list_create();
LIST_APPEND(run_finalizers, x);
- _recursively_bump_finalization_state(x, 3);
+ _recursively_bump_finalization_state(base, x, 3);
}
else {
struct list_s *lst = f->objects_with_finalizers;
@@ -325,17 +328,19 @@
long j;
for (j = 1; j <= NB_SEGMENTS; j++) {
struct stm_priv_segment_info_s *pseg = get_priv_segment(j);
- marked_seg[j] = mark_finalize_step1(pseg->finalizers);
+ marked_seg[j] = mark_finalize_step1(pseg->pub.segment_base,
+ pseg->finalizers);
}
- marked_seg[0] = mark_finalize_step1(&g_finalizers);
+ marked_seg[0] = mark_finalize_step1(stm_object_pages, &g_finalizers);
LIST_FREE(_finalizer_pending);
for (j = 1; j <= NB_SEGMENTS; j++) {
struct stm_priv_segment_info_s *pseg = get_priv_segment(j);
- mark_finalize_step2(pseg->finalizers, marked_seg[j]);
+ mark_finalize_step2(pseg->pub.segment_base, pseg->finalizers,
+ marked_seg[j]);
}
- mark_finalize_step2(&g_finalizers, marked_seg[0]);
+ mark_finalize_step2(stm_object_pages, &g_finalizers, marked_seg[0]);
LIST_FREE(_finalizer_emptystack);
}
diff --git a/c7/stm/finalizer.h b/c7/stm/finalizer.h
--- a/c7/stm/finalizer.h
+++ b/c7/stm/finalizer.h
@@ -1,6 +1,7 @@
struct finalizers_s {
struct list_s *objects_with_finalizers;
+ uintptr_t count_non_young;
struct list_s *run_finalizers;
uintptr_t *running_next;
};
diff --git a/c7/stm/gcpage.c b/c7/stm/gcpage.c
--- a/c7/stm/gcpage.c
+++ b/c7/stm/gcpage.c
@@ -111,20 +111,14 @@
return addr;
}
-static object_t *_allocate_old(ssize_t size_rounded_up)
+object_t *_stm_allocate_old(ssize_t size_rounded_up)
{
+ /* only for tests xxx but stm_setup_prebuilt() uses this now too */
char *p = allocate_outside_nursery_large(size_rounded_up);
memset(p, 0, size_rounded_up);
object_t *o = (object_t *)(p - stm_object_pages);
o->stm_flags = GCFLAG_WRITE_BARRIER;
- return o;
-}
-
-object_t *_stm_allocate_old(ssize_t size_rounded_up)
-{
- /* only for tests xxx but stm_setup_prebuilt() uses this now too */
- object_t *o = _allocate_old(size_rounded_up);
if (testing_prebuilt_objs == NULL)
testing_prebuilt_objs = list_create();
diff --git a/c7/stm/nursery.c b/c7/stm/nursery.c
--- a/c7/stm/nursery.c
+++ b/c7/stm/nursery.c
@@ -435,6 +435,22 @@
}
}
+static void collect_objs_still_young_but_with_finalizers(void)
+{
+ struct list_s *lst = STM_PSEGMENT->finalizers->objects_with_finalizers;
+ uintptr_t i, total = list_count(lst);
+
+ for (i = STM_PSEGMENT->finalizers->count_non_young; i < total; i++) {
+
+ object_t *o = (object_t *)list_item(lst, i);
+ minor_trace_if_young(&o);
+
+ /* was not actually movable */
+ assert(o == (object_t *)list_item(lst, i));
+ }
+ STM_PSEGMENT->finalizers->count_non_young = total;
+}
+
static size_t throw_away_nursery(struct stm_priv_segment_info_s *pseg)
{
#pragma push_macro("STM_PSEGMENT")
@@ -554,6 +570,9 @@
collect_roots_in_nursery();
+ if (STM_PSEGMENT->finalizers != NULL)
+ collect_objs_still_young_but_with_finalizers();
+
collect_oldrefs_to_nursery();
assert(list_is_empty(STM_PSEGMENT->old_objects_with_cards));
diff --git a/c7/test/support.py b/c7/test/support.py
--- a/c7/test/support.py
+++ b/c7/test/support.py
@@ -163,6 +163,8 @@
void (*stmcb_light_finalizer)(object_t *);
void stm_enable_light_finalizer(object_t *);
+
+void (*stmcb_finalizer)(object_t *);
""")
@@ -459,6 +461,18 @@
stm_read(obj)
return lib._get_ptr(obj, idx)
+def stm_allocate_with_finalizer(size):
+ o = lib.stm_allocate_with_finalizer(size)
+ tid = 42 + size
+ lib._set_type_id(o, tid)
+ return o
+
+def stm_allocate_with_finalizer_refs(n):
+ o = lib.stm_allocate_with_finalizer(HDR + n * WORD)
+ tid = 421420 + n
+ lib._set_type_id(o, tid)
+ return o
+
def stm_set_char(obj, c, offset=HDR, use_cards=False):
assert HDR <= offset < stm_get_obj_size(obj)
if use_cards:
diff --git a/c7/test/test_finalizer.py b/c7/test/test_finalizer.py
--- a/c7/test/test_finalizer.py
+++ b/c7/test/test_finalizer.py
@@ -127,3 +127,23 @@
lp1 = stm_allocate_with_finalizer(48)
stm_minor_collect()
self.expect_finalized([])
+
+ def test_finalizer_in_major_collection(self):
+ self.start_transaction()
+ lp1 = stm_allocate_with_finalizer(48)
+ lp2 = stm_allocate_with_finalizer(48)
+ lp3 = stm_allocate_with_finalizer(48)
+ print lp1, lp2, lp3
+ stm_major_collect()
+ self.expect_finalized([lp1, lp2, lp3])
+
+ def test_finalizer_ordering(self):
+ self.start_transaction()
+ lp1 = stm_allocate_with_finalizer_refs(1)
+ lp2 = stm_allocate_with_finalizer_refs(1)
+ lp3 = stm_allocate_with_finalizer_refs(1)
+ print lp1, lp2, lp3
+ stm_set_ref(lp3, 0, lp1)
+ stm_set_ref(lp1, 0, lp2)
+ stm_major_collect()
+ self.expect_finalized([lp3])
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit