Author: Maciej Fijalkowski <fij...@gmail.com> Branch: resume-refactor Changeset: r68991:07f41e9e2678 Date: 2014-01-29 14:52 +0100 http://bitbucket.org/pypy/pypy/changeset/07f41e9e2678/
Log: start fighting with strings 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 @@ -44,24 +44,20 @@ return Position(self.numbering[self.mapping(box)]) def process(self, op): - getattr(self, 'process_' + op.getopname())(op) + func = getattr(self, 'process_' + op.getopname(), None) + if func is not None: + func(op) ResumeBuilder.process(self, op) - def process_enter_frame(self, op): - pass - - def process_leave_frame(self, op): - pass - - def process_resume_set_pc(self, op): - pass - - def process_resume_new_with_vtable(self, op): - pass - def process_resume_setfield_gc(self, op): self._add_box_to_numbering(op.getarg(1)) + def process_resume_concatstr(self, op): + self._add_box_to_numbering(op.getarg(0)) + self._add_box_to_numbering(op.getarg(1)) + + process_resume_concatunicode = process_resume_concatstr + def _add_box_to_numbering(self, box): if isinstance(box, Const): return @@ -70,9 +66,6 @@ def process_resume_put(self, op): self._add_box_to_numbering(op.getarg(0)) - - def process_resume_clear(self, op): - pass class LLTrace(object): has_been_freed = False 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 @@ -503,6 +503,7 @@ return vvalue def make_varray(self, arraydescr, size, box, source_op=None): + xxx if arraydescr.is_array_of_structs(): vvalue = VArrayStructValue(arraydescr, size, box, source_op) else: @@ -519,12 +520,14 @@ return vvalue def make_virtual_raw_memory(self, size, box, source_op): + xxx logops = self.optimizer.loop.logops vvalue = VRawBufferValue(self.optimizer.cpu, logops, size, box, source_op) self.make_equal_to(box, vvalue) return vvalue def make_virtual_raw_slice(self, rawbuffer_value, offset, box, source_op): + xxx vvalue = VRawSliceValue(rawbuffer_value, offset, box, source_op) self.make_equal_to(box, vvalue) return vvalue diff --git a/rpython/jit/metainterp/optimizeopt/vstring.py b/rpython/jit/metainterp/optimizeopt/vstring.py --- a/rpython/jit/metainterp/optimizeopt/vstring.py +++ b/rpython/jit/metainterp/optimizeopt/vstring.py @@ -19,6 +19,7 @@ class StrOrUnicode(object): def __init__(self, LLTYPE, hlstr, emptystr, chr, NEWSTR, STRLEN, STRGETITEM, STRSETITEM, COPYSTRCONTENT, + RESUME_NEW, RESUME_CONCAT, OS_offset): self.LLTYPE = LLTYPE self.hlstr = hlstr @@ -29,6 +30,8 @@ self.STRGETITEM = STRGETITEM self.STRSETITEM = STRSETITEM self.COPYSTRCONTENT = COPYSTRCONTENT + self.RESUME_NEW = RESUME_NEW + self.RESUME_CONCAT = RESUME_CONCAT self.OS_offset = OS_offset def _freeze_(self): @@ -36,10 +39,12 @@ mode_string = StrOrUnicode(rstr.STR, annlowlevel.hlstr, '', chr, rop.NEWSTR, rop.STRLEN, rop.STRGETITEM, - rop.STRSETITEM, rop.COPYSTRCONTENT, 0) + rop.STRSETITEM, rop.COPYSTRCONTENT, + rop.RESUME_NEWSTR, rop.RESUME_CONCATSTR, 0) mode_unicode = StrOrUnicode(rstr.UNICODE, annlowlevel.hlunicode, u'', unichr, rop.NEWUNICODE, rop.UNICODELEN, rop.UNICODEGETITEM, rop.UNICODESETITEM, rop.COPYUNICODECONTENT, + rop.RESUME_NEWUNICODE, rop.RESUME_CONCATUNICODE, EffectInfo._OS_offset_uni) # ____________________________________________________________ @@ -390,17 +395,22 @@ def new(self): return OptString() - def make_vstring_plain(self, box, source_op, mode): + def make_vstring_plain(self, box, source_op, mode, length): vvalue = VStringPlainValue(box, source_op, mode) + vvalue.setup(length) + self.optimizer.resumebuilder.new_vstring(vvalue, length, mode) self.make_equal_to(box, vvalue) return vvalue - def make_vstring_concat(self, box, source_op, mode): + def make_vstring_concat(self, box, source_op, mode, left, right): vvalue = VStringConcatValue(box, source_op, mode) + vvalue.setup(left, right) + self.optimizer.resumebuilder.vstring_concat(vvalue, left, right, mode) self.make_equal_to(box, vvalue) return vvalue def make_vstring_slice(self, box, source_op, mode): + xxx vvalue = VStringSliceValue(box, source_op, mode) self.make_equal_to(box, vvalue) return vvalue @@ -417,8 +427,8 @@ # build a new one with the ConstInt argument if not isinstance(op.getarg(0), ConstInt): op = ResOperation(mode.NEWSTR, [length_box], op.result) - vvalue = self.make_vstring_plain(op.result, op, mode) - vvalue.setup(length_box.getint()) + self.make_vstring_plain(op.result, op, mode, + length_box.getint()) else: self.getvalue(op.result).ensure_nonnull() self.emit_operation(op) @@ -430,7 +440,10 @@ if value.is_virtual() and isinstance(value, VStringPlainValue): indexbox = self.get_constant_box(op.getarg(1)) if indexbox is not None: - value.setitem(indexbox.getint(), self.getvalue(op.getarg(2))) + index = indexbox.getint() + varg = self.getvalue(op.getarg(2)) + value.setitem(index, varg) + self.optimizer.resumebuilder.strsetitem(value, varg) return value.ensure_nonnull() self.emit_operation(op) @@ -592,8 +605,7 @@ vright = self.getvalue(op.getarg(2)) vleft.ensure_nonnull() vright.ensure_nonnull() - value = self.make_vstring_concat(op.result, op, mode) - value.setup(vleft, vright) + self.make_vstring_concat(op.result, op, mode, vleft, vright) return True def opt_call_stroruni_STR_SLICE(self, op, mode): 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 @@ -480,6 +480,9 @@ 'RESUME_NEW_ARRAY/1d', 'RESUME_NEWSTR/1', 'RESUME_NEWUNICODE/1', + 'RESUME_CONCATSTR/2', + 'RESUME_CONCATUNICODE/2', + 'RESUME_STRSETITEM/2', 'RESUME_SETFIELD_GC/2d', 'RESUME_SET_PC/1', 'RESUME_CLEAR/2', diff --git a/rpython/jit/resume/backend.py b/rpython/jit/resume/backend.py --- a/rpython/jit/resume/backend.py +++ b/rpython/jit/resume/backend.py @@ -1,10 +1,31 @@ from rpython.jit.metainterp.resoperation import rop -from rpython.jit.metainterp.history import Box, Const +from rpython.jit.metainterp.history import Box, Const, AbstractDescr from rpython.jit.resume.rescode import ResumeBytecodeBuilder, TAGBOX,\ ResumeBytecode, TAGVIRTUAL from rpython.jit.codewriter.jitcode import JitCode +class DescrForStr(AbstractDescr): + pass + +left_descr = DescrForStr() +right_descr = DescrForStr() + +class BaseDeps(object): + pass + +class DepsFields(BaseDeps): + def __init__(self): + self.fields = {} + +class DepsConcat(BaseDeps): + def __init__(self, left, right): + self.left = left + self.right = right + +class DepsArray(BaseDeps): + def __init__(self, size): + self.l = [None] * size class LivenessAnalyzer(object): def __init__(self): @@ -26,13 +47,22 @@ self.framestack[framepos][frontend_pos] = None def resume_new(self, result, descr): - self.deps[result] = {} + self.deps[result] = DepsFields() + + def resume_newunicode(self, result, length): + self.deps[result] = DepsArray(length) + + def resume_concatunicode(self, result, left, right): + self.deps[result] = DepsConcat(left, right) def resume_new_with_vtable(self, result, klass): - self.deps[result] = {} + self.deps[result] = DepsFields() def resume_setfield_gc(self, arg0, arg1, descr): - self.deps[arg0][descr] = arg1 + self.deps[arg0].fields[descr] = arg1 + + def resume_strsetitem(self, arg0, arg1): + xxx def resume_set_pc(self, pc): pass @@ -64,6 +94,16 @@ elif op.getopnum() == rop.RESUME_CLEAR: self.resume_clear(op.getarg(0).getint(), op.getarg(1).getint()) + elif op.getopnum() == rop.RESUME_NEWSTR: + xxx + elif op.getopnum() == rop.RESUME_NEWUNICODE: + self.resume_newunicode(op.result, op.getarg(0).getint()) + elif op.getopnum() == rop.RESUME_CONCATSTR: + xxx + elif op.getopnum() == rop.RESUME_CONCATUNICODE: + self.resume_concatunicode(op.result, op.getarg(0), op.getarg(1)) + elif op.getopnum() == rop.RESUME_STRSETITEM: + self.resume_strsetitem(op.getarg(0), op.getarg(1)) elif not op.is_resume(): pos += 1 continue @@ -150,6 +190,20 @@ elif op.getopnum() == rop.RESUME_CLEAR: self.builder.resume_clear(op.getarg(0).getint(), op.getarg(1).getint()) + elif op.getopnum() == rop.RESUME_NEWSTR: + xxx + elif op.getopnum() == rop.RESUME_NEWUNICODE: + v_pos = len(self.virtuals) + self.virtuals[op.result] = v_pos + self.builder.resume_newunicode(v_pos, op.getarg(0).getint()) + elif op.getopnum() == rop.RESUME_CONCATSTR: + xxx + elif op.getopnum() == rop.RESUME_CONCATUNICODE: + v_pos = len(self.virtuals) + self.virtuals[op.result] = v_pos + leftpos = self.get_box_pos(op.getarg(0)) + rightpos = self.get_box_pos(op.getarg(0)) + self.builder.resume_concatunicode(v_pos, leftpos, rightpos) else: raise Exception("strange operation") diff --git a/rpython/jit/resume/frontend.py b/rpython/jit/resume/frontend.py --- a/rpython/jit/resume/frontend.py +++ b/rpython/jit/resume/frontend.py @@ -76,11 +76,9 @@ return self.virtuals_cache[index] except KeyError: pass - val = self.virtuals[index].allocate_direct(self.cpu) + val = self.virtuals[index].allocate_direct(self, self.cpu) self.virtuals_cache[index] = val - fields = self.virtuals[index].fields - for fielddescr, encoded_field_pos in fields.iteritems(): - self.setfield_gc(val, encoded_field_pos, fielddescr) + self.virtuals[index].populate_fields(val, self) return val def setfield_gc(self, struct, encoded_field_pos, fielddescr): diff --git a/rpython/jit/resume/optimizer.py b/rpython/jit/resume/optimizer.py --- a/rpython/jit/resume/optimizer.py +++ b/rpython/jit/resume/optimizer.py @@ -51,10 +51,6 @@ else: self.opt.emit_operation(op) - def new_virtual(self, box): - xxx - self.optimizer.emit_operation(rop.RESUME_NEW) - def new_virtual_with_vtable(self, box, vtable, vvalue): virtualbox = BoxPtr() op = ResOperation(rop.RESUME_NEW_WITH_VTABLE, [vtable], virtualbox) @@ -67,6 +63,26 @@ op = ResOperation(rop.RESUME_NEW, [], newbox, descr=structdescr) self.opt._newoperations.append(op) + def new_vstring(self, vstring, lgt, mode): + newbox = BoxPtr() + vstring.resume_box = newbox + op = ResOperation(mode.RESUME_NEW, [ConstInt(lgt)], newbox) + self.opt._newoperations.append(op) + + def vstring_concat(self, vstring, left, right, mode): + leftbox = left.get_resume_box() + rightbox = right.get_resume_box() + newbox = BoxPtr() + vstring.resume_box = newbox + op = ResOperation(mode.RESUME_CONCAT, [leftbox, rightbox], newbox) + self.opt._newoperations.append(op) + + def strsetitem(self, vstring, varg): + argbox = varg.get_resume_box() + op = ResOperation(rop.RESUME_STRSETITEM, [vstring.get_resume_box(), + argbox], None) + self.opt._newoperations.append(op) + def setfield(self, box, fieldbox, descr): op = ResOperation(rop.RESUME_SETFIELD_GC, [box, fieldbox], None, descr=descr) diff --git a/rpython/jit/resume/reader.py b/rpython/jit/resume/reader.py --- a/rpython/jit/resume/reader.py +++ b/rpython/jit/resume/reader.py @@ -1,4 +1,7 @@ +from rpython.rtyper.lltypesystem import lltype, rstr, llmemory + +from rpython.jit.codewriter.effectinfo import EffectInfo from rpython.jit.metainterp.resoperation import rop from rpython.jit.metainterp.history import ConstInt from rpython.jit.codewriter import heaptracker @@ -11,9 +14,16 @@ self.pc = -1 class BaseVirtual(object): - pass + def populate_fields(self, reader): + pass -class VirtualStruct(BaseVirtual): +class BaseVirtualStruct(BaseVirtual): + def populate_fields(self, val, reader): + fields = self.fields + for fielddescr, encoded_field_pos in fields.iteritems(): + reader.setfield_gc(val, encoded_field_pos, fielddescr) + +class VirtualStruct(BaseVirtualStruct): def __init__(self, pos, descr): self.pos = pos self.fields = {} @@ -22,10 +32,10 @@ def allocate_box(self, metainterp): return metainterp.execute_and_record(rop.NEW, self.descr) - def allocate_direct(self, cpu): + def allocate_direct(self, reader, cpu): return cpu.bh_new(self.descr) -class VirtualWithVtable(BaseVirtual): +class VirtualWithVtable(BaseVirtualStruct): def __init__(self, pos, const_class): self.pos = pos self.const_class = const_class @@ -35,10 +45,37 @@ return metainterp.execute_and_record(rop.NEW_WITH_VTABLE, None, ConstInt(self.const_class)) - def allocate_direct(self, cpu): + def allocate_direct(self, reader, cpu): descr = heaptracker.vtable2descr(cpu, self.const_class) return cpu.bh_new_with_vtable(self.const_class, descr) +class VirtualStr(BaseVirtual): + def __init__(self, pos, lgt, mode): + self.pos = pos + self.lgt = lgt + self.mode = mode + +class VirtualConcat(BaseVirtual): + def __init__(self, pos, left, right, mode): + self.pos = pos + self.left = left + self.right = right + self.mode = mode + + def allocate_direct(self, reader, cpu): + leftval = reader.getref(self.left) + rightval = reader.getref(self.right) + cic = reader.staticdata.callinfocollection + if self.mode == 'u': + funcptr = cic.funcptr_for_oopspec(EffectInfo.OS_UNI_CONCAT) + str1 = lltype.cast_opaque_ptr(lltype.Ptr(rstr.UNICODE), leftval) + str2 = lltype.cast_opaque_ptr(lltype.Ptr(rstr.UNICODE), rightval) + result = funcptr(str1, str2) + return lltype.cast_opaque_ptr(llmemory.GCREF, result) + else: + xxx + xxx + class AbstractResumeReader(object): """ A resume reader that can follow resume until given point. Consult the concrete classes for details @@ -73,6 +110,22 @@ v = VirtualStruct(v_pos, descr) self._add_to_virtuals(v, v_pos) + def resume_newstr(self, v_pos, lgt): + v = VirtualStr(v_pos, lgt, 's') + self._add_to_virtuals(v, v_pos) + + def resume_newunicode(self, v_pos, lgt): + v = VirtualStr(v_pos, lgt, 'u') + self._add_to_virtuals(v, v_pos) + + def resume_concatstr(self, v_pos, leftpos, rightpos): + v = VirtualConcat(v_pos, leftpos, rightpos, 's') + self._add_to_virtuals(v, v_pos) + + def resume_concatunicode(self, v_pos, leftpos, rightpos): + v = VirtualConcat(v_pos, leftpos, rightpos, 'u') + self._add_to_virtuals(v, v_pos) + def resume_new_with_vtable(self, v_pos, c_const_class): const_class = c_const_class.getint() v = VirtualWithVtable(v_pos, const_class) @@ -153,6 +206,21 @@ pc = self.read_short(pos + 1) self.resume_set_pc(pc) pos += 3 + elif op == rescode.RESUME_NEWSTR: + xxx + elif op == rescode.RESUME_NEWUNICODE: + v_pos = self.read_short(pos + 1) + lgt = self.read(pos + 3) + self.resume_newunicode(v_pos, lgt) + pos += 4 + elif op == rescode.RESUME_CONCATSTR: + xxx + elif op == rescode.RESUME_CONCATUNICODE: + v_pos = self.read_short(pos + 1) + left = self.read_short(pos + 3) + right = self.read_short(pos + 5) + self.resume_concatunicode(v_pos, left, right) + pos += 7 else: xxx self.bytecode = None @@ -179,6 +247,18 @@ def resume_clear(self, frame_pos, pos_in_frame): self.l.append("resume_clear %d %d" % (frame_pos, pos_in_frame)) + def resume_newstr(self, v_pos, lgt): + xxx + + def resume_newunicode(self, v_pos, lgt): + xxx + + def resume_concatstr(self, v_pos, leftpos, rightpos): + xxx + + def resume_concatunicode(self, v_pos, leftpos, rightpos): + xxx + def resume_new_with_vtable(self, v_pos, c_const_class): self.l.append("%d = resume_new_with_vtable %d" % (v_pos, c_const_class.getint())) diff --git a/rpython/jit/resume/rescode.py b/rpython/jit/resume/rescode.py --- a/rpython/jit/resume/rescode.py +++ b/rpython/jit/resume/rescode.py @@ -4,7 +4,8 @@ (UNUSED, ENTER_FRAME, LEAVE_FRAME, RESUME_PUT, RESUME_NEW, RESUME_NEW_WITH_VTABLE, RESUME_SETFIELD_GC, - RESUME_SET_PC, RESUME_CLEAR) = range(9) + RESUME_SET_PC, RESUME_CLEAR, RESUME_NEWSTR, RESUME_NEWUNICODE, + RESUME_CONCATSTR, RESUME_CONCATUNICODE) = range(13) TAGCONST = 0x0 TAGVIRTUAL = 0x2 @@ -88,6 +89,17 @@ self.write_short(v_pos) # XXX byte virtuals? self.write_short(descr.global_descr_index) + def resume_newunicode(self, v_pos, lgt): + self.write(RESUME_NEWUNICODE) + self.write_short(v_pos) # XXX byte virtuals? + self.write(lgt) + + def resume_concatunicode(self, v_pos, leftpos, rightpos): + self.write(RESUME_CONCATUNICODE) + self.write_short(v_pos) + self.write_short(leftpos) + self.write_short(rightpos) + def resume_new_with_vtable(self, v_pos, const_class): self.write(RESUME_NEW_WITH_VTABLE) self.write_short(v_pos) # XXX byte virtuals? diff --git a/rpython/jit/resume/test/test_frontend.py b/rpython/jit/resume/test/test_frontend.py --- a/rpython/jit/resume/test/test_frontend.py +++ b/rpython/jit/resume/test/test_frontend.py @@ -2,7 +2,7 @@ from rpython.jit.tool.oparser import parse from rpython.jit.codewriter.jitcode import JitCode from rpython.jit.metainterp.history import AbstractDescr, Const, INT, Stats,\ - ConstInt, REF + ConstInt, REF, FLOAT from rpython.jit.resume.frontend import rebuild_from_resumedata,\ blackhole_from_resumedata from rpython.jit.resume.rescode import ResumeBytecode, TAGBOX,\ @@ -30,6 +30,9 @@ def is_field_signed(self): return self.kind == INT + def is_float_field(self): + return self.kind == FLOAT + class MockLoop(object): pass @@ -251,12 +254,12 @@ rebuild_from_resumedata(metainterp, "myframe", descr) expected = [(rop.NEW, descr), (rop.SETFIELD_GC, d2, AnyBox(), EqConstInt(1)), - (rop.NEW_WITH_VTABLE, EqConstInt(cls_as_int)), + (rop.NEW_WITH_VTABLE, None, EqConstInt(cls_as_int)), (rop.SETFIELD_GC, d3, AnyBox(), AnyBox()), (rop.RESUME_PUT, None, AnyBox(), EqConstInt(0), EqConstInt(0))] expected2 = [(rop.NEW, descr), - (rop.NEW_WITH_VTABLE, EqConstInt(cls_as_int)), + (rop.NEW_WITH_VTABLE, None, EqConstInt(cls_as_int)), (rop.SETFIELD_GC, d3, AnyBox(), AnyBox()), (rop.SETFIELD_GC, d2, AnyBox(), EqConstInt(1)), (rop.RESUME_PUT, None, AnyBox(), EqConstInt(0), _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit