[pypy-svn] r47414 - in pypy/dist/pypy/rpython/memory: . gctransform

arigo at codespeak.net arigo at codespeak.net
Fri Oct 12 20:57:51 CEST 2007


Author: arigo
Date: Fri Oct 12 20:57:51 2007
New Revision: 47414

Modified:
   pypy/dist/pypy/rpython/memory/gc.py
   pypy/dist/pypy/rpython/memory/gctransform/framework.py
Log:
* allow the framework to inline a version of malloc_fixedsize
  for the most common case.
* tweak SemiSpaceGC so that its malloc_fixedsize contains the
  minimum amount of operations after such an inlining.


Modified: pypy/dist/pypy/rpython/memory/gc.py
==============================================================================
--- pypy/dist/pypy/rpython/memory/gc.py	(original)
+++ pypy/dist/pypy/rpython/memory/gc.py	Fri Oct 12 20:57:51 2007
@@ -951,6 +951,7 @@
 class SemiSpaceGC(GCBase):
     _alloc_flavor_ = "raw"
     moving_gc = True
+    inline_simple_malloc = True
 
     HDR = lltype.Struct('header', ('forw', llmemory.Address),
                                   ('typeid', lltype.Signed))
@@ -980,13 +981,14 @@
                          contains_weakptr=False):
         size_gc_header = self.gcheaderbuilder.size_gc_header
         totalsize = size_gc_header + size
-        if raw_malloc_usage(totalsize) > self.top_of_space - self.free:
-            if not can_collect or not self.obtain_free_space(totalsize):
-                raise memoryError
         result = self.free
+        if raw_malloc_usage(totalsize) > self.top_of_space - result:
+            if not can_collect:
+                raise memoryError
+            result = self.obtain_free_space(totalsize)
         llarena.arena_reserve(result, totalsize)
         self.init_gc_object(result, typeid)
-        self.free += totalsize
+        self.free = result + totalsize
         if has_finalizer:
             self.objects_with_finalizers.append(result + size_gc_header)
         if contains_weakptr:
@@ -1002,14 +1004,15 @@
             totalsize = ovfcheck(nonvarsize + varsize)
         except OverflowError:
             raise memoryError
-        if raw_malloc_usage(totalsize) > self.top_of_space - self.free:
-            if not can_collect or not self.obtain_free_space(totalsize):
-                raise memoryError
         result = self.free
+        if raw_malloc_usage(totalsize) > self.top_of_space - result:
+            if not can_collect:
+                raise memoryError
+            result = self.obtain_free_space(totalsize)
         llarena.arena_reserve(result, totalsize)
         self.init_gc_object(result, typeid)
         (result + size_gc_header + offset_to_length).signed[0] = length
-        self.free += llarena.round_up_for_allocation(totalsize)
+        self.free = result + llarena.round_up_for_allocation(totalsize)
         if has_finalizer:
             self.objects_with_finalizers.append(result + size_gc_header)
         return llmemory.cast_adr_to_ptr(result+size_gc_header, llmemory.GCREF)
@@ -1019,6 +1022,14 @@
     malloc_varsize_clear   = malloc_varsize
 
     def obtain_free_space(self, needed):
+        # a bit of tweaking to maximize the performance and minimize the
+        # amount of code in an inlined version of malloc_fixedsize()
+        if not self.try_obtain_free_space(needed):
+            raise memoryError
+        return self.free
+    obtain_free_space.dont_inline = True
+
+    def try_obtain_free_space(self, needed):
         # XXX for bonus points do big objects differently
         needed = raw_malloc_usage(needed)
         self.semispace_collect()

Modified: pypy/dist/pypy/rpython/memory/gctransform/framework.py
==============================================================================
--- pypy/dist/pypy/rpython/memory/gctransform/framework.py	(original)
+++ pypy/dist/pypy/rpython/memory/gctransform/framework.py	Fri Oct 12 20:57:51 2007
@@ -13,6 +13,7 @@
 from pypy.rpython.rbuiltin import gen_cast
 from pypy.rpython.memory.gctypelayout import ll_weakref_deref, WEAKREF
 from pypy.rpython.memory.gctypelayout import convert_weakref_to, WEAKREFPTR
+from pypy.tool.sourcetools import func_with_new_name
 import sys
 
 
@@ -216,6 +217,26 @@
         self.collect_ptr = getfn(GCClass.collect.im_func,
             [s_gc], annmodel.s_None)
 
+        # in some GCs we can inline the common case of
+        # malloc_fixedsize(typeid, size, True, False, False)
+        if getattr(GCClass, 'inline_simple_malloc', False):
+            # make a copy of this function so that it gets annotated
+            # independently and the constants are folded inside
+            malloc_fast = func_with_new_name(
+                GCClass.malloc_fixedsize.im_func,
+                "malloc_fast")
+            s_False = annmodel.SomeBool(); s_False.const = False
+            s_True  = annmodel.SomeBool(); s_True .const = True
+            self.malloc_fast_ptr = getfn(
+                malloc_fast,
+                [s_gc, annmodel.SomeInteger(nonneg=True),
+                 annmodel.SomeInteger(nonneg=True),
+                 s_True, s_False,
+                 s_False], s_gcref,
+                inline = True)
+        else:
+            self.malloc_fast_ptr = self.malloc_fixedsize_ptr
+
         self.statistics_ptr = getfn(GCClass.statistics.im_func,
                                     [s_gc, annmodel.SomeInteger()],
                                     annmodel.SomeInteger())
@@ -396,6 +417,8 @@
             zero = flags.get('zero', False)
             if zero:
                 malloc_ptr = self.malloc_fixedsize_clear_ptr
+            elif c_can_collect.value and not c_has_finalizer.value:
+                malloc_ptr = self.malloc_fast_ptr
             else:
                 malloc_ptr = self.malloc_fixedsize_ptr
             args = [self.c_const_gc, c_type_id, c_size, c_can_collect,



More information about the Pypy-commit mailing list