mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 723350 - Improve last-ditch GC trigger. r=billm
This commit is contained in:
parent
6fe7f5539e
commit
7a2a29c947
@ -757,7 +757,6 @@ JSRuntime::JSRuntime()
|
||||
gcCallback(NULL),
|
||||
gcSliceCallback(NULL),
|
||||
gcFinalizeCallback(NULL),
|
||||
gcMallocBytes(0),
|
||||
gcBlackRootsTraceOp(NULL),
|
||||
gcBlackRootsData(NULL),
|
||||
gcGrayRootsTraceOp(NULL),
|
||||
|
@ -1102,22 +1102,10 @@ JSContext::runningWithTrustedPrincipals() const
|
||||
void
|
||||
JSRuntime::updateMallocCounter(JSContext *cx, size_t nbytes)
|
||||
{
|
||||
/* We tolerate any thread races when updating gcMallocBytes. */
|
||||
ptrdiff_t oldCount = gcMallocBytes;
|
||||
ptrdiff_t newCount = oldCount - ptrdiff_t(nbytes);
|
||||
gcMallocBytes = newCount;
|
||||
if (JS_UNLIKELY(newCount <= 0 && oldCount > 0))
|
||||
onTooMuchMalloc();
|
||||
else if (cx && cx->compartment)
|
||||
if (cx && cx->compartment)
|
||||
cx->compartment->updateMallocCounter(nbytes);
|
||||
}
|
||||
|
||||
JS_FRIEND_API(void)
|
||||
JSRuntime::onTooMuchMalloc()
|
||||
{
|
||||
TriggerGC(this, gcreason::TOO_MUCH_MALLOC);
|
||||
}
|
||||
|
||||
JS_FRIEND_API(void *)
|
||||
JSRuntime::onOutOfMemory(void *p, size_t nbytes, JSContext *cx)
|
||||
{
|
||||
|
@ -644,13 +644,6 @@ struct JSRuntime : js::RuntimeFriendFields
|
||||
js::GCSliceCallback gcSliceCallback;
|
||||
JSFinalizeCallback gcFinalizeCallback;
|
||||
|
||||
private:
|
||||
/*
|
||||
* Malloc counter to measure memory pressure for GC scheduling. It runs
|
||||
* from gcMaxMallocBytes down to zero.
|
||||
*/
|
||||
volatile ptrdiff_t gcMallocBytes;
|
||||
|
||||
public:
|
||||
/*
|
||||
* The trace operations to trace embedding-specific GC roots. One is for
|
||||
@ -855,17 +848,8 @@ struct JSRuntime : js::RuntimeFriendFields
|
||||
JS_DECLARE_NEW_METHODS(malloc_, JS_ALWAYS_INLINE)
|
||||
JS_DECLARE_DELETE_METHODS(free_, JS_ALWAYS_INLINE)
|
||||
|
||||
bool isGCMallocLimitReached() const { return gcMallocBytes <= 0; }
|
||||
|
||||
void resetGCMallocBytes() { gcMallocBytes = ptrdiff_t(gcMaxMallocBytes); }
|
||||
|
||||
void setGCMaxMallocBytes(size_t value) {
|
||||
/*
|
||||
* For compatibility treat any value that exceeds PTRDIFF_T_MAX to
|
||||
* mean that value.
|
||||
*/
|
||||
gcMaxMallocBytes = (ptrdiff_t(value) >= 0) ? value : size_t(-1) >> 1;
|
||||
resetGCMallocBytes();
|
||||
gcMaxMallocBytes = value;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -877,12 +861,6 @@ struct JSRuntime : js::RuntimeFriendFields
|
||||
* the caller must ensure that no deadlock possible during OOM reporting.
|
||||
*/
|
||||
void updateMallocCounter(JSContext *cx, size_t nbytes);
|
||||
|
||||
/*
|
||||
* The function must be called outside the GC lock.
|
||||
*/
|
||||
JS_FRIEND_API(void) onTooMuchMalloc();
|
||||
|
||||
/*
|
||||
* This should be called after system malloc/realloc returns NULL to try
|
||||
* to recove some memory or to report an error. Failures in malloc and
|
||||
|
@ -535,17 +535,13 @@ JSCompartment::purge()
|
||||
void
|
||||
JSCompartment::resetGCMallocBytes()
|
||||
{
|
||||
gcMallocBytes = ptrdiff_t(gcMaxMallocBytes);
|
||||
gcMallocBytes = gcMaxMallocBytes;
|
||||
}
|
||||
|
||||
void
|
||||
JSCompartment::setGCMaxMallocBytes(size_t value)
|
||||
{
|
||||
/*
|
||||
* For compatibility treat any value that exceeds PTRDIFF_T_MAX to
|
||||
* mean that value.
|
||||
*/
|
||||
gcMaxMallocBytes = (ptrdiff_t(value) >= 0) ? value : size_t(-1) >> 1;
|
||||
gcMaxMallocBytes = value;
|
||||
resetGCMallocBytes();
|
||||
}
|
||||
|
||||
|
@ -178,7 +178,6 @@ struct JSCompartment
|
||||
|
||||
size_t gcBytes;
|
||||
size_t gcTriggerBytes;
|
||||
size_t gcMaxMallocBytes;
|
||||
|
||||
bool hold;
|
||||
bool isSystemCompartment;
|
||||
@ -245,7 +244,8 @@ struct JSCompartment
|
||||
* gcMaxMallocBytes down to zero. This counter should be used only when it's
|
||||
* not possible to know the size of a free.
|
||||
*/
|
||||
ptrdiff_t gcMallocBytes;
|
||||
size_t gcMallocBytes;
|
||||
size_t gcMaxMallocBytes;
|
||||
|
||||
enum { DebugFromC = 1, DebugFromJS = 2 };
|
||||
|
||||
@ -281,13 +281,19 @@ struct JSCompartment
|
||||
void resetGCMallocBytes();
|
||||
void setGCMaxMallocBytes(size_t value);
|
||||
void updateMallocCounter(size_t nbytes) {
|
||||
ptrdiff_t oldCount = gcMallocBytes;
|
||||
ptrdiff_t newCount = oldCount - ptrdiff_t(nbytes);
|
||||
size_t oldCount = gcMallocBytes;
|
||||
size_t newCount = oldCount - nbytes;
|
||||
gcMallocBytes = newCount;
|
||||
if (JS_UNLIKELY(newCount <= 0 && oldCount > 0))
|
||||
// gcMallocBytes will wrap around and be bigger than gcMaxAllocBytes if a signed value
|
||||
// would be < 0
|
||||
if (JS_UNLIKELY(oldCount <= gcMaxMallocBytes && newCount > gcMaxMallocBytes))
|
||||
onTooMuchMalloc();
|
||||
}
|
||||
|
||||
bool isTooMuchMalloc() const {
|
||||
return gcMallocBytes > gcMaxMallocBytes;
|
||||
}
|
||||
|
||||
void onTooMuchMalloc();
|
||||
|
||||
void mallocInCompartment(size_t nbytes) {
|
||||
|
@ -1666,7 +1666,8 @@ ArenaLists::refillFreeList(JSContext *cx, AllocKind thingKind)
|
||||
JSRuntime *rt = comp->rt;
|
||||
JS_ASSERT(!rt->gcRunning);
|
||||
|
||||
bool runGC = rt->gcIncrementalState != NO_INCREMENTAL && comp->gcBytes > comp->gcTriggerBytes;
|
||||
bool runGC = rt->gcIncrementalState != NO_INCREMENTAL &&
|
||||
(comp->gcBytes > comp->gcTriggerBytes || comp->isTooMuchMalloc());
|
||||
for (;;) {
|
||||
if (JS_UNLIKELY(runGC)) {
|
||||
PrepareCompartmentForGC(comp);
|
||||
@ -3308,8 +3309,6 @@ AutoGCSession::AutoGCSession(JSRuntime *rt)
|
||||
|
||||
runtime->gcNumber++;
|
||||
|
||||
runtime->resetGCMallocBytes();
|
||||
|
||||
/* Clear gcMallocBytes for all compartments */
|
||||
for (CompartmentsIter c(runtime); !c.done(); c.next())
|
||||
c->resetGCMallocBytes();
|
||||
|
Loading…
Reference in New Issue
Block a user