[pypy-svn] r50345 - in pypy/branch/applevel-ctypes/pypy/rpython/memory: . gc gctransform gctransform/test test
fijal at codespeak.net
fijal at codespeak.net
Sat Jan 5 11:15:23 CET 2008
Author: fijal
Date: Sat Jan 5 11:15:22 2008
New Revision: 50345
Modified:
pypy/branch/applevel-ctypes/pypy/rpython/memory/gc/base.py
pypy/branch/applevel-ctypes/pypy/rpython/memory/gc/generation.py
pypy/branch/applevel-ctypes/pypy/rpython/memory/gc/marksweep.py
pypy/branch/applevel-ctypes/pypy/rpython/memory/gc/semispace.py
pypy/branch/applevel-ctypes/pypy/rpython/memory/gctransform/boehm.py
pypy/branch/applevel-ctypes/pypy/rpython/memory/gctransform/framework.py
pypy/branch/applevel-ctypes/pypy/rpython/memory/gctransform/refcounting.py
pypy/branch/applevel-ctypes/pypy/rpython/memory/gctransform/test/test_refcounting.py
pypy/branch/applevel-ctypes/pypy/rpython/memory/gctransform/transform.py
pypy/branch/applevel-ctypes/pypy/rpython/memory/gctypelayout.py
pypy/branch/applevel-ctypes/pypy/rpython/memory/gcwrapper.py
pypy/branch/applevel-ctypes/pypy/rpython/memory/support.py
pypy/branch/applevel-ctypes/pypy/rpython/memory/test/test_gctypelayout.py
pypy/branch/applevel-ctypes/pypy/rpython/memory/test/test_transformed_gc.py
Log:
Merge the gc from dist, as translation is now broken on this branch.
Modified: pypy/branch/applevel-ctypes/pypy/rpython/memory/gc/base.py
==============================================================================
--- pypy/branch/applevel-ctypes/pypy/rpython/memory/gc/base.py (original)
+++ pypy/branch/applevel-ctypes/pypy/rpython/memory/gc/base.py Sat Jan 5 11:15:22 2008
@@ -6,6 +6,7 @@
moving_gc = False
needs_write_barrier = False
needs_zero_gc_pointers = True
+ prebuilt_gc_objects_are_static_roots = True
def set_query_functions(self, is_varsize, has_gcptr_in_varsize,
is_gcarrayofgcptr,
@@ -160,6 +161,12 @@
# more non-prebuild GC objects; this is fine because the
# internal GC ptr in the prebuilt list or dict is found by
# gctypelayout and listed in addresses_of_static_ptrs.
+
+ # XXX I'm not sure any more about the warning above. The fields
+ # of 'self' are found by gctypelayout and added to
+ # addresses_of_static_ptrs_in_nongc, so in principle they could
+ # be mutated and still be found by collect().
+
self.wr_to_objects_with_id = []
self.object_id_dict = {}
self.object_id_dict_ends_at = 0
Modified: pypy/branch/applevel-ctypes/pypy/rpython/memory/gc/generation.py
==============================================================================
--- pypy/branch/applevel-ctypes/pypy/rpython/memory/gc/generation.py (original)
+++ pypy/branch/applevel-ctypes/pypy/rpython/memory/gc/generation.py Sat Jan 5 11:15:22 2008
@@ -11,7 +11,11 @@
# in the nursery. It is initially set on all prebuilt and old objects,
# and gets cleared by the write_barrier() when we write in them a
# pointer to a young object.
-GCFLAG_NO_YOUNG_PTRS = 2 << GCFLAGSHIFT
+GCFLAG_NO_YOUNG_PTRS = 1 << (GCFLAGSHIFT+1)
+
+# The following flag is set for static roots which are not on the list
+# of static roots yet, but will appear with write barrier
+GCFLAG_NO_HEAP_PTRS = 1 << (GCFLAGSHIFT+2)
DEBUG_PRINT = False
@@ -22,7 +26,9 @@
list, chained to each other via their 'forw' header field.
"""
inline_simple_malloc = True
+ inline_simple_malloc_varsize = True
needs_write_barrier = True
+ prebuilt_gc_objects_are_static_roots = False
def __init__(self, AddressLinkedList,
nursery_size=128,
@@ -135,7 +141,8 @@
def init_gc_object(self, addr, typeid, flags=GCFLAG_NO_YOUNG_PTRS):
SemiSpaceGC.init_gc_object(self, addr, typeid, flags)
- def init_gc_object_immortal(self, addr, typeid, flags=GCFLAG_NO_YOUNG_PTRS):
+ def init_gc_object_immortal(self, addr, typeid,
+ flags=GCFLAG_NO_YOUNG_PTRS|GCFLAG_NO_HEAP_PTRS):
SemiSpaceGC.init_gc_object_immortal(self, addr, typeid, flags)
def semispace_collect(self, size_changing=False):
@@ -288,12 +295,22 @@
if self.header(addr_struct).tid & GCFLAG_NO_YOUNG_PTRS:
self.remember_young_pointer(addr_struct, newvalue)
+ def append_to_static_roots(self, pointer, arg):
+ self.get_roots.append_static_root(pointer)
+
+ def move_to_static_roots(self, addr_struct):
+ objhdr = self.header(addr_struct)
+ objhdr.tid &= ~GCFLAG_NO_HEAP_PTRS
+ self.trace(addr_struct, self.append_to_static_roots, None)
+
def remember_young_pointer(self, addr_struct, addr):
ll_assert(not self.is_in_nursery(addr_struct),
"nursery object with GCFLAG_NO_YOUNG_PTRS")
+ oldhdr = self.header(addr_struct)
if self.is_in_nursery(addr):
- oldhdr = self.header(addr_struct)
oldhdr.forw = self.old_objects_pointing_to_young
self.old_objects_pointing_to_young = addr_struct
oldhdr.tid &= ~GCFLAG_NO_YOUNG_PTRS
- remember_young_pointer.dont_inline = True
+ if oldhdr.tid & GCFLAG_NO_HEAP_PTRS:
+ self.move_to_static_roots(addr_struct)
+ remember_young_pointer._dont_inline_ = True
Modified: pypy/branch/applevel-ctypes/pypy/rpython/memory/gc/marksweep.py
==============================================================================
--- pypy/branch/applevel-ctypes/pypy/rpython/memory/gc/marksweep.py (original)
+++ pypy/branch/applevel-ctypes/pypy/rpython/memory/gc/marksweep.py Sat Jan 5 11:15:22 2008
@@ -102,7 +102,7 @@
#llop.debug_print(lltype.Void, 'malloc typeid', typeid,
# '->', llmemory.cast_adr_to_int(result))
return llmemory.cast_adr_to_ptr(result, llmemory.GCREF)
- malloc_fixedsize.dont_inline = True
+ malloc_fixedsize._dont_inline_ = True
def malloc_fixedsize_clear(self, typeid, size, can_collect,
has_finalizer=False, contains_weakptr=False):
@@ -136,7 +136,7 @@
#llop.debug_print(lltype.Void, 'malloc typeid', typeid,
# '->', llmemory.cast_adr_to_int(result))
return llmemory.cast_adr_to_ptr(result, llmemory.GCREF)
- malloc_fixedsize_clear.dont_inline = True
+ malloc_fixedsize_clear._dont_inline_ = True
def malloc_varsize(self, typeid, length, size, itemsize, offset_to_length,
can_collect, has_finalizer=False):
@@ -171,7 +171,7 @@
# 'typeid', typeid,
# '->', llmemory.cast_adr_to_int(result))
return llmemory.cast_adr_to_ptr(result, llmemory.GCREF)
- malloc_varsize.dont_inline = True
+ malloc_varsize._dont_inline_ = True
def malloc_varsize_clear(self, typeid, length, size, itemsize,
offset_to_length, can_collect,
@@ -208,7 +208,7 @@
# 'typeid', typeid,
# '->', llmemory.cast_adr_to_int(result))
return llmemory.cast_adr_to_ptr(result, llmemory.GCREF)
- malloc_varsize_clear.dont_inline = True
+ malloc_varsize_clear._dont_inline_ = True
def collect(self):
# 1. mark from the roots, and also the objects that objects-with-del
@@ -483,8 +483,9 @@
hdr = llmemory.cast_adr_to_ptr(addr, self.HDRPTR)
hdr.typeid = typeid << 1
- def init_gc_object_immortal(self, addr, typeid):
+ def init_gc_object_immortal(self, addr, typeid, flags=0):
# prebuilt gc structures always have the mark bit set
+ # ignore flags
hdr = llmemory.cast_adr_to_ptr(addr, self.HDRPTR)
hdr.typeid = (typeid << 1) | 1
Modified: pypy/branch/applevel-ctypes/pypy/rpython/memory/gc/semispace.py
==============================================================================
--- pypy/branch/applevel-ctypes/pypy/rpython/memory/gc/semispace.py (original)
+++ pypy/branch/applevel-ctypes/pypy/rpython/memory/gc/semispace.py Sat Jan 5 11:15:22 2008
@@ -21,6 +21,7 @@
class SemiSpaceGC(MovingGCBase):
_alloc_flavor_ = "raw"
inline_simple_malloc = True
+ inline_simple_malloc_varsize = True
needs_zero_gc_pointers = False
HDR = lltype.Struct('header', ('forw', llmemory.Address),
@@ -107,7 +108,7 @@
if not self.try_obtain_free_space(needed):
raise memoryError
return self.free
- obtain_free_space.dont_inline = True
+ obtain_free_space._dont_inline_ = True
def try_obtain_free_space(self, needed):
# XXX for bonus points do big objects differently
Modified: pypy/branch/applevel-ctypes/pypy/rpython/memory/gctransform/boehm.py
==============================================================================
--- pypy/branch/applevel-ctypes/pypy/rpython/memory/gctransform/boehm.py (original)
+++ pypy/branch/applevel-ctypes/pypy/rpython/memory/gctransform/boehm.py Sat Jan 5 11:15:22 2008
@@ -108,7 +108,7 @@
" v = cast_adr_to_ptr(addr, PTR_TYPE)\n"
"%s\n")%(static_body,)
exec src in d
- fptr = self.annotate_helper(d['ll_finalizer'], [llmemory.Address], lltype.Void)
+ fptr = self.annotate_finalizer(d['ll_finalizer'], [llmemory.Address], lltype.Void)
elif destrptr:
EXC_INSTANCE_TYPE = self.translator.rtyper.exceptiondata.lltype_of_exception_value
def ll_finalizer(addr):
@@ -116,7 +116,7 @@
v = llmemory.cast_adr_to_ptr(addr, DESTR_ARG)
ll_call_destructor(destrptr, v)
llop.gc_restore_exception(lltype.Void, exc_instance)
- fptr = self.annotate_helper(ll_finalizer, [llmemory.Address], lltype.Void)
+ fptr = self.annotate_finalizer(ll_finalizer, [llmemory.Address], lltype.Void)
else:
fptr = lltype.nullptr(self.FINALIZER_PTR.TO)
Modified: pypy/branch/applevel-ctypes/pypy/rpython/memory/gctransform/framework.py
==============================================================================
--- pypy/branch/applevel-ctypes/pypy/rpython/memory/gctransform/framework.py (original)
+++ pypy/branch/applevel-ctypes/pypy/rpython/memory/gctransform/framework.py Sat Jan 5 11:15:22 2008
@@ -17,6 +17,7 @@
from pypy.rpython.memory.gctypelayout import convert_weakref_to, WEAKREFPTR
from pypy.rpython.memory.gctransform.log import log
from pypy.tool.sourcetools import func_with_new_name
+from pypy.rpython.lltypesystem.lloperation import llop
import sys
@@ -87,8 +88,8 @@
mallocvars = {target.inputargs[index]: True}
mallocnum += 1
find_in_block(target, mallocvars)
- if result:
- print "found %s initializing stores in %s" % (len(result), graph.name)
+ #if result:
+ # print "found %s initializing stores in %s" % (len(result), graph.name)
return result
class FrameworkGCTransformer(GCTransformer):
@@ -113,16 +114,19 @@
self.get_type_id = self.layoutbuilder.get_type_id
# set up dummy a table, to be overwritten with the real one in finish()
- type_info_table = lltype.malloc(gctypelayout.GCData.TYPE_INFO_TABLE, 0,
- immortal=True)
+ type_info_table = lltype._ptr(
+ lltype.Ptr(gctypelayout.GCData.TYPE_INFO_TABLE),
+ "delayed!type_info_table", solid=True)
gcdata = gctypelayout.GCData(type_info_table)
# initialize the following two fields with a random non-NULL address,
# to make the annotator happy. The fields are patched in finish()
- # to point to a real array (not 'type_info_table', another one).
- a_random_address = llmemory.cast_ptr_to_adr(type_info_table)
+ # to point to a real array.
+ foo = lltype.malloc(lltype.FixedSizeArray(llmemory.Address, 1),
+ immortal=True, zero=True)
+ a_random_address = llmemory.cast_ptr_to_adr(foo)
gcdata.static_root_start = a_random_address # patched in finish()
- gcdata.static_root_nongcstart = a_random_address # patched in finish()
+ gcdata.static_root_nongcend = a_random_address # patched in finish()
gcdata.static_root_end = a_random_address # patched in finish()
self.gcdata = gcdata
self.malloc_fnptr_cache = {}
@@ -143,16 +147,13 @@
bk = self.translator.annotator.bookkeeper
# the point of this little dance is to not annotate
- # self.gcdata.type_info_table as a constant.
+ # self.gcdata.static_root_xyz as constants. XXX is it still needed??
data_classdef = bk.getuniqueclassdef(gctypelayout.GCData)
data_classdef.generalize_attr(
- 'type_info_table',
- annmodel.SomePtr(lltype.Ptr(gctypelayout.GCData.TYPE_INFO_TABLE)))
- data_classdef.generalize_attr(
'static_root_start',
annmodel.SomeAddress())
data_classdef.generalize_attr(
- 'static_root_nongcstart',
+ 'static_root_nongcend',
annmodel.SomeAddress())
data_classdef.generalize_attr(
'static_root_end',
@@ -256,6 +257,28 @@
else:
self.malloc_fast_ptr = None
+ # in some GCs we can also inline the common case of
+ # malloc_varsize(typeid, length, (3 constant sizes), True, False)
+ if getattr(GCClass, 'inline_simple_malloc_varsize', False):
+ # make a copy of this function so that it gets annotated
+ # independently and the constants are folded inside
+ malloc_varsize_clear_fast = func_with_new_name(
+ GCClass.malloc_varsize_clear.im_func,
+ "malloc_varsize_clear_fast")
+ s_False = annmodel.SomeBool(); s_False.const = False
+ s_True = annmodel.SomeBool(); s_True .const = True
+ self.malloc_varsize_clear_fast_ptr = getfn(
+ malloc_varsize_clear_fast,
+ [s_gc, annmodel.SomeInteger(nonneg=True),
+ annmodel.SomeInteger(nonneg=True),
+ annmodel.SomeInteger(nonneg=True),
+ annmodel.SomeInteger(nonneg=True),
+ annmodel.SomeInteger(nonneg=True),
+ s_True, s_False], s_gcref,
+ inline = True)
+ else:
+ self.malloc_varsize_clear_fast_ptr = None
+
if GCClass.moving_gc:
self.id_ptr = getfn(GCClass.id.im_func,
[s_gc, s_gcref], annmodel.SomeInteger(),
@@ -349,6 +372,11 @@
gcdata.root_stack_top = top + n*sizeofaddr
return top
incr_stack = staticmethod(incr_stack)
+
+ def append_static_root(adr):
+ gcdata.static_root_end.address[0] = adr
+ gcdata.static_root_end += sizeofaddr
+ append_static_root = staticmethod(append_static_root)
def decr_stack(n):
top = gcdata.root_stack_top - n*sizeofaddr
@@ -371,16 +399,16 @@
def __init__(self, with_static=True):
self.stack_current = gcdata.root_stack_top
if with_static:
- self.static_current = gcdata.static_root_start
+ self.static_current = gcdata.static_root_end
else:
- self.static_current = gcdata.static_root_nongcstart
+ self.static_current = gcdata.static_root_nongcend
def pop(self):
- while self.static_current != gcdata.static_root_end:
- result = self.static_current
- self.static_current += sizeofaddr
- if result.address[0].address[0] != llmemory.NULL:
- return result.address[0]
+ while self.static_current != gcdata.static_root_start:
+ self.static_current -= sizeofaddr
+ result = self.static_current.address[0]
+ if result.address[0] != llmemory.NULL:
+ return result
while self.stack_current != gcdata.root_stack_base:
self.stack_current -= sizeofaddr
if self.stack_current.address[0] != llmemory.NULL:
@@ -418,9 +446,10 @@
# replace the type_info_table pointer in gcdata -- at this point,
# the database is in principle complete, so it has already seen
- # the old (empty) array. We need to force it to consider the new
- # array now. It's a bit hackish as the old empty array will also
- # be generated in the C source, but that's a rather minor problem.
+ # the delayed pointer. We need to force it to consider the new
+ # array now.
+
+ self.gcdata.type_info_table._become(table)
# XXX because we call inputconst already in replace_malloc, we can't
# modify the instance, we have to modify the 'rtyped instance'
@@ -430,24 +459,24 @@
self.gcdata)
r_gcdata = self.translator.rtyper.getrepr(s_gcdata)
ll_instance = rmodel.inputconst(r_gcdata, self.gcdata).value
- ll_instance.inst_type_info_table = table
- #self.gcdata.type_info_table = table
addresses_of_static_ptrs = (
- self.layoutbuilder.addresses_of_static_ptrs +
- self.layoutbuilder.addresses_of_static_ptrs_in_nongc)
+ self.layoutbuilder.addresses_of_static_ptrs_in_nongc +
+ self.layoutbuilder.addresses_of_static_ptrs)
log.info("found %s static roots" % (len(addresses_of_static_ptrs), ))
+ additional_ptrs = self.layoutbuilder.additional_roots_sources
+ log.info("additional %d potential static roots" % additional_ptrs)
ll_static_roots_inside = lltype.malloc(lltype.Array(llmemory.Address),
- len(addresses_of_static_ptrs),
+ len(addresses_of_static_ptrs) +
+ additional_ptrs,
immortal=True)
for i in range(len(addresses_of_static_ptrs)):
ll_static_roots_inside[i] = addresses_of_static_ptrs[i]
ll_instance.inst_static_root_start = llmemory.cast_ptr_to_adr(ll_static_roots_inside) + llmemory.ArrayItemsOffset(lltype.Array(llmemory.Address))
- ll_instance.inst_static_root_nongcstart = ll_instance.inst_static_root_start + llmemory.sizeof(llmemory.Address) * len(self.layoutbuilder.addresses_of_static_ptrs)
- ll_instance.inst_static_root_end = ll_instance.inst_static_root_start + llmemory.sizeof(llmemory.Address) * len(ll_static_roots_inside)
+ ll_instance.inst_static_root_nongcend = ll_instance.inst_static_root_start + llmemory.sizeof(llmemory.Address) * len(self.layoutbuilder.addresses_of_static_ptrs_in_nongc)
+ ll_instance.inst_static_root_end = ll_instance.inst_static_root_start + llmemory.sizeof(llmemory.Address) * len(addresses_of_static_ptrs)
newgcdependencies = []
- newgcdependencies.append(table)
newgcdependencies.append(ll_static_roots_inside)
self.write_typeid_list()
return newgcdependencies
@@ -514,11 +543,11 @@
v_length = op.args[-1]
c_ofstolength = rmodel.inputconst(lltype.Signed, info.ofstolength)
c_varitemsize = rmodel.inputconst(lltype.Signed, info.varitemsize)
- malloc_ptr = self.malloc_varsize_clear_ptr
-## if op.opname.startswith('zero'):
-## malloc_ptr = self.malloc_varsize_clear_ptr
-## else:
-## malloc_ptr = self.malloc_varsize_clear_ptr
+ if (self.malloc_varsize_clear_fast_ptr is not None and
+ c_can_collect.value and not c_has_finalizer.value):
+ malloc_ptr = self.malloc_varsize_clear_fast_ptr
+ else:
+ malloc_ptr = self.malloc_varsize_clear_ptr
args = [self.c_const_gc, c_type_id, v_length, c_size,
c_varitemsize, c_ofstolength, c_can_collect,
c_has_finalizer]
@@ -772,9 +801,9 @@
def ll_finalizer(addr):
v = llmemory.cast_adr_to_ptr(addr, DESTR_ARG)
ll_call_destructor(destrptr, v)
- fptr = self.transformer.annotate_helper(ll_finalizer,
- [llmemory.Address],
- lltype.Void)
+ fptr = self.transformer.annotate_finalizer(ll_finalizer,
+ [llmemory.Address],
+ lltype.Void)
else:
fptr = lltype.nullptr(gctypelayout.GCData.FINALIZERTYPE.TO)
return fptr
Modified: pypy/branch/applevel-ctypes/pypy/rpython/memory/gctransform/refcounting.py
==============================================================================
--- pypy/branch/applevel-ctypes/pypy/rpython/memory/gctransform/refcounting.py (original)
+++ pypy/branch/applevel-ctypes/pypy/rpython/memory/gctransform/refcounting.py Sat Jan 5 11:15:22 2008
@@ -115,8 +115,8 @@
self.dynamic_deallocator_funcptrs = {}
self.queryptr2dynamic_deallocator_funcptr = {}
- def finish_helpers(self):
- GCTransformer.finish_helpers(self)
+ def finish_helpers(self, **kwds):
+ GCTransformer.finish_helpers(self, **kwds)
from pypy.translator.backendopt.malloc import remove_mallocs
seen = {}
graphs = []
@@ -247,7 +247,7 @@
'HDRPTR':lltype.Ptr(self.HDR)}
exec src in d
this = d['ll_deallocator']
- fptr = self.annotate_helper(this, [llmemory.Address], lltype.Void)
+ fptr = self.annotate_finalizer(this, [llmemory.Address], lltype.Void)
self.static_deallocator_funcptrs[TYPE] = fptr
for p in find_gc_ptrs_in_type(TYPE):
self.static_deallocation_funcptr_for_type(p.TO)
Modified: pypy/branch/applevel-ctypes/pypy/rpython/memory/gctransform/test/test_refcounting.py
==============================================================================
--- pypy/branch/applevel-ctypes/pypy/rpython/memory/gctransform/test/test_refcounting.py (original)
+++ pypy/branch/applevel-ctypes/pypy/rpython/memory/gctransform/test/test_refcounting.py Sat Jan 5 11:15:22 2008
@@ -127,7 +127,7 @@
transformer = cls(t)
fptr = getattr(transformer, attr)(TYPE)
transformer.transform_graph(graphof(t, f))
- transformer.finish()
+ transformer.finish(backendopt=False)
if conftest.option.view:
t.view()
if fptr:
Modified: pypy/branch/applevel-ctypes/pypy/rpython/memory/gctransform/transform.py
==============================================================================
--- pypy/branch/applevel-ctypes/pypy/rpython/memory/gctransform/transform.py (original)
+++ pypy/branch/applevel-ctypes/pypy/rpython/memory/gctransform/transform.py Sat Jan 5 11:15:22 2008
@@ -111,6 +111,7 @@
self.lltype_to_classdef = translator.rtyper.lltype_to_classdef_mapping()
self.graphs_to_inline = {}
self.graph_dependencies = {}
+ self.ll_finalizers_ptrs = []
if self.MinimalGCTransformer:
self.minimalgctransformer = self.MinimalGCTransformer(self)
else:
@@ -279,24 +280,37 @@
self.need_minimal_transform(graph)
if inline:
self.graphs_to_inline[graph] = True
- return self.mixlevelannotator.graph2delayed(graph)
+ FUNCTYPE = lltype.FuncType(ll_args, ll_result)
+ return self.mixlevelannotator.graph2delayed(graph, FUNCTYPE=FUNCTYPE)
def inittime_helper(self, ll_helper, ll_args, ll_result, inline=True):
ptr = self.annotate_helper(ll_helper, ll_args, ll_result, inline=inline)
return Constant(ptr, lltype.typeOf(ptr))
- def finish_helpers(self):
+ def annotate_finalizer(self, ll_finalizer, ll_args, ll_result):
+ fptr = self.annotate_helper(ll_finalizer, ll_args, ll_result)
+ self.ll_finalizers_ptrs.append(fptr)
+ return fptr
+
+ def finish_helpers(self, backendopt=True):
if self.translator is not None:
self.mixlevelannotator.finish_annotate()
self.finished_helpers = True
if self.translator is not None:
self.mixlevelannotator.finish_rtype()
+ if backendopt:
+ self.mixlevelannotator.backend_optimize()
+ # Make sure that the database also sees all finalizers now.
+ # XXX we need to think more about the interaction with stackless...
+ # It is likely that the finalizers need special support there
+ newgcdependencies = self.ll_finalizers_ptrs
+ return newgcdependencies
def finish_tables(self):
pass
- def finish(self):
- self.finish_helpers()
+ def finish(self, backendopt=True):
+ self.finish_helpers(backendopt=backendopt)
self.finish_tables()
def transform_generic_set(self, hop):
@@ -415,7 +429,7 @@
except OverflowError:
raise MemoryError()
return tot_size
- _ll_compute_size._inline_ = True
+ _ll_compute_size._always_inline_ = True
def _ll_malloc_varsize_no_length(length, size, itemsize):
tot_size = _ll_compute_size(length, size, itemsize)
Modified: pypy/branch/applevel-ctypes/pypy/rpython/memory/gctypelayout.py
==============================================================================
--- pypy/branch/applevel-ctypes/pypy/rpython/memory/gctypelayout.py (original)
+++ pypy/branch/applevel-ctypes/pypy/rpython/memory/gctypelayout.py Sat Jan 5 11:15:22 2008
@@ -159,21 +159,14 @@
ARRAY = TYPE._flds[TYPE._arrayfld]
ofs1 = llmemory.offsetof(TYPE, TYPE._arrayfld)
info.ofstolength = ofs1 + llmemory.ArrayLengthOffset(ARRAY)
- if ARRAY.OF != lltype.Void:
- info.ofstovar = ofs1 + llmemory.itemoffsetof(ARRAY, 0)
- else:
- info.fixedsize = ofs1 + llmemory.sizeof(lltype.Signed)
+ info.ofstovar = ofs1 + llmemory.itemoffsetof(ARRAY, 0)
# XXX we probably don't need isrpystring any more
if ARRAY._hints.get('isrpystring'):
info.fixedsize = llmemory.sizeof(TYPE, 1)
else:
ARRAY = TYPE
info.ofstolength = llmemory.ArrayLengthOffset(ARRAY)
- if ARRAY.OF != lltype.Void:
- info.ofstovar = llmemory.itemoffsetof(TYPE, 0)
- else:
- info.fixedsize = (llmemory.ArrayLengthOffset(ARRAY) +
- llmemory.sizeof(lltype.Signed))
+ info.ofstovar = llmemory.itemoffsetof(TYPE, 0)
assert isinstance(ARRAY, lltype.Array)
if ARRAY.OF != lltype.Void:
offsets = offsets_to_gc_pointers(ARRAY.OF)
@@ -203,6 +196,10 @@
self.addresses_of_static_ptrs = []
# this lists contains pointers in raw Structs and Arrays
self.addresses_of_static_ptrs_in_nongc = []
+ # if not gc.prebuilt_gc_objects_are_static_roots, then
+ # additional_roots_sources counts the number of locations
+ # within prebuilt GC objects that are of type Ptr(Gc)
+ self.additional_roots_sources = 0
self.finalizer_funcptrs = {}
self.offsettable_cache = {}
self.next_typeid_cache = {}
@@ -272,7 +269,8 @@
return fptr
def make_finalizer_funcptr_for_type(self, TYPE):
- return None # must be overridden for proper finalizer support
+ # must be overridden for proper finalizer support
+ return lltype.nullptr(GCData.ADDRESS_VOID_FUNC)
def initialize_gc_query_function(self, gc):
return GCData(self.type_info_list).set_query_functions(gc)
@@ -296,10 +294,15 @@
# they could be changed later to point to GC heap objects.
adr = llmemory.cast_ptr_to_adr(value._as_ptr())
if TYPE._gckind == "gc":
- appendto = self.addresses_of_static_ptrs
+ if not gc.prebuilt_gc_objects_are_static_roots:
+ for a in gc_pointers_inside(value, adr):
+ self.additional_roots_sources += 1
+ return
+ else:
+ appendto = self.addresses_of_static_ptrs
else:
appendto = self.addresses_of_static_ptrs_in_nongc
- for a in mutable_gc_pointers_inside(value, adr):
+ for a in gc_pointers_inside(value, adr, mutable_only=True):
appendto.append(a)
# ____________________________________________________________
@@ -338,28 +341,30 @@
return llmemory.offsetof(WEAKREF, "weakptr")
return -1
-def mutable_gc_pointers_inside(v, adr):
+def gc_pointers_inside(v, adr, mutable_only=False):
t = lltype.typeOf(v)
if isinstance(t, lltype.Struct):
- if t._hints.get('immutable'):
+ if mutable_only and t._hints.get('immutable'):
return
for n, t2 in t._flds.iteritems():
if isinstance(t2, lltype.Ptr) and t2.TO._gckind == 'gc':
yield adr + llmemory.offsetof(t, n)
elif isinstance(t2, (lltype.Array, lltype.Struct)):
- for a in mutable_gc_pointers_inside(getattr(v, n),
- adr + llmemory.offsetof(t, n)):
+ for a in gc_pointers_inside(getattr(v, n),
+ adr + llmemory.offsetof(t, n),
+ mutable_only):
yield a
elif isinstance(t, lltype.Array):
- if t._hints.get('immutable'):
+ if mutable_only and t._hints.get('immutable'):
return
if isinstance(t.OF, lltype.Ptr) and t.OF.TO._gckind == 'gc':
for i in range(len(v.items)):
yield adr + llmemory.itemoffsetof(t, i)
elif isinstance(t.OF, lltype.Struct):
for i in range(len(v.items)):
- for a in mutable_gc_pointers_inside(v.items[i],
- adr + llmemory.itemoffsetof(t, i)):
+ for a in gc_pointers_inside(v.items[i],
+ adr + llmemory.itemoffsetof(t, i),
+ mutable_only):
yield a
def zero_gc_pointers(p):
Modified: pypy/branch/applevel-ctypes/pypy/rpython/memory/gcwrapper.py
==============================================================================
--- pypy/branch/applevel-ctypes/pypy/rpython/memory/gcwrapper.py (original)
+++ pypy/branch/applevel-ctypes/pypy/rpython/memory/gcwrapper.py Sat Jan 5 11:15:22 2008
@@ -11,10 +11,13 @@
def __init__(self, llinterp, flowgraphs, gc_class, GC_PARAMS={}):
self.AddressLinkedList = get_address_linked_list(10)
self.gc = gc_class(self.AddressLinkedList, **GC_PARAMS)
- self.gc.get_roots = self.get_roots_from_llinterp
+ def my_get_roots(with_static=True):
+ return self.get_roots_from_llinterp(with_static)
+ self.gc.get_roots = my_get_roots
self.llinterp = llinterp
self.prepare_graphs(flowgraphs)
self.gc.setup()
+ my_get_roots.append_static_root = self.constantroots.append
def prepare_graphs(self, flowgraphs):
layoutbuilder = DirectRunLayoutBuilder(self.llinterp)
@@ -26,7 +29,7 @@
TYPE = lltype.typeOf(obj)
layoutbuilder.consider_constant(TYPE, obj, self.gc)
- self.constantroots = layoutbuilder.addresses_of_static_ptrs
+ self.constantroots = list(layoutbuilder.addresses_of_static_ptrs)
self.constantrootsnongc = layoutbuilder.addresses_of_static_ptrs_in_nongc
def get_roots_from_llinterp(self, with_static=True):
Modified: pypy/branch/applevel-ctypes/pypy/rpython/memory/support.py
==============================================================================
--- pypy/branch/applevel-ctypes/pypy/rpython/memory/support.py (original)
+++ pypy/branch/applevel-ctypes/pypy/rpython/memory/support.py Sat Jan 5 11:15:22 2008
@@ -47,14 +47,14 @@
new.length = 0
self.chunk = new
return new
- enlarge.dont_inline = True
+ enlarge._dont_inline_ = True
def shrink(self):
old = self.chunk
self.chunk = old.previous
unused_chunks.put(old)
return self.chunk
- shrink.dont_inline = True
+ shrink._dont_inline_ = True
def append(self, addr):
if addr == llmemory.NULL:
Modified: pypy/branch/applevel-ctypes/pypy/rpython/memory/test/test_gctypelayout.py
==============================================================================
--- pypy/branch/applevel-ctypes/pypy/rpython/memory/test/test_gctypelayout.py (original)
+++ pypy/branch/applevel-ctypes/pypy/rpython/memory/test/test_gctypelayout.py Sat Jan 5 11:15:22 2008
@@ -1,4 +1,4 @@
-from pypy.rpython.memory.gctypelayout import TypeLayoutBuilder
+from pypy.rpython.memory.gctypelayout import TypeLayoutBuilder, GCData
from pypy.rpython.memory.gctypelayout import offsets_to_gc_pointers
from pypy.rpython.lltypesystem import lltype
@@ -36,6 +36,7 @@
for T1, T2 in [(GC_A, GC_S), (GC_A2, GC_S2), (GC_S3, GC_S2)]:
tid1 = layoutbuilder.get_type_id(T1)
tid2 = layoutbuilder.get_type_id(T2)
- lst1 = layoutbuilder.q_varsize_offsets_to_gcpointers_in_var_part(tid1)
- lst2 = layoutbuilder.q_offsets_to_gc_pointers(tid2)
+ gcdata = GCData(layoutbuilder.type_info_list)
+ lst1 = gcdata.q_varsize_offsets_to_gcpointers_in_var_part(tid1)
+ lst2 = gcdata.q_offsets_to_gc_pointers(tid2)
assert len(lst1) == len(lst2)
Modified: pypy/branch/applevel-ctypes/pypy/rpython/memory/test/test_transformed_gc.py
==============================================================================
--- pypy/branch/applevel-ctypes/pypy/rpython/memory/test/test_transformed_gc.py (original)
+++ pypy/branch/applevel-ctypes/pypy/rpython/memory/test/test_transformed_gc.py Sat Jan 5 11:15:22 2008
@@ -37,7 +37,8 @@
gcpolicy = None
stacklessgc = False
- def runner(self, f, nbargs=0, statistics=False, **extraconfigopts):
+ def runner(self, f, nbargs=0, statistics=False, transformer=False,
+ **extraconfigopts):
if nbargs == 2:
def entrypoint(args):
x = args[0]
@@ -84,6 +85,8 @@
def statistics(index):
return llinterp.eval_graph(statisticsgraph, [ll_gc, index])
return run, statistics
+ elif transformer:
+ return run, db.gctransformer
else:
return run
@@ -862,6 +865,42 @@
run = self.runner(f, nbargs=0)
run([])
+ def test_immutable_to_old_promotion(self):
+ T_CHILD = lltype.Ptr(lltype.GcStruct('Child', ('field', lltype.Signed)))
+ T_PARENT = lltype.Ptr(lltype.GcStruct('Parent', ('sub', T_CHILD)))
+ child = lltype.malloc(T_CHILD.TO)
+ child2 = lltype.malloc(T_CHILD.TO)
+ parent = lltype.malloc(T_PARENT.TO)
+ parent2 = lltype.malloc(T_PARENT.TO)
+ parent.sub = child
+ child.field = 3
+ parent2.sub = child2
+ child2.field = 8
+
+ T_ALL = lltype.Ptr(lltype.GcArray(T_PARENT))
+ all = lltype.malloc(T_ALL.TO, 2)
+ all[0] = parent
+ all[1] = parent2
+
+ def f(x, y):
+ res = all[x]
+ #all[x] = lltype.nullptr(T_PARENT.TO)
+ return res.sub.field
+
+ run, transformer = self.runner(f, nbargs=2, transformer=True)
+ run([1, 4])
+ assert len(transformer.layoutbuilder.addresses_of_static_ptrs) == 0
+ assert transformer.layoutbuilder.additional_roots_sources >= 4
+ # NB. Remember that additional_roots_sources does not count
+ # the number of prebuilt GC objects, but the number of locations
+ # within prebuilt GC objects that are of type Ptr(Gc).
+ # At the moment we get additional_roots_sources == 6:
+ # * all[0]
+ # * all[1]
+ # * parent.sub
+ # * parent2.sub
+ # * the GcArray pointer from gc.wr_to_objects_with_id
+ # * the GcArray pointer from gc.object_id_dict.
class TestGenerationalNoFullCollectGC(GCTest):
# test that nursery is doing its job and that no full collection
More information about the Pypy-commit
mailing list