Author: Armin Rigo <[email protected]>
Branch:
Changeset: r354:70f314b926f7
Date: 2013-07-06 11:27 +0200
http://bitbucket.org/pypy/stmgc/changeset/70f314b926f7/
Log: Move the stm_hash/stm_id/stm_pointer_equal to a new file, extra.c,
whose purpose is to contain "non-core" things offered in stmgc.h.
diff --git a/c4/Makefile b/c4/Makefile
--- a/c4/Makefile
+++ b/c4/Makefile
@@ -16,10 +16,10 @@
H_FILES = atomic_ops.h stmgc.h stmimpl.h \
et.h lists.h steal.h nursery.h gcpage.h \
- stmsync.h dbgmem.h fprintcolor.h
+ stmsync.h extra.h dbgmem.h fprintcolor.h
C_FILES = et.c lists.c steal.c nursery.c gcpage.c \
- stmsync.c dbgmem.c fprintcolor.c
+ stmsync.c extra.c dbgmem.c fprintcolor.c
DEBUG = -g -DGC_NURSERY=0x10000 -D_GC_DEBUG=1 -DDUMP_EXTRA=1
-D_GC_DEBUGPRINTS=1
diff --git a/c4/extra.c b/c4/extra.c
new file mode 100644
--- /dev/null
+++ b/c4/extra.c
@@ -0,0 +1,139 @@
+#include "stmimpl.h"
+
+
+void stm_copy_to_old_id_copy(gcptr obj, gcptr id)
+{
+ //assert(!is_in_nursery(thread_descriptor, id));
+ assert(id->h_tid & GCFLAG_OLD);
+
+ size_t size = stmgc_size(obj);
+ memcpy(id, obj, size);
+ id->h_tid &= ~GCFLAG_HAS_ID;
+ id->h_tid |= GCFLAG_OLD;
+ dprintf(("copy_to_old_id_copy(%p -> %p)\n", obj, id));
+}
+
+/************************************************************/
+/* Each object has a h_original pointer to an old copy of
+ the same object (e.g. an old revision), the "original".
+ The memory location of this old object is used as the ID
+ for this object. If h_original is NULL *and* it is an
+ old object copy, it itself is the original. This invariant
+ must be upheld by all code dealing with h_original.
+ The original copy must never be moved again. Also, it may
+ be just a stub-object.
+
+ If we want the ID of an object which is still young,
+ we must preallocate an old shadow-original that is used
+ as the target of the young object in a minor collection.
+ In this case, we set the HAS_ID flag on the young obj
+ to notify minor_collect.
+ This flag can be lost if the young obj is stolen. Then
+ the stealing thread uses the shadow-original itself and
+ minor_collect must not overwrite it again.
+ Also, if there is already a backup-copy around, we use
+ this instead of allocating another old object to use as
+ the shadow-original.
+ */
+
+static revision_t mangle_hash(revision_t n)
+{
+ /* To hash pointers in dictionaries. Assumes that i shows some
+ alignment (to 4, 8, maybe 16 bytes), so we use the following
+ formula to avoid the trailing bits being always 0.
+ This formula is reversible: two different values of 'i' will
+ always give two different results.
+ */
+ return n ^ (((urevision_t)n) >> 4);
+}
+
+
+revision_t stm_hash(gcptr p)
+{
+ /* Prebuilt objects may have a specific hash stored in an extra
+ field. For now, we will simply always follow h_original and
+ see, if it is a prebuilt object (XXX: maybe propagate a flag
+ to all copies of a prebuilt to avoid this cache miss).
+ */
+ if (p->h_original) {
+ if (p->h_tid & GCFLAG_PREBUILT_ORIGINAL) {
+ return p->h_original;
+ }
+ gcptr orig = (gcptr)p->h_original;
+ if ((orig->h_tid & GCFLAG_PREBUILT_ORIGINAL) && orig->h_original) {
+ return orig->h_original;
+ }
+ }
+ return mangle_hash(stm_id(p));
+}
+
+
+revision_t stm_id(gcptr p)
+{
+ struct tx_descriptor *d = thread_descriptor;
+ revision_t result;
+
+ if (p->h_original) { /* fast path */
+ if (p->h_tid & GCFLAG_PREBUILT_ORIGINAL) {
+ /* h_original may contain a specific hash value,
+ but in case of the prebuilt original version,
+ its memory location is the id */
+ return (revision_t)p;
+ }
+
+ dprintf(("stm_id(%p) has orig fst: %p\n",
+ p, (gcptr)p->h_original));
+ return p->h_original;
+ }
+ else if (p->h_tid & GCFLAG_OLD) {
+ /* old objects must have an h_original xOR be
+ the original itself. */
+ dprintf(("stm_id(%p) is old, orig=0 fst: %p\n", p, p));
+ return (revision_t)p;
+ }
+
+ spinlock_acquire(d->public_descriptor->collection_lock, 'I');
+ /* old objects must have an h_original xOR be
+ the original itself.
+ if some thread stole p when it was still young,
+ it must have set h_original. stealing an old obj
+ makes the old obj "original".
+ */
+ if (p->h_original) { /* maybe now? */
+ result = p->h_original;
+ dprintf(("stm_id(%p) has orig: %p\n",
+ p, (gcptr)p->h_original));
+ }
+ else {
+ /* must create shadow original object XXX: or use
+ backup, if exists */
+
+ /* XXX use stmgcpage_malloc() directly, we don't need to copy
+ * the contents yet */
+ gcptr O = stmgc_duplicate_old(p);
+ p->h_original = (revision_t)O;
+ p->h_tid |= GCFLAG_HAS_ID;
+
+ if (p->h_tid & GCFLAG_PRIVATE_FROM_PROTECTED) {
+ gcptr B = (gcptr)p->h_revision;
+ B->h_original = (revision_t)O;
+ }
+
+ result = (revision_t)O;
+ dprintf(("stm_id(%p) young, make shadow %p\n", p, O));
+ }
+
+ spinlock_release(d->public_descriptor->collection_lock);
+ return result;
+}
+
+_Bool stm_pointer_equal(gcptr p1, gcptr p2)
+{
+ /* fast path for two equal pointers */
+ if (p1 == p2)
+ return 1;
+ /* types must be the same */
+ if ((p1->h_tid & STM_USER_TID_MASK) != (p2->h_tid & STM_USER_TID_MASK))
+ return 0;
+ return stm_id(p1) == stm_id(p2);
+}
diff --git a/c4/extra.h b/c4/extra.h
new file mode 100644
--- /dev/null
+++ b/c4/extra.h
@@ -0,0 +1,8 @@
+#ifndef _SRCSTM_EXTRA_H
+#define _SRCSTM_EXTRA_H
+
+
+void stm_copy_to_old_id_copy(gcptr obj, gcptr id);
+
+
+#endif
diff --git a/c4/nursery.c b/c4/nursery.c
--- a/c4/nursery.c
+++ b/c4/nursery.c
@@ -125,131 +125,6 @@
}
/************************************************************/
-/* Each object has a h_original pointer to an old copy of
- the same object (e.g. an old revision), the "original".
- The memory location of this old object is used as the ID
- for this object. If h_original is NULL *and* it is an
- old object copy, it itself is the original. This invariant
- must be upheld by all code dealing with h_original.
- The original copy must never be moved again. Also, it may
- be just a stub-object.
-
- If we want the ID of an object which is still young,
- we must preallocate an old shadow-original that is used
- as the target of the young object in a minor collection.
- In this case, we set the HAS_ID flag on the young obj
- to notify minor_collect.
- This flag can be lost if the young obj is stolen. Then
- the stealing thread uses the shadow-original itself and
- minor_collect must not overwrite it again.
- Also, if there is already a backup-copy around, we use
- this instead of allocating another old object to use as
- the shadow-original.
- */
-
-static revision_t mangle_hash(revision_t n)
-{
- /* To hash pointers in dictionaries. Assumes that i shows some
- alignment (to 4, 8, maybe 16 bytes), so we use the following
- formula to avoid the trailing bits being always 0.
- This formula is reversible: two different values of 'i' will
- always give two different results.
- */
- return n ^ (((urevision_t)n) >> 4);
-}
-
-
-revision_t stm_hash(gcptr p)
-{
- /* Prebuilt objects may have a specific hash stored in an extra
- field. For now, we will simply always follow h_original and
- see, if it is a prebuilt object (XXX: maybe propagate a flag
- to all copies of a prebuilt to avoid this cache miss).
- */
- if (p->h_original) {
- if (p->h_tid & GCFLAG_PREBUILT_ORIGINAL) {
- return p->h_original;
- }
- gcptr orig = (gcptr)p->h_original;
- if ((orig->h_tid & GCFLAG_PREBUILT_ORIGINAL) && orig->h_original) {
- return orig->h_original;
- }
- }
- return mangle_hash(stm_id(p));
-}
-
-
-revision_t stm_id(gcptr p)
-{
- struct tx_descriptor *d = thread_descriptor;
- revision_t result;
-
- if (p->h_original) { /* fast path */
- if (p->h_tid & GCFLAG_PREBUILT_ORIGINAL) {
- /* h_original may contain a specific hash value,
- but in case of the prebuilt original version,
- its memory location is the id */
- return (revision_t)p;
- }
-
- dprintf(("stm_id(%p) has orig fst: %p\n",
- p, (gcptr)p->h_original));
- return p->h_original;
- }
- else if (p->h_tid & GCFLAG_OLD) {
- /* old objects must have an h_original xOR be
- the original itself. */
- dprintf(("stm_id(%p) is old, orig=0 fst: %p\n", p, p));
- return (revision_t)p;
- }
-
- spinlock_acquire(d->public_descriptor->collection_lock, 'I');
- /* old objects must have an h_original xOR be
- the original itself.
- if some thread stole p when it was still young,
- it must have set h_original. stealing an old obj
- makes the old obj "original".
- */
- if (p->h_original) { /* maybe now? */
- result = p->h_original;
- dprintf(("stm_id(%p) has orig: %p\n",
- p, (gcptr)p->h_original));
- }
- else {
- /* must create shadow original object XXX: or use
- backup, if exists */
-
- /* XXX use stmgcpage_malloc() directly, we don't need to copy
- * the contents yet */
- gcptr O = stmgc_duplicate_old(p);
- p->h_original = (revision_t)O;
- p->h_tid |= GCFLAG_HAS_ID;
-
- if (p->h_tid & GCFLAG_PRIVATE_FROM_PROTECTED) {
- gcptr B = (gcptr)p->h_revision;
- B->h_original = (revision_t)O;
- }
-
- result = (revision_t)O;
- dprintf(("stm_id(%p) young, make shadow %p\n", p, O));
- }
-
- spinlock_release(d->public_descriptor->collection_lock);
- return result;
-}
-
-_Bool stm_pointer_equal(gcptr p1, gcptr p2)
-{
- /* fast path for two equal pointers */
- if (p1 == p2)
- return 1;
- /* types must be the same */
- if ((p1->h_tid & STM_USER_TID_MASK) != (p2->h_tid & STM_USER_TID_MASK))
- return 0;
- return stm_id(p1) == stm_id(p2);
-}
-
-/************************************************************/
static inline gcptr create_old_object_copy(gcptr obj)
{
@@ -266,18 +141,6 @@
return fresh_old_copy;
}
-void copy_to_old_id_copy(gcptr obj, gcptr id)
-{
- assert(!is_in_nursery(thread_descriptor, id));
- assert(id->h_tid & GCFLAG_OLD);
-
- size_t size = stmgc_size(obj);
- memcpy(id, obj, size);
- id->h_tid &= ~GCFLAG_HAS_ID;
- id->h_tid |= GCFLAG_OLD;
- dprintf(("copy_to_old_id_copy(%p -> %p)\n", obj, id));
-}
-
static void visit_if_young(gcptr *root)
{
gcptr obj = *root;
@@ -303,7 +166,7 @@
/* already has a place to go to */
gcptr id_obj = (gcptr)obj->h_original;
- copy_to_old_id_copy(obj, id_obj);
+ stm_copy_to_old_id_copy(obj, id_obj);
fresh_old_copy = id_obj;
obj->h_tid &= ~GCFLAG_HAS_ID;
}
diff --git a/c4/steal.c b/c4/steal.c
--- a/c4/steal.c
+++ b/c4/steal.c
@@ -1,8 +1,6 @@
#include "stmimpl.h"
-void copy_to_old_id_copy(gcptr obj, gcptr id);
-
gcptr stm_stub_malloc(struct tx_public_descriptor *pd)
{
assert(pd->collection_lock != 0);
@@ -167,7 +165,7 @@
/* use id-copy for us */
O = (gcptr)L->h_original;
L->h_tid &= ~GCFLAG_HAS_ID;
- copy_to_old_id_copy(L, O);
+ stm_copy_to_old_id_copy(L, O);
O->h_original = 0;
} else {
/* Copy the object out of the other thread's nursery,
diff --git a/c4/stmgc.c b/c4/stmgc.c
--- a/c4/stmgc.c
+++ b/c4/stmgc.c
@@ -9,5 +9,6 @@
#include "nursery.c"
#include "gcpage.c"
#include "stmsync.c"
+#include "extra.c"
#include "dbgmem.c"
#include "fprintcolor.c"
diff --git a/c4/stmimpl.h b/c4/stmimpl.h
--- a/c4/stmimpl.h
+++ b/c4/stmimpl.h
@@ -12,7 +12,7 @@
# endif
#endif
-#ifdef _GC_DEBUG
+#if defined(_GC_DEBUG) && !defined(DUMP_EXTRA)
# if _GC_DEBUG >= 2
# define DUMP_EXTRA
# endif
@@ -35,5 +35,6 @@
#include "et.h"
#include "steal.h"
#include "stmsync.h"
+#include "extra.h"
#endif
diff --git a/c4/test/support.py b/c4/test/support.py
--- a/c4/test/support.py
+++ b/c4/test/support.py
@@ -11,11 +11,11 @@
header_files = [os.path.join(parent_dir, _n) for _n in
"et.h lists.h steal.h nursery.h gcpage.h "
- "stmsync.h dbgmem.h fprintcolor.h "
+ "stmsync.h extra.h dbgmem.h fprintcolor.h "
"stmgc.h stmimpl.h atomic_ops.h".split()]
source_files = [os.path.join(parent_dir, _n) for _n in
"et.c lists.c steal.c nursery.c gcpage.c "
- "stmsync.c dbgmem.c fprintcolor.c".split()]
+ "stmsync.c extra.c dbgmem.c fprintcolor.c".split()]
_pycache_ = os.path.join(parent_dir, 'test', '__pycache__')
if os.path.exists(_pycache_):
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit