[pypy-svn] r47269 - in pypy/branch/kill-keepalives-again/pypy: annotation rpython rpython/lltypesystem rpython/memory rpython/memory/gctransform rpython/memory/test translator

arigo at codespeak.net arigo at codespeak.net
Sun Oct 7 18:56:38 CEST 2007


Author: arigo
Date: Sun Oct  7 18:56:37 2007
New Revision: 47269

Added:
   pypy/branch/kill-keepalives-again/pypy/rpython/memory/gctypelayout.py   (contents, props changed)
   pypy/branch/kill-keepalives-again/pypy/rpython/memory/test/test_gctypelayout.py
      - copied, changed from r47254, pypy/branch/kill-keepalives-again/pypy/rpython/memory/test/test_lltypelayout.py
Removed:
   pypy/branch/kill-keepalives-again/pypy/rpython/memory/convertlltype.py
   pypy/branch/kill-keepalives-again/pypy/rpython/memory/gclltype.py
   pypy/branch/kill-keepalives-again/pypy/rpython/memory/lladdress.py
   pypy/branch/kill-keepalives-again/pypy/rpython/memory/lltypesimulation.py
   pypy/branch/kill-keepalives-again/pypy/rpython/memory/test/test_address.py
   pypy/branch/kill-keepalives-again/pypy/rpython/memory/test/test_convertlltype.py
   pypy/branch/kill-keepalives-again/pypy/rpython/memory/test/test_llinterpsim.py
   pypy/branch/kill-keepalives-again/pypy/rpython/memory/test/test_lltypelayout.py
   pypy/branch/kill-keepalives-again/pypy/rpython/memory/test/test_lltypesimulation.py
Modified:
   pypy/branch/kill-keepalives-again/pypy/annotation/bookkeeper.py
   pypy/branch/kill-keepalives-again/pypy/annotation/builtin.py
   pypy/branch/kill-keepalives-again/pypy/annotation/unaryop.py
   pypy/branch/kill-keepalives-again/pypy/rpython/llinterp.py
   pypy/branch/kill-keepalives-again/pypy/rpython/lltypesystem/llmemory.py
   pypy/branch/kill-keepalives-again/pypy/rpython/memory/gc.py
   pypy/branch/kill-keepalives-again/pypy/rpython/memory/gctransform/framework.py
   pypy/branch/kill-keepalives-again/pypy/rpython/memory/gctransform/refcounting.py
   pypy/branch/kill-keepalives-again/pypy/rpython/memory/gctransform/transform.py
   pypy/branch/kill-keepalives-again/pypy/rpython/memory/gcwrapper.py
   pypy/branch/kill-keepalives-again/pypy/rpython/memory/lltypelayout.py
   pypy/branch/kill-keepalives-again/pypy/rpython/memory/support.py
   pypy/branch/kill-keepalives-again/pypy/rpython/memory/test/test_gc.py
   pypy/branch/kill-keepalives-again/pypy/rpython/memory/test/test_support.py
   pypy/branch/kill-keepalives-again/pypy/rpython/memory/test/test_transformed_gc.py
   pypy/branch/kill-keepalives-again/pypy/rpython/raddress.py
   pypy/branch/kill-keepalives-again/pypy/rpython/rbuiltin.py
   pypy/branch/kill-keepalives-again/pypy/translator/exceptiontransform.py
Log:
Kill the memory simulator and lladdress.

Factor out the parts that compute the GC table into a new module
gctypelayout.py, used both by gctransform/framework and by
gcwrapper.  The latter can be used to test GCs by running them
directly, with the llinterpreter doing the calls to it.

Many tests pass, but it's still work in progress.


Modified: pypy/branch/kill-keepalives-again/pypy/annotation/bookkeeper.py
==============================================================================
--- pypy/branch/kill-keepalives-again/pypy/annotation/bookkeeper.py	(original)
+++ pypy/branch/kill-keepalives-again/pypy/annotation/bookkeeper.py	Sun Oct  7 18:56:37 2007
@@ -24,7 +24,6 @@
 from pypy.tool.algo.unionfind import UnionFind
 from pypy.rpython.lltypesystem import lltype, llmemory
 from pypy.rpython.ootypesystem import ootype
-from pypy.rpython.memory import lladdress
 from pypy.rpython import extregistry
 
 class Stats:

Modified: pypy/branch/kill-keepalives-again/pypy/annotation/builtin.py
==============================================================================
--- pypy/branch/kill-keepalives-again/pypy/annotation/builtin.py	(original)
+++ pypy/branch/kill-keepalives-again/pypy/annotation/builtin.py	Sun Oct  7 18:56:37 2007
@@ -629,8 +629,6 @@
 #_________________________________
 # memory address
 
-from pypy.rpython.memory import lladdress
-
 def raw_malloc(s_size):
     assert isinstance(s_size, SomeInteger) #XXX add noneg...?
     return SomeAddress()
@@ -655,12 +653,6 @@
     assert not s_addr2.is_null
     assert isinstance(s_int, SomeInteger) #XXX add noneg...?
 
-BUILTIN_ANALYZERS[lladdress.raw_malloc] = raw_malloc
-BUILTIN_ANALYZERS[lladdress.raw_malloc_usage] = raw_malloc_usage
-BUILTIN_ANALYZERS[lladdress.raw_free] = raw_free
-BUILTIN_ANALYZERS[lladdress.raw_memclear] = raw_memclear
-BUILTIN_ANALYZERS[lladdress.raw_memcopy] = raw_memcopy
-
 BUILTIN_ANALYZERS[llmemory.raw_malloc] = raw_malloc
 BUILTIN_ANALYZERS[llmemory.raw_malloc_usage] = raw_malloc_usage
 BUILTIN_ANALYZERS[llmemory.raw_free] = raw_free

Modified: pypy/branch/kill-keepalives-again/pypy/annotation/unaryop.py
==============================================================================
--- pypy/branch/kill-keepalives-again/pypy/annotation/unaryop.py	(original)
+++ pypy/branch/kill-keepalives-again/pypy/annotation/unaryop.py	Sun Oct  7 18:56:37 2007
@@ -763,15 +763,15 @@
 #_________________________________________
 # memory addresses
 
-from pypy.rpython.memory import lladdress
+from pypy.rpython.lltypesystem import llmemory
 
 class __extend__(SomeAddress):
     def getattr(s_addr, s_attr):
         assert s_attr.is_constant()
         assert isinstance(s_attr, SomeString)
-        assert s_attr.const in lladdress.supported_access_types
+        assert s_attr.const in llmemory.supported_access_types
         return SomeTypedAddressAccess(
-            lladdress.supported_access_types[s_attr.const])
+            llmemory.supported_access_types[s_attr.const])
     getattr.can_only_throw = []
 
     def is_true(s_addr):

Modified: pypy/branch/kill-keepalives-again/pypy/rpython/llinterp.py
==============================================================================
--- pypy/branch/kill-keepalives-again/pypy/rpython/llinterp.py	(original)
+++ pypy/branch/kill-keepalives-again/pypy/rpython/llinterp.py	Sun Oct  7 18:56:37 2007
@@ -42,20 +42,18 @@
 class LLInterpreter(object):
     """ low level interpreter working with concrete values. """
 
-    def __init__(self, typer, heap=llheap, tracing=True, exc_data_ptr=None,
+    def __init__(self, typer, tracing=True, exc_data_ptr=None,
                  malloc_check=True):
         self.bindings = {}
         self.typer = typer
-        self.heap = heap  #module that provides malloc, etc for lltypes
+        # 'heap' is module or object that provides malloc, etc for lltype ops
+        self.heap = llheap
         self.exc_data_ptr = exc_data_ptr
         self.active_frame = None
         self.tracer = None
         self.malloc_check = malloc_check
         self.frame_class = LLFrame
         self.mallocs = {}
-        if hasattr(heap, "prepare_graphs_and_create_gc"):
-            flowgraphs = typer.annotator.translator.graphs
-            heap.prepare_graphs_and_create_gc(self, flowgraphs)
         if tracing:
             self.tracer = Tracer()
 
@@ -574,7 +572,7 @@
                 obj = obj[o]
         T = obj._T
         if isinstance(finalfield, str):
-            if getattr(T, fieldname) is not lltype.Void:
+            if getattr(T, finalfield) is not lltype.Void:
                 heap.setfield(obj, finalfield, fieldvalue)
         else:
             if T.OF is not lltype.Void:

Modified: pypy/branch/kill-keepalives-again/pypy/rpython/lltypesystem/llmemory.py
==============================================================================
--- pypy/branch/kill-keepalives-again/pypy/rpython/lltypesystem/llmemory.py	(original)
+++ pypy/branch/kill-keepalives-again/pypy/rpython/lltypesystem/llmemory.py	Sun Oct  7 18:56:37 2007
@@ -470,6 +470,11 @@
             raise TypeError(TARGETTYPE)
         ptr[0] = value
 
+supported_access_types = {"signed":    lltype.Signed,
+                          "unsigned":  lltype.Unsigned,
+                          "char":      lltype.Char,
+                          "address":   Address,
+                          }
 
 fakeaddress.signed = property(_signed_fakeaccessor)
 fakeaddress.char = property(_char_fakeaccessor)

Modified: pypy/branch/kill-keepalives-again/pypy/rpython/memory/gc.py
==============================================================================
--- pypy/branch/kill-keepalives-again/pypy/rpython/memory/gc.py	(original)
+++ pypy/branch/kill-keepalives-again/pypy/rpython/memory/gc.py	Sun Oct  7 18:56:37 2007
@@ -3,7 +3,6 @@
 from pypy.rpython.lltypesystem.llmemory import NULL, raw_malloc_usage
 from pypy.rpython.memory.support import get_address_linked_list
 from pypy.rpython.memory.gcheader import GCHeaderBuilder
-from pypy.rpython.memory import lltypesimulation
 from pypy.rpython.lltypesystem import lltype, llmemory, llarena
 from pypy.rlib.objectmodel import free_non_gc_object, debug_assert
 from pypy.rpython.lltypesystem.lloperation import llop
@@ -11,9 +10,6 @@
 
 import sys, os
 
-int_size = lltypesimulation.sizeof(lltype.Signed)
-gc_header_two_ints = 2*int_size
-
 X_POOL = lltype.GcOpaqueType('gc.pool')
 X_POOL_PTR = lltype.Ptr(X_POOL)
 X_CLONE = lltype.GcStruct('CloneData', ('gcobjectptr', llmemory.GCREF),
@@ -184,7 +180,7 @@
         size = self.fixed_size(typeid)
         needs_finalizer =  bool(self.getfinalizer(typeid))
         contains_weakptr = self.weakpointer_offset(typeid) != -1
-        assert needs_finalizer != contains_weakptr
+        assert not (needs_finalizer and contains_weakptr)
         if self.is_varsize(typeid):
             assert not contains_weakptr
             itemsize = self.varsize_item_sizes(typeid)
@@ -1326,5 +1322,5 @@
         addr.signed[1] = typeid
 
     def size_gc_header(self, typeid=0):
-        return gc_header_two_ints
+        XXX
 

Modified: pypy/branch/kill-keepalives-again/pypy/rpython/memory/gctransform/framework.py
==============================================================================
--- pypy/branch/kill-keepalives-again/pypy/rpython/memory/gctransform/framework.py	(original)
+++ pypy/branch/kill-keepalives-again/pypy/rpython/memory/gctransform/framework.py	Sun Oct  7 18:56:37 2007
@@ -3,7 +3,7 @@
      get_rtti, ll_call_destructor, type_contains_pyobjs
 from pypy.rpython.lltypesystem import lltype, llmemory
 from pypy.rpython import rmodel
-from pypy.rpython.memory import gc, lladdress
+from pypy.rpython.memory import gc, gctypelayout
 from pypy.rpython.memory.gcheader import GCHeaderBuilder
 from pypy.rlib.rarithmetic import ovfcheck
 from pypy.rlib.objectmodel import debug_assert
@@ -11,6 +11,8 @@
 from pypy.annotation import model as annmodel
 from pypy.rpython import annlowlevel
 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
 import sys
 
 
@@ -27,7 +29,6 @@
 class FrameworkGCTransformer(GCTransformer):
     use_stackless = False
     extra_static_slots = 0
-    finished_tables = False
     root_stack_depth = 163840
 
     from pypy.rpython.memory.gc import MarkSweepGC as GCClass
@@ -38,7 +39,6 @@
         super(FrameworkGCTransformer, self).__init__(translator, inline=True)
         AddressLinkedList = get_address_linked_list()
         GCClass = self.GCClass
-        self.finalizer_funcptrs = {}
         self.FINALIZERTYPE = lltype.Ptr(ADDRESS_VOID_FUNC)
         class GCData(object):
             # types of the GC information tables
@@ -92,6 +92,9 @@
             debug_assert(typeid > 0, "invalid type_id")
             return gcdata.type_info_table[typeid].weakptrofs
 
+        self.layoutbuilder = TransformerLayoutBuilder(self)
+        self.get_type_id = self.layoutbuilder.get_type_id
+
         gcdata = GCData()
         # set up dummy a table, to be overwritten with the real one in finish()
         gcdata.type_info_table = lltype.malloc(GCData.TYPE_INFO_TABLE, 0,
@@ -105,14 +108,6 @@
         gcdata.static_root_start = a_random_address   # patched in finish()
         gcdata.static_root_end = a_random_address     # patched in finish()
         self.gcdata = gcdata
-        dummy = {"weakptrofs": -1,
-                 "ofstolength": -1}
-        self.type_info_list = [dummy]   # don't use typeid 0, helps debugging
-        self.id_of_type = {}      # {LLTYPE: type_id}
-        self.seen_roots = {}
-        self.static_gc_roots = []
-        self.addresses_of_static_ptrs_in_nongc = []
-        self.offsettable_cache = {}
         self.malloc_fnptr_cache = {}
 
         sizeofaddr = llmemory.sizeof(llmemory.Address)
@@ -272,9 +267,9 @@
         class StackRootIterator:
             _alloc_flavor_ = 'raw'
             def setup_root_stack():
-                stackbase = lladdress.raw_malloc(rootstacksize)
+                stackbase = llmemory.raw_malloc(rootstacksize)
                 debug_assert(bool(stackbase), "could not allocate root stack")
-                lladdress.raw_memclear(stackbase, rootstacksize)
+                llmemory.raw_memclear(stackbase, rootstacksize)
                 gcdata.root_stack_top  = stackbase
                 gcdata.root_stack_base = stackbase
                 i = 0
@@ -327,101 +322,15 @@
 
         return StackRootIterator
 
-    def get_type_id(self, TYPE):
-        try:
-            return self.id_of_type[TYPE]
-        except KeyError:
-            assert not self.finished_tables
-            assert isinstance(TYPE, (lltype.GcStruct, lltype.GcArray))
-            # Record the new type_id description as a small dict for now.
-            # It will be turned into a Struct("type_info") in finish()
-            type_id = len(self.type_info_list)
-            info = {}
-            self.type_info_list.append(info)
-            self.id_of_type[TYPE] = type_id
-            offsets = offsets_to_gc_pointers(TYPE)
-            info["ofstoptrs"] = self.offsets2table(offsets, TYPE)
-            info["finalyzer"] = self.finalizer_funcptr_for_type(TYPE)
-            info["weakptrofs"] = weakpointer_offset(TYPE)
-            if not TYPE._is_varsize():
-                info["isvarsize"] = False
-                info["fixedsize"] = llmemory.sizeof(TYPE)
-                info["ofstolength"] = -1
-            else:
-                info["isvarsize"] = True
-                info["fixedsize"] = llmemory.sizeof(TYPE, 0)
-                if isinstance(TYPE, lltype.Struct):
-                    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)
-                    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)
-                assert isinstance(ARRAY, lltype.Array)
-                if ARRAY.OF != lltype.Void:
-                    offsets = offsets_to_gc_pointers(ARRAY.OF)
-                    info["varofstoptrs"] = self.offsets2table(offsets, ARRAY.OF)
-                    info["varitemsize"] = llmemory.sizeof(ARRAY.OF)
-                else:
-                    info["varofstoptrs"] = self.offsets2table((), lltype.Void)
-                    info["varitemsize"] = llmemory.sizeof(ARRAY.OF)
-            return type_id
-
-    def finalizer_funcptr_for_type(self, TYPE):
-        if TYPE in self.finalizer_funcptrs:
-            return self.finalizer_funcptrs[TYPE]
-
-        rtti = get_rtti(TYPE)
-        if rtti is not None and hasattr(rtti._obj, 'destructor_funcptr'):
-            destrptr = rtti._obj.destructor_funcptr
-            DESTR_ARG = lltype.typeOf(destrptr).TO.ARGS[0]
-        else:
-            destrptr = None
-            DESTR_ARG = None
-
-        assert not type_contains_pyobjs(TYPE), "not implemented"
-        if destrptr:
-            def ll_finalizer(addr):
-                v = llmemory.cast_adr_to_ptr(addr, DESTR_ARG)
-                ll_call_destructor(destrptr, v)
-            fptr = self.annotate_helper(ll_finalizer, [llmemory.Address], lltype.Void)
-        else:
-            fptr = lltype.nullptr(ADDRESS_VOID_FUNC)
-
-        self.finalizer_funcptrs[TYPE] = fptr
-        return fptr
-
     def consider_constant(self, TYPE, value):
-        if value is not lltype.top_container(value):
-            return
-        if id(value) in self.seen_roots:
-            return
-        self.seen_roots[id(value)] = True
+        self.layoutbuilder.consider_constant(TYPE, value, self.gcdata.gc)
 
-        if isinstance(TYPE, (lltype.GcStruct, lltype.GcArray)):
-            typeid = self.get_type_id(TYPE)
-            hdrbuilder = self.gcdata.gc.gcheaderbuilder
-            hdr = hdrbuilder.new_header(value)
-            adr = llmemory.cast_ptr_to_adr(hdr)
-            self.gcdata.gc.init_gc_object(adr, typeid)
-
-        if find_gc_ptrs_in_type(TYPE):
-            adr = llmemory.cast_ptr_to_adr(value._as_ptr())
-            if isinstance(TYPE, (lltype.GcStruct, lltype.GcArray)):
-                self.static_gc_roots.append(adr)
-            else:
-                for a in gc_pointers_inside(value, adr):
-                    self.addresses_of_static_ptrs_in_nongc.append(a)
+    #def get_type_id(self, TYPE):
+    #    this method is attached to the instance and redirects to
+    #    layoutbuilder.get_type_id().
+
+    def finalizer_funcptr_for_type(self, TYPE):
+        return self.layoutbuilder.finalizer_funcptr_for_type(TYPE)
 
     def gc_fields(self):
         return self._gc_fields
@@ -431,25 +340,8 @@
         HDR = self._gc_HDR
         return [getattr(hdr, fldname) for fldname in HDR._names]
 
-    def offsets2table(self, offsets, TYPE):
-        try:
-            return self.offsettable_cache[TYPE]
-        except KeyError:
-            cachedarray = lltype.malloc(self.gcdata.OFFSETS_TO_GC_PTR,
-                                        len(offsets), immortal=True)
-            for i, value in enumerate(offsets):
-                cachedarray[i] = value
-            self.offsettable_cache[TYPE] = cachedarray
-            return cachedarray
-
     def finish_tables(self):
-        self.finished_tables = True
-        table = lltype.malloc(self.gcdata.TYPE_INFO_TABLE,
-                              len(self.type_info_list), immortal=True)
-        for tableentry, newcontent in zip(table, self.type_info_list):
-            for key, value in newcontent.items():
-                setattr(tableentry, key, value)
-        self.offsettable_cache = None
+        table = self.layoutbuilder.flatten_table()
 
         # replace the type_info_table pointer in gcdata -- at this point,
         # the database is in principle complete, so it has already seen
@@ -468,20 +360,23 @@
         ll_instance.inst_type_info_table = table
         #self.gcdata.type_info_table = table
 
+        static_gc_roots = self.layoutbuilder.static_gc_roots
         ll_static_roots = lltype.malloc(lltype.Array(llmemory.Address),
-                                        len(self.static_gc_roots) +
+                                        len(static_gc_roots) +
                                             self.extra_static_slots,
                                         immortal=True)
-        for i in range(len(self.static_gc_roots)):
-            adr = self.static_gc_roots[i]
+        for i in range(len(static_gc_roots)):
+            adr = static_gc_roots[i]
             ll_static_roots[i] = adr
         ll_instance.inst_static_roots = ll_static_roots
 
+        addresses_of_static_ptrs_in_nongc = \
+            self.layoutbuilder.addresses_of_static_ptrs_in_nongc
         ll_static_roots_inside = lltype.malloc(lltype.Array(llmemory.Address),
-                                               len(self.addresses_of_static_ptrs_in_nongc),
+                                               len(addresses_of_static_ptrs_in_nongc),
                                                immortal=True)
-        for i in range(len(self.addresses_of_static_ptrs_in_nongc)):
-            ll_static_roots_inside[i] = self.addresses_of_static_ptrs_in_nongc[i]
+        for i in range(len(addresses_of_static_ptrs_in_nongc)):
+            ll_static_roots_inside[i] = addresses_of_static_ptrs_in_nongc[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_end = ll_instance.inst_static_root_start + llmemory.sizeof(llmemory.Address) * len(ll_static_roots_inside)
 
@@ -511,10 +406,10 @@
         type_id = self.get_type_id(TYPE)
 
         c_type_id = rmodel.inputconst(lltype.Signed, type_id)
-        info = self.type_info_list[type_id]
+        info = self.layoutbuilder.type_info_list[type_id]
         c_size = rmodel.inputconst(lltype.Signed, info["fixedsize"])
-        c_has_finalizer = rmodel.inputconst(
-            lltype.Bool, bool(self.finalizer_funcptr_for_type(TYPE)))
+        has_finalizer = bool(self.finalizer_funcptr_for_type(TYPE))
+        c_has_finalizer = rmodel.inputconst(lltype.Bool, has_finalizer)
 
         if not op.opname.endswith('_varsize'):
             #malloc_ptr = self.malloc_fixedsize_ptr
@@ -594,7 +489,7 @@
         type_id = self.get_type_id(WEAKREF)
 
         c_type_id = rmodel.inputconst(lltype.Signed, type_id)
-        info = self.type_info_list[type_id]
+        info = self.layoutbuilder.type_info_list[type_id]
         c_size = rmodel.inputconst(lltype.Signed, info["fixedsize"])
         malloc_ptr = self.malloc_fixedsize_ptr
         c_has_finalizer = rmodel.inputconst(lltype.Bool, False)
@@ -653,38 +548,57 @@
 ##             hop.genop("direct_call", [self.pop_root_ptr])
 ##             #hop.genop("gc_reload_possibly_moved", [var])
 
-# XXX copied and modified from lltypelayout.py
-def offsets_to_gc_pointers(TYPE):
-    offsets = []
-    if isinstance(TYPE, lltype.Struct):
-        for name in TYPE._names:
-            FIELD = getattr(TYPE, name)
-            if isinstance(FIELD, lltype.Array):
-                continue    # skip inlined array
-            baseofs = llmemory.offsetof(TYPE, name)
-            suboffsets = offsets_to_gc_pointers(FIELD)
-            for s in suboffsets:
-                try:
-                    knownzero = s == 0
-                except TypeError:
-                    knownzero = False
-                if knownzero:
-                    offsets.append(baseofs)
-                else:
-                    offsets.append(baseofs + s)
-        # sanity check
-        #ex = lltype.Ptr(TYPE)._example()
-        #adr = llmemory.cast_ptr_to_adr(ex)
-        #for off in offsets:
-        #    (adr + off)
-    elif isinstance(TYPE, lltype.Ptr) and TYPE.TO._gckind == 'gc':
-        offsets.append(0)
-    return offsets
-
-def weakpointer_offset(TYPE):
-    if TYPE == WEAKREF:
-        return llmemory.offsetof(WEAKREF, "weakptr")
-    return -1
+
+class TransformerLayoutBuilder(gctypelayout.TypeLayoutBuilder):
+
+    def __init__(self, transformer):
+        super(TransformerLayoutBuilder, self).__init__()
+        self.transformer = transformer
+        self.offsettable_cache = {}
+
+    def make_finalizer_funcptr_for_type(self, TYPE):
+        rtti = get_rtti(TYPE)
+        if rtti is not None and hasattr(rtti._obj, 'destructor_funcptr'):
+            destrptr = rtti._obj.destructor_funcptr
+            DESTR_ARG = lltype.typeOf(destrptr).TO.ARGS[0]
+        else:
+            destrptr = None
+            DESTR_ARG = None
+
+        assert not type_contains_pyobjs(TYPE), "not implemented"
+        if destrptr:
+            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)
+        else:
+            fptr = lltype.nullptr(ADDRESS_VOID_FUNC)
+        return fptr
+
+    def offsets2table(self, offsets, TYPE):
+        try:
+            return self.offsettable_cache[TYPE]
+        except KeyError:
+            gcdata = self.transformer.gcdata
+            cachedarray = lltype.malloc(gcdata.OFFSETS_TO_GC_PTR,
+                                        len(offsets), immortal=True)
+            for i, value in enumerate(offsets):
+                cachedarray[i] = value
+            self.offsettable_cache[TYPE] = cachedarray
+            return cachedarray
+
+    def flatten_table(self):
+        self.can_add_new_types = False
+        table = lltype.malloc(self.transformer.gcdata.TYPE_INFO_TABLE,
+                              len(self.type_info_list), immortal=True)
+        for tableentry, newcontent in zip(table, self.type_info_list):
+            for key, value in newcontent.items():
+                setattr(tableentry, key, value)
+        self.offsettable_cache = None
+        return table
+
 
 def gen_zero_gc_pointers(TYPE, v, llops, previous_steps=None):
     if previous_steps is None:
@@ -702,45 +616,3 @@
                             [v] + previous_steps + [c_name, c_null])
         elif isinstance(FIELD, lltype.Struct):
             gen_zero_gc_pointers(FIELD, v, llops, previous_steps + [c_name])
-
-def gc_pointers_inside(v, adr):
-    t = lltype.typeOf(v)
-    if isinstance(t, lltype.Struct):
-        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 gc_pointers_inside(getattr(v, n), adr + llmemory.offsetof(t, n)):
-                    yield a
-    elif isinstance(t, lltype.Array):
-        if isinstance(t.OF, lltype.Ptr) and t2._needsgc():
-            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 gc_pointers_inside(v.items[i], adr + llmemory.itemoffsetof(t, i)):
-                    yield a
-
-
-########## weakrefs ##########
-# framework: weakref objects are small structures containing only an address
-
-WEAKREF = lltype.GcStruct("weakref", ("weakptr", llmemory.Address))
-WEAKREFPTR = lltype.Ptr(WEAKREF)
-sizeof_weakref= llmemory.sizeof(WEAKREF)
-empty_weakref = lltype.malloc(WEAKREF, immortal=True)
-empty_weakref.weakptr = llmemory.NULL
-
-def ll_weakref_deref(wref):
-    wref = llmemory.cast_weakrefptr_to_ptr(WEAKREFPTR, wref)
-    return wref.weakptr
-
-def convert_weakref_to(targetptr):
-    # Prebuilt weakrefs don't really need to be weak at all,
-    # but we need to emulate the structure expected by ll_weakref_deref().
-    if not targetptr:
-        return empty_weakref
-    else:
-        link = lltype.malloc(WEAKREF, immortal=True)
-        link.weakptr = llmemory.cast_ptr_to_adr(targetptr)
-        return link

Modified: pypy/branch/kill-keepalives-again/pypy/rpython/memory/gctransform/refcounting.py
==============================================================================
--- pypy/branch/kill-keepalives-again/pypy/rpython/memory/gctransform/refcounting.py	(original)
+++ pypy/branch/kill-keepalives-again/pypy/rpython/memory/gctransform/refcounting.py	Sun Oct  7 18:56:37 2007
@@ -6,7 +6,6 @@
 from pypy.rpython.lltypesystem.lloperation import llop
 from pypy.translator.backendopt.support import var_needsgc
 from pypy.rpython import rmodel
-from pypy.rpython.memory import lladdress
 from pypy.rpython.memory.gcheader import GCHeaderBuilder
 from pypy.rlib.rarithmetic import ovfcheck
 from pypy.rpython.rbuiltin import gen_cast
@@ -73,11 +72,11 @@
             llop.cpy_free(lltype.Void, adr)
 
         mh = mallocHelpers()
-        mh.allocate = lladdress.raw_malloc
+        mh.allocate = llmemory.raw_malloc
         def ll_malloc_fixedsize(size):
             size = gc_header_offset + size
             result = mh._ll_malloc_fixedsize(size)
-            lladdress.raw_memclear(result, size)
+            llmemory.raw_memclear(result, size)
             result += gc_header_offset
             return result
         def ll_malloc_varsize_no_length(length, size, itemsize):
@@ -88,7 +87,7 @@
             except OverflowError:
                 raise MemoryError()
             result = mh._ll_malloc_fixedsize(tot_size)
-            lladdress.raw_memclear(result, tot_size)
+            llmemory.raw_memclear(result, tot_size)
             result += gc_header_offset
             return result
         mh.ll_malloc_varsize_no_length = ll_malloc_varsize_no_length

Modified: pypy/branch/kill-keepalives-again/pypy/rpython/memory/gctransform/transform.py
==============================================================================
--- pypy/branch/kill-keepalives-again/pypy/rpython/memory/gctransform/transform.py	(original)
+++ pypy/branch/kill-keepalives-again/pypy/rpython/memory/gctransform/transform.py	Sun Oct  7 18:56:37 2007
@@ -18,7 +18,6 @@
 from pypy.rpython.rbuiltin import gen_cast
 from pypy.rlib.rarithmetic import ovfcheck
 import sets, os, sys
-from pypy.rpython.memory import lladdress
 from pypy.rpython.lltypesystem.lloperation import llop
 
 def var_ispyobj(var):
@@ -404,7 +403,7 @@
         result = mh.allocate(tot_size)
         if not result:
             raise MemoryError()
-        lladdress.raw_memclear(result, tot_size)
+        llmemory.raw_memclear(result, tot_size)
         return result
     mh.ll_malloc_varsize_no_length_zero = _ll_malloc_varsize_no_length_zero
 
@@ -416,7 +415,7 @@
         super(GCTransformer, self).__init__(translator, inline=inline)
 
         mh = mallocHelpers()
-        mh.allocate = lladdress.raw_malloc
+        mh.allocate = llmemory.raw_malloc
         ll_raw_malloc_fixedsize = mh._ll_malloc_fixedsize
         ll_raw_malloc_varsize_no_length = mh.ll_malloc_varsize_no_length
         ll_raw_malloc_varsize = mh.ll_malloc_varsize

Added: pypy/branch/kill-keepalives-again/pypy/rpython/memory/gctypelayout.py
==============================================================================
--- (empty file)
+++ pypy/branch/kill-keepalives-again/pypy/rpython/memory/gctypelayout.py	Sun Oct  7 18:56:37 2007
@@ -0,0 +1,224 @@
+from pypy.rpython.lltypesystem import lltype, llmemory
+from pypy.rpython.memory.gctransform.support import find_gc_ptrs_in_type
+
+
+class TypeLayoutBuilder(object):
+    can_add_new_types = True
+
+    def __init__(self):
+        dummy = {"weakptrofs": -1,
+                 "ofstolength": -1}
+        self.type_info_list = [dummy]   # don't use typeid 0, helps debugging
+        self.id_of_type = {}      # {LLTYPE: type_id}
+        self.seen_roots = {}
+        self.static_gc_roots = []
+        self.addresses_of_static_ptrs_in_nongc = []
+        self.finalizer_funcptrs = {}
+
+    def get_type_id(self, TYPE):
+        try:
+            return self.id_of_type[TYPE]
+        except KeyError:
+            assert self.can_add_new_types
+            assert isinstance(TYPE, (lltype.GcStruct, lltype.GcArray))
+            # Record the new type_id description as a small dict for now.
+            # It will be turned into a Struct("type_info") in finish()
+            type_id = len(self.type_info_list)
+            info = {}
+            self.type_info_list.append(info)
+            self.id_of_type[TYPE] = type_id
+            offsets = offsets_to_gc_pointers(TYPE)
+            info["ofstoptrs"] = self.offsets2table(offsets, TYPE)
+            info["finalyzer"] = self.make_finalizer_funcptr_for_type(TYPE)
+            info["weakptrofs"] = weakpointer_offset(TYPE)
+            if not TYPE._is_varsize():
+                info["isvarsize"] = False
+                info["fixedsize"] = llmemory.sizeof(TYPE)
+                info["ofstolength"] = -1
+            else:
+                info["isvarsize"] = True
+                info["fixedsize"] = llmemory.sizeof(TYPE, 0)
+                if isinstance(TYPE, lltype.Struct):
+                    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)
+                    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)
+                assert isinstance(ARRAY, lltype.Array)
+                if ARRAY.OF != lltype.Void:
+                    offsets = offsets_to_gc_pointers(ARRAY.OF)
+                    info["varofstoptrs"] = self.offsets2table(offsets, ARRAY.OF)
+                    info["varitemsize"] = llmemory.sizeof(ARRAY.OF)
+                else:
+                    info["varofstoptrs"] = self.offsets2table((), lltype.Void)
+                    info["varitemsize"] = llmemory.sizeof(ARRAY.OF)
+            return type_id
+
+    def offsets2table(self, offsets, TYPE):
+        return offsets
+
+    def finalizer_funcptr_for_type(self, TYPE):
+        if TYPE in self.finalizer_funcptrs:
+            return self.finalizer_funcptrs[TYPE]
+        fptr = self.make_finalizer_funcptr_for_type(TYPE)
+        self.finalizer_funcptrs[TYPE] = fptr
+        return fptr
+
+    def make_finalizer_funcptr_for_type(self, TYPE):
+        return None   # must be overridden for proper finalizer support
+
+    def q_is_varsize(self, typeid):
+        assert typeid > 0
+        return self.type_info_list[typeid]["isvarsize"]
+
+    def q_finalyzer(self, typeid):
+        assert typeid > 0
+        return self.type_info_list[typeid]["finalyzer"]
+
+    def q_offsets_to_gc_pointers(self, typeid):
+        assert typeid > 0
+        return self.type_info_list[typeid]["ofstoptrs"]
+
+    def q_fixed_size(self, typeid):
+        assert typeid > 0
+        return self.type_info_list[typeid]["fixedsize"]
+
+    def q_varsize_item_sizes(self, typeid):
+        assert typeid > 0
+        return self.type_info_list[typeid]["varitemsize"]
+
+    def q_varsize_offset_to_variable_part(self, typeid):
+        assert typeid > 0
+        return self.type_info_list[typeid]["ofstovar"]
+
+    def q_varsize_offset_to_length(self, typeid):
+        assert typeid > 0
+        return self.type_info_list[typeid]["ofstolength"]
+
+    def q_varsize_offsets_to_gcpointers_in_var_part(self, typeid):
+        assert typeid > 0
+        return self.type_info_list[typeid]["varofstoptrs"]
+
+    def q_weakpointer_offset(self, typeid):
+        assert typeid > 0
+        return self.type_info_list[typeid]["weakptrofs"]
+
+    def get_query_functions(self):
+        return (self.q_is_varsize,
+                self.q_finalyzer,
+                self.q_offsets_to_gc_pointers,
+                self.q_fixed_size,
+                self.q_varsize_item_sizes,
+                self.q_varsize_offset_to_variable_part,
+                self.q_varsize_offset_to_length,
+                self.q_varsize_offsets_to_gcpointers_in_var_part,
+                self.q_weakpointer_offset)
+
+    def consider_constant(self, TYPE, value, gc):
+        if value is not lltype.top_container(value):
+            return
+        if id(value) in self.seen_roots:
+            return
+        self.seen_roots[id(value)] = True
+
+        if isinstance(TYPE, (lltype.GcStruct, lltype.GcArray)):
+            typeid = self.get_type_id(TYPE)
+            hdr = gc.gcheaderbuilder.new_header(value)
+            adr = llmemory.cast_ptr_to_adr(hdr)
+            gc.init_gc_object_immortal(adr, typeid)
+
+        if find_gc_ptrs_in_type(TYPE):
+            adr = llmemory.cast_ptr_to_adr(value._as_ptr())
+            if isinstance(TYPE, (lltype.GcStruct, lltype.GcArray)):
+                self.static_gc_roots.append(adr)
+            else:
+                for a in gc_pointers_inside(value, adr):
+                    self.addresses_of_static_ptrs_in_nongc.append(a)
+
+# ____________________________________________________________
+#
+# Helpers to discover GC pointers inside structures
+
+def offsets_to_gc_pointers(TYPE):
+    offsets = []
+    if isinstance(TYPE, lltype.Struct):
+        for name in TYPE._names:
+            FIELD = getattr(TYPE, name)
+            if isinstance(FIELD, lltype.Array):
+                continue    # skip inlined array
+            baseofs = llmemory.offsetof(TYPE, name)
+            suboffsets = offsets_to_gc_pointers(FIELD)
+            for s in suboffsets:
+                try:
+                    knownzero = s == 0
+                except TypeError:
+                    knownzero = False
+                if knownzero:
+                    offsets.append(baseofs)
+                else:
+                    offsets.append(baseofs + s)
+        # sanity check
+        #ex = lltype.Ptr(TYPE)._example()
+        #adr = llmemory.cast_ptr_to_adr(ex)
+        #for off in offsets:
+        #    (adr + off)
+    elif isinstance(TYPE, lltype.Ptr) and TYPE.TO._gckind == 'gc':
+        offsets.append(0)
+    return offsets
+
+def weakpointer_offset(TYPE):
+    if TYPE == WEAKREF:
+        return llmemory.offsetof(WEAKREF, "weakptr")
+    return -1
+
+def gc_pointers_inside(v, adr):
+    t = lltype.typeOf(v)
+    if isinstance(t, lltype.Struct):
+        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 gc_pointers_inside(getattr(v, n), adr + llmemory.offsetof(t, n)):
+                    yield a
+    elif isinstance(t, lltype.Array):
+        if isinstance(t.OF, lltype.Ptr) and t2._needsgc():
+            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 gc_pointers_inside(v.items[i], adr + llmemory.itemoffsetof(t, i)):
+                    yield a
+
+########## weakrefs ##########
+# framework: weakref objects are small structures containing only an address
+
+WEAKREF = lltype.GcStruct("weakref", ("weakptr", llmemory.Address))
+WEAKREFPTR = lltype.Ptr(WEAKREF)
+sizeof_weakref= llmemory.sizeof(WEAKREF)
+empty_weakref = lltype.malloc(WEAKREF, immortal=True)
+empty_weakref.weakptr = llmemory.NULL
+
+def ll_weakref_deref(wref):
+    wref = llmemory.cast_weakrefptr_to_ptr(WEAKREFPTR, wref)
+    return wref.weakptr
+
+def convert_weakref_to(targetptr):
+    # Prebuilt weakrefs don't really need to be weak at all,
+    # but we need to emulate the structure expected by ll_weakref_deref().
+    if not targetptr:
+        return empty_weakref
+    else:
+        link = lltype.malloc(WEAKREF, immortal=True)
+        link.weakptr = llmemory.cast_ptr_to_adr(targetptr)
+        return link

Modified: pypy/branch/kill-keepalives-again/pypy/rpython/memory/gcwrapper.py
==============================================================================
--- pypy/branch/kill-keepalives-again/pypy/rpython/memory/gcwrapper.py	(original)
+++ pypy/branch/kill-keepalives-again/pypy/rpython/memory/gcwrapper.py	Sun Oct  7 18:56:37 2007
@@ -1,346 +1,111 @@
-from pypy.annotation.annrpython import RPythonAnnotator
-from pypy.rpython.rtyper import RPythonTyper
 from pypy.rpython.lltypesystem import lltype, llmemory
-from pypy.rpython.memory.support import get_address_linked_list, INT_SIZE
-from pypy.rpython.memory.lladdress import raw_malloc, raw_free, NULL
-from pypy.rpython.memory import lltypelayout
-from pypy.rpython.memory import lltypesimulation
-from pypy.rpython.memory import gc
-from pypy.rpython.memory.convertlltype import FlowGraphConstantConverter
-
-class QueryTypes(object):
-    def __init__(self):
-        self.types = []
-        self.type_to_typeid = {}
-
-    def get_typeid(self, TYPE, nonewtype=False):
-        if TYPE not in self.type_to_typeid:
-            if nonewtype:
-                raise Exception, "unknown type: %s" % TYPE
-            index = len(self.types)
-            self.type_to_typeid[TYPE] = index
-            self.types.append(TYPE)
-            return index
-        typeid = self.type_to_typeid[TYPE]
-        return typeid
-
-    def create_query_functions(self):
-        from pypy.rpython.lltypesystem import rstr
-        _is_varsize = []
-        _finalizers = []
-        _offsets_to_gc_pointers = []
-        _fixed_size = []
-        _varsize_item_sizes = []
-        _varsize_offset_to_variable_part = []
-        _varsize_offset_to_length = []
-        _varsize_offsets_to_gcpointers_in_var_part = []
-        tttid = zip(*zip(*self.type_to_typeid.items())[::-1])
-        tttid.sort()
-        tttid = zip(*zip(*tttid)[::-1])
-        for TYPE, typeid in tttid:
-            varsize = self.is_varsize(typeid)
-            _is_varsize.append(varsize)
-            _finalizers.append(None)
-            _offsets_to_gc_pointers.append(self.offsets_to_gc_pointers(typeid))
-            _fixed_size.append(self.fixed_size(typeid))
-            if varsize:
-                _varsize_item_sizes.append(self.varsize_item_sizes(typeid))
-                _varsize_offset_to_variable_part.append(
-                    self.varsize_offset_to_variable_part(typeid))
-                _varsize_offset_to_length.append(
-                    self.varsize_offset_to_length(typeid))
-                _varsize_offsets_to_gcpointers_in_var_part.append(
-                    lltypelayout.varsize_offsets_to_gcpointers_in_var_part(TYPE))
-            else:
-                _varsize_item_sizes.append(0)
-                _varsize_offset_to_variable_part.append(0)
-                _varsize_offset_to_length.append(0)
-                _varsize_offsets_to_gcpointers_in_var_part.append([])
-        # trick to make the annotator see that the list can contain functions:
-        _finalizers.append(lambda addr: None)
-        def is_varsize(typeid):
-            return _is_varsize[typeid]
-        def getfinalizer(typeid):
-            return _finalizers[typeid]
-        def offsets_to_gc_pointers(typeid):
-            return _offsets_to_gc_pointers[typeid]
-        def fixed_size(typeid):
-            return _fixed_size[typeid]
-        def varsize_item_sizes(typeid):
-            return _varsize_item_sizes[typeid]
-        def varsize_offset_to_variable_part(typeid):
-            return _varsize_offset_to_variable_part[typeid]
-        def varsize_offset_to_length(typeid):
-            return _varsize_offset_to_length[typeid]
-        def varsize_offsets_to_gcpointers_in_var_part(typeid):
-            return _varsize_offsets_to_gcpointers_in_var_part[typeid]
-        def weakpointer_offset(typeid):
-            return -1
-        return (is_varsize, getfinalizer, offsets_to_gc_pointers, fixed_size,
-                varsize_item_sizes, varsize_offset_to_variable_part,
-                varsize_offset_to_length,
-                varsize_offsets_to_gcpointers_in_var_part,
-                weakpointer_offset)
-
-    def is_varsize(self, typeid):
-        assert typeid >= 0
-        TYPE = self.types[typeid]
-        return (isinstance(TYPE, lltype.Array) or
-                (isinstance(TYPE, lltype.Struct) and
-                 TYPE._arrayfld is not None))
-
-    def getfinalizer(self, typeid):
-        return None
-
-    def offsets_to_gc_pointers(self, typeid):
-        assert typeid >= 0
-        return lltypelayout.offsets_to_gc_pointers(self.types[typeid])
-
-    def fixed_size(self, typeid):
-        assert typeid >= 0
-        return lltypelayout.get_fixed_size(self.types[typeid])
-
-    def varsize_item_sizes(self, typeid):
-        assert typeid >= 0
-        if self.is_varsize(typeid):
-            return lltypelayout.get_variable_size(self.types[typeid])
-        else:
-            return 0
-
-    def varsize_offset_to_variable_part(self, typeid):
-        assert typeid >= 0
-        if self.is_varsize(typeid):
-            return lltypelayout.get_fixed_size(self.types[typeid])
-        else:
-            return 0
-
-    def varsize_offset_to_length(self, typeid):
-        assert typeid >= 0
-        if self.is_varsize(typeid):
-            return lltypelayout.varsize_offset_to_length(self.types[typeid])
-        else:
-            return 0
-
-    def varsize_offsets_to_gcpointers_in_var_part(self, typeid):
-        assert typeid >= 0
-        if self.is_varsize(typeid):
-            return lltypelayout.varsize_offsets_to_gcpointers_in_var_part(
-                self.types[typeid])
-        else:
-            return 0
-
-    def weakpointer_offset(self, typeid):
-        return -1
+from pypy.rpython.memory.support import get_address_linked_list
+from pypy.rpython.memory import gctypelayout
+from pypy.objspace.flow.model import Constant
 
-    def get_setup_query_functions(self):
-        return (self.is_varsize, self.getfinalizer,
-                self.offsets_to_gc_pointers, self.fixed_size,
-                self.varsize_item_sizes, self.varsize_offset_to_variable_part,
-                self.varsize_offset_to_length,
-                self.varsize_offsets_to_gcpointers_in_var_part,
-                self.weakpointer_offset)
-
-    
-def getfunctionptr(annotator, graphfunc):
-    """Make a functionptr from the given Python function."""
-    graph = annotator.bookkeeper.getdesc(graphfunc).getuniquegraph()
-    llinputs = [v.concretetype for v in graph.getargs()]
-    lloutput = graph.getreturnvar().concretetype
-    FT = lltype.FuncType(llinputs, lloutput)
-    _callable = graphfunc
-    return lltypesimulation.functionptr(FT, graphfunc.func_name,
-                                        graph=graph, _callable=_callable)
 
+class GCManagedHeap(object):
 
-class GcWrapper(object):
     def __init__(self, llinterp, flowgraphs, gc_class):
-        self.query_types = QueryTypes()
-        self.AddressLinkedList = get_address_linked_list(3, hackishpop=True)
-        # XXX there might me GCs that have headers that depend on the type
-        # therefore we have to change the query functions to annotatable ones
-        # later
+        self.AddressLinkedList = get_address_linked_list(10, hackishpop=True)
         self.gc = gc_class(self.AddressLinkedList)
-        self.gc.set_query_functions(*self.query_types.get_setup_query_functions())
-        fgcc = FlowGraphConstantConverter(flowgraphs, self.gc, self.query_types)
-        fgcc.convert()
-        self.gc.set_query_functions(*self.query_types.create_query_functions())
+        self.gc.get_roots = self.get_roots_from_llinterp
         self.llinterp = llinterp
-        self.gc.get_roots = self.get_roots
-        self.constantroots = fgcc.cvter.constantroots
-        self.pseudo_root_pointers = NULL
-        self.roots = []
+        self.constantroots = []
+        self.prepare_graphs(flowgraphs)
         self.gc.setup()
 
-
-    def get_arg_malloc(self, TYPE, size=0):
-        typeid = self.query_types.get_typeid(TYPE, nonewtype=True)
-        return [typeid, size]
-
-    def get_funcptr_malloc(self):
-        return self.llinterp.heap.functionptr(gc.gc_interface["malloc"], "malloc",
-                                             _callable=self.gc.malloc)
-
-    def adjust_result_malloc(self, address, TYPE, size=0):
-        result = lltypesimulation.init_object_on_address(address, TYPE, size)
-        self.update_changed_addresses()
-        return result
-
-
-    def needs_write_barrier(self, TYPE):
-        return (hasattr(self.gc, "write_barrier") and
-                isinstance(TYPE, lltype.Ptr) and
-                isinstance(TYPE.TO, (lltype.GcStruct, lltype.GcArray)))
-
-    def get_arg_write_barrier(self, obj, index_or_field, item):
-        #XXX: quick hack to get the correct addresses, fix later
-        layout = lltypelayout.get_layout(lltype.typeOf(obj).TO)
-        if isinstance(lltype.typeOf(obj).TO, lltype.Array):
-            assert isinstance(index_or_field, int)
-            offset = layout[0] + layout[1] * index_or_field
-            addr_to = obj._address + layout[0] + index_or_field * layout[1]
-            return item._address, addr_to, obj._address
-        else:
-            offset = layout[index_or_field]
-            addr_to = obj._address + offset
-            return item._address, addr_to, obj._address
-            
-
-    def get_funcptr_write_barrier(self):
-        return self.llinterp.heap.functionptr(gc.gc_interface["write_barrier"],
-                                             "write_barrier",
-                                             _callable=self.gc.write_barrier)
- 
-
-    def update_changed_addresses(self):
-        for i, root in enumerate(self.roots):
-            root.__dict__['_address'] = self.pseudo_root_pointers.address[i]
+    def prepare_graphs(self, flowgraphs):
+        layoutbuilder = DirectRunLayoutBuilder()
+        self.get_type_id = layoutbuilder.get_type_id
+        self.gc.set_query_functions(*layoutbuilder.get_query_functions())
+
+        constants = collect_constants(flowgraphs)
+        for obj in constants:
+            TYPE = lltype.typeOf(obj)
+            layoutbuilder.consider_constant(TYPE, obj, self.gc)
+
+        sizeofaddr = llmemory.sizeof(llmemory.Address)
+        for addr in layoutbuilder.static_gc_roots:
+            addrofaddr = llmemory.raw_malloc(sizeofaddr)
+            addrofaddr.address[0] = addr
+            self.constantroots.append(addrofaddr)
+        self.constantroots += layoutbuilder.addresses_of_static_ptrs_in_nongc
 
     def get_roots_from_llinterp(self):
-        if self.pseudo_root_pointers != NULL:
-            raw_free(self.pseudo_root_pointers)
-        roots = [r for r in self.llinterp.find_roots()
-                     if isinstance(r._TYPE.TO,
-                                   (lltype.GcStruct, lltype.GcArray))]
-        self.roots = roots + self.constantroots
-        self.roots = [r for r in self.roots
-                          if isinstance(r._TYPE.TO,
-                                        (lltype.Struct, lltype.Array))]
-        if len(self.roots) == 0:
-            self.pseudo_root_pointers = NULL
-        else:
-            self.pseudo_root_pointers = raw_malloc(len(self.roots) * INT_SIZE)
-        return self.roots
-
-    def get_roots(self):
-        self.get_roots_from_llinterp()
+        sizeofaddr = llmemory.sizeof(llmemory.Address)
         ll = self.AddressLinkedList()
-        for i, root in enumerate(self.roots):
-            self.pseudo_root_pointers.address[i] = root._address
-            ll.append(self.pseudo_root_pointers + INT_SIZE * i)
+        for addrofaddr in self.constantroots:
+            ll.append(addrofaddr)
+        for root in self.llinterp.find_roots():
+            if lltype.typeOf(root).TO._gckind == 'gc':
+                addrofaddr = llmemory.raw_malloc(sizeofaddr)
+                addrofaddr.address[0] = llmemory.cast_ptr_to_adr(root)
+                ll.append(addrofaddr)
         return ll
 
-class AnnotatingGcWrapper(GcWrapper):
-    def __init__(self, llinterp, flowgraphs, gc_class):
-        super(AnnotatingGcWrapper, self).__init__(llinterp, flowgraphs, gc_class)
-        # tell the real-built gc to free its memory as it is only used for
-        # initialisation
-        self.gc.free_memory()
-        self.annotate_rtype_gc()
-
-    def annotate_rtype_gc(self):
-        # annotate and specialize functions
-        gc_class = self.gc.__class__
-        AddressLinkedList = self.AddressLinkedList
-        def instantiate_linked_list():
-            return AddressLinkedList()
-        f1, f2, f3, f4, f5, f6, f7, f8, f9 = self.query_types.create_query_functions()
-        the_gc = gc_class(AddressLinkedList)
-        def instantiate_gc():
-            the_gc.set_query_functions(f1, f2, f3, f4, f5, f6, f7, f8, f9)
-            the_gc.setup()
-            return the_gc
-        func, dummy_get_roots1, dummy_get_roots2 = gc.get_dummy_annotate(
-            the_gc, self.AddressLinkedList)
-        self.gc.get_roots = dummy_get_roots1
-        a = RPythonAnnotator()
-        a.build_types(instantiate_gc, [])
-        a.build_types(func, [])
-        a.build_types(instantiate_linked_list, [])
-        typer = RPythonTyper(a)
-        typer.specialize()
-        self.annotator = a
-        
-        # convert constants
-        fgcc = FlowGraphConstantConverter(a.translator.graphs)
-        fgcc.convert()
-        self.malloc_graph = a.bookkeeper.getdesc(self.gc.malloc.im_func).getuniquegraph()
-        self.write_barrier_graph = a.bookkeeper.getdesc(self.gc.write_barrier.im_func).getuniquegraph()
-
-        # create a gc via invoking instantiate_gc
-        self.gcptr = self.llinterp.eval_graph(
-            a.bookkeeper.getdesc(instantiate_gc).getuniquegraph())
-        GETROOTS_FUNCTYPE = lltype.typeOf(
-            getfunctionptr(a, dummy_get_roots1)).TO
-        setattr(self.gcptr, "inst_get_roots",
-                lltypesimulation.functionptr(GETROOTS_FUNCTYPE, "get_roots",
-                                             _callable=self.get_roots))
-        #get funcptrs neccessary to build the result of get_roots
-        self.instantiate_linked_list = getfunctionptr(
-            a, instantiate_linked_list)
-        self.append_linked_list = getfunctionptr(
-            a, AddressLinkedList.append.im_func)
-        self.pop_linked_list = getfunctionptr(
-            a, AddressLinkedList.pop.im_func)
-        self.gc.get_roots = None
-        self.translator = a.translator
-##         a.translator.view()
-
-    def get_arg_malloc(self, TYPE, size=0):
-        typeid = self.query_types.get_typeid(TYPE, nonewtype=True)
-        return [self.gcptr, typeid, size]
-
-    def get_funcptr_malloc(self):
-        FUNC = gc.gc_interface["malloc"]
-        FUNC = lltype.FuncType([lltype.typeOf(self.gcptr)] + list(FUNC.ARGS), FUNC.RESULT)
-        return self.llinterp.heap.functionptr(FUNC, "malloc",
-                                              _callable=self.gc.malloc,
-                                              graph=self.malloc_graph)
-
-    def adjust_result_malloc(self, address, TYPE, size=0):
-        result = lltypesimulation.init_object_on_address(address, TYPE, size)
-        self.update_changed_addresses()
-        return result
-
-    def get_arg_write_barrier(self, obj, index_or_field, item):
-        #XXX: quick hack to get the correct addresses, fix later
-        layout = lltypelayout.get_layout(lltype.typeOf(obj).TO)
-        if isinstance(lltype.typeOf(obj).TO, lltype.Array):
-            assert isinstance(index_or_field, int)
-            offset = layout[0] + layout[1] * index_or_field
-            addr_to = obj._address + layout[0] + index_or_field * layout[1]
-            return self.gcptr, item._address, addr_to, obj._address
-        else:
-            offset = layout[index_or_field]
-            addr_to = obj._address + offset
-            return self.gcptr, item._address, addr_to, obj._address
-            
-    def get_funcptr_write_barrier(self):
-        FUNC = gc.gc_interface["write_barrier"]
-        FUNC = lltype.FuncType([lltype.typeOf(self.gcptr)] + list(FUNC.ARGS), FUNC.RESULT)
-        return self.llinterp.heap.functionptr(FUNC,
-                                             "write_barrier",
-                                             _callable=self.gc.write_barrier,
-                                             graph=self.write_barrier_graph)
-
-
-    def get_roots(self):
-        # call the llinterpreter to construct the result in a suitable way
-        self.get_roots_from_llinterp()
-        ll = self.llinterp.active_frame.op_direct_call(
-            self.instantiate_linked_list)
-        for i, root in enumerate(self.roots):
-            self.pseudo_root_pointers.address[i] = root._address
-            self.llinterp.active_frame.op_direct_call(
-                self.append_linked_list, ll,
-                self.pseudo_root_pointers + INT_SIZE * i)
-        return ll
+    # ____________________________________________________________
+    #
+    # Interface for the llinterp
+    #
+    def malloc(self, TYPE, n=None, flavor='gc', zero=False):
+        if flavor == 'gc':
+            typeid = self.get_type_id(TYPE)
+            addr = self.gc.malloc(typeid, n)
+            return llmemory.cast_adr_to_ptr(addr, lltype.Ptr(TYPE))
+        else:
+            return lltype.malloc(TYPE, n, flavor=flavor, zero=zero)
+
+    def setfield(self, obj, fieldname, fieldvalue):
+        # XXX use write_barrier - but we need the address of the GcStruct
+        setattr(obj, fieldname, fieldvalue)
+
+    def setarrayitem(self, array, index, newitem):
+        # XXX use write_barrier - but we need the address of the GcStruct
+        array[index] = newitem
+
+    # ____________________________________________________________
+
+
+class DirectRunLayoutBuilder(gctypelayout.TypeLayoutBuilder):
+
+    def make_finalizer_funcptr_for_type(self, TYPE):
+        return None     # XXX
+
+
+def collect_constants(graphs):
+    constants = {}
+    def collect_args(args):
+        for arg in args:
+            if (isinstance(arg, Constant) and
+                arg.concretetype is not lltype.Void):
+                reccollect(constants, arg.value)
+    for graph in graphs:
+        for block in graph.iterblocks():
+            collect_args(block.inputargs)
+            for op in block.operations:
+                collect_args(op.args)
+        for link in graph.iterlinks():
+            collect_args(link.args)
+            if hasattr(link, "llexitcase"):
+                reccollect(constants, link.llexitcase)
+    return constants
+
+def reccollect(constants, llvalue):
+    T = lltype.typeOf(llvalue)
+    if isinstance(T, lltype.Ptr) and llvalue and llvalue._obj not in constants:
+        constants[llvalue._obj] = True
+        TYPE = T.TO
+        if isinstance(TYPE, lltype.Struct):
+            for name in TYPE._names:
+                reccollect(constants, getattr(llvalue, name))
+        elif isinstance(TYPE, lltype.Array):
+            for llitem in llvalue:
+                reccollect(constants, llitem)
+        parent, parentindex = lltype.parentlink(llvalue._obj)
+        if parent is not None:
+            reccollect(constants, parent._as_ptr())
+
+def prepare_graphs_and_create_gc(llinterp, GCClass):
+    flowgraphs = llinterp.typer.annotator.translator.graphs[:]
+    llinterp.heap = GCManagedHeap(llinterp, flowgraphs, GCClass)

Modified: pypy/branch/kill-keepalives-again/pypy/rpython/memory/lltypelayout.py
==============================================================================
--- pypy/branch/kill-keepalives-again/pypy/rpython/memory/lltypelayout.py	(original)
+++ pypy/branch/kill-keepalives-again/pypy/rpython/memory/lltypelayout.py	Sun Oct  7 18:56:37 2007
@@ -108,39 +108,3 @@
         return 0
     else:
         raise Exception("unknown offset type %r"%offset)
-        
-# _____________________________________________________________________________
-# the following functions are used to find contained pointers
-
-
-def offsets_to_gc_pointers(TYPE):
-    if isinstance(TYPE, lltype.Struct):
-        offsets = []
-        for name in TYPE._names:
-            FIELD = getattr(TYPE, name)
-            if isinstance(FIELD, lltype.Ptr) and FIELD.TO._gckind == 'gc':
-                offsets.append(llmemory.offsetof(TYPE, name))
-            elif isinstance(FIELD, lltype.Struct):
-                suboffsets = offsets_to_gc_pointers(FIELD)
-                offsets += [s + llmemory.offsetof(TYPE, name) for s in suboffsets]
-        return offsets
-    return []
-
-def varsize_offset_to_length(TYPE):
-    if isinstance(TYPE, lltype.Array):
-        return 0
-    elif isinstance(TYPE, lltype.Struct):
-        layout = get_layout(TYPE)
-        return layout[TYPE._arrayfld]
-
-def varsize_offsets_to_gcpointers_in_var_part(TYPE):
-    if isinstance(TYPE, lltype.Array):
-        if isinstance(TYPE.OF, lltype.Ptr):
-            return [0]
-        elif isinstance(TYPE.OF, lltype.Struct):
-            return offsets_to_gc_pointers(TYPE.OF)
-        return []
-    elif isinstance(TYPE, lltype.Struct):
-        return varsize_offsets_to_gcpointers_in_var_part(getattr(TYPE,
-                                                                 TYPE._arrayfld)) 
-    

Modified: pypy/branch/kill-keepalives-again/pypy/rpython/memory/support.py
==============================================================================
--- pypy/branch/kill-keepalives-again/pypy/rpython/memory/support.py	(original)
+++ pypy/branch/kill-keepalives-again/pypy/rpython/memory/support.py	Sun Oct  7 18:56:37 2007
@@ -1,9 +1,6 @@
 from pypy.rpython.lltypesystem import lltype, llmemory
-from pypy.rpython.memory.lltypelayout import sizeof
 from pypy.rlib.objectmodel import free_non_gc_object
 
-INT_SIZE = sizeof(lltype.Signed)
-
 DEFAULT_CHUNK_SIZE = 1019
 
 def get_address_linked_list(chunk_size=DEFAULT_CHUNK_SIZE, hackishpop=False):
@@ -16,8 +13,6 @@
                                    llmemory.Address, chunk_size))))
     null_chunk = lltype.nullptr(CHUNK)
 
-    SIZEOF_CHUNK = llmemory.sizeof(CHUNK)
-
     class FreeList(object):
         _alloc_flavor_ = "raw"
 
@@ -26,10 +21,7 @@
 
         def get(self):
             if not self.free_list:
-                from pypy.rpython.memory.lladdress import raw_memclear
-                r = lltype.malloc(CHUNK, flavor="raw")
-                raw_memclear(llmemory.cast_ptr_to_adr(r), SIZEOF_CHUNK)
-                return r
+                return lltype.malloc(CHUNK, flavor="raw")
                 
             result = self.free_list
             self.free_list = result.previous

Modified: pypy/branch/kill-keepalives-again/pypy/rpython/memory/test/test_gc.py
==============================================================================
--- pypy/branch/kill-keepalives-again/pypy/rpython/memory/test/test_gc.py	(original)
+++ pypy/branch/kill-keepalives-again/pypy/rpython/memory/test/test_gc.py	Sun Oct  7 18:56:37 2007
@@ -1,48 +1,36 @@
 import py
 import sys
 
-from pypy.annotation import model as annmodel
-from pypy.annotation.annrpython import RPythonAnnotator
-from pypy.rpython.rtyper import RPythonTyper
-from pypy.rpython.memory.gc import GCError, MarkSweepGC, SemiSpaceGC
-from pypy.rpython.memory.gc import DeferredRefcountingGC, DummyGC
-from pypy.rpython.memory.support import INT_SIZE
-from pypy.rpython.memory import support
-from pypy.rpython.memory.lladdress import raw_malloc, raw_free, NULL
-from pypy.rpython.memory.simulator import MemorySimulatorError
-from pypy.rpython.memory import gclltype
-from pypy.rpython.memory.test.test_llinterpsim import interpret
-from pypy.rpython.memory.lladdress import simulator
-from pypy.rlib.objectmodel import free_non_gc_object
-
-def setup_module(mod):
-    def stdout_ignore_ll_functions(msg):
-        strmsg = str(msg)
-        if "evaluating" in strmsg and "ll_" in strmsg:
-            return
-        print >>sys.stdout, strmsg
-    mod.logstate = py.log._getstate()
-    py.log.setconsumer("llinterp", py.log.STDOUT)
-    py.log.setconsumer("llinterp frame", stdout_ignore_ll_functions)
-    py.log.setconsumer("llinterp operation", None)
+#from pypy.rpython.memory.support import INT_SIZE
+from pypy.rpython.memory import gcwrapper
+from pypy.rpython.test.test_llinterp import get_interpreter
+
+
+def stdout_ignore_ll_functions(msg):
+    strmsg = str(msg)
+    if "evaluating" in strmsg and "ll_" in strmsg:
+        return
+    print >>sys.stdout, strmsg
 
 
 class GCTest(object):
 
     def setup_class(cls):
-        gclltype.prepare_graphs_and_create_gc = gclltype.create_gc
-        gclltype.use_gc = cls.GCClass
-        from pypy.rpython.memory import gc as gcimpl
-        gcimpl.DEBUG_PRINT = False
-        
+        cls._saved_logstate = py.log._getstate()
+        py.log.setconsumer("llinterp", py.log.STDOUT)
+        py.log.setconsumer("llinterp frame", stdout_ignore_ll_functions)
+        py.log.setconsumer("llinterp operation", None)
+
     def teardown_class(cls):
-        gclltype.prepare_graphs_and_create_gc =  gclltype.create_no_gc
-        gclltype.use_gc = MarkSweepGC
-        from pypy.rpython.memory import gc as gcimpl
-        gcimpl.DEBUG_PRINT = True
+        py.log._setstate(cls._saved_logstate)
+
+    def interpret(self, func, values, **kwds):
+        interp, graph = get_interpreter(func, values, **kwds)
+        gcwrapper.prepare_graphs_and_create_gc(interp, self.GCClass)
+        return interp.eval_graph(graph, values)
 
     def test_llinterp_lists(self):
-        curr = simulator.current_size
+        #curr = simulator.current_size
         def malloc_a_lot():
             i = 0
             while i < 10:
@@ -52,12 +40,12 @@
                 while j < 20:
                     j += 1
                     a.append(j)
-        res = interpret(malloc_a_lot, [])
-        assert simulator.current_size - curr < 16000 * INT_SIZE / 4
-        print "size before: %s, size after %s" % (curr, simulator.current_size)
+        res = self.interpret(malloc_a_lot, [])
+        #assert simulator.current_size - curr < 16000 * INT_SIZE / 4
+        #print "size before: %s, size after %s" % (curr, simulator.current_size)
 
     def test_llinterp_tuples(self):
-        curr = simulator.current_size
+        #curr = simulator.current_size
         def malloc_a_lot():
             i = 0
             while i < 10:
@@ -68,39 +56,41 @@
                 while j < 20:
                     j += 1
                     b.append((1, j, i))
-        res = interpret(malloc_a_lot, [])
-        assert simulator.current_size - curr < 16000 * INT_SIZE / 4
-        print "size before: %s, size after %s" % (curr, simulator.current_size)
+        res = self.interpret(malloc_a_lot, [])
+        #assert simulator.current_size - curr < 16000 * INT_SIZE / 4
+        #print "size before: %s, size after %s" % (curr, simulator.current_size)
 
     def test_global_list(self):
         lst = []
         def append_to_list(i, j):
             lst.append([i] * 50)
             return lst[j][0]
-        res = interpret(append_to_list, [0, 0])
+        res = self.interpret(append_to_list, [0, 0])
         assert res == 0
         for i in range(1, 15):
-            res = interpret(append_to_list, [i, i - 1])
+            res = self.interpret(append_to_list, [i, i - 1])
             assert res == i - 1 # crashes if constants are not considered roots
             
     def test_string_concatenation(self):
-        curr = simulator.current_size
+        #curr = simulator.current_size
         def concat(j):
             lst = []
             for i in range(j):
                 lst.append(str(i))
             return len("".join(lst))
-        res = interpret(concat, [100])
+        res = self.interpret(concat, [100])
         assert res == concat(100)
-        assert simulator.current_size - curr < 16000 * INT_SIZE / 4
+        #assert simulator.current_size - curr < 16000 * INT_SIZE / 4
 
 class TestMarkSweepGC(GCTest):
-    GCClass = MarkSweepGC
+    from pypy.rpython.memory.gc import MarkSweepGC as GCClass
 
 class TestSemiSpaceGC(GCTest):
-    GCClass = SemiSpaceGC
+    from pypy.rpython.memory.gc import SemiSpaceGC as GCClass
+    def setup_class(cls):
+        py.test.skip("in-progress")
 
 class TestDeferredRefcountingGC(GCTest):
-    GCClass = DeferredRefcountingGC
+    from pypy.rpython.memory.gc import DeferredRefcountingGC as GCClass
     def setup_class(cls):
         py.test.skip("DeferredRefcounting is unmaintained")

Modified: pypy/branch/kill-keepalives-again/pypy/rpython/memory/test/test_support.py
==============================================================================
--- pypy/branch/kill-keepalives-again/pypy/rpython/memory/test/test_support.py	(original)
+++ pypy/branch/kill-keepalives-again/pypy/rpython/memory/test/test_support.py	Sun Oct  7 18:56:37 2007
@@ -3,55 +3,60 @@
 
 from pypy.rpython.test.test_llinterp import interpret
 from pypy.rpython.lltypesystem import lltype, llmemory
+from pypy.rpython.lltypesystem.llmemory import raw_malloc, raw_free, NULL
 
 class TestAddressLinkedList(object):
     def test_simple_access(self):
-        from pypy.rpython.memory.lladdress import raw_malloc, raw_free, NULL
         AddressLinkedList = get_address_linked_list()
-        addr = raw_malloc(100)
+        addr0 = raw_malloc(llmemory.sizeof(lltype.Signed))
+        addr1 = raw_malloc(llmemory.sizeof(lltype.Signed))
+        addr2 = raw_malloc(llmemory.sizeof(lltype.Signed))
         ll = AddressLinkedList()
-        ll.append(addr)
-        ll.append(addr + 1)
-        ll.append(addr + 2)
+        ll.append(addr0)
+        ll.append(addr1)
+        ll.append(addr2)
         assert ll.non_empty()
         a = ll.pop()
-        assert a - addr == 2
+        assert a == addr2
         assert ll.non_empty()
         a = ll.pop()
-        assert a - addr == 1
+        assert a == addr1
         assert ll.non_empty()
         a = ll.pop()
-        assert a == addr
+        assert a == addr0
         assert not ll.non_empty()
-        ll.append(addr)
+        ll.append(addr0)
         ll.delete()
         ll = AddressLinkedList()
-        ll.append(addr)
-        ll.append(addr + 1)
-        ll.append(addr + 2)
+        ll.append(addr0)
+        ll.append(addr1)
+        ll.append(addr2)
         ll.delete()
-        raw_free(addr)
+        raw_free(addr2)
+        raw_free(addr1)
+        raw_free(addr0)
 
     def test_big_access(self):
-        from pypy.rpython.memory.lladdress import raw_malloc, raw_free, NULL        
         AddressLinkedList = get_address_linked_list()
-        addr = raw_malloc(1)
+        addrs = [raw_malloc(llmemory.sizeof(lltype.Signed))
+                 for i in range(3000)]
         ll = AddressLinkedList()
         for i in range(3000):
             print i
-            ll.append(addr + i)
+            ll.append(addrs[i])
         for i in range(3000)[::-1]:
             a = ll.pop()
-            assert a - addr == i
+            assert a == addrs[i]
         for i in range(3000):
             print i
-            ll.append(addr + i)
+            ll.append(addrs[i])
         for i in range(3000)[::-1]:
             a = ll.pop()
-            assert a - addr == i
+            assert a == addrs[i]
         ll.delete()
-        raw_free(addr)
-        
+        for addr in addrs:
+            raw_free(addr)
+
 def test_linked_list_annotate():
     AddressLinkedList = get_address_linked_list(60)
     INT_SIZE = llmemory.sizeof(lltype.Signed)
@@ -89,10 +94,7 @@
         raw_free(addr)
         return res
 
-    NULL = llmemory.NULL
-    raw_malloc, raw_free = llmemory.raw_malloc, llmemory.raw_free
     assert f()
-    from pypy.rpython.memory.lladdress import raw_malloc, raw_free
     AddressLinkedList = get_address_linked_list()
     res = interpret(f, [], malloc_check=False)
     assert res

Modified: pypy/branch/kill-keepalives-again/pypy/rpython/memory/test/test_transformed_gc.py
==============================================================================
--- pypy/branch/kill-keepalives-again/pypy/rpython/memory/test/test_transformed_gc.py	(original)
+++ pypy/branch/kill-keepalives-again/pypy/rpython/memory/test/test_transformed_gc.py	Sun Oct  7 18:56:37 2007
@@ -1,169 +1,17 @@
 import py
 import sys
-
-## from pypy.annotation import model as annmodel
-## from pypy.annotation.annrpython import RPythonAnnotator
-## from pypy.rpython.rtyper import RPythonTyper
-## from pypy.rpython.memory.gc import GCError, MarkSweepGC, SemiSpaceGC
-## from pypy.rpython.memory.gc import DeferredRefcountingGC, DummyGC
-## from pypy.rpython.memory import support
-## from pypy.rpython.memory.lladdress import raw_malloc, raw_free, NULL
-## from pypy.rpython.memory.simulator import MemorySimulatorError
-## from pypy.rpython.memory import gclltype
-## from pypy.rpython.memory.test.test_llinterpsim import interpret
-## from pypy.rpython.memory.lladdress import simulator
-## from pypy.rlib.objectmodel import free_non_gc_object
-
-## def setup_module(mod):
-##     def stdout_ignore_ll_functions(msg):
-##         strmsg = str(msg)
-##         if "evaluating" in strmsg and "ll_" in strmsg:
-##             return
-##         print >>sys.stdout, strmsg
-##     mod.logstate = py.log._getstate()
-##     py.log.setconsumer("llinterp", py.log.STDOUT)
-##     py.log.setconsumer("llinterp frame", stdout_ignore_ll_functions)
-##     py.log.setconsumer("llinterp operation", None)
-##     gclltype.prepare_graphs_and_create_gc = gclltype.create_gc
-
-## def teardown_module(mod):
-##     gclltype.prepare_graphs_and_create_gc = gclltype.create_no_gc
-
-## class TestMarkSweepGC(object):
-##     def setup_class(cls):
-##         cls.prep_old = gclltype.prepare_graphs_and_create_gc
-##         cls.old = gclltype.use_gc
-##         gclltype.use_gc = MarkSweepGC
-
-##     def teardown_class(cls):
-##         gclltype.prepare_graphs_and_create_gc = cls.prep_old.im_func
-##         gclltype.use_gc = cls.old
-
-##     def test_llinterp_lists(self):
-##         curr = simulator.current_size
-##         def malloc_a_lot():
-##             i = 0
-##             while i < 10:
-##                 i += 1
-##                 a = [1] * 10
-##                 j = 0
-##                 while j < 20:
-##                     j += 1
-##                     a.append(j)
-##         res = interpret(malloc_a_lot, [])
-##         assert simulator.current_size - curr < 16000 * INT_SIZE / 4
-##         print "size before: %s, size after %s" % (curr, simulator.current_size)
-
-##     def test_llinterp_tuples(self):
-##         curr = simulator.current_size
-##         def malloc_a_lot():
-##             i = 0
-##             while i < 10:
-##                 i += 1
-##                 a = (1, 2, i)
-##                 b = [a] * 10
-##                 j = 0
-##                 while j < 20:
-##                     j += 1
-##                     b.append((1, j, i))
-##         res = interpret(malloc_a_lot, [])
-##         assert simulator.current_size - curr < 16000 * INT_SIZE / 4
-##         print "size before: %s, size after %s" % (curr, simulator.current_size)
-
-##     def test_global_list(self):
-##         lst = []
-##         def append_to_list(i, j):
-##             lst.append([i] * 50)
-##             return lst[j][0]
-##         res = interpret(append_to_list, [0, 0])
-##         assert res == 0
-##         for i in range(1, 15):
-##             res = interpret(append_to_list, [i, i - 1])
-##             assert res == i - 1 # crashes if constants are not considered roots
-            
-##     def test_string_concatenation(self):
-##         curr = simulator.current_size
-##         def concat(j):
-##             lst = []
-##             for i in range(j):
-##                 lst.append(str(i))
-##             return len("".join(lst))
-##         res = interpret(concat, [100])
-##         assert res == concat(100)
-##         assert simulator.current_size - curr < 16000 * INT_SIZE / 4
-
-## class TestMarkSweepGCRunningOnLLinterp(TestMarkSweepGC):
-##     def setup_class(cls):
-##         cls.prep_old = gclltype.prepare_graphs_and_create_gc
-##         gclltype.prepare_graphs_and_create_gc = gclltype.create_gc_run_on_llinterp
-##     def teardown_class(cls):
-##         gclltype.prepare_graphs_and_create_gc = cls.prep_old.im_func
-
-## class TestSemiSpaceGC(TestMarkSweepGC):
-##     def setup_class(cls):
-##         gclltype.use_gc = SemiSpaceGC
-##         cls.old = gclltype.use_gc
-##     def teardown_class(cls):
-##         gclltype.use_gc = cls.old
-
-## class TestSemiSpaceGCRunningOnLLinterp(TestMarkSweepGC):
-##     def setup_class(cls):
-##         cls.prep_old = gclltype.prepare_graphs_and_create_gc
-##         gclltype.prepare_graphs_and_create_gc = gclltype.create_gc_run_on_llinterp
-##         gclltype.use_gc = SemiSpaceGC
-##         cls.old = gclltype.use_gc
-
-##     def teardown_class(cls):
-##         gclltype.prepare_graphs_and_create_gc = cls.prep_old.im_func
-##         gclltype.use_gc = cls.old
-
-## class TestDeferredRefcountingGC(TestMarkSweepGC):
-##     def setup_class(cls):
-##         gclltype.use_gc = DeferredRefcountingGC
-##         cls.old = gclltype.use_gc
-##     def teardown_class(cls):
-##         gclltype.use_gc = cls.old
-
-
-## class TestDeferredRefcountingGCRunningOnLLinterp(TestMarkSweepGC):
-##     def setup_class(cls):
-##         cls.prep_old = gclltype.prepare_graphs_and_create_gc
-##         gclltype.prepare_graphs_and_create_gc = gclltype.create_gc_run_on_llinterp
-##         gclltype.use_gc = DeferredRefcountingGC
-##         cls.old = gclltype.use_gc
-
-##     def teardown_class(cls):
-##         gclltype.prepare_graphs_and_create_gc = cls.prep_old.im_func
-##         gclltype.use_gc = cls.old
-
-## class TestDummyGC(TestMarkSweepGC):
-##     def setup_class(cls):
-##         gclltype.use_gc = DummyGC
-##         cls.old = gclltype.use_gc
-##     def teardown_class(cls):
-##         gclltype.use_gc = cls.old
-
-## class TestDummyGCRunningOnLLinterp(TestMarkSweepGC):
-##     def setup_class(cls):
-##         cls.prep_old = gclltype.prepare_graphs_and_create_gc
-##         gclltype.prepare_graphs_and_create_gc = gclltype.create_gc_run_on_llinterp
-##         gclltype.use_gc = DummyGC
-##         cls.old = gclltype.use_gc
-
-##     def teardown_class(cls):
-##         gclltype.prepare_graphs_and_create_gc = cls.prep_old.im_func
-##         gclltype.use_gc = cls.old
-
+import struct
 from pypy.translator.c import gc
 from pypy.annotation import model as annmodel
 from pypy.rpython.lltypesystem import lltype, llmemory
 from pypy.rpython.memory.gctransform import framework
 from pypy.rpython.memory.gctransform import stacklessframework
 from pypy.rpython.lltypesystem.lloperation import llop
-from pypy.rpython.memory.support import INT_SIZE
 from pypy.rpython.memory.gc import X_CLONE, X_POOL, X_POOL_PTR
 from pypy import conftest
 
+INT_SIZE = struct.calcsize("i")   # only for estimates
+
 
 def rtype(func, inputtypes, specialize=True, gcname='ref', stacklessgc=False):
     from pypy.translator.translator import TranslationContext

Modified: pypy/branch/kill-keepalives-again/pypy/rpython/raddress.py
==============================================================================
--- pypy/branch/kill-keepalives-again/pypy/rpython/raddress.py	(original)
+++ pypy/branch/kill-keepalives-again/pypy/rpython/raddress.py	Sun Oct  7 18:56:37 2007
@@ -1,9 +1,8 @@
 # rtyping of memory address operations
 from pypy.annotation.pairtype import pairtype
 from pypy.annotation import model as annmodel
-from pypy.rpython.memory.lladdress import _address
 from pypy.rpython.lltypesystem.llmemory import NULL, Address, \
-     cast_adr_to_int
+     cast_adr_to_int, fakeaddress
 from pypy.rpython.rmodel import Repr, IntegerRepr
 from pypy.rpython.rptr import PtrRepr
 from pypy.rpython.lltypesystem import lltype
@@ -27,7 +26,9 @@
     lowleveltype = Address
 
     def convert_const(self, value):
-        assert not isinstance(value, _address)
+        # note that llarena.fakearenaaddress is not supported as a constant
+        # in graphs
+        assert type(value) is fakeaddress
         return value
 
     def ll_str(self, a):

Modified: pypy/branch/kill-keepalives-again/pypy/rpython/rbuiltin.py
==============================================================================
--- pypy/branch/kill-keepalives-again/pypy/rpython/rbuiltin.py	(original)
+++ pypy/branch/kill-keepalives-again/pypy/rpython/rbuiltin.py	Sun Oct  7 18:56:37 2007
@@ -569,7 +569,6 @@
 # _________________________________________________________________
 # memory addresses
 
-from pypy.rpython.memory import lladdress
 from pypy.rpython.lltypesystem import llmemory
 
 def rtype_raw_malloc(hop):
@@ -594,12 +593,6 @@
     v_list = hop.inputargs(llmemory.Address, lltype.Signed)
     return hop.genop('raw_memclear', v_list)
 
-BUILTIN_TYPER[lladdress.raw_malloc] = rtype_raw_malloc
-BUILTIN_TYPER[lladdress.raw_malloc_usage] = rtype_raw_malloc_usage
-BUILTIN_TYPER[lladdress.raw_free] = rtype_raw_free
-BUILTIN_TYPER[lladdress.raw_memclear] = rtype_raw_memclear
-BUILTIN_TYPER[lladdress.raw_memcopy] = rtype_raw_memcopy
-
 BUILTIN_TYPER[llmemory.raw_malloc] = rtype_raw_malloc
 BUILTIN_TYPER[llmemory.raw_malloc_usage] = rtype_raw_malloc_usage
 BUILTIN_TYPER[llmemory.raw_free] = rtype_raw_free

Modified: pypy/branch/kill-keepalives-again/pypy/translator/exceptiontransform.py
==============================================================================
--- pypy/branch/kill-keepalives-again/pypy/translator/exceptiontransform.py	(original)
+++ pypy/branch/kill-keepalives-again/pypy/translator/exceptiontransform.py	Sun Oct  7 18:56:37 2007
@@ -7,7 +7,7 @@
 from pypy.rpython.lltypesystem import lltype, llmemory, rffi
 from pypy.rpython.ootypesystem import ootype
 from pypy.rpython.lltypesystem import lloperation
-from pypy.rpython.memory.lladdress import NULL
+from pypy.rpython.lltypesystem.llmemory import NULL
 from pypy.rpython import rtyper
 from pypy.rpython import rclass
 from pypy.rpython.rmodel import inputconst



More information about the Pypy-commit mailing list