[pypy-svn] r24539 - in pypy/dist/pypy/rpython/memory: . test
cfbolz at codespeak.net
cfbolz at codespeak.net
Sat Mar 18 19:14:30 CET 2006
Author: cfbolz
Date: Sat Mar 18 19:14:28 2006
New Revision: 24539
Modified:
pypy/dist/pypy/rpython/memory/gc.py
pypy/dist/pypy/rpython/memory/support.py
pypy/dist/pypy/rpython/memory/test/test_gc.py
pypy/dist/pypy/rpython/memory/test/test_gctransform.py
pypy/dist/pypy/rpython/memory/test/test_support.py
Log:
make the linked list implementation less braindead: don't allocate a cell of 8
byte for every append. use bigger chunks and also reuse them. This made some
changes necessary: Fix the deferred refcounting, because it inspected the
linked list directly in a non-valid way. Reset the FreeList in some tests,
because the annotator tries to make a pbc out of it, which is a bad idea, since
it contains non-NULL address constants.
Modified: pypy/dist/pypy/rpython/memory/gc.py
==============================================================================
--- pypy/dist/pypy/rpython/memory/gc.py (original)
+++ pypy/dist/pypy/rpython/memory/gc.py Sat Mar 18 19:14:28 2006
@@ -387,15 +387,15 @@
else:
self.collecting = True
roots = self.get_roots()
- curr = roots.first
- while 1:
- root = curr.address[1]
+ roots_copy = AddressLinkedList()
+ curr = roots.pop()
+ while curr != NULL:
## print "root", root, root.address[0]
## assert self.refcount(root.address[0]) >= 0, "refcount negative"
- self.incref(root.address[0])
- if curr.address[0] == NULL:
- break
- curr = curr.address[0]
+ self.incref(curr.address[0])
+ roots_copy.append(curr)
+ curr = roots.pop()
+ roots = roots_copy
dealloc_list = AddressLinkedList()
self.length_zero_ref_counts = 0
while 1:
Modified: pypy/dist/pypy/rpython/memory/support.py
==============================================================================
--- pypy/dist/pypy/rpython/memory/support.py (original)
+++ pypy/dist/pypy/rpython/memory/support.py Sat Mar 18 19:14:28 2006
@@ -5,31 +5,59 @@
INT_SIZE = sizeof(lltype.Signed)
+CHUNK_SIZE = 30
+
+class FreeList(object):
+ _alloc_flavor_ = "raw"
+
+ def __init__(self, size):
+ self.free_list = NULL
+ self.size = size
+
+ def get(self):
+ if self.free_list == NULL:
+ return raw_malloc(self.size * INT_SIZE)
+ result = self.free_list
+ self.free_list = result.address[0]
+ return result
+
+ def put(self, chunk):
+ chunk.address[0] = self.free_list
+ self.free_list = chunk
+
class AddressLinkedList(object):
_alloc_flavor_ = "raw"
+
+ unused_chunks = FreeList(CHUNK_SIZE + 2)
+
def __init__(self):
- self.first = NULL
- self.last = NULL
+ self.chunk = NULL
def append(self, addr):
if addr == NULL:
return
- new = raw_malloc(2 * INT_SIZE)
- if self.first == NULL:
- self.first = new
- else:
- self.last.address[0] = new
- self.last = new
- new.address[0] = NULL
- new.address[1] = addr
+ if self.chunk == NULL or self.chunk.signed[1] == CHUNK_SIZE:
+ new = AddressLinkedList.unused_chunks.get()
+ new.address[0] = self.chunk
+ new.signed[1] = 0
+ self.chunk = new
+ used_chunks = self.chunk.signed[1]
+ self.chunk.signed[1] += 1
+ self.chunk.address[used_chunks + 2] = addr
def pop(self):
- if self.first == NULL:
- return NULL
- result = self.first.address[1]
- next = self.first.address[0]
- raw_free(self.first)
- self.first = next
+ used_chunks = self.chunk.signed[1]
+ if used_chunks == 0:
+ old = self.chunk
+ previous = old.address[0]
+ if previous == NULL:
+ return NULL
+ self.chunk = previous
+ AddressLinkedList.unused_chunks.put(old)
+ used_chunks = self.chunk.signed[1]
+ result = self.chunk.address[used_chunks + 1]
+ self.chunk.address[used_chunks + 1] = NULL
+ self.chunk.signed[1] = used_chunks - 1
return result
def free(self):
Modified: pypy/dist/pypy/rpython/memory/test/test_gc.py
==============================================================================
--- pypy/dist/pypy/rpython/memory/test/test_gc.py (original)
+++ pypy/dist/pypy/rpython/memory/test/test_gc.py Sat Mar 18 19:14:28 2006
@@ -6,7 +6,7 @@
from pypy.rpython.rtyper import RPythonTyper
from pypy.rpython.memory.gc import GCError, MarkSweepGC, SemiSpaceGC
from pypy.rpython.memory.gc import DeferredRefcountingGC, DummyGC
-from pypy.rpython.memory.support import AddressLinkedList, INT_SIZE
+from pypy.rpython.memory.support import AddressLinkedList, INT_SIZE, CHUNK_SIZE, FreeList
from pypy.rpython.memory.lladdress import raw_malloc, raw_free, NULL
from pypy.rpython.memory.simulator import MemorySimulatorError
from pypy.rpython.memory import gclltype
@@ -97,6 +97,7 @@
class TestMarkSweepGCRunningOnLLinterp(TestMarkSweepGC):
def setup_class(cls):
+ AddressLinkedList.unused_chunks = FreeList(CHUNK_SIZE + 2) # 'leaks' but well
cls.prep_old = gclltype.prepare_graphs_and_create_gc
gclltype.prepare_graphs_and_create_gc = gclltype.create_gc_run_on_llinterp
def teardown_class(cls):
@@ -111,6 +112,7 @@
class TestSemiSpaceGCRunningOnLLinterp(TestMarkSweepGC):
def setup_class(cls):
+ AddressLinkedList.unused_chunks = FreeList(CHUNK_SIZE + 2) # 'leaks' but well
cls.prep_old = gclltype.prepare_graphs_and_create_gc
gclltype.prepare_graphs_and_create_gc = gclltype.create_gc_run_on_llinterp
gclltype.use_gc = SemiSpaceGC
@@ -130,6 +132,7 @@
class TestDeferredRefcountingGCRunningOnLLinterp(TestMarkSweepGC):
def setup_class(cls):
+ AddressLinkedList.unused_chunks = FreeList(CHUNK_SIZE + 2) # 'leaks' but well
cls.prep_old = gclltype.prepare_graphs_and_create_gc
gclltype.prepare_graphs_and_create_gc = gclltype.create_gc_run_on_llinterp
gclltype.use_gc = DeferredRefcountingGC
@@ -148,6 +151,7 @@
class TestDummyGCRunningOnLLinterp(TestMarkSweepGC):
def setup_class(cls):
+ AddressLinkedList.unused_chunks = FreeList(CHUNK_SIZE + 2) # 'leaks' but well
cls.prep_old = gclltype.prepare_graphs_and_create_gc
gclltype.prepare_graphs_and_create_gc = gclltype.create_gc_run_on_llinterp
gclltype.use_gc = DummyGC
Modified: pypy/dist/pypy/rpython/memory/test/test_gctransform.py
==============================================================================
--- pypy/dist/pypy/rpython/memory/test/test_gctransform.py (original)
+++ pypy/dist/pypy/rpython/memory/test/test_gctransform.py Sat Mar 18 19:14:28 2006
@@ -1,4 +1,4 @@
-from pypy.rpython.memory import gctransform
+from pypy.rpython.memory import gctransform, support
from pypy.objspace.flow.model import c_last_exception, Variable
from pypy.rpython.memory.gctransform import var_needsgc, var_ispyobj
from pypy.translator.translator import TranslationContext, graphof
@@ -620,6 +620,7 @@
# tests for FrameworkGCTransformer
def test_framework_simple():
+ support.AddressLinkedList.unused_chunks = support.FreeList(support.CHUNK_SIZE + 2) # 'leaks' but well
def g(x):
return x + 1
class A(object):
Modified: pypy/dist/pypy/rpython/memory/test/test_support.py
==============================================================================
--- pypy/dist/pypy/rpython/memory/test/test_support.py (original)
+++ pypy/dist/pypy/rpython/memory/test/test_support.py Sat Mar 18 19:14:28 2006
@@ -1,5 +1,5 @@
from pypy.rpython.objectmodel import free_non_gc_object
-from pypy.rpython.memory.support import AddressLinkedList
+from pypy.rpython.memory.support import AddressLinkedList, FreeList, CHUNK_SIZE
from pypy.rpython.memory.lladdress import raw_malloc, raw_free, NULL
from pypy.rpython.memory.test.test_llinterpsim import interpret
@@ -11,11 +11,11 @@
ll.append(addr + 1)
ll.append(addr + 2)
a = ll.pop()
- assert a == addr
+ assert a - addr == 2
a = ll.pop()
assert a - addr == 1
a = ll.pop()
- assert a - addr == 2
+ assert a == addr
assert ll.pop() == NULL
assert ll.pop() == NULL
ll.append(addr)
@@ -28,6 +28,25 @@
ll.free()
free_non_gc_object(ll)
raw_free(addr)
+
+ def test_big_access(self):
+ addr = raw_malloc(1)
+ ll = AddressLinkedList()
+ for i in range(1000):
+ print i
+ ll.append(addr + i)
+ for i in range(1000)[::-1]:
+ a = ll.pop()
+ assert a - addr == i
+ for i in range(1000):
+ print i
+ ll.append(addr + i)
+ for i in range(1000)[::-1]:
+ a = ll.pop()
+ assert a - addr == i
+ ll.free()
+ free_non_gc_object(ll)
+ raw_free(addr)
def test_linked_list_annotate():
def f():
@@ -37,14 +56,24 @@
ll.append(addr + 1)
ll.append(addr + 2)
a = ll.pop()
- res = a == addr
+ res = (a - addr == 2)
a = ll.pop()
res = res and (a - addr == 1)
a = ll.pop()
- res = res and (a - addr == 2)
+ res = res and a == addr
res = res and (ll.pop() == NULL)
res = res and (ll.pop() == NULL)
ll.append(addr)
+ for i in range(100):
+ ll.append(addr + i)
+ for i in range(99, -1, -1):
+ a = ll.pop()
+ res = res and (a - addr == i)
+ for i in range(100):
+ ll.append(addr + i)
+ for i in range(99, -1, -1):
+ a = ll.pop()
+ res = res and (a - addr == i)
ll.free()
free_non_gc_object(ll)
ll = AddressLinkedList()
@@ -59,5 +88,8 @@
## res = a.build_types(f, [])
## a.translator.specialize()
## a.translator.view()
+ assert f()
+ # grumpf: make sure that we don't get a polluted class attribute
+ AddressLinkedList.unused_chunks = FreeList(CHUNK_SIZE + 2)
res = interpret(f, [])
assert res
More information about the Pypy-commit
mailing list