зеркало из https://github.com/mozilla/pjs.git
Bug 731094 - Expose a testing function that permits only deterministic GCs (r=igor)
This commit is contained in:
Родитель
61365656cd
Коммит
38627da91d
|
@ -8,6 +8,7 @@
|
|||
#include "jscntxt.h"
|
||||
#include "jscompartment.h"
|
||||
#include "jsfriendapi.h"
|
||||
#include "jsgc.h"
|
||||
#include "jsobj.h"
|
||||
#include "jsprf.h"
|
||||
#include "jswrapper.h"
|
||||
|
@ -221,6 +222,19 @@ GCSlice(JSContext *cx, unsigned argc, jsval *vp)
|
|||
*vp = JSVAL_VOID;
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
static JSBool
|
||||
DeterministicGC(JSContext *cx, unsigned argc, jsval *vp)
|
||||
{
|
||||
if (argc != 1) {
|
||||
ReportUsageError(cx, &JS_CALLEE(cx, vp).toObject(), "Wrong number of arguments");
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
gc::SetDeterministicGC(cx, js_ValueToBoolean(vp[2]));
|
||||
*vp = JSVAL_VOID;
|
||||
return JS_TRUE;
|
||||
}
|
||||
#endif /* JS_GC_ZEAL */
|
||||
|
||||
typedef struct JSCountHeapNode JSCountHeapNode;
|
||||
|
@ -516,6 +530,10 @@ static JSFunctionSpecWithHelp TestingFunctions[] = {
|
|||
JS_FN_HELP("gcslice", GCSlice, 1, 0,
|
||||
"gcslice(n)",
|
||||
" Run an incremental GC slice that marks about n objects."),
|
||||
|
||||
JS_FN_HELP("deterministicgc", DeterministicGC, 1, 0,
|
||||
"deterministicgc(true|false)",
|
||||
" If true, only allow determinstic GCs to run."),
|
||||
#endif
|
||||
|
||||
JS_FN_HELP("internalConst", InternalConst, 1, 0,
|
||||
|
|
|
@ -753,6 +753,7 @@ JSRuntime::JSRuntime()
|
|||
gcZealFrequency(0),
|
||||
gcNextScheduled(0),
|
||||
gcDebugCompartmentGC(false),
|
||||
gcDeterministicOnly(false),
|
||||
#endif
|
||||
gcCallback(NULL),
|
||||
gcSliceCallback(NULL),
|
||||
|
|
|
@ -419,6 +419,7 @@ struct JSRuntime : js::RuntimeFriendFields
|
|||
int gcZealFrequency;
|
||||
int gcNextScheduled;
|
||||
bool gcDebugCompartmentGC;
|
||||
bool gcDeterministicOnly;
|
||||
|
||||
int gcZeal() { return gcZeal_; }
|
||||
|
||||
|
|
|
@ -673,7 +673,7 @@ SizeOfJSContext();
|
|||
D(LAST_DITCH) \
|
||||
D(TOO_MUCH_MALLOC) \
|
||||
D(ALLOC_TRIGGER) \
|
||||
D(UNUSED1) /* was CHUNK */ \
|
||||
D(DEBUG_GC) \
|
||||
D(UNUSED2) /* was SHAPE */ \
|
||||
D(UNUSED3) /* was REFILL */ \
|
||||
\
|
||||
|
|
|
@ -1708,13 +1708,13 @@ ArenaLists::finalizeScripts(JSContext *cx)
|
|||
}
|
||||
|
||||
static void
|
||||
RunLastDitchGC(JSContext *cx)
|
||||
RunLastDitchGC(JSContext *cx, gcreason::Reason reason)
|
||||
{
|
||||
JSRuntime *rt = cx->runtime;
|
||||
|
||||
/* The last ditch GC preserves all atoms. */
|
||||
AutoKeepAtoms keep(rt);
|
||||
GC(cx, rt->gcTriggerCompartment, GC_NORMAL, gcreason::LAST_DITCH);
|
||||
GC(cx, rt->gcTriggerCompartment, GC_NORMAL, reason);
|
||||
}
|
||||
|
||||
/* static */ void *
|
||||
|
@ -1729,7 +1729,7 @@ ArenaLists::refillFreeList(JSContext *cx, AllocKind thingKind)
|
|||
bool runGC = rt->gcIncrementalState != NO_INCREMENTAL && comp->gcBytes > comp->gcTriggerBytes;
|
||||
for (;;) {
|
||||
if (JS_UNLIKELY(runGC)) {
|
||||
RunLastDitchGC(cx);
|
||||
RunLastDitchGC(cx, gcreason::LAST_DITCH);
|
||||
|
||||
/*
|
||||
* The JSGC_END callback can legitimately allocate new GC
|
||||
|
@ -3662,6 +3662,20 @@ GCCycle(JSContext *cx, JSCompartment *comp, int64_t budget, JSGCInvocationKind g
|
|||
#endif
|
||||
}
|
||||
|
||||
#ifdef JS_GC_ZEAL
|
||||
static bool
|
||||
IsDeterministicGCReason(gcreason::Reason reason)
|
||||
{
|
||||
if (reason > gcreason::DEBUG_GC && reason != gcreason::CC_FORCED)
|
||||
return false;
|
||||
|
||||
if (reason == gcreason::MAYBEGC)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
Collect(JSContext *cx, JSCompartment *comp, int64_t budget,
|
||||
JSGCInvocationKind gckind, gcreason::Reason reason)
|
||||
|
@ -3669,6 +3683,11 @@ Collect(JSContext *cx, JSCompartment *comp, int64_t budget,
|
|||
JSRuntime *rt = cx->runtime;
|
||||
JS_AbortIfWrongThread(rt);
|
||||
|
||||
#ifdef JS_GC_ZEAL
|
||||
if (rt->gcDeterministicOnly && !IsDeterministicGCReason(reason))
|
||||
return;
|
||||
#endif
|
||||
|
||||
JS_ASSERT_IF(budget != SliceBudget::Unlimited, JSGC_INCREMENTAL);
|
||||
|
||||
#ifdef JS_GC_ZEAL
|
||||
|
@ -3947,7 +3966,16 @@ RunDebugGC(JSContext *cx)
|
|||
if (rt->gcTriggerCompartment == rt->atomsCompartment)
|
||||
rt->gcTriggerCompartment = NULL;
|
||||
|
||||
RunLastDitchGC(cx);
|
||||
RunLastDitchGC(cx, gcreason::DEBUG_GC);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
SetDeterministicGC(JSContext *cx, bool enabled)
|
||||
{
|
||||
#ifdef JS_GC_ZEAL
|
||||
JSRuntime *rt = cx->runtime;
|
||||
rt->gcDeterministicOnly = enabled;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
@ -1968,6 +1968,9 @@ NewCompartment(JSContext *cx, JSPrincipals *principals);
|
|||
void
|
||||
RunDebugGC(JSContext *cx);
|
||||
|
||||
void
|
||||
SetDeterministicGC(JSContext *cx, bool enabled);
|
||||
|
||||
#if defined(JSGC_ROOT_ANALYSIS) && defined(DEBUG) && !defined(JS_THREADSAFE)
|
||||
/* Overwrites stack references to GC things which have not been rooted. */
|
||||
void CheckStackRoots(JSContext *cx);
|
||||
|
|
Загрузка…
Ссылка в новой задаче