[pypy-commit] pypy gc-incminimark-pinning: (wip) add JIT support for object pinning
groggi
noreply at buildbot.pypy.org
Wed Jun 25 18:32:04 CEST 2014
Author: Gregor Wegberg <code at gregorwegberg.com>
Branch: gc-incminimark-pinning
Changeset: r72220:51aa811f0ec2
Date: 2014-06-24 17:41 +0200
http://bitbucket.org/pypy/pypy/changeset/51aa811f0ec2/
Log: (wip) add JIT support for object pinning
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
@@ -8,8 +8,8 @@
from rpython.rtyper.annlowlevel import llhelper, cast_instance_to_gcref
from rpython.translator.tool.cbuild import ExternalCompilationInfo
from rpython.jit.codewriter import heaptracker
-from rpython.jit.metainterp.history import ConstPtr, AbstractDescr
-from rpython.jit.metainterp.resoperation import rop
+from rpython.jit.metainterp.history import ConstPtr, AbstractDescr, BoxPtr, ConstInt
+from rpython.jit.metainterp.resoperation import rop, ResOperation
from rpython.jit.backend.llsupport import symbolic, jitframe
from rpython.jit.backend.llsupport.symbolic import WORD
from rpython.jit.backend.llsupport.descr import SizeDescr, ArrayDescr
@@ -92,26 +92,70 @@
def gc_malloc_unicode(self, num_elem):
return self._bh_malloc_array(num_elem, self.unicode_descr)
- def _record_constptrs(self, op, gcrefs_output_list):
+ class PinnedObjectTracker(object):
+ """Simple helper class to keep informations regarding the 'GcArray'
+ in one place that is used to double load pinned objects.
+ """
+ def __init__(self, cpu, size):
+ self._nextItem = 0
+ self._refArrayType = lltype.GcArray(llmemory.GCREF)
+ self.refArrayDescr = cpu.arraydescrof(self._refArrayType)
+ self._refArray = lltype.malloc(self._refArrayType, size)
+ self.refArrayGCREF = lltype.cast_opaque_ptr(llmemory.GCREF, self._refArray)
+
+ def add_ref(self, ref):
+ index = self._nextItem
+ self._nextItem += 1
+ #
+ self._refArray[index] = ref
+ return index
+
+ def _record_constptrs(self, op, gcrefs_output_list, pinnedObjTracker):
+ newops = []
for i in range(op.numargs()):
v = op.getarg(i)
if isinstance(v, ConstPtr) and bool(v.value):
p = v.value
- rgc._make_sure_does_not_move(p)
- gcrefs_output_list.append(p)
+ if rgc._make_sure_does_not_move(p):
+ gcrefs_output_list.append(p)
+ else:
+ # encountered a moving pointer. Solve the problem by double
+ # loading the address to the pointer each run of the JITed code.
+ resultPtr = BoxPtr()
+ arrayIndex = pinnedObjTracker.add_ref(p)
+ loadOp = ResOperation(rop.GETARRAYITEM_GC,
+ [ConstPtr(pinnedObjTracker.refArrayGCREF), ConstInt(arrayIndex)],
+ resultPtr,
+ descr=pinnedObjTracker.refArrayDescr)
+ newops.append(loadOp)
+ op.setarg(i, resultPtr)
+ #
if op.is_guard() or op.getopnum() == rop.FINISH:
llref = cast_instance_to_gcref(op.getdescr())
- rgc._make_sure_does_not_move(llref)
+ if not rgc._make_sure_does_not_move(llref):
+ raise NotImplementedError("blub") # XXX handle (groggi)
gcrefs_output_list.append(llref)
+ newops.append(op)
+ return newops
def rewrite_assembler(self, cpu, operations, gcrefs_output_list):
rewriter = GcRewriterAssembler(self, cpu)
newops = rewriter.rewrite(operations)
# record all GCREFs, because the GC (or Boehm) cannot see them and
# keep them alive if they end up as constants in the assembler
+
+ # XXX add comment (groggi)
+ # XXX handle size in a not constant way? Get it from the GC? (groggi)
+ pinnedObjTracker = self.PinnedObjectTracker(cpu, 100)
+ gcrefs_output_list.append(pinnedObjTracker.refArrayGCREF)
+ rgc._make_sure_does_not_move(pinnedObjTracker.refArrayGCREF)
+
+ newnewops = [] # XXX better name... (groggi)
+
for op in newops:
- self._record_constptrs(op, gcrefs_output_list)
- return newops
+ ops = self._record_constptrs(op, gcrefs_output_list, pinnedObjTracker)
+ newnewops.extend(ops)
+ return newnewops
@specialize.memo()
def getframedescrs(self, cpu):
More information about the pypy-commit
mailing list