[pypy-svn] r77085 - in pypy/branch/gen2-gc/pypy/rpython/memory/gc: . test
arigo at codespeak.net
arigo at codespeak.net
Wed Sep 15 13:56:02 CEST 2010
Author: arigo
Date: Wed Sep 15 13:56:01 2010
New Revision: 77085
Modified:
pypy/branch/gen2-gc/pypy/rpython/memory/gc/minimarkpage.py
pypy/branch/gen2-gc/pypy/rpython/memory/gc/test/test_minimarkpage.py
Log:
Another test, and implementation.
Modified: pypy/branch/gen2-gc/pypy/rpython/memory/gc/minimarkpage.py
==============================================================================
--- pypy/branch/gen2-gc/pypy/rpython/memory/gc/minimarkpage.py (original)
+++ pypy/branch/gen2-gc/pypy/rpython/memory/gc/minimarkpage.py Wed Sep 15 13:56:01 2010
@@ -187,42 +187,63 @@
size_class = self.small_request_threshold / WORD
while size_class >= 1:
#
- # Walk the pages in 'page_for_size[size_class]' and free objects.
+ # 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 'self.free_pages', and
# become available for reuse by any size class. Pages not
- # completely freed are re-chained in 'newlist'.
- self.mass_free_in_partial_list(size_class, ok_to_free_func)
+ # completely freed are re-chained either in
+ # 'full_page_for_size[]' or 'page_for_size[]'.
+ self.mass_free_in_page(size_class, ok_to_free_func)
#
size_class -= 1
- def mass_free_in_partial_list(self, size_class, ok_to_free_func):
- page = self.page_for_size[size_class]
+ def mass_free_in_page(self, size_class, ok_to_free_func):
nblocks = self.nblocks_for_size[size_class]
block_size = size_class * WORD
- remaining_pages = PAGE_NULL
+ remaining_partial_pages = PAGE_NULL
+ remaining_full_pages = PAGE_NULL
#
- while page != PAGE_NULL:
- #
- # Collect the page.
- surviving = self.walk_page(page, block_size,
- nblocks, ok_to_free_func)
- nextpage = page.nextpage
+ step = 0
+ while step < 2:
+ if step == 0:
+ page = self.full_page_for_size[size_class]
+ else:
+ page = self.page_for_size[size_class]
#
- if surviving > 0:
+ while page != PAGE_NULL:
#
- # Found at least 1 object surviving. Re-insert the page
- # in the chained list.
- page.nextpage = remaining_pages
- remaining_pages = page
+ # Collect the page.
+ surviving = self.walk_page(page, block_size,
+ nblocks, ok_to_free_func)
+ nextpage = page.nextpage
#
- else:
- # No object survives; free the page.
- self.free_page(page)
+ if surviving == nblocks:
+ #
+ # The page is still full. Re-insert it in the
+ # 'remaining_full_pages' chained list.
+ ll_assert(step == 0,
+ "A non-full page became full while freeing")
+ page.nextpage = remaining_full_pages
+ remaining_full_pages = page
+ #
+ elif surviving > 0:
+ #
+ # There is at least 1 object surviving. Re-insert
+ # the page in the 'remaining_partial_pages' chained list.
+ page.nextpage = remaining_partial_pages
+ remaining_partial_pages = page
+ #
+ else:
+ # No object survives; free the page.
+ self.free_page(page)
- page = nextpage
+ page = nextpage
+ #
+ step += 1
#
- self.page_for_size[size_class] = remaining_pages
+ self.page_for_size[size_class] = remaining_partial_pages
+ self.full_page_for_size[size_class] = remaining_full_pages
def free_page(self, page):
Modified: pypy/branch/gen2-gc/pypy/rpython/memory/gc/test/test_minimarkpage.py
==============================================================================
--- pypy/branch/gen2-gc/pypy/rpython/memory/gc/test/test_minimarkpage.py (original)
+++ pypy/branch/gen2-gc/pypy/rpython/memory/gc/test/test_minimarkpage.py Wed Sep 15 13:56:01 2010
@@ -69,10 +69,11 @@
page = llmemory.cast_adr_to_ptr(pageaddr, PAGE_PTR)
page.nfree = 0
page.nuninitialized = nblocks - nusedblocks
- page.freeblock = pageaddr + hdrsize + nusedblocks * size_block
if nusedblocks < nblocks:
+ page.freeblock = pageaddr + hdrsize + nusedblocks * size_block
chainedlists = ac.page_for_size
else:
+ page.freeblock = NULL
chainedlists = ac.full_page_for_size
page.nextpage = chainedlists[size_class]
chainedlists[size_class] = page
@@ -226,3 +227,20 @@
assert pageaddr == ac.free_pages
assert pageaddr.address[0] == NULL
assert ac.page_for_size[2] == PAGE_NULL
+
+def test_mass_free_full_remains_full():
+ pagesize = hdrsize + 7*WORD
+ ac = arena_collection_for_test(pagesize, "#", fill_with_objects=2)
+ ok_to_free = OkToFree(ac, False)
+ ac.mass_free(ok_to_free)
+ assert ok_to_free.seen == [hdrsize + 0*WORD,
+ hdrsize + 2*WORD,
+ hdrsize + 4*WORD]
+ page = getpage(ac, 0)
+ assert page == ac.full_page_for_size[2]
+ assert page.nextpage == PAGE_NULL
+ assert page.nuninitialized == 0
+ assert page.nfree == 0
+ assert page.freeblock == NULL
+ assert ac.free_pages == NULL
+ assert ac.page_for_size[2] == PAGE_NULL
More information about the Pypy-commit
mailing list