[pypy-commit] stmgc c7-refactor: Unify overflow_objects_pointing_to_nursery and
arigo
noreply at buildbot.pypy.org
Mon Feb 24 17:59:12 CET 2014
Author: Armin Rigo <arigo at tunes.org>
Branch: c7-refactor
Changeset: r841:2286fb4f0127
Date: 2014-02-24 17:57 +0100
http://bitbucket.org/pypy/stmgc/changeset/2286fb4f0127/
Log: Unify overflow_objects_pointing_to_nursery and
old_objects_pointing_to_nursery: unless I'm wrong, we can merge the
two lists.
diff --git a/c7/stm/core.c b/c7/stm/core.c
--- a/c7/stm/core.c
+++ b/c7/stm/core.c
@@ -18,10 +18,10 @@
if ((obj->stm_flags & -GCFLAG_OVERFLOW_NUMBER_bit0) ==
STM_PSEGMENT->overflow_number) {
- dprintf_test(("write_slowpath %p -> ovf_obj\n", obj));
+ dprintf_test(("write_slowpath %p -> ovf obj_to_nurs\n", obj));
obj->stm_flags &= ~GCFLAG_WRITE_BARRIER;
- assert(STM_PSEGMENT->overflow_objects_pointing_to_nursery != NULL);
- LIST_APPEND(STM_PSEGMENT->overflow_objects_pointing_to_nursery, obj);
+ assert(STM_PSEGMENT->objects_pointing_to_nursery != NULL);
+ LIST_APPEND(STM_PSEGMENT->objects_pointing_to_nursery, obj);
return;
}
@@ -32,7 +32,7 @@
/* claim the write-lock for this object. In case we're running the
same transaction since a long while, the object can be already in
'modified_old_objects' (but, because it had GCFLAG_WRITE_BARRIER,
- not in 'old_objects_pointing_to_nursery'). We'll detect this case
+ not in 'objects_pointing_to_nursery'). We'll detect this case
by finding that we already own the write-lock. */
uintptr_t lock_idx = (((uintptr_t)obj) >> 4) - WRITELOCK_START;
uint8_t lock_num = STM_PSEGMENT->write_lock_num;
@@ -77,7 +77,7 @@
}
}
else if (write_locks[lock_idx] == lock_num) {
- OPT_ASSERT(STM_PSEGMENT->old_objects_pointing_to_nursery != NULL);
+ OPT_ASSERT(STM_PSEGMENT->objects_pointing_to_nursery != NULL);
#ifdef STM_TESTS
bool found = false;
LIST_FOREACH_R(STM_PSEGMENT->modified_old_objects, object_t *,
@@ -97,11 +97,11 @@
}
/* A common case for write_locks[] that was either 0 or lock_num:
- we need to add the object to 'old_objects_pointing_to_nursery'
+ we need to add the object to 'objects_pointing_to_nursery'
if there is such a list. */
- if (STM_PSEGMENT->old_objects_pointing_to_nursery != NULL) {
- dprintf_test(("write_slowpath %p -> old_obj_pointing_to_nurs\n", obj));
- LIST_APPEND(STM_PSEGMENT->old_objects_pointing_to_nursery, obj);
+ if (STM_PSEGMENT->objects_pointing_to_nursery != NULL) {
+ dprintf_test(("write_slowpath %p -> old obj_to_nurs\n", obj));
+ LIST_APPEND(STM_PSEGMENT->objects_pointing_to_nursery, obj);
}
/* add the write-barrier-already-called flag ONLY if we succeeded in
@@ -173,8 +173,7 @@
}
assert(list_is_empty(STM_PSEGMENT->modified_old_objects));
- assert(STM_PSEGMENT->old_objects_pointing_to_nursery == NULL);
- assert(STM_PSEGMENT->overflow_objects_pointing_to_nursery == NULL);
+ assert(STM_PSEGMENT->objects_pointing_to_nursery == NULL);
assert(STM_PSEGMENT->large_overflow_objects == NULL);
#ifdef STM_TESTS
@@ -318,8 +317,7 @@
STM_PSEGMENT->transaction_state = TS_NONE;
/* reset these lists to NULL for the next transaction */
- LIST_FREE(STM_PSEGMENT->old_objects_pointing_to_nursery);
- LIST_FREE(STM_PSEGMENT->overflow_objects_pointing_to_nursery);
+ LIST_FREE(STM_PSEGMENT->objects_pointing_to_nursery);
LIST_FREE(STM_PSEGMENT->large_overflow_objects);
stm_thread_local_t *tl = STM_SEGMENT->running_thread;
@@ -332,6 +330,9 @@
assert(!_has_mutex());
assert(STM_PSEGMENT->safe_point == SP_RUNNING);
+ bool has_any_overflow_object =
+ (STM_PSEGMENT->objects_pointing_to_nursery != NULL);
+
minor_collection(/*commit=*/ true);
mutex_lock();
@@ -359,7 +360,7 @@
push_modified_to_other_segments();
/* update 'overflow_number' if needed */
- if (STM_PSEGMENT->overflow_objects_pointing_to_nursery != NULL) {
+ if (has_any_overflow_object) {
highest_overflow_number += GCFLAG_OVERFLOW_NUMBER_bit0;
STM_PSEGMENT->overflow_number = highest_overflow_number;
}
diff --git a/c7/stm/core.h b/c7/stm/core.h
--- a/c7/stm/core.h
+++ b/c7/stm/core.h
@@ -67,20 +67,15 @@
that need to be copied to other segments upon commit. */
struct list_s *modified_old_objects;
- /* List of the modified old objects that may point to the nursery.
- If the current transaction didn't span a minor collection so far,
- this is NULL, understood as meaning implicitly "this is the same
- as 'modified_old_objects'". Otherwise, this list is a subset of
- 'modified_old_objects'. */
- struct list_s *old_objects_pointing_to_nursery;
-
- /* List of overflowed objects (from the same transaction but outside
- the nursery) on which the write-barrier was triggered, so that
- they likely contain a pointer to a nursery object. This is used
- by the GC: it's additional roots for the next minor collection.
- This is NULL if the current transaction didn't span a minor
- collection so far. */
- struct list_s *overflow_objects_pointing_to_nursery;
+ /* List of out-of-nursery objects that may contain pointers to
+ nursery objects. This is used to track the GC status: they
+ are all objects outside the nursery on which an stm_write()
+ occurred since the last minor collection. If there was no
+ minor collection yet in the current transaction, this is NULL,
+ understood as meaning implicitly "this is the same as
+ 'modified_old_objects'. This list contains exactly the
+ objects without GCFLAG_WRITE_BARRIER. */
+ struct list_s *objects_pointing_to_nursery;
/* List of all large, overflowed objects. Only non-NULL after the
current transaction spanned a minor collection. */
diff --git a/c7/stm/misc.c b/c7/stm/misc.c
--- a/c7/stm/misc.c
+++ b/c7/stm/misc.c
@@ -48,18 +48,11 @@
return list_count(STM_PSEGMENT->modified_old_objects);
}
-long _stm_count_old_objects_pointing_to_nursery(void)
+long _stm_count_objects_pointing_to_nursery(void)
{
- if (STM_PSEGMENT->old_objects_pointing_to_nursery == NULL)
+ if (STM_PSEGMENT->objects_pointing_to_nursery == NULL)
return -1;
- return list_count(STM_PSEGMENT->old_objects_pointing_to_nursery);
-}
-
-long _stm_count_overflow_objects_pointing_to_nursery(void)
-{
- if (STM_PSEGMENT->overflow_objects_pointing_to_nursery == NULL)
- return -1;
- return list_count(STM_PSEGMENT->overflow_objects_pointing_to_nursery);
+ return list_count(STM_PSEGMENT->objects_pointing_to_nursery);
}
object_t *_stm_enum_modified_old_objects(long index)
@@ -68,15 +61,9 @@
STM_PSEGMENT->modified_old_objects, index);
}
-object_t *_stm_enum_old_objects_pointing_to_nursery(long index)
+object_t *_stm_enum_objects_pointing_to_nursery(long index)
{
return (object_t *)list_item(
- STM_PSEGMENT->old_objects_pointing_to_nursery, index);
-}
-
-object_t *_stm_enum_overflow_objects_pointing_to_nursery(long index)
-{
- return (object_t *)list_item(
- STM_PSEGMENT->overflow_objects_pointing_to_nursery, index);
+ STM_PSEGMENT->objects_pointing_to_nursery, index);
}
#endif
diff --git a/c7/stm/nursery.c b/c7/stm/nursery.c
--- a/c7/stm/nursery.c
+++ b/c7/stm/nursery.c
@@ -113,7 +113,7 @@
*pobj = nobj;
/* Must trace the object later */
- LIST_APPEND(STM_PSEGMENT->old_objects_pointing_to_nursery, nobj);
+ LIST_APPEND(STM_PSEGMENT->objects_pointing_to_nursery, nobj);
}
static void collect_roots_in_nursery(void)
@@ -129,7 +129,7 @@
static void collect_oldrefs_to_nursery(void)
{
- struct list_s *lst = STM_PSEGMENT->old_objects_pointing_to_nursery;
+ struct list_s *lst = STM_PSEGMENT->objects_pointing_to_nursery;
while (!list_is_empty(lst)) {
object_t *obj = (object_t *)list_pop_item(lst);
@@ -140,8 +140,8 @@
obj->stm_flags |= GCFLAG_WRITE_BARRIER;
/* Trace the 'obj' to replace pointers to nursery with pointers
- outside the nursery, possibly forcing nursery objects out
- and adding them to 'old_objects_pointing_to_nursery' as well. */
+ outside the nursery, possibly forcing nursery objects out and
+ adding them to 'objects_pointing_to_nursery' as well. */
char *realobj = REAL_ADDRESS(STM_SEGMENT->segment_base, obj);
stmcb_trace((struct object_s *)realobj, &minor_trace_if_young);
}
@@ -167,9 +167,9 @@
/* We must move out of the nursery any object found within the
nursery. All objects touched are either from the current
- transaction, or are from 'old_objects_pointing_to_young'.
- In all cases, we should only read and change objects belonging
- to the current segment.
+ transaction, or are from 'modified_old_objects'. In all cases,
+ we should only read and change objects belonging to the current
+ segment.
XXX improve: it might be possible to run this function in
a safe-point but without the mutex, if we are careful
@@ -178,8 +178,15 @@
dprintf(("minor_collection commit=%d\n", (int)commit));
STM_PSEGMENT->minor_collect_will_commit_now = commit;
- if (STM_PSEGMENT->old_objects_pointing_to_nursery == NULL)
- STM_PSEGMENT->old_objects_pointing_to_nursery = list_create();
+
+ /* All the objects we move out of the nursery become "overflow"
+ objects. We use the list 'objects_pointing_to_nursery'
+ to hold the ones we didn't trace so far. */
+ if (STM_PSEGMENT->objects_pointing_to_nursery == NULL)
+ STM_PSEGMENT->objects_pointing_to_nursery = list_create();
+
+ /* We need this to track the large overflow objects for a future
+ commit. We don't need it if we're committing now. */
if (!commit && STM_PSEGMENT->large_overflow_objects == NULL)
STM_PSEGMENT->large_overflow_objects = list_create();
@@ -189,9 +196,7 @@
reset_nursery();
- assert(list_is_empty(STM_PSEGMENT->old_objects_pointing_to_nursery));
- if (!commit && STM_PSEGMENT->overflow_objects_pointing_to_nursery == NULL)
- STM_PSEGMENT->overflow_objects_pointing_to_nursery = list_create();
+ assert(list_is_empty(STM_PSEGMENT->objects_pointing_to_nursery));
}
void stm_collect(long level)
diff --git a/c7/stm/setup.c b/c7/stm/setup.c
--- a/c7/stm/setup.c
+++ b/c7/stm/setup.c
@@ -53,7 +53,7 @@
pr->write_lock_num = i + 1;
pr->pub.segment_num = i;
pr->pub.segment_base = segment_base;
- pr->overflow_objects_pointing_to_nursery = NULL;
+ pr->objects_pointing_to_nursery = NULL;
pr->large_overflow_objects = NULL;
pr->modified_old_objects = list_create();
pr->overflow_number = GCFLAG_OVERFLOW_NUMBER_bit0 * (i + 1);
@@ -85,9 +85,8 @@
long i;
for (i = 0; i < NB_SEGMENTS; i++) {
struct stm_priv_segment_info_s *pr = get_priv_segment(i);
- assert(pr->overflow_objects_pointing_to_nursery == NULL);
+ assert(pr->objects_pointing_to_nursery == NULL);
assert(pr->large_overflow_objects == NULL);
- assert(pr->old_objects_pointing_to_nursery == NULL);
list_free(pr->modified_old_objects);
}
diff --git a/c7/stmgc.h b/c7/stmgc.h
--- a/c7/stmgc.h
+++ b/c7/stmgc.h
@@ -82,11 +82,9 @@
void _stm_stop_safe_point(void);
void _stm_set_nursery_free_count(uint64_t free_count);
long _stm_count_modified_old_objects(void);
-long _stm_count_old_objects_pointing_to_nursery(void);
-long _stm_count_overflow_objects_pointing_to_nursery(void);
+long _stm_count_objects_pointing_to_nursery(void);
object_t *_stm_enum_modified_old_objects(long index);
-object_t *_stm_enum_old_objects_pointing_to_nursery(long index);
-object_t *_stm_enum_overflow_objects_pointing_to_nursery(long index);
+object_t *_stm_enum_objects_pointing_to_nursery(long index);
#endif
#define _STM_GCFLAG_WRITE_BARRIER 0x01
diff --git a/c7/test/support.py b/c7/test/support.py
--- a/c7/test/support.py
+++ b/c7/test/support.py
@@ -77,11 +77,9 @@
ssize_t stmcb_size_rounded_up(struct object_s *obj);
long _stm_count_modified_old_objects(void);
-long _stm_count_old_objects_pointing_to_nursery(void);
-long _stm_count_overflow_objects_pointing_to_nursery(void);
+long _stm_count_objects_pointing_to_nursery(void);
object_t *_stm_enum_modified_old_objects(long index);
-object_t *_stm_enum_old_objects_pointing_to_nursery(long index);
-object_t *_stm_enum_overflow_objects_pointing_to_nursery(long index);
+object_t *_stm_enum_objects_pointing_to_nursery(long index);
void stm_collect(long level);
""")
@@ -367,17 +365,11 @@
return None
return map(lib._stm_enum_modified_old_objects, range(count))
-def old_objects_pointing_to_nursery():
- count = lib._stm_count_old_objects_pointing_to_nursery()
+def objects_pointing_to_nursery():
+ count = lib._stm_count_objects_pointing_to_nursery()
if count < 0:
return None
- return map(lib._stm_enum_old_objects_pointing_to_nursery, range(count))
-
-def overflow_objects_pointing_to_nursery():
- count = lib._stm_count_overflow_objects_pointing_to_nursery()
- if count < 0:
- return None
- return map(lib._stm_enum_overflow_objects_pointing_to_nursery,range(count))
+ return map(lib._stm_enum_objects_pointing_to_nursery, range(count))
SHADOWSTACK_LENGTH = 1000
diff --git a/c7/test/test_basic.py b/c7/test/test_basic.py
--- a/c7/test/test_basic.py
+++ b/c7/test/test_basic.py
@@ -51,8 +51,7 @@
stm_write(lp1)
assert stm_was_written(lp1)
assert modified_old_objects() == [] # object not old
- assert old_objects_pointing_to_nursery() == None # short transac.
- assert overflow_objects_pointing_to_nursery() == None # short transac.
+ assert objects_pointing_to_nursery() == None # short transaction
self.commit_transaction()
def test_allocate_old(self):
@@ -89,7 +88,7 @@
assert modified_old_objects() == []
stm_write(lp1)
assert modified_old_objects() == [lp1]
- assert old_objects_pointing_to_nursery() == None
+ assert objects_pointing_to_nursery() == None
assert stm_get_char(lp1) == 'a'
stm_set_char(lp1, 'b')
#
More information about the pypy-commit
mailing list