Chromium Code Reviews| Index: src/hydrogen.cc |
| diff --git a/src/hydrogen.cc b/src/hydrogen.cc |
| index 7d120b7f81749248831427c13e952e86df40e850..02cb63a04aa8fa6c575d9dd5ccafd506b6438283 100644 |
| --- a/src/hydrogen.cc |
| +++ b/src/hydrogen.cc |
| @@ -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), |
| @@ -729,7 +714,7 @@ HGraphBuilder::IfBuilder::IfBuilder( |
| first_true_block_(NULL), |
| first_false_block_(NULL), |
| split_edge_merge_block_(NULL), |
| - merge_block_(NULL) { |
| + merge_block_(NULL) { |
|
Jakob Kummerow
2013/07/22 16:53:12
nit: unnecessary whitespace change
danno
2013/07/23 12:18:14
Done.
|
| continuation->Continue(&first_true_block_, |
| &first_false_block_, |
| &position_); |
| @@ -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); |
| } |
| @@ -880,7 +864,15 @@ void HGraphBuilder::IfBuilder::End() { |
| ASSERT(!last_true_block_->IsFinished()); |
| HBasicBlock* last_false_block = builder_->current_block(); |
| ASSERT(!last_false_block->IsFinished()); |
| + if (deopt_then_) { |
| + builder_->PadEnvironmentForContinuation(last_true_block_, |
|
Jakob Kummerow
2013/07/22 16:53:12
IIUC, this call never does anything, because merge
danno
2013/07/23 12:18:14
Done.
|
| + merge_block_); |
| + } |
| 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 +983,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 +1005,39 @@ 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 so that the environment match during the |
|
Jakob Kummerow
2013/07/22 16:53:12
nit: "the environments match"
danno
2013/07/23 12:18:14
Done.
|
| + // join. Popping values isn't allowed, that would kill the live ranges of |
| + // values that might be needed after the deopt. |
| + int continuation_env_length = continuation->last_environment()->length(); |
| + ASSERT(continuation_env_length >= from->last_environment()->length()); |
| + while (continuation_env_length > from->last_environment()->length()) { |
| + from->last_environment()->Push(graph()->GetConstantUndefined()); |
| + } |
| + } else { |
| + ASSERT(continuation->predecessors()->length() == 0); |
| + } |
| +} |
| + |
| + |
| HValue* HGraphBuilder::BuildCheckMap(HValue* obj, |
| - Handle<Map> map) { |
| + Handle<Map> map) { |
|
Jakob Kummerow
2013/07/22 16:53:12
nit: fits on last line?
danno
2013/07/23 12:18:14
Done.
|
| HCheckMaps* check = HCheckMaps::New(obj, map, zone()); |
| AddInstruction(check); |
| return check; |
| @@ -1729,7 +1722,7 @@ HInstruction* HGraphBuilder::BuildUnaryMathOp( |
| input, graph()->GetConstantMinus1()); |
| Representation rep = Representation::FromType(type); |
| if (type->Is(Type::None())) { |
| - AddSoftDeoptimize(); |
| + Add<HDeoptimize>(); |
|
Jakob Kummerow
2013/07/22 16:53:12
I'm not a fan of this parameterless convenience me
danno
2013/07/23 12:18:14
Done.
|
| } |
| if (instr->IsBinaryOperation()) { |
| HBinaryOperation* binop = HBinaryOperation::cast(instr); |
| @@ -1740,7 +1733,7 @@ HInstruction* HGraphBuilder::BuildUnaryMathOp( |
| } |
| case Token::BIT_NOT: |
| if (type->Is(Type::None())) { |
| - AddSoftDeoptimize(); |
| + Add<HDeoptimize>(); |
| } |
| return new(zone()) HBitNot(input); |
| } |
| @@ -2648,7 +2641,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); |
| } |
| } |
| @@ -2690,7 +2683,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); |
| } |
| } |
| @@ -2746,7 +2739,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); |
| @@ -2934,7 +2927,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); |
| @@ -2943,7 +2936,7 @@ bool HOptimizedGraphBuilder::BuildGraph() { |
| if (HasStackOverflow()) return false; |
| if (current_block() != NULL) { |
| - AddReturn(graph()->GetConstantUndefined()); |
| + Add<HReturn>(graph()->GetConstantUndefined()); |
| set_current_block(NULL); |
| } |
| @@ -3233,10 +3226,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(); |
| @@ -3343,7 +3336,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 |
| @@ -3435,7 +3428,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(); |
| @@ -3475,7 +3468,7 @@ void HOptimizedGraphBuilder::VisitSwitchStatement(SwitchStatement* stmt) { |
| if (stmt->switch_type() == SwitchStatement::SMI_SWITCH) { |
| if (!clause->compare_type()->Is(Type::Smi())) { |
| - AddSoftDeoptimize(); |
| + Add<HDeoptimize>(); |
| } |
| HCompareNumericAndBranch* compare_ = |
| @@ -3525,7 +3518,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(); |
| } |
| @@ -3579,7 +3572,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); |
| @@ -3740,7 +3733,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); |
| @@ -4337,7 +4330,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)); |
| @@ -4502,7 +4495,7 @@ void HOptimizedGraphBuilder::VisitArrayLiteral(ArrayLiteral* expr) { |
| break; |
| } |
| - AddSimulate(expr->GetIdForElement(i)); |
| + Add<HSimulate>(expr->GetIdForElement(i)); |
| } |
| Drop(1); // array literal index |
| @@ -4833,7 +4826,7 @@ bool HOptimizedGraphBuilder::TryStorePolymorphicAsMonomorphic( |
| Push(store_value); |
| store->set_position(position); |
| AddInstruction(store); |
| - AddSimulate(assignment_id); |
| + Add<HSimulate>(assignment_id); |
| if (result_value != NULL) Drop(1); |
| ast_context()->ReturnValue(Pop()); |
| return true; |
| @@ -4896,7 +4889,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); |
| @@ -4914,11 +4907,11 @@ void HOptimizedGraphBuilder::HandlePolymorphicStoreNamedField( |
| // unoptimized code). |
| if (instr->HasObservableSideEffects()) { |
| if (ast_context()->IsEffect()) { |
| - AddSimulate(id, REMOVABLE_SIMULATE); |
| + Add<HSimulate>(id, REMOVABLE_SIMULATE); |
| } else { |
| if (result_value != NULL) Push(result_value); |
| Push(store_value); |
| - AddSimulate(id, REMOVABLE_SIMULATE); |
| + Add<HSimulate>(id, REMOVABLE_SIMULATE); |
| Drop(result_value != NULL ? 2 : 1); |
| } |
| } |
| @@ -4948,7 +4941,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>(); |
| return BuildStoreNamed(expr, expr->id(), expr->position(), |
| expr->AssignmentId(), prop, object, value); |
| } else { |
| @@ -4965,7 +4958,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()); |
| } |
| } |
| @@ -4994,14 +4987,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(); |
| @@ -5011,7 +5004,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); |
| } |
| } |
| @@ -5074,7 +5067,7 @@ void HOptimizedGraphBuilder::BuildStoreNamed(Expression* expr, |
| instr->set_position(position); |
| AddInstruction(instr); |
| if (instr->HasObservableSideEffects()) { |
| - AddSimulate(assignment_id, REMOVABLE_SIMULATE); |
| + Add<HSimulate>(assignment_id, REMOVABLE_SIMULATE); |
| } |
| if (result_value != NULL) Drop(1); |
| return ast_context()->ReturnValue(Pop()); |
| @@ -5152,7 +5145,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; |
| } |
| @@ -5193,7 +5186,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())); |
| @@ -5203,7 +5196,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(), |
| @@ -5221,7 +5214,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(); |
| @@ -5230,7 +5223,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(), |
| @@ -5242,7 +5235,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()); |
| } |
| @@ -5364,7 +5357,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()); |
| } |
| @@ -5398,7 +5391,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); |
| } |
| @@ -5430,7 +5423,7 @@ HInstruction* HOptimizedGraphBuilder::BuildLoadNamedGeneric( |
| Handle<String> name, |
| Property* expr) { |
| if (expr->IsUninitialized()) { |
| - AddSoftDeoptimize(); |
| + Add<HDeoptimize>(); |
| } |
| HValue* context = environment()->LookupContext(); |
| return new(zone()) HLoadNamedGeneric(context, object, name); |
| @@ -5716,6 +5709,8 @@ HValue* HOptimizedGraphBuilder::HandlePolymorphicElementAccess( |
| STATIC_ASSERT(FAST_DOUBLE_ELEMENTS < FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND); |
| STATIC_ASSERT(DICTIONARY_ELEMENTS < FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND); |
| + NoObservableSideEffectsScope scope(this); |
| + |
| for (ElementsKind elements_kind = FIRST_ELEMENTS_KIND; |
| elements_kind <= LAST_ELEMENTS_KIND; |
| elements_kind = ElementsKind(elements_kind + 1)) { |
| @@ -5814,7 +5809,7 @@ HValue* HOptimizedGraphBuilder::HandlePolymorphicElementAccess( |
| } |
| // Deopt if none of the cases matched. |
| - current_block()->FinishExitWithDeoptimization(HDeoptimize::kNoUses); |
| + FinishExitWithHardDeoptimization(join); |
| set_current_block(join); |
| return is_store ? NULL : Pop(); |
| } |
| @@ -5850,12 +5845,12 @@ HValue* HOptimizedGraphBuilder::HandleKeyedElementAccess( |
| } else { |
| if (is_store) { |
| if (expr->IsAssignment() && expr->AsAssignment()->IsUninitialized()) { |
| - AddSoftDeoptimize(); |
| + Add<HDeoptimize>(); |
| } |
| instr = BuildStoreKeyedGeneric(obj, key, val); |
| } else { |
| if (expr->AsProperty()->IsUninitialized()) { |
| - AddSoftDeoptimize(); |
| + Add<HDeoptimize>(); |
| } |
| instr = BuildLoadKeyedGeneric(obj, key); |
| } |
| @@ -6034,10 +6029,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); |
| } |
| } |
| @@ -6139,7 +6134,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()); |
| } |
| @@ -6271,7 +6266,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); |
| @@ -6529,7 +6524,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; |
| @@ -7715,7 +7710,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; |
| } |
| @@ -7758,7 +7753,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); |
| @@ -7782,7 +7777,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); |
| @@ -7799,7 +7794,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); |
| } |
| } |
| @@ -7905,12 +7900,12 @@ HInstruction* HOptimizedGraphBuilder::BuildBinaryOperation( |
| Representation result_rep = Representation::FromType(result_type); |
| if (left_type->Is(Type::None())) { |
| - AddSoftDeoptimize(); |
| + Add<HDeoptimize>(); |
| // 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>(); |
| right_type = handle(Type::Any(), isolate()); |
| } |
| HInstruction* instr = NULL; |
| @@ -8260,7 +8255,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>(); |
| combined_type = left_type = right_type = handle(Type::Any(), isolate()); |
| } |
| @@ -8760,7 +8755,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; |
| @@ -8798,7 +8793,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; |
| } |