Bug 882162: Part 2 - Begin to push mJSHolders down into mozilla::CycleCollectedJSRuntime. r=mccr8

This commit is contained in:
Kyle Huey 2013-06-18 12:02:14 -07:00
parent da1a10929b
commit fd912ef78f
4 changed files with 84 additions and 73 deletions

View File

@ -412,61 +412,6 @@ CompartmentDestroyedCallback(JSFreeOp *fop, JSCompartment *compartment)
JS_SetCompartmentPrivate(compartment, nullptr);
}
void
XPCJSRuntime::AddJSHolder(void* aHolder, nsScriptObjectTracer* aTracer)
{
MOZ_ASSERT(aTracer->Trace, "AddJSHolder needs a non-null Trace function");
bool wasEmpty = mJSHolders.Count() == 0;
mJSHolders.Put(aHolder, aTracer);
if (wasEmpty && mJSHolders.Count() == 1) {
nsLayoutStatics::AddRef();
}
}
#ifdef DEBUG
static void
AssertNoGcThing(void* aGCThing, const char* aName, void* aClosure)
{
MOZ_ASSERT(!aGCThing);
}
void
XPCJSRuntime::AssertNoObjectsToTrace(void* aPossibleJSHolder)
{
nsScriptObjectTracer* tracer = mJSHolders.Get(aPossibleJSHolder);
if (tracer && tracer->Trace) {
tracer->Trace(aPossibleJSHolder, TraceCallbackFunc(AssertNoGcThing), nullptr);
}
}
#endif
void
XPCJSRuntime::RemoveJSHolder(void* aHolder)
{
#ifdef DEBUG
// Assert that the holder doesn't try to keep any GC things alive.
// In case of unlinking cycle collector calls AssertNoObjectsToTrace
// manually because we don't want to check the holder before we are
// finished unlinking it
if (aHolder != mObjectToUnlink) {
AssertNoObjectsToTrace(aHolder);
}
#endif
bool hadOne = mJSHolders.Count() == 1;
mJSHolders.Remove(aHolder);
if (hadOne && mJSHolders.Count() == 0) {
nsLayoutStatics::Release();
}
}
#ifdef DEBUG
bool
XPCJSRuntime::TestJSHolder(void* aHolder)
{
return mJSHolders.Get(aHolder, nullptr);
}
#endif
// static
void XPCJSRuntime::TraceBlackJS(JSTracer* trc, void* data)
{
@ -2822,9 +2767,6 @@ XPCJSRuntime::XPCJSRuntime(nsXPConnect* aXPConnect)
mTimeAtLastRuntimeStateChange(PR_Now()),
mJunkScope(nullptr),
mExceptionManagerNotAvailable(false)
#ifdef DEBUG
, mObjectToUnlink(nullptr)
#endif
{
#ifdef XPC_CHECK_WRAPPERS_AT_SHUTDOWN
DEBUG_WrappedNativeHashtable =
@ -2915,8 +2857,6 @@ XPCJSRuntime::XPCJSRuntime(nsXPConnect* aXPConnect)
NS_RegisterMemoryReporter(new NS_MEMORY_REPORTER_NAME(JSMainRuntimeTemporaryPeak));
NS_RegisterMemoryMultiReporter(new JSCompartmentsMultiReporter);
mJSHolders.Init(512);
// Install a JavaScript 'debugger' keyword handler in debug builds only
#ifdef DEBUG
if (!JS_GetGlobalDebugHooks(runtime)->debuggerHandler)

View File

@ -770,14 +770,6 @@ public:
inline void AddWrappedJSRoot(nsXPCWrappedJS* wrappedJS);
inline void AddObjectHolderRoot(XPCJSObjectHolder* holder);
void AddJSHolder(void* aHolder, nsScriptObjectTracer* aTracer);
void RemoveJSHolder(void* aHolder);
#ifdef DEBUG
bool TestJSHolder(void* aHolder);
void SetObjectToUnlink(void* aObject) { mObjectToUnlink = aObject; }
void AssertNoObjectsToTrace(void* aPossibleJSHolder);
#endif
static void SuspectWrappedNative(XPCWrappedNative *wrapper,
nsCycleCollectionNoteRootCallback &cb);
@ -905,7 +897,6 @@ private:
XPCRootSetElem *mVariantRoots;
XPCRootSetElem *mWrappedJSRoots;
XPCRootSetElem *mObjectHolderRoots;
nsDataHashtable<nsPtrHashKey<void>, nsScriptObjectTracer*> mJSHolders;
PRLock *mWatchdogLock;
PRCondVar *mWatchdogWakeup;
PRThread *mWatchdogThread;
@ -940,10 +931,6 @@ private:
friend class AutoLockWatchdog;
friend class XPCIncrementalReleaseRunnable;
#ifdef DEBUG
void* mObjectToUnlink;
#endif
};
/***************************************************************************/

View File

@ -5,16 +5,24 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/CycleCollectedJSRuntime.h"
#include "nsCycleCollectionParticipant.h"
#include "nsLayoutStatics.h"
using namespace mozilla;
CycleCollectedJSRuntime::CycleCollectedJSRuntime(uint32_t aMaxbytes,
JSUseHelperThreads aUseHelperThreads)
: mJSRuntime(nullptr)
#ifdef DEBUG
, mObjectToUnlink(nullptr)
#endif
{
mJSRuntime = JS_NewRuntime(aMaxbytes, aUseHelperThreads);
if (!mJSRuntime) {
MOZ_CRASH();
}
mJSHolders.Init(512);
}
CycleCollectedJSRuntime::~CycleCollectedJSRuntime()
@ -22,3 +30,57 @@ CycleCollectedJSRuntime::~CycleCollectedJSRuntime()
JS_DestroyRuntime(mJSRuntime);
mJSRuntime = nullptr;
}
void
CycleCollectedJSRuntime::AddJSHolder(void* aHolder, nsScriptObjectTracer* aTracer)
{
MOZ_ASSERT(aTracer->Trace, "AddJSHolder needs a non-null Trace function");
bool wasEmpty = mJSHolders.Count() == 0;
mJSHolders.Put(aHolder, aTracer);
if (wasEmpty && mJSHolders.Count() == 1) {
nsLayoutStatics::AddRef();
}
}
void
CycleCollectedJSRuntime::RemoveJSHolder(void* aHolder)
{
#ifdef DEBUG
// Assert that the holder doesn't try to keep any GC things alive.
// In case of unlinking cycle collector calls AssertNoObjectsToTrace
// manually because we don't want to check the holder before we are
// finished unlinking it
if (aHolder != mObjectToUnlink) {
AssertNoObjectsToTrace(aHolder);
}
#endif
bool hadOne = mJSHolders.Count() == 1;
mJSHolders.Remove(aHolder);
if (hadOne && mJSHolders.Count() == 0) {
nsLayoutStatics::Release();
}
}
#ifdef DEBUG
bool
CycleCollectedJSRuntime::TestJSHolder(void* aHolder)
{
return mJSHolders.Get(aHolder, nullptr);
}
static void
AssertNoGcThing(void* aGCThing, const char* aName, void* aClosure)
{
MOZ_ASSERT(!aGCThing);
}
void
CycleCollectedJSRuntime::AssertNoObjectsToTrace(void* aPossibleJSHolder)
{
nsScriptObjectTracer* tracer = mJSHolders.Get(aPossibleJSHolder);
if (tracer && tracer->Trace) {
tracer->Trace(aPossibleJSHolder, TraceCallbackFunc(AssertNoGcThing), nullptr);
}
}
#endif

View File

@ -9,6 +9,11 @@
#include "jsapi.h"
#include "nsDataHashtable.h"
#include "nsHashKeys.h"
class nsScriptObjectTracer;
namespace mozilla {
class CycleCollectedJSRuntime
@ -24,8 +29,25 @@ protected:
return mJSRuntime;
}
public:
void AddJSHolder(void* aHolder, nsScriptObjectTracer* aTracer);
void RemoveJSHolder(void* aHolder);
#ifdef DEBUG
bool TestJSHolder(void* aHolder);
void SetObjectToUnlink(void* aObject) { mObjectToUnlink = aObject; }
void AssertNoObjectsToTrace(void* aPossibleJSHolder);
#endif
// XXXkhuey should be private
protected:
nsDataHashtable<nsPtrHashKey<void>, nsScriptObjectTracer*> mJSHolders;
private:
JSRuntime* mJSRuntime;
#ifdef DEBUG
void* mObjectToUnlink;
#endif
};
} // namespace mozilla