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