Commit 219018d1 authored by titzer's avatar titzer Committed by Commit bot

[turbofan] Fix OSR into functions where the expression stack is not empty.

R=mstarzinger@chromium.org
BUG=

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

Cr-Commit-Position: refs/heads/master@{#26376}
parent 4bf1f542
...@@ -405,6 +405,12 @@ class CompilationInfo { ...@@ -405,6 +405,12 @@ class CompilationInfo {
ast_value_factory_owned_ = owned; ast_value_factory_owned_ = owned;
} }
int osr_expr_stack_height() { return osr_expr_stack_height_; }
void set_osr_expr_stack_height(int height) {
DCHECK(height >= 0);
osr_expr_stack_height_ = height;
}
#if DEBUG #if DEBUG
void PrintAstForTesting(); void PrintAstForTesting();
#endif #endif
...@@ -531,6 +537,8 @@ class CompilationInfo { ...@@ -531,6 +537,8 @@ class CompilationInfo {
// should be abandoned due to dependency change. // should be abandoned due to dependency change.
bool aborted_due_to_dependency_change_; bool aborted_due_to_dependency_change_;
int osr_expr_stack_height_;
DISALLOW_COPY_AND_ASSIGN(CompilationInfo); DISALLOW_COPY_AND_ASSIGN(CompilationInfo);
}; };
......
...@@ -8,7 +8,6 @@ ...@@ -8,7 +8,6 @@
#include "src/compiler/code-generator-impl.h" #include "src/compiler/code-generator-impl.h"
#include "src/compiler/gap-resolver.h" #include "src/compiler/gap-resolver.h"
#include "src/compiler/node-matchers.h" #include "src/compiler/node-matchers.h"
#include "src/compiler/osr.h"
#include "src/scopes.h" #include "src/scopes.h"
namespace v8 { namespace v8 {
...@@ -807,10 +806,8 @@ void CodeGenerator::AssemblePrologue() { ...@@ -807,10 +806,8 @@ void CodeGenerator::AssemblePrologue() {
// remaining stack slots. // remaining stack slots.
if (FLAG_code_comments) __ RecordComment("-- OSR entrypoint --"); if (FLAG_code_comments) __ RecordComment("-- OSR entrypoint --");
osr_pc_offset_ = __ pc_offset(); osr_pc_offset_ = __ pc_offset();
int unoptimized_slots = DCHECK(stack_slots >= frame()->GetOsrStackSlotCount());
static_cast<int>(OsrHelper(info()).UnoptimizedFrameSlots()); stack_slots -= frame()->GetOsrStackSlotCount();
DCHECK(stack_slots >= unoptimized_slots);
stack_slots -= unoptimized_slots;
} }
if (stack_slots > 0) { if (stack_slots > 0) {
......
...@@ -8,7 +8,6 @@ ...@@ -8,7 +8,6 @@
#include "src/compiler/code-generator-impl.h" #include "src/compiler/code-generator-impl.h"
#include "src/compiler/gap-resolver.h" #include "src/compiler/gap-resolver.h"
#include "src/compiler/node-matchers.h" #include "src/compiler/node-matchers.h"
#include "src/compiler/osr.h"
#include "src/scopes.h" #include "src/scopes.h"
namespace v8 { namespace v8 {
...@@ -900,10 +899,8 @@ void CodeGenerator::AssemblePrologue() { ...@@ -900,10 +899,8 @@ void CodeGenerator::AssemblePrologue() {
// remaining stack slots. // remaining stack slots.
if (FLAG_code_comments) __ RecordComment("-- OSR entrypoint --"); if (FLAG_code_comments) __ RecordComment("-- OSR entrypoint --");
osr_pc_offset_ = __ pc_offset(); osr_pc_offset_ = __ pc_offset();
int unoptimized_slots = DCHECK(stack_slots >= frame()->GetOsrStackSlotCount());
static_cast<int>(OsrHelper(info()).UnoptimizedFrameSlots()); stack_slots -= frame()->GetOsrStackSlotCount();
DCHECK(stack_slots >= unoptimized_slots);
stack_slots -= unoptimized_slots;
} }
if (stack_slots > 0) { if (stack_slots > 0) {
......
...@@ -604,7 +604,7 @@ void AstGraphBuilder::VisitSwitchStatement(SwitchStatement* stmt) { ...@@ -604,7 +604,7 @@ void AstGraphBuilder::VisitSwitchStatement(SwitchStatement* stmt) {
void AstGraphBuilder::VisitDoWhileStatement(DoWhileStatement* stmt) { void AstGraphBuilder::VisitDoWhileStatement(DoWhileStatement* stmt) {
LoopBuilder while_loop(this); LoopBuilder while_loop(this);
while_loop.BeginLoop(GetVariablesAssignedInLoop(stmt), IsOsrLoopEntry(stmt)); while_loop.BeginLoop(GetVariablesAssignedInLoop(stmt), CheckOsrEntry(stmt));
VisitIterationBody(stmt, &while_loop, 0); VisitIterationBody(stmt, &while_loop, 0);
while_loop.EndBody(); while_loop.EndBody();
VisitForTest(stmt->cond()); VisitForTest(stmt->cond());
...@@ -616,7 +616,7 @@ void AstGraphBuilder::VisitDoWhileStatement(DoWhileStatement* stmt) { ...@@ -616,7 +616,7 @@ void AstGraphBuilder::VisitDoWhileStatement(DoWhileStatement* stmt) {
void AstGraphBuilder::VisitWhileStatement(WhileStatement* stmt) { void AstGraphBuilder::VisitWhileStatement(WhileStatement* stmt) {
LoopBuilder while_loop(this); LoopBuilder while_loop(this);
while_loop.BeginLoop(GetVariablesAssignedInLoop(stmt), IsOsrLoopEntry(stmt)); while_loop.BeginLoop(GetVariablesAssignedInLoop(stmt), CheckOsrEntry(stmt));
VisitForTest(stmt->cond()); VisitForTest(stmt->cond());
Node* condition = environment()->Pop(); Node* condition = environment()->Pop();
while_loop.BreakUnless(condition); while_loop.BreakUnless(condition);
...@@ -629,7 +629,7 @@ void AstGraphBuilder::VisitWhileStatement(WhileStatement* stmt) { ...@@ -629,7 +629,7 @@ void AstGraphBuilder::VisitWhileStatement(WhileStatement* stmt) {
void AstGraphBuilder::VisitForStatement(ForStatement* stmt) { void AstGraphBuilder::VisitForStatement(ForStatement* stmt) {
LoopBuilder for_loop(this); LoopBuilder for_loop(this);
VisitIfNotNull(stmt->init()); VisitIfNotNull(stmt->init());
for_loop.BeginLoop(GetVariablesAssignedInLoop(stmt), IsOsrLoopEntry(stmt)); for_loop.BeginLoop(GetVariablesAssignedInLoop(stmt), CheckOsrEntry(stmt));
if (stmt->cond() != NULL) { if (stmt->cond() != NULL) {
VisitForTest(stmt->cond()); VisitForTest(stmt->cond());
Node* condition = environment()->Pop(); Node* condition = environment()->Pop();
...@@ -714,7 +714,7 @@ void AstGraphBuilder::VisitForInStatement(ForInStatement* stmt) { ...@@ -714,7 +714,7 @@ void AstGraphBuilder::VisitForInStatement(ForInStatement* stmt) {
// TODO(dcarney): this is a big function. Try to clean up some. // TODO(dcarney): this is a big function. Try to clean up some.
void AstGraphBuilder::VisitForInBody(ForInStatement* stmt) { void AstGraphBuilder::VisitForInBody(ForInStatement* stmt) {
LoopBuilder for_loop(this); LoopBuilder for_loop(this);
for_loop.BeginLoop(GetVariablesAssignedInLoop(stmt), IsOsrLoopEntry(stmt)); for_loop.BeginLoop(GetVariablesAssignedInLoop(stmt), CheckOsrEntry(stmt));
// These stack values are renamed in the case of OSR, so reload them // These stack values are renamed in the case of OSR, so reload them
// from the environment. // from the environment.
...@@ -793,7 +793,7 @@ void AstGraphBuilder::VisitForInBody(ForInStatement* stmt) { ...@@ -793,7 +793,7 @@ void AstGraphBuilder::VisitForInBody(ForInStatement* stmt) {
void AstGraphBuilder::VisitForOfStatement(ForOfStatement* stmt) { void AstGraphBuilder::VisitForOfStatement(ForOfStatement* stmt) {
LoopBuilder for_loop(this); LoopBuilder for_loop(this);
VisitForEffect(stmt->assign_iterator()); VisitForEffect(stmt->assign_iterator());
for_loop.BeginLoop(GetVariablesAssignedInLoop(stmt), IsOsrLoopEntry(stmt)); for_loop.BeginLoop(GetVariablesAssignedInLoop(stmt), CheckOsrEntry(stmt));
VisitForEffect(stmt->next_result()); VisitForEffect(stmt->next_result());
VisitForTest(stmt->result_done()); VisitForTest(stmt->result_done());
Node* condition = environment()->Pop(); Node* condition = environment()->Pop();
...@@ -2412,8 +2412,13 @@ Node* AstGraphBuilder::BuildStackCheck() { ...@@ -2412,8 +2412,13 @@ Node* AstGraphBuilder::BuildStackCheck() {
} }
bool AstGraphBuilder::IsOsrLoopEntry(IterationStatement* stmt) { bool AstGraphBuilder::CheckOsrEntry(IterationStatement* stmt) {
return info()->osr_ast_id() == stmt->OsrEntryId(); if (info()->osr_ast_id() == stmt->OsrEntryId()) {
info()->set_osr_expr_stack_height(std::max(
environment()->stack_height(), info()->osr_expr_stack_height()));
return true;
}
return false;
} }
......
...@@ -116,7 +116,9 @@ class AstGraphBuilder : public StructuredGraphBuilder, public AstVisitor { ...@@ -116,7 +116,9 @@ class AstGraphBuilder : public StructuredGraphBuilder, public AstVisitor {
// Builder for stack-check guards. // Builder for stack-check guards.
Node* BuildStackCheck(); Node* BuildStackCheck();
bool IsOsrLoopEntry(IterationStatement* stmt); // Check if the given statement is an OSR entry.
// If so, record the stack height into the compilation and return {true}.
bool CheckOsrEntry(IterationStatement* stmt);
#define DECLARE_VISIT(type) void Visit##type(type* node) OVERRIDE; #define DECLARE_VISIT(type) void Visit##type(type* node) OVERRIDE;
......
...@@ -23,6 +23,7 @@ class Frame : public ZoneObject { ...@@ -23,6 +23,7 @@ class Frame : public ZoneObject {
: register_save_area_size_(0), : register_save_area_size_(0),
spill_slot_count_(0), spill_slot_count_(0),
double_spill_slot_count_(0), double_spill_slot_count_(0),
osr_stack_slot_count_(0),
allocated_registers_(NULL), allocated_registers_(NULL),
allocated_double_registers_(NULL) {} allocated_double_registers_(NULL) {}
...@@ -50,6 +51,14 @@ class Frame : public ZoneObject { ...@@ -50,6 +51,14 @@ class Frame : public ZoneObject {
int GetRegisterSaveAreaSize() { return register_save_area_size_; } int GetRegisterSaveAreaSize() { return register_save_area_size_; }
// OSR stack slots, including locals and expression stack slots.
void SetOsrStackSlotCount(int slots) {
DCHECK(slots >= 0);
osr_stack_slot_count_ = slots;
}
int GetOsrStackSlotCount() { return osr_stack_slot_count_; }
int AllocateSpillSlot(bool is_double) { int AllocateSpillSlot(bool is_double) {
// If 32-bit, skip one if the new slot is a double. // If 32-bit, skip one if the new slot is a double.
if (is_double) { if (is_double) {
...@@ -72,6 +81,7 @@ class Frame : public ZoneObject { ...@@ -72,6 +81,7 @@ class Frame : public ZoneObject {
int register_save_area_size_; int register_save_area_size_;
int spill_slot_count_; int spill_slot_count_;
int double_spill_slot_count_; int double_spill_slot_count_;
int osr_stack_slot_count_;
BitVector* allocated_registers_; BitVector* allocated_registers_;
BitVector* allocated_double_registers_; BitVector* allocated_double_registers_;
......
...@@ -7,7 +7,6 @@ ...@@ -7,7 +7,6 @@
#include "src/compiler/code-generator-impl.h" #include "src/compiler/code-generator-impl.h"
#include "src/compiler/gap-resolver.h" #include "src/compiler/gap-resolver.h"
#include "src/compiler/node-matchers.h" #include "src/compiler/node-matchers.h"
#include "src/compiler/osr.h"
#include "src/ia32/assembler-ia32.h" #include "src/ia32/assembler-ia32.h"
#include "src/ia32/macro-assembler-ia32.h" #include "src/ia32/macro-assembler-ia32.h"
#include "src/scopes.h" #include "src/scopes.h"
...@@ -974,8 +973,7 @@ void CodeGenerator::AssembleDeoptimizerCall(int deoptimization_id) { ...@@ -974,8 +973,7 @@ void CodeGenerator::AssembleDeoptimizerCall(int deoptimization_id) {
void CodeGenerator::AssemblePrologue() { void CodeGenerator::AssemblePrologue() {
CallDescriptor* descriptor = linkage()->GetIncomingDescriptor(); CallDescriptor* descriptor = linkage()->GetIncomingDescriptor();
Frame* frame = this->frame(); int stack_slots = frame()->GetSpillSlotCount();
int stack_slots = frame->GetSpillSlotCount();
if (descriptor->kind() == CallDescriptor::kCallAddress) { if (descriptor->kind() == CallDescriptor::kCallAddress) {
// Assemble a prologue similar the to cdecl calling convention. // Assemble a prologue similar the to cdecl calling convention.
__ push(ebp); __ push(ebp);
...@@ -988,18 +986,18 @@ void CodeGenerator::AssemblePrologue() { ...@@ -988,18 +986,18 @@ void CodeGenerator::AssemblePrologue() {
__ push(Register::from_code(i)); __ push(Register::from_code(i));
register_save_area_size += kPointerSize; register_save_area_size += kPointerSize;
} }
frame->SetRegisterSaveAreaSize(register_save_area_size); frame()->SetRegisterSaveAreaSize(register_save_area_size);
} }
} else if (descriptor->IsJSFunctionCall()) { } else if (descriptor->IsJSFunctionCall()) {
// TODO(turbofan): this prologue is redundant with OSR, but needed for // TODO(turbofan): this prologue is redundant with OSR, but needed for
// code aging. // code aging.
CompilationInfo* info = this->info(); CompilationInfo* info = this->info();
__ Prologue(info->IsCodePreAgingActive()); __ Prologue(info->IsCodePreAgingActive());
frame->SetRegisterSaveAreaSize( frame()->SetRegisterSaveAreaSize(
StandardFrameConstants::kFixedFrameSizeFromFp); StandardFrameConstants::kFixedFrameSizeFromFp);
} else { } else {
__ StubPrologue(); __ StubPrologue();
frame->SetRegisterSaveAreaSize( frame()->SetRegisterSaveAreaSize(
StandardFrameConstants::kFixedFrameSizeFromFp); StandardFrameConstants::kFixedFrameSizeFromFp);
} }
...@@ -1013,10 +1011,8 @@ void CodeGenerator::AssemblePrologue() { ...@@ -1013,10 +1011,8 @@ void CodeGenerator::AssemblePrologue() {
// remaining stack slots. // remaining stack slots.
if (FLAG_code_comments) __ RecordComment("-- OSR entrypoint --"); if (FLAG_code_comments) __ RecordComment("-- OSR entrypoint --");
osr_pc_offset_ = __ pc_offset(); osr_pc_offset_ = __ pc_offset();
int unoptimized_slots = DCHECK(stack_slots >= frame()->GetOsrStackSlotCount());
static_cast<int>(OsrHelper(info()).UnoptimizedFrameSlots()); stack_slots -= frame()->GetOsrStackSlotCount();
DCHECK(stack_slots >= unoptimized_slots);
stack_slots -= unoptimized_slots;
} }
if (stack_slots > 0) { if (stack_slots > 0) {
......
...@@ -6,7 +6,6 @@ ...@@ -6,7 +6,6 @@
#include "src/compiler/code-generator-impl.h" #include "src/compiler/code-generator-impl.h"
#include "src/compiler/gap-resolver.h" #include "src/compiler/gap-resolver.h"
#include "src/compiler/node-matchers.h" #include "src/compiler/node-matchers.h"
#include "src/compiler/osr.h"
#include "src/mips/macro-assembler-mips.h" #include "src/mips/macro-assembler-mips.h"
#include "src/scopes.h" #include "src/scopes.h"
...@@ -916,10 +915,8 @@ void CodeGenerator::AssemblePrologue() { ...@@ -916,10 +915,8 @@ void CodeGenerator::AssemblePrologue() {
// remaining stack slots. // remaining stack slots.
if (FLAG_code_comments) __ RecordComment("-- OSR entrypoint --"); if (FLAG_code_comments) __ RecordComment("-- OSR entrypoint --");
osr_pc_offset_ = __ pc_offset(); osr_pc_offset_ = __ pc_offset();
int unoptimized_slots = DCHECK(stack_slots >= frame()->GetOsrStackSlotCount());
static_cast<int>(OsrHelper(info()).UnoptimizedFrameSlots()); stack_slots -= frame()->GetOsrStackSlotCount();
DCHECK(stack_slots >= unoptimized_slots);
stack_slots -= unoptimized_slots;
} }
if (stack_slots > 0) { if (stack_slots > 0) {
......
...@@ -6,7 +6,6 @@ ...@@ -6,7 +6,6 @@
#include "src/compiler/code-generator-impl.h" #include "src/compiler/code-generator-impl.h"
#include "src/compiler/gap-resolver.h" #include "src/compiler/gap-resolver.h"
#include "src/compiler/node-matchers.h" #include "src/compiler/node-matchers.h"
#include "src/compiler/osr.h"
#include "src/mips/macro-assembler-mips.h" #include "src/mips/macro-assembler-mips.h"
#include "src/scopes.h" #include "src/scopes.h"
...@@ -1086,10 +1085,8 @@ void CodeGenerator::AssemblePrologue() { ...@@ -1086,10 +1085,8 @@ void CodeGenerator::AssemblePrologue() {
// remaining stack slots. // remaining stack slots.
if (FLAG_code_comments) __ RecordComment("-- OSR entrypoint --"); if (FLAG_code_comments) __ RecordComment("-- OSR entrypoint --");
osr_pc_offset_ = __ pc_offset(); osr_pc_offset_ = __ pc_offset();
int unoptimized_slots = DCHECK(stack_slots >= frame()->GetOsrStackSlotCount());
static_cast<int>(OsrHelper(info()).UnoptimizedFrameSlots()); stack_slots -= frame()->GetOsrStackSlotCount();
DCHECK(stack_slots >= unoptimized_slots);
stack_slots -= unoptimized_slots;
} }
if (stack_slots > 0) { if (stack_slots > 0) {
......
...@@ -20,7 +20,8 @@ namespace compiler { ...@@ -20,7 +20,8 @@ namespace compiler {
OsrHelper::OsrHelper(CompilationInfo* info) OsrHelper::OsrHelper(CompilationInfo* info)
: parameter_count_(info->scope()->num_parameters()), : parameter_count_(info->scope()->num_parameters()),
stack_slot_count_(info->scope()->num_stack_slots()) {} stack_slot_count_(info->scope()->num_stack_slots() +
info->osr_expr_stack_height()) {}
bool OsrHelper::Deconstruct(JSGraph* jsgraph, CommonOperatorBuilder* common, bool OsrHelper::Deconstruct(JSGraph* jsgraph, CommonOperatorBuilder* common,
...@@ -75,6 +76,8 @@ void OsrHelper::SetupFrame(Frame* frame) { ...@@ -75,6 +76,8 @@ void OsrHelper::SetupFrame(Frame* frame) {
// The optimized frame will subsume the unoptimized frame. Do so by reserving // The optimized frame will subsume the unoptimized frame. Do so by reserving
// the first spill slots. // the first spill slots.
frame->ReserveSpillSlots(UnoptimizedFrameSlots()); frame->ReserveSpillSlots(UnoptimizedFrameSlots());
// The frame needs to be adjusted by the number of unoptimized frame slots.
frame->SetOsrStackSlotCount(static_cast<int>(UnoptimizedFrameSlots()));
} }
......
...@@ -7,7 +7,6 @@ ...@@ -7,7 +7,6 @@
#include "src/compiler/code-generator-impl.h" #include "src/compiler/code-generator-impl.h"
#include "src/compiler/gap-resolver.h" #include "src/compiler/gap-resolver.h"
#include "src/compiler/node-matchers.h" #include "src/compiler/node-matchers.h"
#include "src/compiler/osr.h"
#include "src/scopes.h" #include "src/scopes.h"
#include "src/x64/assembler-x64.h" #include "src/x64/assembler-x64.h"
#include "src/x64/macro-assembler-x64.h" #include "src/x64/macro-assembler-x64.h"
...@@ -1179,10 +1178,8 @@ void CodeGenerator::AssemblePrologue() { ...@@ -1179,10 +1178,8 @@ void CodeGenerator::AssemblePrologue() {
// remaining stack slots. // remaining stack slots.
if (FLAG_code_comments) __ RecordComment("-- OSR entrypoint --"); if (FLAG_code_comments) __ RecordComment("-- OSR entrypoint --");
osr_pc_offset_ = __ pc_offset(); osr_pc_offset_ = __ pc_offset();
int unoptimized_slots = DCHECK(stack_slots >= frame()->GetOsrStackSlotCount());
static_cast<int>(OsrHelper(info()).UnoptimizedFrameSlots()); stack_slots -= frame()->GetOsrStackSlotCount();
DCHECK(stack_slots >= unoptimized_slots);
stack_slots -= unoptimized_slots;
} }
if (stack_slots > 0) { if (stack_slots > 0) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment