Author: Armin Rigo <ar...@tunes.org> Branch: concurrent-marksweep Changeset: r47929:014eb2e11cf5 Date: 2011-10-11 11:19 +0200 http://bitbucket.org/pypy/pypy/changeset/014eb2e11cf5/
Log: Simplify the linked list support. 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 @@ -135,7 +135,7 @@ self.collect_finalizer_tails = self.NULL self.collect_run_finalizers_head = self.NULL self.collect_run_finalizers_tail = self.NULL - self.run_finalizers = self.NULL + self.objects_with_finalizers_to_run = self.NULL # # The following character is either MARK_VALUE_1 or MARK_VALUE_2, # and represents the character that must be in the 'mark' field @@ -226,7 +226,7 @@ n = rawtotalsize >> WORD_POWER_2 result = self.free_lists[n] if result != self.NULL: - self.free_lists[n] = self.cast_int_to_hdrptr(result.tid) + self.free_lists[n] = list_next(result) obj = self.grow_reservation(result, totalsize) hdr = self.header(obj) hdr.tid = self.combine(typeid, self.current_mark, 0) @@ -264,7 +264,7 @@ n = rawtotalsize >> WORD_POWER_2 result = self.free_lists[n] if result != self.NULL: - self.free_lists[n] = self.cast_int_to_hdrptr(result.tid) + self.free_lists[n] = list_next(result) obj = self.grow_reservation(result, totalsize) hdr = self.header(obj) hdr.tid = self.combine(typeid, self.current_mark, 0) @@ -298,7 +298,7 @@ n = rawtotalsize >> WORD_POWER_2 head = self.free_lists[n] if head: - self.free_lists[n] = self.cast_int_to_hdrptr(head.tid) + self.free_lists[n] = list_next(head) obj = self.grow_reservation(head, totalsize) hdr = self.header(obj) hdr.tid = self.combine(typeid, self.current_mark, 0) @@ -310,11 +310,11 @@ if newpage == self.NULL: self.allocate_next_arena() newpage = self.free_pages - self.free_pages = self.cast_int_to_hdrptr(newpage.tid) + self.free_pages = list_next(newpage) # # Put the free page in the list 'nonfree_pages[n]'. This is # a linked list chained through the first word of each page. - newpage.tid = self.cast_hdrptr_to_int(self.nonfree_pages[n]) + set_next(newpage, self.nonfree_pages[n]) self.nonfree_pages[n] = newpage # # Initialize the free page to contain objects of the given @@ -328,7 +328,7 @@ adr = newpageadr + i llarena.arena_reserve(adr, self.HDRSIZE) p = llmemory.cast_adr_to_ptr(adr, self.HDRPTR) - p.tid = self.cast_hdrptr_to_int(head) + set_next(p, head) head = p i -= rawtotalsize self.free_lists[n] = head @@ -351,7 +351,7 @@ raise MemoryError llarena.arena_reserve(block, self.HDRSIZE) blockhdr = llmemory.cast_adr_to_ptr(block, self.HDRPTR) - blockhdr.tid = self.cast_hdrptr_to_int(self.nonfree_pages[0]) + set_next(blockhdr, self.nonfree_pages[0]) self.nonfree_pages[0] = blockhdr result = block + 8 # @@ -408,7 +408,7 @@ blockhdr = llmemory.cast_adr_to_ptr(block, self.HDRPTR) # the changes are only in the following two lines: we add the block # to a different linked list - blockhdr.tid = self.cast_hdrptr_to_int(self.finalizer_pages) + set_next(blockhdr, self.finalizer_pages) self.finalizer_pages = blockhdr result = block + 8 # @@ -540,28 +540,26 @@ n = 1 while n < self.pagelists_length: if self.collect_tails[n] != self.NULL: - self.collect_tails[n].tid = self.cast_hdrptr_to_int( - self.free_lists[n]) + set_next(self.collect_tails[n], self.free_lists[n]) self.free_lists[n] = self.collect_heads[n] n += 1 # # Do the same with 'collect_heads[0]/collect_tails[0]'. if self.collect_tails[0] != self.NULL: - self.collect_tails[0].tid = self.cast_hdrptr_to_int( - self.nonfree_pages[0]) + set_next(self.collect_tails[0], self.nonfree_pages[0]) self.nonfree_pages[0] = self.collect_heads[0] # # Do the same with 'collect_finalizer_pages/tails' if self.collect_finalizer_tails != self.NULL: - self.collect_finalizer_tails.tid = self.cast_hdrptr_to_int( - self.finalizer_pages) + set_next(self.collect_finalizer_tails, self.finalizer_pages) self.finalizer_pages = self.collect_finalizer_pages # # Do the same with 'collect_run_finalizers_head/tail' if self.collect_run_finalizers_tail != self.NULL: - self.collect_run_finalizers_tail.tid = self.cast_hdrptr_to_int( - self.run_finalizers) - self.run_finalizers = self.collect_run_finalizers_head + set_next(self.collect_run_finalizers_tail, + self.objects_with_finalizers_to_run) + self.objects_with_finalizers_to_run = ( + self.collect_run_finalizers_head) # if self.DEBUG: self.debug_check_lists() @@ -574,22 +572,17 @@ def execute_finalizers_ll(self): self.finalizer_lock_count += 1 try: -## print 'execute_finalizers_ll: %d' % self.finalizer_lock_count -## p = self.run_finalizers -## while p != self.NULL: -## print p -## p = self.cast_int_to_hdrptr(p.tid) - - while self.run_finalizers != self.NULL: + while self.objects_with_finalizers_to_run != self.NULL: if self.finalizer_lock_count > 1: # the outer invocation of execute_finalizers() will do it break # - x = llmemory.cast_ptr_to_adr(self.run_finalizers) + x = llmemory.cast_ptr_to_adr( + self.objects_with_finalizers_to_run) x = llarena.getfakearenaaddress(x) + 8 obj = x + self.gcheaderbuilder.size_gc_header - self.run_finalizers = self.cast_int_to_hdrptr( - self.run_finalizers.tid) + self.objects_with_finalizers_to_run = list_next( + self.objects_with_finalizers_to_run) # finalizer = self.getfinalizer(self.get_type_id(obj)) finalizer(obj, llmemory.NULL) @@ -632,13 +625,13 @@ # Add the prebuilt root objects that have been written to self.prebuilt_root_objects.foreach(self._add_prebuilt_root, None) # - # Add the objects still waiting in 'run_finalizers' - p = self.run_finalizers + # Add the objects still waiting in 'objects_with_finalizers_to_run' + p = self.objects_with_finalizers_to_run while p != self.NULL: x = llmemory.cast_ptr_to_adr(p) x = llarena.getfakearenaaddress(x) + 8 self.gray_objects.append(x + self.gcheaderbuilder.size_gc_header) - p = self.cast_int_to_hdrptr(p.tid) + p = list_next(p) # # Invert this global variable, which has the effect that on all # objects' state go instantly from "marked" to "non marked" @@ -681,7 +674,7 @@ self.debug_check_list(self.free_lists[n]) n += 1 self.debug_check_list(self.finalizer_pages) - self.debug_check_list(self.run_finalizers) + self.debug_check_list(self.objects_with_finalizers_to_run) def debug_check_list(self, page): try: @@ -691,7 +684,7 @@ # prevent constant-folding, and detects loops of length 1 ll_assert(page != previous_page, "loop!") previous_page = page - page = self.cast_int_to_hdrptr(page.tid) + page = list_next(page) count += 1 return count except KeyboardInterrupt: @@ -717,14 +710,6 @@ exc, val, tb = self._exc_info raise exc, val, tb - def cast_int_to_hdrptr(self, tid): - return llmemory.cast_adr_to_ptr(llmemory.cast_int_to_adr(tid), - self.HDRPTR) - - def cast_hdrptr_to_int(self, hdr): - return llmemory.cast_adr_to_int(llmemory.cast_ptr_to_adr(hdr), - "symbolic") - def collector_run_nontranslated(self): try: @@ -851,7 +836,7 @@ linked_list = self.NULL first_block_in_linked_list = self.NULL while block != self.NULL: - nextblock = self.cast_int_to_hdrptr(block.tid) + nextblock = list_next(block) blockadr = llmemory.cast_ptr_to_adr(block) blockadr = llarena.getfakearenaaddress(blockadr) hdr = llmemory.cast_adr_to_ptr(blockadr + 8, self.HDRPTR) @@ -864,7 +849,7 @@ # the object was marked: relink it ll_assert(mark == self.current_mark, "bad mark in large object") - block.tid = self.cast_hdrptr_to_int(linked_list) + set_next(block, linked_list) linked_list = block if first_block_in_linked_list == self.NULL: first_block_in_linked_list = block @@ -900,7 +885,7 @@ llarena.arena_reset(adr, object_size, 0) llarena.arena_reserve(adr, self.HDRSIZE) hdr = llmemory.cast_adr_to_ptr(adr, self.HDRPTR) - hdr.tid = self.cast_hdrptr_to_int(linked_list) + set_next(hdr, linked_list) linked_list = hdr if first_loc_in_linked_list == self.NULL: first_loc_in_linked_list = hdr @@ -935,7 +920,7 @@ # i -= object_size # - page = self.cast_int_to_hdrptr(page.tid) + page = list_next(page) # self.collect_heads[n] = linked_list self.collect_tails[n] = first_loc_in_linked_list @@ -954,7 +939,7 @@ self.collect_finalizer_pages = self.NULL self.collect_finalizer_tails = self.NULL while finalizer_page != self.NULL: - next_page = self.cast_int_to_hdrptr(finalizer_page.tid) + next_page = list_next(finalizer_page) # x = llmemory.cast_ptr_to_adr(finalizer_page) x = llarena.getfakearenaaddress(x) + 8 @@ -962,8 +947,7 @@ if (hdr.tid & 0xFF) != marked: # non-marked: add to collect_run_finalizers, # and mark the object and its dependencies - finalizer_page.tid = self.cast_hdrptr_to_int( - self.collect_run_finalizers_head) + set_next(finalizer_page, self.collect_run_finalizers_head) self.collect_run_finalizers_head = finalizer_page if self.collect_run_finalizers_tail == self.NULL: self.collect_run_finalizers_tail = finalizer_page @@ -971,8 +955,7 @@ self.gray_objects.append(obj) else: # marked: relink into the collect_finalizer_pages list - finalizer_page.tid = self.cast_hdrptr_to_int( - self.collect_finalizer_pages) + set_next(finalizer_page, self.collect_finalizer_pages) self.collect_finalizer_pages = finalizer_page if self.collect_finalizer_tails != self.NULL: self.collect_finalizer_tails = finalizer_page @@ -988,6 +971,19 @@ # ____________________________________________________________ # +# Support for linked lists (used here because AddressStack is not thread-safe) + +def list_next(hdr): + return llmemory.cast_adr_to_ptr(llmemory.cast_int_to_adr(hdr.tid), + MostlyConcurrentMarkSweepGC.HDRPTR) + +def set_next(hdr, nexthdr): + hdr.tid = llmemory.cast_adr_to_int(llmemory.cast_ptr_to_adr(nexthdr), + "symbolic") + + +# ____________________________________________________________ +# # Hack to write the 'mark' or the 'flags' bytes of an object header # without overwriting the whole word. Essential in the rare case where # the other thread might be concurrently writing the other byte. _______________________________________________ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit