Bug 1152177 - Make jsid and Value pre barriers symetrical. r=jonco, a=2.1+
authorTerrence Cole <terrence@mozilla.com>
Fri, 10 Apr 2015 08:58:26 -0700
changeset 222026 685fa69b59dc6793ed8bda65f530b2f5a1c1673d
parent 222025 b85d4f4a6d61c015610779474deb3522758fb4d6
child 222027 6a68a038146a016169afa3f8a9a1680da0a8f43a
push id475
push userryanvm@gmail.com
push dateTue, 21 Apr 2015 20:56:23 +0000
treeherdermozilla-b2g34_v2_1@685fa69b59dc [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjonco, 2
bugs1152177
milestone34.0
Bug 1152177 - Make jsid and Value pre barriers symetrical. r=jonco, a=2.1+
js/src/gc/Barrier.h
--- a/js/src/gc/Barrier.h
+++ b/js/src/gc/Barrier.h
@@ -370,16 +370,23 @@ MOZ_ALWAYS_INLINE JS::Zone*
 ZoneOfValueFromAnyThread(const JS::Value& value)
 {
     JS_ASSERT(value.isMarkable());
     if (value.isObject())
         return ZoneOfObjectFromAnyThread(value.toObject());
     return static_cast<js::gc::Cell*>(value.toGCThing())->tenuredZoneFromAnyThread();
 }
 
+MOZ_ALWAYS_INLINE JS::Zone*
+ZoneOfIdFromAnyThread(const jsid& id)
+{
+    MOZ_ASSERT(JSID_IS_GCTHING(id));
+    return static_cast<gc::Cell*>(JSID_TO_GCTHING(id))->tenuredZoneFromAnyThread();
+}
+
 void
 ValueReadBarrier(const Value& value);
 
 template <typename T>
 struct InternalGCMethods {};
 
 template <typename T>
 struct InternalGCMethods<T*>
@@ -470,42 +477,55 @@ struct InternalGCMethods<Value>
         JS::shadow::Runtime* shadowRuntime = JS::shadow::Runtime::asShadowRuntime(rt);
         shadowRuntime->gcStoreBufferPtr()->removeRelocatableValueFromAnyThread(vp);
 #endif
     }
 
     static void readBarrier(const Value& v) { ValueReadBarrier(v); }
 };
 
+namespace gc {
+void
+MarkIdUnbarriered(JSTracer* trc, jsid* id, const char* name);
+} // namespace gc
+
 template <>
 struct InternalGCMethods<jsid>
 {
     static bool isMarkable(jsid id) { return JSID_IS_STRING(id) || JSID_IS_SYMBOL(id); }
 
     static void preBarrier(jsid id) {
 #ifdef JSGC_INCREMENTAL
-        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");
-                JS_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");
-                JS_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);
+#endif
+    }
+  private:
+    static JSRuntime* runtimeFromAnyThread(jsid id) {
+        MOZ_ASSERT(JSID_IS_GCTHING(id));
+        return static_cast<gc::Cell*>(JSID_TO_GCTHING(id))->runtimeFromAnyThread();
+    }
+    static JS::shadow::Runtime* shadowRuntimeFromAnyThread(jsid id) {
+        return reinterpret_cast<JS::shadow::Runtime*>(runtimeFromAnyThread(id));
+    }
+    static void preBarrierImpl(Zone *zone, jsid id) {
+#ifdef JSGC_INCREMENTAL
+        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);
         }
 #endif
     }
-    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 {};