From 7f55aee2e10c4797887160826cac7f26fa056970 Mon Sep 17 00:00:00 2001 From: Chris Leary Date: Thu, 22 Sep 2011 15:13:36 -0700 Subject: [PATCH] Bug 684039: Don't use JSArenaPool in nsJSEnvironment. (r=mrbkap) --- dom/base/nsJSEnvironment.cpp | 64 ++++++++++++++++++++---------------- dom/base/nsJSEnvironment.h | 5 ++- 2 files changed, 38 insertions(+), 31 deletions(-) diff --git a/dom/base/nsJSEnvironment.cpp b/dom/base/nsJSEnvironment.cpp index 0649a7b41bc..5b5ebe2d5be 100644 --- a/dom/base/nsJSEnvironment.cpp +++ b/dom/base/nsJSEnvironment.cpp @@ -199,6 +199,33 @@ nsMemoryPressureObserver::Observe(nsISupports* aSubject, const char* aTopic, return NS_OK; } +class nsRootedJSValueArray { +public: + explicit nsRootedJSValueArray(JSContext *cx) : avr(cx, vals.Length(), vals.Elements()) {} + + PRBool SetCapacity(JSContext *cx, size_t capacity) { + PRBool ok = vals.SetCapacity(capacity); + if (!ok) + return PR_FALSE; + // Values must be safe for the GC to inspect (they must not contain garbage). + memset(vals.Elements(), 0, vals.SizeOf()); + resetRooter(cx); + return PR_TRUE; + } + + jsval *Elements() { + return vals.Elements(); + } + +private: + void resetRooter(JSContext *cx) { + avr.changeArray(vals.Elements(), vals.Length()); + } + + nsAutoTArray vals; + js::AutoArrayRooter avr; +}; + /**************************************************************** ************************** AutoFree **************************** ****************************************************************/ @@ -218,15 +245,6 @@ private: void *mPtr; }; -class nsAutoPoolRelease { -public: - nsAutoPoolRelease(JSArenaPool *p, void *m) : mPool(p), mMark(m) {} - ~nsAutoPoolRelease() { JS_ARENA_RELEASE(mPool, mMark); } -private: - JSArenaPool *mPool; - void *mMark; -}; - // A utility function for script languages to call. Although it looks small, // the use of nsIDocShell and nsPresContext triggers a huge number of // dependencies that most languages would not otherwise need. @@ -1912,16 +1930,14 @@ nsJSContext::CallEventHandler(nsISupports* aTarget, void *aScope, void *aHandler return NS_ERROR_FAILURE; } - Maybe poolRelease; - Maybe tvr; + Maybe tempStorage; // Use |target| as the scope for wrapping the arguments, since aScope is // the safe scope in many cases, which isn't very useful. Wrapping aTarget // was OK because those typically have PreCreate methods that give them the // right scope anyway, and we want to make sure that the arguments end up // in the same scope as aTarget. - rv = ConvertSupportsTojsvals(aargv, target, &argc, - &argv, poolRelease, tvr); + rv = ConvertSupportsTojsvals(aargv, target, &argc, &argv, tempStorage); NS_ENSURE_SUCCESS(rv, rv); ++mExecuteDepth; @@ -2343,12 +2359,10 @@ nsJSContext::SetProperty(void *aTarget, const char *aPropName, nsISupports *aArg JSAutoRequest ar(mContext); - Maybe poolRelease; - Maybe tvr; + Maybe tempStorage; nsresult rv; - rv = ConvertSupportsTojsvals(aArgs, GetNativeGlobal(), &argc, - &argv, poolRelease, tvr); + rv = ConvertSupportsTojsvals(aArgs, GetNativeGlobal(), &argc, &argv, tempStorage); NS_ENSURE_SUCCESS(rv, rv); jsval vargs; @@ -2384,8 +2398,7 @@ nsJSContext::ConvertSupportsTojsvals(nsISupports *aArgs, void *aScope, PRUint32 *aArgc, jsval **aArgv, - Maybe &aPoolRelease, - Maybe &aRooter) + Maybe &aTempStorage) { nsresult rv = NS_OK; @@ -2420,16 +2433,11 @@ nsJSContext::ConvertSupportsTojsvals(nsISupports *aArgs, argCount = 1; // the nsISupports which is not an array } - void *mark = JS_ARENA_MARK(&mContext->tempPool); - jsval *argv; - size_t nbytes = argCount * sizeof(jsval); - JS_ARENA_ALLOCATE_CAST(argv, jsval *, &mContext->tempPool, nbytes); - NS_ENSURE_TRUE(argv, NS_ERROR_OUT_OF_MEMORY); - memset(argv, 0, nbytes); /* initialize so GC-able */ - // Use the caller's auto guards to release and unroot. - aPoolRelease.construct(&mContext->tempPool, mark); - aRooter.construct(mContext, argCount, argv); + aTempStorage.construct(mContext); + PRBool ok = aTempStorage.ref().SetCapacity(mContext, argCount); + NS_ENSURE_TRUE(ok, NS_ERROR_OUT_OF_MEMORY); + jsval *argv = aTempStorage.ref().Elements(); if (argsArray) { for (argCtr = 0; argCtr < argCount && NS_SUCCEEDED(rv); argCtr++) { diff --git a/dom/base/nsJSEnvironment.h b/dom/base/nsJSEnvironment.h index 54434ee0dfe..7ce9a377d08 100644 --- a/dom/base/nsJSEnvironment.h +++ b/dom/base/nsJSEnvironment.h @@ -48,7 +48,7 @@ #include "nsScriptNameSpaceManager.h" class nsIXPConnectJSObjectHolder; -class nsAutoPoolRelease; +class nsRootedJSValueArray; namespace js { class AutoArrayRooter; } @@ -204,8 +204,7 @@ protected: void *aScope, PRUint32 *aArgc, jsval **aArgv, - mozilla::Maybe &aPoolRelease, - mozilla::Maybe &aRooter); + mozilla::Maybe &aPoolRelease); nsresult AddSupportsPrimitiveTojsvals(nsISupports *aArg, jsval *aArgv);