[pypy-svn] r65221 - in pypy/branch/pyjitpl5/pypy: config jit/backend/llgraph jit/backend/minimal jit/backend/x86 jit/backend/x86/test jit/metainterp jit/metainterp/test

arigo at codespeak.net arigo at codespeak.net
Mon May 11 18:33:12 CEST 2009


Author: arigo
Date: Mon May 11 18:33:10 2009
New Revision: 65221

Added:
   pypy/branch/pyjitpl5/pypy/jit/metainterp/gc.py   (contents, props changed)
Modified:
   pypy/branch/pyjitpl5/pypy/config/translationoption.py
   pypy/branch/pyjitpl5/pypy/jit/backend/llgraph/runner.py
   pypy/branch/pyjitpl5/pypy/jit/backend/minimal/runner.py
   pypy/branch/pyjitpl5/pypy/jit/backend/x86/TODO
   pypy/branch/pyjitpl5/pypy/jit/backend/x86/assembler.py
   pypy/branch/pyjitpl5/pypy/jit/backend/x86/runner.py
   pypy/branch/pyjitpl5/pypy/jit/backend/x86/support.py
   pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_zrpy_gc.py
   pypy/branch/pyjitpl5/pypy/jit/metainterp/codewriter.py
   pypy/branch/pyjitpl5/pypy/jit/metainterp/pyjitpl.py
   pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_basic.py
   pypy/branch/pyjitpl5/pypy/jit/metainterp/warmspot.py
Log:
Start supporting the framework GC in addition to Boehm.  Infrastructure
work only; future work is described in backend/x86/TODO.


Modified: pypy/branch/pyjitpl5/pypy/config/translationoption.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/config/translationoption.py	(original)
+++ pypy/branch/pyjitpl5/pypy/config/translationoption.py	Mon May 11 18:33:10 2009
@@ -111,9 +111,9 @@
     # JIT generation
     BoolOption("jit", "generate a JIT",
                default=False, cmdline="--jit",
-               requires=[("translation.gc", "boehm"),
-                         ("translation.list_comprehension_operations", True),
-                         ("translation.thread", False)]),
+               requires=[("translation.thread", False)],
+               suggests=[("translation.gc", "boehm"),         # for now
+                         ("translation.list_comprehension_operations", True)]),
     ChoiceOption("jit_backend", "choose the backend for the JIT",
                  ["auto", "minimal", "x86"],
                  default="auto", cmdline="--jit-backend"),

Modified: pypy/branch/pyjitpl5/pypy/jit/backend/llgraph/runner.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/backend/llgraph/runner.py	(original)
+++ pypy/branch/pyjitpl5/pypy/jit/backend/llgraph/runner.py	Mon May 11 18:33:10 2009
@@ -69,7 +69,7 @@
 class BaseCPU(model.AbstractCPU):
 
     def __init__(self, rtyper, stats=None, translate_support_code=False,
-                 annmixlevel=None):
+                 annmixlevel=None, gcdescr=None):
         self.rtyper = rtyper
         self.translate_support_code = translate_support_code
         self.stats = stats or MiniStats()

Modified: pypy/branch/pyjitpl5/pypy/jit/backend/minimal/runner.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/backend/minimal/runner.py	(original)
+++ pypy/branch/pyjitpl5/pypy/jit/backend/minimal/runner.py	Mon May 11 18:33:10 2009
@@ -30,7 +30,7 @@
 class BaseCPU(model.AbstractCPU):
 
     def __init__(self, rtyper, stats, translate_support_code=False,
-                 mixlevelann=None):
+                 mixlevelann=None, gcdescr=None):
         self.rtyper = rtyper
         if rtyper:
             if self.is_oo:

Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/TODO
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/backend/x86/TODO	(original)
+++ pypy/branch/pyjitpl5/pypy/jit/backend/x86/TODO	Mon May 11 18:33:10 2009
@@ -10,3 +10,13 @@
 * optimization of comparison followed by a guard
 
 * MC_SIZE, FRAMESIZE
+
+
+Support for non-Boehm GCs:
+
+* support calls to malloc and malloc_varsize from the generated assembler
+
+* support root stack enumeration (at first, the easiest is probably to
+  do it with asmgcc, which is good for performance :-)
+
+* support write_barriers (later; at first, we support the semispace gc only)

Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/assembler.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/backend/x86/assembler.py	(original)
+++ pypy/branch/pyjitpl5/pypy/jit/backend/x86/assembler.py	Mon May 11 18:33:10 2009
@@ -105,6 +105,7 @@
         self._exception_data = lltype.nullptr(rffi.CArray(lltype.Signed))
         self._exception_addr = 0
         self.mcstack = MachineCodeStack()
+        self.gc_malloc_fn = gc_malloc_fnaddr(cpu.gcdescr)
         
     def _get_log(self):
         s = os.environ.get('PYPYJITLOG')
@@ -144,10 +145,8 @@
                 self._exception_bck)
             self.mc = self.mcstack.next_mc()
             self.mc2 = self.mcstack.next_mc()
-            # the address of the function called by 'new': directly use
-            # Boehm's GC_malloc function.
-            if self.malloc_func_addr == 0:
-                self.malloc_func_addr = gc_malloc_fnaddr()
+            # the address of the function called by 'new'
+            self.malloc_func_addr = rffi.cast(lltype.Signed, self.gc_malloc_fn)
 
     def eventually_log_operations(self, inputargs, operations, memo=None,
                                   myid=0):

Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/runner.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/backend/x86/runner.py	(original)
+++ pypy/branch/pyjitpl5/pypy/jit/backend/x86/runner.py	Mon May 11 18:33:10 2009
@@ -72,9 +72,10 @@
     BOOTSTRAP_TP = lltype.FuncType([], lltype.Signed)
 
     def __init__(self, rtyper, stats, translate_support_code=False,
-                 mixlevelann=None):
+                 mixlevelann=None, gcdescr=None):
         self.rtyper = rtyper
         self.stats = stats
+        self.gcdescr = gcdescr
         self.translate_support_code = translate_support_code
         if translate_support_code:
             assert mixlevelann

Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/support.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/backend/x86/support.py	(original)
+++ pypy/branch/pyjitpl5/pypy/jit/backend/x86/support.py	Mon May 11 18:33:10 2009
@@ -3,15 +3,30 @@
 
 GC_MALLOC = lltype.Ptr(lltype.FuncType([lltype.Signed], llmemory.Address))
 
-compilation_info = ExternalCompilationInfo(libraries=['gc'])
 
-malloc_fn_ptr = rffi.llexternal("GC_malloc",
-                                [lltype.Signed], # size_t, but good enough
-                                llmemory.Address,
-                                compilation_info=compilation_info,
-                                sandboxsafe=True,
-                                _nowrapper=True)
-
-def gc_malloc_fnaddr():
-    """Returns the address of the Boehm 'malloc' function."""
-    return rffi.cast(lltype.Signed, malloc_fn_ptr)
+def gc_malloc__boehm(gcdescr):
+    """Returns a pointer to the Boehm 'malloc' function."""
+    compilation_info = ExternalCompilationInfo(libraries=['gc'])
+    malloc_fn_ptr = rffi.llexternal("GC_malloc",
+                                    [lltype.Signed], # size_t, but good enough
+                                    llmemory.Address,
+                                    compilation_info=compilation_info,
+                                    sandboxsafe=True,
+                                    _nowrapper=True)
+    return malloc_fn_ptr
+
+
+def gc_malloc__framework(gcdescr):
+    """Returns a pointer to the framework 'malloc' function."""
+    return 0       # XXX write me!
+
+
+def gc_malloc_fnaddr(gcdescr):
+    """Returns a pointer to the proper 'malloc' function."""
+    name = gcdescr.config.translation.gctransformer
+    try:
+        func = globals()['gc_malloc__' + name]
+    except KeyError:
+        raise NotImplementedError("GC transformer %r not supported by "
+                                  "the x86 backend" % (name,))
+    return func(gcdescr)

Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_zrpy_gc.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_zrpy_gc.py	(original)
+++ pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_zrpy_gc.py	Mon May 11 18:33:10 2009
@@ -33,19 +33,30 @@
 g._dont_inline_ = True
 
 def f(args):
-    r = g(3000)
-    rgc.collect(); rgc.collect(); rgc.collect()
-    print int(r() is None)
+    r_list = []
+    for i in range(20):
+        r = g(1000)
+        r_list.append(r)
+        rgc.collect()
+    rgc.collect(); rgc.collect()
+    freed = 0
+    for r in r_list:
+        if r() is None:
+            freed += 1
+    print freed
     return 0
 
 
-def test_compile():
+def compile_and_run(gc, **kwds):
     from pypy.translator.translator import TranslationContext
     from pypy.jit.metainterp.warmspot import apply_jit
     from pypy.translator.c import genc
     #
     t = TranslationContext()
-    t.config.translation.jit = True    # forces other options as well
+    t.config.translation.gc = gc
+    t.config.translation.jit = True
+    for name, value in kwds.items():
+        setattr(t.config.translation, name, value)
     t.buildannotator().build_types(f, [int])
     t.buildrtyper().specialize()
     apply_jit(t, CPUClass=CPU386)
@@ -54,4 +65,16 @@
     cbuilder.compile()
     #
     data = cbuilder.cmdexec('')
-    assert int(data.strip()) == 1
+    res = int(data.strip())
+    if gc == "boehm":
+        assert res >= 16
+    else:
+        assert res == 20
+
+
+def test_compile_boehm():
+    compile_and_run("boehm")
+
+def test_compile_semispace():
+    # a moving GC, but with no write barrier
+    compile_and_run("semispace", gcrootfinder="asmgcc")

Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/codewriter.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/metainterp/codewriter.py	(original)
+++ pypy/branch/pyjitpl5/pypy/jit/metainterp/codewriter.py	Mon May 11 18:33:10 2009
@@ -735,7 +735,10 @@
         self.register_var(op.result)
 
     def serialize_op_zero_gc_pointers_inside(self, op):
-        pass   # XXX assume Boehm for now
+        # XXX this is always a no-op for now
+        warmrunnerdesc = self.codewriter.metainterp_sd.warmrunnerdesc
+        if warmrunnerdesc is not None:
+            assert warmrunnerdesc.gcdescr.malloc_zero_filled
 
     def serialize_op_getfield(self, op):
         if self.is_typeptr_getset(op):

Added: pypy/branch/pyjitpl5/pypy/jit/metainterp/gc.py
==============================================================================
--- (empty file)
+++ pypy/branch/pyjitpl5/pypy/jit/metainterp/gc.py	Mon May 11 18:33:10 2009
@@ -0,0 +1,42 @@
+
+
+class GcDescription:
+    def __init__(self, config):
+        self.config = config
+
+
+class GC_boehm(GcDescription):
+    malloc_zero_filled = True
+
+class GC_semispace(GcDescription):
+    malloc_zero_filled = True
+
+
+def get_description(config):
+    name = config.translation.gc
+    try:
+        cls = globals()['GC_' + name]
+    except KeyError:
+        raise NotImplementedError('GC %r not supported by the JIT' % (name,))
+    return cls(config)
+
+
+class GcDescription:
+    def __init__(self, config):
+        self.config = config
+
+
+class GC_boehm(GcDescription):
+    malloc_zero_filled = True
+
+class GC_semispace(GcDescription):
+    malloc_zero_filled = True
+
+
+def get_description(config):
+    name = config.translation.gc
+    try:
+        cls = globals()['GC_' + name]
+    except KeyError:
+        raise NotImplementedError('GC %r not supported by the JIT' % (name,))
+    return cls(config)

Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/pyjitpl.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/metainterp/pyjitpl.py	(original)
+++ pypy/branch/pyjitpl5/pypy/jit/metainterp/pyjitpl.py	Mon May 11 18:33:10 2009
@@ -867,7 +867,6 @@
 # ____________________________________________________________
 
 class MetaInterpStaticData(object):
-    num_green_args = 0
 
     def __init__(self, portal_graph, graphs, cpu, stats, options,
                  optimizer=None, profile=None):
@@ -909,9 +908,14 @@
     def _freeze_(self):
         return True
 
-    def finish_setup(self, num_green_args, state):
-        self.num_green_args = num_green_args
-        self.state = state
+    def finish_setup(self, warmrunnerdesc):
+        self.warmrunnerdesc = warmrunnerdesc
+        if warmrunnerdesc is not None:
+            self.num_green_args = warmrunnerdesc.num_green_args
+            self.state = warmrunnerdesc.state
+        else:
+            self.num_green_args = 0
+            self.state = None
         self.globaldata = MetaInterpGlobalData(self)
 
     def _setup_once(self):

Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_basic.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_basic.py	(original)
+++ pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_basic.py	Mon May 11 18:33:10 2009
@@ -24,7 +24,7 @@
     graph = rtyper.annotator.translator.graphs[0]
     opt = history.Options(specialize=False, listops=listops)
     metainterp_sd = pyjitpl.MetaInterpStaticData(graph, [], cpu, stats, opt)
-    metainterp_sd.finish_setup(0, None)
+    metainterp_sd.finish_setup(None)
     metainterp = pyjitpl.MetaInterp(metainterp_sd)
     return metainterp, rtyper
 
@@ -523,6 +523,7 @@
                                         inline_threshold=0, type_system=self.type_system)
         clear_tcache()
         translator = interp.typer.annotator.translator
+        translator.config.translation.gc = "boehm"
         warmrunnerdesc = WarmRunnerDesc(translator,
                                         CPUClass=self.CPUClass,
                                         optimizer=SimpleOptimizer)

Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/warmspot.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/metainterp/warmspot.py	(original)
+++ pypy/branch/pyjitpl5/pypy/jit/metainterp/warmspot.py	Mon May 11 18:33:10 2009
@@ -17,7 +17,7 @@
 from pypy.translator.simplify import get_funcobj, get_functype
 from pypy.translator.unsimplify import call_final_function
 
-from pypy.jit.metainterp import support, history, pyjitpl
+from pypy.jit.metainterp import support, history, pyjitpl, gc
 from pypy.jit.metainterp.pyjitpl import MetaInterpStaticData, MetaInterp
 from pypy.jit.metainterp.policy import JitPolicy
 from pypy.jit.metainterp.typesystem import LLTypeHelper, OOTypeHelper
@@ -56,6 +56,7 @@
 
 def jittify_and_run(interp, graph, args, repeat=1, hash_bits=None, **kwds):
     translator = interp.typer.annotator.translator
+    translator.config.translation.gc = "boehm"
     warmrunnerdesc = WarmRunnerDesc(translator, **kwds)
     warmrunnerdesc.state.set_param_threshold(3)          # for tests
     warmrunnerdesc.state.set_param_trace_eagerness(2)    # for tests
@@ -133,7 +134,7 @@
         self.make_enter_function()
         self.rewrite_can_enter_jit()
         self.add_profiler_finish()
-        self.metainterp_sd.finish_setup(self.num_green_args, self.state)
+        self.metainterp_sd.finish_setup(self)
 
     def finish(self):
         if self.cpu.translate_support_code:
@@ -149,6 +150,7 @@
         else:
             assert translator.rtyper.type_system.name == 'ootypesystem'
             self.ts = OOTypeHelper()
+        self.gcdescr = gc.get_description(translator.config)
 
     def build_meta_interp(self, CPUClass=None, view="auto",
                           translate_support_code=False, optimizer=None,
@@ -162,7 +164,7 @@
         else:
             annhelper = None
         cpu = CPUClass(self.translator.rtyper, self.stats,
-                       translate_support_code, annhelper)
+                       translate_support_code, annhelper, self.gcdescr)
         self.cpu = cpu
         graphs = self.translator.graphs
         self.jit_merge_point_pos = find_jit_merge_point(graphs)



More information about the Pypy-commit mailing list