Author: Remi Meier <[email protected]>
Branch: card-marking
Changeset: r1213:aeafbbe2bb03
Date: 2014-05-19 16:45 +0200
http://bitbucket.org/pypy/stmgc/changeset/aeafbbe2bb03/
Log: wip
diff --git a/c7/stm/core.c b/c7/stm/core.c
--- a/c7/stm/core.c
+++ b/c7/stm/core.c
@@ -40,6 +40,39 @@
#endif
}
+static bool _stm_write_slowpath_overflow_objs(object_t *obj, uintptr_t offset)
+{
+ /* is this an object from the same transaction, outside the nursery? */
+ if ((obj->stm_flags & -GCFLAG_OVERFLOW_NUMBER_bit0)
+ == STM_PSEGMENT->overflow_number) {
+
+ assert(STM_PSEGMENT->objects_pointing_to_nursery != NULL);
+ dprintf_test(("write_slowpath %p -> ovf obj_to_nurs\n", obj));
+
+ if (!offset) {
+ /* no card to be marked */
+ obj->stm_flags &= ~GCFLAG_WRITE_BARRIER;
+ LIST_APPEND(STM_PSEGMENT->objects_pointing_to_nursery, obj);
+ } else {
+ /* don't remove GCFLAG_WRITE_BARRIER because we need to be
+ here for every card to mark */
+ if (!(obj->stm_flags & GCFLAG_CARDS_SET)) {
+ /* not yet in the list */
+ LIST_APPEND(STM_PSEGMENT->objects_pointing_to_nursery, obj);
+ obj->stm_flags |= GCFLAG_CARDS_SET;
+ }
+
+ /* just acquire the corresponding lock for the next
minor_collection
+ to know what may have changed. only we know about this object:
*/
+ uintptr_t lock_idx = get_write_lock_idx((uintptr_t)obj + offset);
+ assert(!write_locks[lock_idx]);
+ write_locks[lock_idx] = STM_PSEGMENT->write_lock_num;
+ }
+ return true;
+ }
+ return false;
+}
+
void _stm_write_slowpath(object_t *obj, uintptr_t offset)
{
assert(IMPLY(!(obj->stm_flags & GCFLAG_HAS_CARDS),
@@ -49,16 +82,8 @@
assert(!_is_young(obj));
assert(obj->stm_flags & GCFLAG_WRITE_BARRIER);
- /* is this an object from the same transaction, outside the nursery? */
- if ((obj->stm_flags & -GCFLAG_OVERFLOW_NUMBER_bit0) ==
- STM_PSEGMENT->overflow_number) {
-
- dprintf_test(("write_slowpath %p -> ovf obj_to_nurs\n", obj));
- obj->stm_flags &= ~GCFLAG_WRITE_BARRIER;
- assert(STM_PSEGMENT->objects_pointing_to_nursery != NULL);
- LIST_APPEND(STM_PSEGMENT->objects_pointing_to_nursery, obj);
+ if (_stm_write_slowpath_overflow_objs(obj, offset))
return;
- }
/* do a read-barrier now. Note that this must occur before the
safepoints that may be issued in write_write_contention_management(). */
@@ -71,7 +96,7 @@
'modified_old_objects' (but, because it had GCFLAG_WRITE_BARRIER,
not in 'objects_pointing_to_nursery'). We'll detect this case
by finding that we already own the write-lock. */
- uintptr_t lock_idx = get_write_lock_idx(obj);
+ uintptr_t lock_idx = get_write_lock_idx((uintptr_t)obj);
uint8_t lock_num = STM_PSEGMENT->write_lock_num;
assert(lock_idx < sizeof(write_locks));
retry:
diff --git a/c7/stm/core.h b/c7/stm/core.h
--- a/c7/stm/core.h
+++ b/c7/stm/core.h
@@ -58,6 +58,8 @@
/* Set on objects after allocation that may use card marking */
GCFLAG_HAS_CARDS = _STM_GCFLAG_HAS_CARDS,
+ /* Set on objects that have at least one card marked */
+ GCFLAG_CARDS_SET = _STM_GCFLAG_CARDS_SET,
/* All remaining bits of the 32-bit 'stm_flags' field are taken by
the "overflow number". This is a number that identifies the
@@ -66,7 +68,7 @@
current transaction that have been flushed out of the nursery,
which occurs if the same transaction allocates too many objects.
*/
- GCFLAG_OVERFLOW_NUMBER_bit0 = 0x10 /* must be last */
+ GCFLAG_OVERFLOW_NUMBER_bit0 = 0x20 /* must be last */
};
@@ -220,8 +222,8 @@
#define REAL_ADDRESS(segment_base, src) ((segment_base) + (uintptr_t)(src))
-static inline uintptr_t get_write_lock_idx(object_t *obj) {
- return (((uintptr_t)obj) >> 4) - WRITELOCK_START;
+static inline uintptr_t get_write_lock_idx(uintptr_t obj) {
+ return (obj >> 4) - WRITELOCK_START;
}
static inline char *get_segment_base(long segment_num) {
diff --git a/c7/stm/misc.c b/c7/stm/misc.c
--- a/c7/stm/misc.c
+++ b/c7/stm/misc.c
@@ -47,9 +47,9 @@
STM_SEGMENT->transaction_read_version);
}
-bool _stm_was_written_card(object_t *obj, uintptr_t offset)
+bool _stm_was_written_card(object_t *obj)
{
- return write_locks[get_write_lock_idx((object_t*)((uintptr_t)obj +
offset))];
+ return obj->stm_flags & _STM_GCFLAG_CARDS_SET;
}
#ifdef STM_TESTS
diff --git a/c7/stm/setup.c b/c7/stm/setup.c
--- a/c7/stm/setup.c
+++ b/c7/stm/setup.c
@@ -84,6 +84,7 @@
/* Check that some values are acceptable */
assert(NB_SEGMENTS <= NB_SEGMENTS_MAX);
assert(CARD_SIZE > 0 && CARD_SIZE % 16 == 0);
+ assert(CARD_SIZE == 16); /* actually, it is hardcoded in some places
right now.. */
assert(4096 <= ((uintptr_t)STM_SEGMENT));
assert((uintptr_t)STM_SEGMENT == (uintptr_t)STM_PSEGMENT);
assert(((uintptr_t)STM_PSEGMENT) + sizeof(*STM_PSEGMENT) <= 8192);
diff --git a/c7/stmgc.h b/c7/stmgc.h
--- a/c7/stmgc.h
+++ b/c7/stmgc.h
@@ -121,7 +121,7 @@
bool _stm_was_read(object_t *obj);
bool _stm_was_written(object_t *obj);
bool _stm_was_read_card(object_t *obj, uintptr_t offset);
-bool _stm_was_written_card(object_t *obj, uintptr_t offset);
+bool _stm_was_written_card(object_t *obj);
uintptr_t _stm_get_private_page(uintptr_t pagenum);
bool _stm_in_transaction(stm_thread_local_t *tl);
char *_stm_get_segment_base(long index);
@@ -146,6 +146,7 @@
#define _STM_GCFLAG_WRITE_BARRIER 0x01
#define _STM_GCFLAG_HAS_CARDS 0x08
+#define _STM_GCFLAG_CARDS_SET 0x10
#define _STM_CARD_SIZE 16 /* modulo 16 == 0! */
#define _STM_NSE_SIGNAL_MAX _STM_TIME_N
#define _STM_FAST_ALLOC (66*1024)
diff --git a/c7/test/support.py b/c7/test/support.py
--- a/c7/test/support.py
+++ b/c7/test/support.py
@@ -60,7 +60,7 @@
bool _stm_was_read(object_t *obj);
bool _stm_was_read_card(object_t *obj, uintptr_t offset);
bool _stm_was_written(object_t *obj);
-bool _stm_was_written_card(object_t *obj, uintptr_t offset);
+bool _stm_was_written_card(object_t *obj);
char *_stm_real_address(object_t *obj);
char *_stm_get_segment_base(long index);
bool _stm_in_transaction(stm_thread_local_t *tl);
@@ -443,8 +443,8 @@
def stm_was_read_card(o, offset):
return lib._stm_was_read_card(o, offset)
-def stm_was_written_card(o, offset):
- return lib._stm_was_written_card(o, offset)
+def stm_was_written_card(o):
+ return lib._stm_was_written_card(o)
def stm_start_safe_point():
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit