[pypy-svn] r51641 - in pypy/branch/no-forw-ptr/pypy: rpython/lltypesystem rpython/memory/gc rpython/memory/gctransform rpython/memory/test translator/llvm/test

arigo at codespeak.net arigo at codespeak.net
Tue Feb 19 17:23:50 CET 2008


Author: arigo
Date: Tue Feb 19 17:23:49 2008
New Revision: 51641

Modified:
   pypy/branch/no-forw-ptr/pypy/rpython/lltypesystem/lloperation.py
   pypy/branch/no-forw-ptr/pypy/rpython/memory/gc/base.py
   pypy/branch/no-forw-ptr/pypy/rpython/memory/gc/generation.py
   pypy/branch/no-forw-ptr/pypy/rpython/memory/gc/marksweep.py
   pypy/branch/no-forw-ptr/pypy/rpython/memory/gctransform/framework.py
   pypy/branch/no-forw-ptr/pypy/rpython/memory/test/test_transformed_gc.py
   pypy/branch/no-forw-ptr/pypy/translator/llvm/test/test_newgc.py
Log:
Merge trunk into branch, r51622:51634.


Modified: pypy/branch/no-forw-ptr/pypy/rpython/lltypesystem/lloperation.py
==============================================================================
--- pypy/branch/no-forw-ptr/pypy/rpython/lltypesystem/lloperation.py	(original)
+++ pypy/branch/no-forw-ptr/pypy/rpython/lltypesystem/lloperation.py	Tue Feb 19 17:23:49 2008
@@ -403,10 +403,6 @@
     'gc_x_clone':           LLOp(canraise=(MemoryError, RuntimeError),
                                  canunwindgc=True),
     'gc_x_size_header':     LLOp(),
-    # this one is even more experimental; only implemented with the
-    # Mark&Sweep GC, and likely only useful when combined with
-    # stackless:
-    'gc_x_become':          LLOp(canraise=(RuntimeError,), canunwindgc=True),
 
     # for llvm.gcroot() support.  can change at any time
     'llvm_frameaddress':    LLOp(sideeffects=False),

Modified: pypy/branch/no-forw-ptr/pypy/rpython/memory/gc/base.py
==============================================================================
--- pypy/branch/no-forw-ptr/pypy/rpython/memory/gc/base.py	(original)
+++ pypy/branch/no-forw-ptr/pypy/rpython/memory/gc/base.py	Tue Feb 19 17:23:49 2008
@@ -111,9 +111,6 @@
     def x_clone(self, clonedata):
         raise RuntimeError("no support for x_clone in the GC")
 
-    def x_become(self, target_addr, source_addr):
-        raise RuntimeError("no support for x_become in the GC")
-
     def trace(self, obj, callback, arg):
         """Enumerate the locations inside the given obj that can contain
         GC pointers.  For each such location, callback(pointer, arg) is

Modified: pypy/branch/no-forw-ptr/pypy/rpython/memory/gc/generation.py
==============================================================================
--- pypy/branch/no-forw-ptr/pypy/rpython/memory/gc/generation.py	(original)
+++ pypy/branch/no-forw-ptr/pypy/rpython/memory/gc/generation.py	Tue Feb 19 17:23:49 2008
@@ -11,11 +11,11 @@
 # in the nursery.  It is initially set on all prebuilt and old objects,
 # and gets cleared by the write_barrier() when we write in them a
 # pointer to a young object.
-GCFLAG_NO_YOUNG_PTRS = SemiSpaceGC.first_unused_gcflag << 1
+GCFLAG_NO_YOUNG_PTRS = SemiSpaceGC.first_unused_gcflag << 0
 
 # The following flag is set for static roots which are not on the list
 # of static roots yet, but will appear with write barrier
-GCFLAG_NO_HEAP_PTRS = SemiSpaceGC.first_unused_gcflag << 2
+GCFLAG_NO_HEAP_PTRS = SemiSpaceGC.first_unused_gcflag << 1
 
 DEBUG_PRINT = False
 
@@ -29,7 +29,7 @@
     inline_simple_malloc_varsize = True
     needs_write_barrier = True
     prebuilt_gc_objects_are_static_roots = False
-    first_unused_gcflag = SemiSpaceGC.first_unused_gcflag << 3
+    first_unused_gcflag = SemiSpaceGC.first_unused_gcflag << 2
 
     def __init__(self, chunk_size=DEFAULT_CHUNK_SIZE,
                  nursery_size=128,

Modified: pypy/branch/no-forw-ptr/pypy/rpython/memory/gc/marksweep.py
==============================================================================
--- pypy/branch/no-forw-ptr/pypy/rpython/memory/gc/marksweep.py	(original)
+++ pypy/branch/no-forw-ptr/pypy/rpython/memory/gc/marksweep.py	Tue Feb 19 17:23:49 2008
@@ -673,176 +673,6 @@
         # reinstall the pool that was current at the beginning of x_clone()
         clonedata.pool = self.x_swap_pool(curpool)
 
-    def add_reachable_to_stack2(self, obj, objects):
-        size_gc_header = self.gcheaderbuilder.size_gc_header
-        gc_info = obj - size_gc_header
-        hdr = llmemory.cast_adr_to_ptr(gc_info, self.HDRPTR)
-        if hdr.typeid & 1:
-            return
-        self.trace(obj, self._add_reachable_and_rename, objects)
-
-    def _add_reachable_and_rename(self, pointer, objects):
-        obj = pointer.address[0]
-        if obj:
-            if obj == self.x_become_target_addr:
-                obj = pointer.address[0] = self.x_become_source_addr
-            objects.append(obj)
-
-    def x_become(self, target_addr, source_addr):
-        # 1. mark from the roots, and also the objects that objects-with-del
-        #    point to (using the list of malloced_objects_with_finalizer)
-        # 2. walk the list of objects-without-del and free the ones not marked
-        # 3. walk the list of objects-with-del and for the ones not marked:
-        #    call __del__, move the object to the list of object-without-del
-        import time
-        from pypy.rpython.lltypesystem.lloperation import llop
-        if DEBUG_PRINT:
-            llop.debug_print(lltype.Void, 'collecting...')
-        start_time = time.time()
-        size_gc_header = self.gcheaderbuilder.size_gc_header
-##        llop.debug_view(lltype.Void, self.malloced_objects, self.poolnodes,
-##                        size_gc_header)
-
-        # push the roots on the mark stack
-        objects = self.AddressStack() # mark stack
-        self._mark_stack = objects
-        # the last sweep did not clear the mark bit of static roots, 
-        # since they are not in the malloced_objects list
-        self.root_walker.walk_roots(
-            MarkSweepGC._mark_root_and_clear_bit,  # stack roots
-            MarkSweepGC._mark_root_and_clear_bit,  # static in prebuilt non-gc
-            MarkSweepGC._mark_root_and_clear_bit)  # static in prebuilt gc
-
-        # from this point onwards, no more mallocs should be possible
-        old_malloced = self.bytes_malloced
-        self.bytes_malloced = 0
-        curr_heap_size = 0
-        freed_size = 0
-
-        self.x_become_target_addr = target_addr
-        self.x_become_source_addr = source_addr
-
-        # mark objects reachable by objects with a finalizer, but not those
-        # themselves. add their size to curr_heap_size, since they always
-        # survive the collection
-        hdr = self.malloced_objects_with_finalizer
-        while hdr:
-            next = hdr.next
-            typeid = hdr.typeid >> 1
-            gc_info = llmemory.cast_ptr_to_adr(hdr)
-            obj = gc_info + size_gc_header
-            self.add_reachable_to_stack2(obj, objects)
-            addr = llmemory.cast_ptr_to_adr(hdr)
-            size = self.fixed_size(typeid)
-            if self.is_varsize(typeid):
-                length = (obj + self.varsize_offset_to_length(typeid)).signed[0]
-                size += self.varsize_item_sizes(typeid) * length
-            estimate = raw_malloc_usage(size_gc_header + size)
-            curr_heap_size += estimate
-            hdr = next
-
-        # mark thinks on the mark stack and put their descendants onto the
-        # stack until the stack is empty
-        while objects.non_empty():  #mark
-            curr = objects.pop()
-            self.add_reachable_to_stack2(curr, objects)
-            gc_info = curr - size_gc_header
-            hdr = llmemory.cast_adr_to_ptr(gc_info, self.HDRPTR)
-            if hdr.typeid & 1:
-                continue
-            hdr.typeid = hdr.typeid | 1
-        objects.delete()
-        # also mark self.curpool
-        if self.curpool:
-            gc_info = llmemory.cast_ptr_to_adr(self.curpool) - size_gc_header
-            hdr = llmemory.cast_adr_to_ptr(gc_info, self.HDRPTR)
-            hdr.typeid = hdr.typeid | 1
-
-        # sweep: delete objects without del if they are not marked
-        # unmark objects without del that are marked
-        firstpoolnode = lltype.malloc(self.POOLNODE, flavor='raw')
-        firstpoolnode.linkedlist = self.malloced_objects
-        firstpoolnode.nextnode = self.poolnodes
-        prevpoolnode = lltype.nullptr(self.POOLNODE)
-        poolnode = firstpoolnode
-        while poolnode:   #sweep
-            ppnext = llmemory.cast_ptr_to_adr(poolnode)
-            ppnext += llmemory.offsetof(self.POOLNODE, 'linkedlist')
-            hdr = poolnode.linkedlist
-            while hdr:  #sweep
-                typeid = hdr.typeid >> 1
-                next = hdr.next
-                addr = llmemory.cast_ptr_to_adr(hdr)
-                size = self.fixed_size(typeid)
-                if self.is_varsize(typeid):
-                    length = (addr + size_gc_header + self.varsize_offset_to_length(typeid)).signed[0]
-                    size += self.varsize_item_sizes(typeid) * length
-                estimate = raw_malloc_usage(size_gc_header + size)
-                if hdr.typeid & 1:
-                    hdr.typeid = hdr.typeid & (~1)
-                    ppnext.address[0] = addr
-                    ppnext = llmemory.cast_ptr_to_adr(hdr)
-                    ppnext += llmemory.offsetof(self.HDR, 'next')
-                    curr_heap_size += estimate
-                else:
-                    freed_size += estimate
-                    raw_free(addr)
-                hdr = next
-            ppnext.address[0] = llmemory.NULL
-            next = poolnode.nextnode
-            if not poolnode.linkedlist and prevpoolnode:
-                # completely empty node
-                prevpoolnode.nextnode = next
-                lltype.free(poolnode, flavor='raw')
-            else:
-                prevpoolnode = poolnode
-            poolnode = next
-        self.malloced_objects = firstpoolnode.linkedlist
-        self.poolnodes = firstpoolnode.nextnode
-        lltype.free(firstpoolnode, flavor='raw')
-
-        if curr_heap_size > self.bytes_malloced_threshold:
-            self.bytes_malloced_threshold = curr_heap_size
-        end_time = time.time()
-        self.total_collection_time += end_time - start_time
-        if DEBUG_PRINT:
-            llop.debug_print(lltype.Void,
-                             "  malloced since previous collection:",
-                             old_malloced, "bytes")
-            llop.debug_print(lltype.Void,
-                             "  heap usage at start of collection: ",
-                             self.heap_usage + old_malloced, "bytes")
-            llop.debug_print(lltype.Void,
-                             "  freed:                             ",
-                             freed_size, "bytes")
-            llop.debug_print(lltype.Void,
-                             "  new heap usage:                    ",
-                             curr_heap_size, "bytes")
-            llop.debug_print(lltype.Void,
-                             "  total time spent collecting:       ",
-                             self.total_collection_time, "seconds")
-##        llop.debug_view(lltype.Void, self.malloced_objects, self.poolnodes,
-##                        size_gc_header)
-        assert self.heap_usage + old_malloced == curr_heap_size + freed_size
-
-        # call finalizers if needed
-        self.heap_usage = curr_heap_size
-        hdr = self.malloced_objects_with_finalizer
-        self.malloced_objects_with_finalizer = lltype.nullptr(self.HDR)
-        while hdr:
-            next = hdr.next
-            if hdr.typeid & 1:
-                hdr.next = self.malloced_objects_with_finalizer
-                self.malloced_objects_with_finalizer = hdr
-                hdr.typeid = hdr.typeid & (~1)
-            else:
-                obj = llmemory.cast_ptr_to_adr(hdr) + size_gc_header
-                finalizer = self.getfinalizer(hdr.typeid >> 1)
-                finalizer(obj)
-                hdr.next = self.malloced_objects
-                self.malloced_objects = hdr
-            hdr = next
-
 
 class PrintingMarkSweepGC(MarkSweepGC):
     _alloc_flavor_ = "raw"

Modified: pypy/branch/no-forw-ptr/pypy/rpython/memory/gctransform/framework.py
==============================================================================
--- pypy/branch/no-forw-ptr/pypy/rpython/memory/gctransform/framework.py	(original)
+++ pypy/branch/no-forw-ptr/pypy/rpython/memory/gctransform/framework.py	Tue Feb 19 17:23:49 2008
@@ -23,7 +23,7 @@
 
 class CollectAnalyzer(graphanalyze.GraphAnalyzer):
     def operation_is_true(self, op):
-        if op.opname in ('gc__collect', 'gc_x_become'):
+        if op.opname == 'gc__collect':
             return True
         if op.opname in ('malloc', 'malloc_varsize'):
             flags = op.args[1].value
@@ -316,11 +316,6 @@
                                  annmodel.s_None,
                                  minimal_transform = False)
 
-        self.x_become_ptr = getfn(
-            GCClass.x_become.im_func,
-            [s_gc, annmodel.SomeAddress(), annmodel.SomeAddress()],
-            annmodel.s_None)
-
         annhelper.finish()   # at this point, annotate all mix-level helpers
         annhelper.backend_optimize()
 
@@ -549,15 +544,6 @@
                   [c_result],
                   resultvar=op.result)
 
-    def gct_gc_x_become(self, hop):
-        op = hop.spaceop
-        [v_target, v_source] = op.args
-        livevars = self.push_roots(hop)
-        hop.genop("direct_call",
-                  [self.x_become_ptr, self.c_const_gc, v_target, v_source],
-                  resultvar=op.result)
-        self.pop_roots(hop, livevars)
-
     def gct_zero_gc_pointers_inside(self, hop):
         if self.needs_zero_gc_pointers:
             v_ob = hop.spaceop.args[0]

Modified: pypy/branch/no-forw-ptr/pypy/rpython/memory/test/test_transformed_gc.py
==============================================================================
--- pypy/branch/no-forw-ptr/pypy/rpython/memory/test/test_transformed_gc.py	(original)
+++ pypy/branch/no-forw-ptr/pypy/rpython/memory/test/test_transformed_gc.py	Tue Feb 19 17:23:49 2008
@@ -729,26 +729,6 @@
     def test_instances(self):
         py.test.skip("fails for a stupid reasons")
 
-    def test_x_become(self):
-        from pypy.rlib import objectmodel
-        S = lltype.GcStruct("S", ('x', lltype.Signed))
-        def f():
-            x = lltype.malloc(S)
-            x.x = 10
-            y = lltype.malloc(S)
-            y.x = 20
-            z = x
-            llop.gc_x_become(lltype.Void,
-                             llmemory.cast_ptr_to_adr(x),
-                             llmemory.cast_ptr_to_adr(y))
-            # keep 'y' alive until the x_become() is finished, because in
-            # theory it could go away as soon as only its address is present
-            objectmodel.keepalive_until_here(y)
-            return z.x
-        run = self.runner(f)
-        res = run([])
-        assert res == 20
-
 
 class TestPrintingGC(GenericGCTests):
     gcname = "statistics"

Modified: pypy/branch/no-forw-ptr/pypy/translator/llvm/test/test_newgc.py
==============================================================================
--- pypy/branch/no-forw-ptr/pypy/translator/llvm/test/test_newgc.py	(original)
+++ pypy/branch/no-forw-ptr/pypy/translator/llvm/test/test_newgc.py	Tue Feb 19 17:23:49 2008
@@ -5,7 +5,7 @@
 from pypy.rpython.lltypesystem import lltype, llmemory, llarena
 
 def test_gc_offsets():
-    STRUCT = lltype.GcStruct('S1', ('x', lltype.Signed))
+    STRUCT = lltype.GcStruct('S1', ('x', lltype.Signed), ('y', lltype.Char))
     ARRAY = lltype.GcArray(lltype.Signed)
     s1 = llarena.round_up_for_allocation(llmemory.sizeof(STRUCT))
     s2 = llmemory.offsetof(STRUCT, 'x')
@@ -25,10 +25,10 @@
     i3 = (res // 10000) % 100
     i4 = (res // 100) % 100
     i5 = (res // 1) % 100
-    assert i1 % 8 == 0
+    assert i1 % 4 == 0
     assert 12 <= i1 <= 24
     assert 8 <= i2 <= i1 - 4
-    assert 8 <= i3 <= 16
+    assert 4 <= i3 <= 12
     assert i4 == i5
     assert i3 + 4 <= i5
 



More information about the Pypy-commit mailing list