[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