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

Reply via email to