[turbofan] Add JSStackCheck into loop bodies.
This allows loopy TurboFan code to be interrupted by placing a stack check (i.e. JSStackCheck node) into each loop. Note that we currently limit this to non-asm.js code. Also note that stack checks are actually placed after loop headers and not at back-branches, which allows us to reuse existing BailoutIds from Crankshaft. R=titzer@chromium.org Review URL: https://codereview.chromium.org/1065923002 Cr-Commit-Position: refs/heads/master@{#27666}
This commit is contained in:
parent
87a27e42ea
commit
322cfb3589
@ -1484,12 +1484,6 @@ MaybeHandle<Code> Compiler::GetOptimizedCode(Handle<JSFunction> function,
|
||||
return MaybeHandle<Code>();
|
||||
}
|
||||
|
||||
// TODO(titzer): Some top-level code times out because of missing interrupt
|
||||
// checks at back-branches, these are currently marked with --no-turbo-osr.
|
||||
if (shared->is_toplevel() && !FLAG_turbo_osr) {
|
||||
return MaybeHandle<Code>();
|
||||
}
|
||||
|
||||
info->SetOptimizing(osr_ast_id, current_code);
|
||||
|
||||
if (mode == CONCURRENT) {
|
||||
|
@ -2487,6 +2487,12 @@ void AstGraphBuilder::VisitIfNotNull(Statement* stmt) {
|
||||
void AstGraphBuilder::VisitIterationBody(IterationStatement* stmt,
|
||||
LoopBuilder* loop) {
|
||||
ControlScopeForIteration scope(this, stmt, loop);
|
||||
// TODO(mstarzinger): For now we only allow to interrupt non-asm.js code,
|
||||
// which is a gigantic hack and should be extended to all code at some point.
|
||||
if (!info()->shared_info()->asm_function()) {
|
||||
Node* node = NewNode(javascript()->StackCheck());
|
||||
PrepareFrameState(node, stmt->StackCheckId());
|
||||
}
|
||||
Visit(stmt->body());
|
||||
}
|
||||
|
||||
|
@ -20037,7 +20037,6 @@ class RequestInterruptTestWithFunctionCall
|
||||
isolate_, ShouldContinueCallback, v8::External::New(isolate_, this));
|
||||
env_->Global()->Set(v8_str("ShouldContinue"), func);
|
||||
|
||||
i::FLAG_turbo_osr = false; // TODO(titzer): interrupts in TF loops.
|
||||
CompileRun("while (ShouldContinue()) { }");
|
||||
}
|
||||
};
|
||||
@ -20053,7 +20052,6 @@ class RequestInterruptTestWithMethodCall
|
||||
isolate_, ShouldContinueCallback, v8::External::New(isolate_, this)));
|
||||
env_->Global()->Set(v8_str("Klass"), t->GetFunction());
|
||||
|
||||
i::FLAG_turbo_osr = false; // TODO(titzer): interrupts in TF loops.
|
||||
CompileRun("var obj = new Klass; while (obj.shouldContinue()) { }");
|
||||
}
|
||||
};
|
||||
@ -20069,7 +20067,6 @@ class RequestInterruptTestWithAccessor
|
||||
isolate_, ShouldContinueCallback, v8::External::New(isolate_, this)));
|
||||
env_->Global()->Set(v8_str("Klass"), t->GetFunction());
|
||||
|
||||
i::FLAG_turbo_osr = false; // TODO(titzer): interrupts in TF loops.
|
||||
CompileRun("var obj = new Klass; while (obj.shouldContinue) { }");
|
||||
}
|
||||
};
|
||||
@ -20087,7 +20084,6 @@ class RequestInterruptTestWithNativeAccessor
|
||||
v8::External::New(isolate_, this));
|
||||
env_->Global()->Set(v8_str("Klass"), t->GetFunction());
|
||||
|
||||
i::FLAG_turbo_osr = false; // TODO(titzer): interrupts in TF loops.
|
||||
CompileRun("var obj = new Klass; while (obj.shouldContinue) { }");
|
||||
}
|
||||
|
||||
@ -20117,7 +20113,6 @@ class RequestInterruptTestWithMethodCallAndInterceptor
|
||||
|
||||
env_->Global()->Set(v8_str("Klass"), t->GetFunction());
|
||||
|
||||
i::FLAG_turbo_osr = false; // TODO(titzer): interrupts in TF loops.
|
||||
CompileRun("var obj = new Klass; while (obj.shouldContinue()) { }");
|
||||
}
|
||||
|
||||
@ -20142,7 +20137,6 @@ class RequestInterruptTestWithMathAbs
|
||||
v8::External::New(isolate_, this)));
|
||||
|
||||
i::FLAG_allow_natives_syntax = true;
|
||||
i::FLAG_turbo_osr = false; // TODO(titzer): interrupts in TF loops.
|
||||
CompileRun("function loopish(o) {"
|
||||
" var pre = 10;"
|
||||
" while (o.abs(1) > 0) {"
|
||||
@ -20226,7 +20220,6 @@ class RequestMultipleInterrupts : public RequestInterruptTestBase {
|
||||
isolate_, ShouldContinueCallback, v8::External::New(isolate_, this));
|
||||
env_->Global()->Set(v8_str("ShouldContinue"), func);
|
||||
|
||||
i::FLAG_turbo_osr = false; // TODO(titzer): interrupts in TF loops.
|
||||
CompileRun("while (ShouldContinue()) { }");
|
||||
}
|
||||
|
||||
|
@ -6697,7 +6697,6 @@ TEST(ProcessDebugMessagesThreaded) {
|
||||
v8::FunctionTemplate::New(isolate, StartSendingCommands);
|
||||
env->Global()->Set(v8_str("start"), start->GetFunction());
|
||||
|
||||
i::FLAG_turbo_osr = false; // TODO(titzer): interrupts in TF loops.
|
||||
CompileRun("start(); while (true) { }");
|
||||
|
||||
CHECK_EQ(20, counting_message_handler_counter);
|
||||
|
@ -152,7 +152,6 @@ TEST(TerminateOnlyV8ThreadFromThreadItselfNoLoop) {
|
||||
// Run a loop that will be infinite if thread termination does not work.
|
||||
v8::Handle<v8::String> source = v8::String::NewFromUtf8(
|
||||
CcTest::isolate(), "try { loop(); fail(); } catch(e) { fail(); }");
|
||||
i::FLAG_turbo_osr = false; // TODO(titzer): interrupts in TF loops.
|
||||
v8::Script::Compile(source)->Run();
|
||||
CHECK(!v8::V8::IsExecutionTerminating(CcTest::isolate()));
|
||||
// Test that we can run the code again after thread termination.
|
||||
@ -193,7 +192,6 @@ TEST(TerminateOnlyV8ThreadFromOtherThread) {
|
||||
// Run a loop that will be infinite if thread termination does not work.
|
||||
v8::Handle<v8::String> source = v8::String::NewFromUtf8(
|
||||
CcTest::isolate(), "try { loop(); fail(); } catch(e) { fail(); }");
|
||||
i::FLAG_turbo_osr = false; // TODO(titzer): interrupts in TF loops.
|
||||
v8::Script::Compile(source)->Run();
|
||||
|
||||
thread.Join();
|
||||
@ -362,7 +360,6 @@ TEST(TerminateCancelTerminateFromThreadItself) {
|
||||
CHECK(!v8::V8::IsExecutionTerminating(CcTest::isolate()));
|
||||
v8::Handle<v8::String> source = v8::String::NewFromUtf8(
|
||||
isolate, "try { doloop(); } catch(e) { fail(); } 'completed';");
|
||||
i::FLAG_turbo_osr = false; // TODO(titzer): interrupts in TF loops.
|
||||
// Check that execution completed with correct return value.
|
||||
CHECK(v8::Script::Compile(source)->Run()->Equals(v8_str("completed")));
|
||||
}
|
||||
@ -379,7 +376,6 @@ void MicrotaskLoopForever(const v8::FunctionCallbackInfo<v8::Value>& info) {
|
||||
// Enqueue another should-not-run task to ensure we clean out the queue
|
||||
// when we terminate.
|
||||
isolate->EnqueueMicrotask(v8::Function::New(isolate, MicrotaskShouldNotRun));
|
||||
i::FLAG_turbo_osr = false; // TODO(titzer): interrupts in TF loops.
|
||||
CompileRun("terminate(); while (true) { }");
|
||||
CHECK(v8::V8::IsExecutionTerminating());
|
||||
}
|
||||
@ -509,7 +505,6 @@ TEST(TerminationInInnerTryCall) {
|
||||
v8::Context::Scope context_scope(context);
|
||||
{
|
||||
v8::TryCatch try_catch;
|
||||
i::FLAG_turbo_osr = false; // TODO(titzer): interrupts in TF loops.
|
||||
CompileRun("inner_try_call_terminate()");
|
||||
CHECK(try_catch.HasTerminated());
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user