[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