Author: Armin Rigo <ar...@tunes.org>
Branch: optresult-unroll
Changeset: r79410:39efc5926eb8
Date: 2015-09-04 10:28 +0200
http://bitbucket.org/pypy/pypy/changeset/39efc5926eb8/

Log:    Untested so far: guard_is_object

diff --git a/rpython/jit/backend/llsupport/gc.py 
b/rpython/jit/backend/llsupport/gc.py
--- a/rpython/jit/backend/llsupport/gc.py
+++ b/rpython/jit/backend/llsupport/gc.py
@@ -438,6 +438,7 @@
             self._make_gcrootmap()
             self._setup_gcclass()
             self._setup_tid()
+            self._setup_guard_is_object()
         self._setup_write_barrier()
         self._setup_str()
         self._make_functions(really_not_translated)
@@ -662,6 +663,48 @@
     def get_malloc_slowpath_array_addr(self):
         return self.get_malloc_fn_addr('malloc_array')
 
+    def get_typeid_from_classptr_if_gcremovetypeptr(self, classptr):
+        """Returns the typeid corresponding from a vtable pointer 'classptr'.
+        This function only works if cpu.vtable_offset is None, i.e. in
+        a translation with --gcremovetypeptr.
+         """
+        from rpython.memory.gctypelayout import GCData
+        assert translator.config.translation.gcremovetypeptr
+
+        # hard-coded assumption: to go from an object to its class
+        # we would use the following algorithm:
+        #   - read the typeid from mem(locs[0]), i.e. at offset 0;
+        #     this is a complete word (N=4 bytes on 32-bit, N=8 on
+        #     64-bits)
+        #   - keep the lower half of what is read there (i.e.
+        #     truncate to an unsigned 'N / 2' bytes value)
+        #   - multiply by 4 (on 32-bits only) and use it as an
+        #     offset in type_info_group
+        #   - add 16/32 bytes, to go past the TYPE_INFO structure
+        # here, we have to go back from 'classptr' back to the typeid,
+        # so we do (part of) these computations in reverse.
+
+        sizeof_ti = rffi.sizeof(GCData.TYPE_INFO)
+        type_info_group = llop.gc_get_type_info_group(llmemory.Address)
+        type_info_group = rffi.cast(lltype.Signed, type_info_group)
+        expected_typeid = classptr - sizeof_ti - type_info_group
+        if IS_X86_32:
+            expected_typeid >>= 2
+        return expected_typeid
+
+    def _setup_guard_is_object(self):
+        from rpython.memory.gctypelayout import GCData, T_IS_RPYTHON_INSTANCE
+        self._infobits_offset = symbolic.get_field_token(GCData.TYPE_INFO,
+                                                         'infobits', True)
+        self._T_IS_RPYTHON_INSTANCE = T_IS_RPYTHON_INSTANCE
+
+    def get_translated_info_for_guard_is_object(self):
+        type_info_group = llop.gc_get_type_info_group(llmemory.Address)
+        type_info_group = rffi.cast(lltype.Signed, type_info_group)
+        infobits_offset = rffi.cast(lltype.Signed, self._infobits_offset)
+        return (type_info_group + infobits_offset, self._T_IS_RPYTHON_INSTANCE)
+
+
 # ____________________________________________________________
 
 def get_ll_description(gcdescr, translator=None, rtyper=None):
diff --git a/rpython/jit/backend/x86/assembler.py 
b/rpython/jit/backend/x86/assembler.py
--- a/rpython/jit/backend/x86/assembler.py
+++ b/rpython/jit/backend/x86/assembler.py
@@ -1741,25 +1741,10 @@
         if offset is not None:
             self.mc.CMP(mem(loc_ptr, offset), loc_classptr)
         else:
-            # XXX hard-coded assumption: to go from an object to its class
-            # we use the following algorithm:
-            #   - read the typeid from mem(locs[0]), i.e. at offset 0;
-            #     this is a complete word (N=4 bytes on 32-bit, N=8 on
-            #     64-bits)
-            #   - keep the lower half of what is read there (i.e.
-            #     truncate to an unsigned 'N / 2' bytes value)
-            #   - multiply by 4 (on 32-bits only) and use it as an
-            #     offset in type_info_group
-            #   - add 16/32 bytes, to go past the TYPE_INFO structure
             assert isinstance(loc_classptr, ImmedLoc)
             classptr = loc_classptr.value
-            # here, we have to go back from 'classptr' to the value expected
-            # from reading the half-word in the object header.
-            from rpython.memory.gctypelayout import GCData
-            sizeof_ti = rffi.sizeof(GCData.TYPE_INFO)
-            type_info_group = llop.gc_get_type_info_group(llmemory.Address)
-            type_info_group = rffi.cast(lltype.Signed, type_info_group)
-            expected_typeid = classptr - sizeof_ti - type_info_group
+            expected_typeid = (self.cpu.gc_ll_descr
+                    .get_typeid_from_classptr_if_gcremovetypeptr(classptr))
             self._cmp_guard_gc_type(loc_ptr, ImmedLoc(expected_typeid))
 
     def _cmp_guard_gc_type(self, loc_ptr, loc_expected_typeid):
@@ -1795,6 +1780,25 @@
         self._cmp_guard_gc_type(locs[0], locs[1])
         self.implement_guard(guard_token, 'NE')
 
+    def genop_guard_guard_is_object(self, ign_1, guard_op,
+                                    guard_token, locs, ign_2):
+        assert self.cpu.supports_guard_gc_type
+        [loc_object, loc_typeid] = locs
+        # idea: read the typeid, fetch the field 'infobits' from the big
+        # typeinfo table, and check the flag 'T_IS_RPYTHON_INSTANCE'.
+        base_type_info, IS_OBJECT_FLAG = (
+            self.cpu.gc_ll_descr.get_translated_info_for_guard_is_object())
+        if IS_X86_32:
+            self.mc.MOVZX16(loc_typeid, mem(loc_object, 0))
+            shift_by = 2
+        else:
+            self.mc.MOVZX32(loc_typeid, mem(loc_object, 0))
+            shift_by = 0
+        loc_infobits = addr_add(imm(base_type_info), loc_typeid, 
scale=shift_by)
+        self.mc.TEST(loc_infobits, imm(IS_OBJECT_FLAG))
+        #
+        self.implement_guard(guard_token, 'Z')
+
     def implement_guard_recovery(self, guard_opnum, faildescr, failargs,
                                  fail_locs, frame_depth):
         exc = (guard_opnum == rop.GUARD_EXCEPTION or
diff --git a/rpython/jit/backend/x86/regalloc.py 
b/rpython/jit/backend/x86/regalloc.py
--- a/rpython/jit/backend/x86/regalloc.py
+++ b/rpython/jit/backend/x86/regalloc.py
@@ -431,7 +431,11 @@
     consider_guard_gc_type = consider_guard_class
 
     def consider_guard_is_object(self, op):
-        xxx
+        x = self.make_sure_var_in_reg(op.getarg(0))
+        tmp_box = TempVar()
+        y = self.rm.force_allocate_reg(tmp_box)
+        self.rm.possibly_free_var(tmp_box)
+        self.perform_guard(op, [x, y], None)
 
     def consider_guard_subclass(self, op):
         xxx
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to