[pypy-svn] r70950 - in pypy/branch/gc-huge-list/pypy/rpython/memory/gc: . test
arigo at codespeak.net
arigo at codespeak.net
Thu Jan 28 14:35:30 CET 2010
Author: arigo
Date: Thu Jan 28 14:35:29 2010
New Revision: 70950
Modified:
pypy/branch/gc-huge-list/pypy/rpython/memory/gc/generation.py
pypy/branch/gc-huge-list/pypy/rpython/memory/gc/hybrid.py
pypy/branch/gc-huge-list/pypy/rpython/memory/gc/test/test_direct.py
Log:
(arigo, fijal)
Finish and cleanup implementation of writebarrier_before_copy.
Implement assume_young_pointers
Modified: pypy/branch/gc-huge-list/pypy/rpython/memory/gc/generation.py
==============================================================================
--- pypy/branch/gc-huge-list/pypy/rpython/memory/gc/generation.py (original)
+++ pypy/branch/gc-huge-list/pypy/rpython/memory/gc/generation.py Thu Jan 28 14:35:29 2010
@@ -476,12 +476,15 @@
objhdr.tid &= ~GCFLAG_NO_HEAP_PTRS
self.last_generation_root_objects.append(addr_struct)
- def assume_young_pointers(self, addr_struct):
- # XXX fix for hybrid
+ def _assume_young_pointers(self, addr_struct):
objhdr = self.header(addr_struct)
if objhdr.tid & GCFLAG_NO_YOUNG_PTRS:
self.old_objects_pointing_to_young.append(addr_struct)
objhdr.tid &= ~GCFLAG_NO_YOUNG_PTRS
+
+ def assume_young_pointers(self, addr_struct):
+ self._assume_young_pointers(addr_struct)
+ objhdr = self.header(addr_struct)
if objhdr.tid & GCFLAG_NO_HEAP_PTRS:
objhdr.tid &= ~GCFLAG_NO_HEAP_PTRS
self.last_generation_root_objects.append(addr_struct)
Modified: pypy/branch/gc-huge-list/pypy/rpython/memory/gc/hybrid.py
==============================================================================
--- pypy/branch/gc-huge-list/pypy/rpython/memory/gc/hybrid.py (original)
+++ pypy/branch/gc-huge-list/pypy/rpython/memory/gc/hybrid.py Thu Jan 28 14:35:29 2010
@@ -573,19 +573,23 @@
if hdr.tid & GCFLAG_CARDMARKS:
# Mark the correct card, don't clear GCFLAG_NO_YOUNG_PTRS flag.
# Note that 'offset' does not include the size_gc_header.
- size_gc_header = self.gcheaderbuilder.size_gc_header
num = raw_malloc_usage(offset) / self.card_size
- addr = (addr_struct - size_gc_header + llarena.negative_byte_index(num>>3))
- flag = 1 << (num&7)
- value = ord(addr.char[0])
- if value & flag == 0:
- addr.char[0] = chr(value | flag)
- if hdr.tid & GCFLAG_CARDMARK_SET == 0:
- hdr.tid |= GCFLAG_CARDMARK_SET
- self.old_objects_pointing_to_young.append(addr_struct)
+ self.set_card_mark(addr_struct, num)
else:
GenerationGC.remember_pointer_to_nursery(self, addr_struct, offset)
+ def set_card_mark(self, addr_struct, num):
+ size_gc_header = self.gcheaderbuilder.size_gc_header
+ addr = (addr_struct - size_gc_header + llarena.negative_byte_index(num>>3))
+ flag = 1 << (num&7)
+ value = ord(addr.char[0])
+ if value & flag == 0:
+ addr.char[0] = chr(value | flag)
+ hdr = self.header(addr_struct)
+ if hdr.tid & GCFLAG_CARDMARK_SET == 0:
+ hdr.tid |= GCFLAG_CARDMARK_SET
+ self.old_objects_pointing_to_young.append(addr_struct)
+
def reset_young_gcflags(self):
oldlist = self.old_objects_pointing_to_young
while oldlist.non_empty():
@@ -676,43 +680,40 @@
i += 1
def mark_cards(self, addr, start, length):
- size_gc_header = self.gcheaderbuilder.size_gc_header
- hdr = self.header(addr)
- hdr.tid |= GCFLAG_CARDMARK_SET
typeid = self.get_type_id(addr)
itemsize = self.varsize_item_sizes(typeid)
offset = self.varsize_offset_to_variable_part(typeid) + itemsize * start
first_card = raw_malloc_usage(offset) / self.card_size
offset += itemsize * length
- last_card = raw_malloc_usage(offset) / self.card_size
- i = first_card >> 3
- while i <= last_card >> 3:
- card_adr = addr - size_gc_header + llarena.negative_byte_index(i)
- card_adr.char[0] = chr(0xff)
+ last_card = (raw_malloc_usage(offset) - 1) / self.card_size
+ i = first_card
+ while i <= last_card:
+ self.set_card_mark(addr, i)
i += 1
+ def _assume_young_pointers(self, addr):
+ hdr = self.header(addr)
+ if hdr.tid & GCFLAG_CARDMARKS:
+ typeid = self.get_type_id(addr)
+ offset_to_length = self.varsize_offset_to_length(typeid)
+ self.mark_cards(addr, 0, (addr + offset_to_length).signed[0])
+ else:
+ GenerationGC._assume_young_pointers(self, addr)
+
def _writebarrier_before_copy(self, source_addr, dest_addr, source_start,
dest_start, length):
- """ A hook for hybrid gc
- """
source_hdr = self.header(source_addr)
+ if (source_hdr.tid & (GCFLAG_NO_YOUNG_PTRS & GCFLAG_CARDMARK_SET) ==
+ GCFLAG_NO_YOUNG_PTRS):
+ return # the source object has no young pointer at all
dest_hdr = self.header(dest_addr)
- if source_hdr.tid & GCFLAG_NO_YOUNG_PTRS == 0:
- if dest_hdr.tid & GCFLAG_CARDMARKS:
- # we copy from small -> larg list, set all cards up
- self.mark_cards(dest_addr, dest_start, length)
- return
- if source_hdr.tid & GCFLAG_CARDMARK_SET:
- if dest_hdr.tid & GCFLAG_CARDMARKS:
- # large -> large, copy cardmarks.
- # XXX for now just set all cards within range
- # that's why we need source_start, possibly
- self.mark_cards(dest_addr, dest_start, length)
- return
- # large -> small
- # there might be an object in source that is in nursery
- self.old_objects_pointing_to_young.append(dest_addr)
- dest_hdr.tid &= ~GCFLAG_NO_YOUNG_PTRS
+ if dest_hdr.tid & GCFLAG_CARDMARKS:
+ # we copy into a large object with card marks:
+ # mark all cards that have been overwritten
+ self.mark_cards(dest_addr, dest_start, length)
+ else:
+ self.old_objects_pointing_to_young.append(dest_addr)
+ dest_hdr.tid &= ~GCFLAG_NO_YOUNG_PTRS
def debug_check_object_no_nursery_pointer(self, obj):
tid = self.header(obj).tid
Modified: pypy/branch/gc-huge-list/pypy/rpython/memory/gc/test/test_direct.py
==============================================================================
--- pypy/branch/gc-huge-list/pypy/rpython/memory/gc/test/test_direct.py (original)
+++ pypy/branch/gc-huge-list/pypy/rpython/memory/gc/test/test_direct.py Thu Jan 28 14:35:29 2010
@@ -472,9 +472,10 @@
assert gc.header(addr1).tid & GCFLAG_CARDMARK_SET
assert gc.header(addr2).tid & GCFLAG_CARDMARK_SET == 0
gc.writebarrier_before_copy(addr1, addr2, 0, 0, 48)
- for i in range(3):
+ for i in range(2):
addr = addr2 - size_gc_header + llarena.negative_byte_index(i)
assert addr.char[0] == '\xff', i
+ assert (addr2 - size_gc_header + llarena.negative_byte_index(2)).char[0] == '\x01'
objs = []
def callback(obj, arg):
@@ -485,6 +486,20 @@
obj2[0] = p
gc.foreach_marked_card(addr2, callback, None)
assert objs == [addrp]
+
+ def test_assume_young_pointers_cardmarking(self):
+ from pypy.rpython.lltypesystem import llarena
+
+ gc = self.gc
+ size_gc_header = gc.gcheaderbuilder.size_gc_header
+ typeid = self.get_type_id(VAR)
+ addr1 = llmemory.cast_ptr_to_adr(gc.malloc_varsize_slowpath(typeid, 48))
+ obj = llmemory.cast_adr_to_ptr(addr1, lltype.Ptr(VAR))
+ gc.assume_young_pointers(addr1)
+ for i in range(2):
+ addr = addr1 - size_gc_header + llarena.negative_byte_index(i)
+ assert addr.char[0] == '\xff', i
+ assert (addr1 - size_gc_header + llarena.negative_byte_index(2)).char[0] == '\x01'
class TestMarkCompactGC(DirectGCTest):
from pypy.rpython.memory.gc.markcompact import MarkCompactGC as GCClass
More information about the Pypy-commit
mailing list