[pypy-commit] pypy default: also add an explicit way to record a class
cfbolz
noreply at buildbot.pypy.org
Fri Dec 2 12:10:51 CET 2011
Author: Carl Friedrich Bolz <cfbolz at gmx.de>
Branch:
Changeset: r50057:09d322fa3784
Date: 2011-12-02 10:01 +0100
http://bitbucket.org/pypy/pypy/changeset/09d322fa3784/
Log: also add an explicit way to record a class
diff --git a/pypy/jit/codewriter/jtransform.py b/pypy/jit/codewriter/jtransform.py
--- a/pypy/jit/codewriter/jtransform.py
+++ b/pypy/jit/codewriter/jtransform.py
@@ -220,6 +220,9 @@
return [None, # hack, do the right renaming from op.args[0] to op.result
SpaceOperation("record_known_class", [op.args[0], const_vtable], None)]
+ def rewrite_op_jit_record_known_class(self, op):
+ return SpaceOperation("record_known_class", [op.args[0], op.args[1]], None)
+
def rewrite_op_cast_bool_to_int(self, op): pass
def rewrite_op_cast_bool_to_uint(self, op): pass
def rewrite_op_cast_char_to_int(self, op): pass
diff --git a/pypy/jit/metainterp/test/test_ajit.py b/pypy/jit/metainterp/test/test_ajit.py
--- a/pypy/jit/metainterp/test/test_ajit.py
+++ b/pypy/jit/metainterp/test/test_ajit.py
@@ -14,7 +14,7 @@
from pypy.rlib.jit import (JitDriver, we_are_jitted, hint, dont_look_inside,
loop_invariant, elidable, promote, jit_debug, assert_green,
AssertGreenFailed, unroll_safe, current_trace_length, look_inside_iff,
- isconstant, isvirtual, promote_string, set_param)
+ isconstant, isvirtual, promote_string, set_param, record_known_class)
from pypy.rlib.rarithmetic import ovfcheck
from pypy.rpython.lltypesystem import lltype, llmemory, rffi
from pypy.rpython.ootypesystem import ootype
@@ -3585,7 +3585,7 @@
self.interp_operations(f, [5], translationoptions=translationoptions)
- def test_annotation_gives_knowledge_to_tracer(self):
+ def test_annotation_gives_class_knowledge_to_tracer(self):
class Base(object):
pass
class A(Base):
@@ -3645,6 +3645,70 @@
# here it works again
self.check_operations_history(guard_class=0, record_known_class=1)
+ def test_give_class_knowledge_to_tracer_explicitly(self):
+ from pypy.rpython.lltypesystem.lloperation import llop
+ class Base(object):
+ def f(self):
+ raise NotImplementedError
+ def g(self):
+ raise NotImplementedError
+ class A(Base):
+ def f(self):
+ return self.a
+ def g(self):
+ return self.a + 1
+ class B(Base):
+ def f(self):
+ return self.b
+ def g(self):
+ return self.b + 1
+ class C(B):
+ def f(self):
+ self.c += 1
+ return self.c
+ def g(self):
+ return self.c + 1
+ @dont_look_inside
+ def make(x):
+ if x > 0:
+ a = A()
+ a.a = x + 1
+ elif x < 0:
+ a = B()
+ a.b = -x
+ else:
+ a = C()
+ a.c = 10
+ return a
+ def f(x):
+ a = make(x)
+ if x > 0:
+ record_known_class(a, A)
+ z = a.f()
+ elif x < 0:
+ record_known_class(a, B)
+ z = a.f()
+ else:
+ record_known_class(a, C)
+ z = a.f()
+ return z + a.g()
+ res1 = f(6)
+ res2 = self.interp_operations(f, [6])
+ assert res1 == res2
+ self.check_operations_history(guard_class=0, record_known_class=1)
+
+ res1 = f(-6)
+ res2 = self.interp_operations(f, [-6])
+ assert res1 == res2
+ # cannot use record_known_class here, because B has a subclass
+ self.check_operations_history(guard_class=1)
+
+ res1 = f(0)
+ res2 = self.interp_operations(f, [0])
+ assert res1 == res2
+ # here it works again
+ self.check_operations_history(guard_class=0, record_known_class=1)
+
class TestLLtype(BaseLLtypeTests, LLJitMixin):
def test_tagged(self):
diff --git a/pypy/rlib/jit.py b/pypy/rlib/jit.py
--- a/pypy/rlib/jit.py
+++ b/pypy/rlib/jit.py
@@ -738,3 +738,26 @@
return hop.genop('jit_marker', vlist,
resulttype=lltype.Void)
+def record_known_class(value, cls):
+ """
+ Assure the JIT that value is an instance of cls. This is not a precise
+ class check, unlike a guard_class.
+ """
+ assert isinstance(value, cls)
+
+
+class Entry(ExtRegistryEntry):
+ _about_ = record_known_class
+
+ def compute_result_annotation(self, *args):
+ pass
+
+ def specialize_call(self, hop):
+ from pypy.rpython.lltypesystem import lltype, rclass
+ classrepr = rclass.get_type_repr(hop.rtyper)
+
+ hop.exception_cannot_occur()
+ v_inst = hop.inputarg(hop.args_r[0], arg=0)
+ v_cls = hop.inputarg(classrepr, arg=1)
+ return hop.genop('jit_record_known_class', [v_inst, v_cls],
+ resulttype=lltype.Void)
diff --git a/pypy/rpython/llinterp.py b/pypy/rpython/llinterp.py
--- a/pypy/rpython/llinterp.py
+++ b/pypy/rpython/llinterp.py
@@ -548,6 +548,9 @@
def op_jit_marker(self, *args):
pass
+ def op_jit_record_known_class(self, *args):
+ pass
+
def op_get_exception_addr(self, *args):
raise NotImplementedError
diff --git a/pypy/rpython/lltypesystem/lloperation.py b/pypy/rpython/lltypesystem/lloperation.py
--- a/pypy/rpython/lltypesystem/lloperation.py
+++ b/pypy/rpython/lltypesystem/lloperation.py
@@ -430,6 +430,7 @@
'jit_force_virtual': LLOp(canrun=True),
'jit_is_virtual': LLOp(canrun=True),
'jit_force_quasi_immutable': LLOp(canrun=True),
+ 'jit_record_known_class' : LLOp(canrun=True),
'get_exception_addr': LLOp(),
'get_exc_value_addr': LLOp(),
'do_malloc_fixedsize_clear':LLOp(canmallocgc=True),
diff --git a/pypy/rpython/lltypesystem/opimpl.py b/pypy/rpython/lltypesystem/opimpl.py
--- a/pypy/rpython/lltypesystem/opimpl.py
+++ b/pypy/rpython/lltypesystem/opimpl.py
@@ -548,6 +548,9 @@
def op_jit_force_quasi_immutable(*args):
pass
+def op_jit_record_known_class(x, y):
+ pass
+
def op_get_group_member(TYPE, grpptr, memberoffset):
from pypy.rpython.lltypesystem import llgroup
assert isinstance(memberoffset, llgroup.GroupMemberOffset)
More information about the pypy-commit
mailing list