Backed out 5 changesets (bug 1099152) for hazard build failures on a CLOSED TREE

Backed out changeset 3d195c54dcf1 (bug 1099152)
Backed out changeset e5a903979b5f (bug 1099152)
Backed out changeset 969965f4c893 (bug 1099152)
Backed out changeset 1e4e3b85c620 (bug 1099152)
Backed out changeset 501a22044336 (bug 1099152)
This commit is contained in:
Wes Kocher 2015-01-02 12:43:48 -08:00
parent dea2e73aed
commit 2ab57c410e
12 changed files with 107 additions and 138 deletions

View File

@ -1459,7 +1459,7 @@ nsJSContext::GarbageCollectNow(JS::gcreason::Reason aReason,
if (sCCLockedOut && aIncremental == IncrementalGC) {
// We're in the middle of incremental GC. Do another slice.
JS::PrepareForIncrementalGC(sRuntime);
JS::IncrementalGCSlice(sRuntime, aReason, aSliceMillis);
JS::IncrementalGC(sRuntime, aReason, aSliceMillis);
return;
}
@ -1472,10 +1472,11 @@ nsJSContext::GarbageCollectNow(JS::gcreason::Reason aReason,
if (aIncremental == IncrementalGC) {
MOZ_ASSERT(aShrinking == NonShrinkingGC);
JS::StartIncrementalGC(sRuntime, GC_NORMAL, aReason, aSliceMillis);
JS::IncrementalGC(sRuntime, aReason, aSliceMillis);
} else if (aShrinking == ShrinkingGC) {
JS::ShrinkingGC(sRuntime, aReason);
} else {
JSGCInvocationKind gckind = aShrinking == ShrinkingGC ? GC_SHRINK : GC_NORMAL;
JS::GCForReason(sRuntime, gckind, aReason);
JS::GCForReason(sRuntime, aReason);
}
}

View File

@ -6026,14 +6026,14 @@ WorkerPrivate::GarbageCollectInternal(JSContext* aCx, bool aShrinking,
JS::PrepareForFullGC(rt);
if (aShrinking) {
JS::GCForReason(rt, GC_SHRINK, JS::gcreason::DOM_WORKER);
JS::ShrinkingGC(rt, JS::gcreason::DOM_WORKER);
if (!aCollectChildren) {
LOG(("Worker %p collected idle garbage\n", this));
}
}
else {
JS::GCForReason(rt, GC_NORMAL, JS::gcreason::DOM_WORKER);
JS::GCForReason(rt, JS::gcreason::DOM_WORKER);
LOG(("Worker %p collected garbage\n", this));
}
}

View File

@ -31,17 +31,6 @@ typedef enum JSGCMode {
JSGC_MODE_INCREMENTAL = 2
} JSGCMode;
/*
* Kinds of js_GC invocation.
*/
typedef enum JSGCInvocationKind {
/* Normal invocation. */
GC_NORMAL = 0,
/* Minimize GC triggers and release empty GC chunks right away. */
GC_SHRINK = 1
} JSGCInvocationKind;
namespace JS {
#define GCREASONS(D) \
@ -60,7 +49,6 @@ namespace JS {
D(EVICT_NURSERY) \
D(FULL_STORE_BUFFER) \
D(SHARED_MEMORY_LIMIT) \
D(INCREMENTAL_ALLOC_TRIGGER) \
\
/* These are reserved for future use. */ \
D(RESERVED0) \
@ -81,6 +69,7 @@ namespace JS {
D(RESERVED15) \
D(RESERVED16) \
D(RESERVED17) \
D(RESERVED18) \
\
/* Reasons from Firefox */ \
D(DOM_WINDOW_UTILS) \
@ -179,16 +168,20 @@ SkipZoneForGC(Zone *zone);
*/
/*
* Performs a non-incremental collection of all selected zones.
*
* If the gckind argument is GC_NORMAL, then some objects that are unreachable
* from the program may still be alive afterwards because of internal
* references; if GC_SHRINK is passed then caches and other temporary references
* to objects will be cleared and all unreferenced objects will be removed from
* the system.
* Performs a non-incremental collection of all selected zones. Some objects
* that are unreachable from the program may still be alive afterwards because
* of internal references.
*/
extern JS_FRIEND_API(void)
GCForReason(JSRuntime *rt, JSGCInvocationKind gckind, gcreason::Reason reason);
GCForReason(JSRuntime *rt, gcreason::Reason reason);
/*
* Perform a non-incremental collection after clearing caches and other
* temporary references to objects. This will remove all unreferenced objects
* in the system.
*/
extern JS_FRIEND_API(void)
ShrinkingGC(JSRuntime *rt, gcreason::Reason reason);
/*
* Incremental GC:
@ -214,28 +207,16 @@ GCForReason(JSRuntime *rt, JSGCInvocationKind gckind, gcreason::Reason reason);
*/
/*
* Begin an incremental collection and perform one slice worth of work. When
* this function returns, the collection may not be complete.
* IncrementalGCSlice() must be called repeatedly until
* !IsIncrementalGCInProgress(rt).
* Begin an incremental collection and perform one slice worth of work or
* perform a slice of an ongoing incremental collection. When this function
* returns, the collection is not complete. This function must be called
* repeatedly until !IsIncrementalGCInProgress(rt).
*
* Note: SpiderMonkey's GC is not realtime. Slices in practice may be longer or
* shorter than the requested interval.
*/
extern JS_FRIEND_API(void)
StartIncrementalGC(JSRuntime *rt, JSGCInvocationKind gckind, gcreason::Reason reason,
int64_t millis = 0);
/*
* Perform a slice of an ongoing incremental collection. When this function
* returns, the collection may not be complete. It must be called repeatedly
* until !IsIncrementalGCInProgress(rt).
*
* Note: SpiderMonkey's GC is not realtime. Slices in practice may be longer or
* shorter than the requested interval.
*/
extern JS_FRIEND_API(void)
IncrementalGCSlice(JSRuntime *rt, gcreason::Reason reason, int64_t millis = 0);
IncrementalGC(JSRuntime *rt, gcreason::Reason reason, int64_t millis = 0);
/*
* If IsIncrementalGCInProgress(rt), this call finishes the ongoing collection

View File

@ -238,8 +238,10 @@ GC(JSContext *cx, unsigned argc, jsval *vp)
else
JS::PrepareForFullGC(cx->runtime());
JSGCInvocationKind gckind = shrinking ? GC_SHRINK : GC_NORMAL;
JS::GCForReason(cx->runtime(), gckind, JS::gcreason::API);
if (shrinking)
JS::ShrinkingGC(cx->runtime(), JS::gcreason::API);
else
JS::GCForReason(cx->runtime(), JS::gcreason::API);
char buf[256] = { '\0' };
#ifndef JS_MORE_DETERMINISTIC

View File

@ -320,9 +320,8 @@ class GCRuntime
void evictNursery(JS::gcreason::Reason reason = JS::gcreason::EVICT_NURSERY) { minorGC(reason); }
bool gcIfNeeded(JSContext *cx = nullptr);
void gc(JSGCInvocationKind gckind, JS::gcreason::Reason reason);
void startGC(JSGCInvocationKind gckind, JS::gcreason::Reason reason, int64_t millis = 0);
void gcSlice(JS::gcreason::Reason reason, int64_t millis = 0);
void finishGC(JS::gcreason::Reason reason);
void gcSlice(JSGCInvocationKind gckind, JS::gcreason::Reason reason, int64_t millis = 0);
void gcFinalSlice(JSGCInvocationKind gckind, JS::gcreason::Reason reason);
void gcDebugSlice(SliceBudget &budget);
void runDebugGC();
@ -559,9 +558,10 @@ class GCRuntime
void startBackgroundAllocTaskIfIdle();
void requestMajorGC(JS::gcreason::Reason reason);
SliceBudget defaultBudget(JS::gcreason::Reason reason, int64_t millis);
void collect(bool incremental, SliceBudget budget, JS::gcreason::Reason reason);
bool gcCycle(bool incremental, SliceBudget &budget, JS::gcreason::Reason reason);
void collect(bool incremental, SliceBudget &budget, JSGCInvocationKind gckind,
JS::gcreason::Reason reason);
bool gcCycle(bool incremental, SliceBudget &budget, JSGCInvocationKind gckind,
JS::gcreason::Reason reason);
gcstats::ZoneGCStats scanZonesBeforeGC();
void budgetIncrementalGC(SliceBudget &budget);
void resetIncrementalGC(const char *reason);

View File

@ -24,7 +24,7 @@ BEGIN_TEST(testGCFinalizeCallback)
/* Full GC, incremental. */
FinalizeCalls = 0;
JS::PrepareForFullGC(rt);
JS::StartIncrementalGC(rt, GC_NORMAL, JS::gcreason::API, 1000000);
JS::IncrementalGC(rt, JS::gcreason::API, 1000000);
CHECK(!rt->gc.isIncrementalGCInProgress());
CHECK(rt->gc.isFullGc());
CHECK(checkMultipleGroups());
@ -41,7 +41,7 @@ BEGIN_TEST(testGCFinalizeCallback)
/* Compartment GC, non-incremental, single compartment. */
FinalizeCalls = 0;
JS::PrepareZoneForGC(global1->zone());
JS::GCForReason(rt, GC_NORMAL, JS::gcreason::API);
JS::GCForReason(rt, JS::gcreason::API);
CHECK(!rt->gc.isFullGc());
CHECK(checkSingleGroup());
CHECK(checkFinalizeStatus());
@ -52,7 +52,7 @@ BEGIN_TEST(testGCFinalizeCallback)
JS::PrepareZoneForGC(global1->zone());
JS::PrepareZoneForGC(global2->zone());
JS::PrepareZoneForGC(global3->zone());
JS::GCForReason(rt, GC_NORMAL, JS::gcreason::API);
JS::GCForReason(rt, JS::gcreason::API);
CHECK(!rt->gc.isFullGc());
CHECK(checkSingleGroup());
CHECK(checkFinalizeStatus());
@ -61,7 +61,7 @@ BEGIN_TEST(testGCFinalizeCallback)
/* Compartment GC, incremental, single compartment. */
FinalizeCalls = 0;
JS::PrepareZoneForGC(global1->zone());
JS::StartIncrementalGC(rt, GC_NORMAL, JS::gcreason::API, 1000000);
JS::IncrementalGC(rt, JS::gcreason::API, 1000000);
CHECK(!rt->gc.isIncrementalGCInProgress());
CHECK(!rt->gc.isFullGc());
CHECK(checkSingleGroup());
@ -73,7 +73,7 @@ BEGIN_TEST(testGCFinalizeCallback)
JS::PrepareZoneForGC(global1->zone());
JS::PrepareZoneForGC(global2->zone());
JS::PrepareZoneForGC(global3->zone());
JS::StartIncrementalGC(rt, GC_NORMAL, JS::gcreason::API, 1000000);
JS::IncrementalGC(rt, JS::gcreason::API, 1000000);
CHECK(!rt->gc.isIncrementalGCInProgress());
CHECK(!rt->gc.isFullGc());
CHECK(checkMultipleGroups());

View File

@ -65,10 +65,10 @@ testPreserveJitCode(bool preserveJitCode, unsigned remainingIonScripts)
CHECK_EQUAL(value.toInt32(), 45);
CHECK_EQUAL(countIonScripts(global), 1u);
GCForReason(rt, GC_NORMAL, gcreason::API);
GCForReason(rt, gcreason::API);
CHECK_EQUAL(countIonScripts(global), remainingIonScripts);
GCForReason(rt, GC_SHRINK, gcreason::API);
ShrinkingGC(rt, gcreason::API);
CHECK_EQUAL(countIonScripts(global), 0u);
return true;

View File

@ -196,29 +196,27 @@ JS::SkipZoneForGC(Zone *zone)
}
JS_FRIEND_API(void)
JS::GCForReason(JSRuntime *rt, JSGCInvocationKind gckind, gcreason::Reason reason)
JS::GCForReason(JSRuntime *rt, gcreason::Reason reason)
{
MOZ_ASSERT(gckind == GC_NORMAL || gckind == GC_SHRINK);
rt->gc.gc(gckind, reason);
rt->gc.gc(GC_NORMAL, reason);
}
JS_FRIEND_API(void)
JS::StartIncrementalGC(JSRuntime *rt, JSGCInvocationKind gckind, gcreason::Reason reason, int64_t millis)
JS::ShrinkingGC(JSRuntime *rt, gcreason::Reason reason)
{
MOZ_ASSERT(gckind == GC_NORMAL || gckind == GC_SHRINK);
rt->gc.startGC(gckind, reason, millis);
rt->gc.gc(GC_SHRINK, reason);
}
JS_FRIEND_API(void)
JS::IncrementalGCSlice(JSRuntime *rt, gcreason::Reason reason, int64_t millis)
JS::IncrementalGC(JSRuntime *rt, gcreason::Reason reason, int64_t millis)
{
rt->gc.gcSlice(reason, millis);
rt->gc.gcSlice(GC_NORMAL, reason, millis);
}
JS_FRIEND_API(void)
JS::FinishIncrementalGC(JSRuntime *rt, gcreason::Reason reason)
{
rt->gc.finishGC(reason);
rt->gc.gcFinalSlice(GC_NORMAL, reason);
}
JS_FRIEND_API(JSPrincipals *)

View File

@ -3252,7 +3252,7 @@ GCRuntime::maybeAllocTriggerZoneGC(Zone *zone, const AutoLockGC &lock)
// to try to avoid performing non-incremental GCs on zones
// which allocate a lot of data, even when incremental slices
// can't be triggered via scheduling in the event loop.
triggerZoneGC(zone, JS::gcreason::INCREMENTAL_ALLOC_TRIGGER);
triggerZoneGC(zone, JS::gcreason::ALLOC_TRIGGER);
// Delay the next slice until a certain amount of allocation
// has been performed.
@ -3321,7 +3321,7 @@ GCRuntime::maybeGC(Zone *zone)
!isBackgroundSweeping())
{
PrepareZoneForGC(zone);
gc(GC_NORMAL, JS::gcreason::MAYBEGC);
gcSlice(GC_NORMAL, JS::gcreason::MAYBEGC);
return true;
}
@ -3347,7 +3347,7 @@ GCRuntime::maybePeriodicFullGC()
numArenasFreeCommitted > decommitThreshold)
{
JS::PrepareForFullGC(rt);
gc(GC_SHRINK, JS::gcreason::MAYBEGC);
gcSlice(GC_SHRINK, JS::gcreason::MAYBEGC);
} else {
nextFullGCTime = now + GC_IDLE_FULL_SPAN;
}
@ -5763,16 +5763,9 @@ GCRuntime::resetIncrementalGC(const char *reason)
/* Finish sweeping the current zone group, then abort. */
abortSweepAfterCurrentGroup = true;
/* Don't perform any compaction after sweeping. */
JSGCInvocationKind oldInvocationKind = invocationKind;
invocationKind = GC_NORMAL;
SliceBudget budget;
incrementalCollectSlice(budget, JS::gcreason::RESET);
invocationKind = oldInvocationKind;
{
gcstats::AutoPhase ap(stats, gcstats::PHASE_WAIT_BACKGROUND_THREAD);
rt->gc.waitBackgroundSweepOrAllocEnd();
@ -6095,7 +6088,8 @@ class AutoDisableStoreBuffer
* to run another cycle.
*/
MOZ_NEVER_INLINE bool
GCRuntime::gcCycle(bool incremental, SliceBudget &budget, JS::gcreason::Reason reason)
GCRuntime::gcCycle(bool incremental, SliceBudget &budget, JSGCInvocationKind gckind,
JS::gcreason::Reason reason)
{
minorGC(reason);
@ -6158,6 +6152,10 @@ GCRuntime::gcCycle(bool incremental, SliceBudget &budget, JS::gcreason::Reason r
TraceMajorGCStart();
/* Set the invocation kind in the first slice. */
if (!isIncrementalGCInProgress())
invocationKind = gckind;
incrementalCollectSlice(budget, reason);
#ifndef JS_MORE_DETERMINISTIC
@ -6242,7 +6240,8 @@ GCRuntime::scanZonesBeforeGC()
}
void
GCRuntime::collect(bool incremental, SliceBudget budget, JS::gcreason::Reason reason)
GCRuntime::collect(bool incremental, SliceBudget &budget, JSGCInvocationKind gckind,
JS::gcreason::Reason reason)
{
/* GC shouldn't be running in parallel execution mode */
MOZ_ALWAYS_TRUE(!InParallelSection());
@ -6269,9 +6268,9 @@ GCRuntime::collect(bool incremental, SliceBudget budget, JS::gcreason::Reason re
AutoStopVerifyingBarriers av(rt, reason == JS::gcreason::SHUTDOWN_CC ||
reason == JS::gcreason::DESTROY_RUNTIME);
gcstats::AutoGCSlice agc(stats, scanZonesBeforeGC(), invocationKind, reason);
gcstats::AutoGCSlice agc(stats, scanZonesBeforeGC(), gckind, reason);
cleanUpEverything = ShouldCleanUpEverything(reason, invocationKind);
cleanUpEverything = ShouldCleanUpEverything(reason, gckind);
bool repeat = false;
do {
@ -6286,7 +6285,7 @@ GCRuntime::collect(bool incremental, SliceBudget budget, JS::gcreason::Reason re
}
poked = false;
bool wasReset = gcCycle(incremental, budget, reason);
bool wasReset = gcCycle(incremental, budget, gckind, reason);
if (!isIncrementalGCInProgress()) {
gcstats::AutoPhase ap(stats, gcstats::PHASE_GC_END);
@ -6328,48 +6327,34 @@ GCRuntime::collect(bool incremental, SliceBudget budget, JS::gcreason::Reason re
EnqueuePendingParseTasksAfterGC(rt);
}
SliceBudget
GCRuntime::defaultBudget(JS::gcreason::Reason reason, int64_t millis)
{
if (millis == 0) {
if (reason == JS::gcreason::ALLOC_TRIGGER)
millis = sliceBudget;
else if (schedulingState.inHighFrequencyGCMode() && tunables.isDynamicMarkSliceEnabled())
millis = sliceBudget * IGC_MARK_SLICE_MULTIPLIER;
else
millis = sliceBudget;
}
return SliceBudget(TimeBudget(millis));
}
void
GCRuntime::gc(JSGCInvocationKind gckind, JS::gcreason::Reason reason)
{
invocationKind = gckind;
collect(false, SliceBudget(), reason);
SliceBudget budget;
collect(false, budget, gckind, reason);
}
void
GCRuntime::startGC(JSGCInvocationKind gckind, JS::gcreason::Reason reason, int64_t millis)
GCRuntime::gcSlice(JSGCInvocationKind gckind, JS::gcreason::Reason reason, int64_t millis)
{
MOZ_ASSERT(!isIncrementalGCInProgress());
invocationKind = gckind;
collect(true, defaultBudget(reason, millis), reason);
SliceBudget budget;
if (millis)
budget = SliceBudget(TimeBudget(millis));
else if (reason == JS::gcreason::ALLOC_TRIGGER)
budget = SliceBudget(TimeBudget(sliceBudget));
else if (schedulingState.inHighFrequencyGCMode() && tunables.isDynamicMarkSliceEnabled())
budget = SliceBudget(TimeBudget(sliceBudget * IGC_MARK_SLICE_MULTIPLIER));
else
budget = SliceBudget(TimeBudget(sliceBudget));
collect(true, budget, gckind, reason);
}
void
GCRuntime::gcSlice(JS::gcreason::Reason reason, int64_t millis)
GCRuntime::gcFinalSlice(JSGCInvocationKind gckind, JS::gcreason::Reason reason)
{
MOZ_ASSERT(isIncrementalGCInProgress());
collect(true, defaultBudget(reason, millis), reason);
}
void
GCRuntime::finishGC(JS::gcreason::Reason reason)
{
MOZ_ASSERT(isIncrementalGCInProgress());
collect(true, SliceBudget(), reason);
SliceBudget budget;
collect(true, budget, gckind, reason);
}
void
@ -6388,14 +6373,14 @@ GCRuntime::notifyDidPaint()
if (zealMode == ZealFrameGCValue) {
JS::PrepareForFullGC(rt);
gc(GC_NORMAL, JS::gcreason::REFRESH_FRAME);
gcSlice(GC_NORMAL, JS::gcreason::REFRESH_FRAME);
return;
}
#endif
if (isIncrementalGCInProgress() && !interFrameGC) {
if (JS::IsIncrementalGCInProgress(rt) && !interFrameGC) {
JS::PrepareForIncrementalGC(rt);
gcSlice(JS::gcreason::REFRESH_FRAME);
gcSlice(GC_NORMAL, JS::gcreason::REFRESH_FRAME);
}
interFrameGC = false;
@ -6415,14 +6400,12 @@ void
GCRuntime::gcDebugSlice(SliceBudget &budget)
{
if (!ZonesSelected(rt)) {
if (isIncrementalGCInProgress())
if (JS::IsIncrementalGCInProgress(rt))
JS::PrepareForIncrementalGC(rt);
else
JS::PrepareForFullGC(rt);
}
if (!isIncrementalGCInProgress())
invocationKind = GC_NORMAL;
collect(true, budget, JS::gcreason::DEBUG_GC);
collect(true, budget, GC_NORMAL, JS::gcreason::DEBUG_GC);
}
/* Schedule a full GC unless a zone will already be collected. */
@ -6543,14 +6526,7 @@ GCRuntime::gcIfNeeded(JSContext *cx /* = nullptr */)
}
if (majorGCRequested) {
if (majorGCTriggerReason == JS::gcreason::INCREMENTAL_ALLOC_TRIGGER) {
if (!isIncrementalGCInProgress())
startGC(GC_NORMAL, majorGCTriggerReason);
else
gcSlice(majorGCTriggerReason);
} else {
gc(GC_NORMAL, majorGCTriggerReason);
}
gcSlice(GC_NORMAL, rt->gc.majorGCTriggerReason);
return true;
}
@ -6715,9 +6691,7 @@ GCRuntime::runDebugGC()
budget = SliceBudget(WorkBudget(1));
}
if (!isIncrementalGCInProgress())
invocationKind = GC_NORMAL;
collect(true, budget, JS::gcreason::DEBUG_GC);
collect(true, budget, GC_NORMAL, JS::gcreason::DEBUG_GC);
/*
* For multi-slice zeal, reset the slice size when we get to the sweep
@ -6729,9 +6703,9 @@ GCRuntime::runDebugGC()
incrementalLimit = zealFrequency / 2;
}
} else if (type == ZealCompactValue) {
gc(GC_SHRINK, JS::gcreason::DEBUG_GC);
collect(false, budget, GC_SHRINK, JS::gcreason::DEBUG_GC);
} else {
gc(GC_NORMAL, JS::gcreason::DEBUG_GC);
collect(false, budget, GC_NORMAL, JS::gcreason::DEBUG_GC);
}
#endif

View File

@ -945,6 +945,17 @@ TraceRuntime(JSTracer *trc);
extern void
ReleaseAllJITCode(FreeOp *op);
/*
* Kinds of js_GC invocation.
*/
typedef enum JSGCInvocationKind {
/* Normal invocation. */
GC_NORMAL = 0,
/* Minimize GC triggers and release empty GC chunks right away. */
GC_SHRINK = 1
} JSGCInvocationKind;
extern void
PrepareForDebugGC(JSRuntime *rt);

View File

@ -2750,7 +2750,7 @@ nsXPCComponents_Utils::ForceGC()
{
JSRuntime* rt = nsXPConnect::GetRuntimeInstance()->Runtime();
PrepareForFullGC(rt);
GCForReason(rt, GC_NORMAL, gcreason::COMPONENT_UTILS);
GCForReason(rt, gcreason::COMPONENT_UTILS);
return NS_OK;
}
@ -2800,7 +2800,7 @@ nsXPCComponents_Utils::ForceShrinkingGC()
{
JSRuntime* rt = nsXPConnect::GetRuntimeInstance()->Runtime();
PrepareForFullGC(rt);
GCForReason(rt, GC_SHRINK, gcreason::COMPONENT_UTILS);
ShrinkingGC(rt, gcreason::COMPONENT_UTILS);
return NS_OK;
}
@ -2823,8 +2823,10 @@ class PreciseGCRunnable : public nsRunnable
}
PrepareForFullGC(rt);
JSGCInvocationKind gckind = mShrinking ? GC_SHRINK : GC_NORMAL;
GCForReason(rt, gckind, gcreason::COMPONENT_UTILS);
if (mShrinking)
ShrinkingGC(rt, gcreason::COMPONENT_UTILS);
else
GCForReason(rt, gcreason::COMPONENT_UTILS);
mCallback->Callback();
return NS_OK;

View File

@ -1025,7 +1025,7 @@ CycleCollectedJSRuntime::GarbageCollect(uint32_t aReason) const
JS::gcreason::Reason gcreason = static_cast<JS::gcreason::Reason>(aReason);
JS::PrepareForFullGC(mJSRuntime);
JS::GCForReason(mJSRuntime, GC_NORMAL, gcreason);
JS::GCForReason(mJSRuntime, gcreason);
}
void