Commits

Armin Rigo  committed 294bb3f

Progress.

  • Participants
  • Parent commits bffefba
  • Branches concurrent-marksweep

Comments (0)

Files changed (5)

File pypy/config/translationoption.py

                  }),
     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"],

File pypy/rpython/lltypesystem/opimpl.py

     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
 

File pypy/rpython/memory/gc/concurrentms.py

 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
         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
         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
         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
         #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()
         # 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
             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)
                 # ---------- 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)
                                         "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."""
         #

File pypy/rpython/memory/gctransform/framework.py

         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,

File pypy/rpython/memory/test/test_transformed_gc.py

             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()