[pypy-commit] pypy optresult-unroll: guard_is_object, guard_subclass in the llgraph backend
arigo
noreply at buildbot.pypy.org
Thu Sep 3 07:52:14 CEST 2015
Author: Armin Rigo <arigo at tunes.org>
Branch: optresult-unroll
Changeset: r79387:a714b41006ed
Date: 2015-09-03 07:52 +0200
http://bitbucket.org/pypy/pypy/changeset/a714b41006ed/
Log: guard_is_object, guard_subclass in the llgraph backend
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
@@ -913,6 +913,26 @@
if TYPE != typeid.STRUCT_OR_ARRAY:
self.fail_guard(descr)
+ def execute_guard_is_object(self, descr, arg):
+ TYPE = arg._obj.container._TYPE
+ while TYPE is not rclass.OBJECT:
+ if not isinstance(TYPE, lltype.GcStruct): # or TYPE is None
+ self.fail_guard(descr)
+ return
+ _, TYPE = TYPE._first_struct()
+
+ def execute_guard_subclass(self, descr, arg, klass):
+ value = lltype.cast_opaque_ptr(rclass.OBJECTPTR, arg)
+ expected_class = llmemory.cast_adr_to_ptr(
+ llmemory.cast_int_to_adr(klass),
+ rclass.CLASSTYPE)
+ if (expected_class.subclassrange_min
+ <= value.typeptr.subclassrange_min
+ <= expected_class.subclassrange_max):
+ pass
+ else:
+ self.fail_guard(descr)
+
def execute_guard_no_exception(self, descr):
if self.last_exception is not None:
self.fail_guard(descr)
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
@@ -4867,3 +4867,71 @@
]:
assert self.execute_operation(opname, args, 'void') == None
assert self.guard_failed
+
+ def test_guard_is_object(self):
+ if not self.cpu.supports_guard_gc_type:
+ py.test.skip("guard_gc_type not available")
+ t_box, _, _ = self.alloc_instance(self.T)
+ self.execute_operation(rop.GUARD_IS_OBJECT, [t_box], 'void')
+ #
+ assert not self.guard_failed
+ a_box, _ = self.alloc_array_of(rffi.SHORT, 342)
+ self.execute_operation(rop.GUARD_IS_OBJECT, [a_box], 'void')
+ assert self.guard_failed
+ #
+ S = lltype.GcStruct('S')
+ s = lltype.malloc(S, immortal=True, zero=True)
+ s_box = InputArgRef(lltype.cast_opaque_ptr(llmemory.GCREF, s))
+ self.execute_operation(rop.GUARD_IS_OBJECT, [s_box], 'void')
+ assert self.guard_failed
+
+ def test_guard_subclass(self):
+ if not self.cpu.supports_guard_gc_type:
+ py.test.skip("guard_gc_type not available")
+
+ xtp = lltype.malloc(rclass.OBJECT_VTABLE, immortal=True)
+ xtp.subclassrange_min = 1
+ xtp.subclassrange_max = 3
+ X = lltype.GcStruct('X', ('parent', rclass.OBJECT),
+ hints={'vtable': xtp._obj})
+ xptr = lltype.malloc(X)
+ xptr.parent.typeptr = xtp
+ x_box = InputArgRef(lltype.cast_opaque_ptr(llmemory.GCREF, xptr))
+ X_box = ConstInt(heaptracker.adr2int(llmemory.cast_ptr_to_adr(xtp)))
+
+ ytp = lltype.malloc(rclass.OBJECT_VTABLE, immortal=True)
+ ytp.subclassrange_min = 2
+ ytp.subclassrange_max = 2
+ assert rclass.ll_issubclass(ytp, xtp)
+ Y = lltype.GcStruct('Y', ('parent', X),
+ hints={'vtable': ytp._obj})
+ yptr = lltype.malloc(Y)
+ yptr.parent.parent.typeptr = ytp
+ y_box = InputArgRef(lltype.cast_opaque_ptr(llmemory.GCREF, yptr))
+ Y_box = ConstInt(heaptracker.adr2int(llmemory.cast_ptr_to_adr(ytp)))
+
+ ztp = lltype.malloc(rclass.OBJECT_VTABLE, immortal=True)
+ ztp.subclassrange_min = 4
+ ztp.subclassrange_max = 5
+ assert not rclass.ll_issubclass(ztp, xtp)
+ assert not rclass.ll_issubclass(xtp, ztp)
+ Z = lltype.GcStruct('Z', ('parent', rclass.OBJECT),
+ hints={'vtable': ztp._obj})
+ zptr = lltype.malloc(Z)
+ zptr.parent.typeptr = ztp
+ z_box = InputArgRef(lltype.cast_opaque_ptr(llmemory.GCREF, zptr))
+ Z_box = ConstInt(heaptracker.adr2int(llmemory.cast_ptr_to_adr(ztp)))
+
+ for num, arg, klass, is_subclass in [
+ (1, x_box, X_box, True),
+ (2, x_box, Y_box, False),
+ (3, x_box, Z_box, False),
+ (4, y_box, X_box, True),
+ (5, y_box, Y_box, True),
+ (6, y_box, Z_box, False),
+ (7, z_box, X_box, False),
+ (8, z_box, Y_box, False),
+ (9, z_box, Z_box, True),
+ ]:
+ self.execute_operation(rop.GUARD_SUBCLASS, [arg, klass], 'void')
+ assert self.guard_failed == (not is_subclass)
More information about the pypy-commit
mailing list