Author: Alex Gaynor <[email protected]>
Branch: better-jit-hooks
Changeset: r51142:ade5f6c6f404
Date: 2012-01-08 12:54 -0600
http://bitbucket.org/pypy/pypy/changeset/ade5f6c6f404/
Log: merged upstream
diff --git a/pypy/jit/metainterp/compile.py b/pypy/jit/metainterp/compile.py
--- a/pypy/jit/metainterp/compile.py
+++ b/pypy/jit/metainterp/compile.py
@@ -305,6 +305,13 @@
show_procedures(metainterp_sd, loop)
loop.check_consistency()
+ if metainterp_sd.warmrunnerdesc is not None:
+ portal = metainterp_sd.warmrunnerdesc.portal
+ portal.before_compile(jitdriver_sd.jitdriver, metainterp_sd.logger_ops,
+ original_jitcell_token, loop.operations, type,
+ greenkey)
+ else:
+ portal = None
operations = get_deep_immutable_oplist(loop.operations)
metainterp_sd.profiler.start_backend()
debug_start("jit-backend")
@@ -316,11 +323,10 @@
finally:
debug_stop("jit-backend")
metainterp_sd.profiler.end_backend()
- if metainterp_sd.warmrunnerdesc is not None:
- portal = metainterp_sd.warmrunnerdesc.portal
- portal.on_compile(jitdriver_sd.jitdriver, metainterp_sd.logger_ops,
- original_jitcell_token, loop.operations, type,
- greenkey, ops_offset, asmstart, asmlen)
+ if portal is not None:
+ portal.after_compile(jitdriver_sd.jitdriver, metainterp_sd.logger_ops,
+ original_jitcell_token, loop.operations, type,
+ greenkey, ops_offset, asmstart, asmlen)
metainterp_sd.stats.add_new_loop(loop)
if not we_are_translated():
metainterp_sd.stats.compiled()
@@ -341,8 +347,15 @@
show_procedures(metainterp_sd)
seen = dict.fromkeys(inputargs)
TreeLoop.check_consistency_of_branch(operations, seen)
+ if metainterp_sd.warmrunnerdesc is not None:
+ portal = metainterp_sd.warmrunnerdesc.portal
+ portal.before_compile_bridge(jitdriver_sd.jitdriver,
+ metainterp_sd.logger_ops,
+ original_loop_token, operations, n)
+ else:
+ portal = None
+ operations = get_deep_immutable_oplist(operations)
metainterp_sd.profiler.start_backend()
- operations = get_deep_immutable_oplist(operations)
debug_start("jit-backend")
try:
tp = metainterp_sd.cpu.compile_bridge(faildescr, inputargs, operations,
@@ -351,12 +364,12 @@
finally:
debug_stop("jit-backend")
metainterp_sd.profiler.end_backend()
- if metainterp_sd.warmrunnerdesc is not None:
- portal = metainterp_sd.warmrunnerdesc.portal
- portal.on_compile_bridge(jitdriver_sd.jitdriver,
- metainterp_sd.logger_ops,
- original_loop_token, operations, n,
ops_offset,
- asmstart, asmlen)
+ if portal is not None:
+ portal.after_compile_bridge(jitdriver_sd.jitdriver,
+ metainterp_sd.logger_ops,
+ original_loop_token, operations, n,
+ ops_offset,
+ asmstart, asmlen)
if not we_are_translated():
metainterp_sd.stats.compiled()
metainterp_sd.log("compiled new bridge")
diff --git a/pypy/jit/metainterp/test/test_jitportal.py
b/pypy/jit/metainterp/test/test_jitportal.py
--- a/pypy/jit/metainterp/test/test_jitportal.py
+++ b/pypy/jit/metainterp/test/test_jitportal.py
@@ -5,6 +5,7 @@
from pypy.jit.codewriter.policy import JitPolicy
from pypy.jit.metainterp.jitprof import ABORT_FORCE_QUASIIMMUT
from pypy.jit.metainterp.resoperation import rop
+from pypy.rpython.annlowlevel import hlstr
class TestJitPortal(LLJitMixin):
def test_abort_quasi_immut(self):
@@ -41,14 +42,25 @@
assert reasons == [ABORT_FORCE_QUASIIMMUT] * 2
def test_on_compile(self):
- called = {}
+ called = []
class MyJitPortal(JitPortal):
- def on_compile(self, jitdriver, logger, looptoken, operations,
- type, greenkey, ops_offset, asmaddr, asmlen):
+ def after_compile(self, jitdriver, logger, looptoken, operations,
+ type, greenkey, ops_offset, asmaddr, asmlen):
assert asmaddr == 0
assert asmlen == 0
- called[(greenkey[1].getint(), greenkey[0].getint(), type)] =
looptoken
+ called.append(("compile", greenkey[1].getint(),
+ greenkey[0].getint(), type))
+
+ def before_compile(self, jitdriver, logger, looptoken, oeprations,
+ type, greenkey):
+ called.append(("optimize", greenkey[1].getint(),
+ greenkey[0].getint(), type))
+
+ def before_optimize(self, jitdriver, logger, looptoken, oeprations,
+ type, greenkey):
+ called.append(("trace", greenkey[1].getint(),
+ greenkey[0].getint(), type))
portal = MyJitPortal()
@@ -62,26 +74,35 @@
i += 1
self.meta_interp(loop, [1, 4], policy=JitPolicy(portal))
- assert sorted(called.keys()) == [(4, 1, "loop")]
+ assert called == [#("trace", 4, 1, "loop"),
+ ("optimize", 4, 1, "loop"),
+ ("compile", 4, 1, "loop")]
self.meta_interp(loop, [2, 4], policy=JitPolicy(portal))
- assert sorted(called.keys()) == [(4, 1, "loop"),
- (4, 2, "loop")]
+ assert called == [#("trace", 4, 1, "loop"),
+ ("optimize", 4, 1, "loop"),
+ ("compile", 4, 1, "loop"),
+ #("trace", 4, 2, "loop"),
+ ("optimize", 4, 2, "loop"),
+ ("compile", 4, 2, "loop")]
def test_on_compile_bridge(self):
- called = {}
+ called = []
class MyJitPortal(JitPortal):
- def on_compile(self, jitdriver, logger, looptoken, operations,
+ def after_compile(self, jitdriver, logger, looptoken, operations,
type, greenkey, ops_offset, asmaddr, asmlen):
assert asmaddr == 0
assert asmlen == 0
- called[(greenkey[1].getint(), greenkey[0].getint(), type)] =
looptoken
+ called.append("compile")
- def on_compile_bridge(self, jitdriver, logger, orig_token,
- operations, n, ops_offset, asmstart, asmlen):
- assert 'bridge' not in called
- called['bridge'] = orig_token
+ def after_compile_bridge(self, jitdriver, logger, orig_token,
+ operations, n, ops_offset, asmstart,
asmlen):
+ called.append("compile_bridge")
+ def before_compile_bridge(self, jitdriver, logger, orig_token,
+ operations, n):
+ called.append("before_compile_bridge")
+
driver = JitDriver(greens = ['n', 'm'], reds = ['i'])
def loop(n, m):
@@ -94,7 +115,7 @@
i += 1
self.meta_interp(loop, [1, 10], policy=JitPolicy(MyJitPortal()))
- assert sorted(called.keys()) == ['bridge', (10, 1, "loop")]
+ assert called == ["compile", "before_compile_bridge", "compile_bridge"]
def test_resop_interface(self):
driver = JitDriver(greens = [], reds = ['i'])
@@ -110,7 +131,18 @@
[jit_hooks.boxint_new(3),
jit_hooks.boxint_new(4)],
jit_hooks.boxint_new(1))
- return jit_hooks.resop_opnum(op)
+ assert hlstr(jit_hooks.resop_getopname(op)) == 'int_add'
+ assert jit_hooks.resop_getopnum(op) == rop.INT_ADD
+ box = jit_hooks.resop_getarg(op, 0)
+ assert jit_hooks.box_getint(box) == 3
+ box2 = jit_hooks.box_clone(box)
+ assert box2 != box
+ assert jit_hooks.box_getint(box2) == 3
+ assert not jit_hooks.box_isconst(box2)
+ box3 = jit_hooks.box_constbox(box)
+ assert jit_hooks.box_getint(box) == 3
+ assert jit_hooks.box_isconst(box3)
+ box4 = jit_hooks.box_nonconstbox(box)
+ assert not jit_hooks.box_isconst(box4)
- res = self.meta_interp(main, [])
- assert res == rop.INT_ADD
+ self.meta_interp(main, [])
diff --git a/pypy/module/pypyjit/__init__.py b/pypy/module/pypyjit/__init__.py
--- a/pypy/module/pypyjit/__init__.py
+++ b/pypy/module/pypyjit/__init__.py
@@ -8,8 +8,10 @@
'set_param': 'interp_jit.set_param',
'residual_call': 'interp_jit.residual_call',
'set_compile_hook': 'interp_resop.set_compile_hook',
+ 'set_optimize_hook': 'interp_resop.set_optimize_hook',
'set_abort_hook': 'interp_resop.set_abort_hook',
'ResOperation': 'interp_resop.WrappedOp',
+ 'Box': 'interp_resop.WrappedBox',
}
def setup_after_space_initialization(self):
diff --git a/pypy/module/pypyjit/interp_resop.py
b/pypy/module/pypyjit/interp_resop.py
--- a/pypy/module/pypyjit/interp_resop.py
+++ b/pypy/module/pypyjit/interp_resop.py
@@ -5,7 +5,7 @@
from pypy.interpreter.pycode import PyCode
from pypy.interpreter.error import OperationError
from pypy.rpython.lltypesystem import lltype, llmemory
-from pypy.rpython.annlowlevel import cast_base_ptr_to_instance
+from pypy.rpython.annlowlevel import cast_base_ptr_to_instance, hlstr
from pypy.rpython.lltypesystem.rclass import OBJECT
from pypy.jit.metainterp.resoperation import rop, AbstractResOp
from pypy.rlib.nonconst import NonConstant
@@ -61,6 +61,37 @@
cache.in_recursion = NonConstant(False)
return space.w_None
+def set_optimize_hook(space, w_hook):
+ """ set_compile_hook(hook)
+
+ Set a compiling hook that will be called each time a loop is optimized,
+ but before assembler compilation. This allows to add additional
+ optimizations on Python level.
+
+ The hook will be called with the following signature:
+ hook(jitdriver_name, loop_type, greenkey or guard_number, operations)
+
+ jitdriver_name is the name of this particular jitdriver, 'pypyjit' is
+ the main interpreter loop
+
+ loop_type can be either `loop` `entry_bridge` or `bridge`
+ in case loop is not `bridge`, greenkey will be a tuple of constants
+ or a string describing it.
+
+ for the interpreter loop` it'll be a tuple
+ (code, offset, is_being_profiled)
+
+ Note that jit hook is not reentrant. It means that if the code
+ inside the jit hook is itself jitted, it will get compiled, but the
+ jit hook won't be called for that.
+
+ Result value will be the resulting list of operations, or None
+ """
+ cache = space.fromcache(Cache)
+ cache.w_optimize_hook = w_hook
+ cache.in_recursion = NonConstant(False)
+ return space.w_None
+
def set_abort_hook(space, w_hook):
""" set_abort_hook(hook)
@@ -83,14 +114,12 @@
logops.repr_of_resop(op)) for op in operations]
@unwrap_spec(num=int, offset=int, repr=str)
-def descr_new_resop(space, w_tp, num, w_args, w_res=NoneNotWrapped, offset=-1,
+def descr_new_resop(space, w_tp, num, w_args, w_res=None, offset=-1,
repr=''):
- args = [jit_hooks.boxint_new(space.int_w(w_arg)) for w_arg in
+ args = [space.interp_w(WrappedBox, w_arg).llbox for w_arg in
space.listview(w_args)]
- if w_res is None:
- llres = lltype.nullptr(llmemory.GCREF.TO)
- else:
- llres = jit_hooks.boxint_new(space.int_w(w_res))
+ llres = space.interp_w(WrappedBox, w_res).llbox
+ # XXX None case
return WrappedOp(jit_hooks.resop_new(num, args, llres), offset, repr)
class WrappedOp(Wrappable):
@@ -105,7 +134,14 @@
return space.wrap(self.repr_of_resop)
def descr_num(self, space):
- return space.wrap(jit_hooks.resop_opnum(self.op))
+ return space.wrap(jit_hooks.resop_getopnum(self.op))
+
+ def descr_name(self, space):
+ return space.wrap(hlstr(jit_hooks.resop_getopname(self.op)))
+
+ @unwrap_spec(no=int)
+ def descr_getarg(self, space, no):
+ return WrappedBox(jit_hooks.resop_getarg(self.op, no))
WrappedOp.typedef = TypeDef(
'ResOperation',
@@ -113,5 +149,26 @@
__new__ = interp2app(descr_new_resop),
__repr__ = interp2app(WrappedOp.descr_repr),
num = GetSetProperty(WrappedOp.descr_num),
+ name = GetSetProperty(WrappedOp.descr_name),
+ getarg = interp2app(WrappedOp.descr_getarg),
)
WrappedOp.acceptable_as_base_class = False
+
+class WrappedBox(Wrappable):
+ """ A class representing a single box
+ """
+ def __init__(self, llbox):
+ self.llbox = llbox
+
+ def descr_getint(self, space):
+ return space.wrap(jit_hooks.box_getint(self.llbox))
+
+@unwrap_spec(no=int)
+def descr_new_box(space, w_tp, no):
+ return WrappedBox(jit_hooks.boxint_new(no))
+
+WrappedBox.typedef = TypeDef(
+ 'Box',
+ __new__ = interp2app(descr_new_box),
+ getint = interp2app(WrappedBox.descr_getint),
+)
diff --git a/pypy/module/pypyjit/policy.py b/pypy/module/pypyjit/policy.py
--- a/pypy/module/pypyjit/policy.py
+++ b/pypy/module/pypyjit/policy.py
@@ -1,8 +1,10 @@
from pypy.jit.codewriter.policy import JitPolicy
from pypy.rlib.jit import JitPortal
+from pypy.rlib import jit_hooks
from pypy.interpreter.error import OperationError
from pypy.jit.metainterp.jitprof import counter_names
-from pypy.module.pypyjit.interp_resop import wrap_oplist, Cache, wrap_greenkey
+from pypy.module.pypyjit.interp_resop import wrap_oplist, Cache,
wrap_greenkey,\
+ WrappedOp
class PyPyPortal(JitPortal):
def on_abort(self, reason, jitdriver, greenkey):
@@ -21,18 +23,28 @@
e.write_unraisable(space, "jit hook ", cache.w_abort_hook)
cache.in_recursion = False
- def on_compile(self, jitdriver, logger, looptoken, operations, type,
- greenkey, ops_offset, asmstart, asmlen):
+ def after_compile(self, jitdriver, logger, looptoken, operations, type,
+ greenkey, ops_offset, asmstart, asmlen):
self._compile_hook(jitdriver, logger, operations, type,
ops_offset, asmstart, asmlen,
wrap_greenkey(self.space, jitdriver, greenkey))
- def on_compile_bridge(self, jitdriver, logger, orig_looptoken, operations,
- n, ops_offset, asmstart, asmlen):
+ def after_compile_bridge(self, jitdriver, logger, orig_looptoken,
+ operations, n, ops_offset, asmstart, asmlen):
self._compile_hook(jitdriver, logger, operations, 'bridge',
ops_offset, asmstart, asmlen,
self.space.wrap(n))
+ def before_compile(self, jitdriver, logger, looptoken, operations, type,
+ greenkey):
+ self._optimize_hook(jitdriver, logger, operations, type,
+ wrap_greenkey(self.space, jitdriver, greenkey))
+
+ def before_compile_bridge(self, jitdriver, logger, orig_looptoken,
+ operations, n):
+ self._optimize_hook(jitdriver, logger, operations, 'bridge',
+ self.space.wrap(n))
+
def _compile_hook(self, jitdriver, logger, operations, type,
ops_offset, asmstart, asmlen, w_arg):
space = self.space
@@ -55,6 +67,34 @@
e.write_unraisable(space, "jit hook ", cache.w_compile_hook)
cache.in_recursion = False
+ def _optimize_hook(self, jitdriver, logger, operations, type, w_arg):
+ space = self.space
+ cache = space.fromcache(Cache)
+ if cache.in_recursion:
+ return
+ if space.is_true(cache.w_optimize_hook):
+ logops = logger._make_log_operations()
+ list_w = wrap_oplist(space, logops, operations, {})
+ cache.in_recursion = True
+ try:
+ w_res = space.call_function(cache.w_optimize_hook,
+ space.wrap(jitdriver.name),
+ space.wrap(type),
+ w_arg,
+ space.newlist(list_w))
+ if space.is_w(w_res, space.w_None):
+ return
+ l = []
+ for w_item in space.listview(w_res):
+ item = space.interp_w(WrappedOp, w_item)
+ l.append(jit_hooks._cast_to_resop(item.op))
+ operations[:] = l # modifying operations above is probably not
+ # a great idea since types may not work and we'll end up with
+ # half-working list and a segfault/fatal RPython error
+ except OperationError, e:
+ e.write_unraisable(space, "jit hook ", cache.w_compile_hook)
+ cache.in_recursion = False
+
pypy_portal = PyPyPortal()
class PyPyJitPolicy(JitPolicy):
diff --git a/pypy/module/pypyjit/test/test_jit_hook.py
b/pypy/module/pypyjit/test/test_jit_hook.py
--- a/pypy/module/pypyjit/test/test_jit_hook.py
+++ b/pypy/module/pypyjit/test/test_jit_hook.py
@@ -47,27 +47,32 @@
code_gcref = lltype.cast_opaque_ptr(llmemory.GCREF, ll_code)
logger = Logger(MockSD())
- oplist = parse("""
- [i1, i2]
+ cls.origoplist = parse("""
+ [i1, i2, p2]
i3 = int_add(i1, i2)
debug_merge_point(0, 0, 0, 0, ConstPtr(ptr0))
+ guard_nonnull(p2) []
guard_true(i3) []
""", namespace={'ptr0': code_gcref}).operations
greenkey = [ConstInt(0), ConstInt(0), ConstPtr(code_gcref)]
offset = {}
- for i, op in enumerate(oplist):
+ for i, op in enumerate(cls.origoplist):
if i != 1:
offset[op] = i
def interp_on_compile():
- pypy_portal.on_compile(pypyjitdriver, logger, JitCellToken(),
- oplist, 'loop', greenkey, offset,
- 0, 0)
+ pypy_portal.after_compile(pypyjitdriver, logger, JitCellToken(),
+ cls.oplist, 'loop', greenkey, offset,
+ 0, 0)
def interp_on_compile_bridge():
- pypy_portal.on_compile_bridge(pypyjitdriver, logger,
- JitCellToken(), oplist, 0,
- offset, 0, 0)
+ pypy_portal.after_compile_bridge(pypyjitdriver, logger,
+ JitCellToken(), cls.oplist, 0,
+ offset, 0, 0)
+
+ def interp_on_optimize():
+ pypy_portal.before_compile(pypyjitdriver, logger, JitCellToken(),
+ cls.oplist, 'loop', greenkey)
def interp_on_abort():
pypy_portal.on_abort(ABORT_TOO_LONG, pypyjitdriver, greenkey)
@@ -76,6 +81,10 @@
cls.w_on_compile_bridge =
space.wrap(interp2app(interp_on_compile_bridge))
cls.w_on_abort = space.wrap(interp2app(interp_on_abort))
cls.w_int_add_num = space.wrap(rop.INT_ADD)
+ cls.w_on_optimize = space.wrap(interp2app(interp_on_optimize))
+
+ def setup_method(self, meth):
+ self.__class__.oplist = self.origoplist
def test_on_compile(self):
import pypyjit
@@ -94,7 +103,7 @@
assert elem[2][0].co_name == 'function'
assert elem[2][1] == 0
assert elem[2][2] == False
- assert len(elem[3]) == 3
+ assert len(elem[3]) == 4
int_add = elem[3][0]
#assert int_add.name == 'int_add'
assert int_add.num == self.int_add_num
@@ -160,8 +169,27 @@
self.on_abort()
assert l == [('pypyjit', 'ABORT_TOO_LONG')]
+ def test_on_optimize(self):
+ import pypyjit
+ l = []
+
+ def hook(name, looptype, tuple_or_guard_no, ops, *args):
+ l.append(ops)
+
+ def optimize_hook(name, looptype, tuple_or_guard_no, ops):
+ return []
+
+ pypyjit.set_compile_hook(hook)
+ pypyjit.set_optimize_hook(optimize_hook)
+ self.on_optimize()
+ self.on_compile()
+ assert l == [[]]
+
def test_creation(self):
- import pypyjit
+ from pypyjit import Box, ResOperation
- op = pypyjit.ResOperation(self.int_add_num, [1, 3], 4)
+ op = ResOperation(self.int_add_num, [Box(1), Box(3)], Box(4))
assert op.num == self.int_add_num
+ assert op.name == 'int_add'
+ box = op.getarg(0)
+ assert box.getint() == 1
diff --git a/pypy/rlib/jit.py b/pypy/rlib/jit.py
--- a/pypy/rlib/jit.py
+++ b/pypy/rlib/jit.py
@@ -731,29 +731,62 @@
like JIT loops compiled, aborts etc.
An instance of this class might be returned by the policy.get_jit_portal
method in order to function.
+
+ each hook will accept some of the following args:
+
+
+ greenkey - a list of green boxes
+ jitdriver - an instance of jitdriver where tracing started
+ logger - an instance of jit.metainterp.logger.LogOperations
+ ops_offset
+ asmaddr - (int) raw address of assembler block
+ asmlen - assembler block length
+ type - either 'loop' or 'entry bridge'
"""
def on_abort(self, reason, jitdriver, greenkey):
""" A hook called each time a loop is aborted with jitdriver and
greenkey where it started, reason is a string why it got aborted
"""
- def on_compile(self, jitdriver, logger, looptoken, operations, type,
- greenkey, ops_offset, asmaddr, asmlen):
- """ A hook called when loop is compiled. Overwrite
- for your own jitdriver if you want to do something special, like
- call applevel code.
+ #def before_optimize(self, jitdriver, logger, looptoken, operations,
+ # type, greenkey):
+ # """ A hook called before optimizer is run, args described in class
+ # docstring. Overwrite for custom behavior
+ # """
+ # DISABLED
- jitdriver - an instance of jitdriver where tracing started
- logger - an instance of jit.metainterp.logger.LogOperations
- asmaddr - (int) raw address of assembler block
- asmlen - assembler block length
- type - either 'loop' or 'entry bridge'
+ def before_compile(self, jitdriver, logger, looptoken, operations, type,
+ greenkey):
+ """ A hook called after a loop is optimized, before compiling
assembler,
+ args described ni class docstring. Overwrite for custom behavior
"""
- def on_compile_bridge(self, jitdriver, logger, orig_looptoken, operations,
- fail_descr_no, ops_offset, asmaddr, asmlen):
- """ A hook called when a bridge is compiled. Overwrite
- for your own jitdriver if you want to do something special
+ def after_compile(self, jitdriver, logger, looptoken, operations, type,
+ greenkey, ops_offset, asmaddr, asmlen):
+ """ A hook called after a loop has compiled assembler,
+ args described in class docstring. Overwrite for custom behavior
+ """
+
+ #def before_optimize_bridge(self, jitdriver, logger, orig_looptoken,
+ # operations, fail_descr_no):
+ # """ A hook called before a bridge is optimized.
+ # Args described in class docstring, Overwrite for
+ # custom behavior
+ # """
+ # DISABLED
+
+ def before_compile_bridge(self, jitdriver, logger, orig_looptoken,
+ operations, fail_descr_no):
+ """ A hook called before a bridge is compiled, but after optimizations
+ are performed. Args described in class docstring, Overwrite for
+ custom behavior
+ """
+
+ def after_compile_bridge(self, jitdriver, logger, orig_looptoken,
+ operations, fail_descr_no, ops_offset, asmaddr,
+ asmlen):
+ """ A hook called after a bridge is compiled, args described in class
+ docstring, Overwrite for custom behavior
"""
def get_stats(self):
diff --git a/pypy/rlib/jit_hooks.py b/pypy/rlib/jit_hooks.py
--- a/pypy/rlib/jit_hooks.py
+++ b/pypy/rlib/jit_hooks.py
@@ -4,26 +4,28 @@
from pypy.rpython.lltypesystem import llmemory, lltype
from pypy.rpython.lltypesystem import rclass
from pypy.rpython.annlowlevel import cast_instance_to_base_ptr,\
- cast_base_ptr_to_instance
+ cast_base_ptr_to_instance, llstr, hlstr
from pypy.rlib.objectmodel import specialize
-def register_helper(helper, s_result):
-
- class Entry(ExtRegistryEntry):
- _about_ = helper
+def register_helper(s_result):
+ def wrapper(helper):
+ class Entry(ExtRegistryEntry):
+ _about_ = helper
- def compute_result_annotation(self, *args):
- return s_result
+ def compute_result_annotation(self, *args):
+ return s_result
- def specialize_call(self, hop):
- from pypy.rpython.lltypesystem import lltype
+ def specialize_call(self, hop):
+ from pypy.rpython.lltypesystem import lltype
- c_func = hop.inputconst(lltype.Void, helper)
- c_name = hop.inputconst(lltype.Void, 'access_helper')
- args_v = [hop.inputarg(arg, arg=i)
- for i, arg in enumerate(hop.args_r)]
- return hop.genop('jit_marker', [c_name, c_func] + args_v,
- resulttype=hop.r_result)
+ c_func = hop.inputconst(lltype.Void, helper)
+ c_name = hop.inputconst(lltype.Void, 'access_helper')
+ args_v = [hop.inputarg(arg, arg=i)
+ for i, arg in enumerate(hop.args_r)]
+ return hop.genop('jit_marker', [c_name, c_func] + args_v,
+ resulttype=hop.r_result)
+ return helper
+ return wrapper
def _cast_to_box(llref):
from pypy.jit.metainterp.history import AbstractValue
@@ -42,6 +44,7 @@
return lltype.cast_opaque_ptr(llmemory.GCREF,
cast_instance_to_base_ptr(obj))
+@register_helper(annmodel.SomePtr(llmemory.GCREF))
def resop_new(no, llargs, llres):
from pypy.jit.metainterp.history import ResOperation
@@ -49,15 +52,40 @@
res = _cast_to_box(llres)
return _cast_to_gcref(ResOperation(no, args, res))
-register_helper(resop_new, annmodel.SomePtr(llmemory.GCREF))
-
+@register_helper(annmodel.SomePtr(llmemory.GCREF))
def boxint_new(no):
from pypy.jit.metainterp.history import BoxInt
return _cast_to_gcref(BoxInt(no))
-register_helper(boxint_new, annmodel.SomePtr(llmemory.GCREF))
-
-def resop_opnum(llop):
+@register_helper(annmodel.SomeInteger())
+def resop_getopnum(llop):
return _cast_to_resop(llop).getopnum()
-register_helper(resop_opnum, annmodel.SomeInteger())
+@register_helper(annmodel.SomeString(can_be_None=True))
+def resop_getopname(llop):
+ return llstr(_cast_to_resop(llop).getopname())
+
+@register_helper(annmodel.SomePtr(llmemory.GCREF))
+def resop_getarg(llop, no):
+ return _cast_to_gcref(_cast_to_resop(llop).getarg(no))
+
+@register_helper(annmodel.SomeInteger())
+def box_getint(llbox):
+ return _cast_to_box(llbox).getint()
+
+@register_helper(annmodel.SomePtr(llmemory.GCREF))
+def box_clone(llbox):
+ return _cast_to_gcref(_cast_to_box(llbox).clonebox())
+
+@register_helper(annmodel.SomePtr(llmemory.GCREF))
+def box_constbox(llbox):
+ return _cast_to_gcref(_cast_to_box(llbox).constbox())
+
+@register_helper(annmodel.SomePtr(llmemory.GCREF))
+def box_nonconstbox(llbox):
+ return _cast_to_gcref(_cast_to_box(llbox).nonconstbox())
+
+@register_helper(annmodel.SomeBool())
+def box_isconst(llbox):
+ from pypy.jit.metainterp.history import Const
+ return isinstance(_cast_to_box(llbox), Const)
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit