Bug 1384513 - Change all public APIs to take JS::AutoRequireNoGC instead of JS::AutoCheckCannotGC. r=jonco
authorTill Schneidereit <till@tillschneidereit.net>
Wed, 26 Jul 2017 12:20:59 +0200
changeset 419998 000f28217a30b8cf649573ad2f52a03a8b426ef7
parent 419997 753fd959084178188123c48f52f7f4196a387108
child 419999 19f1250e37cdaafb4b608f2f4c188da3d20e5bef
push id7566
push usermtabara@mozilla.com
push dateWed, 02 Aug 2017 08:25:16 +0000
treeherdermozilla-beta@86913f512c3c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjonco
bugs1384513
milestone56.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 1384513 - Change all public APIs to take JS::AutoRequireNoGC instead of JS::AutoCheckCannotGC. r=jonco Additionally, change the base class of AutoSuppressGCAnalysis from AutoAssertNoAlloc to AutoAssertNoGC. In combination, these chances enable passing either JS::AutoCheckCannotGC or JS::AutoSuppressGCAnalysis, depending on whether suppressing the GC analysis is desired or not. MozReview-Commit-ID: Eg1cl28ezeJ
js/public/GCAPI.h
js/public/UbiNodeBreadthFirst.h
js/src/builtin/DataViewObject.cpp
js/src/jsapi-tests/testTypedArrays.cpp
js/src/jsapi.cpp
js/src/jsapi.h
js/src/jsfriendapi.h
js/src/jsgc.cpp
js/src/vm/ArrayBufferObject.cpp
js/src/vm/SharedArrayObject.cpp
js/src/vm/String.h
js/src/vm/TypedArrayObject.cpp
--- a/js/public/GCAPI.h
+++ b/js/public/GCAPI.h
@@ -527,56 +527,34 @@ class JS_PUBLIC_API(AutoAssertNoGC) : pu
     JSContext* cx_;
 
   public:
     explicit AutoAssertNoGC(JSContext* cx = nullptr);
     ~AutoAssertNoGC();
 };
 
 /**
- * Assert if an allocation of a GC thing occurs while this class is live. This
- * class does not disable the static rooting hazard analysis.
- */
-class JS_PUBLIC_API(AutoAssertNoAlloc)
-{
-#ifdef JS_DEBUG
-    js::gc::GCRuntime* gc;
-
-  public:
-    AutoAssertNoAlloc() : gc(nullptr) {}
-    explicit AutoAssertNoAlloc(JSContext* cx);
-    void disallowAlloc(JSRuntime* rt);
-    ~AutoAssertNoAlloc();
-#else
-  public:
-    AutoAssertNoAlloc() {}
-    explicit AutoAssertNoAlloc(JSContext* cx) {}
-    void disallowAlloc(JSRuntime* rt) {}
-#endif
-};
-
-/**
  * Disable the static rooting hazard analysis in the live region and assert if
  * any allocation that could potentially trigger a GC occurs while this guard
  * object is live. This is most useful to help the exact rooting hazard analysis
  * in complex regions, since it cannot understand dataflow.
  *
  * Note: GC behavior is unpredictable even when deterministic and is generally
  *       non-deterministic in practice. The fact that this guard has not
  *       asserted is not a guarantee that a GC cannot happen in the guarded
  *       region. As a rule, anyone performing a GC unsafe action should
  *       understand the GC properties of all code in that region and ensure
  *       that the hazard analysis is correct for that code, rather than relying
  *       on this class.
  */
-class JS_PUBLIC_API(AutoSuppressGCAnalysis) : public AutoAssertNoAlloc
+class JS_PUBLIC_API(AutoSuppressGCAnalysis) : public AutoAssertNoGC
 {
   public:
-    AutoSuppressGCAnalysis() : AutoAssertNoAlloc() {}
-    explicit AutoSuppressGCAnalysis(JSContext* cx) : AutoAssertNoAlloc(cx) {}
+    AutoSuppressGCAnalysis() : AutoAssertNoGC() {}
+    explicit AutoSuppressGCAnalysis(JSContext* cx) : AutoAssertNoGC(cx) {}
 } JS_HAZ_GC_SUPPRESSED;
 
 /**
  * Assert that code is only ever called from a GC callback, disable the static
  * rooting hazard analysis and assert if any allocation that could potentially
  * trigger a GC occurs while this guard object is live.
  *
  * This is useful to make the static analysis ignore code that runs in GC
--- a/js/public/UbiNodeBreadthFirst.h
+++ b/js/public/UbiNodeBreadthFirst.h
@@ -78,17 +78,17 @@ template<typename Handler>
 struct BreadthFirst {
 
     // Construct a breadth-first traversal object that reports the nodes it
     // reaches to |handler|. The traversal asserts that no GC happens in its
     // runtime during its lifetime.
     //
     // We do nothing with noGC, other than require it to exist, with a lifetime
     // that encloses our own.
-    BreadthFirst(JSContext* cx, Handler& handler, const JS::AutoCheckCannotGC& noGC)
+    BreadthFirst(JSContext* cx, Handler& handler, const JS::AutoRequireNoGC& noGC)
       : wantNames(true), cx(cx), visited(), handler(handler), pending(),
         traversalBegun(false), stopRequested(false), abandonRequested(false)
     { }
 
     // Initialize this traversal object. Return false on OOM.
     bool init() { return visited.init(); }
 
     // Add |node| as a starting point for the traversal. You may add
--- a/js/src/builtin/DataViewObject.cpp
+++ b/js/src/builtin/DataViewObject.cpp
@@ -1008,17 +1008,17 @@ JS_GetDataViewByteOffset(JSObject* obj)
 {
     obj = CheckedUnwrap(obj);
     if (!obj)
         return 0;
     return obj->as<DataViewObject>().byteOffset();
 }
 
 JS_FRIEND_API(void*)
-JS_GetDataViewData(JSObject* obj, bool* isSharedMemory, const JS::AutoCheckCannotGC&)
+JS_GetDataViewData(JSObject* obj, bool* isSharedMemory, const JS::AutoRequireNoGC&)
 {
     obj = CheckedUnwrap(obj);
     if (!obj)
         return nullptr;
     DataViewObject& dv = obj->as<DataViewObject>();
     *isSharedMemory = dv.isSharedMemory();
     return dv.dataPointerEither().unwrap(/*safe - caller sees isSharedMemory*/);
 }
--- a/js/src/jsapi-tests/testTypedArrays.cpp
+++ b/js/src/jsapi-tests/testTypedArrays.cpp
@@ -68,17 +68,17 @@ BEGIN_TEST(testTypedArrays)
     return ok;
 }
 
 // Shared memory can only be mapped by a TypedArray by creating the
 // TypedArray with a SharedArrayBuffer explicitly, so no tests here.
 
 template<JSObject* Create(JSContext*, uint32_t),
          typename Element,
-         Element* GetData(JSObject*, bool* isShared, const JS::AutoCheckCannotGC&)>
+         Element* GetData(JSObject*, bool* isShared, const JS::AutoRequireNoGC&)>
 bool
 TestPlainTypedArray(JSContext* cx)
 {
     {
         RootedObject notArray(cx, Create(cx, UINT32_MAX));
         CHECK(!notArray);
     }
 
@@ -106,17 +106,17 @@ TestPlainTypedArray(JSContext* cx)
 
     return true;
 }
 
 template<JSObject* CreateWithBuffer(JSContext*, JS::HandleObject, uint32_t, int32_t),
          JSObject* CreateFromArray(JSContext*, JS::HandleObject),
          typename Element,
          bool Shared,
-         Element* GetData(JSObject*, bool*, const JS::AutoCheckCannotGC&)>
+         Element* GetData(JSObject*, bool*, const JS::AutoRequireNoGC&)>
 bool
 TestArrayFromBuffer(JSContext* cx)
 {
     if (Shared && !cx->compartment()->creationOptions().getSharedMemoryAndAtomicsEnabled())
         return true;
 
     size_t elts = 8;
     size_t nbytes = elts * sizeof(Element);
--- a/js/src/jsapi.cpp
+++ b/js/src/jsapi.cpp
@@ -5447,32 +5447,32 @@ JS_StringIsFlat(JSString* str)
 
 JS_PUBLIC_API(bool)
 JS_StringHasLatin1Chars(JSString* str)
 {
     return str->hasLatin1Chars();
 }
 
 JS_PUBLIC_API(const JS::Latin1Char*)
-JS_GetLatin1StringCharsAndLength(JSContext* cx, const JS::AutoCheckCannotGC& nogc, JSString* str,
+JS_GetLatin1StringCharsAndLength(JSContext* cx, const JS::AutoRequireNoGC& nogc, JSString* str,
                                  size_t* plength)
 {
     MOZ_ASSERT(plength);
     AssertHeapIsIdleOrStringIsFlat(str);
     CHECK_REQUEST(cx);
     assertSameCompartment(cx, str);
     JSLinearString* linear = str->ensureLinear(cx);
     if (!linear)
         return nullptr;
     *plength = linear->length();
     return linear->latin1Chars(nogc);
 }
 
 JS_PUBLIC_API(const char16_t*)
-JS_GetTwoByteStringCharsAndLength(JSContext* cx, const JS::AutoCheckCannotGC& nogc, JSString* str,
+JS_GetTwoByteStringCharsAndLength(JSContext* cx, const JS::AutoRequireNoGC& nogc, JSString* str,
                                   size_t* plength)
 {
     MOZ_ASSERT(plength);
     AssertHeapIsIdleOrStringIsFlat(str);
     CHECK_REQUEST(cx);
     assertSameCompartment(cx, str);
     JSLinearString* linear = str->ensureLinear(cx);
     if (!linear)
@@ -5520,27 +5520,27 @@ JS_CopyStringChars(JSContext* cx, mozill
         return false;
 
     MOZ_ASSERT(linear->length() <= dest.length());
     CopyChars(dest.begin().get(), *linear);
     return true;
 }
 
 JS_PUBLIC_API(const Latin1Char*)
-JS_GetLatin1InternedStringChars(const JS::AutoCheckCannotGC& nogc, JSString* str)
+JS_GetLatin1InternedStringChars(const JS::AutoRequireNoGC& nogc, JSString* str)
 {
     MOZ_ASSERT(str->isAtom());
     JSFlatString* flat = str->ensureFlat(nullptr);
     if (!flat)
         return nullptr;
     return flat->latin1Chars(nogc);
 }
 
 JS_PUBLIC_API(const char16_t*)
-JS_GetTwoByteInternedStringChars(const JS::AutoCheckCannotGC& nogc, JSString* str)
+JS_GetTwoByteInternedStringChars(const JS::AutoRequireNoGC& nogc, JSString* str)
 {
     MOZ_ASSERT(str->isAtom());
     JSFlatString* flat = str->ensureFlat(nullptr);
     if (!flat)
         return nullptr;
     return flat->twoByteChars(nogc);
 }
 
@@ -5552,23 +5552,23 @@ JS_FlattenString(JSContext* cx, JSString
     assertSameCompartment(cx, str);
     JSFlatString* flat = str->ensureFlat(cx);
     if (!flat)
         return nullptr;
     return flat;
 }
 
 extern JS_PUBLIC_API(const Latin1Char*)
-JS_GetLatin1FlatStringChars(const JS::AutoCheckCannotGC& nogc, JSFlatString* str)
+JS_GetLatin1FlatStringChars(const JS::AutoRequireNoGC& nogc, JSFlatString* str)
 {
     return str->latin1Chars(nogc);
 }
 
 extern JS_PUBLIC_API(const char16_t*)
-JS_GetTwoByteFlatStringChars(const JS::AutoCheckCannotGC& nogc, JSFlatString* str)
+JS_GetTwoByteFlatStringChars(const JS::AutoRequireNoGC& nogc, JSFlatString* str)
 {
     return str->twoByteChars(nogc);
 }
 
 JS_PUBLIC_API(bool)
 JS_CompareStrings(JSContext* cx, JSString* str1, JSString* str2, int32_t* result)
 {
     AssertHeapIsIdle();
--- a/js/src/jsapi.h
+++ b/js/src/jsapi.h
@@ -5000,21 +5000,21 @@ JS_GetStringLength(JSString* str);
 extern JS_PUBLIC_API(bool)
 JS_StringIsFlat(JSString* str);
 
 /** Returns true iff the string's characters are stored as Latin1. */
 extern JS_PUBLIC_API(bool)
 JS_StringHasLatin1Chars(JSString* str);
 
 extern JS_PUBLIC_API(const JS::Latin1Char*)
-JS_GetLatin1StringCharsAndLength(JSContext* cx, const JS::AutoCheckCannotGC& nogc, JSString* str,
+JS_GetLatin1StringCharsAndLength(JSContext* cx, const JS::AutoRequireNoGC& nogc, JSString* str,
                                  size_t* length);
 
 extern JS_PUBLIC_API(const char16_t*)
-JS_GetTwoByteStringCharsAndLength(JSContext* cx, const JS::AutoCheckCannotGC& nogc, JSString* str,
+JS_GetTwoByteStringCharsAndLength(JSContext* cx, const JS::AutoRequireNoGC& nogc, JSString* str,
                                   size_t* length);
 
 extern JS_PUBLIC_API(bool)
 JS_GetStringCharAt(JSContext* cx, JSString* str, size_t index, char16_t* res);
 
 extern JS_PUBLIC_API(char16_t)
 JS_GetFlatStringCharAt(JSFlatString* str, size_t index);
 
@@ -5023,20 +5023,20 @@ JS_GetTwoByteExternalStringChars(JSStrin
 
 extern JS_PUBLIC_API(bool)
 JS_CopyStringChars(JSContext* cx, mozilla::Range<char16_t> dest, JSString* str);
 
 extern JS_PUBLIC_API(JSFlatString*)
 JS_FlattenString(JSContext* cx, JSString* str);
 
 extern JS_PUBLIC_API(const JS::Latin1Char*)
-JS_GetLatin1FlatStringChars(const JS::AutoCheckCannotGC& nogc, JSFlatString* str);
+JS_GetLatin1FlatStringChars(const JS::AutoRequireNoGC& nogc, JSFlatString* str);
 
 extern JS_PUBLIC_API(const char16_t*)
-JS_GetTwoByteFlatStringChars(const JS::AutoCheckCannotGC& nogc, JSFlatString* str);
+JS_GetTwoByteFlatStringChars(const JS::AutoRequireNoGC& nogc, JSFlatString* str);
 
 static MOZ_ALWAYS_INLINE JSFlatString*
 JSID_TO_FLAT_STRING(jsid id)
 {
     MOZ_ASSERT(JSID_IS_STRING(id));
     return (JSFlatString*)(JSID_BITS(id));
 }
 
--- a/js/src/jsfriendapi.h
+++ b/js/src/jsfriendapi.h
@@ -813,29 +813,29 @@ AtomHasLatin1Chars(JSAtom* atom)
 
 MOZ_ALWAYS_INLINE bool
 StringHasLatin1Chars(JSString* s)
 {
     return reinterpret_cast<shadow::String*>(s)->flags & shadow::String::LATIN1_CHARS_BIT;
 }
 
 MOZ_ALWAYS_INLINE const JS::Latin1Char*
-GetLatin1LinearStringChars(const JS::AutoCheckCannotGC& nogc, JSLinearString* linear)
+GetLatin1LinearStringChars(const JS::AutoRequireNoGC& nogc, JSLinearString* linear)
 {
     MOZ_ASSERT(LinearStringHasLatin1Chars(linear));
 
     using shadow::String;
     String* s = reinterpret_cast<String*>(linear);
     if (s->flags & String::INLINE_CHARS_BIT)
         return s->inlineStorageLatin1;
     return s->nonInlineCharsLatin1;
 }
 
 MOZ_ALWAYS_INLINE const char16_t*
-GetTwoByteLinearStringChars(const JS::AutoCheckCannotGC& nogc, JSLinearString* linear)
+GetTwoByteLinearStringChars(const JS::AutoRequireNoGC& nogc, JSLinearString* linear)
 {
     MOZ_ASSERT(!LinearStringHasLatin1Chars(linear));
 
     using shadow::String;
     String* s = reinterpret_cast<String*>(linear);
     if (s->flags & String::INLINE_CHARS_BIT)
         return s->inlineStorageTwoByte;
     return s->nonInlineCharsTwoByte;
@@ -855,23 +855,23 @@ AtomToFlatString(JSAtom* atom)
 
 MOZ_ALWAYS_INLINE JSLinearString*
 FlatStringToLinearString(JSFlatString* s)
 {
     return reinterpret_cast<JSLinearString*>(s);
 }
 
 MOZ_ALWAYS_INLINE const JS::Latin1Char*
-GetLatin1AtomChars(const JS::AutoCheckCannotGC& nogc, JSAtom* atom)
+GetLatin1AtomChars(const JS::AutoRequireNoGC& nogc, JSAtom* atom)
 {
     return GetLatin1LinearStringChars(nogc, AtomToLinearString(atom));
 }
 
 MOZ_ALWAYS_INLINE const char16_t*
-GetTwoByteAtomChars(const JS::AutoCheckCannotGC& nogc, JSAtom* atom)
+GetTwoByteAtomChars(const JS::AutoRequireNoGC& nogc, JSAtom* atom)
 {
     return GetTwoByteLinearStringChars(nogc, AtomToLinearString(atom));
 }
 
 MOZ_ALWAYS_INLINE bool
 IsExternalString(JSString* str, const JSStringFinalizer** fin, const char16_t** chars)
 {
     using shadow::String;
@@ -1949,17 +1949,17 @@ GetArrayBufferLengthAndData(JSObject* ob
 // There is an isShared out argument for API consistency (eases use from DOM).
 // It will always be set to true.
 extern JS_FRIEND_API(void)
 GetSharedArrayBufferLengthAndData(JSObject* obj, uint32_t* length, bool* isSharedMemory, uint8_t** data);
 
 } // namespace js
 
 JS_FRIEND_API(uint8_t*)
-JS_GetSharedArrayBufferData(JSObject* obj, bool* isSharedMemory, const JS::AutoCheckCannotGC&);
+JS_GetSharedArrayBufferData(JSObject* obj, bool* isSharedMemory, const JS::AutoRequireNoGC&);
 
 /*
  * Unwrap Typed arrays all at once. Return nullptr without throwing if the
  * object cannot be viewed as the correct typed array, or the typed array
  * object on success, filling both outparameters.
  */
 extern JS_FRIEND_API(JSObject*)
 JS_GetObjectAsInt8Array(JSObject* obj, uint32_t* length, bool* isSharedMemory, int8_t** data);
@@ -2047,17 +2047,17 @@ JS_ArrayBufferHasData(JSObject* obj);
  * |obj| must have passed a JS_IsArrayBufferObject test, or somehow be known
  * that it would pass such a test: it is an ArrayBuffer or a wrapper of an
  * ArrayBuffer, and the unwrapping will succeed.
  *
  * |*isSharedMemory| will be set to false, the argument is present to simplify
  * its use from code that also interacts with SharedArrayBuffer.
  */
 extern JS_FRIEND_API(uint8_t*)
-JS_GetArrayBufferData(JSObject* obj, bool* isSharedMemory, const JS::AutoCheckCannotGC&);
+JS_GetArrayBufferData(JSObject* obj, bool* isSharedMemory, const JS::AutoRequireNoGC&);
 
 /**
  * Check whether the obj is ArrayBufferObject and memory mapped. Note that this
  * may return false if a security wrapper is encountered that denies the
  * unwrapping.
  */
 extern JS_FRIEND_API(bool)
 JS_IsMappedArrayBufferObject(JSObject* obj);
@@ -2118,40 +2118,40 @@ JS_GetArrayBufferViewByteLength(JSObject
  * pass such a test: it is a typed array or a wrapper of a typed array, and the
  * unwrapping will succeed.
  *
  * |*isSharedMemory| will be set to true if the typed array maps a
  * SharedArrayBuffer, otherwise to false.
  */
 
 extern JS_FRIEND_API(int8_t*)
-JS_GetInt8ArrayData(JSObject* obj, bool* isSharedMemory, const JS::AutoCheckCannotGC&);
+JS_GetInt8ArrayData(JSObject* obj, bool* isSharedMemory, const JS::AutoRequireNoGC&);
 extern JS_FRIEND_API(uint8_t*)
-JS_GetUint8ArrayData(JSObject* obj, bool* isSharedMemory, const JS::AutoCheckCannotGC&);
+JS_GetUint8ArrayData(JSObject* obj, bool* isSharedMemory, const JS::AutoRequireNoGC&);
 extern JS_FRIEND_API(uint8_t*)
-JS_GetUint8ClampedArrayData(JSObject* obj, bool* isSharedMemory, const JS::AutoCheckCannotGC&);
+JS_GetUint8ClampedArrayData(JSObject* obj, bool* isSharedMemory, const JS::AutoRequireNoGC&);
 extern JS_FRIEND_API(int16_t*)
-JS_GetInt16ArrayData(JSObject* obj, bool* isSharedMemory, const JS::AutoCheckCannotGC&);
+JS_GetInt16ArrayData(JSObject* obj, bool* isSharedMemory, const JS::AutoRequireNoGC&);
 extern JS_FRIEND_API(uint16_t*)
-JS_GetUint16ArrayData(JSObject* obj, bool* isSharedMemory, const JS::AutoCheckCannotGC&);
+JS_GetUint16ArrayData(JSObject* obj, bool* isSharedMemory, const JS::AutoRequireNoGC&);
 extern JS_FRIEND_API(int32_t*)
-JS_GetInt32ArrayData(JSObject* obj, bool* isSharedMemory, const JS::AutoCheckCannotGC&);
+JS_GetInt32ArrayData(JSObject* obj, bool* isSharedMemory, const JS::AutoRequireNoGC&);
 extern JS_FRIEND_API(uint32_t*)
-JS_GetUint32ArrayData(JSObject* obj, bool* isSharedMemory, const JS::AutoCheckCannotGC&);
+JS_GetUint32ArrayData(JSObject* obj, bool* isSharedMemory, const JS::AutoRequireNoGC&);
 extern JS_FRIEND_API(float*)
-JS_GetFloat32ArrayData(JSObject* obj, bool* isSharedMemory, const JS::AutoCheckCannotGC&);
+JS_GetFloat32ArrayData(JSObject* obj, bool* isSharedMemory, const JS::AutoRequireNoGC&);
 extern JS_FRIEND_API(double*)
-JS_GetFloat64ArrayData(JSObject* obj, bool* isSharedMemory, const JS::AutoCheckCannotGC&);
+JS_GetFloat64ArrayData(JSObject* obj, bool* isSharedMemory, const JS::AutoRequireNoGC&);
 
 /**
  * Same as above, but for any kind of ArrayBufferView. Prefer the type-specific
  * versions when possible.
  */
 extern JS_FRIEND_API(void*)
-JS_GetArrayBufferViewData(JSObject* obj, bool* isSharedMemory, const JS::AutoCheckCannotGC&);
+JS_GetArrayBufferViewData(JSObject* obj, bool* isSharedMemory, const JS::AutoRequireNoGC&);
 
 /**
  * Return the ArrayBuffer or SharedArrayBuffer underlying an ArrayBufferView.
  * This may return a detached buffer.  |obj| must be an object that would
  * return true for JS_IsArrayBufferViewObject().
  */
 extern JS_FRIEND_API(JSObject*)
 JS_GetArrayBufferViewBuffer(JSContext* cx, JS::HandleObject obj, bool* isSharedMemory);
@@ -2218,17 +2218,17 @@ JS_GetDataViewByteLength(JSObject* obj);
  * it would pass such a test: it is a data view or a wrapper of a data view,
  * and the unwrapping will succeed. If cx is nullptr, then DEBUG builds may be
  * unable to assert when unwrapping should be disallowed.
  *
  * |*isSharedMemory| will be set to true if the DataView maps a SharedArrayBuffer,
  * otherwise to false.
  */
 JS_FRIEND_API(void*)
-JS_GetDataViewData(JSObject* obj, bool* isSharedMemory, const JS::AutoCheckCannotGC&);
+JS_GetDataViewData(JSObject* obj, bool* isSharedMemory, const JS::AutoRequireNoGC&);
 
 namespace js {
 
 /**
  * Add a watchpoint -- in the Object.prototype.watch sense -- to |obj| for the
  * property |id|, using the callable object |callable| as the function to be
  * called for notifications.
  *
--- a/js/src/jsgc.cpp
+++ b/js/src/jsgc.cpp
@@ -7789,45 +7789,29 @@ js::gc::AssertGCThingHasType(js::gc::Cel
     else
         MOZ_ASSERT(MapAllocToTraceKind(cell->asTenured().getAllocKind()) == kind);
 }
 #endif
 
 JS::AutoAssertNoGC::AutoAssertNoGC(JSContext* maybecx)
   : cx_(maybecx ? maybecx : TlsContext.get())
 {
-    cx_->inUnsafeRegion++;
+    if (cx_)
+        cx_->inUnsafeRegion++;
 }
 
 JS::AutoAssertNoGC::~AutoAssertNoGC()
 {
-    MOZ_ASSERT(cx_->inUnsafeRegion > 0);
-    cx_->inUnsafeRegion--;
+    if (cx_) {
+        MOZ_ASSERT(cx_->inUnsafeRegion > 0);
+        cx_->inUnsafeRegion--;
+    }
 }
 
 #ifdef DEBUG
-JS::AutoAssertNoAlloc::AutoAssertNoAlloc(JSContext* cx)
-  : gc(nullptr)
-{
-    disallowAlloc(cx->runtime());
-}
-
-void JS::AutoAssertNoAlloc::disallowAlloc(JSRuntime* rt)
-{
-    MOZ_ASSERT(!gc);
-    gc = &rt->gc;
-    TlsContext.get()->disallowAlloc();
-}
-
-JS::AutoAssertNoAlloc::~AutoAssertNoAlloc()
-{
-    if (gc)
-        TlsContext.get()->allowAlloc();
-}
-
 AutoAssertNoNurseryAlloc::AutoAssertNoNurseryAlloc()
 {
     TlsContext.get()->disallowNurseryAlloc();
 }
 
 AutoAssertNoNurseryAlloc::~AutoAssertNoNurseryAlloc()
 {
     TlsContext.get()->allowNurseryAlloc();
--- a/js/src/vm/ArrayBufferObject.cpp
+++ b/js/src/vm/ArrayBufferObject.cpp
@@ -1610,17 +1610,17 @@ js::UnwrapArrayBufferView(JSObject* obj)
 JS_FRIEND_API(uint32_t)
 JS_GetArrayBufferByteLength(JSObject* obj)
 {
     obj = CheckedUnwrap(obj);
     return obj ? AsArrayBuffer(obj).byteLength() : 0;
 }
 
 JS_FRIEND_API(uint8_t*)
-JS_GetArrayBufferData(JSObject* obj, bool* isSharedMemory, const JS::AutoCheckCannotGC&)
+JS_GetArrayBufferData(JSObject* obj, bool* isSharedMemory, const JS::AutoRequireNoGC&)
 {
     obj = CheckedUnwrap(obj);
     if (!obj)
         return nullptr;
     if (!IsArrayBuffer(obj))
         return nullptr;
     *isSharedMemory = false;
     return AsArrayBuffer(obj).dataPointer();
@@ -1827,17 +1827,17 @@ JS_IsMappedArrayBufferObject(JSObject* o
     obj = CheckedUnwrap(obj);
     if (!obj)
         return false;
 
     return obj->is<ArrayBufferObject>() && obj->as<ArrayBufferObject>().isMapped();
 }
 
 JS_FRIEND_API(void*)
-JS_GetArrayBufferViewData(JSObject* obj, bool* isSharedMemory, const JS::AutoCheckCannotGC&)
+JS_GetArrayBufferViewData(JSObject* obj, bool* isSharedMemory, const JS::AutoRequireNoGC&)
 {
     obj = CheckedUnwrap(obj);
     if (!obj)
         return nullptr;
     if (obj->is<DataViewObject>()) {
         DataViewObject& dv = obj->as<DataViewObject>();
         *isSharedMemory = dv.isSharedMemory();
         return dv.dataPointerEither().unwrap(/*safe - caller sees isSharedMemory flag*/);
--- a/js/src/vm/SharedArrayObject.cpp
+++ b/js/src/vm/SharedArrayObject.cpp
@@ -508,16 +508,16 @@ JS_NewSharedArrayBuffer(JSContext* cx, u
 JS_FRIEND_API(bool)
 JS_IsSharedArrayBufferObject(JSObject* obj)
 {
     obj = CheckedUnwrap(obj);
     return obj ? obj->is<SharedArrayBufferObject>() : false;
 }
 
 JS_FRIEND_API(uint8_t*)
-JS_GetSharedArrayBufferData(JSObject* obj, bool* isSharedMemory, const JS::AutoCheckCannotGC&)
+JS_GetSharedArrayBufferData(JSObject* obj, bool* isSharedMemory, const JS::AutoRequireNoGC&)
 {
     obj = CheckedUnwrap(obj);
     if (!obj)
         return nullptr;
     *isSharedMemory = true;
     return obj->as<SharedArrayBufferObject>().dataPointerShared().unwrap(/*safe - caller knows*/);
 }
--- a/js/src/vm/String.h
+++ b/js/src/vm/String.h
@@ -647,52 +647,52 @@ class JSLinearString : public JSString
     }
 
     MOZ_ALWAYS_INLINE const JS::Latin1Char* rawLatin1Chars() const;
     MOZ_ALWAYS_INLINE const char16_t* rawTwoByteChars() const;
 
   public:
     template<typename CharT>
     MOZ_ALWAYS_INLINE
-    const CharT* nonInlineChars(const JS::AutoCheckCannotGC& nogc) const;
+    const CharT* nonInlineChars(const JS::AutoRequireNoGC& nogc) const;
 
     MOZ_ALWAYS_INLINE
-    const JS::Latin1Char* nonInlineLatin1Chars(const JS::AutoCheckCannotGC& nogc) const {
+    const JS::Latin1Char* nonInlineLatin1Chars(const JS::AutoRequireNoGC& nogc) const {
         MOZ_ASSERT(!isInline());
         MOZ_ASSERT(hasLatin1Chars());
         return d.s.u2.nonInlineCharsLatin1;
     }
 
     MOZ_ALWAYS_INLINE
-    const char16_t* nonInlineTwoByteChars(const JS::AutoCheckCannotGC& nogc) const {
+    const char16_t* nonInlineTwoByteChars(const JS::AutoRequireNoGC& nogc) const {
         MOZ_ASSERT(!isInline());
         MOZ_ASSERT(hasTwoByteChars());
         return d.s.u2.nonInlineCharsTwoByte;
     }
 
     template<typename CharT>
     MOZ_ALWAYS_INLINE
-    const CharT* chars(const JS::AutoCheckCannotGC& nogc) const;
+    const CharT* chars(const JS::AutoRequireNoGC& nogc) const;
 
     MOZ_ALWAYS_INLINE
-    const JS::Latin1Char* latin1Chars(const JS::AutoCheckCannotGC& nogc) const {
+    const JS::Latin1Char* latin1Chars(const JS::AutoRequireNoGC& nogc) const {
         return rawLatin1Chars();
     }
 
     MOZ_ALWAYS_INLINE
-    const char16_t* twoByteChars(const JS::AutoCheckCannotGC& nogc) const {
+    const char16_t* twoByteChars(const JS::AutoRequireNoGC& nogc) const {
         return rawTwoByteChars();
     }
 
-    mozilla::Range<const JS::Latin1Char> latin1Range(const JS::AutoCheckCannotGC& nogc) const {
+    mozilla::Range<const JS::Latin1Char> latin1Range(const JS::AutoRequireNoGC& nogc) const {
         MOZ_ASSERT(JSString::isLinear());
         return mozilla::Range<const JS::Latin1Char>(latin1Chars(nogc), length());
     }
 
-    mozilla::Range<const char16_t> twoByteRange(const JS::AutoCheckCannotGC& nogc) const {
+    mozilla::Range<const char16_t> twoByteRange(const JS::AutoRequireNoGC& nogc) const {
         MOZ_ASSERT(JSString::isLinear());
         return mozilla::Range<const char16_t>(twoByteChars(nogc), length());
     }
 
     MOZ_ALWAYS_INLINE
     char16_t latin1OrTwoByteChar(size_t index) const {
         MOZ_ASSERT(JSString::isLinear());
         MOZ_ASSERT(index < length());
@@ -859,24 +859,24 @@ class JSExtensibleString : public JSFlat
 
 static_assert(sizeof(JSExtensibleString) == sizeof(JSString),
               "string subclasses must be binary-compatible with JSString");
 
 class JSInlineString : public JSFlatString
 {
   public:
     MOZ_ALWAYS_INLINE
-    const JS::Latin1Char* latin1Chars(const JS::AutoCheckCannotGC& nogc) const {
+    const JS::Latin1Char* latin1Chars(const JS::AutoRequireNoGC& nogc) const {
         MOZ_ASSERT(JSString::isInline());
         MOZ_ASSERT(hasLatin1Chars());
         return d.inlineStorageLatin1;
     }
 
     MOZ_ALWAYS_INLINE
-    const char16_t* twoByteChars(const JS::AutoCheckCannotGC& nogc) const {
+    const char16_t* twoByteChars(const JS::AutoRequireNoGC& nogc) const {
         MOZ_ASSERT(JSString::isInline());
         MOZ_ASSERT(hasTwoByteChars());
         return d.inlineStorageTwoByte;
     }
 
     template<typename CharT>
     static bool lengthFits(size_t length);
 
@@ -1419,38 +1419,38 @@ JSString::base() const
 {
     MOZ_ASSERT(hasBase());
     MOZ_ASSERT(!d.s.u3.base->isInline());
     return d.s.u3.base;
 }
 
 template<>
 MOZ_ALWAYS_INLINE const char16_t*
-JSLinearString::nonInlineChars(const JS::AutoCheckCannotGC& nogc) const
+JSLinearString::nonInlineChars(const JS::AutoRequireNoGC& nogc) const
 {
     return nonInlineTwoByteChars(nogc);
 }
 
 template<>
 MOZ_ALWAYS_INLINE const JS::Latin1Char*
-JSLinearString::nonInlineChars(const JS::AutoCheckCannotGC& nogc) const
+JSLinearString::nonInlineChars(const JS::AutoRequireNoGC& nogc) const
 {
     return nonInlineLatin1Chars(nogc);
 }
 
 template<>
 MOZ_ALWAYS_INLINE const char16_t*
-JSLinearString::chars(const JS::AutoCheckCannotGC& nogc) const
+JSLinearString::chars(const JS::AutoRequireNoGC& nogc) const
 {
     return rawTwoByteChars();
 }
 
 template<>
 MOZ_ALWAYS_INLINE const JS::Latin1Char*
-JSLinearString::chars(const JS::AutoCheckCannotGC& nogc) const
+JSLinearString::chars(const JS::AutoRequireNoGC& nogc) const
 {
     return rawLatin1Chars();
 }
 
 template <>
 MOZ_ALWAYS_INLINE bool
 JSRope::copyChars<JS::Latin1Char>(JSContext* cx,
                                   js::ScopedJSFreePtr<JS::Latin1Char>& out) const
--- a/js/src/vm/TypedArrayObject.cpp
+++ b/js/src/vm/TypedArrayObject.cpp
@@ -2344,113 +2344,113 @@ JS_GetArrayBufferViewType(JSObject* obj)
     if (obj->is<TypedArrayObject>())
         return obj->as<TypedArrayObject>().type();
     if (obj->is<DataViewObject>())
         return Scalar::MaxTypedArrayViewType;
     MOZ_CRASH("invalid ArrayBufferView type");
 }
 
 JS_FRIEND_API(int8_t*)
-JS_GetInt8ArrayData(JSObject* obj, bool* isSharedMemory, const JS::AutoCheckCannotGC&)
+JS_GetInt8ArrayData(JSObject* obj, bool* isSharedMemory, const JS::AutoRequireNoGC&)
 {
     obj = CheckedUnwrap(obj);
     if (!obj)
         return nullptr;
     TypedArrayObject* tarr = &obj->as<TypedArrayObject>();
     MOZ_ASSERT((int32_t) tarr->type() == Scalar::Int8);
     *isSharedMemory = tarr->isSharedMemory();
     return static_cast<int8_t*>(tarr->viewDataEither().unwrap(/*safe - caller sees isShared*/));
 }
 
 JS_FRIEND_API(uint8_t*)
-JS_GetUint8ArrayData(JSObject* obj, bool* isSharedMemory, const JS::AutoCheckCannotGC&)
+JS_GetUint8ArrayData(JSObject* obj, bool* isSharedMemory, const JS::AutoRequireNoGC&)
 {
     obj = CheckedUnwrap(obj);
     if (!obj)
         return nullptr;
     TypedArrayObject* tarr = &obj->as<TypedArrayObject>();
     MOZ_ASSERT((int32_t) tarr->type() == Scalar::Uint8);
     *isSharedMemory = tarr->isSharedMemory();
     return static_cast<uint8_t*>(tarr->viewDataEither().unwrap(/*safe - caller sees isSharedMemory*/));
 }
 
 JS_FRIEND_API(uint8_t*)
-JS_GetUint8ClampedArrayData(JSObject* obj, bool* isSharedMemory, const JS::AutoCheckCannotGC&)
+JS_GetUint8ClampedArrayData(JSObject* obj, bool* isSharedMemory, const JS::AutoRequireNoGC&)
 {
     obj = CheckedUnwrap(obj);
     if (!obj)
         return nullptr;
     TypedArrayObject* tarr = &obj->as<TypedArrayObject>();
     MOZ_ASSERT((int32_t) tarr->type() == Scalar::Uint8Clamped);
     *isSharedMemory = tarr->isSharedMemory();
     return static_cast<uint8_t*>(tarr->viewDataEither().unwrap(/*safe - caller sees isSharedMemory*/));
 }
 
 JS_FRIEND_API(int16_t*)
-JS_GetInt16ArrayData(JSObject* obj, bool* isSharedMemory, const JS::AutoCheckCannotGC&)
+JS_GetInt16ArrayData(JSObject* obj, bool* isSharedMemory, const JS::AutoRequireNoGC&)
 {
     obj = CheckedUnwrap(obj);
     if (!obj)
         return nullptr;
     TypedArrayObject* tarr = &obj->as<TypedArrayObject>();
     MOZ_ASSERT((int32_t) tarr->type() == Scalar::Int16);
     *isSharedMemory = tarr->isSharedMemory();
     return static_cast<int16_t*>(tarr->viewDataEither().unwrap(/*safe - caller sees isSharedMemory*/));
 }
 
 JS_FRIEND_API(uint16_t*)
-JS_GetUint16ArrayData(JSObject* obj, bool* isSharedMemory, const JS::AutoCheckCannotGC&)
+JS_GetUint16ArrayData(JSObject* obj, bool* isSharedMemory, const JS::AutoRequireNoGC&)
 {
     obj = CheckedUnwrap(obj);
     if (!obj)
         return nullptr;
     TypedArrayObject* tarr = &obj->as<TypedArrayObject>();
     MOZ_ASSERT((int32_t) tarr->type() == Scalar::Uint16);
     *isSharedMemory = tarr->isSharedMemory();
     return static_cast<uint16_t*>(tarr->viewDataEither().unwrap(/*safe - caller sees isSharedMemory*/));
 }
 
 JS_FRIEND_API(int32_t*)
-JS_GetInt32ArrayData(JSObject* obj, bool* isSharedMemory, const JS::AutoCheckCannotGC&)
+JS_GetInt32ArrayData(JSObject* obj, bool* isSharedMemory, const JS::AutoRequireNoGC&)
 {
     obj = CheckedUnwrap(obj);
     if (!obj)
         return nullptr;
     TypedArrayObject* tarr = &obj->as<TypedArrayObject>();
     MOZ_ASSERT((int32_t) tarr->type() == Scalar::Int32);
     *isSharedMemory = tarr->isSharedMemory();
     return static_cast<int32_t*>(tarr->viewDataEither().unwrap(/*safe - caller sees isSharedMemory*/));
 }
 
 JS_FRIEND_API(uint32_t*)
-JS_GetUint32ArrayData(JSObject* obj, bool* isSharedMemory, const JS::AutoCheckCannotGC&)
+JS_GetUint32ArrayData(JSObject* obj, bool* isSharedMemory, const JS::AutoRequireNoGC&)
 {
     obj = CheckedUnwrap(obj);
     if (!obj)
         return nullptr;
     TypedArrayObject* tarr = &obj->as<TypedArrayObject>();
     MOZ_ASSERT((int32_t) tarr->type() == Scalar::Uint32);
     *isSharedMemory = tarr->isSharedMemory();
     return static_cast<uint32_t*>(tarr->viewDataEither().unwrap(/*safe - caller sees isSharedMemory*/));
 }
 
 JS_FRIEND_API(float*)
-JS_GetFloat32ArrayData(JSObject* obj, bool* isSharedMemory, const JS::AutoCheckCannotGC&)
+JS_GetFloat32ArrayData(JSObject* obj, bool* isSharedMemory, const JS::AutoRequireNoGC&)
 {
     obj = CheckedUnwrap(obj);
     if (!obj)
         return nullptr;
     TypedArrayObject* tarr = &obj->as<TypedArrayObject>();
     MOZ_ASSERT((int32_t) tarr->type() == Scalar::Float32);
     *isSharedMemory = tarr->isSharedMemory();
     return static_cast<float*>(tarr->viewDataEither().unwrap(/*safe - caller sees isSharedMemory*/));
 }
 
 JS_FRIEND_API(double*)
-JS_GetFloat64ArrayData(JSObject* obj, bool* isSharedMemory, const JS::AutoCheckCannotGC&)
+JS_GetFloat64ArrayData(JSObject* obj, bool* isSharedMemory, const JS::AutoRequireNoGC&)
 {
     obj = CheckedUnwrap(obj);
     if (!obj)
         return nullptr;
     TypedArrayObject* tarr = &obj->as<TypedArrayObject>();
     MOZ_ASSERT((int32_t) tarr->type() == Scalar::Float64);
     *isSharedMemory = tarr->isSharedMemory();
     return static_cast<double*>(tarr->viewDataEither().unwrap(/*safe - caller sees isSharedMemory*/));