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

arigo at codespeak.net arigo at codespeak.net
Wed Dec 5 08:30:44 CET 2007


Author: arigo
Date: Wed Dec  5 08:30:44 2007
New Revision: 49359

Modified:
   pypy/dist/pypy/rpython/memory/gc/base.py
   pypy/dist/pypy/rpython/memory/gc/generation.py
   pypy/dist/pypy/rpython/memory/gc/semispace.py
   pypy/dist/pypy/rpython/memory/gctransform/framework.py
   pypy/dist/pypy/rpython/memory/gcwrapper.py
Log:
Arguably a clean-up: this removes the need for the error-prone
lines that were missing in GenerationGC (see previous check-in).
It adds fallback rules in case methods are not defined at all,
as documented in GCBase.malloc().


Modified: pypy/dist/pypy/rpython/memory/gc/base.py
==============================================================================
--- pypy/dist/pypy/rpython/memory/gc/base.py	(original)
+++ pypy/dist/pypy/rpython/memory/gc/base.py	Wed Dec  5 08:30:44 2007
@@ -39,8 +39,14 @@
     def malloc(self, typeid, length=0, zero=False, coallocator=None):
         """For testing.  The interface used by the gctransformer is
         the four malloc_[fixed,var]size[_clear]() functions.
-        And (if they exist) to the coalloc_[fixed,var]size functios
+        And (if they exist) to the coalloc_[fixed,var]size_clear functions
         """
+        # Rules about fallbacks in case of missing malloc methods:
+        #  * malloc_fixedsize_clear() and malloc_varsize_clear() are mandatory
+        #  * malloc_fixedsize() and malloc_varsize() fallback to the above
+        #  * coalloc_fixedsize_clear() and coalloc_varsize_clear() are optional
+        # There is no non-clear version of coalloc for now.
+
         size = self.fixed_size(typeid)
         needs_finalizer = bool(self.getfinalizer(typeid))
         weakptr_offset = self.weakpointer_offset(typeid)
@@ -56,28 +62,31 @@
             assert not contains_weakptr
             itemsize = self.varsize_item_sizes(typeid)
             offset_to_length = self.varsize_offset_to_length(typeid)
-            if zero:
-                malloc_varsize = self.malloc_varsize_clear
-            else:
-                malloc_varsize = self.malloc_varsize
-            if coallocator is not None and hasattr(self, "coalloc_varsize"):
+            if (coallocator is not None and
+                hasattr(self, "coalloc_varsize_clear")):
                 assert not needs_finalizer
                 coallocator = llmemory.cast_ptr_to_adr(coallocator)
-                ref = self.coalloc_varsize(coallocator, typeid, length, size,
-                                           itemsize, offset_to_length)
-            else:
+                ref = self.coalloc_varsize_clear(coallocator, typeid,
+                                                 length, size,
+                                                 itemsize, offset_to_length)
+            else:
+                if zero or not hasattr(self, 'malloc_varsize'):
+                    malloc_varsize = self.malloc_varsize_clear
+                else:
+                    malloc_varsize = self.malloc_varsize
                 ref = malloc_varsize(typeid, length, size, itemsize,
                                      offset_to_length, True, needs_finalizer)
         else:
-            if zero:
-                malloc_fixedsize = self.malloc_fixedsize_clear
-            else:
-                malloc_fixedsize = self.malloc_fixedsize
-            if coallocator is not None and hasattr(self, "coalloc_fixedsize"):
+            if (coallocator is not None and
+                hasattr(self, "coalloc_fixedsize_clear")):
                 assert not needs_finalizer
                 coallocator = llmemory.cast_ptr_to_adr(coallocator)
-                ref = self.coalloc_fixedsize(coallocator, typeid, size)
+                ref = self.coalloc_fixedsize_clear(coallocator, typeid, size)
             else:
+                if zero or not hasattr(self, 'malloc_fixedsize'):
+                    malloc_fixedsize = self.malloc_fixedsize_clear
+                else:
+                    malloc_fixedsize = self.malloc_fixedsize
                 ref = malloc_fixedsize(typeid, size, True, needs_finalizer,
                                        contains_weakptr)
         # lots of cast and reverse-cast around...

Modified: pypy/dist/pypy/rpython/memory/gc/generation.py
==============================================================================
--- pypy/dist/pypy/rpython/memory/gc/generation.py	(original)
+++ pypy/dist/pypy/rpython/memory/gc/generation.py	Wed Dec  5 08:30:44 2007
@@ -57,15 +57,16 @@
     def is_in_nursery(self, addr):
         return self.nursery <= addr < self.nursery_top
 
-    def malloc_fixedsize(self, typeid, size, can_collect, has_finalizer=False,
-                         contains_weakptr=False):
+    def malloc_fixedsize_clear(self, typeid, size, can_collect,
+                               has_finalizer=False, contains_weakptr=False):
         if (has_finalizer or not can_collect or
             raw_malloc_usage(size) >= self.nursery_size // 2):
             ll_assert(not contains_weakptr, "wrong case for mallocing weakref")
             # "non-simple" case or object too big: don't use the nursery
-            return SemiSpaceGC.malloc_fixedsize(self, typeid, size,
-                                                can_collect, has_finalizer,
-                                                contains_weakptr)
+            return SemiSpaceGC.malloc_fixedsize_clear(self, typeid, size,
+                                                      can_collect,
+                                                      has_finalizer,
+                                                      contains_weakptr)
         size_gc_header = self.gcheaderbuilder.size_gc_header
         totalsize = size_gc_header + size
         result = self.nursery_free
@@ -79,27 +80,29 @@
             self.young_objects_with_weakrefs.append(result + size_gc_header)
         return llmemory.cast_adr_to_ptr(result+size_gc_header, llmemory.GCREF)
 
-    def coalloc_fixedsize(self, coallocator, typeid, size):
+    def coalloc_fixedsize_clear(self, coallocator, typeid, size):
         # note: a coallocated object can never return a weakref, since the
         # coallocation analysis is done at a time where weakrefs are
         # represented as opaque objects which aren't allocated using malloc but
         # with weakref_create
         if self.is_in_nursery(coallocator):
-            return self.malloc_fixedsize(typeid, size, True, False, False)
+            return self.malloc_fixedsize_clear(typeid, size,
+                                               True, False, False)
         else:
-            return SemiSpaceGC.malloc_fixedsize(self, typeid, size, True,
-                                                False, False)
+            return SemiSpaceGC.malloc_fixedsize_clear(self, typeid, size,
+                                                      True, False, False)
 
-    def malloc_varsize(self, typeid, length, size, itemsize, offset_to_length,
-                       can_collect, has_finalizer=False):
+    def malloc_varsize_clear(self, typeid, length, size, itemsize,
+                             offset_to_length, can_collect,
+                             has_finalizer=False):
         # only use the nursery if there are not too many items
         if (has_finalizer or not can_collect or
             (raw_malloc_usage(itemsize) and
              length > self.nursery_size // 4 // raw_malloc_usage(itemsize)) or
             raw_malloc_usage(size) > self.nursery_size // 4):
-            return SemiSpaceGC.malloc_varsize(self, typeid, length, size,
-                                              itemsize, offset_to_length,
-                                              can_collect, has_finalizer)
+            return SemiSpaceGC.malloc_varsize_clear(self, typeid, length, size,
+                                                    itemsize, offset_to_length,
+                                                    can_collect, has_finalizer)
         # with the above checks we know now that totalsize cannot be more
         # than about half of the nursery size; in particular, the + and *
         # cannot overflow
@@ -115,18 +118,16 @@
         self.nursery_free = result + llarena.round_up_for_allocation(totalsize)
         return llmemory.cast_adr_to_ptr(result+size_gc_header, llmemory.GCREF)
 
-    def coalloc_varsize(self, coallocator, typeid, length, size, itemsize,
-                        offset_to_length):
+    def coalloc_varsize_clear(self, coallocator, typeid,
+                              length, size, itemsize,
+                              offset_to_length):
         if self.is_in_nursery(coallocator):
-            return self.malloc_varsize(typeid, length, size, itemsize,
-                                       offset_to_length, True, False)
+            return self.malloc_varsize_clear(typeid, length, size, itemsize,
+                                             offset_to_length, True, False)
         else:
-            return SemiSpaceGC.malloc_varsize(self, typeid, length, size,
-                                              itemsize, offset_to_length,
-                                              True, False)
-
-    malloc_fixedsize_clear = malloc_fixedsize
-    malloc_varsize_clear   = malloc_varsize
+            return SemiSpaceGC.malloc_varsize_clear(self, typeid, length, size,
+                                                    itemsize, offset_to_length,
+                                                    True, False)
 
     # override the init_gc_object methods to change the default value of 'flags',
     # used by objects that are directly created outside the nursery by the SemiSpaceGC.

Modified: pypy/dist/pypy/rpython/memory/gc/semispace.py
==============================================================================
--- pypy/dist/pypy/rpython/memory/gc/semispace.py	(original)
+++ pypy/dist/pypy/rpython/memory/gc/semispace.py	Wed Dec  5 08:30:44 2007
@@ -57,8 +57,11 @@
         if self.run_finalizers.non_empty():
             self.execute_finalizers()
 
-    def malloc_fixedsize(self, typeid, size, can_collect, has_finalizer=False,
-                         contains_weakptr=False):
+    # This class only defines the malloc_{fixed,var}size_clear() methods
+    # because the spaces are filled with zeroes in advance.
+
+    def malloc_fixedsize_clear(self, typeid, size, can_collect,
+                               has_finalizer=False, contains_weakptr=False):
         size_gc_header = self.gcheaderbuilder.size_gc_header
         totalsize = size_gc_header + size
         result = self.free
@@ -75,8 +78,9 @@
             self.objects_with_weakrefs.append(result + size_gc_header)
         return llmemory.cast_adr_to_ptr(result+size_gc_header, llmemory.GCREF)
 
-    def malloc_varsize(self, typeid, length, size, itemsize, offset_to_length,
-                       can_collect, has_finalizer=False):
+    def malloc_varsize_clear(self, typeid, length, size, itemsize,
+                             offset_to_length, can_collect,
+                             has_finalizer=False):
         size_gc_header = self.gcheaderbuilder.size_gc_header
         nonvarsize = size_gc_header + size
         try:
@@ -97,13 +101,9 @@
             self.objects_with_finalizers.append(result + size_gc_header)
         return llmemory.cast_adr_to_ptr(result+size_gc_header, llmemory.GCREF)
 
-    # for now, the spaces are filled with zeroes in advance
-    malloc_fixedsize_clear = malloc_fixedsize
-    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()
+        # amount of code in an inlined version of malloc_fixedsize_clear()
         if not self.try_obtain_free_space(needed):
             raise memoryError
         return self.free

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	Wed Dec  5 08:30:44 2007
@@ -264,20 +264,27 @@
         classdef = bk.getuniqueclassdef(GCClass)
         s_gc = annmodel.SomeInstance(classdef)
         s_gcref = annmodel.SomePtr(llmemory.GCREF)
-        self.malloc_fixedsize_ptr = getfn(
-            GCClass.malloc_fixedsize.im_func,
-            [s_gc, annmodel.SomeInteger(nonneg=True),
-             annmodel.SomeInteger(nonneg=True),
-             annmodel.SomeBool(), annmodel.SomeBool(),
-             annmodel.SomeBool()], s_gcref,
-            inline = False)
+
+        malloc_fixedsize_clear_meth = GCClass.malloc_fixedsize_clear.im_func
         self.malloc_fixedsize_clear_ptr = getfn(
-            GCClass.malloc_fixedsize_clear.im_func,
+            malloc_fixedsize_clear_meth,
             [s_gc, annmodel.SomeInteger(nonneg=True),
              annmodel.SomeInteger(nonneg=True),
              annmodel.SomeBool(), annmodel.SomeBool(),
              annmodel.SomeBool()], s_gcref,
             inline = False)
+        if hasattr(GCClass, 'malloc_fixedsize'):
+            malloc_fixedsize_meth = GCClass.malloc_fixedsize.im_func
+            self.malloc_fixedsize_ptr = getfn(
+                malloc_fixedsize_meth,
+                [s_gc, annmodel.SomeInteger(nonneg=True),
+                 annmodel.SomeInteger(nonneg=True),
+                 annmodel.SomeBool(), annmodel.SomeBool(),
+                 annmodel.SomeBool()], s_gcref,
+                inline = False)
+        else:
+            malloc_fixedsize_meth = None
+            self.malloc_fixedsize_ptr = self.malloc_fixedsize_clear_ptr
 ##         self.malloc_varsize_ptr = getfn(
 ##             GCClass.malloc_varsize.im_func,
 ##             [s_gc] + [annmodel.SomeInteger(nonneg=True) for i in range(5)]
@@ -294,8 +301,14 @@
         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
+            if malloc_fixedsize_meth is None:
+                malloc_fast_meth = malloc_fixedsize_clear_meth
+                self.malloc_fast_is_clearing = True
+            else:
+                malloc_fast_meth = malloc_fixedsize_meth
+                self.malloc_fast_is_clearing = False
             malloc_fast = func_with_new_name(
-                GCClass.malloc_fixedsize.im_func,
+                malloc_fast_meth,
                 "malloc_fast")
             s_False = annmodel.SomeBool(); s_False.const = False
             s_True  = annmodel.SomeBool(); s_True .const = True
@@ -307,7 +320,7 @@
                  s_False], s_gcref,
                 inline = True)
         else:
-            self.malloc_fast_ptr = self.malloc_fixedsize_ptr
+            self.malloc_fast_ptr = None
 
         if GCClass.moving_gc:
             self.id_ptr = getfn(GCClass.id.im_func,
@@ -326,15 +339,15 @@
                                            inline=True)
         else:
             self.write_barrier_ptr = None
-        if hasattr(GCClass, "coalloc_fixedsize"):
+        if hasattr(GCClass, "coalloc_fixedsize_clear"):
             self.coalloc_clear_ptr = getfn(
-                GCClass.coalloc_fixedsize.im_func,
+                GCClass.coalloc_fixedsize_clear.im_func,
                 [s_gc, annmodel.SomeAddress(),
                  annmodel.SomeInteger(nonneg=True),
                  annmodel.SomeInteger(nonneg=True)],
                 s_gcref, inline=True)
             self.coalloc_varsize_clear_ptr = getfn(
-                GCClass.coalloc_varsize.im_func,
+                GCClass.coalloc_varsize_clear.im_func,
                 [s_gc, annmodel.SomeAddress()] +
                 [annmodel.SomeInteger(nonneg=True) for i in range(5)],
                 s_gcref, inline=True)
@@ -552,10 +565,12 @@
         if not op.opname.endswith('_varsize'):
             #malloc_ptr = self.malloc_fixedsize_ptr
             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:
+            if (self.malloc_fast_ptr is not None and
+                c_can_collect.value and not c_has_finalizer.value and
+                (self.malloc_fast_is_clearing or not zero)):
                 malloc_ptr = self.malloc_fast_ptr
+            elif zero:
+                malloc_ptr = self.malloc_fixedsize_clear_ptr
             else:
                 malloc_ptr = self.malloc_fixedsize_ptr
             args = [self.c_const_gc, c_type_id, c_size, c_can_collect,

Modified: pypy/dist/pypy/rpython/memory/gcwrapper.py
==============================================================================
--- pypy/dist/pypy/rpython/memory/gcwrapper.py	(original)
+++ pypy/dist/pypy/rpython/memory/gcwrapper.py	Wed Dec  5 08:30:44 2007
@@ -63,7 +63,7 @@
         return lltype.free(TYPE, flavor=flavor)
 
     def coalloc(self, TYPE, coallocator, size=None, zero=False):
-        if hasattr(self.gc, "coalloc_fixedsize"):
+        if hasattr(self.gc, "coalloc_fixedsize_clear"):
             typeid = self.get_type_id(TYPE)
             addr = self.gc.malloc(typeid, size, zero=zero,
                                   coallocator=coallocator)



More information about the Pypy-commit mailing list