Bug 1460957 - Make shadow::Symbol to remove mayBeOwnedByOtherRuntimeSlow, r=jonco
authorSteve Fink <sfink@mozilla.com>
Thu, 10 May 2018 22:02:59 -0700
changeset 418240 8fad63bd942ea0feb2ddd9221bbcd3ff2b295e7c
parent 418239 7aa19a11e2e3a1a376696556434f7b45ca4f3ef9
child 418241 0dde66eb4736c118f744659b1739f300f1e5a621
push id103258
push usersfink@mozilla.com
push dateMon, 14 May 2018 22:35:23 +0000
treeherdermozilla-inbound@8fad63bd942e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjonco
bugs1460957
milestone62.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 1460957 - Make shadow::Symbol to remove mayBeOwnedByOtherRuntimeSlow, r=jonco
js/public/HeapAPI.h
js/src/gc/GC.cpp
js/src/jsapi.h
js/src/vm/SymbolType.h
--- a/js/public/HeapAPI.h
+++ b/js/public/HeapAPI.h
@@ -230,16 +230,25 @@ struct String
     }
 
     static bool isPermanentAtom(const js::gc::Cell* cell) {
         uint32_t flags = reinterpret_cast<const String*>(cell)->flags;
         return (flags & PERMANENT_ATOM_MASK) == PERMANENT_ATOM_FLAGS;
     }
 };
 
+struct Symbol {
+    uint32_t code_;
+    static const uint32_t WellKnownAPILimit = 0x80000000;
+
+    static bool isWellKnownSymbol(const js::gc::Cell* cell) {
+        return reinterpret_cast<const Symbol*>(cell)->code_ < WellKnownAPILimit;
+    }
+};
+
 } /* namespace shadow */
 
 /**
  * A GC pointer, tagged with the trace kind.
  *
  * In general, a GC pointer should be stored with an exact type. This class
  * is for use when that is not possible because a single pointer must point
  * to several kinds of GC thing.
@@ -305,17 +314,18 @@ class JS_FRIEND_API(GCCellPtr)
         return reinterpret_cast<uintptr_t>(asCell());
     }
 
     MOZ_ALWAYS_INLINE bool mayBeOwnedByOtherRuntime() const {
         if (!is<JSString>() && !is<JS::Symbol>())
             return false;
         if (is<JSString>())
             return JS::shadow::String::isPermanentAtom(asCell());
-        return mayBeOwnedByOtherRuntimeSlow();
+        MOZ_ASSERT(is<JS::Symbol>());
+        return JS::shadow::Symbol::isWellKnownSymbol(asCell());
     }
 
   private:
     static uintptr_t checkedCast(void* p, JS::TraceKind traceKind) {
         js::gc::Cell* cell = static_cast<js::gc::Cell*>(p);
         MOZ_ASSERT((uintptr_t(p) & OutOfLineTraceKindMask) == 0);
         AssertGCThingHasType(cell, traceKind);
         // Note: the OutOfLineTraceKindMask bits are set on all out-of-line kinds
--- a/js/src/gc/GC.cpp
+++ b/js/src/gc/GC.cpp
@@ -8443,23 +8443,16 @@ JS::GCCellPtr::GCCellPtr(const Value& v)
 JS::TraceKind
 JS::GCCellPtr::outOfLineKind() const
 {
     MOZ_ASSERT((ptr & OutOfLineTraceKindMask) == OutOfLineTraceKindMask);
     MOZ_ASSERT(asCell()->isTenured());
     return MapAllocToTraceKind(asCell()->asTenured().getAllocKind());
 }
 
-bool
-JS::GCCellPtr::mayBeOwnedByOtherRuntimeSlow() const
-{
-    MOZ_ASSERT(is<Symbol>());
-    return as<Symbol>().isWellKnownSymbol();
-}
-
 #ifdef JSGC_HASH_TABLE_CHECKS
 void
 js::gc::CheckHashTablesAfterMovingGC(JSRuntime* rt)
 {
     /*
      * Check that internal hash tables no longer have any pointers to things
      * that have been moved.
      */
--- a/js/src/jsapi.h
+++ b/js/src/jsapi.h
@@ -5038,16 +5038,17 @@ GetSymbolDescription(HandleSymbol symbol
     macro(asyncIterator)
 
 enum class SymbolCode : uint32_t {
     // There is one SymbolCode for each well-known symbol.
 #define JS_DEFINE_SYMBOL_ENUM(name) name,
     JS_FOR_EACH_WELL_KNOWN_SYMBOL(JS_DEFINE_SYMBOL_ENUM)  // SymbolCode::iterator, etc.
 #undef JS_DEFINE_SYMBOL_ENUM
     Limit,
+    WellKnownAPILimit = 0x80000000, // matches JS::shadow::Symbol::WellKnownAPILimit for inline use
     InSymbolRegistry = 0xfffffffe,  // created by Symbol.for() or JS::GetSymbolFor()
     UniqueSymbol = 0xffffffff       // created by Symbol() or JS::NewSymbol()
 };
 
 /* For use in loops that iterate over the well-known symbols. */
 const size_t WellKnownSymbolLimit = size_t(SymbolCode::Limit);
 
 /**
--- a/js/src/vm/SymbolType.h
+++ b/js/src/vm/SymbolType.h
@@ -12,16 +12,17 @@
 #include <stdio.h>
 
 #include "jsapi.h"
 
 #include "gc/Barrier.h"
 #include "gc/Tracer.h"
 #include "js/AllocPolicy.h"
 #include "js/GCHashTable.h"
+#include "js/HeapAPI.h"
 #include "js/RootingAPI.h"
 #include "js/TypeDecls.h"
 #include "js/Utility.h"
 #include "vm/Printer.h"
 #include "vm/StringType.h"
 
 namespace js {
 class AutoLockForExclusiveAccess;
@@ -45,16 +46,18 @@ class Symbol : public js::gc::TenuredCel
     // the minimum size on both.
     size_t unused_;
 
     Symbol(SymbolCode code, js::HashNumber hash, JSAtom* desc)
         : code_(code), hash_(hash), description_(desc)
     {
         // Silence warnings about unused_ being... unused.
         (void)unused_;
+        static_assert(uint32_t(SymbolCode::WellKnownAPILimit) == JS::shadow::Symbol::WellKnownAPILimit,
+                      "JS::shadow::Symbol::WellKnownAPILimit must match SymbolCode::WellKnownAPILimit");
     }
 
     Symbol(const Symbol&) = delete;
     void operator=(const Symbol&) = delete;
 
     static Symbol*
     newInternal(JSContext* cx, SymbolCode code, js::HashNumber hash,
                 JSAtom* description, js::AutoLockForExclusiveAccess& lock);