Bug 1105069 - Part 14: Convert NoteJSChild to GCCellPtr; r=mccr8, r=jonco

--HG--
extra : rebase_source : 2338e0a57779401f9bc4744bc2fa59a4b31d76bf
This commit is contained in:
Terrence Cole 2014-12-05 09:38:34 -08:00
parent c3e592a91b
commit 54972a74ea
14 changed files with 99 additions and 54 deletions

View File

@ -43,7 +43,7 @@ nsWrapperCache::ReleaseWrapper(void* aScriptObjectHolder)
class DebugWrapperTraversalCallback : public nsCycleCollectionTraversalCallback
{
public:
explicit DebugWrapperTraversalCallback(void* aWrapper)
explicit DebugWrapperTraversalCallback(JSObject* aWrapper)
: mFound(false)
, mWrapper(aWrapper)
{
@ -60,12 +60,15 @@ public:
{
}
NS_IMETHOD_(void) NoteJSChild(void* aChild)
NS_IMETHOD_(void) NoteJSObject(JSObject* aChild)
{
if (aChild == mWrapper) {
mFound = true;
}
}
NS_IMETHOD_(void) NoteJSScript(JSScript* aChild)
{
}
NS_IMETHOD_(void) NoteXPCOMChild(nsISupports* aChild)
{
}
@ -81,15 +84,17 @@ public:
bool mFound;
private:
void* mWrapper;
JSObject* mWrapper;
};
static void
DebugWrapperTraceCallback(void* aP, const char* aName, void* aClosure)
DebugWrapperTraceCallback(JS::GCCellPtr aPtr, const char* aName, void* aClosure)
{
DebugWrapperTraversalCallback* callback =
static_cast<DebugWrapperTraversalCallback*>(aClosure);
callback->NoteJSChild(aP);
if (aPtr.isObject()) {
callback->NoteJSObject(aPtr.toObject());
}
}
void
@ -103,6 +108,10 @@ nsWrapperCache::CheckCCWrapperTraversal(void* aScriptObjectHolder,
DebugWrapperTraversalCallback callback(wrapper);
// The CC traversal machinery cannot trigger GC; however, the analysis cannot
// see through the COM layer, so we use a suppression to help it.
JS::AutoSuppressGCAnalysis suppress;
aTracer->Traverse(aScriptObjectHolder, callback);
MOZ_ASSERT(callback.mFound,
"Cycle collection participant didn't traverse to preserved "

View File

@ -28,10 +28,10 @@ nsWrapperCache::IsBlack()
}
static void
SearchGray(void* aGCThing, const char* aName, void* aClosure)
SearchGray(JS::GCCellPtr aGCThing, const char* aName, void* aClosure)
{
bool* hasGrayObjects = static_cast<bool*>(aClosure);
if (!*hasGrayObjects && aGCThing && JS::GCThingIsMarkedGray(aGCThing)) {
if (!*hasGrayObjects && aGCThing && JS::GCThingIsMarkedGray(aGCThing.asCell())) {
*hasGrayObjects = true;
}
}

View File

@ -98,9 +98,9 @@ NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(nsXBLDocumentInfo)
NS_IMPL_CYCLE_COLLECTION_TRACE_END
static void
UnmarkXBLJSObject(void* aP, const char* aName, void* aClosure)
UnmarkXBLJSObject(JS::GCCellPtr aPtr, const char* aName, void* aClosure)
{
JS::ExposeObjectToActiveJS(static_cast<JSObject*>(aP));
JS::ExposeObjectToActiveJS(aPtr.toObject());
}
static PLDHashOperator

View File

@ -139,10 +139,14 @@ JSID_IS_GCTHING(jsid id)
return JSID_IS_STRING(id) || JSID_IS_SYMBOL(id);
}
static MOZ_ALWAYS_INLINE void *
static MOZ_ALWAYS_INLINE JS::GCCellPtr
JSID_TO_GCTHING(jsid id)
{
return (void *)(JSID_BITS(id) & ~(size_t)JSID_TYPE_MASK);
void *thing = (void *)(JSID_BITS(id) & ~(size_t)JSID_TYPE_MASK);
if (JSID_IS_STRING(id))
return JS::GCCellPtr(thing, JSTRACE_STRING);
MOZ_ASSERT(JSID_IS_SYMBOL(id));
return JS::GCCellPtr(thing, JSTRACE_SYMBOL);
}
static MOZ_ALWAYS_INLINE bool

View File

@ -83,9 +83,9 @@ NS_IMPL_CYCLE_COLLECTION_CLASS(XPCVariant)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(XPCVariant)
JS::Value val = tmp->GetJSValPreserveColor();
if (val.isObjectOrNull()) {
if (val.isObject()) {
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mJSVal");
cb.NoteJSChild(val.toObjectOrNull());
cb.NoteJSObject(&val.toObject());
}
nsVariant::Traverse(tmp->mData, cb);

View File

@ -123,7 +123,7 @@ NS_CYCLE_COLLECTION_CLASSNAME(nsXPCWrappedJS)::Traverse
if (tmp->IsValid()) {
MOZ_ASSERT(refcnt > 1);
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mJSObj");
cb.NoteJSChild(tmp->GetJSObjectPreserveColor());
cb.NoteJSObject(tmp->GetJSObjectPreserveColor());
}
if (tmp->IsRootWrapper()) {

View File

@ -77,7 +77,7 @@ NS_CYCLE_COLLECTION_CLASSNAME(XPCWrappedNative)::Traverse
JSObject *obj = tmp->GetFlatJSObjectPreserveColor();
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mFlatJSObject");
cb.NoteJSChild(obj);
cb.NoteJSObject(obj);
}
// XPCWrappedNative keeps its native object alive.

View File

@ -243,12 +243,6 @@ static inline bool IS_WN_REFLECTOR(JSObject *obj)
// returned as function call result values they are not addref'd. Exceptions
// to this rule are noted explicitly.
inline bool
AddToCCKind(JSGCTraceKind kind)
{
return kind == JSTRACE_OBJECT || kind == JSTRACE_SCRIPT;
}
class nsXPConnect : public nsIXPConnect,
public nsIThreadObserver,
public nsSupportsWeakReference,

View File

@ -119,12 +119,6 @@ public:
} // namespace mozilla
inline bool
AddToCCKind(JSGCTraceKind aKind)
{
return aKind == JSTRACE_OBJECT || aKind == JSTRACE_SCRIPT;
}
static void
TraceWeakMappingChild(JSTracer* aTrc, void** aThingp, JSGCTraceKind aKind);
@ -308,7 +302,7 @@ struct Closure
};
static void
CheckParticipatesInCycleCollection(void* aThing, const char* aName,
CheckParticipatesInCycleCollection(JS::GCCellPtr aThing, const char* aName,
void* aClosure)
{
Closure* closure = static_cast<Closure*>(aClosure);
@ -317,8 +311,8 @@ CheckParticipatesInCycleCollection(void* aThing, const char* aName,
return;
}
if (AddToCCKind(js::GCThingTraceKind(aThing)) &&
xpc_IsGrayGCThing(aThing)) {
if (AddToCCKind(aThing.kind()) &&
xpc_IsGrayGCThing(aThing.asCell())) {
closure->mCycleCollectionEnabled = true;
}
}
@ -424,7 +418,12 @@ NoteJSChild(JSTracer* aTrc, void* aThing, JSGCTraceKind aTraceKind)
tracer->mCb.NoteNextEdgeName(static_cast<const char*>(tracer->debugPrintArg()));
}
}
tracer->mCb.NoteJSChild(aThing);
JS::GCCellPtr thing(aThing, aTraceKind);
if (thing.isObject()) {
tracer->mCb.NoteJSObject(thing.toObject());
} else {
tracer->mCb.NoteJSScript(thing.toScript());
}
} else if (aTraceKind == JSTRACE_SHAPE) {
JS_TraceShapeCycleCollectorChildren(aTrc, aThing);
} else if (aTraceKind != JSTRACE_STRING) {
@ -915,7 +914,7 @@ CycleCollectedJSRuntime::IsJSHolder(void* aHolder)
}
static void
AssertNoGcThing(void* aGCThing, const char* aName, void* aClosure)
AssertNoGcThing(JS::GCCellPtr aGCThing, const char* aName, void* aClosure)
{
MOZ_ASSERT(!aGCThing);
}

View File

@ -334,6 +334,12 @@ MOZ_FINISH_NESTED_ENUM_CLASS(CycleCollectedJSRuntime::OOMState)
void TraceScriptHolder(nsISupports* aHolder, JSTracer* aTracer);
// Returns true if the JSGCTraceKind is one the cycle collector cares about.
inline bool AddToCCKind(JSGCTraceKind aKind)
{
return aKind == JSTRACE_OBJECT || aKind == JSTRACE_SCRIPT;
}
} // namespace mozilla
#endif // mozilla_CycleCollectedJSRuntime_h__

View File

@ -2082,12 +2082,15 @@ public:
uint64_t aCompartmentAddress);
NS_IMETHOD_(void) NoteXPCOMChild(nsISupports* aChild);
NS_IMETHOD_(void) NoteJSChild(void* aChild);
NS_IMETHOD_(void) NoteJSObject(JSObject* aChild);
NS_IMETHOD_(void) NoteJSScript(JSScript* aChild);
NS_IMETHOD_(void) NoteNativeChild(void* aChild,
nsCycleCollectionParticipant* aParticipant);
NS_IMETHOD_(void) NoteNextEdgeName(const char* aName);
private:
void NoteJSChild(JS::GCCellPtr aChild);
NS_IMETHOD_(void) NoteRoot(void* aRoot,
nsCycleCollectionParticipant* aParticipant)
{
@ -2318,7 +2321,19 @@ CCGraphBuilder::NoteNativeChild(void* aChild,
}
NS_IMETHODIMP_(void)
CCGraphBuilder::NoteJSChild(void* aChild)
CCGraphBuilder::NoteJSObject(JSObject* aChild)
{
return NoteJSChild(JS::GCCellPtr(aChild));
}
NS_IMETHODIMP_(void)
CCGraphBuilder::NoteJSScript(JSScript* aChild)
{
return NoteJSChild(JS::GCCellPtr(aChild));
}
void
CCGraphBuilder::NoteJSChild(JS::GCCellPtr aChild)
{
if (!aChild) {
return;
@ -2330,11 +2345,11 @@ CCGraphBuilder::NoteJSChild(void* aChild)
mNextEdgeName.Truncate();
}
if (xpc_GCThingIsGrayCCThing(aChild) || MOZ_UNLIKELY(WantAllTraces())) {
if (JS::Zone* zone = MergeZone(aChild)) {
if (xpc_GCThingIsGrayCCThing(aChild.asCell()) || MOZ_UNLIKELY(WantAllTraces())) {
if (JS::Zone* zone = MergeZone(aChild.asCell())) {
NoteChild(zone, mJSZoneParticipant, edgeName);
} else {
NoteChild(aChild, mJSParticipant, edgeName);
NoteChild(aChild.asCell(), mJSParticipant, edgeName);
}
}
}
@ -2410,7 +2425,8 @@ public:
NS_IMETHOD_(void) NoteXPCOMChild(nsISupports* aChild);
NS_IMETHOD_(void) NoteNativeChild(void* aChild,
nsCycleCollectionParticipant* aHelper);
NS_IMETHOD_(void) NoteJSChild(void* aChild);
NS_IMETHOD_(void) NoteJSObject(JSObject* aChild);
NS_IMETHOD_(void) NoteJSScript(JSScript* aChild);
NS_IMETHOD_(void) DescribeRefCountedNode(nsrefcnt aRefcount,
const char* aObjname)
@ -2459,7 +2475,15 @@ ChildFinder::NoteNativeChild(void* aChild,
}
NS_IMETHODIMP_(void)
ChildFinder::NoteJSChild(void* aChild)
ChildFinder::NoteJSObject(JSObject* aChild)
{
if (aChild && xpc_GCThingIsGrayCCThing(aChild)) {
mMayHaveChild = true;
}
}
NS_IMETHODIMP_(void)
ChildFinder::NoteJSScript(JSScript* aChild)
{
if (aChild && xpc_GCThingIsGrayCCThing(aChild)) {
mMayHaveChild = true;

View File

@ -5,8 +5,10 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "nsCycleCollectionParticipant.h"
#include "mozilla/CycleCollectedJSRuntime.h"
#include "nsCOMPtr.h"
#include "jsapi.h"
#include "jsfriendapi.h"
#ifdef MOZILLA_INTERNAL_API
#include "nsString.h"
@ -15,13 +17,19 @@
#endif
void
nsScriptObjectTracer::NoteJSChild(void* aScriptThing, const char* aName,
nsScriptObjectTracer::NoteJSChild(JS::GCCellPtr aGCThing, const char* aName,
void* aClosure)
{
nsCycleCollectionTraversalCallback* cb =
static_cast<nsCycleCollectionTraversalCallback*>(aClosure);
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(*cb, aName);
cb->NoteJSChild(aScriptThing);
if (aGCThing.isObject()) {
cb->NoteJSObject(aGCThing.toObject());
} else if (aGCThing.isScript()) {
cb->NoteJSScript(aGCThing.toScript());
} else {
MOZ_ASSERT(!mozilla::AddToCCKind(aGCThing.kind()));
}
}
NS_IMETHODIMP_(void)
@ -72,7 +80,7 @@ TraceCallbackFunc::Trace(JS::Heap<JS::Value>* aPtr, const char* aName,
void* aClosure) const
{
if (aPtr->isMarkable()) {
mCallback(aPtr->toGCThing(), aName, aClosure);
mCallback(JS::GCCellPtr(*aPtr), aName, aClosure);
}
}
@ -80,9 +88,8 @@ void
TraceCallbackFunc::Trace(JS::Heap<jsid>* aPtr, const char* aName,
void* aClosure) const
{
void* thing = JSID_TO_GCTHING(*aPtr);
if (thing) {
mCallback(thing, aName, aClosure);
if (JSID_IS_GCTHING(*aPtr)) {
mCallback(JSID_TO_GCTHING(*aPtr), aName, aClosure);
}
}
@ -90,33 +97,33 @@ void
TraceCallbackFunc::Trace(JS::Heap<JSObject*>* aPtr, const char* aName,
void* aClosure) const
{
mCallback(*aPtr, aName, aClosure);
mCallback(JS::GCCellPtr(*aPtr), aName, aClosure);
}
void
TraceCallbackFunc::Trace(JS::TenuredHeap<JSObject*>* aPtr, const char* aName,
void* aClosure) const
{
mCallback(*aPtr, aName, aClosure);
mCallback(JS::GCCellPtr(*aPtr), aName, aClosure);
}
void
TraceCallbackFunc::Trace(JS::Heap<JSFunction*>* aPtr, const char* aName,
void* aClosure) const
{
mCallback(*aPtr, aName, aClosure);
mCallback(JS::GCCellPtr(*aPtr), aName, aClosure);
}
void
TraceCallbackFunc::Trace(JS::Heap<JSString*>* aPtr, const char* aName,
void* aClosure) const
{
mCallback(*aPtr, aName, aClosure);
mCallback(JS::GCCellPtr(*aPtr), aName, aClosure);
}
void
TraceCallbackFunc::Trace(JS::Heap<JSScript*>* aPtr, const char* aName,
void* aClosure) const
{
mCallback(aPtr->get(), aName, aClosure);
mCallback(JS::GCCellPtr(*aPtr), aName, aClosure);
}

View File

@ -80,7 +80,7 @@ struct TraceCallbacks
*/
struct TraceCallbackFunc : public TraceCallbacks
{
typedef void (*Func)(void* aPtr, const char* aName, void* aClosure);
typedef void (*Func)(JS::GCCellPtr aPtr, const char* aName, void* aClosure);
explicit TraceCallbackFunc(Func aCb) : mCallback(aCb) {}
@ -184,7 +184,7 @@ public:
NS_IMETHOD_(void) Trace(void* aPtr, const TraceCallbacks& aCb,
void* aClosure) = 0;
static void NoteJSChild(void* aScriptThing, const char* aName,
static void NoteJSChild(JS::GCCellPtr aGCThing, const char* aName,
void* aClosure);
};

View File

@ -7,6 +7,7 @@
#ifndef nsCycleCollectionTraversalCallback_h__
#define nsCycleCollectionTraversalCallback_h__
#include "jspubtd.h"
#include "nsISupports.h"
class nsCycleCollectionParticipant;
@ -26,12 +27,13 @@ public:
uint64_t aCompartmentAddress = 0) = 0;
NS_IMETHOD_(void) NoteXPCOMChild(nsISupports* aChild) = 0;
NS_IMETHOD_(void) NoteJSChild(void* aChild) = 0;
NS_IMETHOD_(void) NoteJSObject(JSObject* aChild) = 0;
NS_IMETHOD_(void) NoteJSScript(JSScript* aChild) = 0;
NS_IMETHOD_(void) NoteNativeChild(void* aChild,
nsCycleCollectionParticipant* aHelper) = 0;
// Give a name to the edge associated with the next call to
// NoteXPCOMChild, NoteJSChild, or NoteNativeChild.
// NoteXPCOMChild, NoteJSObject, NoteJSScript, or NoteNativeChild.
// Callbacks who care about this should set WANT_DEBUG_INFO in the
// flags.
NS_IMETHOD_(void) NoteNextEdgeName(const char* aName) = 0;