author | Olli Pettay <Olli.Pettay@helsinki.fi> |
Thu, 07 Mar 2013 20:53:19 +0200 | |
changeset 124141 | c1ef9a062a881813022c38d51d66c71546a21dab |
parent 124140 | e0d9902b2bbfe9829cdd888b58f6fa7d4e0e1507 |
child 124142 | fed3eba78414639f448d9e1c02a60983f2c2daf1 |
push id | 24408 |
push user | ryanvm@gmail.com |
push date | Fri, 08 Mar 2013 04:58:11 +0000 |
treeherder | mozilla-central@cb432984d5ce [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | mccr8 |
bugs | 844313 |
milestone | 22.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
|
--- a/content/events/src/nsDOMEvent.cpp +++ b/content/events/src/nsDOMEvent.cpp @@ -17,16 +17,17 @@ #include "nsIContent.h" #include "nsIPresShell.h" #include "nsIDocument.h" #include "nsIInterfaceRequestor.h" #include "nsIInterfaceRequestorUtils.h" #include "nsGkAtoms.h" #include "nsMutationEvent.h" #include "nsContentUtils.h" +#include "nsJSEnvironment.h" #include "nsIURI.h" #include "nsIScriptSecurityManager.h" #include "nsIScriptError.h" #include "mozilla/Preferences.h" #include "nsJSUtils.h" #include "DictionaryHelpers.h" #include "nsLayoutUtils.h" #include "nsIScrollableFrame.h" @@ -71,16 +72,17 @@ nsDOMEvent::nsDOMEvent(nsPresContext* aP ... } */ mEvent = new nsEvent(false, 0); mEvent->time = PR_Now(); } InitPresContextData(aPresContext); + nsJSContext::LikelyShortLivingObjectCreated(); } void nsDOMEvent::InitPresContextData(nsPresContext* aPresContext) { mPresContext = aPresContext; // Get the explicit original target (if it's anonymous make it null) {
--- a/content/events/src/nsDOMTouchEvent.cpp +++ b/content/events/src/nsDOMTouchEvent.cpp @@ -133,16 +133,17 @@ nsDOMTouch::Equals(nsIDOMTouch* aTouch) (mRotationAngle != orientation) || (mRadius.x != radiusX) || (mRadius.y != radiusY); } // TouchList nsDOMTouchList::nsDOMTouchList(nsTArray<nsCOMPtr<nsIDOMTouch> > &aTouches) { mPoints.AppendElements(aTouches); + nsJSContext::LikelyShortLivingObjectCreated(); } DOMCI_DATA(TouchList, nsDOMTouchList) NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsDOMTouchList) NS_INTERFACE_MAP_ENTRY(nsISupports) NS_INTERFACE_MAP_ENTRY(nsIDOMTouchList) NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(TouchList)
--- a/content/events/src/nsDOMTouchEvent.h +++ b/content/events/src/nsDOMTouchEvent.h @@ -5,16 +5,17 @@ #ifndef nsDOMTouchEvent_h_ #define nsDOMTouchEvent_h_ #include "nsDOMUIEvent.h" #include "nsIDOMTouchEvent.h" #include "nsString.h" #include "nsTArray.h" #include "mozilla/Attributes.h" +#include "nsJSEnvironment.h" class nsDOMTouch MOZ_FINAL : public nsIDOMTouch { public: nsDOMTouch(nsIDOMEventTarget* aTarget, int32_t aIdentifier, int32_t aPageX, int32_t aPageY, @@ -36,16 +37,17 @@ public: mPointsInitialized = true; mRadius.x = aRadiusX; mRadius.y = aRadiusY; mRotationAngle = aRotationAngle; mForce = aForce; mChanged = false; mMessage = 0; + nsJSContext::LikelyShortLivingObjectCreated(); } nsDOMTouch(int32_t aIdentifier, nsIntPoint aPoint, nsIntPoint aRadius, float aRotationAngle, float aForce) { mIdentifier = aIdentifier; @@ -55,16 +57,17 @@ public: mRefPoint = aPoint; mPointsInitialized = false; mRadius = aRadius; mRotationAngle = aRotationAngle; mForce = aForce; mChanged = false; mMessage = 0; + nsJSContext::LikelyShortLivingObjectCreated(); } NS_DECL_CYCLE_COLLECTING_ISUPPORTS NS_DECL_CYCLE_COLLECTION_CLASS(nsDOMTouch) NS_DECL_NSIDOMTOUCH void InitializePoints(nsPresContext* aPresContext, nsEvent* aEvent) { if (mPointsInitialized) { return; @@ -99,17 +102,20 @@ protected: class nsDOMTouchList MOZ_FINAL : public nsIDOMTouchList { public: NS_DECL_CYCLE_COLLECTING_ISUPPORTS NS_DECL_CYCLE_COLLECTION_CLASS(nsDOMTouchList) NS_DECL_NSIDOMTOUCHLIST - nsDOMTouchList() { } + nsDOMTouchList() + { + nsJSContext::LikelyShortLivingObjectCreated(); + } nsDOMTouchList(nsTArray<nsCOMPtr<nsIDOMTouch> > &aTouches); void Append(nsIDOMTouch* aPoint) { mPoints.AppendElement(aPoint); } nsIDOMTouch* GetItemAt(uint32_t aIndex)
--- a/dom/base/nsJSEnvironment.cpp +++ b/dom/base/nsJSEnvironment.cpp @@ -159,16 +159,17 @@ static bool sHasRunGC; // have an easy place to know when a load ends or is interrupted in // all cases. This counter also gets reset if we end up GC'ing while // we're waiting for a slow page to load. IOW, this count may be 0 // even when there are pending loads. static uint32_t sPendingLoadCount; static bool sLoadingInProgress; static uint32_t sCCollectedWaitingForGC; +static uint32_t sLikelyShortLivingObjectsNeedingGC; static bool sPostGCEventsToConsole; static bool sPostGCEventsToObserver; static bool sDisableExplicitCompartmentGC; static uint32_t sCCTimerFireCount = 0; static uint32_t sMinForgetSkippableTime = UINT32_MAX; static uint32_t sMaxForgetSkippableTime = 0; static uint32_t sTotalForgetSkippableTime = 0; static uint32_t sRemovedPurples = 0; @@ -2766,17 +2767,18 @@ nsJSContext::CycleCollectNow(nsICycleCol // Prepare to actually run the CC. bool mergingCC = DoMergingCC(aForced); nsCycleCollectorResults ccResults; nsCycleCollector_collect(mergingCC, &ccResults, aListener); sCCollectedWaitingForGC += ccResults.mFreedRefCounted + ccResults.mFreedGCed; // If we collected a substantial amount of cycles, poke the GC since more objects // might be unreachable now. - if (sCCollectedWaitingForGC > 250) { + if (sCCollectedWaitingForGC > 250 || + sLikelyShortLivingObjectsNeedingGC > 2500) { PokeGC(JS::gcreason::CC_WAITING); } PRTime endCCTime = PR_Now(); // Log information about the CC via telemetry, JSON and the console. uint32_t ccNowDuration = TimeBetween(start, endCCTime); Telemetry::Accumulate(Telemetry::CYCLE_COLLECTOR_FINISH_IGC, finishedIGC); @@ -2805,24 +2807,25 @@ nsJSContext::CycleCollectNow(nsICycleCol } nsCString gcMsg; if (ccResults.mForcedGC) { gcMsg.AssignLiteral(", forced a GC"); } NS_NAMED_MULTILINE_LITERAL_STRING(kFmt, - NS_LL("CC(T+%.1f) duration: %lums, suspected: %lu, visited: %lu RCed and %lu%s GCed, collected: %lu RCed and %lu GCed (%lu waiting for GC)%s\n") + NS_LL("CC(T+%.1f) duration: %lums, suspected: %lu, visited: %lu RCed and %lu%s GCed, collected: %lu RCed and %lu GCed (%lu|%lu waiting for GC)%s\n") NS_LL("ForgetSkippable %lu times before CC, min: %lu ms, max: %lu ms, avg: %lu ms, total: %lu ms, sync: %lu ms, removed: %lu")); nsString msg; msg.Adopt(nsTextFormatter::smprintf(kFmt.get(), double(delta) / PR_USEC_PER_SEC, ccNowDuration, suspected, ccResults.mVisitedRefCounted, ccResults.mVisitedGCed, mergeMsg.get(), ccResults.mFreedRefCounted, ccResults.mFreedGCed, - sCCollectedWaitingForGC, gcMsg.get(), + sCCollectedWaitingForGC, sLikelyShortLivingObjectsNeedingGC, + gcMsg.get(), sForgetSkippableBeforeCC, minForgetSkippableTime / PR_USEC_PER_MSEC, sMaxForgetSkippableTime / PR_USEC_PER_MSEC, (sTotalForgetSkippableTime / cleanups) / PR_USEC_PER_MSEC, sTotalForgetSkippableTime / PR_USEC_PER_MSEC, skippableDuration, sRemovedPurples)); nsCOMPtr<nsIConsoleService> cs = @@ -2841,32 +2844,34 @@ nsJSContext::CycleCollectNow(nsICycleCol NS_LL("\"suspected\": %lu, ") NS_LL("\"visited\": { ") NS_LL("\"RCed\": %lu, ") NS_LL("\"GCed\": %lu }, ") NS_LL("\"collected\": { ") NS_LL("\"RCed\": %lu, ") NS_LL("\"GCed\": %lu }, ") NS_LL("\"waiting_for_gc\": %lu, ") + NS_LL("\"short_living_objects_waiting_for_gc\": %lu, ") NS_LL("\"forced_gc\": %d, ") NS_LL("\"forget_skippable\": { ") NS_LL("\"times_before_cc\": %lu, ") NS_LL("\"min\": %lu, ") NS_LL("\"max\": %lu, ") NS_LL("\"avg\": %lu, ") NS_LL("\"total\": %lu, ") NS_LL("\"removed\": %lu } ") NS_LL("}")); nsString json; json.Adopt(nsTextFormatter::smprintf(kJSONFmt.get(), endCCTime, ccNowDuration, gcDuration, skippableDuration, suspected, ccResults.mVisitedRefCounted, ccResults.mVisitedGCed, ccResults.mFreedRefCounted, ccResults.mFreedGCed, sCCollectedWaitingForGC, + sLikelyShortLivingObjectsNeedingGC, ccResults.mForcedGC, sForgetSkippableBeforeCC, minForgetSkippableTime / PR_USEC_PER_MSEC, sMaxForgetSkippableTime / PR_USEC_PER_MSEC, (sTotalForgetSkippableTime / cleanups) / PR_USEC_PER_MSEC, sTotalForgetSkippableTime / PR_USEC_PER_MSEC, sRemovedPurples)); @@ -3229,16 +3234,17 @@ DOMGCSliceCallback(JSRuntime *aRt, JS::G } } if (aProgress == JS::GC_CYCLE_END) { // May need to kill the inter-slice GC timer nsJSContext::KillInterSliceGCTimer(); sCCollectedWaitingForGC = 0; + sLikelyShortLivingObjectsNeedingGC = 0; sCleanupsSinceLastGC = 0; sNeedsFullCC = true; sHasRunGC = true; nsJSContext::MaybePokeCC(); if (aDesc.isCompartment_) { ++sCompartmentGCCount; if (!sFullGCTimer && !sShuttingDown) { @@ -3320,16 +3326,22 @@ nsJSContext::DropScriptObject(void* aScr void nsJSContext::ReportPendingException() { if (mIsInitialized) { nsJSUtils::ReportPendingException(mContext); } } +void +nsJSContext::LikelyShortLivingObjectCreated() +{ + ++sLikelyShortLivingObjectsNeedingGC; +} + /********************************************************************** * nsJSRuntime implementation *********************************************************************/ // QueryInterface implementation for nsJSRuntime NS_INTERFACE_MAP_BEGIN(nsJSRuntime) NS_INTERFACE_MAP_ENTRY(nsIScriptRuntime) NS_INTERFACE_MAP_END @@ -3355,16 +3367,17 @@ nsJSRuntime::Startup() sGCTimer = sFullGCTimer = sCCTimer = nullptr; sCCLockedOut = false; sCCLockedOutTime = 0; sLastCCEndTime = 0; sHasRunGC = false; sPendingLoadCount = 0; sLoadingInProgress = false; sCCollectedWaitingForGC = 0; + sLikelyShortLivingObjectsNeedingGC = 0; sPostGCEventsToConsole = false; sDisableExplicitCompartmentGC = false; sNeedsFullCC = false; gNameSpaceManager = nullptr; sRuntimeService = nullptr; sRuntime = nullptr; sIsInitialized = false; sDidShutdown = false;
--- a/dom/base/nsJSEnvironment.h +++ b/dom/base/nsJSEnvironment.h @@ -143,16 +143,19 @@ public: static void PokeShrinkGCBuffers(); static void KillShrinkGCBuffersTimer(); static void MaybePokeCC(); static void KillCCTimer(); static void KillFullGCTimer(); static void KillInterSliceGCTimer(); + // Calling LikelyShortLivingObjectCreated() makes a GC more likely. + static void LikelyShortLivingObjectCreated(); + virtual void GC(JS::gcreason::Reason aReason); static uint32_t CleanupsSinceLastGC(); nsIScriptGlobalObject* GetCachedGlobalObject() { // Verify that we have a global so that this // does always return a null when GetGlobalObject() is null.