diff -r 000000000000 -r 6474c204b198 xpcom/base/CycleCollectedJSRuntime.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/xpcom/base/CycleCollectedJSRuntime.h Wed Dec 31 06:09:35 2014 +0100 @@ -0,0 +1,247 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef mozilla_CycleCollectedJSRuntime_h__ +#define mozilla_CycleCollectedJSRuntime_h__ + +#include "mozilla/MemoryReporting.h" +#include "jsapi.h" + +#include "nsCycleCollector.h" +#include "nsCycleCollectionParticipant.h" +#include "nsDataHashtable.h" +#include "nsHashKeys.h" +#include "nsTArray.h" + +class nsCycleCollectionNoteRootCallback; +class nsIException; + +namespace js { +class Class; +} + +namespace mozilla { + +class JSGCThingParticipant: public nsCycleCollectionParticipant +{ +public: + NS_IMETHOD_(void) Root(void *n) + { + } + + NS_IMETHOD_(void) Unlink(void *n) + { + } + + NS_IMETHOD_(void) Unroot(void *n) + { + } + + NS_IMETHOD_(void) DeleteCycleCollectable(void *n) + { + } + + NS_IMETHOD Traverse(void *n, nsCycleCollectionTraversalCallback &cb); +}; + +class JSZoneParticipant : public nsCycleCollectionParticipant +{ +public: + MOZ_CONSTEXPR JSZoneParticipant(): nsCycleCollectionParticipant() {} + + NS_IMETHOD_(void) Root(void *p) + { + } + + NS_IMETHOD_(void) Unlink(void *p) + { + } + + NS_IMETHOD_(void) Unroot(void *p) + { + } + + NS_IMETHOD_(void) DeleteCycleCollectable(void *n) + { + } + + NS_IMETHOD Traverse(void *p, nsCycleCollectionTraversalCallback &cb); +}; + +class IncrementalFinalizeRunnable; + +// Contains various stats about the cycle collection. +struct CycleCollectorResults +{ + void Init() + { + mForcedGC = false; + mMergedZones = false; + mVisitedRefCounted = 0; + mVisitedGCed = 0; + mFreedRefCounted = 0; + mFreedGCed = 0; + } + + bool mForcedGC; + bool mMergedZones; + uint32_t mVisitedRefCounted; + uint32_t mVisitedGCed; + uint32_t mFreedRefCounted; + uint32_t mFreedGCed; +}; + +class CycleCollectedJSRuntime +{ + friend class JSGCThingParticipant; + friend class JSZoneParticipant; + friend class IncrementalFinalizeRunnable; +protected: + CycleCollectedJSRuntime(JSRuntime* aParentRuntime, + uint32_t aMaxbytes, + JSUseHelperThreads aUseHelperThreads); + virtual ~CycleCollectedJSRuntime(); + + size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const; + void UnmarkSkippableJSHolders(); + + virtual void TraverseAdditionalNativeRoots(nsCycleCollectionNoteRootCallback& aCb) {} + virtual void TraceAdditionalNativeGrayRoots(JSTracer* aTracer) {} + + virtual void CustomGCCallback(JSGCStatus aStatus) {} + virtual bool CustomContextCallback(JSContext* aCx, unsigned aOperation) + { + return true; // Don't block context creation. + } + +private: + + void + DescribeGCThing(bool aIsMarked, void* aThing, JSGCTraceKind aTraceKind, + nsCycleCollectionTraversalCallback& aCb) const; + + virtual bool + DescribeCustomObjects(JSObject* aObject, const js::Class* aClasp, + char (&aName)[72]) const + { + return false; // We did nothing. + } + + void + NoteGCThingJSChildren(void* aThing, JSGCTraceKind aTraceKind, + nsCycleCollectionTraversalCallback& aCb) const; + + void + NoteGCThingXPCOMChildren(const js::Class* aClasp, JSObject* aObj, + nsCycleCollectionTraversalCallback& aCb) const; + + virtual bool + NoteCustomGCThingXPCOMChildren(const js::Class* aClasp, JSObject* aObj, + nsCycleCollectionTraversalCallback& aCb) const + { + return false; // We did nothing. + } + + enum TraverseSelect { + TRAVERSE_CPP, + TRAVERSE_FULL + }; + + void + TraverseGCThing(TraverseSelect aTs, void* aThing, + JSGCTraceKind aTraceKind, + nsCycleCollectionTraversalCallback& aCb); + + void + TraverseZone(JS::Zone* aZone, nsCycleCollectionTraversalCallback& aCb); + + static void + TraverseObjectShim(void* aData, void* aThing); + + void TraverseNativeRoots(nsCycleCollectionNoteRootCallback& aCb); + + static void TraceBlackJS(JSTracer* aTracer, void* aData); + static void TraceGrayJS(JSTracer* aTracer, void* aData); + static void GCCallback(JSRuntime* aRuntime, JSGCStatus aStatus, void* aData); + static bool ContextCallback(JSContext* aCx, unsigned aOperation, + void* aData); + + virtual void TraceNativeBlackRoots(JSTracer* aTracer) { }; + void TraceNativeGrayRoots(JSTracer* aTracer); + + enum DeferredFinalizeType { + FinalizeIncrementally, + FinalizeNow, + }; + + void FinalizeDeferredThings(DeferredFinalizeType aType); + + void OnGC(JSGCStatus aStatus); + +public: + void AddJSHolder(void* aHolder, nsScriptObjectTracer* aTracer); + void RemoveJSHolder(void* aHolder); +#ifdef DEBUG + bool IsJSHolder(void* aHolder); + void AssertNoObjectsToTrace(void* aPossibleJSHolder); +#endif + + already_AddRefed GetPendingException() const; + void SetPendingException(nsIException* aException); + + nsCycleCollectionParticipant* GCThingParticipant(); + nsCycleCollectionParticipant* ZoneParticipant(); + + nsresult TraverseRoots(nsCycleCollectionNoteRootCallback &aCb); + bool UsefulToMergeZones() const; + void FixWeakMappingGrayBits() const; + bool NeedCollect() const; + void Collect(uint32_t reason) const; + + void DeferredFinalize(DeferredFinalizeAppendFunction aAppendFunc, + DeferredFinalizeFunction aFunc, + void* aThing); + void DeferredFinalize(nsISupports* aSupports); + + void DumpJSHeap(FILE* aFile); + + virtual void PrepareForForgetSkippable() = 0; + virtual void BeginCycleCollectionCallback() = 0; + virtual void EndCycleCollectionCallback(CycleCollectorResults &aResults) = 0; + virtual void DispatchDeferredDeletion(bool aContinuation) = 0; + + JSRuntime* Runtime() const + { + MOZ_ASSERT(mJSRuntime); + return mJSRuntime; + } + + // Get the current thread's CycleCollectedJSRuntime. Returns null if there + // isn't one. + static CycleCollectedJSRuntime* Get(); + +private: + JSGCThingParticipant mGCThingCycleCollectorGlobal; + + JSZoneParticipant mJSZoneCycleCollectorGlobal; + + JSRuntime* mJSRuntime; + + nsDataHashtable, nsScriptObjectTracer*> mJSHolders; + + nsTArray mDeferredSupports; + typedef nsDataHashtable, void*> + DeferredFinalizerTable; + DeferredFinalizerTable mDeferredFinalizerTable; + + nsRefPtr mFinalizeRunnable; + + nsCOMPtr mPendingException; +}; + +} // namespace mozilla + +#endif // mozilla_CycleCollectedJSRuntime_h__