зеркало из https://github.com/mozilla/gecko-dev.git
Bug 751618 - Add js/GCAPI.h (r=terrence)
This commit is contained in:
Родитель
a0c5a1f359
Коммит
f192791e29
|
@ -13,6 +13,7 @@
|
|||
#include "nsIProgrammingLanguage.h"
|
||||
#include "jsfriendapi.h"
|
||||
#include "jspubtd.h"
|
||||
#include "js/GCAPI.h"
|
||||
|
||||
class nsIScriptGlobalObject;
|
||||
class nsIScriptSecurityManager;
|
||||
|
@ -201,7 +202,7 @@ public:
|
|||
*
|
||||
* @return NS_OK if the method is successful
|
||||
*/
|
||||
virtual void GC(js::gcreason::Reason aReason) = 0;
|
||||
virtual void GC(JS::gcreason::Reason aReason) = 0;
|
||||
|
||||
/**
|
||||
* Inform the context that a script was evaluated.
|
||||
|
|
|
@ -146,7 +146,7 @@ static PRTime sLastCCEndTime;
|
|||
static bool sCCLockedOut;
|
||||
static PRTime sCCLockedOutTime;
|
||||
|
||||
static js::GCSliceCallback sPrevGCSliceCallback;
|
||||
static JS::GCSliceCallback sPrevGCSliceCallback;
|
||||
static js::AnalysisPurgeCallback sPrevAnalysisPurgeCallback;
|
||||
|
||||
// The number of currently pending document loads. This count isn't
|
||||
|
@ -235,7 +235,7 @@ nsJSEnvironmentObserver::Observe(nsISupports* aSubject, const char* aTopic,
|
|||
const PRUnichar* aData)
|
||||
{
|
||||
if (sGCOnMemoryPressure && !nsCRT::strcmp(aTopic, "memory-pressure")) {
|
||||
nsJSContext::GarbageCollectNow(js::gcreason::MEM_PRESSURE,
|
||||
nsJSContext::GarbageCollectNow(JS::gcreason::MEM_PRESSURE,
|
||||
nsJSContext::NonIncrementalGC,
|
||||
nsJSContext::NonCompartmentGC,
|
||||
nsJSContext::ShrinkingGC);
|
||||
|
@ -1181,7 +1181,7 @@ nsJSContext::DestroyJSContext()
|
|||
js_options_dot_str, this);
|
||||
|
||||
if (mGCOnDestruction) {
|
||||
PokeGC(js::gcreason::NSJSCONTEXT_DESTROY);
|
||||
PokeGC(JS::gcreason::NSJSCONTEXT_DESTROY);
|
||||
}
|
||||
|
||||
// Let xpconnect destroy the JSContext when it thinks the time is right.
|
||||
|
@ -2536,13 +2536,13 @@ FullGCTimerFired(nsITimer* aTimer, void* aClosure)
|
|||
NS_RELEASE(sFullGCTimer);
|
||||
|
||||
uintptr_t reason = reinterpret_cast<uintptr_t>(aClosure);
|
||||
nsJSContext::GarbageCollectNow(static_cast<js::gcreason::Reason>(reason),
|
||||
nsJSContext::GarbageCollectNow(static_cast<JS::gcreason::Reason>(reason),
|
||||
nsJSContext::IncrementalGC);
|
||||
}
|
||||
|
||||
//static
|
||||
void
|
||||
nsJSContext::GarbageCollectNow(js::gcreason::Reason aReason,
|
||||
nsJSContext::GarbageCollectNow(JS::gcreason::Reason aReason,
|
||||
IsIncremental aIncremental,
|
||||
IsCompartment aCompartment,
|
||||
IsShrinking aShrinking,
|
||||
|
@ -2570,8 +2570,8 @@ nsJSContext::GarbageCollectNow(js::gcreason::Reason aReason,
|
|||
|
||||
if (sCCLockedOut && aIncremental == IncrementalGC) {
|
||||
// We're in the middle of incremental GC. Do another slice.
|
||||
js::PrepareForIncrementalGC(nsJSRuntime::sRuntime);
|
||||
js::IncrementalGC(nsJSRuntime::sRuntime, aReason, aSliceMillis);
|
||||
JS::PrepareForIncrementalGC(nsJSRuntime::sRuntime);
|
||||
JS::IncrementalGC(nsJSRuntime::sRuntime, aReason, aSliceMillis);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -2581,20 +2581,20 @@ nsJSContext::GarbageCollectNow(js::gcreason::Reason aReason,
|
|||
if (!sDisableExplicitCompartmentGC &&
|
||||
aShrinking != ShrinkingGC && aCompartment != NonCompartmentGC &&
|
||||
sCompartmentGCCount < NS_MAX_COMPARTMENT_GC_COUNT) {
|
||||
js::PrepareForFullGC(nsJSRuntime::sRuntime);
|
||||
JS::PrepareForFullGC(nsJSRuntime::sRuntime);
|
||||
for (nsJSContext* cx = sContextList; cx; cx = cx->mNext) {
|
||||
if (!cx->mActive && cx->mContext) {
|
||||
if (JSObject* global = cx->GetNativeGlobal()) {
|
||||
js::SkipCompartmentForGC(js::GetObjectCompartment(global));
|
||||
JS::SkipCompartmentForGC(js::GetObjectCompartment(global));
|
||||
}
|
||||
}
|
||||
cx->mActive = false;
|
||||
}
|
||||
if (js::IsGCScheduled(nsJSRuntime::sRuntime)) {
|
||||
if (JS::IsGCScheduled(nsJSRuntime::sRuntime)) {
|
||||
if (aIncremental == IncrementalGC) {
|
||||
js::IncrementalGC(nsJSRuntime::sRuntime, aReason, aSliceMillis);
|
||||
JS::IncrementalGC(nsJSRuntime::sRuntime, aReason, aSliceMillis);
|
||||
} else {
|
||||
js::GCForReason(nsJSRuntime::sRuntime, aReason);
|
||||
JS::GCForReason(nsJSRuntime::sRuntime, aReason);
|
||||
}
|
||||
}
|
||||
return;
|
||||
|
@ -2603,11 +2603,11 @@ nsJSContext::GarbageCollectNow(js::gcreason::Reason aReason,
|
|||
for (nsJSContext* cx = sContextList; cx; cx = cx->mNext) {
|
||||
cx->mActive = false;
|
||||
}
|
||||
js::PrepareForFullGC(nsJSRuntime::sRuntime);
|
||||
JS::PrepareForFullGC(nsJSRuntime::sRuntime);
|
||||
if (aIncremental == IncrementalGC) {
|
||||
js::IncrementalGC(nsJSRuntime::sRuntime, aReason, aSliceMillis);
|
||||
JS::IncrementalGC(nsJSRuntime::sRuntime, aReason, aSliceMillis);
|
||||
} else {
|
||||
js::GCForReason(nsJSRuntime::sRuntime, aReason);
|
||||
JS::GCForReason(nsJSRuntime::sRuntime, aReason);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2619,7 +2619,7 @@ nsJSContext::ShrinkGCBuffersNow()
|
|||
|
||||
KillShrinkGCBuffersTimer();
|
||||
|
||||
JS_ShrinkGCBuffers(nsJSRuntime::sRuntime);
|
||||
JS::ShrinkGCBuffers(nsJSRuntime::sRuntime);
|
||||
}
|
||||
|
||||
// Return true if any JSContext has a "global object" with a gray
|
||||
|
@ -2636,7 +2636,7 @@ AnyGrayGlobalParent()
|
|||
while ((cx = JS_ContextIterator(nsJSRuntime::sRuntime, &iter))) {
|
||||
if (JSObject *global = JS_GetGlobalObject(cx)) {
|
||||
if (JSObject *parent = js::GetObjectParent(global)) {
|
||||
if (js::GCThingIsMarkedGray(parent) &&
|
||||
if (JS::GCThingIsMarkedGray(parent) &&
|
||||
!js::IsSystemCompartment(js::GetGCThingCompartment(parent))) {
|
||||
return true;
|
||||
}
|
||||
|
@ -2686,8 +2686,8 @@ FinishAnyIncrementalGC()
|
|||
{
|
||||
if (sCCLockedOut) {
|
||||
// We're in the middle of an incremental GC, so finish it.
|
||||
js::PrepareForIncrementalGC(nsJSRuntime::sRuntime);
|
||||
js::FinishIncrementalGC(nsJSRuntime::sRuntime, js::gcreason::CC_FORCED);
|
||||
JS::PrepareForIncrementalGC(nsJSRuntime::sRuntime);
|
||||
JS::FinishIncrementalGC(nsJSRuntime::sRuntime, JS::gcreason::CC_FORCED);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2770,7 +2770,7 @@ nsJSContext::CycleCollectNow(nsICycleCollectorListener *aListener,
|
|||
// If we collected a substantial amount of cycles, poke the GC since more objects
|
||||
// might be unreachable now.
|
||||
if (sCCollectedWaitingForGC > 250) {
|
||||
PokeGC(js::gcreason::CC_WAITING);
|
||||
PokeGC(JS::gcreason::CC_WAITING);
|
||||
}
|
||||
|
||||
PRTime endCCTime = PR_Now();
|
||||
|
@ -2888,7 +2888,7 @@ void
|
|||
InterSliceGCTimerFired(nsITimer *aTimer, void *aClosure)
|
||||
{
|
||||
NS_RELEASE(sInterSliceGCTimer);
|
||||
nsJSContext::GarbageCollectNow(js::gcreason::INTER_SLICE_GC,
|
||||
nsJSContext::GarbageCollectNow(JS::gcreason::INTER_SLICE_GC,
|
||||
nsJSContext::IncrementalGC,
|
||||
nsJSContext::CompartmentGC,
|
||||
nsJSContext::NonShrinkingGC,
|
||||
|
@ -2902,7 +2902,7 @@ GCTimerFired(nsITimer *aTimer, void *aClosure)
|
|||
NS_RELEASE(sGCTimer);
|
||||
|
||||
uintptr_t reason = reinterpret_cast<uintptr_t>(aClosure);
|
||||
nsJSContext::GarbageCollectNow(static_cast<js::gcreason::Reason>(reason),
|
||||
nsJSContext::GarbageCollectNow(static_cast<JS::gcreason::Reason>(reason),
|
||||
nsJSContext::IncrementalGC,
|
||||
nsJSContext::CompartmentGC);
|
||||
}
|
||||
|
@ -3019,12 +3019,12 @@ nsJSContext::LoadEnd()
|
|||
|
||||
// Its probably a good idea to GC soon since we have finished loading.
|
||||
sLoadingInProgress = false;
|
||||
PokeGC(js::gcreason::LOAD_END);
|
||||
PokeGC(JS::gcreason::LOAD_END);
|
||||
}
|
||||
|
||||
// static
|
||||
void
|
||||
nsJSContext::PokeGC(js::gcreason::Reason aReason, int aDelay)
|
||||
nsJSContext::PokeGC(JS::gcreason::Reason aReason, int aDelay)
|
||||
{
|
||||
if (sGCTimer || sShuttingDown) {
|
||||
// There's already a timer for GC'ing, just return
|
||||
|
@ -3145,7 +3145,7 @@ nsJSContext::KillCCTimer()
|
|||
}
|
||||
|
||||
void
|
||||
nsJSContext::GC(js::gcreason::Reason aReason)
|
||||
nsJSContext::GC(JS::gcreason::Reason aReason)
|
||||
{
|
||||
mActive = true;
|
||||
PokeGC(aReason);
|
||||
|
@ -3179,11 +3179,11 @@ NotifyGCEndRunnable::Run()
|
|||
}
|
||||
|
||||
static void
|
||||
DOMGCSliceCallback(JSRuntime *aRt, js::GCProgress aProgress, const js::GCDescription &aDesc)
|
||||
DOMGCSliceCallback(JSRuntime *aRt, JS::GCProgress aProgress, const JS::GCDescription &aDesc)
|
||||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "GCs must run on the main thread");
|
||||
|
||||
if (aProgress == js::GC_CYCLE_END) {
|
||||
if (aProgress == JS::GC_CYCLE_END) {
|
||||
PRTime delta = GetCollectionTimeDelta();
|
||||
|
||||
if (sPostGCEventsToConsole) {
|
||||
|
@ -3208,15 +3208,15 @@ DOMGCSliceCallback(JSRuntime *aRt, js::GCProgress aProgress, const js::GCDescrip
|
|||
}
|
||||
|
||||
// Prevent cycle collections and shrinking during incremental GC.
|
||||
if (aProgress == js::GC_CYCLE_BEGIN) {
|
||||
if (aProgress == JS::GC_CYCLE_BEGIN) {
|
||||
sCCLockedOut = true;
|
||||
nsJSContext::KillShrinkGCBuffersTimer();
|
||||
} else if (aProgress == js::GC_CYCLE_END) {
|
||||
} else if (aProgress == JS::GC_CYCLE_END) {
|
||||
sCCLockedOut = false;
|
||||
}
|
||||
|
||||
// The GC has more work to do, so schedule another GC slice.
|
||||
if (aProgress == js::GC_SLICE_END) {
|
||||
if (aProgress == JS::GC_SLICE_END) {
|
||||
nsJSContext::KillInterSliceGCTimer();
|
||||
if (!sShuttingDown) {
|
||||
CallCreateInstance("@mozilla.org/timer;1", &sInterSliceGCTimer);
|
||||
|
@ -3227,7 +3227,7 @@ DOMGCSliceCallback(JSRuntime *aRt, js::GCProgress aProgress, const js::GCDescrip
|
|||
}
|
||||
}
|
||||
|
||||
if (aProgress == js::GC_CYCLE_END) {
|
||||
if (aProgress == JS::GC_CYCLE_END) {
|
||||
// May need to kill the inter-slice GC timer
|
||||
nsJSContext::KillInterSliceGCTimer();
|
||||
|
||||
|
@ -3240,7 +3240,7 @@ DOMGCSliceCallback(JSRuntime *aRt, js::GCProgress aProgress, const js::GCDescrip
|
|||
++sCompartmentGCCount;
|
||||
if (!sFullGCTimer && !sShuttingDown) {
|
||||
CallCreateInstance("@mozilla.org/timer;1", &sFullGCTimer);
|
||||
js::gcreason::Reason reason = js::gcreason::FULL_GC_TIMER;
|
||||
JS::gcreason::Reason reason = JS::gcreason::FULL_GC_TIMER;
|
||||
sFullGCTimer->InitWithFuncCallback(FullGCTimerFired,
|
||||
reinterpret_cast<void *>(reason),
|
||||
NS_FULL_GC_DELAY,
|
||||
|
@ -3567,7 +3567,7 @@ nsJSRuntime::Init()
|
|||
// Let's make sure that our main thread is the same as the xpcom main thread.
|
||||
NS_ASSERTION(NS_IsMainThread(), "bad");
|
||||
|
||||
sPrevGCSliceCallback = js::SetGCSliceCallback(sRuntime, DOMGCSliceCallback);
|
||||
sPrevGCSliceCallback = JS::SetGCSliceCallback(sRuntime, DOMGCSliceCallback);
|
||||
sPrevAnalysisPurgeCallback = js::SetAnalysisPurgeCallback(sRuntime, DOMAnalysisPurgeCallback);
|
||||
|
||||
// Set up the structured clone callbacks.
|
||||
|
|
|
@ -125,7 +125,7 @@ public:
|
|||
NonIncrementalGC
|
||||
};
|
||||
|
||||
static void GarbageCollectNow(js::gcreason::Reason reason,
|
||||
static void GarbageCollectNow(JS::gcreason::Reason reason,
|
||||
IsIncremental aIncremental = NonIncrementalGC,
|
||||
IsCompartment aCompartment = NonCompartmentGC,
|
||||
IsShrinking aShrinking = NonShrinkingGC,
|
||||
|
@ -137,7 +137,7 @@ public:
|
|||
int32_t aExtraForgetSkippableCalls = 0,
|
||||
bool aForced = true);
|
||||
|
||||
static void PokeGC(js::gcreason::Reason aReason, int aDelay = 0);
|
||||
static void PokeGC(JS::gcreason::Reason aReason, int aDelay = 0);
|
||||
static void KillGCTimer();
|
||||
|
||||
static void PokeShrinkGCBuffers();
|
||||
|
@ -148,7 +148,7 @@ public:
|
|||
static void KillFullGCTimer();
|
||||
static void KillInterSliceGCTimer();
|
||||
|
||||
virtual void GC(js::gcreason::Reason aReason);
|
||||
virtual void GC(JS::gcreason::Reason aReason);
|
||||
|
||||
static uint32_t CleanupsSinceLastGC();
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include "jsapi.h"
|
||||
#include "jsfriendapi.h"
|
||||
#include "js/Vector.h"
|
||||
#include "js/GCAPI.h"
|
||||
#include "mozilla/Util.h"
|
||||
#include "nsAutoJSValHolder.h"
|
||||
|
||||
|
@ -77,8 +78,8 @@ struct ListenerData : PRCList
|
|||
static void
|
||||
Remove(JSContext* aCx, ListenerData* aListenerData)
|
||||
{
|
||||
if (js::IsIncrementalBarrierNeeded(aCx)) {
|
||||
js:: IncrementalReferenceBarrier(aListenerData->mListener);
|
||||
if (JS::IsIncrementalBarrierNeeded(aCx)) {
|
||||
JS:: IncrementalReferenceBarrier(aListenerData->mListener);
|
||||
}
|
||||
|
||||
PR_REMOVE_LINK(aListenerData);
|
||||
|
|
|
@ -8,6 +8,8 @@
|
|||
#include "jslock.h"
|
||||
#include "jsd_xpc.h"
|
||||
|
||||
#include "js/GCAPI.h"
|
||||
|
||||
#include "nsIXPConnect.h"
|
||||
#include "mozilla/ModuleUtils.h"
|
||||
#include "nsIServiceManager.h"
|
||||
|
@ -77,7 +79,7 @@
|
|||
#define JSD_STARTUP_ENTRY "JSDebugger Startup Observer"
|
||||
|
||||
static void
|
||||
jsds_GCSliceCallbackProc (JSRuntime *rt, js::GCProgress progress, const js::GCDescription &desc);
|
||||
jsds_GCSliceCallbackProc (JSRuntime *rt, JS::GCProgress progress, const JS::GCDescription &desc);
|
||||
|
||||
/*******************************************************************************
|
||||
* global vars
|
||||
|
@ -98,7 +100,7 @@ uint32_t gFrameCount = 0;
|
|||
#endif
|
||||
|
||||
static jsdService *gJsds = 0;
|
||||
static js::GCSliceCallback gPrevGCSliceCallback = jsds_GCSliceCallbackProc;
|
||||
static JS::GCSliceCallback gPrevGCSliceCallback = jsds_GCSliceCallbackProc;
|
||||
static bool gGCRunning = false;
|
||||
|
||||
static struct DeadScript {
|
||||
|
@ -478,9 +480,9 @@ jsds_NotifyPendingDeadScripts (JSRuntime *rt)
|
|||
}
|
||||
|
||||
static void
|
||||
jsds_GCSliceCallbackProc (JSRuntime *rt, js::GCProgress progress, const js::GCDescription &desc)
|
||||
jsds_GCSliceCallbackProc (JSRuntime *rt, JS::GCProgress progress, const JS::GCDescription &desc)
|
||||
{
|
||||
if (progress == js::GC_CYCLE_END || progress == js::GC_SLICE_END) {
|
||||
if (progress == JS::GC_CYCLE_END || progress == JS::GC_SLICE_END) {
|
||||
NS_ASSERTION(gGCRunning, "GC slice callback was missed");
|
||||
|
||||
while (gDeadScripts)
|
||||
|
@ -2556,7 +2558,7 @@ jsdService::ActivateDebugger (JSRuntime *rt)
|
|||
|
||||
if (gPrevGCSliceCallback == jsds_GCSliceCallbackProc)
|
||||
/* condition indicates that the callback proc has not been set yet */
|
||||
gPrevGCSliceCallback = js::SetGCSliceCallback (rt, jsds_GCSliceCallbackProc);
|
||||
gPrevGCSliceCallback = JS::SetGCSliceCallback (rt, jsds_GCSliceCallbackProc);
|
||||
|
||||
mCx = JSD_DebuggerOnForUser (rt, NULL, NULL);
|
||||
if (!mCx)
|
||||
|
|
|
@ -0,0 +1,244 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*/
|
||||
/* 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 js_gc_api_h___
|
||||
#define js_gc_api_h___
|
||||
|
||||
#include "HeapAPI.h"
|
||||
|
||||
namespace JS {
|
||||
|
||||
#define GCREASONS(D) \
|
||||
/* Reasons internal to the JS engine */ \
|
||||
D(API) \
|
||||
D(MAYBEGC) \
|
||||
D(LAST_CONTEXT) \
|
||||
D(DESTROY_CONTEXT) \
|
||||
D(LAST_DITCH) \
|
||||
D(TOO_MUCH_MALLOC) \
|
||||
D(ALLOC_TRIGGER) \
|
||||
D(DEBUG_GC) \
|
||||
D(DEBUG_MODE_GC) \
|
||||
D(TRANSPLANT) \
|
||||
D(RESET) \
|
||||
\
|
||||
/* Reasons from Firefox */ \
|
||||
D(DOM_WINDOW_UTILS) \
|
||||
D(COMPONENT_UTILS) \
|
||||
D(MEM_PRESSURE) \
|
||||
D(CC_WAITING) \
|
||||
D(CC_FORCED) \
|
||||
D(LOAD_END) \
|
||||
D(POST_COMPARTMENT) \
|
||||
D(PAGE_HIDE) \
|
||||
D(NSJSCONTEXT_DESTROY) \
|
||||
D(SET_NEW_DOCUMENT) \
|
||||
D(SET_DOC_SHELL) \
|
||||
D(DOM_UTILS) \
|
||||
D(DOM_IPC) \
|
||||
D(DOM_WORKER) \
|
||||
D(INTER_SLICE_GC) \
|
||||
D(REFRESH_FRAME) \
|
||||
D(FULL_GC_TIMER) \
|
||||
D(SHUTDOWN_CC)
|
||||
|
||||
namespace gcreason {
|
||||
|
||||
/* GCReasons will end up looking like JSGC_MAYBEGC */
|
||||
enum Reason {
|
||||
#define MAKE_REASON(name) name,
|
||||
GCREASONS(MAKE_REASON)
|
||||
#undef MAKE_REASON
|
||||
NO_REASON,
|
||||
NUM_REASONS,
|
||||
|
||||
/*
|
||||
* For telemetry, we want to keep a fixed max bucket size over time so we
|
||||
* don't have to switch histograms. 100 is conservative; as of this writing
|
||||
* there are 26. But the cost of extra buckets seems to be low while the
|
||||
* cost of switching histograms is high.
|
||||
*/
|
||||
NUM_TELEMETRY_REASONS = 100
|
||||
};
|
||||
|
||||
} /* namespace gcreason */
|
||||
|
||||
extern JS_FRIEND_API(void)
|
||||
PrepareCompartmentForGC(JSCompartment *comp);
|
||||
|
||||
extern JS_FRIEND_API(void)
|
||||
PrepareForFullGC(JSRuntime *rt);
|
||||
|
||||
extern JS_FRIEND_API(void)
|
||||
PrepareForIncrementalGC(JSRuntime *rt);
|
||||
|
||||
extern JS_FRIEND_API(bool)
|
||||
IsGCScheduled(JSRuntime *rt);
|
||||
|
||||
extern JS_FRIEND_API(void)
|
||||
SkipCompartmentForGC(JSCompartment *comp);
|
||||
|
||||
/*
|
||||
* When triggering a GC using one of the functions below, it is first necessary
|
||||
* to select the compartments to be collected. To do this, you can call
|
||||
* PrepareCompartmentForGC on each compartment, or you can call PrepareForFullGC
|
||||
* to select all compartments. Failing to select any compartment is an error.
|
||||
*/
|
||||
|
||||
extern JS_FRIEND_API(void)
|
||||
GCForReason(JSRuntime *rt, gcreason::Reason reason);
|
||||
|
||||
extern JS_FRIEND_API(void)
|
||||
ShrinkingGC(JSRuntime *rt, gcreason::Reason reason);
|
||||
|
||||
extern JS_FRIEND_API(void)
|
||||
ShrinkGCBuffers(JSRuntime *rt);
|
||||
|
||||
extern JS_FRIEND_API(void)
|
||||
IncrementalGC(JSRuntime *rt, gcreason::Reason reason, int64_t millis = 0);
|
||||
|
||||
extern JS_FRIEND_API(void)
|
||||
FinishIncrementalGC(JSRuntime *rt, gcreason::Reason reason);
|
||||
|
||||
enum GCProgress {
|
||||
/*
|
||||
* During non-incremental GC, the GC is bracketed by JSGC_CYCLE_BEGIN/END
|
||||
* callbacks. During an incremental GC, the sequence of callbacks is as
|
||||
* follows:
|
||||
* JSGC_CYCLE_BEGIN, JSGC_SLICE_END (first slice)
|
||||
* JSGC_SLICE_BEGIN, JSGC_SLICE_END (second slice)
|
||||
* ...
|
||||
* JSGC_SLICE_BEGIN, JSGC_CYCLE_END (last slice)
|
||||
*/
|
||||
|
||||
GC_CYCLE_BEGIN,
|
||||
GC_SLICE_BEGIN,
|
||||
GC_SLICE_END,
|
||||
GC_CYCLE_END
|
||||
};
|
||||
|
||||
struct JS_FRIEND_API(GCDescription) {
|
||||
bool isCompartment;
|
||||
|
||||
GCDescription(bool isCompartment)
|
||||
: isCompartment(isCompartment) {}
|
||||
|
||||
jschar *formatMessage(JSRuntime *rt) const;
|
||||
jschar *formatJSON(JSRuntime *rt, uint64_t timestamp) const;
|
||||
};
|
||||
|
||||
typedef void
|
||||
(* GCSliceCallback)(JSRuntime *rt, GCProgress progress, const GCDescription &desc);
|
||||
|
||||
extern JS_FRIEND_API(GCSliceCallback)
|
||||
SetGCSliceCallback(JSRuntime *rt, GCSliceCallback callback);
|
||||
|
||||
/*
|
||||
* Signals a good place to do an incremental slice, because the browser is
|
||||
* drawing a frame.
|
||||
*/
|
||||
extern JS_FRIEND_API(void)
|
||||
NotifyDidPaint(JSRuntime *rt);
|
||||
|
||||
extern JS_FRIEND_API(bool)
|
||||
IsIncrementalGCEnabled(JSRuntime *rt);
|
||||
|
||||
JS_FRIEND_API(bool)
|
||||
IsIncrementalGCInProgress(JSRuntime *rt);
|
||||
|
||||
extern JS_FRIEND_API(void)
|
||||
DisableIncrementalGC(JSRuntime *rt);
|
||||
|
||||
extern JS_FRIEND_API(bool)
|
||||
IsIncrementalBarrierNeeded(JSRuntime *rt);
|
||||
|
||||
extern JS_FRIEND_API(bool)
|
||||
IsIncrementalBarrierNeeded(JSContext *cx);
|
||||
|
||||
extern JS_FRIEND_API(void)
|
||||
IncrementalReferenceBarrier(void *ptr);
|
||||
|
||||
extern JS_FRIEND_API(void)
|
||||
IncrementalValueBarrier(const Value &v);
|
||||
|
||||
extern JS_FRIEND_API(void)
|
||||
PokeGC(JSRuntime *rt);
|
||||
|
||||
/* Was the most recent GC run incrementally? */
|
||||
extern JS_FRIEND_API(bool)
|
||||
WasIncrementalGC(JSRuntime *rt);
|
||||
|
||||
class ObjectPtr
|
||||
{
|
||||
JSObject *value;
|
||||
|
||||
public:
|
||||
ObjectPtr() : value(NULL) {}
|
||||
|
||||
ObjectPtr(JSObject *obj) : value(obj) {}
|
||||
|
||||
/* Always call finalize before the destructor. */
|
||||
~ObjectPtr() { JS_ASSERT(!value); }
|
||||
|
||||
void finalize(JSRuntime *rt) {
|
||||
if (IsIncrementalBarrierNeeded(rt))
|
||||
IncrementalReferenceBarrier(value);
|
||||
value = NULL;
|
||||
}
|
||||
|
||||
void init(JSObject *obj) { value = obj; }
|
||||
|
||||
JSObject *get() const { return value; }
|
||||
|
||||
void writeBarrierPre(JSRuntime *rt) {
|
||||
IncrementalReferenceBarrier(value);
|
||||
}
|
||||
|
||||
ObjectPtr &operator=(JSObject *obj) {
|
||||
IncrementalReferenceBarrier(value);
|
||||
value = obj;
|
||||
return *this;
|
||||
}
|
||||
|
||||
JSObject &operator*() const { return *value; }
|
||||
JSObject *operator->() const { return value; }
|
||||
operator JSObject *() const { return value; }
|
||||
};
|
||||
|
||||
/*
|
||||
* Unsets the gray bit for anything reachable from |thing|. |kind| should not be
|
||||
* JSTRACE_SHAPE. |thing| should be non-null.
|
||||
*/
|
||||
extern JS_FRIEND_API(void)
|
||||
UnmarkGrayGCThingRecursively(void *thing, JSGCTraceKind kind);
|
||||
|
||||
/*
|
||||
* This should be called when an object that is marked gray is exposed to the JS
|
||||
* engine (by handing it to running JS code or writing it into live JS
|
||||
* data). During incremental GC, since the gray bits haven't been computed yet,
|
||||
* we conservatively mark the object black.
|
||||
*/
|
||||
static JS_ALWAYS_INLINE void
|
||||
ExposeGCThingToActiveJS(void *thing, JSGCTraceKind kind)
|
||||
{
|
||||
JS_ASSERT(kind != JSTRACE_SHAPE);
|
||||
|
||||
if (GCThingIsMarkedGray(thing))
|
||||
UnmarkGrayGCThingRecursively(thing, kind);
|
||||
else if (IsIncrementalBarrierNeededOnGCThing(thing, kind))
|
||||
IncrementalReferenceBarrier(thing);
|
||||
}
|
||||
|
||||
static JS_ALWAYS_INLINE void
|
||||
ExposeValueToActiveJS(const Value &v)
|
||||
{
|
||||
if (v.isMarkable())
|
||||
ExposeGCThingToActiveJS(v.toGCThing(), v.gcKind());
|
||||
}
|
||||
|
||||
} /* namespace JS */
|
||||
|
||||
#endif /* js_gc_api_h___ */
|
|
@ -7,8 +7,6 @@
|
|||
#ifndef js_heap_api_h___
|
||||
#define js_heap_api_h___
|
||||
|
||||
#include "jsfriendapi.h"
|
||||
|
||||
/* These values are private to the JS engine. */
|
||||
namespace js {
|
||||
namespace gc {
|
||||
|
@ -140,30 +138,6 @@ IsIncrementalBarrierNeededOnGCThing(void *thing, JSGCTraceKind kind)
|
|||
return reinterpret_cast<shadow::Compartment *>(comp)->needsBarrier_;
|
||||
}
|
||||
|
||||
/*
|
||||
* This should be called when an object that is marked gray is exposed to the JS
|
||||
* engine (by handing it to running JS code or writing it into live JS
|
||||
* data). During incremental GC, since the gray bits haven't been computed yet,
|
||||
* we conservatively mark the object black.
|
||||
*/
|
||||
static JS_ALWAYS_INLINE void
|
||||
ExposeGCThingToActiveJS(void *thing, JSGCTraceKind kind)
|
||||
{
|
||||
JS_ASSERT(kind != JSTRACE_SHAPE);
|
||||
|
||||
if (GCThingIsMarkedGray(thing))
|
||||
js::UnmarkGrayGCThingRecursively(thing, kind);
|
||||
else if (IsIncrementalBarrierNeededOnGCThing(thing, kind))
|
||||
js::IncrementalReferenceBarrier(thing);
|
||||
}
|
||||
|
||||
static JS_ALWAYS_INLINE void
|
||||
ExposeValueToActiveJS(const Value &v)
|
||||
{
|
||||
if (v.isMarkable())
|
||||
ExposeGCThingToActiveJS(v.toGCThing(), v.gcKind());
|
||||
}
|
||||
|
||||
} /* namespace JS */
|
||||
|
||||
#endif /* js_heap_api_h___ */
|
||||
|
|
|
@ -228,6 +228,7 @@ EXPORTS_js = \
|
|||
CharacterEncoding.h \
|
||||
HashTable.h \
|
||||
HeapAPI.h \
|
||||
GCAPI.h \
|
||||
LegacyIntTypes.h \
|
||||
MemoryMetrics.h \
|
||||
TemplateLib.h \
|
||||
|
|
|
@ -1660,7 +1660,7 @@ UnmarkGrayChildren(JSTracer *trc, void **thingp, JSGCTraceKind kind)
|
|||
}
|
||||
|
||||
JS_FRIEND_API(void)
|
||||
js::UnmarkGrayGCThingRecursively(void *thing, JSGCTraceKind kind)
|
||||
JS::UnmarkGrayGCThingRecursively(void *thing, JSGCTraceKind kind)
|
||||
{
|
||||
JS_ASSERT(kind != JSTRACE_SHAPE);
|
||||
|
||||
|
|
|
@ -17,6 +17,8 @@
|
|||
#include "jspubtd.h"
|
||||
#include "jsutil.h"
|
||||
|
||||
#include "js/GCAPI.h"
|
||||
|
||||
struct JSCompartment;
|
||||
|
||||
namespace js {
|
||||
|
|
|
@ -127,20 +127,20 @@ JS_NewObjectWithUniqueType(JSContext *cx, JSClass *clasp, JSObject *protoArg, JS
|
|||
}
|
||||
|
||||
JS_FRIEND_API(void)
|
||||
js::PrepareCompartmentForGC(JSCompartment *comp)
|
||||
JS::PrepareCompartmentForGC(JSCompartment *comp)
|
||||
{
|
||||
comp->scheduleGC();
|
||||
}
|
||||
|
||||
JS_FRIEND_API(void)
|
||||
js::PrepareForFullGC(JSRuntime *rt)
|
||||
JS::PrepareForFullGC(JSRuntime *rt)
|
||||
{
|
||||
for (CompartmentsIter c(rt); !c.done(); c.next())
|
||||
c->scheduleGC();
|
||||
}
|
||||
|
||||
JS_FRIEND_API(void)
|
||||
js::PrepareForIncrementalGC(JSRuntime *rt)
|
||||
JS::PrepareForIncrementalGC(JSRuntime *rt)
|
||||
{
|
||||
if (!IsIncrementalGCInProgress(rt))
|
||||
return;
|
||||
|
@ -152,7 +152,7 @@ js::PrepareForIncrementalGC(JSRuntime *rt)
|
|||
}
|
||||
|
||||
JS_FRIEND_API(bool)
|
||||
js::IsGCScheduled(JSRuntime *rt)
|
||||
JS::IsGCScheduled(JSRuntime *rt)
|
||||
{
|
||||
for (CompartmentsIter c(rt); !c.done(); c.next()) {
|
||||
if (c->isGCScheduled())
|
||||
|
@ -163,41 +163,35 @@ js::IsGCScheduled(JSRuntime *rt)
|
|||
}
|
||||
|
||||
JS_FRIEND_API(void)
|
||||
js::SkipCompartmentForGC(JSCompartment *comp)
|
||||
JS::SkipCompartmentForGC(JSCompartment *comp)
|
||||
{
|
||||
comp->unscheduleGC();
|
||||
}
|
||||
|
||||
JS_FRIEND_API(void)
|
||||
js::GCForReason(JSRuntime *rt, gcreason::Reason reason)
|
||||
JS::GCForReason(JSRuntime *rt, gcreason::Reason reason)
|
||||
{
|
||||
GC(rt, GC_NORMAL, reason);
|
||||
}
|
||||
|
||||
JS_FRIEND_API(void)
|
||||
js::ShrinkingGC(JSRuntime *rt, gcreason::Reason reason)
|
||||
JS::ShrinkingGC(JSRuntime *rt, gcreason::Reason reason)
|
||||
{
|
||||
GC(rt, GC_SHRINK, reason);
|
||||
}
|
||||
|
||||
JS_FRIEND_API(void)
|
||||
js::IncrementalGC(JSRuntime *rt, gcreason::Reason reason, int64_t millis)
|
||||
JS::IncrementalGC(JSRuntime *rt, gcreason::Reason reason, int64_t millis)
|
||||
{
|
||||
GCSlice(rt, GC_NORMAL, reason, millis);
|
||||
}
|
||||
|
||||
JS_FRIEND_API(void)
|
||||
js::FinishIncrementalGC(JSRuntime *rt, gcreason::Reason reason)
|
||||
JS::FinishIncrementalGC(JSRuntime *rt, gcreason::Reason reason)
|
||||
{
|
||||
GCFinalSlice(rt, GC_NORMAL, reason);
|
||||
}
|
||||
|
||||
JS_FRIEND_API(void)
|
||||
JS_ShrinkGCBuffers(JSRuntime *rt)
|
||||
{
|
||||
ShrinkGCBuffers(rt);
|
||||
}
|
||||
|
||||
JS_FRIEND_API(JSPrincipals *)
|
||||
JS_GetCompartmentPrincipals(JSCompartment *compartment)
|
||||
{
|
||||
|
@ -786,7 +780,7 @@ js::GetRuntimeCompartments(JSRuntime *rt)
|
|||
}
|
||||
|
||||
JS_FRIEND_API(GCSliceCallback)
|
||||
js::SetGCSliceCallback(JSRuntime *rt, GCSliceCallback callback)
|
||||
JS::SetGCSliceCallback(JSRuntime *rt, GCSliceCallback callback)
|
||||
{
|
||||
GCSliceCallback old = rt->gcSliceCallback;
|
||||
rt->gcSliceCallback = callback;
|
||||
|
@ -794,7 +788,7 @@ js::SetGCSliceCallback(JSRuntime *rt, GCSliceCallback callback)
|
|||
}
|
||||
|
||||
JS_FRIEND_API(bool)
|
||||
js::WasIncrementalGC(JSRuntime *rt)
|
||||
JS::WasIncrementalGC(JSRuntime *rt)
|
||||
{
|
||||
return rt->gcIsIncremental;
|
||||
}
|
||||
|
@ -820,7 +814,7 @@ js::SetAnalysisPurgeCallback(JSRuntime *rt, AnalysisPurgeCallback callback)
|
|||
}
|
||||
|
||||
JS_FRIEND_API(void)
|
||||
js::NotifyDidPaint(JSRuntime *rt)
|
||||
JS::NotifyDidPaint(JSRuntime *rt)
|
||||
{
|
||||
if (rt->gcZeal() == gc::ZealFrameVerifierPreValue) {
|
||||
gc::VerifyBarriers(rt, gc::PreBarrierVerifier);
|
||||
|
@ -847,37 +841,37 @@ js::NotifyDidPaint(JSRuntime *rt)
|
|||
}
|
||||
|
||||
JS_FRIEND_API(bool)
|
||||
js::IsIncrementalGCEnabled(JSRuntime *rt)
|
||||
JS::IsIncrementalGCEnabled(JSRuntime *rt)
|
||||
{
|
||||
return rt->gcIncrementalEnabled && rt->gcMode == JSGC_MODE_INCREMENTAL;
|
||||
}
|
||||
|
||||
JS_FRIEND_API(bool)
|
||||
js::IsIncrementalGCInProgress(JSRuntime *rt)
|
||||
JS::IsIncrementalGCInProgress(JSRuntime *rt)
|
||||
{
|
||||
return (rt->gcIncrementalState != gc::NO_INCREMENTAL && !rt->gcVerifyPreData);
|
||||
}
|
||||
|
||||
JS_FRIEND_API(void)
|
||||
js::DisableIncrementalGC(JSRuntime *rt)
|
||||
JS::DisableIncrementalGC(JSRuntime *rt)
|
||||
{
|
||||
rt->gcIncrementalEnabled = false;
|
||||
}
|
||||
|
||||
JS_FRIEND_API(bool)
|
||||
js::IsIncrementalBarrierNeeded(JSRuntime *rt)
|
||||
JS::IsIncrementalBarrierNeeded(JSRuntime *rt)
|
||||
{
|
||||
return (rt->gcIncrementalState == gc::MARK && !rt->isHeapBusy());
|
||||
}
|
||||
|
||||
JS_FRIEND_API(bool)
|
||||
js::IsIncrementalBarrierNeeded(JSContext *cx)
|
||||
JS::IsIncrementalBarrierNeeded(JSContext *cx)
|
||||
{
|
||||
return IsIncrementalBarrierNeeded(cx->runtime);
|
||||
}
|
||||
|
||||
JS_FRIEND_API(void)
|
||||
js::IncrementalReferenceBarrier(void *ptr)
|
||||
JS::IncrementalReferenceBarrier(void *ptr)
|
||||
{
|
||||
if (!ptr)
|
||||
return;
|
||||
|
@ -905,13 +899,13 @@ js::IncrementalReferenceBarrier(void *ptr)
|
|||
}
|
||||
|
||||
JS_FRIEND_API(void)
|
||||
js::IncrementalValueBarrier(const Value &v)
|
||||
JS::IncrementalValueBarrier(const Value &v)
|
||||
{
|
||||
HeapValue::writeBarrierPre(v);
|
||||
}
|
||||
|
||||
JS_FRIEND_API(void)
|
||||
js::PokeGC(JSRuntime *rt)
|
||||
JS::PokeGC(JSRuntime *rt)
|
||||
{
|
||||
rt->gcPoke = true;
|
||||
}
|
||||
|
|
|
@ -50,9 +50,6 @@ JS_NewObjectWithUniqueType(JSContext *cx, JSClass *clasp, JSObject *proto, JSObj
|
|||
extern JS_FRIEND_API(uint32_t)
|
||||
JS_ObjectCountDynamicSlots(JSHandleObject obj);
|
||||
|
||||
extern JS_FRIEND_API(void)
|
||||
JS_ShrinkGCBuffers(JSRuntime *rt);
|
||||
|
||||
extern JS_FRIEND_API(size_t)
|
||||
JS_GetE4XObjectsCreated(JSContext *cx);
|
||||
|
||||
|
@ -272,13 +269,6 @@ TraceWeakMaps(WeakMapTracer *trc);
|
|||
extern JS_FRIEND_API(bool)
|
||||
AreGCGrayBitsValid(JSRuntime *rt);
|
||||
|
||||
/*
|
||||
* Unsets the gray bit for anything reachable from |thing|. |kind| should not be
|
||||
* JSTRACE_SHAPE. |thing| should be non-null.
|
||||
*/
|
||||
extern JS_FRIEND_API(void)
|
||||
UnmarkGrayGCThingRecursively(void *thing, JSGCTraceKind kind);
|
||||
|
||||
typedef void
|
||||
(*GCThingCallback)(void *closure, void *gcthing);
|
||||
|
||||
|
@ -739,138 +729,12 @@ typedef Vector<JSCompartment*, 0, SystemAllocPolicy> CompartmentVector;
|
|||
extern JS_FRIEND_API(const CompartmentVector&)
|
||||
GetRuntimeCompartments(JSRuntime *rt);
|
||||
|
||||
#define GCREASONS(D) \
|
||||
/* Reasons internal to the JS engine */ \
|
||||
D(API) \
|
||||
D(MAYBEGC) \
|
||||
D(LAST_CONTEXT) \
|
||||
D(DESTROY_CONTEXT) \
|
||||
D(LAST_DITCH) \
|
||||
D(TOO_MUCH_MALLOC) \
|
||||
D(ALLOC_TRIGGER) \
|
||||
D(DEBUG_GC) \
|
||||
D(DEBUG_MODE_GC) \
|
||||
D(TRANSPLANT) \
|
||||
D(RESET) \
|
||||
\
|
||||
/* Reasons from Firefox */ \
|
||||
D(DOM_WINDOW_UTILS) \
|
||||
D(COMPONENT_UTILS) \
|
||||
D(MEM_PRESSURE) \
|
||||
D(CC_WAITING) \
|
||||
D(CC_FORCED) \
|
||||
D(LOAD_END) \
|
||||
D(POST_COMPARTMENT) \
|
||||
D(PAGE_HIDE) \
|
||||
D(NSJSCONTEXT_DESTROY) \
|
||||
D(SET_NEW_DOCUMENT) \
|
||||
D(SET_DOC_SHELL) \
|
||||
D(DOM_UTILS) \
|
||||
D(DOM_IPC) \
|
||||
D(DOM_WORKER) \
|
||||
D(INTER_SLICE_GC) \
|
||||
D(REFRESH_FRAME) \
|
||||
D(FULL_GC_TIMER) \
|
||||
D(SHUTDOWN_CC)
|
||||
|
||||
namespace gcreason {
|
||||
|
||||
/* GCReasons will end up looking like JSGC_MAYBEGC */
|
||||
enum Reason {
|
||||
#define MAKE_REASON(name) name,
|
||||
GCREASONS(MAKE_REASON)
|
||||
#undef MAKE_REASON
|
||||
NO_REASON,
|
||||
NUM_REASONS,
|
||||
|
||||
/*
|
||||
* For telemetry, we want to keep a fixed max bucket size over time so we
|
||||
* don't have to switch histograms. 100 is conservative; as of this writing
|
||||
* there are 26. But the cost of extra buckets seems to be low while the
|
||||
* cost of switching histograms is high.
|
||||
*/
|
||||
NUM_TELEMETRY_REASONS = 100
|
||||
};
|
||||
|
||||
} /* namespace gcreason */
|
||||
|
||||
extern JS_FRIEND_API(void)
|
||||
PrepareCompartmentForGC(JSCompartment *comp);
|
||||
|
||||
extern JS_FRIEND_API(void)
|
||||
PrepareForFullGC(JSRuntime *rt);
|
||||
|
||||
extern JS_FRIEND_API(void)
|
||||
PrepareForIncrementalGC(JSRuntime *rt);
|
||||
|
||||
extern JS_FRIEND_API(bool)
|
||||
IsGCScheduled(JSRuntime *rt);
|
||||
|
||||
extern JS_FRIEND_API(void)
|
||||
SkipCompartmentForGC(JSCompartment *comp);
|
||||
|
||||
/*
|
||||
* When triggering a GC using one of the functions below, it is first necessary
|
||||
* to select the compartments to be collected. To do this, you can call
|
||||
* PrepareCompartmentForGC on each compartment, or you can call PrepareForFullGC
|
||||
* to select all compartments. Failing to select any compartment is an error.
|
||||
*/
|
||||
|
||||
extern JS_FRIEND_API(void)
|
||||
GCForReason(JSRuntime *rt, gcreason::Reason reason);
|
||||
|
||||
extern JS_FRIEND_API(void)
|
||||
ShrinkingGC(JSRuntime *rt, gcreason::Reason reason);
|
||||
|
||||
extern JS_FRIEND_API(void)
|
||||
IncrementalGC(JSRuntime *rt, gcreason::Reason reason, int64_t millis = 0);
|
||||
|
||||
extern JS_FRIEND_API(void)
|
||||
FinishIncrementalGC(JSRuntime *rt, gcreason::Reason reason);
|
||||
|
||||
enum GCProgress {
|
||||
/*
|
||||
* During non-incremental GC, the GC is bracketed by JSGC_CYCLE_BEGIN/END
|
||||
* callbacks. During an incremental GC, the sequence of callbacks is as
|
||||
* follows:
|
||||
* JSGC_CYCLE_BEGIN, JSGC_SLICE_END (first slice)
|
||||
* JSGC_SLICE_BEGIN, JSGC_SLICE_END (second slice)
|
||||
* ...
|
||||
* JSGC_SLICE_BEGIN, JSGC_CYCLE_END (last slice)
|
||||
*/
|
||||
|
||||
GC_CYCLE_BEGIN,
|
||||
GC_SLICE_BEGIN,
|
||||
GC_SLICE_END,
|
||||
GC_CYCLE_END
|
||||
};
|
||||
|
||||
struct JS_FRIEND_API(GCDescription) {
|
||||
bool isCompartment;
|
||||
|
||||
GCDescription(bool isCompartment)
|
||||
: isCompartment(isCompartment) {}
|
||||
|
||||
jschar *formatMessage(JSRuntime *rt) const;
|
||||
jschar *formatJSON(JSRuntime *rt, uint64_t timestamp) const;
|
||||
};
|
||||
|
||||
typedef void
|
||||
(* GCSliceCallback)(JSRuntime *rt, GCProgress progress, const GCDescription &desc);
|
||||
|
||||
extern JS_FRIEND_API(GCSliceCallback)
|
||||
SetGCSliceCallback(JSRuntime *rt, GCSliceCallback callback);
|
||||
|
||||
typedef void
|
||||
(* AnalysisPurgeCallback)(JSRuntime *rt, JSFlatString *desc);
|
||||
|
||||
extern JS_FRIEND_API(AnalysisPurgeCallback)
|
||||
SetAnalysisPurgeCallback(JSRuntime *rt, AnalysisPurgeCallback callback);
|
||||
|
||||
/* Was the most recent GC run incrementally? */
|
||||
extern JS_FRIEND_API(bool)
|
||||
WasIncrementalGC(JSRuntime *rt);
|
||||
|
||||
typedef JSBool
|
||||
(* DOMInstanceClassMatchesProto)(JSHandleObject protoObject, uint32_t protoID,
|
||||
uint32_t depth);
|
||||
|
@ -885,74 +749,6 @@ SetDOMCallbacks(JSRuntime *rt, const DOMCallbacks *callbacks);
|
|||
extern JS_FRIEND_API(const DOMCallbacks *)
|
||||
GetDOMCallbacks(JSRuntime *rt);
|
||||
|
||||
/*
|
||||
* Signals a good place to do an incremental slice, because the browser is
|
||||
* drawing a frame.
|
||||
*/
|
||||
extern JS_FRIEND_API(void)
|
||||
NotifyDidPaint(JSRuntime *rt);
|
||||
|
||||
extern JS_FRIEND_API(bool)
|
||||
IsIncrementalGCEnabled(JSRuntime *rt);
|
||||
|
||||
JS_FRIEND_API(bool)
|
||||
IsIncrementalGCInProgress(JSRuntime *rt);
|
||||
|
||||
extern JS_FRIEND_API(void)
|
||||
DisableIncrementalGC(JSRuntime *rt);
|
||||
|
||||
extern JS_FRIEND_API(bool)
|
||||
IsIncrementalBarrierNeeded(JSRuntime *rt);
|
||||
|
||||
extern JS_FRIEND_API(bool)
|
||||
IsIncrementalBarrierNeeded(JSContext *cx);
|
||||
|
||||
extern JS_FRIEND_API(void)
|
||||
IncrementalReferenceBarrier(void *ptr);
|
||||
|
||||
extern JS_FRIEND_API(void)
|
||||
IncrementalValueBarrier(const Value &v);
|
||||
|
||||
extern JS_FRIEND_API(void)
|
||||
PokeGC(JSRuntime *rt);
|
||||
|
||||
class ObjectPtr
|
||||
{
|
||||
JSObject *value;
|
||||
|
||||
public:
|
||||
ObjectPtr() : value(NULL) {}
|
||||
|
||||
ObjectPtr(JSObject *obj) : value(obj) {}
|
||||
|
||||
/* Always call finalize before the destructor. */
|
||||
~ObjectPtr() { JS_ASSERT(!value); }
|
||||
|
||||
void finalize(JSRuntime *rt) {
|
||||
if (IsIncrementalBarrierNeeded(rt))
|
||||
IncrementalReferenceBarrier(value);
|
||||
value = NULL;
|
||||
}
|
||||
|
||||
void init(JSObject *obj) { value = obj; }
|
||||
|
||||
JSObject *get() const { return value; }
|
||||
|
||||
void writeBarrierPre(JSRuntime *rt) {
|
||||
IncrementalReferenceBarrier(value);
|
||||
}
|
||||
|
||||
ObjectPtr &operator=(JSObject *obj) {
|
||||
IncrementalReferenceBarrier(value);
|
||||
value = obj;
|
||||
return *this;
|
||||
}
|
||||
|
||||
JSObject &operator*() const { return *value; }
|
||||
JSObject *operator->() const { return value; }
|
||||
operator JSObject *() const { return value; }
|
||||
};
|
||||
|
||||
extern JS_FRIEND_API(JSObject *)
|
||||
GetTestingFunctions(JSContext *cx);
|
||||
|
||||
|
|
|
@ -4513,8 +4513,8 @@ js::PrepareForDebugGC(JSRuntime *rt)
|
|||
PrepareForFullGC(rt);
|
||||
}
|
||||
|
||||
void
|
||||
js::ShrinkGCBuffers(JSRuntime *rt)
|
||||
JS_FRIEND_API(void)
|
||||
JS::ShrinkGCBuffers(JSRuntime *rt)
|
||||
{
|
||||
AutoLockGC lock(rt);
|
||||
JS_ASSERT(!rt->isHeapBusy());
|
||||
|
|
|
@ -544,9 +544,6 @@ TriggerCompartmentGC(JSCompartment *comp, js::gcreason::Reason reason);
|
|||
extern void
|
||||
MaybeGC(JSContext *cx);
|
||||
|
||||
extern void
|
||||
ShrinkGCBuffers(JSRuntime *rt);
|
||||
|
||||
extern void
|
||||
ReleaseAllJITCode(FreeOp *op);
|
||||
|
||||
|
|
|
@ -513,7 +513,7 @@ private:
|
|||
if (delegateMightNeedMarking && kkind == JSTRACE_OBJECT) {
|
||||
JSObject *kdelegate = js::GetWeakmapKeyDelegate((JSObject *)k);
|
||||
if (kdelegate && !xpc_IsGrayGCThing(kdelegate)) {
|
||||
js::UnmarkGrayGCThingRecursively(k, JSTRACE_OBJECT);
|
||||
JS::UnmarkGrayGCThingRecursively(k, JSTRACE_OBJECT);
|
||||
tracer->mAnyMarked = true;
|
||||
}
|
||||
}
|
||||
|
@ -523,7 +523,7 @@ private:
|
|||
(!m || !xpc_IsGrayGCThing(m)) &&
|
||||
vkind != JSTRACE_SHAPE)
|
||||
{
|
||||
js::UnmarkGrayGCThingRecursively(v, vkind);
|
||||
JS::UnmarkGrayGCThingRecursively(v, vkind);
|
||||
tracer->mAnyMarked = true;
|
||||
}
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include "jspubtd.h"
|
||||
#include "jsproxy.h"
|
||||
#include "js/HeapAPI.h"
|
||||
#include "js/GCAPI.h"
|
||||
|
||||
#include "nsISupports.h"
|
||||
#include "nsIPrincipal.h"
|
||||
|
|
|
@ -84,7 +84,7 @@
|
|||
},
|
||||
"GC_REASON_2": {
|
||||
"kind": "enumerated",
|
||||
"n_values": "js::gcreason::NUM_TELEMETRY_REASONS",
|
||||
"n_values": "JS::gcreason::NUM_TELEMETRY_REASONS",
|
||||
"description": "Reason (enum value) for initiating a GC"
|
||||
},
|
||||
"GC_IS_COMPARTMENTAL": {
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include "mozilla/Services.h"
|
||||
#include "jsapi.h"
|
||||
#include "jsfriendapi.h"
|
||||
#include "js/GCAPI.h"
|
||||
#include "nsStringGlue.h"
|
||||
#include "nsITelemetry.h"
|
||||
#include "nsIFile.h"
|
||||
|
|
|
@ -2820,7 +2820,7 @@ nsCycleCollector::FixGrayBits(bool aForceGC)
|
|||
// mJSRuntime->Collect() must be called from the main thread,
|
||||
// because it invokes XPCJSRuntime::GCCallback(cx, JSGC_BEGIN)
|
||||
// which returns false if not in the main thread.
|
||||
mJSRuntime->Collect(aForceGC ? js::gcreason::SHUTDOWN_CC : js::gcreason::CC_FORCED);
|
||||
mJSRuntime->Collect(aForceGC ? JS::gcreason::SHUTDOWN_CC : JS::gcreason::CC_FORCED);
|
||||
timeLog.Checkpoint("GC()");
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче