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

Reply via email to