[pypy-commit] pypy miniscan: Check-in intermediate progress for completeness, and close this

arigo noreply at buildbot.pypy.org
Mon Feb 27 18:21:21 CET 2012


Author: Armin Rigo <arigo at tunes.org>
Branch: miniscan
Changeset: r52944:698dc6400468
Date: 2012-02-27 18:20 +0100
http://bitbucket.org/pypy/pypy/changeset/698dc6400468/

Log:	Check-in intermediate progress for completeness, and close this
	branch as abandoned.

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
@@ -1300,10 +1300,17 @@
         # then the write_barrier must have ensured that the prebuilt
         # GcStruct is in the list self.old_objects_pointing_to_young.
         debug_start("gc-minor-walkroots")
+        if self.root_walker.conservative_stack_roots:
+            self.prepare_conservative_stack_roots_minor()
+            stack_roots = MiniMarkGC.conservative_stack_roots_minor
+        else:
+            stack_roots = MiniMarkGC._trace_drag_out1
         self.root_walker.walk_roots(
-            MiniMarkGC._trace_drag_out1,  # stack roots
+            stack_roots,                  # stack roots
             MiniMarkGC._trace_drag_out1,  # static in prebuilt non-gc
             None)                         # static in prebuilt gc
+        if self.root_walker.conservative_stack_roots:
+            self.finish_conservative_stack_roots_minor()
         debug_stop("gc-minor-walkroots")
 
     def collect_cardrefs_to_nursery(self):
@@ -1708,10 +1715,17 @@
                                            self.objects_to_trace)
         #
         # Add the roots from the other sources.
+        if self.root_walker.conservative_stack_roots:
+            self.prepare_conservative_stack_roots_major()
+            stack_roots = MiniMarkGC.conservative_stack_roots_major
+        else:
+            stack_roots = MiniMarkGC._collect_ref_stk
         self.root_walker.walk_roots(
-            MiniMarkGC._collect_ref_stk, # stack roots
+            stack_roots,                 # stack roots
             MiniMarkGC._collect_ref_stk, # static in prebuilt non-gc structures
             None)   # we don't need the static in all prebuilt gc objects
+        if self.root_walker.conservative_stack_roots:
+            self.finish_conservative_stack_roots_major()
         #
         # If we are in an inner collection caused by a call to a finalizer,
         # the 'run_finalizers' objects also need to be kept alive.
@@ -2022,6 +2036,42 @@
         self.old_objects_with_weakrefs.delete()
         self.old_objects_with_weakrefs = new_with_weakref
 
+    # ----------
+    # Conservative stack scanning, for --gcrootfinder=scan
+
+    SMALL_VALUE_MAX = 4095
+
+    def prepare_conservative_stack_roots_minor(self):
+        ...
+
+    def conservative_stack_roots_minor(self, start, stop):
+        """Called during a minor collection.  Must conservatively find
+        addresses from the stack, between 'start' and 'stop', that
+        point to young objects.  These objects must be pinned down.
+        """
+        scan = start
+        while scan != stop:
+            addr = scan.address[0]       # maybe an address
+            addrint = llmemory.cast_adr_to_int(addr)
+            scan += llmemory.sizeof(llmemory.Address)
+            #
+            # A first quick check for NULLs or small positive integers
+            if r_uint(addrint) <= r_uint(self.SMALL_VALUE_MAX):
+                continue
+            #
+            # If it's not aligned to a WORD, no chance
+            if addrint & (WORD-1) != 0:
+                continue
+            #
+            # Is it in the nursery?
+            if self.is_in_nursery(addr):
+                #
+                # ././.
+            
+
+    def conservative_stack_roots_major(self, start, stop):
+        xxx
+
 
 # ____________________________________________________________
 
diff --git a/pypy/rpython/memory/gctransform/framework.py b/pypy/rpython/memory/gctransform/framework.py
--- a/pypy/rpython/memory/gctransform/framework.py
+++ b/pypy/rpython/memory/gctransform/framework.py
@@ -1341,6 +1341,7 @@
 class BaseRootWalker(object):
     need_root_stack = False
     thread_setup = None
+    conservative_stack_roots = False
 
     def __init__(self, gctransformer):
         self.gcdata = gctransformer.gcdata
diff --git a/pypy/rpython/memory/gctransform/scan.py b/pypy/rpython/memory/gctransform/scan.py
--- a/pypy/rpython/memory/gctransform/scan.py
+++ b/pypy/rpython/memory/gctransform/scan.py
@@ -35,6 +35,7 @@
 
 
 class ScanStackRootWalker(BaseRootWalker):
+    conservative_stack_roots = True
 
     def __init__(self, gctransformer):
         BaseRootWalker.__init__(self, gctransformer)
@@ -44,25 +45,50 @@
         self._asm_callback = _asm_callback
 
     #def need_stacklet_support(self, gctransformer, getfn):
-    #   anything needed?
+    #   xxx
 
     #def need_thread_support(self, gctransformer, getfn):
     #   xxx
 
-    def walk_stack_roots(self, collect_stack_root):
+    def walk_stack_roots(self, collect_stack_root_range):
         gcdata = self.gcdata
-        gcdata._gc_collect_stack_root = collect_stack_root
+        gcdata._gc_collect_stack_root_range = collect_stack_root_range
         pypy_asm_close_for_scanning(
             llhelper(ASM_CALLBACK_PTR, self._asm_callback))
 
     def walk_stack_from(self):
-        raise NotImplementedError
+        bottom = pypy_get_asm_tmp_stack_bottom()    # highest address
+        top = pypy_get_asm_stackptr()               # lowest address
+        collect_stack_root_range = self.gcdata._gc_collect_stack_root_range
+        collect_stack_root_range(self.gc, top, bottom)
 
 
 eci = ExternalCompilationInfo(
-    post_include_bits = ["extern void pypy_asm_close_for_scanning(void*);\n"],
+    post_include_bits = ['''
+extern void pypy_asm_close_for_scanning(void*);
+extern void *pypy_asm_tmp_stack_bottom;
+#define pypy_get_asm_tmp_stack_bottom()  pypy_asm_tmp_stack_bottom
+
+#if defined(__amd64__)
+#  define _pypy_get_asm_stackptr(result)  asm("movq %%rsp, %0" : "=g"(result))
+#else
+#  define _pypy_get_asm_stackptr(result)  asm("movl %%esp, %0" : "=g"(result))
+#endif
+
+static void *pypy_get_asm_stackptr(void)
+{
+    /* might return a "esp" whose value is slightly smaller than necessary,
+       due to the extra function call. */
+    void *result;
+    _pypy_get_asm_stackptr(result);
+    return result;
+}
+
+'''],
     separate_module_sources = ['''
 
+void *pypy_asm_tmp_stack_bottom = 0;    /* temporary */
+
 void pypy_asm_close_for_scanning(void *fn)
 {
     /* We have to do the call by clobbering all registers.  This is
@@ -87,3 +113,13 @@
                                               _nowrapper=True,
                                               random_effects_on_gcobjs=True,
                                               compilation_info=eci)
+pypy_get_asm_tmp_stack_bottom =rffi.llexternal('pypy_get_asm_tmp_stack_bottom',
+                                               [], llmemory.Address,
+                                               sandboxsafe=True,
+                                               _nowrapper=True,
+                                               compilation_info=eci)
+pypy_get_asm_stackptr = rffi.llexternal('pypy_get_asm_stackptr',
+                                        [], llmemory.Address,
+                                        sandboxsafe=True,
+                                        _nowrapper=True,
+                                        compilation_info=eci)
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
@@ -412,6 +412,11 @@
     def GC_KEEPALIVE(self, funcgen, v):
         return 'pypy_asm_keepalive(%s);' % funcgen.expr(v)
 
+    def OP_GC_STACK_BOTTOM(self, funcgen, op):
+        # XXX temporary
+        return ('assert(!pypy_asm_tmp_stack_bottom);   /* temporary */\n' +
+                '_pypy_get_asm_stackptr(pypy_asm_tmp_stack_bottom);' % asm)
+
     def OP_GC_RELOAD_POSSIBLY_MOVED(self, funcgen, op):
         raise Exception("should not be produced with --gcrootfinder=scan")
 
diff --git a/pypy/translator/c/test/test_scan.py b/pypy/translator/c/test/test_scan.py
--- a/pypy/translator/c/test/test_scan.py
+++ b/pypy/translator/c/test/test_scan.py
@@ -1,5 +1,6 @@
 from pypy.translator.c.test import test_newgc
 
 
-class TestMiniMarkGC(test_newgc.TestMiniMarkGC):
+class TestScanMiniMarkGC(test_newgc.TestMiniMarkGC):
+    gcpolicy = "minimark"
     gcrootfinder = "scan"


More information about the pypy-commit mailing list