Bug 977287, part 1 - Rename the "operation callback" to "interrupt callback". r=luke.
authorJason Orendorff <jorendorff@mozilla.com>
Mon, 10 Mar 2014 16:28:43 -0500
changeset 190044 53139214dcf3fc3b886bb913a2b4b301e5e70bf4
parent 190043 91a34de66289511aa1dae4ebeb13818a15612b73
child 190045 02400c717fa61b09b91b5f08326d50404eaad3b8
push id3503
push userraliiev@mozilla.com
push dateMon, 28 Apr 2014 18:51:11 +0000
treeherdermozilla-beta@c95ac01e332e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersluke
bugs977287
milestone30.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 977287, part 1 - Rename the "operation callback" to "interrupt callback". r=luke.
dom/base/nsGlobalWindow.cpp
dom/workers/RuntimeService.cpp
dom/workers/WorkerPrivate.cpp
dom/workers/WorkerPrivate.h
js/src/gc/StoreBuffer.cpp
js/src/jit/AsmJS.cpp
js/src/jit/AsmJSModule.cpp
js/src/jit/AsmJSModule.h
js/src/jit/AsmJSSignalHandlers.cpp
js/src/jit/AsmJSSignalHandlers.h
js/src/jit/CodeGenerator.cpp
js/src/jit/Ion.cpp
js/src/jit/Ion.h
js/src/jit/IonLinker.h
js/src/jit/JitCompartment.h
js/src/jit/ParallelFunctions.cpp
js/src/jit/VMFunctions.cpp
js/src/jsapi-tests/testSlowScript.cpp
js/src/jsapi.cpp
js/src/jsapi.h
js/src/jsarray.cpp
js/src/jscntxt.cpp
js/src/jscntxt.h
js/src/jscompartment.cpp
js/src/jsgc.cpp
js/src/jsgcinlines.h
js/src/jsiter.cpp
js/src/json.cpp
js/src/jsproxy.cpp
js/src/jsstr.cpp
js/src/jsworkers.cpp
js/src/shell/js.cpp
js/src/vm/ForkJoin.cpp
js/src/vm/ForkJoin.h
js/src/vm/Interpreter.cpp
js/src/vm/Runtime.cpp
js/src/vm/Runtime.h
js/src/vm/Stack.cpp
js/src/yarr/YarrInterpreter.cpp
js/xpconnect/src/XPCJSRuntime.cpp
js/xpconnect/src/XPCShellImpl.cpp
js/xpconnect/src/xpcprivate.h
js/xpconnect/tests/unit/head_watchdog.js
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -10647,24 +10647,24 @@ nsGlobalWindow::ShowSlowScriptDialog()
                           (nsIPrompt::BUTTON_POS_0 + nsIPrompt::BUTTON_POS_1));
 
   // Add a third button if necessary.
   if (debugPossible)
     buttonFlags += nsIPrompt::BUTTON_TITLE_IS_STRING * nsIPrompt::BUTTON_POS_2;
 
   // Null out the operation callback while we're re-entering JS here.
   JSRuntime* rt = JS_GetRuntime(cx);
-  JSOperationCallback old = JS_SetOperationCallback(rt, nullptr);
+  JSInterruptCallback old = JS_SetInterruptCallback(rt, nullptr);
 
   // Open the dialog.
   rv = prompt->ConfirmEx(title, msg, buttonFlags, waitButton, stopButton,
                          debugButton, neverShowDlg, &neverShowDlgChk,
                          &buttonPressed);
 
-  JS_SetOperationCallback(rt, old);
+  JS_SetInterruptCallback(rt, old);
 
   if (NS_SUCCEEDED(rv) && (buttonPressed == 0)) {
     return neverShowDlgChk ? AlwaysContinueSlowScript : ContinueSlowScript;
   }
   if ((buttonPressed == 2) && debugPossible) {
     return js_CallContextDebugHandler(cx) ? ContinueSlowScript : KillSlowScript;
   }
   JS_ClearPendingException(cx);
--- a/dom/workers/RuntimeService.cpp
+++ b/dom/workers/RuntimeService.cpp
@@ -595,25 +595,25 @@ ErrorReporter(JSContext* aCx, const char
 {
   WorkerPrivate* worker = GetWorkerPrivateFromContext(aCx);
   MOZ_ASSERT(worker);
 
   return worker->ReportError(aCx, aMessage, aReport);
 }
 
 bool
-OperationCallback(JSContext* aCx)
+InterruptCallback(JSContext* aCx)
 {
   WorkerPrivate* worker = GetWorkerPrivateFromContext(aCx);
   MOZ_ASSERT(worker);
 
   // Now is a good time to turn on profiling if it's pending.
   profiler_js_operation_callback();
 
-  return worker->OperationCallback(aCx);
+  return worker->InterruptCallback(aCx);
 }
 
 class LogViolationDetailsRunnable MOZ_FINAL : public nsRunnable
 {
   WorkerPrivate* mWorkerPrivate;
   nsCOMPtr<nsIEventTarget> mSyncLoopTarget;
   nsString mFileName;
   uint32_t mLineNum;
@@ -815,17 +815,17 @@ CreateJSContextForWorker(WorkerPrivate* 
 
   auto rtPrivate = new WorkerThreadRuntimePrivate();
   memset(rtPrivate, 0, sizeof(WorkerThreadRuntimePrivate));
   rtPrivate->mWorkerPrivate = aWorkerPrivate;
   JS_SetRuntimePrivate(aRuntime, rtPrivate);
 
   JS_SetErrorReporter(workerCx, ErrorReporter);
 
-  JS_SetOperationCallback(aRuntime, OperationCallback);
+  JS_SetInterruptCallback(aRuntime, InterruptCallback);
 
   js::SetCTypesActivityCallback(aRuntime, CTypesActivityCallback);
 
   JS::ContextOptionsRef(workerCx) =
     aWorkerPrivate->IsChromeWorker() ? settings.chrome.contextOptions
                                      : settings.content.contextOptions;
 
 #ifdef JS_GC_ZEAL
--- a/dom/workers/WorkerPrivate.cpp
+++ b/dom/workers/WorkerPrivate.cpp
@@ -2237,17 +2237,17 @@ WorkerPrivateParent<Derived>::DispatchCo
     self->mControlQueue.Push(runnable.forget().get());
 
     if (JSContext* cx = self->mJSContext) {
       MOZ_ASSERT(self->mThread);
 
       JSRuntime* rt = JS_GetRuntime(cx);
       MOZ_ASSERT(rt);
 
-      JS_TriggerOperationCallback(rt);
+      JS_RequestInterruptCallback(rt);
     }
 
     mCondVar.Notify();
   }
 
   return NS_OK;
 }
 
@@ -4186,17 +4186,17 @@ WorkerPrivate::ShutdownGCTimers()
   mGCTimer = nullptr;
   mPeriodicGCTimerTarget = nullptr;
   mIdleGCTimerTarget = nullptr;
   mPeriodicGCTimerRunning = false;
   mIdleGCTimerRunning = false;
 }
 
 bool
-WorkerPrivate::OperationCallback(JSContext* aCx)
+WorkerPrivate::InterruptCallback(JSContext* aCx)
 {
   AssertIsOnWorkerThread();
 
   bool mayContinue = true;
   bool scheduledIdleGC = false;
 
   for (;;) {
     // Run all control events now.
@@ -4305,20 +4305,20 @@ WorkerPrivate::BlockAndCollectRuntimeSta
 
   // This signals the worker that it should block itself as soon as possible.
   mMemoryReporterRunning = true;
 
   NS_ASSERTION(mJSContext, "This must never be null!");
   JSRuntime* rt = JS_GetRuntime(mJSContext);
 
   // If the worker is not already blocked (e.g. waiting for a worker event or
-  // currently in a ctypes call) then we need to trigger the operation
+  // currently in a ctypes call) then we need to trigger the interrupt
   // callback to trap the worker.
   if (!mBlockedForMemoryReporter) {
-    JS_TriggerOperationCallback(rt);
+    JS_RequestInterruptCallback(rt);
 
     // Wait until the worker actually blocks.
     while (!mBlockedForMemoryReporter) {
       mMemoryReportCondVar.Wait();
     }
   }
 
   bool succeeded = false;
--- a/dom/workers/WorkerPrivate.h
+++ b/dom/workers/WorkerPrivate.h
@@ -801,17 +801,17 @@ public:
   GetLoadInfo(JSContext* aCx, nsPIDOMWindow* aWindow, WorkerPrivate* aParent,
               const nsAString& aScriptURL, bool aIsChromeWorker,
               LoadInfo* aLoadInfo);
 
   void
   DoRunLoop(JSContext* aCx);
 
   bool
-  OperationCallback(JSContext* aCx);
+  InterruptCallback(JSContext* aCx);
 
   nsresult
   IsOnCurrentThread(bool* aIsOnCurrentThread);
 
   bool
   CloseInternal(JSContext* aCx)
   {
     AssertIsOnWorkerThread();
--- a/js/src/gc/StoreBuffer.cpp
+++ b/js/src/gc/StoreBuffer.cpp
@@ -321,17 +321,17 @@ StoreBuffer::markAll(JSTracer *trc)
     bufferRelocCell.mark(this, trc);
     bufferGeneric.mark(this, trc);
 }
 
 void
 StoreBuffer::setAboutToOverflow()
 {
     aboutToOverflow_ = true;
-    runtime_->triggerOperationCallback(JSRuntime::TriggerCallbackMainThread);
+    runtime_->requestInterrupt(JSRuntime::RequestInterruptMainThread);
 }
 
 bool
 StoreBuffer::inParallelSection() const
 {
     return InParallelSection();
 }
 
--- a/js/src/jit/AsmJS.cpp
+++ b/js/src/jit/AsmJS.cpp
@@ -1033,17 +1033,17 @@ class MOZ_STACK_CLASS ModuleCompiler
 
     GlobalMap                      globals_;
     FuncVector                     functions_;
     FuncPtrTableVector             funcPtrTables_;
     ExitMap                        exits_;
     MathNameMap                    standardLibraryMathNames_;
     GlobalAccessVector             globalAccesses_;
     Label                          stackOverflowLabel_;
-    Label                          operationCallbackLabel_;
+    Label                          interruptLabel_;
 
     char *                         errorString_;
     uint32_t                       errorOffset_;
     bool                           errorOverRecursed_;
 
     int64_t                        usecBefore_;
     SlowFunctionVector             slowFunctions_;
 
@@ -1097,18 +1097,18 @@ class MOZ_STACK_CLASS ModuleCompiler
             js_free(errorString_);
         }
         if (errorOverRecursed_)
             js_ReportOverRecursed(cx_);
 
         // Avoid spurious Label assertions on compilation failure.
         if (!stackOverflowLabel_.bound())
             stackOverflowLabel_.bind(0);
-        if (!operationCallbackLabel_.bound())
-            operationCallbackLabel_.bind(0);
+        if (!interruptLabel_.bound())
+            interruptLabel_.bind(0);
     }
 
     bool init() {
         if (!globals_.init() || !exits_.init())
             return false;
 
         if (!standardLibraryMathNames_.init() ||
             !addStandardLibraryMathName("sin", AsmJSMathBuiltin_sin) ||
@@ -1213,17 +1213,17 @@ class MOZ_STACK_CLASS ModuleCompiler
     }
 
     /*************************************************** Read-only interface */
 
     ExclusiveContext *cx() const { return cx_; }
     AsmJSParser &parser() const { return parser_; }
     MacroAssembler &masm() { return masm_; }
     Label &stackOverflowLabel() { return stackOverflowLabel_; }
-    Label &operationCallbackLabel() { return operationCallbackLabel_; }
+    Label &interruptLabel() { return interruptLabel_; }
     bool hasError() const { return errorString_ != nullptr; }
     const AsmJSModule &module() const { return *module_.get(); }
 
     ParseNode *moduleFunctionNode() const { return moduleFunctionNode_; }
     PropertyName *moduleFunctionName() const { return moduleFunctionName_; }
 
     const Global *lookupGlobal(PropertyName *name) const {
         if (GlobalMap::Ptr p = globals_.lookup(name))
@@ -1550,17 +1550,17 @@ class MOZ_STACK_CLASS ModuleCompiler
             for (uint32_t i = 0; i < basicBlocks.length(); i++) {
                 Record &r = basicBlocks[i];
                 r.startOffset = masm_.actualOffset(r.startOffset);
                 r.endOffset = masm_.actualOffset(r.endOffset);
             }
         }
 #endif
 
-        module_->setOperationCallbackOffset(masm_.actualOffset(operationCallbackLabel_.offset()));
+        module_->setInterruptOffset(masm_.actualOffset(interruptLabel_.offset()));
 
         // CodeLabels produced during codegen
         for (size_t i = 0; i < masm_.numCodeLabels(); i++) {
             CodeLabel src = masm_.codeLabel(i);
             int32_t labelOffset = src.dest()->offset();
             int32_t targetOffset = masm_.actualOffset(src.src()->offset());
             // The patched uses of a label embed a linked list where the
             // to-be-patched immediate is the offset of the next to-be-patched
@@ -6691,27 +6691,27 @@ GenerateStackOverflowExit(ModuleCompiler
     masm.jump(throwLabel);
 
     return !masm.oom();
 }
 
 // The operation-callback exit is called from arbitrarily-interrupted asm.js
 // code. That means we must first save *all* registers and restore *all*
 // registers (except the stack pointer) when we resume. The address to resume to
-// (assuming that js_HandleExecutionInterrupt doesn't indicate that the
+// (assuming that js::HandleExecutionInterrupt doesn't indicate that the
 // execution should be aborted) is stored in AsmJSActivation::resumePC_.
 // Unfortunately, loading this requires a scratch register which we don't have
 // after restoring all registers. To hack around this, push the resumePC on the
 // stack so that it can be popped directly into PC.
 static bool
-GenerateOperationCallbackExit(ModuleCompiler &m, Label *throwLabel)
+GenerateInterruptExit(ModuleCompiler &m, Label *throwLabel)
 {
     MacroAssembler &masm = m.masm();
     masm.align(CodeAlignment);
-    masm.bind(&m.operationCallbackLabel());
+    masm.bind(&m.interruptLabel());
 
 #ifndef JS_CODEGEN_ARM
     // Be very careful here not to perturb the machine state before saving it
     // to the stack. In particular, add/sub instructions may set conditions in
     // the flags register.
     masm.push(Imm32(0));            // space for resumePC
     masm.pushFlags();               // after this we are safe to use sub
     masm.setFramePushed(0);         // set to zero so we can use masm.framePushed() below
@@ -6853,17 +6853,17 @@ GenerateStubs(ModuleCompiler &m)
             return false;
     }
 
     if (m.stackOverflowLabel().used()) {
         if (!GenerateStackOverflowExit(m, &throwLabel))
             return false;
     }
 
-    if (!GenerateOperationCallbackExit(m, &throwLabel))
+    if (!GenerateInterruptExit(m, &throwLabel))
         return false;
 
     if (!GenerateThrowExit(m, &throwLabel))
         return false;
 
     return true;
 }
 
--- a/js/src/jit/AsmJSModule.cpp
+++ b/js/src/jit/AsmJSModule.cpp
@@ -216,17 +216,17 @@ AddressOf(AsmJSImmKind kind, ExclusiveCo
     switch (kind) {
       case AsmJSImm_Runtime:
         return cx->runtimeAddressForJit();
       case AsmJSImm_StackLimit:
         return cx->stackLimitAddressForJitCode(StackForUntrustedScript);
       case AsmJSImm_ReportOverRecursed:
         return RedirectCall(FuncCast<void (JSContext*)>(js_ReportOverRecursed), Args_General1);
       case AsmJSImm_HandleExecutionInterrupt:
-        return RedirectCall(FuncCast(js_HandleExecutionInterrupt), Args_General1);
+        return RedirectCall(FuncCast(js::HandleExecutionInterrupt), Args_General1);
       case AsmJSImm_InvokeFromAsmJS_Ignore:
         return RedirectCall(FuncCast(InvokeFromAsmJS_Ignore), Args_General4);
       case AsmJSImm_InvokeFromAsmJS_ToInt32:
         return RedirectCall(FuncCast(InvokeFromAsmJS_ToInt32), Args_General4);
       case AsmJSImm_InvokeFromAsmJS_ToNumber:
         return RedirectCall(FuncCast(InvokeFromAsmJS_ToNumber), Args_General4);
       case AsmJSImm_CoerceInPlace_ToInt32:
         return RedirectCall(FuncCast(CoerceInPlace_ToInt32), Args_General2);
@@ -311,17 +311,17 @@ AsmJSModule::restoreToInitialState(Array
     }
 }
 
 void
 AsmJSModule::staticallyLink(ExclusiveContext *cx)
 {
     // Process staticLinkData_
 
-    operationCallbackExit_ = code_ + staticLinkData_.operationCallbackExitOffset;
+    interruptExit_ = code_ + staticLinkData_.interruptExitOffset;
 
     for (size_t i = 0; i < staticLinkData_.relativeLinks.length(); i++) {
         RelativeLink link = staticLinkData_.relativeLinks[i];
         *(void **)(code_ + link.patchAtOffset) = code_ + link.targetOffset;
     }
 
     for (size_t i = 0; i < staticLinkData_.absoluteLinks.length(); i++) {
         AbsoluteLink link = staticLinkData_.absoluteLinks[i];
@@ -338,17 +338,17 @@ AsmJSModule::staticallyLink(ExclusiveCon
     }
 }
 
 AsmJSModule::AsmJSModule(ScriptSource *scriptSource, uint32_t charsBegin)
   : globalArgumentName_(nullptr),
     importArgumentName_(nullptr),
     bufferArgumentName_(nullptr),
     code_(nullptr),
-    operationCallbackExit_(nullptr),
+    interruptExit_(nullptr),
     dynamicallyLinked_(false),
     loadedFromCache_(false),
     charsBegin_(charsBegin),
     scriptSource_(scriptSource),
     codeIsProtected_(false)
 {
     mozilla::PodZero(&pod);
     scriptSource_->incref();
@@ -729,35 +729,35 @@ AsmJSModule::StaticLinkData::serializedS
     return sizeof(uint32_t) +
            SerializedPodVectorSize(relativeLinks) +
            SerializedPodVectorSize(absoluteLinks);
 }
 
 uint8_t *
 AsmJSModule::StaticLinkData::serialize(uint8_t *cursor) const
 {
-    cursor = WriteScalar<uint32_t>(cursor, operationCallbackExitOffset);
+    cursor = WriteScalar<uint32_t>(cursor, interruptExitOffset);
     cursor = SerializePodVector(cursor, relativeLinks);
     cursor = SerializePodVector(cursor, absoluteLinks);
     return cursor;
 }
 
 const uint8_t *
 AsmJSModule::StaticLinkData::deserialize(ExclusiveContext *cx, const uint8_t *cursor)
 {
-    (cursor = ReadScalar<uint32_t>(cursor, &operationCallbackExitOffset)) &&
+    (cursor = ReadScalar<uint32_t>(cursor, &interruptExitOffset)) &&
     (cursor = DeserializePodVector(cx, cursor, &relativeLinks)) &&
     (cursor = DeserializePodVector(cx, cursor, &absoluteLinks));
     return cursor;
 }
 
 bool
 AsmJSModule::StaticLinkData::clone(ExclusiveContext *cx, StaticLinkData *out) const
 {
-    out->operationCallbackExitOffset = operationCallbackExitOffset;
+    out->interruptExitOffset = interruptExitOffset;
     return ClonePodVector(cx, relativeLinks, &out->relativeLinks) &&
            ClonePodVector(cx, absoluteLinks, &out->absoluteLinks);
 }
 
 size_t
 AsmJSModule::StaticLinkData::sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const
 {
     return relativeLinks.sizeOfExcludingThis(mallocSizeOf) +
@@ -820,17 +820,17 @@ AsmJSModule::deserialize(ExclusiveContex
 
 // When a module is cloned, we memcpy its executable code. If, right before or
 // during the clone, another thread calls AsmJSModule::protectCode() then the
 // executable code will become inaccessible. In theory, we could take away only
 // PROT_EXEC, but this seems to break emulators.
 class AutoUnprotectCodeForClone
 {
     JSRuntime *rt_;
-    JSRuntime::AutoLockForOperationCallback lock_;
+    JSRuntime::AutoLockForInterrupt lock_;
     const AsmJSModule &module_;
     const bool protectedBefore_;
 
   public:
     AutoUnprotectCodeForClone(JSContext *cx, const AsmJSModule &module)
       : rt_(cx->runtime()),
         lock_(rt_),
         module_(module),
@@ -885,17 +885,17 @@ AsmJSModule::clone(JSContext *cx, Scoped
 
     out.restoreToInitialState(maybeHeap_, cx);
     return true;
 }
 
 void
 AsmJSModule::protectCode(JSRuntime *rt) const
 {
-    JS_ASSERT(rt->currentThreadOwnsOperationCallbackLock());
+    JS_ASSERT(rt->currentThreadOwnsInterruptLock());
 
     codeIsProtected_ = true;
 
     if (!pod.functionBytes_)
         return;
 
     // Technically, we should be able to only take away the execute permissions,
     // however this seems to break our emulators which don't always check
@@ -908,17 +908,17 @@ AsmJSModule::protectCode(JSRuntime *rt) 
     if (mprotect(codeBase(), functionBytes(), PROT_NONE))
         MOZ_CRASH();
 #endif
 }
 
 void
 AsmJSModule::unprotectCode(JSRuntime *rt) const
 {
-    JS_ASSERT(rt->currentThreadOwnsOperationCallbackLock());
+    JS_ASSERT(rt->currentThreadOwnsInterruptLock());
 
     codeIsProtected_ = false;
 
     if (!pod.functionBytes_)
         return;
 
 #if defined(XP_WIN)
     DWORD oldProtect;
@@ -928,17 +928,17 @@ AsmJSModule::unprotectCode(JSRuntime *rt
     if (mprotect(codeBase(), functionBytes(), PROT_READ | PROT_WRITE | PROT_EXEC))
         MOZ_CRASH();
 #endif
 }
 
 bool
 AsmJSModule::codeIsProtected(JSRuntime *rt) const
 {
-    JS_ASSERT(rt->currentThreadOwnsOperationCallbackLock());
+    JS_ASSERT(rt->currentThreadOwnsInterruptLock());
     return codeIsProtected_;
 }
 
 static bool
 GetCPUID(uint32_t *cpuId)
 {
     enum Arch {
         X86 = 0x1,
--- a/js/src/jit/AsmJSModule.h
+++ b/js/src/jit/AsmJSModule.h
@@ -356,17 +356,17 @@ class AsmJSModule
     typedef Vector<AbsoluteLink, 0, SystemAllocPolicy> AbsoluteLinkVector;
 
     // Static-link data is used to patch a module either after it has been
     // compiled or deserialized with various absolute addresses (of code or
     // data in the process) or relative addresses (of code or data in the same
     // AsmJSModule).
     struct StaticLinkData
     {
-        uint32_t operationCallbackExitOffset;
+        uint32_t interruptExitOffset;
         RelativeLinkVector relativeLinks;
         AbsoluteLinkVector absoluteLinks;
 
         size_t serializedSize() const;
         uint8_t *serialize(uint8_t *cursor) const;
         const uint8_t *deserialize(ExclusiveContext *cx, const uint8_t *cursor);
         bool clone(ExclusiveContext *cx, StaticLinkData *out) const;
 
@@ -410,31 +410,30 @@ class AsmJSModule
         bool                              hasArrayView_;
         size_t                            functionBytes_; // just the function bodies, no stubs
         size_t                            codeBytes_;     // function bodies and stubs
         size_t                            totalBytes_;    // function bodies, stubs, and global data
         uint32_t                          minHeapLength_;
     } pod;
 
     uint8_t *                             code_;
-    uint8_t *                             operationCallbackExit_;
+    uint8_t *                             interruptExit_;
 
     StaticLinkData                        staticLinkData_;
     bool                                  dynamicallyLinked_;
     bool                                  loadedFromCache_;
     HeapPtr<ArrayBufferObject>            maybeHeap_;
 
     uint32_t                              charsBegin_;
     ScriptSource *                        scriptSource_;
 
     FunctionCountsVector                  functionCounts_;
 
-    // This field is accessed concurrently when triggering the operation
-    // callback and access must be synchronized via the runtime's operation
-    // callback lock.
+    // This field is accessed concurrently when requesting an interrupt.
+    // Access must be synchronized via the runtime's interrupt lock.
     mutable bool                          codeIsProtected_;
 
   public:
     explicit AsmJSModule(ScriptSource *scriptSource, uint32_t charsBegin);
     ~AsmJSModule();
 
     void trace(JSTracer *trc) {
         for (unsigned i = 0; i < globals_.length(); i++)
@@ -746,31 +745,31 @@ class AsmJSModule
     // StaticLinkData setters (called after finishing compilation, before
     // staticLink).
     bool addRelativeLink(RelativeLink link) {
         return staticLinkData_.relativeLinks.append(link);
     }
     bool addAbsoluteLink(AbsoluteLink link) {
         return staticLinkData_.absoluteLinks.append(link);
     }
-    void setOperationCallbackOffset(uint32_t offset) {
-        staticLinkData_.operationCallbackExitOffset = offset;
+    void setInterruptOffset(uint32_t offset) {
+        staticLinkData_.interruptExitOffset = offset;
     }
 
     void restoreToInitialState(ArrayBufferObject *maybePrevBuffer, ExclusiveContext *cx);
     void staticallyLink(ExclusiveContext *cx);
 
     uint8_t *codeBase() const {
         JS_ASSERT(code_);
         JS_ASSERT(uintptr_t(code_) % AsmJSPageSize == 0);
         return code_;
     }
 
-    uint8_t *operationCallbackExit() const {
-        return operationCallbackExit_;
+    uint8_t *interruptExit() const {
+        return interruptExit_;
     }
 
     void setIsDynamicallyLinked() {
         JS_ASSERT(!dynamicallyLinked_);
         dynamicallyLinked_ = true;
     }
     bool isDynamicallyLinked() const {
         return dynamicallyLinked_;
@@ -820,18 +819,18 @@ class AsmJSModule
 
     size_t serializedSize() const;
     uint8_t *serialize(uint8_t *cursor) const;
     const uint8_t *deserialize(ExclusiveContext *cx, const uint8_t *cursor);
     bool loadedFromCache() const { return loadedFromCache_; }
 
     bool clone(JSContext *cx, ScopedJSDeletePtr<AsmJSModule> *moduleOut) const;
 
-    // These methods may only be called while holding the Runtime's operation
-    // callback lock.
+    // These methods may only be called while holding the Runtime's interrupt
+    // lock.
     void protectCode(JSRuntime *rt) const;
     void unprotectCode(JSRuntime *rt) const;
     bool codeIsProtected(JSRuntime *rt) const;
 };
 
 // Store the just-parsed module in the cache using AsmJSCacheOps.
 extern bool
 StoreAsmJSModuleInCache(AsmJSParser &parser,
--- a/js/src/jit/AsmJSSignalHandlers.cpp
+++ b/js/src/jit/AsmJSSignalHandlers.cpp
@@ -342,17 +342,17 @@ HandleSimulatorInterrupt(JSRuntime *rt, 
     // handlers are currently only used for Odin code, see bug 964258.
 
 #ifdef JS_ARM_SIMULATOR
     const AsmJSModule &module = activation->module();
     if (module.containsPC((void *)rt->mainThread.simulator()->get_pc()) &&
         module.containsPC(faultingAddress))
     {
         activation->setResumePC(nullptr);
-        int32_t nextpc = int32_t(module.operationCallbackExit());
+        int32_t nextpc = int32_t(module.interruptExit());
         rt->mainThread.simulator()->set_resume_pc(nextpc);
         return true;
     }
 #endif
     return false;
 }
 
 #if !defined(XP_MACOSX)
@@ -446,25 +446,25 @@ HandleException(PEXCEPTION_POINTERS exce
     if (!activation)
         return false;
 
     const AsmJSModule &module = activation->module();
     if (!module.containsPC(pc))
         return false;
 
     // If we faulted trying to execute code in 'module', this must be an
-    // operation callback (see TriggerOperationCallbackForAsmJSCode). Redirect
-    // execution to a trampoline which will call js_HandleExecutionInterrupt.
+    // interrupt callback (see RequestInterruptForAsmJSCode). Redirect
+    // execution to a trampoline which will call js::HandleExecutionInterrupt.
     // The trampoline will jump to activation->resumePC if execution isn't
     // interrupted.
     if (module.containsPC(faultingAddress)) {
         activation->setResumePC(pc);
-        *ppc = module.operationCallbackExit();
+        *ppc = module.interruptExit();
 
-        JSRuntime::AutoLockForOperationCallback lock(rt);
+        JSRuntime::AutoLockForInterrupt lock(rt);
         module.unprotectCode(rt);
         return true;
     }
 
 # if defined(JS_CODEGEN_X64)
     // These checks aren't necessary, but, since we can, check anyway to make
     // sure we aren't covering up a real bug.
     if (!module.maybeHeap() ||
@@ -640,34 +640,34 @@ HandleMachException(JSRuntime *rt, const
         return true;
 
     AsmJSActivation *activation = rt->mainThread.asmJSActivationStackFromAnyThread();
     if (!activation)
         return false;
 
     const AsmJSModule &module = activation->module();
     if (HandleSimulatorInterrupt(rt, activation, faultingAddress)) {
-        JSRuntime::AutoLockForOperationCallback lock(rt);
+        JSRuntime::AutoLockForInterrupt lock(rt);
         module.unprotectCode(rt);
         return true;
     }
 
     if (!module.containsPC(pc))
         return false;
 
     // If we faulted trying to execute code in 'module', this must be an
-    // operation callback (see TriggerOperationCallbackForAsmJSCode). Redirect
-    // execution to a trampoline which will call js_HandleExecutionInterrupt.
+    // interrupt callback (see RequestInterruptForAsmJSCode). Redirect
+    // execution to a trampoline which will call js::HandleExecutionInterrupt.
     // The trampoline will jump to activation->resumePC if execution isn't
     // interrupted.
     if (module.containsPC(faultingAddress)) {
         activation->setResumePC(pc);
-        *ppc = module.operationCallbackExit();
+        *ppc = module.interruptExit();
 
-        JSRuntime::AutoLockForOperationCallback lock(rt);
+        JSRuntime::AutoLockForInterrupt lock(rt);
         module.unprotectCode(rt);
 
         // Update the thread state with the new pc.
         kret = thread_set_state(rtThread, x86_THREAD_STATE, (thread_state_t)&state, x86_THREAD_STATE_COUNT);
         return kret == KERN_SUCCESS;
     }
 
 # if defined(JS_CODEGEN_X64)
@@ -890,34 +890,34 @@ HandleSignal(int signum, siginfo_t *info
         return true;
 
     AsmJSActivation *activation = InnermostAsmJSActivation();
     if (!activation)
         return false;
 
     const AsmJSModule &module = activation->module();
     if (HandleSimulatorInterrupt(rt, activation, faultingAddress)) {
-        JSRuntime::AutoLockForOperationCallback lock(rt);
+        JSRuntime::AutoLockForInterrupt lock(rt);
         module.unprotectCode(rt);
         return true;
     }
 
     if (!module.containsPC(pc))
         return false;
 
     // If we faulted trying to execute code in 'module', this must be an
-    // operation callback (see TriggerOperationCallbackForAsmJSCode). Redirect
-    // execution to a trampoline which will call js_HandleExecutionInterrupt.
+    // interrupt callback (see RequestInterruptForAsmJSCode). Redirect
+    // execution to a trampoline which will call js::HandleExecutionInterrupt.
     // The trampoline will jump to activation->resumePC if execution isn't
     // interrupted.
     if (module.containsPC(faultingAddress)) {
         activation->setResumePC(pc);
-        *ppc = module.operationCallbackExit();
+        *ppc = module.interruptExit();
 
-        JSRuntime::AutoLockForOperationCallback lock(rt);
+        JSRuntime::AutoLockForInterrupt lock(rt);
         module.unprotectCode(rt);
         return true;
     }
 
 # if defined(JS_CODEGEN_X64)
     // These checks aren't necessary, but, since we can, check anyway to make
     // sure we aren't covering up a real bug.
     if (!module.maybeHeap() ||
@@ -1010,29 +1010,29 @@ js::EnsureAsmJSSignalHandlersInstalled(J
 # endif
 
     sHandlersInstalled = true;
 #endif
     return true;
 }
 
 // To interrupt execution of a JSRuntime, any thread may call
-// JS_TriggerOperationCallback (JSRuntime::triggerOperationCallback from inside
-// the engine). Normally, this sets some state that is polled at regular
-// intervals (function prologues, loop headers), even from jit-code. For tight
-// loops, this poses non-trivial overhead. For asm.js, we can do better: when
-// another thread triggers the operation callback, we simply mprotect all of
-// the innermost asm.js module activation's code. This will trigger a SIGSEGV,
-// taking us into AsmJSFaultHandler. From there, we can manually redirect
-// execution to call js_HandleExecutionInterrupt. The memory is un-protected
-// from the signal handler after control flow is redirected.
+// JS_RequestInterruptCallback (JSRuntime::requestInterruptCallback from inside
+// the engine). In the simplest case, this sets some state that is polled at
+// regular intervals (function prologues, loop headers). For tight loops, this
+// poses non-trivial overhead. For asm.js, we can do better: when another
+// thread requests an interrupt, we simply mprotect all of the innermost asm.js
+// module activation's code. This will trigger a SIGSEGV, taking us into
+// AsmJSFaultHandler. From there, we can manually redirect execution to call
+// js::HandleExecutionInterrupt. The memory is un-protected from the signal
+// handler after control flow is redirected.
 void
-js::TriggerOperationCallbackForAsmJSCode(JSRuntime *rt)
+js::RequestInterruptForAsmJSCode(JSRuntime *rt)
 {
-    JS_ASSERT(rt->currentThreadOwnsOperationCallbackLock());
+    JS_ASSERT(rt->currentThreadOwnsInterruptLock());
 
     AsmJSActivation *activation = rt->mainThread.asmJSActivationStackFromAnyThread();
     if (!activation)
         return;
 
     activation->module().protectCode(rt);
 }
 
--- a/js/src/jit/AsmJSSignalHandlers.h
+++ b/js/src/jit/AsmJSSignalHandlers.h
@@ -17,19 +17,19 @@ struct JSRuntime;
 namespace js {
 
 // Returns whether signal handlers for asm.js and for JitRuntime access
 // violations have been installed.
 bool
 EnsureAsmJSSignalHandlersInstalled(JSRuntime *rt);
 
 // Force any currently-executing asm.js code to call
-// js_HandleExecutionInterrupt.
+// js::HandleExecutionInterrupt.
 extern void
-TriggerOperationCallbackForAsmJSCode(JSRuntime *rt);
+RequestInterruptForAsmJSCode(JSRuntime *rt);
 
 // On OSX we are forced to use the lower-level Mach exception mechanism instead
 // of Unix signals. Mach exceptions are not handled on the victim's stack but
 // rather require an extra thread. For simplicity, we create one such thread
 // per JSRuntime (upon the first use of asm.js in the JSRuntime). This thread
 // and related resources are owned by AsmJSMachExceptionHandler which is owned
 // by JSRuntime.
 #ifdef XP_MACOSX
--- a/js/src/jit/CodeGenerator.cpp
+++ b/js/src/jit/CodeGenerator.cpp
@@ -6191,21 +6191,21 @@ CodeGenerator::link(JSContext *cx, types
                      cacheList_.length(), runtimeData_.length(),
                      safepoints_.size(), callTargets.length(),
                      patchableBackedges_.length(), optimizationLevel);
     if (!ionScript) {
         recompileInfo.compilerOutput(cx->zone()->types)->invalidate();
         return false;
     }
 
-    // Lock the runtime against operation callbacks during the link.
-    // We don't want an operation callback to protect the code for the script
+    // Lock the runtime against interrupt callbacks during the link.
+    // We don't want an interrupt request to protect the code for the script
     // before it has been filled in, as we could segv before the runtime's
     // patchable backedges have been fully updated.
-    JSRuntime::AutoLockForOperationCallback lock(cx->runtime());
+    JSRuntime::AutoLockForInterrupt lock(cx->runtime());
 
     // Make sure we don't segv while filling in the code, to avoid deadlocking
     // inside the signal handler.
     cx->runtime()->jitRuntime()->ensureIonCodeAccessible(cx->runtime());
 
     // Implicit interrupts are used only for sequential code. In parallel mode
     // use the normal executable allocator so that we cannot segv during
     // execution off the main thread.
--- a/js/src/jit/Ion.cpp
+++ b/js/src/jit/Ion.cpp
@@ -166,26 +166,26 @@ JitRuntime::JitRuntime()
 {
 }
 
 JitRuntime::~JitRuntime()
 {
     js_delete(functionWrappers_);
     freeOsrTempData();
 
-    // Note: the operation callback lock is not taken here as JitRuntime is
-    // only destroyed along with its containing JSRuntime.
+    // Note: The interrupt lock is not taken here, as JitRuntime is only
+    // destroyed along with its containing JSRuntime.
     js_delete(ionAlloc_);
 }
 
 bool
 JitRuntime::initialize(JSContext *cx)
 {
     JS_ASSERT(cx->runtime()->currentThreadHasExclusiveAccess());
-    JS_ASSERT(cx->runtime()->currentThreadOwnsOperationCallbackLock());
+    JS_ASSERT(cx->runtime()->currentThreadOwnsInterruptLock());
 
     AutoCompartment ac(cx, cx->atomsCompartment());
 
     IonContext ictx(cx, nullptr);
     AutoFlushCache afc("JitRuntime::initialize", this);
 
     execAlloc_ = cx->runtime()->getExecAlloc(cx);
     if (!execAlloc_)
@@ -314,28 +314,28 @@ JitRuntime::freeOsrTempData()
 {
     js_free(osrTempData_);
     osrTempData_ = nullptr;
 }
 
 JSC::ExecutableAllocator *
 JitRuntime::createIonAlloc(JSContext *cx)
 {
-    JS_ASSERT(cx->runtime()->currentThreadOwnsOperationCallbackLock());
+    JS_ASSERT(cx->runtime()->currentThreadOwnsInterruptLock());
 
     ionAlloc_ = js_new<JSC::ExecutableAllocator>();
     if (!ionAlloc_)
         js_ReportOutOfMemory(cx);
     return ionAlloc_;
 }
 
 void
 JitRuntime::ensureIonCodeProtected(JSRuntime *rt)
 {
-    JS_ASSERT(rt->currentThreadOwnsOperationCallbackLock());
+    JS_ASSERT(rt->currentThreadOwnsInterruptLock());
 
     if (!rt->signalHandlersInstalled() || ionCodeProtected_ || !ionAlloc_)
         return;
 
     // Protect all Ion code in the runtime to trigger an access violation the
     // next time any of it runs on the main thread.
     ionAlloc_->toggleAllCodeAsAccessible(false);
     ionCodeProtected_ = true;
@@ -343,39 +343,39 @@ JitRuntime::ensureIonCodeProtected(JSRun
 
 bool
 JitRuntime::handleAccessViolation(JSRuntime *rt, void *faultingAddress)
 {
     if (!rt->signalHandlersInstalled() || !ionAlloc_ || !ionAlloc_->codeContains((char *) faultingAddress))
         return false;
 
 #ifdef JS_THREADSAFE
-    // All places where the operation callback lock is taken must either ensure
-    // that Ion code memory won't be accessed within, or call ensureIonCodeAccessible
-    // to render the memory safe for accessing. Otherwise taking the lock below
+    // All places where the interrupt lock is taken must either ensure that Ion
+    // code memory won't be accessed within, or call ensureIonCodeAccessible to
+    // render the memory safe for accessing. Otherwise taking the lock below
     // will deadlock the process.
-    JS_ASSERT(!rt->currentThreadOwnsOperationCallbackLock());
+    JS_ASSERT(!rt->currentThreadOwnsInterruptLock());
 #endif
 
     // Taking this lock is necessary to prevent the interrupting thread from marking
     // the memory as inaccessible while we are patching backedges. This will cause us
     // to SEGV while still inside the signal handler, and the process will terminate.
-    JSRuntime::AutoLockForOperationCallback lock(rt);
+    JSRuntime::AutoLockForInterrupt lock(rt);
 
     // Ion code in the runtime faulted after it was made inaccessible. Reset
     // the code privileges and patch all loop backedges to perform an interrupt
     // check instead.
     ensureIonCodeAccessible(rt);
     return true;
 }
 
 void
 JitRuntime::ensureIonCodeAccessible(JSRuntime *rt)
 {
-    JS_ASSERT(rt->currentThreadOwnsOperationCallbackLock());
+    JS_ASSERT(rt->currentThreadOwnsInterruptLock());
 
     // This can only be called on the main thread and while handling signals,
     // which happens on a separate thread in OS X.
 #ifndef XP_MACOSX
     JS_ASSERT(CurrentThreadCanAccessRuntime(rt));
 #endif
 
     if (ionCodeProtected_) {
@@ -410,54 +410,53 @@ JitRuntime::patchIonBackedges(JSRuntime 
         PatchableBackedge *patchableBackedge = *iter;
         PatchJump(patchableBackedge->backedge, target == BackedgeLoopHeader
                                                ? patchableBackedge->loopHeader
                                                : patchableBackedge->interruptCheck);
     }
 }
 
 void
-jit::TriggerOperationCallbackForIonCode(JSRuntime *rt,
-                                        JSRuntime::OperationCallbackTrigger trigger)
+jit::RequestInterruptForIonCode(JSRuntime *rt, JSRuntime::InterruptMode mode)
 {
     JitRuntime *jitRuntime = rt->jitRuntime();
     if (!jitRuntime)
         return;
 
-    JS_ASSERT(rt->currentThreadOwnsOperationCallbackLock());
-
-    // The mechanism for interrupting normal ion code varies between how the
-    // interrupt is being triggered.
-    switch (trigger) {
-      case JSRuntime::TriggerCallbackMainThread:
-        // When triggering an interrupt from the main thread, Ion loop
+    JS_ASSERT(rt->currentThreadOwnsInterruptLock());
+
+    // The mechanism for interrupting normal ion code varies depending on how
+    // the interrupt is being requested.
+    switch (mode) {
+      case JSRuntime::RequestInterruptMainThread:
+        // When requesting an interrupt from the main thread, Ion loop
         // backedges can be patched directly. Make sure we don't segv while
         // patching the backedges, to avoid deadlocking inside the signal
         // handler.
         JS_ASSERT(CurrentThreadCanAccessRuntime(rt));
         jitRuntime->ensureIonCodeAccessible(rt);
         break;
 
-      case JSRuntime::TriggerCallbackAnyThread:
-        // When triggering an interrupt from off the main thread, protect
+      case JSRuntime::RequestInterruptAnyThread:
+        // When requesting an interrupt from off the main thread, protect
         // Ion code memory so that the main thread will fault and enter a
         // signal handler when trying to execute the code. The signal
         // handler will unprotect the code and patch loop backedges so
         // that the interrupt handler is invoked afterwards.
         jitRuntime->ensureIonCodeProtected(rt);
         break;
 
-      case JSRuntime::TriggerCallbackAnyThreadDontStopIon:
-      case JSRuntime::TriggerCallbackAnyThreadForkJoin:
-        // When the trigger does not require Ion code to be interrupted,
-        // nothing more needs to be done.
+      case JSRuntime::RequestInterruptAnyThreadDontStopIon:
+      case JSRuntime::RequestInterruptAnyThreadForkJoin:
+        // The caller does not require Ion code to be interrupted.
+        // Nothing more needs to be done.
         break;
 
       default:
-        MOZ_ASSUME_UNREACHABLE("Bad trigger");
+        MOZ_ASSUME_UNREACHABLE("Bad interrupt mode");
     }
 }
 
 JitCompartment::JitCompartment(JitRuntime *rt)
   : rt(rt),
     stubCodes_(nullptr),
     baselineCallReturnAddr_(nullptr),
     baselineGetPropReturnAddr_(nullptr),
@@ -667,22 +666,22 @@ JitCode::trace(JSTracer *trc)
     }
 }
 
 void
 JitCode::finalize(FreeOp *fop)
 {
     // Make sure this can't race with an interrupting thread, which may try
     // to read the contents of the pool we are releasing references in.
-    JS_ASSERT(fop->runtime()->currentThreadOwnsOperationCallbackLock());
+    JS_ASSERT(fop->runtime()->currentThreadOwnsInterruptLock());
 
 #ifdef DEBUG
     // Buffer can be freed at any time hereafter. Catch use-after-free bugs.
     // Don't do this if the Ion code is protected, as the signal handler will
-    // deadlock trying to reaqcuire the operation callback lock.
+    // deadlock trying to reacquire the interrupt lock.
     if (fop->runtime()->jitRuntime() && !fop->runtime()->jitRuntime()->ionCodeProtected())
         JS_POISON(code_, JS_FREE_PATTERN, bufferSize_);
 #endif
 
     // Horrible hack: if we are using perf integration, we don't
     // want to reuse code addresses, so we just leak the memory instead.
     if (PerfEnabled())
         return;
@@ -920,17 +919,17 @@ IonScript::copyPatchableBackedges(JSCont
         CodeLocationJump backedge(code, info.backedge);
         CodeLocationLabel loopHeader(code, CodeOffsetLabel(info.loopHeader->offset()));
         CodeLocationLabel interruptCheck(code, CodeOffsetLabel(info.interruptCheck->offset()));
         new(patchableBackedge) PatchableBackedge(backedge, loopHeader, interruptCheck);
 
         // Point the backedge to either of its possible targets, according to
         // whether an interrupt is currently desired, matching the targets
         // established by ensureIonCodeAccessible() above. We don't handle the
-        // interrupt immediately as the operation callback lock is held here.
+        // interrupt immediately as the interrupt lock is held here.
         PatchJump(backedge, cx->runtime()->interrupt ? interruptCheck : loopHeader);
 
         cx->runtime()->jitRuntime()->addPatchableBackedge(patchableBackedge);
     }
 }
 
 void
 IonScript::copySafepointIndices(const SafepointIndex *si, MacroAssembler &masm)
@@ -1113,17 +1112,17 @@ IonScript::unlinkFromRuntime(FreeOp *fop
         }
 
         fop->delete_(dependentAsmJSModules);
         dependentAsmJSModules = nullptr;
     }
 
     // The writes to the executable buffer below may clobber backedge jumps, so
     // make sure that those backedges are unlinked from the runtime and not
-    // reclobbered with garbage if an interrupt is triggered.
+    // reclobbered with garbage if an interrupt is requested.
     JSRuntime *rt = fop->runtime();
     for (size_t i = 0; i < backedgeEntries_; i++) {
         PatchableBackedge *backedge = &backedgeList()[i];
         rt->jitRuntime()->removePatchableBackedge(backedge);
     }
 
     // Clear the list of backedges, so that this method is idempotent. It is
     // called during destruction, and may be additionally called when the
@@ -1567,18 +1566,20 @@ AttachFinishedCompilations(JSContext *cx
                 // Release the worker thread lock and root the compiler for GC.
                 AutoTempAllocatorRooter root(cx, &builder->alloc());
                 AutoUnlockWorkerThreadState unlock;
                 AutoFlushCache afc("AttachFinishedCompilations", cx->runtime()->jitRuntime());
                 success = codegen->link(cx, builder->constraints());
             }
 
             if (!success) {
-                // Silently ignore OOM during code generation, we're at an
-                // operation callback and can't propagate failures.
+                // Silently ignore OOM during code generation. The caller is
+                // InvokeInterruptCallback, which always runs at a
+                // nondeterministic time. It's not OK to throw a catchable
+                // exception from there.
                 cx->clearPendingException();
             }
         }
 
         FinishOffThreadBuilder(builder);
     }
 #endif
 }
--- a/js/src/jit/Ion.h
+++ b/js/src/jit/Ion.h
@@ -181,16 +181,16 @@ TooManyArguments(unsigned nargs)
 void ForbidCompilation(JSContext *cx, JSScript *script);
 void ForbidCompilation(JSContext *cx, JSScript *script, ExecutionMode mode);
 
 void PurgeCaches(JSScript *script, JS::Zone *zone);
 size_t SizeOfIonData(JSScript *script, mozilla::MallocSizeOf mallocSizeOf);
 void DestroyIonScripts(FreeOp *fop, JSScript *script);
 void TraceIonScripts(JSTracer* trc, JSScript *script);
 
-void TriggerOperationCallbackForIonCode(JSRuntime *rt, JSRuntime::OperationCallbackTrigger trigger);
+void RequestInterruptForIonCode(JSRuntime *rt, JSRuntime::InterruptMode mode);
 
 } // namespace jit
 } // namespace js
 
 #endif // JS_ION
 
 #endif /* jit_Ion_h */
--- a/js/src/jit/IonLinker.h
+++ b/js/src/jit/IonLinker.h
@@ -81,19 +81,19 @@ class Linker
         return newCode<allowGC>(cx, cx->compartment()->jitCompartment()->execAlloc(), kind);
     }
 
     JitCode *newCodeForIonScript(JSContext *cx) {
 #ifdef JS_CODEGEN_ARM
         // ARM does not yet use implicit interrupt checks, see bug 864220.
         return newCode<CanGC>(cx, JSC::ION_CODE);
 #else
-        // The caller must lock the runtime against operation callback triggers,
-        // as the triggering thread may use the executable allocator below.
-        JS_ASSERT(cx->runtime()->currentThreadOwnsOperationCallbackLock());
+        // The caller must lock the runtime against interrupt requests, as the
+        // thread requesting an interrupt may use the executable allocator below.
+        JS_ASSERT(cx->runtime()->currentThreadOwnsInterruptLock());
 
         JSC::ExecutableAllocator *alloc = cx->runtime()->jitRuntime()->getIonAlloc(cx);
         if (!alloc)
             return nullptr;
 
         return newCode<CanGC>(cx, alloc, JSC::ION_CODE);
 #endif
     }
--- a/js/src/jit/JitCompartment.h
+++ b/js/src/jit/JitCompartment.h
@@ -143,19 +143,19 @@ class JitRuntime
     friend class JitCompartment;
 
     // Executable allocator for all code except the main code in an IonScript.
     // Shared with the runtime.
     JSC::ExecutableAllocator *execAlloc_;
 
     // Executable allocator used for allocating the main code in an IonScript.
     // All accesses on this allocator must be protected by the runtime's
-    // operation callback lock, as the executable memory may be protected()
-    // when triggering a callback to force a fault in the Ion code and avoid
-    // the neeed for explicit interrupt checks.
+    // interrupt lock, as the executable memory may be protected() when
+    // requesting an interrupt to force a fault in the Ion code and avoid the
+    // need for explicit interrupt checks.
     JSC::ExecutableAllocator *ionAlloc_;
 
     // Shared post-exception-handler tail
     JitCode *exceptionTail_;
 
     // Shared post-bailout-handler tail.
     JitCode *bailoutTail_;
 
@@ -241,22 +241,22 @@ class JitRuntime
         return flusher_;
     }
     void setFlusher(AutoFlushCache *fl) {
         if (!flusher_ || !fl)
             flusher_ = fl;
     }
 
     JSC::ExecutableAllocator *getIonAlloc(JSContext *cx) {
-        JS_ASSERT(cx->runtime()->currentThreadOwnsOperationCallbackLock());
+        JS_ASSERT(cx->runtime()->currentThreadOwnsInterruptLock());
         return ionAlloc_ ? ionAlloc_ : createIonAlloc(cx);
     }
 
     JSC::ExecutableAllocator *ionAlloc(JSRuntime *rt) {
-        JS_ASSERT(rt->currentThreadOwnsOperationCallbackLock());
+        JS_ASSERT(rt->currentThreadOwnsInterruptLock());
         return ionAlloc_;
     }
 
     bool ionCodeProtected() {
         return ionCodeProtected_;
     }
 
     void addPatchableBackedge(PatchableBackedge *backedge) {
--- a/js/src/jit/ParallelFunctions.cpp
+++ b/js/src/jit/ParallelFunctions.cpp
@@ -176,20 +176,20 @@ jit::TraceLIR(IonLIRTraceData *current)
 }
 
 bool
 jit::CheckOverRecursedPar(ForkJoinContext *cx)
 {
     JS_ASSERT(ForkJoinContext::current() == cx);
     int stackDummy_;
 
-    // When an interrupt is triggered, the main thread stack limit is
+    // When an interrupt is requested, the main thread stack limit is
     // overwritten with a sentinel value that brings us here.
     // Therefore, we must check whether this is really a stack overrun
-    // and, if not, check whether an interrupt is needed.
+    // and, if not, check whether an interrupt was requested.
     //
     // When not on the main thread, we don't overwrite the stack
     // limit, but we do still call into this routine if the interrupt
     // flag is set, so we still need to double check.
 
 #ifdef JS_ARM_SIMULATOR
     if (Simulator::Current()->overRecursed()) {
         cx->bailoutRecord->setCause(ParallelBailoutOverRecursed);
--- a/js/src/jit/VMFunctions.cpp
+++ b/js/src/jit/VMFunctions.cpp
@@ -104,18 +104,18 @@ NewGCObject(JSContext *cx, gc::AllocKind
 {
     return js::NewGCObject<CanGC>(cx, allocKind, 0, initialHeap);
 }
 
 bool
 CheckOverRecursed(JSContext *cx)
 {
     // IonMonkey's stackLimit is equal to nativeStackLimit by default. When we
-    // want to trigger an operation callback, we set the jitStackLimit to nullptr,
-    // which causes the stack limit check to fail.
+    // request an interrupt, we set the jitStackLimit to nullptr, which causes
+    // the stack limit check to fail.
     //
     // There are two states we're concerned about here:
     //   (1) The interrupt bit is set, and we need to fire the interrupt callback.
     //   (2) The stack limit has been exceeded, and we need to throw an error.
     //
     // Note that we can reach here if jitStackLimit is MAXADDR, but interrupt
     // has not yet been set to 1. That's okay; it will be set to 1 very shortly,
     // and in the interim we might just fire a few useless calls to
@@ -501,17 +501,17 @@ InterruptCheck(JSContext *cx)
     // and end up with a state where some fraction of the backedges point to
     // the interrupt handler and some don't. This is ok since the interrupt
     // is definitely about to be handled; if there are still backedges
     // afterwards which point to the interrupt handler, the next time they are
     // taken the backedges will just be reset again.
     cx->runtime()->jitRuntime()->patchIonBackedges(cx->runtime(),
                                                    JitRuntime::BackedgeLoopHeader);
 
-    return !!js_HandleExecutionInterrupt(cx);
+    return !!HandleExecutionInterrupt(cx);
 }
 
 HeapSlot *
 NewSlots(JSRuntime *rt, unsigned nslots)
 {
     JS_STATIC_ASSERT(sizeof(Value) == sizeof(HeapSlot));
 
     Value *slots = reinterpret_cast<Value *>(rt->malloc_(nslots * sizeof(Value)));
--- a/js/src/jsapi-tests/testSlowScript.cpp
+++ b/js/src/jsapi-tests/testSlowScript.cpp
@@ -1,61 +1,61 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "jsapi-tests/tests.h"
 
 static bool
-OperationCallback(JSContext *cx)
+InterruptCallback(JSContext *cx)
 {
     return false;
 }
 
 static unsigned sRemain;
 
 static bool
-TriggerOperationCallback(JSContext *cx, unsigned argc, jsval *vp)
+RequestInterruptCallback(JSContext *cx, unsigned argc, jsval *vp)
 {
     if (!sRemain--)
-        JS_TriggerOperationCallback(JS_GetRuntime(cx));
+        JS_RequestInterruptCallback(JS_GetRuntime(cx));
     *vp = JSVAL_VOID;
     return true;
 }
 
 BEGIN_TEST(testSlowScript)
 {
-    JS_SetOperationCallback(cx, OperationCallback);
-    JS_DefineFunction(cx, global, "triggerOperationCallback", TriggerOperationCallback, 0, 0);
+    JS_SetInterruptCallback(cx, InterruptCallback);
+    JS_DefineFunction(cx, global, "requestInterruptCallback", RequestInterruptCallback, 0, 0);
 
     test("while (true)"
          "  for (i in [0,0,0,0])"
-         "    triggerOperationCallback();");
+         "    requestInterruptCallback();");
 
     test("while (true)"
          "  for (i in [0,0,0,0])"
          "    for (j in [0,0,0,0])"
-         "      triggerOperationCallback();");
+         "      requestInterruptCallback();");
 
     test("while (true)"
          "  for (i in [0,0,0,0])"
          "    for (j in [0,0,0,0])"
          "      for (k in [0,0,0,0])"
-         "        triggerOperationCallback();");
+         "        requestInterruptCallback();");
 
-    test("function f() { while (true) yield triggerOperationCallback() }"
+    test("function f() { while (true) yield requestInterruptCallback() }"
          "for (i in f()) ;");
 
     test("function f() { while (true) yield 1 }"
          "for (i in f())"
-         "  triggerOperationCallback();");
+         "  requestInterruptCallback();");
 
     test("(function() {"
          "  while (true)"
-         "    let (x = 1) { eval('triggerOperationCallback()'); }"
+         "    let (x = 1) { eval('requestInterruptCallback()'); }"
          "})()");
 
     return true;
 }
 
 bool
 test(const char *bytes)
 {
--- a/js/src/jsapi.cpp
+++ b/js/src/jsapi.cpp
@@ -2155,17 +2155,17 @@ js::RecomputeStackLimit(JSRuntime *rt, S
     // If there's no pending interrupt request set on the runtime's main thread's
     // jitStackLimit, then update it so that it reflects the new nativeStacklimit.
     //
     // Note that, for now, we use the untrusted limit for ion. This is fine,
     // because it's the most conservative limit, and if we hit it, we'll bail
     // out of ion into the interpeter, which will do a proper recursion check.
 #ifdef JS_ION
     if (kind == StackForUntrustedScript) {
-        JSRuntime::AutoLockForOperationCallback lock(rt);
+        JSRuntime::AutoLockForInterrupt lock(rt);
         if (rt->mainThread.jitStackLimit != uintptr_t(-1)) {
             rt->mainThread.jitStackLimit = rt->mainThread.nativeStackLimit[kind];
 #ifdef JS_ARM_SIMULATOR
             rt->mainThread.jitStackLimit = jit::Simulator::StackLimit();
 #endif
         }
     }
 #endif
@@ -4982,34 +4982,34 @@ JS_New(JSContext *cx, JSObject *ctorArg,
                                  bytes.ptr());
         }
         return nullptr;
     }
 
     return &args.rval().toObject();
 }
 
-JS_PUBLIC_API(JSOperationCallback)
-JS_SetOperationCallback(JSRuntime *rt, JSOperationCallback callback)
-{
-    JSOperationCallback old = rt->operationCallback;
-    rt->operationCallback = callback;
+JS_PUBLIC_API(JSInterruptCallback)
+JS_SetInterruptCallback(JSRuntime *rt, JSInterruptCallback callback)
+{
+    JSInterruptCallback old = rt->interruptCallback;
+    rt->interruptCallback = callback;
     return old;
 }
 
-JS_PUBLIC_API(JSOperationCallback)
-JS_GetOperationCallback(JSRuntime *rt)
-{
-    return rt->operationCallback;
+JS_PUBLIC_API(JSInterruptCallback)
+JS_GetInterruptCallback(JSRuntime *rt)
+{
+    return rt->interruptCallback;
 }
 
 JS_PUBLIC_API(void)
-JS_TriggerOperationCallback(JSRuntime *rt)
-{
-    rt->triggerOperationCallback(JSRuntime::TriggerCallbackAnyThread);
+JS_RequestInterruptCallback(JSRuntime *rt)
+{
+    rt->requestInterrupt(JSRuntime::RequestInterruptAnyThread);
 }
 
 JS_PUBLIC_API(bool)
 JS_IsRunning(JSContext *cx)
 {
     return cx->currentlyRunning();
 }
 
--- a/js/src/jsapi.h
+++ b/js/src/jsapi.h
@@ -715,17 +715,17 @@ typedef enum JSFinalizeStatus {
      */
     JSFINALIZE_COLLECTION_END
 } JSFinalizeStatus;
 
 typedef void
 (* JSFinalizeCallback)(JSFreeOp *fop, JSFinalizeStatus status, bool isCompartment);
 
 typedef bool
-(* JSOperationCallback)(JSContext *cx);
+(* JSInterruptCallback)(JSContext *cx);
 
 typedef void
 (* JSErrorReporter)(JSContext *cx, const char *message, JSErrorReport *report);
 
 #ifdef MOZ_TRACE_JSCALLS
 typedef void
 (* JSFunctionCallback)(const JSFunction *fun,
                        const JSScript *scr,
@@ -3827,36 +3827,36 @@ Call(JSContext *cx, JS::HandleValue this
     JS_ASSERT(funObj);
     JS::RootedValue fun(cx, JS::ObjectValue(*funObj));
     return Call(cx, thisv, fun, args, rval);
 }
 
 } /* namespace JS */
 
 /*
- * These functions allow setting an operation callback that will be called
+ * These functions allow setting an interrupt callback that will be called
  * from the JS thread some time after any thread triggered the callback using
- * JS_TriggerOperationCallback(rt).
+ * JS_RequestInterruptCallback(rt).
  *
  * To schedule the GC and for other activities the engine internally triggers
- * operation callbacks. The embedding should thus not rely on callbacks being
+ * interrupt callbacks. The embedding should thus not rely on callbacks being
  * triggered through the external API only.
  *
  * Important note: Additional callbacks can occur inside the callback handler
  * if it re-enters the JS engine. The embedding must ensure that the callback
  * is disconnected before attempting such re-entry.
  */
-extern JS_PUBLIC_API(JSOperationCallback)
-JS_SetOperationCallback(JSRuntime *rt, JSOperationCallback callback);
-
-extern JS_PUBLIC_API(JSOperationCallback)
-JS_GetOperationCallback(JSRuntime *rt);
+extern JS_PUBLIC_API(JSInterruptCallback)
+JS_SetInterruptCallback(JSRuntime *rt, JSInterruptCallback callback);
+
+extern JS_PUBLIC_API(JSInterruptCallback)
+JS_GetInterruptCallback(JSRuntime *rt);
 
 extern JS_PUBLIC_API(void)
-JS_TriggerOperationCallback(JSRuntime *rt);
+JS_RequestInterruptCallback(JSRuntime *rt);
 
 extern JS_PUBLIC_API(bool)
 JS_IsRunning(JSContext *cx);
 
 /*
  * Saving and restoring frame chains.
  *
  * These two functions are used to set aside cx's call stack while that stack
@@ -3871,17 +3871,17 @@ extern JS_PUBLIC_API(bool)
 JS_SaveFrameChain(JSContext *cx);
 
 extern JS_PUBLIC_API(void)
 JS_RestoreFrameChain(JSContext *cx);
 
 #ifdef MOZ_TRACE_JSCALLS
 /*
  * The callback is expected to be quick and noninvasive. It should not
- * trigger interrupts, turn on debugging, or produce uncaught JS
+ * request interrupts, turn on debugging, or produce uncaught JS
  * exceptions. The state of the stack and registers in the context
  * cannot be relied upon, since this callback may be invoked directly
  * from either JIT. The 'entering' field means we are entering a
  * function if it is positive, leaving a function if it is zero or
  * negative.
  */
 extern JS_PUBLIC_API(void)
 JS_SetFunctionCallback(JSContext *cx, JSFunctionCallback fcb);
--- a/js/src/jsarray.cpp
+++ b/js/src/jsarray.cpp
@@ -611,17 +611,17 @@ js::ArraySetLength(typename ExecutionMod
 
             Vector<uint32_t> indexes(cx);
             {
                 AutoIdVector props(cx);
                 if (!GetPropertyNames(cx, arr, JSITER_OWNONLY | JSITER_HIDDEN, &props))
                     return false;
 
                 for (size_t i = 0; i < props.length(); i++) {
-                    if (!JS_CHECK_OPERATION_LIMIT(cx))
+                    if (!CheckForInterrupt(cx))
                         return false;
 
                     uint32_t index;
                     if (!js_IdIsIndex(props[i], &index))
                         continue;
 
                     if (index >= newLen && index < oldLen) {
                         if (!indexes.append(index))
@@ -896,17 +896,17 @@ array_toSource_impl(JSContext *cx, CallA
         return false;
 
     uint32_t length;
     if (!GetLengthProperty(cx, obj, &length))
         return false;
 
     for (uint32_t index = 0; index < length; index++) {
         bool hole;
-        if (!JS_CHECK_OPERATION_LIMIT(cx) ||
+        if (!CheckForInterrupt(cx) ||
             !GetElement(cx, obj, index, &hole, &elt)) {
             return false;
         }
 
         /* Get element's character string. */
         JSString *str;
         if (hole) {
             str = cx->runtime()->emptyString;
@@ -983,17 +983,17 @@ ArrayJoinKernel(JSContext *cx, Separator
     uint32_t i = 0;
 
     if (!Locale && obj->is<ArrayObject>() && !ObjectMayHaveExtraIndexedProperties(obj)) {
         // This loop handles all elements up to initializedLength. If
         // length > initLength we rely on the second loop to add the
         // other elements.
         uint32_t initLength = obj->getDenseInitializedLength();
         while (i < initLength) {
-            if (!JS_CHECK_OPERATION_LIMIT(cx))
+            if (!CheckForInterrupt(cx))
                 return false;
 
             const Value &elem = obj->getDenseElement(i);
 
             if (elem.isString()) {
                 if (!sb.append(elem.toString()))
                     return false;
             } else if (elem.isNumber()) {
@@ -1016,17 +1016,17 @@ ArrayJoinKernel(JSContext *cx, Separator
             if (++i != length && !sepOp(cx, sb))
                 return false;
         }
     }
 
     if (i != length) {
         RootedValue v(cx);
         while (i < length) {
-            if (!JS_CHECK_OPERATION_LIMIT(cx))
+            if (!CheckForInterrupt(cx))
                 return false;
 
             bool hole;
             if (!GetElement(cx, obj, i, &hole, &v))
                 return false;
             if (!hole && !v.isNullOrUndefined()) {
                 if (Locale) {
                     JSObject *robj = ToObject(cx, v);
@@ -1273,17 +1273,17 @@ InitArrayElements(JSContext *cx, HandleO
         JS_ASSERT(count < UINT32_MAX / sizeof(Value));
         arr->copyDenseElements(start, vector, count);
         JS_ASSERT_IF(count != 0, !arr->getDenseElement(newlen - 1).isMagic(JS_ELEMENTS_HOLE));
         return true;
     } while (false);
 
     const Value* end = vector + count;
     while (vector < end && start <= MAX_ARRAY_INDEX) {
-        if (!JS_CHECK_OPERATION_LIMIT(cx) ||
+        if (!CheckForInterrupt(cx) ||
             !SetArrayElement(cx, obj, start++, HandleValue::fromMarkedLocation(vector++))) {
             return false;
         }
     }
 
     if (vector == end)
         return true;
 
@@ -1375,17 +1375,17 @@ array_reverse(JSContext *cx, unsigned ar
          */
         args.rval().setObject(*obj);
         return true;
     } while (false);
 
     RootedValue lowval(cx), hival(cx);
     for (uint32_t i = 0, half = len / 2; i < half; i++) {
         bool hole, hole2;
-        if (!JS_CHECK_OPERATION_LIMIT(cx) ||
+        if (!CheckForInterrupt(cx) ||
             !GetElement(cx, obj, i, &hole, &lowval) ||
             !GetElement(cx, obj, len - i - 1, &hole2, &hival))
         {
             return false;
         }
 
         if (!hole && !hole2) {
             if (!SetArrayElement(cx, obj, i, hival))
@@ -1410,17 +1410,17 @@ array_reverse(JSContext *cx, unsigned ar
     return true;
 }
 
 namespace {
 
 inline bool
 CompareStringValues(JSContext *cx, const Value &a, const Value &b, bool *lessOrEqualp)
 {
-    if (!JS_CHECK_OPERATION_LIMIT(cx))
+    if (!CheckForInterrupt(cx))
         return false;
 
     JSString *astr = a.toString();
     JSString *bstr = b.toString();
     int32_t result;
     if (!CompareStrings(cx, astr, bstr, &result))
         return false;
 
@@ -1489,17 +1489,17 @@ CompareLexicographicInt32(const Value &a
 
     return true;
 }
 
 static inline bool
 CompareSubStringValues(JSContext *cx, const jschar *s1, size_t l1,
                        const jschar *s2, size_t l2, bool *lessOrEqualp)
 {
-    if (!JS_CHECK_OPERATION_LIMIT(cx))
+    if (!CheckForInterrupt(cx))
         return false;
 
     if (!s1 || !s2)
         return false;
 
     int32_t result = CompareChars(s1, l1, s2, l2);
     *lessOrEqualp = (result <= 0);
     return true;
@@ -1563,17 +1563,17 @@ SortComparatorFunction::operator()(const
 {
     /*
      * array_sort deals with holes and undefs on its own and they should not
      * come here.
      */
     JS_ASSERT(!a.isMagic() && !a.isUndefined());
     JS_ASSERT(!a.isMagic() && !b.isUndefined());
 
-    if (!JS_CHECK_OPERATION_LIMIT(cx))
+    if (!CheckForInterrupt(cx))
         return false;
 
     InvokeArgs &args = fig.args();
     if (!args.init(2))
         return false;
 
     args.setCallee(fval);
     args.setThis(UndefinedValue());
@@ -1772,17 +1772,17 @@ SortLexicographically(JSContext *cx, Aut
 
     /* MergeSort uses the upper half as scratch space. */
     if (!strElements.reserve(2 * len))
         return false;
 
     /* Convert Values to strings. */
     size_t cursor = 0;
     for (size_t i = 0; i < len; i++) {
-        if (!JS_CHECK_OPERATION_LIMIT(cx))
+        if (!CheckForInterrupt(cx))
             return false;
 
         if (!ValueToStringBuffer(cx, (*vec)[i], sb))
             return false;
 
         StringifiedElement el = { cursor, sb.length(), i };
         strElements.infallibleAppend(el);
         cursor = sb.length();
@@ -1810,17 +1810,17 @@ SortNumerically(JSContext *cx, AutoValue
     Vector<NumericElement, 0, TempAllocPolicy> numElements(cx);
 
     /* MergeSort uses the upper half as scratch space. */
     if (!numElements.reserve(2 * len))
         return false;
 
     /* Convert Values to numerics. */
     for (size_t i = 0; i < len; i++) {
-        if (!JS_CHECK_OPERATION_LIMIT(cx))
+        if (!CheckForInterrupt(cx))
             return false;
 
         double dv;
         if (!ToNumber(cx, vec->handleAt(i), &dv))
             return false;
 
         NumericElement el = { dv, i };
         numElements.infallibleAppend(el);
@@ -1903,17 +1903,17 @@ js::array_sort(JSContext *cx, unsigned a
          * of elements, append undefs after them and then make holes after
          * undefs.
          */
         undefs = 0;
         bool allStrings = true;
         bool allInts = true;
         RootedValue v(cx);
         for (uint32_t i = 0; i < len; i++) {
-            if (!JS_CHECK_OPERATION_LIMIT(cx))
+            if (!CheckForInterrupt(cx))
                 return false;
 
             /* Clear vec[newlen] before including it in the rooted set. */
             bool hole;
             if (!GetElement(cx, obj, i, &hole, &v))
                 return false;
             if (hole)
                 continue;
@@ -1986,23 +1986,23 @@ js::array_sort(JSContext *cx, unsigned a
 
         if (!InitArrayElements(cx, obj, 0, uint32_t(n), vec.begin(), DontUpdateTypes))
             return false;
     }
 
     /* Set undefs that sorted after the rest of elements. */
     while (undefs != 0) {
         --undefs;
-        if (!JS_CHECK_OPERATION_LIMIT(cx) || !SetArrayElement(cx, obj, n++, UndefinedHandleValue))
+        if (!CheckForInterrupt(cx) || !SetArrayElement(cx, obj, n++, UndefinedHandleValue))
             return false;
     }
 
     /* Re-create any holes that sorted to the end of the array. */
     while (len > n) {
-        if (!JS_CHECK_OPERATION_LIMIT(cx) || !DeletePropertyOrThrow(cx, obj, --len))
+        if (!CheckForInterrupt(cx) || !DeletePropertyOrThrow(cx, obj, --len))
             return false;
     }
     args.rval().setObject(*obj);
     return true;
 }
 
 bool
 js::NewbornArrayPush(JSContext *cx, HandleObject obj, const Value &v)
@@ -2195,17 +2195,17 @@ js::array_shift(JSContext *cx, unsigned 
     /* Steps 5, 10. */
     bool hole;
     if (!GetElement(cx, obj, uint32_t(0), &hole, args.rval()))
         return false;
 
     /* Steps 6-7. */
     RootedValue value(cx);
     for (uint32_t i = 0; i < newlen; i++) {
-        if (!JS_CHECK_OPERATION_LIMIT(cx))
+        if (!CheckForInterrupt(cx))
             return false;
         if (!GetElement(cx, obj, i + 1, &hole, &value))
             return false;
         if (hole) {
             if (!DeletePropertyOrThrow(cx, obj, i))
                 return false;
         } else {
             if (!SetArrayElement(cx, obj, i, value))
@@ -2260,17 +2260,17 @@ array_unshift(JSContext *cx, unsigned ar
 
             if (!optimized) {
                 double last = length;
                 double upperIndex = last + args.length();
                 RootedValue value(cx);
                 do {
                     --last, --upperIndex;
                     bool hole;
-                    if (!JS_CHECK_OPERATION_LIMIT(cx))
+                    if (!CheckForInterrupt(cx))
                         return false;
                     if (!GetElement(cx, obj, last, &hole, &value))
                         return false;
                     if (hole) {
                         if (!DeletePropertyOrThrow(cx, obj, upperIndex))
                             return false;
                     } else {
                         if (!SetArrayElement(cx, obj, upperIndex, value))
@@ -2409,17 +2409,17 @@ array_splice(JSContext *cx, unsigned arg
         arr = NewDenseAllocatedArray(cx, actualDeleteCount);
         if (!arr)
             return false;
         TryReuseArrayType(obj, arr);
 
         RootedValue fromValue(cx);
         for (uint32_t k = 0; k < actualDeleteCount; k++) {
             bool hole;
-            if (!JS_CHECK_OPERATION_LIMIT(cx) ||
+            if (!CheckForInterrupt(cx) ||
                 !GetElement(cx, obj, actualStart + k, &hole, &fromValue) ||
                 (!hole && !JSObject::defineElement(cx, arr, k, fromValue)))
             {
                 return false;
             }
         }
     }
 
@@ -2448,24 +2448,24 @@ array_splice(JSContext *cx, unsigned arg
 
             /* Fix running enumerators for the deleted items. */
             if (!js_SuppressDeletedElements(cx, obj, finalLength, len))
                 return false;
         } else {
             /*
              * This is all very slow if the length is very large. We don't yet
              * have the ability to iterate in sorted order, so we just do the
-             * pessimistic thing and let JS_CHECK_OPERATION_LIMIT handle the
+             * pessimistic thing and let CheckForInterrupt handle the
              * fallout.
              */
 
             /* Steps 12(a)-(b). */
             RootedValue fromValue(cx);
             for (uint32_t from = sourceIndex, to = targetIndex; from < len; from++, to++) {
-                if (!JS_CHECK_OPERATION_LIMIT(cx))
+                if (!CheckForInterrupt(cx))
                     return false;
 
                 bool hole;
                 if (!GetElement(cx, obj, from, &hole, &fromValue))
                     return false;
                 if (hole) {
                     if (!DeletePropertyOrThrow(cx, obj, to))
                         return false;
@@ -2523,17 +2523,17 @@ array_splice(JSContext *cx, unsigned arg
                                    actualStart + actualDeleteCount,
                                    len - (actualStart + actualDeleteCount));
 
             if (cx->typeInferenceEnabled())
                 obj->setDenseInitializedLength(len + itemCount - actualDeleteCount);
         } else {
             RootedValue fromValue(cx);
             for (double k = len - actualDeleteCount; k > actualStart; k--) {
-                if (!JS_CHECK_OPERATION_LIMIT(cx))
+                if (!CheckForInterrupt(cx))
                     return false;
 
                 double from = k + actualDeleteCount - 1;
                 double to = k + itemCount - 1;
 
                 bool hole;
                 if (!GetElement(cx, obj, from, &hole, &fromValue))
                     return false;
@@ -2631,29 +2631,29 @@ js::array_concat(JSContext *cx, unsigned
         if (!narr)
             return false;
         args.rval().setObject(*narr);
         length = 0;
     }
 
     /* Loop over [0, argc] to concat args into narr, expanding all Arrays. */
     for (unsigned i = 0; i <= argc; i++) {
-        if (!JS_CHECK_OPERATION_LIMIT(cx))
+        if (!CheckForInterrupt(cx))
             return false;
         HandleValue v = HandleValue::fromMarkedLocation(&p[i]);
         if (v.isObject()) {
             RootedObject obj(cx, &v.toObject());
             if (ObjectClassIs(obj, ESClass_Array, cx)) {
                 uint32_t alength;
                 if (!GetLengthProperty(cx, obj, &alength))
                     return false;
                 RootedValue tmp(cx);
                 for (uint32_t slot = 0; slot < alength; slot++) {
                     bool hole;
-                    if (!JS_CHECK_OPERATION_LIMIT(cx) || !GetElement(cx, obj, slot, &hole, &tmp))
+                    if (!CheckForInterrupt(cx) || !GetElement(cx, obj, slot, &hole, &tmp))
                         return false;
 
                     /*
                      * Per ECMA 262, 15.4.4.4, step 9, ignore nonexistent
                      * properties.
                      */
                     if (!hole && !SetArrayElement(cx, narr, length + slot, tmp))
                         return false;
@@ -2761,17 +2761,17 @@ array_slice(JSContext *cx, unsigned argc
 
 JS_FRIEND_API(bool)
 js::SliceSlowly(JSContext* cx, HandleObject obj, HandleObject receiver,
                 uint32_t begin, uint32_t end, HandleObject result)
 {
     RootedValue value(cx);
     for (uint32_t slot = begin; slot < end; slot++) {
         bool hole;
-        if (!JS_CHECK_OPERATION_LIMIT(cx) ||
+        if (!CheckForInterrupt(cx) ||
             !GetElement(cx, obj, receiver, slot, &hole, &value))
         {
             return false;
         }
         if (!hole && !JSObject::defineElement(cx, result, slot - begin, value))
             return false;
     }
     return true;
@@ -2821,17 +2821,17 @@ array_filter(JSContext *cx, unsigned arg
     uint32_t to = 0;
 
     /* Step 9. */
     JS_ASSERT(!InParallelSection());
     FastInvokeGuard fig(cx, ObjectValue(*callable));
     InvokeArgs &args2 = fig.args();
     RootedValue kValue(cx);
     while (k < len) {
-        if (!JS_CHECK_OPERATION_LIMIT(cx))
+        if (!CheckForInterrupt(cx))
             return false;
 
         /* Step a, b, and c.i. */
         bool kNotPresent;
         if (!GetElement(cx, obj, k, &kNotPresent, &kValue))
             return false;
 
         /* Step c.ii-iii. */
--- a/js/src/jscntxt.cpp
+++ b/js/src/jscntxt.cpp
@@ -996,68 +996,68 @@ JS_FRIEND_API(const JSErrorFormatString 
 js_GetErrorMessage(void *userRef, const char *locale, const unsigned errorNumber)
 {
     if ((errorNumber > 0) && (errorNumber < JSErr_Limit))
         return &js_ErrorFormatString[errorNumber];
     return nullptr;
 }
 
 bool
-js_InvokeOperationCallback(JSContext *cx)
+js::InvokeInterruptCallback(JSContext *cx)
 {
     JS_ASSERT_REQUEST_DEPTH(cx);
 
     JSRuntime *rt = cx->runtime();
     JS_ASSERT(rt->interrupt);
 
     // Reset the callback counter first, then run GC and yield. If another
     // thread is racing us here we will accumulate another callback request
     // which will be serviced at the next opportunity.
     rt->interrupt = false;
 
-    // IonMonkey sets its stack limit to UINTPTR_MAX to trigger operation
+    // IonMonkey sets its stack limit to UINTPTR_MAX to trigger interrupt
     // callbacks.
     rt->resetJitStackLimit();
 
     js::gc::GCIfNeeded(cx);
 
 #ifdef JS_ION
 #ifdef JS_THREADSAFE
     rt->interruptPar = false;
 #endif
 
-    // A worker thread may have set the callback after finishing an Ion
+    // A worker thread may have requested an interrupt after finishing an Ion
     // compilation.
     jit::AttachFinishedCompilations(cx);
 #endif
 
     // Important: Additional callbacks can occur inside the callback handler
     // if it re-enters the JS engine. The embedding must ensure that the
     // callback is disconnected before attempting such re-entry.
-    JSOperationCallback cb = cx->runtime()->operationCallback;
+    JSInterruptCallback cb = cx->runtime()->interruptCallback;
     if (!cb || cb(cx))
         return true;
 
     // No need to set aside any pending exception here: ComputeStackString
     // already does that.
     Rooted<JSString*> stack(cx, ComputeStackString(cx));
     const jschar *chars = stack ? stack->getCharsZ(cx) : nullptr;
     if (!chars)
         chars = MOZ_UTF16("(stack not available)");
     JS_ReportErrorFlagsAndNumberUC(cx, JSREPORT_WARNING, js_GetErrorMessage, nullptr,
                                    JSMSG_TERMINATED, chars);
 
     return false;
 }
 
 bool
-js_HandleExecutionInterrupt(JSContext *cx)
+js::HandleExecutionInterrupt(JSContext *cx)
 {
     if (cx->runtime()->interrupt)
-        return js_InvokeOperationCallback(cx);
+        return InvokeInterruptCallback(cx);
     return true;
 }
 
 js::ThreadSafeContext::ThreadSafeContext(JSRuntime *rt, PerThreadData *pt, ContextKind kind)
   : ContextFriendFields(rt),
     contextKind_(kind),
     perThreadData(pt),
     allocator_(nullptr)
--- a/js/src/jscntxt.h
+++ b/js/src/jscntxt.h
@@ -813,40 +813,47 @@ char *
 js_strdup(js::ExclusiveContext *cx, const char *s);
 
 #ifdef JS_THREADSAFE
 # define JS_ASSERT_REQUEST_DEPTH(cx)  JS_ASSERT((cx)->runtime()->requestDepth >= 1)
 #else
 # define JS_ASSERT_REQUEST_DEPTH(cx)  ((void) 0)
 #endif
 
+namespace js {
+
 /*
- * Invoke the operation callback and return false if the current execution
+ * Invoke the interrupt callback and return false if the current execution
  * is to be terminated.
  */
-extern bool
-js_InvokeOperationCallback(JSContext *cx);
+bool
+InvokeInterruptCallback(JSContext *cx);
 
-extern bool
-js_HandleExecutionInterrupt(JSContext *cx);
+bool
+HandleExecutionInterrupt(JSContext *cx);
 
 /*
- * If the operation callback flag was set, call the operation callback.
- * This macro can run the full GC. Return true if it is OK to continue and
- * false otherwise.
+ * Process any pending interrupt requests. Long-running inner loops in C++ must
+ * call this periodically to make sure they are interruptible --- that is, to
+ * make sure they do not prevent the slow script dialog from appearing.
+ *
+ * This can run a full GC or call the interrupt callback, which could do
+ * anything. In the browser, it displays the slow script dialog.
+ *
+ * If this returns true, the caller can continue; if false, the caller must
+ * break out of its loop. This happens if, for example, the user clicks "Stop
+ * script" on the slow script dialog; treat it as an uncatchable error.
  */
-static MOZ_ALWAYS_INLINE bool
-JS_CHECK_OPERATION_LIMIT(JSContext *cx)
+inline bool
+CheckForInterrupt(JSContext *cx)
 {
     JS_ASSERT_REQUEST_DEPTH(cx);
-    return !cx->runtime()->interrupt || js_InvokeOperationCallback(cx);
+    return !cx->runtime()->interrupt || InvokeInterruptCallback(cx);
 }
 
-namespace js {
-
 /************************************************************************/
 
 class AutoStringVector : public AutoVectorRooter<JSString *>
 {
   public:
     explicit AutoStringVector(JSContext *cx
                               MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
         : AutoVectorRooter<JSString *>(cx, STRINGVECTOR)
--- a/js/src/jscompartment.cpp
+++ b/js/src/jscompartment.cpp
@@ -125,19 +125,19 @@ JSCompartment::init(JSContext *cx)
 jit::JitRuntime *
 JSRuntime::createJitRuntime(JSContext *cx)
 {
     // The shared stubs are created in the atoms compartment, which may be
     // accessed by other threads with an exclusive context.
     AutoLockForExclusiveAccess atomsLock(cx);
 
     // The runtime will only be created on its owning thread, but reads of a
-    // runtime's jitRuntime() can occur when another thread is triggering an
-    // operation callback.
-    AutoLockForOperationCallback lock(this);
+    // runtime's jitRuntime() can occur when another thread is requesting an
+    // interrupt.
+    AutoLockForInterrupt lock(this);
 
     JS_ASSERT(!jitRuntime_);
 
     jitRuntime_ = cx->new_<jit::JitRuntime>();
 
     if (!jitRuntime_)
         return nullptr;
 
--- a/js/src/jsgc.cpp
+++ b/js/src/jsgc.cpp
@@ -590,18 +590,18 @@ FinalizeArenas(FreeOp *fop,
       case FINALIZE_SHORT_STRING:
         return FinalizeTypedArenas<JSShortString>(fop, src, dest, thingKind, budget);
       case FINALIZE_EXTERNAL_STRING:
         return FinalizeTypedArenas<JSExternalString>(fop, src, dest, thingKind, budget);
       case FINALIZE_JITCODE:
 #ifdef JS_ION
       {
         // JitCode finalization may release references on an executable
-        // allocator that is accessed when triggering interrupts.
-        JSRuntime::AutoLockForOperationCallback lock(fop->runtime());
+        // allocator that is accessed when requesting interrupts.
+        JSRuntime::AutoLockForInterrupt lock(fop->runtime());
         return FinalizeTypedArenas<jit::JitCode>(fop, src, dest, thingKind, budget);
       }
 #endif
       default:
         MOZ_ASSUME_UNREACHABLE("Invalid alloc kind");
     }
 }
 
@@ -2099,47 +2099,47 @@ js::SetMarkStackLimit(JSRuntime *rt, siz
 
 void
 js::MarkCompartmentActive(StackFrame *fp)
 {
     fp->script()->compartment()->zone()->active = true;
 }
 
 static void
-TriggerOperationCallback(JSRuntime *rt, JS::gcreason::Reason reason)
+RequestInterrupt(JSRuntime *rt, JS::gcreason::Reason reason)
 {
     if (rt->gcIsNeeded)
         return;
 
     rt->gcIsNeeded = true;
     rt->gcTriggerReason = reason;
-    rt->triggerOperationCallback(JSRuntime::TriggerCallbackMainThread);
+    rt->requestInterrupt(JSRuntime::RequestInterruptMainThread);
 }
 
 bool
 js::TriggerGC(JSRuntime *rt, JS::gcreason::Reason reason)
 {
     /* Wait till end of parallel section to trigger GC. */
     if (InParallelSection()) {
         ForkJoinContext::current()->requestGC(reason);
         return true;
     }
 
-    /* Don't trigger GCs when allocating under the operation callback lock. */
-    if (rt->currentThreadOwnsOperationCallbackLock())
+    /* Don't trigger GCs when allocating under the interrupt callback lock. */
+    if (rt->currentThreadOwnsInterruptLock())
         return false;
 
     JS_ASSERT(CurrentThreadCanAccessRuntime(rt));
 
     /* GC is already running. */
     if (rt->isHeapCollecting())
         return false;
 
     JS::PrepareForFullGC(rt);
-    TriggerOperationCallback(rt, reason);
+    RequestInterrupt(rt, reason);
     return true;
 }
 
 bool
 js::TriggerZoneGC(Zone *zone, JS::gcreason::Reason reason)
 {
     /*
      * If parallel threads are running, wait till they
@@ -2151,18 +2151,18 @@ js::TriggerZoneGC(Zone *zone, JS::gcreas
     }
 
     /* Zones in use by a thread with an exclusive context can't be collected. */
     if (zone->usedByExclusiveThread)
         return false;
 
     JSRuntime *rt = zone->runtimeFromMainThread();
 
-    /* Don't trigger GCs when allocating under the operation callback lock. */
-    if (rt->currentThreadOwnsOperationCallbackLock())
+    /* Don't trigger GCs when allocating under the interrupt callback lock. */
+    if (rt->currentThreadOwnsInterruptLock())
         return false;
 
     /* GC is already running. */
     if (rt->isHeapCollecting())
         return false;
 
     if (rt->gcZeal() == ZealAllocValue) {
         TriggerGC(rt, reason);
@@ -2171,17 +2171,17 @@ js::TriggerZoneGC(Zone *zone, JS::gcreas
 
     if (rt->isAtomsZone(zone)) {
         /* We can't do a zone GC of the atoms compartment. */
         TriggerGC(rt, reason);
         return true;
     }
 
     PrepareZoneForGC(zone);
-    TriggerOperationCallback(rt, reason);
+    RequestInterrupt(rt, reason);
     return true;
 }
 
 void
 js::MaybeGC(JSContext *cx)
 {
     JSRuntime *rt = cx->runtime();
     JS_ASSERT(CurrentThreadCanAccessRuntime(rt));
--- a/js/src/jsgcinlines.h
+++ b/js/src/jsgcinlines.h
@@ -418,30 +418,28 @@ CheckAllocatorState(ThreadSafeContext *c
     JS_ASSERT_IF(rt->isAtomsCompartment(ncx->compartment()),
                  kind == FINALIZE_STRING ||
                  kind == FINALIZE_SHORT_STRING ||
                  kind == FINALIZE_JITCODE);
     JS_ASSERT(!rt->isHeapBusy());
     JS_ASSERT(!rt->noGCOrAllocationCheck);
 #endif
 
-    /* For testing out of memory conditions */
+    // For testing out of memory conditions
     JS_OOM_POSSIBLY_FAIL_REPORT(ncx);
 
     if (allowGC) {
 #ifdef JS_GC_ZEAL
         if (rt->needZealousGC())
             js::gc::RunDebugGC(ncx);
 #endif
 
         if (rt->interrupt) {
-            /*
-             * Invoking the operation handler can fail and we can't usefully
-             * handle that here. Just check in case we need to collect instead.
-             */
+            // Invoking the interrupt callback can fail and we can't usefully
+            // handle that here. Just check in case we need to collect instead.
             js::gc::GCIfNeeded(ncx);
         }
 
         MaybeCheckStackRoots(ncx);
     }
 
     return true;
 }
--- a/js/src/jsiter.cpp
+++ b/js/src/jsiter.cpp
@@ -929,18 +929,18 @@ CloseLegacyGenerator(JSContext *cx, Hand
 
 bool
 js::ValueToIterator(JSContext *cx, unsigned flags, MutableHandleValue vp)
 {
     /* JSITER_KEYVALUE must always come with JSITER_FOREACH */
     JS_ASSERT_IF(flags & JSITER_KEYVALUE, flags & JSITER_FOREACH);
 
     /*
-     * Make sure the more/next state machine doesn't get stuck. A value might be
-     * left in iterValue when a trace is left due to an operation time-out after
+     * Make sure the more/next state machine doesn't get stuck. A value might
+     * be left in iterValue when a trace is left due to an interrupt after
      * JSOP_MOREITER but before the value is picked up by FOR*.
      */
     cx->iterValue.setMagic(JS_NO_ITER_VALUE);
 
     RootedObject obj(cx);
     if (vp.isObject()) {
         /* Common case. */
         obj = &vp.toObject();
@@ -1346,17 +1346,17 @@ ForOfIterator::init(HandleValue iterable
     return true;
 }
 
 inline bool
 ForOfIterator::nextFromOptimizedArray(MutableHandleValue vp, bool *done)
 {
     JS_ASSERT(index != NOT_ARRAY);
 
-    if (!JS_CHECK_OPERATION_LIMIT(cx_))
+    if (!CheckForInterrupt(cx_))
         return false;
 
     JS_ASSERT(iterator->isNative());
     JS_ASSERT(iterator->is<ArrayObject>());
 
     if (index >= iterator->as<ArrayObject>().length()) {
         vp.setUndefined();
         *done = true;
--- a/js/src/json.cpp
+++ b/js/src/json.cpp
@@ -555,17 +555,17 @@ js_Stringify(JSContext *cx, MutableHandl
                 return false;
 
             /* Step 4b(iii). */
             uint32_t i = 0;
 
             /* Step 4b(iv). */
             RootedValue v(cx);
             for (; i < len; i++) {
-                if (!JS_CHECK_OPERATION_LIMIT(cx))
+                if (!CheckForInterrupt(cx))
                     return false;
 
                 /* Step 4b(iv)(2). */
                 if (!JSObject::getElement(cx, replacer, replacer, i, &v))
                     return false;
 
                 RootedId id(cx);
                 if (v.isNumber()) {
--- a/js/src/jsproxy.cpp
+++ b/js/src/jsproxy.cpp
@@ -733,17 +733,17 @@ ArrayToIdVector(JSContext *cx, const Val
 
     RootedObject obj(cx, &array.toObject());
     uint32_t length;
     if (!GetLengthProperty(cx, obj, &length))
         return false;
 
     RootedValue v(cx);
     for (uint32_t n = 0; n < length; ++n) {
-        if (!JS_CHECK_OPERATION_LIMIT(cx))
+        if (!CheckForInterrupt(cx))
             return false;
         if (!JSObject::getElement(cx, obj, obj, n, &v))
             return false;
         RootedId id(cx);
         if (!ValueToId<CanGC>(cx, v, &id))
             return false;
         if (!props.append(id))
             return false;
--- a/js/src/jsstr.cpp
+++ b/js/src/jsstr.cpp
@@ -1897,17 +1897,17 @@ DoMatchGlobal(JSContext *cx, CallArgs ar
     // index 0, for which [[Get]]s have no side effects.
     //
     // Filling in a new array using [[DefineOwnProperty]] is unobservable.
     //
     // This is a tricky point, because after this set, our implementation *can*
     // fail.  The key is that script can't distinguish these failure modes from
     // one where, in spec terms, we fail immediately after step 8a.  That *in
     // reality* we might have done extra matching work, or created a partial
-    // results array to return, or hit the operation limit, is irrelevant.  The
+    // results array to return, or hit an interrupt, is irrelevant.  The
     // script can't tell we did any of those things but didn't update
     // .lastIndex.  Thus we can optimize steps 8b onward however we want,
     // including eliminating intermediate .lastIndex sets, as long as we don't
     // add ways for script to observe the intermediate states.
     //
     // In short: it's okay to cheat (by setting .lastIndex to 0, once) because
     // we can't get caught.
     if (!g.zeroLastIndex(cx))
@@ -1922,17 +1922,17 @@ DoMatchGlobal(JSContext *cx, CallArgs ar
     // techniques from the spec to implement step 8f's loop.
 
     // Step 8f.
     MatchPair match;
     size_t charsLen = input->length();
     const jschar *chars = input->chars();
     RegExpShared &re = g.regExp();
     for (size_t searchIndex = 0; searchIndex <= charsLen; ) {
-        if (!JS_CHECK_OPERATION_LIMIT(cx))
+        if (!CheckForInterrupt(cx))
             return false;
 
         // Steps 8f(i-ii), minus "lastIndex" updates (see above).
         size_t nextSearchIndex = searchIndex;
         RegExpRunStatus status = re.executeMatchOnly(cx, chars, charsLen, &nextSearchIndex, match);
         if (status == RegExpRunStatus_Error)
             return false;
 
@@ -2181,17 +2181,17 @@ DoMatchForReplaceLocal(JSContext *cx, Re
 
 static bool
 DoMatchForReplaceGlobal(JSContext *cx, RegExpStatics *res, Handle<JSLinearString*> linearStr,
                         RegExpShared &re, ReplaceData &rdata)
 {
     size_t charsLen = linearStr->length();
     ScopedMatchPairs matches(&cx->tempLifoAlloc());
     for (size_t count = 0, i = 0; i <= charsLen; ++count) {
-        if (!JS_CHECK_OPERATION_LIMIT(cx))
+        if (!CheckForInterrupt(cx))
             return false;
 
         RegExpRunStatus status = re.execute(cx, linearStr->chars(), charsLen, &i, matches);
         if (status == RegExpRunStatus_Error)
             return false;
 
         if (status == RegExpRunStatus_Success_NotFound)
             break;
@@ -2711,17 +2711,17 @@ StrReplaceRegexpRemove(JSContext *cx, Ha
 
     MatchPair match;
     size_t startIndex = 0; /* Index used for iterating through the string. */
     size_t lastIndex = 0;  /* Index after last successful match. */
     size_t lazyIndex = 0;  /* Index before last successful match. */
 
     /* Accumulate StringRanges for unmatched substrings. */
     while (startIndex <= charsLen) {
-        if (!JS_CHECK_OPERATION_LIMIT(cx))
+        if (!CheckForInterrupt(cx))
             return false;
 
         RegExpRunStatus status =
             re.executeMatchOnly(cx, flatStr->chars(), charsLen, &startIndex, match);
         if (status == RegExpRunStatus_Error)
             return false;
         if (status == RegExpRunStatus_Success_NotFound)
             break;
--- a/js/src/jsworkers.cpp
+++ b/js/src/jsworkers.cpp
@@ -793,20 +793,20 @@ WorkerThread::handleIonWorkload()
                              &ionBuilder->alloc());
         ionBuilder->setBackgroundCodegen(jit::CompileBackEnd(ionBuilder));
     }
 
     FinishOffThreadIonCompile(ionBuilder);
     ionBuilder = nullptr;
 
     // Ping the main thread so that the compiled code can be incorporated
-    // at the next operation callback. Don't interrupt Ion code for this, as
+    // at the next interrupt callback. Don't interrupt Ion code for this, as
     // this incorporation can be delayed indefinitely without affecting
     // performance as long as the main thread is actually executing Ion code.
-    rt->triggerOperationCallback(JSRuntime::TriggerCallbackAnyThreadDontStopIon);
+    rt->requestInterrupt(JSRuntime::RequestInterruptAnyThreadDontStopIon);
 
     // Notify the main thread in case it is waiting for the compilation to finish.
     WorkerThreadState().notifyAll(GlobalWorkerThreadState::CONSUMER);
 #else
     MOZ_CRASH();
 #endif // JS_ION
 }
 
--- a/js/src/shell/js.cpp
+++ b/js/src/shell/js.cpp
@@ -326,17 +326,17 @@ JSStringToUTF8(JSContext *cx, JSString *
         return nullptr;
 
     return TwoByteCharsToNewUTF8CharsZ(cx, linear->range()).c_str();
 }
 
 /*
  * State to store as JSContext private.
  *
- * We declare such timestamp as volatile as they are updated in the operation
+ * We declare such timestamp as volatile as they are updated in the interrupt
  * callback without taking any locks. Any possible race can only lead to more
  * frequent callback calls. This is safe as the callback does everything based
  * on timing.
  */
 struct JSShellContextData {
     volatile int64_t startTime;
 };
 
@@ -360,17 +360,17 @@ GetContextData(JSContext *cx)
 {
     JSShellContextData *data = (JSShellContextData *) JS_GetContextPrivate(cx);
 
     JS_ASSERT(data);
     return data;
 }
 
 static bool
-ShellOperationCallback(JSContext *cx)
+ShellInterruptCallback(JSContext *cx)
 {
     if (!gTimedOut)
         return true;
 
     bool result;
     if (!gTimeoutFunc.isNull()) {
         JS::AutoSaveExceptionState savedExc(cx);
         JSAutoCompartment ac(cx, &gTimeoutFunc.toObject());
@@ -3180,33 +3180,33 @@ WatchdogMain(void *arg)
 
     JSRuntime *rt = (JSRuntime *) arg;
 
     PR_Lock(gWatchdogLock);
     while (gWatchdogThread) {
         int64_t now = PRMJ_Now();
         if (gWatchdogHasTimeout && !IsBefore(now, gWatchdogTimeout)) {
             /*
-             * The timeout has just expired. Trigger the operation callback
+             * The timeout has just expired. Request an interrupt callback
              * outside the lock.
              */
             gWatchdogHasTimeout = false;
             PR_Unlock(gWatchdogLock);
             CancelExecution(rt);
             PR_Lock(gWatchdogLock);
 
             /* Wake up any threads doing sleep. */
             PR_NotifyAllCondVar(gSleepWakeup);
         } else {
             if (gWatchdogHasTimeout) {
                 /*
-                 * Time hasn't expired yet. Simulate an operation callback
+                 * Time hasn't expired yet. Simulate an interrupt callback
                  * which doesn't abort execution.
                  */
-                JS_TriggerOperationCallback(rt);
+                JS_RequestInterruptCallback(rt);
             }
 
             uint64_t sleepDuration = PR_INTERVAL_NO_TIMEOUT;
             if (gWatchdogHasTimeout)
                 sleepDuration = PR_TicksPerSecond() / 10;
             mozilla::DebugOnly<PRStatus> status =
               PR_WaitCondVar(gWatchdogWakeup, sleepDuration);
             JS_ASSERT(status == PR_SUCCESS);
@@ -3317,17 +3317,17 @@ ScheduleWatchdog(JSRuntime *rt, double t
 }
 
 #endif /* !JS_THREADSAFE */
 
 static void
 CancelExecution(JSRuntime *rt)
 {
     gTimedOut = true;
-    JS_TriggerOperationCallback(rt);
+    JS_RequestInterruptCallback(rt);
 
     if (!gTimeoutFunc.isNull()) {
         static const char msg[] = "Script runs for too long, terminating.\n";
 #if defined(XP_UNIX) && !defined(JS_THREADSAFE)
         /* It is not safe to call fputs from signals. */
         /* Dummy assignment avoids GCC warning on "attribute warn_unused_result" */
         ssize_t dummy = write(2, msg, sizeof(msg) - 1);
         (void)dummy;
@@ -5547,17 +5547,17 @@ static JS::AsmJSCacheOps asmJSCacheOps =
     ShellCloseAsmJSCacheEntryForWrite,
     ShellBuildId
 };
 
 /*
  * Avoid a reentrancy hazard.
  *
  * The non-JS_THREADSAFE shell uses a signal handler to implement timeout().
- * The JS engine is not really reentrant, but JS_TriggerAllOperationCallbacks
+ * The JS engine is not really reentrant, but JS_RequestInterruptCallback
  * is mostly safe--the only danger is that we might interrupt JS_NewContext or
  * JS_DestroyContext while the context list is being modified. Therefore we
  * disable the signal handler around calls to those functions.
  */
 #ifdef JS_THREADSAFE
 # define WITH_SIGNALS_DISABLED(x)  x
 #else
 # define WITH_SIGNALS_DISABLED(x)                                               \
@@ -6180,17 +6180,17 @@ main(int argc, char **argv, char **envp)
     size_t availMem = op.getIntOption("available-memory");
     if (availMem > 0)
         JS_SetGCParametersBasedOnAvailableMemory(rt, availMem);
 
     JS_SetTrustedPrincipals(rt, &ShellPrincipals::fullyTrusted);
     JS_SetSecurityCallbacks(rt, &ShellPrincipals::securityCallbacks);
     JS_InitDestroyPrincipalsCallback(rt, ShellPrincipals::destroy);
 
-    JS_SetOperationCallback(rt, ShellOperationCallback);
+    JS_SetInterruptCallback(rt, ShellInterruptCallback);
     JS::SetAsmJSCacheOps(rt, &asmJSCacheOps);
 
     JS_SetNativeStackQuota(rt, gMaxStackSize);
 
 #ifdef JS_THREADSAFE
     if (!offThreadState.init())
         return 1;
 #endif
--- a/js/src/vm/ForkJoin.cpp
+++ b/js/src/vm/ForkJoin.cpp
@@ -386,17 +386,17 @@ class ForkJoinShared : public ParallelJo
 
 
     // Requests a GC, either full or specific to a zone.
     void requestGC(JS::gcreason::Reason reason);
     void requestZoneGC(JS::Zone *zone, JS::gcreason::Reason reason);
 
     // Requests that computation abort.
     void setAbortFlagDueToInterrupt(ForkJoinContext &cx);
-    void setAbortFlagAndTriggerOperationCallback(bool fatal);
+    void setAbortFlagAndRequestInterrupt(bool fatal);
 
     // Set the fatal flag for the next abort.
     void setPendingAbortFatal() { fatal_ = true; }
 
     JSRuntime *runtime() { return cx_->runtime(); }
     JS::Zone *zone() { return cx_->zone(); }
     JSCompartment *compartment() { return cx_->compartment(); }
 
@@ -1141,17 +1141,17 @@ ForkJoinOperation::warmupExecution(bool 
             *status = ExecutionWarmup;
             return RedLight;
         }
 
         // If we finished all slices in warmup, be sure check the
         // interrupt flag. This is because we won't be running more JS
         // code, and thus no more automatic checking of the interrupt
         // flag.
-        if (!js_HandleExecutionInterrupt(cx_)) {
+        if (!HandleExecutionInterrupt(cx_)) {
             *status = ExecutionFatal;
             return RedLight;
         }
 
         return GreenLight;
     }
 
     Spew(SpewOps, "Executing warmup.");
@@ -1450,17 +1450,17 @@ ForkJoinShared::transferArenasToCompartm
     }
 }
 
 bool
 ForkJoinShared::executeFromWorker(ThreadPoolWorker *worker, uintptr_t stackLimit)
 {
     PerThreadData thisThread(cx_->runtime());
     if (!thisThread.init()) {
-        setAbortFlagAndTriggerOperationCallback(true);
+        setAbortFlagAndRequestInterrupt(true);
         return false;
     }
     TlsPerThreadData.set(&thisThread);
 
 #ifdef JS_ARM_SIMULATOR
     stackLimit = Simulator::StackLimit();
 #endif
 
@@ -1512,58 +1512,58 @@ ForkJoinShared::executePortion(PerThread
 
     if (!fun_->nonLazyScript()->hasParallelIonScript()) {
         // Sometimes, particularly with GCZeal, the parallel ion
         // script can be collected between starting the parallel
         // op and reaching this point.  In that case, we just fail
         // and fallback.
         Spew(SpewOps, "Down (Script no longer present)");
         cx.bailoutRecord->setCause(ParallelBailoutMainScriptNotPresent);
-        setAbortFlagAndTriggerOperationCallback(false);
+        setAbortFlagAndRequestInterrupt(false);
     } else {
         ParallelIonInvoke<2> fii(cx_->runtime(), fun_, 2);
 
         fii.args[0] = Int32Value(worker->id());
         fii.args[1] = BooleanValue(false);
 
         bool ok = fii.invoke(perThread);
         JS_ASSERT(ok == !cx.bailoutRecord->topScript);
         if (!ok)
-            setAbortFlagAndTriggerOperationCallback(false);
+            setAbortFlagAndRequestInterrupt(false);
     }
 
     Spew(SpewOps, "Down");
 }
 
 void
 ForkJoinShared::setAbortFlagDueToInterrupt(ForkJoinContext &cx)
 {
     JS_ASSERT(cx_->runtime()->interruptPar);
     // The GC Needed flag should not be set during parallel
     // execution.  Instead, one of the requestGC() or
     // requestZoneGC() methods should be invoked.
     JS_ASSERT(!cx_->runtime()->gcIsNeeded);
 
     if (!abort_) {
         cx.bailoutRecord->setCause(ParallelBailoutInterrupt);
-        setAbortFlagAndTriggerOperationCallback(false);
+        setAbortFlagAndRequestInterrupt(false);
     }
 }
 
 void
-ForkJoinShared::setAbortFlagAndTriggerOperationCallback(bool fatal)
+ForkJoinShared::setAbortFlagAndRequestInterrupt(bool fatal)
 {
     AutoLockMonitor lock(*this);
 
     abort_ = true;
     fatal_ = fatal_ || fatal;
 
     // Note: The ForkJoin trigger here avoids the expensive memory protection needed to
     // interrupt Ion code compiled for sequential execution.
-    cx_->runtime()->triggerOperationCallback(JSRuntime::TriggerCallbackAnyThreadForkJoin);
+    cx_->runtime()->requestInterrupt(JSRuntime::RequestInterruptAnyThreadForkJoin);
 }
 
 void
 ForkJoinShared::requestGC(JS::gcreason::Reason reason)
 {
     AutoLockMonitor lock(*this);
 
     gcZone_ = nullptr;
@@ -1666,25 +1666,25 @@ ForkJoinContext::check()
     return true;
 }
 
 void
 ForkJoinContext::requestGC(JS::gcreason::Reason reason)
 {
     shared_->requestGC(reason);
     bailoutRecord->setCause(ParallelBailoutRequestedGC);
-    shared_->setAbortFlagAndTriggerOperationCallback(false);
+    shared_->setAbortFlagAndRequestInterrupt(false);
 }
 
 void
 ForkJoinContext::requestZoneGC(JS::Zone *zone, JS::gcreason::Reason reason)
 {
     shared_->requestZoneGC(zone, reason);
     bailoutRecord->setCause(ParallelBailoutRequestedZoneGC);
-    shared_->setAbortFlagAndTriggerOperationCallback(false);
+    shared_->setAbortFlagAndRequestInterrupt(false);
 }
 
 bool
 ForkJoinContext::setPendingAbortFatal(ParallelBailoutCause cause)
 {
     shared_->setPendingAbortFatal();
     bailoutRecord->setCause(cause);
     return false;
@@ -2120,20 +2120,19 @@ js::ParallelTestsShouldPass(JSContext *c
     return jit::IsIonEnabled(cx) &&
            jit::IsBaselineEnabled(cx) &&
            !jit::js_JitOptions.eagerCompilation &&
            jit::js_JitOptions.baselineUsesBeforeCompile != 0 &&
            cx->runtime()->gcZeal() == 0;
 }
 
 void
-js::TriggerOperationCallbackForForkJoin(JSRuntime *rt,
-                                        JSRuntime::OperationCallbackTrigger trigger)
+js::RequestInterruptForForkJoin(JSRuntime *rt, JSRuntime::InterruptMode mode)
 {
-    if (trigger != JSRuntime::TriggerCallbackAnyThreadDontStopIon)
+    if (mode != JSRuntime::RequestInterruptAnyThreadDontStopIon)
         rt->interruptPar = true;
 }
 
 bool
 js::intrinsic_SetForkJoinTargetRegion(JSContext *cx, unsigned argc, Value *vp)
 {
     // This version of SetForkJoinTargetRegion is called during
     // sequential execution. It is a no-op. The parallel version
--- a/js/src/vm/ForkJoin.h
+++ b/js/src/vm/ForkJoin.h
@@ -119,22 +119,22 @@
 //   call to process all remaining data, just a chunk.  After this
 //   recovery execution is complete, we again attempt parallel
 //   execution.
 //
 // - If more than a fixed number of bailouts occur, we give up on
 //   parallelization and just invoke |func()| N times in a row (once
 //   for each worker) but with |warmup| set to false.
 //
-// Operation callback:
+// Interrupts:
 //
-// During parallel execution, |cx.check()| must be periodically
-// invoked to check for the operation callback. This is automatically
-// done by the Ion-generated code. If the operation callback is
-// necessary, |cx.check()| abort the parallel execution.
+// During parallel execution, |cx.check()| must be periodically invoked to
+// check for interrupts. This is automatically done by the Ion-generated
+// code. If an interrupt has been requested |cx.check()| aborts parallel
+// execution.
 //
 // Transitive compilation:
 //
 // One of the challenges for parallel compilation is that we
 // (currently) have to abort when we encounter an uncompiled script.
 // Therefore, we try to compile everything that might be needed
 // beforehand. The exact strategy is described in `ParallelDo::apply()`
 // in ForkJoin.cpp, but at the highest level the idea is:
@@ -463,18 +463,17 @@ class LockedJSContext
     operator JSContext *() { return jscx_; }
     JSContext *operator->() { return jscx_; }
 };
 
 bool InExclusiveParallelSection();
 
 bool ParallelTestsShouldPass(JSContext *cx);
 
-void TriggerOperationCallbackForForkJoin(JSRuntime *rt,
-                                         JSRuntime::OperationCallbackTrigger trigger);
+void RequestInterruptForForkJoin(JSRuntime *rt, JSRuntime::InterruptMode mode);
 
 bool intrinsic_SetForkJoinTargetRegion(JSContext *cx, unsigned argc, Value *vp);
 extern const JSJitInfo intrinsic_SetForkJoinTargetRegionInfo;
 
 ///////////////////////////////////////////////////////////////////////////
 // Debug Spew
 
 namespace jit {
--- a/js/src/vm/Interpreter.cpp
+++ b/js/src/vm/Interpreter.cpp
@@ -1412,17 +1412,17 @@ Interpret(JSContext *cx, RunState &state
 #define END_CASE(OP)              ADVANCE_AND_DISPATCH(OP##_LENGTH);
 
     /*
      * Prepare to call a user-supplied branch handler, and abort the script
      * if it returns false.
      */
 #define CHECK_BRANCH()                                                        \
     JS_BEGIN_MACRO                                                            \
-        if (cx->runtime()->interrupt && !js_HandleExecutionInterrupt(cx))     \
+        if (cx->runtime()->interrupt && !HandleExecutionInterrupt(cx))        \
             goto error;                                                       \
     JS_END_MACRO
 
     /*
      * This is a simple wrapper around ADVANCE_AND_DISPATCH which also does
      * a CHECK_BRANCH() if n is not positive, which possibly indicates that it
      * is the backedge of a loop.
      */
@@ -3718,17 +3718,17 @@ js::GetAndClearException(JSContext *cx, 
     bool status = cx->getPendingException(res);
     cx->clearPendingException();
     if (!status)
         return false;
 
     // Check the interrupt flag to allow interrupting deeply nested exception
     // handling.
     if (cx->runtime()->interrupt)
-        return js_HandleExecutionInterrupt(cx);
+        return HandleExecutionInterrupt(cx);
     return true;
 }
 
 template <bool strict>
 bool
 js::SetProperty(JSContext *cx, HandleObject obj, HandleId id, const Value &value)
 {
     RootedValue v(cx, value);
--- a/js/src/vm/Runtime.cpp
+++ b/js/src/vm/Runtime.cpp
@@ -117,26 +117,26 @@ JSRuntime::JSRuntime(JSRuntime *parentRu
     ),
     mainThread(this),
     parentRuntime(parentRuntime),
     interrupt(false),
 #if defined(JS_THREADSAFE) && defined(JS_ION)
     interruptPar(false),
 #endif
     handlingSignal(false),
-    operationCallback(nullptr),
+    interruptCallback(nullptr),
 #ifdef JS_THREADSAFE
-    operationCallbackLock(nullptr),
-    operationCallbackOwner(nullptr),
+    interruptLock(nullptr),
+    interruptLockOwner(nullptr),
     exclusiveAccessLock(nullptr),
     exclusiveAccessOwner(nullptr),
     mainThreadHasExclusiveAccess(false),
     numExclusiveThreads(0),
 #else
-    operationCallbackLockTaken(false),
+    interruptLockTaken(false),
 #endif
     systemZone(nullptr),
     numCompartments(0),
     localeCallbacks(nullptr),
     defaultLocale(nullptr),
     defaultVersion_(JSVERSION_DEFAULT),
 #ifdef JS_THREADSAFE
     ownerThread_(nullptr),
@@ -342,18 +342,18 @@ JitSupportsFloatingPoint()
 }
 
 bool
 JSRuntime::init(uint32_t maxbytes)
 {
 #ifdef JS_THREADSAFE
     ownerThread_ = PR_GetCurrentThread();
 
-    operationCallbackLock = PR_NewLock();
-    if (!operationCallbackLock)
+    interruptLock = PR_NewLock();
+    if (!interruptLock)
         return false;
 
     gcLock = PR_NewLock();
     if (!gcLock)
         return false;
 
     exclusiveAccessLock = PR_NewLock();
     if (!exclusiveAccessLock)
@@ -482,19 +482,19 @@ JSRuntime::~JSRuntime()
     JS_ASSERT(!exclusiveAccessOwner);
     if (exclusiveAccessLock)
         PR_DestroyLock(exclusiveAccessLock);
 
     // Avoid bogus asserts during teardown.
     JS_ASSERT(!numExclusiveThreads);
     mainThreadHasExclusiveAccess = true;
 
-    JS_ASSERT(!operationCallbackOwner);
-    if (operationCallbackLock)
-        PR_DestroyLock(operationCallbackLock);
+    JS_ASSERT(!interruptLockOwner);
+    if (interruptLock)
+        PR_DestroyLock(interruptLock);
 #endif
 
     /*
      * Even though all objects in the compartment are dead, we may have keep
      * some filenames around because of gcKeepAtoms.
      */
     FreeScriptData(this);
 
@@ -566,17 +566,17 @@ NewObjectCache::clearNurseryObjects(JSRu
             PodZero(&e);
         }
     }
 }
 
 void
 JSRuntime::resetJitStackLimit()
 {
-    AutoLockForOperationCallback lock(this);
+    AutoLockForInterrupt lock(this);
     mainThread.setJitStackLimit(mainThread.nativeStackLimit[js::StackForUntrustedScript]);
 
 #ifdef JS_ARM_SIMULATOR
     mainThread.setJitStackLimit(js::jit::Simulator::StackLimit());
 #endif
  }
 
 void
@@ -613,17 +613,17 @@ JSRuntime::addSizeOfIncludingThis(mozill
     rtSizes->scriptData += scriptDataTable().sizeOfExcludingThis(mallocSizeOf);
     for (ScriptDataTable::Range r = scriptDataTable().all(); !r.empty(); r.popFront())
         rtSizes->scriptData += mallocSizeOf(r.front());
 
     if (execAlloc_)
         execAlloc_->addSizeOfCode(&rtSizes->code);
 #ifdef JS_ION
     {
-        AutoLockForOperationCallback lock(this);
+        AutoLockForInterrupt lock(this);
         if (jitRuntime()) {
             if (JSC::ExecutableAllocator *ionAlloc = jitRuntime()->ionAlloc(this))
                 ionAlloc->addSizeOfCode(&rtSizes->code);
         }
     }
 #endif
 
     rtSizes->gc.marker += gcMarker.sizeOfExcludingThis(mallocSizeOf);
@@ -637,42 +637,42 @@ static bool
 SignalBasedTriggersDisabled()
 {
   // Don't bother trying to cache the getenv lookup; this should be called
   // infrequently.
   return !!getenv("JS_DISABLE_SLOW_SCRIPT_SIGNALS");
 }
 
 void
-JSRuntime::triggerOperationCallback(OperationCallbackTrigger trigger)
+JSRuntime::requestInterrupt(InterruptMode mode)
 {
-    AutoLockForOperationCallback lock(this);
+    AutoLockForInterrupt lock(this);
 
     /*
      * Invalidate ionTop to trigger its over-recursion check. Note this must be
-     * set before interrupt, to avoid racing with js_InvokeOperationCallback,
+     * set before interrupt, to avoid racing with js::InvokeInterruptCallback,
      * into a weird state where interrupt is stuck at 0 but jitStackLimit is
      * MAXADDR.
      */
     mainThread.setJitStackLimit(-1);
 
     interrupt = true;
 
 #ifdef JS_ION
 #ifdef JS_THREADSAFE
-    TriggerOperationCallbackForForkJoin(this, trigger);
+    RequestInterruptForForkJoin(this, mode);
 #endif
 
     /*
      * asm.js and, optionally, normal Ion code use memory protection and signal
      * handlers to halt running code.
      */
     if (!SignalBasedTriggersDisabled()) {
-        TriggerOperationCallbackForAsmJSCode(this);
-        jit::TriggerOperationCallbackForIonCode(this, trigger);
+        RequestInterruptForAsmJSCode(this);
+        jit::RequestInterruptForIonCode(this, mode);
     }
 #endif
 }
 
 JSC::ExecutableAllocator *
 JSRuntime::createExecutableAllocator(JSContext *cx)
 {
     JS_ASSERT(!execAlloc_);
@@ -918,18 +918,18 @@ JSRuntime::assertCanLock(RuntimeLock whi
     // In the switch below, each case falls through to the one below it. None
     // of the runtime locks are reentrant, and when multiple locks are acquired
     // it must be done in the order below.
     switch (which) {
       case ExclusiveAccessLock:
         JS_ASSERT(exclusiveAccessOwner != PR_GetCurrentThread());
       case WorkerThreadStateLock:
         JS_ASSERT(!WorkerThreadState().isLocked());
-      case OperationCallbackLock:
-        JS_ASSERT(!currentThreadOwnsOperationCallbackLock());
+      case InterruptLock:
+        JS_ASSERT(!currentThreadOwnsInterruptLock());
       case GCLock:
         JS_ASSERT(gcLockOwner != PR_GetCurrentThread());
         break;
       default:
         MOZ_CRASH();
     }
 #endif // JS_THREADSAFE
 }
--- a/js/src/vm/Runtime.h
+++ b/js/src/vm/Runtime.h
@@ -479,17 +479,17 @@ AtomStateOffsetToName(const JSAtomState 
 }
 
 // There are several coarse locks in the enum below. These may be either
 // per-runtime or per-process. When acquiring more than one of these locks,
 // the acquisition must be done in the order below to avoid deadlocks.
 enum RuntimeLock {
     ExclusiveAccessLock,
     WorkerThreadStateLock,
-    OperationCallbackLock,
+    InterruptLock,
     GCLock
 };
 
 #ifdef DEBUG
 void AssertCurrentThreadCanLock(RuntimeLock which);
 #else
 inline void AssertCurrentThreadCanLock(RuntimeLock which) {}
 #endif
@@ -547,38 +547,38 @@ class PerThreadData : public PerThreadDa
      * set to null to force JIT code to exit (e.g., for the operation callback).
      */
     uintptr_t            jitStackLimit;
 
     inline void setJitStackLimit(uintptr_t limit);
 
     /*
      * asm.js maintains a stack of AsmJSModule activations (see AsmJS.h). This
-     * stack is used by JSRuntime::triggerOperationCallback to stop long-
-     * running asm.js without requiring dynamic polling operations in the
-     * generated code. Since triggerOperationCallback may run on a separate
-     * thread than the JSRuntime's owner thread all reads/writes must be
-     * synchronized (by rt->operationCallbackLock).
+     * stack is used by JSRuntime::requestInterrupt to stop long-running asm.js
+     * without requiring dynamic polling operations in the generated
+     * code. Since requestInterrupt may run on a separate thread than the
+     * JSRuntime's owner thread all reads/writes must be synchronized (by
+     * rt->interruptLock).
      */
   private:
     friend class js::Activation;
     friend class js::ActivationIterator;
     friend class js::jit::JitActivation;
     friend class js::AsmJSActivation;
 #ifdef DEBUG
     friend void js::AssertCurrentThreadCanLock(RuntimeLock which);
 #endif
 
     /*
      * Points to the most recent activation running on the thread.
      * See Activation comment in vm/Stack.h.
      */
     js::Activation *activation_;
 
-    /* See AsmJSActivation comment. Protected by rt->operationCallbackLock. */
+    /* See AsmJSActivation comment. Protected by rt->interruptLock. */
     js::AsmJSActivation *asmJSActivationStack_;
 
 #ifdef JS_ARM_SIMULATOR
     js::jit::Simulator *simulator_;
     uintptr_t simulatorStackLimit_;
 #endif
 
   public:
@@ -685,86 +685,85 @@ struct JSRuntime : public JS::shadow::Ru
 
     /*
      * If non-null, another runtime guaranteed to outlive this one and whose
      * permanent data may be used by this one where possible.
      */
     JSRuntime *parentRuntime;
 
     /*
-     * If true, we've been asked to call the operation callback as soon as
+     * If true, we've been asked to call the interrupt callback as soon as
      * possible.
      */
     mozilla::Atomic<bool, mozilla::Relaxed> interrupt;
 
 #if defined(JS_THREADSAFE) && defined(JS_ION)
     /*
      * If non-zero, ForkJoin should service an interrupt. This is a separate
      * flag from |interrupt| because we cannot use the mprotect trick with PJS
      * code and ignore the TriggerCallbackAnyThreadDontStopIon trigger.
      */
     mozilla::Atomic<bool, mozilla::Relaxed> interruptPar;
 #endif
 
     /* Set when handling a signal for a thread associated with this runtime. */
     bool handlingSignal;
 
-    /* Branch callback */
-    JSOperationCallback operationCallback;
+    JSInterruptCallback interruptCallback;
 
 #ifdef DEBUG
     void assertCanLock(js::RuntimeLock which);
 #else
     void assertCanLock(js::RuntimeLock which) {}
 #endif
 
   private:
     /*
-     * Lock taken when triggering the operation callback from another thread.
+     * Lock taken when triggering an interrupt from another thread.
      * Protects all data that is touched in this process.
      */
 #ifdef JS_THREADSAFE
-    PRLock *operationCallbackLock;
-    PRThread *operationCallbackOwner;
+    PRLock *interruptLock;
+    PRThread *interruptLockOwner;
 #else
-    bool operationCallbackLockTaken;
+    bool interruptLockTaken;
 #endif // JS_THREADSAFE
   public:
 
-    class AutoLockForOperationCallback {
+    class AutoLockForInterrupt {
         JSRuntime *rt;
       public:
-        AutoLockForOperationCallback(JSRuntime *rt MOZ_GUARD_OBJECT_NOTIFIER_PARAM) : rt(rt) {
+        AutoLockForInterrupt(JSRuntime *rt MOZ_GUARD_OBJECT_NOTIFIER_PARAM) : rt(rt) {
             MOZ_GUARD_OBJECT_NOTIFIER_INIT;
-            rt->assertCanLock(js::OperationCallbackLock);
+            rt->assertCanLock(js::InterruptLock);
 #ifdef JS_THREADSAFE
-            PR_Lock(rt->operationCallbackLock);
-            rt->operationCallbackOwner = PR_GetCurrentThread();
+            PR_Lock(rt->interruptLock);
+            rt->interruptLockOwner = PR_GetCurrentThread();
 #else
-            rt->operationCallbackLockTaken = true;
+            rt->interruptLockTaken = true;
 #endif // JS_THREADSAFE
         }
-        ~AutoLockForOperationCallback() {
-            JS_ASSERT(rt->currentThreadOwnsOperationCallbackLock());
+        ~AutoLockForInterrupt() {
+            JS_ASSERT(rt->currentThreadOwnsInterruptLock());
 #ifdef JS_THREADSAFE
-            rt->operationCallbackOwner = nullptr;
-            PR_Unlock(rt->operationCallbackLock);
+            rt->interruptLockOwner = nullptr;
+            PR_Unlock(rt->interruptLock);
 #else
-            rt->operationCallbackLockTaken = false;
+            rt->interruptLockTaken = false;
 #endif // JS_THREADSAFE
         }
 
         MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
     };
 
-    bool currentThreadOwnsOperationCallbackLock() {
+    bool currentThreadOwnsInterruptLock() {
 #if defined(JS_THREADSAFE)
-        return operationCallbackOwner == PR_GetCurrentThread();
+        return interruptLockOwner == PR_GetCurrentThread();
 #else
-        return operationCallbackLockTaken;
+        return interruptLockTaken;
 #endif
     }
 
 #ifdef JS_THREADSAFE
 
   private:
     /*
      * Lock taken when using per-runtime or per-zone data that could otherwise
@@ -1685,26 +1684,26 @@ struct JSRuntime : public JS::shadow::Ru
      * calloc are signaled by p == null and p == reinterpret_cast<void *>(1).
      * Other values of p mean a realloc failure.
      *
      * The function must be called outside the GC lock.
      */
     JS_FRIEND_API(void *) onOutOfMemory(void *p, size_t nbytes);
     JS_FRIEND_API(void *) onOutOfMemory(void *p, size_t nbytes, JSContext *cx);
 
-    // Ways in which the operation callback on the runtime can be triggered,
+    // Ways in which the interrupt callback on the runtime can be triggered,
     // varying based on which thread is triggering the callback.
-    enum OperationCallbackTrigger {
-        TriggerCallbackMainThread,
-        TriggerCallbackAnyThread,
-        TriggerCallbackAnyThreadDontStopIon,
-        TriggerCallbackAnyThreadForkJoin
+    enum InterruptMode {
+        RequestInterruptMainThread,
+        RequestInterruptAnyThread,
+        RequestInterruptAnyThreadDontStopIon,
+        RequestInterruptAnyThreadForkJoin
     };
 
-    void triggerOperationCallback(OperationCallbackTrigger trigger);
+    void requestInterrupt(InterruptMode mode);
 
     void addSizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf, JS::RuntimeSizes *runtime);
 
   private:
     JS::RuntimeOptions options_;
 
     JSUseHelperThreads useHelperThreads_;
 
@@ -1941,17 +1940,17 @@ class MOZ_STACK_CLASS AutoKeepAtoms
             rt->keepAtoms_--;
         }
     }
 };
 
 inline void
 PerThreadData::setJitStackLimit(uintptr_t limit)
 {
-    JS_ASSERT(runtime_->currentThreadOwnsOperationCallbackLock());
+    JS_ASSERT(runtime_->currentThreadOwnsInterruptLock());
     jitStackLimit = limit;
 }
 
 inline JSRuntime *
 PerThreadData::runtimeFromMainThread()
 {
     JS_ASSERT(CurrentThreadCanAccessRuntime(runtime_));
     return runtime_;
--- a/js/src/vm/Stack.cpp
+++ b/js/src/vm/Stack.cpp
@@ -1555,30 +1555,30 @@ AsmJSActivation::AsmJSActivation(JSConte
         // (For now use a single static string to avoid further slowing down
         // calls into asm.js.)
         profiler_ = &cx->runtime()->spsProfiler;
         profiler_->enterNative("asm.js code :0", this);
     }
 
     prevAsmJS_ = cx_->runtime()->mainThread.asmJSActivationStack_;
 
-    JSRuntime::AutoLockForOperationCallback lock(cx_->runtime());
+    JSRuntime::AutoLockForInterrupt lock(cx_->runtime());
     cx_->runtime()->mainThread.asmJSActivationStack_ = this;
 
     (void) errorRejoinSP_;  // squelch GCC warning
 }
 
 AsmJSActivation::~AsmJSActivation()
 {
     if (profiler_)
         profiler_->exitNative();
 
     JS_ASSERT(cx_->runtime()->mainThread.asmJSActivationStack_ == this);
 
-    JSRuntime::AutoLockForOperationCallback lock(cx_->runtime());
+    JSRuntime::AutoLockForInterrupt lock(cx_->runtime());
     cx_->runtime()->mainThread.asmJSActivationStack_ = prevAsmJS_;
 }
 
 InterpreterFrameIterator &
 InterpreterFrameIterator::operator++()
 {
     JS_ASSERT(!done());
     if (fp_ != activation_->entryFrame_) {
--- a/js/src/yarr/YarrInterpreter.cpp
+++ b/js/src/yarr/YarrInterpreter.cpp
@@ -1117,17 +1117,17 @@ public:
 
         context->matchBegin = input.getPos();
         context->term = 0;
 
     matchAgain:
         ASSERT(context->term < static_cast<int>(disjunction->terms.size()));
 
         // Prevent jank resulting from getting stuck in Yarr for a long time.
-        if (!JS_CHECK_OPERATION_LIMIT(this->cx))
+        if (!CheckForInterrupt(this->cx))
             return JSRegExpErrorInternal;
 
         switch (currentTerm().type) {
         case ByteTerm::TypeSubpatternBegin:
             MATCH_NEXT();
         case ByteTerm::TypeSubpatternEnd:
             context->matchEnd = input.getPos();
             return JSRegExpMatch;
@@ -1279,17 +1279,17 @@ public:
 
         // We should never fall-through to here.
         ASSERT_NOT_REACHED();
 
     backtrack:
         ASSERT(context->term < static_cast<int>(disjunction->terms.size()));
 
         // Prevent jank resulting from getting stuck in Yarr for a long time.
-        if (!JS_CHECK_OPERATION_LIMIT(this->cx))
+        if (!CheckForInterrupt(this->cx))
             return JSRegExpErrorInternal;
 
         switch (currentTerm().type) {
         case ByteTerm::TypeSubpatternBegin:
             return JSRegExpNoMatch;
         case ByteTerm::TypeSubpatternEnd:
             ASSERT_NOT_REACHED();
 
--- a/js/xpconnect/src/XPCJSRuntime.cpp
+++ b/js/xpconnect/src/XPCJSRuntime.cpp
@@ -1280,28 +1280,28 @@ WatchdogMain(void *arg)
             manager->RecordTimestamp(TimestampWatchdogHibernateStart);
             self->Hibernate();
             manager->RecordTimestamp(TimestampWatchdogHibernateStop);
         }
 
         // Rise and shine.
         manager->RecordTimestamp(TimestampWatchdogWakeup);
 
-        // Don't trigger the operation callback if activity started less than one second ago.
+        // Don't request an interrupt callback if activity started less than one second ago.
         // The callback is only used for detecting long running scripts, and triggering the
         // callback from off the main thread can be expensive.
         if (manager->IsRuntimeActive() &&
             manager->TimeSinceLastRuntimeStateChange() >= PRTime(PR_USEC_PER_SEC))
         {
             bool debuggerAttached = false;
             nsCOMPtr<nsIDebug2> dbg = do_GetService("@mozilla.org/xpcom/debug;1");
             if (dbg)
                 dbg->GetIsDebuggerAttached(&debuggerAttached);
             if (!debuggerAttached)
-                JS_TriggerOperationCallback(manager->Runtime()->Runtime());
+                JS_RequestInterruptCallback(manager->Runtime()->Runtime());
         }
     }
 
     // Tell the manager that we've shut down.
     self->Finished();
 }
 
 PRTime
@@ -1345,28 +1345,28 @@ XPCJSRuntime::CTypesActivityCallback(JSC
       MOZ_CRASH();
   } else if (type == js::CTYPES_CALLBACK_END) {
     xpc::PopJSContextNoScriptContext();
   }
 }
 
 // static
 bool
-XPCJSRuntime::OperationCallback(JSContext *cx)
+XPCJSRuntime::InterruptCallback(JSContext *cx)
 {
     XPCJSRuntime *self = XPCJSRuntime::Get();
 
-    // If this is the first time the operation callback has fired since we last
+    // If this is the first time the interrupt callback has fired since we last
     // returned to the event loop, mark the checkpoint.
     if (self->mSlowScriptCheckpoint.IsNull()) {
         self->mSlowScriptCheckpoint = TimeStamp::NowLoRes();
         return true;
     }
 
-    // This is at least the second operation callback we've received since
+    // This is at least the second interrupt callback we've received since
     // returning to the event loop. See how long it's been, and what the limit
     // is.
     TimeDuration duration = TimeStamp::NowLoRes() - self->mSlowScriptCheckpoint;
     bool chrome =
       nsContentUtils::IsSystemPrincipal(nsContentUtils::GetSubjectPrincipal());
     const char *prefName = chrome ? "dom.max_chrome_script_run_time"
                                   : "dom.max_script_run_time";
     int32_t limit = Preferences::GetInt(prefName, chrome ? 20 : 10);
@@ -3119,17 +3119,17 @@ XPCJSRuntime::XPCJSRuntime(nsXPConnect* 
 #ifdef MOZ_ENABLE_PROFILER_SPS
     if (PseudoStack *stack = mozilla_get_pseudo_stack())
         stack->sampleRuntime(runtime);
 #endif
     JS_SetAccumulateTelemetryCallback(runtime, AccumulateTelemetryCallback);
     js::SetDefaultJSContextCallback(runtime, DefaultJSContextCallback);
     js::SetActivityCallback(runtime, ActivityCallback, this);
     js::SetCTypesActivityCallback(runtime, CTypesActivityCallback);
-    JS_SetOperationCallback(runtime, OperationCallback);
+    JS_SetInterruptCallback(runtime, InterruptCallback);
     JS::SetOutOfMemoryCallback(runtime, OutOfMemoryCallback);
 
     // The JS engine needs to keep the source code around in order to implement
     // Function.prototype.toSource(). It'd be nice to not have to do this for
     // chrome code and simply stub out requests for source on it. Life is not so
     // easy, unfortunately. Nobody relies on chrome toSource() working in core
     // browser code, but chrome tests use it. The worst offenders are addons,
     // which like to monkeypatch chrome functions by calling toSource() on them
--- a/js/xpconnect/src/XPCShellImpl.cpp
+++ b/js/xpconnect/src/XPCShellImpl.cpp
@@ -644,62 +644,62 @@ File(JSContext *cx, unsigned argc, Value
   if (NS_FAILED(rv)) {
     JS_ReportError(cx, "Could not wrap native object!");
     return false;
   }
 
   return true;
 }
 
-static Value sScriptedOperationCallback = UndefinedValue();
+static Value sScriptedInterruptCallback = UndefinedValue();
 
 static bool
-XPCShellOperationCallback(JSContext *cx)
+XPCShellInterruptCallback(JSContext *cx)
 {
-    // If no operation callback was set by script, no-op.
-    if (sScriptedOperationCallback.isUndefined())
+    // If no interrupt callback was set by script, no-op.
+    if (sScriptedInterruptCallback.isUndefined())
         return true;
 
-    JSAutoCompartment ac(cx, &sScriptedOperationCallback.toObject());
+    JSAutoCompartment ac(cx, &sScriptedInterruptCallback.toObject());
     RootedValue rv(cx);
-    RootedValue callback(cx, sScriptedOperationCallback);
+    RootedValue callback(cx, sScriptedInterruptCallback);
     if (!JS_CallFunctionValue(cx, JS::NullPtr(), callback, JS::HandleValueArray::empty(), &rv) ||
         !rv.isBoolean())
     {
-        NS_WARNING("Scripted operation callback failed! Terminating script.");
+        NS_WARNING("Scripted interrupt callback failed! Terminating script.");
         JS_ClearPendingException(cx);
         return false;
     }
 
     return rv.toBoolean();
 }
 
 static bool
-SetOperationCallback(JSContext *cx, unsigned argc, jsval *vp)
+SetInterruptCallback(JSContext *cx, unsigned argc, jsval *vp)
 {
     // Sanity-check args.
     JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
     if (args.length() != 1) {
         JS_ReportError(cx, "Wrong number of arguments");
         return false;
     }
 
-    // Allow callers to remove the operation callback by passing undefined.
+    // Allow callers to remove the interrupt callback by passing undefined.
     if (args[0].isUndefined()) {
-        sScriptedOperationCallback = UndefinedValue();
+        sScriptedInterruptCallback = UndefinedValue();
         return true;
     }
 
     // Otherwise, we should have a callable object.
     if (!args[0].isObject() || !JS_ObjectIsCallable(cx, &args[0].toObject())) {
         JS_ReportError(cx, "Argument must be callable");
         return false;
     }
 
-    sScriptedOperationCallback = args[0];
+    sScriptedInterruptCallback = args[0];
 
     return true;
 }
 
 static bool
 SimulateActivityCallback(JSContext *cx, unsigned argc, jsval *vp)
 {
     // Sanity-check args.
@@ -728,17 +728,17 @@ static const JSFunctionSpec glob_functio
 #endif
     JS_FS("options",         Options,        0,0),
     JS_FN("parent",          Parent,         1,0),
     JS_FS("sendCommand",     SendCommand,    1,0),
     JS_FS("atob",            Atob,           1,0),
     JS_FS("btoa",            Btoa,           1,0),
     JS_FS("Blob",            Blob,           2,JSFUN_CONSTRUCTOR),
     JS_FS("File",            File,           2,JSFUN_CONSTRUCTOR),
-    JS_FS("setOperationCallback", SetOperationCallback, 1,0),
+    JS_FS("setInterruptCallback", SetInterruptCallback, 1,0),
     JS_FS("simulateActivityCallback", SimulateActivityCallback, 1,0),
     JS_FS_END
 };
 
 static bool
 env_setProperty(JSContext *cx, HandleObject obj, HandleId id, bool strict, MutableHandleValue vp)
 {
 /* XXX porting may be easy, but these don't seem to supply setenv by default */
@@ -1467,20 +1467,20 @@ XRE_XPCShellMain(int argc, char **argv, 
 
         if (NS_FAILED(rtsvc->GetRuntime(&rt)) || !rt) {
             printf("failed to get JSRuntime from nsJSRuntimeService!\n");
             return 1;
         }
 
         rtsvc->RegisterContextCallback(ContextCallback);
 
-        // Override the default XPConnect operation callback. We could store the
+        // Override the default XPConnect interrupt callback. We could store the
         // old one and restore it before shutting down, but there's not really a
         // reason to bother.
-        JS_SetOperationCallback(rt, XPCShellOperationCallback);
+        JS_SetInterruptCallback(rt, XPCShellInterruptCallback);
 
         cx = JS_NewContext(rt, 8192);
         if (!cx) {
             printf("JS_NewContext failed!\n");
             return 1;
         }
 
         argc--;
@@ -1582,19 +1582,19 @@ XRE_XPCShellMain(int argc, char **argv, 
 
             nsAutoString workingDirectory;
             if (GetCurrentWorkingDirectory(workingDirectory))
                 gWorkingDirectory = &workingDirectory;
 
             JS_DefineProperty(cx, glob, "__LOCATION__", JSVAL_VOID,
                               GetLocationProperty, nullptr, 0);
 
-            JS_AddValueRoot(cx, &sScriptedOperationCallback);
+            JS_AddValueRoot(cx, &sScriptedInterruptCallback);
             result = ProcessArgs(cx, glob, argv, argc, &dirprovider);
-            JS_RemoveValueRoot(cx, &sScriptedOperationCallback);
+            JS_RemoveValueRoot(cx, &sScriptedInterruptCallback);
 
             JS_DropPrincipals(rt, gJSPrincipals);
             JS_SetAllNonReservedSlotsToUndefined(cx, glob);
             JS_GC(rt);
         }
         pusher.Pop();
         JS_GC(rt);
         JS_DestroyContext(cx);
--- a/js/xpconnect/src/xpcprivate.h
+++ b/js/xpconnect/src/xpcprivate.h
@@ -544,17 +544,17 @@ public:
     void RemoveGCCallback(xpcGCCallback cb);
     void AddContextCallback(xpcContextCallback cb);
     void RemoveContextCallback(xpcContextCallback cb);
 
     static JSContext* DefaultJSContextCallback(JSRuntime *rt);
     static void ActivityCallback(void *arg, bool active);
     static void CTypesActivityCallback(JSContext *cx,
                                        js::CTypesActivityType type);
-    static bool OperationCallback(JSContext *cx);
+    static bool InterruptCallback(JSContext *cx);
     static void OutOfMemoryCallback(JSContext *cx);
 
     size_t SizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf);
 
     AutoMarkingPtr**  GetAutoRootsAdr() {return &mAutoRoots;}
 
     JSObject* GetJunkScope();
     void DeleteJunkScope();
--- a/js/xpconnect/tests/unit/head_watchdog.js
+++ b/js/xpconnect/tests/unit/head_watchdog.js
@@ -48,33 +48,33 @@ function executeSoon(fn) {
 // When running, the watchdog wakes up every second, and fires the operation
 // callback if the script has been running for >= one second. As such, a script
 // should never be able to run for two seconds or longer without servicing the
 // operation callback. We wait 3 seconds, just to be safe.
 //
 
 function checkWatchdog(expectInterrupt, continuation) {
   var lastWatchdogWakeup = Cu.getWatchdogTimestamp("WatchdogWakeup");
-  setOperationCallback(function() {
+  setInterruptCallback(function() {
     // If the watchdog didn't actually trigger the operation callback, ignore
     // this call. This allows us to test the actual watchdog behavior without
     // interference from other sites where we trigger the operation callback.
     if (lastWatchdogWakeup == Cu.getWatchdogTimestamp("WatchdogWakeup")) {
       return true;
     }
     do_check_true(expectInterrupt);
-    setOperationCallback(undefined);
+    setInterruptCallback(undefined);
     // Schedule our continuation before we kill this script.
     executeSoon(continuation);
     return false;
   });
   executeSoon(function() {
     busyWait(3000);
     do_check_true(!expectInterrupt);
-    setOperationCallback(undefined);
+    setInterruptCallback(undefined);
     continuation();
   });
 }
 
 var gGenerator;
 function continueTest() {
   gGenerator.next();
 }