Author: Maciej Fijalkowski <[email protected]>
Branch: resume-refactor
Changeset: r68706:af3f1d0b6333
Date: 2014-01-16 17:35 +0100
http://bitbucket.org/pypy/pypy/changeset/af3f1d0b6333/

Log:    Some rewrite in progress in order to support new a bit everywhere.
        More rewrite in the pipeline ;-)

diff --git a/TODO b/TODO
--- a/TODO
+++ b/TODO
@@ -1,3 +1,9 @@
 
 * kill resumedescr.guard_opnum and replace by classes
 
+* in resume2.py, stuff stored on self.virtuals is inefficient
+
+* compress the resumedata in the backend
+
+* do escape analysis in the resumeopt.py
+
diff --git a/rpython/jit/backend/resumebuilder.py 
b/rpython/jit/backend/resumebuilder.py
--- a/rpython/jit/backend/resumebuilder.py
+++ b/rpython/jit/backend/resumebuilder.py
@@ -26,9 +26,6 @@
     def resume_clear(self, framepos, frontend_pos):
         self.framestack[framepos][frontend_pos] = None
 
-    def resume_put_const(self, box, framepos, frontend_pos):
-        xxx
-
     def resume_new(self, result, descr):
         self.deps[result] = {}
 
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
@@ -473,7 +473,6 @@
     'RESUME_PUT/3', # arguments are as follows - box or position in the 
backend,
                     # the frame index (counting from top) and position in the
                     # frontend
-    'RESUME_PUT_CONST/3', # the same but for a constant
     'RESUME_NEW/0d',
     'RESUME_NEW_WITH_VTABLE/1',
     'RESUME_NEW_ARRAY/1d',
diff --git a/rpython/jit/metainterp/resume2.py 
b/rpython/jit/metainterp/resume2.py
--- a/rpython/jit/metainterp/resume2.py
+++ b/rpython/jit/metainterp/resume2.py
@@ -1,6 +1,8 @@
 
+import sys
 from rpython.jit.metainterp.resoperation import rop
-from rpython.jit.metainterp.history import BoxInt, BoxPtr, BoxFloat, ConstInt
+from rpython.jit.metainterp.history import BoxInt, BoxPtr, BoxFloat, ConstInt,\
+     Box, INT, REF, FLOAT
 from rpython.jit.metainterp import history
 from rpython.jit.codewriter.jitcode import JitCode
 from rpython.rlib import rstack
@@ -17,7 +19,21 @@
         self.registers = [-1] * jitcode.num_regs()
         self.jitcode = jitcode
         self.pc = -1
-        
+
+TAGCONST = 0x0
+TAGVIRTUAL = 0x2
+TAGBOX = 0x3
+TAGSMALLINT = 0x1
+
+TAGOFFSET = 2
+
+class Virtual(object):
+    def __init__(self, pos, descr):
+        self.pos = pos
+        self.fields = {}
+        self.descr = descr
+
+
 class AbstractResumeReader(object):
     """ A resume reader that can follow resume until given point. Consult
     the concrete classes for details
@@ -26,6 +42,8 @@
     def __init__(self):
         self.framestack = []
         self.consts = [] # XXX cache?
+        self.virtuals = {}
+        self.virtual_list = []
 
     def rebuild(self, faildescr):
         self._rebuild_until(faildescr.rd_resume_bytecode,
@@ -41,16 +59,47 @@
             self.framestack[-1].pc = pc
         self.framestack.append(ResumeFrame(jitcode))
 
-    def resume_put(self, jitframe_pos_const, frame_no, frontend_position):
-        jitframe_pos = jitframe_pos_const.getint()
+    def encode_box(self, pos):
+        return TAGBOX | (pos << TAGOFFSET)
+
+    def encode_virtual(self, box):
+        return TAGVIRTUAL | (self.virtuals[box].pos << TAGOFFSET)
+
+    def encode_const(self, const):
+        if isinstance(const, ConstInt) and const.getint() < (sys.maxint >> 3):
+            return TAGSMALLINT | (const.getint() << TAGOFFSET)
+        self.consts.append(const)
+        return TAGCONST | ((len(self.consts) - 1) << TAGOFFSET)
+
+    def decode(self, pos):
+        return pos & 0x3, pos >> TAGOFFSET
+
+    def resume_put(self, jitframe_pos_box, frame_no, frontend_position):
+        if isinstance(jitframe_pos_box, Box):
+            jitframe_pos = self.encode_virtual(jitframe_pos_box)
+        else:
+            jitframe_pos = self.encode_box(jitframe_pos_box.getint())
         self.framestack[frame_no].registers[frontend_position] = jitframe_pos
 
+    def encode(self, box):
+        xxx
+
+    def resume_new(self, box, descr):
+        # XXX make it a list
+        v = Virtual(len(self.virtual_list), descr)
+        self.virtuals[box] = v
+        self.virtual_list.append(v)
+
+    def resume_setfield_gc(self, box, fieldbox, descr):
+        # XXX optimize fields
+        self.virtuals[box].fields[descr] = self.encode(fieldbox)
+
     def resume_clear(self, frame_no, frontend_position):
         self.framestack[frame_no].registers[frontend_position] = -1
 
     def resume_put_const(self, const, frame_no, frontend_position):
-        self.framestack[frame_no].registers[frontend_position] = - 2 - 
len(self.consts)
-        self.consts.append(const)
+        pos = self.encode_const(const)
+        self.framestack[frame_no].registers[frontend_position] = pos
 
     def resume_set_pc(self, pc):
         self.framestack[-1].pc = pc
@@ -160,21 +209,54 @@
         self.deadframe = deadframe
         AbstractResumeReader.__init__(self)
 
+    def get_box_value(self, encoded_pos, TP):
+        if encoded_pos == -1:
+            return None
+        if encoded_pos in self.cache:
+            return self.cache[encoded_pos]
+        tag, pos = self.decode(encoded_pos)
+        if tag == TAGBOX:
+            if TP == INT:
+                val = self.metainterp.cpu.get_int_value(self.deadframe, pos)
+                res = BoxInt(val)
+            else:
+                xxx
+            self.cache[encoded_pos] = res
+            return res
+        elif tag == TAGSMALLINT:
+            return ConstInt(pos)
+        elif tag == TAGCONST:
+            return self.consts[pos]
+        else:
+            assert tag == TAGVIRTUAL
+            virtual = self.virtual_list[pos]
+            virtual_box = self.allocate_struct(virtual)
+            for fielddescr, encoded_field_pos in virtual.fields.iteritems():
+                self.setfield(virtual, fielddescr, encoded_field_pos)
+            self.cache[encoded_pos] = virtual_box
+            return virtual_box
+
+    def allocate_struct(self, virtual):
+        return self.metainterp.execute_and_record(rop.NEW, virtual.descr)
+
+    def setfield(self, virtual, fielddescr, encoded_field_pos):
+        xxx
+
     def store_int_box(self, res, pos, miframe, i, jitframe_pos):
-        if jitframe_pos in self.cache:
-            box = self.cache[jitframe_pos]
-        elif jitframe_pos == -1:
+        box = self.get_box_value(jitframe_pos, INT)
+        if box is None:
             return
-        elif jitframe_pos >= 0:
-            box = BoxInt(self.metainterp.cpu.get_int_value(self.deadframe,
-                                                           jitframe_pos))
-        elif jitframe_pos <= -2:
-            box = self.consts[-jitframe_pos - 2]
         miframe.registers_i[i] = box
-        self.cache[jitframe_pos] = box
         res[-1][pos] = box
 
     def store_ref_box(self, res, pos, miframe, i, jitframe_pos):
+        box = self.get_box_value(jitframe_pos, REF)
+        if box is None:
+            return
+        miframe.registers_r[i] = box
+        res[-1][pos] = box
+        return
+        xxx
         if jitframe_pos in self.cache:
             box = self.cache[jitframe_pos]
         elif jitframe_pos == -1:
@@ -189,6 +271,10 @@
         res[-1][pos] = box
 
     def store_float_box(self, res, pos, miframe, i, jitframe_pos):
+        box = self.get_box_value(jitframe_pos)
+        if box is None:
+            return
+        xxx
         if jitframe_pos in self.cache:
             box = self.cache[jitframe_pos]
         elif jitframe_pos == -1:
diff --git a/rpython/jit/metainterp/test/test_resume2.py 
b/rpython/jit/metainterp/test/test_resume2.py
--- a/rpython/jit/metainterp/test/test_resume2.py
+++ b/rpython/jit/metainterp/test/test_resume2.py
@@ -5,6 +5,7 @@
 from rpython.jit.metainterp.history import AbstractDescr, Const, INT, Stats
 from rpython.jit.metainterp.resume2 import rebuild_from_resumedata,\
      ResumeBytecode, AbstractResumeReader
+from rpython.jit.metainterp.resoperation import rop
 from rpython.jit.codewriter.format import unformat_assembler
 from rpython.jit.codewriter.codewriter import CodeWriter
 from rpython.jit.backend.llgraph.runner import LLGraphCPU
@@ -37,10 +38,19 @@
         lst += [backend_values[x] for x in self.registers_r]
         lst += [backend_values[x] for x in self.registers_f]
 
+class AnyBox(object):
+    def __eq__(self, other):
+        return True
+        
 class MockMetaInterp(object):
     def __init__(self):
         self.cpu = MockCPU()
         self.framestack = []
+        self.history = []
+
+    def execute_and_record(self, *args):
+        self.history.append(args)
+        return AnyBox()
 
     def newframe(self, jitcode, record_resume=False):
         f = Frame(jitcode)
@@ -157,16 +167,23 @@
 
     def test_new(self):
         jitcode1 = JitCode("jitcode")
-        jitcode1.setup(num_regs_i=1, num_regs_r=0, num_regs_f=0)
+        jitcode1.setup(num_regs_i=0, num_regs_r=1, num_regs_f=0)
         base = parse("""
         []
         enter_frame(-1, descr=jitcode)
-        i0 = new(descr=structdescr)
-        resume_setfield(i0, 13, descr=fielddescr)
-        backend_put(12,
+        p0 = resume_new()
+        resume_setfield_gc(p0, 13)
+        resume_put(p0, 0, 0)
         leave_frame()
         """, namespace={'jitcode':jitcode1})
-        XXX
+        descr = Descr()
+        descr.rd_resume_bytecode = ResumeBytecode(base.operations)
+        descr.rd_bytecode_position = 4
+        metainterp = MockMetaInterp()
+        metainterp.cpu = MockCPU()
+        rebuild_from_resumedata(metainterp, "myframe", descr)
+        assert metainterp.history == [(rop.NEW, None),
+                                      (rop.SETFIELD_GC, None, AnyBox())]
 
     def test_reconstructing_resume_reader(self):
         jitcode1 = JitCode("jitcode")
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to