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 {
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
void PrintAstForTesting();
#endif
......@@ -531,6 +537,8 @@ class CompilationInfo {
// should be abandoned due to dependency change.
bool aborted_due_to_dependency_change_;
int osr_expr_stack_height_;
DISALLOW_COPY_AND_ASSIGN(CompilationInfo);
};
......
......@@ -8,7 +8,6 @@
#include "src/compiler/code-generator-impl.h"
#include "src/compiler/gap-resolver.h"
#include "src/compiler/node-matchers.h"
#include "src/compiler/osr.h"
#include "src/scopes.h"
namespace v8 {
......@@ -807,10 +806,8 @@ void CodeGenerator::AssemblePrologue() {
// remaining stack slots.
if (FLAG_code_comments) __ RecordComment("-- OSR entrypoint --");
osr_pc_offset_ = __ pc_offset();
int unoptimized_slots =
static_cast<int>(OsrHelper(info()).UnoptimizedFrameSlots());
DCHECK(stack_slots >= unoptimized_slots);
stack_slots -= unoptimized_slots;
DCHECK(stack_slots >= frame()->GetOsrStackSlotCount());
stack_slots -= frame()->GetOsrStackSlotCount();
}
if (stack_slots > 0) {
......
......@@ -8,7 +8,6 @@
#include "src/compiler/code-generator-impl.h"
#include "src/compiler/gap-resolver.h"
#include "src/compiler/node-matchers.h"
#include "src/compiler/osr.h"
#include "src/scopes.h"
namespace v8 {
......@@ -900,10 +899,8 @@ void CodeGenerator::AssemblePrologue() {
// remaining stack slots.
if (FLAG_code_comments) __ RecordComment("-- OSR entrypoint --");
osr_pc_offset_ = __ pc_offset();
int unoptimized_slots =
static_cast<int>(OsrHelper(info()).UnoptimizedFrameSlots());
DCHECK(stack_slots >= unoptimized_slots);
stack_slots -= unoptimized_slots;
DCHECK(stack_slots >= frame()->GetOsrStackSlotCount());
stack_slots -= frame()->GetOsrStackSlotCount();
}
if (stack_slots > 0) {
......
......@@ -604,7 +604,7 @@ void AstGraphBuilder::VisitSwitchStatement(SwitchStatement* stmt) {
void AstGraphBuilder::VisitDoWhileStatement(DoWhileStatement* stmt) {
LoopBuilder while_loop(this);
while_loop.BeginLoop(GetVariablesAssignedInLoop(stmt), IsOsrLoopEntry(stmt));
while_loop.BeginLoop(GetVariablesAssignedInLoop(stmt), CheckOsrEntry(stmt));
VisitIterationBody(stmt, &while_loop, 0);
while_loop.EndBody();
VisitForTest(stmt->cond());
......@@ -616,7 +616,7 @@ void AstGraphBuilder::VisitDoWhileStatement(DoWhileStatement* stmt) {
void AstGraphBuilder::VisitWhileStatement(WhileStatement* stmt) {
LoopBuilder while_loop(this);
while_loop.BeginLoop(GetVariablesAssignedInLoop(stmt), IsOsrLoopEntry(stmt));
while_loop.BeginLoop(GetVariablesAssignedInLoop(stmt), CheckOsrEntry(stmt));
VisitForTest(stmt->cond());
Node* condition = environment()->Pop();
while_loop.BreakUnless(condition);
......@@ -629,7 +629,7 @@ void AstGraphBuilder::VisitWhileStatement(WhileStatement* stmt) {
void AstGraphBuilder::VisitForStatement(ForStatement* stmt) {
LoopBuilder for_loop(this);
VisitIfNotNull(stmt->init());
for_loop.BeginLoop(GetVariablesAssignedInLoop(stmt), IsOsrLoopEntry(stmt));
for_loop.BeginLoop(GetVariablesAssignedInLoop(stmt), CheckOsrEntry(stmt));
if (stmt->cond() != NULL) {
VisitForTest(stmt->cond());
Node* condition = environment()->Pop();
......@@ -714,7 +714,7 @@ void AstGraphBuilder::VisitForInStatement(ForInStatement* stmt) {
// TODO(dcarney): this is a big function. Try to clean up some.
void AstGraphBuilder::VisitForInBody(ForInStatement* stmt) {
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
// from the environment.
......@@ -793,7 +793,7 @@ void AstGraphBuilder::VisitForInBody(ForInStatement* stmt) {
void AstGraphBuilder::VisitForOfStatement(ForOfStatement* stmt) {
LoopBuilder for_loop(this);
VisitForEffect(stmt->assign_iterator());
for_loop.BeginLoop(GetVariablesAssignedInLoop(stmt), IsOsrLoopEntry(stmt));
for_loop.BeginLoop(GetVariablesAssignedInLoop(stmt), CheckOsrEntry(stmt));
VisitForEffect(stmt->next_result());
VisitForTest(stmt->result_done());
Node* condition = environment()->Pop();
......@@ -2412,8 +2412,13 @@ Node* AstGraphBuilder::BuildStackCheck() {
}
bool AstGraphBuilder::IsOsrLoopEntry(IterationStatement* stmt) {
return info()->osr_ast_id() == stmt->OsrEntryId();
bool AstGraphBuilder::CheckOsrEntry(IterationStatement* stmt) {
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 {
// Builder for stack-check guards.
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;
......
......@@ -23,6 +23,7 @@ class Frame : public ZoneObject {
: register_save_area_size_(0),
spill_slot_count_(0),
double_spill_slot_count_(0),
osr_stack_slot_count_(0),
allocated_registers_(NULL),
allocated_double_registers_(NULL) {}
......@@ -50,6 +51,14 @@ class Frame : public ZoneObject {
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) {
// If 32-bit, skip one if the new slot is a double.
if (is_double) {
......@@ -72,6 +81,7 @@ class Frame : public ZoneObject {
int register_save_area_size_;
int spill_slot_count_;
int double_spill_slot_count_;
int osr_stack_slot_count_;
BitVector* allocated_registers_;
BitVector* allocated_double_registers_;
......
......@@ -7,7 +7,6 @@
#include "src/compiler/code-generator-impl.h"
#include "src/compiler/gap-resolver.h"
#include "src/compiler/node-matchers.h"
#include "src/compiler/osr.h"
#include "src/ia32/assembler-ia32.h"
#include "src/ia32/macro-assembler-ia32.h"
#include "src/scopes.h"
......@@ -974,8 +973,7 @@ void CodeGenerator::AssembleDeoptimizerCall(int deoptimization_id) {
void CodeGenerator::AssemblePrologue() {
CallDescriptor* descriptor = linkage()->GetIncomingDescriptor();
Frame* frame = this->frame();
int stack_slots = frame->GetSpillSlotCount();
int stack_slots = frame()->GetSpillSlotCount();
if (descriptor->kind() == CallDescriptor::kCallAddress) {
// Assemble a prologue similar the to cdecl calling convention.
__ push(ebp);
......@@ -988,18 +986,18 @@ void CodeGenerator::AssemblePrologue() {
__ push(Register::from_code(i));
register_save_area_size += kPointerSize;
}
frame->SetRegisterSaveAreaSize(register_save_area_size);
frame()->SetRegisterSaveAreaSize(register_save_area_size);
}
} else if (descriptor->IsJSFunctionCall()) {
// TODO(turbofan): this prologue is redundant with OSR, but needed for
// code aging.
CompilationInfo* info = this->info();
__ Prologue(info->IsCodePreAgingActive());
frame->SetRegisterSaveAreaSize(
frame()->SetRegisterSaveAreaSize(
StandardFrameConstants::kFixedFrameSizeFromFp);
} else {
__ StubPrologue();
frame->SetRegisterSaveAreaSize(
frame()->SetRegisterSaveAreaSize(
StandardFrameConstants::kFixedFrameSizeFromFp);
}
......@@ -1013,10 +1011,8 @@ void CodeGenerator::AssemblePrologue() {
// remaining stack slots.
if (FLAG_code_comments) __ RecordComment("-- OSR entrypoint --");
osr_pc_offset_ = __ pc_offset();
int unoptimized_slots =
static_cast<int>(OsrHelper(info()).UnoptimizedFrameSlots());
DCHECK(stack_slots >= unoptimized_slots);
stack_slots -= unoptimized_slots;
DCHECK(stack_slots >= frame()->GetOsrStackSlotCount());
stack_slots -= frame()->GetOsrStackSlotCount();
}
if (stack_slots > 0) {
......
......@@ -6,7 +6,6 @@
#include "src/compiler/code-generator-impl.h"
#include "src/compiler/gap-resolver.h"
#include "src/compiler/node-matchers.h"
#include "src/compiler/osr.h"
#include "src/mips/macro-assembler-mips.h"
#include "src/scopes.h"
......@@ -916,10 +915,8 @@ void CodeGenerator::AssemblePrologue() {
// remaining stack slots.
if (FLAG_code_comments) __ RecordComment("-- OSR entrypoint --");
osr_pc_offset_ = __ pc_offset();
int unoptimized_slots =
static_cast<int>(OsrHelper(info()).UnoptimizedFrameSlots());
DCHECK(stack_slots >= unoptimized_slots);
stack_slots -= unoptimized_slots;
DCHECK(stack_slots >= frame()->GetOsrStackSlotCount());
stack_slots -= frame()->GetOsrStackSlotCount();
}
if (stack_slots > 0) {
......
......@@ -6,7 +6,6 @@
#include "src/compiler/code-generator-impl.h"
#include "src/compiler/gap-resolver.h"
#include "src/compiler/node-matchers.h"
#include "src/compiler/osr.h"
#include "src/mips/macro-assembler-mips.h"
#include "src/scopes.h"
......@@ -1086,10 +1085,8 @@ void CodeGenerator::AssemblePrologue() {
// remaining stack slots.
if (FLAG_code_comments) __ RecordComment("-- OSR entrypoint --");
osr_pc_offset_ = __ pc_offset();
int unoptimized_slots =
static_cast<int>(OsrHelper(info()).UnoptimizedFrameSlots());
DCHECK(stack_slots >= unoptimized_slots);
stack_slots -= unoptimized_slots;
DCHECK(stack_slots >= frame()->GetOsrStackSlotCount());
stack_slots -= frame()->GetOsrStackSlotCount();
}
if (stack_slots > 0) {
......
......@@ -20,7 +20,8 @@ namespace compiler {
OsrHelper::OsrHelper(CompilationInfo* info)
: 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,
......@@ -75,6 +76,8 @@ void OsrHelper::SetupFrame(Frame* frame) {
// The optimized frame will subsume the unoptimized frame. Do so by reserving
// the first spill slots.
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 @@
#include "src/compiler/code-generator-impl.h"
#include "src/compiler/gap-resolver.h"
#include "src/compiler/node-matchers.h"
#include "src/compiler/osr.h"
#include "src/scopes.h"
#include "src/x64/assembler-x64.h"
#include "src/x64/macro-assembler-x64.h"
......@@ -1179,10 +1178,8 @@ void CodeGenerator::AssemblePrologue() {
// remaining stack slots.
if (FLAG_code_comments) __ RecordComment("-- OSR entrypoint --");
osr_pc_offset_ = __ pc_offset();
int unoptimized_slots =
static_cast<int>(OsrHelper(info()).UnoptimizedFrameSlots());
DCHECK(stack_slots >= unoptimized_slots);
stack_slots -= unoptimized_slots;
DCHECK(stack_slots >= frame()->GetOsrStackSlotCount());
stack_slots -= frame()->GetOsrStackSlotCount();
}
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