Bug 1535994 - Part 7: Move object and number to PerScriptData class. r=jorendorff
☠☠ backed out by 7fb3acf38591 ☠ ☠
authorTooru Fujisawa <arai_a@mac.com>
Wed, 10 Apr 2019 08:27:02 +0000
changeset 468764 096ab8585046007ed3a7853e4b2ce6ce37f55243
parent 468763 8a480b0bbd0565adc7dfac295f6cac482e4d3350
child 468765 db520471b4073f6ca3a9f671d522987f1298fa50
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 7: Move object and number to PerScriptData class. r=jorendorff Differential Revision: https://phabricator.services.mozilla.com/D25737
js/src/frontend/BytecodeEmitter.cpp
js/src/frontend/BytecodeEmitter.h
js/src/frontend/FunctionEmitter.cpp
js/src/vm/JSScript.cpp
--- a/js/src/frontend/BytecodeEmitter.cpp
+++ b/js/src/frontend/BytecodeEmitter.cpp
@@ -89,34 +89,34 @@ static bool ParseNodeRequiresSpecialLine
   ParseNodeKind kind = pn->getKind();
   return kind == ParseNodeKind::WhileStmt || kind == ParseNodeKind::ForStmt ||
          kind == ParseNodeKind::Function;
 }
 
 BytecodeEmitter::BytecodeSection::BytecodeSection(JSContext* cx)
     : code_(cx), notes_(cx), tryNoteList_(cx), scopeNoteList_(cx) {}
 
-BytecodeEmitter::PerScriptData::PerScriptData(JSContext* cx) : scopeList_(cx) {}
+BytecodeEmitter::PerScriptData::PerScriptData(JSContext* cx)
+    : scopeList_(cx), numberList_(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),
       perScriptData_(cx),
       currentLine_(lineNum),
       fieldInitializers_(fieldInitializers),
       atomIndices(cx->frontendCollectionPool()),
       firstLine(lineNum),
-      numberList(cx),
       resumeOffsetList(cx),
       emitterMode(emitterMode) {
   MOZ_ASSERT_IF(emitterMode == LazyFunction, lazyScript);
 
   if (sc->isFunctionBox()) {
     // Functions have IC entries for type monitoring |this| and arguments.
     numICEntries = sc->asFunctionBox()->function()->nargs() + 1;
   }
@@ -948,28 +948,28 @@ bool BytecodeEmitter::emitAtomOp(uint32_
 bool BytecodeEmitter::emitInternedScopeOp(uint32_t index, JSOp op) {
   MOZ_ASSERT(JOF_OPTYPE(op) == JOF_SCOPE);
   MOZ_ASSERT(index < perScriptData().scopeList().length());
   return emitIndex32(op, index);
 }
 
 bool BytecodeEmitter::emitInternedObjectOp(uint32_t index, JSOp op) {
   MOZ_ASSERT(JOF_OPTYPE(op) == JOF_OBJECT);
-  MOZ_ASSERT(index < objectList.length);
+  MOZ_ASSERT(index < perScriptData().objectList().length);
   return emitIndex32(op, index);
 }
 
 bool BytecodeEmitter::emitObjectOp(ObjectBox* objbox, JSOp op) {
-  return emitInternedObjectOp(objectList.add(objbox), op);
+  return emitInternedObjectOp(perScriptData().objectList().add(objbox), op);
 }
 
 bool BytecodeEmitter::emitObjectPairOp(ObjectBox* objbox1, ObjectBox* objbox2,
                                        JSOp op) {
-  uint32_t index = objectList.add(objbox1);
-  objectList.add(objbox2);
+  uint32_t index = perScriptData().objectList().add(objbox1);
+  perScriptData().objectList().add(objbox2);
   return emitInternedObjectOp(index, op);
 }
 
 bool BytecodeEmitter::emitRegExp(uint32_t index) {
   return emitIndex32(JSOP_REGEXP, index);
 }
 
 bool BytecodeEmitter::emitLocalOp(JSOp op, uint32_t slot) {
@@ -1718,17 +1718,17 @@ bool BytecodeEmitter::iteratorResultShap
     return false;
   }
 
   ObjectBox* objbox = parser->newObjectBox(obj);
   if (!objbox) {
     return false;
   }
 
-  *shape = objectList.add(objbox);
+  *shape = perScriptData().objectList().add(objbox);
 
   return true;
 }
 
 bool BytecodeEmitter::emitPrepareIteratorResult() {
   unsigned shape;
   if (!iteratorResultShape(&shape)) {
     return false;
@@ -4961,20 +4961,20 @@ bool BytecodeEmitter::emitCopyDataProper
     return false;
   }
 
   MOZ_ASSERT(depth - int(argc) == bytecodeSection().stackDepth());
   return true;
 }
 
 bool BytecodeEmitter::emitBigIntOp(BigInt* bigint) {
-  if (!numberList.append(BigIntValue(bigint))) {
-    return false;
-  }
-  return emitIndex32(JSOP_BIGINT, numberList.length() - 1);
+  if (!perScriptData().numberList().append(BigIntValue(bigint))) {
+    return false;
+  }
+  return emitIndex32(JSOP_BIGINT, perScriptData().numberList().length() - 1);
 }
 
 bool BytecodeEmitter::emitIterator() {
   // Convert iterable to iterator.
   if (!emit1(JSOP_DUP)) {
     //              [stack] OBJ OBJ
     return false;
   }
@@ -8185,17 +8185,17 @@ bool BytecodeEmitter::replaceNewInitWith
   if (!objbox) {
     return false;
   }
 
   static_assert(
       JSOP_NEWINIT_LENGTH == JSOP_NEWOBJECT_LENGTH,
       "newinit and newobject must have equal length to edit in-place");
 
-  uint32_t index = objectList.add(objbox);
+  uint32_t index = perScriptData().objectList().add(objbox);
   jsbytecode* code = bytecodeSection().code(offset);
 
   MOZ_ASSERT(code[0] == JSOP_NEWINIT);
   code[0] = JSOP_NEWOBJECT;
   SET_UINT32(code, index);
 
   return true;
 }
@@ -9236,17 +9236,18 @@ bool BytecodeEmitter::emitTree(
 
     case ParseNodeKind::BigIntExpr:
       if (!emitBigIntOp(pn->as<BigIntLiteral>().box()->value())) {
         return false;
       }
       break;
 
     case ParseNodeKind::RegExpExpr:
-      if (!emitRegExp(objectList.add(pn->as<RegExpLiteral>().objbox()))) {
+      if (!emitRegExp(perScriptData().objectList().add(
+              pn->as<RegExpLiteral>().objbox()))) {
         return false;
       }
       break;
 
     case ParseNodeKind::TrueExpr:
       if (!emit1(JSOP_TRUE)) {
         return false;
       }
--- a/js/src/frontend/BytecodeEmitter.h
+++ b/js/src/frontend/BytecodeEmitter.h
@@ -234,21 +234,37 @@ struct MOZ_STACK_CLASS BytecodeEmitter {
    public:
     explicit PerScriptData(JSContext* cx);
 
     // ---- Scope ----
 
     CGScopeList& scopeList() { return scopeList_; }
     const CGScopeList& scopeList() const { return scopeList_; }
 
+    // ---- Literals ----
+
+    CGNumberList& numberList() { return numberList_; }
+    const CGNumberList& numberList() const { return numberList_; }
+
+    CGObjectList& objectList() { return objectList_; }
+    const CGObjectList& objectList() const { return objectList_; }
+
    private:
     // ---- Scope ----
 
     // List of emitted scopes.
     CGScopeList scopeList_;
+
+    // ---- Literals ----
+
+    // List of double and bigint values used by script.
+    CGNumberList numberList_;
+
+    // List of emitted objects.
+    CGObjectList objectList_;
   };
 
   PerScriptData perScriptData_;
 
  public:
   PerScriptData& perScriptData() { return perScriptData_; }
   const PerScriptData& perScriptData() const { return perScriptData_; }
 
@@ -306,19 +322,16 @@ struct MOZ_STACK_CLASS BytecodeEmitter {
   EmitterScope* innermostEmitterScope() const {
     MOZ_ASSERT(!unstableEmitterScope);
     return innermostEmitterScopeNoCheck();
   }
   EmitterScope* innermostEmitterScopeNoCheck() const {
     return innermostEmitterScope_;
   }
 
-  CGNumberList numberList; /* double and bigint values used by script */
-  CGObjectList objectList; /* list of emitted objects */
-
   // Certain ops (yield, await, gosub) have an entry in the script's
   // resumeOffsets list. This can be used to map from the op's resumeIndex to
   // the bytecode offset of the next pc. This indirection makes it easy to
   // resume in the JIT (because BaselineScript stores a resumeIndex => native
   // code array).
   CGResumeOffsetList resumeOffsetList;
 
   // Number of JOF_IC opcodes emitted.
--- a/js/src/frontend/FunctionEmitter.cpp
+++ b/js/src/frontend/FunctionEmitter.cpp
@@ -215,17 +215,17 @@ bool FunctionEmitter::emitAsmJSModule() 
 #ifdef DEBUG
   state_ = State::End;
 #endif
   return true;
 }
 
 bool FunctionEmitter::emitFunction() {
   // Make the function object a literal in the outer script's pool.
-  unsigned index = bce_->objectList.add(funbox_);
+  unsigned index = bce_->perScriptData().objectList().add(funbox_);
 
   //                [stack]
 
   if (isHoisted_ == IsHoisted::No) {
     return emitNonHoisted(index);
     //              [stack] FUN?
   }
 
--- a/js/src/vm/JSScript.cpp
+++ b/js/src/vm/JSScript.cpp
@@ -3234,38 +3234,38 @@ PrivateScriptData* PrivateScriptData::ne
   // GCPtrs are put into a safe state.
   return new (raw) PrivateScriptData(nscopes, nconsts, nobjects, ntrynotes,
                                      nscopenotes, nresumeoffsets);
 }
 
 /* static */ bool PrivateScriptData::InitFromEmitter(
     JSContext* cx, js::HandleScript script, frontend::BytecodeEmitter* bce) {
   uint32_t nscopes = bce->perScriptData().scopeList().length();
-  uint32_t nconsts = bce->numberList.length();
-  uint32_t nobjects = bce->objectList.length;
+  uint32_t nconsts = bce->perScriptData().numberList().length();
+  uint32_t nobjects = bce->perScriptData().objectList().length;
   uint32_t ntrynotes = bce->bytecodeSection().tryNoteList().length();
   uint32_t nscopenotes = bce->bytecodeSection().scopeNoteList().length();
   uint32_t nresumeoffsets = bce->resumeOffsetList.length();
 
   // Create and initialize PrivateScriptData
   if (!JSScript::createPrivateScriptData(cx, script, nscopes, nconsts, nobjects,
                                          ntrynotes, nscopenotes,
                                          nresumeoffsets)) {
     return false;
   }
 
   js::PrivateScriptData* data = script->data_;
   if (nscopes) {
     bce->perScriptData().scopeList().finish(data->scopes());
   }
   if (nconsts) {
-    bce->numberList.finish(data->consts());
+    bce->perScriptData().numberList().finish(data->consts());
   }
   if (nobjects) {
-    bce->objectList.finish(data->objects());
+    bce->perScriptData().objectList().finish(data->objects());
   }
   if (ntrynotes) {
     bce->bytecodeSection().tryNoteList().finish(data->tryNotes());
   }
   if (nscopenotes) {
     bce->bytecodeSection().scopeNoteList().finish(data->scopeNotes());
   }
   if (nresumeoffsets) {
@@ -3561,17 +3561,17 @@ bool JSScript::fullyInitFromEmitter(JSCo
   // If initialization fails, we must call JSScript::freeScriptData in order to
   // neuter the script. Various things that iterate raw scripts in a GC arena
   // use the presense of this data to detect if initialization is complete.
   auto scriptDataGuard =
       mozilla::MakeScopeExit([&] { script->freeScriptData(); });
 
   /* The counts of indexed things must be checked during code generation. */
   MOZ_ASSERT(bce->atomIndices->count() <= INDEX_LIMIT);
-  MOZ_ASSERT(bce->objectList.length <= INDEX_LIMIT);
+  MOZ_ASSERT(bce->perScriptData().objectList().length <= INDEX_LIMIT);
 
   uint64_t nslots =
       bce->maxFixedSlots +
       static_cast<uint64_t>(bce->bytecodeSection().maxStackDepth());
   if (nslots > UINT32_MAX) {
     bce->reportError(nullptr, JSMSG_NEED_DIET, js_script_str);
     return false;
   }
@@ -3624,17 +3624,17 @@ bool JSScript::fullyInitFromEmitter(JSCo
     } else {
       fun->setScript(script);
     }
   }
 
   // Part of the parse result – the scope containing each inner function – must
   // be stored in the inner function itself. Do this now that compilation is
   // complete and can no longer fail.
-  bce->objectList.finishInnerFunctions();
+  bce->perScriptData().objectList().finishInnerFunctions();
 
 #ifdef JS_STRUCTURED_SPEW
   // We want this to happen after line number initialization to allow filtering
   // to work.
   script->setSpewEnabled(StructuredSpewer::enabled(script));
 #endif
 
 #ifdef DEBUG