[pypy-commit] pypy resume-refactor: start fighting with strings
fijal
noreply at buildbot.pypy.org
Wed Jan 29 16:13:57 CET 2014
Author: Maciej Fijalkowski <fijall at gmail.com>
Branch: resume-refactor
Changeset: r68991:07f41e9e2678
Date: 2014-01-29 14:52 +0100
http://bitbucket.org/pypy/pypy/changeset/07f41e9e2678/
Log: start fighting with strings
diff --git a/rpython/jit/backend/llgraph/runner.py b/rpython/jit/backend/llgraph/runner.py
--- a/rpython/jit/backend/llgraph/runner.py
+++ b/rpython/jit/backend/llgraph/runner.py
@@ -44,24 +44,20 @@
return Position(self.numbering[self.mapping(box)])
def process(self, op):
- getattr(self, 'process_' + op.getopname())(op)
+ func = getattr(self, 'process_' + op.getopname(), None)
+ if func is not None:
+ func(op)
ResumeBuilder.process(self, op)
- def process_enter_frame(self, op):
- pass
-
- def process_leave_frame(self, op):
- pass
-
- def process_resume_set_pc(self, op):
- pass
-
- def process_resume_new_with_vtable(self, op):
- pass
-
def process_resume_setfield_gc(self, op):
self._add_box_to_numbering(op.getarg(1))
+ def process_resume_concatstr(self, op):
+ self._add_box_to_numbering(op.getarg(0))
+ self._add_box_to_numbering(op.getarg(1))
+
+ process_resume_concatunicode = process_resume_concatstr
+
def _add_box_to_numbering(self, box):
if isinstance(box, Const):
return
@@ -70,9 +66,6 @@
def process_resume_put(self, op):
self._add_box_to_numbering(op.getarg(0))
-
- def process_resume_clear(self, op):
- pass
class LLTrace(object):
has_been_freed = False
diff --git a/rpython/jit/metainterp/optimizeopt/virtualize.py b/rpython/jit/metainterp/optimizeopt/virtualize.py
--- a/rpython/jit/metainterp/optimizeopt/virtualize.py
+++ b/rpython/jit/metainterp/optimizeopt/virtualize.py
@@ -503,6 +503,7 @@
return vvalue
def make_varray(self, arraydescr, size, box, source_op=None):
+ xxx
if arraydescr.is_array_of_structs():
vvalue = VArrayStructValue(arraydescr, size, box, source_op)
else:
@@ -519,12 +520,14 @@
return vvalue
def make_virtual_raw_memory(self, size, box, source_op):
+ xxx
logops = self.optimizer.loop.logops
vvalue = VRawBufferValue(self.optimizer.cpu, logops, size, box, source_op)
self.make_equal_to(box, vvalue)
return vvalue
def make_virtual_raw_slice(self, rawbuffer_value, offset, box, source_op):
+ xxx
vvalue = VRawSliceValue(rawbuffer_value, offset, box, source_op)
self.make_equal_to(box, vvalue)
return vvalue
diff --git a/rpython/jit/metainterp/optimizeopt/vstring.py b/rpython/jit/metainterp/optimizeopt/vstring.py
--- a/rpython/jit/metainterp/optimizeopt/vstring.py
+++ b/rpython/jit/metainterp/optimizeopt/vstring.py
@@ -19,6 +19,7 @@
class StrOrUnicode(object):
def __init__(self, LLTYPE, hlstr, emptystr, chr,
NEWSTR, STRLEN, STRGETITEM, STRSETITEM, COPYSTRCONTENT,
+ RESUME_NEW, RESUME_CONCAT,
OS_offset):
self.LLTYPE = LLTYPE
self.hlstr = hlstr
@@ -29,6 +30,8 @@
self.STRGETITEM = STRGETITEM
self.STRSETITEM = STRSETITEM
self.COPYSTRCONTENT = COPYSTRCONTENT
+ self.RESUME_NEW = RESUME_NEW
+ self.RESUME_CONCAT = RESUME_CONCAT
self.OS_offset = OS_offset
def _freeze_(self):
@@ -36,10 +39,12 @@
mode_string = StrOrUnicode(rstr.STR, annlowlevel.hlstr, '', chr,
rop.NEWSTR, rop.STRLEN, rop.STRGETITEM,
- rop.STRSETITEM, rop.COPYSTRCONTENT, 0)
+ rop.STRSETITEM, rop.COPYSTRCONTENT,
+ rop.RESUME_NEWSTR, rop.RESUME_CONCATSTR, 0)
mode_unicode = StrOrUnicode(rstr.UNICODE, annlowlevel.hlunicode, u'', unichr,
rop.NEWUNICODE, rop.UNICODELEN, rop.UNICODEGETITEM,
rop.UNICODESETITEM, rop.COPYUNICODECONTENT,
+ rop.RESUME_NEWUNICODE, rop.RESUME_CONCATUNICODE,
EffectInfo._OS_offset_uni)
# ____________________________________________________________
@@ -390,17 +395,22 @@
def new(self):
return OptString()
- def make_vstring_plain(self, box, source_op, mode):
+ def make_vstring_plain(self, box, source_op, mode, length):
vvalue = VStringPlainValue(box, source_op, mode)
+ vvalue.setup(length)
+ self.optimizer.resumebuilder.new_vstring(vvalue, length, mode)
self.make_equal_to(box, vvalue)
return vvalue
- def make_vstring_concat(self, box, source_op, mode):
+ def make_vstring_concat(self, box, source_op, mode, left, right):
vvalue = VStringConcatValue(box, source_op, mode)
+ vvalue.setup(left, right)
+ self.optimizer.resumebuilder.vstring_concat(vvalue, left, right, mode)
self.make_equal_to(box, vvalue)
return vvalue
def make_vstring_slice(self, box, source_op, mode):
+ xxx
vvalue = VStringSliceValue(box, source_op, mode)
self.make_equal_to(box, vvalue)
return vvalue
@@ -417,8 +427,8 @@
# build a new one with the ConstInt argument
if not isinstance(op.getarg(0), ConstInt):
op = ResOperation(mode.NEWSTR, [length_box], op.result)
- vvalue = self.make_vstring_plain(op.result, op, mode)
- vvalue.setup(length_box.getint())
+ self.make_vstring_plain(op.result, op, mode,
+ length_box.getint())
else:
self.getvalue(op.result).ensure_nonnull()
self.emit_operation(op)
@@ -430,7 +440,10 @@
if value.is_virtual() and isinstance(value, VStringPlainValue):
indexbox = self.get_constant_box(op.getarg(1))
if indexbox is not None:
- value.setitem(indexbox.getint(), self.getvalue(op.getarg(2)))
+ index = indexbox.getint()
+ varg = self.getvalue(op.getarg(2))
+ value.setitem(index, varg)
+ self.optimizer.resumebuilder.strsetitem(value, varg)
return
value.ensure_nonnull()
self.emit_operation(op)
@@ -592,8 +605,7 @@
vright = self.getvalue(op.getarg(2))
vleft.ensure_nonnull()
vright.ensure_nonnull()
- value = self.make_vstring_concat(op.result, op, mode)
- value.setup(vleft, vright)
+ self.make_vstring_concat(op.result, op, mode, vleft, vright)
return True
def opt_call_stroruni_STR_SLICE(self, op, mode):
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
@@ -480,6 +480,9 @@
'RESUME_NEW_ARRAY/1d',
'RESUME_NEWSTR/1',
'RESUME_NEWUNICODE/1',
+ 'RESUME_CONCATSTR/2',
+ 'RESUME_CONCATUNICODE/2',
+ 'RESUME_STRSETITEM/2',
'RESUME_SETFIELD_GC/2d',
'RESUME_SET_PC/1',
'RESUME_CLEAR/2',
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
@@ -1,10 +1,31 @@
from rpython.jit.metainterp.resoperation import rop
-from rpython.jit.metainterp.history import Box, Const
+from rpython.jit.metainterp.history import Box, Const, AbstractDescr
from rpython.jit.resume.rescode import ResumeBytecodeBuilder, TAGBOX,\
ResumeBytecode, TAGVIRTUAL
from rpython.jit.codewriter.jitcode import JitCode
+class DescrForStr(AbstractDescr):
+ pass
+
+left_descr = DescrForStr()
+right_descr = DescrForStr()
+
+class BaseDeps(object):
+ pass
+
+class DepsFields(BaseDeps):
+ def __init__(self):
+ self.fields = {}
+
+class DepsConcat(BaseDeps):
+ def __init__(self, left, right):
+ self.left = left
+ self.right = right
+
+class DepsArray(BaseDeps):
+ def __init__(self, size):
+ self.l = [None] * size
class LivenessAnalyzer(object):
def __init__(self):
@@ -26,13 +47,22 @@
self.framestack[framepos][frontend_pos] = None
def resume_new(self, result, descr):
- self.deps[result] = {}
+ self.deps[result] = DepsFields()
+
+ def resume_newunicode(self, result, length):
+ self.deps[result] = DepsArray(length)
+
+ def resume_concatunicode(self, result, left, right):
+ self.deps[result] = DepsConcat(left, right)
def resume_new_with_vtable(self, result, klass):
- self.deps[result] = {}
+ self.deps[result] = DepsFields()
def resume_setfield_gc(self, arg0, arg1, descr):
- self.deps[arg0][descr] = arg1
+ self.deps[arg0].fields[descr] = arg1
+
+ def resume_strsetitem(self, arg0, arg1):
+ xxx
def resume_set_pc(self, pc):
pass
@@ -64,6 +94,16 @@
elif op.getopnum() == rop.RESUME_CLEAR:
self.resume_clear(op.getarg(0).getint(),
op.getarg(1).getint())
+ elif op.getopnum() == rop.RESUME_NEWSTR:
+ xxx
+ elif op.getopnum() == rop.RESUME_NEWUNICODE:
+ self.resume_newunicode(op.result, op.getarg(0).getint())
+ elif op.getopnum() == rop.RESUME_CONCATSTR:
+ xxx
+ elif op.getopnum() == rop.RESUME_CONCATUNICODE:
+ self.resume_concatunicode(op.result, op.getarg(0), op.getarg(1))
+ elif op.getopnum() == rop.RESUME_STRSETITEM:
+ self.resume_strsetitem(op.getarg(0), op.getarg(1))
elif not op.is_resume():
pos += 1
continue
@@ -150,6 +190,20 @@
elif op.getopnum() == rop.RESUME_CLEAR:
self.builder.resume_clear(op.getarg(0).getint(),
op.getarg(1).getint())
+ elif op.getopnum() == rop.RESUME_NEWSTR:
+ xxx
+ elif op.getopnum() == rop.RESUME_NEWUNICODE:
+ v_pos = len(self.virtuals)
+ self.virtuals[op.result] = v_pos
+ self.builder.resume_newunicode(v_pos, op.getarg(0).getint())
+ elif op.getopnum() == rop.RESUME_CONCATSTR:
+ xxx
+ elif op.getopnum() == rop.RESUME_CONCATUNICODE:
+ v_pos = len(self.virtuals)
+ self.virtuals[op.result] = v_pos
+ leftpos = self.get_box_pos(op.getarg(0))
+ rightpos = self.get_box_pos(op.getarg(0))
+ self.builder.resume_concatunicode(v_pos, leftpos, rightpos)
else:
raise Exception("strange operation")
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
@@ -76,11 +76,9 @@
return self.virtuals_cache[index]
except KeyError:
pass
- val = self.virtuals[index].allocate_direct(self.cpu)
+ val = self.virtuals[index].allocate_direct(self, self.cpu)
self.virtuals_cache[index] = val
- fields = self.virtuals[index].fields
- for fielddescr, encoded_field_pos in fields.iteritems():
- self.setfield_gc(val, encoded_field_pos, fielddescr)
+ self.virtuals[index].populate_fields(val, self)
return val
def setfield_gc(self, struct, encoded_field_pos, fielddescr):
diff --git a/rpython/jit/resume/optimizer.py b/rpython/jit/resume/optimizer.py
--- a/rpython/jit/resume/optimizer.py
+++ b/rpython/jit/resume/optimizer.py
@@ -51,10 +51,6 @@
else:
self.opt.emit_operation(op)
- def new_virtual(self, box):
- xxx
- self.optimizer.emit_operation(rop.RESUME_NEW)
-
def new_virtual_with_vtable(self, box, vtable, vvalue):
virtualbox = BoxPtr()
op = ResOperation(rop.RESUME_NEW_WITH_VTABLE, [vtable], virtualbox)
@@ -67,6 +63,26 @@
op = ResOperation(rop.RESUME_NEW, [], newbox, descr=structdescr)
self.opt._newoperations.append(op)
+ def new_vstring(self, vstring, lgt, mode):
+ newbox = BoxPtr()
+ vstring.resume_box = newbox
+ op = ResOperation(mode.RESUME_NEW, [ConstInt(lgt)], newbox)
+ self.opt._newoperations.append(op)
+
+ def vstring_concat(self, vstring, left, right, mode):
+ leftbox = left.get_resume_box()
+ rightbox = right.get_resume_box()
+ newbox = BoxPtr()
+ vstring.resume_box = newbox
+ op = ResOperation(mode.RESUME_CONCAT, [leftbox, rightbox], newbox)
+ self.opt._newoperations.append(op)
+
+ def strsetitem(self, vstring, varg):
+ argbox = varg.get_resume_box()
+ op = ResOperation(rop.RESUME_STRSETITEM, [vstring.get_resume_box(),
+ argbox], None)
+ self.opt._newoperations.append(op)
+
def setfield(self, box, fieldbox, descr):
op = ResOperation(rop.RESUME_SETFIELD_GC, [box, fieldbox], None,
descr=descr)
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
@@ -1,4 +1,7 @@
+from rpython.rtyper.lltypesystem import lltype, rstr, llmemory
+
+from rpython.jit.codewriter.effectinfo import EffectInfo
from rpython.jit.metainterp.resoperation import rop
from rpython.jit.metainterp.history import ConstInt
from rpython.jit.codewriter import heaptracker
@@ -11,9 +14,16 @@
self.pc = -1
class BaseVirtual(object):
- pass
+ def populate_fields(self, reader):
+ pass
-class VirtualStruct(BaseVirtual):
+class BaseVirtualStruct(BaseVirtual):
+ def populate_fields(self, val, reader):
+ fields = self.fields
+ for fielddescr, encoded_field_pos in fields.iteritems():
+ reader.setfield_gc(val, encoded_field_pos, fielddescr)
+
+class VirtualStruct(BaseVirtualStruct):
def __init__(self, pos, descr):
self.pos = pos
self.fields = {}
@@ -22,10 +32,10 @@
def allocate_box(self, metainterp):
return metainterp.execute_and_record(rop.NEW, self.descr)
- def allocate_direct(self, cpu):
+ def allocate_direct(self, reader, cpu):
return cpu.bh_new(self.descr)
-class VirtualWithVtable(BaseVirtual):
+class VirtualWithVtable(BaseVirtualStruct):
def __init__(self, pos, const_class):
self.pos = pos
self.const_class = const_class
@@ -35,10 +45,37 @@
return metainterp.execute_and_record(rop.NEW_WITH_VTABLE, None,
ConstInt(self.const_class))
- def allocate_direct(self, cpu):
+ def allocate_direct(self, reader, cpu):
descr = heaptracker.vtable2descr(cpu, self.const_class)
return cpu.bh_new_with_vtable(self.const_class, descr)
+class VirtualStr(BaseVirtual):
+ def __init__(self, pos, lgt, mode):
+ self.pos = pos
+ self.lgt = lgt
+ self.mode = mode
+
+class VirtualConcat(BaseVirtual):
+ def __init__(self, pos, left, right, mode):
+ self.pos = pos
+ self.left = left
+ self.right = right
+ self.mode = mode
+
+ def allocate_direct(self, reader, cpu):
+ leftval = reader.getref(self.left)
+ rightval = reader.getref(self.right)
+ cic = reader.staticdata.callinfocollection
+ if self.mode == 'u':
+ funcptr = cic.funcptr_for_oopspec(EffectInfo.OS_UNI_CONCAT)
+ str1 = lltype.cast_opaque_ptr(lltype.Ptr(rstr.UNICODE), leftval)
+ str2 = lltype.cast_opaque_ptr(lltype.Ptr(rstr.UNICODE), rightval)
+ result = funcptr(str1, str2)
+ 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
the concrete classes for details
@@ -73,6 +110,22 @@
v = VirtualStruct(v_pos, descr)
self._add_to_virtuals(v, v_pos)
+ def resume_newstr(self, v_pos, lgt):
+ v = VirtualStr(v_pos, lgt, 's')
+ self._add_to_virtuals(v, v_pos)
+
+ def resume_newunicode(self, v_pos, lgt):
+ v = VirtualStr(v_pos, lgt, 'u')
+ self._add_to_virtuals(v, v_pos)
+
+ def resume_concatstr(self, v_pos, leftpos, rightpos):
+ v = VirtualConcat(v_pos, leftpos, rightpos, 's')
+ self._add_to_virtuals(v, v_pos)
+
+ def resume_concatunicode(self, v_pos, leftpos, rightpos):
+ v = VirtualConcat(v_pos, leftpos, rightpos, 'u')
+ self._add_to_virtuals(v, v_pos)
+
def resume_new_with_vtable(self, v_pos, c_const_class):
const_class = c_const_class.getint()
v = VirtualWithVtable(v_pos, const_class)
@@ -153,6 +206,21 @@
pc = self.read_short(pos + 1)
self.resume_set_pc(pc)
pos += 3
+ elif op == rescode.RESUME_NEWSTR:
+ xxx
+ elif op == rescode.RESUME_NEWUNICODE:
+ v_pos = self.read_short(pos + 1)
+ lgt = self.read(pos + 3)
+ self.resume_newunicode(v_pos, lgt)
+ pos += 4
+ elif op == rescode.RESUME_CONCATSTR:
+ xxx
+ elif op == rescode.RESUME_CONCATUNICODE:
+ v_pos = self.read_short(pos + 1)
+ left = self.read_short(pos + 3)
+ right = self.read_short(pos + 5)
+ self.resume_concatunicode(v_pos, left, right)
+ pos += 7
else:
xxx
self.bytecode = None
@@ -179,6 +247,18 @@
def resume_clear(self, frame_pos, pos_in_frame):
self.l.append("resume_clear %d %d" % (frame_pos, pos_in_frame))
+ def resume_newstr(self, v_pos, lgt):
+ xxx
+
+ def resume_newunicode(self, v_pos, lgt):
+ xxx
+
+ def resume_concatstr(self, v_pos, leftpos, rightpos):
+ xxx
+
+ def resume_concatunicode(self, v_pos, leftpos, rightpos):
+ xxx
+
def resume_new_with_vtable(self, v_pos, c_const_class):
self.l.append("%d = resume_new_with_vtable %d" % (v_pos,
c_const_class.getint()))
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
@@ -4,7 +4,8 @@
(UNUSED, ENTER_FRAME, LEAVE_FRAME, RESUME_PUT,
RESUME_NEW, RESUME_NEW_WITH_VTABLE, RESUME_SETFIELD_GC,
- RESUME_SET_PC, RESUME_CLEAR) = range(9)
+ RESUME_SET_PC, RESUME_CLEAR, RESUME_NEWSTR, RESUME_NEWUNICODE,
+ RESUME_CONCATSTR, RESUME_CONCATUNICODE) = range(13)
TAGCONST = 0x0
TAGVIRTUAL = 0x2
@@ -88,6 +89,17 @@
self.write_short(v_pos) # XXX byte virtuals?
self.write_short(descr.global_descr_index)
+ def resume_newunicode(self, v_pos, lgt):
+ self.write(RESUME_NEWUNICODE)
+ self.write_short(v_pos) # XXX byte virtuals?
+ self.write(lgt)
+
+ def resume_concatunicode(self, v_pos, leftpos, rightpos):
+ self.write(RESUME_CONCATUNICODE)
+ self.write_short(v_pos)
+ self.write_short(leftpos)
+ self.write_short(rightpos)
+
def resume_new_with_vtable(self, v_pos, const_class):
self.write(RESUME_NEW_WITH_VTABLE)
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
@@ -2,7 +2,7 @@
from rpython.jit.tool.oparser import parse
from rpython.jit.codewriter.jitcode import JitCode
from rpython.jit.metainterp.history import AbstractDescr, Const, INT, Stats,\
- ConstInt, REF
+ ConstInt, REF, FLOAT
from rpython.jit.resume.frontend import rebuild_from_resumedata,\
blackhole_from_resumedata
from rpython.jit.resume.rescode import ResumeBytecode, TAGBOX,\
@@ -30,6 +30,9 @@
def is_field_signed(self):
return self.kind == INT
+ def is_float_field(self):
+ return self.kind == FLOAT
+
class MockLoop(object):
pass
@@ -251,12 +254,12 @@
rebuild_from_resumedata(metainterp, "myframe", descr)
expected = [(rop.NEW, descr),
(rop.SETFIELD_GC, d2, AnyBox(), EqConstInt(1)),
- (rop.NEW_WITH_VTABLE, EqConstInt(cls_as_int)),
+ (rop.NEW_WITH_VTABLE, None, EqConstInt(cls_as_int)),
(rop.SETFIELD_GC, d3, AnyBox(), AnyBox()),
(rop.RESUME_PUT, None, AnyBox(), EqConstInt(0),
EqConstInt(0))]
expected2 = [(rop.NEW, descr),
- (rop.NEW_WITH_VTABLE, EqConstInt(cls_as_int)),
+ (rop.NEW_WITH_VTABLE, None, EqConstInt(cls_as_int)),
(rop.SETFIELD_GC, d3, AnyBox(), AnyBox()),
(rop.SETFIELD_GC, d2, AnyBox(), EqConstInt(1)),
(rop.RESUME_PUT, None, AnyBox(), EqConstInt(0),
More information about the pypy-commit
mailing list