Author: Maciej Fijalkowski <[email protected]>
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
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit