Author: Maciej Fijalkowski <fij...@gmail.com> Branch: resume-refactor Changeset: r68992:f87bcc7fdc34 Date: 2014-01-29 15:27 +0100 http://bitbucket.org/pypy/pypy/changeset/f87bcc7fdc34/
Log: more string support 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 @@ -18,15 +18,28 @@ def __init__(self): self.fields = {} + def foreach(self, callback, arg): + for v in self.fields.itervalues(): + callback(arg, v) + class DepsConcat(BaseDeps): def __init__(self, left, right): self.left = left self.right = right + def foreach(self, callback, arg): + callback(arg, self.left) + callback(arg, self.right) + class DepsArray(BaseDeps): def __init__(self, size): self.l = [None] * size + def foreach(self, callback, arg): + for item in self.l: + if item is not None: + callback(arg, item) + class LivenessAnalyzer(object): def __init__(self): self.liveness = {} @@ -113,8 +126,7 @@ def _track(self, allboxes, box): if box in self.deps: - for dep in self.deps[box].values(): - self._track(allboxes, dep) + self.deps[box].foreach(self._track, allboxes) if not isinstance(box, Const) and box is not None: allboxes.append(box) 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 @@ -81,6 +81,12 @@ self.virtuals[index].populate_fields(val, self) return val + def strsetitem(self, str, index, char, mode): + if mode == 's': + self.cpu.bh_strsetitem(str, index, char) + else: + self.cpu.bh_unicodesetitem(str, index, char) + def setfield_gc(self, struct, encoded_field_pos, fielddescr): if fielddescr.is_field_signed(): intval = self.getint(encoded_field_pos) @@ -142,8 +148,7 @@ virtual = self.virtuals[pos] virtual_box = virtual.allocate_box(self.metainterp) self.cache[encoded_pos] = virtual_box - for fielddescr, encoded_field_pos in virtual.fields.iteritems(): - self.setfield_gc(virtual_box, encoded_field_pos, fielddescr) + virtual.populate_fields_boxes(virtual_box, self) if pos_in_frame != -1: self.metainterp.history.record(rop.RESUME_PUT, [virtual_box, @@ -167,6 +172,13 @@ self.metainterp.execute_and_record(rop.SETFIELD_GC, fielddescr, box, field_box) + def strsetitem(self, box, ibox, vbox, mode): + if mode == 's': + resop = rop.STRSETITEM + else: + resop = rop.UNICODESETITEM + self.metainterp.execute_and_record(resop, None, box, ibox, vbox) + def store_int_box(self, frame_pos, pos, miframe, i, jitframe_pos): box = self.get_box_value(frame_pos, pos, jitframe_pos, INT) if box is None: 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 @@ -3,7 +3,7 @@ from rpython.jit.codewriter.effectinfo import EffectInfo from rpython.jit.metainterp.resoperation import rop -from rpython.jit.metainterp.history import ConstInt +from rpython.jit.metainterp.history import ConstInt, INT from rpython.jit.codewriter import heaptracker from rpython.jit.resume import rescode @@ -23,6 +23,10 @@ for fielddescr, encoded_field_pos in fields.iteritems(): reader.setfield_gc(val, encoded_field_pos, fielddescr) + def populate_fields_boxes(self, box, reader): + for fielddescr, encoded_field_pos in self.fields.iteritems(): + reader.setfield_gc(box, encoded_field_pos, fielddescr) + class VirtualStruct(BaseVirtualStruct): def __init__(self, pos, descr): self.pos = pos @@ -54,6 +58,33 @@ self.pos = pos self.lgt = lgt self.mode = mode + self.chars = [-1] * lgt + + def populate_fields_boxes(self, box, reader): + for i in range(len(self.chars)): + ch = self.chars[i] + if ch != -1: + vbox = reader.get_box_value(-1, -1, ch, INT) + reader.strsetitem(box, ConstInt(i), vbox, self.mode) + + def populate_fields(self, val, reader): + for i in range(len(self.chars)): + ch = self.chars[i] + if ch != -1: + itemval = reader.getint(ch) + reader.strsetitem(val, i, itemval, self.mode) + + def allocate_box(self, metainterp): + if self.mode == 's': + resop = rop.NEWSTR + else: + resop = rop.NEWUNICODE + return metainterp.execute_and_record(resop, [ConstInt(self.lgt)]) + + def allocate_direct(self, reader, cpu): + if self.mode == 's': + return cpu.bh_newstr(self.lgt) + return cpu.bh_newunicode(self.lgt) class VirtualConcat(BaseVirtual): def __init__(self, pos, left, right, mode): @@ -62,6 +93,12 @@ self.right = right self.mode = mode + def populate_fields_boxes(self, box, reader): + pass + + def populate_fields(self, val, reader): + pass + def allocate_direct(self, reader, cpu): leftval = reader.getref(self.left) rightval = reader.getref(self.right) @@ -74,7 +111,6 @@ 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 @@ -126,6 +162,11 @@ v = VirtualConcat(v_pos, leftpos, rightpos, 'u') self._add_to_virtuals(v, v_pos) + def resume_strsetitem(self, v_pos, index, sourcepos): + v = self.virtuals[v_pos] + assert isinstance(v, VirtualStr) + v.chars[index] = sourcepos + def resume_new_with_vtable(self, v_pos, c_const_class): const_class = c_const_class.getint() v = VirtualWithVtable(v_pos, const_class) @@ -207,7 +248,10 @@ self.resume_set_pc(pc) pos += 3 elif op == rescode.RESUME_NEWSTR: - xxx + v_pos = self.read_short(pos + 1) + lgt = self.read(pos + 3) + self.resume_newstr(v_pos, lgt) + pos += 4 elif op == rescode.RESUME_NEWUNICODE: v_pos = self.read_short(pos + 1) lgt = self.read(pos + 3) @@ -221,6 +265,12 @@ right = self.read_short(pos + 5) self.resume_concatunicode(v_pos, left, right) pos += 7 + elif op == rescode.RESUME_STRSETITEM: + v_pos = self.read_short(pos + 1) + index = self.read(pos + 3) + source = self.read(pos + 4) + self.resume_strsetitem(v_pos, index, source) + pos += 6 else: xxx self.bytecode = None 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 @@ -5,7 +5,7 @@ (UNUSED, ENTER_FRAME, LEAVE_FRAME, RESUME_PUT, RESUME_NEW, RESUME_NEW_WITH_VTABLE, RESUME_SETFIELD_GC, RESUME_SET_PC, RESUME_CLEAR, RESUME_NEWSTR, RESUME_NEWUNICODE, - RESUME_CONCATSTR, RESUME_CONCATUNICODE) = range(13) + RESUME_CONCATSTR, RESUME_CONCATUNICODE, RESUME_STRSETITEM) = range(14) TAGCONST = 0x0 TAGVIRTUAL = 0x2 @@ -89,6 +89,17 @@ self.write_short(v_pos) # XXX byte virtuals? self.write_short(descr.global_descr_index) + def resume_newstr(self, v_pos, lgt): + self.write(RESUME_NEWSTR) + self.write_short(v_pos) # XXX byte virtuals? + self.write(lgt) + + def resume_strsetitem(self, v_pos, index, encoded_source): + self.write(RESUME_STRSETITEM) + self.write_short(v_pos) # XXX byte virtuals? + self.write(index) + self.write_short(encoded_source) + def resume_newunicode(self, v_pos, lgt): self.write(RESUME_NEWUNICODE) 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 @@ -93,6 +93,14 @@ self.history.append(("new", descr)) return "new" + def bh_newstr(self, lgt): + self.history.append(("newstr", lgt)) + return "newstr" + + def bh_strsetitem(self, val, i, char): + assert val == "newstr" + self.history.append(("strsetitem", i, char)) + def bh_setfield_gc_i(self, struct, intval, fielddescr): self.history.append(("setfield_gc_i", struct, intval, fielddescr)) @@ -284,6 +292,43 @@ assert hist == dir_expected or hist == dir_expected2 assert ib.interp.registers_r[0] == "new" + def test_newstr_unicode(self): + jitcode1 = JitCode("jitcode") + jitcode1.global_index = 0 + jitcode1.setup(num_regs_i=0, num_regs_r=1, num_regs_f=0) + builder = ResumeBytecodeBuilder() + builder.enter_frame(-1, jitcode1) + builder.resume_newstr(0, 5) + builder.resume_strsetitem(0, 0, TAGBOX | (13 << 2)) + builder.resume_put(TAGVIRTUAL | (0 << 2), 0, 0) + + metainterp = MockMetaInterp() + metainterp.staticdata = MockStaticData([jitcode1], []) + metainterp.cpu = MockCPU() + metainterp.staticdata.cpu = metainterp.cpu + rd = builder.build() + descr = Descr() + descr.rd_resume_bytecode = ResumeBytecode(rd, []) + descr.rd_bytecode_position = len(rd) + + rebuild_from_resumedata(metainterp, "myframe", descr) + expected = [ + (rop.NEWSTR, [EqConstInt(5)]), + (rop.STRSETITEM, None, AnyBox(), EqConstInt(0), AnyBox()), + (rop.RESUME_PUT, None, AnyBox(), EqConstInt(0), EqConstInt(0)), + ] + assert expected == metainterp.history + ib = FakeInterpBuilder() + blackhole_from_resumedata(ib, metainterp.staticdata, + descr, "myframe") + hist = metainterp.cpu.history + dir_expected = [ + ("newstr", 5), + ("strsetitem", 0, 16) + ] + assert hist == dir_expected + assert ib.interp.registers_r[0] == "newstr" + def test_reconstructing_resume_reader(self): jitcode1 = JitCode("jitcode") jitcode1.global_index = 0 _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit