Author: Armin Rigo <[email protected]>
Branch: stm-gc-2
Changeset: r63276:ecd0227c4dfb
Date: 2013-04-10 20:32 +0200
http://bitbucket.org/pypy/pypy/changeset/ecd0227c4dfb/

Log:    tweaks

diff --git a/rpython/memory/gc/stmshared.py b/rpython/memory/gc/stmshared.py
--- a/rpython/memory/gc/stmshared.py
+++ b/rpython/memory/gc/stmshared.py
@@ -98,41 +98,36 @@
         self.pages_for_size = lltype.malloc(
             rffi.CArray(PAGE_PTR), length, flavor='raw', zero=True)
         #
-        # This array contains 'length' chained lists of free object locations.
-        self.free_objects_for_size = lltype.malloc(
+        # This array contains 'length' chained lists of free locations.
+        self.free_loc_for_size = lltype.malloc(
             rffi.CArray(llmemory.Address), length, flavor='raw', zero=True)
         #
         if not we_are_translated():
             self._seen_pages = set()
 
-    def free(self):
-        lltype.free(self.free_objects_for_size, flavor='raw')
-        lltype.free(self.pages_for_size, flavor='raw')
-        self.delete()
-
     def _malloc_size_class(self, size_class):
         """Malloc one object of the given size_class (== number of WORDs)."""
         ll_assert(size_class > 0, "malloc_size_class: null or neg size_class")
         ll_assert(size_class <= self.sharedarea.small_request_threshold,
                   "malloc_size_class: too big")
         #
-        # The result is simply 'free_objects_for_size[size_class]'
-        result = self.free_objects_for_size[size_class]
+        # The result is simply 'free_loc_for_size[size_class]'
+        result = self.free_loc_for_size[size_class]
         if not result:
             result = self._allocate_new_page(size_class)
-        self.free_objects_for_size[size_class] = result.address[0]
+        self.free_loc_for_size[size_class] = result.address[0]
         llarena.arena_reset(result, llmemory.sizeof(llmemory.Address), 0)
         return result
     _malloc_size_class._always_inline_ = True
 
-    def _free_size_class(self, obj, size_class):
-        """Free a single object 'obj', which is of the given size_class."""
-        # just link 'obj' to the start of 'free_objects_for_size[size_class]'
-        obj = llarena.getfakearenaaddress(obj)
-        llarena.arena_reset(obj, size_class << WORD_POWER_2, 0)
-        llarena.arena_reserve(obj, llmemory.sizeof(llmemory.Address))
-        obj.address[0] = self.free_objects_for_size[size_class]
-        self.free_objects_for_size[size_class] = obj
+    def _free_size_class(self, adr, size_class):
+        """Free a single location 'adr', which is of the given size_class."""
+        # just link 'adr' to the start of 'free_loc_for_size[size_class]'
+        adr = llarena.getfakearenaaddress(adr)
+        llarena.arena_reset(adr, size_class << WORD_POWER_2, 0)
+        llarena.arena_reserve(adr, llmemory.sizeof(llmemory.Address))
+        adr.address[0] = self.free_loc_for_size[size_class]
+        self.free_loc_for_size[size_class] = adr
     _free_size_class._always_inline_ = True
 
     def _allocate_new_page(self, size_class):
@@ -141,7 +136,7 @@
         result = llarena.arena_malloc(self.sharedarea.page_size, 0)
         if not result:
             fatalerror("FIXME: Out of memory! (should raise MemoryError)")
-            return PAGE_NULL
+            return NULL
         if not we_are_translated():
             self._seen_pages.add(result)
         llarena.arena_reserve(result, llmemory.sizeof(PAGE_HEADER))
@@ -153,9 +148,9 @@
         #
         # Initialize the chained list in the page
         head = result + llmemory.sizeof(PAGE_HEADER)
-        ll_assert(not self.free_objects_for_size[size_class],
-                  "free_objects_for_size is supposed to contain NULL here")
-        self.free_objects_for_size[size_class] = head
+        ll_assert(not self.free_loc_for_size[size_class],
+                  "free_loc_for_size is supposed to contain NULL here")
+        self.free_loc_for_size[size_class] = head
         #
         i = self.sharedarea.nblocks_for_size[size_class]
         nsize = size_class << WORD_POWER_2
@@ -180,11 +175,11 @@
         if nsize <= self.sharedarea.small_request_threshold:
             size_class = (nsize + WORD_POWER_2 - 1) >> WORD_POWER_2
             result = self._malloc_size_class(size_class)
-            llarena.arena_reserve(result, _dummy_size(totalsize))
-            return result
         else:
-            XXX
-            #llarena.arena_malloc(llmemory.raw_malloc_usage(totalsize), 0)
+            result = llarena.arena_malloc(
+                llmemory.raw_malloc_usage(totalsize), 0)
+        llarena.arena_reserve(result, _dummy_size(totalsize))
+        return result + self.gc.gcheaderbuilder.size_gc_header
 
     def add_regular(self, obj):
         """After malloc_object(), register the object in the internal chained
@@ -193,12 +188,12 @@
         self.chained_list = obj
 
     def free_object(self, obj):
+        adr1 = obj - self.gc.gcheaderbuilder.size_gc_header
         osize = self.gc.get_size_incl_hash(obj)
         if osize <= self.sharedarea.small_request_threshold:
             size_class = (osize + WORD_POWER_2 - 1) >> WORD_POWER_2
-            self._free_size_class(obj, size_class)
+            self._free_size_class(adr1, size_class)
         else:
-            adr1 = obj - self.gc.gcheaderbuilder.size_gc_header
             llarena.arena_free(llarena.getfakearenaaddress(adr1))
 
     def free_and_clear(self):
@@ -214,6 +209,8 @@
             self.free_object(lst.pop())
 
     def delete(self):
+        lltype.free(self.free_loc_for_size, flavor='raw')
+        lltype.free(self.pages_for_size, flavor='raw')
         free_non_gc_object(self)
 
 
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
@@ -77,7 +77,7 @@
         self._cleanup_state()
         self._unregister_with_C_code()
         self.local_weakrefs.delete()
-        self.sharedarea_tls.free()
+        self.sharedarea_tls.delete()
         self._free_nursery(self.nursery_start)
         free_non_gc_object(self)
 
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
@@ -3,8 +3,21 @@
 from rpython.memory.gc.stmshared import StmGCThreadLocalAllocator
 
 
+class FakeGC:
+    class gcheaderbuilder:
+        size_gc_header = 3
+    def __init__(self):
+        self._object_sizes = {}
+    def set_size(self, obj, size):
+        assert obj not in self._object_sizes
+        self._object_sizes[obj] = size
+    def get_size_incl_hash(self, obj):
+        return self._object_sizes[obj]
+
+
 def test_simple():
-    shared = StmGCSharedArea("gc", 10*WORD, 2*WORD)
+    gc = FakeGC()
+    shared = StmGCSharedArea(gc, 10*WORD, 2*WORD)
     shared.setup()
     thl1 = StmGCThreadLocalAllocator(shared)
     thl1.malloc_object(2*WORD-1)
@@ -19,16 +32,7 @@
     assert len(thl1._seen_pages) == 3
     thl1.malloc_object(2*WORD)
     assert len(thl1._seen_pages) == 3
-    thl1.free()
-
-class FakeGC:
-    def __init__(self):
-        self._object_sizes = {}
-    def set_size(self, obj, size):
-        assert obj not in self._object_sizes
-        self._object_sizes[obj] = size
-    def get_size_incl_hash(self, obj):
-        return self._object_sizes[obj]
+    thl1.delete()
 
 def test_free():
     gc = FakeGC()
@@ -40,4 +44,14 @@
     thl1.free_object(obj)
     obj2 = thl1.malloc_object(2*WORD)
     assert obj2 == obj     # reusing the same location
-    thl1.free()
+    thl1.delete()
+
+def test_big_object():
+    gc = FakeGC()
+    shared = StmGCSharedArea(gc, 10*WORD, 2*WORD)
+    shared.setup()
+    thl1 = StmGCThreadLocalAllocator(shared)
+    obj = thl1.malloc_object(3*WORD)
+    gc.set_size(obj, 3*WORD)
+    thl1.free_object(obj)
+    thl1.delete()
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to