[pypy-svn] r69714 - in pypy/branch/virtual-forcing/pypy/jit: backend/llgraph backend/test backend/x86 metainterp metainterp/test

arigo at codespeak.net arigo at codespeak.net
Fri Nov 27 22:40:47 CET 2009


Author: arigo
Date: Fri Nov 27 22:40:46 2009
New Revision: 69714

Modified:
   pypy/branch/virtual-forcing/pypy/jit/backend/llgraph/llimpl.py
   pypy/branch/virtual-forcing/pypy/jit/backend/test/runner_test.py
   pypy/branch/virtual-forcing/pypy/jit/backend/x86/runner.py
   pypy/branch/virtual-forcing/pypy/jit/metainterp/codewriter.py
   pypy/branch/virtual-forcing/pypy/jit/metainterp/compile.py
   pypy/branch/virtual-forcing/pypy/jit/metainterp/effectinfo.py
   pypy/branch/virtual-forcing/pypy/jit/metainterp/pyjitpl.py
   pypy/branch/virtual-forcing/pypy/jit/metainterp/resume.py
   pypy/branch/virtual-forcing/pypy/jit/metainterp/test/test_virtualizable.py
   pypy/branch/virtual-forcing/pypy/jit/metainterp/typesystem.py
   pypy/branch/virtual-forcing/pypy/jit/metainterp/virtualizable.py
   pypy/branch/virtual-forcing/pypy/jit/metainterp/warmstate.py
Log:
(pedronis, arigo)

Progress.  The tests pass, but the work is not done.



Modified: pypy/branch/virtual-forcing/pypy/jit/backend/llgraph/llimpl.py
==============================================================================
--- pypy/branch/virtual-forcing/pypy/jit/backend/llgraph/llimpl.py	(original)
+++ pypy/branch/virtual-forcing/pypy/jit/backend/llgraph/llimpl.py	Fri Nov 27 22:40:46 2009
@@ -401,8 +401,10 @@
         fail_args = []
         if op.fail_args:
             for fail_arg in op.fail_args:
-                if fail_arg is None or fail_arg is skip:
+                if fail_arg is None:
                     fail_args.append(None)
+                elif fail_arg is skip:
+                    fail_args.append(fail_arg.concretetype._defl())
                 else:
                     fail_args.append(self.getenv(fail_arg))
         self.fail_args = fail_args

Modified: pypy/branch/virtual-forcing/pypy/jit/backend/test/runner_test.py
==============================================================================
--- pypy/branch/virtual-forcing/pypy/jit/backend/test/runner_test.py	(original)
+++ pypy/branch/virtual-forcing/pypy/jit/backend/test/runner_test.py	Fri Nov 27 22:40:46 2009
@@ -1225,9 +1225,10 @@
         values = []
         def maybe_force(token, flag):
             if flag:
-               self.cpu.force(token)
-               values.append(self.cpu.get_latest_value_int(0))
-               values.append(self.cpu.get_latest_value_int(1))
+                descr = self.cpu.force(token)
+                values.append(descr)
+                values.append(self.cpu.get_latest_value_int(0))
+                values.append(self.cpu.get_latest_value_int(1))
 
         FUNC = self.FuncType([lltype.Signed, lltype.Signed], lltype.Void)
         func_ptr = llhelper(lltype.Ptr(FUNC), maybe_force)
@@ -1261,7 +1262,7 @@
         assert fail.identifier == 1
         assert self.cpu.get_latest_value_int(0) == 1
         assert self.cpu.get_latest_value_int(1) == 10
-        assert values == [1, 10]
+        assert values == [faildescr, 1, 10]
 
     def test_force_operations_returning_int(self):
         values = []

Modified: pypy/branch/virtual-forcing/pypy/jit/backend/x86/runner.py
==============================================================================
--- pypy/branch/virtual-forcing/pypy/jit/backend/x86/runner.py	(original)
+++ pypy/branch/virtual-forcing/pypy/jit/backend/x86/runner.py	Fri Nov 27 22:40:46 2009
@@ -106,6 +106,7 @@
         self.assembler.leave_jitted_hook()
         # end of "no gc operation!" block
         assert fail_index == fail_index_2
+        return faildescr
 
 
 class CPU386_NO_SSE2(CPU386):

Modified: pypy/branch/virtual-forcing/pypy/jit/metainterp/codewriter.py
==============================================================================
--- pypy/branch/virtual-forcing/pypy/jit/metainterp/codewriter.py	(original)
+++ pypy/branch/virtual-forcing/pypy/jit/metainterp/codewriter.py	Fri Nov 27 22:40:46 2009
@@ -1214,6 +1214,7 @@
             canraise = True  # if we need to look into the delayed ptr that is
                              # the portal, then it's certainly going to raise
         if pure:
+            assert not calldescr.effectinfo.promotes_virtualizables
             self.emit('residual_call_pure')
         elif canraise:
             self.emit('residual_call')

Modified: pypy/branch/virtual-forcing/pypy/jit/metainterp/compile.py
==============================================================================
--- pypy/branch/virtual-forcing/pypy/jit/metainterp/compile.py	(original)
+++ pypy/branch/virtual-forcing/pypy/jit/metainterp/compile.py	Fri Nov 27 22:40:46 2009
@@ -221,6 +221,7 @@
             if box:
                 fail_arg_types[i] = box.type
         self.fail_arg_types = fail_arg_types
+        # XXX ^^^ kill this attribute
 
     def handle_fail(self, metainterp_sd):
         from pypy.jit.metainterp.pyjitpl import MetaInterp
@@ -236,6 +237,17 @@
         send_bridge_to_backend(metainterp.staticdata, self, inputargs,
                                new_loop.operations)
 
+    def force_virtualizable(self, vinfo, virtualizable):
+        from pypy.jit.metainterp.pyjitpl import MetaInterp
+        from pypy.jit.metainterp.resume import force_from_resumedata
+        metainterp = MetaInterp(self.metainterp_sd)
+        metainterp.history = None    # blackholing
+        liveboxes = metainterp.load_values_from_failure(self)
+        virtualizable_boxes = force_from_resumedata(metainterp,
+                                                    liveboxes, self)
+        vinfo.write_boxes(virtualizable, virtualizable_boxes)
+
+
 class ResumeFromInterpDescr(ResumeDescr):
     def __init__(self, original_greenkey, redkey):
         ResumeDescr.__init__(self, original_greenkey)

Modified: pypy/branch/virtual-forcing/pypy/jit/metainterp/effectinfo.py
==============================================================================
--- pypy/branch/virtual-forcing/pypy/jit/metainterp/effectinfo.py	(original)
+++ pypy/branch/virtual-forcing/pypy/jit/metainterp/effectinfo.py	Fri Nov 27 22:40:46 2009
@@ -8,7 +8,7 @@
     _cache = {}
 
     def __new__(cls, write_descrs_fields, write_descrs_arrays,
-                promotes_virtualizables):
+                promotes_virtualizables=False):
         key = (frozenset(write_descrs_fields), frozenset(write_descrs_arrays),
                promotes_virtualizables)
         if key in cls._cache:

Modified: pypy/branch/virtual-forcing/pypy/jit/metainterp/pyjitpl.py
==============================================================================
--- pypy/branch/virtual-forcing/pypy/jit/metainterp/pyjitpl.py	(original)
+++ pypy/branch/virtual-forcing/pypy/jit/metainterp/pyjitpl.py	Fri Nov 27 22:40:46 2009
@@ -632,6 +632,7 @@
                 varargs = [jitcode.cfnptr] + varargs
                 res = self.execute_varargs(rop.CALL, varargs,
                                              descr=jitcode.calldescr, exc=True)
+                self.metainterp.load_fields_from_virtualizable()
             else:
                 # for oosends (ootype only): calldescr is a MethDescr
                 res = self.execute_varargs(rop.OOSEND, varargs,
@@ -651,7 +652,7 @@
 
     @arguments("descr", "varargs")
     def opimpl_residual_call(self, calldescr, varargs):
-        return self.execute_varargs(rop.CALL, varargs, descr=calldescr, exc=True)
+        return self.do_residual_call(varargs, descr=calldescr, exc=True)
 
     @arguments("varargs")
     def opimpl_recursion_leave_prep(self, varargs):
@@ -675,11 +676,11 @@
             greenkey = varargs[1:num_green_args + 1]
             if warmrunnerstate.can_inline_callable(greenkey):
                 return self.perform_call(portal_code, varargs[1:], greenkey)
-        return self.execute_varargs(rop.CALL, varargs, descr=calldescr, exc=True)
+        return self.do_residual_call(varargs, descr=calldescr, exc=True)
 
     @arguments("descr", "varargs")
     def opimpl_residual_call_noexception(self, calldescr, varargs):
-        self.execute_varargs(rop.CALL, varargs, descr=calldescr, exc=False)
+        self.do_residual_call(varargs, descr=calldescr, exc=False)
 
     @arguments("descr", "varargs")
     def opimpl_residual_call_pure(self, calldescr, varargs):
@@ -696,8 +697,8 @@
             return self.perform_call(jitcode, varargs)
         else:
             # but we should not follow calls to that graph
-            return self.execute_varargs(rop.CALL, [box] + varargs,
-                                        descr=calldescr, exc=True)
+            return self.do_residual_call([box] + varargs,
+                                         descr=calldescr, exc=True)
 
     @arguments("orgpc", "methdescr", "varargs")
     def opimpl_oosend(self, pc, methdescr, varargs):
@@ -980,6 +981,24 @@
             return self.metainterp.handle_exception()
         return False
 
+    def do_residual_call(self, argboxes, descr, exc):
+        effectinfo = descr.get_extra_info()
+        if effectinfo is None or effectinfo.promotes_virtualizables:
+            # residual calls require attention to keep virtualizables in-sync
+            self.metainterp.vable_before_residual_call()
+            # xxx do something about code duplication
+            resbox = self.metainterp.execute_and_record_varargs(
+                rop.CALL_MAY_FORCE, argboxes, descr=descr)
+            self.metainterp.vable_after_residual_call()
+            if resbox is not None:
+                self.make_result_box(resbox)
+            self.generate_guard(self.pc, rop.GUARD_NOT_FORCED, None, [])
+            if exc:
+                return self.metainterp.handle_exception()
+            return False
+        else:
+            return self.execute_varargs(rop.CALL, argboxes, descr, exc)
+
 # ____________________________________________________________
 
 class MetaInterpStaticData(object):
@@ -1298,7 +1317,8 @@
     @specialize.arg(1)
     def execute_and_record(self, opnum, descr, *argboxes):
         history.check_descr(descr)
-        assert opnum != rop.CALL and opnum != rop.OOSEND
+        assert (opnum != rop.CALL and opnum != rop.CALL_MAY_FORCE
+                and opnum != rop.OOSEND)
         # execute the operation
         profiler = self.staticdata.profiler
         profiler.count_ops(opnum)
@@ -1315,12 +1335,6 @@
     @specialize.arg(1)
     def execute_and_record_varargs(self, opnum, argboxes, descr=None):
         history.check_descr(descr)
-        # residual calls require attention to keep virtualizables in-sync.
-        # CALL_PURE doesn't need it because so far 'promote_virtualizable'
-        # as an operation is enough to make the called function non-pure.
-        is_a_call = (opnum == rop.CALL or opnum == rop.OOSEND)
-        if is_a_call:
-            self.before_residual_call()
         # execute the operation
         profiler = self.staticdata.profiler
         profiler.count_ops(opnum)
@@ -1334,8 +1348,6 @@
                 resbox = self._record_helper_pure_varargs(opnum, resbox, descr, argboxes)
             else:
                 resbox = self._record_helper_nonpure_varargs(opnum, resbox, descr, argboxes)
-        if is_a_call:
-            self.after_residual_call()
         return resbox
 
     def _record_helper_pure(self, opnum, resbox, descr, *argboxes): 
@@ -1719,9 +1731,9 @@
         vinfo = self.staticdata.virtualizable_info
         virtualizable_box = self.virtualizable_boxes[-1]
         virtualizable = vinfo.unwrap_virtualizable_box(virtualizable_box)
-        vinfo.clear_vable_rti(virtualizable)
+        vinfo.clear_vable_token(virtualizable)
 
-    def before_residual_call(self):
+    def vable_before_residual_call(self):
         if self.is_blackholing():
             return
         vinfo = self.staticdata.virtualizable_info
@@ -1729,8 +1741,14 @@
             virtualizable_box = self.virtualizable_boxes[-1]
             virtualizable = vinfo.unwrap_virtualizable_box(virtualizable_box)
             vinfo.tracing_before_residual_call(virtualizable)
+            #
+            force_token_box = history.BoxInt()
+            self.history.record(rop.FORCE_TOKEN, [], force_token_box)
+            self.history.record(rop.SETFIELD_GC, [virtualizable_box,
+                                                  force_token_box],
+                                None, descr=vinfo.vable_token_descr)
 
-    def after_residual_call(self):
+    def vable_after_residual_call(self):
         if self.is_blackholing():
             vable_escapes = True
         else:
@@ -1787,7 +1805,7 @@
             # is and stays NULL.
             virtualizable_box = self.virtualizable_boxes[-1]
             virtualizable = vinfo.unwrap_virtualizable_box(virtualizable_box)
-            assert not virtualizable.vable_rti
+            assert not virtualizable.vable_token
             self.synchronize_virtualizable()
 
     def check_synchronized_virtualizable(self):

Modified: pypy/branch/virtual-forcing/pypy/jit/metainterp/resume.py
==============================================================================
--- pypy/branch/virtual-forcing/pypy/jit/metainterp/resume.py	(original)
+++ pypy/branch/virtual-forcing/pypy/jit/metainterp/resume.py	Fri Nov 27 22:40:46 2009
@@ -455,6 +455,10 @@
     metainterp.framestack.reverse()
     return virtualizable_boxes
 
+def force_from_resumedata(metainterp, newboxes, storage):
+    resumereader = ResumeDataReader(storage, newboxes, metainterp)
+    return resumereader.consume_boxes()
+
 
 class ResumeDataReader(object):
     virtuals = None

Modified: pypy/branch/virtual-forcing/pypy/jit/metainterp/test/test_virtualizable.py
==============================================================================
--- pypy/branch/virtual-forcing/pypy/jit/metainterp/test/test_virtualizable.py	(original)
+++ pypy/branch/virtual-forcing/pypy/jit/metainterp/test/test_virtualizable.py	Fri Nov 27 22:40:46 2009
@@ -7,7 +7,6 @@
 from pypy.rlib.jit import OPTIMIZER_SIMPLE, OPTIMIZER_FULL
 from pypy.rlib.rarithmetic import intmask
 from pypy.jit.metainterp.test.test_basic import LLJitMixin, OOJitMixin
-from pypy.rpython.lltypesystem.rvirtualizable2 import VABLERTIPTR
 from pypy.rpython.rclass import FieldListAccessor
 from pypy.jit.metainterp.warmspot import get_stats, get_translator
 from pypy.jit.metainterp import history, heaptracker
@@ -41,8 +40,7 @@
     XY = lltype.GcStruct(
         'XY',
         ('parent', rclass.OBJECT),
-        ('vable_base', llmemory.Address),
-        ('vable_rti', VABLERTIPTR),
+        ('vable_token', lltype.Signed),
         ('inst_x', lltype.Signed),
         ('inst_node', lltype.Ptr(LLtypeMixin.NODE)),
         hints = {'virtualizable2_accessor': FieldListAccessor()})
@@ -57,7 +55,7 @@
 
     def setup(self):
         xy = lltype.malloc(self.XY)
-        xy.vable_rti = lltype.nullptr(VABLERTIPTR.TO)
+        xy.vable_token = 0
         xy.parent.typeptr = self.xy_vtable
         return xy
 
@@ -205,8 +203,7 @@
     XY2 = lltype.GcStruct(
         'XY2',
         ('parent', rclass.OBJECT),
-        ('vable_base', llmemory.Address),
-        ('vable_rti', VABLERTIPTR),
+        ('vable_token', lltype.Signed),
         ('inst_x', lltype.Signed),
         ('inst_l1', lltype.Ptr(lltype.GcArray(lltype.Signed))),
         ('inst_l2', lltype.Ptr(lltype.GcArray(lltype.Signed))),
@@ -219,7 +216,7 @@
 
     def setup2(self):
         xy2 = lltype.malloc(self.XY2)
-        xy2.vable_rti = lltype.nullptr(VABLERTIPTR.TO)
+        xy2.vable_token = 0
         xy2.parent.typeptr = self.xy2_vtable
         return xy2
 
@@ -392,7 +389,7 @@
 
     def setup2sub(self):
         xy2 = lltype.malloc(self.XY2SUB)
-        xy2.parent.vable_rti = lltype.nullptr(VABLERTIPTR.TO)
+        xy2.parent.vable_token = 0
         xy2.parent.parent.typeptr = self.xy2_vtable
         return xy2
 
@@ -619,8 +616,8 @@
         self.check_tree_loop_count(0)
 
     def test_external_read_sometimes(self):
-        py.test.skip("known bug: access the frame in a residual call but"
-                     " only sometimes, so that it's not seen during tracing")
+        #py.test.skip("known bug: access the frame in a residual call but"
+        #             " only sometimes, so that it's not seen during tracing")
         jitdriver = JitDriver(greens = [], reds = ['frame'],
                               virtualizables = ['frame'])
         

Modified: pypy/branch/virtual-forcing/pypy/jit/metainterp/typesystem.py
==============================================================================
--- pypy/branch/virtual-forcing/pypy/jit/metainterp/typesystem.py	(original)
+++ pypy/branch/virtual-forcing/pypy/jit/metainterp/typesystem.py	Fri Nov 27 22:40:46 2009
@@ -49,10 +49,6 @@
     CONST_NULL = history.ConstPtr(history.ConstPtr.value)
     CVAL_NULLREF = None # patched by optimizeopt.py
 
-    def get_VABLERTI(self):
-        from pypy.rpython.lltypesystem.rvirtualizable2 import VABLERTIPTR
-        return VABLERTIPTR
-
     def new_ConstRef(self, x):
         ptrval = lltype.cast_opaque_ptr(llmemory.GCREF, x)
         return history.ConstPtr(ptrval)
@@ -159,10 +155,6 @@
     loops_done_with_this_frame_ref = None # patched by compile.py
     CONST_NULL = history.ConstObj(history.ConstObj.value)
     CVAL_NULLREF = None # patched by optimizeopt.py
-
-    def get_VABLERTI(self):
-        from pypy.rpython.ootypesystem.rvirtualizable2 import VABLERTI
-        return VABLERTI
     
     def new_ConstRef(self, x):
         obj = ootype.cast_to_object(x)

Modified: pypy/branch/virtual-forcing/pypy/jit/metainterp/virtualizable.py
==============================================================================
--- pypy/branch/virtual-forcing/pypy/jit/metainterp/virtualizable.py	(original)
+++ pypy/branch/virtual-forcing/pypy/jit/metainterp/virtualizable.py	Fri Nov 27 22:40:46 2009
@@ -4,19 +4,24 @@
 from pypy.rpython import rvirtualizable2
 from pypy.rlib.objectmodel import we_are_translated
 from pypy.rlib.unroll import unrolling_iterable
+from pypy.rlib.nonconst import NonConstant
 from pypy.jit.metainterp.typesystem import deref, fieldType, arrayItem
 from pypy.jit.metainterp import history
 from pypy.jit.metainterp.warmstate import wrap, unwrap
 
 
 class VirtualizableInfo:
+    token_none    = 0
+    token_tracing = -1
+
     def __init__(self, warmrunnerdesc):
         self.warmrunnerdesc = warmrunnerdesc
         jitdriver = warmrunnerdesc.jitdriver
         cpu = warmrunnerdesc.cpu
+        if cpu.ts.name == 'ootype':
+            import py
+            py.test.skip("ootype: fix virtualizables")
         self.cpu = cpu
-        self.VABLERTI = cpu.ts.get_VABLERTI()
-        self.null_vable_rti = cpu.ts.nullptr(deref(self.VABLERTI))
         self.BoxArray = cpu.ts.BoxRef
         #
         assert len(jitdriver.virtualizables) == 1    # for now
@@ -29,6 +34,7 @@
         self.VTYPEPTR = VTYPEPTR
         self.VTYPE = VTYPE = deref(VTYPEPTR)
         self.null_vable = cpu.ts.nullptr(VTYPE)
+        self.vable_token_descr = cpu.fielddescrof(VTYPE, 'vable_token')
         #
         accessor = VTYPE._hints['virtualizable2_accessor']
         all_fields = accessor.fields
@@ -148,7 +154,7 @@
     def finish(self):
         #
         def force_if_necessary(virtualizable):
-            if virtualizable.vable_rti:
+            if virtualizable.vable_token:
                 self.force_now(virtualizable)
         force_if_necessary._always_inline_ = True
         #
@@ -169,72 +175,55 @@
     def is_vtypeptr(self, TYPE):
         return rvirtualizable2.match_virtualizable_type(TYPE, self.VTYPEPTR)
 
-    def cast_instance_to_base_ptr(self, vable_rti):
-        if we_are_translated():
-            return self.cpu.ts.cast_instance_to_base_ref(vable_rti)
-        else:
-            vable_rti._TYPE = self.VABLERTI   # hack for non-translated mode
-            return vable_rti
+    def reset_vable_token(self, virtualizable):
+        virtualizable.vable_token = self.token_none
 
-    def clear_vable_rti(self, virtualizable):
-        if virtualizable.vable_rti:
+    def clear_vable_token(self, virtualizable):
+        if virtualizable.vable_token:
             self.force_now(virtualizable)
-            assert not virtualizable.vable_rti
+            assert not virtualizable.vable_token
 
     def tracing_before_residual_call(self, virtualizable):
-        assert not virtualizable.vable_rti
-        ptr = self.cast_instance_to_base_ptr(tracing_vable_rti)
-        virtualizable.vable_rti = ptr
+        assert not virtualizable.vable_token
+        virtualizable.vable_token = self.token_tracing
 
     def tracing_after_residual_call(self, virtualizable):
-        if virtualizable.vable_rti:
+        if virtualizable.vable_token:
             # not modified by the residual call; assert that it is still
             # set to 'tracing_vable_rti' and clear it.
-            ptr = self.cast_instance_to_base_ptr(tracing_vable_rti)
-            assert virtualizable.vable_rti == ptr
-            virtualizable.vable_rti = self.null_vable_rti
+            assert virtualizable.vable_token == self.token_tracing
+            virtualizable.vable_token = self.token_none
             return False
         else:
             # marker "modified during residual call" set.
             return True
 
     def force_now(self, virtualizable):
-        rti = virtualizable.vable_rti
-        virtualizable.vable_rti = self.null_vable_rti
-        if we_are_translated():
-            rti = cast_base_ptr_to_instance(AbstractVableRti, rti)
-        rti.force_now(virtualizable)
+        token = virtualizable.vable_token
+        virtualizable.vable_token = self.token_none
+        if token == self.token_tracing:
+            # The values in the virtualizable are always correct during
+            # tracing.  We only need to reset vable_token to token_none
+            # as a marker for the tracing, to tell it that this
+            # virtualizable escapes.
+            pass
+        else:
+            faildescr = self.cpu.force(token)
+            faildescr.force_virtualizable(self, virtualizable)
     force_now._dont_inline_ = True
 
 # ____________________________________________________________
 #
-# The 'vable_rti' field of a virtualizable is either NULL or points
-# to an instance of the following classes.  It is:
+# The 'vable_token' field of a virtualizable is either 0, -1, or points
+# into the CPU stack to a particular field in the current frame.  It is:
 #
-#   1. NULL if not in the JIT at all, except as described below.
+#   1. 0 (token_none) if not in the JIT at all, except as described below.
 #
-#   2. always NULL when tracing is in progress.
+#   2. equal to 0 when tracing is in progress; except:
 #
-#   3. 'tracing_vable_rti' during tracing when we do a residual call,
+#   3. equal to -1 (token_tracing) during tracing when we do a residual call,
 #      calling random unknown other parts of the interpreter; it is
-#      reset to NULL as soon as something occurs to the virtualizable.
+#      reset to 0 as soon as something occurs to the virtualizable.
 #
-#   4. NULL for now when running the machine code with a virtualizable;
-#      later it will be a RunningVableRti().
-
-
-class AbstractVableRti(object):
-
-    def force_now(self, virtualizable):
-        raise NotImplementedError
-
-
-class TracingVableRti(AbstractVableRti):
-
-    def force_now(self, virtualizable):
-        # The values if the virtualizable are always correct during tracing.
-        # We only need to set a marker to tell that forcing occurred.
-        # As the caller resets vable_rti to NULL, it plays the role of marker.
-        pass
-
-tracing_vable_rti = TracingVableRti()
+#   4. when running the machine code with a virtualizable, it is set
+#      to the address in the CPU stack by the FORCE_TOKEN operation.

Modified: pypy/branch/virtual-forcing/pypy/jit/metainterp/warmstate.py
==============================================================================
--- pypy/branch/virtual-forcing/pypy/jit/metainterp/warmstate.py	(original)
+++ pypy/branch/virtual-forcing/pypy/jit/metainterp/warmstate.py	Fri Nov 27 22:40:46 2009
@@ -213,6 +213,8 @@
                 virtualizable = vinfo.cast_to_vtype(virtualizable)
                 assert virtualizable != globaldata.blackhole_virtualizable, (
                     "reentering same frame via blackhole")
+            else:
+                virtualizable = None
 
             # look for the cell corresponding to the current greenargs
             greenargs = args[:num_green_args]
@@ -247,6 +249,8 @@
                 fail_descr = metainterp_sd.cpu.execute_token(loop_token)
                 debug_stop("jit-running")
                 metainterp_sd.profiler.end_running()
+                if vinfo is not None:
+                    vinfo.reset_vable_token(virtualizable)
                 loop_token = fail_descr.handle_fail(metainterp_sd)
 
         maybe_compile_and_run._dont_inline_ = True



More information about the Pypy-commit mailing list