| Index: src/hydrogen.cc
|
| diff --git a/src/hydrogen.cc b/src/hydrogen.cc
|
| index 7d120b7f81749248831427c13e952e86df40e850..e24927ecd8344012a47dbcb108a7c8d4161210c5 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());
|
| @@ -266,7 +246,7 @@ void HBasicBlock::SetJoinId(BailoutId ast_id) {
|
| ASSERT(i != 0 ||
|
| (predecessor->last_environment()->closure().is_null() ||
|
| predecessor->last_environment()->closure()->shared()
|
| - ->VerifyBailoutId(ast_id)));
|
| + ->VerifyBailoutId(ast_id)));
|
| simulate->set_ast_id(ast_id);
|
| predecessor->last_environment()->set_ast_id(ast_id);
|
| }
|
| @@ -706,7 +686,8 @@ HGraphBuilder::IfBuilder::IfBuilder(HGraphBuilder* builder, int position)
|
| 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;
|
| @@ -729,7 +710,7 @@ HGraphBuilder::IfBuilder::IfBuilder(
|
| first_true_block_(NULL),
|
| first_false_block_(NULL),
|
| split_edge_merge_block_(NULL),
|
| - merge_block_(NULL) {
|
| + merge_block_(NULL) {
|
| continuation->Continue(&first_true_block_,
|
| &first_false_block_,
|
| &position_);
|
| @@ -836,14 +817,7 @@ void HGraphBuilder::IfBuilder::Else() {
|
|
|
|
|
| void HGraphBuilder::IfBuilder::Deopt() {
|
| - HBasicBlock* block = builder_->current_block();
|
| - block->FinishExitWithDeoptimization(HDeoptimize::kUseAll);
|
| - builder_->set_current_block(NULL);
|
| - if (did_else_) {
|
| - first_false_block_ = NULL;
|
| - } else {
|
| - first_true_block_ = NULL;
|
| - }
|
| + builder_->Add<HDeoptimize>(Deoptimizer::EAGER);
|
| }
|
|
|
|
|
| @@ -991,36 +965,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,6 +987,23 @@ HValue* HGraphBuilder::BuildCheckHeapObject(HValue* obj) {
|
| }
|
|
|
|
|
| +void HGraphBuilder::Deoptimize(HBasicBlock* continuation) {
|
| + while (true) {
|
| + if (continuation->last_environment()->length() >
|
| + environment()->length()) {
|
| + environment()->Push(graph()->GetConstantUndefined());
|
| + } else if (continuation->last_environment()->length() <
|
| + environment()->length()) {
|
| + environment()->Pop();
|
| + } else {
|
| + break;
|
| + }
|
| + }
|
| + Add<HDeoptimize>(Deoptimizer::EAGER);
|
| + current_block()->Goto(continuation);
|
| +}
|
| +
|
| +
|
| HValue* HGraphBuilder::BuildCheckMap(HValue* obj,
|
| Handle<Map> map) {
|
| HCheckMaps* check = HCheckMaps::New(obj, map, zone());
|
| @@ -1050,7 +1011,6 @@ HValue* HGraphBuilder::BuildCheckMap(HValue* obj,
|
| return check;
|
| }
|
|
|
| -
|
| HInstruction* HGraphBuilder::BuildExternalArrayElementAccess(
|
| HValue* external_elements,
|
| HValue* checked_key,
|
| @@ -1729,7 +1689,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);
|
| @@ -1740,7 +1700,7 @@ HInstruction* HGraphBuilder::BuildUnaryMathOp(
|
| }
|
| case Token::BIT_NOT:
|
| if (type->Is(Type::None())) {
|
| - AddSoftDeoptimize();
|
| + Add<HDeoptimize>(Deoptimizer::SOFT);
|
| }
|
| return new(zone()) HBitNot(input);
|
| }
|
| @@ -2081,7 +2041,6 @@ HBasicBlock* HOptimizedGraphBuilder::CreateLoop(IterationStatement* statement,
|
|
|
| void HBasicBlock::FinishExit(HControlInstruction* instruction) {
|
| Finish(instruction);
|
| - ClearEnvironment();
|
| }
|
|
|
|
|
| @@ -2648,7 +2607,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 +2649,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 +2705,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 +2893,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 +2902,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 +3192,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 +3302,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 +3394,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 +3434,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_ =
|
| @@ -3525,7 +3484,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 +3538,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 +3699,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 +4296,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 +4461,7 @@ void HOptimizedGraphBuilder::VisitArrayLiteral(ArrayLiteral* expr) {
|
| break;
|
| }
|
|
|
| - AddSimulate(expr->GetIdForElement(i));
|
| + Add<HSimulate>(expr->GetIdForElement(i));
|
| }
|
|
|
| Drop(1); // array literal index
|
| @@ -4833,13 +4792,59 @@ 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;
|
| }
|
|
|
|
|
| +void HOptimizedGraphBuilder::HandlePolymorphicStoreNamedFieldHelper(
|
| + HValue* object,
|
| + Handle<String> name,
|
| + HValue* value,
|
| + SmallMapList* types,
|
| + int current_type,
|
| + int stored_count,
|
| + int position) {
|
| + HInstruction* instr = NULL;
|
| + if (stored_count == kMaxStorePolymorphism ||
|
| + (current_type == types->length() - 1)) {
|
| + if (FLAG_deoptimize_uncommon_cases) {
|
| + Add<HDeoptimize>(Deoptimizer::SOFT);
|
| + } else {
|
| + instr = BuildStoreNamedGeneric(object, name, value);
|
| + instr->set_position(position);
|
| + AddInstruction(instr);
|
| + }
|
| + return;
|
| + }
|
| +
|
| + Handle<Map> map = types->at(current_type);
|
| + LookupResult lookup(isolate());
|
| + if (!ComputeLoadStoreField(map, name, &lookup, true)) {
|
| + HandlePolymorphicStoreNamedFieldHelper(object, name, value, types,
|
| + current_type + 1, stored_count,
|
| + position);
|
| + return;
|
| + }
|
| +
|
| + IfBuilder builder(this);
|
| + builder.If<HCompareMap>(object, map);
|
| +
|
| + builder.Then();
|
| + CHECK_ALIVE(instr = BuildStoreNamedField(object, name, value, map, &lookup));
|
| + instr->set_position(position);
|
| + AddInstruction(instr);
|
| +
|
| + builder.Else();
|
| + HandlePolymorphicStoreNamedFieldHelper(object, name, value, types,
|
| + current_type + 1, stored_count + 1,
|
| + position);
|
| + builder.End();
|
| +}
|
| +
|
| +
|
| void HOptimizedGraphBuilder::HandlePolymorphicStoreNamedField(
|
| BailoutId id,
|
| int position,
|
| @@ -4855,82 +4860,19 @@ void HOptimizedGraphBuilder::HandlePolymorphicStoreNamedField(
|
| return;
|
| }
|
|
|
| - // TODO(ager): We should recognize when the prototype chains for different
|
| - // maps are identical. In that case we can avoid repeatedly generating the
|
| - // same prototype map checks.
|
| - int count = 0;
|
| - HBasicBlock* join = NULL;
|
| - for (int i = 0; i < types->length() && count < kMaxStorePolymorphism; ++i) {
|
| - Handle<Map> map = types->at(i);
|
| - LookupResult lookup(isolate());
|
| - if (ComputeLoadStoreField(map, name, &lookup, true)) {
|
| - if (count == 0) {
|
| - BuildCheckHeapObject(object);
|
| - join = graph()->CreateBasicBlock();
|
| - }
|
| - ++count;
|
| - HBasicBlock* if_true = graph()->CreateBasicBlock();
|
| - HBasicBlock* if_false = graph()->CreateBasicBlock();
|
| - HCompareMap* compare =
|
| - new(zone()) HCompareMap(object, map, if_true, if_false);
|
| - current_block()->Finish(compare);
|
| -
|
| - set_current_block(if_true);
|
| - HInstruction* instr;
|
| - CHECK_ALIVE(instr = BuildStoreNamedField(
|
| - object, name, store_value, map, &lookup));
|
| - instr->set_position(position);
|
| - // Goto will add the HSimulate for the store.
|
| - AddInstruction(instr);
|
| - if (!ast_context()->IsEffect()) {
|
| - if (result_value != NULL) Push(result_value);
|
| - Push(store_value);
|
| - }
|
| - current_block()->Goto(join);
|
| -
|
| - set_current_block(if_false);
|
| - }
|
| + {
|
| + Add<HCheckHeapObject>(object);
|
| + NoObservableSideEffectsScope no_effects(this);
|
| + HandlePolymorphicStoreNamedFieldHelper(object, name, store_value, types,
|
| + 0, 0, position);
|
| }
|
|
|
| - // Finish up. Unconditionally deoptimize if we've handled all the maps we
|
| - // 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);
|
| + if (ast_context()->IsEffect()) {
|
| + Add<HSimulate>(id, REMOVABLE_SIMULATE);
|
| } else {
|
| - HInstruction* instr = BuildStoreNamedGeneric(object, name, store_value);
|
| - instr->set_position(position);
|
| - AddInstruction(instr);
|
| -
|
| - if (join != NULL) {
|
| - if (!ast_context()->IsEffect()) {
|
| - if (result_value != NULL) Push(result_value);
|
| - Push(store_value);
|
| - }
|
| - current_block()->Goto(join);
|
| - } else {
|
| - // The HSimulate for the store should not see the stored value in
|
| - // effect contexts (it is not materialized at expr->id() in the
|
| - // unoptimized code).
|
| - if (instr->HasObservableSideEffects()) {
|
| - if (ast_context()->IsEffect()) {
|
| - AddSimulate(id, REMOVABLE_SIMULATE);
|
| - } else {
|
| - if (result_value != NULL) Push(result_value);
|
| - Push(store_value);
|
| - AddSimulate(id, REMOVABLE_SIMULATE);
|
| - Drop(result_value != NULL ? 2 : 1);
|
| - }
|
| - }
|
| - return ast_context()->ReturnValue(
|
| - result_value != NULL ? result_value : store_value);
|
| - }
|
| - }
|
| -
|
| - ASSERT(join != NULL);
|
| - join->SetJoinId(id);
|
| - set_current_block(join);
|
| - if (!ast_context()->IsEffect()) {
|
| + if (result_value != NULL) Push(result_value);
|
| + Push(store_value);
|
| + Add<HSimulate>(id, REMOVABLE_SIMULATE);
|
| if (result_value != NULL) Drop(1);
|
| ast_context()->ReturnValue(Pop());
|
| }
|
| @@ -4948,7 +4890,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);
|
| } else {
|
| @@ -4965,7 +4907,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 +4936,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 +4953,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 +5016,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 +5094,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 +5135,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 +5145,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 +5163,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 +5172,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 +5184,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 +5306,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 +5340,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 +5372,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);
|
| @@ -5814,7 +5756,7 @@ HValue* HOptimizedGraphBuilder::HandlePolymorphicElementAccess(
|
| }
|
|
|
| // Deopt if none of the cases matched.
|
| - current_block()->FinishExitWithDeoptimization(HDeoptimize::kNoUses);
|
| + Deoptimize(join);
|
| set_current_block(join);
|
| return is_store ? NULL : Pop();
|
| }
|
| @@ -5850,12 +5792,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);
|
| }
|
| @@ -6034,10 +5976,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 +6081,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 +6213,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);
|
| + Deoptimize(join);
|
| } else {
|
| HValue* context = environment()->LookupContext();
|
| HCallNamed* call = new(zone()) HCallNamed(context, name, argument_count);
|
| @@ -6529,7 +6471,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 +7657,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 +7700,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 +7724,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 +7741,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 +7847,12 @@ HInstruction* HOptimizedGraphBuilder::BuildBinaryOperation(
|
| Representation result_rep = Representation::FromType(result_type);
|
|
|
| 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;
|
| @@ -8260,7 +8202,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());
|
| }
|
|
|
| @@ -8760,7 +8702,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 +8740,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;
|
| }
|
|
|