Author: edelsohn
Branch: ppc-jit-backend
Changeset: r54540:5b05d7de13d5
Date: 2012-04-19 11:30 -0400
http://bitbucket.org/pypy/pypy/changeset/5b05d7de13d5/

Log:    (edelsohn, arigato): Complete guard_class support for GC.

diff --git a/pypy/jit/backend/ppc/opassembler.py 
b/pypy/jit/backend/ppc/opassembler.py
--- a/pypy/jit/backend/ppc/opassembler.py
+++ b/pypy/jit/backend/ppc/opassembler.py
@@ -259,14 +259,22 @@
     def _cmp_guard_class(self, op, locs, regalloc):
         offset = locs[2]
         if offset is not None:
-            #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)
             with scratch_reg(self.mc):
                 self.mc.load(r.SCRATCH.value, locs[0].value, offset.value)
                 self.mc.cmp_op(0, r.SCRATCH.value, locs[1].value)
         else:
-            raise NotImplementedError
-            # XXX port from x86 backend once gc support is in place
+            typeid = locs[1]
+            # here, we have to go back from 'classptr' to the value expected
+            # from reading the half-word in the object header.  Note that
+            # this half-word is at offset 0 on a little-endian machine;
+            # it would be at offset 2 (32 bit) or 4 (64 bit) on a
+            # big-endian machine.
+            with scratch_reg(self.mc):
+                if IS_PPC_32:
+                    self.mc.lhz(r.SCRATCH.value, locs[0].value, 2)
+                else:
+                    self.mc.lwz(r.SCRATCH.value, locs[0].value, 4)
+                self.mc.cmp_op(0, r.SCRATCH.value, typeid.value, 
imm=typeid.is_imm())
 
     def emit_guard_not_invalidated(self, op, locs, regalloc):
         return self._emit_guard(op, locs, c.EQ, is_guard_not_invalidated=True)
diff --git a/pypy/jit/backend/ppc/regalloc.py b/pypy/jit/backend/ppc/regalloc.py
--- a/pypy/jit/backend/ppc/regalloc.py
+++ b/pypy/jit/backend/ppc/regalloc.py
@@ -1,6 +1,6 @@
 from pypy.jit.backend.llsupport.regalloc import (RegisterManager, FrameManager,
                                                  TempBox, 
compute_vars_longevity)
-from pypy.jit.backend.ppc.arch import (WORD, MY_COPY_OF_REGS)
+from pypy.jit.backend.ppc.arch import (WORD, MY_COPY_OF_REGS, IS_PPC_32)
 from pypy.jit.backend.ppc.jump import remap_frame_layout
 from pypy.jit.backend.ppc.locations import imm
 from pypy.jit.backend.ppc.helper.regalloc import (_check_imm_arg,
@@ -15,7 +15,8 @@
 from pypy.jit.metainterp.history import JitCellToken, TargetToken
 from pypy.jit.metainterp.resoperation import rop
 from pypy.jit.backend.ppc import locations
-from pypy.rpython.lltypesystem import rffi, lltype, rstr
+from pypy.rpython.lltypesystem import rffi, lltype, rstr, llmemory
+from pypy.rpython.lltypesystem.lloperation import llop
 from pypy.jit.backend.llsupport import symbolic
 from pypy.jit.backend.llsupport.descr import ArrayDescr
 import pypy.jit.backend.ppc.register as r
@@ -452,17 +453,45 @@
         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))
 
-        return arglocs
+            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 half-word read there
+            #   - 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
+            classptr = y_val
+            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
+            if IS_PPC_32:
+                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)
 
     prepare_guard_nonnull_class = prepare_guard_class
 
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to