Bug 1525924 - Part 9: Reorder steps of XDRScript r=jandem
authorTed Campbell <tcampbell@mozilla.com>
Mon, 11 Feb 2019 14:55:19 +0000
changeset 458547 df6a7d40a383def18671e1f81a0905594653d53b
parent 458546 634ba2074e16f0d105aee091502e634d15ff1c19
child 458548 5f4edb1fe66f3cc2794d5738bfe3805c39f798f3
push id111855
push userbtara@mozilla.com
push dateMon, 11 Feb 2019 22:01:49 +0000
treeherdermozilla-inbound@42a097167d36 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjandem
bugs1525924
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 1525924 - Part 9: Reorder steps of XDRScript r=jandem This makes XDRScript better follow the field layout of JSScript. Differential Revision: https://phabricator.services.mozilla.com/D19227
js/src/vm/JSScript.cpp
--- a/js/src/vm/JSScript.cpp
+++ b/js/src/vm/JSScript.cpp
@@ -743,32 +743,38 @@ template
 template <XDRMode mode>
 XDRResult js::XDRScript(XDRState<mode>* xdr, HandleScope scriptEnclosingScope,
                         HandleScriptSourceObject sourceObjectArg,
                         HandleFunction fun, MutableHandleScript scriptp) {
   using ImmutableFlags = JSScript::ImmutableFlags;
 
   /* NB: Keep this in sync with CopyScript. */
 
-  enum ScriptBits {
+  enum XDRScriptFlags {
     OwnSource,
     HasLazyScript,
   };
 
-  uint32_t lineno, column, nfixed, nslots;
-  uint32_t prologueLength;
-  uint32_t funLength = 0;
-  uint32_t numBytecodeTypeSets = 0;
-  uint32_t scriptBits = 0;
+  uint8_t xdrScriptFlags = 0;
+
+  uint32_t lineno = 0;
+  uint32_t column = 0;
+  uint32_t mainOffset = 0;
+  uint32_t nfixed = 0;
+  uint32_t nslots = 0;
   uint32_t bodyScopeIndex = 0;
-  uint32_t immutableFlags = 0;
   uint32_t sourceStart = 0;
   uint32_t sourceEnd = 0;
   uint32_t toStringStart = 0;
   uint32_t toStringEnd = 0;
+  uint32_t immutableFlags = 0;
+  uint16_t funLength = 0;
+  uint16_t numBytecodeTypeSets = 0;
+
+  // NOTE: |mutableFlags| are not preserved by XDR.
 
   JSContext* cx = xdr->cx();
   RootedScript script(cx);
 
   if (mode == XDR_ENCODE) {
     script = scriptp.get();
     MOZ_ASSERT(script->functionNonDelazifying() == fun);
 
@@ -779,80 +785,84 @@ XDRResult js::XDRScript(XDRState<mode>* 
       // cloning in JSOP_OBJECT or if we ever didn't clone in it in the
       // past.
       Realm* realm = cx->realm();
       if (!realm->creationOptions().cloneSingletons() ||
           !realm->behaviors().getSingletonsAsTemplates()) {
         return xdr->fail(JS::TranscodeResult_Failure_RunOnceNotSupported);
       }
     }
-  }
+
+    if (!sourceObjectArg) {
+      xdrScriptFlags |= (1 << OwnSource);
+    }
+    if (script->isRelazifiableIgnoringJitCode()) {
+      xdrScriptFlags |= (1 << HasLazyScript);
+    }
+  }
+
+  MOZ_TRY(xdr->codeUint8(&xdrScriptFlags));
 
   if (mode == XDR_ENCODE) {
-    prologueLength = script->mainOffset();
     lineno = script->lineno();
     column = script->column();
+    mainOffset = script->mainOffset();
     nfixed = script->nfixed();
     nslots = script->nslots();
-
     bodyScopeIndex = script->bodyScopeIndex();
 
-    immutableFlags = script->immutableFlags_;
-
     sourceStart = script->sourceStart();
     sourceEnd = script->sourceEnd();
     toStringStart = script->toStringStart();
     toStringEnd = script->toStringEnd();
 
-    numBytecodeTypeSets = script->numBytecodeTypeSets();
+    immutableFlags = script->immutableFlags_;
+
     funLength = script->funLength();
-
-    if (!sourceObjectArg) {
-      scriptBits |= (1 << OwnSource);
-    }
-    if (script->isRelazifiableIgnoringJitCode()) {
-      scriptBits |= (1 << HasLazyScript);
-    }
-  }
-
-  MOZ_TRY(xdr->codeUint32(&prologueLength));
-
-  MOZ_TRY(xdr->codeUint32(&numBytecodeTypeSets));
-  MOZ_TRY(xdr->codeUint32(&funLength));
-  MOZ_TRY(xdr->codeUint32(&scriptBits));
-  MOZ_TRY(xdr->codeUint32(&immutableFlags));
+    numBytecodeTypeSets = script->numBytecodeTypeSets();
+  }
+
+  MOZ_TRY(xdr->codeUint32(&lineno));
+  MOZ_TRY(xdr->codeUint32(&column));
+  MOZ_TRY(xdr->codeUint32(&mainOffset));
+  MOZ_TRY(xdr->codeUint32(&nfixed));
+  MOZ_TRY(xdr->codeUint32(&nslots));
+  MOZ_TRY(xdr->codeUint32(&bodyScopeIndex));
   MOZ_TRY(xdr->codeUint32(&sourceStart));
   MOZ_TRY(xdr->codeUint32(&sourceEnd));
   MOZ_TRY(xdr->codeUint32(&toStringStart));
   MOZ_TRY(xdr->codeUint32(&toStringEnd));
+  MOZ_TRY(xdr->codeUint32(&immutableFlags));
+  MOZ_TRY(xdr->codeUint16(&funLength));
+  MOZ_TRY(xdr->codeUint16(&numBytecodeTypeSets));
 
   RootedScriptSourceObject sourceObject(cx, sourceObjectArg);
   Maybe<CompileOptions> options;
 
   if (mode == XDR_DECODE) {
     // When loading from the bytecode cache, we get the CompileOptions from
     // the document. If the noScriptRval or selfHostingMode flag doesn't
     // match, we should fail. This only applies to the top-level and not
     // its inner functions.
     bool noScriptRval =
         !!(immutableFlags & uint32_t(ImmutableFlags::NoScriptRval));
     bool selfHosted = !!(immutableFlags & uint32_t(ImmutableFlags::SelfHosted));
-    if (xdr->hasOptions() && (scriptBits & (1 << OwnSource))) {
+    if (xdr->hasOptions() && (xdrScriptFlags & (1 << OwnSource))) {
       options.emplace(xdr->cx(), xdr->options());
       if (options->noScriptRval != noScriptRval ||
           options->selfHostingMode != selfHosted) {
         return xdr->fail(JS::TranscodeResult_Failure_WrongCompileOption);
       }
     } else {
       options.emplace(xdr->cx());
       (*options).setNoScriptRval(noScriptRval).setSelfHostingMode(selfHosted);
     }
   }
 
-  if (scriptBits & (1 << OwnSource)) {
+  if (xdrScriptFlags & (1 << OwnSource)) {
     Rooted<ScriptSourceHolder> ssHolder(cx);
 
     // We are relying on the script's ScriptSource so the caller should not
     // have passed in an explicit one.
     MOZ_ASSERT(sourceObjectArg == nullptr);
 
     if (mode == XDR_ENCODE) {
       sourceObject = script->sourceObject();
@@ -884,53 +894,39 @@ XDRResult js::XDRScript(XDRState<mode>* 
   }
 
   if (mode == XDR_DECODE) {
     script = JSScript::Create(cx, *options, sourceObject, sourceStart,
                               sourceEnd, toStringStart, toStringEnd);
     if (!script) {
       return xdr->fail(JS::TranscodeResult_Throw);
     }
+    scriptp.set(script);
+
+    script->lineno_ = lineno;
+    script->column_ = column;
+    script->mainOffset_ = mainOffset;
+    script->nfixed_ = nfixed;
+    script->nslots_ = nslots;
+    script->bodyScopeIndex_ = bodyScopeIndex;
+    script->immutableFlags_ = immutableFlags;
+    script->funLength_ = funLength;
+    script->numBytecodeTypeSets_ = numBytecodeTypeSets;
+
+    if (script->hasFlag(ImmutableFlags::ArgsHasVarBinding)) {
+      // Call setArgumentsHasVarBinding to initialize the
+      // NeedsArgsAnalysis flag.
+      script->setArgumentsHasVarBinding();
+    }
 
     // Set the script in its function now so that inner scripts to be
     // decoded may iterate the static scope chain.
     if (fun) {
       fun->initScript(script);
     }
-
-    MOZ_ASSERT(!script->mainOffset());
-    script->mainOffset_ = prologueLength;
-    script->funLength_ = funLength;
-
-    MOZ_ASSERT(numBytecodeTypeSets <= UINT16_MAX);
-    script->numBytecodeTypeSets_ = uint16_t(numBytecodeTypeSets);
-
-    scriptp.set(script);
-
-    script->immutableFlags_ = immutableFlags;
-
-    if (script->hasFlag(ImmutableFlags::ArgsHasVarBinding)) {
-      // Call setArgumentsHasVarBinding to initialize the
-      // NeedsArgsAnalysis flag.
-      script->setArgumentsHasVarBinding();
-    }
-  }
-
-  MOZ_TRY(xdr->codeUint32(&lineno));
-  MOZ_TRY(xdr->codeUint32(&column));
-  MOZ_TRY(xdr->codeUint32(&nfixed));
-  MOZ_TRY(xdr->codeUint32(&nslots));
-  MOZ_TRY(xdr->codeUint32(&bodyScopeIndex));
-
-  if (mode == XDR_DECODE) {
-    script->lineno_ = lineno;
-    script->column_ = column;
-    script->nfixed_ = nfixed;
-    script->nslots_ = nslots;
-    script->bodyScopeIndex_ = bodyScopeIndex;
   }
 
   // If XDR operation 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([&] {
     if (mode == XDR_DECODE) {
@@ -944,33 +940,31 @@ XDRResult js::XDRScript(XDRState<mode>* 
   MOZ_TRY(SharedScriptData::XDR<mode>(xdr, script));
 
   if (mode == XDR_DECODE) {
     if (!script->shareScriptData(cx)) {
       return xdr->fail(JS::TranscodeResult_Throw);
     }
   }
 
-  if (scriptBits & (1 << HasLazyScript)) {
+  if (xdrScriptFlags & (1 << HasLazyScript)) {
     Rooted<LazyScript*> lazy(cx);
     if (mode == XDR_ENCODE) {
       lazy = script->maybeLazyScript();
     }
 
     MOZ_TRY(
         XDRRelazificationInfo(xdr, fun, script, scriptEnclosingScope, &lazy));
 
     if (mode == XDR_DECODE) {
       script->setLazyScript(lazy);
     }
   }
 
   if (mode == XDR_DECODE) {
-    scriptp.set(script);
-
     /* see BytecodeEmitter::tellDebuggerAboutCompiledScript */
     if (!fun && !cx->helperThread()) {
       Debugger::onNewScript(cx, script);
     }
   }
 
   scriptDataGuard.release();
   return Ok();