Bug 413447, backing out to see if unit tests pass.

This commit is contained in:
bent.mozilla@gmail.com 2008-02-12 12:53:03 -08:00
Родитель b9a1e2a23d
Коммит d7657b85ae
6 изменённых файлов: 58 добавлений и 122 удалений

Просмотреть файл

@ -368,6 +368,12 @@ nsXBLPrototypeBinding::UnlinkJSObjects()
{ {
if (mImplementation) if (mImplementation)
mImplementation->UnlinkJSObjects(); mImplementation->UnlinkJSObjects();
nsXBLPrototypeHandler* curr = mPrototypeHandler;
while (curr) {
curr->UnlinkJSObjects();
curr = curr->GetNextHandler();
}
} }
void void
@ -375,6 +381,12 @@ nsXBLPrototypeBinding::Trace(TraceCallback aCallback, void *aClosure) const
{ {
if (mImplementation) if (mImplementation)
mImplementation->Trace(aCallback, aClosure); mImplementation->Trace(aCallback, aClosure);
nsXBLPrototypeHandler* curr = mPrototypeHandler;
while (curr) {
curr->Trace(aCallback, aClosure);
curr = curr->GetNextHandler();
}
} }
void void

Просмотреть файл

@ -118,6 +118,7 @@ nsXBLPrototypeHandler::nsXBLPrototypeHandler(const PRUnichar* aEvent,
PRUint32 aLineNumber) PRUint32 aLineNumber)
: mHandlerText(nsnull), : mHandlerText(nsnull),
mLineNumber(aLineNumber), mLineNumber(aLineNumber),
mCachedHandler(nsnull),
mNextHandler(nsnull), mNextHandler(nsnull),
mPrototypeBinding(aBinding) mPrototypeBinding(aBinding)
{ {
@ -134,6 +135,7 @@ nsXBLPrototypeHandler::nsXBLPrototypeHandler(const PRUnichar* aEvent,
nsXBLPrototypeHandler::nsXBLPrototypeHandler(nsIContent* aHandlerElement) nsXBLPrototypeHandler::nsXBLPrototypeHandler(nsIContent* aHandlerElement)
: mHandlerElement(nsnull), : mHandlerElement(nsnull),
mLineNumber(0), mLineNumber(0),
mCachedHandler(nsnull),
mNextHandler(nsnull), mNextHandler(nsnull),
mPrototypeBinding(nsnull) mPrototypeBinding(nsnull)
{ {
@ -159,6 +161,19 @@ nsXBLPrototypeHandler::~nsXBLPrototypeHandler()
delete mNextHandler; delete mNextHandler;
} }
void
nsXBLPrototypeHandler::Trace(TraceCallback aCallback, void *aClosure) const
{
if (mCachedHandler)
aCallback(nsIProgrammingLanguage::JAVASCRIPT, mCachedHandler, aClosure);
}
void
nsXBLPrototypeHandler::UnlinkJSObjects()
{
ForgetCachedHandler();
}
already_AddRefed<nsIContent> already_AddRefed<nsIContent>
nsXBLPrototypeHandler::GetHandlerElement() nsXBLPrototypeHandler::GetHandlerElement()
{ {
@ -181,9 +196,11 @@ nsXBLPrototypeHandler::AppendHandlerText(const nsAString& aText)
mHandlerText = ToNewUnicode(nsDependentString(temp) + aText); mHandlerText = ToNewUnicode(nsDependentString(temp) + aText);
nsMemory::Free(temp); nsMemory::Free(temp);
} }
else { else
mHandlerText = ToNewUnicode(aText); mHandlerText = ToNewUnicode(aText);
}
// Remove our cached handler
ForgetCachedHandler();
} }
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
@ -352,12 +369,15 @@ nsXBLPrototypeHandler::EnsureEventHandler(nsIScriptGlobalObject* aGlobal,
nsScriptObjectHolder &aHandler) nsScriptObjectHolder &aHandler)
{ {
// Check to see if we've already compiled this // Check to see if we've already compiled this
nsCOMPtr<nsPIDOMWindow> pWindow = do_QueryInterface(aGlobal); if (mCachedHandler) {
if (pWindow) { nsCOMPtr<nsIScriptGlobalObject> cachedGlobal =
void* cachedHandler = pWindow->GetCachedXBLPrototypeHandler(this); do_QueryReferent(mGlobalForCachedHandler);
if (cachedHandler) { if (cachedGlobal == aGlobal) {
aHandler.set(cachedHandler); aHandler.set(mCachedHandler);
return aHandler ? NS_OK : NS_ERROR_FAILURE; if (!aHandler)
return NS_ERROR_FAILURE;
return NS_OK;
} }
} }
@ -378,9 +398,8 @@ nsXBLPrototypeHandler::EnsureEventHandler(nsIScriptGlobalObject* aGlobal,
mLineNumber, aHandler); mLineNumber, aHandler);
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
if (pWindow) { mCachedHandler = aHandler;
pWindow->CacheXBLPrototypeHandler(this, aHandler); mGlobalForCachedHandler = do_GetWeakReference(aGlobal);
}
return NS_OK; return NS_OK;
} }
@ -852,6 +871,7 @@ nsXBLPrototypeHandler::ConstructPrototype(nsIContent* aKeyElement,
mMisc = 0; mMisc = 0;
mKeyMask = 0; mKeyMask = 0;
mPhase = NS_PHASE_BUBBLING; mPhase = NS_PHASE_BUBBLING;
ForgetCachedHandler();
if (aAction) if (aAction)
mHandlerText = ToNewUnicode(nsDependentString(aAction)); mHandlerText = ToNewUnicode(nsDependentString(aAction));

Просмотреть файл

@ -153,6 +153,9 @@ public:
return (mType & NS_HANDLER_ALLOW_UNTRUSTED) != 0; return (mType & NS_HANDLER_ALLOW_UNTRUSTED) != 0;
} }
void Trace(TraceCallback aCallback, void *aClosure) const;
void UnlinkJSObjects();
public: public:
static PRUint32 gRefCnt; static PRUint32 gRefCnt;
@ -177,6 +180,11 @@ protected:
nsresult EnsureEventHandler(nsIScriptGlobalObject* aGlobal, nsresult EnsureEventHandler(nsIScriptGlobalObject* aGlobal,
nsIScriptContext *aBoundContext, nsIAtom *aName, nsIScriptContext *aBoundContext, nsIAtom *aName,
nsScriptObjectHolder &aHandler); nsScriptObjectHolder &aHandler);
void ForgetCachedHandler()
{
mCachedHandler = nsnull;
mGlobalForCachedHandler = nsnull;
}
static PRInt32 KeyToMask(PRInt32 key); static PRInt32 KeyToMask(PRInt32 key);
static PRInt32 kAccelKey; static PRInt32 kAccelKey;
@ -222,6 +230,10 @@ protected:
PRInt32 mDetail; // For key events, contains a charcode or keycode. For PRInt32 mDetail; // For key events, contains a charcode or keycode. For
// mouse events, stores the button info. // mouse events, stores the button info.
// cache a handler to avoid compiling each time
void *mCachedHandler;
nsWeakPtr mGlobalForCachedHandler;
// Prototype handlers are chained. We own the next handler in the chain. // Prototype handlers are chained. We own the next handler in the chain.
nsXBLPrototypeHandler* mNextHandler; nsXBLPrototypeHandler* mNextHandler;
nsCOMPtr<nsIAtom> mEventName; // The type of the event, e.g., "keypress" nsCOMPtr<nsIAtom> mEventName; // The type of the event, e.g., "keypress"

Просмотреть файл

@ -70,8 +70,6 @@ class nsIDocument;
class nsIScriptTimeoutHandler; class nsIScriptTimeoutHandler;
class nsPresContext; class nsPresContext;
struct nsTimeout; struct nsTimeout;
class nsScriptObjectHolder;
class nsXBLPrototypeHandler;
#define NS_PIDOMWINDOW_IID \ #define NS_PIDOMWINDOW_IID \
{ 0x909852b5, 0xb9e6, 0x4d94, \ { 0x909852b5, 0xb9e6, 0x4d94, \
@ -381,10 +379,6 @@ public:
*/ */
virtual void InitJavaProperties() = 0; virtual void InitJavaProperties() = 0;
virtual void* GetCachedXBLPrototypeHandler(nsXBLPrototypeHandler* aKey) = 0;
virtual void CacheXBLPrototypeHandler(nsXBLPrototypeHandler* aKey,
nsScriptObjectHolder& aHandler) = 0;
protected: protected:
// The nsPIDOMWindow constructor. The aOuterWindow argument should // The nsPIDOMWindow constructor. The aOuterWindow argument should
// be null if and only if the created window itself is an outer // be null if and only if the created window itself is an outer

Просмотреть файл

@ -580,6 +580,7 @@ nsTimeout::~nsTimeout()
MOZ_COUNT_DTOR(nsTimeout); MOZ_COUNT_DTOR(nsTimeout);
} }
//***************************************************************************** //*****************************************************************************
//*** nsGlobalWindow: Object Management //*** nsGlobalWindow: Object Management
@ -752,23 +753,6 @@ nsGlobalWindow::ShutDown()
NS_IF_RELEASE(sComputedDOMStyleFactory); NS_IF_RELEASE(sComputedDOMStyleFactory);
} }
// static
void
nsGlobalWindow::CleanupCachedXBLHandlers(nsGlobalWindow* aWindow)
{
if (aWindow->mCachedXBLPrototypeHandlers.IsInitialized() &&
aWindow->mCachedXBLPrototypeHandlers.Count() > 0) {
aWindow->mCachedXBLPrototypeHandlers.Clear();
nsCOMPtr<nsISupports> supports;
aWindow->QueryInterface(NS_GET_IID(nsCycleCollectionISupports),
getter_AddRefs(supports));
NS_ASSERTION(supports, "Failed to QI to nsCycleCollectionISupports?!");
nsContentUtils::DropJSObjects(supports);
}
}
void void
nsGlobalWindow::CleanUp() nsGlobalWindow::CleanUp()
{ {
@ -814,8 +798,6 @@ nsGlobalWindow::CleanUp()
mArguments = nsnull; mArguments = nsnull;
mArgumentsLast = nsnull; mArgumentsLast = nsnull;
CleanupCachedXBLHandlers(this);
#ifdef DEBUG #ifdef DEBUG
nsCycleCollector_DEBUG_shouldBeFreed(static_cast<nsIScriptGlobalObject*>(this)); nsCycleCollector_DEBUG_shouldBeFreed(static_cast<nsIScriptGlobalObject*>(this));
#endif #endif
@ -900,8 +882,6 @@ nsGlobalWindow::FreeInnerObjects(PRBool aClearScope)
} }
#endif #endif
CleanupCachedXBLHandlers(this);
#ifdef DEBUG #ifdef DEBUG
nsCycleCollector_DEBUG_shouldBeFreed(static_cast<nsIScriptGlobalObject*>(this)); nsCycleCollector_DEBUG_shouldBeFreed(static_cast<nsIScriptGlobalObject*>(this));
#endif #endif
@ -1008,33 +988,6 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsGlobalWindow)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END NS_IMPL_CYCLE_COLLECTION_UNLINK_END
struct TraceData
{
TraceData(TraceCallback& aCallback, void* aClosure) :
callback(aCallback), closure(aClosure) {}
TraceCallback& callback;
void* closure;
};
PR_STATIC_CALLBACK(PLDHashOperator)
TraceXBLHandlers(const void* aKey, void* aData, void* aClosure)
{
TraceData* data = static_cast<TraceData*>(aClosure);
data->callback(nsIProgrammingLanguage::JAVASCRIPT, aData, data->closure);
return PL_DHASH_NEXT;
}
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(nsGlobalWindow)
if (tmp->mCachedXBLPrototypeHandlers.IsInitialized()) {
TraceData data(aCallback, aClosure);
tmp->mCachedXBLPrototypeHandlers.EnumerateRead(TraceXBLHandlers, &data);
}
NS_IMPL_CYCLE_COLLECTION_TRACE_END
NS_IMPL_CYCLE_COLLECTION_ROOT_BEGIN(nsGlobalWindow)
nsGlobalWindow::CleanupCachedXBLHandlers(tmp);
NS_IMPL_CYCLE_COLLECTION_ROOT_END
//***************************************************************************** //*****************************************************************************
// nsGlobalWindow::nsIScriptGlobalObject // nsGlobalWindow::nsIScriptGlobalObject
@ -5583,49 +5536,6 @@ nsGlobalWindow::InitJavaProperties()
#endif #endif
} }
void*
nsGlobalWindow::GetCachedXBLPrototypeHandler(nsXBLPrototypeHandler* aKey)
{
void* handler = nsnull;
if (mCachedXBLPrototypeHandlers.IsInitialized()) {
mCachedXBLPrototypeHandlers.Get(aKey, &handler);
}
return handler;
}
void
nsGlobalWindow::CacheXBLPrototypeHandler(nsXBLPrototypeHandler* aKey,
nsScriptObjectHolder& aHandler)
{
if (!mCachedXBLPrototypeHandlers.IsInitialized() &&
!mCachedXBLPrototypeHandlers.Init()) {
NS_ERROR("Failed to initiailize hashtable!");
return;
}
if (!mCachedXBLPrototypeHandlers.Count()) {
// Can't use macros to get the participant because nsGlobalChromeWindow also
// runs through this code. Use QueryInterface to get the correct objects.
nsXPCOMCycleCollectionParticipant* participant;
CallQueryInterface(this, &participant);
NS_ASSERTION(participant,
"Failed to QI to nsXPCOMCycleCollectionParticipant!");
nsCOMPtr<nsISupports> thisSupports;
QueryInterface(NS_GET_IID(nsCycleCollectionISupports),
getter_AddRefs(thisSupports));
NS_ASSERTION(thisSupports, "Failed to QI to nsCycleCollectionISupports!");
nsresult rv = nsContentUtils::HoldJSObjects(thisSupports, participant);
if (NS_FAILED(rv)) {
NS_ERROR("nsContentUtils::HoldJSObjects failed!");
return;
}
}
mCachedXBLPrototypeHandlers.Put(aKey, aHandler);
}
NS_IMETHODIMP NS_IMETHODIMP
nsGlobalWindow::GetFrameElement(nsIDOMElement** aFrameElement) nsGlobalWindow::GetFrameElement(nsIDOMElement** aFrameElement)
{ {

Просмотреть файл

@ -51,7 +51,6 @@
#include "nsHashtable.h" #include "nsHashtable.h"
#include "nsDataHashtable.h" #include "nsDataHashtable.h"
#include "nsCycleCollectionParticipant.h" #include "nsCycleCollectionParticipant.h"
#include "nsDOMScriptObjectHolder.h"
// Interfaces Needed // Interfaces Needed
#include "nsDOMWindowList.h" #include "nsDOMWindowList.h"
@ -411,7 +410,6 @@ public:
const PRUnichar* aData); const PRUnichar* aData);
static void ShutDown(); static void ShutDown();
static void CleanupCachedXBLHandlers(nsGlobalWindow* aWindow);
static PRBool IsCallerChrome(); static PRBool IsCallerChrome();
static void CloseBlockScriptTerminationFunc(nsISupports *aRef); static void CloseBlockScriptTerminationFunc(nsISupports *aRef);
@ -420,19 +418,11 @@ public:
friend class WindowStateHolder; friend class WindowStateHolder;
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_AMBIGUOUS(nsGlobalWindow, NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsGlobalWindow,
nsIScriptGlobalObject) nsIScriptGlobalObject)
void InitJavaProperties(); void InitJavaProperties();
virtual NS_HIDDEN_(void*)
GetCachedXBLPrototypeHandler(nsXBLPrototypeHandler* aKey);
virtual NS_HIDDEN_(void)
CacheXBLPrototypeHandler(nsXBLPrototypeHandler* aKey,
nsScriptObjectHolder& aHandler);
protected: protected:
// Object Management // Object Management
virtual ~nsGlobalWindow(); virtual ~nsGlobalWindow();
@ -732,8 +722,6 @@ protected:
nsCOMPtr<nsIDOMOfflineResourceList> mApplicationCache; nsCOMPtr<nsIDOMOfflineResourceList> mApplicationCache;
nsDataHashtable<nsVoidPtrHashKey, void*> mCachedXBLPrototypeHandlers;
friend class nsDOMScriptableHelper; friend class nsDOMScriptableHelper;
friend class nsDOMWindowUtils; friend class nsDOMWindowUtils;
static nsIFactory *sComputedDOMStyleFactory; static nsIFactory *sComputedDOMStyleFactory;