Bug 987995, part 1 - Add testing functions reportOutOfMemory and reportLargeAllocationFailure. r=terrence.

This commit is contained in:
Jason Orendorff 2014-05-22 08:18:01 -05:00
parent edcba926bc
commit ea37a7d727
3 changed files with 45 additions and 9 deletions

View File

@ -1622,6 +1622,26 @@ DumpObject(JSContext *cx, unsigned argc, jsval *vp)
}
#endif
static bool
ReportOutOfMemory(JSContext *cx, unsigned argc, jsval *vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
JS_ReportOutOfMemory(cx);
cx->clearPendingException();
args.rval().setUndefined();
return true;
}
static bool
ReportLargeAllocationFailure(JSContext *cx, unsigned argc, jsval *vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
void *buf = cx->runtime()->onOutOfMemoryCanGC(NULL, JSRuntime::LARGE_ALLOCATION);
js_free(buf);
args.rval().setUndefined();
return true;
}
static const JSFunctionSpecWithHelp TestingFunctions[] = {
JS_FN_HELP("gc", ::GC, 0, 0,
"gc([obj] | 'compartment')",
@ -1892,6 +1912,16 @@ static const JSFunctionSpecWithHelp TestingFunctions[] = {
"stopTraceLogger()",
" Stop logging the mainThread."),
JS_FN_HELP("reportOutOfMemory", ReportOutOfMemory, 0, 0,
"reportOutOfMemory()",
" Report OOM, then clear the exception and return undefined. For crash testing."),
JS_FN_HELP("reportLargeAllocationFailure", ReportLargeAllocationFailure, 0, 0,
"reportLargeAllocationFailure()",
" Call the large allocation failure callback, as though a large malloc call failed,\n"
" then return undefined. In Gecko, this sends a memory pressure notification, which\n"
" can free up some memory."),
#ifdef DEBUG
JS_FN_HELP("dumpObject", DumpObject, 1, 0,
"dumpObject()",

View File

@ -759,7 +759,7 @@ JSRuntime::onOutOfMemory(void *p, size_t nbytes, JSContext *cx)
else if (p == reinterpret_cast<void *>(1))
p = js_calloc(nbytes);
else
p = js_realloc(p, nbytes);
p = js_realloc(p, nbytes);
if (p)
return p;
if (cx)
@ -767,6 +767,15 @@ JSRuntime::onOutOfMemory(void *p, size_t nbytes, JSContext *cx)
return nullptr;
}
void *
JSRuntime::onOutOfMemoryCanGC(void *p, size_t bytes)
{
if (!largeAllocationFailureCallback || bytes < LARGE_ALLOCATION)
return nullptr;
largeAllocationFailureCallback();
return onOutOfMemory(p, bytes);
}
bool
JSRuntime::activeGCInAtomsZone()
{

View File

@ -1316,6 +1316,9 @@ struct JSRuntime : public JS::shadow::Runtime,
JS_FRIEND_API(void *) onOutOfMemory(void *p, size_t nbytes);
JS_FRIEND_API(void *) onOutOfMemory(void *p, size_t nbytes, JSContext *cx);
/* onOutOfMemory but can call the largeAllocationFailureCallback. */
JS_FRIEND_API(void *) onOutOfMemoryCanGC(void *p, size_t bytes);
// Ways in which the interrupt callback on the runtime can be triggered,
// varying based on which thread is triggering the callback.
enum InterruptMode {
@ -1406,20 +1409,14 @@ struct JSRuntime : public JS::shadow::Runtime,
void *p = calloc_(bytes);
if (MOZ_LIKELY(!!p))
return p;
if (!largeAllocationFailureCallback || bytes < LARGE_ALLOCATION)
return nullptr;
largeAllocationFailureCallback();
return onOutOfMemory(reinterpret_cast<void *>(1), bytes);
return onOutOfMemoryCanGC(reinterpret_cast<void *>(1), bytes);
}
void *reallocCanGC(void *p, size_t bytes) {
void *p2 = realloc_(p, bytes);
if (MOZ_LIKELY(!!p2))
return p2;
if (!largeAllocationFailureCallback || bytes < LARGE_ALLOCATION)
return nullptr;
largeAllocationFailureCallback();
return onOutOfMemory(p, bytes);
return onOutOfMemoryCanGC(p, bytes);
}
};