Author: Armin Rigo <[email protected]>
Branch: stm-gc-2
Changeset: r63334:064ecad6af6b
Date: 2013-04-13 16:01 +0200
http://bitbucket.org/pypy/pypy/changeset/064ecad6af6b/
Log: in-progress
diff --git a/rpython/memory/gc/stmtls.py b/rpython/memory/gc/stmtls.py
--- a/rpython/memory/gc/stmtls.py
+++ b/rpython/memory/gc/stmtls.py
@@ -29,7 +29,7 @@
nontranslated_dict = {}
- def __init__(self, gc):
+ def __init__(self, gc, StmGCThreadLocalAllocator=None):
debug_start("gc-init")
self.gc = gc
self.stm_operations = self.gc.stm_operations
@@ -41,6 +41,9 @@
llmemory.Address)
self.adr_of_stack_top = llop.gc_adr_of_root_stack_top(
llmemory.Address)
+ if StmGCThreadLocalAllocator is None:
+ from rpython.memory.gc.stmshared import StmGCThreadLocalAllocator
+ self.StmGCThreadLocalAllocator = StmGCThreadLocalAllocator
#
# --- current position, or NULL when mallocs are forbidden
self.nursery_free = NULL
@@ -59,8 +62,8 @@
self.nursery_top = self.nursery_stop
#
# --- a thread-local allocator for the shared area
- from rpython.memory.gc.stmshared import StmGCThreadLocalAllocator
- self.sharedarea_tls = StmGCThreadLocalAllocator(self.gc.sharedarea)
+ self.sharedarea_tls = self.StmGCThreadLocalAllocator(
+ self.gc.sharedarea)
# --- the LOCAL objects which are weakrefs. They are also listed
# in the appropriate place, like sharedarea_tls, if needed.
self.local_weakrefs = self.AddressStack()
@@ -196,9 +199,9 @@
self.detect_flag_combination = -1
#
# Move away the previous sharedarea_tls and start a new one.
- from rpython.memory.gc.stmshared import StmGCThreadLocalAllocator
previous_sharedarea_tls = self.sharedarea_tls
- self.sharedarea_tls = StmGCThreadLocalAllocator(self.gc.sharedarea)
+ self.sharedarea_tls = self.StmGCThreadLocalAllocator(
+ self.gc.sharedarea)
#
# List of LOCAL objects pending a visit. Note that no GLOBAL
# object can at any point contain a reference to a LOCAL object.
@@ -268,16 +271,17 @@
if not self.nursery_free:
fatalerror("malloc in a non-main thread but outside a transaction")
if llmemory.raw_malloc_usage(size) > self.nursery_size // 8 * 7:
- fatalerror("object too large to ever fit in the nursery")
- self.local_collection()
- free = self.nursery_free
- top = self.nursery_top
- if (top - free) < llmemory.raw_malloc_usage(size):
- # try again
- self.local_collection(run_finalizers=False)
- ll_assert(self.local_nursery_is_empty(), "nursery must be empty
[0]")
+ fatalerror("XXX object too large to ever fit in the nursery")
+ self.stm_operations.should_break_transaction()
+ step = 0
+ while True:
free = self.nursery_free
- return free
+ top = self.nursery_top
+ if (top - free) >= llmemory.raw_malloc_usage(size):
+ return free
+ ll_assert(step < 2, "nursery must be empty [0]")
+ self.local_collection(run_finalizers=(step==0))
+ step += 1
def is_in_nursery(self, addr):
ll_assert(llmemory.cast_adr_to_int(addr) & 1 == 0,
diff --git a/rpython/memory/gc/test/test_stmshared.py
b/rpython/memory/gc/test/test_stmshared.py
--- a/rpython/memory/gc/test/test_stmshared.py
+++ b/rpython/memory/gc/test/test_stmshared.py
@@ -55,3 +55,21 @@
gc.set_size(obj, 3*WORD)
thl1.free_object(obj)
thl1.delete()
+
+def test_allocation_is_thread_local():
+ gc = FakeGC()
+ shared = StmGCSharedArea(gc, 10*WORD, 2*WORD)
+ shared.setup()
+ thl1 = StmGCThreadLocalAllocator(shared)
+ thl2 = StmGCThreadLocalAllocator(shared)
+ #
+ assert len(thl1._seen_pages) == 0
+ thl1.malloc_object(2*WORD)
+ assert len(thl1._seen_pages) == 1
+ #
+ assert len(thl2._seen_pages) == 0
+ thl2.malloc_object(2*WORD)
+ assert len(thl2._seen_pages) == 1
+ #
+ thl1.delete()
+ thl2.delete()
diff --git a/rpython/memory/gc/test/test_stmtls.py
b/rpython/memory/gc/test/test_stmtls.py
--- a/rpython/memory/gc/test/test_stmtls.py
+++ b/rpython/memory/gc/test/test_stmtls.py
@@ -20,10 +20,45 @@
pass
def del_tls(self, tlsaddr):
pass
+ def should_break_transaction(self):
+ return False
class FakeSharedArea:
pass
+class FakeStmGCTL:
+ def __init__(self, stmshared):
+ assert isinstance(stmshared, FakeSharedArea)
+ self.gc = stmshared.gc
+ self.chained_list = NULL
+
+ def malloc_object_addr(self, totalsize):
+ return llarena.arena_malloc(llmemory.raw_malloc_usage(totalsize), 0)
+
+ def add_regular(self, obj):
+ self.gc.set_obj_revision(obj, self.chained_list)
+ self.chained_list = obj
+
+ def free_object(self, adr2):
+ adr1 = adr2 - self.gc.gcheaderbuilder.size_gc_header
+ llarena.arena_free(llarena.getfakearenaaddress(adr1))
+
+ def free_and_clear(self):
+ obj = self.chained_list
+ self.chained_list = NULL
+ while obj:
+ next = self.gc.obj_revision(obj)
+ self.free_object(obj)
+ obj = next
+
+ def free_and_clear_list(self, lst):
+ while lst.non_empty():
+ self.free_object(lst.pop())
+
+ def delete(self):
+ del self.gc
+ del self.chained_list
+
class FakeRootWalker:
STACK_DEPTH = 200
prebuilt_nongc = ()
@@ -111,8 +146,8 @@
def setup_method(self, meth):
self.gc = FakeGC()
self.gc.sharedarea.gc = self.gc
- self.gctls_main = StmGCTLS(self.gc)
- self.gctls_thrd = StmGCTLS(self.gc)
+ self.gctls_main = StmGCTLS(self.gc, FakeStmGCTL)
+ self.gctls_thrd = StmGCTLS(self.gc, FakeStmGCTL)
self.gc.main_thread_tls = self.gctls_main
self.gctls_main.start_transaction()
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit