Пример #1
0
    def double_space_size(self):
        self.red_zone = 0
        old_fromspace = self.fromspace
        newsize = self.space_size * 2
        newspace = llarena.arena_malloc(newsize, True)
        if not newspace:
            return False    # out of memory
        llarena.arena_free(old_fromspace)
        self.fromspace = newspace
        # now self.tospace contains the existing objects and
        # self.fromspace is the freshly allocated bigger space

        self.semispace_collect(size_changing=True)
        self.top_of_space = self.tospace + newsize
        # now self.tospace is the freshly allocated bigger space,
        # and self.fromspace is the old smaller space, now empty
        llarena.arena_free(self.fromspace)

        newspace = llarena.arena_malloc(newsize, True)
        if not newspace:
            # Complex failure case: we have in self.tospace a big chunk
            # of memory, and the two smaller original spaces are already gone.
            # Unsure if it's worth these efforts, but we can artificially
            # split self.tospace in two again...
            self.max_space_size = self.space_size    # don't try to grow again,
            #              because doing arena_free(self.fromspace) would crash
            self.fromspace = self.tospace + self.space_size
            self.top_of_space = self.fromspace
            ll_assert(self.free <= self.top_of_space,
                         "unexpected growth of GC space usage during collect")
            return False     # out of memory

        self.fromspace = newspace
        self.space_size = newsize
        return True    # success
Пример #2
0
    def double_space_size(self):
        self.red_zone = 0
        old_fromspace = self.fromspace
        newsize = self.space_size * 2
        newspace = llarena.arena_malloc(newsize, True)
        if not newspace:
            return False  # out of memory
        llarena.arena_free(old_fromspace)
        self.fromspace = newspace
        # now self.tospace contains the existing objects and
        # self.fromspace is the freshly allocated bigger space

        self.semispace_collect(size_changing=True)
        self.top_of_space = self.tospace + newsize
        # now self.tospace is the freshly allocated bigger space,
        # and self.fromspace is the old smaller space, now empty
        llarena.arena_free(self.fromspace)

        newspace = llarena.arena_malloc(newsize, True)
        if not newspace:
            # Complex failure case: we have in self.tospace a big chunk
            # of memory, and the two smaller original spaces are already gone.
            # Unsure if it's worth these efforts, but we can artificially
            # split self.tospace in two again...
            self.max_space_size = self.space_size  # don't try to grow again,
            #              because doing arena_free(self.fromspace) would crash
            self.fromspace = self.tospace + self.space_size
            self.top_of_space = self.fromspace
            ll_assert(self.free <= self.top_of_space,
                      "unexpected growth of GC space usage during collect")
            return False  # out of memory

        self.fromspace = newspace
        self.space_size = newsize
        return True  # success
Пример #3
0
 def mass_free(self, ok_to_free_func):
     objs = self.all_objects
     self.all_objects = []
     self.total_memory_used = 0
     for rawobj, nsize in objs:
         if ok_to_free_func(rawobj):
             llarena.arena_free(rawobj)
         else:
             self.all_objects.append((rawobj, nsize))
             self.total_memory_used += nsize
Пример #4
0
 def mass_free(self, ok_to_free_func):
     """For each object, if ok_to_free_func(obj) returns True, then free
     the object.
     """
     self.total_memory_used = r_uint(0)
     #
     # For each size class:
     size_class = self.small_request_threshold >> WORD_POWER_2
     while size_class >= 1:
         #
         # Walk the pages in 'page_for_size[size_class]' and
         # 'full_page_for_size[size_class]' and free some objects.
         # Pages completely freed are added to 'page.arena.freepages',
         # and become available for reuse by any size class.  Pages
         # not completely freed are re-chained either in
         # 'full_page_for_size[]' or 'page_for_size[]'.
         self.mass_free_in_pages(size_class, ok_to_free_func)
         #
         size_class -= 1
     #
     # Rehash arenas into the correct arenas_lists[i].  If
     # 'self.current_arena' contains an arena too, it remains there.
     (self.old_arenas_lists, self.arenas_lists) = (
         self.arenas_lists, self.old_arenas_lists)
     #
     i = 0
     while i < self.max_pages_per_arena:
         self.arenas_lists[i] = ARENA_NULL
         i += 1
     #
     i = 0
     while i < self.max_pages_per_arena:
         arena = self.old_arenas_lists[i]
         while arena != ARENA_NULL:
             nextarena = arena.nextarena
             #
             if arena.nfreepages == arena.totalpages:
                 #
                 # The whole arena is empty.  Free it.
                 llarena.arena_free(arena.base)
                 lltype.free(arena, flavor='raw', track_allocation=False)
                 #
             else:
                 # Insert 'arena' in the correct arenas_lists[n]
                 n = arena.nfreepages
                 ll_assert(n < self.max_pages_per_arena,
                          "totalpages != nfreepages >= max_pages_per_arena")
                 arena.nextarena = self.arenas_lists[n]
                 self.arenas_lists[n] = arena
             #
             arena = nextarena
         i += 1
     #
     self.min_empty_nfreepages = 1
Пример #5
0
 def mass_free_incremental(self, ok_to_free_func, max_pages):
     old = self.old_all_objects
     while old:
         rawobj, nsize = old.pop()
         if ok_to_free_func(rawobj):
             llarena.arena_free(rawobj)
         else:
             self.all_objects.append((rawobj, nsize))
             self.total_memory_used += nsize
         max_pages -= 0.1
         if max_pages <= 0:
             return False
     return True
Пример #6
0
 def mass_free_incremental(self, ok_to_free_func, max_pages):
     old = self.old_all_objects
     while old:
         rawobj, nsize = old.pop()
         if ok_to_free_func(rawobj):
             llarena.arena_free(rawobj)
         else:
             self.all_objects.append((rawobj, nsize))
             self.total_memory_used += nsize
         max_pages -= 0.1
         if max_pages <= 0:
             return False
     return True
Пример #7
0
def test_look_inside_object():
    # this code is also used in translation tests below
    myarenasize = 50
    a = arena_malloc(myarenasize, False)
    b = a + round_up_for_allocation(llmemory.sizeof(lltype.Char))
    arena_reserve(b, precomputed_size)
    (b + llmemory.offsetof(SX, 'x')).signed[0] = 123
    assert llmemory.cast_adr_to_ptr(b, SPTR).x == 123
    llmemory.cast_adr_to_ptr(b, SPTR).x += 1
    assert (b + llmemory.offsetof(SX, 'x')).signed[0] == 124
    arena_reset(a, myarenasize, True)
    arena_reserve(b, round_up_for_allocation(llmemory.sizeof(SX)))
    assert llmemory.cast_adr_to_ptr(b, SPTR).x == 0
    arena_free(a)
    return 42
Пример #8
0
def test_look_inside_object():
    # this code is also used in translation tests below
    myarenasize = 50
    a = arena_malloc(myarenasize, False)
    b = a + round_up_for_allocation(llmemory.sizeof(lltype.Char))
    arena_reserve(b, precomputed_size)
    (b + llmemory.offsetof(SX, 'x')).signed[0] = 123
    assert llmemory.cast_adr_to_ptr(b, SPTR).x == 123
    llmemory.cast_adr_to_ptr(b, SPTR).x += 1
    assert (b + llmemory.offsetof(SX, 'x')).signed[0] == 124
    arena_reset(a, myarenasize, True)
    arena_reserve(b, round_up_for_allocation(llmemory.sizeof(SX)))
    assert llmemory.cast_adr_to_ptr(b, SPTR).x == 0
    arena_free(a)
    return 42
Пример #9
0
 def _rehash_arenas_lists(self):
     #
     # Rehash arenas into the correct arenas_lists[i].  If
     # 'self.current_arena' contains an arena too, it remains there.
     (self.old_arenas_lists, self.arenas_lists) = (self.arenas_lists,
                                                   self.old_arenas_lists)
     #
     i = 0
     while i < self.max_pages_per_arena:
         self.arenas_lists[i] = ARENA_NULL
         i += 1
     #
     i = 0
     while i < self.max_pages_per_arena:
         arena = self.old_arenas_lists[i]
         while arena != ARENA_NULL:
             nextarena = arena.nextarena
             #
             if arena.nfreepages == arena.totalpages:
                 #
                 # The whole arena is empty.  Free it.
                 llarena.arena_reset(arena.base, self.arena_size, 4)
                 llarena.arena_free(arena.base)
                 self.total_memory_alloced -= self.arena_size
                 lltype.free(arena, flavor='raw', track_allocation=False)
                 self.arenas_count -= 1
                 #
             else:
                 # Insert 'arena' in the correct arenas_lists[n]
                 n = arena.nfreepages
                 ll_assert(
                     n < self.max_pages_per_arena,
                     "totalpages != nfreepages >= max_pages_per_arena")
                 arena.nextarena = self.arenas_lists[n]
                 self.arenas_lists[n] = arena
             #
             arena = nextarena
         i += 1
     #
     self.min_empty_nfreepages = 1
Пример #10
0
 def _rehash_arenas_lists(self):
     #
     # Rehash arenas into the correct arenas_lists[i].  If
     # 'self.current_arena' contains an arena too, it remains there.
     (self.old_arenas_lists, self.arenas_lists) = (
         self.arenas_lists, self.old_arenas_lists)
     #
     i = 0
     while i < self.max_pages_per_arena:
         self.arenas_lists[i] = ARENA_NULL
         i += 1
     #
     i = 0
     while i < self.max_pages_per_arena:
         arena = self.old_arenas_lists[i]
         while arena != ARENA_NULL:
             nextarena = arena.nextarena
             #
             if arena.nfreepages == arena.totalpages:
                 #
                 # The whole arena is empty.  Free it.
                 llarena.arena_reset(arena.base, self.arena_size, 4)
                 llarena.arena_free(arena.base)
                 lltype.free(arena, flavor='raw', track_allocation=False)
                 #
             else:
                 # Insert 'arena' in the correct arenas_lists[n]
                 n = arena.nfreepages
                 ll_assert(n < self.max_pages_per_arena,
                          "totalpages != nfreepages >= max_pages_per_arena")
                 arena.nextarena = self.arenas_lists[n]
                 self.arenas_lists[n] = arena
             #
             arena = nextarena
         i += 1
     #
     self.min_empty_nfreepages = 1
Пример #11
0
 def _teardown(self):
     debug_print("Teardown")
     llarena.arena_free(self.fromspace)
     llarena.arena_free(self.tospace)
Пример #12
0
 def f():
     a = llarena.arena_malloc(800, False)
     llarena.arena_reset(a, 800, 2)
     llarena.arena_free(a)
Пример #13
0
 def _teardown(self):
     debug_print("Teardown")
     llarena.arena_free(self.fromspace)
     llarena.arena_free(self.tospace)