| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/crankshaft/hydrogen.h" | 5 #include "src/crankshaft/hydrogen.h" |
| 6 | 6 |
| 7 #include <sstream> | 7 #include <sstream> |
| 8 | 8 |
| 9 #include "src/allocation-site-scopes.h" | 9 #include "src/allocation-site-scopes.h" |
| 10 #include "src/ast/ast-numbering.h" | 10 #include "src/ast/ast-numbering.h" |
| (...skipping 3513 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3524 return first; | 3524 return first; |
| 3525 } else { | 3525 } else { |
| 3526 HBasicBlock* join_block = graph()->CreateBasicBlock(); | 3526 HBasicBlock* join_block = graph()->CreateBasicBlock(); |
| 3527 Goto(first, join_block); | 3527 Goto(first, join_block); |
| 3528 Goto(second, join_block); | 3528 Goto(second, join_block); |
| 3529 join_block->SetJoinId(join_id); | 3529 join_block->SetJoinId(join_id); |
| 3530 return join_block; | 3530 return join_block; |
| 3531 } | 3531 } |
| 3532 } | 3532 } |
| 3533 | 3533 |
| 3534 | 3534 template <class IterationStatement> |
| 3535 HBasicBlock* HOptimizedGraphBuilder::JoinContinue(IterationStatement* statement, | 3535 HBasicBlock* HOptimizedGraphBuilder::JoinContinue(IterationStatement* statement, |
| 3536 HBasicBlock* exit_block, | 3536 HBasicBlock* exit_block, |
| 3537 HBasicBlock* continue_block) { | 3537 HBasicBlock* continue_block) { |
| 3538 if (continue_block != NULL) { | 3538 if (continue_block != NULL) { |
| 3539 if (exit_block != NULL) Goto(exit_block, continue_block); | 3539 if (exit_block != NULL) Goto(exit_block, continue_block); |
| 3540 continue_block->SetJoinId(statement->ContinueId()); | 3540 continue_block->SetJoinId(statement->ContinueId()); |
| 3541 return continue_block; | 3541 return continue_block; |
| 3542 } | 3542 } |
| 3543 return exit_block; | 3543 return exit_block; |
| 3544 } | 3544 } |
| (...skipping 1532 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5077 last_block, | 5077 last_block, |
| 5078 stmt->ExitId())); | 5078 stmt->ExitId())); |
| 5079 } else { | 5079 } else { |
| 5080 if (fall_through_block != NULL) Goto(fall_through_block, break_block); | 5080 if (fall_through_block != NULL) Goto(fall_through_block, break_block); |
| 5081 if (last_block != NULL) Goto(last_block, break_block); | 5081 if (last_block != NULL) Goto(last_block, break_block); |
| 5082 break_block->SetJoinId(stmt->ExitId()); | 5082 break_block->SetJoinId(stmt->ExitId()); |
| 5083 set_current_block(break_block); | 5083 set_current_block(break_block); |
| 5084 } | 5084 } |
| 5085 } | 5085 } |
| 5086 | 5086 |
| 5087 | 5087 template <class IterationStatement> |
| 5088 void HOptimizedGraphBuilder::VisitLoopBody(IterationStatement* stmt, | 5088 void HOptimizedGraphBuilder::VisitLoopBody(IterationStatement* stmt, |
| 5089 HBasicBlock* loop_entry) { | 5089 HBasicBlock* loop_entry) { |
| 5090 Add<HSimulate>(stmt->StackCheckId()); | 5090 Add<HSimulate>(stmt->StackCheckId()); |
| 5091 HStackCheck* stack_check = | 5091 HStackCheck* stack_check = |
| 5092 HStackCheck::cast(Add<HStackCheck>(HStackCheck::kBackwardsBranch)); | 5092 HStackCheck::cast(Add<HStackCheck>(HStackCheck::kBackwardsBranch)); |
| 5093 DCHECK(loop_entry->IsLoopHeader()); | 5093 DCHECK(loop_entry->IsLoopHeader()); |
| 5094 loop_entry->loop_information()->set_stack_check(stack_check); | 5094 loop_entry->loop_information()->set_stack_check(stack_check); |
| 5095 CHECK_BAILOUT(Visit(stmt->body())); | 5095 CHECK_BAILOUT(Visit(stmt->body())); |
| 5096 } | 5096 } |
| 5097 | 5097 |
| (...skipping 1592 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6690 DCHECK(join != NULL); | 6690 DCHECK(join != NULL); |
| 6691 if (join->HasPredecessor()) { | 6691 if (join->HasPredecessor()) { |
| 6692 join->SetJoinId(ast_id); | 6692 join->SetJoinId(ast_id); |
| 6693 set_current_block(join); | 6693 set_current_block(join); |
| 6694 if (!ast_context()->IsEffect()) ast_context()->ReturnValue(Pop()); | 6694 if (!ast_context()->IsEffect()) ast_context()->ReturnValue(Pop()); |
| 6695 } else { | 6695 } else { |
| 6696 set_current_block(NULL); | 6696 set_current_block(NULL); |
| 6697 } | 6697 } |
| 6698 } | 6698 } |
| 6699 | 6699 |
| 6700 template <class Expression> |
| 6700 static bool ComputeReceiverTypes(Expression* expr, HValue* receiver, | 6701 static bool ComputeReceiverTypes(Expression* expr, HValue* receiver, |
| 6701 SmallMapList** t, | 6702 SmallMapList** t, |
| 6702 HOptimizedGraphBuilder* builder) { | 6703 HOptimizedGraphBuilder* builder) { |
| 6703 Zone* zone = builder->zone(); | 6704 Zone* zone = builder->zone(); |
| 6704 SmallMapList* maps = expr->GetReceiverTypes(); | 6705 SmallMapList* maps = expr->GetReceiverTypes(); |
| 6705 *t = maps; | 6706 *t = maps; |
| 6706 bool monomorphic = expr->IsMonomorphic(); | 6707 bool monomorphic = expr->IsMonomorphic(); |
| 6707 if (maps != NULL && receiver->HasMonomorphicJSObjectType()) { | 6708 if (maps != NULL && receiver->HasMonomorphicJSObjectType()) { |
| 6708 if (maps->length() > 0) { | 6709 if (maps->length() > 0) { |
| 6709 Map* root_map = receiver->GetMonomorphicJSObjectMap()->FindRootMap(); | 6710 Map* root_map = receiver->GetMonomorphicJSObjectMap()->FindRootMap(); |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6743 } | 6744 } |
| 6744 | 6745 |
| 6745 | 6746 |
| 6746 static bool AreStringTypes(SmallMapList* maps) { | 6747 static bool AreStringTypes(SmallMapList* maps) { |
| 6747 for (int i = 0; i < maps->length(); i++) { | 6748 for (int i = 0; i < maps->length(); i++) { |
| 6748 if (maps->at(i)->instance_type() >= FIRST_NONSTRING_TYPE) return false; | 6749 if (maps->at(i)->instance_type() >= FIRST_NONSTRING_TYPE) return false; |
| 6749 } | 6750 } |
| 6750 return true; | 6751 return true; |
| 6751 } | 6752 } |
| 6752 | 6753 |
| 6753 | 6754 template <class Expression> |
| 6754 void HOptimizedGraphBuilder::BuildStore(Expression* expr, Property* prop, | 6755 void HOptimizedGraphBuilder::BuildStore(Expression* expr, Property* prop, |
| 6755 FeedbackVectorSlot slot, | 6756 FeedbackVectorSlot slot, |
| 6756 BailoutId ast_id, BailoutId return_id, | 6757 BailoutId ast_id, BailoutId return_id, |
| 6757 bool is_uninitialized) { | 6758 bool is_uninitialized) { |
| 6758 if (!prop->key()->IsPropertyName()) { | 6759 if (!prop->key()->IsPropertyName()) { |
| 6759 // Keyed store. | 6760 // Keyed store. |
| 6760 HValue* value = Pop(); | 6761 HValue* value = Pop(); |
| 6761 HValue* key = Pop(); | 6762 HValue* key = Pop(); |
| 6762 HValue* object = Pop(); | 6763 HValue* object = Pop(); |
| 6763 bool has_side_effects = false; | 6764 bool has_side_effects = false; |
| (...skipping 812 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7576 // generic access in the case length() == 0. | 7577 // generic access in the case length() == 0. |
| 7577 DCHECK(join->predecessors()->length() > 0); | 7578 DCHECK(join->predecessors()->length() > 0); |
| 7578 // Deopt if none of the cases matched. | 7579 // Deopt if none of the cases matched. |
| 7579 NoObservableSideEffectsScope scope(this); | 7580 NoObservableSideEffectsScope scope(this); |
| 7580 FinishExitWithHardDeoptimization( | 7581 FinishExitWithHardDeoptimization( |
| 7581 Deoptimizer::kUnknownMapInPolymorphicElementAccess); | 7582 Deoptimizer::kUnknownMapInPolymorphicElementAccess); |
| 7582 set_current_block(join); | 7583 set_current_block(join); |
| 7583 return access_type == STORE ? val : Pop(); | 7584 return access_type == STORE ? val : Pop(); |
| 7584 } | 7585 } |
| 7585 | 7586 |
| 7586 | 7587 template <class Expression> |
| 7587 HValue* HOptimizedGraphBuilder::HandleKeyedElementAccess( | 7588 HValue* HOptimizedGraphBuilder::HandleKeyedElementAccess( |
| 7588 HValue* obj, HValue* key, HValue* val, Expression* expr, | 7589 HValue* obj, HValue* key, HValue* val, Expression* expr, |
| 7589 FeedbackVectorSlot slot, BailoutId ast_id, BailoutId return_id, | 7590 FeedbackVectorSlot slot, BailoutId ast_id, BailoutId return_id, |
| 7590 PropertyAccessType access_type, bool* has_side_effects) { | 7591 PropertyAccessType access_type, bool* has_side_effects) { |
| 7591 // A keyed name access with type feedback may contain the name. | 7592 // A keyed name access with type feedback may contain the name. |
| 7592 Handle<TypeFeedbackVector> vector = | 7593 Handle<TypeFeedbackVector> vector = |
| 7593 handle(current_feedback_vector(), isolate()); | 7594 handle(current_feedback_vector(), isolate()); |
| 7594 HValue* expected_key = key; | 7595 HValue* expected_key = key; |
| 7595 if (!key->ActualValue()->IsConstant()) { | 7596 if (!key->ActualValue()->IsConstant()) { |
| 7596 Name* name = nullptr; | 7597 Name* name = nullptr; |
| (...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7789 arguments_environment()->parameter_count() - 1; | 7790 arguments_environment()->parameter_count() - 1; |
| 7790 HInstruction* length = Add<HConstant>(argument_count); | 7791 HInstruction* length = Add<HConstant>(argument_count); |
| 7791 HInstruction* checked_key = Add<HBoundsCheck>(key, length); | 7792 HInstruction* checked_key = Add<HBoundsCheck>(key, length); |
| 7792 result = New<HAccessArgumentsAt>(elements, length, checked_key); | 7793 result = New<HAccessArgumentsAt>(elements, length, checked_key); |
| 7793 } | 7794 } |
| 7794 } | 7795 } |
| 7795 ast_context()->ReturnInstruction(result, expr->id()); | 7796 ast_context()->ReturnInstruction(result, expr->id()); |
| 7796 return true; | 7797 return true; |
| 7797 } | 7798 } |
| 7798 | 7799 |
| 7799 | 7800 template <class Expression> |
| 7800 HValue* HOptimizedGraphBuilder::BuildNamedAccess( | 7801 HValue* HOptimizedGraphBuilder::BuildNamedAccess( |
| 7801 PropertyAccessType access, BailoutId ast_id, BailoutId return_id, | 7802 PropertyAccessType access, BailoutId ast_id, BailoutId return_id, |
| 7802 Expression* expr, FeedbackVectorSlot slot, HValue* object, | 7803 Expression* expr, FeedbackVectorSlot slot, HValue* object, |
| 7803 Handle<Name> name, HValue* value, bool is_uninitialized) { | 7804 Handle<Name> name, HValue* value, bool is_uninitialized) { |
| 7804 SmallMapList* maps; | 7805 SmallMapList* maps; |
| 7805 ComputeReceiverTypes(expr, object, &maps, this); | 7806 ComputeReceiverTypes(expr, object, &maps, this); |
| 7806 DCHECK(maps != NULL); | 7807 DCHECK(maps != NULL); |
| 7807 | 7808 |
| 7808 if (maps->length() > 0) { | 7809 if (maps->length() > 0) { |
| 7809 PropertyAccessInfo info(this, access, maps->first(), name); | 7810 PropertyAccessInfo info(this, access, maps->first(), name); |
| (...skipping 2885 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10695 if (instr->IsAdd()) { | 10696 if (instr->IsAdd()) { |
| 10696 HAdd* add = HAdd::cast(instr); | 10697 HAdd* add = HAdd::cast(instr); |
| 10697 add->set_observed_input_representation(1, rep); | 10698 add->set_observed_input_representation(1, rep); |
| 10698 add->set_observed_input_representation(2, Representation::Smi()); | 10699 add->set_observed_input_representation(2, Representation::Smi()); |
| 10699 } | 10700 } |
| 10700 instr->ClearAllSideEffects(); | 10701 instr->ClearAllSideEffects(); |
| 10701 instr->SetFlag(HInstruction::kCannotBeTagged); | 10702 instr->SetFlag(HInstruction::kCannotBeTagged); |
| 10702 return instr; | 10703 return instr; |
| 10703 } | 10704 } |
| 10704 | 10705 |
| 10705 | 10706 template <class Expression> |
| 10706 void HOptimizedGraphBuilder::BuildStoreForEffect( | 10707 void HOptimizedGraphBuilder::BuildStoreForEffect( |
| 10707 Expression* expr, Property* prop, FeedbackVectorSlot slot, BailoutId ast_id, | 10708 Expression* expr, Property* prop, FeedbackVectorSlot slot, BailoutId ast_id, |
| 10708 BailoutId return_id, HValue* object, HValue* key, HValue* value) { | 10709 BailoutId return_id, HValue* object, HValue* key, HValue* value) { |
| 10709 EffectContext for_effect(this); | 10710 EffectContext for_effect(this); |
| 10710 Push(object); | 10711 Push(object); |
| 10711 if (key != NULL) Push(key); | 10712 if (key != NULL) Push(key); |
| 10712 Push(value); | 10713 Push(value); |
| 10713 BuildStore(expr, prop, slot, ast_id, return_id); | 10714 BuildStore(expr, prop, slot, ast_id, return_id); |
| 10714 } | 10715 } |
| 10715 | 10716 |
| (...skipping 2713 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 13429 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 13430 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
| 13430 } | 13431 } |
| 13431 | 13432 |
| 13432 #ifdef DEBUG | 13433 #ifdef DEBUG |
| 13433 graph_->Verify(false); // No full verify. | 13434 graph_->Verify(false); // No full verify. |
| 13434 #endif | 13435 #endif |
| 13435 } | 13436 } |
| 13436 | 13437 |
| 13437 } // namespace internal | 13438 } // namespace internal |
| 13438 } // namespace v8 | 13439 } // namespace v8 |
| OLD | NEW |