[pypy-svn] r77209 - in pypy/branch/smaller-writebarrier/pypy/rpython/memory/gc: . test
arigo at codespeak.net
arigo at codespeak.net
Mon Sep 20 17:40:04 CEST 2010
Author: arigo
Date: Mon Sep 20 17:40:01 2010
New Revision: 77209
Modified:
pypy/branch/smaller-writebarrier/pypy/rpython/memory/gc/generation.py
pypy/branch/smaller-writebarrier/pypy/rpython/memory/gc/minimark.py
pypy/branch/smaller-writebarrier/pypy/rpython/memory/gc/test/test_direct.py
Log:
Reduce the arity and complexity of remember_young_pointer() methods.
Modified: pypy/branch/smaller-writebarrier/pypy/rpython/memory/gc/generation.py
==============================================================================
--- pypy/branch/smaller-writebarrier/pypy/rpython/memory/gc/generation.py (original)
+++ pypy/branch/smaller-writebarrier/pypy/rpython/memory/gc/generation.py Mon Sep 20 17:40:01 2010
@@ -321,7 +321,7 @@
addr = pointer.address[0]
newaddr = self.copy(addr)
pointer.address[0] = newaddr
- self.write_into_last_generation_obj(obj, newaddr)
+ self.write_into_last_generation_obj(obj)
# ____________________________________________________________
# Implementation of nursery-only collections
@@ -452,11 +452,12 @@
# "if addr_struct.int0 & JIT_WB_IF_FLAG: remember_young_pointer()")
JIT_WB_IF_FLAG = GCFLAG_NO_YOUNG_PTRS
- def write_barrier(self, newvalue, addr_struct):
+ def write_barrier(self, addr_struct):
if self.header(addr_struct).tid & GCFLAG_NO_YOUNG_PTRS:
- self.remember_young_pointer(addr_struct, newvalue)
+ self.remember_young_pointer(addr_struct)
def _setup_wb(self):
+ DEBUG = self.DEBUG
# The purpose of attaching remember_young_pointer to the instance
# instead of keeping it as a regular method is to help the JIT call it.
# Additionally, it makes the code in write_barrier() marginally smaller
@@ -464,33 +465,24 @@
# For x86, there is also an extra requirement: when the JIT calls
# remember_young_pointer(), it assumes that it will not touch the SSE
# registers, so it does not save and restore them (that's a *hack*!).
- def remember_young_pointer(addr_struct, addr):
+ def remember_young_pointer(addr_struct):
#llop.debug_print(lltype.Void, "\tremember_young_pointer",
# addr_struct, "<-", addr)
- ll_assert(not self.is_in_nursery(addr_struct),
- "nursery object with GCFLAG_NO_YOUNG_PTRS")
- # if we have tagged pointers around, we first need to check whether
- # we have valid pointer here, otherwise we can do it after the
- # is_in_nursery check
- if (self.config.taggedpointers and
- not self.is_valid_gc_object(addr)):
- return
- if self.is_in_nursery(addr):
- self.old_objects_pointing_to_young.append(addr_struct)
- self.header(addr_struct).tid &= ~GCFLAG_NO_YOUNG_PTRS
- elif (not self.config.taggedpointers and
- not self.is_valid_gc_object(addr)):
- return
- self.write_into_last_generation_obj(addr_struct, addr)
+ if DEBUG:
+ ll_assert(not self.is_in_nursery(addr_struct),
+ "nursery object with GCFLAG_NO_YOUNG_PTRS")
+ self.old_objects_pointing_to_young.append(addr_struct)
+ self.header(addr_struct).tid &= ~GCFLAG_NO_YOUNG_PTRS
+ self.write_into_last_generation_obj(addr_struct)
remember_young_pointer._dont_inline_ = True
self.remember_young_pointer = remember_young_pointer
- def write_into_last_generation_obj(self, addr_struct, addr):
+ def write_into_last_generation_obj(self, addr_struct):
objhdr = self.header(addr_struct)
if objhdr.tid & GCFLAG_NO_HEAP_PTRS:
- if not self.is_last_generation(addr):
- objhdr.tid &= ~GCFLAG_NO_HEAP_PTRS
- self.last_generation_root_objects.append(addr_struct)
+ objhdr.tid &= ~GCFLAG_NO_HEAP_PTRS
+ self.last_generation_root_objects.append(addr_struct)
+ write_into_last_generation_obj._always_inline_ = True
def assume_young_pointers(self, addr_struct):
objhdr = self.header(addr_struct)
Modified: pypy/branch/smaller-writebarrier/pypy/rpython/memory/gc/minimark.py
==============================================================================
--- pypy/branch/smaller-writebarrier/pypy/rpython/memory/gc/minimark.py (original)
+++ pypy/branch/smaller-writebarrier/pypy/rpython/memory/gc/minimark.py Mon Sep 20 17:40:01 2010
@@ -675,19 +675,19 @@
# "if addr_struct.int0 & JIT_WB_IF_FLAG: remember_young_pointer()")
JIT_WB_IF_FLAG = GCFLAG_NO_YOUNG_PTRS
- def write_barrier(self, newvalue, addr_struct):
+ def write_barrier(self, addr_struct):
if self.header(addr_struct).tid & GCFLAG_NO_YOUNG_PTRS:
- self.remember_young_pointer(addr_struct, newvalue)
+ self.remember_young_pointer(addr_struct)
- def write_barrier_from_array(self, newvalue, addr_array, index):
+ def write_barrier_from_array(self, addr_array, index):
if self.header(addr_array).tid & GCFLAG_NO_YOUNG_PTRS:
if self.card_page_indices > 0: # <- constant-folded
- self.remember_young_pointer_from_array(addr_array, index,
- newvalue)
+ self.remember_young_pointer_from_array(addr_array, index)
else:
- self.remember_young_pointer(addr_array, newvalue)
+ self.remember_young_pointer(addr_array)
def _init_writebarrier_logic(self):
+ DEBUG = self.DEBUG
# The purpose of attaching remember_young_pointer to the instance
# instead of keeping it as a regular method is to help the JIT call it.
# Additionally, it makes the code in write_barrier() marginally smaller
@@ -695,30 +695,22 @@
# For x86, there is also an extra requirement: when the JIT calls
# remember_young_pointer(), it assumes that it will not touch the SSE
# registers, so it does not save and restore them (that's a *hack*!).
- def remember_young_pointer(addr_struct, addr):
- # 'addr_struct' is the address of the object in which we write;
- # 'addr' is the address that we write in 'addr_struct'.
- ll_assert(not self.is_in_nursery(addr_struct),
- "nursery object with GCFLAG_NO_YOUNG_PTRS")
- # if we have tagged pointers around, we first need to check whether
- # we have valid pointer here, otherwise we can do it after the
- # is_in_nursery check
- if (self.config.taggedpointers and
- not self.is_valid_gc_object(addr)):
- return
- #
- # Core logic: if the 'addr' is in the nursery, then we need
+ def remember_young_pointer(addr_struct):
+ # 'addr_struct' is the address of the object in which we write.
+ if DEBUG:
+ ll_assert(not self.is_in_nursery(addr_struct),
+ "nursery object with GCFLAG_NO_YOUNG_PTRS")
+ #
+ # We assume that what we are writing is a pointer to the nursery
+ # (and don't care for the fact that this new pointer may not
+ # actually point to the nursery, which seems ok). What we need is
# to remove the flag GCFLAG_NO_YOUNG_PTRS and add the old object
# to the list 'old_objects_pointing_to_young'. We know that
# 'addr_struct' cannot be in the nursery, because nursery objects
# never have the flag GCFLAG_NO_YOUNG_PTRS to start with.
+ self.old_objects_pointing_to_young.append(addr_struct)
objhdr = self.header(addr_struct)
- if self.is_in_nursery(addr):
- self.old_objects_pointing_to_young.append(addr_struct)
- objhdr.tid &= ~GCFLAG_NO_YOUNG_PTRS
- elif (not self.config.taggedpointers and
- not self.is_valid_gc_object(addr)):
- return
+ objhdr.tid &= ~GCFLAG_NO_YOUNG_PTRS
#
# Second part: if 'addr_struct' is actually a prebuilt GC
# object and it's the first time we see a write to it, we
@@ -737,17 +729,16 @@
def _init_writebarrier_with_card_marker(self):
- def remember_young_pointer_from_array(addr_array, index, addr):
+ def remember_young_pointer_from_array(addr_array, index):
# 'addr_array' is the address of the object in which we write,
# which must have an array part; 'index' is the index of the
- # item that is (or contains) the pointer that we write;
- # 'addr' is the address that we write in the array.
+ # item that is (or contains) the pointer that we write.
objhdr = self.header(addr_array)
if objhdr.tid & GCFLAG_HAS_CARDS == 0:
#
# no cards, use default logic. The 'nocard_logic()' is just
# 'remember_young_pointer()', but forced to be inlined here.
- nocard_logic(addr_array, addr)
+ nocard_logic(addr_array)
return
#
# 'addr_array' is a raw_malloc'ed array with card markers
@@ -764,22 +755,13 @@
if byte & bitmask:
return
#
- # As in remember_young_pointer, check if 'addr' is a valid
- # pointer, in case it can be a tagged integer
- if (self.config.taggedpointers and
- not self.is_valid_gc_object(addr)):
- return
- #
- # If the 'addr' is in the nursery, then we need to set the flag.
- # Note that the following check is done after the bit check
- # above, because it is expected that the "bit already set"
- # situation is the most common.
- if self.is_in_nursery(addr):
- addr_byte.char[0] = chr(byte | bitmask)
- #
- if objhdr.tid & GCFLAG_CARDS_SET == 0:
- self.old_objects_with_cards_set.append(addr_array)
- objhdr.tid |= GCFLAG_CARDS_SET
+ # We set the flag (even if the newly written address does not
+ # actually point to the nursery -- like remember_young_pointer()).
+ addr_byte.char[0] = chr(byte | bitmask)
+ #
+ if objhdr.tid & GCFLAG_CARDS_SET == 0:
+ self.old_objects_with_cards_set.append(addr_array)
+ objhdr.tid |= GCFLAG_CARDS_SET
nocard_logic = func_with_new_name(self.remember_young_pointer,
'remember_young_pointer_nocard')
Modified: pypy/branch/smaller-writebarrier/pypy/rpython/memory/gc/test/test_direct.py
==============================================================================
--- pypy/branch/smaller-writebarrier/pypy/rpython/memory/gc/test/test_direct.py (original)
+++ pypy/branch/smaller-writebarrier/pypy/rpython/memory/gc/test/test_direct.py Mon Sep 20 17:40:01 2010
@@ -86,19 +86,17 @@
def write(self, p, fieldname, newvalue):
if self.gc.needs_write_barrier:
- newaddr = llmemory.cast_ptr_to_adr(newvalue)
addr_struct = llmemory.cast_ptr_to_adr(p)
- self.gc.write_barrier(newaddr, addr_struct)
+ self.gc.write_barrier(addr_struct)
setattr(p, fieldname, newvalue)
def writearray(self, p, index, newvalue):
if self.gc.needs_write_barrier:
- newaddr = llmemory.cast_ptr_to_adr(newvalue)
addr_struct = llmemory.cast_ptr_to_adr(p)
if hasattr(self.gc, 'write_barrier_from_array'):
- self.gc.write_barrier_from_array(newaddr, addr_struct, index)
+ self.gc.write_barrier_from_array(addr_struct, index)
else:
- self.gc.write_barrier(newaddr, addr_struct)
+ self.gc.write_barrier(addr_struct)
p[index] = newvalue
def malloc(self, TYPE, n=None):
More information about the Pypy-commit
mailing list