Bug 720808 - Add nsJSEventListener and nsGlobalWndow to BBP, r=mccr8

--HG--
extra : rebase_source : e6512fe1b8b19b3ddd959b992ce0f2672b0b072f
This commit is contained in:
Olli Pettay 2012-01-26 16:03:21 +01:00
parent 12ceb58a9b
commit e45ec4dc02
7 changed files with 103 additions and 13 deletions

View File

@ -51,11 +51,15 @@ class nsCCUncollectableMarker : public nsIObserver
/**
* Checks if we're collecting during a given generation
*/
static bool InGeneration(PRUint32 aGeneration)
{
return aGeneration && aGeneration == sGeneration;
}
static bool InGeneration(nsCycleCollectionTraversalCallback &cb,
PRUint32 aGeneration) {
return !cb.WantAllTraces() &&
aGeneration &&
aGeneration == sGeneration;
PRUint32 aGeneration)
{
return InGeneration(aGeneration) && !cb.WantAllTraces();
}
static PRUint32 sGeneration;

View File

@ -1405,11 +1405,32 @@ NS_INTERFACE_MAP_END
NS_IMPL_CYCLE_COLLECTING_ADDREF(nsGlobalWindow)
NS_IMPL_CYCLE_COLLECTING_RELEASE(nsGlobalWindow)
static PLDHashOperator
MarkXBLHandlers(const void* aKey, JSObject* aData, void* aClosure)
{
xpc_UnmarkGrayObject(aData);
return PL_DHASH_NEXT;
}
NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_BEGIN(nsGlobalWindow)
if (tmp->IsBlackForCC()) {
if (tmp->mCachedXBLPrototypeHandlers.IsInitialized()) {
tmp->mCachedXBLPrototypeHandlers.EnumerateRead(MarkXBLHandlers, nsnull);
}
return true;
}
NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_END
NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_IN_CC_BEGIN(nsGlobalWindow)
return tmp->IsBlackForCC();
NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_IN_CC_END
NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_THIS_BEGIN(nsGlobalWindow)
return tmp->IsBlackForCC();
NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_THIS_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsGlobalWindow)
if ((tmp->mDoc && nsCCUncollectableMarker::InGeneration(
cb, tmp->mDoc->GetMarkedCCGeneration())) ||
(nsCCUncollectableMarker::sGeneration && tmp->IsBlack())) {
if (!cb.WantAllTraces() && tmp->IsBlackForCC()) {
return NS_SUCCESS_INTERRUPTED_TRAVERSE;
}
@ -1518,6 +1539,28 @@ NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(nsGlobalWindow)
}
NS_IMPL_CYCLE_COLLECTION_TRACE_END
bool
nsGlobalWindow::IsBlackForCC()
{
return
(mDoc &&
nsCCUncollectableMarker::InGeneration(mDoc->GetMarkedCCGeneration())) ||
(nsCCUncollectableMarker::sGeneration && IsBlack());
}
void
nsGlobalWindow::UnmarkGrayTimers()
{
for (nsTimeout* timeout = FirstTimeout();
timeout && IsTimeout(timeout);
timeout = timeout->Next()) {
if (timeout->mScriptHandler) {
JSObject* o = timeout->mScriptHandler->GetScriptObject();
xpc_UnmarkGrayObject(o);
}
}
}
//*****************************************************************************
// nsGlobalWindow::nsIScriptGlobalObject
//*****************************************************************************

View File

@ -327,6 +327,8 @@ public:
virtual void OnFinalize(JSObject* aObject);
virtual void SetScriptsEnabled(bool aEnabled, bool aFireTimeouts);
virtual bool IsBlackForCC();
// nsIScriptObjectPrincipal
virtual nsIPrincipal* GetPrincipal();
@ -508,8 +510,8 @@ public:
friend class WindowStateHolder;
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_AMBIGUOUS(nsGlobalWindow,
nsIScriptGlobalObject)
NS_DECL_CYCLE_COLLECTION_SKIPPABLE_SCRIPT_HOLDER_CLASS_AMBIGUOUS(nsGlobalWindow,
nsIScriptGlobalObject)
void InitJavaProperties();
@ -575,6 +577,7 @@ public:
PRInt64 SizeOf() const;
void UnmarkGrayTimers();
private:
// Enable updates for the accelerometer.
void EnableDeviceMotionUpdates();

View File

@ -100,8 +100,8 @@ NS_HandleScriptError(nsIScriptGlobalObject *aScriptGlobal,
#define NS_ISCRIPTGLOBALOBJECT_IID \
{ 0x08f73284, 0x26e3, 0x4fa6, \
{ 0xbf, 0x89, 0x83, 0x26, 0xf9, 0x2a, 0x94, 0xb3 } }
{ 0x8f19a761, 0x0717, 0x4b3f, \
{ 0x80, 0xc5, 0xed, 0x7e, 0x9c, 0xbc, 0x40, 0xb1 } }
/**
* The global object which keeps a script context for each supported script
@ -162,6 +162,8 @@ public:
nsEventStatus *aEventStatus) {
return NS_HandleScriptError(this, aErrorEvent, aEventStatus);
}
virtual bool IsBlackForCC() { return false; }
};
NS_DEFINE_STATIC_IID_ACCESSOR(nsIScriptGlobalObject,

View File

@ -197,6 +197,13 @@ public:
virtual void GC(js::gcreason::Reason aReason);
nsIScriptGlobalObject* GetCachedGlobalObject()
{
// Verify that we have a global so that this
// does always return a null when GetGlobalObject() is null.
JSObject* global = JS_GetGlobalObject(mContext);
return global ? mGlobalObjectRef.get() : nsnull;
}
protected:
nsresult InitializeExternalClasses();

View File

@ -54,8 +54,10 @@
#include "nsGkAtoms.h"
#include "nsIDOMEventTarget.h"
#include "nsIJSContextStack.h"
#ifdef NS_DEBUG
#include "xpcpublic.h"
#include "nsJSEnvironment.h"
#include "nsDOMJSUtils.h"
#ifdef NS_DEBUG
#include "nspr.h" // PR_fprintf
@ -127,6 +129,18 @@ NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(nsJSEventListener)
mHandler)
NS_IMPL_CYCLE_COLLECTION_TRACE_END
NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_BEGIN(nsJSEventListener)
return tmp->IsBlackForCC();
NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_END
NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_IN_CC_BEGIN(nsJSEventListener)
return tmp->IsBlackForCC();
NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_IN_CC_END
NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_THIS_BEGIN(nsJSEventListener)
return tmp->IsBlackForCC();
NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_THIS_END
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsJSEventListener)
NS_INTERFACE_MAP_ENTRY(nsIDOMEventListener)
NS_INTERFACE_MAP_ENTRY(nsIJSEventListener)
@ -136,6 +150,20 @@ NS_INTERFACE_MAP_END
NS_IMPL_CYCLE_COLLECTING_ADDREF(nsJSEventListener)
NS_IMPL_CYCLE_COLLECTING_RELEASE(nsJSEventListener)
bool
nsJSEventListener::IsBlackForCC()
{
if ((mContext && mContext->GetScriptTypeID() ==
nsIProgrammingLanguage::JAVASCRIPT) &&
(!mScopeObject || !xpc_IsGrayGCThing(mScopeObject)) &&
(!mHandler || !xpc_IsGrayGCThing(mHandler))) {
nsIScriptGlobalObject* sgo =
static_cast<nsJSContext*>(mContext.get())->GetCachedGlobalObject();
return sgo && sgo->IsBlackForCC();
}
return false;
}
nsresult
nsJSEventListener::HandleEvent(nsIDOMEvent* aEvent)
{

View File

@ -69,8 +69,11 @@ public:
return sizeof(*this);
}
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(nsJSEventListener)
NS_DECL_CYCLE_COLLECTION_SKIPPABLE_SCRIPT_HOLDER_CLASS(nsJSEventListener)
protected:
bool IsBlackForCC();
nsCOMPtr<nsIAtom> mEventName;
};