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