Bug 1585372 - Run InitScriptCoverage after initialization. r=jandem,nbp
authorTed Campbell <tcampbell@mozilla.com>
Mon, 04 Nov 2019 20:21:28 +0000
changeset 500453 b3a76c2b11b343f6170ccb599d1af7d8cfd06858
parent 500452 821b104d357b899ba03415a82066e96db6aa269b
child 500454 dfd48b94b7456751af03213a57625faa335da1dc
push id114164
push useraiakab@mozilla.com
push dateTue, 05 Nov 2019 10:06:15 +0000
treeherdermozilla-inbound@4d585c7edc76 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjandem, nbp
bugs1585372
milestone72.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 1585372 - Run InitScriptCoverage after initialization. r=jandem,nbp To allow InitScriptCoverage to be more flexible, we need to delay the call until the JSScript is actually initialized. This moves the calls from JSScript constructor until the JSScript is actually initialized. This is similar to the debugger onNewScript call, but more cleanup would be needed to unify these. Differential Revision: https://phabricator.services.mozilla.com/D51473
js/src/vm/CodeCoverage.cpp
js/src/vm/JSScript.cpp
--- a/js/src/vm/CodeCoverage.cpp
+++ b/js/src/vm/CodeCoverage.cpp
@@ -681,16 +681,18 @@ void LCovRuntime::writeLCovResult(LCovRe
 
   realm.exportInto(out_, &isEmpty_);
   out_.flush();
   finishFile();
 }
 
 bool InitScriptCoverage(JSContext* cx, JSScript* script) {
   MOZ_ASSERT(IsLCovEnabled());
+  MOZ_ASSERT(!script->isUncompleted(),
+             "Only initialize coverage data for fully initialized scripts.");
 
   // Don't allocate LCovSource if we on helper thread since we will have our
   // realm migrated. The 'GCRunime::mergeRealms' code will do this
   // initialization.
   if (cx->isHelperThreadContext()) {
     return true;
   }
 
--- a/js/src/vm/JSScript.cpp
+++ b/js/src/vm/JSScript.cpp
@@ -1200,16 +1200,22 @@ XDRResult js::XDRScript(XDRState<mode>* 
         XDRRelazificationInfo(xdr, fun, script, scriptEnclosingScope, &lazy));
 
     if (mode == XDR_DECODE) {
       script->setLazyScript(lazy);
     }
   }
 
   if (mode == XDR_DECODE) {
+    if (coverage::IsLCovEnabled()) {
+      if (!coverage::InitScriptCoverage(cx, script)) {
+        return xdr->fail(JS::TranscodeResult_Throw);
+      }
+    }
+
     /* see BytecodeEmitter::tellDebuggerAboutCompiledScript */
     if (!fun && !cx->isHelperThreadContext()) {
       DebugAPI::onNewScript(cx, script);
     }
   }
 
   MOZ_ASSERT(script->code(), "Where's our bytecode?");
   scriptDataGuard.release();
@@ -3927,22 +3933,16 @@ JSScript* JSScript::Create(JSContext* cx
   script->setFlag(ImmutableFlags::SelfHosted, options.selfHostingMode);
   script->setFlag(ImmutableFlags::TreatAsRunOnce, options.isRunOnce);
   script->setFlag(MutableFlags::HideScriptFromDebugger,
                   options.hideScriptFromDebugger);
 
   script->setFlag(MutableFlags::TrackRecordReplayProgress,
                   ShouldTrackRecordReplayProgress(script));
 
-  if (coverage::IsLCovEnabled()) {
-    if (!coverage::InitScriptCoverage(cx, script)) {
-      return nullptr;
-    }
-  }
-
   return script;
 }
 
 /* static */ JSScript* JSScript::CreateFromLazy(JSContext* cx,
                                                 Handle<LazyScript*> lazy) {
   RootedScriptSourceObject sourceObject(cx, lazy->sourceObject());
   RootedObject fun(cx, lazy->function());
   RootedScript script(cx,
@@ -3951,22 +3951,16 @@ JSScript* JSScript::Create(JSContext* cx
                                     lazy->toStringEnd()));
   if (!script) {
     return nullptr;
   }
 
   script->setFlag(MutableFlags::TrackRecordReplayProgress,
                   ShouldTrackRecordReplayProgress(script));
 
-  if (coverage::IsLCovEnabled()) {
-    if (!coverage::InitScriptCoverage(cx, script)) {
-      return nullptr;
-    }
-  }
-
   return script;
 }
 
 #ifdef MOZ_VTUNE
 uint32_t JSScript::vtuneMethodID() {
   if (!zone()->scriptVTuneIdMap) {
     auto map = MakeUnique<ScriptVTuneIdMap>();
     if (!map) {
@@ -4147,16 +4141,22 @@ bool JSScript::fullyInitFromEmitter(JSCo
   // to work.
   script->setSpewEnabled(cx->spewer().enabled(script));
 #endif
 
 #ifdef DEBUG
   script->assertValidJumpTargets();
 #endif
 
+  if (coverage::IsLCovEnabled()) {
+    if (!coverage::InitScriptCoverage(cx, script)) {
+      return false;
+    }
+  }
+
   scriptDataGuard.release();
   return true;
 }
 
 #ifdef DEBUG
 void JSScript::assertValidJumpTargets() const {
   BytecodeLocation mainLoc = mainLocation();
   BytecodeLocation endLoc = endLocation();
@@ -4739,17 +4739,29 @@ JSScript* js::CloneGlobalScript(JSContex
   Rooted<GCVector<Scope*>> scopes(cx, GCVector<Scope*>(cx));
   Rooted<GlobalScope*> original(cx, &src->bodyScope()->as<GlobalScope>());
   GlobalScope* clone = GlobalScope::clone(cx, original, scopeKind);
   if (!clone || !scopes.append(clone)) {
     return nullptr;
   }
 
   RootedObject global(cx, cx->global());
-  return detail::CopyScript(cx, src, global, sourceObject, &scopes);
+  RootedScript dst(cx,
+                   detail::CopyScript(cx, src, global, sourceObject, &scopes));
+  if (!dst) {
+    return nullptr;
+  }
+
+  if (coverage::IsLCovEnabled()) {
+    if (!coverage::InitScriptCoverage(cx, dst)) {
+      return nullptr;
+    }
+  }
+
+  return dst;
 }
 
 JSScript* js::CloneScriptIntoFunction(
     JSContext* cx, HandleScope enclosingScope, HandleFunction fun,
     HandleScript src, Handle<ScriptSourceObject*> sourceObject) {
   MOZ_ASSERT(fun->isInterpreted());
   MOZ_ASSERT(!fun->hasScript() || fun->hasUncompletedScript());
 
@@ -4790,16 +4802,22 @@ JSScript* js::CloneScriptIntoFunction(
 
   // Finally set the script after all the fallible operations.
   if (fun->isInterpretedLazy()) {
     fun->setUnlazifiedScript(dst);
   } else {
     fun->initScript(dst);
   }
 
+  if (coverage::IsLCovEnabled()) {
+    if (!coverage::InitScriptCoverage(cx, dst)) {
+      return nullptr;
+    }
+  }
+
   return dst;
 }
 
 /* static */ bool ImmutableScriptData::InitFromEmitter(
     JSContext* cx, js::HandleScript script, frontend::BytecodeEmitter* bce,
     uint32_t nslots) {
   size_t codeLength = bce->bytecodeSection().code().length();
   MOZ_RELEASE_ASSERT(codeLength <= frontend::MaxBytecodeLength);