Author: Armin Rigo <[email protected]>
Branch: concurrent-marksweep
Changeset: r48356:cba48e6cce2e
Date: 2011-10-23 11:51 +0200
http://bitbucket.org/pypy/pypy/changeset/cba48e6cce2e/

Log:    Varsized.

diff --git a/pypy/rpython/memory/gc/concurrentgen.py 
b/pypy/rpython/memory/gc/concurrentgen.py
--- a/pypy/rpython/memory/gc/concurrentgen.py
+++ b/pypy/rpython/memory/gc/concurrentgen.py
@@ -175,6 +175,8 @@
         size_gc_header = self.gcheaderbuilder.size_gc_header
         totalsize = size_gc_header + size
         adr = llarena.arena_malloc(llmemory.raw_malloc_usage(totalsize), 2)
+        if adr == llmemory.NULL:
+            raise MemoryError
         llarena.arena_reserve(adr, totalsize)
         obj = adr + size_gc_header
         hdr = self.header(obj)
@@ -185,47 +187,33 @@
 
     def malloc_varsize_clear(self, typeid, length, size, itemsize,
                              offset_to_length):
+        #
+        # For now, we always start the next collection as soon as the
+        # previous one is finished
+        if self.collector.running <= 0:
+            self.trigger_next_collection()
+        #
         size_gc_header = self.gcheaderbuilder.size_gc_header
         nonvarsize = size_gc_header + size
         #
-        # Compute the maximal length that makes the object still below
-        # 'small_request_threshold'.  All the following logic is usually
-        # constant-folded because size and itemsize are constants (due
-        # to inlining).
-        maxsize = self.small_request_threshold - raw_malloc_usage(nonvarsize)
-        if maxsize < 0:
-            toobig = r_uint(0)    # the nonvarsize alone is too big
-        elif raw_malloc_usage(itemsize):
-            toobig = r_uint(maxsize // raw_malloc_usage(itemsize)) + 1
-        else:
-            toobig = r_uint(sys.maxint) + 1
-
-        if r_uint(length) < r_uint(toobig):
-            # With the above checks we know now that totalsize cannot be more
-            # than 'small_request_threshold'; in particular, the + and *
-            # cannot overflow.
-            totalsize = nonvarsize + itemsize * length
-            totalsize = llarena.round_up_for_allocation(totalsize)
-            rawtotalsize = raw_malloc_usage(totalsize)
-            ll_assert(rawtotalsize & (WORD - 1) == 0,
-                      "round_up_for_allocation failed")
-            #
-            n = rawtotalsize >> WORD_POWER_2
-            result = self.location_free_lists[n]
-            if result != self.NULL:
-                self.location_free_lists[n] = list_next(result)
-                obj = self.grow_reservation(result, totalsize)
-                hdr = self.header(obj)
-                hdr.tid = self.combine(typeid, self.current_young_marker, 0)
-                (obj + offset_to_length).signed[0] = length
-                #debug_print("malloc_varsize_clear", obj)
-                return llmemory.cast_adr_to_ptr(obj, llmemory.GCREF)
+        if length < 0:
+            raise MemoryError
+        try:
+            totalsize = ovfcheck(nonvarsize + ovfcheck(itemsize * length))
+        except OverflowError:
+            raise MemoryError
         #
-        # If the total size of the object would be larger than
-        # 'small_request_threshold', or if the free_list is empty,
-        # then allocate it externally.  We also go there if 'length'
-        # is actually negative.
-        return self._malloc_varsize_slowpath(typeid, length)
+        adr = llarena.arena_malloc(llmemory.raw_malloc_usage(totalsize), 2)
+        if adr == llmemory.NULL:
+            raise MemoryError
+        llarena.arena_reserve(adr, totalsize)
+        obj = adr + size_gc_header
+        (obj + offset_to_length).signed[0] = length
+        hdr = self.header(obj)
+        hdr.tid = self.combine(typeid, self.current_young_marker, 0)
+        hdr.next = self.young_objects
+        self.young_objects = hdr
+        return llmemory.cast_adr_to_ptr(obj, llmemory.GCREF)
 
     # ----------
     # Other functions in the GC API
@@ -814,12 +802,13 @@
             if mark == cam:
                 # the object is still not marked.  Free it.
                 blockadr = llmemory.cast_ptr_to_adr(hdr)
+                blockadr = llarena.getfakearenaaddress(blockadr)
                 llarena.arena_free(blockadr)
                 #
             else:
                 # the object was marked: relink it
-                ll_assert(mark == MARK_BYTE_OLD,
-                          "bad mark in large object")
+                ll_assert(mark == self.gc.current_young_marker or
+                          mark == MARK_BYTE_OLD, "sweep: bad mark")
                 hdr.next = linked_list
                 linked_list = hdr
                 #
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to