[pypy-commit] stmgc c7-refactor: Introduce GCFLAG_SMALL_UNIFORM to replace GCFLAG_CROSS_PAGE, which

arigo noreply at buildbot.pypy.org
Mon Feb 17 17:21:19 CET 2014


Author: Armin Rigo <arigo at tunes.org>
Branch: c7-refactor
Changeset: r761:1f0ca1e7fe06
Date: 2014-02-17 17:21 +0100
http://bitbucket.org/pypy/stmgc/changeset/1f0ca1e7fe06/

Log:	Introduce GCFLAG_SMALL_UNIFORM to replace GCFLAG_CROSS_PAGE, which
	cannot work because even small nursery objects may cross two pages.

diff --git a/c7/stm/core.c b/c7/stm/core.c
--- a/c7/stm/core.c
+++ b/c7/stm/core.c
@@ -28,13 +28,25 @@
     /* otherwise, we need to privatize the pages containing the object,
        if they are still SHARED_PAGE.  The common case is that there is
        only one page in total. */
-    if (UNLIKELY((obj->stm_flags & GCFLAG_CROSS_PAGE) != 0)) {
-        abort();
-        //...
+    size_t size = 0;
+    uintptr_t first_page = ((uintptr_t)obj) / 4096UL;
+    uintptr_t page_count = 1;
+
+    /* If the object is in the uniform pages of small objects (outside the
+       nursery), then it fits into one page.  Otherwise, we need to compute
+       it based on its location and size. */
+    if ((obj->stm_flags & GCFLAG_SMALL_UNIFORM) == 0) {
+
+        /* get the size of the object */
+        size = stmcb_size_rounded_up(
+            (struct object_s *)REAL_ADDRESS(STM_SEGMENT->segment_base, obj));
+
+        /* that's the page *following* the last page with the object */
+        uintptr_t end_page = (((uintptr_t)obj) + size + 4095) / 4096UL;
+
+        page_count = end_page - first_page;
     }
-    else {
-        pages_privatize(((uintptr_t)obj) / 4096UL, 1);
-    }
+    pages_privatize(first_page, page_count);
 
     /* do a read-barrier *before* the safepoints that may be issued in
        contention_management() */
diff --git a/c7/stm/core.h b/c7/stm/core.h
--- a/c7/stm/core.h
+++ b/c7/stm/core.h
@@ -35,9 +35,8 @@
        _stm_write_slowpath() is called, and then the flag is set to
        say "called once already, no need to call again". */
     GCFLAG_WRITE_BARRIER_CALLED = _STM_GCFLAG_WRITE_BARRIER_CALLED,
-    /* objects that are allocated crossing a page boundary have this
-       flag set */
-    GCFLAG_CROSS_PAGE = 0x02,
+    /* allocated by gcpage.c in uniformly-sized pages of small objects */
+    GCFLAG_SMALL_UNIFORM = 0x02,
     /* only used during collections to mark an obj as moved out of the
        generation it was in */
     GCFLAG_MOVED = 0x04,
diff --git a/c7/stm/gcpage.c b/c7/stm/gcpage.c
--- a/c7/stm/gcpage.c
+++ b/c7/stm/gcpage.c
@@ -94,8 +94,5 @@
     memset(addr, 0, size_rounded_up);
 
     stm_char* o = (stm_char *)(addr - stm_object_pages);
-    if (CROSS_PAGE_BOUNDARY(o, o + size_rounded_up))
-        ((object_t *)o)->stm_flags = GCFLAG_CROSS_PAGE;
-
     return (object_t *)o;
 }


More information about the pypy-commit mailing list