Bug 489581 - Reduce Addref/Release when calling event handlers, r+sr=jst

This commit is contained in:
Olli Pettay 2009-04-24 12:18:37 +03:00
parent 38469312fc
commit 7f711199fa
12 changed files with 69 additions and 51 deletions

View File

@ -1362,8 +1362,8 @@ public:
static nsresult ProcessViewportInfo(nsIDocument *aDocument,
const nsAString &viewportInfo);
static nsresult GetContextForEventHandlers(nsINode* aNode,
nsIScriptContext** aContext);
static nsIScriptContext* GetContextForEventHandlers(nsINode* aNode,
nsresult* aRv);
static JSContext *GetCurrentJSContext();

View File

@ -2710,8 +2710,9 @@ nsCxPusher::Push(nsPIDOMEventTarget *aCurrentTarget)
}
NS_ENSURE_TRUE(aCurrentTarget, PR_FALSE);
nsCOMPtr<nsIScriptContext> scx;
nsresult rv = aCurrentTarget->GetContextForEventHandlers(getter_AddRefs(scx));
nsresult rv;
nsIScriptContext* scx =
aCurrentTarget->GetContextForEventHandlers(&rv);
NS_ENSURE_SUCCESS(rv, PR_FALSE);
if (!scx) {
@ -4503,26 +4504,38 @@ nsContentUtils::URIIsLocalFile(nsIURI *aURI)
}
/* static */
nsresult
nsIScriptContext*
nsContentUtils::GetContextForEventHandlers(nsINode* aNode,
nsIScriptContext** aContext)
nsresult* aRv)
{
*aContext = nsnull;
*aRv = NS_OK;
nsIDocument* ownerDoc = aNode->GetOwnerDoc();
NS_ENSURE_STATE(ownerDoc);
nsCOMPtr<nsIScriptGlobalObject> sgo;
PRBool hasHadScriptObject = PR_TRUE;
sgo = ownerDoc->GetScriptHandlingObject(hasHadScriptObject);
// It is bad if the document doesn't have event handling context,
// but it used to have one.
NS_ENSURE_STATE(sgo || !hasHadScriptObject);
if (sgo) {
NS_IF_ADDREF(*aContext = sgo->GetContext());
// Bad, no context from script global object!
NS_ENSURE_STATE(*aContext);
if (!ownerDoc) {
*aRv = NS_ERROR_UNEXPECTED;
return nsnull;
}
return NS_OK;
PRBool hasHadScriptObject = PR_TRUE;
nsIScriptGlobalObject* sgo =
ownerDoc->GetScriptHandlingObject(hasHadScriptObject);
// It is bad if the document doesn't have event handling context,
// but it used to have one.
if (!sgo && hasHadScriptObject) {
*aRv = NS_ERROR_UNEXPECTED;
return nsnull;
}
if (sgo) {
nsIScriptContext* scx = sgo->GetContext();
// Bad, no context from script global object!
if (!scx) {
*aRv = NS_ERROR_UNEXPECTED;
return nsnull;
}
return scx;
}
return nsnull;
}
/* static */

View File

@ -109,9 +109,9 @@ public:
virtual nsresult RemoveEventListenerByIID(nsIDOMEventListener *aListener,
const nsIID& aIID);
virtual nsresult GetSystemEventGroup(nsIDOMEventGroup** aGroup);
virtual nsresult GetContextForEventHandlers(nsIScriptContext** aContext)
virtual nsIScriptContext* GetContextForEventHandlers(nsresult* aRv)
{
return nsContentUtils::GetContextForEventHandlers(this, aContext);
return nsContentUtils::GetContextForEventHandlers(this, aRv);
}
virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;

View File

@ -821,9 +821,9 @@ public:
virtual nsresult RemoveEventListenerByIID(nsIDOMEventListener *aListener,
const nsIID& aIID);
virtual nsresult GetSystemEventGroup(nsIDOMEventGroup** aGroup);
virtual nsresult GetContextForEventHandlers(nsIScriptContext** aContext)
virtual nsIScriptContext* GetContextForEventHandlers(nsresult* aRv)
{
return nsContentUtils::GetContextForEventHandlers(this, aContext);
return nsContentUtils::GetContextForEventHandlers(this, aRv);
}
virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const
{

View File

@ -179,9 +179,9 @@ public:
virtual nsresult RemoveEventListenerByIID(nsIDOMEventListener *aListener,
const nsIID& aIID);
virtual nsresult GetSystemEventGroup(nsIDOMEventGroup** aGroup);
virtual nsresult GetContextForEventHandlers(nsIScriptContext** aContext)
virtual nsIScriptContext* GetContextForEventHandlers(nsresult* aRv)
{
return nsContentUtils::GetContextForEventHandlers(this, aContext);
return nsContentUtils::GetContextForEventHandlers(this, aRv);
}
// Implementation for nsIContent

View File

@ -366,9 +366,9 @@ public:
virtual nsresult RemoveEventListenerByIID(nsIDOMEventListener *aListener,
const nsIID& aIID);
virtual nsresult GetSystemEventGroup(nsIDOMEventGroup** aGroup);
virtual nsresult GetContextForEventHandlers(nsIScriptContext** aContext)
virtual nsIScriptContext* GetContextForEventHandlers(nsresult* aRv)
{
return nsContentUtils::GetContextForEventHandlers(this, aContext);
return nsContentUtils::GetContextForEventHandlers(this, aRv);
}
// nsIContent interface methods

View File

@ -589,8 +589,10 @@ nsXHREventTarget::AddEventListener(const nsAString& aType,
nsIDOMEventListener* aListener,
PRBool aUseCapture)
{
nsCOMPtr<nsIScriptContext> context;
GetContextForEventHandlers(getter_AddRefs(context));
nsresult rv;
nsIScriptContext* context =
GetContextForEventHandlers(&rv);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIDocument> doc = GetDocumentFromScriptContext(context);
PRBool wantsUntrusted = doc && !nsContentUtils::IsChromeDoc(doc);
return AddEventListener(aType, aListener, aUseCapture, wantsUntrusted);
@ -826,13 +828,14 @@ nsXHREventTarget::GetSystemEventGroup(nsIDOMEventGroup** aGroup)
return rv;
}
nsresult
nsXHREventTarget::GetContextForEventHandlers(nsIScriptContext** aContext)
nsIScriptContext*
nsXHREventTarget::GetContextForEventHandlers(nsresult* aRv)
{
nsresult rv = CheckInnerWindowCorrectness();
NS_ENSURE_SUCCESS(rv, rv);
NS_IF_ADDREF(*aContext = mScriptContext);
return NS_OK;
*aRv = CheckInnerWindowCorrectness();
if (NS_FAILED(*aRv)) {
return nsnull;
}
return mScriptContext;
}
/////////////////////////////////////////////
@ -3357,8 +3360,10 @@ NS_IMETHODIMP
nsXMLHttpRequest::GetUpload(nsIXMLHttpRequestUpload** aUpload)
{
*aUpload = nsnull;
nsCOMPtr<nsIScriptContext> scriptContext;
nsresult rv = GetContextForEventHandlers(getter_AddRefs(scriptContext));
nsresult rv;
nsIScriptContext* scriptContext =
GetContextForEventHandlers(&rv);
NS_ENSURE_SUCCESS(rv, rv);
if (!mUpload) {
mUpload = new nsXMLHttpRequestUpload(mOwner, scriptContext);

View File

@ -186,7 +186,7 @@ public:
virtual nsresult RemoveEventListenerByIID(nsIDOMEventListener *aListener,
const nsIID& aIID);
virtual nsresult GetSystemEventGroup(nsIDOMEventGroup** aGroup);
virtual nsresult GetContextForEventHandlers(nsIScriptContext** aContext);
virtual nsIScriptContext* GetContextForEventHandlers(nsresult* aRv);
PRBool HasListenersFor(const nsAString& aType)
{

View File

@ -52,8 +52,8 @@ class nsIScriptContext;
// 25982813-af2e-4ab6-b512-e6c6ada6d0ec
#define NS_PIDOMEVENTTARGET_IID \
{ 0x25982813, 0xaf2e, 0x4ab6, \
{ 0xb5, 0x12, 0xe6, 0xc6, 0xad, 0xa6, 0xd0, 0xec } }
{ 0x358f2990, 0x5107, 0x49ba, \
{ 0x88, 0x94, 0x14, 0x34, 0x86, 0xd5, 0x99, 0x85 } }
class nsPIDOMEventTarget : public nsISupports
{
@ -163,8 +163,9 @@ public:
/**
* Get the script context in which the event handlers should be run.
* May return null.
* @note Caller *must* check the value of aRv.
*/
virtual nsresult GetContextForEventHandlers(nsIScriptContext** aContext) = 0;
virtual nsIScriptContext* GetContextForEventHandlers(nsresult* aRv) = 0;
};
NS_DEFINE_STATIC_IID_ACCESSOR(nsPIDOMEventTarget, NS_PIDOMEVENTTARGET_IID)

View File

@ -6456,13 +6456,12 @@ nsGlobalWindow::GetSystemEventGroup(nsIDOMEventGroup **aGroup)
return NS_ERROR_FAILURE;
}
nsresult
nsGlobalWindow::GetContextForEventHandlers(nsIScriptContext** aContext)
nsIScriptContext*
nsGlobalWindow::GetContextForEventHandlers(nsresult* aRv)
{
NS_IF_ADDREF(*aContext = GetContext());
// Bad, no context from script global object!
NS_ENSURE_STATE(*aContext);
return NS_OK;
nsIScriptContext* scx = GetContext();
*aRv = scx ? NS_OK : NS_ERROR_UNEXPECTED;
return scx;
}
//*****************************************************************************

View File

@ -335,7 +335,7 @@ public:
virtual NS_HIDDEN_(nsresult) RemoveEventListenerByIID(nsIDOMEventListener *aListener,
const nsIID& aIID);
virtual NS_HIDDEN_(nsresult) GetSystemEventGroup(nsIDOMEventGroup** aGroup);
virtual NS_HIDDEN_(nsresult) GetContextForEventHandlers(nsIScriptContext** aContext);
virtual NS_HIDDEN_(nsIScriptContext*) GetContextForEventHandlers(nsresult* aRv);
virtual NS_HIDDEN_(void) SetDocShell(nsIDocShell* aDocShell);
virtual NS_HIDDEN_(nsresult) SetNewDocument(nsIDocument *aDocument,

View File

@ -83,10 +83,10 @@ public:
virtual nsresult RemoveEventListenerByIID(nsIDOMEventListener *aListener,
const nsIID& aIID);
virtual nsresult GetSystemEventGroup(nsIDOMEventGroup** aGroup);
virtual nsresult GetContextForEventHandlers(nsIScriptContext** aContext)
virtual nsIScriptContext* GetContextForEventHandlers(nsresult* aRv)
{
*aContext = nsnull;
return NS_OK;
*aRv = NS_OK;
return nsnull;
}
// nsPIWindowRoot