Example #1
0
    def _optimize_call_arrayop(self, op, source_box, dest_box,
                               source_start_box, dest_start_box, length_box):
        length = self.get_constant_box(length_box)
        if length and length.getint() == 0:
            return True  # 0-length arraycopy or arraymove

        source_info = getptrinfo(source_box)
        dest_info = getptrinfo(dest_box)
        source_start_box = self.get_constant_box(source_start_box)
        dest_start_box = self.get_constant_box(dest_start_box)
        extrainfo = op.getdescr().get_extra_info()
        if (source_start_box and dest_start_box and length and
            ((dest_info and dest_info.is_virtual()) or length.getint() <= 8)
                and ((source_info and source_info.is_virtual())
                     or length.getint() <= 8)
                and extrainfo.single_write_descr_array
                is not None):  #<-sanity check
            source_start = source_start_box.getint()
            dest_start = dest_start_box.getint()
            arraydescr = extrainfo.single_write_descr_array
            if arraydescr.is_array_of_structs():
                return False  # not supported right now

            index_current = 0
            index_delta = +1
            index_stop = length.getint()
            if (source_box is dest_box and  # ARRAYMOVE only
                    source_start < dest_start):  # iterate in reverse order
                index_current = index_stop - 1
                index_delta = -1
                index_stop = -1

            # XXX fish fish fish
            while index_current != index_stop:
                index = index_current
                index_current += index_delta
                assert index >= 0
                if source_info and source_info.is_virtual():
                    val = source_info.getitem(arraydescr, index + source_start)
                else:
                    opnum = OpHelpers.getarrayitem_for_descr(arraydescr)
                    newop = ResOperation(
                        opnum, [source_box,
                                ConstInt(index + source_start)],
                        descr=arraydescr)
                    self.optimizer.send_extra_operation(newop)
                    val = newop
                if val is None:
                    continue
                if dest_info and dest_info.is_virtual():
                    dest_info.setitem(arraydescr, index + dest_start,
                                      get_box_replacement(dest_box), val)
                else:
                    newop = ResOperation(
                        rop.SETARRAYITEM_GC,
                        [dest_box, ConstInt(index + dest_start), val],
                        descr=arraydescr)
                    self.optimizer.send_extra_operation(newop)
            return True
        return False
Example #2
0
 def produce_short_preamble_ops(self, structbox, descr, index, optimizer, shortboxes):
     if self._items is None:
         return
     if index >= len(self._items):
         # we don't know about this item
         return
     item = self._items[index]
     if item is not None:
         op = optimizer.get_box_replacement(item)
         opnum = OpHelpers.getarrayitem_for_descr(descr)
         getarrayitem_op = ResOperation(opnum, [structbox, ConstInt(index)], descr=descr)
         shortboxes.add_heap_op(op, getarrayitem_op)
Example #3
0
 def produce_short_preamble_ops(self, structbox, descr, index, optimizer,
                                shortboxes):
     if self._items is None:
         return
     if index >= len(self._items):
         # we don't know about this item
         return
     item = self._items[index]
     if item is not None:
         op = optimizer.get_box_replacement(item)
         opnum = OpHelpers.getarrayitem_for_descr(descr)
         getarrayitem_op = ResOperation(
             opnum, [structbox, ConstInt(index)], descr=descr)
         shortboxes.add_heap_op(op, getarrayitem_op)
Example #4
0
    def _optimize_CALL_ARRAYCOPY(self, op):
        length = self.get_constant_box(op.getarg(5))
        if length and length.getint() == 0:
            return None  # 0-length arraycopy

        source_info = self.getptrinfo(op.getarg(1))
        dest_info = self.getptrinfo(op.getarg(2))
        source_start_box = self.get_constant_box(op.getarg(3))
        dest_start_box = self.get_constant_box(op.getarg(4))
        extrainfo = op.getdescr().get_extra_info()
        if (source_start_box and dest_start_box and length and
            ((dest_info and dest_info.is_virtual()) or length.getint() <= 8)
                and ((source_info and source_info.is_virtual())
                     or length.getint() <= 8)
                and extrainfo.single_write_descr_array
                is not None):  #<-sanity check
            source_start = source_start_box.getint()
            dest_start = dest_start_box.getint()
            arraydescr = extrainfo.single_write_descr_array
            if arraydescr.is_array_of_structs():
                return self.emit(op)  # not supported right now

            # XXX fish fish fish
            for index in range(length.getint()):
                if source_info and source_info.is_virtual():
                    val = source_info.getitem(arraydescr, index + source_start)
                else:
                    opnum = OpHelpers.getarrayitem_for_descr(arraydescr)
                    newop = ResOperation(
                        opnum, [op.getarg(1),
                                ConstInt(index + source_start)],
                        descr=arraydescr)
                    self.optimizer.send_extra_operation(newop)
                    val = newop
                if val is None:
                    continue
                if dest_info and dest_info.is_virtual():
                    dest_info.setitem(arraydescr, index + dest_start,
                                      self.get_box_replacement(op.getarg(2)),
                                      val)
                else:
                    newop = ResOperation(
                        rop.SETARRAYITEM_GC,
                        [op.getarg(2),
                         ConstInt(index + dest_start), val],
                        descr=arraydescr)
                    self.optimizer.send_extra_operation(newop)
            return None
        return self.emit(op)
Example #5
0
    def _optimize_CALL_ARRAYCOPY(self, op):
        length = self.get_constant_box(op.getarg(5))
        if length and length.getint() == 0:
            return True # 0-length arraycopy

        source_info = self.getptrinfo(op.getarg(1))
        dest_info = self.getptrinfo(op.getarg(2))
        source_start_box = self.get_constant_box(op.getarg(3))
        dest_start_box = self.get_constant_box(op.getarg(4))
        extrainfo = op.getdescr().get_extra_info()
        if (source_start_box and dest_start_box
            and length and ((dest_info and dest_info.is_virtual()) or
                            length.getint() <= 8) and
            ((source_info and source_info.is_virtual()) or length.getint() <= 8)
            and len(extrainfo.write_descrs_arrays) == 1):   # <-sanity check
            source_start = source_start_box.getint()
            dest_start = dest_start_box.getint()
            arraydescr = extrainfo.write_descrs_arrays[0]
            if arraydescr.is_array_of_structs():
                return False       # not supported right now

            # XXX fish fish fish
            for index in range(length.getint()):
                if source_info and source_info.is_virtual():
                    val = source_info.getitem(arraydescr, index + source_start)
                else:
                    opnum = OpHelpers.getarrayitem_for_descr(arraydescr)
                    newop = ResOperation(opnum,
                                      [op.getarg(1),
                                       ConstInt(index + source_start)],
                                       descr=arraydescr)
                    self.optimizer.send_extra_operation(newop)
                    val = newop
                if val is None:
                    continue
                if dest_info and dest_info.is_virtual():
                    dest_info.setitem(arraydescr, index + dest_start,
                                      self.get_box_replacement(op.getarg(2)),
                                      val)
                else:
                    newop = ResOperation(rop.SETARRAYITEM_GC,
                                         [op.getarg(2),
                                          ConstInt(index + dest_start),
                                          val],
                                         descr=arraydescr)
                    self.emit_operation(newop)
            return True
        return False
Example #6
0
def patch_new_loop_to_load_virtualizable_fields(loop, jitdriver_sd, vable):
    # XXX merge with rewriting
    vinfo = jitdriver_sd.virtualizable_info
    extra_ops = []
    inputargs = loop.inputargs
    vable_box = inputargs[jitdriver_sd.index_of_virtualizable]
    i = jitdriver_sd.num_red_args
    loop.inputargs = inputargs[:i]
    for descr in vinfo.static_field_descrs:
        assert i < len(inputargs)
        box = inputargs[i]
        opnum = OpHelpers.getfield_for_descr(descr)
        emit_op(extra_ops,
                ResOperation(opnum, [vable_box], descr))
        box.set_forwarded(extra_ops[-1])
        i += 1
    arrayindex = 0
    for descr in vinfo.array_field_descrs:
        arraylen = vinfo.get_array_length(vable, arrayindex)
        arrayop = ResOperation(rop.GETFIELD_GC_R, [vable_box], descr)
        emit_op(extra_ops, arrayop)
        arraydescr = vinfo.array_descrs[arrayindex]
        assert i + arraylen <= len(inputargs)
        for index in range(arraylen):
            opnum = OpHelpers.getarrayitem_for_descr(arraydescr)
            box = inputargs[i]
            emit_op(extra_ops,
                ResOperation(opnum,
                             [arrayop, ConstInt(index)],
                             descr=arraydescr))
            i += 1
            box.set_forwarded(extra_ops[-1])
        arrayindex += 1
    assert i == len(inputargs)
    for op in loop.operations:
        emit_op(extra_ops, op)
    loop.operations = extra_ops
Example #7
0
def patch_new_loop_to_load_virtualizable_fields(loop, jitdriver_sd, vable):
    # XXX merge with rewriting
    vinfo = jitdriver_sd.virtualizable_info
    extra_ops = []
    inputargs = loop.inputargs
    vable_box = inputargs[jitdriver_sd.index_of_virtualizable]
    i = jitdriver_sd.num_red_args
    loop.inputargs = inputargs[:i]
    for descr in vinfo.static_field_descrs:
        assert i < len(inputargs)
        box = inputargs[i]
        opnum = OpHelpers.getfield_for_descr(descr)
        emit_op(extra_ops,
                ResOperation(opnum, [vable_box], descr=descr))
        box.set_forwarded(extra_ops[-1])
        i += 1
    arrayindex = 0
    for descr in vinfo.array_field_descrs:
        arraylen = vinfo.get_array_length(vable, arrayindex)
        arrayop = ResOperation(rop.GETFIELD_GC_R, [vable_box], descr=descr)
        emit_op(extra_ops, arrayop)
        arraydescr = vinfo.array_descrs[arrayindex]
        assert i + arraylen <= len(inputargs)
        for index in range(arraylen):
            opnum = OpHelpers.getarrayitem_for_descr(arraydescr)
            box = inputargs[i]
            emit_op(extra_ops,
                ResOperation(opnum,
                             [arrayop, ConstInt(index)],
                             descr=arraydescr))
            i += 1
            box.set_forwarded(extra_ops[-1])
        arrayindex += 1
    assert i == len(inputargs)
    for op in loop.operations:
        emit_op(extra_ops, op)
    loop.operations = extra_ops