Author: Maciej Fijalkowski <fij...@gmail.com> Branch: optresult Changeset: r76269:917cc4c8ef85 Date: 2015-03-07 14:05 +0200 http://bitbucket.org/pypy/pypy/changeset/917cc4c8ef85/
Log: basic virtuals 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 @@ -89,8 +89,10 @@ return getkind(self.RESULT)[0] class SizeDescr(AbstractDescr): - def __init__(self, S): + def __init__(self, S, runner): self.S = S + self.all_fielddescrs = heaptracker.all_fielddescrs(runner, S, + get_field_descr=LLGraphCPU.fielddescrof) def as_vtable_size_descr(self): return self @@ -106,6 +108,7 @@ self.S = S self.fieldname = fieldname self.FIELD = getattr(S, fieldname) + self.index = heaptracker.get_fielddescr_index_in(S, fieldname) def get_vinfo(self): return self.vinfo @@ -374,7 +377,7 @@ try: return self.descrs[key] except KeyError: - descr = SizeDescr(S) + descr = SizeDescr(S, self) self.descrs[key] = descr return descr 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 @@ -36,10 +36,11 @@ tid = llop.combine_ushort(lltype.Signed, 0, 0) def __init__(self, size, count_fields_if_immut=-1, - gc_fielddescrs=None): + gc_fielddescrs=None, all_fielddescrs=None): self.size = size self.count_fields_if_immut = count_fields_if_immut self.gc_fielddescrs = gc_fielddescrs + self.all_fielddescrs = all_fielddescrs def count_fields_if_immutable(self): return self.count_fields_if_immut @@ -61,12 +62,13 @@ size = symbolic.get_size(STRUCT, gccache.translate_support_code) count_fields_if_immut = heaptracker.count_fields_if_immutable(STRUCT) gc_fielddescrs = heaptracker.gc_fielddescrs(gccache, STRUCT) + all_fielddescrs = heaptracker.all_fielddescrs(gccache, STRUCT) if heaptracker.has_gcstruct_a_vtable(STRUCT): sizedescr = SizeDescrWithVTable(size, count_fields_if_immut, - gc_fielddescrs) + gc_fielddescrs, all_fielddescrs) else: sizedescr = SizeDescr(size, count_fields_if_immut, - gc_fielddescrs) + gc_fielddescrs, all_fielddescrs) gccache.init_size_descr(STRUCT, sizedescr) cache[STRUCT] = sizedescr return sizedescr 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 @@ -136,9 +136,12 @@ vtable = llmemory.cast_ptr_to_adr(vtable) return adr2int(vtable) -def fielddescrs_from_struct(gccache, STRUCT, only_gc=False, res=None): +def all_fielddescrs(gccache, STRUCT, only_gc=False, res=None, + get_field_descr=None): from rpython.jit.backend.llsupport import descr + if get_field_descr is None: + get_field_descr = descr.get_field_descr if res is None: res = [] # order is not relevant, except for tests @@ -146,11 +149,31 @@ FIELD = getattr(STRUCT, name) if FIELD is lltype.Void: continue + if name == 'typeptr': + continue # dealt otherwise elif isinstance(FIELD, lltype.Struct): - fielddescrs_from_struct(gccache, FIELD, only_gc, res) + all_fielddescrs(gccache, FIELD, only_gc, res, get_field_descr) elif (not only_gc) or (isinstance(FIELD, lltype.Ptr) and FIELD._needsgc()): - res.append(descr.get_field_descr(gccache, STRUCT, name)) + res.append(get_field_descr(gccache, STRUCT, name)) return res def gc_fielddescrs(gccache, STRUCT): - return fielddescrs_from_struct(gccache, STRUCT, True) + return all_fielddescrs(gccache, STRUCT, True) + +def get_fielddescr_index_in(STRUCT, fieldname, cur_index=0): + for name in STRUCT._names: + FIELD = getattr(STRUCT, name) + if FIELD is lltype.Void: + continue + if name == 'typeptr': + continue # dealt otherwise + elif isinstance(FIELD, lltype.Struct): + r = get_fielddescr_index_in(FIELD, fieldname, cur_index) + if r != -1: + return r + continue + elif name == fieldname: + return cur_index + cur_index += 1 + return -1 # not found + diff --git a/rpython/jit/metainterp/optimizeopt/heap.py b/rpython/jit/metainterp/optimizeopt/heap.py --- a/rpython/jit/metainterp/optimizeopt/heap.py +++ b/rpython/jit/metainterp/optimizeopt/heap.py @@ -478,6 +478,8 @@ return pendingfields def optimize_GETFIELD_GC_I(self, op): + self.emit_operation(op) + return structvalue = self.getvalue(op.getarg(0)) cf = self.field_cache(op.getdescr()) fieldvalue = cf.getfield_from_cache(self, structvalue) 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 @@ -1,5 +1,6 @@ -from rpython.jit.metainterp.resoperation import AbstractValue +from rpython.jit.metainterp.resoperation import AbstractValue, ResOperation,\ + rop """ The tag field on PtrOptInfo has a following meaning: @@ -52,14 +53,9 @@ def is_nonnull(self): return True - -class InstancePtrInfo(NonNullPtrInfo): - _attrs_ = ('_known_class', '_is_virtual', '_fields') - _fields = None - def __init__(self, known_class=None, is_virtual=False): - self._known_class = known_class - self._is_virtual = is_virtual +class AbstractStructPtrInfo(NonNullPtrInfo): + _attrs_ = ('_is_virtual', '_fields') def force_box(self, op, optforce): if self._is_virtual: @@ -69,20 +65,38 @@ op.set_forwarded(newop) newop.set_forwarded(self) self._is_virtual = False + if self._fields is not None: + descr = op.getdescr() + for i, flddescr in enumerate(descr.all_fielddescrs): + fld = self._fields[i] + if fld is not None: + subbox = optforce.force_box(fld) + op = ResOperation(rop.SETFIELD_GC, [op, subbox], + descr=flddescr) + optforce.emit_operation(op) return newop return op + def init_fields(self, descr): + self._fields = [None] * len(descr.all_fielddescrs) + def setfield_virtual(self, descr, op): - if self._fields is None: - self._fields = {} - self._fields[descr] = op + self._fields[descr.index] = op def getfield_virtual(self, descr): - return self._fields.get(descr, None) + return self._fields[descr.index] def is_virtual(self): return self._is_virtual +class InstancePtrInfo(AbstractStructPtrInfo): + _attrs_ = ('_known_class') + _fields = None + + def __init__(self, known_class=None, is_virtual=False): + self._known_class = known_class + self._is_virtual = is_virtual + def get_known_class(self, cpu): return self._known_class diff --git a/rpython/jit/metainterp/optimizeopt/intbounds.py b/rpython/jit/metainterp/optimizeopt/intbounds.py --- a/rpython/jit/metainterp/optimizeopt/intbounds.py +++ b/rpython/jit/metainterp/optimizeopt/intbounds.py @@ -441,12 +441,12 @@ self.propagate_bounds_backward(box2) def make_int_le(self, box1, box2): - v1 = self.getvalue(box1) - v2 = self.getvalue(box2) - if v1.getintbound().make_le(v2.getintbound()): - self.propagate_bounds_backward(box1, v1) - if v2.getintbound().make_ge(v1.getintbound()): - self.propagate_bounds_backward(box2, v2) + b1 = self.getintbound(box1) + b2 = self.getintbound(box2) + if b1.make_le(b2): + self.propagate_bounds_backward(box1) + if b2.make_ge(b1): + self.propagate_bounds_backward(box2) def make_int_gt(self, box1, box2): self.make_int_lt(box2, box1) diff --git a/rpython/jit/metainterp/optimizeopt/test/test_optimizebasic.py b/rpython/jit/metainterp/optimizeopt/test/test_optimizebasic.py --- a/rpython/jit/metainterp/optimizeopt/test/test_optimizebasic.py +++ b/rpython/jit/metainterp/optimizeopt/test/test_optimizebasic.py @@ -199,14 +199,14 @@ def test_remove_guard_class_2(self): ops = """ [i0] - p0 = new_with_vtable(ConstClass(node_vtable)) + p0 = new_with_vtable(ConstClass(node_vtable), descr=nodesize) escape_n(p0) guard_class(p0, ConstClass(node_vtable)) [] jump(i0) """ expected = """ [i0] - p0 = new_with_vtable(ConstClass(node_vtable)) + p0 = new_with_vtable(ConstClass(node_vtable), descr=nodesize) escape_n(p0) jump(i0) """ @@ -426,7 +426,7 @@ def test_ooisnull_oononnull_via_virtual(self): ops = """ [p0] - pv = new_with_vtable(ConstClass(node_vtable)) + pv = new_with_vtable(ConstClass(node_vtable), descr=nodesize) setfield_gc(pv, p0, descr=valuedescr) guard_nonnull(p0) [] p1 = getfield_gc_r(pv, descr=valuedescr) @@ -575,7 +575,7 @@ [i1, p2, p3] i3 = getfield_gc_i(p3, descr=valuedescr) escape_n(i3) - p1 = new_with_vtable(ConstClass(node_vtable)) + p1 = new_with_vtable(ConstClass(node_vtable), descr=nodesize) setfield_gc(p1, i1, descr=valuedescr) jump(i1, p1, p2) """ 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 @@ -524,6 +524,7 @@ def make_virtual(self, known_class, source_op, descr): opinfo = info.InstancePtrInfo(known_class, is_virtual=True) + opinfo.init_fields(descr) source_op.set_forwarded(opinfo) return opinfo @@ -682,8 +683,7 @@ fieldvalue = self.optimizer.new_const(op.getdescr()) self.make_equal_to(op, fieldop) else: - yyyy - value.ensure_nonnull() + self.make_nonnull(op.getarg(0)) self.emit_operation(op) optimize_GETFIELD_GC_R = optimize_GETFIELD_GC_I optimize_GETFIELD_GC_F = optimize_GETFIELD_GC_I diff --git a/rpython/jit/metainterp/resoperation.py b/rpython/jit/metainterp/resoperation.py --- a/rpython/jit/metainterp/resoperation.py +++ b/rpython/jit/metainterp/resoperation.py @@ -719,7 +719,7 @@ 'GETFIELD_RAW/1d/fi', '_MALLOC_FIRST', 'NEW/0d/r', #-> GcStruct, gcptrs inside are zeroed (not the rest) - 'NEW_WITH_VTABLE/1/r',#-> GcStruct with vtable, gcptrs inside are zeroed + 'NEW_WITH_VTABLE/1d/r',#-> GcStruct with vtable, gcptrs inside are zeroed 'NEW_ARRAY/1d/r', #-> GcArray, not zeroed. only for arrays of primitives 'NEW_ARRAY_CLEAR/1d/r',#-> GcArray, fully zeroed 'NEWSTR/1/r', #-> STR, the hash field is zeroed _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit