Bug 1152177 - Make jsid and Value pre barriers symetrical. r=jonco, a=abillings
authorTerrence Cole <terrence@mozilla.com>
Fri, 10 Apr 2015 08:58:26 -0700
changeset 258515 d79194507f32
parent 258514 6103268d785d
child 258516 18b8b10f2fbd
push id4685
push userryanvm@gmail.com
push date2015-04-17 14:50 +0000
treeherdermozilla-beta@e1dd0d7756c5 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjonco, abillings
bugs1152177
milestone38.0
Bug 1152177 - Make jsid and Value pre barriers symetrical. r=jonco, a=abillings
js/src/gc/Barrier.h
--- a/js/src/gc/Barrier.h
+++ b/js/src/gc/Barrier.h
@@ -236,19 +236,17 @@ template <> struct MapTypeToTraceKind<Ob
 
 // Direct value access used by the write barriers and the jits.
 void
 MarkValueUnbarriered(JSTracer* trc, Value* v, const char* name);
 
 // These three declarations are also present in gc/Marking.h, via the DeclMarker
 // macro.  Not great, but hard to avoid.
 void
-MarkStringUnbarriered(JSTracer* trc, JSString** str, const char* name);
-void
-MarkSymbolUnbarriered(JSTracer* trc, JS::Symbol** sym, const char* name);
+MarkIdUnbarriered(JSTracer* trc, jsid* idp, const char* name);
 
 } // namespace gc
 
 // This context is more basal than the GC things being implemented, so C++ does
 // not know about the inheritance hierarchy yet.
 static inline const gc::TenuredCell* AsTenuredCell(const JSString* str) {
     return reinterpret_cast<const gc::TenuredCell*>(str);
 }
@@ -281,29 +279,35 @@ MOZ_ALWAYS_INLINE JS::Zone*
 ZoneOfValueFromAnyThread(const JS::Value& value)
 {
     MOZ_ASSERT(value.isMarkable());
     if (value.isObject())
         return ZoneOfObjectFromAnyThread(value.toObject());
     return js::gc::TenuredCell::fromPointer(value.toGCThing())->zoneFromAnyThread();
 }
 
+MOZ_ALWAYS_INLINE JS::Zone*
+ZoneOfIdFromAnyThread(const jsid& id)
+{
+    MOZ_ASSERT(JSID_IS_GCTHING(id));
+    return js::gc::TenuredCell::fromPointer(JSID_TO_GCTHING(id).asCell())->zoneFromAnyThread();
+}
+
 void
 ValueReadBarrier(const Value& value);
 
 template <typename T>
 struct InternalGCMethods {};
 
 template <typename T>
 struct InternalGCMethods<T*>
 {
     static bool isMarkable(T* v) { return v != nullptr; }
 
     static void preBarrier(T* v) { T::writeBarrierPre(v); }
-    static void preBarrier(Zone* zone, T* v) { T::writeBarrierPre(zone, v); }
 
     static void postBarrier(T** vp) { T::writeBarrierPost(*vp, vp); }
     static void postBarrierRelocate(T** vp) { T::writeBarrierPostRelocate(*vp, vp); }
     static void postBarrierRemove(T** vp) { T::writeBarrierPostRemove(*vp, vp); }
 
     static void readBarrier(T* v) { T::readBarrier(v); }
 };
 
@@ -377,34 +381,41 @@ struct InternalGCMethods<Value>
 };
 
 template <>
 struct InternalGCMethods<jsid>
 {
     static bool isMarkable(jsid id) { return JSID_IS_STRING(id) || JSID_IS_SYMBOL(id); }
 
     static void preBarrier(jsid id) {
-        if (JSID_IS_STRING(id)) {
-            JSString* str = JSID_TO_STRING(id);
-            JS::shadow::Zone* shadowZone = ShadowZoneOfStringFromAnyThread(str);
-            if (shadowZone->needsIncrementalBarrier()) {
-                js::gc::MarkStringUnbarriered(shadowZone->barrierTracer(), &str, "write barrier");
-                MOZ_ASSERT(str == JSID_TO_STRING(id));
-            }
-        } else if (JSID_IS_SYMBOL(id)) {
-            JS::Symbol* sym = JSID_TO_SYMBOL(id);
-            JS::shadow::Zone* shadowZone = ShadowZoneOfSymbolFromAnyThread(sym);
-            if (shadowZone->needsIncrementalBarrier()) {
-                js::gc::MarkSymbolUnbarriered(shadowZone->barrierTracer(), &sym, "write barrier");
-                MOZ_ASSERT(sym == JSID_TO_SYMBOL(id));
-            }
+        MOZ_ASSERT(!CurrentThreadIsIonCompiling());
+        if (JSID_IS_STRING(id) && StringIsPermanentAtom(JSID_TO_STRING(id)))
+            return;
+        if (JSID_IS_GCTHING(id) && shadowRuntimeFromAnyThread(id)->needsIncrementalBarrier())
+            preBarrierImpl(ZoneOfIdFromAnyThread(id), id);
+    }
+
+  private:
+    static JSRuntime* runtimeFromAnyThread(jsid id) {
+        MOZ_ASSERT(JSID_IS_GCTHING(id));
+        return JSID_TO_GCTHING(id).asCell()->runtimeFromAnyThread();
+    }
+    static JS::shadow::Runtime* shadowRuntimeFromAnyThread(jsid id) {
+        return reinterpret_cast<JS::shadow::Runtime*>(runtimeFromAnyThread(id));
+    }
+    static void preBarrierImpl(Zone *zone, jsid id) {
+        JS::shadow::Zone* shadowZone = JS::shadow::Zone::asShadowZone(zone);
+        if (shadowZone->needsIncrementalBarrier()) {
+            jsid tmp(id);
+            js::gc::MarkIdUnbarriered(shadowZone->barrierTracer(), &tmp, "id write barrier");
+            MOZ_ASSERT(tmp == id);
         }
     }
-    static void preBarrier(Zone* zone, jsid id) { preBarrier(id); }
 
+  public:
     static void postBarrier(jsid* idp) {}
     static void postBarrierRelocate(jsid* idp) {}
     static void postBarrierRemove(jsid* idp) {}
 };
 
 template <typename T>
 class BarrieredBaseMixins {};