Author: Armin Rigo <ar...@tunes.org> Branch: Changeset: r955:8185ee16c279 Date: 2014-03-05 08:24 +0100 http://bitbucket.org/pypy/stmgc/changeset/8185ee16c279/
Log: Copying the hash/id logic from minimark.py, first part diff --git a/c7/stm/core.h b/c7/stm/core.h --- a/c7/stm/core.h +++ b/c7/stm/core.h @@ -46,6 +46,14 @@ */ GCFLAG_SMALL_UNIFORM = 0x02, + /* The following flag is set on nursery objects of which we asked + the id or the identityhash. It means that a space of the size of + the object has already been allocated in the nonmovable part. + The same flag is abused to mark prebuilt objects whose hash has + been taken during translation and is statically recorded just + after the object. */ + GCFLAG_HAS_SHADOW = 0x04, + /* 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 @@ -53,7 +61,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 = 0x04 /* must be last */ + GCFLAG_OVERFLOW_NUMBER_bit0 = 0x08 /* must be last */ }; diff --git a/c7/stm/prebuilt.c b/c7/stm/prebuilt.c --- a/c7/stm/prebuilt.c +++ b/c7/stm/prebuilt.c @@ -27,9 +27,10 @@ return; } - /* We need to make a copy of this object. */ + /* We need to make a copy of this object. The extra "long" is for + the prebuilt hash. */ size_t size = stmcb_size_rounded_up(obj); - object_t *nobj = _stm_allocate_old(size); + object_t *nobj = _stm_allocate_old(size + sizeof(long)); /* Copy the object */ char *realnobj = REAL_ADDRESS(stm_object_pages, nobj); diff --git a/c7/stmgc.c b/c7/stmgc.c --- a/c7/stmgc.c +++ b/c7/stmgc.c @@ -22,6 +22,7 @@ #include "stm/nursery.c" #include "stm/sync.c" #include "stm/setup.c" +#include "stm/hash_id.c" #include "stm/core.c" #include "stm/contention.c" #include "stm/fprintcolor.c" diff --git a/c7/stmgc.h b/c7/stmgc.h --- a/c7/stmgc.h +++ b/c7/stmgc.h @@ -261,6 +261,14 @@ static structure, but it should never be used anyway.) */ object_t *stm_setup_prebuilt(object_t *); +/* Hash, id. The id is just the address of the object (of the address + where it *will* be after the next minor collection). The hash is the + same, mangled -- except on prebuilt objects, where it can be + controlled for each prebuilt object individually. (Useful uor PyPy) */ +long stm_identityhash(object_t *obj); +long stm_id(object_t *obj); +void stm_set_prebuilt_identityhash(object_t *obj, uint64_t hash); + /* ==================== END ==================== */ diff --git a/c7/test/support.py b/c7/test/support.py --- a/c7/test/support.py +++ b/c7/test/support.py @@ -74,6 +74,10 @@ void stm_collect(long level); uint64_t _stm_total_allocated(void); + +long stm_identityhash(object_t *obj); +long stm_id(object_t *obj); +void stm_set_prebuilt_identityhash(object_t *obj, uint64_t hash); """) diff --git a/c7/test/test_hash_id.py b/c7/test/test_hash_id.py new file mode 100644 --- /dev/null +++ b/c7/test/test_hash_id.py @@ -0,0 +1,39 @@ +from support import * +from test_prebuilt import prebuilt +import py + +class TestHashId(BaseTest): + + def test_hash_old_object(self): + lp1 = stm_allocate_old(16) + lp2 = stm_allocate_old(16) + lp3 = stm_allocate_old(16) + lp4 = stm_allocate_old(16) + self.start_transaction() + h1 = lib.stm_identityhash(lp1) + h2 = lib.stm_identityhash(lp2) + h3 = lib.stm_identityhash(lp3) + h4 = lib.stm_identityhash(lp4) + assert len(set([h1, h2, h3, h4])) == 4 # guaranteed by the algo + + def test_id_old_object(self): + lp1 = stm_allocate_old(16) + self.start_transaction() + h1 = lib.stm_id(lp1) + assert h1 == int(ffi.cast("long", lp1)) + + def test_set_prebuilt_identityhash(self): + static1 = prebuilt(16) + static2 = prebuilt(16) + lp1 = lib.stm_setup_prebuilt(static1) + lp2 = lib.stm_setup_prebuilt(static2) + lib.stm_set_prebuilt_identityhash(lp1, 42) + self.start_transaction() + h1 = lib.stm_identityhash(lp1) + h2 = lib.stm_identityhash(lp2) + assert h1 == 42 + assert h2 != 0 + h1 = lib.stm_id(lp1) + h2 = lib.stm_id(lp2) + assert h1 == int(ffi.cast("long", lp1)) + assert h2 == int(ffi.cast("long", lp2)) _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit