Unify SoftDeoptimize and Deoptimize hydrogen instructions

BUG=chromium:258519
R=jkummerow@chromium.org

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

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@15827 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
danno@chromium.org 2013-07-23 13:35:10 +00:00
parent fa037d1602
commit 8cbbdd066c
25 changed files with 237 additions and 290 deletions

View File

@ -701,11 +701,6 @@ LInstruction* LChunkBuilder::DoEnvironmentMarker(HEnvironmentMarker* instr) {
}
LInstruction* LChunkBuilder::DoSoftDeoptimize(HSoftDeoptimize* instr) {
return AssignEnvironment(new(zone()) LDeoptimize);
}
LInstruction* LChunkBuilder::DoDeoptimize(HDeoptimize* instr) {
return AssignEnvironment(new(zone()) LDeoptimize);
}

View File

@ -427,6 +427,7 @@ class LDummyUse: public LTemplateInstruction<1, 1, 0> {
class LDeoptimize: public LTemplateInstruction<0, 0, 0> {
public:
DECLARE_CONCRETE_INSTRUCTION(Deoptimize, "deoptimize")
DECLARE_HYDROGEN_ACCESSOR(Deoptimize)
};

View File

@ -810,12 +810,6 @@ void LCodeGen::DeoptimizeIf(Condition cc,
}
void LCodeGen::SoftDeoptimize(LEnvironment* environment) {
ASSERT(!info()->IsStub());
DeoptimizeIf(al, environment, Deoptimizer::SOFT);
}
void LCodeGen::RegisterDependentCodeForEmbeddedMaps(Handle<Code> code) {
ZoneList<Handle<Map> > maps(1, zone());
int mode_mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT);
@ -5646,11 +5640,15 @@ void LCodeGen::DoLazyBailout(LLazyBailout* instr) {
void LCodeGen::DoDeoptimize(LDeoptimize* instr) {
if (instr->hydrogen_value()->IsSoftDeoptimize()) {
SoftDeoptimize(instr->environment());
} else {
DeoptimizeIf(al, instr->environment());
Deoptimizer::BailoutType type = instr->hydrogen()->type();
// TODO(danno): Stubs expect all deopts to be lazy for historical reasons (the
// needed return address), even though the implementation of LAZY and EAGER is
// now identical. When LAZY is eventually completely folded into EAGER, remove
// the special case below.
if (info()->IsStub() && type == Deoptimizer::EAGER) {
type = Deoptimizer::LAZY;
}
DeoptimizeIf(al, instr->environment(), type);
}

View File

@ -284,7 +284,6 @@ class LCodeGen BASE_EMBEDDED {
LEnvironment* environment,
Deoptimizer::BailoutType bailout_type);
void DeoptimizeIf(Condition cc, LEnvironment* environment);
void SoftDeoptimize(LEnvironment* environment);
void AddToTranslation(Translation* translation,
LOperand* op,

View File

@ -178,7 +178,7 @@ bool CodeStubGraphBuilderBase::BuildGraph() {
AddInstruction(context_);
start_environment->BindContext(context_);
AddSimulate(BailoutId::StubEntry());
Add<HSimulate>(BailoutId::StubEntry());
NoObservableSideEffectsScope no_effects(this);
@ -397,9 +397,10 @@ HValue* CodeStubGraphBuilder<FastCloneShallowArrayStub>::BuildCodeStub() {
length));
}
HValue* result = environment()->Pop();
checker.ElseDeopt();
return result;
checker.End();
return environment()->Pop();
}
@ -447,8 +448,11 @@ HValue* CodeStubGraphBuilder<FastCloneShallowObjectStub>::BuildCodeStub() {
AddStore(object, access, AddLoad(boilerplate, access));
}
environment()->Push(object);
checker.ElseDeopt();
return object;
checker.End();
return environment()->Pop();
}
@ -929,8 +933,7 @@ HValue* CodeStubGraphBuilder<ElementsTransitionAndStoreStub>::BuildCodeStub() {
if (FLAG_trace_elements_transitions) {
// Tracing elements transitions is the job of the runtime.
current_block()->FinishExitWithDeoptimization(HDeoptimize::kUseAll);
set_current_block(NULL);
Add<HDeoptimize>(Deoptimizer::EAGER);
} else {
info()->MarkAsSavesCallerDoubles();

View File

@ -107,7 +107,7 @@ void HPropagateDeoptimizingMarkPhase::NullifyUnreachableInstructions() {
instr->DeleteAndReplaceWith(last_dummy);
continue;
}
if (instr->IsSoftDeoptimize()) {
if (instr->IsDeoptimize()) {
ASSERT(block->IsDeoptimizing());
nullify = true;
}

View File

@ -172,15 +172,6 @@ void HEnvironmentLivenessAnalysisPhase::UpdateLivenessAtInstruction(
last_simulate_ = NULL;
break;
}
case HValue::kDeoptimize: {
// Keep all environment slots alive.
HDeoptimize* deopt = HDeoptimize::cast(instr);
for (int i = deopt->first_local_index();
i < deopt->first_expression_index(); ++i) {
live->Add(i);
}
break;
}
case HValue::kSimulate:
last_simulate_ = HSimulate::cast(instr);
went_live_since_last_simulate_.Clear();

View File

@ -401,7 +401,7 @@ void HGlobalValueNumberingPhase::ComputeBlockSideEffects() {
for (HInstructionIterator it(block); !it.Done(); it.Advance()) {
HInstruction* instr = it.Current();
side_effects.Add(instr->ChangesFlags());
if (instr->IsSoftDeoptimize()) {
if (instr->IsDeoptimize()) {
block_side_effects_[id].RemoveAll();
side_effects.RemoveAll();
break;

View File

@ -2136,16 +2136,6 @@ void HSimulate::PrintDataTo(StringStream* stream) {
}
void HDeoptimize::PrintDataTo(StringStream* stream) {
if (OperandCount() == 0) return;
OperandAt(0)->PrintNameTo(stream);
for (int i = 1; i < OperandCount(); ++i) {
stream->Add(" ");
OperandAt(i)->PrintNameTo(stream);
}
}
void HEnterInlined::RegisterReturnTarget(HBasicBlock* return_target,
Zone* zone) {
ASSERT(return_target->IsInlineReturnTarget());

View File

@ -33,6 +33,7 @@
#include "allocation.h"
#include "code-stubs.h"
#include "data-flow.h"
#include "deoptimizer.h"
#include "small-pointer-list.h"
#include "string-stream.h"
#include "v8conversions.h"
@ -167,7 +168,6 @@ class LChunkBuilder;
V(Shl) \
V(Shr) \
V(Simulate) \
V(SoftDeoptimize) \
V(StackCheck) \
V(StoreContextSlot) \
V(StoreGlobalCell) \
@ -1499,16 +1499,20 @@ class HNumericConstraint : public HTemplateInstruction<2> {
};
// We insert soft-deoptimize when we hit code with unknown typefeedback,
// so that we get a chance of re-optimizing with useful typefeedback.
// HSoftDeoptimize does not end a basic block as opposed to HDeoptimize.
class HSoftDeoptimize: public HTemplateInstruction<0> {
class HDeoptimize: public HTemplateInstruction<0> {
public:
explicit HDeoptimize(Deoptimizer::BailoutType type) : type_(type) {}
virtual Representation RequiredInputRepresentation(int index) {
return Representation::None();
}
DECLARE_CONCRETE_INSTRUCTION(SoftDeoptimize)
Deoptimizer::BailoutType type() { return type_; }
DECLARE_CONCRETE_INSTRUCTION(Deoptimize)
private:
Deoptimizer::BailoutType type_;
};
@ -1523,59 +1527,6 @@ class HDebugBreak: public HTemplateInstruction<0> {
};
class HDeoptimize: public HControlInstruction {
public:
HDeoptimize(int environment_length,
int first_local_index,
int first_expression_index,
Zone* zone)
: values_(environment_length, zone),
first_local_index_(first_local_index),
first_expression_index_(first_expression_index) { }
virtual Representation RequiredInputRepresentation(int index) {
return Representation::None();
}
virtual int OperandCount() { return values_.length(); }
virtual HValue* OperandAt(int index) const { return values_[index]; }
virtual void PrintDataTo(StringStream* stream);
virtual int SuccessorCount() { return 0; }
virtual HBasicBlock* SuccessorAt(int i) {
UNREACHABLE();
return NULL;
}
virtual void SetSuccessorAt(int i, HBasicBlock* block) {
UNREACHABLE();
}
void AddEnvironmentValue(HValue* value, Zone* zone) {
values_.Add(NULL, zone);
SetOperandAt(values_.length() - 1, value);
}
int first_local_index() { return first_local_index_; }
int first_expression_index() { return first_expression_index_; }
DECLARE_CONCRETE_INSTRUCTION(Deoptimize)
enum UseEnvironment {
kNoUses,
kUseAll
};
protected:
virtual void InternalSetOperandAt(int index, HValue* value) {
values_[index] = value;
}
private:
ZoneList<HValue*> values_;
int first_local_index_;
int first_expression_index_;
};
class HGoto: public HTemplateControlInstruction<1, 0> {
public:
explicit HGoto(HBasicBlock* target) {

View File

@ -94,7 +94,7 @@ HBasicBlock* HOsrBuilder::BuildPossibleOsrLoopEntry(
}
}
builder_->AddSimulate(osr_entry_id);
builder_->Add<HSimulate>(osr_entry_id);
builder_->Add<HOsrEntry>(osr_entry_id);
HContext* context = builder_->Add<HContext>();
environment->BindContext(context);

View File

@ -146,26 +146,6 @@ void HBasicBlock::AddInstruction(HInstruction* instr) {
}
HDeoptimize* HBasicBlock::CreateDeoptimize(
HDeoptimize::UseEnvironment has_uses) {
ASSERT(HasEnvironment());
if (has_uses == HDeoptimize::kNoUses)
return new(zone()) HDeoptimize(0, 0, 0, zone());
HEnvironment* environment = last_environment();
int first_local_index = environment->first_local_index();
int first_expression_index = environment->first_expression_index();
HDeoptimize* instr = new(zone()) HDeoptimize(
environment->length(), first_local_index, first_expression_index, zone());
for (int i = 0; i < environment->length(); i++) {
HValue* val = environment->values()->at(i);
instr->AddEnvironmentValue(val, zone());
}
return instr;
}
HSimulate* HBasicBlock::CreateSimulate(BailoutId ast_id,
RemovableSimulate removable) {
ASSERT(HasEnvironment());
@ -700,13 +680,16 @@ HGraphBuilder::IfBuilder::IfBuilder(HGraphBuilder* builder, int position)
: builder_(builder),
position_(position),
finished_(false),
deopt_then_(false),
deopt_else_(false),
did_then_(false),
did_else_(false),
did_and_(false),
did_or_(false),
captured_(false),
needs_compare_(true),
split_edge_merge_block_(NULL) {
split_edge_merge_block_(NULL),
merge_block_(NULL) {
HEnvironment* env = builder->environment();
first_true_block_ = builder->CreateBasicBlock(env->Copy());
last_true_block_ = NULL;
@ -720,6 +703,8 @@ HGraphBuilder::IfBuilder::IfBuilder(
: builder_(builder),
position_(RelocInfo::kNoPosition),
finished_(false),
deopt_then_(false),
deopt_else_(false),
did_then_(false),
did_else_(false),
did_and_(false),
@ -836,14 +821,13 @@ void HGraphBuilder::IfBuilder::Else() {
void HGraphBuilder::IfBuilder::Deopt() {
HBasicBlock* block = builder_->current_block();
block->FinishExitWithDeoptimization(HDeoptimize::kUseAll);
builder_->set_current_block(NULL);
ASSERT(did_then_);
if (did_else_) {
first_false_block_ = NULL;
deopt_else_ = true;
} else {
first_true_block_ = NULL;
deopt_then_ = true;
}
builder_->Add<HDeoptimize>(Deoptimizer::EAGER);
}
@ -868,20 +852,30 @@ void HGraphBuilder::IfBuilder::End() {
last_true_block_ = builder_->current_block();
}
if (first_true_block_ == NULL) {
// Deopt on true. Nothing to do, just continue the false block.
// Return on true. Nothing to do, just continue the false block.
} else if (first_false_block_ == NULL) {
// Deopt on false. Nothing to do except switching to the true block.
builder_->set_current_block(last_true_block_);
} else {
HEnvironment* merge_env = last_true_block_->last_environment()->Copy();
merge_block_ = builder_->CreateBasicBlock(merge_env);
merge_block_ = builder_->graph()->CreateBasicBlock();
ASSERT(!finished_);
if (!did_else_) Else();
ASSERT(!last_true_block_->IsFinished());
HBasicBlock* last_false_block = builder_->current_block();
ASSERT(!last_false_block->IsFinished());
last_true_block_->GotoNoSimulate(merge_block_);
last_false_block->GotoNoSimulate(merge_block_);
if (deopt_then_) {
last_false_block->GotoNoSimulate(merge_block_);
builder_->PadEnvironmentForContinuation(last_true_block_,
merge_block_);
last_true_block_->GotoNoSimulate(merge_block_);
} else {
last_true_block_->GotoNoSimulate(merge_block_);
if (deopt_else_) {
builder_->PadEnvironmentForContinuation(last_false_block,
merge_block_);
}
last_false_block->GotoNoSimulate(merge_block_);
}
builder_->set_current_block(merge_block_);
}
}
@ -991,36 +985,6 @@ HInstruction* HGraphBuilder::AddInstruction(HInstruction* instr) {
}
void HGraphBuilder::AddSimulate(BailoutId id,
RemovableSimulate removable) {
ASSERT(current_block() != NULL);
ASSERT(no_side_effects_scope_count_ == 0);
current_block()->AddSimulate(id, removable);
}
HReturn* HGraphBuilder::AddReturn(HValue* value) {
HValue* context = environment()->LookupContext();
int num_parameters = graph()->info()->num_parameters();
HValue* params = Add<HConstant>(num_parameters);
HReturn* return_instruction = new(graph()->zone())
HReturn(value, context, params);
current_block()->FinishExit(return_instruction);
return return_instruction;
}
void HGraphBuilder::AddSoftDeoptimize(SoftDeoptimizeMode mode) {
isolate()->counters()->soft_deopts_requested()->Increment();
if (FLAG_always_opt && mode == CAN_OMIT_SOFT_DEOPT) return;
if (current_block()->IsDeoptimizing()) return;
Add<HSoftDeoptimize>();
isolate()->counters()->soft_deopts_inserted()->Increment();
current_block()->MarkAsDeoptimizing();
graph()->set_has_soft_deoptimize(true);
}
HBasicBlock* HGraphBuilder::CreateBasicBlock(HEnvironment* env) {
HBasicBlock* b = graph()->CreateBasicBlock();
b->SetInitialEnvironment(env);
@ -1043,8 +1007,41 @@ HValue* HGraphBuilder::BuildCheckHeapObject(HValue* obj) {
}
void HGraphBuilder::FinishExitWithHardDeoptimization(
HBasicBlock* continuation) {
PadEnvironmentForContinuation(current_block(), continuation);
Add<HDeoptimize>(Deoptimizer::EAGER);
if (no_side_effects_scope_count_ > 0) {
current_block()->GotoNoSimulate(continuation);
} else {
current_block()->Goto(continuation);
}
}
void HGraphBuilder::PadEnvironmentForContinuation(
HBasicBlock* from,
HBasicBlock* continuation) {
if (continuation->last_environment() != NULL) {
// When merging from a deopt block to a continuation, resolve differences in
// environment by pushing undefined and popping extra values so that the
// environments match during the join.
int continuation_env_length = continuation->last_environment()->length();
while (continuation_env_length != from->last_environment()->length()) {
if (continuation_env_length > from->last_environment()->length()) {
from->last_environment()->Push(graph()->GetConstantUndefined());
} else {
from->last_environment()->Pop();
}
}
} else {
ASSERT(continuation->predecessors()->length() == 0);
}
}
HValue* HGraphBuilder::BuildCheckMap(HValue* obj,
Handle<Map> map) {
Handle<Map> map) {
HCheckMaps* check = HCheckMaps::New(obj, map, zone(), top_info());
AddInstruction(check);
return check;
@ -1720,7 +1717,7 @@ HInstruction* HGraphBuilder::BuildUnaryMathOp(
input, graph()->GetConstantMinus1());
Representation rep = Representation::FromType(type);
if (type->Is(Type::None())) {
AddSoftDeoptimize();
Add<HDeoptimize>(Deoptimizer::SOFT);
}
if (instr->IsBinaryOperation()) {
HBinaryOperation* binop = HBinaryOperation::cast(instr);
@ -1731,7 +1728,7 @@ HInstruction* HGraphBuilder::BuildUnaryMathOp(
}
case Token::BIT_NOT:
if (type->Is(Type::None())) {
AddSoftDeoptimize();
Add<HDeoptimize>(Deoptimizer::SOFT);
}
return new(zone()) HBitNot(input);
}
@ -2639,7 +2636,7 @@ void EffectContext::ReturnInstruction(HInstruction* instr, BailoutId ast_id) {
ASSERT(!instr->IsControlInstruction());
owner()->AddInstruction(instr);
if (instr->HasObservableSideEffects()) {
owner()->AddSimulate(ast_id, REMOVABLE_SIMULATE);
owner()->Add<HSimulate>(ast_id, REMOVABLE_SIMULATE);
}
}
@ -2681,7 +2678,7 @@ void ValueContext::ReturnInstruction(HInstruction* instr, BailoutId ast_id) {
owner()->AddInstruction(instr);
owner()->Push(instr);
if (instr->HasObservableSideEffects()) {
owner()->AddSimulate(ast_id, REMOVABLE_SIMULATE);
owner()->Add<HSimulate>(ast_id, REMOVABLE_SIMULATE);
}
}
@ -2737,7 +2734,7 @@ void TestContext::ReturnInstruction(HInstruction* instr, BailoutId ast_id) {
// this one isn't actually needed (and wouldn't work if it were targeted).
if (instr->HasObservableSideEffects()) {
builder->Push(instr);
builder->AddSimulate(ast_id, REMOVABLE_SIMULATE);
builder->Add<HSimulate>(ast_id, REMOVABLE_SIMULATE);
builder->Pop();
}
BuildBranch(instr);
@ -2925,7 +2922,7 @@ bool HOptimizedGraphBuilder::BuildGraph() {
VisitVariableDeclaration(scope->function());
}
VisitDeclarations(scope->declarations());
AddSimulate(BailoutId::Declarations());
Add<HSimulate>(BailoutId::Declarations());
HValue* context = environment()->LookupContext();
Add<HStackCheck>(context, HStackCheck::kFunctionEntry);
@ -2934,7 +2931,7 @@ bool HOptimizedGraphBuilder::BuildGraph() {
if (HasStackOverflow()) return false;
if (current_block() != NULL) {
AddReturn(graph()->GetConstantUndefined());
Add<HReturn>(graph()->GetConstantUndefined());
set_current_block(NULL);
}
@ -3224,10 +3221,10 @@ void HOptimizedGraphBuilder::VisitIfStatement(IfStatement* stmt) {
ASSERT(current_block() != NULL);
ASSERT(current_block()->HasPredecessor());
if (stmt->condition()->ToBooleanIsTrue()) {
AddSimulate(stmt->ThenId());
Add<HSimulate>(stmt->ThenId());
Visit(stmt->then_statement());
} else if (stmt->condition()->ToBooleanIsFalse()) {
AddSimulate(stmt->ElseId());
Add<HSimulate>(stmt->ElseId());
Visit(stmt->else_statement());
} else {
HBasicBlock* cond_true = graph()->CreateBasicBlock();
@ -3334,7 +3331,7 @@ void HOptimizedGraphBuilder::VisitReturnStatement(ReturnStatement* stmt) {
// Not an inlined return, so an actual one.
CHECK_ALIVE(VisitForValue(stmt->expression()));
HValue* result = environment()->Pop();
AddReturn(result);
Add<HReturn>(result);
} else if (state->inlining_kind() == CONSTRUCT_CALL_RETURN) {
// Return from an inlined construct call. In a test context the return value
// will always evaluate to true, in a value context the return value needs
@ -3426,7 +3423,7 @@ void HOptimizedGraphBuilder::VisitSwitchStatement(SwitchStatement* stmt) {
HValue* context = environment()->LookupContext();
CHECK_ALIVE(VisitForValue(stmt->tag()));
AddSimulate(stmt->EntryId());
Add<HSimulate>(stmt->EntryId());
HValue* tag_value = Pop();
HBasicBlock* first_test_block = current_block();
@ -3466,7 +3463,7 @@ void HOptimizedGraphBuilder::VisitSwitchStatement(SwitchStatement* stmt) {
if (stmt->switch_type() == SwitchStatement::SMI_SWITCH) {
if (!clause->compare_type()->Is(Type::Smi())) {
AddSoftDeoptimize();
Add<HDeoptimize>(Deoptimizer::SOFT);
}
HCompareNumericAndBranch* compare_ =
@ -3516,7 +3513,7 @@ void HOptimizedGraphBuilder::VisitSwitchStatement(SwitchStatement* stmt) {
normal_block = last_block;
last_block = NULL; // Cleared to indicate we've handled it.
}
} else if (!curr_test_block->end()->IsDeoptimize()) {
} else {
normal_block = curr_test_block->end()->FirstSuccessor();
curr_test_block = curr_test_block->end()->SecondSuccessor();
}
@ -3570,7 +3567,7 @@ void HOptimizedGraphBuilder::VisitLoopBody(IterationStatement* stmt,
HBasicBlock* loop_entry,
BreakAndContinueInfo* break_info) {
BreakAndContinueScope push(break_info, this);
AddSimulate(stmt->StackCheckId());
Add<HSimulate>(stmt->StackCheckId());
HValue* context = environment()->LookupContext();
HStackCheck* stack_check = Add<HStackCheck>(
context, HStackCheck::kBackwardsBranch);
@ -3731,7 +3728,7 @@ void HOptimizedGraphBuilder::VisitForInStatement(ForInStatement* stmt) {
HInstruction* map = Add<HForInPrepareMap>(
environment()->LookupContext(), enumerable);
AddSimulate(stmt->PrepareId());
Add<HSimulate>(stmt->PrepareId());
HInstruction* array = Add<HForInCacheArray>(
enumerable, map, DescriptorArray::kEnumCacheBridgeCacheIndex);
@ -4328,7 +4325,7 @@ void HOptimizedGraphBuilder::VisitObjectLiteral(ObjectLiteral* expr) {
}
AddInstruction(store);
if (store->HasObservableSideEffects()) {
AddSimulate(key->id(), REMOVABLE_SIMULATE);
Add<HSimulate>(key->id(), REMOVABLE_SIMULATE);
}
} else {
CHECK_ALIVE(VisitForEffect(value));
@ -4493,7 +4490,7 @@ void HOptimizedGraphBuilder::VisitArrayLiteral(ArrayLiteral* expr) {
break;
}
AddSimulate(expr->GetIdForElement(i));
Add<HSimulate>(expr->GetIdForElement(i));
}
Drop(1); // array literal index
@ -4824,7 +4821,7 @@ bool HOptimizedGraphBuilder::TryStorePolymorphicAsMonomorphic(
if (!ast_context()->IsEffect()) Push(result_value);
store->set_position(position);
AddInstruction(store);
AddSimulate(assignment_id);
Add<HSimulate>(assignment_id);
if (!ast_context()->IsEffect()) Drop(1);
ast_context()->ReturnValue(result_value);
return true;
@ -4883,7 +4880,7 @@ void HOptimizedGraphBuilder::HandlePolymorphicStoreNamedField(
// know about and do not want to handle ones we've never seen. Otherwise
// use a generic IC.
if (count == types->length() && FLAG_deoptimize_uncommon_cases) {
current_block()->FinishExitWithDeoptimization(HDeoptimize::kNoUses);
FinishExitWithHardDeoptimization(join);
} else {
HInstruction* instr = BuildStoreNamedGeneric(object, name, store_value);
instr->set_position(position);
@ -4900,10 +4897,10 @@ void HOptimizedGraphBuilder::HandlePolymorphicStoreNamedField(
// unoptimized code).
if (instr->HasObservableSideEffects()) {
if (ast_context()->IsEffect()) {
AddSimulate(assignment_id, REMOVABLE_SIMULATE);
Add<HSimulate>(assignment_id, REMOVABLE_SIMULATE);
} else {
Push(result_value);
AddSimulate(assignment_id, REMOVABLE_SIMULATE);
Add<HSimulate>(assignment_id, REMOVABLE_SIMULATE);
Drop(1);
}
}
@ -4931,7 +4928,7 @@ void HOptimizedGraphBuilder::HandlePropertyAssignment(Assignment* expr) {
HValue* value = environment()->ExpressionStackAt(0);
HValue* object = environment()->ExpressionStackAt(1);
if (expr->IsUninitialized()) AddSoftDeoptimize();
if (expr->IsUninitialized()) Add<HDeoptimize>(Deoptimizer::SOFT);
return BuildStoreNamed(expr, expr->id(), expr->position(),
expr->AssignmentId(), prop, object, value, value);
} else {
@ -4948,7 +4945,7 @@ void HOptimizedGraphBuilder::HandlePropertyAssignment(Assignment* expr) {
&has_side_effects);
Drop(3);
Push(value);
AddSimulate(expr->AssignmentId(), REMOVABLE_SIMULATE);
Add<HSimulate>(expr->AssignmentId(), REMOVABLE_SIMULATE);
return ast_context()->ReturnValue(Pop());
}
}
@ -4977,14 +4974,14 @@ void HOptimizedGraphBuilder::HandleGlobalVariableAssignment(
}
builder.Then();
builder.Else();
AddSoftDeoptimize(MUST_EMIT_SOFT_DEOPT);
Add<HDeoptimize>(Deoptimizer::EAGER);
builder.End();
}
HInstruction* instr =
Add<HStoreGlobalCell>(value, cell, lookup.GetPropertyDetails());
instr->set_position(position);
if (instr->HasObservableSideEffects()) {
AddSimulate(ast_id, REMOVABLE_SIMULATE);
Add<HSimulate>(ast_id, REMOVABLE_SIMULATE);
}
} else {
HValue* context = environment()->LookupContext();
@ -4994,7 +4991,7 @@ void HOptimizedGraphBuilder::HandleGlobalVariableAssignment(
value, function_strict_mode_flag());
instr->set_position(position);
ASSERT(instr->HasObservableSideEffects());
AddSimulate(ast_id, REMOVABLE_SIMULATE);
Add<HSimulate>(ast_id, REMOVABLE_SIMULATE);
}
}
@ -5056,7 +5053,7 @@ void HOptimizedGraphBuilder::BuildStoreNamed(Expression* expr,
instr->set_position(position);
AddInstruction(instr);
if (instr->HasObservableSideEffects()) {
AddSimulate(id, REMOVABLE_SIMULATE);
Add<HSimulate>(id, REMOVABLE_SIMULATE);
}
if (!ast_context()->IsEffect()) Drop(1);
return ast_context()->ReturnValue(result_value);
@ -5134,7 +5131,7 @@ void HOptimizedGraphBuilder::HandleCompoundAssignment(Assignment* expr) {
HStoreContextSlot* instr = Add<HStoreContextSlot>(context, var->index(),
mode, Top());
if (instr->HasObservableSideEffects()) {
AddSimulate(expr->AssignmentId(), REMOVABLE_SIMULATE);
Add<HSimulate>(expr->AssignmentId(), REMOVABLE_SIMULATE);
}
break;
}
@ -5175,7 +5172,7 @@ void HOptimizedGraphBuilder::HandleCompoundAssignment(Assignment* expr) {
if (load == NULL) load = BuildLoadNamedGeneric(object, name, prop);
PushAndAdd(load);
if (load->HasObservableSideEffects()) {
AddSimulate(prop->LoadId(), REMOVABLE_SIMULATE);
Add<HSimulate>(prop->LoadId(), REMOVABLE_SIMULATE);
}
CHECK_ALIVE(VisitForValue(expr->value()));
@ -5185,7 +5182,7 @@ void HOptimizedGraphBuilder::HandleCompoundAssignment(Assignment* expr) {
HInstruction* instr = BuildBinaryOperation(operation, left, right);
PushAndAdd(instr);
if (instr->HasObservableSideEffects()) {
AddSimulate(operation->id(), REMOVABLE_SIMULATE);
Add<HSimulate>(operation->id(), REMOVABLE_SIMULATE);
}
return BuildStoreNamed(prop, expr->id(), expr->position(),
@ -5203,7 +5200,7 @@ void HOptimizedGraphBuilder::HandleCompoundAssignment(Assignment* expr) {
false, // is_store
&has_side_effects);
Push(load);
if (has_side_effects) AddSimulate(prop->LoadId(), REMOVABLE_SIMULATE);
if (has_side_effects) Add<HSimulate>(prop->LoadId(), REMOVABLE_SIMULATE);
CHECK_ALIVE(VisitForValue(expr->value()));
HValue* right = Pop();
@ -5212,7 +5209,7 @@ void HOptimizedGraphBuilder::HandleCompoundAssignment(Assignment* expr) {
HInstruction* instr = BuildBinaryOperation(operation, left, right);
PushAndAdd(instr);
if (instr->HasObservableSideEffects()) {
AddSimulate(operation->id(), REMOVABLE_SIMULATE);
Add<HSimulate>(operation->id(), REMOVABLE_SIMULATE);
}
HandleKeyedElementAccess(obj, key, instr, expr, expr->AssignmentId(),
@ -5224,7 +5221,7 @@ void HOptimizedGraphBuilder::HandleCompoundAssignment(Assignment* expr) {
Drop(3);
Push(instr);
ASSERT(has_side_effects); // Stores always have side effects.
AddSimulate(expr->AssignmentId(), REMOVABLE_SIMULATE);
Add<HSimulate>(expr->AssignmentId(), REMOVABLE_SIMULATE);
return ast_context()->ReturnValue(Pop());
}
@ -5346,7 +5343,7 @@ void HOptimizedGraphBuilder::VisitAssignment(Assignment* expr) {
HStoreContextSlot* instr = Add<HStoreContextSlot>(context, var->index(),
mode, Top());
if (instr->HasObservableSideEffects()) {
AddSimulate(expr->AssignmentId(), REMOVABLE_SIMULATE);
Add<HSimulate>(expr->AssignmentId(), REMOVABLE_SIMULATE);
}
return ast_context()->ReturnValue(Pop());
}
@ -5380,7 +5377,7 @@ void HOptimizedGraphBuilder::VisitThrow(Throw* expr) {
HValue* value = environment()->Pop();
HThrow* instr = Add<HThrow>(context, value);
instr->set_position(expr->position());
AddSimulate(expr->id());
Add<HSimulate>(expr->id());
current_block()->FinishExit(new(zone()) HAbnormalExit);
set_current_block(NULL);
}
@ -5412,7 +5409,7 @@ HInstruction* HOptimizedGraphBuilder::BuildLoadNamedGeneric(
Handle<String> name,
Property* expr) {
if (expr->IsUninitialized()) {
AddSoftDeoptimize();
Add<HDeoptimize>(Deoptimizer::SOFT);
}
HValue* context = environment()->LookupContext();
return new(zone()) HLoadNamedGeneric(context, object, name);
@ -5735,7 +5732,8 @@ HValue* HOptimizedGraphBuilder::HandlePolymorphicElementAccess(
}
// Deopt if none of the cases matched.
current_block()->FinishExitWithDeoptimization(HDeoptimize::kNoUses);
NoObservableSideEffectsScope scope(this);
FinishExitWithHardDeoptimization(join);
set_current_block(join);
return is_store ? NULL : Pop();
}
@ -5771,12 +5769,12 @@ HValue* HOptimizedGraphBuilder::HandleKeyedElementAccess(
} else {
if (is_store) {
if (expr->IsAssignment() && expr->AsAssignment()->IsUninitialized()) {
AddSoftDeoptimize();
Add<HDeoptimize>(Deoptimizer::SOFT);
}
instr = BuildStoreKeyedGeneric(obj, key, val);
} else {
if (expr->AsProperty()->IsUninitialized()) {
AddSoftDeoptimize();
Add<HDeoptimize>(Deoptimizer::SOFT);
}
instr = BuildLoadKeyedGeneric(obj, key);
}
@ -5955,10 +5953,10 @@ void HOptimizedGraphBuilder::VisitProperty(Property* expr) {
&has_side_effects);
if (has_side_effects) {
if (ast_context()->IsEffect()) {
AddSimulate(expr->id(), REMOVABLE_SIMULATE);
Add<HSimulate>(expr->id(), REMOVABLE_SIMULATE);
} else {
Push(load);
AddSimulate(expr->id(), REMOVABLE_SIMULATE);
Add<HSimulate>(expr->id(), REMOVABLE_SIMULATE);
Drop(1);
}
}
@ -6060,7 +6058,7 @@ bool HOptimizedGraphBuilder::TryCallPolymorphicAsMonomorphic(
PreProcessCall(call);
AddInstruction(call);
if (!ast_context()->IsEffect()) Push(call);
AddSimulate(expr->id(), REMOVABLE_SIMULATE);
Add<HSimulate>(expr->id(), REMOVABLE_SIMULATE);
if (!ast_context()->IsEffect()) ast_context()->ReturnValue(Pop());
}
@ -6192,7 +6190,7 @@ void HOptimizedGraphBuilder::HandlePolymorphicCallNamed(
// know about and do not want to handle ones we've never seen. Otherwise
// use a generic IC.
if (ordered_functions == types->length() && FLAG_deoptimize_uncommon_cases) {
current_block()->FinishExitWithDeoptimization(HDeoptimize::kNoUses);
FinishExitWithHardDeoptimization(join);
} else {
HValue* context = environment()->LookupContext();
HCallNamed* call = new(zone()) HCallNamed(context, name, argument_count);
@ -6450,7 +6448,7 @@ bool HOptimizedGraphBuilder::TryInline(CallKind call_kind,
inner_env->BindContext(context);
#endif
AddSimulate(return_id);
Add<HSimulate>(return_id);
current_block()->UpdateEnvironment(inner_env);
HArgumentsObject* arguments_object = NULL;
@ -7628,7 +7626,7 @@ void HOptimizedGraphBuilder::VisitCountOperation(CountOperation* expr) {
HStoreContextSlot* instr = Add<HStoreContextSlot>(context, var->index(),
mode, after);
if (instr->HasObservableSideEffects()) {
AddSimulate(expr->AssignmentId(), REMOVABLE_SIMULATE);
Add<HSimulate>(expr->AssignmentId(), REMOVABLE_SIMULATE);
}
break;
}
@ -7671,7 +7669,7 @@ void HOptimizedGraphBuilder::VisitCountOperation(CountOperation* expr) {
if (load == NULL) load = BuildLoadNamedGeneric(object, name, prop);
PushAndAdd(load);
if (load->HasObservableSideEffects()) {
AddSimulate(prop->LoadId(), REMOVABLE_SIMULATE);
Add<HSimulate>(prop->LoadId(), REMOVABLE_SIMULATE);
}
after = BuildIncrement(returns_original_input, expr);
@ -7694,7 +7692,7 @@ void HOptimizedGraphBuilder::VisitCountOperation(CountOperation* expr) {
false, // is_store
&has_side_effects);
Push(load);
if (has_side_effects) AddSimulate(prop->LoadId(), REMOVABLE_SIMULATE);
if (has_side_effects) Add<HSimulate>(prop->LoadId(), REMOVABLE_SIMULATE);
after = BuildIncrement(returns_original_input, expr);
input = environment()->ExpressionStackAt(0);
@ -7711,7 +7709,7 @@ void HOptimizedGraphBuilder::VisitCountOperation(CountOperation* expr) {
environment()->SetExpressionStackAt(0, after);
if (returns_original_input) environment()->SetExpressionStackAt(1, input);
ASSERT(has_side_effects); // Stores always have side effects.
AddSimulate(expr->AssignmentId(), REMOVABLE_SIMULATE);
Add<HSimulate>(expr->AssignmentId(), REMOVABLE_SIMULATE);
}
}
@ -7859,12 +7857,12 @@ HInstruction* HOptimizedGraphBuilder::BuildBinaryOperation(
}
if (left_type->Is(Type::None())) {
AddSoftDeoptimize();
Add<HDeoptimize>(Deoptimizer::SOFT);
// TODO(rossberg): we should be able to get rid of non-continuous defaults.
left_type = handle(Type::Any(), isolate());
}
if (right_type->Is(Type::None())) {
AddSoftDeoptimize();
Add<HDeoptimize>(Deoptimizer::SOFT);
right_type = handle(Type::Any(), isolate());
}
HInstruction* instr = NULL;
@ -8214,7 +8212,7 @@ void HOptimizedGraphBuilder::VisitCompareOperation(CompareOperation* expr) {
// Cases handled below depend on collected type feedback. They should
// soft deoptimize when there is no type feedback.
if (combined_type->Is(Type::None())) {
AddSoftDeoptimize();
Add<HDeoptimize>(Deoptimizer::SOFT);
combined_type = left_type = right_type = handle(Type::Any(), isolate());
}
@ -8717,7 +8715,7 @@ void HOptimizedGraphBuilder::VisitVariableDeclaration(
HStoreContextSlot* store = Add<HStoreContextSlot>(
context, variable->index(), HStoreContextSlot::kNoCheck, value);
if (store->HasObservableSideEffects()) {
AddSimulate(proxy->id(), REMOVABLE_SIMULATE);
Add<HSimulate>(proxy->id(), REMOVABLE_SIMULATE);
}
}
break;
@ -8755,7 +8753,7 @@ void HOptimizedGraphBuilder::VisitFunctionDeclaration(
HStoreContextSlot* store = Add<HStoreContextSlot>(
context, variable->index(), HStoreContextSlot::kNoCheck, value);
if (store->HasObservableSideEffects()) {
AddSimulate(proxy->id(), REMOVABLE_SIMULATE);
Add<HSimulate>(proxy->id(), REMOVABLE_SIMULATE);
}
break;
}

View File

@ -137,17 +137,15 @@ class HBasicBlock: public ZoneObject {
}
int PredecessorIndexOf(HBasicBlock* predecessor) const;
void AddSimulate(BailoutId ast_id,
RemovableSimulate removable = FIXED_SIMULATE) {
AddInstruction(CreateSimulate(ast_id, removable));
HSimulate* AddSimulate(BailoutId ast_id,
RemovableSimulate removable = FIXED_SIMULATE) {
HSimulate* instr = CreateSimulate(ast_id, removable);
AddInstruction(instr);
return instr;
}
void AssignCommonDominator(HBasicBlock* other);
void AssignLoopSuccessorDominators();
void FinishExitWithDeoptimization(HDeoptimize::UseEnvironment has_uses) {
FinishExit(CreateDeoptimize(has_uses));
}
// Add the inlined function exit sequence, adding an HLeaveInlined
// instruction and updating the bailout environment.
void AddLeaveInlined(HValue* return_value, FunctionState* state);
@ -182,11 +180,12 @@ class HBasicBlock: public ZoneObject {
#endif
private:
friend class HGraphBuilder;
void RegisterPredecessor(HBasicBlock* pred);
void AddDominatedBlock(HBasicBlock* block);
HSimulate* CreateSimulate(BailoutId ast_id, RemovableSimulate removable);
HDeoptimize* CreateDeoptimize(HDeoptimize::UseEnvironment has_uses);
int block_id_;
HGraph* graph_;
@ -1023,11 +1022,6 @@ class HGraphBuilder {
new(zone()) I(p1, p2, p3, p4, p5, p6, p7, p8)));
}
void AddSimulate(BailoutId id,
RemovableSimulate removable = FIXED_SIMULATE);
HReturn* AddReturn(HValue* value);
void IncrementInNoSideEffectsScope() {
no_side_effects_scope_count_++;
}
@ -1122,12 +1116,7 @@ class HGraphBuilder {
void PushAndAdd(HInstruction* instr);
enum SoftDeoptimizeMode {
MUST_EMIT_SOFT_DEOPT,
CAN_OMIT_SOFT_DEOPT
};
void AddSoftDeoptimize(SoftDeoptimizeMode mode = CAN_OMIT_SOFT_DEOPT);
void FinishExitWithHardDeoptimization(HBasicBlock* continuation);
class IfBuilder {
public:
@ -1232,7 +1221,6 @@ class HGraphBuilder {
void ElseDeopt() {
Else();
Deopt();
End();
}
void Return(HValue* value);
@ -1245,6 +1233,8 @@ class HGraphBuilder {
HGraphBuilder* builder_;
int position_;
bool finished_ : 1;
bool deopt_then_ : 1;
bool deopt_else_ : 1;
bool did_then_ : 1;
bool did_else_ : 1;
bool did_and_ : 1;
@ -1426,12 +1416,68 @@ class HGraphBuilder {
private:
HGraphBuilder();
void PadEnvironmentForContinuation(HBasicBlock* from,
HBasicBlock* continuation);
CompilationInfo* info_;
HGraph* graph_;
HBasicBlock* current_block_;
int no_side_effects_scope_count_;
};
template<>
inline HDeoptimize* HGraphBuilder::Add(Deoptimizer::BailoutType type) {
if (type == Deoptimizer::SOFT) {
isolate()->counters()->soft_deopts_requested()->Increment();
if (FLAG_always_opt) return NULL;
}
if (current_block()->IsDeoptimizing()) return NULL;
HDeoptimize* instr = new(zone()) HDeoptimize(type);
AddInstruction(instr);
if (type == Deoptimizer::SOFT) {
isolate()->counters()->soft_deopts_inserted()->Increment();
graph()->set_has_soft_deoptimize(true);
}
current_block()->MarkAsDeoptimizing();
return instr;
}
template<>
inline HSimulate* HGraphBuilder::Add(BailoutId id,
RemovableSimulate removable) {
HSimulate* instr = current_block()->CreateSimulate(id, removable);
AddInstruction(instr);
return instr;
}
template<>
inline HSimulate* HGraphBuilder::Add(BailoutId id) {
return Add<HSimulate>(id, FIXED_SIMULATE);
}
template<>
inline HReturn* HGraphBuilder::Add(HValue* value) {
HValue* context = environment()->LookupContext();
int num_parameters = graph()->info()->num_parameters();
HValue* params = Add<HConstant>(num_parameters);
HReturn* return_instruction = new(graph()->zone())
HReturn(value, context, params);
current_block()->FinishExit(return_instruction);
return return_instruction;
}
template<>
inline HReturn* HGraphBuilder::Add(HConstant* p1) {
return Add<HReturn>(static_cast<HValue*>(p1));
}
class HOptimizedGraphBuilder: public HGraphBuilder, public AstVisitor {
public:
// A class encapsulating (lazily-allocated) break and continue blocks for

View File

@ -1003,12 +1003,6 @@ void LCodeGen::DeoptimizeIf(Condition cc,
}
void LCodeGen::SoftDeoptimize(LEnvironment* environment) {
ASSERT(!info()->IsStub());
DeoptimizeIf(no_condition, environment, Deoptimizer::SOFT);
}
void LCodeGen::RegisterDependentCodeForEmbeddedMaps(Handle<Code> code) {
ZoneList<Handle<Map> > maps(1, zone());
int mode_mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT);
@ -6323,11 +6317,15 @@ void LCodeGen::DoLazyBailout(LLazyBailout* instr) {
void LCodeGen::DoDeoptimize(LDeoptimize* instr) {
if (instr->hydrogen_value()->IsSoftDeoptimize()) {
SoftDeoptimize(instr->environment());
} else {
DeoptimizeIf(no_condition, instr->environment());
Deoptimizer::BailoutType type = instr->hydrogen()->type();
// TODO(danno): Stubs expect all deopts to be lazy for historical reasons (the
// needed return address), even though the implementation of LAZY and EAGER is
// now identical. When LAZY is eventually completely folded into EAGER, remove
// the special case below.
if (info()->IsStub() && type == Deoptimizer::EAGER) {
type = Deoptimizer::LAZY;
}
DeoptimizeIf(no_condition, instr->environment(), type);
}

View File

@ -283,7 +283,6 @@ class LCodeGen BASE_EMBEDDED {
LEnvironment* environment,
Deoptimizer::BailoutType bailout_type);
void DeoptimizeIf(Condition cc, LEnvironment* environment);
void SoftDeoptimize(LEnvironment* environment);
void AddToTranslation(Translation* translation,
LOperand* op,

View File

@ -754,11 +754,6 @@ LInstruction* LChunkBuilder::DoEnvironmentMarker(HEnvironmentMarker* instr) {
}
LInstruction* LChunkBuilder::DoSoftDeoptimize(HSoftDeoptimize* instr) {
return AssignEnvironment(new(zone()) LDeoptimize);
}
LInstruction* LChunkBuilder::DoDeoptimize(HDeoptimize* instr) {
return AssignEnvironment(new(zone()) LDeoptimize);
}

View File

@ -424,6 +424,7 @@ class LDummyUse: public LTemplateInstruction<1, 1, 0> {
class LDeoptimize: public LTemplateInstruction<0, 0, 0> {
public:
DECLARE_CONCRETE_INSTRUCTION(Deoptimize, "deoptimize")
DECLARE_HYDROGEN_ACCESSOR(Deoptimize)
};

View File

@ -790,14 +790,6 @@ void LCodeGen::DeoptimizeIf(Condition cc,
}
void LCodeGen::SoftDeoptimize(LEnvironment* environment,
Register src1,
const Operand& src2) {
ASSERT(!info()->IsStub());
DeoptimizeIf(al, environment, Deoptimizer::SOFT, src1, src2);
}
void LCodeGen::RegisterDependentCodeForEmbeddedMaps(Handle<Code> code) {
ZoneList<Handle<Map> > maps(1, zone());
int mode_mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT);
@ -5649,11 +5641,15 @@ void LCodeGen::DoLazyBailout(LLazyBailout* instr) {
void LCodeGen::DoDeoptimize(LDeoptimize* instr) {
if (instr->hydrogen_value()->IsSoftDeoptimize()) {
SoftDeoptimize(instr->environment(), zero_reg, Operand(zero_reg));
} else {
DeoptimizeIf(al, instr->environment(), zero_reg, Operand(zero_reg));
Deoptimizer::BailoutType type = instr->hydrogen()->type();
// TODO(danno): Stubs expect all deopts to be lazy for historical reasons (the
// needed return address), even though the implementation of LAZY and EAGER is
// now identical. When LAZY is eventually completely folded into EAGER, remove
// the special case below.
if (info()->IsStub() && type == Deoptimizer::EAGER) {
type = Deoptimizer::LAZY;
}
DeoptimizeIf(al, instr->environment(), type, zero_reg, Operand(zero_reg));
}

View File

@ -284,9 +284,6 @@ class LCodeGen BASE_EMBEDDED {
LEnvironment* environment,
Register src1 = zero_reg,
const Operand& src2 = Operand(zero_reg));
void SoftDeoptimize(LEnvironment* environment,
Register src1 = zero_reg,
const Operand& src2 = Operand(zero_reg));
void AddToTranslation(Translation* translation,
LOperand* op,

View File

@ -706,11 +706,6 @@ LInstruction* LChunkBuilder::DoEnvironmentMarker(HEnvironmentMarker* instr) {
}
LInstruction* LChunkBuilder::DoSoftDeoptimize(HSoftDeoptimize* instr) {
return AssignEnvironment(new(zone()) LDeoptimize);
}
LInstruction* LChunkBuilder::DoDeoptimize(HDeoptimize* instr) {
return AssignEnvironment(new(zone()) LDeoptimize);
}

View File

@ -424,6 +424,7 @@ class LDummyUse: public LTemplateInstruction<1, 1, 0> {
class LDeoptimize: public LTemplateInstruction<0, 0, 0> {
public:
DECLARE_CONCRETE_INSTRUCTION(Deoptimize, "deoptimize")
DECLARE_HYDROGEN_ACCESSOR(Deoptimize)
};

View File

@ -697,12 +697,6 @@ void LCodeGen::DeoptimizeIf(Condition cc,
}
void LCodeGen::SoftDeoptimize(LEnvironment* environment) {
ASSERT(!info()->IsStub());
DeoptimizeIf(no_condition, environment, Deoptimizer::SOFT);
}
void LCodeGen::RegisterDependentCodeForEmbeddedMaps(Handle<Code> code) {
ZoneList<Handle<Map> > maps(1, zone());
int mode_mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT);
@ -5364,11 +5358,15 @@ void LCodeGen::DoLazyBailout(LLazyBailout* instr) {
void LCodeGen::DoDeoptimize(LDeoptimize* instr) {
if (instr->hydrogen_value()->IsSoftDeoptimize()) {
SoftDeoptimize(instr->environment());
} else {
DeoptimizeIf(no_condition, instr->environment());
Deoptimizer::BailoutType type = instr->hydrogen()->type();
// TODO(danno): Stubs expect all deopts to be lazy for historical reasons (the
// needed return address), even though the implementation of LAZY and EAGER is
// now identical. When LAZY is eventually completely folded into EAGER, remove
// the special case below.
if (info()->IsStub() && type == Deoptimizer::EAGER) {
type = Deoptimizer::LAZY;
}
DeoptimizeIf(no_condition, instr->environment(), type);
}

View File

@ -245,7 +245,6 @@ class LCodeGen BASE_EMBEDDED {
LEnvironment* environment,
Deoptimizer::BailoutType bailout_type);
void DeoptimizeIf(Condition cc, LEnvironment* environment);
void SoftDeoptimize(LEnvironment* environment);
void AddToTranslation(Translation* translation,
LOperand* op,
bool is_tagged,

View File

@ -710,11 +710,6 @@ LInstruction* LChunkBuilder::DoEnvironmentMarker(HEnvironmentMarker* instr) {
}
LInstruction* LChunkBuilder::DoSoftDeoptimize(HSoftDeoptimize* instr) {
return AssignEnvironment(new(zone()) LDeoptimize);
}
LInstruction* LChunkBuilder::DoDeoptimize(HDeoptimize* instr) {
return AssignEnvironment(new(zone()) LDeoptimize);
}

View File

@ -427,6 +427,7 @@ class LDummyUse: public LTemplateInstruction<1, 1, 0> {
class LDeoptimize: public LTemplateInstruction<0, 0, 0> {
public:
DECLARE_CONCRETE_INSTRUCTION(Deoptimize, "deoptimize")
DECLARE_HYDROGEN_ACCESSOR(Deoptimize)
};