[pypy-svn] r69131 - in pypy/branch/merge-guards-2/pypy/jit/backend: test x86

arigo at codespeak.net arigo at codespeak.net
Tue Nov 10 19:00:21 CET 2009


Author: arigo
Date: Tue Nov 10 19:00:21 2009
New Revision: 69131

Modified:
   pypy/branch/merge-guards-2/pypy/jit/backend/test/runner_test.py
   pypy/branch/merge-guards-2/pypy/jit/backend/test/test_ll_random.py
   pypy/branch/merge-guards-2/pypy/jit/backend/x86/assembler.py
   pypy/branch/merge-guards-2/pypy/jit/backend/x86/regalloc.py
Log:
Implement guard_nonnull_class in the x86 backend.


Modified: pypy/branch/merge-guards-2/pypy/jit/backend/test/runner_test.py
==============================================================================
--- pypy/branch/merge-guards-2/pypy/jit/backend/test/runner_test.py	(original)
+++ pypy/branch/merge-guards-2/pypy/jit/backend/test/runner_test.py	Tue Nov 10 19:00:21 2009
@@ -460,8 +460,8 @@
         #null_box = ConstPtr(lltype.cast_opaque_ptr(llmemory.GCREF, lltype.nullptr(T)))
         self.execute_operation(rop.GUARD_CLASS, [t_box, T_box], 'void')
         assert not self.guard_failed
-        #self.execute_operation(rop.GUARD_CLASS_INVERSE, [t_box, null_box],
-        #                       'void')
+        self.execute_operation(rop.GUARD_NONNULL_CLASS, [t_box, T_box], 'void')
+        assert not self.guard_failed
 
     def test_failing_guards(self):
         t_box, T_box = self.alloc_instance(self.T)
@@ -480,10 +480,12 @@
     def test_failing_guard_class(self):
         t_box, T_box = self.alloc_instance(self.T)
         u_box, U_box = self.alloc_instance(self.U)        
-        #null_box = ConstPtr(lltype.cast_opaque_ptr(llmemory.GCREF, lltype.nullptr(T)))
+        null_box = self.null_instance()
         for opname, args in [(rop.GUARD_CLASS, [t_box, U_box]),
                              (rop.GUARD_CLASS, [u_box, T_box]),
-                             #(rop.GUARD_VALUE_INVERSE, [BoxInt(10), BoxInt(10)]),
+                             (rop.GUARD_NONNULL_CLASS, [t_box, U_box]),
+                             (rop.GUARD_NONNULL_CLASS, [u_box, T_box]),
+                             (rop.GUARD_NONNULL_CLASS, [null_box, T_box]),
                              ]:
             assert self.execute_operation(opname, args, 'void') == None
             assert self.guard_failed

Modified: pypy/branch/merge-guards-2/pypy/jit/backend/test/test_ll_random.py
==============================================================================
--- pypy/branch/merge-guards-2/pypy/jit/backend/test/test_ll_random.py	(original)
+++ pypy/branch/merge-guards-2/pypy/jit/backend/test/test_ll_random.py	Tue Nov 10 19:00:21 2009
@@ -203,6 +203,21 @@
         op = ResOperation(self.opnum, [v, c_vtable2], None)
         return op, (vtable == vtable2)
 
+class GuardNonNullClassOperation(GuardClassOperation):
+    def gen_guard(self, builder, r):
+        if r.random() < 0.5:
+            return GuardClassOperation.gen_guard(self, builder, r)
+        else:
+            v = BoxPtr(lltype.nullptr(llmemory.GCREF.TO))
+            op = ResOperation(rop.SAME_AS, [ConstPtr(v.value)], v)
+            builder.loop.operations.append(op)
+            v2, S2 = builder.get_structptr_var(r, must_have_vtable=True)
+            vtable2 = S2._hints['vtable']._as_ptr()
+            c_vtable2 = ConstAddr(llmemory.cast_ptr_to_adr(vtable2),
+                                  builder.cpu)
+            op = ResOperation(self.opnum, [v, c_vtable2], None)
+            return op, False
+
 class GetFieldOperation(test_random.AbstractOperation):
     def field_descr(self, builder, r):
         v, S = builder.get_structptr_var(r)
@@ -577,6 +592,7 @@
     OPERATIONS.append(RaisingCallOperationGuardNoException(rop.CALL))
     OPERATIONS.append(RaisingCallOperationWrongGuardException(rop.CALL))
     OPERATIONS.append(CallOperationException(rop.CALL))
+OPERATIONS.append(GuardNonNullClassOperation(rop.GUARD_NONNULL_CLASS))
 
 LLtypeOperationBuilder.OPERATIONS = OPERATIONS
 

Modified: pypy/branch/merge-guards-2/pypy/jit/backend/x86/assembler.py
==============================================================================
--- pypy/branch/merge-guards-2/pypy/jit/backend/x86/assembler.py	(original)
+++ pypy/branch/merge-guards-2/pypy/jit/backend/x86/assembler.py	Tue Nov 10 19:00:21 2009
@@ -696,10 +696,10 @@
             self.mc.CMP(locs[0], locs[1])
         return self.implement_guard(addr, self.mc.JNE)
 
-    def genop_guard_guard_class(self, ign_1, guard_op, addr, locs, ign_2):
+    def _cmp_guard_class(self, mc, locs):
         offset = self.cpu.vtable_offset
         if offset is not None:
-            self.mc.CMP(mem(locs[0], offset), locs[1])
+            mc.CMP(mem(locs[0], offset), locs[1])
         else:
             # XXX hard-coded assumption: to go from an object to its class
             # we use the following algorithm:
@@ -714,8 +714,24 @@
             type_info_group = llop.gc_get_type_info_group(llmemory.Address)
             type_info_group = rffi.cast(lltype.Signed, type_info_group)
             expected_typeid = (classptr - type_info_group) >> 2
-            self.mc.CMP16(mem(locs[0], 0), imm32(expected_typeid))
-            #
+            mc.CMP16(mem(locs[0], 0), imm32(expected_typeid))
+
+    def genop_guard_guard_class(self, ign_1, guard_op, addr, locs, ign_2):
+        self._cmp_guard_class(self.mc._mc, locs)
+        return self.implement_guard(addr, self.mc.JNE)
+
+    def genop_guard_guard_nonnull_class(self, ign_1, guard_op,
+                                        addr, locs, ign_2):
+        mc = self.mc._mc
+        mc.CMP(locs[0], imm8(1))
+        mc.write(constlistofchars('\x72\x00'))             # JB later
+        jb_location = mc.get_relative_pos()
+        self._cmp_guard_class(mc, locs)
+        # patch the JB above
+        offset = mc.get_relative_pos() - jb_location
+        assert 0 < offset <= 127
+        mc.overwrite(jb_location-1, [chr(offset)])
+        #
         return self.implement_guard(addr, self.mc.JNE)
 
     def _no_const_locs(self, args):
@@ -880,8 +896,9 @@
         print msg
         raise NotImplementedError(msg)
 
-    def not_implemented_op_guard(self, op, regalloc, arglocs, resloc, descr):
-        msg = "not implemented operation (guard): %s" % op.getopname()
+    def not_implemented_op_guard(self, op, guard_op,
+                                 failaddr, arglocs, resloc):
+        msg = "not implemented operation (guard): %s" % guard_op.getopname()
         print msg
         raise NotImplementedError(msg)
 

Modified: pypy/branch/merge-guards-2/pypy/jit/backend/x86/regalloc.py
==============================================================================
--- pypy/branch/merge-guards-2/pypy/jit/backend/x86/regalloc.py	(original)
+++ pypy/branch/merge-guards-2/pypy/jit/backend/x86/regalloc.py	Tue Nov 10 19:00:21 2009
@@ -424,7 +424,9 @@
         y = self.loc(op.args[1])
         self.perform_guard(op, [x, y], None)
         self.rm.possibly_free_vars(op.args)
-    
+
+    consider_guard_nonnull_class = consider_guard_class
+
     def _consider_binop_part(self, op, ignored):
         x = op.args[0]
         argloc = self.loc(op.args[1])



More information about the Pypy-commit mailing list