[pypy-commit] pypy concurrent-marksweep: Progress.

arigo noreply at buildbot.pypy.org
Sun Oct 9 18:26:42 CEST 2011


Author: Armin Rigo <arigo at tunes.org>
Branch: concurrent-marksweep
Changeset: r47895:294bb3f33706
Date: 2011-10-09 15:10 +0200
http://bitbucket.org/pypy/pypy/changeset/294bb3f33706/

Log:	Progress.

diff --git a/pypy/config/translationoption.py b/pypy/config/translationoption.py
--- a/pypy/config/translationoption.py
+++ b/pypy/config/translationoption.py
@@ -90,6 +90,8 @@
                  }),
     BoolOption("gcremovetypeptr", "Remove the typeptr from every object",
                default=IS_64_BITS, cmdline="--gcremovetypeptr"),
+    BoolOption("gctesttransformed", "Set to True by test_transformed_gc",
+               default=False),
     ChoiceOption("gcrootfinder",
                  "Strategy for finding GC Roots (framework GCs only)",
                  ["n/a", "shadowstack", "asmgcc"],
diff --git a/pypy/rpython/lltypesystem/opimpl.py b/pypy/rpython/lltypesystem/opimpl.py
--- a/pypy/rpython/lltypesystem/opimpl.py
+++ b/pypy/rpython/lltypesystem/opimpl.py
@@ -594,7 +594,13 @@
     hdr = llmemory.cast_adr_to_ptr(hdraddr, lltype.Ptr(HDR))
     typeid = getattr(hdr, fieldname)
     if lltype.typeOf(typeid) == lltype.Signed:
-        typeid = op_extract_ushort(typeid)
+        from pypy.rpython.lltypesystem import llgroup
+        if isinstance(typeid, llgroup.CombinedSymbolic):
+            typeid = op_extract_ushort(typeid)
+        elif isinstance(typeid, llgroup.HighCombinedSymbolic):
+            typeid = op_extract_high_ushort(typeid)
+        else:
+            raise TypeError(typeid)
     return op_get_next_group_member(TYPE, grpptr, typeid, skipoffset)
 op_gc_gettypeptr_group.need_result_type = True
 
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
@@ -5,7 +5,7 @@
 from pypy.rpython.annlowlevel import llhelper
 from pypy.translator.tool.cbuild import ExternalCompilationInfo
 from pypy.rlib.objectmodel import we_are_translated, running_on_llinterp
-from pypy.rlib.debug import ll_assert
+from pypy.rlib.debug import ll_assert, debug_print
 from pypy.rlib.rarithmetic import ovfcheck, LONG_BIT, r_uint
 from pypy.rpython.memory.gc.base import GCBase
 from pypy.module.thread import ll_thread
@@ -70,7 +70,6 @@
         assert small_request_threshold % WORD == 0
         self.small_request_threshold = small_request_threshold
         self.page_size = page_size
-        self.free_pages = lltype.nullptr(self.HDR)
         self.pagelists_length = small_request_threshold // WORD + 1
         #
         # The following are arrays of 36 linked lists: the linked lists
@@ -80,7 +79,7 @@
         def list_of_addresses_per_small_size():
             return lltype.malloc(rffi.CArray(self.HDRPTR),
                                  self.pagelists_length, flavor='raw',
-                                 zero=True, immortal=True)
+                                 immortal=True)
         # 1-35: a linked list of all pages; 0: a linked list of all larger objs
         self.nonfree_pages = list_of_addresses_per_small_size()
         # a snapshot of 'nonfree_pages' done when the collection starts
@@ -92,6 +91,38 @@
         self.collect_heads = list_of_addresses_per_small_size()
         self.collect_tails = list_of_addresses_per_small_size()
         #
+        def collector_start():
+            if we_are_translated():
+                self.collector_run()
+            else:
+                self.collector_run_nontranslated()
+        #
+        collector_start._should_never_raise_ = True
+        self.collector_start = collector_start
+        #
+        self._initialize()
+        #
+        # Write barrier: actually a deletion barrier, triggered when there
+        # is a collection running and the mutator tries to change an object
+        # that was not scanned yet.
+        self._init_writebarrier_logic()
+
+    def _clear_list(self, array):
+        i = 0
+        while i < self.pagelists_length:
+            array[i] = lltype.nullptr(self.HDR)
+            i += 1
+
+    def _initialize(self):
+        self.free_pages = lltype.nullptr(self.HDR)
+        #
+        # Clear the lists
+        self._clear_list(self.nonfree_pages)
+        self._clear_list(self.collect_pages)
+        self._clear_list(self.free_lists)
+        self._clear_list(self.collect_heads)
+        self._clear_list(self.collect_tails)
+        #
         # The following character is either MARK_VALUE_1 or MARK_VALUE_2,
         # and represents the character that must be in the 'mark' field
         # of an object header in order for the object to be considered as
@@ -113,38 +144,19 @@
         #self.ready_to_start_lock = ...built in setup()
         #self.finished_lock = ...built in setup()
         #
-        # NOT_RPYTHON: set to non-empty in _teardown()
+        # set to non-empty in _teardown()
         self._teardown_now = []
         #
-        def collector_start():
-            if we_are_translated():
-                self.collector_run()
-            else:
-                try:
-                    self.collector_run()
-                except Exception, e:
-                    print 'Crash!', e.__class__.__name__, e
-                    self._exc_info = sys.exc_info()
-        #
-        collector_start._should_never_raise_ = True
-        self.collector_start = collector_start
-        #
         #self.mutex_lock = ...built in setup()
         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
-        # that was not scanned yet.
-        self._init_writebarrier_logic()
-        #
-        self.main_thread_ident = ll_thread.get_ident()
 
     def setup(self):
         "Start the concurrent collector thread."
         GCBase.setup(self)
         #
+        self.main_thread_ident = ll_thread.get_ident()
         self.ready_to_start_lock = ll_thread.allocate_ll_lock()
         self.finished_lock = ll_thread.allocate_ll_lock()
         self.mutex_lock = ll_thread.allocate_ll_lock()
@@ -166,9 +178,9 @@
         # which should shut down the collector thread
         self._teardown_now.append(-1)
         self.release(self.ready_to_start_lock)
+        print "teardown!"
         self.acquire(self.finished_lock)
-        if not we_are_translated():
-            del self.ready_to_start_lock, self.finished_lock
+        self._initialize()
 
     def get_type_id(self, obj):
         tid = self.header(obj).tid
@@ -533,6 +545,7 @@
             raise
 
     def acquire(self, lock):
+        debug_print("acquire", ll_thread.get_ident(), self.main_thread_ident)
         if (we_are_translated() or
                 ll_thread.get_ident() != self.main_thread_ident):
             ll_thread.c_thread_acquirelock(lock, 1)
@@ -543,6 +556,7 @@
                 # ---------- EXCEPTION FROM THE COLLECTOR THREAD ----------
                 if hasattr(self, '_exc_info'):
                     self._reraise_from_collector_thread()
+        debug_print("ok", ll_thread.get_ident(), self.main_thread_ident)
 
     def release(self, lock):
         ll_thread.c_thread_releaselock(lock)
@@ -560,6 +574,24 @@
                                         "symbolic")
 
 
+    def collector_run_nontranslated(self):
+        if hasattr(self, 'ready_to_start_lock'):      # normal tests
+            try:
+                self.collector_run()
+            except Exception, e:
+                print 'Crash!', e.__class__.__name__, e
+                self._exc_info = sys.exc_info()
+        else:
+            # this case is for test_transformed_gc: we need to spawn
+            # another LLInterpreter for this new thread.
+            from pypy.rpython.llinterp import LLInterpreter
+            prev = LLInterpreter.current_interpreter
+            llinterp = LLInterpreter(prev.typer)
+            # XXX FISH HORRIBLY for the graph...
+            graph = sys._getframe(2).f_locals['self']._obj.graph
+            llinterp.eval_graph(graph)
+
+
     def collector_run(self):
         """Main function of the collector's thread."""
         #
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
@@ -230,8 +230,9 @@
         self.frameworkgc_setup_ptr = getfn(frameworkgc_setup, [],
                                            annmodel.s_None)
         # for tests
-        self.frameworkgc__teardown_ptr = getfn(frameworkgc__teardown, [],
-                                               annmodel.s_None)
+        if self.translator.config.translation.gctesttransformed:
+            self.frameworkgc__teardown_ptr = getfn(frameworkgc__teardown, [],
+                                                   annmodel.s_None)
         
         if root_walker.need_root_stack:
             self.incr_stack_ptr = getfn(root_walker.incr_stack,
diff --git a/pypy/rpython/memory/test/test_transformed_gc.py b/pypy/rpython/memory/test/test_transformed_gc.py
--- a/pypy/rpython/memory/test/test_transformed_gc.py
+++ b/pypy/rpython/memory/test/test_transformed_gc.py
@@ -105,6 +105,7 @@
             if fixup:
                 fixup(t)
 
+        t.config.translation.gctesttransformed = True
         cbuild = CStandaloneBuilder(t, entrypoint, config=t.config,
                                     gcpolicy=cls.gcpolicy)
         db = cbuild.generate_graphs_for_llinterp()


More information about the pypy-commit mailing list