From 5faf21e36b9e04bb27ebb76feb146c451eb30687 Mon Sep 17 00:00:00 2001 From: "Olli.Pettay@helsinki.fi" Date: Sat, 29 Sep 2007 10:33:22 -0700 Subject: [PATCH] back out Bug 373462 / bug 385322 (again :( ) --- content/base/src/nsXMLHttpRequest.cpp | 3 - content/events/src/nsEventStateManager.cpp | 75 --------- dom/src/base/nsJSEnvironment.cpp | 183 ++------------------- dom/src/base/nsJSEnvironment.h | 23 +-- layout/base/nsDocumentViewer.cpp | 2 +- xpcom/base/nsCycleCollector.cpp | 18 +- xpcom/base/nsCycleCollector.h | 3 +- 7 files changed, 22 insertions(+), 285 deletions(-) diff --git a/content/base/src/nsXMLHttpRequest.cpp b/content/base/src/nsXMLHttpRequest.cpp index 40e3c9dca96..01a99f5a759 100644 --- a/content/base/src/nsXMLHttpRequest.cpp +++ b/content/base/src/nsXMLHttpRequest.cpp @@ -56,7 +56,6 @@ #include "prprf.h" #include "nsIDOMEventListener.h" #include "nsIJSContextStack.h" -#include "nsJSEnvironment.h" #include "nsIScriptSecurityManager.h" #include "nsWeakPtr.h" #include "nsICharsetAlias.h" @@ -1777,7 +1776,6 @@ nsXMLHttpRequest::RequestCompleted() ChangeState(XML_HTTP_REQUEST_OPENED); } - nsJSContext::MaybeCC(PR_FALSE); return rv; } @@ -2320,7 +2318,6 @@ nsXMLHttpRequest::Error(nsIDOMEvent* aEvent) NotifyEventListeners(errorEventListeners, event); } - nsJSContext::MaybeCC(PR_FALSE); return NS_OK; } diff --git a/content/events/src/nsEventStateManager.cpp b/content/events/src/nsEventStateManager.cpp index 83fa7a29de5..2cd1b14bcb5 100644 --- a/content/events/src/nsEventStateManager.cpp +++ b/content/events/src/nsEventStateManager.cpp @@ -136,9 +136,6 @@ #include "nsEventDispatcher.h" #include "nsPresShellIterator.h" -#include "nsServiceManagerUtils.h" -#include "nsITimer.h" - #ifdef XP_MACOSX #include #endif @@ -147,8 +144,6 @@ //#define DEBUG_DOCSHELL_FOCUS #endif -#define NS_USER_INTERACTION_INTERVAL 5000 // ms - static NS_DEFINE_CID(kFrameTraversalCID, NS_FRAMETRAVERSAL_CID); @@ -176,41 +171,6 @@ static PRUint32 sESMInstanceCount = 0; static PRInt32 sChromeAccessModifier = 0, sContentAccessModifier = 0; PRInt32 nsEventStateManager::sUserInputEventDepth = 0; -static PRUint32 gMouseOrKeyboardEventCounter = 0; -static nsITimer* gUserInteractionTimer = nsnull; -static nsITimerCallback* gUserInteractionTimerCallback = nsnull; - -class nsUITimerCallback : public nsITimerCallback -{ -public: - nsUITimerCallback() : mPreviousCount(0) {} - NS_DECL_ISUPPORTS - NS_DECL_NSITIMERCALLBACK -private: - PRUint32 mPreviousCount; -}; - -NS_IMPL_ISUPPORTS1(nsUITimerCallback, nsITimerCallback) - -// If aTimer is nsnull, this method always sends "user-interaction-inactive" -// notification. -NS_IMETHODIMP -nsUITimerCallback::Notify(nsITimer* aTimer) -{ - nsresult rv; - nsCOMPtr obs = - do_GetService("@mozilla.org/observer-service;1", &rv); - NS_ENSURE_SUCCESS(rv, rv); - if ((gMouseOrKeyboardEventCounter == mPreviousCount) || !aTimer) { - gMouseOrKeyboardEventCounter = 0; - obs->NotifyObservers(nsnull, "user-interaction-inactive", nsnull); - } else { - obs->NotifyObservers(nsnull, "user-interaction-active", nsnull); - } - mPreviousCount = gMouseOrKeyboardEventCounter; - return NS_OK; -} - enum { MOUSE_SCROLL_N_LINES, MOUSE_SCROLL_PAGE, @@ -471,18 +431,6 @@ nsEventStateManager::nsEventStateManager() mTabbedThroughDocument(PR_FALSE), mAccessKeys(nsnull) { - if (sESMInstanceCount == 0) { - gUserInteractionTimerCallback = new nsUITimerCallback(); - if (gUserInteractionTimerCallback) { - NS_ADDREF(gUserInteractionTimerCallback); - CallCreateInstance("@mozilla.org/timer;1", &gUserInteractionTimer); - if (gUserInteractionTimer) { - gUserInteractionTimer->InitWithCallback(gUserInteractionTimerCallback, - NS_USER_INTERACTION_INTERVAL, - nsITimer::TYPE_REPEATING_SLACK); - } - } - } ++sESMInstanceCount; } @@ -561,14 +509,6 @@ nsEventStateManager::~nsEventStateManager() if(sESMInstanceCount == 0) { NS_IF_RELEASE(gLastFocusedContent); NS_IF_RELEASE(gLastFocusedDocument); - if (gUserInteractionTimerCallback) { - gUserInteractionTimerCallback->Notify(nsnull); - NS_RELEASE(gUserInteractionTimerCallback); - } - if (gUserInteractionTimer) { - gUserInteractionTimer->Cancel(); - NS_RELEASE(gUserInteractionTimer); - } } delete mAccessKeys; @@ -784,21 +724,6 @@ nsEventStateManager::PreHandleEvent(nsPresContext* aPresContext, if (!mCurrentTarget) return NS_ERROR_NULL_POINTER; } - if (NS_IS_TRUSTED_EVENT(aEvent) && - ((aEvent->eventStructType == NS_MOUSE_EVENT && - static_cast(aEvent)->reason == nsMouseEvent::eReal) || - aEvent->eventStructType == NS_MOUSE_SCROLL_EVENT || - aEvent->eventStructType == NS_KEY_EVENT)) { - if (gMouseOrKeyboardEventCounter == 0) { - nsCOMPtr obs = - do_GetService("@mozilla.org/observer-service;1"); - if (obs) { - obs->NotifyObservers(nsnull, "user-interaction-active", nsnull); - } - } - ++gMouseOrKeyboardEventCounter; - } - *aStatus = nsEventStatus_eIgnore; nsMouseWheelTransaction::OnEvent(aEvent); diff --git a/dom/src/base/nsJSEnvironment.cpp b/dom/src/base/nsJSEnvironment.cpp index bcef36f03a9..db881ffc935 100644 --- a/dom/src/base/nsJSEnvironment.cpp +++ b/dom/src/base/nsJSEnvironment.cpp @@ -154,26 +154,8 @@ static PRLogModuleInfo* gJSDiagnostics; #define JAVASCRIPT nsIProgrammingLanguage::JAVASCRIPT -// The max number of delayed cycle collects.. -#define NS_MAX_DELAYED_CCOLLECT 45 -// The max number of user interaction notifications in inactive state before -// we try to call cycle collector more aggressively. -#define NS_CC_SOFT_LIMIT_INACTIVE 6 -// The max number of user interaction notifications in active state before -// we try to call cycle collector more aggressively. -#define NS_CC_SOFT_LIMIT_ACTIVE 12 -// When higher probability MaybeCC is used, the number of sDelayedCCollectCount -// is multiplied with this number. -#define NS_PROBABILITY_MULTIPLIER 3 -// Cycle collector should never run more often than this value -#define NS_MIN_CC_INTERVAL 5000 // ms - // if you add statics here, add them to the list in nsJSRuntime::Startup -static PRUint32 sDelayedCCollectCount; -static PRUint32 sCCollectCount; -static PRTime sPreviousCCTime; -static PRBool sPreviousCCDidCollect; static nsITimer *sGCTimer; static PRBool sReadyForGC; @@ -217,75 +199,6 @@ static nsICollation *gCollation; static nsIUnicodeDecoder *gDecoder; -// nsUserActivityObserver observes user-interaction-active and -// user-interaction-inactive notifications. It counts the number of -// notifications and if the number is bigger than NS_CC_SOFT_LIMIT_ACTIVE -// (in case the current notification is user-interaction-active) or -// NS_CC_SOFT_LIMIT_INACTIVE (current notification is user-interaction-inactive) -// MaybeCC is called with aHigherParameter set to PR_TRUE, otherwise PR_FALSE. -// -// When moving from active state to inactive, nsJSContext::CC() is called -// unless the timer related to page load is active. - -class nsUserActivityObserver : public nsIObserver -{ -public: - nsUserActivityObserver() - : mUserActivityCounter(0), mOldCCollectCount(0), mUserIsActive(PR_FALSE) {} - NS_DECL_ISUPPORTS - NS_DECL_NSIOBSERVER -private: - PRUint32 mUserActivityCounter; - PRUint32 mOldCCollectCount; - PRBool mUserIsActive; -}; - -NS_IMPL_ISUPPORTS1(nsUserActivityObserver, nsIObserver) - -NS_IMETHODIMP -nsUserActivityObserver::Observe(nsISupports* aSubject, const char* aTopic, - const PRUnichar* aData) -{ - if (mOldCCollectCount != sCCollectCount) { - mOldCCollectCount = sCCollectCount; - // Cycle collector was called between user interaction notifications, so - // we can reset the counter. - mUserActivityCounter = 0; - } - PRBool higherProbability = PR_FALSE; - ++mUserActivityCounter; - if (!strcmp(aTopic, "user-interaction-inactive")) { -#ifdef DEBUG_smaug - printf("user-interaction-inactive\n"); -#endif - if (mUserIsActive) { - mUserIsActive = PR_FALSE; - if (!sGCTimer) { - nsJSContext::CC(); - return NS_OK; - } - } - higherProbability = (mUserActivityCounter > NS_CC_SOFT_LIMIT_INACTIVE); - } else if (!strcmp(aTopic, "user-interaction-active")) { -#ifdef DEBUG_smaug - printf("user-interaction-active\n"); -#endif - mUserIsActive = PR_TRUE; - higherProbability = (mUserActivityCounter > NS_CC_SOFT_LIMIT_ACTIVE); - } else if (!strcmp(aTopic, "xpcom-shutdown")) { - nsCOMPtr obs = - do_GetService("@mozilla.org/observer-service;1"); - if (obs) { - obs->RemoveObserver(this, "user-interaction-active"); - obs->RemoveObserver(this, "user-interaction-inactive"); - obs->RemoveObserver(this, "xpcom-shutdown"); - } - return NS_OK; - } - nsJSContext::MaybeCC(higherProbability); - return NS_OK; -} - /**************************************************************** ************************** AutoFree **************************** ****************************************************************/ @@ -3307,73 +3220,6 @@ nsJSContext::PreserveWrapper(nsIXPConnectWrappedNative *aWrapper) return nsDOMClassInfo::PreserveNodeWrapper(aWrapper); } -//static -void -nsJSContext::MaybeCCOrGC(nsIScriptContext* aContext) -{ - if (!nsJSContext::MaybeCC(PR_TRUE)) { - nsCOMPtr context = aContext; - if (context) { - JSContext* cx = static_cast(context->GetNativeContext()); - if (cx) { -#ifdef DEBUG_smaug - printf("Will call JS_GC\n"); -#endif - ::JS_GC(cx); -#ifdef DEBUG_smaug - printf("Did call JS_GC\n"); -#endif - } - } - } -} - -//static -void -nsJSContext::CC() -{ - sPreviousCCTime = PR_Now(); - sDelayedCCollectCount = 0; - ++sCCollectCount; -#ifdef DEBUG_smaug - printf("Will run cycle collector (%i)\n", sCCollectCount); -#endif - // nsCycleCollector_collect() will run a ::JS_GC() indirectly, so - // we do not explicitly call ::JS_GC() here. - sPreviousCCDidCollect = nsCycleCollector_collect(); -#ifdef DEBUG_smaug - printf("%s\n", sPreviousCCDidCollect ? - "Cycle collector did collect nodes" : - "Cycle collector did not collect nodes"); -#endif -} - -//static -PRBool -nsJSContext::MaybeCC(PRBool aHigherProbability) -{ - ++sDelayedCCollectCount; - // Increase the probability also if the previous call to cycle collector - // collected something. - if (aHigherProbability || sPreviousCCDidCollect) { - sDelayedCCollectCount *= NS_PROBABILITY_MULTIPLIER; - } - - if (!sGCTimer && (sDelayedCCollectCount > NS_MAX_DELAYED_CCOLLECT)) { - if ((PR_Now() - sPreviousCCTime) >= - PRTime(NS_MIN_CC_INTERVAL * PR_USEC_PER_MSEC)) { - nsJSContext::CC(); - return PR_TRUE; - } -#ifdef DEBUG_smaug - else { - printf("Running cycle collector was delayed: NS_MIN_CC_INTERVAL\n"); - } -#endif - } - return PR_FALSE; -} - NS_IMETHODIMP nsJSContext::Notify(nsITimer *timer) { @@ -3392,7 +3238,9 @@ nsJSContext::Notify(nsITimer *timer) // loading and move on as if they weren't. sPendingLoadCount = 0; - MaybeCCOrGC(this); + // nsCycleCollector_collect() will run a ::JS_GC() indirectly, + // so we do not explicitly call ::JS_GC() here. + nsCycleCollector_collect(); } else { FireGCTimer(PR_TRUE); } @@ -3411,7 +3259,7 @@ nsJSContext::LoadStart() // static void -nsJSContext::LoadEnd(nsIScriptGlobalObject* aGlobalObject) +nsJSContext::LoadEnd() { // sPendingLoadCount is not a well managed load counter (and doesn't // need to be), so make sure we don't make it wrap backwards here. @@ -3421,10 +3269,13 @@ nsJSContext::LoadEnd(nsIScriptGlobalObject* aGlobalObject) if (!sPendingLoadCount && sLoadInProgressGCTimer) { sGCTimer->Cancel(); + NS_RELEASE(sGCTimer); sLoadInProgressGCTimer = PR_FALSE; - MaybeCCOrGC(aGlobalObject ? aGlobalObject->GetContext() : nsnull); + // nsCycleCollector_collect() will run a ::JS_GC() indirectly, so + // we do not explicitly call ::JS_GC() here. + nsCycleCollector_collect(); } } @@ -3451,7 +3302,10 @@ nsJSContext::FireGCTimer(PRBool aLoadInProgress) // timer. sLoadInProgressGCTimer = PR_FALSE; - MaybeCCOrGC(this); + // nsCycleCollector_collect() will run a ::JS_GC() indirectly, so + // we do not explicitly call ::JS_GC() here. + nsCycleCollector_collect(); + return; } @@ -3559,10 +3413,6 @@ void nsJSRuntime::Startup() { // initialize all our statics, so that we can restart XPCOM - sDelayedCCollectCount = 0; - sCCollectCount = 0; - sPreviousCCTime = 0; - sPreviousCCDidCollect = PR_FALSE; sGCTimer = nsnull; sReadyForGC = PR_FALSE; sLoadInProgressGCTimer = PR_FALSE; @@ -3697,15 +3547,6 @@ nsJSRuntime::Init() MaxScriptRunTimePrefChangedCallback("dom.max_chrome_script_run_time", nsnull); - nsCOMPtr obs = - do_GetService("@mozilla.org/observer-service;1", &rv); - NS_ENSURE_SUCCESS(rv, rv); - nsIObserver* activityObserver = new nsUserActivityObserver(); - NS_ENSURE_TRUE(activityObserver, NS_ERROR_OUT_OF_MEMORY); - obs->AddObserver(activityObserver, "user-interaction-inactive", PR_FALSE); - obs->AddObserver(activityObserver, "user-interaction-active", PR_FALSE); - obs->AddObserver(activityObserver, "xpcom-shutdown", PR_FALSE); - rv = CallGetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &sSecurityManager); sIsInitialized = NS_SUCCEEDED(rv); diff --git a/dom/src/base/nsJSEnvironment.h b/dom/src/base/nsJSEnvironment.h index e074b303fe3..01d0187f8da 100644 --- a/dom/src/base/nsJSEnvironment.h +++ b/dom/src/base/nsJSEnvironment.h @@ -168,26 +168,7 @@ public: NS_DECL_NSITIMERCALLBACK static void LoadStart(); - static void LoadEnd(nsIScriptGlobalObject* aGlobalObject); - - // CC does always call cycle collector and it also updates the counters - // that MaybeCC uses. - static void CC(); - - // MaybeCC calls cycle collector if certain conditions are fulfilled. - // The conditions are: - // - The timer related to page load (sGCTimer) must not be active. - // - At least NS_MIN_CC_INTERVAL milliseconds must have elapsed since the - // previous cycle collector call. - // - Certain number of MaybeCC calls have occurred. - // The number of needed MaybeCC calls depends on the aHigherProbability - // parameter. If the parameter is true, probability for calling cycle - // collector rises increasingly. If the parameter is all the time false, - // at least NS_MAX_DELAYED_CCOLLECT MaybeCC calls are needed. - // If the previous call to cycle collector did collect something, - // MaybeCC works effectively as if aHigherProbability was true. - // @return PR_TRUE if cycle collector was called. - static PRBool MaybeCC(PRBool aHigherProbability); + static void LoadEnd(); protected: nsresult InitializeExternalClasses(); @@ -210,8 +191,6 @@ protected: nsresult JSObjectFromInterface(nsISupports *aSup, void *aScript, JSObject **aRet); - static void MaybeCCOrGC(nsIScriptContext* aContext); - private: JSContext *mContext; PRUint32 mNumEvaluations; diff --git a/layout/base/nsDocumentViewer.cpp b/layout/base/nsDocumentViewer.cpp index e75864fd7b9..f5d57172f30 100644 --- a/layout/base/nsDocumentViewer.cpp +++ b/layout/base/nsDocumentViewer.cpp @@ -993,7 +993,7 @@ DocumentViewerImpl::LoadComplete(nsresult aStatus) mPresShell->UnsuppressPainting(); } - nsJSContext::LoadEnd(mDocument ? mDocument->GetScriptGlobalObject() : nsnull); + nsJSContext::LoadEnd(); #ifdef NS_PRINTING // Check to see if someone tried to print during the load diff --git a/xpcom/base/nsCycleCollector.cpp b/xpcom/base/nsCycleCollector.cpp index b3620415037..3bfbcea446d 100644 --- a/xpcom/base/nsCycleCollector.cpp +++ b/xpcom/base/nsCycleCollector.cpp @@ -869,7 +869,7 @@ struct nsCycleCollector PRBool Forget(nsISupports *n); void Allocated(void *n, size_t sz); void Freed(void *n); - PRBool Collect(PRUint32 aTryCollections = 1); + void Collect(PRUint32 aTryCollections = 1); void Shutdown(); #ifdef DEBUG_CC @@ -2021,10 +2021,9 @@ nsCycleCollector::Freed(void *n) } #endif -PRBool +void nsCycleCollector::Collect(PRUint32 aTryCollections) { - PRBool didCollect = PR_FALSE; #if defined(DEBUG_CC) && !defined(__MINGW32__) if (!mParams.mDoNothing && mParams.mHookMalloc) InitMemHook(); @@ -2032,7 +2031,7 @@ nsCycleCollector::Collect(PRUint32 aTryCollections) // This can legitimately happen in a few cases. See bug 383651. if (mCollectionInProgress) - return didCollect; + return; #ifdef COLLECT_TIME_DEBUG printf("cc: Starting nsCycleCollector::Collect(%d)\n", aTryCollections); @@ -2169,11 +2168,8 @@ nsCycleCollector::Collect(PRUint32 aTryCollections) // mBuf.GetSize() == 0 check above), we should stop // repeating collections if we didn't collect anything // this time. - if (!collected) { + if (!collected) aTryCollections = 0; - } else { - didCollect = PR_TRUE; - } } #ifdef DEBUG_CC @@ -2198,7 +2194,6 @@ nsCycleCollector::Collect(PRUint32 aTryCollections) #ifdef DEBUG_CC ExplainLiveExpectedGarbage(); #endif - return didCollect; } void @@ -2599,10 +2594,11 @@ NS_CycleCollectorForget(nsISupports *n) } -PRBool +void nsCycleCollector_collect() { - return sCollector ? sCollector->Collect() : PR_FALSE; + if (sCollector) + sCollector->Collect(); } nsresult diff --git a/xpcom/base/nsCycleCollector.h b/xpcom/base/nsCycleCollector.h index ac8ceb5343e..0809ee6dfda 100644 --- a/xpcom/base/nsCycleCollector.h +++ b/xpcom/base/nsCycleCollector.h @@ -66,8 +66,7 @@ struct nsCycleCollectionLanguageRuntime NS_COM void nsCycleCollector_suspectCurrent(nsISupports *n); // NS_COM PRBool nsCycleCollector_forget(nsISupports *n); nsresult nsCycleCollector_startup(); -// Returns PR_TRUE if some nodes were collected. -NS_COM PRBool nsCycleCollector_collect(); +NS_COM void nsCycleCollector_collect(); void nsCycleCollector_shutdown(); #ifdef DEBUG