Пример #1
0
def effectinfo_from_writeanalyze(effects,
                                 cpu,
                                 extraeffect=EffectInfo.EF_CAN_RAISE,
                                 oopspecindex=EffectInfo.OS_NONE,
                                 can_invalidate=False):
    from pypy.translator.backendopt.writeanalyze import top_set
    if effects is top_set or extraeffect == EffectInfo.EF_RANDOM_EFFECTS:
        readonly_descrs_fields = None
        readonly_descrs_arrays = None
        write_descrs_fields = None
        write_descrs_arrays = None
        extraeffect = EffectInfo.EF_RANDOM_EFFECTS
    else:
        readonly_descrs_fields = []
        readonly_descrs_arrays = []
        write_descrs_fields = []
        write_descrs_arrays = []

        def add_struct(descrs_fields, (_, T, fieldname)):
            T = deref(T)
            if consider_struct(T, fieldname):
                descr = cpu.fielddescrof(T, fieldname)
                descrs_fields.append(descr)

        def add_array(descrs_arrays, (_, T)):
            ARRAY = deref(T)
            if consider_array(ARRAY):
                descr = cpu.arraydescrof(ARRAY)
                descrs_arrays.append(descr)
Пример #2
0
def effectinfo_from_writeanalyze(effects, cpu,
                                 extraeffect=EffectInfo.EF_CAN_RAISE,
                                 oopspecindex=EffectInfo.OS_NONE,
                                 can_invalidate=False):
    from pypy.translator.backendopt.writeanalyze import top_set
    if effects is top_set or extraeffect == EffectInfo.EF_RANDOM_EFFECTS:
        readonly_descrs_fields = None
        readonly_descrs_arrays = None
        write_descrs_fields = None
        write_descrs_arrays = None
        extraeffect = EffectInfo.EF_RANDOM_EFFECTS
    else:
        readonly_descrs_fields = []
        readonly_descrs_arrays = []
        write_descrs_fields = []
        write_descrs_arrays = []

        def add_struct(descrs_fields, (_, T, fieldname)):
            T = deref(T)
            if consider_struct(T, fieldname):
                descr = cpu.fielddescrof(T, fieldname)
                descrs_fields.append(descr)

        def add_array(descrs_arrays, (_, T)):
            ARRAY = deref(T)
            if consider_array(ARRAY):
                descr = cpu.arraydescrof(ARRAY)
                descrs_arrays.append(descr)
Пример #3
0
    def test_quasi_immutable(self):
        from pypy.jit.metainterp.typesystem import deref

        class A(object):
            _immutable_fields_ = ["x", "y", "a?", "b?"]

        class B(A):
            pass

        def f():
            a = A()
            a.x = 42
            a.a = 142
            b = B()
            b.x = 43
            b.y = 41
            b.a = 44
            b.b = 45
            return B()

        t, typer, graph = self.gengraph(f, [])
        B_TYPE = deref(graph.getreturnvar().concretetype)
        accessor = B_TYPE._hints["immutable_fields"]
        assert accessor.fields == {"inst_y": IR_IMMUTABLE, "inst_b": IR_QUASIIMMUTABLE} or accessor.fields == {
            "ox": IR_IMMUTABLE,
            "oy": IR_IMMUTABLE,
            "oa": IR_QUASIIMMUTABLE,
            "ob": IR_QUASIIMMUTABLE,
        }  # for ootype
        found = []
        for op in graph.startblock.operations:
            if op.opname == "jit_force_quasi_immutable":
                found.append(op.args[1].value)
        assert found == ["mutate_a", "mutate_a", "mutate_b"]
Пример #4
0
    def test_quasi_immutable_array(self):
        from pypy.jit.metainterp.typesystem import deref

        class A(object):
            _immutable_fields_ = ["c?[*]"]

        class B(A):
            pass

        def f():
            a = A()
            a.c = [3, 4, 5]
            return A()

        t, typer, graph = self.gengraph(f, [])
        A_TYPE = deref(graph.getreturnvar().concretetype)
        accessor = A_TYPE._hints["immutable_fields"]
        assert accessor.fields == {"inst_c": IR_QUASIIMMUTABLE_ARRAY} or accessor.fields == {
            "oc": IR_QUASIIMMUTABLE_ARRAY
        }  # for ootype
        found = []
        for op in graph.startblock.operations:
            if op.opname == "jit_force_quasi_immutable":
                found.append(op.args[1].value)
        assert found == ["mutate_c"]
Пример #5
0
def builtin_func_for_spec(rtyper, oopspec_name, ll_args, ll_res):
    key = (oopspec_name, tuple(ll_args), ll_res)
    try:
        return rtyper._builtin_func_for_spec_cache[key]
    except (KeyError, AttributeError):
        pass
    args_s = [annmodel.lltype_to_annotation(v) for v in ll_args]
    if '.' not in oopspec_name:    # 'newxxx' operations
        LIST_OR_DICT = ll_res
    else:
        LIST_OR_DICT = ll_args[0]
    s_result = annmodel.lltype_to_annotation(ll_res)
    impl = setup_extra_builtin(rtyper, oopspec_name, len(args_s))
    if getattr(impl, 'need_result_type', False):
        bk = rtyper.annotator.bookkeeper
        args_s.insert(0, annmodel.SomePBC([bk.getdesc(deref(ll_res))]))
    #
    mixlevelann = MixLevelHelperAnnotator(rtyper)
    c_func = mixlevelann.constfunc(impl, args_s, s_result)
    mixlevelann.finish()
    #
    if not hasattr(rtyper, '_builtin_func_for_spec_cache'):
        rtyper._builtin_func_for_spec_cache = {}
    rtyper._builtin_func_for_spec_cache[key] = (c_func, LIST_OR_DICT)
    #
    return c_func, LIST_OR_DICT
Пример #6
0
    def test_immutable_fields_subclass_2(self):
        from pypy.jit.metainterp.typesystem import deref

        class A(object):
            _immutable_fields_ = ["x"]

            def __init__(self, x):
                self.x = x

        class B(A):
            _immutable_fields_ = ["y"]

            def __init__(self, x, y):
                A.__init__(self, x)
                self.y = y

        def f():
            return B(3, 5)

        t, typer, graph = self.gengraph(f, [])
        B_TYPE = deref(graph.getreturnvar().concretetype)
        accessor = B_TYPE._hints["immutable_fields"]
        assert accessor.fields == {"inst_x": IR_IMMUTABLE, "inst_y": IR_IMMUTABLE} or accessor.fields == {
            "ox": IR_IMMUTABLE,
            "oy": IR_IMMUTABLE,
        }  # for ootype
Пример #7
0
    def test_quasi_immutable(self):
        from pypy.jit.metainterp.typesystem import deref

        class A(object):
            _immutable_fields_ = ['x', 'y', 'a?', 'b?']

        class B(A):
            pass

        def f():
            a = A()
            a.x = 42
            a.a = 142
            b = B()
            b.x = 43
            b.y = 41
            b.a = 44
            b.b = 45
            return B()

        t, typer, graph = self.gengraph(f, [])
        B_TYPE = deref(graph.getreturnvar().concretetype)
        accessor = B_TYPE._hints["immutable_fields"]
        assert accessor.fields == {"inst_y": IR_IMMUTABLE,
                                   "inst_b": IR_QUASIIMMUTABLE} or \
               accessor.fields == {"ox": IR_IMMUTABLE,
                                   "oy": IR_IMMUTABLE,
                                   "oa": IR_QUASIIMMUTABLE,
                                   "ob": IR_QUASIIMMUTABLE} # for ootype
        found = []
        for op in graph.startblock.operations:
            if op.opname == 'jit_force_quasi_immutable':
                found.append(op.args[1].value)
        assert found == ['mutate_a', 'mutate_a', 'mutate_b']
Пример #8
0
    def test_immutable_fields_subclass_2(self):
        from pypy.jit.metainterp.typesystem import deref

        class A(object):
            _immutable_fields_ = ["x"]

            def __init__(self, x):
                self.x = x

        class B(A):
            _immutable_fields_ = ["y"]

            def __init__(self, x, y):
                A.__init__(self, x)
                self.y = y

        def f():
            return B(3, 5)

        t, typer, graph = self.gengraph(f, [])
        B_TYPE = deref(graph.getreturnvar().concretetype)
        accessor = B_TYPE._hints["immutable_fields"]
        assert accessor.fields == {"inst_x": IR_IMMUTABLE,
                                   "inst_y": IR_IMMUTABLE} or \
               accessor.fields == {"ox": IR_IMMUTABLE,
                                   "oy": IR_IMMUTABLE} # for ootype
Пример #9
0
def builtin_func_for_spec(rtyper, oopspec_name, ll_args, ll_res):
    key = (oopspec_name, tuple(ll_args), ll_res)
    try:
        return rtyper._builtin_func_for_spec_cache[key]
    except (KeyError, AttributeError):
        pass
    args_s = [annmodel.lltype_to_annotation(v) for v in ll_args]
    if "." not in oopspec_name:  # 'newxxx' operations
        LIST_OR_DICT = ll_res
    else:
        LIST_OR_DICT = ll_args[0]
    s_result = annmodel.lltype_to_annotation(ll_res)
    impl = setup_extra_builtin(rtyper, oopspec_name, len(args_s))
    if getattr(impl, "need_result_type", False):
        bk = rtyper.annotator.bookkeeper
        args_s.insert(0, annmodel.SomePBC([bk.getdesc(deref(ll_res))]))
    #
    mixlevelann = MixLevelHelperAnnotator(rtyper)
    c_func = mixlevelann.constfunc(impl, args_s, s_result)
    mixlevelann.finish()
    #
    if not hasattr(rtyper, "_builtin_func_for_spec_cache"):
        rtyper._builtin_func_for_spec_cache = {}
    rtyper._builtin_func_for_spec_cache[key] = (c_func, LIST_OR_DICT)
    #
    return c_func, LIST_OR_DICT
Пример #10
0
def builtin_func_for_spec(rtyper, oopspec_name, ll_args, ll_res,
                          extra=None, extrakey=None):
    assert (extra is None) == (extrakey is None)
    key = (oopspec_name, tuple(ll_args), ll_res, extrakey)
    try:
        return rtyper._builtin_func_for_spec_cache[key]
    except (KeyError, AttributeError):
        pass
    args_s = [annmodel.lltype_to_annotation(v) for v in ll_args]
    if '.' not in oopspec_name:    # 'newxxx' operations
        LIST_OR_DICT = ll_res
    else:
        LIST_OR_DICT = ll_args[0]
    s_result = annmodel.lltype_to_annotation(ll_res)
    impl = setup_extra_builtin(rtyper, oopspec_name, len(args_s), extra)
    if getattr(impl, 'need_result_type', False):
        bk = rtyper.annotator.bookkeeper
        args_s.insert(0, annmodel.SomePBC([bk.getdesc(deref(ll_res))]))
    #
    if hasattr(rtyper, 'annotator'):  # regular case
        mixlevelann = MixLevelHelperAnnotator(rtyper)
        c_func = mixlevelann.constfunc(impl, args_s, s_result)
        mixlevelann.finish()
    else:
        # for testing only
        c_func = Constant(oopspec_name,
                          lltype.Ptr(lltype.FuncType(ll_args, ll_res)))
    #
    if not hasattr(rtyper, '_builtin_func_for_spec_cache'):
        rtyper._builtin_func_for_spec_cache = {}
    rtyper._builtin_func_for_spec_cache[key] = (c_func, LIST_OR_DICT)
    #
    return c_func, LIST_OR_DICT
Пример #11
0
 def test_immutable_subclass_2(self):
     from pypy.jit.metainterp.typesystem import deref
     class A(object):
         pass
     class B(A):
         _immutable_ = True
     def f():
         A()
         B().v = 123
         return B()
     t, typer, graph = self.gengraph(f, [])
     B_TYPE = deref(graph.getreturnvar().concretetype)
     assert B_TYPE._hints["immutable"]
Пример #12
0
def effectinfo_from_writeanalyze(effects, cpu,
                                 forces_virtual_or_virtualizable=False):
    from pypy.translator.backendopt.writeanalyze import top_set
    if effects is top_set:
        return None
    readonly_descrs_fields = []
    # readonly_descrs_arrays = [] --- not enabled for now
    write_descrs_fields = []
    write_descrs_arrays = []

    def add_struct(descrs_fields, (_, T, fieldname)):
        T = deref(T)
        if consider_struct(T, fieldname):
            descr = cpu.fielddescrof(T, fieldname)
            descrs_fields.append(descr)
Пример #13
0
 def test_immutable_subclass_void(self):
     from pypy.jit.metainterp.typesystem import deref
     class A(object):
         pass
     class B(A):
         _immutable_ = True
     def myfunc():
         pass
     def f():
         A().f = myfunc    # it's ok to add Void attributes to A
         B().v = 123       # even though only B is declared _immutable_
         return B()
     t, typer, graph = self.gengraph(f, [])
     B_TYPE = deref(graph.getreturnvar().concretetype)
     assert B_TYPE._hints["immutable"]
Пример #14
0
    def test_immutable_subclass_2(self):
        from pypy.jit.metainterp.typesystem import deref

        class A(object):
            pass

        class B(A):
            _immutable_ = True

        def f():
            A()
            B().v = 123
            return B()

        t, typer, graph = self.gengraph(f, [])
        B_TYPE = deref(graph.getreturnvar().concretetype)
        assert B_TYPE._hints["immutable"]
Пример #15
0
def effectinfo_from_writeanalyze(effects, cpu,
                                 extraeffect=EffectInfo.EF_CAN_RAISE,
                                 oopspecindex=EffectInfo.OS_NONE,
                                 can_invalidate=False):
    from pypy.translator.backendopt.writeanalyze import top_set
    if effects is top_set:
        return None
    readonly_descrs_fields = []
    # readonly_descrs_arrays = [] --- not enabled for now
    write_descrs_fields = []
    write_descrs_arrays = []

    def add_struct(descrs_fields, (_, T, fieldname)):
        T = deref(T)
        if consider_struct(T, fieldname):
            descr = cpu.fielddescrof(T, fieldname)
            descrs_fields.append(descr)
Пример #16
0
    def test_immutable_fields(self):
        from pypy.jit.metainterp.typesystem import deref
        class A(object):
            _immutable_fields_ = ["x", "y[*]"]

            def __init__(self, x, y):
                self.x = x
                self.y = y

        def f():
            return A(3, [])
        t, typer, graph = self.gengraph(f, [])
        A_TYPE = deref(graph.getreturnvar().concretetype)
        accessor = A_TYPE._hints["immutable_fields"]
        assert accessor.fields == {"inst_x": IR_IMMUTABLE,
                                   "inst_y": IR_IMMUTABLE_ARRAY} or \
               accessor.fields == {"ox": IR_IMMUTABLE,
                                   "oy": IR_IMMUTABLE_ARRAY} # for ootype
Пример #17
0
    def test_immutable_fields(self):
        from pypy.jit.metainterp.typesystem import deref

        class A(object):
            _immutable_fields_ = ["x", "y[*]"]

            def __init__(self, x, y):
                self.x = x
                self.y = y

        def f():
            return A(3, [])

        t, typer, graph = self.gengraph(f, [])
        A_TYPE = deref(graph.getreturnvar().concretetype)
        accessor = A_TYPE._hints["immutable_fields"]
        assert accessor.fields == {"inst_x" : "", "inst_y" : "[*]"} or \
               accessor.fields == {"ox" : "", "oy" : "[*]"} # for ootype
Пример #18
0
    def test_immutable_subclass_void(self):
        from pypy.jit.metainterp.typesystem import deref

        class A(object):
            pass

        class B(A):
            _immutable_ = True

        def myfunc():
            pass

        def f():
            A().f = myfunc  # it's ok to add Void attributes to A
            B().v = 123  # even though only B is declared _immutable_
            return B()

        t, typer, graph = self.gengraph(f, [])
        B_TYPE = deref(graph.getreturnvar().concretetype)
        assert B_TYPE._hints["immutable"]
Пример #19
0
 def test_immutable_ok_inheritance_2(self):
     from pypy.jit.metainterp.typesystem import deref
     class A(object):
         _immutable_fields_ = ['v']
     class B(A):
         _immutable_ = True
     def f():
         A().v = 123
         B().w = 456
         return B()
     t, typer, graph = self.gengraph(f, [])
     B_TYPE = deref(graph.getreturnvar().concretetype)
     assert B_TYPE._hints["immutable"]
     try:
         A_TYPE = B_TYPE.super
     except AttributeError:
         A_TYPE = B_TYPE._superclass  # for ootype
     accessor = A_TYPE._hints["immutable_fields"]
     assert accessor.fields == {"inst_v": IR_IMMUTABLE} or \
            accessor.fields == {"ov": IR_IMMUTABLE} # for ootype
Пример #20
0
    def test_quasi_immutable_array(self):
        from pypy.jit.metainterp.typesystem import deref

        class A(object):
            _immutable_fields_ = ['c?[*]']

        class B(A):
            pass

        def f():
            a = A()
            a.c = [3, 4, 5]
            return A()

        t, typer, graph = self.gengraph(f, [])
        A_TYPE = deref(graph.getreturnvar().concretetype)
        accessor = A_TYPE._hints["immutable_fields"]
        assert accessor.fields == {"inst_c": IR_QUASIIMMUTABLE_ARRAY} or \
               accessor.fields == {"oc": IR_QUASIIMMUTABLE_ARRAY} # for ootype
        found = []
        for op in graph.startblock.operations:
            if op.opname == 'jit_force_quasi_immutable':
                found.append(op.args[1].value)
        assert found == ['mutate_c']
Пример #21
0
    def test_immutable_ok_inheritance_2(self):
        from pypy.jit.metainterp.typesystem import deref

        class A(object):
            _immutable_fields_ = ['v']

        class B(A):
            _immutable_ = True

        def f():
            A().v = 123
            B().w = 456
            return B()

        t, typer, graph = self.gengraph(f, [])
        B_TYPE = deref(graph.getreturnvar().concretetype)
        assert B_TYPE._hints["immutable"]
        try:
            A_TYPE = B_TYPE.super
        except AttributeError:
            A_TYPE = B_TYPE._superclass  # for ootype
        accessor = A_TYPE._hints["immutable_fields"]
        assert accessor.fields == {"inst_v": IR_IMMUTABLE} or \
               accessor.fields == {"ov": IR_IMMUTABLE} # for ootype
Пример #22
0
    def __init__(self, warmrunnerdesc, VTYPEPTR):
        self.warmrunnerdesc = warmrunnerdesc
        cpu = warmrunnerdesc.cpu
        if cpu.ts.name == 'ootype':
            import py
            py.test.skip("ootype: fix virtualizables")
        self.cpu = cpu
        self.BoxArray = cpu.ts.BoxRef
        #
        while 'virtualizable2_accessor' not in deref(VTYPEPTR)._hints:
            VTYPEPTR = cpu.ts.get_superclass(VTYPEPTR)
        self.VTYPEPTR = VTYPEPTR
        self.VTYPE = VTYPE = deref(VTYPEPTR)
        self.vable_token_descr = cpu.fielddescrof(VTYPE, 'vable_token')
        #
        accessor = VTYPE._hints['virtualizable2_accessor']
        all_fields = accessor.fields
        static_fields = []
        array_fields = []
        for name, tp in all_fields.iteritems():
            if tp == IR_IMMUTABLE_ARRAY:
                array_fields.append(name)
            elif tp == IR_IMMUTABLE:
                static_fields.append(name)
            else:
                raise Exception("unknown type: %s" % tp)
        self.static_fields = static_fields
        self.array_fields = array_fields
        #
        FIELDTYPES = [fieldType(VTYPE, name) for name in static_fields]
        ARRAYITEMTYPES = []
        for name in array_fields:
            ARRAYPTR = fieldType(VTYPE, name)
            ARRAY = deref(ARRAYPTR)
            assert isinstance(ARRAYPTR, (lltype.Ptr, ootype.Array))
            assert isinstance(ARRAY, (lltype.GcArray, ootype.Array))
            ARRAYITEMTYPES.append(arrayItem(ARRAY))
        self.array_descrs = [
            cpu.arraydescrof(deref(fieldType(VTYPE, name)))
            for name in array_fields
        ]
        #
        self.num_static_extra_boxes = len(static_fields)
        self.num_arrays = len(array_fields)
        self.static_field_to_extra_box = dict([
            (name, i) for (i, name) in enumerate(static_fields)
        ])
        self.array_field_counter = dict([
            (name, i) for (i, name) in enumerate(array_fields)
        ])
        self.static_extra_types = [
            history.getkind(TYPE) for TYPE in FIELDTYPES
        ]
        self.arrayitem_extra_types = [
            history.getkind(ITEM) for ITEM in ARRAYITEMTYPES
        ]
        self.static_field_descrs = [
            cpu.fielddescrof(VTYPE, name) for name in static_fields
        ]
        self.array_field_descrs = [
            cpu.fielddescrof(VTYPE, name) for name in array_fields
        ]
        self.static_field_by_descrs = dict([
            (descr, i) for (i, descr) in enumerate(self.static_field_descrs)
        ])
        self.array_field_by_descrs = dict([
            (descr, i) for (i, descr) in enumerate(self.array_field_descrs)
        ])
        #
        getlength = cpu.ts.getlength
        getarrayitem = cpu.ts.getarrayitem
        setarrayitem = cpu.ts.setarrayitem

        #
        def read_boxes(cpu, virtualizable):
            assert lltype.typeOf(virtualizable) == llmemory.GCREF
            virtualizable = cast_gcref_to_vtype(virtualizable)
            boxes = []
            for _, fieldname in unroll_static_fields:
                x = getattr(virtualizable, fieldname)
                boxes.append(wrap(cpu, x))
            for _, fieldname in unroll_array_fields:
                lst = getattr(virtualizable, fieldname)
                for i in range(getlength(lst)):
                    boxes.append(wrap(cpu, getarrayitem(lst, i)))
            return boxes

        #
        def write_boxes(virtualizable, boxes):
            virtualizable = cast_gcref_to_vtype(virtualizable)
            i = 0
            for FIELDTYPE, fieldname in unroll_static_fields:
                x = unwrap(FIELDTYPE, boxes[i])
                setattr(virtualizable, fieldname, x)
                i = i + 1
            for ARRAYITEMTYPE, fieldname in unroll_array_fields:
                lst = getattr(virtualizable, fieldname)
                for j in range(getlength(lst)):
                    x = unwrap(ARRAYITEMTYPE, boxes[i])
                    setarrayitem(lst, j, x)
                    i = i + 1
            assert len(boxes) == i + 1

        #
        def write_from_resume_data_partial(virtualizable, reader, numb):
            virtualizable = cast_gcref_to_vtype(virtualizable)
            # Load values from the reader (see resume.py) described by
            # the list of numbers 'nums', and write them in their proper
            # place in the 'virtualizable'.  This works from the end of
            # the list and returns the index in 'nums' of the start of
            # the virtualizable data found, allowing the caller to do
            # further processing with the start of the list.
            i = len(numb.nums) - 1
            assert i >= 0
            for ARRAYITEMTYPE, fieldname in unroll_array_fields_rev:
                lst = getattr(virtualizable, fieldname)
                for j in range(getlength(lst) - 1, -1, -1):
                    i -= 1
                    assert i >= 0
                    x = reader.load_value_of_type(ARRAYITEMTYPE, numb.nums[i])
                    setarrayitem(lst, j, x)
            for FIELDTYPE, fieldname in unroll_static_fields_rev:
                i -= 1
                assert i >= 0
                x = reader.load_value_of_type(FIELDTYPE, numb.nums[i])
                setattr(virtualizable, fieldname, x)
            return i

        #
        def load_list_of_boxes(virtualizable, reader, numb):
            virtualizable = cast_gcref_to_vtype(virtualizable)
            # Uses 'virtualizable' only to know the length of the arrays;
            # does not write anything into it.  The returned list is in
            # the format expected of virtualizable_boxes, so it ends in
            # the virtualizable itself.
            i = len(numb.nums) - 1
            assert i >= 0
            boxes = [reader.decode_box_of_type(self.VTYPEPTR, numb.nums[i])]
            for ARRAYITEMTYPE, fieldname in unroll_array_fields_rev:
                lst = getattr(virtualizable, fieldname)
                for j in range(getlength(lst) - 1, -1, -1):
                    i -= 1
                    assert i >= 0
                    box = reader.decode_box_of_type(ARRAYITEMTYPE,
                                                    numb.nums[i])
                    boxes.append(box)
            for FIELDTYPE, fieldname in unroll_static_fields_rev:
                i -= 1
                assert i >= 0
                box = reader.decode_box_of_type(FIELDTYPE, numb.nums[i])
                boxes.append(box)
            boxes.reverse()
            return boxes

        #
        def check_boxes(virtualizable, boxes):
            virtualizable = cast_gcref_to_vtype(virtualizable)
            # for debugging
            i = 0
            for FIELDTYPE, fieldname in unroll_static_fields:
                x = unwrap(FIELDTYPE, boxes[i])
                assert getattr(virtualizable, fieldname) == x
                i = i + 1
            for ARRAYITEMTYPE, fieldname in unroll_array_fields:
                lst = getattr(virtualizable, fieldname)
                for j in range(getlength(lst)):
                    x = unwrap(ARRAYITEMTYPE, boxes[i])
                    assert getarrayitem(lst, j) == x
                    i = i + 1
            assert len(boxes) == i + 1

        #
        def get_index_in_array(virtualizable, arrayindex, index):
            virtualizable = cast_gcref_to_vtype(virtualizable)
            index += self.num_static_extra_boxes
            j = 0
            for _, fieldname in unroll_array_fields:
                if arrayindex == j:
                    return index
                lst = getattr(virtualizable, fieldname)
                index += getlength(lst)
                j = j + 1
            assert False, "invalid arrayindex"

        #
        def get_array_length(virtualizable, arrayindex):
            virtualizable = cast_gcref_to_vtype(virtualizable)
            j = 0
            for _, fieldname in unroll_array_fields:
                if arrayindex == j:
                    lst = getattr(virtualizable, fieldname)
                    return getlength(lst)
                j = j + 1
            assert False, "invalid arrayindex"

        #
        unroll_static_fields = unrolling_iterable(
            zip(FIELDTYPES, static_fields))
        unroll_array_fields = unrolling_iterable(
            zip(ARRAYITEMTYPES, array_fields))
        unroll_static_fields_rev = unrolling_iterable(
            reversed(list(unroll_static_fields)))
        unroll_array_fields_rev = unrolling_iterable(
            reversed(list(unroll_array_fields)))
        self.read_boxes = read_boxes
        self.write_boxes = write_boxes
        self.write_from_resume_data_partial = write_from_resume_data_partial
        self.load_list_of_boxes = load_list_of_boxes
        self.check_boxes = check_boxes
        self.get_index_in_array = get_index_in_array
        self.get_array_length = get_array_length

        def cast_to_vtype(virtualizable):
            return self.cpu.ts.cast_to_instance_maybe(VTYPEPTR, virtualizable)

        self.cast_to_vtype = cast_to_vtype

        def cast_gcref_to_vtype(virtualizable):
            assert lltype.typeOf(virtualizable) == llmemory.GCREF
            return lltype.cast_opaque_ptr(VTYPEPTR, virtualizable)

        self.cast_gcref_to_vtype = cast_gcref_to_vtype

        def reset_vable_token(virtualizable):
            virtualizable.vable_token = VirtualizableInfo.TOKEN_NONE

        self.reset_vable_token = reset_vable_token

        def clear_vable_token(virtualizable):
            virtualizable = cast_gcref_to_vtype(virtualizable)
            if virtualizable.vable_token:
                force_now(virtualizable)
                assert not virtualizable.vable_token

        self.clear_vable_token = clear_vable_token

        def tracing_before_residual_call(virtualizable):
            virtualizable = cast_gcref_to_vtype(virtualizable)
            assert not virtualizable.vable_token
            virtualizable.vable_token = VirtualizableInfo.TOKEN_TRACING_RESCALL

        self.tracing_before_residual_call = tracing_before_residual_call

        def tracing_after_residual_call(virtualizable):
            virtualizable = cast_gcref_to_vtype(virtualizable)
            if virtualizable.vable_token:
                # not modified by the residual call; assert that it is still
                # set to TOKEN_TRACING_RESCALL and clear it.
                assert virtualizable.vable_token == VirtualizableInfo.TOKEN_TRACING_RESCALL
                virtualizable.vable_token = VirtualizableInfo.TOKEN_NONE
                return False
            else:
                # marker "modified during residual call" set.
                return True

        self.tracing_after_residual_call = tracing_after_residual_call

        def force_now(virtualizable):
            token = virtualizable.vable_token
            if token == VirtualizableInfo.TOKEN_TRACING_RESCALL:
                # The values in the virtualizable are always correct during
                # tracing.  We only need to reset vable_token to TOKEN_NONE
                # as a marker for the tracing, to tell it that this
                # virtualizable escapes.
                virtualizable.vable_token = VirtualizableInfo.TOKEN_NONE
            else:
                from pypy.jit.metainterp.compile import ResumeGuardForcedDescr
                ResumeGuardForcedDescr.force_now(cpu, token)
                assert virtualizable.vable_token == VirtualizableInfo.TOKEN_NONE

        force_now._dont_inline_ = True
        self.force_now = force_now

        def is_token_nonnull_gcref(virtualizable):
            virtualizable = cast_gcref_to_vtype(virtualizable)
            return bool(virtualizable.vable_token)

        self.is_token_nonnull_gcref = is_token_nonnull_gcref

        def reset_token_gcref(virtualizable):
            virtualizable = cast_gcref_to_vtype(virtualizable)
            virtualizable.vable_token = VirtualizableInfo.TOKEN_NONE

        self.reset_token_gcref = reset_token_gcref
Пример #23
0
    def __init__(self, warmrunnerdesc):
        self.warmrunnerdesc = warmrunnerdesc
        jitdriver = warmrunnerdesc.jitdriver
        cpu = warmrunnerdesc.cpu
        self.cpu = cpu
        self.VABLERTI = cpu.ts.get_VABLERTI()
        self.null_vable_rti = cpu.ts.nullptr(deref(self.VABLERTI))
        self.BoxArray = cpu.ts.BoxRef
        #
        assert len(jitdriver.virtualizables) == 1  # for now
        [vname] = jitdriver.virtualizables
        index = len(jitdriver.greens) + jitdriver.reds.index(vname)
        self.index_of_virtualizable = index
        VTYPEPTR = warmrunnerdesc.JIT_ENTER_FUNCTYPE.ARGS[index]
        while 'virtualizable2_accessor' not in deref(VTYPEPTR)._hints:
            VTYPEPTR = cpu.ts.get_superclass(VTYPEPTR)
        self.VTYPEPTR = VTYPEPTR
        self.VTYPE = VTYPE = deref(VTYPEPTR)
        self.null_vable = cpu.ts.nullptr(VTYPE)
        #
        accessor = VTYPE._hints['virtualizable2_accessor']
        all_fields = accessor.fields
        static_fields = []
        array_fields = []
        for name, suffix in all_fields.iteritems():
            if suffix == '[*]':
                array_fields.append(name)
            else:
                static_fields.append(name)
        self.static_fields = static_fields
        self.array_fields = array_fields
        #
        FIELDTYPES = [fieldType(VTYPE, name) for name in static_fields]
        ARRAYITEMTYPES = []
        for name in array_fields:
            ARRAYPTR = fieldType(VTYPE, name)
            ARRAY = deref(ARRAYPTR)
            assert isinstance(ARRAYPTR, (lltype.Ptr, ootype.Array))
            assert isinstance(ARRAY, (lltype.GcArray, ootype.Array))
            ARRAYITEMTYPES.append(arrayItem(ARRAY))
        self.array_descrs = [
            cpu.arraydescrof(deref(fieldType(VTYPE, name)))
            for name in array_fields
        ]
        #
        self.num_static_extra_boxes = len(static_fields)
        self.num_arrays = len(array_fields)
        self.static_field_to_extra_box = dict([
            (name, i) for (i, name) in enumerate(static_fields)
        ])
        self.array_field_counter = dict([
            (name, i) for (i, name) in enumerate(array_fields)
        ])
        self.static_extra_types = [
            history.getkind(TYPE) for TYPE in FIELDTYPES
        ]
        self.arrayitem_extra_types = [
            history.getkind(ITEM) for ITEM in ARRAYITEMTYPES
        ]
        self.static_field_descrs = [
            cpu.fielddescrof(VTYPE, name) for name in static_fields
        ]
        self.array_field_descrs = [
            cpu.fielddescrof(VTYPE, name) for name in array_fields
        ]
        #
        getlength = cpu.ts.getlength
        getarrayitem = cpu.ts.getarrayitem
        setarrayitem = cpu.ts.setarrayitem

        #
        def read_boxes(cpu, virtualizable):
            boxes = []
            for _, fieldname in unroll_static_fields:
                x = getattr(virtualizable, fieldname)
                boxes.append(wrap(cpu, x))
            for _, fieldname in unroll_array_fields:
                lst = getattr(virtualizable, fieldname)
                for i in range(getlength(lst)):
                    boxes.append(wrap(cpu, getarrayitem(lst, i)))
            return boxes

        #
        def write_boxes(virtualizable, boxes):
            i = 0
            for FIELDTYPE, fieldname in unroll_static_fields:
                x = unwrap(FIELDTYPE, boxes[i])
                setattr(virtualizable, fieldname, x)
                i = i + 1
            for ARRAYITEMTYPE, fieldname in unroll_array_fields:
                lst = getattr(virtualizable, fieldname)
                for j in range(getlength(lst)):
                    x = unwrap(ARRAYITEMTYPE, boxes[i])
                    setarrayitem(lst, j, x)
                    i = i + 1
            assert len(boxes) == i + 1

        #
        def check_boxes(virtualizable, boxes):
            # for debugging
            i = 0
            for FIELDTYPE, fieldname in unroll_static_fields:
                x = unwrap(FIELDTYPE, boxes[i])
                assert getattr(virtualizable, fieldname) == x
                i = i + 1
            for ARRAYITEMTYPE, fieldname in unroll_array_fields:
                lst = getattr(virtualizable, fieldname)
                for j in range(getlength(lst)):
                    x = unwrap(ARRAYITEMTYPE, boxes[i])
                    assert getarrayitem(lst, j) == x
                    i = i + 1
            assert len(boxes) == i + 1

        #
        def get_index_in_array(virtualizable, arrayindex, index):
            index += self.num_static_extra_boxes
            j = 0
            for _, fieldname in unroll_array_fields:
                if arrayindex == j:
                    return index
                lst = getattr(virtualizable, fieldname)
                index += getlength(lst)
                j = j + 1
            assert False, "invalid arrayindex"

        #
        def get_array_length(virtualizable, arrayindex):
            j = 0
            for _, fieldname in unroll_array_fields:
                if arrayindex == j:
                    lst = getattr(virtualizable, fieldname)
                    return getlength(lst)
                j = j + 1
            assert False, "invalid arrayindex"

        #
        unroll_static_fields = unrolling_iterable(
            zip(FIELDTYPES, static_fields))
        unroll_array_fields = unrolling_iterable(
            zip(ARRAYITEMTYPES, array_fields))
        self.read_boxes = read_boxes
        self.write_boxes = write_boxes
        self.check_boxes = check_boxes
        self.get_index_in_array = get_index_in_array
        self.get_array_length = get_array_length
Пример #24
0
 def __init__(self, warmrunnerdesc):
     self.warmrunnerdesc = warmrunnerdesc
     jitdriver = warmrunnerdesc.jitdriver
     cpu = warmrunnerdesc.cpu
     self.cpu = cpu
     self.VABLERTI = cpu.ts.get_VABLERTI()
     self.null_vable_rti = cpu.ts.nullptr(deref(self.VABLERTI))
     self.BoxArray = cpu.ts.BoxRef
     #
     assert len(jitdriver.virtualizables) == 1    # for now
     [vname] = jitdriver.virtualizables
     index = len(jitdriver.greens) + jitdriver.reds.index(vname)
     self.index_of_virtualizable = index
     VTYPEPTR = warmrunnerdesc.JIT_ENTER_FUNCTYPE.ARGS[index]
     while 'virtualizable2_accessor' not in deref(VTYPEPTR)._hints:
         VTYPEPTR = cpu.ts.get_superclass(VTYPEPTR)
     self.VTYPEPTR = VTYPEPTR
     self.VTYPE = VTYPE = deref(VTYPEPTR)
     self.null_vable = cpu.ts.nullptr(VTYPE)
     #
     accessor = VTYPE._hints['virtualizable2_accessor']
     all_fields = accessor.fields
     static_fields = []
     array_fields = []
     for name, suffix in all_fields.iteritems():
         if suffix == '[*]':
             array_fields.append(name)
         else:
             static_fields.append(name)
     self.static_fields = static_fields
     self.array_fields = array_fields
     #
     FIELDTYPES = [fieldType(VTYPE, name) for name in static_fields]
     ARRAYITEMTYPES = []
     for name in array_fields:
         ARRAYPTR = fieldType(VTYPE, name)
         ARRAY = deref(ARRAYPTR)
         assert isinstance(ARRAYPTR, (lltype.Ptr, ootype.Array))
         assert isinstance(ARRAY, (lltype.GcArray, ootype.Array))
         ARRAYITEMTYPES.append(arrayItem(ARRAY))
     self.array_descrs = [cpu.arraydescrof(deref(fieldType(VTYPE, name)))
                          for name in array_fields]
     #
     self.num_static_extra_boxes = len(static_fields)
     self.num_arrays = len(array_fields)
     self.static_field_to_extra_box = dict(
         [(name, i) for (i, name) in enumerate(static_fields)])
     self.array_field_counter = dict(
         [(name, i) for (i, name) in enumerate(array_fields)])
     self.static_extra_types = [history.getkind(TYPE)
                                for TYPE in FIELDTYPES]
     self.arrayitem_extra_types = [history.getkind(ITEM)
                                   for ITEM in ARRAYITEMTYPES]
     self.static_field_descrs = [cpu.fielddescrof(VTYPE, name)
                                 for name in static_fields]
     self.array_field_descrs = [cpu.fielddescrof(VTYPE, name)
                                for name in array_fields]
     #
     getlength = cpu.ts.getlength
     getarrayitem = cpu.ts.getarrayitem
     setarrayitem = cpu.ts.setarrayitem
     #
     def read_boxes(cpu, virtualizable):
         boxes = []
         for _, fieldname in unroll_static_fields:
             x = getattr(virtualizable, fieldname)
             boxes.append(wrap(cpu, x))
         for _, fieldname in unroll_array_fields:
             lst = getattr(virtualizable, fieldname)
             for i in range(getlength(lst)):
                 boxes.append(wrap(cpu, getarrayitem(lst, i)))
         return boxes
     #
     def write_boxes(virtualizable, boxes):
         i = 0
         for FIELDTYPE, fieldname in unroll_static_fields:
             x = unwrap(FIELDTYPE, boxes[i])
             setattr(virtualizable, fieldname, x)
             i = i + 1
         for ARRAYITEMTYPE, fieldname in unroll_array_fields:
             lst = getattr(virtualizable, fieldname)
             for j in range(getlength(lst)):
                 x = unwrap(ARRAYITEMTYPE, boxes[i])
                 setarrayitem(lst, j, x)
                 i = i + 1
         assert len(boxes) == i + 1
     #
     def check_boxes(virtualizable, boxes):
         # for debugging
         i = 0
         for FIELDTYPE, fieldname in unroll_static_fields:
             x = unwrap(FIELDTYPE, boxes[i])
             assert getattr(virtualizable, fieldname) == x
             i = i + 1
         for ARRAYITEMTYPE, fieldname in unroll_array_fields:
             lst = getattr(virtualizable, fieldname)
             for j in range(getlength(lst)):
                 x = unwrap(ARRAYITEMTYPE, boxes[i])
                 assert getarrayitem(lst, j) == x
                 i = i + 1
         assert len(boxes) == i + 1
     #
     def get_index_in_array(virtualizable, arrayindex, index):
         index += self.num_static_extra_boxes
         j = 0
         for _, fieldname in unroll_array_fields:
             if arrayindex == j:
                 return index
             lst = getattr(virtualizable, fieldname)
             index += getlength(lst)
             j = j + 1
         assert False, "invalid arrayindex"
     #
     def get_array_length(virtualizable, arrayindex):
         j = 0
         for _, fieldname in unroll_array_fields:
             if arrayindex == j:
                 lst = getattr(virtualizable, fieldname)
                 return getlength(lst)
             j = j + 1
         assert False, "invalid arrayindex"
     #
     unroll_static_fields = unrolling_iterable(zip(FIELDTYPES,
                                                   static_fields))
     unroll_array_fields = unrolling_iterable(zip(ARRAYITEMTYPES,
                                                  array_fields))
     self.read_boxes = read_boxes
     self.write_boxes = write_boxes
     self.check_boxes = check_boxes
     self.get_index_in_array = get_index_in_array
     self.get_array_length = get_array_length
Пример #25
0
    def __init__(self, warmrunnerdesc, VTYPEPTR):
        self.warmrunnerdesc = warmrunnerdesc
        cpu = warmrunnerdesc.cpu
        if cpu.ts.name == 'ootype':
            import py
            py.test.skip("ootype: fix virtualizables")
        self.cpu = cpu
        self.BoxArray = cpu.ts.BoxRef
        #
        while 'virtualizable2_accessor' not in deref(VTYPEPTR)._hints:
            VTYPEPTR = cpu.ts.get_superclass(VTYPEPTR)
        self.VTYPEPTR = VTYPEPTR
        self.VTYPE = VTYPE = deref(VTYPEPTR)
        self.vable_token_descr = cpu.fielddescrof(VTYPE, 'vable_token')
        #
        accessor = VTYPE._hints['virtualizable2_accessor']
        all_fields = accessor.fields
        static_fields = []
        array_fields = []
        for name, tp in all_fields.iteritems():
            if tp == IR_IMMUTABLE_ARRAY:
                array_fields.append(name)
            elif tp == IR_IMMUTABLE:
                static_fields.append(name)
            else:
                raise Exception("unknown type: %s" % tp)
        self.static_fields = static_fields
        self.array_fields = array_fields
        #
        FIELDTYPES = [fieldType(VTYPE, name) for name in static_fields]
        ARRAYITEMTYPES = []
        for name in array_fields:
            ARRAYPTR = fieldType(VTYPE, name)
            ARRAY = deref(ARRAYPTR)
            assert isinstance(ARRAYPTR, (lltype.Ptr, ootype.Array))
            assert isinstance(ARRAY, (lltype.GcArray, ootype.Array))
            ARRAYITEMTYPES.append(arrayItem(ARRAY))
        self.array_descrs = [cpu.arraydescrof(deref(fieldType(VTYPE, name)))
                             for name in array_fields]
        #
        self.num_static_extra_boxes = len(static_fields)
        self.num_arrays = len(array_fields)
        self.static_field_to_extra_box = dict(
            [(name, i) for (i, name) in enumerate(static_fields)])
        self.array_field_counter = dict(
            [(name, i) for (i, name) in enumerate(array_fields)])
        self.static_extra_types = [history.getkind(TYPE)
                                   for TYPE in FIELDTYPES]
        self.arrayitem_extra_types = [history.getkind(ITEM)
                                      for ITEM in ARRAYITEMTYPES]
        self.static_field_descrs = [cpu.fielddescrof(VTYPE, name)
                                    for name in static_fields]
        self.array_field_descrs = [cpu.fielddescrof(VTYPE, name)
                                   for name in array_fields]
        self.static_field_by_descrs = dict(
            [(descr, i) for (i, descr) in enumerate(self.static_field_descrs)])
        self.array_field_by_descrs = dict(
            [(descr, i) for (i, descr) in enumerate(self.array_field_descrs)])
        #
        getlength = cpu.ts.getlength
        getarrayitem = cpu.ts.getarrayitem
        setarrayitem = cpu.ts.setarrayitem
        #
        def read_boxes(cpu, virtualizable):
            assert lltype.typeOf(virtualizable) == llmemory.GCREF
            virtualizable = cast_gcref_to_vtype(virtualizable)
            boxes = []
            for _, fieldname in unroll_static_fields:
                x = getattr(virtualizable, fieldname)
                boxes.append(wrap(cpu, x))
            for _, fieldname in unroll_array_fields:
                lst = getattr(virtualizable, fieldname)
                for i in range(getlength(lst)):
                    boxes.append(wrap(cpu, getarrayitem(lst, i)))
            return boxes
        #
        def write_boxes(virtualizable, boxes):
            virtualizable = cast_gcref_to_vtype(virtualizable)
            i = 0
            for FIELDTYPE, fieldname in unroll_static_fields:
                x = unwrap(FIELDTYPE, boxes[i])
                setattr(virtualizable, fieldname, x)
                i = i + 1
            for ARRAYITEMTYPE, fieldname in unroll_array_fields:
                lst = getattr(virtualizable, fieldname)
                for j in range(getlength(lst)):
                    x = unwrap(ARRAYITEMTYPE, boxes[i])
                    setarrayitem(lst, j, x)
                    i = i + 1
            assert len(boxes) == i + 1
        #
        def write_from_resume_data_partial(virtualizable, reader, numb):
            virtualizable = cast_gcref_to_vtype(virtualizable)
            # Load values from the reader (see resume.py) described by
            # the list of numbers 'nums', and write them in their proper
            # place in the 'virtualizable'.  This works from the end of
            # the list and returns the index in 'nums' of the start of
            # the virtualizable data found, allowing the caller to do
            # further processing with the start of the list.
            i = len(numb.nums) - 1
            assert i >= 0
            for ARRAYITEMTYPE, fieldname in unroll_array_fields_rev:
                lst = getattr(virtualizable, fieldname)
                for j in range(getlength(lst)-1, -1, -1):
                    i -= 1
                    assert i >= 0
                    x = reader.load_value_of_type(ARRAYITEMTYPE, numb.nums[i])
                    setarrayitem(lst, j, x)
            for FIELDTYPE, fieldname in unroll_static_fields_rev:
                i -= 1
                assert i >= 0
                x = reader.load_value_of_type(FIELDTYPE, numb.nums[i])
                setattr(virtualizable, fieldname, x)
            return i
        #
        def load_list_of_boxes(virtualizable, reader, numb):
            virtualizable = cast_gcref_to_vtype(virtualizable)
            # Uses 'virtualizable' only to know the length of the arrays;
            # does not write anything into it.  The returned list is in
            # the format expected of virtualizable_boxes, so it ends in
            # the virtualizable itself.
            i = len(numb.nums) - 1
            assert i >= 0
            boxes = [reader.decode_box_of_type(self.VTYPEPTR, numb.nums[i])]
            for ARRAYITEMTYPE, fieldname in unroll_array_fields_rev:
                lst = getattr(virtualizable, fieldname)
                for j in range(getlength(lst)-1, -1, -1):
                    i -= 1
                    assert i >= 0
                    box = reader.decode_box_of_type(ARRAYITEMTYPE,numb.nums[i])
                    boxes.append(box)
            for FIELDTYPE, fieldname in unroll_static_fields_rev:
                i -= 1
                assert i >= 0
                box = reader.decode_box_of_type(FIELDTYPE, numb.nums[i])
                boxes.append(box)
            boxes.reverse()
            return boxes
        #
        def check_boxes(virtualizable, boxes):
            virtualizable = cast_gcref_to_vtype(virtualizable)
            # for debugging
            i = 0
            for FIELDTYPE, fieldname in unroll_static_fields:
                x = unwrap(FIELDTYPE, boxes[i])
                assert getattr(virtualizable, fieldname) == x
                i = i + 1
            for ARRAYITEMTYPE, fieldname in unroll_array_fields:
                lst = getattr(virtualizable, fieldname)
                for j in range(getlength(lst)):
                    x = unwrap(ARRAYITEMTYPE, boxes[i])
                    assert getarrayitem(lst, j) == x
                    i = i + 1
            assert len(boxes) == i + 1
        #
        def get_index_in_array(virtualizable, arrayindex, index):
            virtualizable = cast_gcref_to_vtype(virtualizable)
            index += self.num_static_extra_boxes
            j = 0
            for _, fieldname in unroll_array_fields:
                if arrayindex == j:
                    return index
                lst = getattr(virtualizable, fieldname)
                index += getlength(lst)
                j = j + 1
            assert False, "invalid arrayindex"
        #
        def get_array_length(virtualizable, arrayindex):
            virtualizable = cast_gcref_to_vtype(virtualizable)
            j = 0
            for _, fieldname in unroll_array_fields:
                if arrayindex == j:
                    lst = getattr(virtualizable, fieldname)
                    return getlength(lst)
                j = j + 1
            assert False, "invalid arrayindex"
        #
        unroll_static_fields = unrolling_iterable(zip(FIELDTYPES,
                                                      static_fields))
        unroll_array_fields = unrolling_iterable(zip(ARRAYITEMTYPES,
                                                     array_fields))
        unroll_static_fields_rev = unrolling_iterable(
                                          reversed(list(unroll_static_fields)))
        unroll_array_fields_rev  = unrolling_iterable(
                                          reversed(list(unroll_array_fields)))
        self.read_boxes = read_boxes
        self.write_boxes = write_boxes
        self.write_from_resume_data_partial = write_from_resume_data_partial
        self.load_list_of_boxes = load_list_of_boxes
        self.check_boxes = check_boxes
        self.get_index_in_array = get_index_in_array
        self.get_array_length = get_array_length

        def cast_to_vtype(virtualizable):
            return self.cpu.ts.cast_to_instance_maybe(VTYPEPTR, virtualizable)
        self.cast_to_vtype = cast_to_vtype

        def cast_gcref_to_vtype(virtualizable):
            assert lltype.typeOf(virtualizable) == llmemory.GCREF
            return lltype.cast_opaque_ptr(VTYPEPTR, virtualizable)
        self.cast_gcref_to_vtype = cast_gcref_to_vtype

        def reset_vable_token(virtualizable):
            virtualizable.vable_token = VirtualizableInfo.TOKEN_NONE
        self.reset_vable_token = reset_vable_token

        def clear_vable_token(virtualizable):
            virtualizable = cast_gcref_to_vtype(virtualizable)
            if virtualizable.vable_token:
                force_now(virtualizable)
                assert not virtualizable.vable_token
        self.clear_vable_token = clear_vable_token

        def tracing_before_residual_call(virtualizable):
            virtualizable = cast_gcref_to_vtype(virtualizable)
            assert not virtualizable.vable_token
            virtualizable.vable_token = VirtualizableInfo.TOKEN_TRACING_RESCALL
        self.tracing_before_residual_call = tracing_before_residual_call

        def tracing_after_residual_call(virtualizable):
            virtualizable = cast_gcref_to_vtype(virtualizable)
            if virtualizable.vable_token:
                # not modified by the residual call; assert that it is still
                # set to TOKEN_TRACING_RESCALL and clear it.
                assert virtualizable.vable_token == VirtualizableInfo.TOKEN_TRACING_RESCALL
                virtualizable.vable_token = VirtualizableInfo.TOKEN_NONE
                return False
            else:
                # marker "modified during residual call" set.
                return True
        self.tracing_after_residual_call = tracing_after_residual_call

        def force_now(virtualizable):
            token = virtualizable.vable_token
            if token == VirtualizableInfo.TOKEN_TRACING_RESCALL:
                # The values in the virtualizable are always correct during
                # tracing.  We only need to reset vable_token to TOKEN_NONE
                # as a marker for the tracing, to tell it that this
                # virtualizable escapes.
                virtualizable.vable_token = VirtualizableInfo.TOKEN_NONE
            else:
                from pypy.jit.metainterp.compile import ResumeGuardForcedDescr
                ResumeGuardForcedDescr.force_now(cpu, token)
                assert virtualizable.vable_token == VirtualizableInfo.TOKEN_NONE
        force_now._dont_inline_ = True
        self.force_now = force_now

        def is_token_nonnull_gcref(virtualizable):
            virtualizable = cast_gcref_to_vtype(virtualizable)
            return bool(virtualizable.vable_token)
        self.is_token_nonnull_gcref = is_token_nonnull_gcref

        def reset_token_gcref(virtualizable):
            virtualizable = cast_gcref_to_vtype(virtualizable)
            virtualizable.vable_token = VirtualizableInfo.TOKEN_NONE
        self.reset_token_gcref = reset_token_gcref
Пример #26
0
    from pypy.translator.backendopt.writeanalyze import top_set
    if effects is top_set:
        return None
    readonly_descrs_fields = []
    # readonly_descrs_arrays = [] --- not enabled for now
    write_descrs_fields = []
    write_descrs_arrays = []

    def add_struct(descrs_fields, (_, T, fieldname)):
        T = deref(T)
        if consider_struct(T, fieldname):
            descr = cpu.fielddescrof(T, fieldname)
            descrs_fields.append(descr)

    def add_array(descrs_arrays, (_, T)):
        ARRAY = deref(T)
        if consider_array(ARRAY):
            descr = cpu.arraydescrof(ARRAY)
            descrs_arrays.append(descr)

    for tup in effects:
        if tup[0] == "struct":
            add_struct(write_descrs_fields, tup)
        elif tup[0] == "readstruct":
            tupw = ("struct",) + tup[1:]
            if tupw not in effects:
                add_struct(readonly_descrs_fields, tup)
        elif tup[0] == "array":
            add_array(write_descrs_arrays, tup)
        elif tup[0] == "readarray":
            pass