Bug 1546620 - Add a numDebuggeeRealms counter to JSRuntime. r=jorendorff
authorJan de Mooij <jdemooij@mozilla.com>
Wed, 01 May 2019 08:07:31 +0000
changeset 472052 995c47d0986b486a6323ea87d32962ed634add41
parent 472051 e607a590c53cf628517629383acbdc922534f8a9
child 472053 732976d3f555a01d9032ede89a28121502ee49e2
push id35946
push userapavel@mozilla.com
push dateWed, 01 May 2019 15:54:31 +0000
treeherdermozilla-central@a027a998b8b7 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjorendorff
bugs1546620
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 1546620 - Add a numDebuggeeRealms counter to JSRuntime. r=jorendorff The Baseline Interpreter will use incrementNumDebuggeeRealms and decrementNumDebuggeeRealms to toggle some debugging things if needed. Differential Revision: https://phabricator.services.mozilla.com/D28636
js/src/vm/Realm.cpp
js/src/vm/Realm.h
js/src/vm/Runtime.cpp
js/src/vm/Runtime.h
--- a/js/src/vm/Realm.cpp
+++ b/js/src/vm/Realm.cpp
@@ -61,16 +61,20 @@ Realm::Realm(Compartment* comp, const JS
 Realm::~Realm() {
   MOZ_ASSERT(!hasBeenEnteredIgnoringJit());
 
   // Write the code coverage information in a file.
   if (coverage::IsLCovEnabled()) {
     runtime_->lcovOutput().writeLCovResult(lcovOutput);
   }
 
+  // We cannot have a debuggee realm here so we don't have to call
+  // runtime->decrementNumDebuggeeRealms().
+  MOZ_ASSERT(!isDebuggee());
+
   MOZ_ASSERT(runtime_->numRealms > 0);
   runtime_->numRealms--;
 }
 
 bool ObjectRealm::init(JSContext* cx) {
   NativeIteratorSentinel sentinel(NativeIterator::allocateSentinel(cx));
   if (!sentinel) {
     return false;
@@ -776,20 +780,28 @@ void Realm::updateDebuggerObservesFlag(u
       debugModeBits_ |= flag;
       return;
     }
   }
 
   debugModeBits_ &= ~flag;
 }
 
+void Realm::setIsDebuggee() {
+  if (!isDebuggee()) {
+    debugModeBits_ |= IsDebuggee;
+    runtimeFromMainThread()->incrementNumDebuggeeRealms();
+  }
+}
+
 void Realm::unsetIsDebuggee() {
   if (isDebuggee()) {
     debugModeBits_ &= ~DebuggerObservesMask;
     DebugEnvironments::onRealmUnsetIsDebuggee(this);
+    runtimeFromMainThread()->decrementNumDebuggeeRealms();
   }
 }
 
 void Realm::updateDebuggerObservesCoverage() {
   bool previousState = debuggerObservesCoverage();
   updateDebuggerObservesFlag(DebuggerObservesCoverage);
   if (previousState == debuggerObservesCoverage()) {
     return;
--- a/js/src/vm/Realm.h
+++ b/js/src/vm/Realm.h
@@ -706,17 +706,18 @@ class JS::Realm : public JS::shadow::Rea
   // Note that a debuggee frame may exist without its script being a
   // debuggee script. e.g., Debugger.Frame.prototype.eval only marks the
   // frame in which it is evaluating as a debuggee frame.
   //
 
   // True if this realm's global is a debuggee of some Debugger
   // object.
   bool isDebuggee() const { return !!(debugModeBits_ & IsDebuggee); }
-  void setIsDebuggee() { debugModeBits_ |= IsDebuggee; }
+
+  void setIsDebuggee();
   void unsetIsDebuggee();
 
   // True if this compartment's global is a debuggee of some Debugger
   // object with a live hook that observes all execution; e.g.,
   // onEnterFrame.
   bool debuggerObservesAllExecution() const {
     static const unsigned Mask = IsDebuggee | DebuggerObservesAllExecution;
     return (debugModeBits_ & Mask) == Mask;
--- a/js/src/vm/Runtime.cpp
+++ b/js/src/vm/Runtime.cpp
@@ -116,16 +116,17 @@ JSRuntime::JSRuntime(JSRuntime* parentRu
       windowProxyClass_(nullptr),
       scriptDataLock(mutexid::RuntimeScriptData),
 #ifdef DEBUG
       activeThreadHasScriptDataAccess(false),
 #endif
       numActiveHelperThreadZones(0),
       heapState_(JS::HeapState::Idle),
       numRealms(0),
+      numDebuggeeRealms_(0),
       localeCallbacks(nullptr),
       defaultLocale(nullptr),
       profilingScripts(false),
       scriptAndCountsVector(nullptr),
       lcovOutput_(),
       jitRuntime_(nullptr),
       selfHostingGlobal_(nullptr),
       gc(thisFromCtor()),
@@ -181,16 +182,19 @@ JSRuntime::~JSRuntime() {
 
   DebugOnly<size_t> oldCount = liveRuntimesCount--;
   MOZ_ASSERT(oldCount > 0);
 
   MOZ_ASSERT(wasmInstances.lock()->empty());
 
   MOZ_ASSERT(offThreadParsesRunning_ == 0);
   MOZ_ASSERT(!offThreadParsingBlocked_);
+
+  MOZ_ASSERT(numRealms == 0);
+  MOZ_ASSERT(numDebuggeeRealms_ == 0);
 }
 
 bool JSRuntime::init(JSContext* cx, uint32_t maxbytes,
                      uint32_t maxNurseryBytes) {
 #ifdef DEBUG
   MOZ_ASSERT(!initialized_);
   initialized_ = true;
 #endif
@@ -760,16 +764,26 @@ void JSRuntime::clearUsedByHelperThread(
   }
 
   JSContext* cx = mainContextFromOwnThread();
   if (gc.fullGCForAtomsRequested() && cx->canCollectAtoms()) {
     gc.triggerFullGCForAtoms(cx);
   }
 }
 
+void JSRuntime::incrementNumDebuggeeRealms() {
+  numDebuggeeRealms_++;
+  MOZ_ASSERT(numDebuggeeRealms_ <= numRealms);
+}
+
+void JSRuntime::decrementNumDebuggeeRealms() {
+  MOZ_ASSERT(numDebuggeeRealms_ > 0);
+  numDebuggeeRealms_--;
+}
+
 bool js::CurrentThreadCanAccessRuntime(const JSRuntime* rt) {
   return rt->mainContextFromAnyThread() == TlsContext.get();
 }
 
 bool js::CurrentThreadCanAccessZone(Zone* zone) {
   // Helper thread zones can only be used by their owning thread.
   if (zone->usedByHelperThread()) {
     return zone->ownedByCurrentHelperThread();
--- a/js/src/vm/Runtime.h
+++ b/js/src/vm/Runtime.h
@@ -517,16 +517,28 @@ struct JSRuntime : public js::MallocProv
 
   JS::HeapState heapState() const { return heapState_; }
 
   // How many realms there are across all zones. This number includes
   // off-thread context realms, so it isn't necessarily equal to the
   // number of realms visited by RealmsIter.
   js::MainThreadData<size_t> numRealms;
 
+ private:
+  // Number of debuggee realms in the runtime.
+  js::MainThreadData<size_t> numDebuggeeRealms_;
+
+ public:
+  void incrementNumDebuggeeRealms();
+  void decrementNumDebuggeeRealms();
+
+  size_t numDebuggeeRealms() const {
+    return numDebuggeeRealms_;
+  }
+
   /* Locale-specific callbacks for string conversion. */
   js::MainThreadData<const JSLocaleCallbacks*> localeCallbacks;
 
   /* Default locale for Internationalization API */
   js::MainThreadData<js::UniqueChars> defaultLocale;
 
   /* If true, new scripts must be created with PC counter information. */
   js::MainThreadOrIonCompileData<bool> profilingScripts;