[pypy-commit] pypy arm-backend-2: implement and enable gcremovetypeptr support in the ARM backend

bivab noreply at buildbot.pypy.org
Wed Feb 15 18:35:33 CET 2012


Author: David Schneider <david.schneider at picle.org>
Branch: arm-backend-2
Changeset: r52519:b1614ce9d2cb
Date: 2012-02-15 18:35 +0100
http://bitbucket.org/pypy/pypy/changeset/b1614ce9d2cb/

Log:	implement and enable gcremovetypeptr support in the ARM backend

diff --git a/pypy/jit/backend/arm/opassembler.py b/pypy/jit/backend/arm/opassembler.py
--- a/pypy/jit/backend/arm/opassembler.py
+++ b/pypy/jit/backend/arm/opassembler.py
@@ -261,7 +261,6 @@
     def emit_op_guard_overflow(self, op, arglocs, regalloc, fcond):
         return self._emit_guard(op, arglocs, c.VS, save_exc=False)
 
-    # from ../x86/assembler.py:1265
     def emit_op_guard_class(self, op, arglocs, regalloc, fcond):
         self._cmp_guard_class(op, arglocs, regalloc, fcond)
         self._emit_guard(op, arglocs[3:], c.EQ, save_exc=False)
@@ -279,8 +278,12 @@
             self.mc.LDR_ri(r.ip.value, locs[0].value, offset.value, cond=fcond)
             self.mc.CMP_rr(r.ip.value, locs[1].value, cond=fcond)
         else:
-            raise NotImplementedError
-            # XXX port from x86 backend once gc support is in place
+            typeid = locs[1]
+            self.mc.LDRH_ri(r.ip.value, locs[0].value, cond=fcond)
+            if typeid.is_imm():
+                self.mc.CMP_ri(r.ip.value, typeid.value, cond=fcond)
+            else:
+                self.mc.CMP_rr(r.ip.value, typeid.value, cond=fcond)
 
     def emit_op_guard_not_invalidated(self, op, locs, regalloc, fcond):
         return self._emit_guard(op, locs, fcond, save_exc=False,
diff --git a/pypy/jit/backend/arm/regalloc.py b/pypy/jit/backend/arm/regalloc.py
--- a/pypy/jit/backend/arm/regalloc.py
+++ b/pypy/jit/backend/arm/regalloc.py
@@ -22,7 +22,8 @@
 from pypy.jit.metainterp.resoperation import rop
 from pypy.jit.backend.llsupport.descr import ArrayDescr
 from pypy.jit.backend.llsupport import symbolic
-from pypy.rpython.lltypesystem import lltype, rffi, rstr
+from pypy.rpython.lltypesystem import lltype, rffi, rstr, llmemory
+from pypy.rpython.lltypesystem.lloperation import llop
 from pypy.jit.codewriter.effectinfo import EffectInfo
 from pypy.jit.backend.llsupport.descr import unpack_arraydescr
 from pypy.jit.backend.llsupport.descr import unpack_fielddescr
@@ -653,15 +654,44 @@
         boxes = op.getarglist()
 
         x = self._ensure_value_is_boxed(boxes[0], boxes)
-        y = self.get_scratch_reg(INT, forbidden_vars=boxes)
         y_val = rffi.cast(lltype.Signed, op.getarg(1).getint())
-        self.assembler.load(y, imm(y_val))
+
+        arglocs = [x, None, None]
 
         offset = self.cpu.vtable_offset
-        assert offset is not None
-        assert check_imm_arg(offset)
-        offset_loc = imm(offset)
-        arglocs = self._prepare_guard(op, [x, y, offset_loc])
+        if offset is not None:
+            y = self.get_scratch_reg(INT, forbidden_vars=boxes)
+            self.assembler.load(y, imm(y_val))
+
+            assert check_imm_arg(offset)
+            offset_loc = imm(offset)
+
+            arglocs[1] = y
+            arglocs[2] = offset_loc
+        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
+            #   - keep the lower 16 bits read there
+            #   - multiply by 4 and use it as an offset in type_info_group
+            #   - add 16 bytes, to go past the TYPE_INFO structure
+            classptr = y_val
+            # here, we have to go back from 'classptr' to the value expected
+            # from reading the 16 bits in the object header
+            from pypy.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 >>= 2
+            if check_imm_arg(expected_typeid):
+                arglocs[1] = imm(expected_typeid)
+            else:
+                y = self.get_scratch_reg(INT, forbidden_vars=boxes)
+                self.assembler.load(y, imm(expected_typeid))
+                arglocs[1] = y
+
+        return self._prepare_guard(op, arglocs)
 
         return arglocs
 
diff --git a/pypy/jit/backend/arm/runner.py b/pypy/jit/backend/arm/runner.py
--- a/pypy/jit/backend/arm/runner.py
+++ b/pypy/jit/backend/arm/runner.py
@@ -14,9 +14,6 @@
                  gcdescr=None):
         if gcdescr is not None:
             gcdescr.force_index_ofs = FORCE_INDEX_OFS
-            # XXX for now the arm backend does not support the gcremovetypeptr
-            # translation option
-            assert gcdescr.config.translation.gcremovetypeptr is False
         AbstractLLCPU.__init__(self, rtyper, stats, opts,
                                translate_support_code, gcdescr)
 


More information about the pypy-commit mailing list