Backed out 2 changesets (bug 1500822) for build bustage. CLOSED TREE
authorDorel Luca <dluca@mozilla.com>
Mon, 22 Oct 2018 23:41:44 +0300
changeset 498901 bff46c89a68bebf27458b3f0aaa2715d6062c041
parent 498900 6ad9bd572bf46896dead808303c652bfb9f8d37a
child 498902 d4cbc38654579d04aa00e04d0f676abf2066a8fe
push id10290
push userffxbld-merge
push dateMon, 03 Dec 2018 16:23:23 +0000
treeherdermozilla-beta@700bed2445e6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1500822
milestone65.0a1
backs outcb7ced1eb7edea847195a701f2ef000c70d5e8a5
2eda4a5dffcca83112096781c7ff8cca39308e42
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
Backed out 2 changesets (bug 1500822) for build bustage. CLOSED TREE Backed out changeset cb7ced1eb7ed (bug 1500822) Backed out changeset 2eda4a5dffcc (bug 1500822)
js/src/frontend/BytecodeEmitter.cpp
js/src/frontend/BytecodeEmitter.h
js/src/frontend/CForEmitter.cpp
js/src/frontend/DoWhileEmitter.cpp
js/src/frontend/ForInEmitter.cpp
js/src/frontend/ForOfEmitter.cpp
js/src/frontend/ForOfLoopControl.cpp
js/src/frontend/TryEmitter.cpp
js/src/frontend/WhileEmitter.cpp
js/src/jit/BaselineBailouts.cpp
js/src/jit/BytecodeAnalysis.cpp
js/src/jit/JitFrames.cpp
js/src/shell/js.cpp
js/src/vm/BytecodeUtil.cpp
js/src/vm/Debugger.cpp
js/src/vm/Interpreter.cpp
js/src/vm/Interpreter.h
js/src/vm/JSScript.cpp
js/src/vm/JSScript.h
js/src/vm/ObjectGroup.cpp
--- a/js/src/frontend/BytecodeEmitter.cpp
+++ b/js/src/frontend/BytecodeEmitter.cpp
@@ -679,19 +679,17 @@ NonLocalExitControl::leaveScope(EmitterS
     // record the extent of the enclosing scope. These notes will have
     // their ends recorded in ~NonLocalExitControl().
     uint32_t enclosingScopeIndex = ScopeNote::NoScopeIndex;
     if (es->enclosingInFrame()) {
         enclosingScopeIndex = es->enclosingInFrame()->index();
     }
     if (!bce_->scopeNoteList.append(enclosingScopeIndex, bce_->offset(), bce_->inPrologue(),
                                     openScopeNoteIndex_))
-    {
-        return false;
-    }
+        return false;
     openScopeNoteIndex_ = bce_->scopeNoteList.length() - 1;
 
     return true;
 }
 
 /*
  * Emit additional bytecode(s) for non-local jumps.
  */
@@ -2935,17 +2933,17 @@ BytecodeEmitter::wrapWithDestructuringIt
     }
 
     ptrdiff_t start = offset();
     if (!emitter(this)) {
         return false;
     }
     ptrdiff_t end = offset();
     if (start != end) {
-        return addTryNote(JSTRY_DESTRUCTURING_ITERCLOSE, iterDepth, start, end);
+        return tryNoteList.append(JSTRY_DESTRUCTURING_ITERCLOSE, iterDepth, start, end);
     }
     return true;
 }
 
 bool
 BytecodeEmitter::emitDefault(ParseNode* defaultExpr, ParseNode* pattern)
 {
     IfEmitter ifUndefined(this);
@@ -4859,18 +4857,18 @@ BytecodeEmitter::emitSpread(bool allowSe
     {
         return false;
     }
 
     // No breaks or continues should occur in spreads.
     MOZ_ASSERT(loopInfo.breaks.offset == -1);
     MOZ_ASSERT(loopInfo.continues.offset == -1);
 
-    if (!addTryNote(JSTRY_FOR_OF, stackDepth, loopInfo.headOffset(),
-                    loopInfo.breakTargetOffset()))
+    if (!tryNoteList.append(JSTRY_FOR_OF, stackDepth, loopInfo.headOffset(),
+                            loopInfo.breakTargetOffset()))
     {
         return false;
     }
 
     if (!emit2(JSOP_PICK, 4)) {                           // ITER ARR FINAL_INDEX RESULT NEXT
         return false;
     }
     if (!emit2(JSOP_PICK, 4)) {                           // ARR FINAL_INDEX RESULT NEXT ITER
@@ -8920,26 +8918,16 @@ AllocSrcNote(JSContext* cx, SrcNotesVect
         return false;
     }
 
     *index = notes.length() - 1;
     return true;
 }
 
 bool
-BytecodeEmitter::addTryNote(JSTryNoteKind kind, uint32_t stackDepth, size_t start, size_t end)
-{
-    // The tryNoteList stores offsets relative to current section should must
-    // be main section. During tryNoteList.finish(), the prologueLength will be
-    // added to correct offset.
-    MOZ_ASSERT(!inPrologue());
-    return tryNoteList.append(kind, stackDepth, start, end);
-}
-
-bool
 BytecodeEmitter::newSrcNote(SrcNoteType type, unsigned* indexp)
 {
     SrcNotesVector& notes = this->notes();
     unsigned index;
     if (!AllocSrcNote(cx, notes, &index)) {
         return false;
     }
 
@@ -9196,49 +9184,42 @@ CGScopeList::finish(mozilla::Span<GCPtrS
 
 bool
 CGTryNoteList::append(JSTryNoteKind kind, uint32_t stackDepth, size_t start, size_t end)
 {
     MOZ_ASSERT(start <= end);
     MOZ_ASSERT(size_t(uint32_t(start)) == start);
     MOZ_ASSERT(size_t(uint32_t(end)) == end);
 
-    // Offsets are given relative to sections, but we only expect main-section
-    // to have TryNotes. In finish() we will fixup base offset.
-
     JSTryNote note;
     note.kind = kind;
     note.stackDepth = stackDepth;
     note.start = uint32_t(start);
     note.length = uint32_t(end - start);
 
     return list.append(note);
 }
 
 void
-CGTryNoteList::finish(mozilla::Span<JSTryNote> array, uint32_t prologueLength)
+CGTryNoteList::finish(mozilla::Span<JSTryNote> array)
 {
     MOZ_ASSERT(length() == array.size());
 
     for (unsigned i = 0; i < length(); i++) {
-        list[i].start += prologueLength;
         array[i] = list[i];
     }
 }
 
 bool
 CGScopeNoteList::append(uint32_t scopeIndex, uint32_t offset, bool inPrologue,
                         uint32_t parent)
 {
     CGScopeNote note;
     mozilla::PodZero(&note);
 
-    // Offsets are given relative to sections. In finish() we will fixup base
-    // offset if needed.
-
     note.index = scopeIndex;
     note.start = offset;
     note.parent = parent;
     note.startInPrologue = inPrologue;
 
     return list.append(note);
 }
 
--- a/js/src/frontend/BytecodeEmitter.h
+++ b/js/src/frontend/BytecodeEmitter.h
@@ -61,22 +61,19 @@ struct MOZ_STACK_CLASS CGScopeList {
     uint32_t length() const { return vector.length(); }
     void finish(mozilla::Span<GCPtrScope> array);
 };
 
 struct CGTryNoteList {
     Vector<JSTryNote> list;
     explicit CGTryNoteList(JSContext* cx) : list(cx) {}
 
-    // Start/end offset are relative to main section and will be patch in
-    // finish().
-
     MOZ_MUST_USE bool append(JSTryNoteKind kind, uint32_t stackDepth, size_t start, size_t end);
     size_t length() const { return list.length(); }
-    void finish(mozilla::Span<JSTryNote> array, uint32_t prologueLength);
+    void finish(mozilla::Span<JSTryNote> array);
 };
 
 struct CGScopeNote : public ScopeNote
 {
     // The end offset. Used to compute the length; may need adjusting first if
     // in the prologue.
     uint32_t end;
 
@@ -430,20 +427,16 @@ struct MOZ_STACK_CLASS BytecodeEmitter
     // the main effect, the value left on the stack after the code executes,
     // will be discarded by a pop bytecode.
     MOZ_MUST_USE bool checkSideEffects(ParseNode* pn, bool* answer);
 
 #ifdef DEBUG
     MOZ_MUST_USE bool checkStrictOrSloppy(JSOp op);
 #endif
 
-    // Add TryNote to the tryNoteList array. The start and end offset are
-    // relative to current section.
-    MOZ_MUST_USE bool addTryNote(JSTryNoteKind kind, uint32_t stackDepth, size_t start, size_t end);
-
     // Append a new source note of the given type (and therefore size) to the
     // notes dynamic array, updating noteCount. Return the new note's index
     // within the array pointed at by current->notes as outparam.
     MOZ_MUST_USE bool newSrcNote(SrcNoteType type, unsigned* indexp = nullptr);
     MOZ_MUST_USE bool newSrcNote2(SrcNoteType type, ptrdiff_t offset, unsigned* indexp = nullptr);
     MOZ_MUST_USE bool newSrcNote3(SrcNoteType type, ptrdiff_t offset1, ptrdiff_t offset2,
                                   unsigned* indexp = nullptr);
 
--- a/js/src/frontend/CForEmitter.cpp
+++ b/js/src/frontend/CForEmitter.cpp
@@ -227,18 +227,18 @@ CForEmitter::emitEnd()
     // The third note offset helps us find the loop-closing jump.
     if (!bce_->setSrcNoteOffset(noteIndex_, SrcNote::For::BackJumpOffset,
                                 loopInfo_->loopEndOffset() - biasedTop_))
 
     {
         return false;
     }
 
-    if (!bce_->addTryNote(JSTRY_LOOP, bce_->stackDepth, loopInfo_->headOffset(),
-                          loopInfo_->breakTargetOffset()))
+    if (!bce_->tryNoteList.append(JSTRY_LOOP, bce_->stackDepth, loopInfo_->headOffset(),
+                                  loopInfo_->breakTargetOffset()))
     {
         return false;
     }
 
     if (!loopInfo_->patchBreaksAndContinues(bce_)) {
         return false;
     }
 
--- a/js/src/frontend/DoWhileEmitter.cpp
+++ b/js/src/frontend/DoWhileEmitter.cpp
@@ -77,18 +77,18 @@ bool
 DoWhileEmitter::emitEnd()
 {
     MOZ_ASSERT(state_ == State::Cond);
 
     if (!loopInfo_->emitLoopEnd(bce_, JSOP_IFNE)) {
         return false;
     }
 
-    if (!bce_->addTryNote(JSTRY_LOOP, bce_->stackDepth, loopInfo_->headOffset(),
-                          loopInfo_->breakTargetOffset()))
+    if (!bce_->tryNoteList.append(JSTRY_LOOP, bce_->stackDepth, loopInfo_->headOffset(),
+                                  loopInfo_->breakTargetOffset()))
     {
         return false;
     }
 
     // Update the annotations with the update and back edge positions, for
     // IonBuilder.
     if (!bce_->setSrcNoteOffset(noteIndex_, SrcNote::DoWhile::CondOffset,
                                 loopInfo_->continueTargetOffsetFromLoopHead()))
--- a/js/src/frontend/ForInEmitter.cpp
+++ b/js/src/frontend/ForInEmitter.cpp
@@ -163,18 +163,18 @@ ForInEmitter::emitEnd(const Maybe<uint32
         return false;
     }
 
     // Pop the enumeration value.
     if (!bce_->emit1(JSOP_POP)) {                     // ITER
         return false;
     }
 
-    if (!bce_->addTryNote(JSTRY_FOR_IN, bce_->stackDepth, loopInfo_->headOffset(),
-                          bce_->offset()))
+    if (!bce_->tryNoteList.append(JSTRY_FOR_IN, bce_->stackDepth, loopInfo_->headOffset(),
+                                  bce_->offset()))
     {
         return false;
     }
 
     if (!bce_->emit1(JSOP_ENDITER)) {                 //
         return false;
     }
 
--- a/js/src/frontend/ForOfEmitter.cpp
+++ b/js/src/frontend/ForOfEmitter.cpp
@@ -238,18 +238,18 @@ ForOfEmitter::emitEnd(const Maybe<uint32
     {
         return false;
     }
 
     if (!loopInfo_->patchBreaksAndContinues(bce_)) {
         return false;
     }
 
-    if (!bce_->addTryNote(JSTRY_FOR_OF, bce_->stackDepth, loopInfo_->headOffset(),
-                          loopInfo_->breakTargetOffset()))
+    if (!bce_->tryNoteList.append(JSTRY_FOR_OF, bce_->stackDepth, loopInfo_->headOffset(),
+                                  loopInfo_->breakTargetOffset()))
     {
         return false;
     }
 
     if (!bce_->emitPopN(3)) {                         //
         return false;
     }
 
--- a/js/src/frontend/ForOfLoopControl.cpp
+++ b/js/src/frontend/ForOfLoopControl.cpp
@@ -134,17 +134,17 @@ ForOfLoopControl::emitIteratorCloseInSco
 {
     ptrdiff_t start = bce->offset();
     if (!bce->emitIteratorCloseInScope(currentScope, iterKind_, completionKind,
                                        allowSelfHosted_))
     {
         return false;
     }
     ptrdiff_t end = bce->offset();
-    return bce->addTryNote(JSTRY_FOR_OF_ITERCLOSE, 0, start, end);
+    return bce->tryNoteList.append(JSTRY_FOR_OF_ITERCLOSE, 0, start, end);
 }
 
 // Since we're in the middle of emitting code that will leave
 // |bce->innermostEmitterScope()|, passing the innermost emitter scope to
 // emitIteratorCloseInScope and looking up .generator there would be very,
 // very wrong.  We'd find .generator in the function environment, and we'd
 // compute a NameLocation with the correct slot, but we'd compute a
 // hop-count to the function environment that was too big.  At runtime we'd
--- a/js/src/frontend/TryEmitter.cpp
+++ b/js/src/frontend/TryEmitter.cpp
@@ -278,26 +278,26 @@ TryEmitter::emitEnd()
     // Fix up the end-of-try/catch jumps to come here.
     if (!bce_->emitJumpTargetAndPatch(catchAndFinallyJump_)) {
         return false;
     }
 
     // Add the try note last, to let post-order give us the right ordering
     // (first to last for a given nesting level, inner to outer by level).
     if (hasCatch()) {
-        if (!bce_->addTryNote(JSTRY_CATCH, depth_, tryStart_, tryEnd_.offset)) {
+        if (!bce_->tryNoteList.append(JSTRY_CATCH, depth_, tryStart_, tryEnd_.offset)) {
             return false;
         }
     }
 
     // If we've got a finally, mark try+catch region with additional
     // trynote to catch exceptions (re)thrown from a catch block or
     // for the try{}finally{} case.
     if (hasFinally()) {
-        if (!bce_->addTryNote(JSTRY_FINALLY, depth_, tryStart_, finallyStart_.offset)) {
+        if (!bce_->tryNoteList.append(JSTRY_FINALLY, depth_, tryStart_, finallyStart_.offset)) {
             return false;
         }
     }
 
 #ifdef DEBUG
     state_ = State::End;
 #endif
     return true;
--- a/js/src/frontend/WhileEmitter.cpp
+++ b/js/src/frontend/WhileEmitter.cpp
@@ -104,18 +104,18 @@ bool
 WhileEmitter::emitEnd()
 {
     MOZ_ASSERT(state_ == State::Cond);
 
     if (!loopInfo_->emitLoopEnd(bce_, JSOP_IFNE)) {
         return false;
     }
 
-    if (!bce_->addTryNote(JSTRY_LOOP, bce_->stackDepth, loopInfo_->headOffset(),
-                          loopInfo_->breakTargetOffset()))
+    if (!bce_->tryNoteList.append(JSTRY_LOOP, bce_->stackDepth, loopInfo_->headOffset(),
+                                  loopInfo_->breakTargetOffset()))
     {
         return false;
     }
 
     if (!bce_->setSrcNoteOffset(noteIndex_, SrcNote::While::BackJumpOffset,
                                 loopInfo_->loopEndOffsetFromEntryJump()))
     {
         return false;
--- a/js/src/jit/BaselineBailouts.cpp
+++ b/js/src/jit/BaselineBailouts.cpp
@@ -484,17 +484,17 @@ GetNextNonLoopEntryPc(jsbytecode* pc, js
 
 static bool
 HasLiveStackValueAtDepth(JSScript* script, jsbytecode* pc, uint32_t stackDepth)
 {
     if (!script->hasTrynotes()) {
         return false;
     }
 
-    uint32_t pcOffset = script->pcToOffset(pc);
+    uint32_t pcOffset = uint32_t(pc - script->main());
 
     for (const JSTryNote& tn : script->trynotes()) {
         if (pcOffset < tn.start) {
             continue;
         }
         if (pcOffset >= tn.start + tn.length) {
             continue;
         }
--- a/js/src/jit/BytecodeAnalysis.cpp
+++ b/js/src/jit/BytecodeAnalysis.cpp
@@ -113,18 +113,19 @@ BytecodeAnalysis::init(TempAllocator& al
                 }
                 pc2 += JUMP_OFFSET_LEN;
             }
             break;
           }
 
           case JSOP_TRY: {
             for (const JSTryNote& tn : script_->trynotes()) {
-                if (tn.start == offset + 1) {
-                    unsigned catchOffset = tn.start + tn.length;
+                unsigned startOffset = script_->mainOffset() + tn.start;
+                if (startOffset == offset + 1) {
+                    unsigned catchOffset = startOffset + tn.length;
 
                     if (tn.kind != JSTRY_FOR_IN) {
                         infos_[catchOffset].init(stackDepth);
                         infos_[catchOffset].jumpTarget = true;
                     }
                 }
             }
 
--- a/js/src/jit/JitFrames.cpp
+++ b/js/src/jit/JitFrames.cpp
@@ -229,17 +229,17 @@ HandleExceptionIon(JSContext* cx, const 
           case JSTRY_FOR_IN:
           case JSTRY_DESTRUCTURING_ITERCLOSE:
             // See corresponding comment in ProcessTryNotes.
             if (inForOfIterClose) {
                 break;
             }
 
             MOZ_ASSERT_IF(tn->kind == JSTRY_FOR_IN,
-                          JSOp(*(script->offsetToPC(tn->start + tn->length))) == JSOP_ENDITER);
+                          JSOp(*(script->main() + tn->start + tn->length)) == JSOP_ENDITER);
             CloseLiveIteratorIon(cx, frame, tn);
             break;
 
           case JSTRY_FOR_OF_ITERCLOSE:
             inForOfIterClose = true;
             break;
 
           case JSTRY_FOR_OF:
@@ -257,17 +257,17 @@ HandleExceptionIon(JSContext* cx, const 
                 }
 
                 // Ion can compile try-catch, but bailing out to catch
                 // exceptions is slow. Reset the warm-up counter so that if we
                 // catch many exceptions we won't Ion-compile the script.
                 script->resetWarmUpCounter();
 
                 // Bailout at the start of the catch block.
-                jsbytecode* catchPC = script->offsetToPC(tn->start + tn->length);
+                jsbytecode* catchPC = script->main() + tn->start + tn->length;
                 ExceptionBailoutInfo excInfo(frame.frameNo(), catchPC, tn->stackDepth);
                 uint32_t retval = ExceptionHandlerBailout(cx, frame, rfe, excInfo, overrecursed);
                 if (retval == BAILOUT_RETURN_OK) {
                     // Record exception locations to allow scope unwinding in
                     // |FinishBailoutToBaseline|
                     MOZ_ASSERT(cx->isExceptionPending());
                     rfe->bailoutInfo->tryPC = UnwindEnvironmentToTryPc(frame.script(), tn);
                     rfe->bailoutInfo->faultPC = frame.pc();
@@ -324,17 +324,17 @@ SettleOnTryNote(JSContext* cx, const JST
     if (cx->isExceptionPending()) {
         UnwindEnvironment(cx, ei, UnwindEnvironmentToTryPc(script, tn));
     }
 
     // Compute base pointer and stack pointer.
     BaselineFrameAndStackPointersFromTryNote(tn, frame, &rfe->framePointer, &rfe->stackPointer);
 
     // Compute the pc.
-    *pc = script->offsetToPC(tn->start + tn->length);
+    *pc = script->main() + tn->start + tn->length;
 }
 
 struct AutoBaselineHandlingException
 {
     BaselineFrame* frame;
     AutoBaselineHandlingException(BaselineFrame* frame, jsbytecode* pc)
       : frame(frame)
     {
--- a/js/src/shell/js.cpp
+++ b/js/src/shell/js.cpp
@@ -3097,19 +3097,20 @@ TryNotes(JSContext* cx, HandleScript scr
         return true;
     }
 
     if (!sp->put("\nException table:\nkind               stack    start      end\n")) {
         return false;
     }
 
     for (const JSTryNote& tn : script->trynotes()) {
+        uint32_t startOff = script->pcToOffset(script->main()) + tn.start;
         if (!sp->jsprintf(" %-16s %6u %8u %8u\n",
                           TryNoteName(static_cast<JSTryNoteKind>(tn.kind)),
-                          tn.stackDepth, tn.start, tn.start + tn.length))
+                          tn.stackDepth, startOff, startOff + tn.length))
         {
             return false;
         }
     }
     return true;
 }
 
 static MOZ_MUST_USE bool
--- a/js/src/vm/BytecodeUtil.cpp
+++ b/js/src/vm/BytecodeUtil.cpp
@@ -942,18 +942,19 @@ BytecodeParser::parse()
           }
 
           case JSOP_TRY: {
             // Everything between a try and corresponding catch or finally is conditional.
             // Note that there is no problem with code which is skipped by a thrown
             // exception but is not caught by a later handler in the same function:
             // no more code will execute, and it does not matter what is defined.
             for (const JSTryNote& tn : script_->trynotes()) {
-                if (tn.start == offset + 1) {
-                    uint32_t catchOffset = tn.start + tn.length;
+                uint32_t startOffset = script_->mainOffset() + tn.start;
+                if (startOffset == offset + 1) {
+                    uint32_t catchOffset = startOffset + tn.length;
                     if (tn.kind == JSTRY_CATCH) {
                         if (!addJump(catchOffset, &nextOffset, stackDepth, offsetStack,
                                      pc, JumpKind::TryCatch))
                         {
                             return false;
                         }
                     } else if (tn.kind == JSTRY_FINALLY) {
                         if (!addJump(catchOffset, &nextOffset, stackDepth, offsetStack,
@@ -1450,17 +1451,17 @@ Disassemble1(JSContext* cx, HandleScript
       case JOF_BYTE:
           // Scan the trynotes to find the associated catch block
           // and make the try opcode look like a jump instruction
           // with an offset. This simplifies code coverage analysis
           // based on this disassembled output.
           if (op == JSOP_TRY) {
               size_t mainOffset = script->mainOffset();
               for (const JSTryNote& tn : script->trynotes()) {
-                  if (tn.kind == JSTRY_CATCH && tn.start == loc + 1) {
+                  if (tn.kind == JSTRY_CATCH && tn.start + mainOffset == loc + 1) {
                       if (!sp->jsprintf(" %u (%+d)",
                                         unsigned(loc + tn.length + 1),
                                         int(tn.length + 1)))
                       {
                           return 0;
                       }
                       break;
                   }
--- a/js/src/vm/Debugger.cpp
+++ b/js/src/vm/Debugger.cpp
@@ -6444,18 +6444,19 @@ class FlowGraphSummary {
                 }
             } else if (op == JSOP_TRY) {
                 // As there is no literal incoming edge into the catch block, we
                 // make a fake one by copying the JSOP_TRY location, as-if this
                 // was an incoming edge of the catch block. This is needed
                 // because we only report offsets of entry points which have
                 // valid incoming edges.
                 for (const JSTryNote& tn : script->trynotes()) {
-                    if (tn.start == r.frontOffset() + 1) {
-                        uint32_t catchOffset = tn.start + tn.length;
+                    uint32_t startOffset = script->mainOffset() + tn.start;
+                    if (startOffset == r.frontOffset() + 1) {
+                        uint32_t catchOffset = startOffset + tn.length;
                         if (tn.kind == JSTRY_CATCH || tn.kind == JSTRY_FINALLY) {
                             addEdge(lineno, column, catchOffset);
                         }
                     }
                 }
             }
 
             prevLineno = lineno;
@@ -7461,20 +7462,24 @@ class DebuggerScriptIsInCatchScopeMatche
 
     inline bool isInCatch() const { return isInCatch_; }
 
     ReturnType match(HandleScript script) {
         if (!EnsureScriptOffsetIsValid(cx_, script, offset_)) {
             return false;
         }
 
+        // Try note ranges are relative to the mainOffset of the script, so adjust
+        // offset accordingly.
+        size_t offset = offset_ - script->mainOffset();
+
         if (script->hasTrynotes()) {
             for (const JSTryNote& tn : script->trynotes()) {
-                if (tn.start <= offset_ &&
-                    offset_ < tn.start + tn.length &&
+                if (tn.start <= offset &&
+                    offset <= tn.start + tn.length &&
                     tn.kind == JSTRY_CATCH)
                 {
                     isInCatch_ = true;
                     return true;
                 }
             }
         }
         isInCatch_ = false;
--- a/js/src/vm/Interpreter.cpp
+++ b/js/src/vm/Interpreter.cpp
@@ -1311,17 +1311,17 @@ js::UnwindAllEnvironmentsInFrame(JSConte
 //
 // try { { let x; } }
 //
 // will have no pc location distinguishing the try block scope from the inner
 // let block scope.
 jsbytecode*
 js::UnwindEnvironmentToTryPc(JSScript* script, const JSTryNote* tn)
 {
-    jsbytecode* pc = script->offsetToPC(tn->start);
+    jsbytecode* pc = script->main() + tn->start;
     if (tn->kind == JSTRY_CATCH || tn->kind == JSTRY_FINALLY) {
         pc -= JSOP_TRY_LENGTH;
         MOZ_ASSERT(*pc == JSOP_TRY);
     } else if (tn->kind == JSTRY_DESTRUCTURING_ITERCLOSE) {
         pc -= JSOP_TRY_DESTRUCTURING_ITERCLOSE_LENGTH;
         MOZ_ASSERT(*pc == JSOP_TRY_DESTRUCTURING_ITERCLOSE);
     }
     return pc;
@@ -1340,17 +1340,17 @@ ForcedReturn(JSContext* cx, InterpreterR
 static void
 SettleOnTryNote(JSContext* cx, const JSTryNote* tn, EnvironmentIter& ei, InterpreterRegs& regs)
 {
     // Unwind the environment to the beginning of the JSOP_TRY.
     UnwindEnvironment(cx, ei, UnwindEnvironmentToTryPc(regs.fp()->script(), tn));
 
     // Set pc to the first bytecode after the the try note to point
     // to the beginning of catch or finally.
-    regs.pc = regs.fp()->script()->offsetToPC(tn->start + tn->length);
+    regs.pc = regs.fp()->script()->main() + tn->start + tn->length;
     regs.sp = regs.spForStackDepth(tn->stackDepth);
 }
 
 class InterpreterFrameStackDepthOp
 {
     const InterpreterRegs& regs_;
   public:
     explicit InterpreterFrameStackDepthOp(const InterpreterRegs& regs)
@@ -1463,17 +1463,17 @@ ProcessTryNotes(JSContext* cx, Environme
             // Don't let (extra) values pushed on the stack while closing a
             // for-of iterator confuse us into thinking we still have to close
             // an inner for-in iterator.
             if (inForOfIterClose) {
                 break;
             }
 
             /* This is similar to JSOP_ENDITER in the interpreter loop. */
-            DebugOnly<jsbytecode*> pc = regs.fp()->script()->offsetToPC(tn->start + tn->length);
+            DebugOnly<jsbytecode*> pc = regs.fp()->script()->main() + tn->start + tn->length;
             MOZ_ASSERT(JSOp(*pc) == JSOP_ENDITER);
             Value* sp = regs.spForStackDepth(tn->stackDepth);
             JSObject* obj = &sp[-1].toObject();
             CloseIterator(obj);
             break;
           }
 
           case JSTRY_DESTRUCTURING_ITERCLOSE: {
--- a/js/src/vm/Interpreter.h
+++ b/js/src/vm/Interpreter.h
@@ -388,17 +388,17 @@ class MOZ_STACK_CLASS TryNoteIter
             }
         }
     }
 
   public:
     TryNoteIter(JSContext* cx, JSScript* script, jsbytecode* pc,
                 StackDepthOp getStackDepth)
       : script_(cx, script),
-        pcOffset_(script->pcToOffset(pc)),
+        pcOffset_(pc - script->main()),
         getStackDepth_(getStackDepth)
     {
         if (script->hasTrynotes()) {
             // NOTE: The Span is a temporary so we can't use begin()/end()
             // here or the iterator will outlive the span.
             auto trynotes = script->trynotes();
             tn_ = trynotes.data();
             tnEnd_ = tn_ + trynotes.size();
--- a/js/src/vm/JSScript.cpp
+++ b/js/src/vm/JSScript.cpp
@@ -3517,17 +3517,17 @@ JSScript::fullyInitFromEmitter(JSContext
     }
     if (bce->objectList.length != 0) {
         bce->objectList.finish(script->objects());
     }
     if (bce->scopeList.length() != 0) {
         bce->scopeList.finish(script->scopes());
     }
     if (bce->tryNoteList.length() != 0) {
-        bce->tryNoteList.finish(script->trynotes(), prologueLength);
+        bce->tryNoteList.finish(script->trynotes());
     }
     if (bce->scopeNoteList.length() != 0) {
         bce->scopeNoteList.finish(script->scopeNotes(), prologueLength);
     }
     script->bitFields_.strict_ = bce->sc->strict();
     script->bitFields_.explicitUseStrict_ = bce->sc->hasExplicitUseStrict();
     script->bitFields_.bindingsAccessedDynamically_ = bce->sc->bindingsAccessedDynamically();
     script->bitFields_.hasSingletons_ = bce->hasSingletons;
@@ -3603,17 +3603,17 @@ JSScript::assertValidJumpTargets() const
                 MOZ_ASSERT_IF(off, BytecodeIsJumpTarget(JSOp(*(pc + off))));
             }
         }
     }
 
     // Check catch/finally blocks as jump targets.
     if (hasTrynotes()) {
         for (const JSTryNote& tn : trynotes()) {
-            jsbytecode* tryStart = offsetToPC(tn.start);
+            jsbytecode* tryStart = mainEntry + tn.start;
             jsbytecode* tryPc = tryStart - 1;
             if (tn.kind != JSTRY_CATCH && tn.kind != JSTRY_FINALLY) {
                 continue;
             }
 
             MOZ_ASSERT(JSOp(*tryPc) == JSOP_TRY);
             jsbytecode* tryTarget = tryStart + tn.length;
             MOZ_ASSERT(mainEntry <= tryTarget && tryTarget < end);
--- a/js/src/vm/JSScript.h
+++ b/js/src/vm/JSScript.h
@@ -104,18 +104,18 @@ enum JSTryNoteKind {
 };
 
 /*
  * Exception handling record.
  */
 struct JSTryNote {
     uint8_t         kind;       /* one of JSTryNoteKind */
     uint32_t        stackDepth; /* stack depth upon exception handler entry */
-    uint32_t        start;      /* start of the try statement or loop relative
-                                   to script->code() */
+    uint32_t        start;      /* start of the try statement or loop
+                                   relative to script->main */
     uint32_t        length;     /* length of the try statement or loop */
 };
 
 namespace js {
 
 // A block scope has a range in bytecode: it is entered at some offset, and left
 // at some later offset.  Scopes can be nested.  Given an offset, the
 // ScopeNote containing that offset whose with the highest start value
@@ -134,18 +134,18 @@ struct ScopeNote {
     static const uint32_t NoScopeIndex = UINT32_MAX;
 
     // Sentinel index for no ScopeNote.
     static const uint32_t NoScopeNoteIndex = UINT32_MAX;
 
     uint32_t        index;      // Index of Scope in the scopes array, or
                                 // NoScopeIndex if there is no block scope in
                                 // this range.
-    uint32_t        start;      // Bytecode offset at which this scope starts
-                                // relative to script->code().
+    uint32_t        start;      // Bytecode offset at which this scope starts,
+                                // from script->main().
     uint32_t        length;     // Bytecode length of scope.
     uint32_t        parent;     // Index of parent block scope in notes, or NoScopeNote.
 };
 
 struct ConstArray {
     js::GCPtrValue* vector;     // array of indexed constant values
     uint32_t length;
 };
--- a/js/src/vm/ObjectGroup.cpp
+++ b/js/src/vm/ObjectGroup.cpp
@@ -233,24 +233,27 @@ ObjectGroup::useSingletonForAllocationSi
     }
 
     // All loops in the script will have a try note indicating their boundary.
 
     if (!script->hasTrynotes()) {
         return SingletonObject;
     }
 
-    uint32_t offset = script->pcToOffset(pc);
+    unsigned offset = script->pcToOffset(pc);
 
     for (const JSTryNote& tn : script->trynotes()) {
         if (tn.kind != JSTRY_FOR_IN && tn.kind != JSTRY_FOR_OF && tn.kind != JSTRY_LOOP) {
             continue;
         }
 
-        if (tn.start <= offset && offset < tn.start + tn.length) {
+        unsigned startOffset = script->mainOffset() + tn.start;
+        unsigned endOffset = startOffset + tn.length;
+
+        if (offset >= startOffset && offset < endOffset) {
             return GenericObject;
         }
     }
 
     return SingletonObject;
 }
 
 /* static */ bool