Bug 1535994 - Part 2: Move source notes to BytecodeSection class. r=jorendorff
☠☠ backed out by 7fb3acf38591 ☠ ☠
authorTooru Fujisawa <arai_a@mac.com>
Wed, 10 Apr 2019 08:25:28 +0000
changeset 468759 b77efa8567a299f90c926f5623a6f07325fcfa32
parent 468758 384cdd1ee833dfa72b957072651c1bde10dacf7c
child 468760 ee3359178d5f37c951dd146926c4035d6245299f
push id112755
push userdvarga@mozilla.com
push dateWed, 10 Apr 2019 22:06:41 +0000
treeherdermozilla-inbound@606f85641d0b [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjorendorff
bugs1535994
milestone68.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 1535994 - Part 2: Move source notes to BytecodeSection class. r=jorendorff Differential Revision: https://phabricator.services.mozilla.com/D25732
js/src/frontend/BytecodeEmitter.cpp
js/src/frontend/BytecodeEmitter.h
js/src/frontend/SwitchEmitter.cpp
js/src/vm/JSScript.cpp
--- a/js/src/frontend/BytecodeEmitter.cpp
+++ b/js/src/frontend/BytecodeEmitter.cpp
@@ -86,29 +86,29 @@ static bool ParseNodeRequiresSpecialLine
   // handling to avoid strange stepping behavior.
   // Functions usually shouldn't have location information (bug 1431202).
 
   ParseNodeKind kind = pn->getKind();
   return kind == ParseNodeKind::WhileStmt || kind == ParseNodeKind::ForStmt ||
          kind == ParseNodeKind::Function;
 }
 
-BytecodeEmitter::BytecodeSection::BytecodeSection(JSContext* cx) : code_(cx) {}
+BytecodeEmitter::BytecodeSection::BytecodeSection(JSContext* cx)
+    : code_(cx), notes_(cx) {}
 
 BytecodeEmitter::BytecodeEmitter(
     BytecodeEmitter* parent, SharedContext* sc, HandleScript script,
     Handle<LazyScript*> lazyScript, uint32_t lineNum, EmitterMode emitterMode,
     FieldInitializers fieldInitializers /* = FieldInitializers::Invalid() */)
     : sc(sc),
       cx(sc->cx_),
       parent(parent),
       script(cx, script),
       lazyScript(cx, lazyScript),
       bytecodeSection_(cx),
-      notes_(cx),
       currentLine_(lineNum),
       fieldInitializers_(fieldInitializers),
       atomIndices(cx->frontendCollectionPool()),
       firstLine(lineNum),
       numberList(cx),
       scopeList(cx),
       tryNoteList(cx),
       scopeNoteList(cx),
@@ -9339,29 +9339,31 @@ static bool AllocSrcNote(JSContext* cx, 
 
 bool BytecodeEmitter::addTryNote(JSTryNoteKind kind, uint32_t stackDepth,
                                  size_t start, size_t end) {
   MOZ_ASSERT(!inPrologue());
   return tryNoteList.append(kind, stackDepth, start, end);
 }
 
 bool BytecodeEmitter::newSrcNote(SrcNoteType type, unsigned* indexp) {
-  SrcNotesVector& notes = this->notes();
+  // Prologue shouldn't have source notes.
+  MOZ_ASSERT(!inPrologue());
+  SrcNotesVector& notes = bytecodeSection().notes();
   unsigned index;
   if (!AllocSrcNote(cx, notes, &index)) {
     return false;
   }
 
   /*
    * Compute delta from the last annotated bytecode's offset.  If it's too
    * big to fit in sn, allocate one or more xdelta notes and reset sn.
    */
   ptrdiff_t offset = bytecodeSection().offset();
-  ptrdiff_t delta = offset - lastNoteOffset();
-  lastNoteOffset_ = offset;
+  ptrdiff_t delta = offset - bytecodeSection().lastNoteOffset();
+  bytecodeSection().setLastNoteOffset(offset);
   if (delta >= SN_DELTA_LIMIT) {
     do {
       ptrdiff_t xdelta = Min(delta, SN_XDELTA_MASK);
       SN_MAKE_XDELTA(&notes[index], xdelta);
       delta -= xdelta;
       if (!AllocSrcNote(cx, notes, &index)) {
         return false;
       }
@@ -9421,17 +9423,17 @@ bool BytecodeEmitter::newSrcNote3(SrcNot
 
 bool BytecodeEmitter::setSrcNoteOffset(unsigned index, unsigned which,
                                        ptrdiff_t offset) {
   if (!SN_REPRESENTABLE_OFFSET(offset)) {
     reportError(nullptr, JSMSG_NEED_DIET, js_script_str);
     return false;
   }
 
-  SrcNotesVector& notes = this->notes();
+  SrcNotesVector& notes = bytecodeSection().notes();
 
   /* Find the offset numbered which (i.e., skip exactly which offsets). */
   jssrcnote* sn = &notes[index];
   MOZ_ASSERT(SN_TYPE(sn) != SRC_XDELTA);
   MOZ_ASSERT((int)which < js_SrcNoteSpec[SN_TYPE(sn)].arity);
   for (sn++; which; sn++, which--) {
     if (*sn & SN_4BYTE_OFFSET_FLAG) {
       sn += 3;
@@ -9459,20 +9461,20 @@ bool BytecodeEmitter::setSrcNoteOffset(u
     *sn++ = (jssrcnote)(offset >> 16);
     *sn++ = (jssrcnote)(offset >> 8);
   }
   *sn = (jssrcnote)offset;
   return true;
 }
 
 void BytecodeEmitter::copySrcNotes(jssrcnote* destination, uint32_t nsrcnotes) {
-  unsigned count = notes_.length();
+  unsigned count = bytecodeSection().notes().length();
   // nsrcnotes includes SN_MAKE_TERMINATOR in addition to the srcnotes.
   MOZ_ASSERT(nsrcnotes == count + 1);
-  PodCopy(destination, notes_.begin(), count);
+  PodCopy(destination, bytecodeSection().notes().begin(), count);
   SN_MAKE_TERMINATOR(&destination[count]);
 }
 
 void CGNumberList::finish(mozilla::Span<GCPtrValue> array) {
   MOZ_ASSERT(length() == array.size());
 
   for (unsigned i = 0; i < length(); i++) {
     array[i].init(vector[i]);
--- a/js/src/frontend/BytecodeEmitter.h
+++ b/js/src/frontend/BytecodeEmitter.h
@@ -125,41 +125,54 @@ struct MOZ_STACK_CLASS BytecodeEmitter {
 
  private:
   // Bytecode and all data directly associated with specific opcode/index inside
   // bytecode is stored in this class.
   class BytecodeSection {
    public:
     explicit BytecodeSection(JSContext* cx);
 
+    // ---- Bytecode ----
+
     BytecodeVector& code() { return code_; }
     const BytecodeVector& code() const { return code_; }
 
     jsbytecode* code(ptrdiff_t offset) { return code_.begin() + offset; }
     ptrdiff_t offset() const { return code_.end() - code_.begin(); }
 
+    // ---- Source notes ----
+
+    SrcNotesVector& notes() { return notes_; }
+    const SrcNotesVector& notes() const { return notes_; }
+
+    ptrdiff_t lastNoteOffset() const { return lastNoteOffset_; }
+    void setLastNoteOffset(ptrdiff_t offset) { lastNoteOffset_ = offset; }
+
    private:
     // ---- Bytecode ----
 
     // Bytecode.
     BytecodeVector code_;
+
+    // ---- Source notes ----
+
+    // Source notes
+    SrcNotesVector notes_;
+
+    // Code offset for last source note
+    ptrdiff_t lastNoteOffset_ = 0;
   };
 
   BytecodeSection bytecodeSection_;
 
  public:
   BytecodeSection& bytecodeSection() { return bytecodeSection_; }
   const BytecodeSection& bytecodeSection() const { return bytecodeSection_; }
 
  private:
-  SrcNotesVector notes_; /* source notes, see below */
-
-  // Code offset for last source note
-  ptrdiff_t lastNoteOffset_ = 0;
-
   // Line number for srcnotes.
   //
   // WARNING: If this becomes out of sync with already-emitted srcnotes,
   // we can get undefined behavior.
   uint32_t currentLine_ = 0;
 
   // Zero-based column index on currentLine of last SRC_COLSPAN-annotated
   // opcode.
@@ -429,22 +442,16 @@ struct MOZ_STACK_CLASS BytecodeEmitter {
 
   bool inPrologue() const { return mainOffset_.isNothing(); }
 
   void switchToMain() {
     MOZ_ASSERT(inPrologue());
     mainOffset_.emplace(bytecodeSection().code().length());
   }
 
-  SrcNotesVector& notes() {
-    // Prologue shouldn't have source notes.
-    MOZ_ASSERT(!inPrologue());
-    return notes_;
-  }
-  ptrdiff_t lastNoteOffset() const { return lastNoteOffset_; }
   unsigned currentLine() const { return currentLine_; }
 
   void setCurrentLine(uint32_t line) {
     currentLine_ = line;
     lastColumn_ = 0;
   }
 
   // Check if the last emitted opcode is a jump target.
--- a/js/src/frontend/SwitchEmitter.cpp
+++ b/js/src/frontend/SwitchEmitter.cpp
@@ -238,21 +238,22 @@ bool SwitchEmitter::emitCaseOrDefaultJum
   if (!bce_->emitJump(JSOP_CASE, &caseJump)) {
     return false;
   }
   caseOffsets_[caseIndex] = caseJump.offset;
   lastCaseOffset_ = caseJump.offset;
 
   if (caseIndex == 0) {
     // Switch note's second offset is to first JSOP_CASE.
-    unsigned noteCount = bce_->notes().length();
+    unsigned noteCount = bce_->bytecodeSection().notes().length();
     if (!bce_->setSrcNoteOffset(noteIndex_, 1, lastCaseOffset_ - top_)) {
       return false;
     }
-    unsigned noteCountDelta = bce_->notes().length() - noteCount;
+    unsigned noteCountDelta =
+        bce_->bytecodeSection().notes().length() - noteCount;
     if (noteCountDelta != 0) {
       caseNoteIndex_ += noteCountDelta;
     }
   }
 
   return true;
 }
 
--- a/js/src/vm/JSScript.cpp
+++ b/js/src/vm/JSScript.cpp
@@ -4522,17 +4522,17 @@ bool JSScript::hasBreakpointsAt(jsbyteco
 
 /* static */ bool SharedScriptData::InitFromEmitter(
     JSContext* cx, js::HandleScript script, frontend::BytecodeEmitter* bce) {
   uint32_t natoms = bce->atomIndices->count();
   uint32_t codeLength = bce->bytecodeSection().code().length();
 
   // The + 1 is to account for the final SN_MAKE_TERMINATOR that is appended
   // when the notes are copied to their final destination by copySrcNotes.
-  uint32_t noteLength = bce->notes().length() + 1;
+  uint32_t noteLength = bce->bytecodeSection().notes().length() + 1;
 
   // Create and initialize SharedScriptData
   if (!script->createSharedScriptData(cx, codeLength, noteLength, natoms)) {
     return false;
   }
 
   js::SharedScriptData* data = script->scriptData_;