Bug 1308200 - Assert that we don't create a black->gray edge when writing to a function's extended slots r=sfink
authorJon Coppeard <jcoppeard@mozilla.com>
Fri, 07 Oct 2016 13:58:37 +0200
changeset 316900 09bbad43f50e67b72ee52fcfb27474f3dacf5729
parent 316899 bb5040568cfba1b290517f77ad185541d293e872
child 316901 6217f779742e62f225f2b9538fa82bc424a20a9f
push id82567
push userjcoppeard@mozilla.com
push dateFri, 07 Oct 2016 11:58:54 +0000
treeherdermozilla-inbound@6217f779742e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssfink
bugs1308200
milestone52.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1308200 - Assert that we don't create a black->gray edge when writing to a function's extended slots r=sfink
js/src/gc/Barrier.cpp
js/src/gc/Barrier.h
js/src/jsfun.h
--- a/js/src/gc/Barrier.cpp
+++ b/js/src/gc/Barrier.cpp
@@ -24,17 +24,17 @@ namespace js {
 bool
 RuntimeFromMainThreadIsHeapMajorCollecting(JS::shadow::Zone* shadowZone)
 {
     return shadowZone->runtimeFromMainThread()->isHeapMajorCollecting();
 }
 
 #ifdef DEBUG
 
-static bool
+bool
 IsMarkedBlack(NativeObject* obj)
 {
     // Note: we assume conservatively that Nursery things will be live.
     if (!obj->isTenured())
         return true;
 
     gc::TenuredCell& tenured = obj->asTenured();
     if (tenured.isMarked(gc::BLACK) || tenured.arena()->allocatedDuringIncremental)
--- a/js/src/gc/Barrier.h
+++ b/js/src/gc/Barrier.h
@@ -235,16 +235,19 @@ class JitCode;
 bool
 CurrentThreadIsIonCompiling();
 
 bool
 CurrentThreadIsIonCompilingSafeForMinorGC();
 
 bool
 CurrentThreadIsGCSweeping();
+
+bool
+IsMarkedBlack(NativeObject* obj);
 #endif
 
 namespace gc {
 
 // Marking.h depends on these barrier definitions, so we need a separate
 // entry point for marking to implement the pre-barrier.
 void MarkValueForBarrier(JSTracer* trc, Value* v, const char* name);
 void MarkIdForBarrier(JSTracer* trc, jsid* idp, const char* name);
--- a/js/src/jsfun.h
+++ b/js/src/jsfun.h
@@ -760,16 +760,18 @@ JSFunction::initExtendedSlot(size_t whic
     MOZ_ASSERT(which < mozilla::ArrayLength(toExtended()->extendedSlots));
     toExtended()->extendedSlots[which].init(val);
 }
 
 inline void
 JSFunction::setExtendedSlot(size_t which, const js::Value& val)
 {
     MOZ_ASSERT(which < mozilla::ArrayLength(toExtended()->extendedSlots));
+    MOZ_ASSERT_IF(js::IsMarkedBlack(this) && val.isMarkable(),
+                  !JS::GCThingIsMarkedGray(JS::GCCellPtr(val)));
     toExtended()->extendedSlots[which] = val;
 }
 
 inline const js::Value&
 JSFunction::getExtendedSlot(size_t which) const
 {
     MOZ_ASSERT(which < mozilla::ArrayLength(toExtended()->extendedSlots));
     return toExtended()->extendedSlots[which];