[pypy-commit] pypy concurrent-marksweep: Do something about prebuilt GC objects.

arigo noreply at buildbot.pypy.org
Fri Oct 7 16:17:34 CEST 2011


Author: Armin Rigo <arigo at tunes.org>
Branch: concurrent-marksweep
Changeset: r47856:ba1f195ed5fe
Date: 2011-10-07 16:16 +0200
http://bitbucket.org/pypy/pypy/changeset/ba1f195ed5fe/

Log:	Do something about prebuilt GC objects.

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
@@ -36,6 +36,7 @@
 
 MARK_VALUE_1      = 'M'     #  77, 0x4D
 MARK_VALUE_2      = 'k'     # 107, 0x6B
+MARK_VALUE_STATIC = 'S'     #  83, 0x53
 GCFLAG_WITH_HASH  = 0x01
 
 
@@ -102,6 +103,7 @@
         self.mutex_lock = ll_thread.allocate_lock()
         self.gray_objects = self.AddressStack()
         self.extra_objects_to_mark = self.AddressStack()
+        self.prebuilt_root_objects = self.AddressStack()
         #
         # Write barrier: actually a deletion barrier, triggered when there
         # is a collection running and the mutator tries to change an object
@@ -127,6 +129,13 @@
     def get_type_id(self, obj):
         return self.header(obj).typeid16
 
+    def init_gc_object_immortal(self, addr, typeid, flags=0):
+        # 'flags' is ignored here
+        hdr = llmemory.cast_adr_to_ptr(addr, lltype.Ptr(self.HDR))
+        hdr.typeid16 = typeid
+        hdr.mark = MARK_VALUE_STATIC
+        hdr.flags = '\x00'
+
     def malloc_fixedsize_clear(self, typeid, size,
                                needs_finalizer=False, contains_weakptr=False):
         assert not needs_finalizer  # XXX
@@ -226,15 +235,29 @@
         #
         def force_scan(obj):
             self.mutex_lock.acquire(True)
-            if not self.is_marked(obj, self.current_mark):
-                # it is only possible to reach this point if there is
-                # a collection running in collector_mark(), before it
-                # does mutex_lock itself.  Check this:
-                ll_assert(self.collection_running == 1,
-                          "write barrier: wrong call?")
+            mark = self.header(obj).mark
+            if mark != self.current_mark:
                 #
-                self.set_mark(obj, self.current_mark)
-                self.trace(obj, self._barrier_add_extra, None)
+                if mark == MARK_VALUE_STATIC:
+                    # This is the first write into a prebuilt GC object.
+                    # Record it in 'prebuilt_root_objects'.  Even if a
+                    # collection marking phase is running now, we can
+                    # ignore this object, because at the snapshot-at-the-
+                    # beginning it didn't contain any pointer to non-
+                    # prebuilt objects.
+                    self.prebuilt_root_objects.append(obj)
+                    self.set_mark(obj, self.current_mark)
+                    #
+                else:
+                    # it is only possible to reach this point if there is
+                    # a collection running in collector_mark(), before it
+                    # does mutex_lock itself.  Check this:
+                    ll_assert(self.collection_running == 1,
+                              "write barrier: wrong call?")
+                    #
+                    self.set_mark(obj, self.current_mark)
+                    self.trace(obj, self._barrier_add_extra, None)
+                #
             self.mutex_lock.release()
         #
         force_scan._dont_inline_ = True
@@ -285,6 +308,9 @@
             MostlyConcurrentMarkSweepGC._add_stack_root,  # in prebuilt non-gc
             None)                         # static in prebuilt gc
         #
+        # Add the prebuilt root objects that have been written to
+        self.prebuilt_root_objects.foreach(self._add_prebuilt_root, None)
+        #
         # Invert this global variable, which has the effect that on all
         # objects' state go instantly from "marked" to "non marked"
         self.current_mark = self.other_mark(self.current_mark)
@@ -306,6 +332,9 @@
         obj = root.address[0]
         self.gray_objects.append(obj)
 
+    def _add_prebuilt_root(self, obj, ignored):
+        self.gray_objects.append(obj)
+
     def acquire(self, lock):
         if we_are_translated():
             lock.acquire(True)
@@ -354,7 +383,7 @@
 
     def is_marked(self, obj, current_mark):
         mark = self.header(obj).mark
-        ll_assert(mark == MARK_VALUE_1 or mark == MARK_VALUE_2,
+        ll_assert(mark in (MARK_VALUE_1, MARK_VALUE_2, MARK_VALUE_STATIC),
                   "bad mark byte in object")
         return mark == current_mark
 


More information about the pypy-commit mailing list