Bug 909972 - Avoid unnecessary GCs in asm.js compilation; r=luke

--HG--
extra : rebase_source : 41a55a9f837016efbcf013f9b51e9f5f5c48f28b
This commit is contained in:
Terrence Cole 2013-10-17 09:12:23 -07:00
Родитель 0050cf6519
Коммит f34062284c
2 изменённых файлов: 31 добавлений и 6 удалений

Просмотреть файл

@ -1231,6 +1231,7 @@ class MOZ_STACK_CLASS ModuleCompiler
char * errorString_;
uint32_t errorOffset_;
bool errorOverRecursed_;
int64_t usecBefore_;
SlowFunctionVector slowFunctions_;
@ -1260,6 +1261,7 @@ class MOZ_STACK_CLASS ModuleCompiler
globalAccesses_(cx),
errorString_(nullptr),
errorOffset_(UINT32_MAX),
errorOverRecursed_(false),
usecBefore_(PRMJ_Now()),
slowFunctions_(cx),
finishedFunctionBodies_(false)
@ -1275,6 +1277,8 @@ class MOZ_STACK_CLASS ModuleCompiler
errorString_);
js_free(errorString_);
}
if (errorOverRecursed_)
js_ReportOverRecursed(cx_);
// Avoid spurious Label assertions on compilation failure.
if (!stackOverflowLabel_.bound())
@ -1324,7 +1328,15 @@ class MOZ_STACK_CLASS ModuleCompiler
}
bool fail(ParseNode *pn, const char *str) {
return failOffset(pn ? pn->pn_pos.begin : parser_.tokenStream.peekTokenPos().begin, str);
if (pn)
return failOffset(pn->pn_pos.begin, str);
// The exact rooting static analysis does not perform dataflow analysis, so it believes
// that unrooted things on the stack during compilation may still be accessed after this.
// Since pn is typically only null under OOM, this suppression simply forces any GC to be
// delayed until the compilation is off the stack and more memory can be freed.
gc::AutoSuppressGC nogc(cx_);
return failOffset(parser_.tokenStream.peekTokenPos().begin, str);
}
bool failfVA(ParseNode *pn, const char *fmt, va_list ap) {
@ -1353,6 +1365,11 @@ class MOZ_STACK_CLASS ModuleCompiler
return false;
}
bool failOverRecursed() {
errorOverRecursed_ = true;
return false;
}
static const unsigned SLOW_FUNCTION_THRESHOLD_MS = 250;
bool maybeReportCompileTime(const Func &func) {
@ -3813,7 +3830,7 @@ CheckMathBuiltinCall(FunctionCompiler &f, ParseNode *callNode, AsmJSMathBuiltin
static bool
CheckCall(FunctionCompiler &f, ParseNode *call, RetType retType, MDefinition **def, Type *type)
{
JS_CHECK_RECURSION(f.cx(), return false);
JS_CHECK_RECURSION_DONT_REPORT(f.cx(), return f.m().failOverRecursed());
ParseNode *callee = CallCallee(call);
@ -4104,7 +4121,7 @@ static bool
CheckAddOrSub(FunctionCompiler &f, ParseNode *expr, MDefinition **def, Type *type,
unsigned *numAddOrSubOut = nullptr)
{
JS_CHECK_RECURSION(f.cx(), return false);
JS_CHECK_RECURSION_DONT_REPORT(f.cx(), return f.m().failOverRecursed());
JS_ASSERT(expr->isKind(PNK_ADD) || expr->isKind(PNK_SUB));
ParseNode *lhs = BinaryLeft(expr);
@ -4308,7 +4325,7 @@ CheckBitwise(FunctionCompiler &f, ParseNode *bitwise, MDefinition **def, Type *t
static bool
CheckExpr(FunctionCompiler &f, ParseNode *expr, MDefinition **def, Type *type)
{
JS_CHECK_RECURSION(f.cx(), return false);
JS_CHECK_RECURSION_DONT_REPORT(f.cx(), return f.m().failOverRecursed());
if (!f.mirGen().ensureBallast())
return false;
@ -4781,7 +4798,7 @@ CheckStatementList(FunctionCompiler &f, ParseNode *stmtList)
static bool
CheckStatement(FunctionCompiler &f, ParseNode *stmt, LabelVector *maybeLabels)
{
JS_CHECK_RECURSION(f.cx(), return false);
JS_CHECK_RECURSION_DONT_REPORT(f.cx(), return f.m().failOverRecursed());
if (!f.mirGen().ensureBallast())
return false;

Просмотреть файл

@ -665,7 +665,7 @@ GetNativeStackLimit(JSContext *cx)
* extra space so that we can ensure that crucial code is able to run.
*/
#define JS_CHECK_RECURSION(cx, onerror) \
#define JS_CHECK_RECURSION(cx, onerror) \
JS_BEGIN_MACRO \
int stackDummy_; \
if (!JS_CHECK_STACK_SIZE(js::GetNativeStackLimit(cx), &stackDummy_)) { \
@ -674,6 +674,14 @@ GetNativeStackLimit(JSContext *cx)
} \
JS_END_MACRO
#define JS_CHECK_RECURSION_DONT_REPORT(cx, onerror) \
JS_BEGIN_MACRO \
int stackDummy_; \
if (!JS_CHECK_STACK_SIZE(js::GetNativeStackLimit(cx), &stackDummy_)) { \
onerror; \
} \
JS_END_MACRO
#define JS_CHECK_RECURSION_WITH_SP_DONT_REPORT(cx, sp, onerror) \
JS_BEGIN_MACRO \
if (!JS_CHECK_STACK_SIZE(js::GetNativeStackLimit(cx), sp)) { \