[pypy-svn] r80047 - in pypy/branch/out-of-line-guards/pypy/jit: backend/llgraph metainterp metainterp/test

fijal at codespeak.net fijal at codespeak.net
Tue Dec 14 07:30:22 CET 2010


Author: fijal
Date: Tue Dec 14 07:30:19 2010
New Revision: 80047

Modified:
   pypy/branch/out-of-line-guards/pypy/jit/backend/llgraph/llimpl.py
   pypy/branch/out-of-line-guards/pypy/jit/backend/llgraph/runner.py
   pypy/branch/out-of-line-guards/pypy/jit/metainterp/blackhole.py
   pypy/branch/out-of-line-guards/pypy/jit/metainterp/compile.py
   pypy/branch/out-of-line-guards/pypy/jit/metainterp/history.py
   pypy/branch/out-of-line-guards/pypy/jit/metainterp/memmgr.py
   pypy/branch/out-of-line-guards/pypy/jit/metainterp/pyjitpl.py
   pypy/branch/out-of-line-guards/pypy/jit/metainterp/test/test_basic.py
   pypy/branch/out-of-line-guards/pypy/jit/metainterp/test/test_ztranslation.py
   pypy/branch/out-of-line-guards/pypy/jit/metainterp/warmstate.py
Log:
Finish implementing out of line guards on llgraph backend. Has bugs though


Modified: pypy/branch/out-of-line-guards/pypy/jit/backend/llgraph/llimpl.py
==============================================================================
--- pypy/branch/out-of-line-guards/pypy/jit/backend/llgraph/llimpl.py	(original)
+++ pypy/branch/out-of-line-guards/pypy/jit/backend/llgraph/llimpl.py	Tue Dec 14 07:30:19 2010
@@ -164,6 +164,7 @@
 
 class CompiledLoop(object):
     has_been_freed = False
+    invalidated = False
 
     def __init__(self):
         self.inputargs = []
@@ -294,6 +295,11 @@
     assert not loop.has_been_freed
     loop.has_been_freed = True
 
+def mark_as_invalid(loop):
+    loop = _from_opaque(loop)
+    assert not loop.has_been_freed
+    loop.invalidated = True
+
 def compile_start_int_var(loop):
     return compile_start_ref_var(loop, lltype.Signed)
 
@@ -927,7 +933,10 @@
             raise GuardFailed
 
     def op_guard_not_invariant(self, descr):
-        pass
+        if self.loop.invalidated:
+            import pdb
+            pdb.set_trace()
+            raise GuardFailed
 
 class OOFrame(Frame):
 
@@ -1641,6 +1650,7 @@
 setannotation(compile_add_fail_arg, annmodel.s_None)
 setannotation(compile_redirect_fail, annmodel.s_None)
 setannotation(mark_as_free, annmodel.s_None)
+setannotation(mark_as_invalid, annmodel.s_None)
 
 setannotation(new_frame, s_Frame)
 setannotation(frame_clear, annmodel.s_None)

Modified: pypy/branch/out-of-line-guards/pypy/jit/backend/llgraph/runner.py
==============================================================================
--- pypy/branch/out-of-line-guards/pypy/jit/backend/llgraph/runner.py	(original)
+++ pypy/branch/out-of-line-guards/pypy/jit/backend/llgraph/runner.py	Tue Dec 14 07:30:19 2010
@@ -490,14 +490,18 @@
 
     def get_invalidate_asm(self, TP, fieldname):
         def invalidate_asm(arg, fieldname):
-            prev = getattr(arg, fieldname)
-            next = prev
+            import pdb
+            pdb.set_trace()
+            next = getattr(arg, fieldname)
             while next:
                 prev = next
                 x = llmemory.weakref_deref(history.LoopToken._TYPE,
                                            prev.address)
+                if x:
+                    x.invalidated = True
+                    llimpl.mark_as_invalid(
+                        x.compiled_loop_token.compiled_version)
                 next = next.next
-            XXX # write me
         return invalidate_asm
 
 class OOtypeCPU_xxx_disabled(BaseCPU):

Modified: pypy/branch/out-of-line-guards/pypy/jit/metainterp/blackhole.py
==============================================================================
--- pypy/branch/out-of-line-guards/pypy/jit/metainterp/blackhole.py	(original)
+++ pypy/branch/out-of-line-guards/pypy/jit/metainterp/blackhole.py	Tue Dec 14 07:30:19 2010
@@ -1087,9 +1087,15 @@
     bhimpl_getfield_gc_r_pure = bhimpl_getfield_gc_r
     bhimpl_getfield_gc_f_pure = bhimpl_getfield_gc_f
 
-    bhimpl_getfield_gc_i_invariant = bhimpl_getfield_gc_i
-    bhimpl_getfield_gc_r_invariant = bhimpl_getfield_gc_r
-    bhimpl_getfield_gc_f_invariant = bhimpl_getfield_gc_f
+    @arguments("cpu", "r", "d", "i", returns="i")
+    def bhimpl_getfield_gc_i_invariant(cpu, struct, fielddescr, ignored):
+        return cpu.bh_getfield_gc_i(struct, fielddescr)
+    @arguments("cpu", "r", "d", "i", returns="r")
+    def bhimpl_getfield_gc_r_invariant(cpu, struct, fielddescr, ignored):
+        return cpu.bh_getfield_gc_r(struct, fielddescr)
+    @arguments("cpu", "r", "d", "i", returns="f")
+    def bhimpl_getfield_gc_f_invariant(cpu, struct, fielddescr, ignored):
+        return cpu.bh_getfield_gc_f(struct, fielddescr)
 
     bhimpl_getfield_vable_i = bhimpl_getfield_gc_i
     bhimpl_getfield_vable_r = bhimpl_getfield_gc_r
@@ -1241,6 +1247,8 @@
             # because of GUARD_NONNULL_CLASS.
             pass
         #
+        elif opnum == rop.GUARD_NOT_INVARIANT:
+            pass
         elif (opnum == rop.GUARD_NO_EXCEPTION or
               opnum == rop.GUARD_EXCEPTION or
               opnum == rop.GUARD_NOT_FORCED):

Modified: pypy/branch/out-of-line-guards/pypy/jit/metainterp/compile.py
==============================================================================
--- pypy/branch/out-of-line-guards/pypy/jit/metainterp/compile.py	(original)
+++ pypy/branch/out-of-line-guards/pypy/jit/metainterp/compile.py	Tue Dec 14 07:30:19 2010
@@ -564,7 +564,7 @@
         # know exactly what we must do (ResumeGuardDescr/ResumeFromInterpDescr)
         prepare_last_operation(new_loop, target_loop_token)
         resumekey.compile_and_attach(metainterp, new_loop)
-        metainterp.remember_jit_invariants(target_loop_token)
+        metainterp.remember_jit_invariants(new_loop)
         record_loop_or_bridge(new_loop)
     return target_loop_token
 

Modified: pypy/branch/out-of-line-guards/pypy/jit/metainterp/history.py
==============================================================================
--- pypy/branch/out-of-line-guards/pypy/jit/metainterp/history.py	(original)
+++ pypy/branch/out-of-line-guards/pypy/jit/metainterp/history.py	Tue Dec 14 07:30:19 2010
@@ -725,7 +725,7 @@
     was compiled; but the LoopDescr remains alive and points to the
     generated assembler.
     """
-
+    # <hack> to make tests think we're dealing with an actual lltype
     _TYPE = lltype.Ptr(lltype.GcStruct('dummy struct for tests'))
 
     def _normalizedcontainer(self):
@@ -738,6 +738,7 @@
     _obj = property(_getobj)
     def _was_freed(self):
         return False
+    # </hack>
     
     terminating = False # see TerminatingLoopToken in compile.py
     outermost_jitdriver_sd = None
@@ -751,6 +752,10 @@
     # memory and the ResumeGuards.
     compiled_loop_token = None
 
+    invalidated = False
+    # if True means looptoken was invalidated by setting some field
+    # listed in jit_invariant_setfield that was read in this loop
+
     def __init__(self):
         # For memory management of assembled loops
         self._keepalive_target_looktokens = {}      # set of other LoopTokens

Modified: pypy/branch/out-of-line-guards/pypy/jit/metainterp/memmgr.py
==============================================================================
--- pypy/branch/out-of-line-guards/pypy/jit/metainterp/memmgr.py	(original)
+++ pypy/branch/out-of-line-guards/pypy/jit/metainterp/memmgr.py	Tue Dec 14 07:30:19 2010
@@ -65,7 +65,8 @@
         debug_print("Loop tokens before:", oldtotal)
         max_generation = self.current_generation - (self.max_age-1)
         for looptoken in self.alive_loops.keys():
-            if 0 <= looptoken.generation < max_generation:
+            if (looptoken.invalidated or
+                0 <= looptoken.generation < max_generation):
                 del self.alive_loops[looptoken]
         newtotal = len(self.alive_loops)
         debug_print("Loop tokens freed: ", oldtotal - newtotal)

Modified: pypy/branch/out-of-line-guards/pypy/jit/metainterp/pyjitpl.py
==============================================================================
--- pypy/branch/out-of-line-guards/pypy/jit/metainterp/pyjitpl.py	(original)
+++ pypy/branch/out-of-line-guards/pypy/jit/metainterp/pyjitpl.py	Tue Dec 14 07:30:19 2010
@@ -1,5 +1,6 @@
 import py, os, sys
 from pypy.rpython.lltypesystem import lltype, llmemory, rclass
+from pypy.rpython.annlowlevel import cast_instance_to_base_ptr
 from pypy.rlib.objectmodel import we_are_translated
 from pypy.rlib.unroll import unrolling_iterable
 from pypy.rlib.debug import debug_start, debug_stop, debug_print
@@ -2238,7 +2239,11 @@
         self.history.operations.append(op)
 
     def remember_jit_invariants(self, loop):
-        lltoken_weakref = llmemory.weakref_create(loop.token)
+        if we_are_translated():
+            looptoken = cast_instance_to_base_ptr(loop.token)
+        else:
+            looptoken = loop.token
+        lltoken_weakref = llmemory.weakref_create(looptoken)
         seen = {}
         for b_struct, c_appender in self.invariant_structs:
             if (b_struct, c_appender) not in seen:

Modified: pypy/branch/out-of-line-guards/pypy/jit/metainterp/test/test_basic.py
==============================================================================
--- pypy/branch/out-of-line-guards/pypy/jit/metainterp/test/test_basic.py	(original)
+++ pypy/branch/out-of-line-guards/pypy/jit/metainterp/test/test_basic.py	Tue Dec 14 07:30:19 2010
@@ -746,23 +746,27 @@
         a = A()
         a.x = 1
 
-        myjitdriver = JitDriver(greens = [], reds = ['i'])
+        myjitdriver = JitDriver(greens = [], reds = ['i', 'total'])
 
         @dont_look_inside
         def g(i):
             if i == 5:
-                a.x = 5
+                a.x = 2
 
         def f():
             i = 0
-            while i < 10:
-                myjitdriver.can_enter_jit(i=i)
-                myjitdriver.jit_merge_point(i=i)
+            total = 0
+            while i < 20:
+                myjitdriver.can_enter_jit(i=i, total=total)
+                myjitdriver.jit_merge_point(i=i, total=total)
                 g(i)
                 i += a.x
+                total += i
+            return total
 
-        self.meta_interp(f, [])
+        assert self.meta_interp(f, []) == f()
         self.check_loop_count(2)
+        self.check_history(getfield_gc=0, getfield_gc_pure=0)
 
     def test_setfield_bool(self):
         class A:

Modified: pypy/branch/out-of-line-guards/pypy/jit/metainterp/test/test_ztranslation.py
==============================================================================
--- pypy/branch/out-of-line-guards/pypy/jit/metainterp/test/test_ztranslation.py	(original)
+++ pypy/branch/out-of-line-guards/pypy/jit/metainterp/test/test_ztranslation.py	Tue Dec 14 07:30:19 2010
@@ -22,6 +22,7 @@
         # - jitdriver hooks
         # - two JITs
         # - string concatenation, slicing and comparison
+        # - jit-invariants
 
         class Frame(object):
             _virtualizable2_ = ['i']
@@ -44,7 +45,20 @@
                               get_jitcell_at=get_jitcell_at,
                               set_jitcell_at=set_jitcell_at,
                               get_printable_location=get_printable_location)
+
+
+        class A(object):
+            _jit_invariant_fields_ = ['x']
+
+        @dont_look_inside
+        def g(i):
+            if i == 13:
+                prebuilt_a.x = 2
+
+        prebuilt_a = A()
+
         def f(i):
+            prebuilt_a.x = 1
             for param in unroll_parameters:
                 defl = PARAMETERS[param]
                 jitdriver.set_param(param, defl)
@@ -58,7 +72,8 @@
                 total += frame.i
                 if frame.i >= 20:
                     frame.i -= 2
-                frame.i -= 1
+                g(frame.i)
+                frame.i -= prebuilt_a.x
             return total * 10
         #
         myjitdriver2 = JitDriver(greens = ['g'], reds = ['m', 'x', 's'])

Modified: pypy/branch/out-of-line-guards/pypy/jit/metainterp/warmstate.py
==============================================================================
--- pypy/branch/out-of-line-guards/pypy/jit/metainterp/warmstate.py	(original)
+++ pypy/branch/out-of-line-guards/pypy/jit/metainterp/warmstate.py	Tue Dec 14 07:30:19 2010
@@ -158,7 +158,7 @@
         if self.compiled_merge_points_wref is not None:
             for wref in self.compiled_merge_points_wref:
                 looptoken = wref()
-                if looptoken is not None:
+                if looptoken is not None and not looptoken.invalidated:
                     result.append(looptoken)
         return result
 
@@ -460,6 +460,7 @@
                         cell = lltohlhack[rtyper.type_system.deref(cellref)]
                     else:
                         cell = None
+            # </hacks>
             if not build:
                 return cell
             if cell is None:



More information about the Pypy-commit mailing list