Bug 1384121 part 2 - Add asserts to catch similar bugs and fix some false positives. r=nbp
authorJan de Mooij <jdemooij@mozilla.com>
Wed, 20 Sep 2017 12:13:54 +0200
changeset 431410 eab55565955de81c880c31c1e1c37506b5b042e0
parent 431409 15f2fbd686f628d014429b0ae5cab1f44541fe2a
child 431411 0ff539e59fb14f92c2990d0742f5f1f16aa82ff1
push id7784
push userryanvm@gmail.com
push dateThu, 21 Sep 2017 00:40:13 +0000
treeherdermozilla-beta@efff4f307675 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnbp
bugs1384121
milestone57.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 1384121 part 2 - Add asserts to catch similar bugs and fix some false positives. r=nbp
js/src/jit/Bailouts.cpp
js/src/jit/JSJitFrameIter.cpp
js/src/jit/VMFunctions.cpp
js/src/jit/arm/Trampoline-arm.cpp
js/src/jit/arm64/Trampoline-arm64.cpp
js/src/jit/mips32/Trampoline-mips32.cpp
js/src/jit/mips64/Trampoline-mips64.cpp
js/src/jit/x64/Trampoline-x64.cpp
js/src/jit/x86/Trampoline-x86.cpp
js/src/vm/ObjectGroup-inl.h
js/src/vm/Stack.cpp
js/src/vm/TypeInference.cpp
--- a/js/src/jit/Bailouts.cpp
+++ b/js/src/jit/Bailouts.cpp
@@ -24,18 +24,16 @@
 using namespace js;
 using namespace js::jit;
 
 using mozilla::IsInRange;
 
 uint32_t
 jit::Bailout(BailoutStack* sp, BaselineBailoutInfo** bailoutInfo)
 {
-    AutoUnsafeCallWithABI unsafe;
-
     JSContext* cx = TlsContext.get();
     MOZ_ASSERT(bailoutInfo);
 
     // We don't have an exit frame.
     MOZ_ASSERT(IsInRange(FAKE_EXITFP_FOR_BAILOUT, 0, 0x1000) &&
                IsInRange(FAKE_EXITFP_FOR_BAILOUT + sizeof(CommonFrameLayout), 0, 0x1000),
                "Fake exitfp pointer should be within the first page.");
 
@@ -101,18 +99,16 @@ jit::Bailout(BailoutStack* sp, BaselineB
 
     return retval;
 }
 
 uint32_t
 jit::InvalidationBailout(InvalidationBailoutStack* sp, size_t* frameSizeOut,
                          BaselineBailoutInfo** bailoutInfo)
 {
-    AutoUnsafeCallWithABI unsafe;
-
     sp->checkInvariants();
 
     JSContext* cx = TlsContext.get();
 
     // We don't have an exit frame.
     cx->activation()->asJit()->setExitFP(FAKE_EXITFP_FOR_BAILOUT);
 
     JitActivationIterator jitActivations(cx);
--- a/js/src/jit/JSJitFrameIter.cpp
+++ b/js/src/jit/JSJitFrameIter.cpp
@@ -20,16 +20,18 @@ JSJitFrameIter::JSJitFrameIter(const Jit
     frameSize_(0),
     cachedSafepointIndex_(nullptr),
     activation_(activation)
 {
     if (activation_->bailoutData()) {
         current_ = activation_->bailoutData()->fp();
         frameSize_ = activation_->bailoutData()->topFrameSize();
         type_ = JitFrame_Bailout;
+    } else {
+        MOZ_ASSERT(!TlsContext.get()->inUnsafeCallWithABI);
     }
 }
 
 JSJitFrameIter::JSJitFrameIter(JSContext* cx)
   : JSJitFrameIter(cx->activation()->asJit())
 {
 }
 
--- a/js/src/jit/VMFunctions.cpp
+++ b/js/src/jit/VMFunctions.cpp
@@ -1232,17 +1232,16 @@ LeaveWith(JSContext* cx, BaselineFrame* 
     frame->popOffEnvironmentChain<WithEnvironmentObject>();
     return true;
 }
 
 bool
 InitBaselineFrameForOsr(BaselineFrame* frame, InterpreterFrame* interpFrame,
                         uint32_t numStackValues)
 {
-    AutoUnsafeCallWithABI unsafe;
     return frame->initForOsr(interpFrame, numStackValues);
 }
 
 JSObject*
 CreateDerivedTypedObj(JSContext* cx, HandleObject descr,
                       HandleObject owner, int32_t offset)
 {
     MOZ_ASSERT(descr->is<TypeDescr>());
--- a/js/src/jit/arm/Trampoline-arm.cpp
+++ b/js/src/jit/arm/Trampoline-arm.cpp
@@ -292,17 +292,18 @@ JitRuntime::generateEnterJIT(JSContext* 
 
         masm.push(framePtr); // BaselineFrame
         masm.push(r0); // jitcode
 
         masm.setupUnalignedABICall(scratch);
         masm.passABIArg(r11); // BaselineFrame
         masm.passABIArg(OsrFrameReg); // InterpreterFrame
         masm.passABIArg(numStackValues);
-        masm.callWithABI(JS_FUNC_TO_DATA_PTR(void*, jit::InitBaselineFrameForOsr));
+        masm.callWithABI(JS_FUNC_TO_DATA_PTR(void*, jit::InitBaselineFrameForOsr), MoveOp::GENERAL,
+                         CheckUnsafeCallWithABI::DontCheckHasExitFrame);
 
         Register jitcode = regs.takeAny();
         masm.pop(jitcode);
         masm.pop(framePtr);
 
         MOZ_ASSERT(jitcode != ReturnReg);
 
         Label error;
@@ -429,17 +430,18 @@ JitRuntime::generateInvalidator(JSContex
     masm.mov(sp, r1);
     const int sizeOfBailoutInfo = sizeof(void*)*2;
     masm.reserveStack(sizeOfBailoutInfo);
     masm.mov(sp, r2);
     masm.setupAlignedABICall();
     masm.passABIArg(r0);
     masm.passABIArg(r1);
     masm.passABIArg(r2);
-    masm.callWithABI(JS_FUNC_TO_DATA_PTR(void*, InvalidationBailout));
+    masm.callWithABI(JS_FUNC_TO_DATA_PTR(void*, InvalidationBailout), MoveOp::GENERAL,
+                     CheckUnsafeCallWithABI::DontCheckOther);
 
     masm.ma_ldr(DTRAddr(sp, DtrOffImm(0)), r2);
     {
         ScratchRegisterScope scratch(masm);
         masm.ma_ldr(Address(sp, sizeOfBailoutInfo), r1, scratch);
     }
     // Remove the return address, the IonScript, the register state
     // (InvaliationBailoutStack) and the space that was allocated for the return
@@ -671,17 +673,18 @@ GenerateBailoutThunk(JSContext* cx, Macr
     // Decrement sp by another 4, so we keep alignment. Not Anymore! Pushing
     // both the snapshotoffset as well as the: masm.as_sub(sp, sp, Imm8(4));
 
     // Set the old (4-byte aligned) value of the sp as the first argument.
     masm.passABIArg(r0);
     masm.passABIArg(r1);
 
     // Sp % 8 == 0
-    masm.callWithABI(JS_FUNC_TO_DATA_PTR(void*, Bailout));
+    masm.callWithABI(JS_FUNC_TO_DATA_PTR(void*, Bailout), MoveOp::GENERAL,
+                     CheckUnsafeCallWithABI::DontCheckOther);
     masm.ma_ldr(DTRAddr(sp, DtrOffImm(0)), r2);
     {
         ScratchRegisterScope scratch(masm);
         masm.ma_add(sp, Imm32(sizeOfBailoutInfo), sp, scratch);
     }
 
     // Common size of a bailout frame.
     uint32_t bailoutFrameSize = 0
--- a/js/src/jit/arm64/Trampoline-arm64.cpp
+++ b/js/src/jit/arm64/Trampoline-arm64.cpp
@@ -194,17 +194,18 @@ JitRuntime::generateEnterJIT(JSContext* 
 
         masm.push(BaselineFrameReg, reg_code);
 
         // Initialize the frame, including filling in the slots.
         masm.setupUnalignedABICall(r19);
         masm.passABIArg(BaselineFrameReg); // BaselineFrame.
         masm.passABIArg(reg_osrFrame); // InterpreterFrame.
         masm.passABIArg(reg_osrNStack);
-        masm.callWithABI(JS_FUNC_TO_DATA_PTR(void*, jit::InitBaselineFrameForOsr));
+        masm.callWithABI(JS_FUNC_TO_DATA_PTR(void*, jit::InitBaselineFrameForOsr), MoveOp::GENERAL,
+                         CheckUnsafeCallWithABI::DontCheckHasExitFrame);
 
         masm.pop(r19, BaselineFrameReg);
         MOZ_ASSERT(r19 != ReturnReg);
 
         masm.addToStackPtr(Imm32(ExitFrameLayout::SizeWithFooter()));
         masm.addPtr(Imm32(BaselineFrame::Size()), BaselineFrameReg);
 
         Label error;
@@ -297,17 +298,18 @@ JitRuntime::generateInvalidator(JSContex
     masm.Sub(x2, masm.GetStackPointer64(), Operand(sizeof(size_t) + sizeof(void*)));
     masm.moveToStackPtr(r2);
 
     masm.setupUnalignedABICall(r10);
     masm.passABIArg(r0);
     masm.passABIArg(r1);
     masm.passABIArg(r2);
 
-    masm.callWithABI(JS_FUNC_TO_DATA_PTR(void*, InvalidationBailout));
+    masm.callWithABI(JS_FUNC_TO_DATA_PTR(void*, InvalidationBailout), MoveOp::GENERAL,
+                     CheckUnsafeCallWithABI::DontCheckOther);
 
     masm.pop(r2, r1);
 
     masm.Add(masm.GetStackPointer64(), masm.GetStackPointer64(), x1);
     masm.Add(masm.GetStackPointer64(), masm.GetStackPointer64(),
              Operand(sizeof(InvalidationBailoutStack)));
     masm.syncStackPtr();
 
@@ -494,17 +496,18 @@ GenerateBailoutThunk(JSContext* cx, Macr
     // Make space for the BaselineBailoutInfo* outparam.
     const int sizeOfBailoutInfo = sizeof(void*) * 2;
     masm.reserveStack(sizeOfBailoutInfo);
     masm.moveStackPtrTo(r1);
 
     masm.setupUnalignedABICall(r2);
     masm.passABIArg(r0);
     masm.passABIArg(r1);
-    masm.callWithABI(JS_FUNC_TO_DATA_PTR(void*, Bailout));
+    masm.callWithABI(JS_FUNC_TO_DATA_PTR(void*, Bailout), MoveOp::GENERAL,
+                     CheckUnsafeCallWithABI::DontCheckOther);
 
     masm.Ldr(x2, MemOperand(masm.GetStackPointer64(), 0));
     masm.addToStackPtr(Imm32(sizeOfBailoutInfo));
 
     static const uint32_t BailoutDataSize = sizeof(void*) * Registers::Total +
                                             sizeof(double) * FloatRegisters::TotalPhys;
 
     if (frameClass == NO_FRAME_SIZE_CLASS_ID) {
--- a/js/src/jit/mips32/Trampoline-mips32.cpp
+++ b/js/src/jit/mips32/Trampoline-mips32.cpp
@@ -260,17 +260,18 @@ JitRuntime::generateEnterJIT(JSContext* 
         masm.reserveStack(2 * sizeof(uintptr_t));
         masm.storePtr(framePtr, Address(StackPointer, sizeof(uintptr_t))); // BaselineFrame
         masm.storePtr(reg_code, Address(StackPointer, 0)); // jitcode
 
         masm.setupUnalignedABICall(scratch);
         masm.passABIArg(BaselineFrameReg); // BaselineFrame
         masm.passABIArg(OsrFrameReg); // InterpreterFrame
         masm.passABIArg(numStackValues);
-        masm.callWithABI(JS_FUNC_TO_DATA_PTR(void*, jit::InitBaselineFrameForOsr));
+        masm.callWithABI(JS_FUNC_TO_DATA_PTR(void*, jit::InitBaselineFrameForOsr), MoveOp::GENERAL,
+                         CheckUnsafeCallWithABI::DontCheckHasExitFrame);
 
         regs.add(OsrFrameReg);
         regs.take(JSReturnOperand);
         Register jitcode = regs.takeAny();
         masm.loadPtr(Address(StackPointer, 0), jitcode);
         masm.loadPtr(Address(StackPointer, sizeof(uintptr_t)), framePtr);
         masm.freeStack(2 * sizeof(uintptr_t));
 
@@ -386,17 +387,18 @@ JitRuntime::generateInvalidator(JSContex
     masm.ma_addu(a1, StackPointer, Imm32(sizeof(uintptr_t)));
     // Pass pointer to BailoutInfo
     masm.movePtr(StackPointer, a2);
 
     masm.setupAlignedABICall();
     masm.passABIArg(a0);
     masm.passABIArg(a1);
     masm.passABIArg(a2);
-    masm.callWithABI(JS_FUNC_TO_DATA_PTR(void*, InvalidationBailout));
+    masm.callWithABI(JS_FUNC_TO_DATA_PTR(void*, InvalidationBailout), MoveOp::GENERAL,
+                     CheckUnsafeCallWithABI::DontCheckOther);
 
     masm.loadPtr(Address(StackPointer, 0), a2);
     masm.loadPtr(Address(StackPointer, sizeof(uintptr_t)), a1);
     // Remove the return address, the IonScript, the register state
     // (InvaliationBailoutStack) and the space that was allocated for the
     // return value.
     masm.addPtr(Imm32(sizeof(InvalidationBailoutStack) + 2 * sizeof(uintptr_t)), StackPointer);
     // remove the space that this frame was using before the bailout
@@ -635,17 +637,18 @@ GenerateBailoutThunk(JSContext* cx, Macr
     // Put pointer to BailoutInfo
     masm.subPtr(Imm32(bailoutInfoOutParamSize), StackPointer);
     masm.storePtr(ImmPtr(nullptr), Address(StackPointer, 0));
     masm.movePtr(StackPointer, a1);
 
     masm.setupAlignedABICall();
     masm.passABIArg(a0);
     masm.passABIArg(a1);
-    masm.callWithABI(JS_FUNC_TO_DATA_PTR(void*, Bailout));
+    masm.callWithABI(JS_FUNC_TO_DATA_PTR(void*, Bailout), MoveOp::GENERAL,
+                     CheckUnsafeCallWithABI::DontCheckOther);
 
     // Get BailoutInfo pointer
     masm.loadPtr(Address(StackPointer, 0), a2);
 
     // Remove both the bailout frame and the topmost Ion frame's stack.
     if (frameClass == NO_FRAME_SIZE_CLASS_ID) {
         // Load frameSize from stack
         masm.loadPtr(Address(StackPointer,
--- a/js/src/jit/mips64/Trampoline-mips64.cpp
+++ b/js/src/jit/mips64/Trampoline-mips64.cpp
@@ -277,17 +277,18 @@ JitRuntime::generateEnterJIT(JSContext* 
         masm.reserveStack(2 * sizeof(uintptr_t));
         masm.storePtr(framePtr, Address(StackPointer, sizeof(uintptr_t))); // BaselineFrame
         masm.storePtr(reg_code, Address(StackPointer, 0)); // jitcode
 
         masm.setupUnalignedABICall(scratch);
         masm.passABIArg(BaselineFrameReg); // BaselineFrame
         masm.passABIArg(OsrFrameReg); // InterpreterFrame
         masm.passABIArg(numStackValues);
-        masm.callWithABI(JS_FUNC_TO_DATA_PTR(void*, jit::InitBaselineFrameForOsr));
+        masm.callWithABI(JS_FUNC_TO_DATA_PTR(void*, jit::InitBaselineFrameForOsr), MoveOp::GENERAL,
+                         CheckUnsafeCallWithABI::DontCheckHasExitFrame);
 
         regs.add(OsrFrameReg);
         Register jitcode = regs.takeAny();
         masm.loadPtr(Address(StackPointer, 0), jitcode);
         masm.loadPtr(Address(StackPointer, sizeof(uintptr_t)), framePtr);
         masm.freeStack(2 * sizeof(uintptr_t));
 
         Label error;
@@ -384,17 +385,18 @@ JitRuntime::generateInvalidator(JSContex
     masm.ma_daddu(a1, StackPointer, Imm32(sizeof(uintptr_t)));
     // Pass pointer to BailoutInfo
     masm.movePtr(StackPointer, a2);
 
     masm.setupAlignedABICall();
     masm.passABIArg(a0);
     masm.passABIArg(a1);
     masm.passABIArg(a2);
-    masm.callWithABI(JS_FUNC_TO_DATA_PTR(void*, InvalidationBailout));
+    masm.callWithABI(JS_FUNC_TO_DATA_PTR(void*, InvalidationBailout), MoveOp::GENERAL,
+                     CheckUnsafeCallWithABI::DontCheckOther);
 
     masm.loadPtr(Address(StackPointer, 0), a2);
     masm.loadPtr(Address(StackPointer, sizeof(uintptr_t)), a1);
     // Remove the return address, the IonScript, the register state
     // (InvaliationBailoutStack) and the space that was allocated for the
     // return value.
     masm.addPtr(Imm32(sizeof(InvalidationBailoutStack) + 2 * sizeof(uintptr_t)), StackPointer);
     // remove the space that this frame was using before the bailout
@@ -628,17 +630,18 @@ GenerateBailoutThunk(JSContext* cx, Macr
     // Put pointer to BailoutInfo
     static const uint32_t sizeOfBailoutInfo = sizeof(uintptr_t) * 2;
     masm.subPtr(Imm32(sizeOfBailoutInfo), StackPointer);
     masm.movePtr(StackPointer, a1);
 
     masm.setupAlignedABICall();
     masm.passABIArg(a0);
     masm.passABIArg(a1);
-    masm.callWithABI(JS_FUNC_TO_DATA_PTR(void*, Bailout));
+    masm.callWithABI(JS_FUNC_TO_DATA_PTR(void*, Bailout), MoveOp::GENERAL,
+                     CheckUnsafeCallWithABI::DontCheckOther);
 
     // Get BailoutInfo pointer
     masm.loadPtr(Address(StackPointer, 0), a2);
 
     // Stack is:
     //     [frame]
     //     snapshotOffset
     //     frameSize
--- a/js/src/jit/x64/Trampoline-x64.cpp
+++ b/js/src/jit/x64/Trampoline-x64.cpp
@@ -237,17 +237,18 @@ JitRuntime::generateEnterJIT(JSContext* 
 
         masm.push(framePtr);
         masm.push(reg_code);
 
         masm.setupUnalignedABICall(scratch);
         masm.passABIArg(framePtr); // BaselineFrame
         masm.passABIArg(OsrFrameReg); // InterpreterFrame
         masm.passABIArg(numStackValues);
-        masm.callWithABI(JS_FUNC_TO_DATA_PTR(void*, jit::InitBaselineFrameForOsr));
+        masm.callWithABI(JS_FUNC_TO_DATA_PTR(void*, jit::InitBaselineFrameForOsr), MoveOp::GENERAL,
+                         CheckUnsafeCallWithABI::DontCheckHasExitFrame);
 
         masm.pop(reg_code);
         masm.pop(framePtr);
 
         MOZ_ASSERT(reg_code != ReturnReg);
 
         Label error;
         masm.addPtr(Imm32(ExitFrameLayout::SizeWithFooter()), rsp);
@@ -371,17 +372,18 @@ JitRuntime::generateInvalidator(JSContex
     // Make space for InvalidationBailout's bailoutInfo outparam.
     masm.reserveStack(sizeof(void*));
     masm.movq(rsp, r9);
 
     masm.setupUnalignedABICall(rdx);
     masm.passABIArg(rax);
     masm.passABIArg(rbx);
     masm.passABIArg(r9);
-    masm.callWithABI(JS_FUNC_TO_DATA_PTR(void*, InvalidationBailout));
+    masm.callWithABI(JS_FUNC_TO_DATA_PTR(void*, InvalidationBailout), MoveOp::GENERAL,
+                     CheckUnsafeCallWithABI::DontCheckOther);
 
     masm.pop(r9); // Get the bailoutInfo outparam.
     masm.pop(rbx); // Get the frameSize outparam.
 
     // Pop the machine state and the dead frame.
     masm.lea(Operand(rsp, rbx, TimesOne, sizeof(InvalidationBailoutStack)), rsp);
 
     // Jump to shared bailout tail. The BailoutInfo pointer has to be in r9.
@@ -600,17 +602,18 @@ GenerateBailoutThunk(JSContext* cx, Macr
     // Make space for Bailout's bailoutInfo outparam.
     masm.reserveStack(sizeof(void*));
     masm.movq(rsp, r9);
 
     // Call the bailout function.
     masm.setupUnalignedABICall(rax);
     masm.passABIArg(r8);
     masm.passABIArg(r9);
-    masm.callWithABI(JS_FUNC_TO_DATA_PTR(void*, Bailout));
+    masm.callWithABI(JS_FUNC_TO_DATA_PTR(void*, Bailout), MoveOp::GENERAL,
+                     CheckUnsafeCallWithABI::DontCheckOther);
 
     masm.pop(r9); // Get the bailoutInfo outparam.
 
     // Stack is:
     //     [frame]
     //     snapshotOffset
     //     frameSize
     //     [bailoutFrame]
--- a/js/src/jit/x86/Trampoline-x86.cpp
+++ b/js/src/jit/x86/Trampoline-x86.cpp
@@ -230,17 +230,18 @@ JitRuntime::generateEnterJIT(JSContext* 
 
         masm.push(framePtr);
         masm.push(jitcode);
 
         masm.setupUnalignedABICall(scratch);
         masm.passABIArg(framePtr); // BaselineFrame
         masm.passABIArg(OsrFrameReg); // InterpreterFrame
         masm.passABIArg(numStackValues);
-        masm.callWithABI(JS_FUNC_TO_DATA_PTR(void*, jit::InitBaselineFrameForOsr));
+        masm.callWithABI(JS_FUNC_TO_DATA_PTR(void*, jit::InitBaselineFrameForOsr), MoveOp::GENERAL,
+                         CheckUnsafeCallWithABI::DontCheckHasExitFrame);
 
         masm.pop(jitcode);
         masm.pop(framePtr);
 
         MOZ_ASSERT(jitcode != ReturnReg);
 
         Label error;
         masm.addPtr(Imm32(ExitFrameLayout::SizeWithFooter()), esp);
@@ -363,17 +364,18 @@ JitRuntime::generateInvalidator(JSContex
     // Make space for InvalidationBailout's bailoutInfo outparam.
     masm.reserveStack(sizeof(void*));
     masm.movl(esp, ecx);
 
     masm.setupUnalignedABICall(edx);
     masm.passABIArg(eax);
     masm.passABIArg(ebx);
     masm.passABIArg(ecx);
-    masm.callWithABI(JS_FUNC_TO_DATA_PTR(void*, InvalidationBailout));
+    masm.callWithABI(JS_FUNC_TO_DATA_PTR(void*, InvalidationBailout), MoveOp::GENERAL,
+                     CheckUnsafeCallWithABI::DontCheckOther);
 
     masm.pop(ecx); // Get bailoutInfo outparam.
     masm.pop(ebx); // Get the frameSize outparam.
 
     // Pop the machine state and the dead frame.
     masm.lea(Operand(esp, ebx, TimesOne, sizeof(InvalidationBailoutStack)), esp);
 
     // Jump to shared bailout tail. The BailoutInfo pointer has to be in ecx.
@@ -598,17 +600,18 @@ GenerateBailoutThunk(JSContext* cx, Macr
     // Make space for Bailout's baioutInfo outparam.
     masm.reserveStack(sizeof(void*));
     masm.movl(esp, ebx);
 
     // Call the bailout function. This will correct the size of the bailout.
     masm.setupUnalignedABICall(ecx);
     masm.passABIArg(eax);
     masm.passABIArg(ebx);
-    masm.callWithABI(JS_FUNC_TO_DATA_PTR(void*, Bailout));
+    masm.callWithABI(JS_FUNC_TO_DATA_PTR(void*, Bailout), MoveOp::GENERAL,
+                     CheckUnsafeCallWithABI::DontCheckOther);
 
     masm.pop(ecx); // Get bailoutInfo outparam.
 
     // Common size of stuff we've pushed.
     static const uint32_t BailoutDataSize = 0
         + sizeof(void*) // frameClass
         + sizeof(RegisterDump);
 
--- a/js/src/vm/ObjectGroup-inl.h
+++ b/js/src/vm/ObjectGroup-inl.h
@@ -11,16 +11,17 @@
 
 namespace js {
 
 inline bool
 ObjectGroup::needsSweep()
 {
     // Note: this can be called off thread during compacting GCs, in which case
     // nothing will be running on the active thread.
+    MOZ_ASSERT(!TlsContext.get()->inUnsafeCallWithABI);
     return generation() != zoneFromAnyThread()->types.generation;
 }
 
 inline void
 ObjectGroup::maybeSweep(AutoClearTypeInferenceStateOnOOM* oom)
 {
     if (needsSweep())
         sweep(oom);
--- a/js/src/vm/Stack.cpp
+++ b/js/src/vm/Stack.cpp
@@ -600,16 +600,18 @@ FrameIter::popInterpreterFrame()
         popActivation();
     else
         data_.pc_ = data_.interpFrames_.pc();
 }
 
 void
 FrameIter::settleOnActivation()
 {
+    MOZ_ASSERT(!data_.cx_->inUnsafeCallWithABI);
+
     while (true) {
         if (data_.activations_.done()) {
             data_.state_ = DONE;
             return;
         }
 
         Activation* activation = data_.activations_.activation();
 
--- a/js/src/vm/TypeInference.cpp
+++ b/js/src/vm/TypeInference.cpp
@@ -4423,16 +4423,18 @@ ObjectGroup::sweep(AutoClearTypeInferenc
     } else {
         MOZ_RELEASE_ASSERT(!propertySet);
     }
 }
 
 /* static */ void
 JSScript::maybeSweepTypes(AutoClearTypeInferenceStateOnOOM* oom)
 {
+    MOZ_ASSERT(!TlsContext.get()->inUnsafeCallWithABI);
+
     if (!types_ || typesGeneration() == zone()->types.generation)
         return;
 
     setTypesGeneration(zone()->types.generation);
 
     AssertGCStateForSweep(zone());
 
     Maybe<AutoClearTypeInferenceStateOnOOM> fallbackOOM;
@@ -4606,16 +4608,17 @@ TypeZone::clearAllNewScriptsOnOOM()
             group->maybeClearNewScriptOnOOM();
     }
 }
 
 AutoClearTypeInferenceStateOnOOM::AutoClearTypeInferenceStateOnOOM(Zone* zone)
   : zone(zone), oom(false)
 {
     MOZ_RELEASE_ASSERT(CurrentThreadCanAccessZone(zone));
+    MOZ_ASSERT(!TlsContext.get()->inUnsafeCallWithABI);
     zone->types.setSweepingTypes(true);
 }
 
 AutoClearTypeInferenceStateOnOOM::~AutoClearTypeInferenceStateOnOOM()
 {
     zone->types.setSweepingTypes(false);
 
     if (oom) {