コード例 #1
0
    def test_reuse_closed_handles(self):
        from hpy.universal import _debug
        mod = self.make_module("""
            HPyDef_METH(f, "f", f_impl, HPyFunc_O)
            static HPy f_impl(HPyContext *ctx, HPy self, HPy arg)
            {
                return HPy_Dup(ctx, ctx->h_None);
            }
            HPyDef_METH(leak, "leak", leak_impl, HPyFunc_O)
            static HPy leak_impl(HPyContext *ctx, HPy self, HPy arg)
            {
                HPy_Dup(ctx, arg); // leak!
                return HPy_Dup(ctx, ctx->h_None);
            }
            @EXPORT(f)
            @EXPORT(leak)
            @INIT
        """)

        old_size = _debug.get_closed_handles_queue_max_size()
        try:
            gen = _debug.new_generation()
            # call f twice to open/closes a bunch of handles
            mod.f('hello')
            mod.f('world')
            #
            # make sure that the closed_handles queue is considered full: this
            # will force the reuse of existing closed handles
            _debug.set_closed_handles_queue_max_size(1)
            # during the call to leak, we create handles for:
            #   1. self
            #   2. arg
            #   3. HPy_Dup(arg) (leaking)
            #   4. result
            # So the leaked handle will be 3rd in the old closed_handles queue
            closed_handles = _debug.get_closed_handles()
            mod.leak('foo')
            assert not closed_handles[2].is_closed
            assert closed_handles[2].obj == 'foo'

            closed_handles = _debug.get_closed_handles()
            mod.leak('bar')
            assert not closed_handles[2].is_closed
            assert closed_handles[2].obj == 'bar'

            leaks = _debug.get_open_handles(gen)
            for h in leaks:
                h._force_close()
        finally:
            _debug.set_closed_handles_queue_max_size(old_size)
コード例 #2
0
 def test_closed_handles(self):
     from hpy.universal import _debug
     mod = self.make_leak_module()
     gen = _debug.new_generation()
     mod.leak('hello')
     h_hello, = _debug.get_open_handles(gen)
     assert not h_hello.is_closed
     h_hello._force_close()
     assert h_hello.is_closed
     assert _debug.get_open_handles(gen) == []
     assert h_hello in _debug.get_closed_handles()
     assert repr(h_hello) == "<DebugHandle 0x%x CLOSED>" % h_hello.id
コード例 #3
0
def test_closed_handles(compiler, with_alloc_trace):
    from hpy.universal import _debug
    mod = make_leak_module(compiler)
    gen = _debug.new_generation()
    mod.leak('hello')
    h_hello, = _debug.get_open_handles(gen)
    assert not h_hello.is_closed
    h_hello._force_close()
    assert h_hello.is_closed
    assert _debug.get_open_handles(gen) == []
    assert h_hello in _debug.get_closed_handles()
    assert repr(h_hello).startswith("<DebugHandle 0x%x CLOSED>" % h_hello.id)
コード例 #4
0
ファイル: test_charptr.py プロジェクト: oracle/graalpython
 def clear_raw_data_in_closed_handles():
     closed_size = len(_debug.get_closed_handles())
     old_limit = _debug.get_closed_handles_queue_max_size()
     try:
         # make sure that the closed_handles queue is considered full: this
         # will force the reuse of existing closed handles.
         _debug.set_closed_handles_queue_max_size(closed_size)
         # Dummy call to force the reuse of the existing closed handles
         # -2 because 'self' and the 'arg' should already reuse 2 handles
         mod.g(closed_size - 2)
     finally:
         _debug.set_closed_handles_queue_max_size(old_limit)
     return closed_size
コード例 #5
0
 def test_closed_handles_queue_max_size(self):
     from hpy.universal import _debug
     mod = self.make_module("""
         HPyDef_METH(f, "f", f_impl, HPyFunc_O)
         static HPy f_impl(HPyContext *ctx, HPy self, HPy arg)
         {
             return HPy_Dup(ctx, ctx->h_None);
         }
         @EXPORT(f)
         @INIT
     """)
     old_size = _debug.get_closed_handles_queue_max_size()
     try:
         # by calling "f" we open and close 3 handles: 1 for self, 1 for arg
         # and 1 for the result. So, every call to f() increases the size of
         # closed_handles() by 3
         n1 = len(_debug.get_closed_handles())
         _debug.set_closed_handles_queue_max_size(n1+7)
         assert _debug.get_closed_handles_queue_max_size() == n1+7
         #
         mod.f('aaa')
         n2 = len(_debug.get_closed_handles())
         assert n2 == n1+3
         #
         mod.f('bbb')
         n3 = len(_debug.get_closed_handles())
         assert n3 == n2+3
         # with the next call we reach the maximum size of the queue
         mod.f('ccc')
         n4 = len(_debug.get_closed_handles())
         assert n4 == n1+7
         #
         # same as before
         mod.f('ddd')
         n5 = len(_debug.get_closed_handles())
         assert n5 == n1+7
     finally:
         _debug.set_closed_handles_queue_max_size(old_size)
コード例 #6
0
ファイル: test_charptr.py プロジェクト: oracle/graalpython
def test_charptr_limit_stress_test(compiler):
    from hpy.universal import _debug
    mod = compiler.make_module("""
        HPyDef_METH(f, "f", f_impl, HPyFunc_O)
        static HPy f_impl(HPyContext *ctx, HPy self, HPy arg)
        {
            HPy_ssize_t size;
            HPyUnicode_AsUTF8AndSize(ctx, arg, &size);
            if (size == 0) {
                return HPy_NULL;
            }
            return HPy_Dup(ctx, ctx->h_None);
        }

        // Dummy function just to force handle creation, but should not create
        // any raw data attached to those handles
        HPyDef_METH(g, "g", g_impl, HPyFunc_O)
        static HPy g_impl(HPyContext *ctx, HPy self, HPy arg)
        {
            int len = HPyLong_AsLong(ctx, arg);
            for (int i = 0; i < len; ++i) {
                HPy h = HPyLong_FromLong(ctx, i);
                HPy_Close(ctx, h);
            }
            return HPy_Dup(ctx, ctx->h_None);
        }

        @EXPORT(f)
        @EXPORT(g)
        @INIT
    """)

    def get_raw_data_sizes(handles):
        return list(map(lambda h: h.raw_data_size, handles))

    def clear_raw_data_in_closed_handles():
        closed_size = len(_debug.get_closed_handles())
        old_limit = _debug.get_closed_handles_queue_max_size()
        try:
            # make sure that the closed_handles queue is considered full: this
            # will force the reuse of existing closed handles.
            _debug.set_closed_handles_queue_max_size(closed_size)
            # Dummy call to force the reuse of the existing closed handles
            # -2 because 'self' and the 'arg' should already reuse 2 handles
            mod.g(closed_size - 2)
        finally:
            _debug.set_closed_handles_queue_max_size(old_limit)
        return closed_size

    old_raw_data_max_size = _debug.get_protected_raw_data_max_size()
    old_closed_handles_max_size = _debug.get_closed_handles_queue_max_size()
    _debug.set_protected_raw_data_max_size(100)
    try:
        # Reset the state as much as possible:
        closed_size = clear_raw_data_in_closed_handles()
        # Make enough room for the handles created by this test
        _debug.set_closed_handles_queue_max_size(closed_size + 100)
        # Sanity check: no raw data is now held by closed handles
        initial = get_raw_data_sizes(_debug.get_closed_handles())
        assert all(map(lambda x: x == -1, initial))

        # Large string that shouldn't be retained at all
        gen = _debug.new_generation()
        mod.f('abc' * 50)
        closed1 = get_raw_data_sizes(_debug.get_closed_handles(gen))
        assert closed1 == [-1, -1, -1]  # -1 for 'self' and the return value

        # Two small strings, should be kept, one large that should not fit in
        gen = _debug.new_generation()
        mod.f('a' * 31)
        mod.f('b' * 32)
        mod.f('c' * 50)
        closed2 = get_raw_data_sizes(_debug.get_closed_handles(gen))
        # -1 for 'self'/return value for each call, and the long string
        # note: C strings' size is +1 for the terminating '\0'
        assert sorted(closed2) == [-1] * 7 + [32, 33]

        # Another small string should still fit
        gen = _debug.new_generation()
        mod.f('a' * 13)
        closed3 = get_raw_data_sizes(_debug.get_closed_handles(gen))
        # 'self'/return, and the expected small string
        assert sorted(closed3) == [-1, -1, 14]

        # But another small-ish string not anymore
        gen = _debug.new_generation()
        mod.f('a' * 27)
        closed4 = get_raw_data_sizes(_debug.get_closed_handles(gen))
        # 'self'/return, and the string whose raw data didn't fit in
        assert sorted(closed4) == [-1, -1, -1]

        # Check that raw data of closed handles is freed when the handle
        # is reused
        closed_size = clear_raw_data_in_closed_handles()

        # None of the closed handles should now have any raw data attached
        all_closed = _debug.get_closed_handles()
        assert len(all_closed) == closed_size  # Sanity check
        for h in all_closed:
            assert h.raw_data_size == -1
    finally:
        _debug.set_protected_raw_data_max_size(old_raw_data_max_size)
        _debug.set_closed_handles_queue_max_size(old_closed_handles_max_size)