Author: Armin Rigo <ar...@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" _______________________________________________ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit