[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