[Interpreter] Handles stack overflow in interpreter.

Handles stack overflow in interpreter.
1. When visiting function literal, if the shared function
 info cannot be found we should return a stack overflow.
2. When visiting the ast graph, if stack overflow happens
 then all the ast nodes are not visited, so we need to have
appropriate handling in the AccumulatorResultScope and
RegisterResultScope.
3. MakeBytecode should not return a suceess unconditionally.
If there is a stack overflow, it should return false, so
RangeError can be thrown.

BUG=v8:4280,v8:4680
LOG=N

Review URL: https://codereview.chromium.org/1721983005

Cr-Commit-Position: refs/heads/master@{#34282}
This commit is contained in:
mythria 2016-02-25 03:26:30 -08:00 committed by Commit bot
parent 6809588a9a
commit 4d325854f2
3 changed files with 17 additions and 12 deletions

View File

@ -450,7 +450,7 @@ class BytecodeGenerator::ExpressionResultScope {
virtual ~ExpressionResultScope() {
generator_->set_execution_result(outer_);
DCHECK(result_identified());
DCHECK(result_identified() || generator_->HasStackOverflow());
}
bool IsEffect() const { return kind_ == Expression::kEffect; }
@ -462,6 +462,7 @@ class BytecodeGenerator::ExpressionResultScope {
protected:
ExpressionResultScope* outer() const { return outer_; }
BytecodeArrayBuilder* builder() const { return generator_->builder(); }
BytecodeGenerator* generator() const { return generator_; }
const RegisterAllocationScope* allocator() const { return &allocator_; }
void set_result_identified() {
@ -536,7 +537,12 @@ class BytecodeGenerator::RegisterResultScope final
set_result_identified();
}
Register ResultRegister() const { return result_register_; }
Register ResultRegister() {
if (generator()->HasStackOverflow() && !result_identified()) {
SetResultInAccumulator();
}
return result_register_;
}
private:
Register result_register_;
@ -1267,7 +1273,9 @@ void BytecodeGenerator::VisitFunctionLiteral(FunctionLiteral* expr) {
// Find or build a shared function info.
Handle<SharedFunctionInfo> shared_info =
Compiler::GetSharedFunctionInfo(expr, info()->script(), info());
CHECK(!shared_info.is_null()); // TODO(rmcilroy): Set stack overflow?
if (shared_info.is_null()) {
return SetStackOverflow();
}
builder()->CreateClosure(shared_info,
expr->pretenure() ? TENURED : NOT_TENURED);
execution_result()->SetResultInAccumulator();

View File

@ -90,6 +90,9 @@ bool Interpreter::MakeBytecode(CompilationInfo* info) {
BytecodeGenerator generator(info->isolate(), info->zone());
info->EnsureFeedbackVector();
Handle<BytecodeArray> bytecodes = generator.MakeBytecode(info);
if (generator.HasStackOverflow()) return false;
if (FLAG_print_bytecode) {
OFStream os(stdout);
bytecodes->Print(os);

View File

@ -776,10 +776,6 @@
# Skip strong mode tests since strong mode is unsupported on ignition.
'strong/*': [SKIP],
# TODO(mstarzinger): Flushes out a similar, but different issue to what the
# regression test was designed to test against. Investigate separately.
'regress/regress-crbug-589472': [SKIP],
# TODO(yangguo,4690): Requires debugger support.
'es6/debug*': [SKIP],
'harmony/debug*': [SKIP],
@ -864,11 +860,9 @@
'harmony/reflect-construct': [FAIL],
'es6/promises': [FAIL],
# TODO(rmcilroy,4680): Check failed in
# BytecodeGenerator::VisitFunctionLiteral - !shared_info.is_null().
'regress/regress-crbug-429159': [FAIL],
# TODO(rmcilroy,4680): Pass on debug, fail on release.
# TODO(rmcilroy,4680): Pass on debug, fail on release. Fails in both modes.
# the line numbers in the stack trace are incorrect. In debug mode somehow
# does not get flagged as a failure.
'compiler/regress-stacktrace-methods': [PASS, ['mode == release', FAIL]],
# TODO(rmcilroy,4680): Test assert failures.