[pypy-commit] pypy gc-incminimark-pinning: size of array for movable objects is now as large as it needs to be.
groggi
noreply at buildbot.pypy.org
Thu Aug 14 11:47:14 CEST 2014
Author: Gregor Wegberg <code at gregorwegberg.com>
Branch: gc-incminimark-pinning
Changeset: r72794:5dcc35cb8954
Date: 2014-08-14 11:30 +0200
http://bitbucket.org/pypy/pypy/changeset/5dcc35cb8954/
Log: size of array for movable objects is now as large as it needs to be.
there is still some optimization possible: if only one object is
pinned but used in six operations, the array will contain six
pointers pointing to the same pinned 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
@@ -112,8 +112,8 @@
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, pinned_obj_tracker):
- newops = []
+ def _record_constptrs(self, op, gcrefs_output_list, moving_output_list):
+ moving_output_list[op] = []
for i in range(op.numargs()):
v = op.getarg(i)
if isinstance(v, ConstPtr) and bool(v.value):
@@ -121,22 +121,34 @@
if rgc._make_sure_does_not_move(p):
gcrefs_output_list.append(p)
else:
- # encountered a pointer that points to a possibly moving object.
- # Solve the problem by double loading the address to the object
- # each run of the JITed code.
- result_ptr = BoxPtr()
- array_index = pinned_obj_tracker.add_ref(p)
- load_op = ResOperation(rop.GETARRAYITEM_GC,
- [ConstPtr(pinned_obj_tracker.ref_array_gcref), ConstInt(array_index)],
- result_ptr,
- descr=pinned_obj_tracker.ref_array_descr)
- newops.append(load_op)
- op.setarg(i, result_ptr)
+ moving_output_list[op].append(i)
#
if op.is_guard() or op.getopnum() == rop.FINISH:
llref = cast_instance_to_gcref(op.getdescr())
assert rgc._make_sure_does_not_move(llref)
gcrefs_output_list.append(llref)
+ #
+ if len(moving_output_list[op]) == 0:
+ del moving_output_list[op]
+
+ def _rewrite_constptrs(self, op, moving_output_list, pinned_obj_tracker):
+ newops = []
+ for arg_i in moving_output_list[op]:
+ v = op.getarg(arg_i)
+ # assert to make sure we got what we expected
+ assert isinstance(v, ConstPtr)
+ assert bool(v.value)
+ p = v.value
+ result_ptr = BoxPtr()
+ array_index = pinned_obj_tracker.add_ref(p)
+ load_op = ResOperation(rop.GETARRAYITEM_GC,
+ [ConstPtr(pinned_obj_tracker.ref_array_gcref),
+ ConstInt(array_index)],
+ result_ptr,
+ descr=pinned_obj_tracker.ref_array_descr)
+ newops.append(load_op)
+ op.setarg(arg_i, result_ptr)
+ #
newops.append(op)
return newops
@@ -147,18 +159,27 @@
# 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)
- pinned_obj_tracker = PinnedObjectTracker(cpu, 100)
- if not we_are_translated():
- self.last_pinned_object_tracker = pinned_obj_tracker
- gcrefs_output_list.append(pinned_obj_tracker.ref_array_gcref)
- rgc._make_sure_does_not_move(pinned_obj_tracker.ref_array_gcref)
-
+
newnewops = [] # XXX better name... (groggi)
+ moving_output_list = {}
for op in newops:
- ops = self._record_constptrs(op, gcrefs_output_list, pinned_obj_tracker)
- newnewops.extend(ops)
+ self._record_constptrs(op, gcrefs_output_list, moving_output_list)
+ #
+ if len(moving_output_list) > 0:
+ pinned_obj_tracker = PinnedObjectTracker(cpu, len(moving_output_list))
+ if not we_are_translated():
+ self.last_pinned_object_tracker = pinned_obj_tracker
+ gcrefs_output_list.append(pinned_obj_tracker.ref_array_gcref)
+ rgc._make_sure_does_not_move(pinned_obj_tracker.ref_array_gcref)
+
+ for op in newops:
+ if op in moving_output_list:
+ reops = self._rewrite_constptrs(op, moving_output_list,
+ pinned_obj_tracker)
+ newnewops.extend(reops)
+ else:
+ newnewops.append(op)
return newnewops
@specialize.memo()
More information about the pypy-commit
mailing list