Author: Armin Rigo <ar...@tunes.org> Branch: concurrent-marksweep Changeset: r47936:cbf2c361a9bb Date: 2011-10-11 14:41 +0200 http://bitbucket.org/pypy/pypy/changeset/cbf2c361a9bb/
Log: Rename the write_barrier in concurrentms to "deletion_barrier", as it has subtly different semantics about when it is ok or not to kill a call to it. diff --git a/pypy/rpython/memory/gc/base.py b/pypy/rpython/memory/gc/base.py --- a/pypy/rpython/memory/gc/base.py +++ b/pypy/rpython/memory/gc/base.py @@ -16,6 +16,7 @@ _alloc_flavor_ = "raw" moving_gc = False needs_write_barrier = False + needs_deletion_barrier = False malloc_zero_filled = False prebuilt_gc_objects_are_static_roots = True object_minimal_size = 0 diff --git a/pypy/rpython/memory/gc/concurrentms.py b/pypy/rpython/memory/gc/concurrentms.py --- a/pypy/rpython/memory/gc/concurrentms.py +++ b/pypy/rpython/memory/gc/concurrentms.py @@ -46,7 +46,7 @@ _alloc_flavor_ = "raw" inline_simple_malloc = True inline_simple_malloc_varsize = True - needs_write_barrier = True + needs_deletion_barrier = True prebuilt_gc_objects_are_static_roots = False malloc_zero_filled = True gcflag_extra = FL_EXTRA @@ -468,18 +468,11 @@ return adr + self.gcheaderbuilder.size_gc_header grow_reservation._always_inline_ = True - def write_barrier(self, newvalue, addr_struct): + def deletion_barrier(self, addr_struct): mark = self.header(addr_struct).tid & 0xFF if mark != self.current_mark: self.force_scan(addr_struct) - def writebarrier_before_copy(self, source_addr, dest_addr, - source_start, dest_start, length): - mark = self.header(dest_addr).tid & 0xFF - if mark != self.current_mark: - self.force_scan(dest_addr) - return True - def assume_young_pointers(self, addr_struct): pass # XXX @@ -527,6 +520,7 @@ # self.acquire(self.finished_lock) self.collection_running = 0 + debug_print("collection_running = 0") # # Check invariants ll_assert(not self.extra_objects_to_mark.non_empty(), @@ -655,6 +649,7 @@ # # Start the collector thread self.collection_running = 1 + debug_print("collection_running = 1") self.release(self.ready_to_start_lock) # debug_stop("gc-start") @@ -748,6 +743,7 @@ # Mark self.collector_mark() self.collection_running = 2 + debug_print("collection_running = 2") # self.deal_with_objects_with_finalizers() # @@ -756,6 +752,7 @@ # # Done! self.collection_running = -1 + debug_print("collection_running = -1") self.release(self.finished_lock) diff --git a/pypy/rpython/memory/gc/test/test_direct.py b/pypy/rpython/memory/gc/test/test_direct.py --- a/pypy/rpython/memory/gc/test/test_direct.py +++ b/pypy/rpython/memory/gc/test/test_direct.py @@ -90,6 +90,9 @@ newaddr = llmemory.cast_ptr_to_adr(newvalue) addr_struct = llmemory.cast_ptr_to_adr(p) self.gc.write_barrier(newaddr, addr_struct) + elif self.gc.needs_deletion_barrier: + addr_struct = llmemory.cast_ptr_to_adr(p) + self.gc.deletion_barrier(addr_struct) setattr(p, fieldname, newvalue) def writearray(self, p, index, newvalue): @@ -100,6 +103,9 @@ self.gc.write_barrier_from_array(newaddr, addr_struct, index) else: self.gc.write_barrier(newaddr, addr_struct) + elif self.gc.needs_deletion_barrier: + addr_struct = llmemory.cast_ptr_to_adr(p) + self.gc.deletion_barrier(addr_struct) p[index] = newvalue def malloc(self, TYPE, n=None): diff --git a/pypy/rpython/memory/gctransform/framework.py b/pypy/rpython/memory/gctransform/framework.py --- a/pypy/rpython/memory/gctransform/framework.py +++ b/pypy/rpython/memory/gctransform/framework.py @@ -440,6 +440,7 @@ self.write_barrier_ptr = None self.write_barrier_from_array_ptr = None + self.deletion_barrier_ptr = None if GCClass.needs_write_barrier: self.write_barrier_ptr = getfn(GCClass.write_barrier.im_func, [s_gc, @@ -475,6 +476,12 @@ annmodel.SomeInteger(), annmodel.SomeAddress()], annmodel.s_None) + elif GCClass.needs_deletion_barrier: + self.deletion_barrier_ptr = getfn(GCClass.deletion_barrier.im_func, + [s_gc, annmodel.SomeAddress()], + annmodel.s_None, + inline=True) + self.statistics_ptr = getfn(GCClass.statistics.im_func, [s_gc, annmodel.SomeInteger()], annmodel.SomeInteger()) @@ -551,7 +558,7 @@ log.info("assigned %s typeids" % (len(group.members), )) log.info("added %s push/pop stack root instructions" % ( self.num_pushs, )) - if self.write_barrier_ptr: + if self.write_barrier_ptr or self.deletion_barrier_ptr: log.info("inserted %s write barrier calls" % ( self.write_barrier_calls, )) if self.write_barrier_from_array_ptr: @@ -1136,6 +1143,18 @@ self.c_const_gc, v_newvalue, v_structaddr]) + elif (self.deletion_barrier_ptr + and v_struct.concretetype.TO._gckind == "gc"): + # The MostlyConcurrentMarkSweepGC is a case where the + # write barrier is best called a "deletion barrier" instead. + # It needs different logic here (and at a few other places). + # XXX try harder to omit some calls! + v_structaddr = hop.genop("cast_ptr_to_adr", [v_struct], + resulttype = llmemory.Address) + self.write_barrier_calls += 1 + hop.genop("direct_call", [self.deletion_barrier_ptr, + self.c_const_gc, + v_structaddr]) hop.rename('bare_' + opname) def transform_getfield_typeptr(self, hop): diff --git a/pypy/rpython/memory/gcwrapper.py b/pypy/rpython/memory/gcwrapper.py --- a/pypy/rpython/memory/gcwrapper.py +++ b/pypy/rpython/memory/gcwrapper.py @@ -144,6 +144,10 @@ return self.gc.writebarrier_before_copy(source_addr, dest_addr, source_start, dest_start, length) + elif self.gc.needs_deletion_barrier: + dest_addr = llmemory.cast_ptr_to_adr(dest) + self.gc.deletion_barrier(dest_addr) + return True else: return True _______________________________________________ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit