Ejemplo n.º 1
0
 def RTTI_dtor(self, STRUCT):
     try:
         destr_ptr = lltype.getRuntimeTypeInfo(STRUCT)._obj.destructor_funcptr
         if destr_ptr:
             return True
     except (ValueError, AttributeError), e:
         pass
Ejemplo n.º 2
0
def malloc_to_stack(t):
    adi = AbstractDataFlowInterpreter(t)
    for graph in t.graphs:
        if graph.startblock not in adi.flown_blocks:
            adi.schedule_function(graph)
            adi.complete()
    for graph in t.graphs:
        loop_blocks = support.find_loop_blocks(graph)
        for block, op in graph.iterblockops():
            if op.opname != 'malloc':
                continue
            STRUCT = op.args[0].value
            # must not remove mallocs of structures that have a RTTI with a destructor
            try:
                destr_ptr = lltype.getRuntimeTypeInfo(STRUCT)._obj.destructor_funcptr
                if destr_ptr:
                    continue
            except (ValueError, AttributeError), e:
                pass
            varstate = adi.getstate(op.result)
            assert len(varstate.creation_points) == 1
            crep = varstate.creation_points.keys()[0]
            if not crep.escapes:
                if block not in loop_blocks:
                    print "moving object from heap to stack %s in %s" % (op, graph.name)
                    flags = op.args[1].value
                    assert flags == {'flavor': 'gc'}
                    op.args[1] = Constant({'flavor': 'stack'}, lltype.Void)
                else:
                    print "%s in %s is a non-escaping malloc in a loop" % (op, graph.name)
Ejemplo n.º 3
0
def get_rtti(TYPE):
    if isinstance(TYPE, lltype.RttiStruct):
        try:
            return lltype.getRuntimeTypeInfo(TYPE)
        except ValueError:
            pass
    return None
Ejemplo n.º 4
0
def find_malloc_creps(graph, adi, translator, malloc_graphs):
    # mapping from malloc creation point to graphs that it flows into
    malloc_creps = {}
    # find all mallocs that don't escape
    for block, op in graph.iterblockops():
        if op.opname == 'malloc':
            STRUCT = op.args[0].value
            # must not remove mallocs of structures that have a RTTI with a destructor
            flags = op.args[1].value
            if flags != {'flavor': 'gc'}:
                continue
            try:
                destr_ptr = lltype.getRuntimeTypeInfo(
                    STRUCT)._obj.destructor_funcptr
                if destr_ptr:
                    continue
            except (ValueError, AttributeError), e:
                pass
            varstate = adi.getstate(op.result)
            assert len(varstate.creation_points) == 1
            crep, = varstate.creation_points
            if not crep.escapes and not crep.returns:
                malloc_creps[crep] = {}
        if op.opname == 'direct_call':
            called_graph = get_graph(op.args[0], translator)
            if called_graph not in malloc_graphs:
                continue
            varstate = adi.getstate(op.result)
            assert len(varstate.creation_points) == 1
            crep, = varstate.creation_points
            if not crep.escapes and not crep.returns:
                malloc_creps[crep] = {}
Ejemplo n.º 5
0
    def setup_vtable(self, vtable, rsubcls):
        """Initialize the 'self' portion of the 'vtable' belonging to the
        given subclass."""
        if self.classdef is None:
            # initialize the 'subclassrange_*' and 'name' fields
            if rsubcls.classdef is not None:
                #vtable.parenttypeptr = rsubcls.rbase.getvtable()
                vtable.subclassrange_min = rsubcls.classdef.minid
                vtable.subclassrange_max = rsubcls.classdef.maxid
            else:  #for the root class
                vtable.subclassrange_min = 0
                vtable.subclassrange_max = sys.maxint
            rinstance = getinstancerepr(self.rtyper, rsubcls.classdef)
            rinstance.setup()
            if rinstance.gcflavor == 'gc':
                vtable.rtti = getRuntimeTypeInfo(rinstance.object_type)
            if rsubcls.classdef is None:
                name = 'object'
            else:
                name = rsubcls.classdef.shortname
            vtable.name = alloc_array_name(name)
            if hasattr(rsubcls.classdef, 'my_instantiate_graph'):
                graph = rsubcls.classdef.my_instantiate_graph
                vtable.instantiate = self.rtyper.getcallable(graph)
            #else: the classdef was created recently, so no instantiate()
            #      could reach it
        else:
            # setup class attributes: for each attribute name at the level
            # of 'self', look up its value in the subclass rsubcls
            def assign(mangled_name, value):
                if isinstance(value, Constant) and isinstance(
                        value.value, staticmethod):
                    value = Constant(value.value.__get__(
                        42))  # staticmethod => bare function
                llvalue = r.convert_desc_or_const(value)
                setattr(vtable, mangled_name, llvalue)

            mro = list(rsubcls.classdef.getmro())
            for fldname in self.clsfields:
                mangled_name, r = self.clsfields[fldname]
                if r.lowleveltype is Void:
                    continue
                value = rsubcls.classdef.classdesc.read_attribute(
                    fldname, None)
                if value is not None:
                    assign(mangled_name, value)
            # extra PBC attributes
            for (access_set, attr), (mangled_name,
                                     r) in self.pbcfields.items():
                if rsubcls.classdef.classdesc not in access_set.descs:
                    continue  # only for the classes in the same pbc access set
                if r.lowleveltype is Void:
                    continue
                attrvalue = rsubcls.classdef.classdesc.read_attribute(
                    attr, None)
                if attrvalue is not None:
                    assign(mangled_name, attrvalue)

            # then initialize the 'super' portion of the vtable
            self.rbase.setup_vtable(vtable.super, rsubcls)
Ejemplo n.º 6
0
def malloc_to_stack(t):
    adi = AbstractDataFlowInterpreter(t)
    for graph in t.graphs:
        if graph.startblock not in adi.flown_blocks:
            adi.schedule_function(graph)
            adi.complete()
    for graph in t.graphs:
        loop_blocks = support.find_loop_blocks(graph)
        for block, op in graph.iterblockops():
            if op.opname == 'malloc':
                STRUCT = op.args[0].value
                # must not remove mallocs of structures that have a RTTI with a destructor
                try:
                    destr_ptr = lltype.getRuntimeTypeInfo(STRUCT)._obj.destructor_funcptr
                    if destr_ptr:
                        continue
                except (ValueError, AttributeError), e:
                    pass
                varstate = adi.getstate(op.result)
                assert len(varstate.creation_points) == 1
                crep = varstate.creation_points.keys()[0]
                if not crep.escapes:
                    if block not in loop_blocks:
                        print "moving object from heap to stack %s in %s" % (op, graph.name)
                        op.opname = 'flavored_malloc'
                        op.args.insert(0, inputconst(lltype.Void, 'stack'))
                    else:
                        print "%s in %s is a non-escaping malloc in a loop" % (op, graph.name)
Ejemplo n.º 7
0
def get_rtti(TYPE):
    if isinstance(TYPE, lltype.RttiStruct):
        try:
            return lltype.getRuntimeTypeInfo(TYPE)
        except ValueError:
            pass
    return None
Ejemplo n.º 8
0
def find_malloc_creps(graph, adi, translator, malloc_graphs):
    # mapping from malloc creation point to graphs that it flows into
    malloc_creps = {}
    # find all mallocs that don't escape
    for block, op in graph.iterblockops():
        if op.opname == 'malloc':
            STRUCT = op.args[0].value
            # must not remove mallocs of structures that have a RTTI with a destructor
            flags = op.args[1].value
            if flags != {'flavor': 'gc'}:
                continue
            try:
                destr_ptr = lltype.getRuntimeTypeInfo(
                    STRUCT)._obj.destructor_funcptr
                if destr_ptr:
                    continue
            except (ValueError, AttributeError), e:
                pass
            varstate = adi.getstate(op.result)
            assert len(varstate.creation_points) == 1
            crep, = varstate.creation_points
            if not crep.escapes and not crep.returns:
                malloc_creps[crep] = {}
        if op.opname == 'direct_call':
            called_graph = get_graph(op.args[0], translator)
            if called_graph not in malloc_graphs:
                continue
            varstate = adi.getstate(op.result)
            assert len(varstate.creation_points) == 1
            crep, = varstate.creation_points
            if not crep.escapes and not crep.returns:
                malloc_creps[crep] = {}
Ejemplo n.º 9
0
 def RTTI_dtor(self, STRUCT):
     try:
         destr_ptr = lltype.getRuntimeTypeInfo(
             STRUCT)._obj.destructor_funcptr
         if destr_ptr:
             return True
     except (ValueError, AttributeError), e:
         pass
Ejemplo n.º 10
0
    def setup_vtable(self, vtable, rsubcls):
        """Initialize the 'self' portion of the 'vtable' belonging to the
        given subclass."""
        if self.classdef is None:
            # initialize the 'subclassrange_*' and 'name' fields
            if rsubcls.classdef is not None:
                #vtable.parenttypeptr = rsubcls.rbase.getvtable()
                vtable.subclassrange_min = rsubcls.classdef.minid
                vtable.subclassrange_max = rsubcls.classdef.maxid
            else: #for the root class
                vtable.subclassrange_min = 0
                vtable.subclassrange_max = sys.maxint
            rinstance = getinstancerepr(self.rtyper, rsubcls.classdef)
            rinstance.setup()
            if rinstance.gcflavor in RTTIFLAVORS:
                vtable.rtti = getRuntimeTypeInfo(rinstance.object_type)
            if rsubcls.classdef is None:
                name = 'object'
            else:
                name = rsubcls.classdef.shortname
            vtable.name = malloc(Array(Char), len(name)+1, immortal=True)
            for i in range(len(name)):
                vtable.name[i] = name[i]
            vtable.name[len(name)] = '\x00'
            if hasattr(rsubcls.classdef, 'my_instantiate_graph'):
                graph = rsubcls.classdef.my_instantiate_graph
                vtable.instantiate = self.rtyper.getcallable(graph)
            #else: the classdef was created recently, so no instantiate()
            #      could reach it
        else:
            # setup class attributes: for each attribute name at the level
            # of 'self', look up its value in the subclass rsubcls
            def assign(mangled_name, value):
                if isinstance(value, Constant) and isinstance(value.value, staticmethod):
                    value = Constant(value.value.__get__(42))   # staticmethod => bare function
                llvalue = r.convert_desc_or_const(value)
                setattr(vtable, mangled_name, llvalue)

            mro = list(rsubcls.classdef.getmro())
            for fldname in self.clsfields:
                mangled_name, r = self.clsfields[fldname]
                if r.lowleveltype is Void:
                    continue
                value = rsubcls.classdef.classdesc.read_attribute(fldname, None)
                if value is not None:
                    assign(mangled_name, value)
            # extra PBC attributes
            for (access_set, attr), (mangled_name, r) in self.pbcfields.items():
                if rsubcls.classdef.classdesc not in access_set.descs:
                    continue   # only for the classes in the same pbc access set
                if r.lowleveltype is Void:
                    continue
                attrvalue = rsubcls.classdef.classdesc.read_attribute(attr, None)
                if attrvalue is not None:
                    assign(mangled_name, attrvalue)

            # then initialize the 'super' portion of the vtable
            self.rbase.setup_vtable(vtable.super, rsubcls)
Ejemplo n.º 11
0
def hasdestructor(STRUCT):
    if not isinstance(STRUCT, lltype.Struct):
        return False
    try:
        destr_ptr = lltype.getRuntimeTypeInfo(STRUCT)._obj.destructor_funcptr
        if destr_ptr:
            return True
    except (ValueError, AttributeError), e:
        pass
Ejemplo n.º 12
0
 def check_no_destructor(self):
     STRUCT = self.MALLOCTYPE
     try:
         rttiptr = lltype.getRuntimeTypeInfo(STRUCT)
     except ValueError:
         return    # ok
     destr_ptr = getattr(rttiptr._obj, 'destructor_funcptr', None)
     if destr_ptr:
         raise CannotRemoveThisType
Ejemplo n.º 13
0
 def check_no_destructor(self):
     STRUCT = self.MALLOCTYPE
     try:
         rttiptr = lltype.getRuntimeTypeInfo(STRUCT)
     except ValueError:
         return    # ok
     destr_ptr = getattr(rttiptr._obj, 'destructor_funcptr', None)
     if destr_ptr:
         raise CannotRemoveThisType
Ejemplo n.º 14
0
def hasdestructor(STRUCT):
    if not isinstance(STRUCT, lltype.Struct):
        return False
    try:
        destr_ptr = lltype.getRuntimeTypeInfo(STRUCT)._obj.destructor_funcptr
        if destr_ptr:
            return True
    except (ValueError, AttributeError), e:
        pass
Ejemplo n.º 15
0
 def computegcinfo(self):
     # let the gcpolicy do its own setup
     self.gcinfo = None  # unless overwritten below
     rtti = None
     STRUCT = self.STRUCT
     if isinstance(STRUCT, RttiStruct):
         try:
             rtti = getRuntimeTypeInfo(STRUCT)
         except ValueError:
             pass
     if self.varlength == 1:
         self.db.gcpolicy.struct_setup(self, rtti)
     return self.gcinfo
Ejemplo n.º 16
0
 def computegcinfo(self):
     # let the gcpolicy do its own setup
     self.gcinfo = None   # unless overwritten below
     rtti = None
     STRUCT = self.STRUCT
     if isinstance(STRUCT, RttiStruct):
         try:
             rtti = getRuntimeTypeInfo(STRUCT)
         except ValueError:
             pass
     if self.varlength == 1:
         self.db.gcpolicy.struct_setup(self, rtti)
     return self.gcinfo
Ejemplo n.º 17
0
def find_malloc_creps(graph, adi, translator):
    # mapping from malloc creation point to graphs that it flows into
    malloc_creps = {}
    # find all mallocs that don't escape
    for block, op in graph.iterblockops():
        if op.opname == 'malloc':
            STRUCT = op.args[0].value
            # must not remove mallocs of structures that have a RTTI with a destructor
            try:
                destr_ptr = lltype.getRuntimeTypeInfo(
                    STRUCT)._obj.destructor_funcptr
                if destr_ptr:
                    continue
            except (ValueError, AttributeError), e:
                pass
            varstate = adi.getstate(op.result)
            assert len(varstate.creation_points) == 1
            crep = varstate.creation_points.keys()[0]
            if not crep.escapes:
                malloc_creps[crep] = {}
Ejemplo n.º 18
0
def getRuntimeTypeInfo(T):
    assert T.is_constant()
    return immutablevalue(lltype.getRuntimeTypeInfo(T.const))
Ejemplo n.º 19
0
def getRuntimeTypeInfo(T):
    assert T.is_constant()
    return immutablevalue(lltype.getRuntimeTypeInfo(T.const))
Ejemplo n.º 20
0
 def type_info_S(s):
     return lltype.getRuntimeTypeInfo(S)
Ejemplo n.º 21
0
 def type_info_T(p):
     return lltype.getRuntimeTypeInfo(T)
Ejemplo n.º 22
0
 def type_info_T(p):
     return lltype.getRuntimeTypeInfo(T)
Ejemplo n.º 23
0
 def type_info_S(s):
     return lltype.getRuntimeTypeInfo(S)