[pypy-commit] stmgc finalizer: in-progress
arigo
noreply at buildbot.pypy.org
Tue Oct 7 11:10:17 CEST 2014
Author: Armin Rigo <arigo at tunes.org>
Branch: finalizer
Changeset: r1468:bc9a0f2e120d
Date: 2014-10-07 11:10 +0200
http://bitbucket.org/pypy/stmgc/changeset/bc9a0f2e120d/
Log: in-progress
diff --git a/c7/stm/core.h b/c7/stm/core.h
--- a/c7/stm/core.h
+++ b/c7/stm/core.h
@@ -203,6 +203,7 @@
struct list_s *young_objects_with_light_finalizers;
struct list_s *old_objects_with_light_finalizers;
struct list_s *objects_with_finalizers;
+ struct list_s *run_finalizers;
};
enum /* safe_point */ {
diff --git a/c7/stm/finalizer.c b/c7/stm/finalizer.c
--- a/c7/stm/finalizer.c
+++ b/c7/stm/finalizer.c
@@ -123,15 +123,13 @@
return _finalizer_tmpstack;
}
-static void _recursively_bump_finalization_state(object_t *obj, int from_state)
+static void _recursively_bump_finalization_state(object_t *obj, int to_state)
{
struct list_s *tmpstack = _finalizer_emptystack;
assert(list_is_empty(tmpstack));
- assert(_finalization_state(obj) == from_state);
-
while (1) {
- if (_finalization_state(obj) == from_state) {
+ if (_finalization_state(obj) == to_state - 1) {
/* bump to the next state */
write_locks[mark_loc(obj)]++;
@@ -151,27 +149,35 @@
{
/* for non-light finalizers */
- /* there is one 'objects_with_finalizers' list per segment, but it
- doesn't really matter: all objects are considered equal, and if
- they survive, they are added again into one list that is attached
- at the end to an arbitrary segment. */
- struct list_s *new_with_finalizer = list_create();
- struct list_s *marked = list_create();
- struct list_s *pending = list_create();
+ /* there is one 'objects_with_finalizers' list per segment.
+ Objects that survives remain the their original segment's list.
+ For objects that existed since a long time, it doesn't change
+ anything: any thread, through any segment, should see the same
+ old content. (If the content was different between segments,
+ the object would be in a 'modified_old_objects' list somewhere,
+ and so it wouldn't be dead). But it's important if the object
+ was created by the same transaction: then only that segment
+ sees valid content.
+ */
+ struct list_s *marked_seg[NB_SEGMENTS];
+ struct list_s *pending;
LIST_CREATE(_finalizer_emptystack);
+ LIST_CREATE(pending);
long j;
for (j = 1; j <= NB_SEGMENTS; j++) {
struct stm_priv_segment_info_s *pseg = get_priv_segment(j);
+ struct list_s *marked = list_create();
struct list_s *lst = pseg->objects_with_finalizers;
long i, count = list_count(lst);
+ lst->count = 0;
for (i = 0; i < count; i++) {
object_t *x = (object_t *)list_item(lst, i);
assert(_finalization_state(x) != 1);
if (_finalization_state(x) >= 2) {
- LIST_APPEND(new_with_finalizer, x);
+ list_set_item(lst, lst->count++, (uintptr_t)x);
continue;
}
LIST_APPEND(marked, x);
@@ -184,32 +190,39 @@
pending = finalizer_trace(y, pending);
}
else if (state == 2) {
- _recursively_bump_finalization_state(y, 2);
+ _recursively_bump_finalization_state(y, 3);
}
}
- _recursively_bump_finalization_state(x, 1);
+ assert(_finalization_state(x) == 1);
+ _recursively_bump_finalization_state(x, 2);
}
- list_clear(lst);
+
+ marked_seg[j - 1] = marked;
}
- long i, count = list_count(marked);
- for (i = 0; i < count; i++) {
- object_t *x = (object_t *)list_item(marked, i);
+ LIST_FREE(pending);
- int state = _finalization_state(x);
- assert(state >= 2);
- if (state == 2) {
- LIST_APPEND(run_finalizers, x);
- _recursively_bump_finalization_state(x, 2);
+ for (j = 1; j <= NB_SEGMENTS; j++) {
+ struct stm_priv_segment_info_s *pseg = get_priv_segment(j);
+ struct list_s *lst = pseg->objects_with_finalizers;
+ struct list_s *marked = marked_seg[j - 1];
+
+ long i, count = list_count(marked);
+ for (i = 0; i < count; i++) {
+ object_t *x = (object_t *)list_item(marked, i);
+
+ int state = _finalization_state(x);
+ assert(state >= 2);
+ if (state == 2) {
+ LIST_APPEND(pseg->run_finalizers, x);
+ _recursively_bump_finalization_state(x, 3);
+ }
+ else {
+ list_set_item(lst, lst->count++, (uintptr_t)x);
+ }
}
- else {
- LIST_APPEND(new_with_finalizer, x);
- }
+ list_free(marked);
}
LIST_FREE(_finalizer_emptystack);
- list_free(pending);
- list_free(marked);
- list_free(get_priv_segment(1)->objects_with_finalizers);
- get_priv_segment(1)->objects_with_finalizers = new_with_finalizer;
}
diff --git a/c7/stm/finalizer.h b/c7/stm/finalizer.h
--- a/c7/stm/finalizer.h
+++ b/c7/stm/finalizer.h
@@ -2,5 +2,3 @@
static void deal_with_young_objects_with_finalizers(void);
static void deal_with_old_objects_with_finalizers(void);
static void deal_with_objects_with_finalizers(void);
-
-static struct list_s *run_finalizers;
diff --git a/c7/stm/setup.c b/c7/stm/setup.c
--- a/c7/stm/setup.c
+++ b/c7/stm/setup.c
@@ -131,11 +131,11 @@
pr->young_objects_with_light_finalizers = list_create();
pr->old_objects_with_light_finalizers = list_create();
pr->objects_with_finalizers = list_create();
+ pr->run_finalizers = list_create();
pr->overflow_number = GCFLAG_OVERFLOW_NUMBER_bit0 * i;
highest_overflow_number = pr->overflow_number;
pr->pub.transaction_read_version = 0xff;
}
- run_finalizers = list_create();
/* The pages are shared lazily, as remap_file_pages() takes a relatively
long time for each page.
@@ -176,8 +176,8 @@
list_free(pr->young_objects_with_light_finalizers);
list_free(pr->old_objects_with_light_finalizers);
list_free(pr->objects_with_finalizers);
+ list_free(pr->run_finalizers);
}
- list_free(run_finalizers);
munmap(stm_object_pages, TOTAL_MEMORY);
stm_object_pages = NULL;
More information about the pypy-commit
mailing list