diff --git a/js/src/jit/BaselineBailouts.cpp b/js/src/jit/BaselineBailouts.cpp index 34110d7af66..09bda57dd75 100644 --- a/js/src/jit/BaselineBailouts.cpp +++ b/js/src/jit/BaselineBailouts.cpp @@ -1039,9 +1039,9 @@ InitFromBailout(JSContext *cx, HandleScript caller, jsbytecode *callerPC, if (excInfo && excInfo->propagatingIonExceptionForDebugMode() && resumeAfter) { // When propagating an exception for debug mode, set the - // return address as the return-from-IC for the throwing op, - // so that Debugger hooks report the correct pc offset of the - // throwing op instead of its successor. + // return address as native code for the throwing op, so that + // Debugger hooks report the correct pc offset of the throwing + // op instead of its successor. // // This should not be done if we are at a resume-at point, as // might be the case when propagating an exception thrown from @@ -1051,10 +1051,8 @@ InitFromBailout(JSContext *cx, HandleScript caller, jsbytecode *callerPC, // // Note that we never resume into this address, it is set for // the sake of frame iterators giving the correct answer. - ICEntry &icEntry = baselineScript->anyKindICEntryFromPCOffset(iter.pcOffset()); - nativeCodeForPC = baselineScript->returnAddressForIC(icEntry); - } else { - MOZ_ASSERT(nativeCodeForPC); + jsbytecode *throwPC = script->offsetToPC(iter.pcOffset()); + nativeCodeForPC = baselineScript->nativeCodeForPC(script, throwPC); } MOZ_ASSERT(nativeCodeForPC); diff --git a/js/src/jit/BaselineDebugModeOSR.cpp b/js/src/jit/BaselineDebugModeOSR.cpp index 6c648747b01..4f28e556779 100644 --- a/js/src/jit/BaselineDebugModeOSR.cpp +++ b/js/src/jit/BaselineDebugModeOSR.cpp @@ -214,8 +214,9 @@ CollectJitStackScripts(JSContext *cx, const Debugger::ExecutionObservableSet &ob // Otherwise, we are in the middle of handling an // exception. This happens since we could have bailed out // in place from Ion after a throw, settling on the pc - // *after* the bytecode that threw the exception, which - // may have no ICEntry. + // which may have no ICEntry (e.g., Ion is free to insert + // resume points after non-effectful ops for better + // register allocation). MOZ_ASSERT(iter.baselineFrame()->isDebuggerHandlingException()); jsbytecode *pc = script->baselineScript()->pcForNativeAddress(script, retAddr); if (!entries.append(DebugModeOSREntry(script, script->pcToOffset(pc)))) @@ -400,24 +401,9 @@ PatchBaselineFramesForDebugMode(JSContext *cx, const Debugger::ExecutionObservab BaselineScript *bl = script->baselineScript(); ICEntry::Kind kind = entry.frameKind; - if (kind == ICEntry::Kind_Op || kind == ICEntry::Kind_NonOp) { - uint8_t *retAddr; - if (kind == ICEntry::Kind_Op) { - // Case A above. - retAddr = bl->returnAddressForIC(bl->icEntryFromPCOffset(pcOffset)); - } else { - // Case H above. - // - // It could happen that the in-place Ion bailout chose the - // return-from-IC address of a NonOp IC for the frame - // iterators to report the correct bytecode pc. - // - // See note under propagatingIonExceptionForDebugMode in - // InitFromBailout. - MOZ_ASSERT(iter.baselineFrame()->isDebuggerHandlingException()); - retAddr = bl->returnAddressForIC(bl->anyKindICEntryFromPCOffset(pcOffset)); - } - + if (kind == ICEntry::Kind_Op) { + // Case A above. + // // Patching these cases needs to patch both the stub frame and // the baseline frame. The stub frame is patched below. For // the baseline frame here, we resume right after the IC @@ -425,6 +411,7 @@ PatchBaselineFramesForDebugMode(JSContext *cx, const Debugger::ExecutionObservab // // Since we're using the same IC stub code, we can resume // directly to the IC resume address. + uint8_t *retAddr = bl->returnAddressForIC(bl->icEntryFromPCOffset(pcOffset)); SpewPatchBaselineFrame(prev->returnAddress(), retAddr, script, kind, pc); DebugModeOSRVolatileJitFrameIterator::forwardLiveIterators( cx, prev->returnAddress(), retAddr); diff --git a/js/src/jit/BaselineJIT.cpp b/js/src/jit/BaselineJIT.cpp index 0effbea46c1..cc5927e5884 100644 --- a/js/src/jit/BaselineJIT.cpp +++ b/js/src/jit/BaselineJIT.cpp @@ -550,14 +550,16 @@ BaselineScript::returnAddressForIC(const ICEntry &ent) return method()->raw() + ent.returnOffset().offset(); } -static inline -size_t ComputeBinarySearchMid(BaselineScript *baseline, uint32_t pcOffset) +ICEntry & +BaselineScript::icEntryFromPCOffset(uint32_t pcOffset) { + // Multiple IC entries can have the same PC offset, but this method only looks for + // those which have isForOp() set. size_t bottom = 0; - size_t top = baseline->numICEntries(); + size_t top = numICEntries(); size_t mid = bottom + (top - bottom) / 2; while (mid < top) { - ICEntry &midEntry = baseline->icEntry(mid); + ICEntry &midEntry = icEntry(mid); if (midEntry.pcOffset() < pcOffset) bottom = mid + 1; else if (midEntry.pcOffset() > pcOffset) @@ -566,28 +568,6 @@ size_t ComputeBinarySearchMid(BaselineScript *baseline, uint32_t pcOffset) break; mid = bottom + (top - bottom) / 2; } - return mid; -} - -ICEntry & -BaselineScript::anyKindICEntryFromPCOffset(uint32_t pcOffset) -{ - size_t mid = ComputeBinarySearchMid(this, pcOffset); - - // Return any IC entry with a matching PC offset. - for (size_t i = mid; i < numICEntries() && icEntry(i).pcOffset() == pcOffset; i--) - return icEntry(i); - for (size_t i = mid+1; i < numICEntries() && icEntry(i).pcOffset() == pcOffset; i++) - return icEntry(i); - MOZ_CRASH("Invalid PC offset for IC entry."); -} - -ICEntry & -BaselineScript::icEntryFromPCOffset(uint32_t pcOffset) -{ - // Multiple IC entries can have the same PC offset, but this method only looks for - // those which have isForOp() set. - size_t mid = ComputeBinarySearchMid(this, pcOffset); // Found an IC entry with a matching PC offset. Search backward, and then // forward from this IC entry, looking for one with the same PC offset which diff --git a/js/src/jit/BaselineJIT.h b/js/src/jit/BaselineJIT.h index 503aaaa3bc7..06476c38a6d 100644 --- a/js/src/jit/BaselineJIT.h +++ b/js/src/jit/BaselineJIT.h @@ -330,7 +330,6 @@ struct BaselineScript ICEntry &icEntry(size_t index); ICEntry *maybeICEntryFromReturnOffset(CodeOffsetLabel returnOffset); ICEntry &icEntryFromReturnOffset(CodeOffsetLabel returnOffset); - ICEntry &anyKindICEntryFromPCOffset(uint32_t pcOffset); ICEntry &icEntryFromPCOffset(uint32_t pcOffset); ICEntry &icEntryFromPCOffset(uint32_t pcOffset, ICEntry *prevLookedUpEntry); ICEntry *maybeICEntryFromReturnAddress(uint8_t *returnAddr);