[pypy-commit] pypy continulet-jit-3: in-progress: simplify the JITFRAME and change the goal to be initially

arigo noreply at buildbot.pypy.org
Sat Sep 29 06:00:34 CEST 2012


Author: Armin Rigo <arigo at tunes.org>
Branch: continulet-jit-3
Changeset: r57651:50963e97c8bb
Date: 2012-09-28 22:58 +0200
http://bitbucket.org/pypy/pypy/changeset/50963e97c8bb/

Log:	in-progress: simplify the JITFRAME and change the goal to be
	initially just a removal of global data. Fix fix fix fix fix.

diff --git a/pypy/jit/backend/llgraph/llimpl.py b/pypy/jit/backend/llgraph/llimpl.py
--- a/pypy/jit/backend/llgraph/llimpl.py
+++ b/pypy/jit/backend/llgraph/llimpl.py
@@ -1053,23 +1053,24 @@
                 vable = lltype.nullptr(llmemory.GCREF.TO)
             #
             # Emulate the fast path
-            failindex = self.cpu.get_latest_descr(subframe)
+            failindex = frame_descr_index(subframe)
             if failindex == self.cpu.done_with_this_frame_int_v:
                 reset_vable(jd, vable)
-                return self.cpu.get_latest_value_int(0)
+                return self.cpu.get_latest_value_int(subframe, 0)
             if failindex == self.cpu.done_with_this_frame_ref_v:
                 reset_vable(jd, vable)
-                return self.cpu.get_latest_value_ref(0)
+                return self.cpu.get_latest_value_ref(subframe, 0)
             if failindex == self.cpu.done_with_this_frame_float_v:
                 reset_vable(jd, vable)
-                return self.cpu.get_latest_value_float(0)
+                return self.cpu.get_latest_value_float(subframe, 0)
             if failindex == self.cpu.done_with_this_frame_void_v:
                 reset_vable(jd, vable)
                 return None
             #
             assembler_helper_ptr = jd.assembler_helper_adr.ptr  # fish
+            assembler_helper = assembler_helper_ptr._obj._callable
             try:
-                return assembler_helper_ptr(failindex, vable)
+                return assembler_helper(subframe, vable)
             except LLException, lle:
                 assert self._last_exception is None, "exception left behind"
                 self._last_exception = lle
diff --git a/pypy/jit/backend/model.py b/pypy/jit/backend/model.py
--- a/pypy/jit/backend/model.py
+++ b/pypy/jit/backend/model.py
@@ -1,5 +1,7 @@
 from pypy.rlib.debug import debug_start, debug_print, debug_stop
+from pypy.rlib.rarithmetic import intmask
 from pypy.jit.metainterp import history
+from pypy.jit.codewriter.longlong import longlong2floatstorage
 from pypy.rpython.lltypesystem import lltype
 
 
@@ -125,37 +127,37 @@
     def get_latest_descr(self, jitframe):
         """Return the descr of the last operation executed by the
         jitframe."""
-        raise NotImplementedError
+        return jitframe.jf_descr
 
     def get_latest_value_int(self, jitframe, index):
         """Returns the value for the index'th argument to the
         last executed operation (from 'fail_args' if it was a guard,
         or from 'args' if it was a FINISH).  Returns an int."""
-        raise NotImplementedError
+        return intmask(jitframe.jf_nongcvalues[index])
 
     def get_latest_value_float(self, jitframe, index):
         """Returns the value for the index'th argument to the
         last executed operation (from 'fail_args' if it was a guard,
-        or from 'args' if it was a FINISH).  Returns a float."""
-        raise NotImplementedError
+        or from 'args' if it was a FINISH).  Returns a FLOATSTORAGE."""
+        return longlong2floatstorage(jitframe.jf_nongcvalues[index])
 
     def get_latest_value_ref(self, jitframe, index):
         """Returns the value for the index'th argument to the
         last executed operation (from 'fail_args' if it was a guard,
-        or from 'args' if it was a FINISH).  Returns a ptr or an obj."""
-        raise NotImplementedError
+        or from 'args' if it was a FINISH).  Returns a GCREF."""
+        return jitframe.jf_gcvalues[index]
 
     def get_latest_value_count(self, jitframe):
         """Return how many values are ready to be returned by
         get_latest_value_xxx().  Only after a guard failure; not
         necessarily correct after a FINISH."""
-        raise NotImplementedError
+        return len(jitframe.jf_gcvalues)
 
     def grab_exc_value(self, jitframe):
         """Return and clear the exception set by the latest execute_token(),
         when it exits due to a failure of a GUARD_EXCEPTION or
         GUARD_NO_EXCEPTION.  (Returns a GCREF)"""        # XXX remove me
-        raise NotImplementedError
+        return jitframe.jf_excvalue
 
     def redirect_call_assembler(self, oldlooptoken, newlooptoken):
         """Redirect oldlooptoken to newlooptoken.  More precisely, it is
diff --git a/pypy/jit/backend/test/runner_test.py b/pypy/jit/backend/test/runner_test.py
--- a/pypy/jit/backend/test/runner_test.py
+++ b/pypy/jit/backend/test/runner_test.py
@@ -2716,13 +2716,16 @@
         lltype.free(x, flavor='raw')
 
     def test_assembler_call(self):
+        from pypy.jit.metainterp.jitframe import JITFRAMEPTR
         called = []
-        def assembler_helper(failindex, virtualizable):
-            assert self.cpu.get_latest_value_int(frame, 0) == 97
+        def assembler_helper(jitframe, virtualizable):
+            assert self.cpu.get_latest_value_int(jitframe, 0) == 97
+            faildescr =self.cpu.get_latest_descr(jitframe)
+            failindex = self.cpu.get_fail_descr_number(faildescr)
             called.append(failindex)
             return 4 + 9
 
-        FUNCPTR = lltype.Ptr(lltype.FuncType([lltype.Signed, llmemory.GCREF],
+        FUNCPTR = lltype.Ptr(lltype.FuncType([JITFRAMEPTR, llmemory.GCREF],
                                              lltype.Signed))
         class FakeJitDriverSD:
             index_of_virtualizable = -1
@@ -2787,16 +2790,19 @@
             del self.cpu.done_with_this_frame_int_v
 
     def test_assembler_call_float(self):
+        from pypy.jit.metainterp.jitframe import JITFRAMEPTR
         if not self.cpu.supports_floats:
             py.test.skip("requires floats")
         called = []
-        def assembler_helper(failindex, virtualizable):
-            x = self.cpu.get_latest_value_float(frame, 0)
+        def assembler_helper(jitframe, virtualizable):
+            x = self.cpu.get_latest_value_float(jitframe, 0)
             assert longlong.getrealfloat(x) == 1.2 + 3.2
+            faildescr =self.cpu.get_latest_descr(jitframe)
+            failindex = self.cpu.get_fail_descr_number(faildescr)
             called.append(failindex)
             return 13.5
 
-        FUNCPTR = lltype.Ptr(lltype.FuncType([lltype.Signed, llmemory.GCREF],
+        FUNCPTR = lltype.Ptr(lltype.FuncType([JITFRAMEPTR, llmemory.GCREF],
                                              lltype.Float))
         class FakeJitDriverSD:
             index_of_virtualizable = -1
@@ -2881,16 +2887,19 @@
         lltype.free(a, flavor='raw')
 
     def test_redirect_call_assembler(self):
+        from pypy.jit.metainterp.jitframe import JITFRAMEPTR
         if not self.cpu.supports_floats:
             py.test.skip("requires floats")
         called = []
-        def assembler_helper(failindex, virtualizable):
-            x = self.cpu.get_latest_value_float(frame, 0)
+        def assembler_helper(jitframe, virtualizable):
+            x = self.cpu.get_latest_value_float(jitframe, 0)
             assert longlong.getrealfloat(x) == 1.25 + 3.25
+            faildescr =self.cpu.get_latest_descr(jitframe)
+            failindex = self.cpu.get_fail_descr_number(faildescr)
             called.append(failindex)
             return 13.5
 
-        FUNCPTR = lltype.Ptr(lltype.FuncType([lltype.Signed, llmemory.GCREF],
+        FUNCPTR = lltype.Ptr(lltype.FuncType([JITFRAMEPTR, llmemory.GCREF],
                                              lltype.Float))
         class FakeJitDriverSD:
             index_of_virtualizable = -1
diff --git a/pypy/jit/codewriter/longlong.py b/pypy/jit/codewriter/longlong.py
--- a/pypy/jit/codewriter/longlong.py
+++ b/pypy/jit/codewriter/longlong.py
@@ -26,6 +26,7 @@
     getrealfloat    = lambda x: x
     gethash         = compute_hash
     is_longlong     = lambda TYPE: False
+    longlong2floatstorage = longlong2float.longlong2float
 
     # -------------------------------------
 else:
@@ -42,6 +43,7 @@
     gethash         = lambda xll: rarithmetic.intmask(xll - (xll >> 32))
     is_longlong     = lambda TYPE: (TYPE is lltype.SignedLongLong or
                                     TYPE is lltype.UnsignedLongLong)
+    longlong2floatstorage = lambda x: x
 
     # -------------------------------------
 
diff --git a/pypy/jit/metainterp/blackhole.py b/pypy/jit/metainterp/blackhole.py
--- a/pypy/jit/metainterp/blackhole.py
+++ b/pypy/jit/metainterp/blackhole.py
@@ -1546,13 +1546,14 @@
     # We will continue to loop in _run_forever() from the parent level.
     return blackholeinterp, lle
 
-def resume_in_blackhole(metainterp_sd, jitdriver_sd, resumedescr,
+def resume_in_blackhole(metainterp_sd, jitdriver_sd, jitframe, resumedescr,
                         all_virtuals=None):
     from pypy.jit.metainterp.resume import blackhole_from_resumedata
     #debug_start('jit-blackhole')
     blackholeinterp = blackhole_from_resumedata(
         metainterp_sd.blackholeinterpbuilder,
         jitdriver_sd,
+        jitframe,
         resumedescr,
         all_virtuals)
     if isinstance(resumedescr, ResumeAtPositionDescr):
diff --git a/pypy/jit/metainterp/compile.py b/pypy/jit/metainterp/compile.py
--- a/pypy/jit/metainterp/compile.py
+++ b/pypy/jit/metainterp/compile.py
@@ -407,35 +407,33 @@
     pass
 
 class DoneWithThisFrameDescrVoid(_DoneWithThisFrameDescr):
-    def handle_fail(self, metainterp_sd, jitdriver_sd):
+    def handle_fail(self, metainterp_sd, jitdriver_sd, jitframe):
         assert jitdriver_sd.result_type == history.VOID
         raise metainterp_sd.DoneWithThisFrameVoid()
 
 class DoneWithThisFrameDescrInt(_DoneWithThisFrameDescr):
-    def handle_fail(self, metainterp_sd, jitdriver_sd):
+    def handle_fail(self, metainterp_sd, jitdriver_sd, jitframe):
         assert jitdriver_sd.result_type == history.INT
-        result = metainterp_sd.cpu.get_latest_value_int(0)
+        result = metainterp_sd.cpu.get_latest_value_int(jitframe, 0)
         raise metainterp_sd.DoneWithThisFrameInt(result)
 
 class DoneWithThisFrameDescrRef(_DoneWithThisFrameDescr):
-    def handle_fail(self, metainterp_sd, jitdriver_sd):
+    def handle_fail(self, metainterp_sd, jitdriver_sd, jitframe):
         assert jitdriver_sd.result_type == history.REF
         cpu = metainterp_sd.cpu
-        result = cpu.get_latest_value_ref(0)
-        cpu.clear_latest_values(1)
+        result = cpu.get_latest_value_ref(jitframe, 0)
         raise metainterp_sd.DoneWithThisFrameRef(cpu, result)
 
 class DoneWithThisFrameDescrFloat(_DoneWithThisFrameDescr):
-    def handle_fail(self, metainterp_sd, jitdriver_sd):
+    def handle_fail(self, metainterp_sd, jitdriver_sd, jitframe):
         assert jitdriver_sd.result_type == history.FLOAT
-        result = metainterp_sd.cpu.get_latest_value_float(0)
+        result = metainterp_sd.cpu.get_latest_value_float(jitframe, 0)
         raise metainterp_sd.DoneWithThisFrameFloat(result)
 
 class ExitFrameWithExceptionDescrRef(_DoneWithThisFrameDescr):
-    def handle_fail(self, metainterp_sd, jitdriver_sd):
+    def handle_fail(self, metainterp_sd, jitdriver_sd, jitframe):
         cpu = metainterp_sd.cpu
-        value = cpu.get_latest_value_ref(0)
-        cpu.clear_latest_values(1)
+        value = cpu.get_latest_value_ref(jitframe, 0)
         raise metainterp_sd.ExitFrameWithExceptionRef(cpu, value)
 
 
@@ -518,30 +516,32 @@
             assert cnt > self.CNT_BASE_MASK
             self._counter = cnt | i
 
-    def handle_fail(self, metainterp_sd, jitdriver_sd):
-        if self.must_compile(metainterp_sd, jitdriver_sd):
+    def handle_fail(self, metainterp_sd, jitdriver_sd, jitframe):
+        if self.must_compile(metainterp_sd, jitdriver_sd, jitframe):
             self.start_compiling()
             try:
                 self._trace_and_compile_from_bridge(metainterp_sd,
-                                                    jitdriver_sd)
+                                                    jitdriver_sd,
+                                                    jitframe)
             finally:
                 self.done_compiling()
         else:
             from pypy.jit.metainterp.blackhole import resume_in_blackhole
-            resume_in_blackhole(metainterp_sd, jitdriver_sd, self)
+            resume_in_blackhole(metainterp_sd, jitdriver_sd, jitframe, self)
         assert 0, "unreachable"
 
-    def _trace_and_compile_from_bridge(self, metainterp_sd, jitdriver_sd):
+    def _trace_and_compile_from_bridge(self, metainterp_sd, jitdriver_sd,
+                                       jitframe):
         # 'jitdriver_sd' corresponds to the outermost one, i.e. the one
         # of the jit_merge_point where we started the loop, even if the
         # loop itself may contain temporarily recursion into other
         # jitdrivers.
         from pypy.jit.metainterp.pyjitpl import MetaInterp
         metainterp = MetaInterp(metainterp_sd, jitdriver_sd)
-        metainterp.handle_guard_failure(self)
+        metainterp.handle_guard_failure(jitframe, self)
     _trace_and_compile_from_bridge._dont_inline_ = True
 
-    def must_compile(self, metainterp_sd, jitdriver_sd):
+    def must_compile(self, metainterp_sd, jitdriver_sd, jitframe):
         trace_eagerness = jitdriver_sd.warmstate.trace_eagerness
         #
         if self._counter <= self.CNT_BASE_MASK:
@@ -561,21 +561,24 @@
             typetag = self._counter & self.CNT_TYPE_MASK
             counters = self._counters
             if typetag == self.CNT_INT:
-                intvalue = metainterp_sd.cpu.get_latest_value_int(index)
+                intvalue = metainterp_sd.cpu.get_latest_value_int(jitframe,
+                                                                  index)
                 if counters is None:
                     self._counters = counters = ResumeGuardCountersInt()
                 else:
                     assert isinstance(counters, ResumeGuardCountersInt)
                 counter = counters.see_int(intvalue)
             elif typetag == self.CNT_REF:
-                refvalue = metainterp_sd.cpu.get_latest_value_ref(index)
+                refvalue = metainterp_sd.cpu.get_latest_value_ref(jitframe,
+                                                                  index)
                 if counters is None:
                     self._counters = counters = ResumeGuardCountersRef()
                 else:
                     assert isinstance(counters, ResumeGuardCountersRef)
                 counter = counters.see_ref(refvalue)
             elif typetag == self.CNT_FLOAT:
-                floatvalue = metainterp_sd.cpu.get_latest_value_float(index)
+                floatvalue = metainterp_sd.cpu.get_latest_value_float(jitframe,
+                                                                      index)
                 if counters is None:
                     self._counters = counters = ResumeGuardCountersFloat()
                 else:
@@ -644,7 +647,7 @@
         self.metainterp_sd = metainterp_sd
         self.jitdriver_sd = jitdriver_sd
 
-    def handle_fail(self, metainterp_sd, jitdriver_sd):
+    def handle_fail(self, metainterp_sd, jitdriver_sd, jitframe):
         # Failures of a GUARD_NOT_FORCED are never compiled, but
         # always just blackholed.  First fish for the data saved when
         # the virtualrefs and virtualizable have been forced by
@@ -850,9 +853,9 @@
 # ____________________________________________________________
 
 class PropagateExceptionDescr(AbstractFailDescr):
-    def handle_fail(self, metainterp_sd, jitdriver_sd):
+    def handle_fail(self, metainterp_sd, jitdriver_sd, jitframe):
         cpu = metainterp_sd.cpu
-        exception = cpu.grab_exc_value()
+        exception = cpu.grab_exc_value(jitframe)
         assert exception, "PropagateExceptionDescr: no exception??"
         raise metainterp_sd.ExitFrameWithExceptionRef(cpu, exception)
 
diff --git a/pypy/jit/metainterp/history.py b/pypy/jit/metainterp/history.py
--- a/pypy/jit/metainterp/history.py
+++ b/pypy/jit/metainterp/history.py
@@ -154,7 +154,7 @@
 class AbstractFailDescr(AbstractDescr):
     index = -1
 
-    def handle_fail(self, metainterp_sd, jitdriver_sd):
+    def handle_fail(self, metainterp_sd, jitdriver_sd, jitframe):
         raise NotImplementedError
     def compile_and_attach(self, metainterp, new_loop):
         raise NotImplementedError
diff --git a/pypy/jit/metainterp/jitframe.py b/pypy/jit/metainterp/jitframe.py
--- a/pypy/jit/metainterp/jitframe.py
+++ b/pypy/jit/metainterp/jitframe.py
@@ -3,12 +3,13 @@
 from pypy.rpython.lltypesystem.rvirtualizable2 import JITFRAMEPTR
 
 
-GCINDEXLIST = lltype.GcArray(rffi.USHORT)
+_LONGLONGARRAY = lltype.GcArray(lltype.SignedLongLong)
 
 JITFRAME = lltype.GcStruct('JITFRAME',
-                           ('gcindexlist', lltype.Ptr(GCINDEXLIST)),
-                           ('items', lltype.Array(llmemory.Address)),
-                           rtti=True)
+               ('jf_descr', llmemory.GCREF),
+               ('jf_excvalue', llmemory.GCREF),
+               ('jf_nongcvalues', lltype.Ptr(_LONGLONGARRAY)),
+               ('jf_gcvalues', lltype.Array(llmemory.GCREF)))
 JITFRAMEPTR.TO.become(JITFRAME)
 
 # Constants used for the 'jit_frame' field of virtualizables/virtualrefs:
@@ -28,34 +29,3 @@
 #
 TOKEN_NONE            = lltype.nullptr(JITFRAME)
 TOKEN_TRACING_RESCALL = lltype.malloc(JITFRAME, 0, immortal=True, zero=True)
-
-# ____________________________________________________________
-
-FRAME_ITERATOR = lltype.GcStruct('FRAME_ITERATOR',
-                                 ('remaining_indices', lltype.Signed))
-frame_iterator = lltype.malloc(FRAME_ITERATOR, immortal=True)
-
-GCINDEXLIST_OFS = llmemory.offsetof(JITFRAME, 'gcindexlist')
-ITEMS_BASE_OFS = (llmemory.offsetof(JITFRAME, 'items') +
-                  llmemory.itemoffsetof(JITFRAME.items))
-SIZE_OF_ADDR = llmemory.sizeof(llmemory.Address)
-
-def customtrace(obj, prev):
-    gcindexlist = llmemory.cast_adr_to_ptr(obj, JITFRAMEPTR).gcindexlist
-    if not prev:
-        # return first the address of the 'gcindexlist' field
-        frame_iterator.remaining_indices = len(gcindexlist)
-        return obj + GCINDEXLIST_OFS
-    elif frame_iterator.remaining_indices > 0:
-        # return next the addresses of '.items[n]', for n in gcindexlist
-        frame_iterator.remaining_indices -= 1
-        n = gcindexlist[frame_iterator.remaining_indices]
-        n = lltype.cast_primitive(lltype.Signed, n)
-        return obj + ITEMS_BASE_OFS + n * SIZE_OF_ADDR
-    else:
-        return llmemory.NULL
-
-CUSTOMTRACEFUNC = lltype.FuncType([llmemory.Address, llmemory.Address],
-                                  llmemory.Address)
-customtraceptr = llhelper(lltype.Ptr(CUSTOMTRACEFUNC), customtrace)
-lltype.attachRuntimeTypeInfo(JITFRAME, customtraceptr=customtraceptr)
diff --git a/pypy/jit/metainterp/optimizeopt/test/test_util.py b/pypy/jit/metainterp/optimizeopt/test/test_util.py
--- a/pypy/jit/metainterp/optimizeopt/test/test_util.py
+++ b/pypy/jit/metainterp/optimizeopt/test/test_util.py
@@ -245,7 +245,7 @@
         pass
     FakeWarmRunnerDesc.cpu = cpu
     vrefinfo = VirtualRefInfo(FakeWarmRunnerDesc)
-    virtualtokendescr = vrefinfo.descr_virtual_token
+    virtualtokendescr = vrefinfo.descr_jit_frame
     virtualforceddescr = vrefinfo.descr_forced
     jit_virtual_ref_vtable = vrefinfo.jit_virtual_ref_vtable
     jvr_vtable_adr = llmemory.cast_ptr_to_adr(jit_virtual_ref_vtable)
diff --git a/pypy/jit/metainterp/pyjitpl.py b/pypy/jit/metainterp/pyjitpl.py
--- a/pypy/jit/metainterp/pyjitpl.py
+++ b/pypy/jit/metainterp/pyjitpl.py
@@ -1928,7 +1928,7 @@
             self.run_blackhole_interp_to_cancel_tracing(stb)
         assert False, "should always raise"
 
-    def handle_guard_failure(self, key):
+    def handle_guard_failure(self, jitframe, key):
         debug_start('jit-tracing')
         self.staticdata.profiler.start_tracing()
         assert isinstance(key, compile.ResumeGuardDescr)
@@ -1936,7 +1936,7 @@
         # sure that it stays alive as long as this MetaInterp
         self.resumekey_original_loop_token = key.wref_original_loop_token()
         self.staticdata.try_to_free_some_loops()
-        self.initialize_state_from_guard_failure(key)
+        self.initialize_state_from_guard_failure(jitframe, key)
         try:
             return self._handle_guard_failure(key)
         finally:
@@ -2251,7 +2251,7 @@
         self.initialize_withgreenfields(original_boxes)
         self.initialize_virtualizable(original_boxes)
 
-    def initialize_state_from_guard_failure(self, resumedescr):
+    def initialize_state_from_guard_failure(self, jitframe, resumedescr):
         # guard failure: rebuild a complete MIFrame stack
         # This is stack-critical code: it must not be interrupted by StackOverflow,
         # otherwise the jit_virtual_refs are left in a dangling state.
@@ -2259,7 +2259,8 @@
         try:
             self.portal_call_depth = -1 # always one portal around
             self.history = history.History()
-            inputargs_and_holes = self.rebuild_state_after_failure(resumedescr)
+            inputargs_and_holes = self.rebuild_state_after_failure(jitframe,
+                                                                   resumedescr)
             self.history.inputargs = [box for box in inputargs_and_holes if box]
         finally:
             rstack._stack_criticalcode_stop()
@@ -2291,7 +2292,7 @@
         vinfo = self.jitdriver_sd.virtualizable_info
         virtualizable_box = self.virtualizable_boxes[-1]
         virtualizable = vinfo.unwrap_virtualizable_box(virtualizable_box)
-        vinfo.clear_vable_token(virtualizable)
+        vinfo.clear_jit_frame(virtualizable)
 
     def vable_and_vrefs_before_residual_call(self):
         vrefinfo = self.staticdata.virtualref_info
@@ -2378,12 +2379,12 @@
     def assert_no_exception(self):
         assert self.last_exc_value_box is None
 
-    def rebuild_state_after_failure(self, resumedescr):
+    def rebuild_state_after_failure(self, jitframe, resumedescr):
         vinfo = self.jitdriver_sd.virtualizable_info
         ginfo = self.jitdriver_sd.greenfield_info
         self.framestack = []
-        boxlists = resume.rebuild_from_resumedata(self, resumedescr, vinfo,
-                                                  ginfo)
+        boxlists = resume.rebuild_from_resumedata(self, jitframe, resumedescr,
+                                                  vinfo, ginfo)
         inputargs_and_holes, virtualizable_boxes, virtualref_boxes = boxlists
         #
         # virtual refs: make the vrefs point to the freshly allocated virtuals
diff --git a/pypy/jit/metainterp/resume.py b/pypy/jit/metainterp/resume.py
--- a/pypy/jit/metainterp/resume.py
+++ b/pypy/jit/metainterp/resume.py
@@ -690,8 +690,9 @@
     virtuals_cache = None
     virtual_default = None
 
-    def _init(self, cpu, storage):
+    def _init(self, cpu, jitframe, storage):
         self.cpu = cpu
+        self.jitframe = jitframe
         self.cur_numb = storage.rd_numb
         self.consts = storage.rd_consts
 
@@ -769,14 +770,11 @@
         value = self.decode_float(self.cur_numb.nums[index])
         self.write_a_float(register_index, value)
 
-    def done(self):
-        self.cpu.clear_latest_values(self.cpu.get_latest_value_count())
-
 # ---------- when resuming for pyjitpl.py, make boxes ----------
 
-def rebuild_from_resumedata(metainterp, storage, virtualizable_info,
+def rebuild_from_resumedata(metainterp, jitframe, storage, virtualizable_info,
                             greenfield_info):
-    resumereader = ResumeDataBoxReader(storage, metainterp)
+    resumereader = ResumeDataBoxReader(jitframe, storage, metainterp)
     boxes = resumereader.consume_vref_and_vable_boxes(virtualizable_info,
                                                       greenfield_info)
     virtualizable_boxes, virtualref_boxes = boxes
@@ -790,16 +788,16 @@
         if frameinfo is None:
             break
     metainterp.framestack.reverse()
-    resumereader.done()
     return resumereader.liveboxes, virtualizable_boxes, virtualref_boxes
 
 class ResumeDataBoxReader(AbstractResumeDataReader):
     unique_id = lambda: None
 
-    def __init__(self, storage, metainterp):
-        self._init(metainterp.cpu, storage)
+    def __init__(self, jitframe, storage, metainterp):
+        self._init(metainterp.cpu, jitframe, storage)
         self.metainterp = metainterp
-        self.liveboxes = [None] * metainterp.cpu.get_latest_value_count()
+        count = metainterp.cpu.get_latest_value_count(jitframe)
+        self.liveboxes = [None] * count
         self._prepare(storage)
 
     def consume_boxes(self, info, boxes_i, boxes_r, boxes_f):
@@ -974,12 +972,13 @@
         if num < 0:
             num += len(self.liveboxes)
             assert num >= 0
+        jitframe = self.jitframe
         if kind == INT:
-            box = BoxInt(self.cpu.get_latest_value_int(num))
+            box = BoxInt(self.cpu.get_latest_value_int(jitframe, num))
         elif kind == REF:
-            box = BoxPtr(self.cpu.get_latest_value_ref(num))
+            box = BoxPtr(self.cpu.get_latest_value_ref(jitframe, num))
         elif kind == FLOAT:
-            box = BoxFloat(self.cpu.get_latest_value_float(num))
+            box = BoxFloat(self.cpu.get_latest_value_float(jitframe, num))
         else:
             assert 0, "bad kind: %d" % ord(kind)
         self.liveboxes[num] = box
@@ -1003,14 +1002,14 @@
 
 # ---------- when resuming for blackholing, get direct values ----------
 
-def blackhole_from_resumedata(blackholeinterpbuilder, jitdriver_sd, storage,
-                              all_virtuals=None):
+def blackhole_from_resumedata(blackholeinterpbuilder, jitdriver_sd,
+                              jitframe, storage, all_virtuals=None):
     # The initialization is stack-critical code: it must not be interrupted by
     # StackOverflow, otherwise the jit_virtual_refs are left in a dangling state.
     rstack._stack_criticalcode_start()
     try:
         resumereader = ResumeDataDirectReader(blackholeinterpbuilder.metainterp_sd,
-                                              storage, all_virtuals)
+                                              jitframe, storage, all_virtuals)
         vinfo = jitdriver_sd.virtualizable_info
         ginfo = jitdriver_sd.greenfield_info
         vrefinfo = blackholeinterpbuilder.metainterp_sd.virtualref_info
@@ -1043,7 +1042,6 @@
         frameinfo = frameinfo.prev
         if frameinfo is None:
             break
-    resumereader.done()
     return firstbh
 
 def force_from_resumedata(metainterp_sd, storage, vinfo, ginfo):
@@ -1061,8 +1059,8 @@
     #             1: in handle_async_forcing
     #             2: resuming from the GUARD_NOT_FORCED
 
-    def __init__(self, metainterp_sd, storage, all_virtuals=None):
-        self._init(metainterp_sd.cpu, storage)
+    def __init__(self, metainterp_sd, jitframe, storage, all_virtuals=None):
+        self._init(metainterp_sd.cpu, jitframe, storage)
         self.callinfocollection = metainterp_sd.callinfocollection
         if all_virtuals is None:        # common case
             self._prepare(storage)
@@ -1240,9 +1238,10 @@
             return num
         else:
             assert tag == TAGBOX
+            jitframe = self.jitframe
             if num < 0:
-                num += self.cpu.get_latest_value_count()
-            return self.cpu.get_latest_value_int(num)
+                num += self.cpu.get_latest_value_count(jitframe)
+            return self.cpu.get_latest_value_int(jitframe, num)
 
     def decode_ref(self, tagged):
         num, tag = untag(tagged)
@@ -1254,9 +1253,10 @@
             return self.getvirtual(num)
         else:
             assert tag == TAGBOX
+            jitframe = self.jitframe
             if num < 0:
-                num += self.cpu.get_latest_value_count()
-            return self.cpu.get_latest_value_ref(num)
+                num += self.cpu.get_latest_value_count(jitframe)
+            return self.cpu.get_latest_value_ref(jitframe, num)
 
     def decode_float(self, tagged):
         num, tag = untag(tagged)
@@ -1264,9 +1264,10 @@
             return self.consts[num].getfloatstorage()
         else:
             assert tag == TAGBOX
+            jitframe = self.jitframe
             if num < 0:
-                num += self.cpu.get_latest_value_count()
-            return self.cpu.get_latest_value_float(num)
+                num += self.cpu.get_latest_value_count(jitframe)
+            return self.cpu.get_latest_value_float(jitframe, num)
 
     def write_an_int(self, index, int):
         self.blackholeinterp.setarg_i(index, int)
diff --git a/pypy/jit/metainterp/test/support.py b/pypy/jit/metainterp/test/support.py
--- a/pypy/jit/metainterp/test/support.py
+++ b/pypy/jit/metainterp/test/support.py
@@ -141,14 +141,15 @@
     for i in range(len(args) - num_green_args):
         x = args[num_green_args + i]
         args1.append(unspecialize_value(x))
-    faildescr = cpu.execute_token(procedure_token, *args1)
+    frame = cpu.execute_token(procedure_token, *args1)
+    faildescr = cpu.get_latest_descr(frame)
     assert faildescr.__class__.__name__.startswith('DoneWithThisFrameDescr')
     if metainterp.jitdriver_sd.result_type == history.INT:
-        return cpu.get_latest_value_int(0)
+        return cpu.get_latest_value_int(frame, 0)
     elif metainterp.jitdriver_sd.result_type == history.REF:
-        return cpu.get_latest_value_ref(0)
+        return cpu.get_latest_value_ref(frame, 0)
     elif metainterp.jitdriver_sd.result_type == history.FLOAT:
-        return cpu.get_latest_value_float(0)
+        return cpu.get_latest_value_float(frame, 0)
     else:
         return None
 
diff --git a/pypy/jit/metainterp/test/test_virtualizable.py b/pypy/jit/metainterp/test/test_virtualizable.py
--- a/pypy/jit/metainterp/test/test_virtualizable.py
+++ b/pypy/jit/metainterp/test/test_virtualizable.py
@@ -12,6 +12,7 @@
 from pypy.jit.metainterp.warmspot import get_stats, get_translator
 from pypy.jit.metainterp import history
 from pypy.jit.metainterp.optimizeopt.test.test_util import LLtypeMixin
+from pypy.jit.metainterp.jitframe import JITFRAMEPTR
 
 def promote_virtualizable(*args):
     pass
@@ -41,7 +42,7 @@
     XY = lltype.GcStruct(
         'XY',
         ('parent', rclass.OBJECT),
-        ('vable_token', lltype.Signed),
+        ('jit_frame', JITFRAMEPTR),
         ('inst_x', lltype.Signed),
         ('inst_node', lltype.Ptr(LLtypeMixin.NODE)),
         hints = {'virtualizable2_accessor': FieldListAccessor()})
@@ -56,7 +57,7 @@
 
     def setup(self):
         xy = lltype.malloc(self.XY)
-        xy.vable_token = 0
+        xy.jit_frame = lltype.nullptr(JITFRAMEPTR.TO)
         xy.parent.typeptr = self.xy_vtable
         return xy
 
@@ -206,7 +207,7 @@
     XY2 = lltype.GcStruct(
         'XY2',
         ('parent', rclass.OBJECT),
-        ('vable_token', lltype.Signed),
+        ('jit_frame', JITFRAMEPTR),
         ('inst_x', lltype.Signed),
         ('inst_l1', lltype.Ptr(lltype.GcArray(lltype.Signed))),
         ('inst_l2', lltype.Ptr(lltype.GcArray(lltype.Signed))),
@@ -220,7 +221,7 @@
 
     def setup2(self):
         xy2 = lltype.malloc(self.XY2)
-        xy2.vable_token = 0
+        xy2.jit_frame = lltype.nullptr(JITFRAMEPTR.TO)
         xy2.parent.typeptr = self.xy2_vtable
         return xy2
 
@@ -393,7 +394,7 @@
 
     def setup2sub(self):
         xy2 = lltype.malloc(self.XY2SUB)
-        xy2.parent.vable_token = 0
+        xy2.parent.jit_frame = lltype.nullptr(JITFRAMEPTR.TO)
         xy2.parent.parent.typeptr = self.xy2_vtable
         return xy2
 
diff --git a/pypy/jit/metainterp/warmspot.py b/pypy/jit/metainterp/warmspot.py
--- a/pypy/jit/metainterp/warmspot.py
+++ b/pypy/jit/metainterp/warmspot.py
@@ -549,8 +549,9 @@
             ASMRESTYPE = lltype.Float
         else:
             assert False
+        from pypy.jit.metainterp.jitframe import JITFRAMEPTR
         (_, jd._PTR_ASSEMBLER_HELPER_FUNCTYPE) = self.cpu.ts.get_FuncType(
-            [lltype.Signed, llmemory.GCREF], ASMRESTYPE)
+            [JITFRAMEPTR, llmemory.GCREF], ASMRESTYPE)
 
     def rewrite_can_enter_jits(self):
         sublists = {}
@@ -803,14 +804,14 @@
 
         vinfo = jd.virtualizable_info
 
-        def assembler_call_helper(failindex, virtualizableref):
-            fail_descr = self.cpu.get_fail_descr_from_number(failindex)
+        def assembler_call_helper(jitframe, virtualizableref):
+            fail_descr = self.cpu.get_latest_descr(jitframe)
             if vinfo is not None:
                 virtualizable = lltype.cast_opaque_ptr(
                     vinfo.VTYPEPTR, virtualizableref)
-                vinfo.reset_vable_token(virtualizable)
+                vinfo.reset_jit_frame(virtualizable)
             try:
-                fail_descr.handle_fail(self.metainterp_sd, jd)
+                fail_descr.handle_fail(self.metainterp_sd, jd, jitframe)
             except JitException, e:
                 return handle_jitexception(e)
             else:
@@ -823,7 +824,7 @@
         jd.assembler_helper_adr = llmemory.cast_ptr_to_adr(
             jd._assembler_helper_ptr)
         if vinfo is not None:
-            jd.vable_token_descr = vinfo.vable_token_descr
+            jd.jit_frame_descr = vinfo.jit_frame_descr
 
         def handle_jitexception_from_blackhole(bhcaller, e):
             result = handle_jitexception(e)
diff --git a/pypy/jit/metainterp/warmstate.py b/pypy/jit/metainterp/warmstate.py
--- a/pypy/jit/metainterp/warmstate.py
+++ b/pypy/jit/metainterp/warmstate.py
@@ -303,21 +303,22 @@
         def execute_assembler(loop_token, *args):
             # Call the backend to run the 'looptoken' with the given
             # input args.
-            fail_descr = func_execute_token(loop_token, *args)
+            frame = func_execute_token(loop_token, *args)
+            fail_descr = self.cpu.get_latest_descr(frame)
             #
             # If we have a virtualizable, we have to reset its
-            # 'vable_token' field afterwards
+            # 'jit_frame' field afterwards
             if vinfo is not None:
                 virtualizable = args[index_of_virtualizable]
                 virtualizable = vinfo.cast_gcref_to_vtype(virtualizable)
-                vinfo.reset_vable_token(virtualizable)
+                vinfo.reset_jit_frame(virtualizable)
             #
             # Record in the memmgr that we just ran this loop,
             # so that it will keep it alive for a longer time
             warmrunnerdesc.memory_manager.keep_loop_alive(loop_token)
             #
             # Handle the failure
-            fail_descr.handle_fail(metainterp_sd, jitdriver_sd)
+            fail_descr.handle_fail(metainterp_sd, jitdriver_sd, frame)
             #
             assert 0, "should have raised"
 


More information about the pypy-commit mailing list