Author: Devin Jeanpierre <[email protected]>
Branch: gc-forkfriendly
Changeset: r85051:79a9cecb91c5
Date: 2016-06-09 00:35 -0700
http://bitbucket.org/pypy/pypy/changeset/79a9cecb91c5/

Log:    Fixing little to nothing, make incminimark_remoteheader more
        correctish, maybe.

        e.g. test_zrpy_gc, these two fail (with an assert failure and
        segfault resp.):

         TestRemoteHeaderShadowStack.test_compile_framework_7_interior
        TestRemoteHeaderShadowStack.test_compile_framework_9

        Some rambling notes on the above tests:

        * test_compile_framework_7_interior fails with an assert error:

         PyPy assertion failed at rpython_memory_gc.c:11879: in
        pypy_g_IncrementalMiniMarkGCBase__collect_obj: non-pinned nursery
        obj in _collect_obj

         I find this really confusing and disturbing. Nothing I do to
        nursery objects should be any different. In fact, I tried changing
        set_flags/add_flags/etc. to check is_in_nursery, like this:

         if self.is_in_nursery(obj): return
        incminimark.IncrementalMiniMarkGCBase.add_flags(self, obj, flags)

         Even this didn't solve it, even though it meant that every
        operation was on the tid field for nursery objects, and should be
        identical to incminimark!

         If I unconditionally called
        incminimark.IncrementalMiniMarkGCBase.add_flags etc., then it only
        passed tests if I did it for *all three* mutating methods.

         My conclusion is that the remote_flags for some object in the
        nursery is ignored, and we were setting flags on it at some point
        even though it was is_in_nursery reported it was not in the nursery.
        (e.g.: maybe it was copied to the nursery, but the remote_flags
        field wasn't included. But why?)

         Maybe it's time to step through in rr/gdb again.

        * test_compile_framework_9 fails with a segfault.

         I think this is purely because I have not found all the ways this
        interacts poorly with the JIT compiler, and so it is solvable. For
        example, it is fixed if I do the "if self.is_in_nursery(obj):"
        checks above. My guess is that somewhere, nursery objects are
        allocated with a garbage remote_flags (like the one in the JIT I
        think I fixed in this commit), and I just need to catch that case,
        or else completely stop using remote_flags for young objects.

diff --git a/rpython/jit/backend/llsupport/gc.py 
b/rpython/jit/backend/llsupport/gc.py
--- a/rpython/jit/backend/llsupport/gc.py
+++ b/rpython/jit/backend/llsupport/gc.py
@@ -146,6 +146,7 @@
     round_up              = False
     write_barrier_descr   = None
     fielddescr_tid        = None
+    fielddescr_remote_flags  = None
     gcrootmap             = None
     str_type_id           = 0
     unicode_type_id       = 0
@@ -393,6 +394,10 @@
 
     def _setup_tid(self):
         self.fielddescr_tid = get_field_descr(self, self.GCClass.HDR, 'tid')
+        if self.GCClass.has_remote_flags:
+            self.fielddescr_remote_flags = get_field_descr(self, 
self.GCClass.HDR, 'remote_flags')
+        else:
+            self.fielddescr_remote_flags = None
         frame_tid = self.layoutbuilder.get_type_id(jitframe.JITFRAME)
         self.translator._jit2gc['frame_tid'] = frame_tid
 
diff --git a/rpython/jit/backend/llsupport/rewrite.py 
b/rpython/jit/backend/llsupport/rewrite.py
--- a/rpython/jit/backend/llsupport/rewrite.py
+++ b/rpython/jit/backend/llsupport/rewrite.py
@@ -868,6 +868,11 @@
             # produce a SETFIELD to initialize the GC header
             self.emit_setfield(v_newgcobj, ConstInt(tid),
                                descr=self.gc_ll_descr.fielddescr_tid)
+        if self.gc_ll_descr.fielddescr_remote_flags is not None:
+            # produce a SETFIELD to initialize the rest of the GC header
+            # (Only present in _remoteheader GC)
+            self.emit_setfield(v_newgcobj, ConstInt(0),
+                               descr=self.gc_ll_descr.fielddescr_remote_flags)
 
     def gen_initialize_len(self, v_newgcobj, v_length, arraylen_descr):
         # produce a SETFIELD to initialize the array length
diff --git a/rpython/jit/backend/llsupport/test/zrpy_gc_test.py 
b/rpython/jit/backend/llsupport/test/zrpy_gc_test.py
--- a/rpython/jit/backend/llsupport/test/zrpy_gc_test.py
+++ b/rpython/jit/backend/llsupport/test/zrpy_gc_test.py
@@ -84,6 +84,8 @@
     #
     t = TranslationContext()
     t.config.translation.gc = gc
+    # TODO: re-enable inlining when this test passes
+    t.config.translation.backendopt.inline = False
     if gc != 'boehm':
         t.config.translation.gcremovetypeptr = True
     for name, value in kwds.items():
diff --git a/rpython/jit/backend/x86/test/test_zrpy_gc.py 
b/rpython/jit/backend/x86/test/test_zrpy_gc.py
--- a/rpython/jit/backend/x86/test/test_zrpy_gc.py
+++ b/rpython/jit/backend/x86/test/test_zrpy_gc.py
@@ -4,3 +4,8 @@
 class TestShadowStack(CompileFrameworkTests):
     gcrootfinder = "shadowstack"
     gc = "incminimark"
+
+
+class TestRemoteHeaderShadowStack(CompileFrameworkTests):
+    gcrootfinder = "shadowstack"
+    gc = "incminimark_remoteheader"
diff --git a/rpython/jit/backend/x86/test/test_zrpy_vmprof.py 
b/rpython/jit/backend/x86/test/test_zrpy_vmprof.py
--- a/rpython/jit/backend/x86/test/test_zrpy_vmprof.py
+++ b/rpython/jit/backend/x86/test/test_zrpy_vmprof.py
@@ -2,6 +2,9 @@
 from rpython.jit.backend.llsupport.test.zrpy_vmprof_test import 
CompiledVmprofTest
 
 class TestZVMprof(CompiledVmprofTest):
-    
     gcrootfinder = "shadowstack"
-    gc = "incminimark"
\ No newline at end of file
+    gc = "incminimark"
+
+class TestRemoteHeaderZVMprof(CompiledVmprofTest):
+    gcrootfinder = "shadowstack"
+    gc = "incminimark_remoteheader"
diff --git a/rpython/jit/backend/x86/test/test_zvmprof.py 
b/rpython/jit/backend/x86/test/test_zvmprof.py
--- a/rpython/jit/backend/x86/test/test_zvmprof.py
+++ b/rpython/jit/backend/x86/test/test_zvmprof.py
@@ -2,6 +2,9 @@
 from rpython.jit.backend.llsupport.test.zrpy_vmprof_test import 
CompiledVmprofTest
 
 class TestZVMprof(CompiledVmprofTest):
-    
     gcrootfinder = "shadowstack"
-    gc = "incminimark"
\ No newline at end of file
+    gc = "incminimark"
+
+class TestRemoteHeaderZVMprof(CompiledVmprofTest):
+    gcrootfinder = "shadowstack"
+    gc = "incminimark_remoteheader"
diff --git a/rpython/memory/gc/base.py b/rpython/memory/gc/base.py
--- a/rpython/memory/gc/base.py
+++ b/rpython/memory/gc/base.py
@@ -21,6 +21,7 @@
     can_usually_pin_objects = False
     object_minimal_size = 0
     gcflag_extra = 0   # or a real GC flag that is always 0 when not collecting
+    has_remote_flags = False
 
     def __init__(self, config, chunk_size=DEFAULT_CHUNK_SIZE,
                  translated_to_c=True):
diff --git a/rpython/memory/gc/incminimark.py b/rpython/memory/gc/incminimark.py
--- a/rpython/memory/gc/incminimark.py
+++ b/rpython/memory/gc/incminimark.py
@@ -625,6 +625,7 @@
             #
             # Get the memory from the nursery.  If there is not enough space
             # there, do a collect first.
+            ll_assert(self.nursery_free != llmemory.NULL, "malloc_fixedsize() 
with uninitialized nursery")
             result = self.nursery_free
             self.nursery_free = new_free = result + totalsize
             if new_free > self.nursery_top:
@@ -685,6 +686,7 @@
             #
             # Get the memory from the nursery.  If there is not enough space
             # there, do a collect first.
+            ll_assert(self.nursery_free != llmemory.NULL, "malloc_varsize() 
without initializing nursery")
             result = self.nursery_free
             self.nursery_free = new_free = result + totalsize
             if new_free > self.nursery_top:
@@ -1088,6 +1090,7 @@
         # have been chosen to allow 'flags' to be zero in the common
         # case (hence the 'NO' in their name).
         hdr = llmemory.cast_adr_to_ptr(addr, lltype.Ptr(self.HDR))
+        ll_assert(hdr != lltype.nullptr(self.HDR), "init_gc_object(): 
addr==NULL")
         hdr.tid = self.combine(typeid16, flags)
 
     def init_gc_object_immortal(self, addr, typeid16, flags=0):
@@ -1120,7 +1123,8 @@
         Implemented a bit obscurely by checking an unrelated flag
         that can never be set on a young object -- except if tid == -42.
         """
-        assert self.is_in_nursery(obj)
+        ll_assert(self.is_in_nursery(obj), "is_forwarded(): object not in 
nursery!")
+
         tid = self.get_flags(obj)
         result = (tid & GCFLAG_FINALIZATION_ORDERING != 0)
         if result:
@@ -1439,7 +1443,8 @@
                 self.add_flags(addr_array, GCFLAG_CARDS_SET)
 
         remember_young_pointer_from_array2._dont_inline_ = True
-        assert self.card_page_indices > 0
+        ll_assert(self.card_page_indices > 0,
+                  "_init_writebarrier_with_card_marker(): card_page_indices <= 
0")
         self.remember_young_pointer_from_array2 = (
             remember_young_pointer_from_array2)
 
@@ -1523,7 +1528,8 @@
 
     def manually_copy_card_bits(self, source_addr, dest_addr, length):
         # manually copy the individual card marks from source to dest
-        assert self.card_page_indices > 0
+        ll_assert(self.card_page_indices > 0,
+                  "_init_writebarrier_with_card_marker(): card_page_indices <= 
0")
         bytes = self.card_marking_bytes_for_length(length)
         #
         anybyte = 0
@@ -1684,12 +1690,13 @@
         nursery_barriers = self.AddressDeque()
         prev = self.nursery
         self.surviving_pinned_objects.sort()
-        assert self.pinned_objects_in_nursery == \
-            self.surviving_pinned_objects.length()
+        ll_assert(self.pinned_objects_in_nursery == \
+            self.surviving_pinned_objects.length(),
+            "_minor_collection(): self.pinned_objects_in_nursery != 
self.surviving_pinned_objects.length()")
         while self.surviving_pinned_objects.non_empty():
             #
             cur = self.surviving_pinned_objects.pop()
-            assert cur >= prev
+            ll_assert(cur >= prev, "_minor_collection(): cur < prev")
             #
             # clear the arena between the last pinned object (or arena start)
             # and the pinned object
@@ -1747,7 +1754,7 @@
         debug_stop("gc-minor")
 
     def _reset_flag_old_objects_pointing_to_pinned(self, obj, ignore):
-        assert self.get_flags(obj) & GCFLAG_PINNED_OBJECT_PARENT_KNOWN
+        ll_assert(self.get_flags(obj) & GCFLAG_PINNED_OBJECT_PARENT_KNOWN, 
"_reset_flag_old_objects_pointing_to_pinned(): not 
GCFLAG_PINNED_OBJECT_PARENT_KNOWN")
         self.remove_flags(obj, GCFLAG_PINNED_OBJECT_PARENT_KNOWN)
 
     def _visit_old_objects_pointing_to_pinned(self, obj, ignore):
@@ -3056,7 +3063,6 @@
     gc.finalize_header(hdr)
     return True
 
-
 class IncrementalMiniMarkGC(IncrementalMiniMarkGCBase):
     HDR = lltype.Struct('header', ('tid', lltype.Signed))
     # During a minor collection, the objects in the nursery that are
diff --git a/rpython/memory/gc/incminimark_remoteheader.py 
b/rpython/memory/gc/incminimark_remoteheader.py
--- a/rpython/memory/gc/incminimark_remoteheader.py
+++ b/rpython/memory/gc/incminimark_remoteheader.py
@@ -4,15 +4,19 @@
 from rpython.memory.gc import incminimark
 from rpython.rlib.rarithmetic import LONG_BIT
 from rpython.rtyper.lltypesystem import rffi, lltype, llmemory
+from rpython.rlib.debug import ll_assert
 
 SIGNEDP = lltype.Ptr(lltype.FixedSizeArray(lltype.Signed, 1))
 
 class IncrementalMiniMarkRemoteHeaderGC(incminimark.IncrementalMiniMarkGCBase):
     # The GC header is similar to incminimark, except that the flags can be
     # placed anywhere, not just in the bits of tid.
-    HDR = lltype.Struct('header',
-                        ('tid', lltype.Signed),
-                        ('remote_flags', SIGNEDP))
+    HDR = lltype.Struct(
+        'header',
+        ('tid', lltype.Signed),
+        ('remote_flags', SIGNEDP)
+    )
+    has_remote_flags = True
     minimal_size_in_nursery = (
         llmemory.sizeof(HDR) + llmemory.sizeof(llmemory.Address))
 
@@ -35,21 +39,22 @@
         # This gets compiled to nonsense like (&pypy_g_header_1433.h_tid)
         # at the top level (global variable initialization). Instead, we set
         # it to NULL and lazily initialize it later.
-        ## hdr.remote_flags = lltype.direct_fieldptr(hdr, 'tid')
         hdr.remote_flags = lltype.nullptr(SIGNEDP.TO)
 
     def make_forwardstub(self, obj, forward_to):
-        assert (self.header(obj).remote_flags
-                == lltype.direct_fieldptr(self.header(obj), 'tid')), \
-            "Nursery objects should not have separately-allocated flags."
+        hdr = self.header(obj)
+        ll_assert(
+            hdr.remote_flags == lltype.nullptr(SIGNEDP.TO)
+            or hdr.remote_flags == lltype.direct_fieldptr(hdr, 'tid'),
+            "Nursery objects should not have separately-allocated flags.")
         incminimark.IncrementalMiniMarkGCBase.make_forwardstub(self, obj, 
forward_to)
-        hdr = self.header(obj)
-        hdr.remote_flags = lltype.direct_fieldptr(hdr, 'tid')
 
     def copy_header(self, src, dest):
         dest_hdr = self.header(dest)
         dest_hdr.tid = self.get_flags(src)
-        dest_hdr.remote_flags = lltype.direct_fieldptr(dest_hdr, 'tid')
+        ll_assert(
+            not self.is_in_nursery(dest),
+            "Copying headers to another nursery element?")
         self.__extract_flags_to_pointer(dest_hdr)
 
     def __extract_flags_to_pointer(self, hdr):
@@ -57,9 +62,6 @@
 
         Expects the object to not use inline tid-flags.
         """
-        assert (hdr.remote_flags == lltype.nullptr(SIGNEDP.TO)
-                or hdr.remote_flags == lltype.direct_fieldptr(hdr, 'tid')), \
-                    "leaking old remote_flags!"
         size = llmemory.sizeof(lltype.Signed)
         adr = self.__ac_for_flags.malloc(size)
         hdr.remote_flags = llmemory.cast_adr_to_ptr(adr, SIGNEDP)
@@ -67,7 +69,8 @@
 
     def finalize_header(self, adr):
         hdr = llmemory.cast_adr_to_ptr(adr, lltype.Ptr(self.HDR))
-        if hdr.remote_flags != lltype.nullptr(SIGNEDP.TO):
+        if (hdr.remote_flags != lltype.nullptr(SIGNEDP.TO)
+            and hdr.remote_flags != lltype.direct_fieldptr(hdr, 'tid')):
             # If it points to allocated memory, this will be picked up by
             # __free_flags_if_finalized.
             hdr.remote_flags[0] |= incminimark.GCFLAG_DEAD
@@ -84,31 +87,28 @@
 
     # Manipulate flags through a pointer.
 
-    def __lazy_init_flags(self, hdr):
+    def __lazy_init_flags(self, obj):
+        hdr = self.header(obj)
         # XXX Is there anywhere I can initialize this only once without having
         #     to check for null on EVERY access?
         if hdr.remote_flags == lltype.nullptr(SIGNEDP.TO):
             hdr.remote_flags = lltype.direct_fieldptr(hdr, 'tid')
 
     def get_flags(self, obj):
-        hdr = self.header(obj)
-        self.__lazy_init_flags(hdr)
-        return hdr.remote_flags[0]
+        self.__lazy_init_flags(obj)
+        return self.header(obj).remote_flags[0]
 
     def set_flags(self, obj, flags):
-        hdr = self.header(obj)
-        self.__lazy_init_flags(hdr)
-        hdr.remote_flags[0] = flags
+        self.__lazy_init_flags(obj)
+        self.header(obj).remote_flags[0] = flags
 
     def add_flags(self, obj, flags):
-        hdr = self.header(obj)
-        self.__lazy_init_flags(hdr)
-        hdr.remote_flags[0] |= flags
+        self.__lazy_init_flags(obj)
+        self.header(obj).remote_flags[0] |= flags
 
     def remove_flags(self, obj, flags):
-        hdr = self.header(obj)
-        self.__lazy_init_flags(hdr)
-        hdr.remote_flags[0] &= ~flags
+        self.__lazy_init_flags(obj)
+        self.header(obj).remote_flags[0] &= ~flags
 
 
 def _free_flags_if_finalized(adr, unused_arg):
diff --git a/rpython/translator/c/test/test_newgc.py 
b/rpython/translator/c/test/test_newgc.py
--- a/rpython/translator/c/test/test_newgc.py
+++ b/rpython/translator/c/test/test_newgc.py
@@ -1660,7 +1660,7 @@
             assert res == 42
 
 
-class TestIncrementalMiniMarkRemoteHeadersGC(TestIncrementalMiniMarkGC):
+class TestIncrementalMiniMarkRemoteHeaderGC(TestIncrementalMiniMarkGC):
     gcpolicy = "incminimark_remoteheader"
 
 
@@ -1760,5 +1760,5 @@
 class TestIncrementalMiniMarkGCMostCompact(TaggedPointersTest, 
TestIncrementalMiniMarkGC):
     removetypeptr = True
 
-class TestIncrementalMiniMarkRemoteHeadersGCMostCompact(TaggedPointersTest, 
TestIncrementalMiniMarkRemoteHeadersGC):
+class TestIncrementalMiniMarkRemoteHeaderGCMostCompact(TaggedPointersTest, 
TestIncrementalMiniMarkRemoteHeaderGC):
     removetypeptr = True
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to