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

arigo at codespeak.net arigo at codespeak.net
Mon May 3 10:22:49 CEST 2010


Author: arigo
Date: Mon May  3 10:22:48 2010
New Revision: 74331

Modified:
   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/codewriter/flatten.py
   pypy/branch/blackhole-improvement/pypy/jit/codewriter/jitter.py
   pypy/branch/blackhole-improvement/pypy/jit/codewriter/liveness.py
   pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_flatten.py
   pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_jitter.py
   pypy/branch/blackhole-improvement/pypy/jit/metainterp/blackhole.py
   pypy/branch/blackhole-improvement/pypy/jit/metainterp/executor.py
   pypy/branch/blackhole-improvement/pypy/jit/metainterp/jitprof.py
   pypy/branch/blackhole-improvement/pypy/jit/metainterp/pyjitpl.py
   pypy/branch/blackhole-improvement/pypy/jit/metainterp/typesystem.py
Log:
General progress.


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	Mon May  3 10:22:48 2010
@@ -278,16 +278,6 @@
         self.class_vtables_as_int[descr] = vtable_int
         return descr
 
-    def cast_adr_to_int(self, adr):
-        return llimpl.cast_adr_to_int(self.memo_cast, adr)
-
-    def cast_int_to_adr(self, int):
-        return llimpl.cast_int_to_adr(self.memo_cast, int)
-
-    def cast_gcref_to_int(self, gcref):
-        return self.cast_adr_to_int(llmemory.cast_ptr_to_adr(gcref))
-
-
 
 class LLtypeCPU(BaseCPU):
     is_oo = False
@@ -377,8 +367,6 @@
     def bh_getfield_gc_i(self, struct, fielddescr):
         assert isinstance(fielddescr, Descr)
         return llimpl.do_getfield_gc_int(struct, fielddescr.ofs)
-    bh_getfield_gc_c = bh_getfield_gc_i
-    bh_getfield_gc_u = bh_getfield_gc_i
     def bh_getfield_gc_r(self, struct, fielddescr):
         assert isinstance(fielddescr, Descr)
         return llimpl.do_getfield_gc_ptr(struct, fielddescr.ofs)
@@ -407,8 +395,6 @@
     def bh_getfield_raw_i(self, struct, fielddescr):
         assert isinstance(fielddescr, Descr)
         return llimpl.do_getfield_raw_int(struct, fielddescr.ofs)
-    bh_getfield_raw_c = bh_getfield_raw_i
-    bh_getfield_raw_u = bh_getfield_raw_i
     def bh_getfield_raw_r(self, struct, fielddescr):
         assert isinstance(fielddescr, Descr)
         return llimpl.do_getfield_raw_ptr(struct, fielddescr.ofs)
@@ -485,8 +471,6 @@
     def bh_setfield_gc_i(self, struct, fielddescr, newvalue):
         assert isinstance(fielddescr, Descr)
         llimpl.do_setfield_gc_int(struct, fielddescr.ofs, newvalue)
-    bh_setfield_gc_c = bh_setfield_gc_i
-    bh_setfield_gc_u = bh_setfield_gc_i
     def bh_setfield_gc_r(self, struct, fielddescr, newvalue):
         assert isinstance(fielddescr, Descr)
         llimpl.do_setfield_gc_ptr(struct, fielddescr.ofs, newvalue)
@@ -515,8 +499,6 @@
     def bh_setfield_raw_i(self, struct, fielddescr, newvalue):
         assert isinstance(fielddescr, Descr)
         llimpl.do_setfield_raw_int(struct, fielddescr.ofs, newvalue)
-    bh_setfield_raw_c = bh_setfield_raw_i
-    bh_setfield_raw_u = bh_setfield_raw_i
     def bh_setfield_raw_r(self, struct, fielddescr, newvalue):
         assert isinstance(fielddescr, Descr)
         llimpl.do_setfield_raw_ptr(struct, fielddescr.ofs, newvalue)

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	Mon May  3 10:22:48 2010
@@ -3,6 +3,7 @@
 
 class AbstractCPU(object):
     supports_floats = False
+    _got_exception = None
     # assembler_helper_ptr - a pointer to helper to call after a direct
     #                        assembler call
     portal_calldescr = None
@@ -157,10 +158,6 @@
     
     def bh_getfield_gc_i(self, struct, fielddescr):
         raise NotImplementedError
-    def bh_getfield_gc_c(self, struct, fielddescr):
-        raise NotImplementedError
-    def bh_getfield_gc_u(self, struct, fielddescr):
-        raise NotImplementedError
     def bh_getfield_gc_r(self, struct, fielddescr):
         raise NotImplementedError
     def bh_getfield_gc_f(self, struct, fielddescr):
@@ -168,10 +165,6 @@
 
     def bh_getfield_raw_i(self, struct, fielddescr):
         raise NotImplementedError
-    def bh_getfield_raw_c(self, struct, fielddescr):
-        raise NotImplementedError
-    def bh_getfield_raw_u(self, struct, fielddescr):
-        raise NotImplementedError
     def bh_getfield_raw_r(self, struct, fielddescr):
         raise NotImplementedError
     def bh_getfield_raw_f(self, struct, fielddescr):
@@ -196,10 +189,6 @@
 
     def bh_setfield_gc_i(self, struct, fielddescr, newvalue):
         raise NotImplementedError
-    def bh_setfield_gc_c(self, struct, fielddescr, newvalue):
-        raise NotImplementedError
-    def bh_setfield_gc_u(self, struct, fielddescr, newvalue):
-        raise NotImplementedError
     def bh_setfield_gc_r(self, struct, fielddescr, newvalue):
         raise NotImplementedError
     def bh_setfield_gc_f(self, struct, fielddescr, newvalue):
@@ -207,10 +196,6 @@
 
     def bh_setfield_raw_i(self, struct, fielddescr, newvalue):
         raise NotImplementedError
-    def bh_setfield_raw_c(self, struct, fielddescr, newvalue):
-        raise NotImplementedError
-    def bh_setfield_raw_u(self, struct, fielddescr, newvalue):
-        raise NotImplementedError
     def bh_setfield_raw_r(self, struct, fielddescr, newvalue):
         raise NotImplementedError
     def bh_setfield_raw_f(self, struct, fielddescr, newvalue):

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	Mon May  3 10:22:48 2010
@@ -156,6 +156,8 @@
             # An exception block. See test_exc_exitswitch in test_flatten.py
             # for an example of what kind of code this makes.
             lastopname = block.operations[-1].opname
+            if lastopname == '-live-':
+                lastopname = block.operations[-2].opname
             assert block.exits[0].exitcase is None # is this always True?
             self.emitline('catch_exception', TLabel(block.exits[0]))
             self.make_link(block.exits[0])
@@ -238,11 +240,13 @@
                 # A switch with several possible answers, though not too
                 # many of them -- a chain of int_eq comparisons is fine
                 assert kind == 'int'    # XXX
+                color = self.getcolor(block.exitswitch)
+                self.emitline('int_guard_value', color, color)
                 for switch in switches:
                     # make the case described by 'switch'
                     self.emitline('goto_if_not_int_eq',
                                   TLabel(switch),
-                                  self.getcolor(block.exitswitch),
+                                  color,
                                   Constant(switch.llexitcase,
                                            block.exitswitch.concretetype))
                     # emit code for the "taken" path

Modified: pypy/branch/blackhole-improvement/pypy/jit/codewriter/jitter.py
==============================================================================
--- pypy/branch/blackhole-improvement/pypy/jit/codewriter/jitter.py	(original)
+++ pypy/branch/blackhole-improvement/pypy/jit/codewriter/jitter.py	Mon May  3 10:22:48 2010
@@ -190,7 +190,6 @@
     def rewrite_op_hint(self, op):
         hints = op.args[1].value
         if hints.get('promote') and op.args[0].concretetype is not lltype.Void:
-            #self.minimize_variables()
             assert op.args[0].concretetype != lltype.Ptr(rstr.STR)
             kind = getkind(op.args[0].concretetype)
             return SpaceOperation('%s_guard_value' % kind,
@@ -274,10 +273,7 @@
         argname = getattr(v_inst.concretetype.TO, '_gckind', 'gc')
         descr = self.cpu.fielddescrof(v_inst.concretetype.TO,
                                       c_fieldname.value)
-        if isinstance(RESULT, lltype.Primitive):
-            kind = primitive_type_size[RESULT]
-        else:
-            kind = getkind(RESULT)[0]
+        kind = getkind(RESULT)[0]
         return SpaceOperation('getfield_%s_%s%s' % (argname, kind, pure),
                               [v_inst, descr], op.result)
 
@@ -302,10 +298,7 @@
         argname = getattr(v_inst.concretetype.TO, '_gckind', 'gc')
         descr = self.cpu.fielddescrof(v_inst.concretetype.TO,
                                       c_fieldname.value)
-        if isinstance(RESULT, lltype.Primitive):
-            kind = primitive_type_size[RESULT]
-        else:
-            kind = getkind(RESULT)[0]
+        kind = getkind(RESULT)[0]
         return SpaceOperation('setfield_%s_%s' % (argname, kind),
                               [v_inst, descr, v_value],
                               None)
@@ -406,12 +399,3 @@
     return result
 
 _rewrite_ops = _with_prefix('rewrite_op_')
-
-primitive_type_size = {
-    lltype.Signed:   'i',
-    lltype.Unsigned: 'i',
-    lltype.Bool:     'c',
-    lltype.Char:     'c',
-    lltype.UniChar:  'u',
-    lltype.Float:    'f',
-    }

Modified: pypy/branch/blackhole-improvement/pypy/jit/codewriter/liveness.py
==============================================================================
--- pypy/branch/blackhole-improvement/pypy/jit/codewriter/liveness.py	(original)
+++ pypy/branch/blackhole-improvement/pypy/jit/codewriter/liveness.py	Mon May  3 10:22:48 2010
@@ -13,6 +13,7 @@
 DEFAULT_OPNAMES_REQUIRING_LIVENESS = [
     'residual_call_',
     '(int|ref|float)_guard_value',
+    'guard_class',
     ]
 
 # ____________________________________________________________

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	Mon May  3 10:22:48 2010
@@ -3,7 +3,6 @@
 from pypy.jit.codewriter.flatten import flatten_graph, reorder_renaming_list
 from pypy.jit.codewriter.flatten import GraphFlattener, ListOfKind, Register
 from pypy.jit.codewriter.format import assert_format
-from pypy.jit.codewriter.jitter import transform_graph
 from pypy.jit.metainterp.history import AbstractDescr
 from pypy.rpython.lltypesystem import lltype, rclass, rstr
 from pypy.objspace.flow.model import SpaceOperation, Variable, Constant
@@ -72,10 +71,15 @@
         self.rtyper = support.annotate(func, values, type_system=type_system)
         return self.rtyper.annotator.translator.graphs
 
-    def encoding_test(self, func, args, expected, transform=False):
+    def encoding_test(self, func, args, expected,
+                      transform=False, liveness=False):
         graphs = self.make_graphs(func, args)
         if transform:
+            from pypy.jit.codewriter.jitter import transform_graph
             transform_graph(graphs[0], FakeCPU())
+        if liveness:
+            from pypy.jit.codewriter.liveness import compute_liveness
+            compute_liveness(graphs[0])
         ssarepr = flatten_graph(graphs[0], fake_regallocs())
         assert_format(ssarepr, expected)
 
@@ -187,6 +191,7 @@
             elif n == 7: return 1212
             else:        return 42
         self.encoding_test(f, [65], """
+            int_guard_value %i0, %i0
             goto_if_not_int_eq L1, %i0, $-5
             int_return $12
             L1:
@@ -376,8 +381,9 @@
                 return 42
         self.encoding_test(f, [7, 2], """
             int_add_ovf %i0, %i1, %i2
+            -live- %i2
             catch_exception L1
             int_return %i2
             L1:
             int_return $42
-        """, transform=True)
+        """, transform=True, liveness=True)

Modified: pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_jitter.py
==============================================================================
--- pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_jitter.py	(original)
+++ pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_jitter.py	Mon May  3 10:22:48 2010
@@ -161,9 +161,9 @@
                          ('ps1', 'i'),
                          ('ps2', 'r'),
                          ('flt', 'f'),
-                         ('boo', 'c'),
-                         ('chr', 'c'),
-                         ('unc', 'u')]:
+                         ('boo', 'i'),
+                         ('chr', 'i'),
+                         ('unc', 'i')]:
         v_parent = varoftype(lltype.Ptr(S))
         c_name = Constant(name, lltype.Void)
         v_result = varoftype(getattr(S, name))
@@ -199,9 +199,9 @@
                          ('ps1', 'i'),
                          ('ps2', 'r'),
                          ('flt', 'f'),
-                         ('boo', 'c'),
-                         ('chr', 'c'),
-                         ('unc', 'u')]:
+                         ('boo', 'i'),
+                         ('chr', 'i'),
+                         ('unc', 'i')]:
         v_parent = varoftype(lltype.Ptr(S))
         c_name = Constant(name, lltype.Void)
         v_newvalue = varoftype(getattr(S, name))

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	Mon May  3 10:22:48 2010
@@ -30,6 +30,25 @@
 
 NULL = lltype.nullptr(llmemory.GCREF.TO)
 
+def get_standard_error_llexception(rtyper, Class):
+    exdata = rtyper.getexceptiondata()
+    clsdef = rtyper.annotator.bookkeeper.getuniqueclassdef(Class)
+    evalue = exdata.get_standard_ll_exc_instance(rtyper, clsdef)
+    etype = rclass.ll_type(evalue)
+    return LLException(etype, evalue)
+
+def get_llexception(cpu, e):
+    if we_are_translated():
+        return e
+    if isinstance(e, LLException):
+        return e    # ok
+    if isinstance(e, OverflowError):
+        return get_standard_error_llexception(cpu.rtyper,
+                                              OverflowError)
+    raise   # leave other exceptions be propagated
+
+# ____________________________________________________________
+
 
 class BlackholeInterpBuilder(object):
     verbose = True
@@ -258,13 +277,7 @@
             #except JitException:
             #    ...
             except Exception, e:
-                if not we_are_translated():
-                    if isinstance(e, LLException):
-                        pass    # ok
-                    elif isinstance(e, OverflowError):
-                        e = self.get_standard_error_exception(OverflowError)
-                    else:
-                        raise   # leave other exceptions be propagated
+                e = get_llexception(self.cpu, e)
                 position = self.handle_exception_in_frame(e, code)
 
     def get_result_i(self):
@@ -309,14 +322,6 @@
             target = ord(code[position+1]) | (ord(code[position+2])<<8)
             return target
 
-    def get_standard_error_exception(self, Class):
-        rtyper = self.cpu.rtyper
-        exdata = rtyper.getexceptiondata()
-        clsdef = rtyper.annotator.bookkeeper.getuniqueclassdef(Class)
-        evalue = exdata.get_standard_ll_exc_instance(rtyper, clsdef)
-        etype = rclass.ll_type(evalue)
-        return LLException(etype, evalue)
-
     # XXX must be specialized
     # XXX the real performance impact of the following loop is unclear
     def copy_constants(self, registers, constants):
@@ -757,12 +762,6 @@
     @arguments("cpu", "r", "d", returns="i")
     def bhimpl_getfield_gc_i(cpu, struct, fielddescr):
         return cpu.bh_getfield_gc_i(struct, fielddescr)
-    @arguments("cpu", "r", "d", returns="i")
-    def bhimpl_getfield_gc_c(cpu, struct, fielddescr):
-        return cpu.bh_getfield_gc_c(struct, fielddescr)
-    @arguments("cpu", "r", "d", returns="i")
-    def bhimpl_getfield_gc_u(cpu, struct, fielddescr):
-        return cpu.bh_getfield_gc_u(struct, fielddescr)
     @arguments("cpu", "r", "d", returns="r")
     def bhimpl_getfield_gc_r(cpu, struct, fielddescr):
         return cpu.bh_getfield_gc_r(struct, fielddescr)
@@ -771,20 +770,12 @@
         return cpu.bh_getfield_gc_f(struct, fielddescr)
 
     bhimpl_getfield_gc_i_pure = bhimpl_getfield_gc_i
-    bhimpl_getfield_gc_c_pure = bhimpl_getfield_gc_c
-    bhimpl_getfield_gc_u_pure = bhimpl_getfield_gc_u
     bhimpl_getfield_gc_r_pure = bhimpl_getfield_gc_r
     bhimpl_getfield_gc_f_pure = bhimpl_getfield_gc_f
 
     @arguments("cpu", "i", "d", returns="i")
     def bhimpl_getfield_raw_i(cpu, struct, fielddescr):
         return cpu.bh_getfield_raw_i(struct, fielddescr)
-    @arguments("cpu", "i", "d", returns="i")
-    def bhimpl_getfield_raw_c(cpu, struct, fielddescr):
-        return cpu.bh_getfield_raw_c(struct, fielddescr)
-    @arguments("cpu", "i", "d", returns="i")
-    def bhimpl_getfield_raw_u(cpu, struct, fielddescr):
-        return cpu.bh_getfield_raw_u(struct, fielddescr)
     @arguments("cpu", "i", "d", returns="r")
     def bhimpl_getfield_raw_r(cpu, struct, fielddescr):
         return cpu.bh_getfield_raw_r(struct, fielddescr)
@@ -793,20 +784,12 @@
         return cpu.bh_getfield_raw_f(struct, fielddescr)
 
     bhimpl_getfield_raw_i_pure = bhimpl_getfield_raw_i
-    bhimpl_getfield_raw_c_pure = bhimpl_getfield_raw_c
-    bhimpl_getfield_raw_u_pure = bhimpl_getfield_raw_u
     bhimpl_getfield_raw_r_pure = bhimpl_getfield_raw_r
     bhimpl_getfield_raw_f_pure = bhimpl_getfield_raw_f
 
     @arguments("cpu", "r", "d", "i")
     def bhimpl_setfield_gc_i(cpu, struct, fielddescr, newvalue):
         cpu.bh_setfield_gc_i(struct, fielddescr, newvalue)
-    @arguments("cpu", "r", "d", "i")
-    def bhimpl_setfield_gc_c(cpu, struct, fielddescr, newvalue):
-        cpu.bh_setfield_gc_c(struct, fielddescr, newvalue)
-    @arguments("cpu", "r", "d", "i")
-    def bhimpl_setfield_gc_u(cpu, struct, fielddescr, newvalue):
-        cpu.bh_setfield_gc_u(struct, fielddescr, newvalue)
     @arguments("cpu", "r", "d", "r")
     def bhimpl_setfield_gc_r(cpu, struct, fielddescr, newvalue):
         cpu.bh_setfield_gc_r(struct, fielddescr, newvalue)
@@ -817,12 +800,6 @@
     @arguments("cpu", "i", "d", "i")
     def bhimpl_setfield_raw_i(cpu, struct, fielddescr, newvalue):
         cpu.bh_setfield_raw_i(struct, fielddescr, newvalue)
-    @arguments("cpu", "i", "d", "i")
-    def bhimpl_setfield_raw_c(cpu, struct, fielddescr, newvalue):
-        cpu.bh_setfield_raw_c(struct, fielddescr, newvalue)
-    @arguments("cpu", "i", "d", "i")
-    def bhimpl_setfield_raw_u(cpu, struct, fielddescr, newvalue):
-        cpu.bh_setfield_raw_u(struct, fielddescr, newvalue)
     @arguments("cpu", "i", "d", "r")
     def bhimpl_setfield_raw_r(cpu, struct, fielddescr, newvalue):
         cpu.bh_setfield_raw_r(struct, fielddescr, newvalue)

Modified: pypy/branch/blackhole-improvement/pypy/jit/metainterp/executor.py
==============================================================================
--- pypy/branch/blackhole-improvement/pypy/jit/metainterp/executor.py	(original)
+++ pypy/branch/blackhole-improvement/pypy/jit/metainterp/executor.py	Mon May  3 10:22:48 2010
@@ -12,10 +12,11 @@
 from pypy.jit.metainterp import resoperation
 from pypy.jit.metainterp.resoperation import rop
 from pypy.jit.metainterp.blackhole import BlackholeInterpreter, NULL
+from pypy.jit.metainterp.blackhole import get_llexception
 
 # ____________________________________________________________
 
-def do_call(cpu, argboxes, descr):
+def do_call(metainterp, argboxes, descr):
     # count the number of arguments of the different types
     count_i = count_r = count_f = 0
     for i in range(1, len(argboxes)):
@@ -45,23 +46,41 @@
             count_f += 1
     # get the function address as an integer
     func = argboxes[0].getint()
+    cpu = metainterp.cpu
+    metainterp.latest_exception_might_be = 'E'         # any Exception
     # do the call using the correct function from the cpu
     rettype = descr.get_return_type()
     if rettype == INT:
-        result = cpu.bh_call_i(func, descr, args_i, args_r, args_f)
+        try:
+            result = cpu.bh_call_i(func, descr, args_i, args_r, args_f)
+        except Exception, e:
+            metainterp.got_exception = get_llexception(cpu, e)
+            result = 0
         return BoxInt(result)
     if rettype == REF:
-        result = cpu.bh_call_r(func, descr, args_i, args_r, args_f)
+        try:
+            result = cpu.bh_call_r(func, descr, args_i, args_r, args_f)
+        except Exception, e:
+            metainterp.got_exception = get_llexception(cpu, e)
+            result = NULL
         return BoxPtr(result)
     if rettype == FLOAT:
-        result = cpu.bh_call_f(func, descr, args_i, args_r, args_f)
+        try:
+            result = cpu.bh_call_f(func, descr, args_i, args_r, args_f)
+        except Exception, e:
+            metainterp.got_exception = get_llexception(cpu, e)
+            result = 0.0
         return BoxFloat(result)
     if rettype == 'v':   # void
-        cpu.bh_call_v(func, descr, args_i, args_r, args_f)
+        try:
+            cpu.bh_call_v(func, descr, args_i, args_r, args_f)
+        except Exception, e:
+            metainterp.got_exception = get_llexception(cpu, e)
         return None
     raise AssertionError("bad rettype")
 
-def do_setarrayitem_gc(cpu, arraybox, indexbox, itembox, arraydescr):
+def do_setarrayitem_gc(metainterp, arraybox, indexbox, itembox, arraydescr):
+    cpu = metainterp.cpu
     array = arraybox.getref_base()
     index = indexbox.getint()
     if itembox.type == INT:
@@ -76,6 +95,59 @@
     else:
         raise AssertionError("bad itembox.type")
 
+def do_getfield_gc(metainterp, structbox, fielddescr):
+    cpu = metainterp.cpu
+    struct = structbox.getref_base()
+    if fielddescr.is_pointer_field():
+        return BoxPtr(cpu.bh_getfield_gc_p(struct, fielddescr))
+    elif fielddescr.is_float_field():
+        return BoxFloat(cpu.bh_getfield_gc_f(struct, fielddescr))
+    else:
+        return BoxInt(cpu.bh_getfield_gc_i(struct, fielddescr))
+
+def do_getfield_raw(metainterp, structbox, fielddescr):
+    cpu = metainterp.cpu
+    struct = structbox.getint()
+    if fielddescr.is_pointer_field():
+        return BoxPtr(cpu.bh_getfield_raw_p(struct, fielddescr))
+    elif fielddescr.is_float_field():
+        return BoxFloat(cpu.bh_getfield_raw_f(struct, fielddescr))
+    else:
+        return BoxInt(cpu.bh_getfield_raw_i(struct, fielddescr))
+
+def do_int_add_ovf(metainterp, box1, box2):
+    metainterp.latest_exception_might_be = 'O'    # only OverflowError
+    a = box1.getint()
+    b = box2.getint()
+    try:
+        z = ovfcheck(a + b)
+    except OverflowError, e:
+        metainterp.got_exception = get_llexception(metainterp.cpu, e)
+        z = 0
+    return BoxInt(z)
+
+def do_int_sub_ovf(metainterp, box1, box2):
+    metainterp.latest_exception_might_be = 'O'    # only OverflowError
+    a = box1.getint()
+    b = box2.getint()
+    try:
+        z = ovfcheck(a - b)
+    except OverflowError, e:
+        metainterp.got_exception = get_llexception(metainterp.cpu, e)
+        z = 0
+    return BoxInt(z)
+
+def do_int_mul_ovf(metainterp, box1, box2):
+    metainterp.latest_exception_might_be = 'O'    # only OverflowError
+    a = box1.getint()
+    b = box2.getint()
+    try:
+        z = ovfcheck(a * b)
+    except OverflowError, e:
+        metainterp.got_exception = get_llexception(metainterp.cpu, e)
+        z = 0
+    return BoxInt(z)
+
 # ____________________________________________________________
 
 ##def do_force_token(cpu):
@@ -165,11 +237,11 @@
     argtypes = unrolling_iterable(func.argtypes)
     resulttype = func.resulttype
     #
-    def do(cpu, *argboxes):
+    def do(metainterp, *argboxes):
         newargs = ()
         for argtype in argtypes:
             if argtype == 'cpu':
-                value = cpu
+                value = metainterp.cpu
             elif argtype == 'd':
                 value = argboxes[-1]
                 argboxes = argboxes[:-1]
@@ -211,25 +283,25 @@
 has_descr._annspecialcase_ = 'specialize:memo'
 
 
-def execute(cpu, opnum, descr, *argboxes):
+def execute(metainterp, opnum, descr, *argboxes):
     # only for opnums with a fixed arity
     if has_descr(opnum):
         check_descr(descr)
         argboxes = argboxes + (descr,)
     else:
         assert descr is None
-    func = get_execute_function(cpu, opnum, len(argboxes))
+    func = get_execute_function(metainterp.cpu, opnum, len(argboxes))
     assert func is not None
-    return func(cpu, *argboxes)     # note that the 'argboxes' tuple
-                                    # optionally ends with the descr
+    return func(metainterp, *argboxes)     # note that the 'argboxes' tuple
+                                           # optionally ends with the descr
 execute._annspecialcase_ = 'specialize:arg(1)'
 
-def execute_varargs(cpu, opnum, argboxes, descr):
+def execute_varargs(metainterp, opnum, argboxes, descr):
     # only for opnums with a variable arity (calls, typically)
     check_descr(descr)
-    func = get_execute_function(cpu, opnum, -1)
+    func = get_execute_function(metainterp.cpu, opnum, -1)
     assert func is not None
-    return func(cpu, argboxes, descr)
+    return func(metainterp, argboxes, descr)
 execute_varargs._annspecialcase_ = 'specialize:arg(1)'
 
 

Modified: pypy/branch/blackhole-improvement/pypy/jit/metainterp/jitprof.py
==============================================================================
--- pypy/branch/blackhole-improvement/pypy/jit/metainterp/jitprof.py	(original)
+++ pypy/branch/blackhole-improvement/pypy/jit/metainterp/jitprof.py	Mon May  3 10:22:48 2010
@@ -13,7 +13,6 @@
 BLACKHOLE
 OPS
 RECORDED_OPS
-BLACKHOLED_OPS
 GUARDS
 OPT_OPS
 OPT_GUARDS

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	Mon May  3 10:22:48 2010
@@ -11,7 +11,7 @@
 from pypy.jit.metainterp.resoperation import rop
 from pypy.jit.metainterp import executor
 from pypy.jit.metainterp.logger import Logger
-from pypy.jit.metainterp.jitprof import BLACKHOLED_OPS, EmptyProfiler
+from pypy.jit.metainterp.jitprof import EmptyProfiler
 from pypy.jit.metainterp.jitprof import GUARDS, RECORDED_OPS, ABORT_ESCAPE
 from pypy.jit.metainterp.jitprof import ABORT_TOO_LONG, ABORT_BRIDGE
 from pypy.rlib.rarithmetic import intmask
@@ -19,6 +19,7 @@
 from pypy.rlib.jit import DEBUG_OFF, DEBUG_PROFILE, DEBUG_STEPS, DEBUG_DETAILED
 from pypy.jit.metainterp.compile import GiveUp
 from pypy.jit.codewriter.assembler import JitCode
+from pypy.jit.codewriter.flatten import SwitchDictDescr
 
 # ____________________________________________________________
 
@@ -42,8 +43,13 @@
 
 
 class MIFrame(object):
-    exception_box = None
-    exc_value_box = None
+
+    last_exception = None      # the most recently raised-and-caught exception
+    # ^^^ not to be confused with MetaInterp.got_exception.  The idea is that
+    # got_exception is only briefly != None; as soon as the exception
+    # is caught by opimpl_catch_exception, it is reset to None and
+    # transferred to last_exception here.
+
     # for resume.py operation
     parent_resumedata_snapshot = None
     parent_resumedata_frame_info_list = None
@@ -128,6 +134,7 @@
     # ------------------------------
 
     for _opimpl in ['int_add', 'int_sub', 'int_mul', 'int_floordiv', 'int_mod',
+                    'int_add_ovf', 'int_sub_ovf', 'int_mul_ovf',
                     'int_lt', 'int_le', 'int_eq',
                     'int_ne', 'int_gt', 'int_ge',
                     'int_and', 'int_or', 'int_xor',
@@ -144,14 +151,6 @@
                 return self.execute(rop.%s, b1, b2)
         ''' % (_opimpl, _opimpl.upper())).compile()
 
-    for _opimpl in ['int_add_ovf', 'int_sub_ovf', 'int_mul_ovf']:
-        exec py.code.Source('''
-            @XXX  #arguments("box", "box")
-            def opimpl_%s(self, b1, b2):
-                self.execute(rop.%s, b1, b2)
-                return self.metainterp.handle_overflow_error()
-        ''' % (_opimpl, _opimpl.upper())).compile()
-
     for _opimpl in ['int_is_true', 'int_neg', 'int_invert', 'bool_not',
                     'cast_ptr_to_int', 'cast_float_to_int',
                     'cast_int_to_float', 'float_neg', 'float_abs',
@@ -175,11 +174,62 @@
     def opimpl_void_return(self):
         self.metainterp.finishframe(None)
 
-    @arguments("label")
-    def opimpl_catch_exception(self, target):
-        pass      # see comment in blackhole.py:opimpl_catch_exception.
+    @arguments("box")
+    def _opimpl_any_copy(self, box):
+        return box
 
-    @XXX  #arguments("jumptarget")
+    opimpl_int_copy   = _opimpl_any_copy
+    opimpl_ref_copy   = _opimpl_any_copy
+    opimpl_float_copy = _opimpl_any_copy
+
+    @arguments("box")
+    def _opimpl_any_push(self, box):
+        self.pushed_box = box
+
+    opimpl_int_push   = _opimpl_any_push
+    opimpl_ref_push   = _opimpl_any_push
+    opimpl_float_push = _opimpl_any_push
+
+    @arguments()
+    def _opimpl_any_pop(self):
+        box = self.pushed_box
+        self.pushed_box = None
+        return box
+
+    opimpl_int_pop   = _opimpl_any_pop
+    opimpl_ref_pop   = _opimpl_any_pop
+    opimpl_float_pop = _opimpl_any_pop
+
+    @arguments("orgpc", "catched_exception", "label")
+    def opimpl_catch_exception(self, pc, catched_exception, target):
+        if catched_exception is not None:
+            self.last_exception = catched_exception
+            self.pc = target
+        #
+        extraargs = []
+        latest_exception_might_be = self.metainterp.latest_exception_might_be
+        if not we_are_translated():
+            del self.metainterp.latest_exception_might_be
+        if latest_exception_might_be == 'O':
+            # only for int_xxx_ovf operations
+            if catched_exception is None:
+                opnum = rop.GUARD_NO_OVERFLOW
+            else:
+                opnum = rop.GUARD_OVERFLOW
+        else:
+            # for all residual calls
+            if catched_exception is None:
+                opnum = rop.GUARD_NO_EXCEPTION
+            else:
+                etype = catched_exception.typeptr   # XXX use the typesystem
+                etype = llmemory.cast_ptr_to_adr(etype)
+                etype = llmemory.cast_adr_to_int(etype)
+                exception_box = self.metainterp.cpu.ts.get_exception_box(etype)
+                extraargs = [exception_box]
+                opnum = rop.GUARD_EXCEPTION
+        self.generate_guard(pc, opnum, extraargs=extraargs)
+
+    @arguments("label")
     def opimpl_goto(self, target):
         self.pc = target
 
@@ -236,22 +286,13 @@
         self.load_int()       # past the 'box' argument
         self.ignore_varargs() # past the 'livelist' argument
 
-    @XXX  #arguments("orgpc", "box", "constargs", "jumptargets")
-    def opimpl_switch(self, pc, valuebox, constargs, jumptargets):
-        box = self.implement_guard_value(pc, valuebox)
-        for i in range(len(constargs)):
-            casebox = constargs[i]
-            if box.same_constant(casebox):
-                self.pc = jumptargets[i]
-                break
-
-    @XXX  #arguments("orgpc", "box", "constbox")
-    def opimpl_switch_dict(self, pc, valuebox, switchdict):
+    @arguments("orgpc", "box", "descr")
+    def opimpl_switch(self, pc, valuebox, switchdict):
         box = self.implement_guard_value(pc, valuebox)
-        search_value = box.getint()
-        assert isinstance(switchdict, codewriter.SwitchDict)
+        switchvalue = box.getint()
+        assert isinstance(switchdict, SwitchDictDescr)
         try:
-            self.pc = switchdict.dict[search_value]
+            self.pc = switchdict.dict[switchvalue]
         except KeyError:
             pass
 
@@ -436,28 +477,47 @@
     def opimpl_ptr_ne(self, box1, box2):
         self.execute(rop.OOISNOT, box1, box2)
 
-    opimpl_oois = opimpl_ptr_eq
-    opimpl_ooisnot = opimpl_ptr_ne
-
-    @XXX  #arguments("box", "descr")
-    def opimpl_getfield_gc(self, box, fielddesc):
-        self.execute_with_descr(rop.GETFIELD_GC, fielddesc, box)
-    @XXX  #arguments("box", "descr")
-    def opimpl_getfield_gc_pure(self, box, fielddesc):
-        self.execute_with_descr(rop.GETFIELD_GC_PURE, fielddesc, box)
-    @XXX  #arguments("box", "descr", "box")
-    def opimpl_setfield_gc(self, box, fielddesc, valuebox):
-        self.execute_with_descr(rop.SETFIELD_GC, fielddesc, box, valuebox)
-
-    @XXX  #arguments("box", "descr")
-    def opimpl_getfield_raw(self, box, fielddesc):
-        self.execute_with_descr(rop.GETFIELD_RAW, fielddesc, box)
-    @XXX  #arguments("box", "descr")
-    def opimpl_getfield_raw_pure(self, box, fielddesc):
-        self.execute_with_descr(rop.GETFIELD_RAW_PURE, fielddesc, box)
-    @XXX  #arguments("box", "descr", "box")
-    def opimpl_setfield_raw(self, box, fielddesc, valuebox):
-        self.execute_with_descr(rop.SETFIELD_RAW, fielddesc, box, valuebox)
+    @arguments("box", "descr")
+    def _opimpl_getfield_gc_any(self, box, fielddescr):
+        return self.execute_with_descr(rop.GETFIELD_GC, fielddescr, box)
+    opimpl_getfield_gc_i = _opimpl_getfield_gc_any
+    opimpl_getfield_gc_r = _opimpl_getfield_gc_any
+    opimpl_getfield_gc_f = _opimpl_getfield_gc_any
+
+    @arguments("box", "descr")
+    def _opimpl_getfield_gc_pure_any(self, box, fielddescr):
+        return self.execute_with_descr(rop.GETFIELD_GC_PURE, fielddescr, box)
+    opimpl_getfield_gc_i_pure = _opimpl_getfield_gc_pure_any
+    opimpl_getfield_gc_r_pure = _opimpl_getfield_gc_pure_any
+    opimpl_getfield_gc_f_pure = _opimpl_getfield_gc_pure_any
+
+    @arguments("box", "descr", "box")
+    def _opimpl_setfield_gc_any(self, box, fielddescr, valuebox):
+        self.execute_with_descr(rop.SETFIELD_GC, fielddescr, box, valuebox)
+    opimpl_setfield_gc_i = _opimpl_setfield_gc_any
+    opimpl_setfield_gc_r = _opimpl_setfield_gc_any
+    opimpl_setfield_gc_f = _opimpl_setfield_gc_any
+
+    @arguments("box", "descr")
+    def _opimpl_getfield_raw_any(self, box, fielddescr):
+        return self.execute_with_descr(rop.GETFIELD_RAW, fielddescr, box)
+    opimpl_getfield_raw_i = _opimpl_getfield_raw_any
+    opimpl_getfield_raw_r = _opimpl_getfield_raw_any
+    opimpl_getfield_raw_f = _opimpl_getfield_raw_any
+
+    @arguments("box", "descr")
+    def _opimpl_getfield_raw_pure_any(self, box, fielddescr):
+        return self.execute_with_descr(rop.GETFIELD_RAW_PURE, fielddescr, box)
+    opimpl_getfield_raw_i_pure = _opimpl_getfield_raw_pure_any
+    opimpl_getfield_raw_r_pure = _opimpl_getfield_raw_pure_any
+    opimpl_getfield_raw_f_pure = _opimpl_getfield_raw_pure_any
+
+    @arguments("box", "descr", "box")
+    def _opimpl_setfield_raw_any(self, box, fielddescr, valuebox):
+        self.execute_with_descr(rop.SETFIELD_RAW, fielddescr, box, valuebox)
+    opimpl_setfield_raw_i = _opimpl_setfield_raw_any
+    opimpl_setfield_raw_r = _opimpl_setfield_raw_any
+    opimpl_setfield_raw_f = _opimpl_setfield_raw_any
 
     def _nonstandard_virtualizable(self, pc, box):
         # returns True if 'box' is actually not the "standard" virtualizable
@@ -742,12 +802,11 @@
         constbox = self.implement_guard_value(pc, box)
         self.env[boxindex] = constbox
 
-    @XXX  #arguments("orgpc", "box")
+    @arguments("orgpc", "box")
     def opimpl_guard_class(self, pc, box):
         clsbox = self.cls_of_box(box)
-        if isinstance(box, Box):
-            self.generate_guard(pc, rop.GUARD_CLASS, box, [clsbox])
-        self.make_result_box(clsbox)
+        self.generate_guard(pc, rop.GUARD_CLASS, box, [clsbox])
+        return clsbox
 
 ##    @XXX  #arguments("orgpc", "box", "builtin")
 ##    def opimpl_guard_builtin(self, pc, box, builtin):
@@ -835,37 +894,26 @@
     def opimpl_teardown_exception_block(self):
         self.exception_target = -1
 
-    @XXX  #arguments("constbox", "jumptarget", "orgpc")
-    def opimpl_goto_if_exception_mismatch(self, vtableref, next_exc_target, pc):
-        # XXX used to be:
-        # assert isinstance(self.exception_box, Const)    # XXX
-        # seems this can happen that self.exception_box is not a Const,
-        # but I failed to write a test so far :-(
-        self.exception_box = self.implement_guard_value(pc, self.exception_box)
-        cpu = self.metainterp.cpu
-        ts = self.metainterp.cpu.ts
-        if not ts.subclassOf(cpu, self.exception_box, vtableref):
+    @arguments("box", "label")
+    def opimpl_goto_if_exception_mismatch(self, vtablebox, next_exc_target):
+        # XXX use typesystem.py
+        from pypy.rpython.lltypesystem import rclass
+        assert self.last_exception is not None
+        adr = vtablebox.getaddr(self.metainterp.cpu)
+        bounding_class = llmemory.cast_adr_to_ptr(adr, rclass.CLASSTYPE)
+        if not rclass.ll_isinstance(self.last_exception, bounding_class):
             self.pc = next_exc_target
 
-    @XXX  #arguments("int")
-    def opimpl_put_last_exception(self, index):
-        assert index >= 0
-        self.env.insert(index, self.exception_box)
-
-    @XXX  #arguments("int")
-    def opimpl_put_last_exc_value(self, index):
-        assert index >= 0
-        self.env.insert(index, self.exc_value_box)
-
     @XXX  #arguments()
     def opimpl_raise(self):
         assert len(self.env) == 2
         return self.metainterp.finishframe_exception(self.env[0], self.env[1])
 
-    @XXX  #arguments()
+    @arguments()
     def opimpl_reraise(self):
-        return self.metainterp.finishframe_exception(self.exception_box,
-                                                     self.exc_value_box)
+        assert self.last_exception is not None
+        self.metainterp.got_exception = self.last_exception
+        self.metainterp.propagate_exception_out_of_frame()
 
     @XXX  #arguments("box")
     def opimpl_virtual_ref(self, box):
@@ -950,7 +998,7 @@
         except ChangeFrame:
             pass
 
-    def generate_guard(self, pc, opnum, box, extraargs=[]):
+    def generate_guard(self, pc, opnum, box=None, extraargs=[]):
         if isinstance(box, Const):    # no need for a guard
             return
         metainterp = self.metainterp
@@ -1217,6 +1265,7 @@
 
 class MetaInterp(object):
     in_recursion = 0
+    got_exception = None
     _already_allocated_resume_virtuals = None
 
     def __init__(self, staticdata):
@@ -1355,15 +1404,11 @@
     @specialize.arg(1)
     def execute_and_record(self, opnum, descr, *argboxes):
         history.check_descr(descr)
-        assert (opnum != rop.CALL and opnum != rop.CALL_MAY_FORCE
-                and opnum != rop.OOSEND)
+        assert not (rop._CANRAISE_FIRST <= opnum <= rop._CANRAISE_LAST)
         # execute the operation
         profiler = self.staticdata.profiler
         profiler.count_ops(opnum)
-        resbox = executor.execute(self.cpu, opnum, descr, *argboxes)
-        if self.is_blackholing():
-            profiler.count_ops(opnum, BLACKHOLED_OPS)            
-            return resbox
+        resbox = executor.execute(self, opnum, descr, *argboxes)
         if rop._ALWAYS_PURE_FIRST <= opnum <= rop._ALWAYS_PURE_LAST:
             return self._record_helper_pure(opnum, resbox, descr, *argboxes)
         else:
@@ -1376,7 +1421,7 @@
         # execute the operation
         profiler = self.staticdata.profiler
         profiler.count_ops(opnum)
-        resbox = executor.execute_varargs(self.cpu, opnum, argboxes, descr)
+        resbox = executor.execute_varargs(self, opnum, argboxes, descr)
         if self.is_blackholing():
             profiler.count_ops(opnum, BLACKHOLED_OPS)
         else:
@@ -1848,6 +1893,7 @@
         return False
 
     def handle_overflow_error(self):
+        xxx
         frame = self.framestack[-1]
         if self.cpu._overflow_flag:
             self.cpu._overflow_flag = False
@@ -2096,10 +2142,19 @@
                 position = position3 + 1 + length3
             elif argtype == "orgpc":
                 value = orgpc
+            elif argtype == "catched_exception":
+                value = self.metainterp.got_exception
+                self.metainterp.got_exception = None
             else:
                 raise AssertionError("bad argtype: %r" % (argtype,))
             args += (value,)
         #
+        if self.metainterp.got_exception is not None:
+            # the previous operation raised and the current operation
+            # is not catching it.  Propagate it.
+            self.metainterp.propagate_exception_out_of_frame()
+            return
+        #
         num_return_args = len(argcodes) - next_argcode
         assert num_return_args == 0 or num_return_args == 1
         self.pc = position + num_return_args

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	Mon May  3 10:22:48 2010
@@ -74,7 +74,7 @@
     def cls_of_box(self, cpu, box):
         obj = box.getref(lltype.Ptr(rclass.OBJECT))
         cls = llmemory.cast_ptr_to_adr(obj.typeptr)
-        return history.ConstInt(cpu.cast_adr_to_int(cls))
+        return history.ConstInt(llmemory.cast_adr_to_int(cls))
 
     def subclassOf(self, cpu, clsbox1, clsbox2):
         adr = clsbox2.getaddr(cpu)
@@ -120,7 +120,7 @@
 
     def cast_vtable_to_hashable(self, cpu, ptr):
         adr = llmemory.cast_ptr_to_adr(ptr)
-        return cpu.cast_adr_to_int(adr)
+        return llmemory.cast_adr_to_int(adr)
 
     def cast_from_ref(self, TYPE, value):
         return lltype.cast_opaque_ptr(TYPE, value)



More information about the Pypy-commit mailing list