[pypy-commit] pypy miniscan: In-progress: import existing tests for using them with 'gcrootfinder=scan'.

arigo noreply at buildbot.pypy.org
Tue Feb 28 14:52:46 CET 2012


Author: Armin Rigo <arigo at tunes.org>
Branch: miniscan
Changeset: r52978:8ab8c0ea5f42
Date: 2012-02-28 14:51 +0100
http://bitbucket.org/pypy/pypy/changeset/8ab8c0ea5f42/

Log:	In-progress: import existing tests for using them with
	'gcrootfinder=scan'.

diff --git a/pypy/rpython/memory/gc/minimark.py b/pypy/rpython/memory/gc/minimark.py
--- a/pypy/rpython/memory/gc/minimark.py
+++ b/pypy/rpython/memory/gc/minimark.py
@@ -251,9 +251,12 @@
         self.nursery          = NULL
         self.nursery_next     = NULL
         self.nursery_frag_end = NULL
+        self.nursery_top      = NULL
         self.debug_tiny_nursery = -1
         self.debug_rotating_nurseries = None
         #
+        self.gcrootfinder_scan = (config.gcrootfinder == "scan")
+        #
         # The ArenaCollection() handles the nonmovable objects allocation.
         if ArenaCollectionClass is None:
             ArenaCollectionClass = minimarkpage.ArenaCollection
@@ -396,7 +399,8 @@
         # the current position in the nursery:
         self.nursery_next = self.nursery
         # the end of the nursery:
-        self.nursery_frag_end = self.nursery + self.nursery_size
+        self.nursery_top = self.nursery + self.nursery_size
+        self.nursery_frag_end = self.nursery_top
         # initialize the threshold
         self.min_heap_size = max(self.min_heap_size, self.nursery_size *
                                               self.major_collection_threshold)
@@ -559,10 +563,10 @@
             #
             # Get the memory from the nursery.  If there is not enough space
             # there, do a collect first.
-            result = self.nursery_free
-            self.nursery_free = result + totalsize
-            if self.nursery_free > self.nursery_top:
-                result = self.collect_and_reserve(totalsize)
+            result = self.nursery_next
+            self.nursery_next = result + totalsize
+            if self.nursery_next > self.nursery_frag_end:
+                result = self.pick_next_fragment(totalsize)
             #
             # Build the object.
             llarena.arena_reserve(result, totalsize)
@@ -581,8 +585,17 @@
         if gen > 0:
             self.major_collection()
 
+    def pick_next_fragment(self, totalsize):
+        """To call when nursery_next overflows nursery_frag_end.
+        Pick the next fragment of the nursery, or if there are none
+        big enough for 'totalsize', do a collection.
+        """
+        # XXX
+        return self.collect_and_reserve(totalsize)
+    pick_next_fragment._dont_inline_ = True
+
     def collect_and_reserve(self, totalsize):
-        """To call when nursery_free overflows nursery_top.
+        """To call when we have run out of nursery fragments.
         Do a minor collection, and possibly also a major collection,
         and finally reserve 'totalsize' bytes at the start of the
         now-empty nursery.
@@ -607,7 +620,6 @@
                 self.nursery_free = self.nursery_top - self.debug_tiny_nursery
         #
         return result
-    collect_and_reserve._dont_inline_ = True
 
 
     def external_malloc(self, typeid, length, can_make_young=True):
@@ -753,6 +765,7 @@
         if self.next_major_collection_threshold < 0:
             # cannot trigger a full collection now, but we can ensure
             # that one will occur very soon
+            xxx
             self.nursery_free = self.nursery_top
 
     def can_malloc_nonmovable(self):
@@ -822,7 +835,9 @@
         # have been chosen to allow 'flags' to be zero in the common
         # case (hence the 'NO' in their name).
         hdr = llmemory.cast_adr_to_ptr(addr, lltype.Ptr(self.HDR))
-        hdr.tid = self.combine(typeid16, flags | GCFLAG_HIGH)
+        if self.gcrootfinder_scan:   # don't bother setting these high
+            flags |= GCFLAG_HIGH     # bits if not "scan"
+        hdr.tid = self.combine(typeid16, flags)
 
     def init_gc_object_immortal(self, addr, typeid16, flags=0):
         # For prebuilt GC objects, the flags must contain
@@ -876,8 +891,13 @@
         if result:
             ll_assert(tid == -42, "bogus header for young obj")
         else:
-            ll_assert(bool(tid), "bogus header (1)")
-            ll_assert(tid & ~TID_MASK == 0, "bogus header (2)")
+            htid = llop.extract_ushort(llgroup.HALFWORD, tid)
+            ll_assert(bool(htid), "bogus header (1)")
+            if self.gcrootfinder_scan:
+                expected = GCFLAG_HIGH
+            else:
+                expected = 0
+            ll_assert(tid & GCFLAG_HIGH_MASK == expected, "bogus header (2)")
         return result
 
     def get_forwarding_address(self, obj):
@@ -1294,6 +1314,7 @@
         # the whole nursery with zero and reset the current nursery pointer.
         llarena.arena_reset(self.nursery, self.nursery_size, 2)
         self.debug_rotate_nursery()
+        xxx
         self.nursery_free = self.nursery
         #
         debug_print("minor collect, total memory used:",
diff --git a/pypy/rpython/memory/gcwrapper.py b/pypy/rpython/memory/gcwrapper.py
--- a/pypy/rpython/memory/gcwrapper.py
+++ b/pypy/rpython/memory/gcwrapper.py
@@ -177,6 +177,8 @@
                 if self.gcheap.gc.points_to_valid_gc_object(addrofaddr):
                     collect_static_in_prebuilt_nongc(gc, addrofaddr)
         if collect_stack_root:
+            translator = gcheap.llinterp.typer.annotator.translator
+            assert translator.config.translation.gcrootfinder != 'scan'
             for addrofaddr in gcheap.llinterp.find_roots():
                 if self.gcheap.gc.points_to_valid_gc_object(addrofaddr):
                     collect_stack_root(gc, addrofaddr)
diff --git a/pypy/rpython/memory/test/test_gc.py b/pypy/rpython/memory/test/test_gc.py
--- a/pypy/rpython/memory/test/test_gc.py
+++ b/pypy/rpython/memory/test/test_gc.py
@@ -24,6 +24,7 @@
 
 class GCTest(object):
     GC_PARAMS = {}
+    CONFIG_OPTS = {}
     GC_CAN_MOVE = False
     GC_CAN_MALLOC_NONMOVABLE = True
     GC_CAN_SHRINK_ARRAY = False
@@ -40,6 +41,7 @@
         py.log._setstate(cls._saved_logstate)
 
     def interpret(self, func, values, **kwds):
+        kwds.update(self.CONFIG_OPTS)
         interp, graph = get_interpreter(func, values, **kwds)
         gcwrapper.prepare_graphs_and_create_gc(interp, self.GCClass,
                                                self.GC_PARAMS)
@@ -921,3 +923,6 @@
 
 class TestMiniMarkGCCardMarking(TestMiniMarkGC):
     GC_PARAMS = {'card_page_indices': 4}
+
+class TestMiniMarkGCScan(TestMiniMarkGC):
+    CONFIG_OPTS = {'gcrootfinder': 'scan'}
diff --git a/pypy/translator/c/gc.py b/pypy/translator/c/gc.py
--- a/pypy/translator/c/gc.py
+++ b/pypy/translator/c/gc.py
@@ -6,7 +6,7 @@
      typeOf, Ptr, ContainerType, RttiStruct, \
      RuntimeTypeInfo, getRuntimeTypeInfo, top_container
 from pypy.rpython.memory.gctransform import \
-     refcounting, boehm, framework, asmgcroot
+     refcounting, boehm, framework, asmgcroot, scan
 from pypy.rpython.lltypesystem import lltype, llmemory
 from pypy.translator.tool.cbuild import ExternalCompilationInfo
 
@@ -403,6 +403,12 @@
     def OP_GC_STACK_BOTTOM(self, funcgen, op):
         return 'pypy_asm_stack_bottom();'
 
+class ScanFrameworkGcPolicy(FrameworkGcPolicy):
+    transformerclass = scan.ScanFrameworkGCTransformer
+
+    def GC_KEEPALIVE(self, funcgen, v):
+        return 'pypy_asm_keepalive(%s);' % funcgen.expr(v)
+
 
 name_to_gcpolicy = {
     'boehm': BoehmGcPolicy,
@@ -410,6 +416,5 @@
     'none': NoneGcPolicy,
     'framework': FrameworkGcPolicy,
     'framework+asmgcroot': AsmGcRootFrameworkGcPolicy,
+    'framework+scan': ScanFrameworkGcPolicy,
 }
-
-
diff --git a/pypy/translator/c/genc.py b/pypy/translator/c/genc.py
--- a/pypy/translator/c/genc.py
+++ b/pypy/translator/c/genc.py
@@ -193,6 +193,8 @@
             name = self.config.translation.gctransformer
             if self.config.translation.gcrootfinder == "asmgcc":
                 name = "%s+asmgcroot" % (name,)
+            if self.config.translation.gcrootfinder == "scan":
+                name = "%s+scan" % (name,)
             return gc.name_to_gcpolicy[name]
         return self.gcpolicy
 
diff --git a/pypy/translator/c/test/test_newgc.py b/pypy/translator/c/test/test_newgc.py
--- a/pypy/translator/c/test/test_newgc.py
+++ b/pypy/translator/c/test/test_newgc.py
@@ -15,6 +15,7 @@
 
 class TestUsingFramework(object):
     gcpolicy = "marksweep"
+    gcrootfinder = "shadowstack"
     should_be_moving = False
     removetypeptr = False
     taggedpointers = False
@@ -41,7 +42,8 @@
         t = Translation(main, standalone=True, gc=cls.gcpolicy,
                         policy=annpolicy.StrictAnnotatorPolicy(),
                         taggedpointers=cls.taggedpointers,
-                        gcremovetypeptr=cls.removetypeptr)
+                        gcremovetypeptr=cls.removetypeptr,
+                        gcrootfinder=cls.gcrootfinder)
         t.disable(['backendopt'])
         t.set_backend_extra_options(c_debug_defines=True)
         t.rtype()
@@ -1600,3 +1602,6 @@
 
 class TestMiniMarkGCMostCompact(TaggedPointersTest, TestMiniMarkGC):
     removetypeptr = True
+
+class TestMiniMarkGCScan(TestMiniMarkGC):
+    gcrootfinder = "scan"


More information about the pypy-commit mailing list