[pypy-svn] r74543 - in pypy/branch/blackhole-improvement/pypy/jit: backend backend/llgraph backend/x86 codewriter codewriter/test metainterp metainterp/test

arigo at codespeak.net arigo at codespeak.net
Tue May 18 17:04:46 CEST 2010


Author: arigo
Date: Tue May 18 17:04:44 2010
New Revision: 74543

Modified:
   pypy/branch/blackhole-improvement/pypy/jit/backend/llgraph/llimpl.py
   pypy/branch/blackhole-improvement/pypy/jit/backend/llgraph/runner.py
   pypy/branch/blackhole-improvement/pypy/jit/backend/model.py
   pypy/branch/blackhole-improvement/pypy/jit/backend/x86/assembler.py
   pypy/branch/blackhole-improvement/pypy/jit/backend/x86/support.py
   pypy/branch/blackhole-improvement/pypy/jit/codewriter/assembler.py
   pypy/branch/blackhole-improvement/pypy/jit/codewriter/flatten.py
   pypy/branch/blackhole-improvement/pypy/jit/codewriter/jitcode.py
   pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_assembler.py
   pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_codewriter.py
   pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_flatten.py
   pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_format.py
   pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_jitcode.py
   pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_liveness.py
   pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_regalloc.py
   pypy/branch/blackhole-improvement/pypy/jit/metainterp/blackhole.py
   pypy/branch/blackhole-improvement/pypy/jit/metainterp/compile.py
   pypy/branch/blackhole-improvement/pypy/jit/metainterp/pyjitpl.py
   pypy/branch/blackhole-improvement/pypy/jit/metainterp/resume.py
   pypy/branch/blackhole-improvement/pypy/jit/metainterp/test/test_basic.py
   pypy/branch/blackhole-improvement/pypy/jit/metainterp/typesystem.py
   pypy/branch/blackhole-improvement/pypy/jit/metainterp/warmspot.py
   pypy/branch/blackhole-improvement/pypy/jit/metainterp/warmstate.py
Log:
Start hooking the blackhole interpreter to the rest of the metainterp.


Modified: pypy/branch/blackhole-improvement/pypy/jit/backend/llgraph/llimpl.py
==============================================================================
--- pypy/branch/blackhole-improvement/pypy/jit/backend/llgraph/llimpl.py	(original)
+++ pypy/branch/blackhole-improvement/pypy/jit/backend/llgraph/llimpl.py	Tue May 18 17:04:44 2010
@@ -1063,17 +1063,38 @@
 
 def frame_int_getvalue(frame, num):
     frame = _from_opaque(frame)
+    assert num >= 0
     return frame.fail_args[num]
 
 def frame_float_getvalue(frame, num):
     frame = _from_opaque(frame)
+    assert num >= 0
     return frame.fail_args[num]
 
 def frame_ptr_getvalue(frame, num):
     frame = _from_opaque(frame)
-    result = frame.fail_args[num]
-    frame.fail_args[num] = None
-    return result
+    assert num >= 0
+    return frame.fail_args[num]
+
+def frame_get_value_kind(frame, num):
+    frame = _from_opaque(frame)
+    assert num >= 0
+    TYPE = lltype.typeOf(frame.fail_args[num])
+    if TYPE is lltype.Signed:
+        return INT
+    if TYPE == llmemory.GCREF:
+        return REF
+    if TYPE is lltype.Float:
+        return FLOAT
+    raise TypeError("frame.fail_args[%d] is of type %r" % (num, TYPE))
+
+def get_latest_value_count(frame):
+    frame = _from_opaque(frame)
+    return len(frame.fail_args)
+
+def frame_clear_latest_values(frame):
+    frame = _from_opaque(frame)
+    del frame.fail_args
 
 _last_exception = None
 

Modified: pypy/branch/blackhole-improvement/pypy/jit/backend/llgraph/runner.py
==============================================================================
--- pypy/branch/blackhole-improvement/pypy/jit/backend/llgraph/runner.py	(original)
+++ pypy/branch/blackhole-improvement/pypy/jit/backend/llgraph/runner.py	Tue May 18 17:04:44 2010
@@ -243,26 +243,18 @@
     def get_latest_value_float(self, index):
         return llimpl.frame_float_getvalue(self.latest_frame, index)
 
+    def get_latest_value_kind(self, index):
+        return llimpl.frame_get_value_kind(self.latest_frame, index)
+
+    def get_latest_value_count(self):
+        return llimpl.frame_get_value_count(self.latest_frame)
+
     def get_latest_force_token(self):
         token = llimpl.get_frame_forced_token(self.latest_frame)
         return self.cast_adr_to_int(token)
 
-    def make_boxes_from_latest_values(self, faildescr):
-        inputargs_and_holes = []
-        for i in range(len(faildescr._fail_args_types)):
-            boxtype = faildescr._fail_args_types[i]
-            if boxtype == history.INT:
-                box = history.BoxInt(self.get_latest_value_int(i))
-            elif boxtype == history.REF:
-                box = self.ts.BoxRef(self.get_latest_value_ref(i))
-            elif boxtype == history.FLOAT:
-                box = history.BoxFloat(self.get_latest_value_float(i))
-            elif boxtype == history.HOLE:
-                box = None
-            else:
-                assert False, "bad box type: num=%d" % ord(boxtype)
-            inputargs_and_holes.append(box)
-        return inputargs_and_holes
+    def clear_latest_values(self):
+        llimpl.frame_clear_latest_values(self.latest_frame)
 
     # ----------
 

Modified: pypy/branch/blackhole-improvement/pypy/jit/backend/model.py
==============================================================================
--- pypy/branch/blackhole-improvement/pypy/jit/backend/model.py	(original)
+++ pypy/branch/blackhole-improvement/pypy/jit/backend/model.py	Tue May 18 17:04:44 2010
@@ -85,15 +85,24 @@
         or from 'args' if it was a FINISH).  Returns a ptr or an obj."""
         raise NotImplementedError
 
+    def get_latest_value_kind(self, index):
+        """Return the kind (history.INT, REF or FLOAT) of the index'th
+        argument to the last executed operation."""
+        raise NotImplementedError
+
+    def get_latest_value_count(self):
+        """Return how many values are ready to be returned by
+        get_latest_value_xxx()."""
+        raise NotImplementedError
+
     def get_latest_force_token(self):
         """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 make_boxes_from_latest_value(self, faildescr):
-        """Build a list of Boxes (and None for holes) that contains
-        the current values, as would be returned by calls to
-        get_latest_value_xxx()."""
+    def clear_latest_values(self):
+        """Clear the latest values (at least the ref ones, so that
+        they no longer keep objects alive)."""
         raise NotImplementedError
 
     def get_exception(self):

Modified: pypy/branch/blackhole-improvement/pypy/jit/backend/x86/assembler.py
==============================================================================
--- pypy/branch/blackhole-improvement/pypy/jit/backend/x86/assembler.py	(original)
+++ pypy/branch/blackhole-improvement/pypy/jit/backend/x86/assembler.py	Tue May 18 17:04:44 2010
@@ -1081,13 +1081,8 @@
                 n = self.CODE_HOLE
             mc.writechr(n)
         mc.writechr(self.CODE_STOP)
-        # preallocate the fail_boxes
-        i = len(failargs) - 1
-        if i >= 0:
-            self.fail_boxes_int.get_addr_for_num(i)
-            self.fail_boxes_ptr.get_addr_for_num(i)
-            if self.cpu.supports_floats:
-                self.fail_boxes_float.get_addr_for_num(i)
+        # assert that the fail_boxes lists are big enough
+        assert len(failargs) <= self.fail_boxes_int.SIZE
 
     def rebuild_faillocs_from_descr(self, bytecode):
         from pypy.jit.backend.x86.regalloc import X86FrameManager

Modified: pypy/branch/blackhole-improvement/pypy/jit/backend/x86/support.py
==============================================================================
--- pypy/branch/blackhole-improvement/pypy/jit/backend/x86/support.py	(original)
+++ pypy/branch/blackhole-improvement/pypy/jit/backend/x86/support.py	Tue May 18 17:04:44 2010
@@ -4,6 +4,8 @@
     ATP = lltype.GcArray(TP)
     
     class ValuesArray(object):
+        SIZE = size
+
         def __init__(self):
             self.ar = lltype.malloc(ATP, size, zero=True, immortal=True)
 

Modified: pypy/branch/blackhole-improvement/pypy/jit/codewriter/assembler.py
==============================================================================
--- pypy/branch/blackhole-improvement/pypy/jit/codewriter/assembler.py	(original)
+++ pypy/branch/blackhole-improvement/pypy/jit/codewriter/assembler.py	Tue May 18 17:04:44 2010
@@ -47,6 +47,7 @@
         self.liveness = {}
         self.nextlive = None
         self.startpoints = set()
+        self.alllabels = set()
 
     def emit_reg(self, reg):
         if reg.index >= self.count_regs[reg.kind]:
@@ -113,6 +114,7 @@
                 else:
                     argcodes.append(kind[0])
             elif isinstance(x, TLabel):
+                self.alllabels.add(len(self.code))
                 self.tlabel_positions.append((x.name, len(self.code)))
                 self.code.append("temp 1")
                 self.code.append("temp 2")
@@ -194,4 +196,5 @@
                       self.count_regs['ref'],
                       self.count_regs['float'],
                       liveness=self.liveness,
-                      startpoints=self.startpoints)
+                      startpoints=self.startpoints,
+                      alllabels=self.alllabels)

Modified: pypy/branch/blackhole-improvement/pypy/jit/codewriter/flatten.py
==============================================================================
--- pypy/branch/blackhole-improvement/pypy/jit/codewriter/flatten.py	(original)
+++ pypy/branch/blackhole-improvement/pypy/jit/codewriter/flatten.py	Tue May 18 17:04:44 2010
@@ -210,8 +210,8 @@
                 assert block.exitswitch.concretetype == lltype.Bool
                 opargs = [block.exitswitch]
             #
-            self.emitline(opname, TLabel(linkfalse),
-                          *self.flatten_list(opargs))
+            lst = self.flatten_list(opargs) + [TLabel(linkfalse)]
+            self.emitline(opname, *lst)
             # true path:
             self.make_link(linktrue)
             # false path:
@@ -258,10 +258,10 @@
                 for switch in switches:
                     # make the case described by 'switch'
                     self.emitline('goto_if_not_int_eq',
-                                  TLabel(switch),
                                   color,
                                   Constant(switch.llexitcase,
-                                           block.exitswitch.concretetype))
+                                           block.exitswitch.concretetype),
+                                  TLabel(switch))
                     # emit code for the "taken" path
                     self.make_link(switch)
                     # finally, emit the label for the "non-taken" path

Modified: pypy/branch/blackhole-improvement/pypy/jit/codewriter/jitcode.py
==============================================================================
--- pypy/branch/blackhole-improvement/pypy/jit/codewriter/jitcode.py	(original)
+++ pypy/branch/blackhole-improvement/pypy/jit/codewriter/jitcode.py	Tue May 18 17:04:44 2010
@@ -16,31 +16,33 @@
         self._ssarepr     = None          # debugging
 
     def setup(self, code='', constants_i=[], constants_r=[], constants_f=[],
-              num_regs_i=256, num_regs_r=256, num_regs_f=256,
-              liveness=None, startpoints=None):
+              num_regs_i=255, num_regs_r=255, num_regs_f=255,
+              liveness=None, startpoints=None, alllabels=None):
         self.code = code
         # if the following lists are empty, use a single shared empty list
         self.constants_i = constants_i or self._empty_i
         self.constants_r = constants_r or self._empty_r
         self.constants_f = constants_f or self._empty_f
         # encode the three num_regs into a single integer
-        self.num_regs_encoded = ((num_regs_i << 18) |
-                                 (num_regs_f << 9) |
+        assert num_regs_i < 256 and num_regs_r < 256 and num_regs_f < 256
+        self.num_regs_encoded = ((num_regs_i << 16) |
+                                 (num_regs_f << 8) |
                                  (num_regs_r << 0))
         self.liveness = liveness
         self._startpoints = startpoints   # debugging
+        self._alllabels = alllabels       # debugging
 
     def get_fnaddr_as_int(self):
         return llmemory.cast_adr_to_int(self.fnaddr)
 
     def num_regs_i(self):
-        return self.num_regs_encoded >> 18
+        return self.num_regs_encoded >> 16
 
     def num_regs_f(self):
-        return (self.num_regs_encoded >> 9) & 0x1FF
+        return (self.num_regs_encoded >> 8) & 0xFF
 
     def num_regs_r(self):
-        return self.num_regs_encoded & 0x1FF
+        return self.num_regs_encoded & 0xFF
 
     def has_liveness_info(self, pc):
         return pc in self.liveness

Modified: pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_assembler.py
==============================================================================
--- pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_assembler.py	(original)
+++ pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_assembler.py	Tue May 18 17:04:44 2010
@@ -93,7 +93,7 @@
     i0, i1 = Register('int', 0x16), Register('int', 0x17)
     ssarepr.insns = [
         (Label('L1'),),
-        ('goto_if_not_int_gt', TLabel('L2'), i0, Constant(4, lltype.Signed)),
+        ('goto_if_not_int_gt', i0, Constant(4, lltype.Signed), TLabel('L2')),
         ('int_add', i1, i0, i1),
         ('int_sub', i0, Constant(1, lltype.Signed), i0),
         ('goto', TLabel('L1')),
@@ -102,12 +102,12 @@
         ]
     assembler = Assembler()
     jitcode = assembler.assemble(ssarepr)
-    assert jitcode.code == ("\x00\x10\x00\x16\x04"
+    assert jitcode.code == ("\x00\x16\x04\x10\x00"
                             "\x01\x17\x16\x17"
                             "\x02\x16\x01\x16"
                             "\x03\x00\x00"
                             "\x04\x17")
-    assert assembler.insns == {'goto_if_not_int_gt/Lic': 0,
+    assert assembler.insns == {'goto_if_not_int_gt/icL': 0,
                                'int_add/iii': 1,
                                'int_sub/ici': 2,
                                'goto/L': 3,

Modified: pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_codewriter.py
==============================================================================
--- pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_codewriter.py	(original)
+++ pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_codewriter.py	Tue May 18 17:04:44 2010
@@ -30,12 +30,12 @@
         return b
     cw = CodeWriter()
     jitcode = cw.transform_func_to_jitcode(f, [5, 6])
-    assert jitcode.code == ("\x00\x10\x00\x00\x00"   # ends at 5
+    assert jitcode.code == ("\x00\x00\x00\x10\x00"   # ends at 5
                             "\x01\x01\x00\x01"
                             "\x02\x00\x01\x00"
                             "\x03\x00\x00"
                             "\x04\x01")
-    assert cw.assembler.insns == {'goto_if_not_int_gt/Lic': 0,
+    assert cw.assembler.insns == {'goto_if_not_int_gt/icL': 0,
                                   'int_add/iii': 1,
                                   'int_sub/ici': 2,
                                   'goto/L': 3,
@@ -82,7 +82,8 @@
     jitcode = cw.transform_func_to_jitcode(f, [5, 6])
     blackholeinterpbuilder = BlackholeInterpBuilder(cw)
     blackholeinterp = blackholeinterpbuilder.acquire_interp()
+    blackholeinterp.setposition(jitcode, 0)
     blackholeinterp.setarg_i(0, 6)
     blackholeinterp.setarg_i(1, 100)
-    blackholeinterp.run(jitcode, 0)
+    blackholeinterp.run()
     assert blackholeinterp.get_result_i() == 100+6+5+4+3

Modified: pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_flatten.py
==============================================================================
--- pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_flatten.py	(original)
+++ pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_flatten.py	Tue May 18 17:04:44 2010
@@ -120,7 +120,7 @@
             int_copy %i1, %i3
             L1:
             int_gt %i2, $0, %i4
-            goto_if_not L2, %i4
+            goto_if_not %i4, L2
             int_copy %i2, %i5
             int_copy %i3, %i6
             int_add %i6, %i5, %i7
@@ -142,7 +142,7 @@
             int_copy %i0, %i2
             int_copy %i1, %i3
             L1:
-            goto_if_not_int_gt L2, %i2, $0
+            goto_if_not_int_gt %i2, $0, L2
             int_copy %i2, %i4
             int_copy %i3, %i5
             int_add %i5, %i4, %i6
@@ -210,13 +210,13 @@
             else:        return 42
         self.encoding_test(f, [65], """
             int_guard_value %i0, %i0
-            goto_if_not_int_eq L1, %i0, $-5
+            goto_if_not_int_eq %i0, $-5, L1
             int_return $12
             L1:
-            goto_if_not_int_eq L2, %i0, $2
+            goto_if_not_int_eq %i0, $2, L2
             int_return $51
             L2:
-            goto_if_not_int_eq L3, %i0, $7
+            goto_if_not_int_eq %i0, $7, L3
             int_return $1212
             L3:
             int_return $42
@@ -342,7 +342,7 @@
         # note that 'goto_if_not_int_is_true' is actually the same thing
         # as just 'goto_if_not'.
         self.encoding_test(f, [7], """
-            goto_if_not L1, %i0
+            goto_if_not %i0, L1
             int_return $False
             L1:
             int_return $True

Modified: pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_format.py
==============================================================================
--- pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_format.py	(original)
+++ pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_format.py	Tue May 18 17:04:44 2010
@@ -52,7 +52,7 @@
     i0, i1 = Register('int', 0), Register('int', 1)
     ssarepr.insns = [
         (Label('L1'),),
-        ('goto_if_not_int_gt', TLabel('L2'), i0, Constant(0, lltype.Signed)),
+        ('goto_if_not_int_gt', i0, Constant(0, lltype.Signed), TLabel('L2')),
         ('int_add', i1, i0, i1),
         ('int_sub', i0, Constant(1, lltype.Signed), i0),
         ('goto', TLabel('L1')),
@@ -62,7 +62,7 @@
     asm = format_assembler(ssarepr)
     expected = """
         L1:
-        goto_if_not_int_gt L2, %i0, $0
+        goto_if_not_int_gt %i0, $0, L2
         int_add %i1, %i0, %i1
         int_sub %i0, $1, %i0
         goto L1

Modified: pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_jitcode.py
==============================================================================
--- pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_jitcode.py	(original)
+++ pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_jitcode.py	Tue May 18 17:04:44 2010
@@ -11,10 +11,10 @@
     assert j.num_regs_i() == 0
     assert j.num_regs_r() == 0
     assert j.num_regs_f() == 0
-    j.setup(num_regs_i=256, num_regs_r=256, num_regs_f=256)
-    assert j.num_regs_i() == 256
-    assert j.num_regs_r() == 256
-    assert j.num_regs_f() == 256
+    j.setup(num_regs_i=255, num_regs_r=255, num_regs_f=255)
+    assert j.num_regs_i() == 255
+    assert j.num_regs_r() == 255
+    assert j.num_regs_f() == 255
 
 def test_liveness():
     j = JitCode("test")

Modified: pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_liveness.py
==============================================================================
--- pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_liveness.py	(original)
+++ pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_liveness.py	Tue May 18 17:04:44 2010
@@ -66,7 +66,7 @@
             -live- %i0, %i1
             G_int_add %i0, $5, %i2
             int_is_true %i2, %i3
-            goto_if_not L1, %i3
+            goto_if_not %i3, L1
             int_copy %i0, %i4
             -live-
             G_int_add %i4, $1, %i5
@@ -87,7 +87,7 @@
             -live- %i0, %i1
             G_int_add %i0, $5, %i2
             int_is_true %i2, %i3
-            goto_if_not L1, %i3
+            goto_if_not %i3, L1
             int_copy %i0, %i4
             int_copy %i1, %i5
             -live-
@@ -109,7 +109,7 @@
             -live- %i0
             G_int_add %i0, %i1, %i2
             int_is_true %i2, %i3
-            goto_if_not L1, %i3
+            goto_if_not %i3, L1
             int_copy %i0, %i4
             -live-
             G_int_add %i4, $5, %i5
@@ -129,7 +129,7 @@
         self.encoding_test(f, [5, 6], """
             int_is_true %i0, %i2
             -live- %i0, %i1
-            goto_if_not L1, %i2
+            goto_if_not %i2, L1
             int_return %i0
             L1:
             int_return %i1

Modified: pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_regalloc.py
==============================================================================
--- pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_regalloc.py	(original)
+++ pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_regalloc.py	Tue May 18 17:04:44 2010
@@ -59,7 +59,7 @@
         self.check_assembler(graph, """
             L1:
             int_gt %i0, $0, %i2
-            goto_if_not L2, %i2
+            goto_if_not %i2, L2
             int_add %i1, %i0, %i1
             int_sub %i0, $1, %i0
             goto L1
@@ -76,7 +76,7 @@
         self.check_assembler(graph, """
             L1:
             int_gt %i0, $0, %i2
-            goto_if_not L2, %i2
+            goto_if_not %i2, L2
             int_push %i1
             int_copy %i0, %i1
             int_pop %i0
@@ -94,7 +94,7 @@
         self.check_assembler(graph, """
             L1:
             int_gt %i0, $0, %i0
-            goto_if_not L2, %i0
+            goto_if_not %i0, L2
             int_copy %i1, %i0
             int_copy $2, %i1
             goto L1
@@ -111,7 +111,7 @@
         self.check_assembler(graph, """
             L1:
             int_gt %i0, $0, %i3
-            goto_if_not L2, %i3
+            goto_if_not %i3, L2
             int_push %i1
             int_copy %i2, %i1
             int_copy %i0, %i2
@@ -130,7 +130,7 @@
         self.check_assembler(graph, """
             L1:
             int_gt %i0, $0, %i3
-            goto_if_not L2, %i3
+            goto_if_not %i3, L2
             int_copy %i2, %i1
             goto L1
             L2:

Modified: pypy/branch/blackhole-improvement/pypy/jit/metainterp/blackhole.py
==============================================================================
--- pypy/branch/blackhole-improvement/pypy/jit/metainterp/blackhole.py	(original)
+++ pypy/branch/blackhole-improvement/pypy/jit/metainterp/blackhole.py	Tue May 18 17:04:44 2010
@@ -1,6 +1,7 @@
 from pypy.rlib.unroll import unrolling_iterable
 from pypy.rlib.rarithmetic import intmask, LONG_BIT, r_uint, ovfcheck
 from pypy.rlib.objectmodel import we_are_translated
+from pypy.rlib.debug import debug_start, debug_stop
 from pypy.rlib.debug import make_sure_not_resized
 from pypy.rpython.lltypesystem import lltype, llmemory, rclass
 from pypy.rpython.lltypesystem.lloperation import llop
@@ -53,10 +54,11 @@
 class BlackholeInterpBuilder(object):
     verbose = True
 
-    def __init__(self, codewriter):
+    def __init__(self, codewriter, metainterp_sd=None):
         self.cpu = codewriter.cpu
         self.setup_insns(codewriter.assembler.insns)
         self.setup_descrs(codewriter.assembler.descrs)
+        self.metainterp_sd = metainterp_sd
         self._freeze_()
 
     def _freeze_(self):
@@ -81,7 +83,7 @@
         def dispatch_loop(self, code, position):
             while True:
                 if not we_are_translated():
-                    assert position in self._current_jitcode._startpoints, (
+                    assert position in self.jitcode._startpoints, (
                         "the current position %d is in the middle of "
                         "an instruction!" % position)
                 opcode = ord(code[position])
@@ -233,18 +235,18 @@
             return BlackholeInterpreter(self)
 
     def release_interp(self, interp):
-        interp.cleanup_registers_r()
+        interp.cleanup_registers()
         self.blackholeinterps.append(interp)
 
 
 class BlackholeInterpreter(object):
 
     def __init__(self, builder):
+        self.builder            = builder
         self.cpu                = builder.cpu
         self.dispatch_loop      = builder.dispatch_loop
         self.descrs             = builder.descrs
         self.op_catch_exception = builder.op_catch_exception
-        self.cleanup_required_in_registers_r = 0
         #
         if we_are_translated():
             default_i = 0
@@ -257,6 +259,19 @@
         self.registers_i = [default_i] * 256
         self.registers_r = [default_r] * 256
         self.registers_f = [default_f] * 256
+        self.jitcode = None
+
+    def setposition(self, jitcode, position):
+        if jitcode is not self.jitcode:
+            # the real performance impact of the following code is unclear,
+            # but it should be minimized by the fact that a given
+            # BlackholeInterpreter instance is likely to be reused with
+            # exactly the same jitcode, so we don't do the copy again.
+            self.copy_constants(self.registers_i, jitcode.constants_i)
+            self.copy_constants(self.registers_r, jitcode.constants_r)
+            self.copy_constants(self.registers_f, jitcode.constants_f)
+        self.jitcode = jitcode
+        self.position = position
 
     def setarg_i(self, index, value):
         self.registers_i[index] = value
@@ -267,21 +282,14 @@
     def setarg_f(self, index, value):
         self.registers_f[index] = value
 
-    def run(self, jitcode, position):
-        if not we_are_translated():
-            self._current_jitcode = jitcode
-        self.copy_constants(self.registers_i, jitcode.constants_i)
-        self.copy_constants(self.registers_r, jitcode.constants_r)
-        self.copy_constants(self.registers_f, jitcode.constants_f)
-        code = jitcode.code
-        self.cleanup_required_in_registers_r = max(
-            self.cleanup_required_in_registers_r,
-            jitcode.num_regs_r())
+    def run(self):
+        code = self.jitcode.code
+        position = self.position
         while True:
             try:
                 self.dispatch_loop(self, code, position)
             except LeaveFrame:
-                return
+                break
             except Exception, e:
                 e = get_llexception(self.cpu, e)
                 position = self.handle_exception_in_frame(e, code)
@@ -290,7 +298,12 @@
         return self.tmpreg_i
 
     def get_result_r(self):
-        return self.tmpreg_r
+        result = self.tmpreg_r
+        if we_are_translated():
+            self.tmpreg_r = NULL
+        else:
+            del self.tmpreg_r
+        return result
 
     def get_result_f(self):
         return self.tmpreg_f
@@ -303,14 +316,12 @@
         if self._return_type == 'void': return None
         raise ValueError(self._return_type)
 
-    def cleanup_registers_r(self):
+    def cleanup_registers(self):
         # To avoid keeping references alive, this cleans up the registers_r.
         # It does not clear the references set by copy_constants(), but
         # these are all prebuilt constants anyway.
-        for i in range(self.cleanup_required_in_registers_r):
+        for i in range(self.jitcode.num_regs_r()):
             self.registers_r[i] = NULL
-        self.cleanup_required_in_registers_r = 0
-        self.tmpreg_r = NULL
         self.exception_last_value = None
 
     def handle_exception_in_frame(self, e, code):
@@ -330,11 +341,12 @@
             return target
 
     # XXX must be specialized
-    # XXX the real performance impact of the following loop is unclear
     def copy_constants(self, registers, constants):
         """Copy jitcode.constants[0] to registers[255],
                 jitcode.constants[1] to registers[254],
                 jitcode.constants[2] to registers[253], etc."""
+        make_sure_not_resized(registers)
+        make_sure_not_resized(constants)
         i = len(constants) - 1
         while i >= 0:
             j = 255 - i
@@ -342,6 +354,18 @@
             registers[j] = constants[i]
             i -= 1
 
+    def follow_jump(self):
+        """Assuming that self.position points just after a bytecode
+        instruction that ends with a label, follow that label."""
+        code = self.jitcode.code
+        position = self.position - 2
+        assert position >= 0
+        if not we_are_translated():
+            assert position in self.jitcode._alllabels
+        labelvalue = ord(code[position]) | (ord(code[position+1])<<8)
+        assert labelvalue < len(code)
+        self.position = labelvalue
+
     # ----------
 
     @arguments("i", "i", returns="i")
@@ -497,13 +521,13 @@
 
     @arguments("self", returns="i")
     def bhimpl_int_pop(self):
-        return self.tmpreg_i
+        return self.get_result_i()
     @arguments("self", returns="r")
     def bhimpl_ref_pop(self):
-        return self.tmpreg_r
+        return self.get_result_r()
     @arguments("self", returns="f")
     def bhimpl_float_pop(self):
-        return self.tmpreg_f
+        return self.get_result_f()
 
     # ----------
     # float operations
@@ -590,85 +614,85 @@
             self._return_type = "void"
         raise LeaveFrame
 
-    @arguments("L", "i", "pc", returns="L")
-    def bhimpl_goto_if_not(target, a, pc):
+    @arguments("i", "L", "pc", returns="L")
+    def bhimpl_goto_if_not(a, target, pc):
         if a:
             return pc
         else:
             return target
 
-    @arguments("L", "i", "i", "pc", returns="L")
-    def bhimpl_goto_if_not_int_lt(target, a, b, pc):
+    @arguments("i", "i", "L", "pc", returns="L")
+    def bhimpl_goto_if_not_int_lt(a, b, target, pc):
         if a < b:
             return pc
         else:
             return target
 
-    @arguments("L", "i", "i", "pc", returns="L")
-    def bhimpl_goto_if_not_int_le(target, a, b, pc):
+    @arguments("i", "i", "L", "pc", returns="L")
+    def bhimpl_goto_if_not_int_le(a, b, target, pc):
         if a <= b:
             return pc
         else:
             return target
 
-    @arguments("L", "i", "i", "pc", returns="L")
-    def bhimpl_goto_if_not_int_eq(target, a, b, pc):
+    @arguments("i", "i", "L", "pc", returns="L")
+    def bhimpl_goto_if_not_int_eq(a, b, target, pc):
         if a == b:
             return pc
         else:
             return target
 
-    @arguments("L", "i", "i", "pc", returns="L")
-    def bhimpl_goto_if_not_int_ne(target, a, b, pc):
+    @arguments("i", "i", "L", "pc", returns="L")
+    def bhimpl_goto_if_not_int_ne(a, b, target, pc):
         if a != b:
             return pc
         else:
             return target
 
-    @arguments("L", "i", "i", "pc", returns="L")
-    def bhimpl_goto_if_not_int_gt(target, a, b, pc):
+    @arguments("i", "i", "L", "pc", returns="L")
+    def bhimpl_goto_if_not_int_gt(a, b, target, pc):
         if a > b:
             return pc
         else:
             return target
 
-    @arguments("L", "i", "i", "pc", returns="L")
-    def bhimpl_goto_if_not_int_ge(target, a, b, pc):
+    @arguments("i", "i", "L", "pc", returns="L")
+    def bhimpl_goto_if_not_int_ge(a, b, target, pc):
         if a >= b:
             return pc
         else:
             return target
 
-    @arguments("L", "i", "pc", returns="L")
-    def bhimpl_goto_if_not_int_is_zero(target, a, pc):
+    @arguments("i", "L", "pc", returns="L")
+    def bhimpl_goto_if_not_int_is_zero(a, target, pc):
         if not a:
             return pc
         else:
             return target
 
-    @arguments("L", "r", "r", "pc", returns="L")
-    def bhimpl_goto_if_not_ptr_eq(target, a, b, pc):
+    @arguments("r", "r", "L", "pc", returns="L")
+    def bhimpl_goto_if_not_ptr_eq(a, b, target, pc):
         if a == b:
             return pc
         else:
             return target
 
-    @arguments("L", "r", "r", "pc", returns="L")
-    def bhimpl_goto_if_not_ptr_ne(target, a, b, pc):
+    @arguments("r", "r", "L", "pc", returns="L")
+    def bhimpl_goto_if_not_ptr_ne(a, b, target, pc):
         if a != b:
             return pc
         else:
             return target
 
-    @arguments("L", "r", "pc", returns="L")
-    def bhimpl_goto_if_not_ptr_iszero(target, a, pc):
+    @arguments("r", "L", "pc", returns="L")
+    def bhimpl_goto_if_not_ptr_iszero(a, target, pc):
         if not a:
             return pc
         else:
             return target
 
-    @arguments("L", "r", "pc", returns="L")
-    def bhimpl_goto_if_not_ptr_nonzero(target, a, pc):
+    @arguments("r", "L", "pc", returns="L")
+    def bhimpl_goto_if_not_ptr_nonzero(a, target, pc):
         if a:
             return pc
         else:
@@ -729,6 +753,15 @@
         assert real_instance
         raise real_instance
 
+    @arguments()
+    def bhimpl_can_enter_jit():
+        pass
+
+    @arguments("self", "I", "R", "F", "I", "R", "F")
+    def bhimpl_jit_merge_point(self, *results):
+        CRN = self.builder.metainterp_sd.ContinueRunningNormally
+        raise CRN(*results)
+
     # ----------
     # the following operations are directly implemented by the backend
 
@@ -904,3 +937,60 @@
     @arguments("cpu", "r", "i", "i")
     def bhimpl_unicodesetitem(cpu, unicode, index, newchr):
         cpu.bh_unicodesetitem(unicode, index, newchr)
+
+# ____________________________________________________________
+
+def resume_in_blackhole(metainterp_sd, resumedescr):
+    from pypy.jit.metainterp.resume import blackhole_from_resumedata
+    debug_start('jit-blackhole')
+    metainterp_sd.profiler.start_blackhole()
+    blackholeinterp = blackhole_from_resumedata(
+        metainterp_sd.blackholeinterpbuilder,
+        resumedescr,
+        False)  # XXX
+    # XXX virtualrefs
+    # XXX virtualizable
+    _prepare_resume_from_failure(blackholeinterp, resumedescr.guard_opnum)
+    try:
+        blackholeinterp = _resume_mainloop(
+            metainterp_sd.blackholeinterpbuilder, blackholeinterp)
+    finally:
+        metainterp_sd.profiler.end_blackhole()
+        debug_stop('jit-blackhole')
+    # rare case: we only get there if the blackhole interps all returned
+    # normally (in general we get a ContinueRunningNormally exception).
+    _done_with_this_frame(blackholeinterp)
+
+def _resume_mainloop(blackholeinterpbuilder, blackholeinterp):
+    while True:
+        try:
+            blackholeinterp.run()
+        finally:
+            blackholeinterpbuilder.release_interp(blackholeinterp)
+        #...x.x.x...
+        assert blackholeinterp.nextblackholeinterp is None  # XXX
+        break
+        xxx
+    return blackholeinterp
+
+def _prepare_resume_from_failure(blackholeinterp, opnum):
+    from pypy.jit.metainterp.resoperation import rop
+    if opnum == rop.GUARD_TRUE:      # a goto_if_not_xxx that jumps only now
+        blackholeinterp.follow_jump()
+    elif opnum == rop.GUARD_FALSE:   # a goto_if_not that stops jumping
+        pass
+    else:
+        raise NotImplementedError(opnum)
+
+def _done_with_this_frame(blackholeinterp):
+    sd = blackholeinterp.builder.metainterp_sd
+    if sd.result_type == 'void':
+        raise sd.DoneWithThisFrameVoid()
+    elif sd.result_type == 'int':
+        raise sd.DoneWithThisFrameInt(blackholeinterp.get_result_i())
+    elif sd.result_type == 'ref':
+        raise sd.DoneWithThisFrameRef(blackholeinterp.get_result_r())
+    elif sd.result_type == 'float':
+        raise sd.DoneWithThisFrameFloat(blackholeinterp.get_result_f())
+    else:
+        assert False

Modified: pypy/branch/blackhole-improvement/pypy/jit/metainterp/compile.py
==============================================================================
--- pypy/branch/blackhole-improvement/pypy/jit/metainterp/compile.py	(original)
+++ pypy/branch/blackhole-improvement/pypy/jit/metainterp/compile.py	Tue May 18 17:04:44 2010
@@ -239,16 +239,20 @@
             self._counter = ~i      # use ~(index_of_guarded_box_in_fail_args)
 
     def handle_fail(self, metainterp_sd):
+        from pypy.jit.metainterp.blackhole import resume_in_blackhole
+        return resume_in_blackhole(metainterp_sd, self)
+        XXX
         from pypy.jit.metainterp.pyjitpl import MetaInterp
         metainterp = MetaInterp(metainterp_sd)
         return metainterp.handle_guard_failure(self)
 
-    def must_compile(self, metainterp_sd, inputargs_and_holes):
+    def must_compile(self, metainterp_sd):
         trace_eagerness = metainterp_sd.state.trace_eagerness
         if self._counter >= 0:
             self._counter += 1
             return self._counter >= trace_eagerness
         else:
+            XXX
             box = inputargs_and_holes[~self._counter]
             if self._counters is None:
                 self._counters = ResumeGuardCounters()

Modified: pypy/branch/blackhole-improvement/pypy/jit/metainterp/pyjitpl.py
==============================================================================
--- pypy/branch/blackhole-improvement/pypy/jit/metainterp/pyjitpl.py	(original)
+++ pypy/branch/blackhole-improvement/pypy/jit/metainterp/pyjitpl.py	Tue May 18 17:04:44 2010
@@ -36,11 +36,11 @@
         return func
     return decorate
 
-class XXX:      # XXX temporary hack
+class FixME:      # XXX temporary hack
     def __init__(self, func):
         self.func = func
     def __getattr__(self, _):
-        raise Exception("@XXX: " + self.func.__name__)
+        raise Exception("@FixME: " + self.func.__name__)
 
 # ____________________________________________________________
 
@@ -236,8 +236,8 @@
     def opimpl_goto(self, target):
         self.pc = target
 
-    @arguments("label", "box")
-    def opimpl_goto_if_not(self, target, box):
+    @arguments("box", "label")
+    def opimpl_goto_if_not(self, box, target):
         switchcase = box.getint()
         if switchcase:
             opnum = rop.GUARD_TRUE
@@ -249,19 +249,19 @@
 
     for _opimpl in ['int_is_zero', 'ptr_iszero', 'ptr_nonzero']:
         exec py.code.Source('''
-            @arguments("label", "box")
-            def opimpl_goto_if_not_%s(self, target, box):
+            @arguments("box", "label")
+            def opimpl_goto_if_not_%s(self, box, target):
                 condbox = self.execute(rop.%s, box)
-                self.opimpl_goto_if_not(target, condbox)
+                self.opimpl_goto_if_not(condbox, target)
         ''' % (_opimpl, _opimpl.upper())).compile()
 
     for _opimpl in ['int_lt', 'int_le', 'int_eq', 'int_ne', 'int_gt', 'int_ge',
                     'ptr_eq', 'ptr_ne']:
         exec py.code.Source('''
-            @arguments("label", "box", "box")
-            def opimpl_goto_if_not_%s(self, target, b1, b2):
+            @arguments("box", "box", "label")
+            def opimpl_goto_if_not_%s(self, b1, b2, target):
                 condbox = self.execute(rop.%s, b1, b2)
-                self.opimpl_goto_if_not(target, condbox)
+                self.opimpl_goto_if_not(condbox, target)
         ''' % (_opimpl, _opimpl.upper())).compile()
     
     def follow_jump(self):
@@ -316,18 +316,18 @@
     def opimpl_new_with_vtable(self, sizevtabledescr):
         return self.execute_with_descr(rop.NEW_WITH_VTABLE, sizevtabledescr)
 
-    @XXX  #arguments("box")
+    @FixME  #arguments("box")
     def opimpl_runtimenew(self, classbox):
         self.execute(rop.RUNTIMENEW, classbox)
 
-    @XXX  #arguments("orgpc", "box", "descr")
+    @FixME  #arguments("orgpc", "box", "descr")
     def opimpl_instanceof(self, pc, objbox, typedescr):
         clsbox = self.cls_of_box(objbox)
         if isinstance(objbox, Box):
             self.generate_guard(pc, rop.GUARD_CLASS, objbox, [clsbox])
         self.execute_with_descr(rop.INSTANCEOF, typedescr, objbox)
 
-    @XXX  #arguments("box", "box")
+    @FixME  #arguments("box", "box")
     def opimpl_subclassof(self, box1, box2):
         self.execute(rop.SUBCLASSOF, box1, box2)
 
@@ -335,11 +335,11 @@
     def opimpl_new_array(self, itemsizedescr, countbox):
         return self.execute_with_descr(rop.NEW_ARRAY, itemsizedescr, countbox)
 
-    @XXX  #arguments("box", "descr", "box")
+    @FixME  #arguments("box", "descr", "box")
     def opimpl_getarrayitem_gc(self, arraybox, arraydesc, indexbox):
         self.execute_with_descr(rop.GETARRAYITEM_GC, arraydesc, arraybox, indexbox)
 
-    @XXX  #arguments("box", "descr", "box")
+    @FixME  #arguments("box", "descr", "box")
     def opimpl_getarrayitem_gc_pure(self, arraybox, arraydesc, indexbox):
         self.execute_with_descr(rop.GETARRAYITEM_GC_PURE, arraydesc, arraybox, indexbox)
 
@@ -352,18 +352,18 @@
     opimpl_setarrayitem_gc_r = _opimpl_setarrayitem_gc
     opimpl_setarrayitem_gc_f = _opimpl_setarrayitem_gc
 
-    @XXX  #arguments("box", "descr")
+    @FixME  #arguments("box", "descr")
     def opimpl_arraylen_gc(self, arraybox, arraydesc):
         self.execute_with_descr(rop.ARRAYLEN_GC, arraydesc, arraybox)
 
-    @XXX  #arguments("descr", "box", "box", "box", "box", "box", "box", "descr")
+    @FixME  #arguments("descr", "box", "box", "box", "box", "box", "box", "descr")
     def opimpl_arraycopy(self, calldescr, fnptr, sourcebox, destbox,
                          source_startbox, dest_startbox, lengthbox, arraydescr):
         self.execute_with_descr(rop.ARRAYCOPY, arraydescr, calldescr, fnptr,
                                 sourcebox, destbox, source_startbox,
                                 dest_startbox, lengthbox)
 
-    @XXX  #arguments("orgpc", "box", "descr", "box")
+    @FixME  #arguments("orgpc", "box", "descr", "box")
     def opimpl_check_neg_index(self, pc, arraybox, arraydesc, indexbox):
         negbox = self.metainterp.execute_and_record(
             rop.INT_LT, None, indexbox, ConstInt(0))
@@ -376,7 +376,7 @@
                 rop.INT_ADD, None, indexbox, lenbox)
         self.make_result_box(indexbox)
 
-    @XXX  #arguments("descr", "descr", "descr", "descr", "box")
+    @FixME  #arguments("descr", "descr", "descr", "descr", "box")
     def opimpl_newlist(self, structdescr, lengthdescr, itemsdescr, arraydescr,
                        sizebox):
         sbox = self.metainterp.execute_and_record(rop.NEW, structdescr)
@@ -388,20 +388,20 @@
                                            sbox, abox)
         self.make_result_box(sbox)
 
-    @XXX  #arguments("box", "descr", "descr", "box")
+    @FixME  #arguments("box", "descr", "descr", "box")
     def opimpl_getlistitem_gc(self, listbox, itemsdescr, arraydescr, indexbox):
         arraybox = self.metainterp.execute_and_record(rop.GETFIELD_GC,
                                                       itemsdescr, listbox)
         self.execute_with_descr(rop.GETARRAYITEM_GC, arraydescr, arraybox, indexbox)
 
-    @XXX  #arguments("box", "descr", "descr", "box", "box")
+    @FixME  #arguments("box", "descr", "descr", "box", "box")
     def opimpl_setlistitem_gc(self, listbox, itemsdescr, arraydescr, indexbox,
                               valuebox):
         arraybox = self.metainterp.execute_and_record(rop.GETFIELD_GC,
                                                       itemsdescr, listbox)
         self.execute_with_descr(rop.SETARRAYITEM_GC, arraydescr, arraybox, indexbox, valuebox)
 
-    @XXX  #arguments("orgpc", "box", "descr", "box")
+    @FixME  #arguments("orgpc", "box", "descr", "box")
     def opimpl_check_resizable_neg_index(self, pc, listbox, lengthdesc,
                                          indexbox):
         negbox = self.metainterp.execute_and_record(
@@ -415,7 +415,7 @@
                 rop.INT_ADD, None, indexbox, lenbox)
         self.make_result_box(indexbox)
 
-    @XXX  #arguments("orgpc", "box")
+    @FixME  #arguments("orgpc", "box")
     def opimpl_check_zerodivisionerror(self, pc, box):
         nonzerobox = self.metainterp.execute_and_record(
             rop.INT_NE, None, box, ConstInt(0))
@@ -426,7 +426,7 @@
             # division by zero!
             return self.metainterp.raise_zero_division_error()
 
-    @XXX  #arguments("orgpc", "box", "box")
+    @FixME  #arguments("orgpc", "box", "box")
     def opimpl_check_div_overflow(self, pc, box1, box2):
         # detect the combination "box1 = -sys.maxint-1, box2 = -1".
         import sys
@@ -443,11 +443,11 @@
             # division overflow!
             return self.metainterp.raise_overflow_error()
 
-    @XXX  #arguments()
+    @FixME  #arguments()
     def opimpl_overflow_error(self):
         return self.metainterp.raise_overflow_error()
 
-    @XXX  #arguments("orgpc", "box")
+    @FixME  #arguments("orgpc", "box")
     def opimpl_int_abs(self, pc, box):
         nonneg = self.metainterp.execute_and_record(
             rop.INT_GE, None, box, ConstInt(0))
@@ -457,7 +457,7 @@
         else:
             self.execute(rop.INT_NEG, box)
 
-    @XXX  #arguments("orgpc", "box")
+    @FixME  #arguments("orgpc", "box")
     def opimpl_oononnull(self, pc, box):
         value = box.nonnull()
         if value:
@@ -469,7 +469,7 @@
         self.generate_guard(pc, opnum, box, [])
         self.make_result_box(res)
 
-    @XXX  #arguments("orgpc", "box")
+    @FixME  #arguments("orgpc", "box")
     def opimpl_ooisnull(self, pc, box):
         value = box.nonnull()
         if value:
@@ -481,11 +481,11 @@
         self.generate_guard(pc, opnum, box, [])
         self.make_result_box(res)
 
-    @XXX  #arguments("box", "box")
+    @FixME  #arguments("box", "box")
     def opimpl_ptr_eq(self, box1, box2):
         self.execute(rop.OOIS, box1, box2)
 
-    @XXX  #arguments("box", "box")
+    @FixME  #arguments("box", "box")
     def opimpl_ptr_ne(self, box1, box2):
         self.execute(rop.OOISNOT, box1, box2)
 
@@ -557,7 +557,7 @@
         vinfo = self.metainterp.staticdata.virtualizable_info
         return vinfo.array_descrs[index]
 
-    @XXX  #arguments("orgpc", "box", "int")
+    @FixME  #arguments("orgpc", "box", "int")
     def opimpl_getfield_vable(self, pc, basebox, index):
         if self._nonstandard_virtualizable(pc, basebox):
             self.execute_with_descr(rop.GETFIELD_GC, self._get_virtualizable_field_descr(index), basebox)
@@ -565,7 +565,7 @@
         self.metainterp.check_synchronized_virtualizable()
         resbox = self.metainterp.virtualizable_boxes[index]
         self.make_result_box(resbox)
-    @XXX  #arguments("orgpc", "box", "int", "box")
+    @FixME  #arguments("orgpc", "box", "int", "box")
     def opimpl_setfield_vable(self, pc, basebox, index, valuebox):
         if self._nonstandard_virtualizable(pc, basebox):
             self.execute_with_descr(rop.SETFIELD_GC, self._get_virtualizable_field_descr(index), basebox, valuebox)
@@ -585,7 +585,7 @@
         assert 0 <= index < vinfo.get_array_length(virtualizable, arrayindex)
         return vinfo.get_index_in_array(virtualizable, arrayindex, index)
 
-    @XXX  #arguments("orgpc", "box", "int", "box")
+    @FixME  #arguments("orgpc", "box", "int", "box")
     def opimpl_getarrayitem_vable(self, pc, basebox, arrayindex, indexbox):
         if self._nonstandard_virtualizable(pc, basebox):
             descr = self._get_virtualizable_array_field_descr(arrayindex)
@@ -599,7 +599,7 @@
         index = self._get_arrayitem_vable_index(pc, arrayindex, indexbox)
         resbox = self.metainterp.virtualizable_boxes[index]
         self.make_result_box(resbox)
-    @XXX  #arguments("orgpc", "box", "int", "box", "box")
+    @FixME  #arguments("orgpc", "box", "int", "box", "box")
     def opimpl_setarrayitem_vable(self, pc, basebox, arrayindex, indexbox,
                                   valuebox):
         if self._nonstandard_virtualizable(pc, basebox):
@@ -614,7 +614,7 @@
         self.metainterp.virtualizable_boxes[index] = valuebox
         self.metainterp.synchronize_virtualizable()
         # XXX only the index'th field needs to be synchronized, really
-    @XXX  #arguments("orgpc", "box", "int")
+    @FixME  #arguments("orgpc", "box", "int")
     def opimpl_arraylen_vable(self, pc, basebox, arrayindex):
         if self._nonstandard_virtualizable(pc, basebox):
             descr = self._get_virtualizable_array_field_descr(arrayindex)
@@ -671,11 +671,11 @@
     opimpl_residual_call_irf_f = _opimpl_residual_call3
     opimpl_residual_call_irf_v = _opimpl_residual_call3
 
-    @XXX  #arguments("descr", "varargs")
+    @FixME  #arguments("descr", "varargs")
     def opimpl_residual_call_loopinvariant(self, calldescr, varargs):
         return self.execute_varargs(rop.CALL_LOOPINVARIANT, varargs, calldescr, exc=True)
 
-    @XXX  #arguments("orgpc", "descr", "varargs")
+    @FixME  #arguments("orgpc", "descr", "varargs")
     def opimpl_recursive_call(self, pc, calldescr, varargs):
         warmrunnerstate = self.metainterp.staticdata.state
         token = None
@@ -710,7 +710,7 @@
                                                   call_position)
         return res
 
-    @XXX  #arguments("orgpc", "methdescr", "varargs")
+    @FixME  #arguments("orgpc", "methdescr", "varargs")
     def opimpl_oosend(self, pc, methdescr, varargs):
         objbox = varargs[0]
         clsbox = self.cls_of_box(objbox)
@@ -758,15 +758,15 @@
     def opimpl_newunicode(self, lengthbox):
         return self.execute(rop.NEWUNICODE, lengthbox)
 
-    @XXX  #arguments("descr", "varargs")
+    @FixME  #arguments("descr", "varargs")
     def opimpl_residual_oosend_canraise(self, methdescr, varargs):
         return self.execute_varargs(rop.OOSEND, varargs, descr=methdescr, exc=True)
 
-    @XXX  #arguments("descr", "varargs")
+    @FixME  #arguments("descr", "varargs")
     def opimpl_residual_oosend_noraise(self, methdescr, varargs):
         self.execute_varargs(rop.OOSEND, varargs, descr=methdescr, exc=False)
 
-    @XXX  #arguments("descr", "varargs")
+    @FixME  #arguments("descr", "varargs")
     def opimpl_residual_oosend_pure(self, methdescr, boxes):
         self.execute_varargs(rop.OOSEND_PURE, boxes, descr=methdescr, exc=False)
 
@@ -784,17 +784,17 @@
         self.generate_guard(rop.GUARD_CLASS, box, [clsbox])
         return clsbox
 
-##    @XXX  #arguments("orgpc", "box", "builtin")
+##    @FixME  #arguments("orgpc", "box", "builtin")
 ##    def opimpl_guard_builtin(self, pc, box, builtin):
 ##        self.generate_guard(pc, "guard_builtin", box, [builtin])
 
-##    @XXX  #arguments("orgpc", "box", "builtin")
+##    @FixME  #arguments("orgpc", "box", "builtin")
 ##    def opimpl_guard_len(self, pc, box, builtin):
 ##        intbox = self.metainterp.cpu.execute_operation(
 ##            'len', [builtin.len_func, box], 'int')
 ##        self.generate_guard(pc, "guard_len", box, [intbox])
 
-    @XXX  #arguments("box")
+    @FixME  #arguments("box")
     def opimpl_keepalive(self, box):
         pass     # xxx?
 
@@ -873,7 +873,7 @@
         self.metainterp.popframe()
         self.metainterp.finishframe_exception()
 
-    @XXX  #arguments("box")
+    @FixME  #arguments("box")
     def opimpl_virtual_ref(self, box):
         # Details on the content of metainterp.virtualref_boxes:
         #
@@ -907,7 +907,7 @@
         metainterp.virtualref_boxes.append(resbox)
         self.make_result_box(resbox)
 
-    @XXX  #arguments("box")
+    @FixME  #arguments("box")
     def opimpl_virtual_ref_finish(self, box):
         # virtual_ref_finish() assumes that we have a stack-like, last-in
         # first-out order.
@@ -1134,6 +1134,9 @@
         RESULT = codewriter.portal_graph.getreturnvar().concretetype
         self.result_type = history.getkind(RESULT)
         #
+        from pypy.jit.metainterp.blackhole import BlackholeInterpBuilder
+        self.blackholeinterpbuilder = BlackholeInterpBuilder(codewriter, self)
+        #
         warmrunnerdesc = self.warmrunnerdesc
         if warmrunnerdesc is not None:
             self.num_green_args = warmrunnerdesc.num_green_args
@@ -1460,6 +1463,7 @@
         self.last_exc_value_box = None
 
     def switch_to_blackhole(self, reason):
+        XXX
         self.staticdata.profiler.count(reason)
         debug_print('~~~ ABORTING TRACING')
         debug_stop('jit-tracing')
@@ -1513,10 +1517,7 @@
         try:
             return self._compile_and_run_once(*args)
         finally:
-            if self.history is None:
-                debug_stop('jit-blackhole')
-            else:
-                debug_stop('jit-tracing')
+            debug_stop('jit-tracing')
 
     def _compile_and_run_once(self, *args):
         original_boxes = self.initialize_state_from_start(*args)
@@ -1539,10 +1540,7 @@
         try:
             return self._handle_guard_failure(key)
         finally:
-            if self.history is None:
-                debug_stop('jit-blackhole')
-            else:
-                debug_stop('jit-tracing')
+            debug_stop('jit-tracing')
 
     def _handle_guard_failure(self, key):
         from pypy.jit.metainterp.warmspot import ContinueRunningNormallyBase
@@ -1553,6 +1551,7 @@
         self.current_merge_points = [(original_greenkey, -1)]
         self.resumekey = key
         self.seen_can_enter_jit = False
+        xxx
         started_as_blackhole = self.is_blackholing()
         try:
             self.prepare_resume_from_failure(key.guard_opnum)
@@ -1741,6 +1740,7 @@
         return original_boxes
 
     def initialize_state_from_guard_failure(self, resumedescr):
+        XXX
         # guard failure: rebuild a complete MIFrame stack
         self.in_recursion = -1 # always one portal around
         inputargs_and_holes = self.cpu.make_boxes_from_latest_values(

Modified: pypy/branch/blackhole-improvement/pypy/jit/metainterp/resume.py
==============================================================================
--- pypy/branch/blackhole-improvement/pypy/jit/metainterp/resume.py	(original)
+++ pypy/branch/blackhole-improvement/pypy/jit/metainterp/resume.py	Tue May 18 17:04:44 2010
@@ -1,10 +1,10 @@
 import sys, os
-from pypy.jit.metainterp.history import Box, Const, ConstInt, INT, REF
+from pypy.jit.metainterp.history import Box, Const, ConstInt, INT, REF, FLOAT
 from pypy.jit.metainterp.resoperation import rop
 from pypy.jit.metainterp import jitprof
 from pypy.rpython.lltypesystem import rffi
 from pypy.rlib import rarithmetic
-from pypy.rlib.objectmodel import we_are_translated
+from pypy.rlib.objectmodel import we_are_translated, specialize
 from pypy.rlib.debug import have_debug_prints
 from pypy.rlib.debug import debug_start, debug_stop, debug_print
 
@@ -390,7 +390,9 @@
 class AbstractVirtualInfo(object):
     def allocate(self, metainterp):
         raise NotImplementedError
-    def setfields(self, metainterp, box, fn_decode_box):
+    #def setfields(self, decoder, struct):
+    #    raise NotImplementedError
+    def bh_allocate(self, cpu):
         raise NotImplementedError
     def equals(self, fieldnums):
         return tagged_list_eq(self.fieldnums, fieldnums)
@@ -405,12 +407,14 @@
         self.fielddescrs = fielddescrs
         #self.fieldnums = ...
 
-    def setfields(self, metainterp, box, fn_decode_box):
+    @specialize.argtype(1)
+    def setfields(self, decoder, struct):
         for i in range(len(self.fielddescrs)):
-            fieldbox = fn_decode_box(self.fieldnums[i])
-            metainterp.execute_and_record(rop.SETFIELD_GC,
-                                          self.fielddescrs[i],
-                                          box, fieldbox)
+            descr = self.fielddescrs[i]
+            decoder.setfield(descr, struct, self.fieldnums[i])
+##            fieldbox = fn_decode_box(self.fieldnums[i], kind)
+##            metainterp.execute_and_record(rop.SETFIELD_GC,
+##                                          descr, box, fieldbox)
 
     def debug_prints(self):
         assert len(self.fielddescrs) == len(self.fieldnums)
@@ -455,12 +459,11 @@
                                              self.arraydescr,
                                              ConstInt(length))
 
-    def setfields(self, metainterp, box, fn_decode_box):
+    @specialize.argtype(1)
+    def setfields(self, decoder, array):
+        arraydescr = self.arraydescr
         for i in range(len(self.fieldnums)):
-            itembox = fn_decode_box(self.fieldnums[i])
-            metainterp.execute_and_record(rop.SETARRAYITEM_GC,
-                                          self.arraydescr,
-                                          box, ConstInt(i), itembox)
+            decoder.setarrayitem(descr, array, i, self.fieldnums[i])
 
     def debug_prints(self):
         debug_print("\tvarrayinfo", self.arraydescr)
@@ -496,7 +499,7 @@
     return virtualizable_boxes, virtualref_boxes, resumereader.virtuals
 
 
-class ResumeDataReader(object):
+class ResumeDataBoxReader(object):
     virtuals = None
 
     def __init__(self, storage, liveboxes, metainterp=None):
@@ -545,7 +548,7 @@
         self.cur_numb = numb.prev
         return boxes
 
-    def _decode_box(self, tagged):
+    def _decode_box(self, tagged, kind):
         num, tag = untag(tagged)
         if tag == TAGCONST:
             if tagged_eq(tagged, NULLREF):
@@ -561,6 +564,164 @@
             assert tag == TAGBOX
             return self.liveboxes[num]
 
+
+def blackhole_from_resumedata(blackholeinterpbuilder, storage,
+                              expects_virtualizables):
+    resumereader = ResumeDataDirectReader(storage, blackholeinterpbuilder.cpu)
+    if expects_virtualizables:
+        XXX
+    #virtualref_boxes = resumereader.consume_boxes()
+    resumereader.consume_one_section(None)     # XXX
+    #
+    # First get a chain of blackhole interpreters whose length is given
+    # by the depth of rd_frame_info_list.  The first one we get must be
+    # the bottom one, i.e. the last one in the chain, in order to make
+    # the comment in BlackholeInterpreter.setposition() valid.
+    nextbh = None
+    frameinfo = storage.rd_frame_info_list
+    while True:
+        curbh = blackholeinterpbuilder.acquire_interp()
+        curbh.nextblackholeinterp = nextbh
+        nextbh = curbh
+        frameinfo = frameinfo.prev
+        if frameinfo is None:
+            break
+    firstbh = nextbh
+    #
+    # Now fill the blackhole interpreters with resume data.
+    curbh = firstbh
+    frameinfo = storage.rd_frame_info_list
+    while True:
+        curbh.setposition(frameinfo.jitcode, frameinfo.pc)
+        resumereader.consume_one_section(curbh)
+        curbh = curbh.nextblackholeinterp
+        frameinfo = frameinfo.prev
+        if frameinfo is None:
+            break
+    resumereader.done()
+    return firstbh
+
+class ResumeDataDirectReader(object):
+    virtuals = None
+
+    def __init__(self, storage, cpu):
+        self.cur_numb = storage.rd_numb
+        self.consts = storage.rd_consts
+        self.cpu = cpu
+        self._prepare_virtuals(storage.rd_virtuals)
+        self._prepare_pendingfields(storage.rd_pendingfields)
+
+    def _prepare_virtuals(self, virtuals):
+        if virtuals:
+            self.virtuals = [None] * len(virtuals)
+            for i in range(len(virtuals)):
+                vinfo = virtuals[i]
+                if vinfo is not None:
+                    self.virtuals[i] = vinfo.bh_allocate(self.cpu)
+            for i in range(len(virtuals)):
+                vinfo = virtuals[i]
+                if vinfo is not None:
+                    vinfo.setfields(self, self.virtuals[i])
+
+    def _prepare_pendingfields(self, pendingfields):
+        if pendingfields is not None:
+            for descr, num, fieldnum in pendingfields:
+                struct = self._decode_ref(num)
+                self.setfield(descr, struct, fieldnum)
+
+    def setfield(self, descr, struct, fieldnum):
+        if descr.is_pointer_field():
+            newvalue = self._decode_ref(fieldnum)
+            self.cpu.bh_setfield_gc_r(struct, descr, newfield)
+        elif descr.is_float_field():
+            newvalue = self._decode_float(fieldnum)
+            self.cpu.bh_setfield_gc_f(struct, descr, newfield)
+        else:
+            newvalue = self._decode_int(fieldnum)
+            self.cpu.bh_setfield_gc_i(struct, descr, newfield)
+
+    def setarrayitem(self, arraydescr, array, index, fieldnum):
+        if arraydescr.is_array_of_pointers():
+            newvalue = self._decode_ref(fieldnum)
+            self.cpu.bh_setarrayitem_gc_r(arraydescr, array, index, newvalue)
+        elif arraydescr.is_array_of_floats():
+            newvalue = self._decode_float(fieldnum)
+            self.cpu.bh_setarrayitem_gc_f(arraydescr, array, index, newvalue)
+        else:
+            newvalue = self._decode_int(fieldnum)
+            self.cpu.bh_setarrayitem_gc_i(arraydescr, array, index, newvalue)
+
+    def consume_one_section(self, blackholeinterp):
+        numb = self.cur_numb
+        count_i = count_r = count_f = 0
+        for num in numb.nums:
+            kind = self._decode_kind(num)
+            if kind == INT:
+                blackholeinterp.setarg_i(count_i, self._decode_int(num))
+                count_i += 1
+            elif kind == REF:
+                blackholeinterp.setarg_r(count_r, self._decode_ref(num))
+                count_r += 1
+            elif kind == FLOAT:
+                blackholeinterp.setarg_f(count_f, self._decode_float(num))
+                count_f += 1
+        self.cur_numb = numb.prev
+
+    def _decode_kind(self, tagged):
+        num, tag = untag(tagged)
+        if tag == TAGCONST:
+            if tagged_eq(tagged, NULLREF):
+                return history.REF
+            return self.consts[num].type
+        elif tag == TAGVIRTUAL:
+            return history.REF
+        elif tag == TAGINT:
+            return history.INT
+        else:
+            assert tag == TAGBOX
+            return self.cpu.get_latest_value_kind(num)
+
+    def _decode_int(self, tagged):
+        num, tag = untag(tagged)
+        if tag == TAGCONST:
+            return self.consts[num].getint()
+        elif tag == TAGINT:
+            return num
+        else:
+            assert tag == TAGBOX
+            if num < 0:
+                num += self.cpu.get_latest_value_count()
+            return self.cpu.get_latest_value_int(num)
+
+    def _decode_ref(self, tagged):
+        num, tag = untag(tagged)
+        if tag == TAGCONST:
+            if tagged_eq(tagged, NULLREF):
+                return self.cpu.ts.NULLREF
+            return self.consts[num].getptr_base()
+        elif tag == TAGVIRTUAL:
+            virtuals = self.virtuals
+            assert virtuals is not None
+            return virtuals[num]
+        else:
+            assert tag == TAGBOX
+            if num < 0:
+                num += self.cpu.get_latest_value_count()
+            return self.cpu.get_latest_value_ref(num)
+
+    def _decode_float(self, tagged):
+        num, tag = untag(tagged)
+        if tag == TAGCONST:
+            return self.consts[num].getfloat()
+        else:
+            assert tag == TAGBOX
+            if num < 0:
+                num += self.cpu.get_latest_value_count()
+            return self.cpu.get_latest_value_float(num)
+
+    def done(self):
+        self.cpu.clear_latest_values()
+
 # ____________________________________________________________
 
 def dump_storage(storage, liveboxes):

Modified: pypy/branch/blackhole-improvement/pypy/jit/metainterp/test/test_basic.py
==============================================================================
--- pypy/branch/blackhole-improvement/pypy/jit/metainterp/test/test_basic.py	(original)
+++ pypy/branch/blackhole-improvement/pypy/jit/metainterp/test/test_basic.py	Tue May 18 17:04:44 2010
@@ -43,7 +43,8 @@
             count_f += 1
         else:
             raise TypeError(T)
-    blackholeinterp.run(cw.mainjitcode, 0)
+    blackholeinterp.setposition(cw.mainjitcode, 0)
+    blackholeinterp.run()
     return blackholeinterp._get_result_anytype()
 
 def _run_with_pyjitpl(cw, args, testself):

Modified: pypy/branch/blackhole-improvement/pypy/jit/metainterp/typesystem.py
==============================================================================
--- pypy/branch/blackhole-improvement/pypy/jit/metainterp/typesystem.py	(original)
+++ pypy/branch/blackhole-improvement/pypy/jit/metainterp/typesystem.py	Tue May 18 17:04:44 2010
@@ -45,7 +45,8 @@
     BoxRef = history.BoxPtr
     ConstRef = history.ConstPtr
     loops_done_with_this_frame_ref = None # patched by compile.py
-    CONST_NULL = history.ConstPtr(history.ConstPtr.value)
+    NULLREF = history.ConstPtr.value
+    CONST_NULL = history.ConstPtr(NULLREF)
     CVAL_NULLREF = None # patched by optimizeopt.py
 
     def new_ConstRef(self, x):
@@ -150,7 +151,8 @@
     BoxRef = history.BoxObj
     ConstRef = history.ConstObj
     loops_done_with_this_frame_ref = None # patched by compile.py
-    CONST_NULL = history.ConstObj(history.ConstObj.value)
+    NULLREF = history.ConstObj.value
+    CONST_NULL = history.ConstObj(NULLREF)
     CVAL_NULLREF = None # patched by optimizeopt.py
     
     def new_ConstRef(self, x):

Modified: pypy/branch/blackhole-improvement/pypy/jit/metainterp/warmspot.py
==============================================================================
--- pypy/branch/blackhole-improvement/pypy/jit/metainterp/warmspot.py	(original)
+++ pypy/branch/blackhole-improvement/pypy/jit/metainterp/warmspot.py	Tue May 18 17:04:44 2010
@@ -267,8 +267,7 @@
                                                   warmrunnerdesc=self)
 
     def make_exception_classes(self):
-        portalfunc_ARGS = unrolling_iterable(
-            [(i, 'arg%d' % i, ARG) for i, ARG in enumerate(self.PORTAL_FUNCTYPE.ARGS)])
+
         class DoneWithThisFrameVoid(JitException):
             def __str__(self):
                 return 'DoneWithThisFrameVoid()'
@@ -302,18 +301,19 @@
                 return 'ExitFrameWithExceptionRef(%s)' % (self.value,)
 
         class ContinueRunningNormally(ContinueRunningNormallyBase):
-            def __init__(self, argboxes):
-                # accepts boxes as argument, but unpacks them immediately
-                # before we raise the exception -- the boxes' values will
-                # be modified in a 'finally' by restore_patched_boxes().
-                from pypy.jit.metainterp.warmstate import unwrap
-                for i, name, ARG in portalfunc_ARGS:
-                    v = unwrap(ARG, argboxes[i])
-                    setattr(self, name, v)
-
+            def __init__(self, gi, gr, gf, ri, rr, rf):
+                # the six arguments are: lists of green ints, greens refs,
+                # green floats, red ints, red refs, and red floats.
+                self.green_int = gi
+                self.green_ref = gr
+                self.green_float = gf
+                self.red_int = ri
+                self.red_ref = rr
+                self.red_float = rf
             def __str__(self):
-                return 'ContinueRunningNormally(%s)' % (
-                    ', '.join(map(str, self.args)),)
+                return 'ContinueRunningNormally(%s, %s, %s, %s, %s, %s)' % (
+                    self.green_int, self.green_ref, self.green_float,
+                    self.red_int, self.red_ref, self.red_float)
 
         self.DoneWithThisFrameVoid = DoneWithThisFrameVoid
         self.DoneWithThisFrameInt = DoneWithThisFrameInt
@@ -327,6 +327,7 @@
         self.metainterp_sd.DoneWithThisFrameFloat = DoneWithThisFrameFloat
         self.metainterp_sd.ExitFrameWithExceptionRef = ExitFrameWithExceptionRef
         self.metainterp_sd.ContinueRunningNormally = ContinueRunningNormally
+
     def make_enter_function(self):
         from pypy.jit.metainterp.warmstate import WarmEnterState
         state = WarmEnterState(self)
@@ -497,13 +498,24 @@
         # ____________________________________________________________
         # Prepare the portal_runner() helper
         #
+        from pypy.jit.metainterp.warmstate import specialize_value
         portal_ptr = self.cpu.ts.functionptr(PORTALFUNC, 'portal',
                                          graph = portalgraph)
         self.portal_ptr = portal_ptr
-        portalfunc_ARGS = unrolling_iterable(
-            [(i, 'arg%d' % i, ARG) for i, ARG in enumerate(PORTALFUNC.ARGS)])
-
-
+        #
+        portalfunc_ARGS = []
+        nums = {}
+        for i, ARG in enumerate(PORTALFUNC.ARGS):
+            if i < len(self.jitdriver.greens):
+                color = 'green'
+            else:
+                color = 'red'
+            attrname = '%s_%s' % (color, history.getkind(ARG))
+            count = nums.get(attrname, 0)
+            nums[attrname] = count + 1
+            portalfunc_ARGS.append((ARG, attrname, count))
+        portalfunc_ARGS = unrolling_iterable(portalfunc_ARGS)
+        #
         rtyper = self.translator.rtyper
         RESULT = PORTALFUNC.RESULT
         result_kind = history.getkind(RESULT)
@@ -517,21 +529,22 @@
                                                       portal_ptr)(*args)
                 except self.ContinueRunningNormally, e:
                     args = ()
-                    for _, name, _ in portalfunc_ARGS:
-                        v = getattr(e, name)
-                        args = args + (v,)
+                    for ARGTYPE, attrname, count in portalfunc_ARGS:
+                        x = getattr(e, attrname)[count]
+                        x = specialize_value(ARGTYPE, x)
+                        args = args + (x,)
                 except self.DoneWithThisFrameVoid:
                     assert result_kind == 'void'
                     return
                 except self.DoneWithThisFrameInt, e:
                     assert result_kind == 'int'
-                    return lltype.cast_primitive(RESULT, e.result)
+                    return specialize_value(RESULT, e.result)
                 except self.DoneWithThisFrameRef, e:
                     assert result_kind == 'ref'
-                    return ts.cast_from_ref(RESULT, e.result)
+                    return specialize_value(RESULT, e.result)
                 except self.DoneWithThisFrameFloat, e:
                     assert result_kind == 'float'
-                    return e.result
+                    return specialize_value(RESULT, e.result)
                 except self.ExitFrameWithExceptionRef, e:
                     value = ts.cast_to_baseclass(e.value)
                     if not we_are_translated():
@@ -561,6 +574,7 @@
                     loop_token = fail_descr.handle_fail(self.metainterp_sd)
                     fail_descr = self.cpu.execute_token(loop_token)
                 except self.ContinueRunningNormally, e:
+                    xxxxxxxxx
                     args = ()
                     for _, name, _ in portalfunc_ARGS:
                         v = getattr(e, name)
@@ -571,13 +585,13 @@
                     return
                 except self.DoneWithThisFrameInt, e:
                     assert result_kind == 'int'
-                    return lltype.cast_primitive(RESULT, e.result)
+                    return specialize_value(RESULT, e.result)
                 except self.DoneWithThisFrameRef, e:
                     assert result_kind == 'ref'
-                    return ts.cast_from_ref(RESULT, e.result)
+                    return specialize_value(RESULT, e.result)
                 except self.DoneWithThisFrameFloat, e:
                     assert result_kind == 'float'
-                    return e.result
+                    return specialize_value(RESULT, e.result)
                 except self.ExitFrameWithExceptionRef, e:
                     value = ts.cast_to_baseclass(e.value)
                     if not we_are_translated():

Modified: pypy/branch/blackhole-improvement/pypy/jit/metainterp/warmstate.py
==============================================================================
--- pypy/branch/blackhole-improvement/pypy/jit/metainterp/warmstate.py	(original)
+++ pypy/branch/blackhole-improvement/pypy/jit/metainterp/warmstate.py	Tue May 18 17:04:44 2010
@@ -17,6 +17,20 @@
 # ____________________________________________________________
 
 @specialize.arg(0)
+def specialize_value(TYPE, x):
+    """'x' must be a Signed, a GCREF or a Float.
+    This function casts it to a more specialized type, like Char or Ptr(..).
+    """
+    INPUT = lltype.typeOf(x)
+    if INPUT is lltype.Signed:
+        return lltype.cast_primitive(TYPE, x)    # XXX missing: Ptr(non-gc)
+    elif INPUT is lltype.Float:
+        assert TYPE is lltype.Float
+        return x
+    else:
+        return lltype.cast_opaque_ptr(TYPE, x)
+
+ at specialize.arg(0)
 def unwrap(TYPE, box):
     if TYPE is lltype.Void:
         return None



More information about the Pypy-commit mailing list