Author: Armin Rigo <[email protected]>
Branch: optresult-unroll
Changeset: r79281:947d07bc67fc
Date: 2015-08-28 17:37 +0200
http://bitbucket.org/pypy/pypy/changeset/947d07bc67fc/
Log: Add GUARD_GC_TYPE and GUARD_NONNULL_GC_TYPE, step 1: llgraph only
diff --git a/rpython/jit/backend/llgraph/runner.py
b/rpython/jit/backend/llgraph/runner.py
--- a/rpython/jit/backend/llgraph/runner.py
+++ b/rpython/jit/backend/llgraph/runner.py
@@ -16,6 +16,7 @@
from rpython.rlib.clibffi import FFI_DEFAULT_ABI
from rpython.rlib.rarithmetic import ovfcheck, r_uint, r_ulonglong
+from rpython.rlib.objectmodel import Symbolic
class LLTrace(object):
has_been_freed = False
@@ -88,6 +89,10 @@
def get_result_type(self):
return getkind(self.RESULT)[0]
+class TypeIDSymbolic(Symbolic):
+ def __init__(self, STRUCT_OR_ARRAY):
+ self.STRUCT_OR_ARRAY = STRUCT_OR_ARRAY
+
class SizeDescr(AbstractDescr):
def __init__(self, S, vtable, runner):
assert not isinstance(vtable, bool)
@@ -114,6 +119,10 @@
def is_immutable(self):
return heaptracker.is_immutable_struct(self.S)
+ def get_type_id(self):
+ assert isinstance(self.S, lltype.GcStruct)
+ return TypeIDSymbolic(self.S) # integer-like symbolic
+
def __repr__(self):
return 'SizeDescr(%r)' % (self.S,)
@@ -222,6 +231,10 @@
return intbounds.get_integer_max(
not _is_signed_kind(self.A.OF), rffi.sizeof(self.A.OF))
+ def get_type_id(self):
+ assert isinstance(self.A, lltype.GcArray)
+ return TypeIDSymbolic(self.A) # integer-like symbolic
+
class InteriorFieldDescr(AbstractDescr):
def __init__(self, A, fieldname, runner):
@@ -281,6 +294,7 @@
supports_floats = True
supports_longlong = r_uint is not r_ulonglong
supports_singlefloats = True
+ supports_guard_gc_type = True
translate_support_code = False
is_llgraph = True
@@ -893,6 +907,16 @@
self.execute_guard_nonnull(descr, arg)
self.execute_guard_class(descr, arg, klass)
+ def execute_guard_gc_type(self, descr, arg, typeid):
+ assert isinstance(typeid, TypeIDSymbolic)
+ TYPE = arg._obj.container._TYPE
+ if TYPE != typeid.STRUCT_OR_ARRAY:
+ self.fail_guard(descr)
+
+ def execute_guard_nonnull_gc_type(self, descr, arg, typeid):
+ self.execute_guard_nonnull(descr, arg)
+ self.execute_guard_gc_type(descr, arg, typeid)
+
def execute_guard_no_exception(self, descr):
if self.last_exception is not None:
self.fail_guard(descr)
diff --git a/rpython/jit/backend/model.py b/rpython/jit/backend/model.py
--- a/rpython/jit/backend/model.py
+++ b/rpython/jit/backend/model.py
@@ -15,6 +15,7 @@
# longlongs are supported by the JIT, but stored as doubles.
# Boxes and Consts are BoxFloats and ConstFloats.
supports_singlefloats = False
+ supports_guard_gc_type = False
propagate_exception_descr = None
diff --git a/rpython/jit/backend/test/runner_test.py
b/rpython/jit/backend/test/runner_test.py
--- a/rpython/jit/backend/test/runner_test.py
+++ b/rpython/jit/backend/test/runner_test.py
@@ -4832,3 +4832,49 @@
assert a[i].a == a[i].b == val
else:
assert a[i] == rffi.cast(OF, val)
+
+ def test_passing_guard_gc_type_struct(self):
+ if not self.cpu.supports_guard_gc_type:
+ py.test.skip("guard_gc_type not available")
+ t_box, _, descr = self.alloc_instance(self.T)
+ c_typeid = ConstInt(descr.get_type_id())
+ self.execute_operation(rop.GUARD_GC_TYPE, [t_box, c_typeid], 'void')
+ assert not self.guard_failed
+ self.execute_operation(rop.GUARD_NONNULL_GC_TYPE, [t_box, c_typeid],
+ 'void')
+ assert not self.guard_failed
+
+ def test_passing_guard_gc_type_array(self):
+ if not self.cpu.supports_guard_gc_type:
+ py.test.skip("guard_gc_type not available")
+ a_box, A = self.alloc_array_of(rffi.SHORT, 342)
+ arraydescr = self.cpu.arraydescrof(A)
+ c_typeid = ConstInt(arraydescr.get_type_id())
+ self.execute_operation(rop.GUARD_GC_TYPE, [a_box, c_typeid], 'void')
+ assert not self.guard_failed
+ self.execute_operation(rop.GUARD_NONNULL_GC_TYPE, [a_box, c_typeid],
+ 'void')
+ assert not self.guard_failed
+
+ def test_failing_guard_gc_type(self):
+ t_box, _, tdescr = self.alloc_instance(self.T)
+ u_box, _, udescr = self.alloc_instance(self.U)
+ a_box, A = self.alloc_array_of(rffi.SHORT, 342)
+ adescr = self.cpu.arraydescrof(A)
+ c_ttypeid = ConstInt(tdescr.get_type_id())
+ c_utypeid = ConstInt(udescr.get_type_id())
+ c_atypeid = ConstInt(adescr.get_type_id())
+ null_box = self.null_instance()
+ for opname, args in [(rop.GUARD_GC_TYPE, [t_box, c_utypeid]),
+ (rop.GUARD_GC_TYPE, [u_box, c_ttypeid]),
+ (rop.GUARD_GC_TYPE, [a_box, c_utypeid]),
+ (rop.GUARD_GC_TYPE, [t_box, c_atypeid]),
+ (rop.GUARD_NONNULL_GC_TYPE, [t_box, c_utypeid]),
+ (rop.GUARD_NONNULL_GC_TYPE, [u_box, c_ttypeid]),
+ (rop.GUARD_NONNULL_GC_TYPE, [a_box, c_ttypeid]),
+ (rop.GUARD_NONNULL_GC_TYPE, [u_box, c_atypeid]),
+ (rop.GUARD_NONNULL_GC_TYPE, [null_box,
c_ttypeid]),
+ (rop.GUARD_NONNULL_GC_TYPE, [null_box,
c_atypeid]),
+ ]:
+ assert self.execute_operation(opname, args, 'void') == None
+ assert self.guard_failed
diff --git a/rpython/jit/metainterp/resoperation.py
b/rpython/jit/metainterp/resoperation.py
--- a/rpython/jit/metainterp/resoperation.py
+++ b/rpython/jit/metainterp/resoperation.py
@@ -656,6 +656,8 @@
'GUARD_NONNULL/1d/n',
'GUARD_ISNULL/1d/n',
'GUARD_NONNULL_CLASS/2d/n',
+ 'GUARD_GC_TYPE/2d/n',
+ 'GUARD_NONNULL_GC_TYPE/2d/n',
'_GUARD_FOLDABLE_LAST',
'GUARD_NO_EXCEPTION/0d/n', # may be called with an exception currently
set
'GUARD_EXCEPTION/1d/r', # may be called with an exception currently set
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit