[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