Author: Maciej Fijalkowski <[email protected]>
Branch: cleanup-llgraph-backend
Changeset: r58146:71b0d3849c20
Date: 2012-10-16 21:01 +0200
http://bitbucket.org/pypy/pypy/changeset/71b0d3849c20/
Log: Start rewriting the llgraph backend. Enough
diff --git a/pypy/jit/backend/llgraph/runner.py
b/pypy/jit/backend/llgraph/+runner.py
copy from pypy/jit/backend/llgraph/runner.py
copy to pypy/jit/backend/llgraph/+runner.py
diff --git a/pypy/jit/backend/llgraph/runner.py
b/pypy/jit/backend/llgraph/runner.py
--- a/pypy/jit/backend/llgraph/runner.py
+++ b/pypy/jit/backend/llgraph/runner.py
@@ -1,912 +1,153 @@
-"""
-Minimal-API wrapper around the llinterpreter to run operations.
-"""
-from pypy.rlib.unroll import unrolling_iterable
-from pypy.rlib.objectmodel import we_are_translated
-from pypy.rlib.jit_hooks import LOOP_RUN_CONTAINER
-from pypy.rpython.lltypesystem import lltype, llmemory, rclass
-from pypy.rpython.ootypesystem import ootype
+from weakref import WeakKeyDictionary
+
+from pypy.jit.backend import model
+from pypy.jit.metainterp.history import Const
+from pypy.jit.metainterp.resoperation import rop
from pypy.rpython.llinterp import LLInterpreter
-from pypy.jit.metainterp import history
-from pypy.jit.metainterp.history import REF, INT, FLOAT, STRUCT
-from pypy.jit.metainterp.warmstate import unwrap
-from pypy.jit.metainterp.resoperation import rop
-from pypy.jit.backend import model
-from pypy.jit.backend.llgraph import llimpl, symbolic
-from pypy.jit.metainterp.typesystem import llhelper, oohelper
-from pypy.jit.codewriter import heaptracker, longlong
-class MiniStats:
- pass
+class LLLoop(object):
+ def __init__(self, inputargs, operations):
+ self.inputargs = inputargs
+ self.operations = operations
+class GuardFailed(Exception):
+ def __init__(self, failargs, descr):
+ self.failargs = failargs
+ self.descr = descr
-class Descr(history.AbstractDescr):
+class ExecutionFinished(Exception):
+ def __init__(self, descr, arg):
+ self.descr = descr
+ self.arg = arg
- def __init__(self, ofs, typeinfo, extrainfo=None, name=None,
- arg_types=None, count_fields_if_immut=-1, ffi_flags=0,
width=-1):
+class Jump(Exception):
+ def __init__(self, descr, args):
+ self.descr = descr
+ self.args = args
- self.ofs = ofs
- self.width = width
- self.typeinfo = typeinfo
- self.extrainfo = extrainfo
- self.name = name
- self.arg_types = arg_types
- self.count_fields_if_immut = count_fields_if_immut
- self.ffi_flags = ffi_flags
- self._debug = False
+class LLGraphCPU(model.AbstractCPU):
+ def __init__(self, rtyper):
+ self.rtyper = rtyper
+ self.llinterp = LLInterpreter(rtyper)
+ self.known_labels = WeakKeyDictionary()
- def set_debug(self, v):
- self._debug = True
-
- def get_arg_types(self):
- return self.arg_types
-
- def get_result_type(self):
- return self.typeinfo
-
- def get_extra_info(self):
- return self.extrainfo
-
- def sort_key(self):
- """Returns an integer that can be used as a key when sorting the
- field descrs of a single structure. The property that this
- number has is simply that two different field descrs of the same
- structure give different numbers."""
- return self.ofs
-
- def is_pointer_field(self):
- return self.typeinfo == REF
-
- def is_float_field(self):
- return self.typeinfo == FLOAT
-
- def is_array_of_pointers(self):
- return self.typeinfo == REF
-
- def is_array_of_floats(self):
- return self.typeinfo == FLOAT
-
- def is_array_of_structs(self):
- return self.typeinfo == STRUCT
-
- def as_vtable_size_descr(self):
- return self
-
- def count_fields_if_immutable(self):
- return self.count_fields_if_immut
-
- def get_ffi_flags(self):
- return self.ffi_flags
-
- def __lt__(self, other):
- raise TypeError("cannot use comparison on Descrs")
- def __le__(self, other):
- raise TypeError("cannot use comparison on Descrs")
- def __gt__(self, other):
- raise TypeError("cannot use comparison on Descrs")
- def __ge__(self, other):
- raise TypeError("cannot use comparison on Descrs")
-
- def __repr__(self):
- args = [repr(self.ofs), repr(self.typeinfo)]
- if self.name is not None:
- args.append(repr(self.name))
- if self.extrainfo is not None:
- args.append('E')
- return '<Descr %r>' % (', '.join(args),)
-
-
-history.TreeLoop._compiled_version = lltype.nullptr(llimpl.COMPILEDLOOP.TO)
-
-
-class BaseCPU(model.AbstractCPU):
- supports_floats = True
- supports_longlong = llimpl.IS_32_BIT
- supports_singlefloats = True
-
- def __init__(self, rtyper, stats=None, opts=None,
- translate_support_code=False,
- annmixlevel=None, gcdescr=None):
- assert type(opts) is not bool
- model.AbstractCPU.__init__(self)
- self.rtyper = rtyper
- self.translate_support_code = translate_support_code
- self.stats = stats or MiniStats()
- self.stats.exec_counters = {}
- self.stats.exec_jumps = 0
- self.stats.exec_conditional_jumps = 0
- llimpl._stats = self.stats
- llimpl._llinterp = LLInterpreter(self.rtyper)
- self._future_values = []
- self._descrs = {}
-
- def _cleanup_(self):
- assert self.translate_support_code
-
- def getdescr(self, ofs, typeinfo='?', extrainfo=None, name=None,
- arg_types=None, count_fields_if_immut=-1, ffi_flags=0,
width=-1):
- key = (ofs, typeinfo, extrainfo, name, arg_types,
- count_fields_if_immut, ffi_flags, width)
- try:
- return self._descrs[key]
- except KeyError:
- descr = Descr(ofs, typeinfo, extrainfo, name, arg_types,
- count_fields_if_immut, ffi_flags, width)
- self._descrs[key] = descr
- return descr
-
- def compile_bridge(self, faildescr, inputargs, operations,
- original_loop_token, log=True):
- c = llimpl.compile_start()
- clt = original_loop_token.compiled_loop_token
- clt.loop_and_bridges.append(c)
- clt.compiling_a_bridge()
- self._compile_loop_or_bridge(c, inputargs, operations, clt)
- old, oldindex = faildescr._compiled_fail
- llimpl.compile_redirect_fail(old, oldindex, c)
-
- def compile_loop(self, inputargs, operations, jitcell_token,
- log=True, name=''):
- """In a real assembler backend, this should assemble the given
- list of operations. Here we just generate a similar CompiledLoop
- instance. The code here is RPython, whereas the code in llimpl
- is not.
- """
- c = llimpl.compile_start()
- clt = model.CompiledLoopToken(self, jitcell_token.number)
- clt.loop_and_bridges = [c]
- clt.compiled_version = c
- jitcell_token.compiled_loop_token = clt
- self._compile_loop_or_bridge(c, inputargs, operations, clt)
-
- def free_loop_and_bridges(self, compiled_loop_token):
- for c in compiled_loop_token.loop_and_bridges:
- llimpl.mark_as_free(c)
- model.AbstractCPU.free_loop_and_bridges(self, compiled_loop_token)
-
- def _compile_loop_or_bridge(self, c, inputargs, operations, clt):
- var2index = {}
- for box in inputargs:
- if isinstance(box, history.BoxInt):
- var2index[box] = llimpl.compile_start_int_var(c)
- elif isinstance(box, self.ts.BoxRef):
- TYPE = self.ts.BASETYPE
- var2index[box] = llimpl.compile_start_ref_var(c, TYPE)
- elif isinstance(box, history.BoxFloat):
- var2index[box] = llimpl.compile_start_float_var(c)
- else:
- raise Exception("box is: %r" % (box,))
- llimpl.compile_started_vars(clt)
- self._compile_operations(c, operations, var2index, clt)
- return c
-
- def _compile_operations(self, c, operations, var2index, clt):
- for op in operations:
- if op.getopnum() == -124: # force_spill
- continue
- llimpl.compile_add(c, op.getopnum())
- descr = op.getdescr()
- if isinstance(descr, Descr):
- llimpl.compile_add_descr(c, descr.ofs, descr.typeinfo,
- descr.arg_types, descr.extrainfo,
- descr.width)
- if isinstance(descr, history.JitCellToken):
- assert op.getopnum() != rop.JUMP
- llimpl.compile_add_loop_token(c, descr)
- if isinstance(descr, history.TargetToken) and op.getopnum() ==
rop.LABEL:
- llimpl.compile_add_target_token(c, descr, clt)
- if self.is_oo and isinstance(descr, (OODescr, MethDescr)):
- # hack hack, not rpython
- c._obj.externalobj.operations[-1].setdescr(descr)
- for i in range(op.numargs()):
- x = op.getarg(i)
- if isinstance(x, history.Box):
- llimpl.compile_add_var(c, var2index[x])
- elif isinstance(x, history.ConstInt):
- llimpl.compile_add_int_const(c, x.value)
- elif isinstance(x, self.ts.ConstRef):
- llimpl.compile_add_ref_const(c, x.value, self.ts.BASETYPE)
- elif isinstance(x, history.ConstFloat):
- llimpl.compile_add_float_const(c, x.value)
- elif isinstance(x, Descr):
- llimpl.compile_add_descr_arg(c, x.ofs, x.typeinfo,
- x.arg_types)
- else:
- raise Exception("'%s' args contain: %r" % (op.getopname(),
- x))
- if op.is_guard():
- faildescr = op.getdescr()
- assert isinstance(faildescr, history.AbstractFailDescr)
- faildescr._fail_args_types = []
- for box in op.getfailargs():
- if box is None:
- type = history.HOLE
- else:
- type = box.type
- faildescr._fail_args_types.append(type)
- fail_index = self.get_fail_descr_number(faildescr)
- index = llimpl.compile_add_fail(c, fail_index)
- faildescr._compiled_fail = c, index
- for box in op.getfailargs():
- if box is not None:
- llimpl.compile_add_fail_arg(c, var2index[box])
- else:
- llimpl.compile_add_fail_arg(c, -1)
-
- x = op.result
- if x is not None:
- if isinstance(x, history.BoxInt):
- var2index[x] = llimpl.compile_add_int_result(c)
- elif isinstance(x, self.ts.BoxRef):
- var2index[x] = llimpl.compile_add_ref_result(c,
self.ts.BASETYPE)
- elif isinstance(x, history.BoxFloat):
- var2index[x] = llimpl.compile_add_float_result(c)
- else:
- raise Exception("%s.result contain: %r" % (op.getopname(),
- x))
- op = operations[-1]
- assert op.is_final()
- if op.getopnum() == rop.JUMP:
- targettoken = op.getdescr()
- llimpl.compile_add_jump_target(c, targettoken, clt)
- elif op.getopnum() == rop.FINISH:
- faildescr = op.getdescr()
- index = self.get_fail_descr_number(faildescr)
- llimpl.compile_add_fail(c, index)
- else:
- assert False, "unknown operation"
-
- def _execute_token(self, loop_token):
- compiled_version = loop_token.compiled_loop_token.compiled_version
- frame = llimpl.new_frame(self.is_oo, self)
- # setup the frame
- llimpl.frame_clear(frame, compiled_version)
- # run the loop
- fail_index = llimpl.frame_execute(frame)
- # we hit a FAIL operation.
- self.latest_frame = frame
- return fail_index
+ def compile_loop(self, inputargs, operations, looptoken, log=True,
name=''):
+ for i, op in enumerate(operations):
+ if op.getopnum() == rop.LABEL:
+ self.known_labels[op.getdescr()] = (operations, i)
+ looptoken._llgraph_loop = LLLoop(inputargs, operations)
def make_execute_token(self, *argtypes):
- nb_args = len(argtypes)
- unroll_argtypes = unrolling_iterable(list(enumerate(argtypes)))
- #
- def execute_token(loop_token, *args):
- assert len(args) == nb_args
- for index, TYPE in unroll_argtypes:
- x = args[index]
- assert TYPE == lltype.typeOf(x)
- if TYPE == lltype.Signed:
- llimpl.set_future_value_int(index, x)
- elif TYPE == llmemory.GCREF:
- llimpl.set_future_value_ref(index, x)
- elif TYPE == longlong.FLOATSTORAGE:
- llimpl.set_future_value_float(index, x)
- else:
- assert 0
- #
- fail_index = self._execute_token(loop_token)
- return self.get_fail_descr_from_number(fail_index)
- #
- return execute_token
+ return self._execute_token
+
+ def _execute_token(self, loop_token, *args):
+ loop = loop_token._llgraph_loop
+ frame = LLFrame(self, loop.inputargs, args)
+ try:
+ frame.execute(loop.operations)
+ assert False
+ except ExecutionFinished, e:
+ self.latest_values = [e.arg]
+ return e.descr
+ except GuardFailed, e:
+ self.latest_values = e.failargs
+ return e.descr
def get_latest_value_int(self, index):
- return llimpl.frame_int_getvalue(self.latest_frame, index)
+ return self.latest_values[index]
+ get_latest_value_float = get_latest_value_int
- def get_latest_value_ref(self, index):
- return llimpl.frame_ptr_getvalue(self.latest_frame, index)
+class LLFrame(object):
+ def __init__(self, cpu, argboxes, args):
+ self.env = {}
+ self.cpu = cpu
+ assert len(argboxes) == len(args)
+ for box, arg in zip(argboxes, args):
+ self.env[box] = arg
- def get_latest_value_float(self, index):
- return llimpl.frame_float_getvalue(self.latest_frame, index)
+ def lookup(self, arg):
+ if isinstance(arg, Const):
+ return arg.value
+ return self.env[arg]
- def get_latest_value_count(self):
- return llimpl.frame_get_value_count(self.latest_frame)
+ def execute(self, operations):
+ i = 0
+ while True:
+ op = operations[i]
+ args = [self.lookup(arg) for arg in op.getarglist()]
+ self.current_op = op # for label
+ try:
+ resval = getattr(self, 'execute_' +
op.getopname())(op.getdescr(),
+ *args)
+ except Jump, j:
+ operations, i = self.cpu.known_labels[j.descr]
+ label_op = operations[i]
+ self.do_renaming(label_op.getarglist(), j.args)
+ i += 1
+ continue
+ if op.result is not None:
+ assert resval is not None
+ self.env[op.result] = resval
+ else:
+ assert resval is None
+ i += 1
- def get_latest_force_token(self):
- token = llimpl.get_frame_forced_token(self.latest_frame)
- return heaptracker.adr2int(token)
+ def _getfailargs(self):
+ r = []
+ for arg in self.current_op.getfailargs():
+ if arg is None:
+ r.append(None)
+ else:
+ r.append(self.env[arg])
+ return r
- def clear_latest_values(self, count):
- llimpl.frame_clear_latest_values(self.latest_frame, count)
+ def do_renaming(self, newargs, oldargs):
+ assert len(newargs) == len(oldargs)
+ newenv = {}
+ for new, old in zip(newargs, oldargs):
+ newenv[new] = old
+ self.env = newenv
- def redirect_call_assembler(self, oldlooptoken, newlooptoken):
- if we_are_translated():
- raise ValueError("CALL_ASSEMBLER not supported")
- llimpl.redirect_call_assembler(self, oldlooptoken, newlooptoken)
+ # -----------------------------------------------------
- def invalidate_loop(self, looptoken):
- for loop in looptoken.compiled_loop_token.loop_and_bridges:
- loop._obj.externalobj.invalid = True
+ def execute_finish(self, descr, arg=None):
+ raise ExecutionFinished(descr, arg)
- # ----------
+ def execute_label(self, descr, *args):
+ argboxes = self.current_op.getarglist()
+ self.do_renaming(argboxes, args)
- def sizeof(self, S):
- assert not isinstance(S, lltype.Ptr)
- count = heaptracker.count_fields_if_immutable(S)
- return self.getdescr(symbolic.get_size(S), count_fields_if_immut=count)
+ def execute_guard_true(self, descr, arg):
+ if not arg:
+ raise GuardFailed(self._getfailargs(), descr)
+ def execute_jump(self, descr, *args):
+ raise Jump(descr, args)
-class LLtypeCPU(BaseCPU):
- is_oo = False
- ts = llhelper
+def _setup():
+ def _make_impl_from_blackhole_interp(opname):
+ from pypy.jit.metainterp.blackhole import BlackholeInterpreter
+ name = 'bhimpl_' + opname.lower()
+ try:
+ func = BlackholeInterpreter.__dict__[name]
+ except KeyError:
+ return
+ for argtype in func.argtypes:
+ if argtype not in ('i', 'r', 'f'):
+ return
+ #
+ def _op_default_implementation(self, descr, *args):
+ # for all operations implemented in the blackhole interpreter
+ return func(*args)
+ #
+ _op_default_implementation.func_name = 'execute_' + opname
+ return _op_default_implementation
- def __init__(self, *args, **kwds):
- BaseCPU.__init__(self, *args, **kwds)
- self.fielddescrof_vtable = self.fielddescrof(rclass.OBJECT, 'typeptr')
+ for k, v in rop.__dict__.iteritems():
+ if not k.startswith("_"):
+ func = _make_impl_from_blackhole_interp(k)
+ if func is not None:
+ setattr(LLFrame, 'execute_' + k.lower(), func)
- def fielddescrof(self, S, fieldname):
- ofs, size = symbolic.get_field_token(S, fieldname)
- token = history.getkind(getattr(S, fieldname))
- return self.getdescr(ofs, token[0], name=fieldname)
-
- def interiorfielddescrof(self, A, fieldname):
- S = A.OF
- width = symbolic.get_size(A)
- ofs, size = symbolic.get_field_token(S, fieldname)
- token = history.getkind(getattr(S, fieldname))
- return self.getdescr(ofs, token[0], name=fieldname, width=width)
-
- def calldescrof(self, FUNC, ARGS, RESULT, extrainfo):
- arg_types = []
- for ARG in ARGS:
- token = history.getkind(ARG)
- if token != 'void':
- if token == 'float' and longlong.is_longlong(ARG):
- token = 'L'
- arg_types.append(token[0])
- token = history.getkind(RESULT)
- if token == 'float' and longlong.is_longlong(RESULT):
- token = 'L'
- return self.getdescr(0, token[0], extrainfo=extrainfo,
- arg_types=''.join(arg_types))
-
- def calldescrof_dynamic(self, cif_description, extrainfo):
- from pypy.jit.backend.llsupport.ffisupport import get_ffi_type_kind
- from pypy.jit.backend.llsupport.ffisupport import UnsupportedKind
- arg_types = []
- try:
- for itp in range(cif_description.nargs):
- arg = cif_description.atypes[itp]
- kind = get_ffi_type_kind(self, arg)
- if kind != history.VOID:
- arg_types.append(kind)
- reskind = get_ffi_type_kind(self, cif_description.rtype)
- except UnsupportedKind:
- return None
- return self.getdescr(0, reskind, extrainfo=extrainfo,
- arg_types=''.join(arg_types),
- ffi_flags=cif_description.abi)
-
- def _calldescr_dynamic_for_tests(self, atypes, rtype,
- abiname='FFI_DEFAULT_ABI'):
- from pypy.jit.backend.llsupport import ffisupport
- return ffisupport.calldescr_dynamic_for_tests(self, atypes, rtype,
- abiname)
-
- def grab_exc_value(self):
- return llimpl.grab_exc_value()
-
- def arraydescrof(self, A):
- assert A.OF != lltype.Void
- assert isinstance(A, lltype.GcArray) or A._hints.get('nolength', False)
- size = symbolic.get_size(A)
- if isinstance(A.OF, lltype.Ptr) or isinstance(A.OF, lltype.Primitive):
- token = history.getkind(A.OF)[0]
- elif isinstance(A.OF, lltype.Struct):
- token = 's'
- else:
- token = '?'
- return self.getdescr(size, token)
-
- # ---------- the backend-dependent operations ----------
-
- def bh_strlen(self, string):
- return llimpl.do_strlen(string)
-
- def bh_strgetitem(self, string, index):
- return llimpl.do_strgetitem(string, index)
-
- def bh_unicodelen(self, string):
- return llimpl.do_unicodelen(string)
-
- def bh_unicodegetitem(self, string, index):
- return llimpl.do_unicodegetitem(string, index)
-
- def bh_getarrayitem_gc_i(self, arraydescr, array, index):
- assert isinstance(arraydescr, Descr)
- return llimpl.do_getarrayitem_gc_int(array, index)
- def bh_getarrayitem_raw_i(self, arraydescr, array, index):
- assert isinstance(arraydescr, Descr)
- return llimpl.do_getarrayitem_raw_int(array, index, arraydescr.ofs)
- def bh_getarrayitem_gc_r(self, arraydescr, array, index):
- assert isinstance(arraydescr, Descr)
- return llimpl.do_getarrayitem_gc_ptr(array, index)
- def bh_getarrayitem_gc_f(self, arraydescr, array, index):
- assert isinstance(arraydescr, Descr)
- return llimpl.do_getarrayitem_gc_float(array, index)
- def bh_getarrayitem_raw_f(self, arraydescr, array, index):
- assert isinstance(arraydescr, Descr)
- return llimpl.do_getarrayitem_raw_float(array, index)
-
- def bh_getfield_gc_i(self, struct, fielddescr):
- assert isinstance(fielddescr, Descr)
- return llimpl.do_getfield_gc_int(struct, fielddescr.ofs)
- def bh_getfield_gc_r(self, struct, fielddescr):
- assert isinstance(fielddescr, Descr)
- return llimpl.do_getfield_gc_ptr(struct, fielddescr.ofs)
- def bh_getfield_gc_f(self, struct, fielddescr):
- assert isinstance(fielddescr, Descr)
- return llimpl.do_getfield_gc_float(struct, fielddescr.ofs)
-
- def bh_getfield_raw_i(self, struct, fielddescr):
- assert isinstance(fielddescr, Descr)
- return llimpl.do_getfield_raw_int(struct, fielddescr.ofs)
- def bh_getfield_raw_r(self, struct, fielddescr):
- assert isinstance(fielddescr, Descr)
- return llimpl.do_getfield_raw_ptr(struct, fielddescr.ofs)
- def bh_getfield_raw_f(self, struct, fielddescr):
- assert isinstance(fielddescr, Descr)
- return llimpl.do_getfield_raw_float(struct, fielddescr.ofs)
-
- def bh_getinteriorfield_gc_i(self, array, index, descr):
- assert isinstance(descr, Descr)
- return llimpl.do_getinteriorfield_gc_int(array, index, descr.ofs)
- def bh_getinteriorfield_gc_r(self, array, index, descr):
- assert isinstance(descr, Descr)
- return llimpl.do_getinteriorfield_gc_ptr(array, index, descr.ofs)
- def bh_getinteriorfield_gc_f(self, array, index, descr):
- assert isinstance(descr, Descr)
- return llimpl.do_getinteriorfield_gc_float(array, index, descr.ofs)
-
- def bh_setinteriorfield_gc_i(self, array, index, descr, value):
- assert isinstance(descr, Descr)
- return llimpl.do_setinteriorfield_gc_int(array, index, descr.ofs,
- value)
- def bh_setinteriorfield_gc_r(self, array, index, descr, value):
- assert isinstance(descr, Descr)
- return llimpl.do_setinteriorfield_gc_ptr(array, index, descr.ofs,
- value)
- def bh_setinteriorfield_gc_f(self, array, index, descr, value):
- assert isinstance(descr, Descr)
- return llimpl.do_setinteriorfield_gc_float(array, index, descr.ofs,
- value)
-
- def bh_raw_store_i(self, struct, offset, descr, newvalue):
- assert isinstance(descr, Descr)
- return llimpl.do_raw_store_int(struct, offset, descr.ofs, newvalue)
- def bh_raw_store_f(self, struct, offset, descr, newvalue):
- assert isinstance(descr, Descr)
- return llimpl.do_raw_store_float(struct, offset, newvalue)
- def bh_raw_load_i(self, struct, offset, descr):
- assert isinstance(descr, Descr)
- return llimpl.do_raw_load_int(struct, offset, descr.ofs)
- def bh_raw_load_f(self, struct, offset, descr):
- assert isinstance(descr, Descr)
- return llimpl.do_raw_load_float(struct, offset)
-
- def bh_new(self, sizedescr):
- assert isinstance(sizedescr, Descr)
- return llimpl.do_new(sizedescr.ofs)
-
- def bh_new_with_vtable(self, sizedescr, vtable):
- assert isinstance(sizedescr, Descr)
- result = llimpl.do_new(sizedescr.ofs)
- llimpl.do_setfield_gc_int(result, self.fielddescrof_vtable.ofs, vtable)
- return result
-
- def bh_classof(self, struct):
- struct = lltype.cast_opaque_ptr(rclass.OBJECTPTR, struct)
- result_adr = llmemory.cast_ptr_to_adr(struct.typeptr)
- return heaptracker.adr2int(result_adr)
-
- def bh_new_array(self, arraydescr, length):
- assert isinstance(arraydescr, Descr)
- return llimpl.do_new_array(arraydescr.ofs, length)
-
- def bh_arraylen_gc(self, arraydescr, array):
- assert isinstance(arraydescr, Descr)
- return llimpl.do_arraylen_gc(arraydescr, array)
-
- def bh_setarrayitem_gc_i(self, arraydescr, array, index, newvalue):
- assert isinstance(arraydescr, Descr)
- llimpl.do_setarrayitem_gc_int(array, index, newvalue)
-
- def bh_setarrayitem_raw_i(self, arraydescr, array, index, newvalue):
- assert isinstance(arraydescr, Descr)
- llimpl.do_setarrayitem_raw_int(array, index, newvalue, arraydescr.ofs)
-
- def bh_setarrayitem_gc_r(self, arraydescr, array, index, newvalue):
- assert isinstance(arraydescr, Descr)
- llimpl.do_setarrayitem_gc_ptr(array, index, newvalue)
-
- def bh_setarrayitem_gc_f(self, arraydescr, array, index, newvalue):
- assert isinstance(arraydescr, Descr)
- llimpl.do_setarrayitem_gc_float(array, index, newvalue)
-
- def bh_setarrayitem_raw_f(self, arraydescr, array, index, newvalue):
- assert isinstance(arraydescr, Descr)
- llimpl.do_setarrayitem_raw_float(array, index, newvalue)
-
- def bh_setfield_gc_i(self, struct, fielddescr, newvalue):
- assert isinstance(fielddescr, Descr)
- llimpl.do_setfield_gc_int(struct, fielddescr.ofs, newvalue)
- def bh_setfield_gc_r(self, struct, fielddescr, newvalue):
- assert isinstance(fielddescr, Descr)
- llimpl.do_setfield_gc_ptr(struct, fielddescr.ofs, newvalue)
- def bh_setfield_gc_f(self, struct, fielddescr, newvalue):
- assert isinstance(fielddescr, Descr)
- llimpl.do_setfield_gc_float(struct, fielddescr.ofs, newvalue)
-
- def bh_setfield_raw_i(self, struct, fielddescr, newvalue):
- assert isinstance(fielddescr, Descr)
- llimpl.do_setfield_raw_int(struct, fielddescr.ofs, newvalue)
- def bh_setfield_raw_r(self, struct, fielddescr, newvalue):
- assert isinstance(fielddescr, Descr)
- llimpl.do_setfield_raw_ptr(struct, fielddescr.ofs, newvalue)
- def bh_setfield_raw_f(self, struct, fielddescr, newvalue):
- assert isinstance(fielddescr, Descr)
- llimpl.do_setfield_raw_float(struct, fielddescr.ofs, newvalue)
-
- def bh_newstr(self, length):
- return llimpl.do_newstr(length)
-
- def bh_newunicode(self, length):
- return llimpl.do_newunicode(length)
-
- def bh_strsetitem(self, string, index, newvalue):
- llimpl.do_strsetitem(string, index, newvalue)
-
- def bh_unicodesetitem(self, string, index, newvalue):
- llimpl.do_unicodesetitem(string, index, newvalue)
-
- def bh_call_i(self, func, calldescr, args_i, args_r, args_f):
- self._prepare_call(INT, calldescr, args_i, args_r, args_f)
- return llimpl.do_call_int(func)
- def bh_call_r(self, func, calldescr, args_i, args_r, args_f):
- self._prepare_call(REF, calldescr, args_i, args_r, args_f)
- return llimpl.do_call_ptr(func)
- def bh_call_f(self, func, calldescr, args_i, args_r, args_f):
- self._prepare_call(FLOAT + 'L', calldescr, args_i, args_r, args_f)
- return llimpl.do_call_float(func)
- def bh_call_v(self, func, calldescr, args_i, args_r, args_f):
- self._prepare_call('v', calldescr, args_i, args_r, args_f)
- llimpl.do_call_void(func)
-
- def _prepare_call(self, resulttypeinfo, calldescr, args_i, args_r, args_f):
- assert isinstance(calldescr, Descr)
- assert calldescr.typeinfo in resulttypeinfo
- if args_i is not None:
- for x in args_i:
- llimpl.do_call_pushint(x)
- if args_r is not None:
- for x in args_r:
- llimpl.do_call_pushptr(x)
- if args_f is not None:
- for x in args_f:
- llimpl.do_call_pushfloat(x)
-
- def get_all_loop_runs(self):
- return lltype.malloc(LOOP_RUN_CONTAINER, 0)
-
- def force(self, force_token):
- token = llmemory.cast_int_to_adr(force_token)
- frame = llimpl.get_forced_token_frame(token)
- fail_index = llimpl.force(frame)
- self.latest_frame = frame
- return self.get_fail_descr_from_number(fail_index)
-
-
-class OOtypeCPU_xxx_disabled(BaseCPU):
- is_oo = True
- ts = oohelper
-
- @staticmethod
- def fielddescrof(T, fieldname):
- # use class where the field is really defined as a key
- T1, _ = T._lookup_field(fieldname)
- return FieldDescr.new(T1, fieldname)
-
- @staticmethod
- def calldescrof(FUNC, ARGS, RESULT, extrainfo):
- return StaticMethDescr.new(FUNC, ARGS, RESULT, extrainfo)
-
- @staticmethod
- def methdescrof(SELFTYPE, methname):
- return MethDescr.new(SELFTYPE, methname)
-
- @staticmethod
- def typedescrof(TYPE):
- return TypeDescr.new(TYPE)
-
- @staticmethod
- def arraydescrof(A):
- assert isinstance(A, ootype.Array)
- TYPE = A.ITEM
- return TypeDescr.new(TYPE)
-
- def typedescr2classbox(self, descr):
- assert isinstance(descr, TypeDescr)
- return history.ConstObj(ootype.cast_to_object(
- ootype.runtimeClass(descr.TYPE)))
-
- def get_exception(self):
- if llimpl._last_exception:
- e = llimpl._last_exception.args[0]
- return ootype.cast_to_object(e)
- else:
- return ootype.NULL
-
- def get_exc_value(self):
- if llimpl._last_exception:
- earg = llimpl._last_exception.args[1]
- return ootype.cast_to_object(earg)
- else:
- return ootype.NULL
-
- def get_overflow_error(self):
- ll_err = llimpl._get_error(OverflowError)
- return (ootype.cast_to_object(ll_err.args[0]),
- ootype.cast_to_object(ll_err.args[1]))
-
- def get_zero_division_error(self):
- ll_err = llimpl._get_error(ZeroDivisionError)
- return (ootype.cast_to_object(ll_err.args[0]),
- ootype.cast_to_object(ll_err.args[1]))
-
- def do_new_with_vtable(self, clsbox):
- cls = clsbox.getref_base()
- typedescr = self.class_sizes[cls]
- return typedescr.create()
-
- def do_new_array(self, lengthbox, typedescr):
- assert isinstance(typedescr, TypeDescr)
- return typedescr.create_array(lengthbox)
-
- def do_new(self, typedescr):
- assert isinstance(typedescr, TypeDescr)
- return typedescr.create()
-
- def do_runtimenew(self, classbox):
- "NOT_RPYTHON"
- classobj = classbox.getref(ootype.Class)
- res = ootype.runtimenew(classobj)
- return history.BoxObj(ootype.cast_to_object(res))
-
- def do_instanceof(self, box1, typedescr):
- assert isinstance(typedescr, TypeDescr)
- return typedescr.instanceof(box1)
-
- def do_getfield_gc(self, box1, fielddescr):
- assert isinstance(fielddescr, FieldDescr)
- return fielddescr.getfield(box1)
-
- def do_setfield_gc(self, box1, box2, fielddescr):
- assert isinstance(fielddescr, FieldDescr)
- return fielddescr.setfield(box1, box2)
-
- def do_getarrayitem_gc(self, box1, box2, typedescr):
- assert isinstance(typedescr, TypeDescr)
- return typedescr.getarrayitem(box1, box2)
-
- def do_setarrayitem_gc(self, box1, box2, box3, typedescr):
- assert isinstance(typedescr, TypeDescr)
- return typedescr.setarrayitem(box1, box2, box3)
-
- def do_arraylen_gc(self, box1, typedescr):
- assert isinstance(typedescr, TypeDescr)
- return typedescr.getarraylength(box1)
-
- def do_call_XXX(self, args, descr):
- assert isinstance(descr, StaticMethDescr)
- funcbox = args[0]
- argboxes = args[1:]
- x = descr.callfunc(funcbox, argboxes)
- # XXX: return None if RESULT is Void
- return x
-
- def do_oosend(self, args, descr):
- assert isinstance(descr, MethDescr)
- selfbox = args[0]
- argboxes = args[1:]
- x = descr.callmeth(selfbox, argboxes)
- # XXX: return None if METH.RESULT is Void
- return x
-
-
-def make_getargs(ARGS):
- argsiter = unrolling_iterable(ARGS)
- args_n = len([ARG for ARG in ARGS if ARG is not ootype.Void])
- def getargs(argboxes):
- funcargs = ()
- assert len(argboxes) == args_n
- i = 0
- for ARG in argsiter:
- if ARG is ootype.Void:
- funcargs += (None,)
- else:
- box = argboxes[i]
- i+=1
- funcargs += (unwrap(ARG, box),)
- return funcargs
- return getargs
-
-def boxresult(RESULT, result):
- if isinstance(RESULT, ootype.OOType):
- return history.BoxObj(ootype.cast_to_object(result))
- elif RESULT is lltype.Float:
- return history.BoxFloat(result)
- else:
- return history.BoxInt(lltype.cast_primitive(ootype.Signed, result))
-boxresult._annspecialcase_ = 'specialize:arg(0)'
-
-
-class KeyManager(object):
- """
- Helper class to convert arbitrary dictionary keys to integers.
- """
-
- def __init__(self):
- self.keys = {}
-
- def getkey(self, key):
- try:
- return self.keys[key]
- except KeyError:
- n = len(self.keys)
- self.keys[key] = n
- return n
-
- def _freeze_(self):
- raise Exception("KeyManager is not supposed to be turned into a pbc")
-
-
-descr_cache = {}
-class OODescr(history.AbstractDescr):
-
- @classmethod
- def new(cls, *args):
- 'NOT_RPYTHON'
- key = (cls, args)
- try:
- return descr_cache[key]
- except KeyError:
- res = cls(*args)
- descr_cache[key] = res
- return res
-
-class StaticMethDescr(OODescr):
-
- def __init__(self, FUNC, ARGS, RESULT, extrainfo=None):
- self.FUNC = FUNC
- getargs = make_getargs(FUNC.ARGS)
- def callfunc(funcbox, argboxes):
- funcobj = funcbox.getref(FUNC)
- funcargs = getargs(argboxes)
- res = llimpl.call_maybe_on_top_of_llinterp(funcobj, funcargs)
- if RESULT is not ootype.Void:
- return boxresult(RESULT, res)
- self.callfunc = callfunc
- self.extrainfo = extrainfo
-
- def get_extra_info(self):
- return self.extrainfo
-
-class MethDescr(history.AbstractMethDescr):
-
- callmeth = None
-
- new = classmethod(OODescr.new.im_func)
-
- def __init__(self, SELFTYPE, methname):
- _, meth = SELFTYPE._lookup(methname)
- METH = ootype.typeOf(meth)
- self.SELFTYPE = SELFTYPE
- self.METH = METH
- self.methname = methname
- RESULT = METH.RESULT
- getargs = make_getargs(METH.ARGS)
- def callmeth(selfbox, argboxes):
- selfobj = selfbox.getref(SELFTYPE)
- meth = getattr(selfobj, methname)
- methargs = getargs(argboxes)
- res = llimpl.call_maybe_on_top_of_llinterp(meth, methargs)
- if RESULT is not ootype.Void:
- return boxresult(RESULT, res)
- self.callmeth = callmeth
-
- def __repr__(self):
- return '<MethDescr %r>' % self.methname
-
-class TypeDescr(OODescr):
-
- create = None
-
- def __init__(self, TYPE):
- self.TYPE = TYPE
- self.ARRAY = ARRAY = ootype.Array(TYPE)
- def create():
- return boxresult(TYPE, ootype.new(TYPE))
-
- def create_array(lengthbox):
- n = lengthbox.getint()
- return boxresult(ARRAY, ootype.oonewarray(ARRAY, n))
-
- def getarrayitem(arraybox, ibox):
- array = arraybox.getref(ARRAY)
- i = ibox.getint()
- return boxresult(TYPE, array.ll_getitem_fast(i))
-
- def setarrayitem(arraybox, ibox, valuebox):
- array = arraybox.getref(ARRAY)
- i = ibox.getint()
- value = unwrap(TYPE, valuebox)
- array.ll_setitem_fast(i, value)
-
- def getarraylength(arraybox):
- array = arraybox.getref(ARRAY)
- return boxresult(ootype.Signed, array.ll_length())
-
- def instanceof(box):
- obj = box.getref(ootype.ROOT)
- return history.BoxInt(ootype.instanceof(obj, TYPE))
-
- self.create = create
- self.create_array = create_array
- self.getarrayitem = getarrayitem
- self.setarrayitem = setarrayitem
- self.getarraylength = getarraylength
- self.instanceof = instanceof
- self._is_array_of_pointers = (history.getkind(TYPE) == 'ref')
- self._is_array_of_floats = (history.getkind(TYPE) == 'float')
-
- def is_array_of_pointers(self):
- # for arrays, TYPE is the type of the array item.
- return self._is_array_of_pointers
-
- def is_array_of_floats(self):
- # for arrays, TYPE is the type of the array item.
- return self._is_array_of_floats
-
- def __repr__(self):
- return '<TypeDescr %s>' % self.TYPE._short_name()
-
-class FieldDescr(OODescr):
-
- getfield = None
- _keys = KeyManager()
-
- def __init__(self, TYPE, fieldname):
- self.TYPE = TYPE
- self.fieldname = fieldname
-
- _, T = TYPE._lookup_field(fieldname)
- def getfield(objbox):
- obj = objbox.getref(TYPE)
- value = getattr(obj, fieldname)
- return boxresult(T, value)
- def setfield(objbox, valuebox):
- obj = objbox.getref(TYPE)
- value = unwrap(T, valuebox)
- setattr(obj, fieldname, value)
-
- self.getfield = getfield
- self.setfield = setfield
- self._is_pointer_field = (history.getkind(T) == 'ref')
- self._is_float_field = (history.getkind(T) == 'float')
-
- def sort_key(self):
- return self._keys.getkey((self.TYPE, self.fieldname))
-
- def is_pointer_field(self):
- return self._is_pointer_field
-
- def is_float_field(self):
- return self._is_float_field
-
- def equals(self, other):
- return self.TYPE == other.TYPE and \
- self.fieldname == other.fieldname
-
- def __repr__(self):
- return '<FieldDescr %r>' % self.fieldname
+_setup()
diff --git a/pypy/jit/backend/llgraph/test/test_llgraph.py
b/pypy/jit/backend/llgraph/test/test_llgraph.py
--- a/pypy/jit/backend/llgraph/test/test_llgraph.py
+++ b/pypy/jit/backend/llgraph/test/test_llgraph.py
@@ -14,7 +14,7 @@
# for individual tests see:
# ====> ../../test/runner_test.py
- from pypy.jit.backend.llgraph.runner import LLtypeCPU as cpu_type
+ from pypy.jit.backend.llgraph.runner import LLGraphCPU as cpu_type
def setup_method(self, _):
self.cpu = self.cpu_type(None)
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit