[pypy-svn] r51812 - in pypy/branch/unified-rtti/pypy/rpython/memory: . gc gctransform test
arigo at codespeak.net
arigo at codespeak.net
Fri Feb 22 22:09:32 CET 2008
Author: arigo
Date: Fri Feb 22 22:09:31 2008
New Revision: 51812
Modified:
pypy/branch/unified-rtti/pypy/rpython/memory/gc/base.py
pypy/branch/unified-rtti/pypy/rpython/memory/gc/generation.py
pypy/branch/unified-rtti/pypy/rpython/memory/gc/marksweep.py
pypy/branch/unified-rtti/pypy/rpython/memory/gc/semispace.py
pypy/branch/unified-rtti/pypy/rpython/memory/gctransform/boehm.py
pypy/branch/unified-rtti/pypy/rpython/memory/gctransform/framework.py
pypy/branch/unified-rtti/pypy/rpython/memory/gctransform/refcounting.py
pypy/branch/unified-rtti/pypy/rpython/memory/gctransform/transform.py
pypy/branch/unified-rtti/pypy/rpython/memory/gcwrapper.py
pypy/branch/unified-rtti/pypy/rpython/memory/lltypelayout.py
pypy/branch/unified-rtti/pypy/rpython/memory/test/test_gc.py
Log:
Progress in updating the Semispace and Generation GCs.
Modified: pypy/branch/unified-rtti/pypy/rpython/memory/gc/base.py
==============================================================================
--- pypy/branch/unified-rtti/pypy/rpython/memory/gc/base.py (original)
+++ pypy/branch/unified-rtti/pypy/rpython/memory/gc/base.py Fri Feb 22 22:09:31 2008
@@ -1,5 +1,4 @@
from pypy.rpython.lltypesystem import lltype, llmemory
-from pypy.rpython.memory import gcheader, gctypelayout
from pypy.rlib.debug import ll_assert
class GCBase(object):
@@ -9,10 +8,6 @@
needs_zero_gc_pointers = True
prebuilt_gc_objects_are_static_roots = True
- def __init__(self):
- TYPE_INFO = gctypelayout.GCData.TYPE_INFO
- self.gcheaderbuilder = gcheader.GCHeaderBuilder(self.HDR, TYPE_INFO)
-
def set_query_functions(self, is_varsize, has_gcptr_in_varsize,
is_gcarrayofgcptr,
getfinalizer,
Modified: pypy/branch/unified-rtti/pypy/rpython/memory/gc/generation.py
==============================================================================
--- pypy/branch/unified-rtti/pypy/rpython/memory/gc/generation.py (original)
+++ pypy/branch/unified-rtti/pypy/rpython/memory/gc/generation.py Fri Feb 22 22:09:31 2008
@@ -31,13 +31,15 @@
prebuilt_gc_objects_are_static_roots = False
first_unused_gcflag = SemiSpaceGC.first_unused_gcflag << 2
- def __init__(self, chunk_size=DEFAULT_CHUNK_SIZE,
+ def __init__(self, gcheaderbuilder,
+ chunk_size=DEFAULT_CHUNK_SIZE,
nursery_size=128,
min_nursery_size=128,
auto_nursery_size=False,
space_size=4096,
max_space_size=sys.maxint//2+1):
- SemiSpaceGC.__init__(self, chunk_size = chunk_size,
+ SemiSpaceGC.__init__(self, gcheaderbuilder,
+ chunk_size = chunk_size,
space_size = space_size,
max_space_size = max_space_size)
assert min_nursery_size <= nursery_size <= space_size // 2
@@ -196,9 +198,9 @@
def init_gc_object(self, addr, typeid, flags=GCFLAG_NO_YOUNG_PTRS):
SemiSpaceGC.init_gc_object(self, addr, typeid, flags)
- def init_gc_object_immortal(self, addr, typeid,
+ def init_gc_object_immortal(self, hdr, typeid,
flags=GCFLAG_NO_YOUNG_PTRS|GCFLAG_NO_HEAP_PTRS):
- SemiSpaceGC.init_gc_object_immortal(self, addr, typeid, flags)
+ SemiSpaceGC.init_gc_object_immortal(self, hdr, typeid, flags)
def semispace_collect(self, size_changing=False):
self.reset_young_gcflags() # we are doing a full collection anyway
@@ -214,7 +216,7 @@
def trace_and_copy(self, obj):
# during a full collect, all objects copied might come from the nursery and
# so must have this flag set:
- self.header(obj).tid |= GCFLAG_NO_YOUNG_PTRS
+ self.header(obj).flags |= GCFLAG_NO_YOUNG_PTRS
SemiSpaceGC.trace_and_copy(self, obj)
# history: this was missing and caused an object to become old but without the
# flag set. Such an object is bogus in the sense that the write_barrier doesn't
@@ -227,7 +229,7 @@
while oldlist.non_empty():
obj = oldlist.pop()
hdr = self.header(obj)
- hdr.tid |= GCFLAG_NO_YOUNG_PTRS
+ hdr.flags |= GCFLAG_NO_YOUNG_PTRS
def weakrefs_grow_older(self):
while self.young_objects_with_weakrefs.non_empty():
@@ -308,7 +310,7 @@
"""obj must not be in the nursery. This copies all the
young objects it references out of the nursery.
"""
- self.header(obj).tid |= GCFLAG_NO_YOUNG_PTRS
+ self.header(obj).flags |= GCFLAG_NO_YOUNG_PTRS
self.trace(obj, self._trace_drag_out, None)
def _trace_drag_out(self, pointer, ignored):
@@ -336,7 +338,7 @@
self.objects_with_weakrefs.append(obj)
def write_barrier(self, oldvalue, newvalue, addr_struct):
- if self.header(addr_struct).tid & GCFLAG_NO_YOUNG_PTRS:
+ if self.header(addr_struct).flags & GCFLAG_NO_YOUNG_PTRS:
self.remember_young_pointer(addr_struct, newvalue)
def append_to_static_roots(self, pointer, arg):
@@ -344,7 +346,7 @@
def move_to_static_roots(self, addr_struct):
objhdr = self.header(addr_struct)
- objhdr.tid &= ~GCFLAG_NO_HEAP_PTRS
+ objhdr.flags &= ~GCFLAG_NO_HEAP_PTRS
self.trace(addr_struct, self.append_to_static_roots, None)
def remember_young_pointer(self, addr_struct, addr):
@@ -353,8 +355,8 @@
oldhdr = self.header(addr_struct)
if self.is_in_nursery(addr):
self.old_objects_pointing_to_young.append(addr_struct)
- oldhdr.tid &= ~GCFLAG_NO_YOUNG_PTRS
- if oldhdr.tid & GCFLAG_NO_HEAP_PTRS:
+ oldhdr.flags &= ~GCFLAG_NO_YOUNG_PTRS
+ if oldhdr.flags & GCFLAG_NO_HEAP_PTRS:
self.move_to_static_roots(addr_struct)
remember_young_pointer._dont_inline_ = True
Modified: pypy/branch/unified-rtti/pypy/rpython/memory/gc/marksweep.py
==============================================================================
--- pypy/branch/unified-rtti/pypy/rpython/memory/gc/marksweep.py (original)
+++ pypy/branch/unified-rtti/pypy/rpython/memory/gc/marksweep.py Fri Feb 22 22:09:31 2008
@@ -74,8 +74,9 @@
POOLNODE.become(lltype.Struct('gc_pool_node', ('linkedlisthdr', HDR),
('nextnode', POOLNODEPTR)))
- def __init__(self, chunk_size=DEFAULT_CHUNK_SIZE, start_heap_size=4096):
- GCBase.__init__(self)
+ def __init__(self, gcheaderbuilder,
+ chunk_size=DEFAULT_CHUNK_SIZE, start_heap_size=4096):
+ self.gcheaderbuilder = gcheaderbuilder
self.heap_usage = 0 # at the end of the latest collection
self.bytes_malloced = 0 # since the latest collection
self.bytes_malloced_threshold = start_heap_size
Modified: pypy/branch/unified-rtti/pypy/rpython/memory/gc/semispace.py
==============================================================================
--- pypy/branch/unified-rtti/pypy/rpython/memory/gc/semispace.py (original)
+++ pypy/branch/unified-rtti/pypy/rpython/memory/gc/semispace.py Fri Feb 22 22:09:31 2008
@@ -1,9 +1,8 @@
from pypy.rpython.lltypesystem.llmemory import raw_malloc, raw_free
from pypy.rpython.lltypesystem.llmemory import raw_memcopy, raw_memclear
from pypy.rpython.lltypesystem.llmemory import NULL, raw_malloc_usage
-from pypy.rpython.memory.support import DEFAULT_CHUNK_SIZE
+from pypy.rpython.memory.support import DEFAULT_CHUNK_SIZE, RTTIPTR
from pypy.rpython.memory.support import get_address_stack, get_address_deque
-from pypy.rpython.memory.gcheader import GCHeaderBuilder
from pypy.rpython.lltypesystem import lltype, llmemory, llarena
from pypy.rlib.objectmodel import free_non_gc_object
from pypy.rlib.debug import ll_assert
@@ -14,7 +13,7 @@
import sys, os
TYPEID_MASK = 0xffff
-first_gcflag = 1 << 16
+first_gcflag = 1
GCFLAG_FORWARDED = first_gcflag
GCFLAG_IMMORTAL = first_gcflag << 1
GCFLAG_FINALIZATION_ORDERING = first_gcflag << 2
@@ -31,17 +30,21 @@
total_collection_time = 0.0
total_collection_count = 0
- HDR = lltype.Struct('header', ('tid', lltype.Signed))
- FORWARDSTUB = lltype.GcStruct('forwarding_stub',
- ('forw', llmemory.Address))
- FORWARDSTUBPTR = lltype.Ptr(FORWARDSTUB)
+ # header structure:
+ #
+ # * typeptr: normally a RTTIPTR, but if the object is forwarded,
+ # this is used to hold the forwarding address
+ # * flags: for GCFLAG_XXX
+ #
+ HDR = lltype.Struct('header', ('typeptr', llmemory.Address),
+ ('flags', lltype.Signed))
- def __init__(self, chunk_size=DEFAULT_CHUNK_SIZE, space_size=4096,
- max_space_size=sys.maxint//2+1):
+ def __init__(self, gcheaderbuilder, chunk_size=DEFAULT_CHUNK_SIZE,
+ space_size=4096, max_space_size=sys.maxint//2+1):
MovingGCBase.__init__(self)
+ self.gcheaderbuilder = gcheaderbuilder
self.space_size = space_size
self.max_space_size = max_space_size
- self.gcheaderbuilder = GCHeaderBuilder(self.HDR)
self.AddressStack = get_address_stack(chunk_size)
self.AddressDeque = get_address_deque(chunk_size)
self.finalizer_lock_count = 0
@@ -293,9 +296,10 @@
def copy(self, obj):
if self.is_forwarded(obj):
- #llop.debug_print(lltype.Void, obj, "already copied to", self.get_forwarding_address(obj))
+ # 'obj' already copied to 'self.get_forwarding_address(obj)'
return self.get_forwarding_address(obj)
else:
+ # copying 'obj' to 'newobj'
newaddr = self.free
objsize = self.get_size(obj)
totalsize = self.size_gc_header() + objsize
@@ -303,9 +307,6 @@
raw_memcopy(obj - self.size_gc_header(), newaddr, totalsize)
self.free += totalsize
newobj = newaddr + self.size_gc_header()
- #llop.debug_print(lltype.Void, obj, "copied to", newobj,
- # "tid", self.header(obj).tid,
- # "size", totalsize)
self.set_forwarding_address(obj, newobj, objsize)
return newobj
@@ -317,35 +318,26 @@
pointer.address[0] = self.copy(pointer.address[0])
def is_forwarded(self, obj):
- return self.header(obj).tid & GCFLAG_FORWARDED != 0
+ return self.header(obj).flags & GCFLAG_FORWARDED != 0
# note: all prebuilt objects also have this flag set
def get_forwarding_address(self, obj):
- tid = self.header(obj).tid
- if tid & GCFLAG_IMMORTAL:
+ hdr = self.header(obj)
+ flags = hdr.flags
+ ll_assert(flags & GCFLAG_FORWARDED != 0, "object not forwarded!")
+ if flags & GCFLAG_IMMORTAL:
return obj # prebuilt objects are "forwarded" to themselves
else:
- stub = llmemory.cast_adr_to_ptr(obj, self.FORWARDSTUBPTR)
- return stub.forw
+ return hdr.typeptr # holds the forwarding address
def set_forwarding_address(self, obj, newobj, objsize):
- # To mark an object as forwarded, we set the GCFLAG_FORWARDED and
- # overwrite the object with a FORWARDSTUB. Doing so is a bit
- # long-winded on llarena, but it all melts down to two memory
- # writes after translation to C.
- size_gc_header = self.size_gc_header()
- stubsize = llmemory.sizeof(self.FORWARDSTUB)
- tid = self.header(obj).tid
- ll_assert(tid & GCFLAG_IMMORTAL == 0, "unexpected GCFLAG_IMMORTAL")
- ll_assert(tid & GCFLAG_FORWARDED == 0, "unexpected GCFLAG_FORWARDED")
- # replace the object at 'obj' with a FORWARDSTUB.
- hdraddr = obj - size_gc_header
- llarena.arena_reset(hdraddr, size_gc_header + objsize, False)
- llarena.arena_reserve(hdraddr, size_gc_header + stubsize)
- hdr = llmemory.cast_adr_to_ptr(hdraddr, lltype.Ptr(self.HDR))
- hdr.tid = tid | GCFLAG_FORWARDED
- stub = llmemory.cast_adr_to_ptr(obj, self.FORWARDSTUBPTR)
- stub.forw = newobj
+ # To mark an object as forwarded, we set the GCFLAG_FORWARDED bit.
+ hdr = self.header(obj)
+ flags = hdr.flags
+ ll_assert(flags & GCFLAG_IMMORTAL == 0, "unexpected GCFLAG_IMMORTAL")
+ ll_assert(flags & GCFLAG_FORWARDED == 0, "unexpected GCFLAG_FORWARDED")
+ hdr.flags = flags | GCFLAG_FORWARDED
+ hdr.typeptr = newobj
def get_size(self, obj):
typeid = self.get_type_id(obj)
@@ -362,22 +354,22 @@
return llmemory.cast_adr_to_ptr(addr, lltype.Ptr(self.HDR))
def get_type_id(self, addr):
- tid = self.header(addr).tid
- ll_assert(tid & (GCFLAG_FORWARDED|GCFLAG_IMMORTAL) != GCFLAG_FORWARDED,
- "get_type_id on forwarded obj")
- # Non-prebuilt forwarded objects are overwritten with a FORWARDSTUB.
- # Although calling get_type_id() on a forwarded object works by itself,
- # we catch it as an error because it's likely that what is then
- # done with the typeid is bogus.
- return tid & TYPEID_MASK
+ hdr = self.header(addr)
+ # In non-prebuilt forwarded objects, the typeptr is used to hold
+ # the forwaring address. So far, we don't need to do get_type_id()
+ # on forwarded objects, so we just assert that nobody tries to.
+ ll_assert(hdr.flags & (GCFLAG_FORWARDED|GCFLAG_IMMORTAL)
+ != GCFLAG_FORWARDED, "get_type_id on forwarded obj")
+ return llmemory.cast_adr_to_ptr(hdr.typeptr, RTTIPTR)
def init_gc_object(self, addr, typeid, flags=0):
hdr = llmemory.cast_adr_to_ptr(addr, lltype.Ptr(self.HDR))
- hdr.tid = typeid | flags
+ hdr.typeptr = llmemory.cast_ptr_to_adr(typeid)
+ hdr.flags = flags
- def init_gc_object_immortal(self, addr, typeid, flags=0):
- hdr = llmemory.cast_adr_to_ptr(addr, lltype.Ptr(self.HDR))
- hdr.tid = typeid | flags | GCFLAG_IMMORTAL | GCFLAG_FORWARDED
+ def init_gc_object_immortal(self, hdr, typeid, flags=0):
+ hdr.typeptr = llmemory.cast_ptr_to_adr(typeid)
+ hdr.flags = flags | GCFLAG_IMMORTAL | GCFLAG_FORWARDED
# immortal objects always have GCFLAG_FORWARDED set;
# see get_forwarding_address().
@@ -442,13 +434,13 @@
if self.is_forwarded(obj):
newobj = self.get_forwarding_address(obj)
hdr = self.header(newobj)
- if hdr.tid & GCFLAG_FINALIZATION_ORDERING:
+ if hdr.flags & GCFLAG_FINALIZATION_ORDERING:
return 2
else:
return 3
else:
hdr = self.header(obj)
- if hdr.tid & GCFLAG_FINALIZATION_ORDERING:
+ if hdr.flags & GCFLAG_FINALIZATION_ORDERING:
return 1
else:
return 0
@@ -457,7 +449,7 @@
ll_assert(self._finalization_state(obj) == 0,
"unexpected finalization state != 0")
hdr = self.header(obj)
- hdr.tid |= GCFLAG_FINALIZATION_ORDERING
+ hdr.flags |= GCFLAG_FINALIZATION_ORDERING
def _recursively_bump_finalization_state_from_2_to_3(self, obj):
ll_assert(self._finalization_state(obj) == 2,
@@ -469,8 +461,8 @@
while pending.non_empty():
y = pending.pop()
hdr = self.header(y)
- if hdr.tid & GCFLAG_FINALIZATION_ORDERING: # state 2 ?
- hdr.tid &= ~GCFLAG_FINALIZATION_ORDERING # change to state 3
+ if hdr.flags & GCFLAG_FINALIZATION_ORDERING: # state 2 ?
+ hdr.flags &= ~GCFLAG_FINALIZATION_ORDERING # change to state 3
self.trace(y, self._append_if_nonnull, pending)
def _recursively_bump_finalization_state_from_1_to_2(self, obj, scan):
Modified: pypy/branch/unified-rtti/pypy/rpython/memory/gctransform/boehm.py
==============================================================================
--- pypy/branch/unified-rtti/pypy/rpython/memory/gctransform/boehm.py (original)
+++ pypy/branch/unified-rtti/pypy/rpython/memory/gctransform/boehm.py Fri Feb 22 22:09:31 2008
@@ -16,7 +16,6 @@
def __init__(self, translator, inline=False):
super(BoehmGCTransformer, self).__init__(translator, inline=inline)
- self.newgcheaderbuilder(self.HDR, self.TYPEINFO)
self.finalizer_funcptrs = {}
atomic_mh = mallocHelpers()
Modified: pypy/branch/unified-rtti/pypy/rpython/memory/gctransform/framework.py
==============================================================================
--- pypy/branch/unified-rtti/pypy/rpython/memory/gctransform/framework.py (original)
+++ pypy/branch/unified-rtti/pypy/rpython/memory/gctransform/framework.py Fri Feb 22 22:09:31 2008
@@ -95,9 +95,10 @@
use_stackless = False
root_stack_depth = 163840
+ TYPEINFO = gctypelayout.GCData.TYPE_INFO
+
def __init__(self, translator):
from pypy.rpython.memory.gc.base import choose_gc_from_config
- super(FrameworkGCTransformer, self).__init__(translator, inline=True)
if hasattr(self, 'GC_PARAMS'):
# for tests: the GC choice can be specified as class attributes
from pypy.rpython.memory.gc.marksweep import MarkSweepGC
@@ -107,13 +108,14 @@
# for regular translation: pick the GC from the config
GCClass, GC_PARAMS = choose_gc_from_config(translator.config)
- gc = GCClass(**GC_PARAMS)
- self.setgcheaderbuilder(gc.gcheaderbuilder)
+ self.HDR = GCClass.HDR
+ super(FrameworkGCTransformer, self).__init__(translator, inline=True)
+
self.layoutbuilder = TransformerLayoutBuilder(self)
self.get_type_id = self.layoutbuilder.get_type_id
gcdata = gctypelayout.GCData(self.gcheaderbuilder)
- gcdata.gc = gc
+ gcdata.gc = GCClass(self.gcheaderbuilder, **GC_PARAMS)
# initialize the following two fields with a random non-NULL address,
# to make the annotator happy. The fields are patched in finish()
Modified: pypy/branch/unified-rtti/pypy/rpython/memory/gctransform/refcounting.py
==============================================================================
--- pypy/branch/unified-rtti/pypy/rpython/memory/gctransform/refcounting.py (original)
+++ pypy/branch/unified-rtti/pypy/rpython/memory/gctransform/refcounting.py Fri Feb 22 22:09:31 2008
@@ -48,7 +48,6 @@
# create incref, etc graph
- self.newgcheaderbuilder(self.HDR, self.TYPEINFO)
gchelpers = self.gchelpers
gc_header_offset = gchelpers.gc_header_offset
HDRPTR = lltype.Ptr(self.HDR)
Modified: pypy/branch/unified-rtti/pypy/rpython/memory/gctransform/transform.py
==============================================================================
--- pypy/branch/unified-rtti/pypy/rpython/memory/gctransform/transform.py (original)
+++ pypy/branch/unified-rtti/pypy/rpython/memory/gctransform/transform.py Fri Feb 22 22:09:31 2008
@@ -13,6 +13,7 @@
from pypy.annotation import model as annmodel
from pypy.rpython import rmodel, annlowlevel
from pypy.rpython.memory import gc
+from pypy.rpython.memory.gcheader import GCHeaderBuilder
from pypy.rpython.memory.gctransform.support import var_ispyobj
from pypy.rpython.annlowlevel import MixLevelHelperAnnotator
from pypy.rpython.rtyper import LowLevelOpList
@@ -526,14 +527,10 @@
self.stack_malloc_fixedsize_ptr = self.inittime_helper(
ll_stack_malloc_fixedsize, [lltype.Signed], llmemory.Address)
- def newgcheaderbuilder(self, HDR, TYPEINFO):
- from pypy.rpython.memory.gcheader import GCHeaderBuilder
- self.setgcheaderbuilder(GCHeaderBuilder(HDR, TYPEINFO))
-
- def setgcheaderbuilder(self, gcheaderbuilder):
- # at the moment, all GC transformers are based on a GCHeaderBuilder.
- self.gcheaderbuilder = gcheaderbuilder
- self.gchelpers = GCHelpers(gcheaderbuilder)
+ # at the moment, all GC transformers are based on a GCHeaderBuilder
+ # built from self.HDR and self.TYPEINFO.
+ self.gcheaderbuilder = GCHeaderBuilder(self.HDR, self.TYPEINFO)
+ self.gchelpers = GCHelpers(self.gcheaderbuilder)
if self.translator:
self.gc_runtime_type_info_ptr = self.inittime_helper(
self.gchelpers.gc_runtime_type_info, [llmemory.Address],
Modified: pypy/branch/unified-rtti/pypy/rpython/memory/gcwrapper.py
==============================================================================
--- pypy/branch/unified-rtti/pypy/rpython/memory/gcwrapper.py (original)
+++ pypy/branch/unified-rtti/pypy/rpython/memory/gcwrapper.py Fri Feb 22 22:09:31 2008
@@ -2,20 +2,23 @@
from pypy.rpython import llinterp
from pypy.rpython.annlowlevel import llhelper
from pypy.rpython.memory import gctypelayout
+from pypy.rpython.memory.gcheader import GCHeaderBuilder
from pypy.objspace.flow.model import Constant
class GCManagedHeap(object):
def __init__(self, llinterp, flowgraphs, gc_class, GC_PARAMS={}):
- self.gc = gc_class(chunk_size = 10, **GC_PARAMS)
+ TYPEINFO = gctypelayout.GCData.TYPE_INFO
+ self.gcheaderbuilder = GCHeaderBuilder(gc_class.HDR, TYPEINFO)
+ self.gc = gc_class(self.gcheaderbuilder, chunk_size = 10, **GC_PARAMS)
self.gc.set_root_walker(LLInterpRootWalker(self))
self.llinterp = llinterp
self.prepare_graphs(flowgraphs)
self.gc.setup()
def prepare_graphs(self, flowgraphs):
- layoutbuilder = DirectRunLayoutBuilder(self.gc.gcheaderbuilder,
+ layoutbuilder = DirectRunLayoutBuilder(self.gcheaderbuilder,
self.llinterp)
self.get_type_id = layoutbuilder.get_type_id
layoutbuilder.initialize_gc_query_function(self.gc)
Modified: pypy/branch/unified-rtti/pypy/rpython/memory/lltypelayout.py
==============================================================================
--- pypy/branch/unified-rtti/pypy/rpython/memory/lltypelayout.py (original)
+++ pypy/branch/unified-rtti/pypy/rpython/memory/lltypelayout.py Fri Feb 22 22:09:31 2008
@@ -30,7 +30,7 @@
for name in TYPE._names:
layout[name] = curr
curr += get_fixed_size(TYPE._flds[name])
- layout["_size"] = curr
+ layout["_size"] = curr or 1 # sizeof(empty struct) == 1, as in C
return layout
elif isinstance(TYPE, lltype.Array):
return (get_fixed_size(lltype.Signed), get_fixed_size(TYPE.OF))
Modified: pypy/branch/unified-rtti/pypy/rpython/memory/test/test_gc.py
==============================================================================
--- pypy/branch/unified-rtti/pypy/rpython/memory/test/test_gc.py (original)
+++ pypy/branch/unified-rtti/pypy/rpython/memory/test/test_gc.py Fri Feb 22 22:09:31 2008
@@ -43,6 +43,22 @@
res = ''.join(res.chars)
return res
+ def test_empty_class(self):
+ class A(object):
+ pass
+ def func():
+ a1 = A()
+ a2 = A()
+ a3 = A()
+ assert a1 is not a2
+ assert a1 is not a3
+ assert a2 is not a3
+ llop.gc__collect(lltype.Void)
+ assert a1 is not a2
+ assert a1 is not a3
+ assert a2 is not a3
+ self.interpret(func, [])
+
def test_llinterp_lists(self):
#curr = simulator.current_size
def malloc_a_lot():
More information about the Pypy-commit
mailing list