Commits

Armin Rigo committed c2481d2

in-progress

Comments (0)

Files changed (5)

pypy/jit/backend/llgraph/runner.py

-import weakref
+import py, weakref
 from pypy.jit.backend import model
 from pypy.jit.backend.llgraph import support
 from pypy.jit.metainterp.history import AbstractDescr
     def __init__(self, realdescr):
         self.realdescrref = weakref.ref(realdescr)
 
-    def getrealdescr(self):
-        realdescr = self.realdescrref()
-        assert realdescr is not None, "the descr disappeared: %r" % (op,)
-        return realdescr
-
 class ExecutionFinished(Exception):
     def __init__(self, deadframe):
         self.deadframe = deadframe
         return gcref
 
     def force(self, force_token):
-        xxxx
-        assert not frame._forced
-        frame._forced = True
+        frame = force_token
+        assert isinstance(frame, LLFrame)
+        assert frame.forced_deadframe is None
+        values = []
+        for box in frame.force_guard_op.getfailargs():
+            if box is not None and box is not frame.current_op.result:
+                value = frame.env[box]
+            else:
+                value = None
+            values.append(value)
+        frame.forced_deadframe = LLDeadFrame(
+            _getdescr(frame.force_guard_op), values)
+        return frame.forced_deadframe
 
-    def set_savedata_ref(self, frame, data):
-        frame.saved_data = data
+    def set_savedata_ref(self, deadframe, data):
+        deadframe._saved_data = data
 
-    def get_savedata_ref(self, frame):
-        return frame.saved_data
+    def get_savedata_ref(self, deadframe):
+        assert deadframe._saved_data is not None
+        return deadframe._saved_data
     
     # ------------------------------------------------------------
 
 
 class LLDeadFrame(object):
 
-    def __init__(self, latest_descr, values, last_exception=None):
+    def __init__(self, latest_descr, values,
+                 last_exception=None, saved_data=None):
         self._latest_descr = latest_descr
         self._values = values
         self._last_exception = last_exception
+        self._saved_data = saved_data
 
 
 class LLFrame(object):
-    killed = None
+    _TYPE = lltype.Signed
+
+    forced_deadframe = None
     overflow_flag = False
     last_exception = None
 
 
     # -----------------------------------------------------
 
-    def fail_guard(self, descr):
+    def fail_guard(self, descr, saved_data=None):
         values = []
         for box in self.current_op.getfailargs():
             if box is not None:
             raise Jump(target, values)
         else:
             raise ExecutionFinished(LLDeadFrame(descr, values,
-                                                self.last_exception))
+                                                self.last_exception,
+                                                saved_data))
 
     def execute_force_spill(self, _, arg):
         pass
         return support.cast_to_ptr(res)
 
     def execute_guard_not_forced(self, descr):
-        if self._forced:
-            self.fail_guard(descr)
+        if self.forced_deadframe is not None:
+            saved_data = self.forced_deadframe._saved_data
+            self.fail_guard(descr, saved_data)
 
     def execute_guard_not_invalidated(self, descr):
         if self.lltrace.invalid:
             self.last_exception = lle
             res = _example_res[getkind(TP.RESULT)[0]]
         return res
-    execute_call_i = execute_call
-    execute_call_r = execute_call
-    execute_call_f = execute_call
-    execute_call_v = execute_call
 
     def execute_call_may_force(self, calldescr, func, *args):
         call_op = self.lltrace.operations[self.current_index]
         guard_op = self.lltrace.operations[self.current_index + 1]
         assert guard_op.getopnum() == rop.GUARD_NOT_FORCED
-        self.latest_descr = _getdescr(guard_op)
+        self.force_guard_op = guard_op
         res = self.execute_call(calldescr, func, *args)
-        del self.latest_descr
+        del self.force_guard_op
         return res
-    execute_call_may_force_i = execute_call_may_force
-    execute_call_may_force_r = execute_call_may_force
-    execute_call_may_force_f = execute_call_may_force
-    execute_call_may_force_v = execute_call_may_force
 
     def execute_call_release_gil(self, descr, func, *args):
         call_args = support.cast_call_args_in_order(descr.ARGS, args)
         func_to_call = rffi.cast(lltype.Ptr(FUNC), func)
         result = func_to_call(*call_args)
         return support.cast_result(descr.RESULT, result)
-    execute_call_release_gil_i = execute_call_release_gil
-    execute_call_release_gil_r = execute_call_release_gil
-    execute_call_release_gil_f = execute_call_release_gil
-    execute_call_release_gil_v = execute_call_release_gil
 
     def execute_call_assembler(self, descr, *args):
         # pframe = CALL_ASSEMBLER(args..., descr=looptoken)
         call_op = self.lltrace.operations[self.current_index]
         guard_op = self.lltrace.operations[self.current_index + 1]
         assert guard_op.getopnum() == rop.GUARD_NOT_FORCED
-        self.latest_descr = _getdescr(guard_op)
+        self.force_guard_op = guard_op
         #
         pframe = self.cpu._execute_token(descr, *args)
         if not pframe._fast_path_done:
                 return lltype.nullptr(llmemory.GCREF.TO)
             assert result is pframe
         #
-        del self.latest_descr
+        del self.force_guard_op
         return pframe
 
     def execute_same_as(self, _, x):
         return x
-    execute_same_as_i = execute_same_as
-    execute_same_as_r = execute_same_as
-    execute_same_as_f = execute_same_as
 
     def execute_debug_merge_point(self, descr, *args):
         from pypy.jit.metainterp.warmspot import get_stats
         descr = heaptracker.vtable2descr(self.cpu, vtable)
         return self.cpu.bh_new_with_vtable(vtable, descr)
 
-    def execute_jit_frame(self, _):
+    def execute_force_token(self, _):
         return self
 
+    def execute_cond_call_gc_wb(self, descr, a, b):
+        py.test.skip("cond_call_gc_wb not supported")
+
+    def execute_cond_call_gc_wb_array(self, descr, a, b, c):
+        py.test.skip("cond_call_gc_wb_array not supported")
+
 def _getdescr(op):
     d = op.getdescr()
     if d is not None:
-        d = d.getrealdescr()
+        d = d.realdescrref()
+        assert d is not None, "the descr disappeared: %r" % (op,)
     return d
 
 def _setup():

pypy/jit/backend/model.py

         necessarily correct after a FINISH."""
         raise NotImplementedError
 
-    def get_latest_force_token(self, deadframe):
-        """After a GUARD_NOT_FORCED fails, this function returns the
-        same FORCE_TOKEN result as the one in the just-failed loop."""
-        raise NotImplementedError
-
     def grab_exc_value(self, deadframe):
         """Return the exception set by the latest execute_token(),
         when it exits due to a failure of a GUARD_EXCEPTION or

pypy/jit/backend/test/runner_test.py

     else:
         return BoxFloat(ll)
 
+class RandomGcRef(object):
+    _TYPE = llmemory.GCREF
+random_gcref = RandomGcRef()
+
 
 class Runner(object):
 
             #
             for k in range(len(retvalues)):
                 if isinstance(retboxes[k], BoxInt):
-                    got = self.cpu.get_latest_value_int(k)
+                    got = self.cpu.get_latest_value_int(deadframe, k)
                 else:
-                    got = self.cpu.get_latest_value_float(k)
+                    got = self.cpu.get_latest_value_float(deadframe, k)
                 assert got == retvalues[k]
 
     def test_jump(self):
                     assert 0
             values[index_counter] = 11
             #
-            fail = self.cpu.execute_token(looptoken, *values)
+            deadframe = self.cpu.execute_token(looptoken, *values)
+            fail = self.cpu.get_latest_descr(deadframe)
             assert fail.identifier == 15
             #
             dstvalues = values[:]
             dstvalues[index_counter] = 0
             for i, (box, val) in enumerate(zip(inputargs, dstvalues)):
                 if isinstance(box, BoxInt):
-                    got = self.cpu.get_latest_value_int(i)
+                    got = self.cpu.get_latest_value_int(deadframe, i)
                 elif isinstance(box, BoxPtr):
-                    got = self.cpu.get_latest_value_ref(i)
+                    got = self.cpu.get_latest_value_ref(deadframe, i)
                 elif isinstance(box, BoxFloat):
-                    got = self.cpu.get_latest_value_float(i)
+                    got = self.cpu.get_latest_value_float(deadframe, i)
                 else:
                     assert 0
                 assert type(got) == type(val)
         for i in range(len(fboxes)):
             x = 13.5 + 6.73 * i
             args.append(longlong.getfloatstorage(x))
-        fail = self.cpu.execute_token(looptoken, *args)
+        deadframe = self.cpu.execute_token(looptoken, *args)
+        fail = self.cpu.get_latest_descr(deadframe)
         assert fail.identifier == 2
-        res = self.cpu.get_latest_value_float(0)
+        res = self.cpu.get_latest_value_float(deadframe, 0)
         assert longlong.getrealfloat(res) == 8.5
         for i in range(1, len(fboxes)):
-            got = longlong.getrealfloat(self.cpu.get_latest_value_float(i))
+            got = longlong.getrealfloat(self.cpu.get_latest_value_float(
+                deadframe, i))
             assert got == 13.5 + 6.73 * i
 
     def test_compile_bridge_spilled_float(self):
         args = [1]
         args.append(longlong.getfloatstorage(132.25))
         args.append(longlong.getfloatstorage(0.75))
-        fail = self.cpu.execute_token(looptoken, *args)  #xxx check
+        deadframe = self.cpu.execute_token(looptoken, *args)  #xxx check
+        fail = self.cpu.get_latest_descr(deadframe)
         assert loop.operations[-2].getdescr() == fail
-        f1 = self.cpu.get_latest_value_float(0)
-        f2 = self.cpu.get_latest_value_float(1)
-        f3 = self.cpu.get_latest_value_float(2)
+        f1 = self.cpu.get_latest_value_float(deadframe, 0)
+        f2 = self.cpu.get_latest_value_float(deadframe, 1)
+        f3 = self.cpu.get_latest_value_float(deadframe, 2)
         assert longlong.getrealfloat(f1) == 132.25
         assert longlong.getrealfloat(f2) == 0.75
         assert longlong.getrealfloat(f3) == 133.0
         args = [1,
                 longlong.getfloatstorage(132.25),
                 longlong.getfloatstorage(0.75)]
-        fail = self.cpu.execute_token(looptoken, *args)
+        deadframe = self.cpu.execute_token(looptoken, *args)
+        fail = self.cpu.get_latest_descr(deadframe)
         assert fail.identifier == 100
-        f1 = self.cpu.get_latest_value_float(0)
-        f2 = self.cpu.get_latest_value_float(1)
-        f3 = self.cpu.get_latest_value_float(2)
+        f1 = self.cpu.get_latest_value_float(deadframe, 0)
+        f2 = self.cpu.get_latest_value_float(deadframe, 1)
+        f3 = self.cpu.get_latest_value_float(deadframe, 2)
         assert longlong.getrealfloat(f1) == 132.25
         assert longlong.getrealfloat(f2) == 0.75
         assert longlong.getrealfloat(f3) == 133.0
                 looptoken = JitCellToken()
                 self.cpu.compile_loop(inputargs, operations, looptoken)
                 #
-                cpu = self.cpu
                 for value in [-42, 0, 1, 10]:
-                    fail = cpu.execute_token(looptoken, value)
+                    deadframe = self.cpu.execute_token(looptoken, value)
+                    fail = self.cpu.get_latest_descr(deadframe)
                     #
                     expected = compare(value)
                     expected ^= guard_case
                     looptoken = JitCellToken()
                     self.cpu.compile_loop(inputargs, operations, looptoken)
                     #
-                    cpu = self.cpu
                     for test1 in [-65, -42, -11, 0, 1, 10]:
                         if test1 == -42 or combinaison[0] == 'b':
                             for test2 in [-65, -42, -11, 0, 1, 10]:
                                         args.append(test1)
                                     if combinaison[1] == 'b':
                                         args.append(test2)
-                                    fail = cpu.execute_token(looptoken, *args)
+                                    deadframe = self.cpu.execute_token(
+                                        looptoken, *args)
+                                    fail = self.cpu.get_latest_descr(deadframe)
                                     #
                                     expected = compare(test1, test2)
                                     expected ^= guard_case
                     looptoken = JitCellToken()
                     self.cpu.compile_loop(inputargs, operations, looptoken)
                     #
-                    cpu = self.cpu
                     for test1 in [65, 42, 11, 0, 1]:
                         if test1 == 42 or combinaison[0] == 'b':
                             for test2 in [65, 42, 11, 0, 1]:
                                         args.append(test1)
                                     if combinaison[1] == 'b':
                                         args.append(test2)
-                                    fail = cpu.execute_token(looptoken, *args)
+                                    deadframe = self.cpu.execute_token(
+                                        looptoken, *args)
+                                    fail = self.cpu.get_latest_descr(deadframe)
                                     #
                                     expected = compare(test1, test2)
                                     expected ^= guard_case
                     looptoken = JitCellToken()
                     self.cpu.compile_loop(inputargs, operations, looptoken)
                     #
-                    cpu = self.cpu
                     nan = 1e200 * 1e200
                     nan /= nan
                     for test1 in [-6.5, -4.5, -2.5, nan]:
                                     if combinaison[1] == 'b':
                                         args.append(
                                             longlong.getfloatstorage(test2))
-                                    fail = cpu.execute_token(looptoken, *args)
+                                    deadframe = self.cpu.execute_token(
+                                        looptoken, *args)
+                                    fail = self.cpu.get_latest_descr(deadframe)
                                     #
                                     expected = compare(test1, test2)
                                     expected ^= guard_case
             else:
                 assert 0
         #
-        fail = self.cpu.execute_token(looptoken, *args)
+        deadframe = self.cpu.execute_token(looptoken, *args)
+        fail = self.cpu.get_latest_descr(deadframe)
         assert fail.identifier == 1
 
     def test_nan_and_infinity(self):
                                               looptoken)
                         args = [box.getfloatstorage()
                                 for box in unique_testcase_list]
-                        fail = self.cpu.execute_token(looptoken, *args)
+                        deadframe = self.cpu.execute_token(looptoken, *args)
+                        fail = self.cpu.get_latest_descr(deadframe)
                         if fail.identifier != 5 - (expected_id^expected):
                             if fail.identifier == 4:
                                 msg = "was taken"
         loop = parse(ops, self.cpu, namespace=locals())
         looptoken = JitCellToken()
         self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken)
-        self.cpu.execute_token(looptoken, 1)
-        assert self.cpu.get_latest_value_int(0) == 0
-        assert self.cpu.get_latest_value_ref(1) == xptr
-        excvalue = self.cpu.grab_exc_value()
+        deadframe = self.cpu.execute_token(looptoken, 1)
+        assert self.cpu.get_latest_value_int(deadframe, 0) == 0
+        assert self.cpu.get_latest_value_ref(deadframe, 1) == xptr
+        excvalue = self.cpu.grab_exc_value(deadframe)
         assert not excvalue
-        self.cpu.execute_token(looptoken, 0)
-        assert self.cpu.get_latest_value_int(0) == 1
-        excvalue = self.cpu.grab_exc_value()
+        deadframe = self.cpu.execute_token(looptoken, 0)
+        assert self.cpu.get_latest_value_int(deadframe, 0) == 1
+        excvalue = self.cpu.grab_exc_value(deadframe)
         assert not excvalue
 
         ytp = lltype.malloc(rclass.OBJECT_VTABLE, immortal=True)
         loop = parse(ops, self.cpu, namespace=locals())
         looptoken = JitCellToken()
         self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken)
-        self.cpu.execute_token(looptoken, 1)
-        assert self.cpu.get_latest_value_int(0) == 1
-        excvalue = self.cpu.grab_exc_value()
+        deadframe = self.cpu.execute_token(looptoken, 1)
+        assert self.cpu.get_latest_value_int(deadframe, 0) == 1
+        excvalue = self.cpu.grab_exc_value(deadframe)
         assert excvalue == yptr
-        assert not self.cpu.grab_exc_value()   # cleared
 
         exc_tp = xtp
         exc_ptr = xptr
         loop = parse(ops, self.cpu, namespace=locals())
         looptoken = JitCellToken()
         self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken)
-        self.cpu.execute_token(looptoken, 1)
-        assert self.cpu.get_latest_value_int(0) == 1
-        excvalue = self.cpu.grab_exc_value()
+        deadframe = self.cpu.execute_token(looptoken, 1)
+        assert self.cpu.get_latest_value_int(deadframe, 0) == 1
+        excvalue = self.cpu.grab_exc_value(deadframe)
         assert excvalue == xptr
-        self.cpu.execute_token(looptoken, 0)
-        assert self.cpu.get_latest_value_int(0) == 0
-        excvalue = self.cpu.grab_exc_value()
+        deadframe = self.cpu.execute_token(looptoken, 0)
+        assert self.cpu.get_latest_value_int(deadframe, 0) == 0
+        excvalue = self.cpu.grab_exc_value(deadframe)
         assert not excvalue
 
     def test_cond_call_gc_wb(self):
         values = []
         def maybe_force(token, flag):
             if flag:
-                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))
-                values.append(token)
+                deadframe = self.cpu.force(token)
+                values.append(self.cpu.get_latest_descr(deadframe))
+                values.append(self.cpu.get_latest_value_int(deadframe, 0))
+                values.append(self.cpu.get_latest_value_int(deadframe, 1))
+                self.cpu.set_savedata_ref(deadframe, random_gcref)
 
         FUNC = self.FuncType([lltype.Signed, lltype.Signed], lltype.Void)
         func_ptr = llhelper(lltype.Ptr(FUNC), maybe_force)
         ops[2].setfailargs([i1, i0])
         looptoken = JitCellToken()
         self.cpu.compile_loop([i0, i1], ops, looptoken)
-        fail = self.cpu.execute_token(looptoken, 20, 0)
+        deadframe = self.cpu.execute_token(looptoken, 20, 0)
+        fail = self.cpu.get_latest_descr(deadframe)
         assert fail.identifier == 0
-        assert self.cpu.get_latest_value_int(0) == 20
+        assert self.cpu.get_latest_value_int(deadframe, 0) == 20
         assert values == []
 
-        fail = self.cpu.execute_token(looptoken, 10, 1)
+        deadframe = self.cpu.execute_token(looptoken, 10, 1)
+        fail = self.cpu.get_latest_descr(deadframe)
         assert fail.identifier == 1
-        assert self.cpu.get_latest_value_int(0) == 1
-        assert self.cpu.get_latest_value_int(1) == 10
-        token = self.cpu.get_latest_force_token()
-        assert values == [faildescr, 1, 10, token]
+        assert self.cpu.get_latest_value_int(deadframe, 0) == 1
+        assert self.cpu.get_latest_value_int(deadframe, 1) == 10
+        assert values == [faildescr, 1, 10]
+        assert self.cpu.get_savedata_ref(deadframe) == random_gcref
 
     def test_force_operations_returning_int(self):
         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(2))
-               values.append(token)
+                deadframe = self.cpu.force(token)
+                values.append(self.cpu.get_latest_value_int(deadframe, 0))
+                values.append(self.cpu.get_latest_value_int(deadframe, 2))
+                self.cpu.set_savedata_ref(deadframe, random_gcref)
             return 42
 
         FUNC = self.FuncType([lltype.Signed, lltype.Signed], lltype.Signed)
         ops[2].setfailargs([i1, i2, i0])
         looptoken = JitCellToken()
         self.cpu.compile_loop([i0, i1], ops, looptoken)
-        fail = self.cpu.execute_token(looptoken, 20, 0)
+        deadframe = self.cpu.execute_token(looptoken, 20, 0)
+        fail = self.cpu.get_latest_descr(deadframe)
         assert fail.identifier == 0
-        assert self.cpu.get_latest_value_int(0) == 42
+        assert self.cpu.get_latest_value_int(deadframe, 0) == 42
         assert values == []
 
-        fail = self.cpu.execute_token(looptoken, 10, 1)
+        deadframe = self.cpu.execute_token(looptoken, 10, 1)
+        fail = self.cpu.get_latest_descr(deadframe)
         assert fail.identifier == 1
-        assert self.cpu.get_latest_value_int(0) == 1
-        assert self.cpu.get_latest_value_int(1) == 42
-        assert self.cpu.get_latest_value_int(2) == 10
-        token = self.cpu.get_latest_force_token()
-        assert values == [1, 10, token]
+        assert self.cpu.get_latest_value_int(deadframe, 0) == 1
+        assert self.cpu.get_latest_value_int(deadframe, 1) == 42
+        assert self.cpu.get_latest_value_int(deadframe, 2) == 10
+        assert values == [1, 10]
+        assert self.cpu.get_savedata_ref(deadframe) == random_gcref
 
     def test_force_operations_returning_float(self):
         if not self.cpu.supports_floats:
         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(2))
-               values.append(token)
+                deadframe = self.cpu.force(token)
+                values.append(self.cpu.get_latest_value_int(deadframe, 0))
+                values.append(self.cpu.get_latest_value_int(deadframe, 2))
+                self.cpu.set_savedata_ref(deadframe, random_gcref)
             return 42.5
 
         FUNC = self.FuncType([lltype.Signed, lltype.Signed], lltype.Float)
         ops[2].setfailargs([i1, f2, i0])
         looptoken = JitCellToken()
         self.cpu.compile_loop([i0, i1], ops, looptoken)
-        fail = self.cpu.execute_token(looptoken, 20, 0)
+        deadframe = self.cpu.execute_token(looptoken, 20, 0)
+        fail = self.cpu.get_latest_descr(deadframe)
         assert fail.identifier == 0
-        x = self.cpu.get_latest_value_float(0)
+        x = self.cpu.get_latest_value_float(deadframe, 0)
         assert longlong.getrealfloat(x) == 42.5
         assert values == []
 
-        fail = self.cpu.execute_token(looptoken, 10, 1)
+        deadframe = self.cpu.execute_token(looptoken, 10, 1)
+        fail = self.cpu.get_latest_descr(deadframe)
         assert fail.identifier == 1
-        assert self.cpu.get_latest_value_int(0) == 1
-        x = self.cpu.get_latest_value_float(1)
+        assert self.cpu.get_latest_value_int(deadframe, 0) == 1
+        x = self.cpu.get_latest_value_float(deadframe, 1)
         assert longlong.getrealfloat(x) == 42.5
-        assert self.cpu.get_latest_value_int(2) == 10
-        token = self.cpu.get_latest_force_token()
-        assert values == [1, 10, token]
+        assert self.cpu.get_latest_value_int(deadframe, 2) == 10
+        assert values == [1, 10]
+        assert self.cpu.get_savedata_ref(deadframe) == random_gcref
 
     def test_call_to_c_function(self):
         from pypy.rlib.libffi import CDLL, types, ArgChain, FUNCFLAG_CDECL
         ops[1].setfailargs([i1, i2])
         looptoken = JitCellToken()
         self.cpu.compile_loop([i1], ops, looptoken)
-        fail = self.cpu.execute_token(looptoken, ord('G'))
+        deadframe = self.cpu.execute_token(looptoken, ord('G'))
+        fail = self.cpu.get_latest_descr(deadframe)
         assert fail.identifier == 0
-        assert self.cpu.get_latest_value_int(0) == ord('g')
+        assert self.cpu.get_latest_value_int(deadframe, 0) == ord('g')
 
     def test_call_to_c_function_with_callback(self):
         from pypy.rlib.libffi import CDLL, types, ArgChain, clibffi
                 4,
                 rffi.cast(lltype.Signed, fn)]
         assert glob.lst == []
-        fail = self.cpu.execute_token(looptoken, *args)
+        deadframe = self.cpu.execute_token(looptoken, *args)
+        fail = self.cpu.get_latest_descr(deadframe)
         assert fail.identifier == 0
         assert len(glob.lst) > 0
         lltype.free(raw, flavor='raw')
 
         buffer = lltype.malloc(rffi.CCHARP.TO, buflen, flavor='raw')
         args = [buflen, rffi.cast(lltype.Signed, buffer)]
-        fail = self.cpu.execute_token(looptoken, *args)
+        deadframe = self.cpu.execute_token(looptoken, *args)
+        fail = self.cpu.get_latest_descr(deadframe)
         assert fail.identifier == 0
-        assert self.cpu.get_latest_value_int(0) == len(cwd)
+        assert self.cpu.get_latest_value_int(deadframe, 0) == len(cwd)
         assert rffi.charp2strn(buffer, buflen) == cwd
         lltype.free(buffer, flavor='raw')
 
         looptoken = JitCellToken()
         self.cpu.compile_loop([i0, i1], ops, looptoken)
 
-        fail = self.cpu.execute_token(looptoken, -42, 9)
+        deadframe = self.cpu.execute_token(looptoken, -42, 9)
+        fail = self.cpu.get_latest_descr(deadframe)
         assert fail.identifier == 0
-        assert self.cpu.get_latest_value_int(0) == -42
+        assert self.cpu.get_latest_value_int(deadframe, 0) == -42
         print 'step 1 ok'
         print '-'*79
 
         # mark as failing
         self.cpu.invalidate_loop(looptoken)
 
-        fail = self.cpu.execute_token(looptoken, -42, 9)
+        deadframe = self.cpu.execute_token(looptoken, -42, 9)
+        fail = self.cpu.get_latest_descr(deadframe)
         assert fail is faildescr
-        assert self.cpu.get_latest_value_int(0) == 9
+        assert self.cpu.get_latest_value_int(deadframe, 0) == 9
         print 'step 2 ok'
         print '-'*79
 
         ops[0].setfailargs([])
         self.cpu.compile_bridge(faildescr, [i2], ops, looptoken)
 
-        fail = self.cpu.execute_token(looptoken, -42, 9)
+        deadframe = self.cpu.execute_token(looptoken, -42, 9)
+        fail = self.cpu.get_latest_descr(deadframe)
         assert fail.identifier == 3
-        assert self.cpu.get_latest_value_int(0) == 9
+        assert self.cpu.get_latest_value_int(deadframe, 0) == 9
         print 'step 3 ok'
         print '-'*79
 
         # mark as failing again
         self.cpu.invalidate_loop(looptoken)
 
-        fail = self.cpu.execute_token(looptoken, -42, 9)
+        deadframe = self.cpu.execute_token(looptoken, -42, 9)
+        fail = self.cpu.get_latest_descr(deadframe)
         assert fail is faildescr2
         print 'step 4 ok'
         print '-'*79
         self.cpu.invalidate_loop(looptoken)
         # attach a bridge
         i2 = BoxInt()
-        ops = [
+        ops2 = [
             ResOperation(rop.JUMP, [ConstInt(333)], None, descr=labeldescr),
         ]
-        self.cpu.compile_bridge(faildescr, [], ops, looptoken)
+        self.cpu.compile_bridge(faildescr, [], ops2, looptoken)
         # run: must not be caught in an infinite loop
-        fail = self.cpu.execute_token(looptoken, 16)
+        deadframe = self.cpu.execute_token(looptoken, 16)
+        fail = self.cpu.get_latest_descr(deadframe)
         assert fail.identifier == 3
-        assert self.cpu.get_latest_value_int(0) == 333
+        assert self.cpu.get_latest_value_int(deadframe, 0) == 333
 
     # pure do_ / descr features
 
     def test_assembler_call(self):
         called = []
         def assembler_helper(failindex, virtualizable):
+            xxxxxxxxxxxx
             assert self.cpu.get_latest_value_int(0) == 97
             called.append(failindex)
             return 4 + 9
             lltype.Ptr(lltype.FuncType(ARGS, RES)), ARGS, RES,
             EffectInfo.MOST_GENERAL)
         args = [i+1 for i in range(10)]
-        res = self.cpu.execute_token(looptoken, *args)
-        assert self.cpu.get_latest_value_int(0) == 55
+        deadframe = self.cpu.execute_token(looptoken, *args)
+        assert self.cpu.get_latest_value_int(deadframe, 0) == 55
         ops = '''
         [i0, i1, i2, i3, i4, i5, i6, i7, i8, i9]
         i10 = int_add(i0, 42)
         othertoken = JitCellToken()
         self.cpu.compile_loop(loop.inputargs, loop.operations, othertoken)
         args = [i+1 for i in range(10)]
-        res = self.cpu.execute_token(othertoken, *args)
-        assert self.cpu.get_latest_value_int(0) == 13
+        deadframe = self.cpu.execute_token(othertoken, *args)
+        assert self.cpu.get_latest_value_int(deadframe, 0) == 13
         assert called == [done_number]
 
         # test the fast path, which should not call assembler_helper()
             othertoken = JitCellToken()
             self.cpu.compile_loop(loop.inputargs, loop.operations, othertoken)
             args = [i+1 for i in range(10)]
-            res = self.cpu.execute_token(othertoken, *args)
-            assert self.cpu.get_latest_value_int(0) == 97
+            deadframe = self.cpu.execute_token(othertoken, *args)
+            assert self.cpu.get_latest_value_int(deadframe, 0) == 97
             assert not called
         finally:
             del self.cpu.done_with_this_frame_int_v
             py.test.skip("requires floats")
         called = []
         def assembler_helper(failindex, virtualizable):
+            xxxxxxxxxxxxx
             x = self.cpu.get_latest_value_float(0)
             assert longlong.getrealfloat(x) == 1.2 + 3.2
             called.append(failindex)
         self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken)
         args = [longlong.getfloatstorage(1.2),
                 longlong.getfloatstorage(2.3)]
-        res = self.cpu.execute_token(looptoken, *args)
-        x = self.cpu.get_latest_value_float(0)
+        deadframe = self.cpu.execute_token(looptoken, *args)
+        x = self.cpu.get_latest_value_float(deadframe, 0)
         assert longlong.getrealfloat(x) == 1.2 + 2.3
         ops = '''
         [f4, f5]
         self.cpu.compile_loop(loop.inputargs, loop.operations, othertoken)
         args = [longlong.getfloatstorage(1.2),
                 longlong.getfloatstorage(3.2)]
-        res = self.cpu.execute_token(othertoken, *args)
-        x = self.cpu.get_latest_value_float(0)
+        deadframe = self.cpu.execute_token(othertoken, *args)
+        x = self.cpu.get_latest_value_float(deadframe, 0)
         assert longlong.getrealfloat(x) == 13.5
         assert called == [done_number]
 
             self.cpu.compile_loop(loop.inputargs, loop.operations, othertoken)
             args = [longlong.getfloatstorage(1.2),
                     longlong.getfloatstorage(3.2)]
-            res = self.cpu.execute_token(othertoken, *args)
-            x = self.cpu.get_latest_value_float(0)
+            deadframe = self.cpu.execute_token(othertoken, *args)
+            x = self.cpu.get_latest_value_float(deadframe, 0)
             assert longlong.getrealfloat(x) == 1.2 + 3.2
             assert not called
         finally:
             py.test.skip("requires floats")
         called = []
         def assembler_helper(failindex, virtualizable):
+            xxxxxxxxxxxx
             x = self.cpu.get_latest_value_float(0)
             assert longlong.getrealfloat(x) == 1.25 + 3.25
             called.append(failindex)
         done_number = self.cpu.get_fail_descr_number(loop.operations[-1].getdescr())
         args = [longlong.getfloatstorage(1.25),
                 longlong.getfloatstorage(2.35)]
-        res = self.cpu.execute_token(looptoken, *args)
-        x = self.cpu.get_latest_value_float(0)
+        deadframe = self.cpu.execute_token(looptoken, *args)
+        x = self.cpu.get_latest_value_float(deadframe, 0)
         assert longlong.getrealfloat(x) == 1.25 + 2.35
         assert not called
 
         # normal call_assembler: goes to looptoken
         args = [longlong.getfloatstorage(1.25),
                 longlong.getfloatstorage(3.25)]
-        res = self.cpu.execute_token(othertoken, *args)
-        x = self.cpu.get_latest_value_float(0)
+        deadframe = self.cpu.execute_token(othertoken, *args)
+        x = self.cpu.get_latest_value_float(deadframe, 0)
         assert longlong.getrealfloat(x) == 13.5
         assert called == [done_number]
         del called[:]
         # now, our call_assembler should go to looptoken2
         args = [longlong.getfloatstorage(6.0),
                 longlong.getfloatstorage(1.5)]         # 6.0-1.5 == 1.25+3.25
-        res = self.cpu.execute_token(othertoken, *args)
-        x = self.cpu.get_latest_value_float(0)
+        deadframe = self.cpu.execute_token(othertoken, *args)
+        x = self.cpu.get_latest_value_float(deadframe, 0)
         assert longlong.getrealfloat(x) == 13.5
         assert called == [done_number]
 
         looptoken = JitCellToken()
         self.cpu.compile_loop(inputargs, operations, looptoken)
         # overflowing value:
-        fail = self.cpu.execute_token(looptoken, sys.maxint // 4 + 1)
+        deadframe = self.cpu.execute_token(looptoken, sys.maxint // 4 + 1)
+        fail = self.cpu.get_latest_descr(deadframe)
         assert fail.identifier == excdescr.identifier
         exc = self.cpu.grab_exc_value()
         assert exc == "memoryerror!"
         operations[6].setfailargs([i1])
 
         self.cpu.compile_loop(inputargs, operations, looptoken)
-        fail = self.cpu.execute_token(looptoken, 2)
+        deadframe = self.cpu.execute_token(looptoken, 2)
+        fail = self.cpu.get_latest_descr(deadframe)
         assert fail.identifier == 2
-        res = self.cpu.get_latest_value_int(0)
+        res = self.cpu.get_latest_value_int(deadframe, 0)
         assert res == 10
 
         inputargs = [i0]
             ]
         self.cpu.compile_bridge(faildescr, inputargs, operations, looptoken)
 
-        fail = self.cpu.execute_token(looptoken, 2)
+        deadframe = self.cpu.execute_token(looptoken, 2)
+        fail = self.cpu.get_latest_descr(deadframe)
         assert fail.identifier == 3
-        res = self.cpu.get_latest_value_int(0)
+        res = self.cpu.get_latest_value_int(deadframe, 0)
         assert res == -10
 
     def test_int_force_ge_zero(self):
         looptoken = JitCellToken()
         self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken)
         for inp, outp in [(2,2), (-3, 0)]:
-            self.cpu.execute_token(looptoken, inp)
-            assert outp == self.cpu.get_latest_value_int(0)
+            deadframe = self.cpu.execute_token(looptoken, inp)
+            assert outp == self.cpu.get_latest_value_int(deadframe, 0)
 
     def test_compile_asmlen(self):
         from pypy.jit.backend.llsupport.llmodel import AbstractLLCPU
             ]
         self.cpu.compile_loop(inputargs, operations, looptoken2)
 
-        fail = self.cpu.execute_token(looptoken2, -9)
+        deadframe = self.cpu.execute_token(looptoken2, -9)
+        fail = self.cpu.get_latest_descr(deadframe)
         assert fail.identifier == 42
 
     def test_wrong_guard_nonnull_class(self):
             ResOperation(rop.FINISH, [], None, descr=BasicFailDescr(99))
         ]
         self.cpu.compile_bridge(faildescr, [], operations, looptoken)
-        fail = self.cpu.execute_token(looptoken, null_box.getref_base())
+        deadframe = self.cpu.execute_token(looptoken, null_box.getref_base())
+        fail = self.cpu.get_latest_descr(deadframe)
         assert fail.identifier == 99
 
     def test_raw_load_int(self):
             loop = parse(ops, self.cpu, namespace=locals())
             looptoken = JitCellToken()
             self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken)
-            self.cpu.execute_token(looptoken,
-                                   rffi.cast(lltype.Signed, p), 16)
-            result = self.cpu.get_latest_value_int(0)
+            deadframe = self.cpu.execute_token(looptoken,
+                                               rffi.cast(lltype.Signed, p), 16)
+            result = self.cpu.get_latest_value_int(deadframe, 0)
             assert result == rffi.cast(lltype.Signed, value)
             rawstorage.free_raw_storage(p)
 
             loop = parse(ops, self.cpu, namespace=locals())
             looptoken = JitCellToken()
             self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken)
-            self.cpu.execute_token(looptoken,
-                                   rffi.cast(lltype.Signed, p), 16)
-            result = self.cpu.get_latest_value_float(0)
+            deadframe = self.cpu.execute_token(looptoken,
+                                               rffi.cast(lltype.Signed, p), 16)
+            result = self.cpu.get_latest_value_float(deadframe, 0)
             result = longlong.getrealfloat(result)
             assert result == rffi.cast(lltype.Float, value)
             rawstorage.free_raw_storage(p)
     def test_forcing_op_with_fail_arg_in_reg(self):
         values = []
         def maybe_force(token, flag):
-            self.cpu.force(token)
-            values.append(self.cpu.get_latest_value_int(0))
+            deadframe = self.cpu.force(token)
+            values.append(self.cpu.get_latest_value_int(deadframe, 0))
             values.append(token)
             return 42
 
         ops[2].setfailargs([i2])
         looptoken = JitCellToken()
         self.cpu.compile_loop([i0, i1], ops, looptoken)
-        fail = self.cpu.execute_token(looptoken, 20, 0)
+        deadframe = self.cpu.execute_token(looptoken, 20, 0)
+        fail = self.cpu.get_latest_descr(deadframe)
         assert fail.identifier == 23
-        assert self.cpu.get_latest_value_int(0) == 42
+        assert self.cpu.get_latest_value_int(deadframe, 0) == 42
         # make sure that force reads the registers from a zeroed piece of
         # memory
         assert values[0] == 0
         token = self.cpu.get_latest_force_token()
         assert values[1] == token
-
-class OOtypeBackendTest(BaseBackendTest):
-
-    type_system = 'ootype'
-    Ptr = staticmethod(lambda x: x)
-    FuncType = ootype.StaticMethod
-    malloc = staticmethod(ootype.new)
-    nullptr = staticmethod(ootype.null)
-
-    def setup_class(cls):
-        py.test.skip("ootype tests skipped")
-
-    @classmethod
-    def get_funcbox(cls, cpu, func_ptr):
-        return BoxObj(ootype.cast_to_object(func_ptr))
-
-    S = ootype.Instance('S', ootype.ROOT, {'value': ootype.Signed,
-                                           'chr1': ootype.Char,
-                                           'chr2': ootype.Char})
-    S._add_fields({'next': S})
-    T = ootype.Instance('T', S)
-    U = ootype.Instance('U', T)
-
-    def alloc_instance(self, T):
-        t = ootype.new(T)
-        cls = ootype.classof(t)
-        t_box = BoxObj(ootype.cast_to_object(t))
-        T_box = ConstObj(ootype.cast_to_object(cls))
-        return t_box, T_box
-
-    def null_instance(self):
-        return BoxObj(ootype.NULL)
-
-    def alloc_array_of(self, ITEM, length):
-        py.test.skip("implement me")
-
-    def alloc_string(self, string):
-        py.test.skip("implement me")
-
-    def alloc_unicode(self, unicode):
-        py.test.skip("implement me")
-

pypy/jit/metainterp/resoperation.py

             result = self.result
         if descr is None:
             descr = self.getdescr()
-        newop = ResOperation(opnum, args, result, descr)
+        newop = self.__class__(result)
+        newop.initarglist(args)
+        if descr is not None:
+            assert isinstance(newop, ResOpWithDescr)
+            newop.setdescr(descr)
         return newop
 
     def clone(self):

pypy/jit/tool/oparser.py

 
     OPNUM = -123
 
-    def __init__(self, opnum, args, result, descr=None):
-        assert opnum == self.OPNUM
-        self.result = result
-        self.initarglist(args)
-        self.setdescr(descr)
-
     def getopnum(self):
         return self.OPNUM
 
+    def getopname(self):
+        return 'escape'
+
     def clone(self):
-        return ESCAPE_OP(self.OPNUM, self.getarglist()[:], self.result, self.getdescr())
+        op = ESCAPE_OP(self.result)
+        op.initarglist(self.getarglist()[:])
+        return op
 
 class FORCE_SPILL(UnaryOp, PlainResOp):
 
     OPNUM = -124
 
-    def __init__(self, opnum, args, result=None, descr=None):
-        assert result is None
-        assert descr is None
-        assert opnum == self.OPNUM
-        self.result = result
-        self.initarglist(args)
-
     def getopnum(self):
         return self.OPNUM
 
+    def getopname(self):
+        return 'force_spill'
+
     def clone(self):
-        return FORCE_SPILL(self.OPNUM, self.getarglist()[:])
+        op = FORCE_SPILL(self.result)
+        op.initarglist(self.getarglist()[:])
+        return op
 
 
 def default_fail_descr(model, fail_args=None):
 
     def create_op(self, opnum, args, result, descr):
         if opnum == ESCAPE_OP.OPNUM:
-            return ESCAPE_OP(opnum, args, result, descr)
+            op = ESCAPE_OP(result)
+            op.initarglist(args)
+            assert descr is None
+            return op
         if opnum == FORCE_SPILL.OPNUM:
-            return FORCE_SPILL(opnum, args, result, descr)
+            op = FORCE_SPILL(result)
+            op.initarglist(args)
+            assert descr is None
+            return op
         else:
             return ResOperation(opnum, args, result, descr)