[pypy-svn] r77262 - in pypy/branch/jit-str/pypy: jit/codewriter jit/codewriter/test jit/metainterp jit/metainterp/optimizeopt jit/metainterp/test rpython/lltypesystem
arigo at codespeak.net
arigo at codespeak.net
Wed Sep 22 11:52:53 CEST 2010
Author: arigo
Date: Wed Sep 22 11:52:51 2010
New Revision: 77262
Modified:
pypy/branch/jit-str/pypy/jit/codewriter/support.py
pypy/branch/jit-str/pypy/jit/codewriter/test/test_jtransform.py
pypy/branch/jit-str/pypy/jit/metainterp/optimizefindnode.py
pypy/branch/jit-str/pypy/jit/metainterp/optimizeopt/optimizer.py
pypy/branch/jit-str/pypy/jit/metainterp/optimizeopt/rewrite.py
pypy/branch/jit-str/pypy/jit/metainterp/optimizeopt/virtualize.py
pypy/branch/jit-str/pypy/jit/metainterp/optimizeutil.py
pypy/branch/jit-str/pypy/jit/metainterp/resume.py
pypy/branch/jit-str/pypy/jit/metainterp/test/test_string.py
pypy/branch/jit-str/pypy/jit/metainterp/warmstate.py
pypy/branch/jit-str/pypy/rpython/lltypesystem/rstr.py
Log:
In-progress. Add "virtual one-character strings".
Modified: pypy/branch/jit-str/pypy/jit/codewriter/support.py
==============================================================================
--- pypy/branch/jit-str/pypy/jit/codewriter/support.py (original)
+++ pypy/branch/jit-str/pypy/jit/codewriter/support.py Wed Sep 22 11:52:51 2010
@@ -275,10 +275,12 @@
# ---------- strings and unicode ----------
- _ll_5_string_copy_contents = ll_rstr.copy_string_contents
-
_ll_1_str_str2unicode = ll_rstr.LLHelpers.ll_str2unicode
- _ll_5_unicode_copy_contents = ll_rstr.copy_unicode_contents
+
+ _ll_2_stroruni_concat = ll_rstr.LLHelpers.ll_strconcat
+ _ll_2_stroruni_slice_startonly = ll_rstr.LLHelpers.ll_stringslice_startonly
+ _ll_3_stroruni_slice_startstop = ll_rstr.LLHelpers.ll_stringslice_startstop
+ _ll_1_stroruni_slice_minusone = ll_rstr.LLHelpers.ll_stringslice_minusone
# ---------- malloc with del ----------
Modified: pypy/branch/jit-str/pypy/jit/codewriter/test/test_jtransform.py
==============================================================================
--- pypy/branch/jit-str/pypy/jit/codewriter/test/test_jtransform.py (original)
+++ pypy/branch/jit-str/pypy/jit/codewriter/test/test_jtransform.py Wed Sep 22 11:52:51 2010
@@ -1,3 +1,4 @@
+import py
import random
from pypy.objspace.flow.model import FunctionGraph, Block, Link
from pypy.objspace.flow.model import SpaceOperation, Variable, Constant
@@ -7,6 +8,9 @@
from pypy.translator.unsimplify import varoftype
from pypy.jit.codewriter import heaptracker
+def const(x):
+ return Constant(x, lltype.typeOf(x))
+
class FakeRTyper:
class type_system: name = 'lltypesystem'
instance_reprs = {}
@@ -67,6 +71,14 @@
def calldescr_canraise(self, calldescr):
return False
+class FakeBuiltinCallControl:
+ def guess_call_kind(self, op):
+ return 'builtin'
+ def getcalldescr(self, op):
+ return 'calldescr'
+ def calldescr_canraise(self, calldescr):
+ return False
+
def test_optimize_goto_if_not():
v1 = Variable()
@@ -107,7 +119,7 @@
assert block.operations == []
assert block.exitswitch == ('int_gt', v1, v2)
assert block.exits == exits
- assert exits[1].args == [Constant(True, lltype.Bool)]
+ assert exits[1].args == [const(True)]
def test_optimize_goto_if_not__unknownop():
v3 = Variable(); v3.concretetype = lltype.Bool
@@ -159,8 +171,8 @@
'float_gt': ('float_gt', 'float_lt'),
}
v3 = varoftype(lltype.Signed)
- for v1 in [varoftype(lltype.Signed), Constant(42, lltype.Signed)]:
- for v2 in [varoftype(lltype.Signed), Constant(43, lltype.Signed)]:
+ for v1 in [varoftype(lltype.Signed), const(42)]:
+ for v2 in [varoftype(lltype.Signed), const(43)]:
for name1, name2 in ops.items():
op = SpaceOperation(name1, [v1, v2], v3)
op1 = Transformer(FakeCPU()).rewrite_operation(op)
@@ -177,8 +189,8 @@
def test_symmetric_int_add_ovf():
v3 = varoftype(lltype.Signed)
- for v1 in [varoftype(lltype.Signed), Constant(42, lltype.Signed)]:
- for v2 in [varoftype(lltype.Signed), Constant(43, lltype.Signed)]:
+ for v1 in [varoftype(lltype.Signed), const(42)]:
+ for v2 in [varoftype(lltype.Signed), const(43)]:
op = SpaceOperation('int_add_nonneg_ovf', [v1, v2], v3)
oplist = Transformer(FakeCPU()).rewrite_operation(op)
op0, op1 = oplist
@@ -218,7 +230,7 @@
def get_direct_call_op(argtypes, restype):
FUNC = lltype.FuncType(argtypes, restype)
fnptr = lltype.functionptr(FUNC, "g") # no graph
- c_fnptr = Constant(fnptr, concretetype=lltype.typeOf(fnptr))
+ c_fnptr = const(fnptr)
vars = [varoftype(TYPE) for TYPE in argtypes]
v_result = varoftype(restype)
op = SpaceOperation('direct_call', [c_fnptr] + vars, v_result)
@@ -465,7 +477,7 @@
v1 = varoftype(lltype.Signed)
v2 = varoftype(lltype.Signed)
v3 = varoftype(lltype.Bool)
- c0 = Constant(0, lltype.Signed)
+ c0 = const(0)
#
for opname, reducedname in [('int_eq', 'int_is_zero'),
('int_ne', 'int_is_true')]:
@@ -488,7 +500,7 @@
v1 = varoftype(rclass.OBJECTPTR)
v2 = varoftype(rclass.OBJECTPTR)
v3 = varoftype(lltype.Bool)
- c0 = Constant(lltype.nullptr(rclass.OBJECT), rclass.OBJECTPTR)
+ c0 = const(lltype.nullptr(rclass.OBJECT))
#
for opname, reducedname in [('ptr_eq', 'ptr_iszero'),
('ptr_ne', 'ptr_nonzero')]:
@@ -511,7 +523,7 @@
v1 = varoftype(rclass.NONGCOBJECTPTR)
v2 = varoftype(rclass.NONGCOBJECTPTR)
v3 = varoftype(lltype.Bool)
- c0 = Constant(lltype.nullptr(rclass.NONGCOBJECT), rclass.NONGCOBJECTPTR)
+ c0 = const(lltype.nullptr(rclass.NONGCOBJECT))
#
for opname, reducedname in [('ptr_eq', 'int_is_zero'),
('ptr_ne', 'int_is_true')]:
@@ -656,3 +668,83 @@
oplist = tr.rewrite_operation(op)
assert oplist[0].opname == 'inline_call_ir_i'
assert oplist[0].args[0] == 'somejitcode'
+
+def test_str_newstr():
+ c_STR = Constant(rstr.STR, lltype.Void)
+ c_flavor = Constant({'flavor': 'gc'}, lltype.Void)
+ v1 = varoftype(lltype.Signed)
+ v2 = varoftype(lltype.Ptr(rstr.STR))
+ op = SpaceOperation('malloc_varsize', [c_STR, c_flavor, v1], v2)
+ op1 = Transformer().rewrite_operation(op)
+ assert op1.opname == 'newstr'
+ assert op1.args == [v1]
+ assert op1.result == v2
+
+def test_str_concat():
+ py.test.xfail('later')
+ # test that the oopspec is present and correctly transformed
+ PSTR = lltype.Ptr(rstr.STR)
+ FUNC = lltype.FuncType([PSTR, PSTR], PSTR)
+ func = lltype.functionptr(FUNC, 'll_strconcat',
+ _callable=rstr.LLHelpers.ll_strconcat)
+ v1 = varoftype(PSTR)
+ v2 = varoftype(PSTR)
+ v3 = varoftype(PSTR)
+ op = SpaceOperation('direct_call', [const(func), v1, v2], v3)
+ tr = Transformer(FakeCPU(), FakeBuiltinCallControl())
+ op1 = tr.rewrite_operation(op)
+ assert op1.opname == 'residual_call_r_r'
+ assert list(op1.args[2]) == [v1, v2]
+ assert op1.result == v3
+
+def test_str_stringslice_startonly():
+ # test that the oopspec is present and correctly transformed
+ PSTR = lltype.Ptr(rstr.STR)
+ INT = lltype.Signed
+ FUNC = lltype.FuncType([PSTR, INT], PSTR)
+ func = lltype.functionptr(FUNC, 'll_stringslice_startonly',
+ _callable=rstr.LLHelpers.ll_stringslice_startonly)
+ v1 = varoftype(PSTR)
+ v2 = varoftype(INT)
+ v3 = varoftype(PSTR)
+ op = SpaceOperation('direct_call', [const(func), v1, v2], v3)
+ tr = Transformer(FakeCPU(), FakeBuiltinCallControl())
+ op1 = tr.rewrite_operation(op)
+ assert op1.opname == 'residual_call_ir_r'
+ assert list(op1.args[2]) == [v2]
+ assert list(op1.args[3]) == [v1]
+ assert op1.result == v3
+
+def test_str_stringslice_startstop():
+ # test that the oopspec is present and correctly transformed
+ PSTR = lltype.Ptr(rstr.STR)
+ INT = lltype.Signed
+ FUNC = lltype.FuncType([PSTR, INT, INT], PSTR)
+ func = lltype.functionptr(FUNC, 'll_stringslice_startstop',
+ _callable=rstr.LLHelpers.ll_stringslice_startstop)
+ v1 = varoftype(PSTR)
+ v2 = varoftype(INT)
+ v3 = varoftype(INT)
+ v4 = varoftype(PSTR)
+ op = SpaceOperation('direct_call', [const(func), v1, v2, v3], v4)
+ tr = Transformer(FakeCPU(), FakeBuiltinCallControl())
+ op1 = tr.rewrite_operation(op)
+ assert op1.opname == 'residual_call_ir_r'
+ assert list(op1.args[2]) == [v2, v3]
+ assert list(op1.args[3]) == [v1]
+ assert op1.result == v4
+
+def test_str_stringslice_minusone():
+ # test that the oopspec is present and correctly transformed
+ PSTR = lltype.Ptr(rstr.STR)
+ FUNC = lltype.FuncType([PSTR], PSTR)
+ func = lltype.functionptr(FUNC, 'll_stringslice_minusone',
+ _callable=rstr.LLHelpers.ll_stringslice_minusone)
+ v1 = varoftype(PSTR)
+ v2 = varoftype(PSTR)
+ op = SpaceOperation('direct_call', [const(func), v1], v2)
+ tr = Transformer(FakeCPU(), FakeBuiltinCallControl())
+ op1 = tr.rewrite_operation(op)
+ assert op1.opname == 'residual_call_r_r'
+ assert list(op1.args[2]) == [v1]
+ assert op1.result == v2
Modified: pypy/branch/jit-str/pypy/jit/metainterp/optimizefindnode.py
==============================================================================
--- pypy/branch/jit-str/pypy/jit/metainterp/optimizefindnode.py (original)
+++ pypy/branch/jit-str/pypy/jit/metainterp/optimizefindnode.py Wed Sep 22 11:52:51 2010
@@ -172,7 +172,7 @@
find_nodes_PTR_EQ = find_nodes_no_escape
find_nodes_PTR_NE = find_nodes_no_escape
- find_nodes_INSTANCEOF = find_nodes_no_escape
+ ##find_nodes_INSTANCEOF = find_nodes_no_escape
find_nodes_GUARD_NONNULL = find_nodes_no_escape
find_nodes_GUARD_ISNULL = find_nodes_no_escape
Modified: pypy/branch/jit-str/pypy/jit/metainterp/optimizeopt/optimizer.py
==============================================================================
--- pypy/branch/jit-str/pypy/jit/metainterp/optimizeopt/optimizer.py (original)
+++ pypy/branch/jit-str/pypy/jit/metainterp/optimizeopt/optimizer.py Wed Sep 22 11:52:51 2010
@@ -126,6 +126,12 @@
def setitem(self, index, value):
raise NotImplementedError
+ def getchar(self):
+ raise NotImplementedError
+
+ def setchar(self, charvalue):
+ raise NotImplementedError
+
class ConstantValue(OptValue):
def __init__(self, box):
self.make_constant(box)
Modified: pypy/branch/jit-str/pypy/jit/metainterp/optimizeopt/rewrite.py
==============================================================================
--- pypy/branch/jit-str/pypy/jit/metainterp/optimizeopt/rewrite.py (original)
+++ pypy/branch/jit-str/pypy/jit/metainterp/optimizeopt/rewrite.py Wed Sep 22 11:52:51 2010
@@ -307,17 +307,17 @@
def optimize_PTR_EQ(self, op):
self._optimize_oois_ooisnot(op, False)
- def optimize_INSTANCEOF(self, op):
- value = self.getvalue(op.args[0])
- realclassbox = value.get_constant_class(self.optimizer.cpu)
- if realclassbox is not None:
- checkclassbox = self.optimizer.cpu.typedescr2classbox(op.descr)
- result = self.optimizer.cpu.ts.subclassOf(self.optimizer.cpu,
- realclassbox,
- checkclassbox)
- self.make_constant_int(op.result, result)
- return
- self.emit_operation(op)
+## def optimize_INSTANCEOF(self, op):
+## value = self.getvalue(op.args[0])
+## realclassbox = value.get_constant_class(self.optimizer.cpu)
+## if realclassbox is not None:
+## checkclassbox = self.optimizer.cpu.typedescr2classbox(op.descr)
+## result = self.optimizer.cpu.ts.subclassOf(self.optimizer.cpu,
+## realclassbox,
+## checkclassbox)
+## self.make_constant_int(op.result, result)
+## return
+## self.emit_operation(op)
optimize_ops = _findall(OptRewrite, 'optimize_')
Modified: pypy/branch/jit-str/pypy/jit/metainterp/optimizeopt/virtualize.py
==============================================================================
--- pypy/branch/jit-str/pypy/jit/metainterp/optimizeopt/virtualize.py (original)
+++ pypy/branch/jit-str/pypy/jit/metainterp/optimizeopt/virtualize.py Wed Sep 22 11:52:51 2010
@@ -188,12 +188,43 @@
itemboxes.append(itemvalue.get_key_box())
modifier.register_virtual_fields(self.keybox, itemboxes)
for itemvalue in self._items:
- if itemvalue is not self.constvalue:
- itemvalue.get_args_for_fail(modifier)
+ itemvalue.get_args_for_fail(modifier)
def _make_virtual(self, modifier):
return modifier.make_varray(self.arraydescr)
+class VStringLength1Value(AbstractVirtualValue):
+
+ def __init__(self, optimizer, keybox, source_op=None):
+ AbstractVirtualValue.__init__(self, optimizer, keybox, source_op)
+ self._char = CVAL_ZERO
+
+ def getchar(self):
+ return self._char
+
+ def setchar(self, charvalue):
+ assert isinstance(charvalue, OptValue)
+ self._char = charvalue
+
+ def _really_force(self):
+ assert self.source_op is not None
+ newoperations = self.optimizer.newoperations
+ newoperations.append(self.source_op)
+ self.box = box = self.source_op.result
+ charbox = self._char.force_box()
+ op = ResOperation(rop.STRSETITEM,
+ [box, ConstInt(0), charbox], None)
+ newoperations.append(op)
+
+ def get_args_for_fail(self, modifier):
+ if self.box is None and not modifier.already_seen_virtual(self.keybox):
+ charboxes = [self._char.get_key_box()]
+ modifier.register_virtual_fields(self.keybox, charboxes)
+ self._char.get_args_for_fail(modifier)
+
+ def _make_virtual(self, modifier):
+ return modifier.make_vstring()
+
class __extend__(SpecNode):
def setup_virtual_node(self, optimizer, box, newinputargs):
raise NotImplementedError
@@ -282,6 +313,11 @@
self.make_equal_to(box, vvalue)
return vvalue
+ def make_vstring_length1(self, box, source_op=None):
+ vvalue = VStringLength1Value(self.optimizer, box, source_op)
+ self.make_equal_to(box, vvalue)
+ return vvalue
+
def optimize_JUMP(self, op):
orgop = self.optimizer.loop.operations[-1]
exitargs = []
@@ -358,8 +394,8 @@
def optimize_SETFIELD_GC(self, op):
value = self.getvalue(op.args[0])
- fieldvalue = self.getvalue(op.args[1])
if value.is_virtual():
+ fieldvalue = self.getvalue(op.args[1])
value.setfield(op.descr, fieldvalue)
else:
value.ensure_nonnull()
@@ -444,6 +480,44 @@
self.emit_operation(ResOperation(rop.CALL, op.args[1:], op.result,
descr))
+ def optimize_NEWSTR(self, op):
+ length_box = self.get_constant_box(op.args[0])
+ if length_box and length_box.getint() == 1: # NEWSTR(1)
+ # if the original 'op' did not have a ConstInt as argument,
+ # build a new one with the ConstInt argument
+ if not isinstance(op.args[0], ConstInt):
+ op = ResOperation(rop.NEWSTR, [CONST_1], op.result)
+ self.make_vstring_length1(op.result, op)
+ else:
+ self.emit_operation(op)
+
+ def optimize_STRSETITEM(self, op):
+ value = self.getvalue(op.args[0])
+ if value.is_virtual():
+ charvalue = self.getvalue(op.args[2])
+ value.setchar(charvalue)
+ else:
+ value.ensure_nonnull()
+ self.emit_operation(op)
+
+ def optimize_STRGETITEM(self, op):
+ value = self.getvalue(op.args[0])
+ if value.is_virtual():
+ charvalue = value.getchar()
+ assert charvalue is not None
+ self.make_equal_to(op.result, charvalue)
+ else:
+ value.ensure_nonnull()
+ self.emit_operation(op)
+
+ def optimize_STRLEN(self, op):
+ value = self.getvalue(op.args[0])
+ if value.is_virtual():
+ self.make_constant_int(op.result, 1)
+ else:
+ value.ensure_nonnull()
+ self.emit_operation(op)
+
def propagate_forward(self, op):
opnum = op.opnum
for value, func in optimize_ops:
Modified: pypy/branch/jit-str/pypy/jit/metainterp/optimizeutil.py
==============================================================================
--- pypy/branch/jit-str/pypy/jit/metainterp/optimizeutil.py (original)
+++ pypy/branch/jit-str/pypy/jit/metainterp/optimizeutil.py Wed Sep 22 11:52:51 2010
@@ -14,6 +14,11 @@
def _findall(Class, name_prefix):
result = []
+ for name in dir(Class):
+ if name.startswith(name_prefix):
+ opname = name[len(name_prefix):]
+ if opname.isupper():
+ assert hasattr(resoperation.rop, opname)
for value, name in resoperation.opname.items():
if hasattr(Class, name_prefix + name):
result.append((value, getattr(Class, name_prefix + name)))
Modified: pypy/branch/jit-str/pypy/jit/metainterp/resume.py
==============================================================================
--- pypy/branch/jit-str/pypy/jit/metainterp/resume.py (original)
+++ pypy/branch/jit-str/pypy/jit/metainterp/resume.py Wed Sep 22 11:52:51 2010
@@ -253,6 +253,9 @@
def make_varray(self, arraydescr):
return VArrayInfo(arraydescr)
+ def make_vstring(self):
+ return VStringInfo()
+
def register_virtual_fields(self, virtualbox, fieldboxes):
tagged = self.liveboxes_from_env.get(virtualbox, UNASSIGNEDVIRTUAL)
self.liveboxes[virtualbox] = tagged
@@ -486,6 +489,27 @@
for i in self.fieldnums:
debug_print("\t\t", str(untag(i)))
+class VStringInfo(AbstractVirtualInfo):
+ def __init__(self):
+ pass
+ #self.fieldnums = ...
+
+ @specialize.argtype(1)
+ def allocate(self, decoder):
+ length = len(self.fieldnums)
+ return decoder.allocate_string(length)
+
+ @specialize.argtype(1)
+ def setfields(self, decoder, string):
+ length = len(self.fieldnums)
+ for i in range(length):
+ decoder.strsetitem(string, i, self.fieldnums[i])
+
+ def debug_prints(self):
+ debug_print("\tvstringinfo")
+ for i in self.fieldnums:
+ debug_print("\t\t", str(untag(i)))
+
# ____________________________________________________________
class AbstractResumeDataReader(object):
@@ -622,6 +646,9 @@
return self.metainterp.execute_and_record(rop.NEW_ARRAY,
arraydescr, ConstInt(length))
+ def allocate_string(self, length):
+ return self.metainterp.execute_and_record(rop.NEWSTR, ConstInt(length))
+
def setfield(self, descr, structbox, fieldnum):
if descr.is_pointer_field():
kind = REF
@@ -839,6 +866,9 @@
def allocate_array(self, arraydescr, length):
return self.cpu.bh_new_array(arraydescr, length)
+ def allocate_string(self, length):
+ return self.cpu.bh_newstr(length)
+
def setfield(self, descr, struct, fieldnum):
if descr.is_pointer_field():
newvalue = self.decode_ref(fieldnum)
Modified: pypy/branch/jit-str/pypy/jit/metainterp/test/test_string.py
==============================================================================
--- pypy/branch/jit-str/pypy/jit/metainterp/test/test_string.py (original)
+++ pypy/branch/jit-str/pypy/jit/metainterp/test/test_string.py Wed Sep 22 11:52:51 2010
@@ -1,5 +1,5 @@
import py
-from pypy.rlib.jit import JitDriver
+from pypy.rlib.jit import JitDriver, dont_look_inside, we_are_jitted
from pypy.jit.codewriter.policy import StopAtXPolicy
from pypy.rpython.ootypesystem import ootype
from pypy.jit.metainterp.test.test_basic import LLJitMixin, OOJitMixin
@@ -72,6 +72,104 @@
res = self.meta_interp(f, [6, 10])
assert res == 6
+ def test_char2string_pure(self):
+ for dochr in [chr, ]: #unichr]:
+ jitdriver = JitDriver(greens = [], reds = ['n'])
+ @dont_look_inside
+ def escape(x):
+ pass
+ def f(n):
+ while n > 0:
+ jitdriver.can_enter_jit(n=n)
+ jitdriver.jit_merge_point(n=n)
+ s = dochr(n)
+ if not we_are_jitted():
+ s += s # forces to be a string
+ if n > 100:
+ escape(s)
+ n -= 1
+ return 42
+ self.meta_interp(f, [6])
+ self.check_loops(newstr=0, strsetitem=0, strlen=0,
+ newunicode=0, unicodesetitem=0, unicodelen=0)
+
+ def test_char2string_escape(self):
+ for dochr in [chr, ]: #unichr]:
+ jitdriver = JitDriver(greens = [], reds = ['n', 'total'])
+ @dont_look_inside
+ def escape(x):
+ return ord(x[0])
+ def f(n):
+ total = 0
+ while n > 0:
+ jitdriver.can_enter_jit(n=n, total=total)
+ jitdriver.jit_merge_point(n=n, total=total)
+ s = dochr(n)
+ if not we_are_jitted():
+ s += s # forces to be a string
+ total += escape(s)
+ n -= 1
+ return total
+ res = self.meta_interp(f, [6])
+ assert res == 21
+
+ def test_char2string2char(self):
+ for dochr in [chr, ]: #unichr]:
+ jitdriver = JitDriver(greens = [], reds = ['m', 'total'])
+ def f(m):
+ total = 0
+ while m > 0:
+ jitdriver.can_enter_jit(m=m, total=total)
+ jitdriver.jit_merge_point(m=m, total=total)
+ string = dochr(m)
+ if m > 100:
+ string += string # forces to be a string
+ # read back the character
+ c = string[0]
+ total += ord(c)
+ m -= 1
+ return total
+ res = self.meta_interp(f, [6])
+ assert res == 21
+ self.check_loops(newstr=0, strgetitem=0, strsetitem=0, strlen=0,
+ newunicode=0, unicodegetitem=0, unicodesetitem=0,
+ unicodelen=0)
+
+ def test_slice_startonly(self):
+ if 1: # xxx unicode
+ jitdriver = JitDriver(greens = [], reds = ['m', 'total'])
+ def f(m):
+ total = 0
+ while m >= 0:
+ jitdriver.can_enter_jit(m=m, total=total)
+ jitdriver.jit_merge_point(m=m, total=total)
+ string = 's0dgkwn349tXOGIEQR!'[m:]
+ c = string[2*m]
+ total += ord(c)
+ m -= 1
+ return total
+ res = self.meta_interp(f, [6])
+ assert res == sum(map(ord, 'sgn9OE!'))
+ self.check_loops(call=0, call_pure=0,
+ newstr=0, strgetitem=1, strsetitem=0, strlen=0)
+
+ def test_strconcat_pure(self):
+ for dochr in [chr, ]: #unichr]:
+ @dont_look_inside
+ def escape(x):
+ pass
+ def f(n, m):
+ s = dochr(n) + dochr(m)
+ if not we_are_jitted():
+ escape(s)
+ return 42
+ self.interp_operations(f, [65, 66])
+ py.test.xfail()
+ self.check_operations_history(newstr=0, strsetitem=0,
+ newunicode=0, unicodesetitem=0,
+ call=0, call_pure=0)
+
+
class TestOOtype(StringTests, OOJitMixin):
CALL = "oosend"
CALL_PURE = "oosend_pure"
Modified: pypy/branch/jit-str/pypy/jit/metainterp/warmstate.py
==============================================================================
--- pypy/branch/jit-str/pypy/jit/metainterp/warmstate.py (original)
+++ pypy/branch/jit-str/pypy/jit/metainterp/warmstate.py Wed Sep 22 11:52:51 2010
@@ -83,6 +83,9 @@
return history.ConstFloat(value)
else:
return history.BoxFloat(value)
+ elif isinstance(value, (str, unicode)):
+ assert len(value) == 1 # must be a character
+ value = ord(value)
else:
value = intmask(value)
if in_const_box:
Modified: pypy/branch/jit-str/pypy/rpython/lltypesystem/rstr.py
==============================================================================
--- pypy/branch/jit-str/pypy/rpython/lltypesystem/rstr.py (original)
+++ pypy/branch/jit-str/pypy/rpython/lltypesystem/rstr.py Wed Sep 22 11:52:51 2010
@@ -65,8 +65,8 @@
dst = llmemory.cast_ptr_to_adr(dst) + _str_ofs(dststart)
llmemory.raw_memcopy(src, dst, llmemory.sizeof(CHAR_TP) * length)
copy_string_contents._always_inline_ = True
- copy_string_contents.oopspec = (
- '%s.copy_contents(src, dst, srcstart, dststart, length)' % name)
+ #copy_string_contents.oopspec = (
+ # '%s.copy_contents(src, dst, srcstart, dststart, length)' % name)
return func_with_new_name(copy_string_contents, 'copy_%s_contents' % name)
copy_string_contents = _new_copy_contents_fun(STR, Char, 'string')
@@ -326,6 +326,7 @@
s1.copy_contents(s1, newstr, 0, 0, len1)
s1.copy_contents(s2, newstr, 0, len1, len2)
return newstr
+ #ll_strconcat.oopspec = 'stroruni.concat(s1, s2)'
@purefunction
def ll_strip(s, ch, left, right):
@@ -693,7 +694,6 @@
i += 1
return result
- @purefunction
def ll_stringslice_startonly(s1, start):
len1 = len(s1.chars)
newstr = s1.malloc(len1 - start)
@@ -702,8 +702,8 @@
assert start >= 0
s1.copy_contents(s1, newstr, start, 0, lgt)
return newstr
+ ll_stringslice_startonly.oopspec = 'stroruni.slice_startonly(s1, start)'
- @purefunction
def ll_stringslice_startstop(s1, start, stop):
if stop >= len(s1.chars):
if start == 0:
@@ -715,14 +715,16 @@
assert lgt >= 0
s1.copy_contents(s1, newstr, start, 0, lgt)
return newstr
+ ll_stringslice_startstop.oopspec = ('stroruni.slice_startstop(s1, '
+ 'start, stop)')
- @purefunction
def ll_stringslice_minusone(s1):
newlen = len(s1.chars) - 1
newstr = s1.malloc(newlen)
assert newlen >= 0
s1.copy_contents(s1, newstr, 0, 0, newlen)
return newstr
+ ll_stringslice_minusone.oopspec = 'stroruni.slice_minusone(s1)'
def ll_split_chr(LIST, s, c):
chars = s.chars
More information about the Pypy-commit
mailing list