示例#1
0
 def get_livevars_for_roots(self, hop, keep_current_args=False):
     if self.gcdata.gc.moving_gc and not keep_current_args:
         # moving GCs don't borrow, so the caller does not need to keep
         # the arguments alive
         livevars = [var for var in hop.livevars_after_op()
                         if not var_ispyobj(var)]
     else:
         livevars = hop.livevars_after_op() + hop.current_op_keeps_alive()
         livevars = [var for var in livevars if not var_ispyobj(var)]
     return livevars
示例#2
0
 def get_livevars_for_roots(self, hop, keep_current_args=False):
     if self.gcdata.gc.moving_gc and not keep_current_args:
         # moving GCs don't borrow, so the caller does not need to keep
         # the arguments alive
         livevars = [var for var in hop.livevars_after_op()
                         if not var_ispyobj(var)]
     else:
         livevars = hop.livevars_after_op() + hop.current_op_keeps_alive()
         livevars = [var for var in livevars if not var_ispyobj(var)]
     return livevars
示例#3
0
def checkblock(block, is_borrowed, is_start_block):
    if block.operations == ():
        # a return/exception block -- don't want to think about them
        # (even though the test passes for somewhat accidental reasons)
        return
    if is_start_block:
        refs_in = 0
    else:
        refs_in = len([
            v for v in block.inputargs if isinstance(v, Variable)
            and var_needsgc(v) and not is_borrowed(v)
        ])
    push_alives = len(
        [op for op in block.operations if op.opname == 'gc_push_alive'])
    pyobj_push_alives = len(
        [op for op in block.operations if op.opname == 'gc_push_alive_pyobj'])

    # implicit_pyobj_pushalives included calls to things that return pyobject*
    implicit_pyobj_pushalives = len([
        op for op in block.operations
        if var_ispyobj(op.result) and op.opname not in ('getfield',
                                                        'getarrayitem',
                                                        'same_as')
    ])
    nonpyobj_gc_returning_calls = len([
        op for op in block.operations
        if op.opname in ('direct_call', 'indirect_call')
        and var_needsgc(op.result) and not var_ispyobj(op.result)
    ])

    pop_alives = len(
        [op for op in block.operations if op.opname == 'gc_pop_alive'])
    pyobj_pop_alives = len(
        [op for op in block.operations if op.opname == 'gc_pop_alive_pyobj'])
    if pop_alives == len(block.operations):
        # it's a block we inserted
        return
    for link in block.exits:
        assert block.exitswitch is not c_last_exception
        refs_out = 0
        for v2 in link.target.inputargs:
            if var_needsgc(v2) and not is_borrowed(v2):
                refs_out += 1
        pyobj_pushes = pyobj_push_alives + implicit_pyobj_pushalives
        nonpyobj_pushes = push_alives + nonpyobj_gc_returning_calls
        assert refs_in + pyobj_pushes + nonpyobj_pushes == pop_alives + pyobj_pop_alives + refs_out
示例#4
0
def checkblock(block, is_borrowed, is_start_block):
    if block.operations == ():
        # a return/exception block -- don't want to think about them
        # (even though the test passes for somewhat accidental reasons)
        return
    if is_start_block:
        refs_in = 0
    else:
        refs_in = len([v for v in block.inputargs if isinstance(v, Variable)
                                                  and var_needsgc(v)
                                                  and not is_borrowed(v)])
    push_alives = len([op for op in block.operations
                       if op.opname == 'gc_push_alive'])
    pyobj_push_alives = len([op for op in block.operations
                             if op.opname == 'gc_push_alive_pyobj'])

    # implicit_pyobj_pushalives included calls to things that return pyobject*
    implicit_pyobj_pushalives = len([op for op in block.operations
                                     if var_ispyobj(op.result)
                                     and op.opname not in ('getfield', 'getarrayitem', 'same_as')])
    nonpyobj_gc_returning_calls = len([op for op in block.operations
                                       if op.opname in ('direct_call', 'indirect_call')
                                       and var_needsgc(op.result)
                                       and not var_ispyobj(op.result)])

    pop_alives = len([op for op in block.operations
                      if op.opname == 'gc_pop_alive'])
    pyobj_pop_alives = len([op for op in block.operations
                            if op.opname == 'gc_pop_alive_pyobj'])
    if pop_alives == len(block.operations):
        # it's a block we inserted
        return
    for link in block.exits:
        assert block.exitswitch is not c_last_exception
        refs_out = 0
        for v2 in link.target.inputargs:
            if var_needsgc(v2) and not is_borrowed(v2):
                refs_out += 1
        pyobj_pushes = pyobj_push_alives + implicit_pyobj_pushalives
        nonpyobj_pushes = push_alives + nonpyobj_gc_returning_calls
        assert refs_in + pyobj_pushes + nonpyobj_pushes == pop_alives + pyobj_pop_alives + refs_out
示例#5
0
def test_getfield_pyobj():
    class S:
        pass
    def f(thing):
        s = S()
        s.x = thing
        return s.x
    t, transformer = rtype_and_transform(f, [object], _TestGCTransformer)
    fgraph = graphof(t, f)
    pyobj_getfields = 0
    pyobj_setfields = 0
    for b in fgraph.iterblocks():
        for op in b.operations:
            if op.opname == 'getfield' and var_ispyobj(op.result):
                pyobj_getfields += 1
            elif op.opname == 'bare_setfield' and var_ispyobj(op.args[2]):
                pyobj_setfields += 1
    # although there's only one explicit getfield in the code, a
    # setfield on a pyobj must get the old value out and decref it
    assert pyobj_getfields >= 2
    assert pyobj_setfields >= 1
示例#6
0
def test_call_return_pyobj():
    def g(factory):
        return factory()
    def f(factory):
        g(factory)
    t, transformer = rtype_and_transform(f, [object], _TestGCTransformer)
    fgraph = graphof(t, f)
    ops = getops(fgraph)
    calls = ops['direct_call']
    for call in calls:
        if call.result.concretetype is not lltype.Bool: #RPyExceptionOccurred()
            assert var_ispyobj(call.result)
示例#7
0
def test_getfield_pyobj():
    class S:
        pass

    def f(thing):
        s = S()
        s.x = thing
        return s.x

    t, transformer = rtype_and_transform(f, [object], _TestGCTransformer)
    fgraph = graphof(t, f)
    pyobj_getfields = 0
    pyobj_setfields = 0
    for b in fgraph.iterblocks():
        for op in b.operations:
            if op.opname == 'getfield' and var_ispyobj(op.result):
                pyobj_getfields += 1
            elif op.opname == 'bare_setfield' and var_ispyobj(op.args[2]):
                pyobj_setfields += 1
    # although there's only one explicit getfield in the code, a
    # setfield on a pyobj must get the old value out and decref it
    assert pyobj_getfields >= 2
    assert pyobj_setfields >= 1
示例#8
0
def test_call_return_pyobj():
    def g(factory):
        return factory()

    def f(factory):
        g(factory)

    t, transformer = rtype_and_transform(f, [object], _TestGCTransformer)
    fgraph = graphof(t, f)
    ops = getops(fgraph)
    calls = ops['direct_call']
    for call in calls:
        if call.result.concretetype is not lltype.Bool:  #RPyExceptionOccurred()
            assert var_ispyobj(call.result)
示例#9
0
    def dispatch(self):
        gct = self.gctransformer
        opname = self.spaceop.opname
        v_result = self.spaceop.result

        meth = getattr(gct, 'gct_' + opname, gct.default)
        meth(self)

        if var_needsgc(v_result):
            gct.livevars.append(v_result)
            if var_ispyobj(v_result):
                if opname in ('getfield', 'getarrayitem', 'same_as',
                                 'cast_pointer', 'getsubstruct',
                                 'getinteriorfield'):
                    # XXX more operations?
                    gct.push_alive(v_result, self.llops)
            elif opname not in ('direct_call', 'indirect_call'):
                gct.push_alive(v_result, self.llops)
示例#10
0
 def var_needs_set_transform(self, var):
     return var_ispyobj(var)
示例#11
0
 def pop_alive(self, var, llops):
     if var_ispyobj(var):
         self.pop_alive_pyobj(var, llops)
     else:
         self.pop_alive_nopyobj(var, llops)