Bug 990787, part 1 - When JSObject::shrinkElements can't reallocate the array to shrink it, clear the OOM exception, as we are not going to propagate the error. r=shu.

--HG--
extra : rebase_source : 42d1d8c25a0b31d20b137ca4f2ff7f592e7fdcd8
This commit is contained in:
Jason Orendorff 2014-04-08 12:35:17 -05:00
parent 816a5b2291
commit a8094a4eac
3 changed files with 31 additions and 6 deletions

View File

@ -1056,7 +1056,7 @@ js::HandleExecutionInterrupt(JSContext *cx)
return true;
}
js::ThreadSafeContext::ThreadSafeContext(JSRuntime *rt, PerThreadData *pt, ContextKind kind)
ThreadSafeContext::ThreadSafeContext(JSRuntime *rt, PerThreadData *pt, ContextKind kind)
: ContextFriendFields(rt),
contextKind_(kind),
perThreadData(pt),
@ -1077,6 +1077,25 @@ ThreadSafeContext::asForkJoinContext()
return reinterpret_cast<ForkJoinContext *>(this);
}
void
ThreadSafeContext::recoverFromOutOfMemory()
{
// If this is not a JSContext, there's nothing to do.
if (JSContext *maybecx = maybeJSContext()) {
if (maybecx->isExceptionPending()) {
#ifdef DEBUG
RootedValue v(maybecx);
bool ok = maybecx->getPendingException(&v);
MOZ_ASSERT(ok);
MOZ_ASSERT(v == StringValue(maybecx->names().outOfMemory));
#endif
maybecx->clearPendingException();
} else {
MOZ_ASSERT(maybecx->runtime()->hadOutOfMemory);
}
}
}
JSContext::JSContext(JSRuntime *rt)
: ExclusiveContext(rt, &rt->mainThread, Context_JS),
throwing(false),

View File

@ -266,6 +266,9 @@ struct ThreadSafeContext : ContextFriendFields,
return runtime_->onOutOfMemory(p, nbytes, maybeJSContext());
}
/* Clear the pending exception (if any) due to OOM. */
void recoverFromOutOfMemory();
inline void updateMallocCounter(size_t nbytes) {
// Note: this is racy.
runtime_->updateMallocCounter(zone_, nbytes);

View File

@ -3055,8 +3055,9 @@ ReallocateElements(ThreadSafeContext *cx, JSObject *obj, ObjectElements *oldHead
{
#ifdef JSGC_GENERATIONAL
if (cx->isJSContext()) {
return cx->asJSContext()->runtime()-> gcNursery.reallocateElements(cx->asJSContext(), obj, oldHeader,
oldCount, newCount);
return cx->asJSContext()->runtime()->gcNursery.reallocateElements(cx->asJSContext(), obj,
oldHeader, oldCount,
newCount);
}
#endif
@ -3140,7 +3141,7 @@ JSObject::shrinkElements(ThreadSafeContext *cx, uint32_t newcap)
uint32_t oldcap = getDenseCapacity();
JS_ASSERT(newcap <= oldcap);
/* Don't shrink elements below the minimum capacity. */
// Don't shrink elements below the minimum capacity.
if (oldcap <= SLOT_CAPACITY_MIN || !hasDynamicElements())
return;
@ -3151,8 +3152,10 @@ JSObject::shrinkElements(ThreadSafeContext *cx, uint32_t newcap)
ObjectElements *newheader = ReallocateElements(cx, this, getElementsHeader(),
oldAllocated, newAllocated);
if (!newheader)
return; /* Leave elements at its old size. */
if (!newheader) {
cx->recoverFromOutOfMemory();
return; // Leave elements at its old size.
}
newheader->capacity = newcap;
elements = newheader->elements();