mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-04 13:07:52 +00:00
Bug 1120016 - Allocate short lived JS wrappers in the Nursery, r=mccr8,terrence
This commit is contained in:
parent
ec729f14fe
commit
5ca565690e
@ -9,6 +9,7 @@
|
||||
#include "js/Class.h"
|
||||
#include "js/Proxy.h"
|
||||
#include "mozilla/dom/DOMJSProxyHandler.h"
|
||||
#include "mozilla/CycleCollectedJSRuntime.h"
|
||||
#include "mozilla/HoldDropJSObjects.h"
|
||||
#include "nsCycleCollectionTraversalCallback.h"
|
||||
#include "nsCycleCollector.h"
|
||||
@ -24,11 +25,25 @@ nsWrapperCache::HasJSObjectMovedOp(JSObject* aWrapper)
|
||||
}
|
||||
#endif
|
||||
|
||||
/* static */ void
|
||||
void
|
||||
nsWrapperCache::HoldJSObjects(void* aScriptObjectHolder,
|
||||
nsScriptObjectTracer* aTracer)
|
||||
{
|
||||
cyclecollector::HoldJSObjectsImpl(aScriptObjectHolder, aTracer);
|
||||
if (mWrapper && !JS::ObjectIsTenured(mWrapper)) {
|
||||
CycleCollectedJSRuntime::Get()->NurseryWrapperPreserved(mWrapper);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsWrapperCache::SetWrapperJSObject(JSObject* aWrapper)
|
||||
{
|
||||
mWrapper = aWrapper;
|
||||
UnsetWrapperFlags(kWrapperFlagsMask & ~WRAPPER_IS_NOT_DOM_BINDING);
|
||||
|
||||
if (aWrapper && !JS::ObjectIsTenured(aWrapper)) {
|
||||
CycleCollectedJSRuntime::Get()->NurseryWrapperAdded(this);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -258,14 +258,15 @@ protected:
|
||||
void TraceWrapper(JSTracer* aTrc, const char* name)
|
||||
{
|
||||
if (mWrapper) {
|
||||
JS_CallObjectTracer(aTrc, &mWrapper, name);
|
||||
JS_CallUnbarrieredObjectTracer(aTrc, &mWrapper, name);
|
||||
}
|
||||
}
|
||||
|
||||
void PoisonWrapper()
|
||||
{
|
||||
if (mWrapper) {
|
||||
mWrapper.setToCrashOnTouch();
|
||||
// See setToCrashOnTouch() in RootingAPI.h
|
||||
mWrapper = reinterpret_cast<JSObject*>(1);
|
||||
}
|
||||
}
|
||||
|
||||
@ -287,13 +288,7 @@ private:
|
||||
return mWrapper;
|
||||
}
|
||||
|
||||
void SetWrapperJSObject(JSObject* aWrapper)
|
||||
{
|
||||
mWrapper = aWrapper;
|
||||
UnsetWrapperFlags(kWrapperFlagsMask & ~WRAPPER_IS_NOT_DOM_BINDING);
|
||||
}
|
||||
|
||||
void TraceWrapperJSObject(JSTracer* aTrc, const char* aName);
|
||||
void SetWrapperJSObject(JSObject* aWrapper);
|
||||
|
||||
FlagsType GetWrapperFlags() const
|
||||
{
|
||||
@ -318,8 +313,8 @@ private:
|
||||
mFlags &= ~aFlagsToUnset;
|
||||
}
|
||||
|
||||
static void HoldJSObjects(void* aScriptObjectHolder,
|
||||
nsScriptObjectTracer* aTracer);
|
||||
void HoldJSObjects(void* aScriptObjectHolder,
|
||||
nsScriptObjectTracer* aTracer);
|
||||
|
||||
#ifdef DEBUG
|
||||
public:
|
||||
@ -349,8 +344,8 @@ private:
|
||||
|
||||
enum { kWrapperFlagsMask = (WRAPPER_BIT_PRESERVED | WRAPPER_IS_NOT_DOM_BINDING) };
|
||||
|
||||
JS::Heap<JSObject*> mWrapper;
|
||||
FlagsType mFlags;
|
||||
JSObject* mWrapper;
|
||||
FlagsType mFlags;
|
||||
};
|
||||
|
||||
enum { WRAPPER_CACHE_FLAGS_BITS_USED = 2 };
|
||||
|
@ -53,10 +53,4 @@ nsWrapperCache::IsBlackAndDoesNotNeedTracing(nsISupports* aThis)
|
||||
return IsBlack() && HasNothingToTrace(aThis);
|
||||
}
|
||||
|
||||
inline void
|
||||
nsWrapperCache::TraceWrapperJSObject(JSTracer* aTrc, const char* aName)
|
||||
{
|
||||
JS_CallObjectTracer(aTrc, &mWrapper, aName);
|
||||
}
|
||||
|
||||
#endif /* nsWrapperCache_h___ */
|
||||
|
@ -422,6 +422,8 @@ class CGDOMJSClass(CGThing):
|
||||
classFlags += "JSCLASS_HAS_RESERVED_SLOTS(%d)" % slotCount
|
||||
traceHook = 'nullptr'
|
||||
reservedSlots = slotCount
|
||||
if self.descriptor.interface.isProbablyShortLivingObject():
|
||||
classFlags += " | JSCLASS_SKIP_NURSERY_FINALIZE"
|
||||
if self.descriptor.interface.getExtendedAttribute("NeedResolve"):
|
||||
resolveHook = RESOLVE_HOOK_NAME
|
||||
mayResolveHook = MAY_RESOLVE_HOOK_NAME
|
||||
|
@ -564,6 +564,9 @@ class IDLExternalInterface(IDLObjectWithIdentifier, IDLExposureMixins):
|
||||
def isJSImplemented(self):
|
||||
return False
|
||||
|
||||
def isProbablyShortLivingObject(self):
|
||||
return False
|
||||
|
||||
def getNavigatorProperty(self):
|
||||
return None
|
||||
|
||||
@ -1408,7 +1411,8 @@ class IDLInterface(IDLObjectWithScope, IDLExposureMixins):
|
||||
identifier == "ChromeOnly" or
|
||||
identifier == "Unforgeable" or
|
||||
identifier == "UnsafeInPrerendering" or
|
||||
identifier == "LegacyEventInit"):
|
||||
identifier == "LegacyEventInit" or
|
||||
identifier == "ProbablyShortLivingObject"):
|
||||
# Known extended attributes that do not take values
|
||||
if not attr.noArguments():
|
||||
raise WebIDLError("[%s] must take no arguments" % identifier,
|
||||
@ -1522,6 +1526,14 @@ class IDLInterface(IDLObjectWithScope, IDLExposureMixins):
|
||||
def isJSImplemented(self):
|
||||
return bool(self.getJSImplementation())
|
||||
|
||||
def isProbablyShortLivingObject(self):
|
||||
current = self
|
||||
while current:
|
||||
if current.getExtendedAttribute("ProbablyShortLivingObject"):
|
||||
return True
|
||||
current = current.parent
|
||||
return False
|
||||
|
||||
def getNavigatorProperty(self):
|
||||
naviProp = self.getExtendedAttribute("NavigatorProperty")
|
||||
if not naviProp:
|
||||
|
@ -237,9 +237,6 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
JSObject*
|
||||
Event::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
|
||||
{
|
||||
if (mIsMainThreadEvent && !GetWrapperPreserveColor()) {
|
||||
nsJSContext::LikelyShortLivingObjectCreated();
|
||||
}
|
||||
return WrapObjectInternal(aCx, aGivenProto);
|
||||
}
|
||||
|
||||
|
@ -11,7 +11,7 @@
|
||||
*/
|
||||
|
||||
[Constructor(DOMString type, optional EventInit eventInitDict),
|
||||
Exposed=(Window,Worker,System)]
|
||||
Exposed=(Window,Worker,System), ProbablyShortLivingObject]
|
||||
interface Event {
|
||||
[Pure]
|
||||
readonly attribute DOMString type;
|
||||
|
@ -7,6 +7,7 @@
|
||||
* http://dom.spec.whatwg.org
|
||||
*/
|
||||
|
||||
[ProbablyShortLivingObject]
|
||||
interface MutationRecord {
|
||||
[Constant]
|
||||
readonly attribute DOMString type;
|
||||
|
@ -78,7 +78,8 @@ var ignoreCallees = {
|
||||
"z_stream_s.zfree" : true,
|
||||
"GrGLInterface.fCallback" : true,
|
||||
"std::strstreambuf._M_alloc_fun" : true,
|
||||
"std::strstreambuf._M_free_fun" : true
|
||||
"std::strstreambuf._M_free_fun" : true,
|
||||
"struct js::gc::Callback<void (*)(JSRuntime*, void*)>.op" : true,
|
||||
};
|
||||
|
||||
function fieldCallCannotGC(csu, fullfield)
|
||||
@ -187,6 +188,9 @@ var ignoreFunctions = {
|
||||
"void test::RingbufferDumper::OnTestPartResult(testing::TestPartResult*)" : true,
|
||||
|
||||
"float64 JS_GetCurrentEmbedderTime()" : true,
|
||||
|
||||
"uint64 js::TenuringTracer::moveObjectToTenured(JSObject*, JSObject*, int32)" : true,
|
||||
"uint32 js::TenuringTracer::moveObjectToTenured(JSObject*, JSObject*, int32)" : true,
|
||||
};
|
||||
|
||||
function isProtobuf(name)
|
||||
|
@ -756,6 +756,9 @@ class GCRuntime
|
||||
|
||||
void setGCCallback(JSGCCallback callback, void* data);
|
||||
void callGCCallback(JSGCStatus status) const;
|
||||
void setObjectsTenuredCallback(JSObjectsTenuredCallback callback,
|
||||
void* data);
|
||||
void callObjectsTenuredCallback();
|
||||
bool addFinalizeCallback(JSFinalizeCallback callback, void* data);
|
||||
void removeFinalizeCallback(JSFinalizeCallback func);
|
||||
bool addWeakPointerZoneGroupCallback(JSWeakPointerZoneGroupCallback callback, void* data);
|
||||
@ -1273,6 +1276,7 @@ class GCRuntime
|
||||
bool fullCompartmentChecks;
|
||||
|
||||
Callback<JSGCCallback> gcCallback;
|
||||
Callback<JSObjectsTenuredCallback> tenuredCallback;
|
||||
CallbackVector<JSFinalizeCallback> finalizeCallbacks;
|
||||
CallbackVector<JSWeakPointerZoneGroupCallback> updateWeakPointerZoneGroupCallbacks;
|
||||
CallbackVector<JSWeakPointerCompartmentCallback> updateWeakPointerCompartmentCallbacks;
|
||||
|
@ -2215,6 +2215,8 @@ js::TenuringTracer::moveObjectToTenured(JSObject* dst, JSObject* src, AllocKind
|
||||
tenuredSize += UnboxedArrayObject::objectMovedDuringMinorGC(this, dst, src, dstKind);
|
||||
} else if (src->is<ArgumentsObject>()) {
|
||||
tenuredSize += ArgumentsObject::objectMovedDuringMinorGC(this, dst, src);
|
||||
} else if (JSObjectMovedOp op = dst->getClass()->ext.objectMovedOp) {
|
||||
op(dst, src);
|
||||
} else {
|
||||
// Objects with JSCLASS_SKIP_NURSERY_FINALIZE need to be handled above
|
||||
// to ensure any additional nursery buffers they hold are moved.
|
||||
|
@ -496,6 +496,10 @@ js::Nursery::collect(JSRuntime* rt, JS::gcreason::Reason reason, ObjectGroupList
|
||||
forwardedBuffers.finish();
|
||||
TIME_END(updateJitActivations);
|
||||
|
||||
TIME_START(objectsTenuredCallback);
|
||||
rt->gc.callObjectsTenuredCallback();
|
||||
TIME_END(objectsTenuredCallback);
|
||||
|
||||
// Sweep.
|
||||
TIME_START(freeMallocedBuffers);
|
||||
freeMallocedBuffers();
|
||||
@ -576,6 +580,7 @@ js::Nursery::collect(JSRuntime* rt, JS::gcreason::Reason reason, ObjectGroupList
|
||||
{"mkDbgr", TIME_TOTAL(markDebugger)},
|
||||
{"clrNOC", TIME_TOTAL(clearNewObjectCache)},
|
||||
{"collct", TIME_TOTAL(collectToFP)},
|
||||
{" tenCB", TIME_TOTAL(objectsTenuredCallback)},
|
||||
{"swpABO", TIME_TOTAL(sweepArrayBufferViewList)},
|
||||
{"updtIn", TIME_TOTAL(updateJitActivations)},
|
||||
{"frSlts", TIME_TOTAL(freeMallocedBuffers)},
|
||||
|
@ -1395,6 +1395,14 @@ JS_SetGCCallback(JSRuntime* rt, JSGCCallback cb, void* data)
|
||||
rt->gc.setGCCallback(cb, data);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(void)
|
||||
JS_SetObjectsTenuredCallback(JSRuntime* rt, JSObjectsTenuredCallback cb,
|
||||
void* data)
|
||||
{
|
||||
AssertHeapIsIdle(rt);
|
||||
rt->gc.setObjectsTenuredCallback(cb, data);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(bool)
|
||||
JS_AddFinalizeCallback(JSRuntime* rt, JSFinalizeCallback cb, void* data)
|
||||
{
|
||||
|
@ -572,6 +572,9 @@ typedef enum JSGCStatus {
|
||||
typedef void
|
||||
(* JSGCCallback)(JSRuntime* rt, JSGCStatus status, void* data);
|
||||
|
||||
typedef void
|
||||
(* JSObjectsTenuredCallback)(JSRuntime* rt, void* data);
|
||||
|
||||
typedef enum JSFinalizeStatus {
|
||||
/**
|
||||
* Called when preparing to sweep a group of compartments, before anything
|
||||
@ -1654,6 +1657,10 @@ JS_MaybeGC(JSContext* cx);
|
||||
extern JS_PUBLIC_API(void)
|
||||
JS_SetGCCallback(JSRuntime* rt, JSGCCallback cb, void* data);
|
||||
|
||||
extern JS_PUBLIC_API(void)
|
||||
JS_SetObjectsTenuredCallback(JSRuntime* rt, JSObjectsTenuredCallback cb,
|
||||
void* data);
|
||||
|
||||
extern JS_PUBLIC_API(bool)
|
||||
JS_AddFinalizeCallback(JSRuntime* rt, JSFinalizeCallback cb, void* data);
|
||||
|
||||
|
@ -1606,6 +1606,21 @@ GCRuntime::callGCCallback(JSGCStatus status) const
|
||||
gcCallback.op(rt, status, gcCallback.data);
|
||||
}
|
||||
|
||||
void
|
||||
GCRuntime::setObjectsTenuredCallback(JSObjectsTenuredCallback callback,
|
||||
void* data)
|
||||
{
|
||||
tenuredCallback.op = callback;
|
||||
tenuredCallback.data = data;
|
||||
}
|
||||
|
||||
void
|
||||
GCRuntime::callObjectsTenuredCallback()
|
||||
{
|
||||
if (tenuredCallback.op)
|
||||
tenuredCallback.op(rt, tenuredCallback.data);
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
class AutoNotifyGCActivity {
|
||||
|
@ -73,6 +73,7 @@
|
||||
#include "nsCycleCollector.h"
|
||||
#include "nsDOMJSUtils.h"
|
||||
#include "nsJSUtils.h"
|
||||
#include "nsWrapperCache.h"
|
||||
|
||||
#ifdef MOZ_CRASHREPORTER
|
||||
#include "nsExceptionHandler.h"
|
||||
@ -397,6 +398,12 @@ NoteJSChildGrayWrapperShim(void* aData, JS::GCCellPtr aThing)
|
||||
// CycleCollectedJSRuntime. It should never be used directly.
|
||||
static const JSZoneParticipant sJSZoneCycleCollectorGlobal;
|
||||
|
||||
static
|
||||
void JSObjectsTenuredCb(JSRuntime* aRuntime, void* aData)
|
||||
{
|
||||
static_cast<CycleCollectedJSRuntime*>(aData)->JSObjectsTenured(aRuntime);
|
||||
}
|
||||
|
||||
CycleCollectedJSRuntime::CycleCollectedJSRuntime(JSRuntime* aParentRuntime,
|
||||
uint32_t aMaxBytes,
|
||||
uint32_t aMaxNurseryBytes)
|
||||
@ -430,6 +437,7 @@ CycleCollectedJSRuntime::CycleCollectedJSRuntime(JSRuntime* aParentRuntime,
|
||||
JS_SetGrayGCRootsTracer(mJSRuntime, TraceGrayJS, this);
|
||||
JS_SetGCCallback(mJSRuntime, GCCallback, this);
|
||||
mPrevGCSliceCallback = JS::SetGCSliceCallback(mJSRuntime, GCSliceCallback);
|
||||
JS_SetObjectsTenuredCallback(mJSRuntime, JSObjectsTenuredCb, this);
|
||||
JS::SetOutOfMemoryCallback(mJSRuntime, OutOfMemoryCallback, this);
|
||||
JS::SetLargeAllocationFailureCallback(mJSRuntime,
|
||||
LargeAllocationFailureCallback, this);
|
||||
@ -785,6 +793,11 @@ struct JsGcTracer : public TraceCallbacks
|
||||
{
|
||||
JS_CallObjectTracer(static_cast<JSTracer*>(aClosure), aPtr, aName);
|
||||
}
|
||||
virtual void Trace(JSObject** aPtr, const char* aName,
|
||||
void* aClosure) const override
|
||||
{
|
||||
JS_CallUnbarrieredObjectTracer(static_cast<JSTracer*>(aClosure), aPtr, aName);
|
||||
}
|
||||
virtual void Trace(JS::TenuredHeap<JSObject*>* aPtr, const char* aName,
|
||||
void* aClosure) const override
|
||||
{
|
||||
@ -852,6 +865,12 @@ struct ClearJSHolder : TraceCallbacks
|
||||
*aPtr = nullptr;
|
||||
}
|
||||
|
||||
virtual void Trace(JSObject** aPtr, const char* aName,
|
||||
void* aClosure) const override
|
||||
{
|
||||
*aPtr = nullptr;
|
||||
}
|
||||
|
||||
virtual void Trace(JS::TenuredHeap<JSObject*>* aPtr, const char*, void*) const override
|
||||
{
|
||||
*aPtr = nullptr;
|
||||
@ -1008,6 +1027,46 @@ CycleCollectedJSRuntime::GarbageCollect(uint32_t aReason) const
|
||||
JS::GCForReason(mJSRuntime, GC_NORMAL, gcreason);
|
||||
}
|
||||
|
||||
void
|
||||
CycleCollectedJSRuntime::JSObjectsTenured(JSRuntime* aRuntime)
|
||||
{
|
||||
for (auto iter = mNurseryObjects.Iter(); !iter.Done(); iter.Next()) {
|
||||
nsWrapperCache* cache = iter.Get();
|
||||
JSObject* wrapper = cache->GetWrapperPreserveColor();
|
||||
MOZ_ASSERT(wrapper);
|
||||
if (!JS::ObjectIsTenured(wrapper)) {
|
||||
MOZ_ASSERT(!cache->PreservingWrapper());
|
||||
const JSClass* jsClass = js::GetObjectJSClass(wrapper);
|
||||
jsClass->finalize(nullptr, wrapper);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
for (auto iter = mPreservedNurseryObjects.Iter(); !iter.Done(); iter.Next()) {
|
||||
MOZ_ASSERT(JS::ObjectIsTenured(iter.Get().get()));
|
||||
}
|
||||
#endif
|
||||
|
||||
mNurseryObjects.Clear();
|
||||
mPreservedNurseryObjects.Clear();
|
||||
}
|
||||
|
||||
void
|
||||
CycleCollectedJSRuntime::NurseryWrapperAdded(nsWrapperCache* aCache)
|
||||
{
|
||||
MOZ_ASSERT(aCache);
|
||||
MOZ_ASSERT(aCache->GetWrapperPreserveColor());
|
||||
MOZ_ASSERT(!JS::ObjectIsTenured(aCache->GetWrapperPreserveColor()));
|
||||
mNurseryObjects.InfallibleAppend(aCache);
|
||||
}
|
||||
|
||||
void
|
||||
CycleCollectedJSRuntime::NurseryWrapperPreserved(JSObject* aWrapper)
|
||||
{
|
||||
mPreservedNurseryObjects.InfallibleAppend(
|
||||
JS::PersistentRooted<JSObject*>(mJSRuntime, aWrapper));
|
||||
}
|
||||
|
||||
void
|
||||
CycleCollectedJSRuntime::DeferredFinalize(DeferredFinalizeAppendFunction aAppendFunc,
|
||||
DeferredFinalizeFunction aFunc,
|
||||
|
@ -10,7 +10,9 @@
|
||||
#include <queue>
|
||||
|
||||
#include "mozilla/DeferredFinalize.h"
|
||||
#include "mozilla/mozalloc.h"
|
||||
#include "mozilla/MemoryReporting.h"
|
||||
#include "mozilla/SegmentedVector.h"
|
||||
#include "jsapi.h"
|
||||
|
||||
#include "nsCycleCollectionParticipant.h"
|
||||
@ -22,6 +24,7 @@ class nsCycleCollectionNoteRootCallback;
|
||||
class nsIException;
|
||||
class nsIRunnable;
|
||||
class nsThread;
|
||||
class nsWrapperCache;
|
||||
|
||||
namespace js {
|
||||
struct Class;
|
||||
@ -280,6 +283,10 @@ public:
|
||||
bool AreGCGrayBitsValid() const;
|
||||
void GarbageCollect(uint32_t aReason) const;
|
||||
|
||||
void NurseryWrapperAdded(nsWrapperCache* aCache);
|
||||
void NurseryWrapperPreserved(JSObject* aWrapper);
|
||||
void JSObjectsTenured(JSRuntime* aRuntime);
|
||||
|
||||
void DeferredFinalize(DeferredFinalizeAppendFunction aAppendFunc,
|
||||
DeferredFinalizeFunction aFunc,
|
||||
void* aThing);
|
||||
@ -361,6 +368,13 @@ private:
|
||||
|
||||
OOMState mOutOfMemoryState;
|
||||
OOMState mLargeAllocationFailureState;
|
||||
|
||||
static const size_t kSegmentSize = 512;
|
||||
SegmentedVector<nsWrapperCache*, kSegmentSize, InfallibleAllocPolicy>
|
||||
mNurseryObjects;
|
||||
SegmentedVector<JS::PersistentRooted<JSObject*>, kSegmentSize,
|
||||
InfallibleAllocPolicy>
|
||||
mPreservedNurseryObjects;
|
||||
};
|
||||
|
||||
void TraceScriptHolder(nsISupports* aHolder, JSTracer* aTracer);
|
||||
|
@ -2677,7 +2677,7 @@ public:
|
||||
}
|
||||
|
||||
virtual void Trace(JS::Heap<JS::Value>* aValue, const char* aName,
|
||||
void* aClosure) const
|
||||
void* aClosure) const override
|
||||
{
|
||||
if (aValue->isMarkable() && ValueIsGrayCCThing(*aValue)) {
|
||||
MOZ_ASSERT(!js::gc::IsInsideNursery(aValue->toGCThing()));
|
||||
@ -2686,7 +2686,7 @@ public:
|
||||
}
|
||||
|
||||
virtual void Trace(JS::Heap<jsid>* aId, const char* aName,
|
||||
void* aClosure) const
|
||||
void* aClosure) const override
|
||||
{
|
||||
}
|
||||
|
||||
@ -2699,29 +2699,35 @@ public:
|
||||
}
|
||||
|
||||
virtual void Trace(JS::Heap<JSObject*>* aObject, const char* aName,
|
||||
void* aClosure) const
|
||||
void* aClosure) const override
|
||||
{
|
||||
AppendJSObjectToPurpleBuffer(*aObject);
|
||||
}
|
||||
|
||||
virtual void Trace(JSObject** aObject, const char* aName,
|
||||
void* aClosure) const override
|
||||
{
|
||||
AppendJSObjectToPurpleBuffer(*aObject);
|
||||
}
|
||||
|
||||
virtual void Trace(JS::TenuredHeap<JSObject*>* aObject, const char* aName,
|
||||
void* aClosure) const
|
||||
void* aClosure) const override
|
||||
{
|
||||
AppendJSObjectToPurpleBuffer(*aObject);
|
||||
}
|
||||
|
||||
virtual void Trace(JS::Heap<JSString*>* aString, const char* aName,
|
||||
void* aClosure) const
|
||||
void* aClosure) const override
|
||||
{
|
||||
}
|
||||
|
||||
virtual void Trace(JS::Heap<JSScript*>* aScript, const char* aName,
|
||||
void* aClosure) const
|
||||
void* aClosure) const override
|
||||
{
|
||||
}
|
||||
|
||||
virtual void Trace(JS::Heap<JSFunction*>* aFunction, const char* aName,
|
||||
void* aClosure) const
|
||||
void* aClosure) const override
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -61,6 +61,13 @@ TraceCallbackFunc::Trace(JS::Heap<JSObject*>* aPtr, const char* aName,
|
||||
mCallback(JS::GCCellPtr(aPtr->get()), aName, aClosure);
|
||||
}
|
||||
|
||||
void
|
||||
TraceCallbackFunc::Trace(JSObject** aPtr, const char* aName,
|
||||
void* aClosure) const
|
||||
{
|
||||
mCallback(JS::GCCellPtr(*aPtr), aName, aClosure);
|
||||
}
|
||||
|
||||
void
|
||||
TraceCallbackFunc::Trace(JS::TenuredHeap<JSObject*>* aPtr, const char* aName,
|
||||
void* aClosure) const
|
||||
|
@ -64,6 +64,8 @@ struct TraceCallbacks
|
||||
void* aClosure) const = 0;
|
||||
virtual void Trace(JS::Heap<JSObject*>* aPtr, const char* aName,
|
||||
void* aClosure) const = 0;
|
||||
virtual void Trace(JSObject** aPtr, const char* aName,
|
||||
void* aClosure) const = 0;
|
||||
virtual void Trace(JS::TenuredHeap<JSObject*>* aPtr, const char* aName,
|
||||
void* aClosure) const = 0;
|
||||
virtual void Trace(JS::Heap<JSString*>* aPtr, const char* aName,
|
||||
@ -90,6 +92,8 @@ struct TraceCallbackFunc : public TraceCallbacks
|
||||
void* aClosure) const override;
|
||||
virtual void Trace(JS::Heap<JSObject*>* aPtr, const char* aName,
|
||||
void* aClosure) const override;
|
||||
virtual void Trace(JSObject** aPtr, const char* aName,
|
||||
void* aClosure) const override;
|
||||
virtual void Trace(JS::TenuredHeap<JSObject*>* aPtr, const char* aName,
|
||||
void* aClosure) const override;
|
||||
virtual void Trace(JS::Heap<JSString*>* aPtr, const char* aName,
|
||||
|
Loading…
x
Reference in New Issue
Block a user