Bug 1533003 - Add SharedScriptData::InitFromEmitter r=jandem
authorTed Campbell <tcampbell@mozilla.com>
Wed, 06 Mar 2019 18:09:27 +0000
changeset 520617 6da5f14c500507c525e9b7bc18bbdc4f2b924c84
parent 520616 e993e4a050b059ebb7dd022bd88b58534758ca44
child 520618 ba3dfc81120d01a3e931697d72e6bd95dad09582
push id10862
push userffxbld-merge
push dateMon, 11 Mar 2019 13:01:11 +0000
treeherdermozilla-beta@a2e7f5c935da [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjandem
bugs1533003
milestone67.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 1533003 - Add SharedScriptData::InitFromEmitter r=jandem Depends on D22321 Differential Revision: https://phabricator.services.mozilla.com/D22322
js/src/vm/JSScript.cpp
js/src/vm/JSScript.h
--- a/js/src/vm/JSScript.cpp
+++ b/js/src/vm/JSScript.cpp
@@ -3583,18 +3583,16 @@ bool JSScript::fullyInitFromEmitter(JSCo
 
   uint64_t nslots =
       bce->maxFixedSlots + static_cast<uint64_t>(bce->maxStackDepth);
   if (nslots > UINT32_MAX) {
     bce->reportError(nullptr, JSMSG_NEED_DIET, js_script_str);
     return false;
   }
 
-  uint32_t natoms = bce->atomIndices->count();
-
   // Initialize POD fields
   script->lineno_ = bce->firstLine;
   script->mainOffset_ = bce->mainOffset();
   script->nfixed_ = bce->maxFixedSlots;
   script->nslots_ = nslots;
   script->bodyScopeIndex_ = bce->bodyScopeIndex;
   script->numBytecodeTypeSets_ = bce->typesetCount;
 
@@ -3614,29 +3612,20 @@ bool JSScript::fullyInitFromEmitter(JSCo
   script->setFlag(ImmutableFlags::NeedsFunctionEnvironmentObjects,
                   NeedsFunctionEnvironmentObjects(bce));
 
   // Create and initialize PrivateScriptData
   if (!PrivateScriptData::InitFromEmitter(cx, script, bce)) {
     return false;
   }
 
-  // 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 nsrcnotes = bce->notes().length() + 1;
-  uint32_t codeLength = bce->code().length();
-  if (!script->createSharedScriptData(cx, codeLength, nsrcnotes, natoms)) {
+  // Create and initialize SharedScriptData
+  if (!SharedScriptData::InitFromEmitter(cx, script, bce)) {
     return false;
   }
-
-  jsbytecode* code = script->code();
-  PodCopy<jsbytecode>(code, bce->code().begin(), codeLength);
-  bce->copySrcNotes((jssrcnote*)(code + script->length()), nsrcnotes);
-  InitAtomMap(*bce->atomIndices, script->atoms());
-
   if (!script->shareScriptData(cx)) {
     return false;
   }
 
   // There shouldn't be any fallible operation after initFromFunctionBox,
   // JSFunction::hasUncompletedScript relies on the fact that the existence
   // of the pointer to JSScript means the pointed JSScript is complete.
   if (bce->sc->isFunctionBox()) {
@@ -4549,16 +4538,40 @@ bool JSScript::hasBreakpointsAt(jsbyteco
   BreakpointSite* site = getBreakpointSite(pc);
   if (!site) {
     return false;
   }
 
   return site->enabledCount > 0;
 }
 
+/* static */ bool SharedScriptData::InitFromEmitter(
+    JSContext* cx, js::HandleScript script, frontend::BytecodeEmitter* bce) {
+  uint32_t natoms = bce->atomIndices->count();
+  uint32_t codeLength = bce->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;
+
+  // Create and initialize SharedScriptData
+  if (!script->createSharedScriptData(cx, codeLength, noteLength, natoms)) {
+    return false;
+  }
+
+  js::SharedScriptData* data = script->scriptData_;
+
+  // Initialize trailing arrays
+  std::copy_n(bce->code().begin(), codeLength, data->code());
+  bce->copySrcNotes(data->notes(), noteLength);
+  InitAtomMap(*bce->atomIndices, data->atoms());
+
+  return true;
+}
+
 void SharedScriptData::traceChildren(JSTracer* trc) {
   MOZ_ASSERT(refCount() != 0);
   for (uint32_t i = 0; i < natoms(); ++i) {
     TraceNullableEdge(trc, &atoms()[i], "atom");
   }
 }
 
 void SharedScriptData::markForCrossZone(JSContext* cx) {
--- a/js/src/vm/JSScript.h
+++ b/js/src/vm/JSScript.h
@@ -1518,16 +1518,19 @@ class SharedScriptData {
   static constexpr size_t offsetOfNatoms() {
     return offsetof(SharedScriptData, natoms_);
   }
 
   template <XDRMode mode>
   static MOZ_MUST_USE XDRResult XDR(js::XDRState<mode>* xdr,
                                     js::HandleScript script);
 
+  static bool InitFromEmitter(JSContext* cx, js::HandleScript script,
+                              js::frontend::BytecodeEmitter* bce);
+
   // Mark this SharedScriptData for use in a new zone
   void markForCrossZone(JSContext* cx);
 
  private:
   SharedScriptData() = delete;
   SharedScriptData(const SharedScriptData&) = delete;
   SharedScriptData& operator=(const SharedScriptData&) = delete;
 };
@@ -1852,16 +1855,20 @@ class JSScript : public js::gc::TenuredC
                                      js::HandleScriptSourceObject sourceObject,
                                      js::HandleFunction fun,
                                      js::MutableHandleScript scriptp);
 
   template <js::XDRMode mode>
   friend js::XDRResult js::SharedScriptData::XDR(js::XDRState<mode>* xdr,
                                                  js::HandleScript script);
 
+  friend bool js::SharedScriptData::InitFromEmitter(
+      JSContext* cx, js::HandleScript script,
+      js::frontend::BytecodeEmitter* bce);
+
   template <js::XDRMode mode>
   friend js::XDRResult js::PrivateScriptData::XDR(
       js::XDRState<mode>* xdr, js::HandleScript script,
       js::HandleScriptSourceObject sourceObject,
       js::HandleScope scriptEnclosingScope, js::HandleFunction fun);
 
   friend bool js::PrivateScriptData::Clone(
       JSContext* cx, js::HandleScript src, js::HandleScript dst,