Author: Hakan Ardo <ha...@debian.org> Branch: jit-optimizeopt-cleanups Changeset: r47635:28e8a5accc4b Date: 2011-09-27 21:04 +0200 http://bitbucket.org/pypy/pypy/changeset/28e8a5accc4b/
Log: Convert the optimizer attribute of VirtualValue into an argument of force_box() this way the ops produced by forcing a virtual is emitted from the optimzier stage doing the forcing and not the stage that produced the virtual. Then we make sure to force all virtual strings that survives the OptString stage diff --git a/pypy/jit/metainterp/optimizeopt/optimizer.py b/pypy/jit/metainterp/optimizeopt/optimizer.py --- a/pypy/jit/metainterp/optimizeopt/optimizer.py +++ b/pypy/jit/metainterp/optimizeopt/optimizer.py @@ -114,13 +114,13 @@ self.lenbound = other.lenbound.clone() - def force_box(self): + def force_box(self, optforce): return self.box def get_key_box(self): return self.box - def force_at_end_of_preamble(self, already_forced): + def force_at_end_of_preamble(self, already_forced, optforce): return self def get_args_for_fail(self, modifier): @@ -507,7 +507,7 @@ pass else: self.ensure_imported(value) - op.setarg(i, value.force_box()) + op.setarg(i, value.force_box(self)) self.metainterp_sd.profiler.count(jitprof.OPT_OPS) if op.is_guard(): self.metainterp_sd.profiler.count(jitprof.OPT_GUARDS) diff --git a/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py b/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py --- a/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py +++ b/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py @@ -70,7 +70,7 @@ class FakeVirtualValue(virtualize.AbstractVirtualValue): def _make_virtual(self, *args): return FakeVInfo() - v1 = FakeVirtualValue(None, None, None) + v1 = FakeVirtualValue(None, None) vinfo1 = v1.make_virtual_info(None, [1, 2, 4]) vinfo2 = v1.make_virtual_info(None, [1, 2, 4]) assert vinfo1 is vinfo2 diff --git a/pypy/jit/metainterp/optimizeopt/unroll.py b/pypy/jit/metainterp/optimizeopt/unroll.py --- a/pypy/jit/metainterp/optimizeopt/unroll.py +++ b/pypy/jit/metainterp/optimizeopt/unroll.py @@ -167,8 +167,9 @@ virtual_state = modifier.get_virtual_state(jump_args) values = [self.getvalue(arg) for arg in jump_args] - inputargs = virtual_state.make_inputargs(values) - short_inputargs = virtual_state.make_inputargs(values, keyboxes=True) + inputargs = virtual_state.make_inputargs(values, self.optimizer) + short_inputargs = virtual_state.make_inputargs(values, self.optimizer, + keyboxes=True) self.constant_inputargs = {} for box in jump_args: @@ -211,7 +212,7 @@ continue seen[box] = True value = preamble_optimizer.getvalue(box) - value.force_box() + value.force_box(preamble_optimizer) preamble_optimizer.flush() inputarg_setup_ops += preamble_optimizer.newoperations @@ -244,7 +245,7 @@ virtual_state) loop.inputargs = inputargs - args = [preamble_optimizer.getvalue(self.short_boxes.original(a)).force_box()\ + args = [preamble_optimizer.getvalue(self.short_boxes.original(a)).force_box(preamble_optimizer)\ for a in inputargs] jmp = ResOperation(rop.JUMP, args, None) jmp.setdescr(loop.token) @@ -335,9 +336,10 @@ assert jumpop original_jumpargs = jumpop.getarglist()[:] values = [self.getvalue(arg) for arg in jumpop.getarglist()] - jumpargs = virtual_state.make_inputargs(values) + jumpargs = virtual_state.make_inputargs(values, self.optimizer) jumpop.initarglist(jumpargs) - jmp_to_short_args = virtual_state.make_inputargs(values, keyboxes=True) + jmp_to_short_args = virtual_state.make_inputargs(values, self.optimizer, + keyboxes=True) self.short_inliner = Inliner(short_inputargs, jmp_to_short_args) for box, const in self.constant_inputargs.items(): @@ -468,7 +470,7 @@ inputargs.append(box) box = newresult if box in self.optimizer.values: - box = self.optimizer.values[box].force_box() + box = self.optimizer.values[box].force_box(self.optimizer) jumpargs.append(box) @@ -518,7 +520,7 @@ values = [self.getvalue(arg) for arg in op.getarglist()] - args = sh.virtual_state.make_inputargs(values, + args = sh.virtual_state.make_inputargs(values, self.optimizer, keyboxes=True) inliner = Inliner(sh.inputargs, args) diff --git a/pypy/jit/metainterp/optimizeopt/virtualize.py b/pypy/jit/metainterp/optimizeopt/virtualize.py --- a/pypy/jit/metainterp/optimizeopt/virtualize.py +++ b/pypy/jit/metainterp/optimizeopt/virtualize.py @@ -10,13 +10,12 @@ class AbstractVirtualValue(optimizer.OptValue): - _attrs_ = ('optimizer', 'keybox', 'source_op', '_cached_vinfo') + _attrs_ = ('keybox', 'source_op', '_cached_vinfo') box = None level = optimizer.LEVEL_NONNULL _cached_vinfo = None - def __init__(self, optimizer, keybox, source_op=None): - self.optimizer = optimizer + def __init__(self, keybox, source_op=None): self.keybox = keybox # only used as a key in dictionaries self.source_op = source_op # the NEW_WITH_VTABLE/NEW_ARRAY operation # that builds this box @@ -29,17 +28,17 @@ return self.keybox return self.box - def force_box(self): + def force_box(self, optforce): if self.box is None: - self.optimizer.forget_numberings(self.keybox) - self._really_force() + optforce.forget_numberings(self.keybox) + self._really_force(optforce) return self.box - def force_at_end_of_preamble(self, already_forced): + def force_at_end_of_preamble(self, already_forced, optforce): value = already_forced.get(self, None) if value: return value - return OptValue(self.force_box()) + return OptValue(self.force_box(optforce)) def make_virtual_info(self, modifier, fieldnums): if fieldnums is None: @@ -70,10 +69,11 @@ get_fielddescrlist_cache._annspecialcase_ = "specialize:memo" class AbstractVirtualStructValue(AbstractVirtualValue): - _attrs_ = ('_fields', '_cached_sorted_fields') + _attrs_ = ('_fields', 'cpu', '_cached_sorted_fields') - def __init__(self, optimizer, keybox, source_op=None): - AbstractVirtualValue.__init__(self, optimizer, keybox, source_op) + def __init__(self, cpu, keybox, source_op=None): + AbstractVirtualValue.__init__(self, keybox, source_op) + self.cpu = cpu self._fields = {} self._cached_sorted_fields = None @@ -87,26 +87,26 @@ def _get_descr(self): raise NotImplementedError - def _is_immutable_and_filled_with_constants(self): + def _is_immutable_and_filled_with_constants(self, optforce): count = self._get_descr().count_fields_if_immutable() if count != len(self._fields): # always the case if count == -1 return False for value in self._fields.itervalues(): - subbox = value.force_box() + subbox = value.force_box(optforce) if not isinstance(subbox, Const): return False return True - def force_at_end_of_preamble(self, already_forced): + def force_at_end_of_preamble(self, already_forced, optforce): if self in already_forced: return self already_forced[self] = self if self._fields: for ofs in self._fields.keys(): - self._fields[ofs] = self._fields[ofs].force_at_end_of_preamble(already_forced) + self._fields[ofs] = self._fields[ofs].force_at_end_of_preamble(already_forced, optforce) return self - def _really_force(self): + def _really_force(self, optforce): op = self.source_op assert op is not None # ^^^ This case should not occur any more (see test_bug_3). @@ -114,17 +114,17 @@ if not we_are_translated(): op.name = 'FORCE ' + self.source_op.name - if self._is_immutable_and_filled_with_constants(): - box = self.optimizer.optimizer.constant_fold(op) + if self._is_immutable_and_filled_with_constants(optforce): + box = optforce.optimizer.constant_fold(op) self.make_constant(box) for ofs, value in self._fields.iteritems(): - subbox = value.force_box() + subbox = value.force_box(optforce) assert isinstance(subbox, Const) - execute(self.optimizer.optimizer.cpu, None, rop.SETFIELD_GC, + execute(optforce.optimizer.cpu, None, rop.SETFIELD_GC, ofs, box, subbox) # keep self._fields, because it's all immutable anyway else: - self.optimizer.emit_operation(op) + optforce.emit_operation(op) self.box = box = op.result # iteritems = self._fields.iteritems() @@ -134,11 +134,11 @@ for ofs, value in iteritems: if value.is_null(): continue - subbox = value.force_box() + subbox = value.force_box(optforce) op = ResOperation(rop.SETFIELD_GC, [box, subbox], None, descr=ofs) - self.optimizer.emit_volatile_operation(op) + optforce.emit_volatile_operation(op) def _get_field_descr_list(self): _cached_sorted_fields = self._cached_sorted_fields @@ -155,7 +155,7 @@ else: lst = self._fields.keys() sort_descrs(lst) - cache = get_fielddescrlist_cache(self.optimizer.optimizer.cpu) + cache = get_fielddescrlist_cache(self.cpu) result = cache.get(lst, None) if result is None: cache[lst] = lst @@ -180,8 +180,8 @@ class VirtualValue(AbstractVirtualStructValue): level = optimizer.LEVEL_KNOWNCLASS - def __init__(self, optimizer, known_class, keybox, source_op=None): - AbstractVirtualStructValue.__init__(self, optimizer, keybox, source_op) + def __init__(self, cpu, known_class, keybox, source_op=None): + AbstractVirtualStructValue.__init__(self, cpu, keybox, source_op) assert isinstance(known_class, Const) self.known_class = known_class @@ -190,7 +190,7 @@ return modifier.make_virtual(self.known_class, fielddescrs) def _get_descr(self): - return vtable2descr(self.optimizer.optimizer.cpu, self.known_class.getint()) + return vtable2descr(self.cpu, self.known_class.getint()) def __repr__(self): cls_name = self.known_class.value.adr.ptr._obj._TYPE._name @@ -201,8 +201,8 @@ class VStructValue(AbstractVirtualStructValue): - def __init__(self, optimizer, structdescr, keybox, source_op=None): - AbstractVirtualStructValue.__init__(self, optimizer, keybox, source_op) + def __init__(self, cpu, structdescr, keybox, source_op=None): + AbstractVirtualStructValue.__init__(self, cpu, keybox, source_op) self.structdescr = structdescr def _make_virtual(self, modifier): @@ -215,10 +215,10 @@ class VArrayValue(AbstractVirtualValue): - def __init__(self, optimizer, arraydescr, size, keybox, source_op=None): - AbstractVirtualValue.__init__(self, optimizer, keybox, source_op) + def __init__(self, arraydescr, constvalue, size, keybox, source_op=None): + AbstractVirtualValue.__init__(self, keybox, source_op) self.arraydescr = arraydescr - self.constvalue = optimizer.new_const_item(arraydescr) + self.constvalue = constvalue self._items = [self.constvalue] * size def getlength(self): @@ -232,30 +232,30 @@ assert isinstance(itemvalue, optimizer.OptValue) self._items[index] = itemvalue - def force_at_end_of_preamble(self, already_forced): + def force_at_end_of_preamble(self, already_forced, optforce): if self in already_forced: return self already_forced[self] = self for index in range(len(self._items)): - self._items[index] = self._items[index].force_at_end_of_preamble(already_forced) + self._items[index] = self._items[index].force_at_end_of_preamble(already_forced, optforce) return self - def _really_force(self): + def _really_force(self, optforce): assert self.source_op is not None if not we_are_translated(): self.source_op.name = 'FORCE ' + self.source_op.name - self.optimizer.emit_operation(self.source_op) + optforce.emit_operation(self.source_op) self.box = box = self.source_op.result for index in range(len(self._items)): subvalue = self._items[index] if subvalue is not self.constvalue: if subvalue.is_null(): continue - subbox = subvalue.force_box() + subbox = subvalue.force_box(optforce) op = ResOperation(rop.SETARRAYITEM_GC, [box, ConstInt(index), subbox], None, descr=self.arraydescr) - self.optimizer.emit_volatile_operation(op) + optforce.emit_volatile_operation(op) def get_args_for_fail(self, modifier): if self.box is None and not modifier.already_seen_virtual(self.keybox): @@ -278,17 +278,18 @@ return OptVirtualize() def make_virtual(self, known_class, box, source_op=None): - vvalue = VirtualValue(self, known_class, box, source_op) + vvalue = VirtualValue(self.optimizer.cpu, known_class, box, source_op) self.make_equal_to(box, vvalue) return vvalue def make_varray(self, arraydescr, size, box, source_op=None): - vvalue = VArrayValue(self, arraydescr, size, box, source_op) + constvalue = self.new_const_item(arraydescr) + vvalue = VArrayValue(arraydescr, constvalue, size, box, source_op) self.make_equal_to(box, vvalue) return vvalue def make_vstruct(self, structdescr, box, source_op=None): - vvalue = VStructValue(self, structdescr, box, source_op) + vvalue = VStructValue(self.optimizer.cpu, structdescr, box, source_op) self.make_equal_to(box, vvalue) return vvalue diff --git a/pypy/jit/metainterp/optimizeopt/virtualstate.py b/pypy/jit/metainterp/optimizeopt/virtualstate.py --- a/pypy/jit/metainterp/optimizeopt/virtualstate.py +++ b/pypy/jit/metainterp/optimizeopt/virtualstate.py @@ -30,7 +30,7 @@ def _generate_guards(self, other, box, cpu, extra_guards): raise InvalidLoop - def enum_forced_boxes(self, boxes, value): + def enum_forced_boxes(self, boxes, value, optimizer): raise NotImplementedError def enum(self, virtual_state): @@ -100,14 +100,14 @@ def _generalization_of(self, other): raise NotImplementedError - def enum_forced_boxes(self, boxes, value): + def enum_forced_boxes(self, boxes, value, optimizer): assert isinstance(value, virtualize.AbstractVirtualStructValue) assert value.is_virtual() for i in range(len(self.fielddescrs)): v = value._fields[self.fielddescrs[i]] s = self.fieldstate[i] if s.position > self.position: - s.enum_forced_boxes(boxes, v) + s.enum_forced_boxes(boxes, v, optimizer) def _enum(self, virtual_state): for s in self.fieldstate: @@ -177,14 +177,14 @@ return False return True - def enum_forced_boxes(self, boxes, value): + def enum_forced_boxes(self, boxes, value, optimizer): assert isinstance(value, virtualize.VArrayValue) assert value.is_virtual() for i in range(len(self.fieldstate)): v = value._items[i] s = self.fieldstate[i] if s.position > self.position: - s.enum_forced_boxes(boxes, v) + s.enum_forced_boxes(boxes, v, optimizer) def _enum(self, virtual_state): for s in self.fieldstate: @@ -316,11 +316,11 @@ import pdb; pdb.set_trace() raise NotImplementedError - def enum_forced_boxes(self, boxes, value): + def enum_forced_boxes(self, boxes, value, optimizer): if self.level == LEVEL_CONSTANT: return assert 0 <= self.position_in_notvirtuals - boxes[self.position_in_notvirtuals] = value.force_box() + boxes[self.position_in_notvirtuals] = value.force_box(optimizer) def _enum(self, virtual_state): if self.level == LEVEL_CONSTANT: @@ -377,11 +377,11 @@ self.state[i].generate_guards(other.state[i], args[i], cpu, extra_guards, renum) - def make_inputargs(self, values, keyboxes=False): + def make_inputargs(self, values, optimizer, keyboxes=False): assert len(values) == len(self.state) inputargs = [None] * len(self.notvirtuals) for i in range(len(values)): - self.state[i].enum_forced_boxes(inputargs, values[i]) + self.state[i].enum_forced_boxes(inputargs, values[i], optimizer) if keyboxes: for i in range(len(values)): @@ -434,7 +434,8 @@ def get_virtual_state(self, jump_args): self.optimizer.force_at_end_of_preamble() already_forced = {} - values = [self.getvalue(box).force_at_end_of_preamble(already_forced) + values = [self.getvalue(box).force_at_end_of_preamble(already_forced, + self.optimizer) for box in jump_args] for value in values: diff --git a/pypy/jit/metainterp/optimizeopt/vstring.py b/pypy/jit/metainterp/optimizeopt/vstring.py --- a/pypy/jit/metainterp/optimizeopt/vstring.py +++ b/pypy/jit/metainterp/optimizeopt/vstring.py @@ -55,7 +55,7 @@ if string_optimizer is None: return None self.ensure_nonnull() - box = self.force_box() + box = self.force_box(string_optimizer) lengthbox = BoxInt() string_optimizer.emit_operation(ResOperation(mode.STRLEN, [box], lengthbox)) return lengthbox @@ -73,7 +73,7 @@ # given by 'targetbox', at the specified offset. Returns the offset # at the end of the copy. lengthbox = self.getstrlen(string_optimizer, mode) - srcbox = self.force_box() + srcbox = self.force_box(string_optimizer) return copy_str_content(string_optimizer, srcbox, targetbox, CONST_0, offsetbox, lengthbox, mode) @@ -81,12 +81,12 @@ class VAbstractStringValue(virtualize.AbstractVirtualValue): _attrs_ = ('mode',) - def __init__(self, string_optimizer, keybox, source_op, mode): - virtualize.AbstractVirtualValue.__init__(self, string_optimizer, keybox, + def __init__(self, keybox, source_op, mode): + virtualize.AbstractVirtualValue.__init__(self, keybox, source_op) self.mode = mode - def _really_force(self): + def _really_force(self, optforce): if self.mode is mode_string: s = self.get_constant_string_spec(mode_string) if s is not None: @@ -101,12 +101,12 @@ return assert self.source_op is not None self.box = box = self.source_op.result - lengthbox = self.getstrlen(self.optimizer, self.mode) + lengthbox = self.getstrlen(optforce, self.mode) op = ResOperation(self.mode.NEWSTR, [lengthbox], box) if not we_are_translated(): op.name = 'FORCE' - self.optimizer.emit_operation(op) - self.string_copy_parts(self.optimizer, box, CONST_0, self.mode) + optforce.emit_operation(op) + self.string_copy_parts(optforce, box, CONST_0, self.mode) class VStringPlainValue(VAbstractStringValue): @@ -143,11 +143,11 @@ def string_copy_parts(self, string_optimizer, targetbox, offsetbox, mode): if not self.is_virtual() and targetbox is not self.box: lengthbox = self.getstrlen(string_optimizer, mode) - srcbox = self.force_box() + srcbox = self.force_box(string_optimizer) return copy_str_content(string_optimizer, srcbox, targetbox, CONST_0, offsetbox, lengthbox, mode) for i in range(len(self._chars)): - charbox = self._chars[i].force_box() + charbox = self._chars[i].force_box(string_optimizer) if not (isinstance(charbox, Const) and charbox.same_constant(CONST_0)): string_optimizer.emit_operation(ResOperation(mode.STRSETITEM, [targetbox, offsetbox, @@ -251,8 +251,8 @@ self.vstart = vstart self.vlength = vlength - def getstrlen(self, _, mode): - return self.vlength.force_box() + def getstrlen(self, optforce, mode): + return self.vlength.force_box(optforce) @specialize.arg(1) def get_constant_string_spec(self, mode): @@ -270,8 +270,8 @@ def string_copy_parts(self, string_optimizer, targetbox, offsetbox, mode): lengthbox = self.getstrlen(string_optimizer, mode) return copy_str_content(string_optimizer, - self.vstr.force_box(), targetbox, - self.vstart.force_box(), offsetbox, + self.vstr.force_box(string_optimizer), targetbox, + self.vstart.force_box(string_optimizer), offsetbox, lengthbox, mode) def get_args_for_fail(self, modifier): @@ -375,17 +375,17 @@ return OptString() def make_vstring_plain(self, box, source_op, mode): - vvalue = VStringPlainValue(self, box, source_op, mode) + vvalue = VStringPlainValue(box, source_op, mode) self.make_equal_to(box, vvalue) return vvalue def make_vstring_concat(self, box, source_op, mode): - vvalue = VStringConcatValue(self, box, source_op, mode) + vvalue = VStringConcatValue(box, source_op, mode) self.make_equal_to(box, vvalue) return vvalue def make_vstring_slice(self, box, source_op, mode): - vvalue = VStringSliceValue(self, box, source_op, mode) + vvalue = VStringSliceValue(box, source_op, mode) self.make_equal_to(box, vvalue) return vvalue @@ -436,8 +436,8 @@ # if value.is_virtual() and isinstance(value, VStringSliceValue): fullindexbox = _int_add(self, - value.vstart.force_box(), - vindex.force_box()) + value.vstart.force_box(self), + vindex.force_box(self)) value = value.vstr vindex = self.getvalue(fullindexbox) # @@ -449,7 +449,7 @@ if res is not optimizer.CVAL_UNINITIALIZED_ZERO: return res # - resbox = _strgetitem(self, value.force_box(), vindex.force_box(), mode) + resbox = _strgetitem(self, value.force_box(self), vindex.force_box(self), mode) return self.getvalue(resbox) def optimize_STRLEN(self, op): @@ -478,11 +478,11 @@ if length.is_constant() and length.box.getint() == 0: return copy_str_content(self, - src.force_box(), - dst.force_box(), - srcstart.force_box(), - dststart.force_box(), - length.force_box(), + src.force_box(self), + dst.force_box(self), + srcstart.force_box(self), + dststart.force_box(self), + length.force_box(self), mode, need_next_offset=False ) @@ -547,16 +547,16 @@ return True # vstr.ensure_nonnull() - lengthbox = _int_sub(self, vstop.force_box(), - vstart.force_box()) + lengthbox = _int_sub(self, vstop.force_box(self), + vstart.force_box(self)) # if isinstance(vstr, VStringSliceValue): # double slicing s[i:j][k:l] vintermediate = vstr vstr = vintermediate.vstr startbox = _int_add(self, - vintermediate.vstart.force_box(), - vstart.force_box()) + vintermediate.vstart.force_box(self), + vstart.force_box(self)) vstart = self.getvalue(startbox) # value = self.make_vstring_slice(op.result, op, mode) @@ -594,8 +594,8 @@ do = EffectInfo.OS_STREQ_LENGTHOK else: do = EffectInfo.OS_STREQ_NONNULL - self.generate_modified_call(do, [v1.force_box(), - v2.force_box()], op.result, mode) + self.generate_modified_call(do, [v1.force_box(self), + v2.force_box(self)], op.result, mode) return True return False @@ -614,17 +614,17 @@ vchar1 = self.strgetitem(v1, optimizer.CVAL_ZERO, mode) vchar2 = self.strgetitem(v2, optimizer.CVAL_ZERO, mode) seo = self.optimizer.send_extra_operation - seo(ResOperation(rop.INT_EQ, [vchar1.force_box(), - vchar2.force_box()], + seo(ResOperation(rop.INT_EQ, [vchar1.force_box(self), + vchar2.force_box(self)], resultbox)) return True if isinstance(v1, VStringSliceValue): vchar = self.strgetitem(v2, optimizer.CVAL_ZERO, mode) do = EffectInfo.OS_STREQ_SLICE_CHAR - self.generate_modified_call(do, [v1.vstr.force_box(), - v1.vstart.force_box(), - v1.vlength.force_box(), - vchar.force_box()], + self.generate_modified_call(do, [v1.vstr.force_box(self), + v1.vstart.force_box(self), + v1.vlength.force_box(self), + vchar.force_box(self)], resultbox, mode) return True # @@ -635,7 +635,7 @@ if v1.is_null(): self.make_constant(resultbox, CONST_1) return True - op = ResOperation(rop.PTR_EQ, [v1.force_box(), + op = ResOperation(rop.PTR_EQ, [v1.force_box(self), llhelper.CONST_NULL], resultbox) self.emit_operation(op) @@ -652,8 +652,8 @@ do = EffectInfo.OS_STREQ_NONNULL_CHAR else: do = EffectInfo.OS_STREQ_CHECKNULL_CHAR - self.generate_modified_call(do, [v1.force_box(), - vchar.force_box()], resultbox, + self.generate_modified_call(do, [v1.force_box(self), + vchar.force_box(self)], resultbox, mode) return True # @@ -662,10 +662,10 @@ do = EffectInfo.OS_STREQ_SLICE_NONNULL else: do = EffectInfo.OS_STREQ_SLICE_CHECKNULL - self.generate_modified_call(do, [v1.vstr.force_box(), - v1.vstart.force_box(), - v1.vlength.force_box(), - v2.force_box()], resultbox, mode) + self.generate_modified_call(do, [v1.vstr.force_box(self), + v1.vstart.force_box(self), + v1.vlength.force_box(self), + v2.force_box(self)], resultbox, mode) return True return False @@ -681,8 +681,16 @@ if not self.enabled: self.emit_operation(op) return + dispatch_opt(self, op) - dispatch_opt(self, op) + def emit_operation(self, op): + for arg in op.getarglist(): + if arg in self.optimizer.values: + value = self.getvalue(arg) + if isinstance(value, VAbstractStringValue): + value.force_box(self) + self.next_optimization.propagate_forward(op) + dispatch_opt = make_dispatcher_method(OptString, 'optimize_', _______________________________________________ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit