Author: Remi Meier <remi.me...@inf.ethz.ch> Branch: card-marking Changeset: r1211:38e68ec4f6b5 Date: 2014-05-19 15:32 +0200 http://bitbucket.org/pypy/stmgc/changeset/38e68ec4f6b5/
Log: initial sketch of API diff --git a/c7/stm/core.c b/c7/stm/core.c --- a/c7/stm/core.c +++ b/c7/stm/core.c @@ -40,8 +40,13 @@ #endif } -void _stm_write_slowpath(object_t *obj) +void _stm_write_slowpath(object_t *obj, uintptr_t offset) { + assert(IMPLY(!(obj->stm_flags & GCFLAG_HAS_CARDS), + offset == 0)); + if (offset) + abort(); + assert(_seems_to_be_running_transaction()); assert(!_is_young(obj)); assert(obj->stm_flags & GCFLAG_WRITE_BARRIER); diff --git a/c7/stm/core.h b/c7/stm/core.h --- a/c7/stm/core.h +++ b/c7/stm/core.h @@ -35,6 +35,8 @@ #define WRITELOCK_START ((END_NURSERY_PAGE * 4096UL) >> 4) #define WRITELOCK_END READMARKER_END +#define CARD_SIZE _STM_CARD_SIZE + enum /* stm_flags */ { /* This flag is set on non-nursery objects. It forces stm_write() to call _stm_write_slowpath(). @@ -54,6 +56,9 @@ after the object. */ GCFLAG_HAS_SHADOW = 0x04, + /* Set on objects after allocation that may use card marking */ + GCFLAG_HAS_CARDS = _STM_GCFLAG_HAS_CARDS, + /* All remaining bits of the 32-bit 'stm_flags' field are taken by the "overflow number". This is a number that identifies the "overflow objects" from the current transaction among all old @@ -61,7 +66,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 = 0x8 /* must be last */ + GCFLAG_OVERFLOW_NUMBER_bit0 = 0x10 /* must be last */ }; diff --git a/c7/stm/setup.c b/c7/stm/setup.c --- a/c7/stm/setup.c +++ b/c7/stm/setup.c @@ -83,6 +83,7 @@ { /* Check that some values are acceptable */ assert(NB_SEGMENTS <= NB_SEGMENTS_MAX); + assert(CARD_SIZE > 0 && CARD_SIZE % 16 == 0); 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 @@ -106,7 +106,7 @@ /* this should use llvm's coldcc calling convention, but it's not exposed to C code so far */ -void _stm_write_slowpath(object_t *); +void _stm_write_slowpath(object_t *, uintptr_t); object_t *_stm_allocate_slowpath(ssize_t); object_t *_stm_allocate_external(ssize_t); void _stm_become_inevitable(const char*); @@ -143,6 +143,8 @@ #endif #define _STM_GCFLAG_WRITE_BARRIER 0x01 +#define _STM_GCFLAG_HAS_CARDS 0x08 +#define _STM_CARD_SIZE 16 /* modulo 16 == 0! */ #define _STM_NSE_SIGNAL_MAX _STM_TIME_N #define _STM_FAST_ALLOC (66*1024) @@ -210,7 +212,24 @@ static inline void stm_write(object_t *obj) { if (UNLIKELY((obj->stm_flags & _STM_GCFLAG_WRITE_BARRIER) != 0)) - _stm_write_slowpath(obj); + _stm_write_slowpath(obj, 0); +} + +/* The following are barriers that work on the granularity of CARD_SIZE. + They can only be used on objects one called stm_use_cards() on. */ +__attribute__((always_inline)) +static inline void stm_read_card(object_t *obj, uintptr_t offset) +{ + OPT_ASSERT(obj->stm_flags & _STM_GCFLAG_HAS_CARDS); + ((stm_read_marker_t *)(((uintptr_t)obj + offset) >> 4))->rm = + STM_SEGMENT->transaction_read_version; +} +__attribute__((always_inline)) +static inline void stm_write_card(object_t *obj, uintptr_t offset) +{ + OPT_ASSERT(obj->stm_flags & _STM_GCFLAG_HAS_CARDS); + if (UNLIKELY((obj->stm_flags & _STM_GCFLAG_WRITE_BARRIER) != 0)) + _stm_write_slowpath(obj, offset); } /* Must be provided by the user of this library. @@ -248,6 +267,16 @@ return (object_t *)p; } +/* directly after allocation one can enable card marking for any + kind of object with stm_use_cards(obj). This enables the use + of stm_write/read_card() barriers that do more fine-grained + conflict detection and garbage collection. */ +__attribute__((always_inline)) +static inline void stm_use_cards(object_t* o) +{ + o->stm_flags |= _STM_GCFLAG_HAS_CARDS; +} + /* Allocate a weakref object. Weakref objects have a reference to an object at the byte-offset stmcb_size_rounded_up(obj) - sizeof(void*) diff --git a/c7/test/support.py b/c7/test/support.py --- a/c7/test/support.py +++ b/c7/test/support.py @@ -12,6 +12,8 @@ #define STM_NB_SEGMENTS ... #define _STM_FAST_ALLOC ... #define _STM_GCFLAG_WRITE_BARRIER ... +#define _STM_GCFLAG_HAS_CARDS ... +#define _STM_CARD_SIZE ... #define STM_STACK_MARKER_NEW ... #define STM_STACK_MARKER_OLD ... @@ -41,6 +43,11 @@ object_t *stm_allocate_weakref(ssize_t size_rounded_up); object_t *_stm_allocate_old(ssize_t size_rounded_up); +void stm_use_cards(object_t* o); +void stm_read_card(object_t *obj, uintptr_t offset); +/*void stm_write_card(); use _checked_stm_write_card() instead */ + + void stm_setup(void); void stm_teardown(void); void stm_register_thread_local(stm_thread_local_t *tl); @@ -49,6 +56,7 @@ object_t *stm_setup_prebuilt_weakref(object_t *); bool _checked_stm_write(object_t *obj); +bool _checked_stm_write_card(object_t *obj, uintptr_t offset); bool _stm_was_read(object_t *obj); bool _stm_was_written(object_t *obj); char *_stm_real_address(object_t *obj); @@ -181,6 +189,10 @@ CHECKED(stm_write(object)); } +bool _checked_stm_write_card(object_t *object, uintptr_t offset) { + CHECKED(stm_write_card(object, offset)); +} + bool _check_stop_safe_point(void) { CHECKED(_stm_stop_safe_point()); } @@ -323,6 +335,8 @@ HDR = lib.SIZEOF_MYOBJ assert HDR == 8 GCFLAG_WRITE_BARRIER = lib._STM_GCFLAG_WRITE_BARRIER +GCFLAG_HAS_CARDS = lib._STM_GCFLAG_HAS_CARDS +CARD_SIZE = lib._STM_CARD_SIZE # 16b at least NB_SEGMENTS = lib.STM_NB_SEGMENTS @@ -335,20 +349,26 @@ def is_in_nursery(o): return lib.stm_can_move(o) -def stm_allocate_old(size): +def stm_allocate_old(size, use_cards=False): o = lib._stm_allocate_old(size) + if use_cards: + lib.stm_use_cards(o) tid = 42 + size lib._set_type_id(o, tid) return o -def stm_allocate_old_refs(n): +def stm_allocate_old_refs(n, use_cards=False): o = lib._stm_allocate_old(HDR + n * WORD) + if use_cards: + lib.stm_use_cards(o) tid = 421420 + n lib._set_type_id(o, tid) return o -def stm_allocate(size): +def stm_allocate(size, use_cards=False): o = lib.stm_allocate(size) + if use_cards: + lib.stm_use_cards(o) tid = 42 + size lib._set_type_id(o, tid) return o @@ -365,8 +385,10 @@ def stm_get_weakref(o): return lib._get_weakref(o) -def stm_allocate_refs(n): +def stm_allocate_refs(n, use_cards=False): o = lib.stm_allocate(HDR + n * WORD) + if use_cards: + lib.stm_use_cards(o) tid = 421420 + n lib._set_type_id(o, tid) return o @@ -395,10 +417,21 @@ def stm_read(o): lib.stm_read(o) +def stm_read_card(o, offset): + assert stm_get_flags(o) & GCFLAG_HAS_CARDS + assert offset < stm_get_obj_size(o) + lib.stm_read_card(o, offset) + def stm_write(o): if lib._checked_stm_write(o): raise Conflict() +def stm_write_card(o, offset): + assert stm_get_flags(o) & GCFLAG_HAS_CARDS + assert offset < stm_get_obj_size(o) + if lib._checked_stm_write_card(o, offset): + raise Conflict() + def stm_was_read(o): return lib._stm_was_read(o) _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit