Bug 1206594: Update SavedStacks sampling probability only when a Debugger changes its probability, not on every sample taken. r=fitzgen
authorJim Blandy <jimb@mozilla.com>
Wed, 16 Sep 2015 17:55:14 -0700
changeset 267006 08ad86045731a2668b20541ca7d388d5968a4371
parent 267005 09bde5536609afa6b9cd0af71245433f920b33b4
child 267007 2a4b512df31d589ff52000cd172be8eb8cf17851
push id29504
push usercbook@mozilla.com
push dateFri, 09 Oct 2015 09:43:23 +0000
treeherdermozilla-central@d01dd42e654b [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersfitzgen
bugs1206594
milestone44.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 1206594: Update SavedStacks sampling probability only when a Debugger changes its probability, not on every sample taken. r=fitzgen
js/src/vm/Debugger.cpp
js/src/vm/DebuggerMemory.cpp
js/src/vm/SavedStacks.cpp
--- a/js/src/vm/Debugger.cpp
+++ b/js/src/vm/Debugger.cpp
@@ -1730,17 +1730,17 @@ Debugger::logTenurePromotion(JSRuntime* 
         tenurePromotionsLogOverflowed = true;
     }
 }
 
 bool
 Debugger::appendAllocationSite(JSContext* cx, HandleObject obj, HandleSavedFrame frame,
                                double when)
 {
-    MOZ_ASSERT(trackingAllocationSites);
+    MOZ_ASSERT(trackingAllocationSites && enabled);
 
     AutoCompartment ac(cx, object);
     RootedObject wrappedFrame(cx, frame);
     if (!cx->compartment()->wrap(cx, &wrappedFrame))
         return false;
 
     RootedAtom ctorName(cx);
     {
@@ -2327,26 +2327,30 @@ Debugger::addAllocationsTracking(JSConte
 
     if (Debugger::cannotTrackAllocations(debuggee)) {
         JS_ReportErrorNumber(cx, GetErrorMessage, nullptr,
                              JSMSG_OBJECT_METADATA_CALLBACK_ALREADY_SET);
         return false;
     }
 
     debuggee.compartment()->setObjectMetadataCallback(SavedStacksMetadataCallback);
+    debuggee.compartment()->chooseAllocationSamplingProbability();
     return true;
 }
 
 /* static */ void
 Debugger::removeAllocationsTracking(GlobalObject& global)
 {
     // If there are still Debuggers that are observing allocations, we cannot
-    // remove the metadata callback yet.
-    if (isObservedByDebuggerTrackingAllocations(global))
+    // remove the metadata callback yet. Recompute the sampling probability
+    // based on the remaining debuggers' needs.
+    if (isObservedByDebuggerTrackingAllocations(global)) {
+        global.compartment()->chooseAllocationSamplingProbability();
         return;
+    }
 
     global.compartment()->forgetObjectMetadataCallback();
 }
 
 bool
 Debugger::addAllocationsTrackingForAllDebuggees(JSContext* cx)
 {
     MOZ_ASSERT(trackingAllocationSites);
--- a/js/src/vm/DebuggerMemory.cpp
+++ b/js/src/vm/DebuggerMemory.cpp
@@ -309,17 +309,26 @@ DebuggerMemory::setAllocationSamplingPro
 
     if (probability < 0.0 || probability > 1.0) {
         JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_UNEXPECTED_TYPE,
                              "(set allocationSamplingProbability)'s parameter",
                              "not a number between 0 and 1");
         return false;
     }
 
-    memory->getDebugger()->allocationSamplingProbability = probability;
+    Debugger* dbg = memory->getDebugger();
+    dbg->allocationSamplingProbability = probability;
+
+    // If this is a change any debuggees would observe, have all debuggee
+    // compartments recompute their sampling probabilities.
+    if (dbg->enabled && dbg->trackingAllocationSites) {
+        for (WeakGlobalObjectSet::Range r = dbg->debuggees.all(); !r.empty(); r.popFront())
+            r.front()->compartment()->chooseAllocationSamplingProbability();
+    }
+
     args.rval().setUndefined();
     return true;
 }
 
 /* static */ bool
 DebuggerMemory::getAllocationsLogOverflowed(JSContext* cx, unsigned argc, Value* vp)
 {
     THIS_DEBUGGER_MEMORY(cx, argc, vp, "(get allocationsLogOverflowed)", args, memory);
--- a/js/src/vm/SavedStacks.cpp
+++ b/js/src/vm/SavedStacks.cpp
@@ -1360,17 +1360,16 @@ SavedStacksMetadataCallback(JSContext* c
     RootedObject obj(cx, target);
 
     SavedStacks& stacks = cx->compartment()->savedStacks();
     if (stacks.allocationSkipCount > 0) {
         stacks.allocationSkipCount--;
         return nullptr;
     }
 
-    stacks.chooseSamplingProbability(cx->compartment());
     if (stacks.allocationSamplingProbability == 0.0)
         return nullptr;
 
     // If the sampling probability is set to 1.0, we are always taking a sample
     // and can therefore leave allocationSkipCount at 0.
     if (stacks.allocationSamplingProbability != 1.0) {
         // Rather than generating a random number on every allocation to decide
         // if we want to sample that particular allocation (which would be