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 288177 08ad86045731a2668b20541ca7d388d5968a4371
parent 288176 09bde5536609afa6b9cd0af71245433f920b33b4
child 288178 2a4b512df31d589ff52000cd172be8eb8cf17851
push id8654
push userraliiev@mozilla.com
push dateThu, 29 Oct 2015 11:48:40 +0000
treeherdermozilla-aurora@bc4551debe17 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersfitzgen
bugs1206594
milestone44.0a1
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