Bug 1447693 - Add some assertions around updating type sets after minor GC r=tcampbell
authorJon Coppeard <jcoppeard@mozilla.com>
Mon, 16 Apr 2018 22:29:24 +0200
changeset 467523 f46b5589e6039eb12f9b750bb1f6fd4cd5699c22
parent 467522 a2f017455c094a23f6e069f8d725ae9667065178
child 467524 50091ebf491862711c143ae5dfbbd26000103eb9
push id9165
push userasasaki@mozilla.com
push dateThu, 26 Apr 2018 21:04:54 +0000
treeherdermozilla-beta@064c3804de2e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerstcampbell
bugs1447693
milestone61.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 1447693 - Add some assertions around updating type sets after minor GC r=tcampbell
js/src/vm/TypeInference-inl.h
js/src/vm/TypeInference.cpp
--- a/js/src/vm/TypeInference-inl.h
+++ b/js/src/vm/TypeInference-inl.h
@@ -117,19 +117,19 @@ TypeSet::ObjectKey::singleton()
     JSObject::readBarrier(res);
     return res;
 }
 
 inline JSCompartment*
 TypeSet::ObjectKey::maybeCompartment()
 {
     if (isSingleton())
-        return singleton()->compartment();
+        return singletonNoBarrier()->compartment();
 
-    return group()->compartment();
+    return groupNoBarrier()->compartment();
 }
 
 /* static */ inline TypeSet::Type
 TypeSet::ObjectType(JSObject* obj)
 {
     if (obj->isSingleton())
         return Type(uintptr_t(obj) | 1);
     return Type(uintptr_t(obj->group()));
--- a/js/src/vm/TypeInference.cpp
+++ b/js/src/vm/TypeInference.cpp
@@ -665,23 +665,31 @@ TypeSet::addType(Type type, LifoAlloc* a
 // used during Ion compilation, and if some ConstraintTypeSet contains nursery
 // pointers then any number of TemporaryTypeSets might as well. Thus, if there
 // are any such ConstraintTypeSets in existence, all off thread Ion
 // compilations are canceled by the next minor GC.
 class TypeSetRef : public BufferableRef
 {
     Zone* zone;
     ConstraintTypeSet* types;
+#ifdef DEBUG
+    uint64_t minorGCNumberAtCreation;
+#endif
 
   public:
     TypeSetRef(Zone* zone, ConstraintTypeSet* types)
-      : zone(zone), types(types)
+      : zone(zone)
+      , types(types)
+#ifdef DEBUG
+      , minorGCNumberAtCreation(zone->runtimeFromMainThread()->gc.minorGCCount())
+#endif
     {}
 
     void trace(JSTracer* trc) override {
+        MOZ_ASSERT(trc->runtime()->gc.minorGCCount() == minorGCNumberAtCreation);
         types->trace(zone, trc);
     }
 };
 
 void
 ConstraintTypeSet::postWriteBarrier(JSContext* cx, Type type)
 {
     if (type.isSingletonUnchecked() && IsInsideNursery(type.singletonNoBarrier())) {
@@ -4139,16 +4147,43 @@ ConstraintTypeSet::trace(Zone* zone, JST
                   MemCheckKind::MakeUndefined);
     } else if (objectCount == 1) {
         ObjectKey* key = (ObjectKey*) objectSet;
         TraceObjectKey(trc, &key);
         objectSet = reinterpret_cast<ObjectKey**>(key);
     } else {
         MOZ_RELEASE_ASSERT(!objectSet);
     }
+
+#ifdef DEBUG
+    MOZ_ASSERT(objectCount == baseObjectCount());
+    if (objectCount >= 2) {
+        unsigned capacity = TypeHashSet::Capacity(objectCount);
+        MOZ_ASSERT(uintptr_t(objectSet[-1]) == capacity);
+        for (unsigned i = 0; i < capacity; i++) {
+            ObjectKey* key = objectSet[i];
+            if (!key)
+                continue;
+            if (key->isGroup())
+                CheckGCThingAfterMovingGC(key->groupNoBarrier());
+            else
+                CheckGCThingAfterMovingGC(key->singletonNoBarrier());
+            JSCompartment* compartment = key->maybeCompartment();
+            MOZ_ASSERT_IF(compartment, compartment->zone() == zone);
+        }
+    } else if (objectCount == 1) {
+        ObjectKey* key = (ObjectKey*) objectSet;
+        if (key->isGroup())
+            CheckGCThingAfterMovingGC(key->groupNoBarrier());
+        else
+            CheckGCThingAfterMovingGC(key->singletonNoBarrier());
+        JSCompartment* compartment = key->maybeCompartment();
+        MOZ_ASSERT_IF(compartment, compartment->zone() == zone);
+    }
+#endif
 }
 
 static inline void
 AssertGCStateForSweep(Zone* zone)
 {
     MOZ_ASSERT(zone->isGCSweepingOrCompacting());
 
     // IsAboutToBeFinalized doesn't work right on tenured objects when called