Author: Maciej Fijalkowski <fij...@gmail.com> Branch: optresult-unroll Changeset: r79182:40b6f6640e9e Date: 2015-08-24 10:27 +0200 http://bitbucket.org/pypy/pypy/changeset/40b6f6640e9e/
Log: bakcout diff --git a/rpython/jit/backend/llgraph/runner.py b/rpython/jit/backend/llgraph/runner.py --- a/rpython/jit/backend/llgraph/runner.py +++ b/rpython/jit/backend/llgraph/runner.py @@ -101,6 +101,9 @@ def is_object(self): return self._is_object + def as_vtable_size_descr(self): + return self + def get_vtable(self): return heaptracker.adr2int(llmemory.cast_ptr_to_adr( self._corresponding_vtable)) diff --git a/rpython/jit/backend/llsupport/descr.py b/rpython/jit/backend/llsupport/descr.py --- a/rpython/jit/backend/llsupport/descr.py +++ b/rpython/jit/backend/llsupport/descr.py @@ -59,6 +59,9 @@ return False class SizeDescrWithVTable(SizeDescr): + def as_vtable_size_descr(self): + return self + def is_object(self): return True diff --git a/rpython/jit/backend/llsupport/rewrite.py b/rpython/jit/backend/llsupport/rewrite.py --- a/rpython/jit/backend/llsupport/rewrite.py +++ b/rpython/jit/backend/llsupport/rewrite.py @@ -121,8 +121,7 @@ if op.getopnum() == rop.DEBUG_MERGE_POINT: continue # ---------- GETFIELD_GC ---------- - if op.getopnum() in (rop.GETFIELD_GC_I, rop.GETFIELD_GC_F, - rop.GETFIELD_GC_R): + if op.getopnum() == rop.GETFIELD_GC: self.handle_getfield_gc(op) continue # ---------- turn NEWxxx into CALL_MALLOC_xxx ---------- @@ -195,7 +194,7 @@ followed by a bunch of 'setfields', and the 'pending_zeros' optimization we do here is meant for this case.""" self.emit_pending_zeros() - self.emit_op(op) + self.newops.append(op) # ---------- diff --git a/rpython/jit/backend/llsupport/test/test_pinned_object_rewrite.py b/rpython/jit/backend/llsupport/test/test_pinned_object_rewrite.py --- a/rpython/jit/backend/llsupport/test/test_pinned_object_rewrite.py +++ b/rpython/jit/backend/llsupport/test/test_pinned_object_rewrite.py @@ -8,6 +8,7 @@ from rpython.jit.metainterp.gc import get_description from rpython.jit.tool.oparser import parse from rpython.jit.metainterp.optimizeopt.util import equaloplists +from rpython.jit.codewriter.heaptracker import register_known_gctype from rpython.jit.metainterp.history import JitCellToken, FLOAT from rpython.rtyper.lltypesystem import lltype, rffi, lltype, llmemory from rpython.rtyper import rclass @@ -51,6 +52,7 @@ O = lltype.GcStruct('O', ('parent', rclass.OBJECT), ('x', lltype.Signed)) o_vtable = lltype.malloc(rclass.OBJECT_VTABLE, immortal=True) + register_known_gctype(self.cpu, o_vtable, O) # tiddescr = self.gc_ll_descr.fielddescr_tid wbdescr = self.gc_ll_descr.write_barrier_descr diff --git a/rpython/jit/backend/llsupport/test/test_rewrite.py b/rpython/jit/backend/llsupport/test/test_rewrite.py --- a/rpython/jit/backend/llsupport/test/test_rewrite.py +++ b/rpython/jit/backend/llsupport/test/test_rewrite.py @@ -7,6 +7,7 @@ from rpython.jit.metainterp.gc import get_description from rpython.jit.tool.oparser import parse from rpython.jit.metainterp.optimizeopt.util import equaloplists +from rpython.jit.codewriter.heaptracker import register_known_gctype from rpython.jit.metainterp.history import JitCellToken, FLOAT from rpython.jit.metainterp.history import AbstractFailDescr from rpython.rtyper.lltypesystem import lltype, rffi @@ -63,6 +64,7 @@ ('x', lltype.Signed)) o_descr = self.cpu.sizeof(O, True) o_vtable = globals()['o_vtable'] + register_known_gctype(self.cpu, o_vtable, O) # tiddescr = self.gc_ll_descr.fielddescr_tid wbdescr = self.gc_ll_descr.write_barrier_descr diff --git a/rpython/jit/backend/test/runner_test.py b/rpython/jit/backend/test/runner_test.py --- a/rpython/jit/backend/test/runner_test.py +++ b/rpython/jit/backend/test/runner_test.py @@ -1950,7 +1950,8 @@ cpu = self.cpu t_box, T_box, descr = self.alloc_instance(self.T) vtable = llmemory.cast_adr_to_ptr( - llmemory.cast_int_to_adr(T_box.getint()), rclass.CLASSTYPE) + llmemory.cast_int_to_adr(T_box.getint()), heaptracker.VTABLETYPE) + heaptracker.register_known_gctype(cpu, vtable, self.T) r1 = self.execute_operation(rop.NEW_WITH_VTABLE, [], 'ref', descr) r2 = self.execute_operation(rop.NEW_WITH_VTABLE, [], 'ref', descr) assert r1 != r2 diff --git a/rpython/jit/backend/test/test_ll_random.py b/rpython/jit/backend/test/test_ll_random.py --- a/rpython/jit/backend/test/test_ll_random.py +++ b/rpython/jit/backend/test/test_ll_random.py @@ -123,6 +123,8 @@ vtable.name = rclass.alloc_array_name(name) self.structure_types_and_vtables.append((S, vtable)) # + heaptracker.register_known_gctype(self.cpu, vtable, S) + # return S, vtable def get_random_structure(self, r, has_vtable=False): diff --git a/rpython/jit/codewriter/codewriter.py b/rpython/jit/codewriter/codewriter.py --- a/rpython/jit/codewriter/codewriter.py +++ b/rpython/jit/codewriter/codewriter.py @@ -74,6 +74,7 @@ if not count % 500: log.info("Produced %d jitcodes" % count) self.assembler.finished(self.callcontrol.callinfocollection) + heaptracker.finish_registering(self.cpu) log.info("there are %d JitCode instances." % count) def setup_vrefinfo(self, vrefinfo): diff --git a/rpython/jit/codewriter/heaptracker.py b/rpython/jit/codewriter/heaptracker.py --- a/rpython/jit/codewriter/heaptracker.py +++ b/rpython/jit/codewriter/heaptracker.py @@ -88,6 +88,57 @@ # ____________________________________________________________ +VTABLETYPE = rclass.CLASSTYPE + +def register_known_gctype(cpu, vtable, STRUCT): + # register the correspondance 'vtable' <-> 'STRUCT' in the cpu + sizedescr = cpu.sizeof(STRUCT, vtable) + assert sizedescr.as_vtable_size_descr() is sizedescr + if getattr(sizedescr, '_corresponding_vtable', None): + assert sizedescr._corresponding_vtable == vtable + return + assert lltype.typeOf(vtable) == VTABLETYPE + if not hasattr(cpu.tracker, '_all_size_descrs_with_vtable'): + cpu.tracker._all_size_descrs_with_vtable = [] + cpu.tracker._vtable_to_descr_dict = None + cpu.tracker._all_size_descrs_with_vtable.append(sizedescr) + sizedescr._corresponding_vtable = vtable + +def finish_registering(cpu): + # annotation hack for small examples which have no vtable at all + #if not hasattr(cpu.tracker, '_all_size_descrs_with_vtable'): + # vtable = lltype.malloc(rclass.OBJECT_VTABLE, immortal=True) + # register_known_gctype(cpu, vtable, rclass.OBJECT) + pass + +def vtable2descr(cpu, vtable): + assert lltype.typeOf(vtable) is lltype.Signed + vtable = int2adr(vtable) + if we_are_translated(): + # Build the dict {vtable: sizedescr} at runtime. + # This is necessary because the 'vtables' are just pointers to + # static data, so they can't be used as keys in prebuilt dicts. + d = cpu.tracker._vtable_to_descr_dict + if d is None: + d = cpu.tracker._vtable_to_descr_dict = {} + for descr in cpu.tracker._all_size_descrs_with_vtable: + key = descr._corresponding_vtable + key = llmemory.cast_ptr_to_adr(key) + d[key] = descr + return d[vtable] + else: + vtable = llmemory.cast_adr_to_ptr(vtable, VTABLETYPE) + for descr in cpu.tracker._all_size_descrs_with_vtable: + if descr._corresponding_vtable == vtable: + return descr + raise KeyError(vtable) + +def descr2vtable(cpu, descr): + from rpython.jit.metainterp import history + assert isinstance(descr, history.AbstractDescr) + vtable = descr.as_vtable_size_descr()._corresponding_vtable + vtable = llmemory.cast_ptr_to_adr(vtable) + return adr2int(vtable) def all_fielddescrs(gccache, STRUCT, only_gc=False, res=None, get_field_descr=None): diff --git a/rpython/jit/codewriter/jtransform.py b/rpython/jit/codewriter/jtransform.py --- a/rpython/jit/codewriter/jtransform.py +++ b/rpython/jit/codewriter/jtransform.py @@ -932,6 +932,7 @@ return self._do_builtin_call(op, 'alloc_with_del', [], extra=(RESULT, vtable), extrakey=STRUCT) + heaptracker.register_known_gctype(self.cpu, vtable, STRUCT) opname = 'new_with_vtable' else: opname = 'new' @@ -1935,6 +1936,10 @@ # VirtualRefs. def _handle_virtual_ref_call(self, op, oopspec_name, args): + vrefinfo = self.callcontrol.virtualref_info + heaptracker.register_known_gctype(self.cpu, + vrefinfo.jit_virtual_ref_vtable, + vrefinfo.JIT_VIRTUAL_REF) return SpaceOperation(oopspec_name, list(args), op.result) # ----------- diff --git a/rpython/jit/codewriter/test/test_codewriter.py b/rpython/jit/codewriter/test/test_codewriter.py --- a/rpython/jit/codewriter/test/test_codewriter.py +++ b/rpython/jit/codewriter/test/test_codewriter.py @@ -25,6 +25,8 @@ class FakeSizeDescr(AbstractDescr): def __init__(self, STRUCT): self.STRUCT = STRUCT + def as_vtable_size_descr(self): + return self class FakeArrayDescr(AbstractDescr): def __init__(self, ARRAY): diff --git a/rpython/jit/codewriter/test/test_flatten.py b/rpython/jit/codewriter/test/test_flatten.py --- a/rpython/jit/codewriter/test/test_flatten.py +++ b/rpython/jit/codewriter/test/test_flatten.py @@ -39,6 +39,8 @@ self.oopspecindex = oopspecindex def __repr__(self): return '<Descr>' + def as_vtable_size_descr(self): + return self class FakeDict(object): def __getitem__(self, key): diff --git a/rpython/jit/codewriter/test/test_jtransform.py b/rpython/jit/codewriter/test/test_jtransform.py --- a/rpython/jit/codewriter/test/test_jtransform.py +++ b/rpython/jit/codewriter/test/test_jtransform.py @@ -50,7 +50,8 @@ return FakeDescr(('sizedescr', STRUCT)) class FakeDescr(tuple): - pass + def as_vtable_size_descr(self): + return self class FakeLink: args = [] @@ -568,6 +569,9 @@ op1 = Transformer(cpu).rewrite_operation(op) assert op1.opname == 'new_with_vtable' assert op1.args == [('sizedescr', S)] + #assert heaptracker.descr2vtable(cpu, op1.args[0]) == vtable [type check] + vtable_int = heaptracker.adr2int(llmemory.cast_ptr_to_adr(vtable)) + assert heaptracker.vtable2descr(cpu, vtable_int) == op1.args[0] def test_malloc_new_with_destructor(): vtable = lltype.malloc(rclass.OBJECT_VTABLE, immortal=True) diff --git a/rpython/jit/metainterp/optimizeopt/info.py b/rpython/jit/metainterp/optimizeopt/info.py --- a/rpython/jit/metainterp/optimizeopt/info.py +++ b/rpython/jit/metainterp/optimizeopt/info.py @@ -242,11 +242,6 @@ if self.size != -1: self.buffer = RawBuffer(cpu, None) - def _get_buffer(self): - buffer = self.buffer - assert buffer is not None - return buffer - def getitem_raw(self, offset, itemsize, descr): if not self.is_virtual(): raise InvalidRawOperation @@ -254,39 +249,37 @@ # for the test above: it's not enough to check is_virtual() # on the original object, because it might be a VRawSliceValue # instead. If it is a virtual one, then we'll reach here anway. - return self._get_buffer().read_value(offset, itemsize, descr) + return self.buffer.read_value(offset, itemsize, descr) def setitem_raw(self, offset, itemsize, descr, itemop): if not self.is_virtual(): raise InvalidRawOperation - self._get_buffer().write_value(offset, itemsize, descr, itemop) + self.buffer.write_value(offset, itemsize, descr, itemop) def is_virtual(self): return self.size != -1 def _force_elements(self, op, optforce, descr): self.size = -1 - buffer = self._get_buffer() - for i in range(len(buffer.offsets)): + for i in range(len(self.buffer.offsets)): # write the value - offset = buffer.offsets[i] - descr = buffer.descrs[i] - itembox = buffer.values[i] + offset = self.buffer.offsets[i] + descr = self.buffer.descrs[i] + itembox = self.buffer.values[i] setfield_op = ResOperation(rop.RAW_STORE, [op, ConstInt(offset), itembox], descr=descr) optforce.emit_operation(setfield_op) def _visitor_walk_recursive(self, op, visitor, optimizer): - itemboxes = self._get_buffer().values + itemboxes = self.buffer.values visitor.register_virtual_fields(op, itemboxes) # there can be no virtuals stored in raw buffer @specialize.argtype(1) def visitor_dispatch_virtual_type(self, visitor): - buffer = self._get_buffer() return visitor.visit_vrawbuffer(self.size, - buffer.offsets[:], - buffer.descrs[:]) + self.buffer.offsets[:], + self.buffer.descrs[:]) class RawStructPtrInfo(AbstractRawPtrInfo): def __init__(self): diff --git a/rpython/jit/metainterp/optimizeopt/test/test_util.py b/rpython/jit/metainterp/optimizeopt/test/test_util.py --- a/rpython/jit/metainterp/optimizeopt/test/test_util.py +++ b/rpython/jit/metainterp/optimizeopt/test/test_util.py @@ -12,6 +12,7 @@ from rpython.jit.metainterp.optimizeopt.util import sort_descrs, equaloplists from rpython.jit.codewriter.effectinfo import EffectInfo from rpython.jit.metainterp.logger import LogOperations +from rpython.jit.codewriter.heaptracker import register_known_gctype from rpython.jit.tool.oparser import OpParser from rpython.jit.metainterp.quasiimmut import QuasiImmutDescr from rpython.jit.metainterp import compile, resume, history @@ -351,6 +352,17 @@ jvr_vtable_adr = llmemory.cast_ptr_to_adr(jit_virtual_ref_vtable) vref_descr = cpu.sizeof(vrefinfo.JIT_VIRTUAL_REF, False) + register_known_gctype(cpu, node_vtable, NODE) + register_known_gctype(cpu, node_vtable2, NODE2) + register_known_gctype(cpu, node_vtable3, NODE3) + register_known_gctype(cpu, u_vtable, U) + register_known_gctype(cpu, simple_vtable, SIMPLE) + register_known_gctype(cpu, jit_virtual_ref_vtable,vrefinfo.JIT_VIRTUAL_REF) + register_known_gctype(cpu, intobj_noimmut_vtable, INTOBJ_NOIMMUT) + register_known_gctype(cpu, intobj_immut_vtable, INTOBJ_IMMUT) + register_known_gctype(cpu, ptrobj_immut_vtable, PTROBJ_IMMUT) + register_known_gctype(cpu, w_root_vtable, W_ROOT) + namespace = locals() # ____________________________________________________________ diff --git a/rpython/jit/metainterp/optimizeopt/virtualize.py b/rpython/jit/metainterp/optimizeopt/virtualize.py --- a/rpython/jit/metainterp/optimizeopt/virtualize.py +++ b/rpython/jit/metainterp/optimizeopt/virtualize.py @@ -1,4 +1,5 @@ from rpython.jit.codewriter.effectinfo import EffectInfo +from rpython.jit.codewriter.heaptracker import descr2vtable from rpython.jit.metainterp.history import ConstInt from rpython.jit.metainterp.history import CONST_NULL from rpython.jit.metainterp.optimizeopt import info, optimizer @@ -198,7 +199,7 @@ self.emit_operation(op) def optimize_NEW_WITH_VTABLE(self, op): - known_class = ConstInt(op.getdescr().get_vtable()) + known_class = ConstInt(descr2vtable(self.optimizer.cpu, op.getdescr())) self.make_virtual(known_class, op, op.getdescr()) def optimize_NEW(self, op): diff --git a/rpython/jit/metainterp/test/test_warmspot.py b/rpython/jit/metainterp/test/test_warmspot.py --- a/rpython/jit/metainterp/test/test_warmspot.py +++ b/rpython/jit/metainterp/test/test_warmspot.py @@ -597,7 +597,8 @@ self._no = no class FakeDescr: - pass + def as_vtable_size_descr(self): + return self class FakeCPU(object): supports_floats = False _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit