| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 123 ASSERT(last_environment() != NULL); | 123 ASSERT(last_environment() != NULL); |
| 124 ASSERT(!last_environment()->ast_id().IsNone()); | 124 ASSERT(!last_environment()->ast_id().IsNone()); |
| 125 HBlockEntry* entry = new(zone()) HBlockEntry(); | 125 HBlockEntry* entry = new(zone()) HBlockEntry(); |
| 126 entry->InitializeAsFirst(this); | 126 entry->InitializeAsFirst(this); |
| 127 first_ = last_ = entry; | 127 first_ = last_ = entry; |
| 128 } | 128 } |
| 129 instr->InsertAfter(last_); | 129 instr->InsertAfter(last_); |
| 130 } | 130 } |
| 131 | 131 |
| 132 | 132 |
| 133 HDeoptimize* HBasicBlock::CreateDeoptimize( | |
| 134 HDeoptimize::UseEnvironment has_uses) { | |
| 135 ASSERT(HasEnvironment()); | |
| 136 if (has_uses == HDeoptimize::kNoUses) | |
| 137 return new(zone()) HDeoptimize(0, 0, 0, zone()); | |
| 138 | |
| 139 HEnvironment* environment = last_environment(); | |
| 140 int first_local_index = environment->first_local_index(); | |
| 141 int first_expression_index = environment->first_expression_index(); | |
| 142 HDeoptimize* instr = new(zone()) HDeoptimize( | |
| 143 environment->length(), first_local_index, first_expression_index, zone()); | |
| 144 for (int i = 0; i < environment->length(); i++) { | |
| 145 HValue* val = environment->values()->at(i); | |
| 146 instr->AddEnvironmentValue(val, zone()); | |
| 147 } | |
| 148 | |
| 149 return instr; | |
| 150 } | |
| 151 | |
| 152 | |
| 153 HSimulate* HBasicBlock::CreateSimulate(BailoutId ast_id, | 133 HSimulate* HBasicBlock::CreateSimulate(BailoutId ast_id, |
| 154 RemovableSimulate removable) { | 134 RemovableSimulate removable) { |
| 155 ASSERT(HasEnvironment()); | 135 ASSERT(HasEnvironment()); |
| 156 HEnvironment* environment = last_environment(); | 136 HEnvironment* environment = last_environment(); |
| 157 ASSERT(ast_id.IsNone() || | 137 ASSERT(ast_id.IsNone() || |
| 158 ast_id == BailoutId::StubEntry() || | 138 ast_id == BailoutId::StubEntry() || |
| 159 environment->closure()->shared()->VerifyBailoutId(ast_id)); | 139 environment->closure()->shared()->VerifyBailoutId(ast_id)); |
| 160 | 140 |
| 161 int push_count = environment->push_count(); | 141 int push_count = environment->push_count(); |
| 162 int pop_count = environment->pop_count(); | 142 int pop_count = environment->pop_count(); |
| (...skipping 500 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 663 | 643 |
| 664 HConstant* HGraph::GetInvalidContext() { | 644 HConstant* HGraph::GetInvalidContext() { |
| 665 return GetConstant(&constant_invalid_context_, 0xFFFFC0C7); | 645 return GetConstant(&constant_invalid_context_, 0xFFFFC0C7); |
| 666 } | 646 } |
| 667 | 647 |
| 668 | 648 |
| 669 HGraphBuilder::IfBuilder::IfBuilder(HGraphBuilder* builder, int position) | 649 HGraphBuilder::IfBuilder::IfBuilder(HGraphBuilder* builder, int position) |
| 670 : builder_(builder), | 650 : builder_(builder), |
| 671 position_(position), | 651 position_(position), |
| 672 finished_(false), | 652 finished_(false), |
| 653 deopt_then_(false), |
| 654 deopt_else_(false), |
| 673 did_then_(false), | 655 did_then_(false), |
| 674 did_else_(false), | 656 did_else_(false), |
| 675 did_and_(false), | 657 did_and_(false), |
| 676 did_or_(false), | 658 did_or_(false), |
| 677 captured_(false), | 659 captured_(false), |
| 678 needs_compare_(true), | 660 needs_compare_(true), |
| 679 split_edge_merge_block_(NULL) { | 661 split_edge_merge_block_(NULL), |
| 662 merge_block_(NULL) { |
| 680 HEnvironment* env = builder->environment(); | 663 HEnvironment* env = builder->environment(); |
| 681 first_true_block_ = builder->CreateBasicBlock(env->Copy()); | 664 first_true_block_ = builder->CreateBasicBlock(env->Copy()); |
| 682 last_true_block_ = NULL; | 665 last_true_block_ = NULL; |
| 683 first_false_block_ = builder->CreateBasicBlock(env->Copy()); | 666 first_false_block_ = builder->CreateBasicBlock(env->Copy()); |
| 684 } | 667 } |
| 685 | 668 |
| 686 | 669 |
| 687 HGraphBuilder::IfBuilder::IfBuilder( | 670 HGraphBuilder::IfBuilder::IfBuilder( |
| 688 HGraphBuilder* builder, | 671 HGraphBuilder* builder, |
| 689 HIfContinuation* continuation) | 672 HIfContinuation* continuation) |
| 690 : builder_(builder), | 673 : builder_(builder), |
| 691 position_(RelocInfo::kNoPosition), | 674 position_(RelocInfo::kNoPosition), |
| 692 finished_(false), | 675 finished_(false), |
| 676 deopt_then_(false), |
| 677 deopt_else_(false), |
| 693 did_then_(false), | 678 did_then_(false), |
| 694 did_else_(false), | 679 did_else_(false), |
| 695 did_and_(false), | 680 did_and_(false), |
| 696 did_or_(false), | 681 did_or_(false), |
| 697 captured_(false), | 682 captured_(false), |
| 698 needs_compare_(false), | 683 needs_compare_(false), |
| 699 first_true_block_(NULL), | 684 first_true_block_(NULL), |
| 700 first_false_block_(NULL), | 685 first_false_block_(NULL), |
| 701 split_edge_merge_block_(NULL), | 686 split_edge_merge_block_(NULL), |
| 702 merge_block_(NULL) { | 687 merge_block_(NULL) { |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 819 ASSERT(!captured_); | 804 ASSERT(!captured_); |
| 820 ASSERT(!finished_); | 805 ASSERT(!finished_); |
| 821 last_true_block_ = builder_->current_block(); | 806 last_true_block_ = builder_->current_block(); |
| 822 ASSERT(first_true_block_ == NULL || !last_true_block_->IsFinished()); | 807 ASSERT(first_true_block_ == NULL || !last_true_block_->IsFinished()); |
| 823 builder_->set_current_block(first_false_block_); | 808 builder_->set_current_block(first_false_block_); |
| 824 did_else_ = true; | 809 did_else_ = true; |
| 825 } | 810 } |
| 826 | 811 |
| 827 | 812 |
| 828 void HGraphBuilder::IfBuilder::Deopt() { | 813 void HGraphBuilder::IfBuilder::Deopt() { |
| 829 HBasicBlock* block = builder_->current_block(); | 814 ASSERT(did_then_); |
| 830 block->FinishExitWithDeoptimization(HDeoptimize::kUseAll); | |
| 831 builder_->set_current_block(NULL); | |
| 832 if (did_else_) { | 815 if (did_else_) { |
| 833 first_false_block_ = NULL; | 816 deopt_else_ = true; |
| 834 } else { | 817 } else { |
| 835 first_true_block_ = NULL; | 818 deopt_then_ = true; |
| 836 } | 819 } |
| 820 builder_->Add<HDeoptimize>(Deoptimizer::EAGER); |
| 837 } | 821 } |
| 838 | 822 |
| 839 | 823 |
| 840 void HGraphBuilder::IfBuilder::Return(HValue* value) { | 824 void HGraphBuilder::IfBuilder::Return(HValue* value) { |
| 841 HBasicBlock* block = builder_->current_block(); | 825 HBasicBlock* block = builder_->current_block(); |
| 842 HValue* context = builder_->environment()->LookupContext(); | 826 HValue* context = builder_->environment()->LookupContext(); |
| 843 HValue* parameter_count = builder_->graph()->GetConstantMinus1(); | 827 HValue* parameter_count = builder_->graph()->GetConstantMinus1(); |
| 844 block->FinishExit(new(zone()) HReturn(value, context, parameter_count)); | 828 block->FinishExit(new(zone()) HReturn(value, context, parameter_count)); |
| 845 builder_->set_current_block(NULL); | 829 builder_->set_current_block(NULL); |
| 846 if (did_else_) { | 830 if (did_else_) { |
| 847 first_false_block_ = NULL; | 831 first_false_block_ = NULL; |
| 848 } else { | 832 } else { |
| 849 first_true_block_ = NULL; | 833 first_true_block_ = NULL; |
| 850 } | 834 } |
| 851 } | 835 } |
| 852 | 836 |
| 853 | 837 |
| 854 void HGraphBuilder::IfBuilder::End() { | 838 void HGraphBuilder::IfBuilder::End() { |
| 855 if (!captured_) { | 839 if (!captured_) { |
| 856 ASSERT(did_then_); | 840 ASSERT(did_then_); |
| 857 if (!did_else_) { | 841 if (!did_else_) { |
| 858 last_true_block_ = builder_->current_block(); | 842 last_true_block_ = builder_->current_block(); |
| 859 } | 843 } |
| 860 if (first_true_block_ == NULL) { | 844 if (first_true_block_ == NULL) { |
| 861 // Deopt on true. Nothing to do, just continue the false block. | 845 // Return on true. Nothing to do, just continue the false block. |
| 862 } else if (first_false_block_ == NULL) { | 846 } else if (first_false_block_ == NULL) { |
| 863 // Deopt on false. Nothing to do except switching to the true block. | 847 // Deopt on false. Nothing to do except switching to the true block. |
| 864 builder_->set_current_block(last_true_block_); | 848 builder_->set_current_block(last_true_block_); |
| 865 } else { | 849 } else { |
| 866 HEnvironment* merge_env = last_true_block_->last_environment()->Copy(); | 850 merge_block_ = builder_->graph()->CreateBasicBlock(); |
| 867 merge_block_ = builder_->CreateBasicBlock(merge_env); | |
| 868 ASSERT(!finished_); | 851 ASSERT(!finished_); |
| 869 if (!did_else_) Else(); | 852 if (!did_else_) Else(); |
| 870 ASSERT(!last_true_block_->IsFinished()); | 853 ASSERT(!last_true_block_->IsFinished()); |
| 871 HBasicBlock* last_false_block = builder_->current_block(); | 854 HBasicBlock* last_false_block = builder_->current_block(); |
| 872 ASSERT(!last_false_block->IsFinished()); | 855 ASSERT(!last_false_block->IsFinished()); |
| 873 last_true_block_->GotoNoSimulate(merge_block_); | 856 if (deopt_then_) { |
| 874 last_false_block->GotoNoSimulate(merge_block_); | 857 last_false_block->GotoNoSimulate(merge_block_); |
| 858 builder_->PadEnvironmentForContinuation(last_true_block_, |
| 859 merge_block_); |
| 860 last_true_block_->GotoNoSimulate(merge_block_); |
| 861 } else { |
| 862 last_true_block_->GotoNoSimulate(merge_block_); |
| 863 if (deopt_else_) { |
| 864 builder_->PadEnvironmentForContinuation(last_false_block, |
| 865 merge_block_); |
| 866 } |
| 867 last_false_block->GotoNoSimulate(merge_block_); |
| 868 } |
| 875 builder_->set_current_block(merge_block_); | 869 builder_->set_current_block(merge_block_); |
| 876 } | 870 } |
| 877 } | 871 } |
| 878 finished_ = true; | 872 finished_ = true; |
| 879 } | 873 } |
| 880 | 874 |
| 881 | 875 |
| 882 HGraphBuilder::LoopBuilder::LoopBuilder(HGraphBuilder* builder, | 876 HGraphBuilder::LoopBuilder::LoopBuilder(HGraphBuilder* builder, |
| 883 HValue* context, | 877 HValue* context, |
| 884 LoopBuilder::Direction direction) | 878 LoopBuilder::Direction direction) |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 974 HInstruction* HGraphBuilder::AddInstruction(HInstruction* instr) { | 968 HInstruction* HGraphBuilder::AddInstruction(HInstruction* instr) { |
| 975 ASSERT(current_block() != NULL); | 969 ASSERT(current_block() != NULL); |
| 976 current_block()->AddInstruction(instr); | 970 current_block()->AddInstruction(instr); |
| 977 if (no_side_effects_scope_count_ > 0) { | 971 if (no_side_effects_scope_count_ > 0) { |
| 978 instr->SetFlag(HValue::kHasNoObservableSideEffects); | 972 instr->SetFlag(HValue::kHasNoObservableSideEffects); |
| 979 } | 973 } |
| 980 return instr; | 974 return instr; |
| 981 } | 975 } |
| 982 | 976 |
| 983 | 977 |
| 984 void HGraphBuilder::AddSimulate(BailoutId id, | |
| 985 RemovableSimulate removable) { | |
| 986 ASSERT(current_block() != NULL); | |
| 987 ASSERT(no_side_effects_scope_count_ == 0); | |
| 988 current_block()->AddSimulate(id, removable); | |
| 989 } | |
| 990 | |
| 991 | |
| 992 HBoundsCheck* HGraphBuilder::AddBoundsCheck(HValue* index, HValue* length) { | 978 HBoundsCheck* HGraphBuilder::AddBoundsCheck(HValue* index, HValue* length) { |
| 993 HBoundsCheck* result = new(graph()->zone()) HBoundsCheck(index, length); | 979 HBoundsCheck* result = new(graph()->zone()) HBoundsCheck(index, length); |
| 994 AddInstruction(result); | 980 AddInstruction(result); |
| 995 return result; | 981 return result; |
| 996 } | 982 } |
| 997 | 983 |
| 998 | 984 |
| 999 HReturn* HGraphBuilder::AddReturn(HValue* value) { | |
| 1000 HValue* context = environment()->LookupContext(); | |
| 1001 int num_parameters = graph()->info()->num_parameters(); | |
| 1002 HValue* params = AddInstruction(new(graph()->zone()) | |
| 1003 HConstant(num_parameters)); | |
| 1004 HReturn* return_instruction = new(graph()->zone()) | |
| 1005 HReturn(value, context, params); | |
| 1006 current_block()->FinishExit(return_instruction); | |
| 1007 return return_instruction; | |
| 1008 } | |
| 1009 | |
| 1010 | |
| 1011 HBasicBlock* HGraphBuilder::CreateBasicBlock(HEnvironment* env) { | 985 HBasicBlock* HGraphBuilder::CreateBasicBlock(HEnvironment* env) { |
| 1012 HBasicBlock* b = graph()->CreateBasicBlock(); | 986 HBasicBlock* b = graph()->CreateBasicBlock(); |
| 1013 b->SetInitialEnvironment(env); | 987 b->SetInitialEnvironment(env); |
| 1014 return b; | 988 return b; |
| 1015 } | 989 } |
| 1016 | 990 |
| 1017 | 991 |
| 1018 HBasicBlock* HGraphBuilder::CreateLoopHeaderBlock() { | 992 HBasicBlock* HGraphBuilder::CreateLoopHeaderBlock() { |
| 1019 HBasicBlock* header = graph()->CreateBasicBlock(); | 993 HBasicBlock* header = graph()->CreateBasicBlock(); |
| 1020 HEnvironment* entry_env = environment()->CopyAsLoopHeader(header); | 994 HEnvironment* entry_env = environment()->CopyAsLoopHeader(header); |
| 1021 header->SetInitialEnvironment(entry_env); | 995 header->SetInitialEnvironment(entry_env); |
| 1022 header->AttachLoopInformation(); | 996 header->AttachLoopInformation(); |
| 1023 return header; | 997 return header; |
| 1024 } | 998 } |
| 1025 | 999 |
| 1026 | 1000 |
| 1027 HValue* HGraphBuilder::BuildCheckNonSmi(HValue* obj) { | 1001 HValue* HGraphBuilder::BuildCheckNonSmi(HValue* obj) { |
| 1028 if (obj->type().IsHeapObject()) return obj; | 1002 if (obj->type().IsHeapObject()) return obj; |
| 1029 HCheckNonSmi* check = new(zone()) HCheckNonSmi(obj); | 1003 HCheckNonSmi* check = new(zone()) HCheckNonSmi(obj); |
| 1030 AddInstruction(check); | 1004 AddInstruction(check); |
| 1031 return check; | 1005 return check; |
| 1032 } | 1006 } |
| 1033 | 1007 |
| 1034 | 1008 |
| 1009 void HGraphBuilder::FinishExitWithHardDeoptimization( |
| 1010 HBasicBlock* continuation) { |
| 1011 PadEnvironmentForContinuation(current_block(), continuation); |
| 1012 Add<HDeoptimize>(Deoptimizer::EAGER); |
| 1013 if (no_side_effects_scope_count_ > 0) { |
| 1014 current_block()->GotoNoSimulate(continuation); |
| 1015 } else { |
| 1016 current_block()->Goto(continuation); |
| 1017 } |
| 1018 } |
| 1019 |
| 1020 |
| 1021 void HGraphBuilder::PadEnvironmentForContinuation( |
| 1022 HBasicBlock* from, |
| 1023 HBasicBlock* continuation) { |
| 1024 if (continuation->last_environment() != NULL) { |
| 1025 // When merging from a deopt block to a continuation, resolve differences in |
| 1026 // environment by pushing undefined and popping extra values so that the |
| 1027 // environments match during the join. |
| 1028 int continuation_env_length = continuation->last_environment()->length(); |
| 1029 while (continuation_env_length != from->last_environment()->length()) { |
| 1030 if (continuation_env_length > from->last_environment()->length()) { |
| 1031 from->last_environment()->Push(graph()->GetConstantUndefined()); |
| 1032 } else { |
| 1033 from->last_environment()->Pop(); |
| 1034 } |
| 1035 } |
| 1036 } else { |
| 1037 ASSERT(continuation->predecessors()->length() == 0); |
| 1038 } |
| 1039 } |
| 1040 |
| 1041 |
| 1035 HValue* HGraphBuilder::BuildCheckMap(HValue* obj, | 1042 HValue* HGraphBuilder::BuildCheckMap(HValue* obj, |
| 1036 Handle<Map> map) { | 1043 Handle<Map> map) { |
| 1037 HCheckMaps* check = HCheckMaps::New(obj, map, zone()); | 1044 HCheckMaps* check = HCheckMaps::New(obj, map, zone()); |
| 1038 AddInstruction(check); | 1045 AddInstruction(check); |
| 1039 return check; | 1046 return check; |
| 1040 } | 1047 } |
| 1041 | 1048 |
| 1042 | 1049 |
| 1043 HInstruction* HGraphBuilder::BuildExternalArrayElementAccess( | 1050 HInstruction* HGraphBuilder::BuildExternalArrayElementAccess( |
| 1044 HValue* external_elements, | 1051 HValue* external_elements, |
| 1045 HValue* checked_key, | 1052 HValue* checked_key, |
| 1046 HValue* val, | 1053 HValue* val, |
| (...skipping 1440 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2487 continue; | 2494 continue; |
| 2488 } | 2495 } |
| 2489 HDummyUse* dummy = new(zone()) HDummyUse(operand); | 2496 HDummyUse* dummy = new(zone()) HDummyUse(operand); |
| 2490 dummy->InsertBefore(instr); | 2497 dummy->InsertBefore(instr); |
| 2491 last_dummy = dummy; | 2498 last_dummy = dummy; |
| 2492 } | 2499 } |
| 2493 if (last_dummy == NULL) last_dummy = GetConstant1(); | 2500 if (last_dummy == NULL) last_dummy = GetConstant1(); |
| 2494 instr->DeleteAndReplaceWith(last_dummy); | 2501 instr->DeleteAndReplaceWith(last_dummy); |
| 2495 continue; | 2502 continue; |
| 2496 } | 2503 } |
| 2497 if (instr->IsSoftDeoptimize()) { | 2504 if (instr->IsDeoptimize()) { |
| 2498 ASSERT(block->IsDeoptimizing()); | 2505 ASSERT(block->IsDeoptimizing()); |
| 2499 nullify = true; | 2506 nullify = true; |
| 2500 } | 2507 } |
| 2501 } | 2508 } |
| 2502 } | 2509 } |
| 2503 } | 2510 } |
| 2504 | 2511 |
| 2505 | 2512 |
| 2506 // Replace all phis consisting of a single non-loop operand plus any number of | 2513 // Replace all phis consisting of a single non-loop operand plus any number of |
| 2507 // loop operands by that single non-loop operand. | 2514 // loop operands by that single non-loop operand. |
| (...skipping 1109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3617 | 3624 |
| 3618 void TestContext::ReturnValue(HValue* value) { | 3625 void TestContext::ReturnValue(HValue* value) { |
| 3619 BuildBranch(value); | 3626 BuildBranch(value); |
| 3620 } | 3627 } |
| 3621 | 3628 |
| 3622 | 3629 |
| 3623 void EffectContext::ReturnInstruction(HInstruction* instr, BailoutId ast_id) { | 3630 void EffectContext::ReturnInstruction(HInstruction* instr, BailoutId ast_id) { |
| 3624 ASSERT(!instr->IsControlInstruction()); | 3631 ASSERT(!instr->IsControlInstruction()); |
| 3625 owner()->AddInstruction(instr); | 3632 owner()->AddInstruction(instr); |
| 3626 if (instr->HasObservableSideEffects()) { | 3633 if (instr->HasObservableSideEffects()) { |
| 3627 owner()->AddSimulate(ast_id, REMOVABLE_SIMULATE); | 3634 owner()->Add<HSimulate>(ast_id, REMOVABLE_SIMULATE); |
| 3628 } | 3635 } |
| 3629 } | 3636 } |
| 3630 | 3637 |
| 3631 | 3638 |
| 3632 void EffectContext::ReturnControl(HControlInstruction* instr, | 3639 void EffectContext::ReturnControl(HControlInstruction* instr, |
| 3633 BailoutId ast_id) { | 3640 BailoutId ast_id) { |
| 3634 ASSERT(!instr->HasObservableSideEffects()); | 3641 ASSERT(!instr->HasObservableSideEffects()); |
| 3635 HBasicBlock* empty_true = owner()->graph()->CreateBasicBlock(); | 3642 HBasicBlock* empty_true = owner()->graph()->CreateBasicBlock(); |
| 3636 HBasicBlock* empty_false = owner()->graph()->CreateBasicBlock(); | 3643 HBasicBlock* empty_false = owner()->graph()->CreateBasicBlock(); |
| 3637 instr->SetSuccessorAt(0, empty_true); | 3644 instr->SetSuccessorAt(0, empty_true); |
| (...skipping 21 matching lines...) Expand all Loading... |
| 3659 | 3666 |
| 3660 | 3667 |
| 3661 void ValueContext::ReturnInstruction(HInstruction* instr, BailoutId ast_id) { | 3668 void ValueContext::ReturnInstruction(HInstruction* instr, BailoutId ast_id) { |
| 3662 ASSERT(!instr->IsControlInstruction()); | 3669 ASSERT(!instr->IsControlInstruction()); |
| 3663 if (!arguments_allowed() && instr->CheckFlag(HValue::kIsArguments)) { | 3670 if (!arguments_allowed() && instr->CheckFlag(HValue::kIsArguments)) { |
| 3664 return owner()->Bailout("bad value context for arguments object value"); | 3671 return owner()->Bailout("bad value context for arguments object value"); |
| 3665 } | 3672 } |
| 3666 owner()->AddInstruction(instr); | 3673 owner()->AddInstruction(instr); |
| 3667 owner()->Push(instr); | 3674 owner()->Push(instr); |
| 3668 if (instr->HasObservableSideEffects()) { | 3675 if (instr->HasObservableSideEffects()) { |
| 3669 owner()->AddSimulate(ast_id, REMOVABLE_SIMULATE); | 3676 owner()->Add<HSimulate>(ast_id, REMOVABLE_SIMULATE); |
| 3670 } | 3677 } |
| 3671 } | 3678 } |
| 3672 | 3679 |
| 3673 | 3680 |
| 3674 void ValueContext::ReturnControl(HControlInstruction* instr, BailoutId ast_id) { | 3681 void ValueContext::ReturnControl(HControlInstruction* instr, BailoutId ast_id) { |
| 3675 ASSERT(!instr->HasObservableSideEffects()); | 3682 ASSERT(!instr->HasObservableSideEffects()); |
| 3676 if (!arguments_allowed() && instr->CheckFlag(HValue::kIsArguments)) { | 3683 if (!arguments_allowed() && instr->CheckFlag(HValue::kIsArguments)) { |
| 3677 return owner()->Bailout("bad value context for arguments object value"); | 3684 return owner()->Bailout("bad value context for arguments object value"); |
| 3678 } | 3685 } |
| 3679 HBasicBlock* materialize_false = owner()->graph()->CreateBasicBlock(); | 3686 HBasicBlock* materialize_false = owner()->graph()->CreateBasicBlock(); |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3715 | 3722 |
| 3716 | 3723 |
| 3717 void TestContext::ReturnInstruction(HInstruction* instr, BailoutId ast_id) { | 3724 void TestContext::ReturnInstruction(HInstruction* instr, BailoutId ast_id) { |
| 3718 ASSERT(!instr->IsControlInstruction()); | 3725 ASSERT(!instr->IsControlInstruction()); |
| 3719 HOptimizedGraphBuilder* builder = owner(); | 3726 HOptimizedGraphBuilder* builder = owner(); |
| 3720 builder->AddInstruction(instr); | 3727 builder->AddInstruction(instr); |
| 3721 // We expect a simulate after every expression with side effects, though | 3728 // We expect a simulate after every expression with side effects, though |
| 3722 // this one isn't actually needed (and wouldn't work if it were targeted). | 3729 // this one isn't actually needed (and wouldn't work if it were targeted). |
| 3723 if (instr->HasObservableSideEffects()) { | 3730 if (instr->HasObservableSideEffects()) { |
| 3724 builder->Push(instr); | 3731 builder->Push(instr); |
| 3725 builder->AddSimulate(ast_id, REMOVABLE_SIMULATE); | 3732 builder->Add<HSimulate>(ast_id, REMOVABLE_SIMULATE); |
| 3726 builder->Pop(); | 3733 builder->Pop(); |
| 3727 } | 3734 } |
| 3728 BuildBranch(instr); | 3735 BuildBranch(instr); |
| 3729 } | 3736 } |
| 3730 | 3737 |
| 3731 | 3738 |
| 3732 void TestContext::ReturnControl(HControlInstruction* instr, BailoutId ast_id) { | 3739 void TestContext::ReturnControl(HControlInstruction* instr, BailoutId ast_id) { |
| 3733 ASSERT(!instr->HasObservableSideEffects()); | 3740 ASSERT(!instr->HasObservableSideEffects()); |
| 3734 HBasicBlock* empty_true = owner()->graph()->CreateBasicBlock(); | 3741 HBasicBlock* empty_true = owner()->graph()->CreateBasicBlock(); |
| 3735 HBasicBlock* empty_false = owner()->graph()->CreateBasicBlock(); | 3742 HBasicBlock* empty_false = owner()->graph()->CreateBasicBlock(); |
| (...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3903 current_block()->Goto(body_entry); | 3910 current_block()->Goto(body_entry); |
| 3904 body_entry->SetJoinId(BailoutId::FunctionEntry()); | 3911 body_entry->SetJoinId(BailoutId::FunctionEntry()); |
| 3905 set_current_block(body_entry); | 3912 set_current_block(body_entry); |
| 3906 | 3913 |
| 3907 // Handle implicit declaration of the function name in named function | 3914 // Handle implicit declaration of the function name in named function |
| 3908 // expressions before other declarations. | 3915 // expressions before other declarations. |
| 3909 if (scope->is_function_scope() && scope->function() != NULL) { | 3916 if (scope->is_function_scope() && scope->function() != NULL) { |
| 3910 VisitVariableDeclaration(scope->function()); | 3917 VisitVariableDeclaration(scope->function()); |
| 3911 } | 3918 } |
| 3912 VisitDeclarations(scope->declarations()); | 3919 VisitDeclarations(scope->declarations()); |
| 3913 AddSimulate(BailoutId::Declarations()); | 3920 Add<HSimulate>(BailoutId::Declarations()); |
| 3914 | 3921 |
| 3915 HValue* context = environment()->LookupContext(); | 3922 HValue* context = environment()->LookupContext(); |
| 3916 AddInstruction( | 3923 AddInstruction( |
| 3917 new(zone()) HStackCheck(context, HStackCheck::kFunctionEntry)); | 3924 new(zone()) HStackCheck(context, HStackCheck::kFunctionEntry)); |
| 3918 | 3925 |
| 3919 VisitStatements(current_info()->function()->body()); | 3926 VisitStatements(current_info()->function()->body()); |
| 3920 if (HasStackOverflow()) return false; | 3927 if (HasStackOverflow()) return false; |
| 3921 | 3928 |
| 3922 if (current_block() != NULL) { | 3929 if (current_block() != NULL) { |
| 3923 AddReturn(graph()->GetConstantUndefined()); | 3930 Add<HReturn>(graph()->GetConstantUndefined()); |
| 3924 set_current_block(NULL); | 3931 set_current_block(NULL); |
| 3925 } | 3932 } |
| 3926 | 3933 |
| 3927 // If the checksum of the number of type info changes is the same as the | 3934 // If the checksum of the number of type info changes is the same as the |
| 3928 // last time this function was compiled, then this recompile is likely not | 3935 // last time this function was compiled, then this recompile is likely not |
| 3929 // due to missing/inadequate type feedback, but rather too aggressive | 3936 // due to missing/inadequate type feedback, but rather too aggressive |
| 3930 // optimization. Disable optimistic LICM in that case. | 3937 // optimization. Disable optimistic LICM in that case. |
| 3931 Handle<Code> unoptimized_code(current_info()->shared_info()->code()); | 3938 Handle<Code> unoptimized_code(current_info()->shared_info()->code()); |
| 3932 ASSERT(unoptimized_code->kind() == Code::FUNCTION); | 3939 ASSERT(unoptimized_code->kind() == Code::FUNCTION); |
| 3933 Handle<TypeFeedbackInfo> type_info( | 3940 Handle<TypeFeedbackInfo> type_info( |
| (...skipping 718 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4652 current_block()->AddPhi(instr); | 4659 current_block()->AddPhi(instr); |
| 4653 } | 4660 } |
| 4654 | 4661 |
| 4655 | 4662 |
| 4656 void HOptimizedGraphBuilder::PushAndAdd(HInstruction* instr) { | 4663 void HOptimizedGraphBuilder::PushAndAdd(HInstruction* instr) { |
| 4657 Push(instr); | 4664 Push(instr); |
| 4658 AddInstruction(instr); | 4665 AddInstruction(instr); |
| 4659 } | 4666 } |
| 4660 | 4667 |
| 4661 | 4668 |
| 4662 void HOptimizedGraphBuilder::AddSoftDeoptimize() { | |
| 4663 if (FLAG_always_opt) return; | |
| 4664 if (current_block()->IsDeoptimizing()) return; | |
| 4665 AddInstruction(new(zone()) HSoftDeoptimize()); | |
| 4666 current_block()->MarkAsDeoptimizing(); | |
| 4667 graph()->set_has_soft_deoptimize(true); | |
| 4668 } | |
| 4669 | |
| 4670 | |
| 4671 template <class Instruction> | 4669 template <class Instruction> |
| 4672 HInstruction* HOptimizedGraphBuilder::PreProcessCall(Instruction* call) { | 4670 HInstruction* HOptimizedGraphBuilder::PreProcessCall(Instruction* call) { |
| 4673 int count = call->argument_count(); | 4671 int count = call->argument_count(); |
| 4674 ZoneList<HValue*> arguments(count, zone()); | 4672 ZoneList<HValue*> arguments(count, zone()); |
| 4675 for (int i = 0; i < count; ++i) { | 4673 for (int i = 0; i < count; ++i) { |
| 4676 arguments.Add(Pop(), zone()); | 4674 arguments.Add(Pop(), zone()); |
| 4677 } | 4675 } |
| 4678 | 4676 |
| 4679 while (!arguments.is_empty()) { | 4677 while (!arguments.is_empty()) { |
| 4680 AddInstruction(new(zone()) HPushArgument(arguments.RemoveLast())); | 4678 AddInstruction(new(zone()) HPushArgument(arguments.RemoveLast())); |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4767 ASSERT(current_block() != NULL); | 4765 ASSERT(current_block() != NULL); |
| 4768 ASSERT(current_block()->HasPredecessor()); | 4766 ASSERT(current_block()->HasPredecessor()); |
| 4769 } | 4767 } |
| 4770 | 4768 |
| 4771 | 4769 |
| 4772 void HOptimizedGraphBuilder::VisitIfStatement(IfStatement* stmt) { | 4770 void HOptimizedGraphBuilder::VisitIfStatement(IfStatement* stmt) { |
| 4773 ASSERT(!HasStackOverflow()); | 4771 ASSERT(!HasStackOverflow()); |
| 4774 ASSERT(current_block() != NULL); | 4772 ASSERT(current_block() != NULL); |
| 4775 ASSERT(current_block()->HasPredecessor()); | 4773 ASSERT(current_block()->HasPredecessor()); |
| 4776 if (stmt->condition()->ToBooleanIsTrue()) { | 4774 if (stmt->condition()->ToBooleanIsTrue()) { |
| 4777 AddSimulate(stmt->ThenId()); | 4775 Add<HSimulate>(stmt->ThenId()); |
| 4778 Visit(stmt->then_statement()); | 4776 Visit(stmt->then_statement()); |
| 4779 } else if (stmt->condition()->ToBooleanIsFalse()) { | 4777 } else if (stmt->condition()->ToBooleanIsFalse()) { |
| 4780 AddSimulate(stmt->ElseId()); | 4778 Add<HSimulate>(stmt->ElseId()); |
| 4781 Visit(stmt->else_statement()); | 4779 Visit(stmt->else_statement()); |
| 4782 } else { | 4780 } else { |
| 4783 HBasicBlock* cond_true = graph()->CreateBasicBlock(); | 4781 HBasicBlock* cond_true = graph()->CreateBasicBlock(); |
| 4784 HBasicBlock* cond_false = graph()->CreateBasicBlock(); | 4782 HBasicBlock* cond_false = graph()->CreateBasicBlock(); |
| 4785 CHECK_BAILOUT(VisitForControl(stmt->condition(), cond_true, cond_false)); | 4783 CHECK_BAILOUT(VisitForControl(stmt->condition(), cond_true, cond_false)); |
| 4786 | 4784 |
| 4787 if (cond_true->HasPredecessor()) { | 4785 if (cond_true->HasPredecessor()) { |
| 4788 cond_true->SetJoinId(stmt->ThenId()); | 4786 cond_true->SetJoinId(stmt->ThenId()); |
| 4789 set_current_block(cond_true); | 4787 set_current_block(cond_true); |
| 4790 CHECK_BAILOUT(Visit(stmt->then_statement())); | 4788 CHECK_BAILOUT(Visit(stmt->then_statement())); |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4877 void HOptimizedGraphBuilder::VisitReturnStatement(ReturnStatement* stmt) { | 4875 void HOptimizedGraphBuilder::VisitReturnStatement(ReturnStatement* stmt) { |
| 4878 ASSERT(!HasStackOverflow()); | 4876 ASSERT(!HasStackOverflow()); |
| 4879 ASSERT(current_block() != NULL); | 4877 ASSERT(current_block() != NULL); |
| 4880 ASSERT(current_block()->HasPredecessor()); | 4878 ASSERT(current_block()->HasPredecessor()); |
| 4881 FunctionState* state = function_state(); | 4879 FunctionState* state = function_state(); |
| 4882 AstContext* context = call_context(); | 4880 AstContext* context = call_context(); |
| 4883 if (context == NULL) { | 4881 if (context == NULL) { |
| 4884 // Not an inlined return, so an actual one. | 4882 // Not an inlined return, so an actual one. |
| 4885 CHECK_ALIVE(VisitForValue(stmt->expression())); | 4883 CHECK_ALIVE(VisitForValue(stmt->expression())); |
| 4886 HValue* result = environment()->Pop(); | 4884 HValue* result = environment()->Pop(); |
| 4887 AddReturn(result); | 4885 Add<HReturn>(result); |
| 4888 } else if (state->inlining_kind() == CONSTRUCT_CALL_RETURN) { | 4886 } else if (state->inlining_kind() == CONSTRUCT_CALL_RETURN) { |
| 4889 // Return from an inlined construct call. In a test context the return value | 4887 // Return from an inlined construct call. In a test context the return value |
| 4890 // will always evaluate to true, in a value context the return value needs | 4888 // will always evaluate to true, in a value context the return value needs |
| 4891 // to be a JSObject. | 4889 // to be a JSObject. |
| 4892 if (context->IsTest()) { | 4890 if (context->IsTest()) { |
| 4893 TestContext* test = TestContext::cast(context); | 4891 TestContext* test = TestContext::cast(context); |
| 4894 CHECK_ALIVE(VisitForEffect(stmt->expression())); | 4892 CHECK_ALIVE(VisitForEffect(stmt->expression())); |
| 4895 current_block()->Goto(test->if_true(), state); | 4893 current_block()->Goto(test->if_true(), state); |
| 4896 } else if (context->IsEffect()) { | 4894 } else if (context->IsEffect()) { |
| 4897 CHECK_ALIVE(VisitForEffect(stmt->expression())); | 4895 CHECK_ALIVE(VisitForEffect(stmt->expression())); |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4969 } | 4967 } |
| 4970 | 4968 |
| 4971 ASSERT(stmt->switch_type() != SwitchStatement::UNKNOWN_SWITCH); | 4969 ASSERT(stmt->switch_type() != SwitchStatement::UNKNOWN_SWITCH); |
| 4972 if (stmt->switch_type() == SwitchStatement::GENERIC_SWITCH) { | 4970 if (stmt->switch_type() == SwitchStatement::GENERIC_SWITCH) { |
| 4973 return Bailout("SwitchStatement: mixed or non-literal switch labels"); | 4971 return Bailout("SwitchStatement: mixed or non-literal switch labels"); |
| 4974 } | 4972 } |
| 4975 | 4973 |
| 4976 HValue* context = environment()->LookupContext(); | 4974 HValue* context = environment()->LookupContext(); |
| 4977 | 4975 |
| 4978 CHECK_ALIVE(VisitForValue(stmt->tag())); | 4976 CHECK_ALIVE(VisitForValue(stmt->tag())); |
| 4979 AddSimulate(stmt->EntryId()); | 4977 Add<HSimulate>(stmt->EntryId()); |
| 4980 HValue* tag_value = Pop(); | 4978 HValue* tag_value = Pop(); |
| 4981 HBasicBlock* first_test_block = current_block(); | 4979 HBasicBlock* first_test_block = current_block(); |
| 4982 | 4980 |
| 4983 HUnaryControlInstruction* string_check = NULL; | 4981 HUnaryControlInstruction* string_check = NULL; |
| 4984 HBasicBlock* not_string_block = NULL; | 4982 HBasicBlock* not_string_block = NULL; |
| 4985 | 4983 |
| 4986 // Test switch's tag value if all clauses are string literals | 4984 // Test switch's tag value if all clauses are string literals |
| 4987 if (stmt->switch_type() == SwitchStatement::STRING_SWITCH) { | 4985 if (stmt->switch_type() == SwitchStatement::STRING_SWITCH) { |
| 4988 string_check = new(zone()) HIsStringAndBranch(tag_value); | 4986 string_check = new(zone()) HIsStringAndBranch(tag_value); |
| 4989 first_test_block = graph()->CreateBasicBlock(); | 4987 first_test_block = graph()->CreateBasicBlock(); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 5009 CHECK_ALIVE(VisitForValue(clause->label())); | 5007 CHECK_ALIVE(VisitForValue(clause->label())); |
| 5010 HValue* label_value = Pop(); | 5008 HValue* label_value = Pop(); |
| 5011 | 5009 |
| 5012 HBasicBlock* next_test_block = graph()->CreateBasicBlock(); | 5010 HBasicBlock* next_test_block = graph()->CreateBasicBlock(); |
| 5013 HBasicBlock* body_block = graph()->CreateBasicBlock(); | 5011 HBasicBlock* body_block = graph()->CreateBasicBlock(); |
| 5014 | 5012 |
| 5015 HControlInstruction* compare; | 5013 HControlInstruction* compare; |
| 5016 | 5014 |
| 5017 if (stmt->switch_type() == SwitchStatement::SMI_SWITCH) { | 5015 if (stmt->switch_type() == SwitchStatement::SMI_SWITCH) { |
| 5018 if (!clause->compare_type()->Is(Type::Integer31())) { | 5016 if (!clause->compare_type()->Is(Type::Integer31())) { |
| 5019 AddSoftDeoptimize(); | 5017 Add<HDeoptimize>(Deoptimizer::SOFT); |
| 5020 } | 5018 } |
| 5021 | 5019 |
| 5022 HCompareIDAndBranch* compare_ = | 5020 HCompareIDAndBranch* compare_ = |
| 5023 new(zone()) HCompareIDAndBranch(tag_value, | 5021 new(zone()) HCompareIDAndBranch(tag_value, |
| 5024 label_value, | 5022 label_value, |
| 5025 Token::EQ_STRICT); | 5023 Token::EQ_STRICT); |
| 5026 compare_->set_observed_input_representation( | 5024 compare_->set_observed_input_representation( |
| 5027 Representation::Smi(), Representation::Smi()); | 5025 Representation::Smi(), Representation::Smi()); |
| 5028 compare = compare_; | 5026 compare = compare_; |
| 5029 } else { | 5027 } else { |
| (...skipping 29 matching lines...) Expand all Loading... |
| 5059 CaseClause* clause = clauses->at(i); | 5057 CaseClause* clause = clauses->at(i); |
| 5060 | 5058 |
| 5061 // Identify the block where normal (non-fall-through) control flow | 5059 // Identify the block where normal (non-fall-through) control flow |
| 5062 // goes to. | 5060 // goes to. |
| 5063 HBasicBlock* normal_block = NULL; | 5061 HBasicBlock* normal_block = NULL; |
| 5064 if (clause->is_default()) { | 5062 if (clause->is_default()) { |
| 5065 if (last_block != NULL) { | 5063 if (last_block != NULL) { |
| 5066 normal_block = last_block; | 5064 normal_block = last_block; |
| 5067 last_block = NULL; // Cleared to indicate we've handled it. | 5065 last_block = NULL; // Cleared to indicate we've handled it. |
| 5068 } | 5066 } |
| 5069 } else if (!curr_test_block->end()->IsDeoptimize()) { | 5067 } else { |
| 5070 normal_block = curr_test_block->end()->FirstSuccessor(); | 5068 normal_block = curr_test_block->end()->FirstSuccessor(); |
| 5071 curr_test_block = curr_test_block->end()->SecondSuccessor(); | 5069 curr_test_block = curr_test_block->end()->SecondSuccessor(); |
| 5072 } | 5070 } |
| 5073 | 5071 |
| 5074 // Identify a block to emit the body into. | 5072 // Identify a block to emit the body into. |
| 5075 if (normal_block == NULL) { | 5073 if (normal_block == NULL) { |
| 5076 if (fall_through_block == NULL) { | 5074 if (fall_through_block == NULL) { |
| 5077 // (a) Unreachable. | 5075 // (a) Unreachable. |
| 5078 if (clause->is_default()) { | 5076 if (clause->is_default()) { |
| 5079 continue; // Might still be reachable clause bodies. | 5077 continue; // Might still be reachable clause bodies. |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5153 for (int i = first_expression_index; i < length; ++i) { | 5151 for (int i = first_expression_index; i < length; ++i) { |
| 5154 HUnknownOSRValue* osr_value = new(zone()) HUnknownOSRValue; | 5152 HUnknownOSRValue* osr_value = new(zone()) HUnknownOSRValue; |
| 5155 AddInstruction(osr_value); | 5153 AddInstruction(osr_value); |
| 5156 environment()->Push(osr_value); | 5154 environment()->Push(osr_value); |
| 5157 osr_values->Add(osr_value, zone()); | 5155 osr_values->Add(osr_value, zone()); |
| 5158 } | 5156 } |
| 5159 } | 5157 } |
| 5160 | 5158 |
| 5161 graph()->set_osr_values(osr_values); | 5159 graph()->set_osr_values(osr_values); |
| 5162 | 5160 |
| 5163 AddSimulate(osr_entry_id); | 5161 Add<HSimulate>(osr_entry_id); |
| 5164 AddInstruction(new(zone()) HOsrEntry(osr_entry_id)); | 5162 AddInstruction(new(zone()) HOsrEntry(osr_entry_id)); |
| 5165 HContext* context = new(zone()) HContext; | 5163 HContext* context = new(zone()) HContext; |
| 5166 AddInstruction(context); | 5164 AddInstruction(context); |
| 5167 environment()->BindContext(context); | 5165 environment()->BindContext(context); |
| 5168 current_block()->Goto(loop_predecessor); | 5166 current_block()->Goto(loop_predecessor); |
| 5169 loop_predecessor->SetJoinId(statement->EntryId()); | 5167 loop_predecessor->SetJoinId(statement->EntryId()); |
| 5170 set_current_block(loop_predecessor); | 5168 set_current_block(loop_predecessor); |
| 5171 return true; | 5169 return true; |
| 5172 } | 5170 } |
| 5173 | 5171 |
| 5174 | 5172 |
| 5175 void HOptimizedGraphBuilder::VisitLoopBody(IterationStatement* stmt, | 5173 void HOptimizedGraphBuilder::VisitLoopBody(IterationStatement* stmt, |
| 5176 HBasicBlock* loop_entry, | 5174 HBasicBlock* loop_entry, |
| 5177 BreakAndContinueInfo* break_info) { | 5175 BreakAndContinueInfo* break_info) { |
| 5178 BreakAndContinueScope push(break_info, this); | 5176 BreakAndContinueScope push(break_info, this); |
| 5179 AddSimulate(stmt->StackCheckId()); | 5177 Add<HSimulate>(stmt->StackCheckId()); |
| 5180 HValue* context = environment()->LookupContext(); | 5178 HValue* context = environment()->LookupContext(); |
| 5181 HStackCheck* stack_check = | 5179 HStackCheck* stack_check = |
| 5182 new(zone()) HStackCheck(context, HStackCheck::kBackwardsBranch); | 5180 new(zone()) HStackCheck(context, HStackCheck::kBackwardsBranch); |
| 5183 AddInstruction(stack_check); | 5181 AddInstruction(stack_check); |
| 5184 ASSERT(loop_entry->IsLoopHeader()); | 5182 ASSERT(loop_entry->IsLoopHeader()); |
| 5185 loop_entry->loop_information()->set_stack_check(stack_check); | 5183 loop_entry->loop_information()->set_stack_check(stack_check); |
| 5186 CHECK_BAILOUT(Visit(stmt->body())); | 5184 CHECK_BAILOUT(Visit(stmt->body())); |
| 5187 } | 5185 } |
| 5188 | 5186 |
| 5189 | 5187 |
| (...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5344 return Bailout("ForInStatement with non-local each variable"); | 5342 return Bailout("ForInStatement with non-local each variable"); |
| 5345 } | 5343 } |
| 5346 | 5344 |
| 5347 Variable* each_var = stmt->each()->AsVariableProxy()->var(); | 5345 Variable* each_var = stmt->each()->AsVariableProxy()->var(); |
| 5348 | 5346 |
| 5349 CHECK_ALIVE(VisitForValue(stmt->enumerable())); | 5347 CHECK_ALIVE(VisitForValue(stmt->enumerable())); |
| 5350 HValue* enumerable = Top(); // Leave enumerable at the top. | 5348 HValue* enumerable = Top(); // Leave enumerable at the top. |
| 5351 | 5349 |
| 5352 HInstruction* map = AddInstruction(new(zone()) HForInPrepareMap( | 5350 HInstruction* map = AddInstruction(new(zone()) HForInPrepareMap( |
| 5353 environment()->LookupContext(), enumerable)); | 5351 environment()->LookupContext(), enumerable)); |
| 5354 AddSimulate(stmt->PrepareId()); | 5352 Add<HSimulate>(stmt->PrepareId()); |
| 5355 | 5353 |
| 5356 HInstruction* array = AddInstruction( | 5354 HInstruction* array = AddInstruction( |
| 5357 new(zone()) HForInCacheArray( | 5355 new(zone()) HForInCacheArray( |
| 5358 enumerable, | 5356 enumerable, |
| 5359 map, | 5357 map, |
| 5360 DescriptorArray::kEnumCacheBridgeCacheIndex)); | 5358 DescriptorArray::kEnumCacheBridgeCacheIndex)); |
| 5361 | 5359 |
| 5362 HInstruction* enum_length = AddInstruction(new(zone()) HMapEnumLength(map)); | 5360 HInstruction* enum_length = AddInstruction(new(zone()) HMapEnumLength(map)); |
| 5363 | 5361 |
| 5364 HInstruction* start_index = AddInstruction(new(zone()) HConstant(0)); | 5362 HInstruction* start_index = AddInstruction(new(zone()) HConstant(0)); |
| (...skipping 583 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5948 Handle<JSObject> holder; | 5946 Handle<JSObject> holder; |
| 5949 ASSERT(!LookupSetter(map, name, &setter, &holder)); | 5947 ASSERT(!LookupSetter(map, name, &setter, &holder)); |
| 5950 #endif | 5948 #endif |
| 5951 CHECK_ALIVE(store = BuildStoreNamedMonomorphic(literal, | 5949 CHECK_ALIVE(store = BuildStoreNamedMonomorphic(literal, |
| 5952 name, | 5950 name, |
| 5953 value, | 5951 value, |
| 5954 map)); | 5952 map)); |
| 5955 } | 5953 } |
| 5956 AddInstruction(store); | 5954 AddInstruction(store); |
| 5957 if (store->HasObservableSideEffects()) { | 5955 if (store->HasObservableSideEffects()) { |
| 5958 AddSimulate(key->id(), REMOVABLE_SIMULATE); | 5956 Add<HSimulate>(key->id(), REMOVABLE_SIMULATE); |
| 5959 } | 5957 } |
| 5960 } else { | 5958 } else { |
| 5961 CHECK_ALIVE(VisitForEffect(value)); | 5959 CHECK_ALIVE(VisitForEffect(value)); |
| 5962 } | 5960 } |
| 5963 break; | 5961 break; |
| 5964 } | 5962 } |
| 5965 // Fall through. | 5963 // Fall through. |
| 5966 case ObjectLiteral::Property::PROTOTYPE: | 5964 case ObjectLiteral::Property::PROTOTYPE: |
| 5967 case ObjectLiteral::Property::SETTER: | 5965 case ObjectLiteral::Property::SETTER: |
| 5968 case ObjectLiteral::Property::GETTER: | 5966 case ObjectLiteral::Property::GETTER: |
| (...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6124 elements, | 6122 elements, |
| 6125 key, | 6123 key, |
| 6126 value, | 6124 value, |
| 6127 boilerplate_elements_kind)); | 6125 boilerplate_elements_kind)); |
| 6128 break; | 6126 break; |
| 6129 default: | 6127 default: |
| 6130 UNREACHABLE(); | 6128 UNREACHABLE(); |
| 6131 break; | 6129 break; |
| 6132 } | 6130 } |
| 6133 | 6131 |
| 6134 AddSimulate(expr->GetIdForElement(i)); | 6132 Add<HSimulate>(expr->GetIdForElement(i)); |
| 6135 } | 6133 } |
| 6136 | 6134 |
| 6137 Drop(1); // array literal index | 6135 Drop(1); // array literal index |
| 6138 return ast_context()->ReturnValue(Pop()); | 6136 return ast_context()->ReturnValue(Pop()); |
| 6139 } | 6137 } |
| 6140 | 6138 |
| 6141 | 6139 |
| 6142 // Sets the lookup result and returns true if the load/store can be inlined. | 6140 // Sets the lookup result and returns true if the load/store can be inlined. |
| 6143 static bool ComputeLoadStoreField(Handle<Map> type, | 6141 static bool ComputeLoadStoreField(Handle<Map> type, |
| 6144 Handle<String> name, | 6142 Handle<String> name, |
| (...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6428 BuildCheckNonSmi(object); | 6426 BuildCheckNonSmi(object); |
| 6429 AddInstruction(HCheckMaps::New(object, types, zone())); | 6427 AddInstruction(HCheckMaps::New(object, types, zone())); |
| 6430 HInstruction* store; | 6428 HInstruction* store; |
| 6431 CHECK_ALIVE_OR_RETURN( | 6429 CHECK_ALIVE_OR_RETURN( |
| 6432 store = BuildStoreNamedField( | 6430 store = BuildStoreNamedField( |
| 6433 object, name, value, types->at(count - 1), &lookup), | 6431 object, name, value, types->at(count - 1), &lookup), |
| 6434 true); | 6432 true); |
| 6435 Push(value); | 6433 Push(value); |
| 6436 store->set_position(position); | 6434 store->set_position(position); |
| 6437 AddInstruction(store); | 6435 AddInstruction(store); |
| 6438 AddSimulate(assignment_id); | 6436 Add<HSimulate>(assignment_id); |
| 6439 ast_context()->ReturnValue(Pop()); | 6437 ast_context()->ReturnValue(Pop()); |
| 6440 return true; | 6438 return true; |
| 6441 } | 6439 } |
| 6442 | 6440 |
| 6443 | 6441 |
| 6444 void HOptimizedGraphBuilder::HandlePolymorphicStoreNamedField( | 6442 void HOptimizedGraphBuilder::HandlePolymorphicStoreNamedField( |
| 6445 BailoutId id, | 6443 BailoutId id, |
| 6446 int position, | 6444 int position, |
| 6447 BailoutId assignment_id, | 6445 BailoutId assignment_id, |
| 6448 HValue* object, | 6446 HValue* object, |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6485 current_block()->Goto(join); | 6483 current_block()->Goto(join); |
| 6486 | 6484 |
| 6487 set_current_block(if_false); | 6485 set_current_block(if_false); |
| 6488 } | 6486 } |
| 6489 } | 6487 } |
| 6490 | 6488 |
| 6491 // Finish up. Unconditionally deoptimize if we've handled all the maps we | 6489 // Finish up. Unconditionally deoptimize if we've handled all the maps we |
| 6492 // know about and do not want to handle ones we've never seen. Otherwise | 6490 // know about and do not want to handle ones we've never seen. Otherwise |
| 6493 // use a generic IC. | 6491 // use a generic IC. |
| 6494 if (count == types->length() && FLAG_deoptimize_uncommon_cases) { | 6492 if (count == types->length() && FLAG_deoptimize_uncommon_cases) { |
| 6495 current_block()->FinishExitWithDeoptimization(HDeoptimize::kNoUses); | 6493 FinishExitWithHardDeoptimization(join); |
| 6496 } else { | 6494 } else { |
| 6497 HInstruction* instr = BuildStoreNamedGeneric(object, name, value); | 6495 HInstruction* instr = BuildStoreNamedGeneric(object, name, value); |
| 6498 instr->set_position(position); | 6496 instr->set_position(position); |
| 6499 AddInstruction(instr); | 6497 AddInstruction(instr); |
| 6500 | 6498 |
| 6501 if (join != NULL) { | 6499 if (join != NULL) { |
| 6502 if (!ast_context()->IsEffect()) Push(value); | 6500 if (!ast_context()->IsEffect()) Push(value); |
| 6503 current_block()->Goto(join); | 6501 current_block()->Goto(join); |
| 6504 } else { | 6502 } else { |
| 6505 // The HSimulate for the store should not see the stored value in | 6503 // The HSimulate for the store should not see the stored value in |
| 6506 // effect contexts (it is not materialized at expr->id() in the | 6504 // effect contexts (it is not materialized at expr->id() in the |
| 6507 // unoptimized code). | 6505 // unoptimized code). |
| 6508 if (instr->HasObservableSideEffects()) { | 6506 if (instr->HasObservableSideEffects()) { |
| 6509 if (ast_context()->IsEffect()) { | 6507 if (ast_context()->IsEffect()) { |
| 6510 AddSimulate(id, REMOVABLE_SIMULATE); | 6508 Add<HSimulate>(id, REMOVABLE_SIMULATE); |
| 6511 } else { | 6509 } else { |
| 6512 Push(value); | 6510 Push(value); |
| 6513 AddSimulate(id, REMOVABLE_SIMULATE); | 6511 Add<HSimulate>(id, REMOVABLE_SIMULATE); |
| 6514 Drop(1); | 6512 Drop(1); |
| 6515 } | 6513 } |
| 6516 } | 6514 } |
| 6517 return ast_context()->ReturnValue(value); | 6515 return ast_context()->ReturnValue(value); |
| 6518 } | 6516 } |
| 6519 } | 6517 } |
| 6520 | 6518 |
| 6521 ASSERT(join != NULL); | 6519 ASSERT(join != NULL); |
| 6522 join->SetJoinId(id); | 6520 join->SetJoinId(id); |
| 6523 set_current_block(join); | 6521 set_current_block(join); |
| (...skipping 21 matching lines...) Expand all Loading... |
| 6545 HValue* value = environment()->ExpressionStackAt(0); | 6543 HValue* value = environment()->ExpressionStackAt(0); |
| 6546 HValue* key = environment()->ExpressionStackAt(1); | 6544 HValue* key = environment()->ExpressionStackAt(1); |
| 6547 HValue* object = environment()->ExpressionStackAt(2); | 6545 HValue* object = environment()->ExpressionStackAt(2); |
| 6548 bool has_side_effects = false; | 6546 bool has_side_effects = false; |
| 6549 HandleKeyedElementAccess(object, key, value, expr, expr->AssignmentId(), | 6547 HandleKeyedElementAccess(object, key, value, expr, expr->AssignmentId(), |
| 6550 expr->position(), | 6548 expr->position(), |
| 6551 true, // is_store | 6549 true, // is_store |
| 6552 &has_side_effects); | 6550 &has_side_effects); |
| 6553 Drop(3); | 6551 Drop(3); |
| 6554 Push(value); | 6552 Push(value); |
| 6555 AddSimulate(expr->AssignmentId(), REMOVABLE_SIMULATE); | 6553 Add<HSimulate>(expr->AssignmentId(), REMOVABLE_SIMULATE); |
| 6556 return ast_context()->ReturnValue(Pop()); | 6554 return ast_context()->ReturnValue(Pop()); |
| 6557 } | 6555 } |
| 6558 } | 6556 } |
| 6559 | 6557 |
| 6560 | 6558 |
| 6561 // Because not every expression has a position and there is not common | 6559 // Because not every expression has a position and there is not common |
| 6562 // superclass of Assignment and CountOperation, we cannot just pass the | 6560 // superclass of Assignment and CountOperation, we cannot just pass the |
| 6563 // owning expression instead of position and ast_id separately. | 6561 // owning expression instead of position and ast_id separately. |
| 6564 void HOptimizedGraphBuilder::HandleGlobalVariableAssignment( | 6562 void HOptimizedGraphBuilder::HandleGlobalVariableAssignment( |
| 6565 Variable* var, | 6563 Variable* var, |
| 6566 HValue* value, | 6564 HValue* value, |
| 6567 int position, | 6565 int position, |
| 6568 BailoutId ast_id) { | 6566 BailoutId ast_id) { |
| 6569 LookupResult lookup(isolate()); | 6567 LookupResult lookup(isolate()); |
| 6570 GlobalPropertyAccess type = LookupGlobalProperty(var, &lookup, true); | 6568 GlobalPropertyAccess type = LookupGlobalProperty(var, &lookup, true); |
| 6571 if (type == kUseCell) { | 6569 if (type == kUseCell) { |
| 6572 Handle<GlobalObject> global(current_info()->global_object()); | 6570 Handle<GlobalObject> global(current_info()->global_object()); |
| 6573 Handle<PropertyCell> cell(global->GetPropertyCell(&lookup)); | 6571 Handle<PropertyCell> cell(global->GetPropertyCell(&lookup)); |
| 6574 HInstruction* instr = | 6572 HInstruction* instr = |
| 6575 new(zone()) HStoreGlobalCell(value, cell, lookup.GetPropertyDetails()); | 6573 new(zone()) HStoreGlobalCell(value, cell, lookup.GetPropertyDetails()); |
| 6576 instr->set_position(position); | 6574 instr->set_position(position); |
| 6577 AddInstruction(instr); | 6575 AddInstruction(instr); |
| 6578 if (instr->HasObservableSideEffects()) { | 6576 if (instr->HasObservableSideEffects()) { |
| 6579 AddSimulate(ast_id, REMOVABLE_SIMULATE); | 6577 Add<HSimulate>(ast_id, REMOVABLE_SIMULATE); |
| 6580 } | 6578 } |
| 6581 } else { | 6579 } else { |
| 6582 HValue* context = environment()->LookupContext(); | 6580 HValue* context = environment()->LookupContext(); |
| 6583 HGlobalObject* global_object = new(zone()) HGlobalObject(context); | 6581 HGlobalObject* global_object = new(zone()) HGlobalObject(context); |
| 6584 AddInstruction(global_object); | 6582 AddInstruction(global_object); |
| 6585 HStoreGlobalGeneric* instr = | 6583 HStoreGlobalGeneric* instr = |
| 6586 new(zone()) HStoreGlobalGeneric(context, | 6584 new(zone()) HStoreGlobalGeneric(context, |
| 6587 global_object, | 6585 global_object, |
| 6588 var->name(), | 6586 var->name(), |
| 6589 value, | 6587 value, |
| 6590 function_strict_mode_flag()); | 6588 function_strict_mode_flag()); |
| 6591 instr->set_position(position); | 6589 instr->set_position(position); |
| 6592 AddInstruction(instr); | 6590 AddInstruction(instr); |
| 6593 ASSERT(instr->HasObservableSideEffects()); | 6591 ASSERT(instr->HasObservableSideEffects()); |
| 6594 AddSimulate(ast_id, REMOVABLE_SIMULATE); | 6592 Add<HSimulate>(ast_id, REMOVABLE_SIMULATE); |
| 6595 } | 6593 } |
| 6596 } | 6594 } |
| 6597 | 6595 |
| 6598 | 6596 |
| 6599 void HOptimizedGraphBuilder::BuildStoreNamed(Expression* expr, | 6597 void HOptimizedGraphBuilder::BuildStoreNamed(Expression* expr, |
| 6600 BailoutId id, | 6598 BailoutId id, |
| 6601 int position, | 6599 int position, |
| 6602 BailoutId assignment_id, | 6600 BailoutId assignment_id, |
| 6603 Property* prop, | 6601 Property* prop, |
| 6604 HValue* object, | 6602 HValue* object, |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6642 id, position, assignment_id, object, value, types, name); | 6640 id, position, assignment_id, object, value, types, name); |
| 6643 } else { | 6641 } else { |
| 6644 Drop(2); | 6642 Drop(2); |
| 6645 instr = BuildStoreNamedGeneric(object, name, value); | 6643 instr = BuildStoreNamedGeneric(object, name, value); |
| 6646 } | 6644 } |
| 6647 | 6645 |
| 6648 Push(value); | 6646 Push(value); |
| 6649 instr->set_position(position); | 6647 instr->set_position(position); |
| 6650 AddInstruction(instr); | 6648 AddInstruction(instr); |
| 6651 if (instr->HasObservableSideEffects()) { | 6649 if (instr->HasObservableSideEffects()) { |
| 6652 AddSimulate(assignment_id, REMOVABLE_SIMULATE); | 6650 Add<HSimulate>(assignment_id, REMOVABLE_SIMULATE); |
| 6653 } | 6651 } |
| 6654 return ast_context()->ReturnValue(Pop()); | 6652 return ast_context()->ReturnValue(Pop()); |
| 6655 } | 6653 } |
| 6656 | 6654 |
| 6657 | 6655 |
| 6658 void HOptimizedGraphBuilder::HandleCompoundAssignment(Assignment* expr) { | 6656 void HOptimizedGraphBuilder::HandleCompoundAssignment(Assignment* expr) { |
| 6659 Expression* target = expr->target(); | 6657 Expression* target = expr->target(); |
| 6660 VariableProxy* proxy = target->AsVariableProxy(); | 6658 VariableProxy* proxy = target->AsVariableProxy(); |
| 6661 Property* prop = target->AsProperty(); | 6659 Property* prop = target->AsProperty(); |
| 6662 ASSERT(proxy == NULL || prop == NULL); | 6660 ASSERT(proxy == NULL || prop == NULL); |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6720 UNREACHABLE(); | 6718 UNREACHABLE(); |
| 6721 default: | 6719 default: |
| 6722 mode = HStoreContextSlot::kNoCheck; | 6720 mode = HStoreContextSlot::kNoCheck; |
| 6723 } | 6721 } |
| 6724 | 6722 |
| 6725 HValue* context = BuildContextChainWalk(var); | 6723 HValue* context = BuildContextChainWalk(var); |
| 6726 HStoreContextSlot* instr = | 6724 HStoreContextSlot* instr = |
| 6727 new(zone()) HStoreContextSlot(context, var->index(), mode, Top()); | 6725 new(zone()) HStoreContextSlot(context, var->index(), mode, Top()); |
| 6728 AddInstruction(instr); | 6726 AddInstruction(instr); |
| 6729 if (instr->HasObservableSideEffects()) { | 6727 if (instr->HasObservableSideEffects()) { |
| 6730 AddSimulate(expr->AssignmentId(), REMOVABLE_SIMULATE); | 6728 Add<HSimulate>(expr->AssignmentId(), REMOVABLE_SIMULATE); |
| 6731 } | 6729 } |
| 6732 break; | 6730 break; |
| 6733 } | 6731 } |
| 6734 | 6732 |
| 6735 case Variable::LOOKUP: | 6733 case Variable::LOOKUP: |
| 6736 return Bailout("compound assignment to lookup slot"); | 6734 return Bailout("compound assignment to lookup slot"); |
| 6737 } | 6735 } |
| 6738 return ast_context()->ReturnValue(Pop()); | 6736 return ast_context()->ReturnValue(Pop()); |
| 6739 | 6737 |
| 6740 } else if (prop != NULL) { | 6738 } else if (prop != NULL) { |
| (...skipping 20 matching lines...) Expand all Loading... |
| 6761 load = BuildCallGetter(object, map, getter, holder); | 6759 load = BuildCallGetter(object, map, getter, holder); |
| 6762 } else { | 6760 } else { |
| 6763 load = BuildLoadNamedMonomorphic(object, name, prop, map); | 6761 load = BuildLoadNamedMonomorphic(object, name, prop, map); |
| 6764 } | 6762 } |
| 6765 } else if (types != NULL && types->length() > 1) { | 6763 } else if (types != NULL && types->length() > 1) { |
| 6766 load = TryLoadPolymorphicAsMonomorphic(prop, object, types, name); | 6764 load = TryLoadPolymorphicAsMonomorphic(prop, object, types, name); |
| 6767 } | 6765 } |
| 6768 if (load == NULL) load = BuildLoadNamedGeneric(object, name, prop); | 6766 if (load == NULL) load = BuildLoadNamedGeneric(object, name, prop); |
| 6769 PushAndAdd(load); | 6767 PushAndAdd(load); |
| 6770 if (load->HasObservableSideEffects()) { | 6768 if (load->HasObservableSideEffects()) { |
| 6771 AddSimulate(prop->LoadId(), REMOVABLE_SIMULATE); | 6769 Add<HSimulate>(prop->LoadId(), REMOVABLE_SIMULATE); |
| 6772 } | 6770 } |
| 6773 | 6771 |
| 6774 CHECK_ALIVE(VisitForValue(expr->value())); | 6772 CHECK_ALIVE(VisitForValue(expr->value())); |
| 6775 HValue* right = Pop(); | 6773 HValue* right = Pop(); |
| 6776 HValue* left = Pop(); | 6774 HValue* left = Pop(); |
| 6777 | 6775 |
| 6778 HInstruction* instr = BuildBinaryOperation(operation, left, right); | 6776 HInstruction* instr = BuildBinaryOperation(operation, left, right); |
| 6779 PushAndAdd(instr); | 6777 PushAndAdd(instr); |
| 6780 if (instr->HasObservableSideEffects()) { | 6778 if (instr->HasObservableSideEffects()) { |
| 6781 AddSimulate(operation->id(), REMOVABLE_SIMULATE); | 6779 Add<HSimulate>(operation->id(), REMOVABLE_SIMULATE); |
| 6782 } | 6780 } |
| 6783 | 6781 |
| 6784 return BuildStoreNamed(prop, expr->id(), expr->position(), | 6782 return BuildStoreNamed(prop, expr->id(), expr->position(), |
| 6785 expr->AssignmentId(), prop, object, instr); | 6783 expr->AssignmentId(), prop, object, instr); |
| 6786 } else { | 6784 } else { |
| 6787 // Keyed property. | 6785 // Keyed property. |
| 6788 CHECK_ALIVE(VisitForValue(prop->obj())); | 6786 CHECK_ALIVE(VisitForValue(prop->obj())); |
| 6789 CHECK_ALIVE(VisitForValue(prop->key())); | 6787 CHECK_ALIVE(VisitForValue(prop->key())); |
| 6790 HValue* obj = environment()->ExpressionStackAt(1); | 6788 HValue* obj = environment()->ExpressionStackAt(1); |
| 6791 HValue* key = environment()->ExpressionStackAt(0); | 6789 HValue* key = environment()->ExpressionStackAt(0); |
| 6792 | 6790 |
| 6793 bool has_side_effects = false; | 6791 bool has_side_effects = false; |
| 6794 HValue* load = HandleKeyedElementAccess( | 6792 HValue* load = HandleKeyedElementAccess( |
| 6795 obj, key, NULL, prop, prop->LoadId(), RelocInfo::kNoPosition, | 6793 obj, key, NULL, prop, prop->LoadId(), RelocInfo::kNoPosition, |
| 6796 false, // is_store | 6794 false, // is_store |
| 6797 &has_side_effects); | 6795 &has_side_effects); |
| 6798 Push(load); | 6796 Push(load); |
| 6799 if (has_side_effects) AddSimulate(prop->LoadId(), REMOVABLE_SIMULATE); | 6797 if (has_side_effects) Add<HSimulate>(prop->LoadId(), REMOVABLE_SIMULATE); |
| 6800 | 6798 |
| 6801 CHECK_ALIVE(VisitForValue(expr->value())); | 6799 CHECK_ALIVE(VisitForValue(expr->value())); |
| 6802 HValue* right = Pop(); | 6800 HValue* right = Pop(); |
| 6803 HValue* left = Pop(); | 6801 HValue* left = Pop(); |
| 6804 | 6802 |
| 6805 HInstruction* instr = BuildBinaryOperation(operation, left, right); | 6803 HInstruction* instr = BuildBinaryOperation(operation, left, right); |
| 6806 PushAndAdd(instr); | 6804 PushAndAdd(instr); |
| 6807 if (instr->HasObservableSideEffects()) { | 6805 if (instr->HasObservableSideEffects()) { |
| 6808 AddSimulate(operation->id(), REMOVABLE_SIMULATE); | 6806 Add<HSimulate>(operation->id(), REMOVABLE_SIMULATE); |
| 6809 } | 6807 } |
| 6810 | 6808 |
| 6811 HandleKeyedElementAccess(obj, key, instr, expr, expr->AssignmentId(), | 6809 HandleKeyedElementAccess(obj, key, instr, expr, expr->AssignmentId(), |
| 6812 RelocInfo::kNoPosition, | 6810 RelocInfo::kNoPosition, |
| 6813 true, // is_store | 6811 true, // is_store |
| 6814 &has_side_effects); | 6812 &has_side_effects); |
| 6815 | 6813 |
| 6816 // Drop the simulated receiver, key, and value. Return the value. | 6814 // Drop the simulated receiver, key, and value. Return the value. |
| 6817 Drop(3); | 6815 Drop(3); |
| 6818 Push(instr); | 6816 Push(instr); |
| 6819 ASSERT(has_side_effects); // Stores always have side effects. | 6817 ASSERT(has_side_effects); // Stores always have side effects. |
| 6820 AddSimulate(expr->AssignmentId(), REMOVABLE_SIMULATE); | 6818 Add<HSimulate>(expr->AssignmentId(), REMOVABLE_SIMULATE); |
| 6821 return ast_context()->ReturnValue(Pop()); | 6819 return ast_context()->ReturnValue(Pop()); |
| 6822 } | 6820 } |
| 6823 | 6821 |
| 6824 } else { | 6822 } else { |
| 6825 return Bailout("invalid lhs in compound assignment"); | 6823 return Bailout("invalid lhs in compound assignment"); |
| 6826 } | 6824 } |
| 6827 } | 6825 } |
| 6828 | 6826 |
| 6829 | 6827 |
| 6830 void HOptimizedGraphBuilder::VisitAssignment(Assignment* expr) { | 6828 void HOptimizedGraphBuilder::VisitAssignment(Assignment* expr) { |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6933 ASSERT(expr->op() == Token::INIT_CONST); | 6931 ASSERT(expr->op() == Token::INIT_CONST); |
| 6934 | 6932 |
| 6935 mode = HStoreContextSlot::kCheckIgnoreAssignment; | 6933 mode = HStoreContextSlot::kCheckIgnoreAssignment; |
| 6936 } | 6934 } |
| 6937 | 6935 |
| 6938 HValue* context = BuildContextChainWalk(var); | 6936 HValue* context = BuildContextChainWalk(var); |
| 6939 HStoreContextSlot* instr = new(zone()) HStoreContextSlot( | 6937 HStoreContextSlot* instr = new(zone()) HStoreContextSlot( |
| 6940 context, var->index(), mode, Top()); | 6938 context, var->index(), mode, Top()); |
| 6941 AddInstruction(instr); | 6939 AddInstruction(instr); |
| 6942 if (instr->HasObservableSideEffects()) { | 6940 if (instr->HasObservableSideEffects()) { |
| 6943 AddSimulate(expr->AssignmentId(), REMOVABLE_SIMULATE); | 6941 Add<HSimulate>(expr->AssignmentId(), REMOVABLE_SIMULATE); |
| 6944 } | 6942 } |
| 6945 return ast_context()->ReturnValue(Pop()); | 6943 return ast_context()->ReturnValue(Pop()); |
| 6946 } | 6944 } |
| 6947 | 6945 |
| 6948 case Variable::LOOKUP: | 6946 case Variable::LOOKUP: |
| 6949 return Bailout("assignment to LOOKUP variable"); | 6947 return Bailout("assignment to LOOKUP variable"); |
| 6950 } | 6948 } |
| 6951 } else { | 6949 } else { |
| 6952 return Bailout("invalid left-hand side in assignment"); | 6950 return Bailout("invalid left-hand side in assignment"); |
| 6953 } | 6951 } |
| (...skipping 14 matching lines...) Expand all Loading... |
| 6968 // assignments, count operations, or for-in. Consequently throw can | 6966 // assignments, count operations, or for-in. Consequently throw can |
| 6969 // currently only occur in an effect context. | 6967 // currently only occur in an effect context. |
| 6970 ASSERT(ast_context()->IsEffect()); | 6968 ASSERT(ast_context()->IsEffect()); |
| 6971 CHECK_ALIVE(VisitForValue(expr->exception())); | 6969 CHECK_ALIVE(VisitForValue(expr->exception())); |
| 6972 | 6970 |
| 6973 HValue* context = environment()->LookupContext(); | 6971 HValue* context = environment()->LookupContext(); |
| 6974 HValue* value = environment()->Pop(); | 6972 HValue* value = environment()->Pop(); |
| 6975 HThrow* instr = new(zone()) HThrow(context, value); | 6973 HThrow* instr = new(zone()) HThrow(context, value); |
| 6976 instr->set_position(expr->position()); | 6974 instr->set_position(expr->position()); |
| 6977 AddInstruction(instr); | 6975 AddInstruction(instr); |
| 6978 AddSimulate(expr->id()); | 6976 Add<HSimulate>(expr->id()); |
| 6979 current_block()->FinishExit(new(zone()) HAbnormalExit); | 6977 current_block()->FinishExit(new(zone()) HAbnormalExit); |
| 6980 set_current_block(NULL); | 6978 set_current_block(NULL); |
| 6981 } | 6979 } |
| 6982 | 6980 |
| 6983 | 6981 |
| 6984 HLoadNamedField* HGraphBuilder::BuildLoadNamedField( | 6982 HLoadNamedField* HGraphBuilder::BuildLoadNamedField( |
| 6985 HValue* object, | 6983 HValue* object, |
| 6986 HObjectAccess access, | 6984 HObjectAccess access, |
| 6987 Representation representation) { | 6985 Representation representation) { |
| 6988 bool load_double = false; | 6986 bool load_double = false; |
| (...skipping 11 matching lines...) Expand all Loading... |
| 7000 } | 6998 } |
| 7001 return field; | 6999 return field; |
| 7002 } | 7000 } |
| 7003 | 7001 |
| 7004 | 7002 |
| 7005 HInstruction* HOptimizedGraphBuilder::BuildLoadNamedGeneric( | 7003 HInstruction* HOptimizedGraphBuilder::BuildLoadNamedGeneric( |
| 7006 HValue* object, | 7004 HValue* object, |
| 7007 Handle<String> name, | 7005 Handle<String> name, |
| 7008 Property* expr) { | 7006 Property* expr) { |
| 7009 if (expr->IsUninitialized()) { | 7007 if (expr->IsUninitialized()) { |
| 7010 AddSoftDeoptimize(); | 7008 Add<HDeoptimize>(Deoptimizer::SOFT); |
| 7011 } else { | 7009 } else { |
| 7012 // OS::DebugBreak(); | 7010 // OS::DebugBreak(); |
| 7013 } | 7011 } |
| 7014 HValue* context = environment()->LookupContext(); | 7012 HValue* context = environment()->LookupContext(); |
| 7015 return new(zone()) HLoadNamedGeneric(context, object, name); | 7013 return new(zone()) HLoadNamedGeneric(context, object, name); |
| 7016 } | 7014 } |
| 7017 | 7015 |
| 7018 | 7016 |
| 7019 HInstruction* HOptimizedGraphBuilder::BuildCallGetter( | 7017 HInstruction* HOptimizedGraphBuilder::BuildCallGetter( |
| 7020 HValue* object, | 7018 HValue* object, |
| (...skipping 372 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7393 if (position != RelocInfo::kNoPosition) access->set_position(position); | 7391 if (position != RelocInfo::kNoPosition) access->set_position(position); |
| 7394 if (!is_store) { | 7392 if (!is_store) { |
| 7395 Push(access); | 7393 Push(access); |
| 7396 } | 7394 } |
| 7397 current_block()->GotoNoSimulate(join); | 7395 current_block()->GotoNoSimulate(join); |
| 7398 set_current_block(if_false); | 7396 set_current_block(if_false); |
| 7399 } | 7397 } |
| 7400 } | 7398 } |
| 7401 | 7399 |
| 7402 // Deopt if none of the cases matched. | 7400 // Deopt if none of the cases matched. |
| 7403 current_block()->FinishExitWithDeoptimization(HDeoptimize::kNoUses); | 7401 NoObservableSideEffectsScope scope(this); |
| 7402 FinishExitWithHardDeoptimization(join); |
| 7404 set_current_block(join); | 7403 set_current_block(join); |
| 7405 return is_store ? NULL : Pop(); | 7404 return is_store ? NULL : Pop(); |
| 7406 } | 7405 } |
| 7407 | 7406 |
| 7408 | 7407 |
| 7409 HValue* HOptimizedGraphBuilder::HandleKeyedElementAccess( | 7408 HValue* HOptimizedGraphBuilder::HandleKeyedElementAccess( |
| 7410 HValue* obj, | 7409 HValue* obj, |
| 7411 HValue* key, | 7410 HValue* key, |
| 7412 HValue* val, | 7411 HValue* val, |
| 7413 Expression* expr, | 7412 Expression* expr, |
| (...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7611 HValue* key = Pop(); | 7610 HValue* key = Pop(); |
| 7612 HValue* obj = Pop(); | 7611 HValue* obj = Pop(); |
| 7613 | 7612 |
| 7614 bool has_side_effects = false; | 7613 bool has_side_effects = false; |
| 7615 HValue* load = HandleKeyedElementAccess( | 7614 HValue* load = HandleKeyedElementAccess( |
| 7616 obj, key, NULL, expr, expr->id(), expr->position(), | 7615 obj, key, NULL, expr, expr->id(), expr->position(), |
| 7617 false, // is_store | 7616 false, // is_store |
| 7618 &has_side_effects); | 7617 &has_side_effects); |
| 7619 if (has_side_effects) { | 7618 if (has_side_effects) { |
| 7620 if (ast_context()->IsEffect()) { | 7619 if (ast_context()->IsEffect()) { |
| 7621 AddSimulate(expr->id(), REMOVABLE_SIMULATE); | 7620 Add<HSimulate>(expr->id(), REMOVABLE_SIMULATE); |
| 7622 } else { | 7621 } else { |
| 7623 Push(load); | 7622 Push(load); |
| 7624 AddSimulate(expr->id(), REMOVABLE_SIMULATE); | 7623 Add<HSimulate>(expr->id(), REMOVABLE_SIMULATE); |
| 7625 Drop(1); | 7624 Drop(1); |
| 7626 } | 7625 } |
| 7627 } | 7626 } |
| 7628 return ast_context()->ReturnValue(load); | 7627 return ast_context()->ReturnValue(load); |
| 7629 } | 7628 } |
| 7630 instr->set_position(expr->position()); | 7629 instr->set_position(expr->position()); |
| 7631 return ast_context()->ReturnInstruction(instr, expr->id()); | 7630 return ast_context()->ReturnInstruction(instr, expr->id()); |
| 7632 } | 7631 } |
| 7633 | 7632 |
| 7634 | 7633 |
| (...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7803 } | 7802 } |
| 7804 | 7803 |
| 7805 if (current_block() != NULL) current_block()->Goto(join); | 7804 if (current_block() != NULL) current_block()->Goto(join); |
| 7806 set_current_block(if_false); | 7805 set_current_block(if_false); |
| 7807 } | 7806 } |
| 7808 | 7807 |
| 7809 // Finish up. Unconditionally deoptimize if we've handled all the maps we | 7808 // Finish up. Unconditionally deoptimize if we've handled all the maps we |
| 7810 // know about and do not want to handle ones we've never seen. Otherwise | 7809 // know about and do not want to handle ones we've never seen. Otherwise |
| 7811 // use a generic IC. | 7810 // use a generic IC. |
| 7812 if (ordered_functions == types->length() && FLAG_deoptimize_uncommon_cases) { | 7811 if (ordered_functions == types->length() && FLAG_deoptimize_uncommon_cases) { |
| 7813 current_block()->FinishExitWithDeoptimization(HDeoptimize::kNoUses); | 7812 // Because the deopt may be the only path in the polymorphic call, make sure |
| 7813 // that the environment stack matches the depth on deopt that it otherwise |
| 7814 // would have had after a successful call. |
| 7815 Drop(argument_count - (ast_context()->IsEffect() ? 0 : 1)); |
| 7816 FinishExitWithHardDeoptimization(join); |
| 7814 } else { | 7817 } else { |
| 7815 HValue* context = environment()->LookupContext(); | 7818 HValue* context = environment()->LookupContext(); |
| 7816 HCallNamed* call = new(zone()) HCallNamed(context, name, argument_count); | 7819 HCallNamed* call = new(zone()) HCallNamed(context, name, argument_count); |
| 7817 call->set_position(expr->position()); | 7820 call->set_position(expr->position()); |
| 7818 PreProcessCall(call); | 7821 PreProcessCall(call); |
| 7819 | 7822 |
| 7820 if (join != NULL) { | 7823 if (join != NULL) { |
| 7821 AddInstruction(call); | 7824 AddInstruction(call); |
| 7822 if (!ast_context()->IsEffect()) Push(call); | 7825 if (!ast_context()->IsEffect()) Push(call); |
| 7823 current_block()->Goto(join); | 7826 current_block()->Goto(join); |
| (...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8063 // environment with the correct one. | 8066 // environment with the correct one. |
| 8064 // | 8067 // |
| 8065 // TODO(kmillikin): implement the same inlining on other platforms so we | 8068 // TODO(kmillikin): implement the same inlining on other platforms so we |
| 8066 // can remove the unsightly ifdefs in this function. | 8069 // can remove the unsightly ifdefs in this function. |
| 8067 HConstant* context = | 8070 HConstant* context = |
| 8068 new(zone()) HConstant(Handle<Context>(target->context())); | 8071 new(zone()) HConstant(Handle<Context>(target->context())); |
| 8069 AddInstruction(context); | 8072 AddInstruction(context); |
| 8070 inner_env->BindContext(context); | 8073 inner_env->BindContext(context); |
| 8071 #endif | 8074 #endif |
| 8072 | 8075 |
| 8073 AddSimulate(return_id); | 8076 Add<HSimulate>(return_id); |
| 8074 current_block()->UpdateEnvironment(inner_env); | 8077 current_block()->UpdateEnvironment(inner_env); |
| 8075 HArgumentsObject* arguments_object = NULL; | 8078 HArgumentsObject* arguments_object = NULL; |
| 8076 | 8079 |
| 8077 // If the function uses arguments object create and bind one, also copy | 8080 // If the function uses arguments object create and bind one, also copy |
| 8078 // current arguments values to use them for materialization. | 8081 // current arguments values to use them for materialization. |
| 8079 if (function->scope()->arguments() != NULL) { | 8082 if (function->scope()->arguments() != NULL) { |
| 8080 ASSERT(function->scope()->arguments()->IsStackAllocated()); | 8083 ASSERT(function->scope()->arguments()->IsStackAllocated()); |
| 8081 HEnvironment* arguments_env = inner_env->arguments_environment(); | 8084 HEnvironment* arguments_env = inner_env->arguments_environment(); |
| 8082 int arguments_count = arguments_env->parameter_count(); | 8085 int arguments_count = arguments_env->parameter_count(); |
| 8083 arguments_object = new(zone()) HArgumentsObject(arguments_count, zone()); | 8086 arguments_object = new(zone()) HArgumentsObject(arguments_count, zone()); |
| (...skipping 1018 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9102 | 9105 |
| 9103 void HOptimizedGraphBuilder::VisitSub(UnaryOperation* expr) { | 9106 void HOptimizedGraphBuilder::VisitSub(UnaryOperation* expr) { |
| 9104 CHECK_ALIVE(VisitForValue(expr->expression())); | 9107 CHECK_ALIVE(VisitForValue(expr->expression())); |
| 9105 HValue* value = Pop(); | 9108 HValue* value = Pop(); |
| 9106 HValue* context = environment()->LookupContext(); | 9109 HValue* context = environment()->LookupContext(); |
| 9107 HInstruction* instr = | 9110 HInstruction* instr = |
| 9108 HMul::New(zone(), context, value, graph()->GetConstantMinus1()); | 9111 HMul::New(zone(), context, value, graph()->GetConstantMinus1()); |
| 9109 Handle<Type> type = expr->type(); | 9112 Handle<Type> type = expr->type(); |
| 9110 Representation rep = ToRepresentation(type); | 9113 Representation rep = ToRepresentation(type); |
| 9111 if (type->Is(Type::None())) { | 9114 if (type->Is(Type::None())) { |
| 9112 AddSoftDeoptimize(); | 9115 Add<HDeoptimize>(Deoptimizer::SOFT); |
| 9113 type = handle(Type::Any(), isolate()); | 9116 type = handle(Type::Any(), isolate()); |
| 9114 } | 9117 } |
| 9115 if (instr->IsBinaryOperation()) { | 9118 if (instr->IsBinaryOperation()) { |
| 9116 HBinaryOperation::cast(instr)->set_observed_input_representation(1, rep); | 9119 HBinaryOperation::cast(instr)->set_observed_input_representation(1, rep); |
| 9117 HBinaryOperation::cast(instr)->set_observed_input_representation(2, rep); | 9120 HBinaryOperation::cast(instr)->set_observed_input_representation(2, rep); |
| 9118 } | 9121 } |
| 9119 return ast_context()->ReturnInstruction(instr, expr->id()); | 9122 return ast_context()->ReturnInstruction(instr, expr->id()); |
| 9120 } | 9123 } |
| 9121 | 9124 |
| 9122 | 9125 |
| 9123 void HOptimizedGraphBuilder::VisitBitNot(UnaryOperation* expr) { | 9126 void HOptimizedGraphBuilder::VisitBitNot(UnaryOperation* expr) { |
| 9124 CHECK_ALIVE(VisitForValue(expr->expression())); | 9127 CHECK_ALIVE(VisitForValue(expr->expression())); |
| 9125 HValue* value = Pop(); | 9128 HValue* value = Pop(); |
| 9126 Handle<Type> info = expr->type(); | 9129 Handle<Type> info = expr->type(); |
| 9127 if (info->Is(Type::None())) { | 9130 if (info->Is(Type::None())) { |
| 9128 AddSoftDeoptimize(); | 9131 Add<HDeoptimize>(Deoptimizer::SOFT); |
| 9129 } | 9132 } |
| 9130 HInstruction* instr = new(zone()) HBitNot(value); | 9133 HInstruction* instr = new(zone()) HBitNot(value); |
| 9131 return ast_context()->ReturnInstruction(instr, expr->id()); | 9134 return ast_context()->ReturnInstruction(instr, expr->id()); |
| 9132 } | 9135 } |
| 9133 | 9136 |
| 9134 | 9137 |
| 9135 void HOptimizedGraphBuilder::VisitNot(UnaryOperation* expr) { | 9138 void HOptimizedGraphBuilder::VisitNot(UnaryOperation* expr) { |
| 9136 if (ast_context()->IsTest()) { | 9139 if (ast_context()->IsTest()) { |
| 9137 TestContext* context = TestContext::cast(ast_context()); | 9140 TestContext* context = TestContext::cast(ast_context()); |
| 9138 VisitForControl(expr->expression(), | 9141 VisitForControl(expr->expression(), |
| (...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9275 } | 9278 } |
| 9276 } | 9279 } |
| 9277 | 9280 |
| 9278 HValue* context = BuildContextChainWalk(var); | 9281 HValue* context = BuildContextChainWalk(var); |
| 9279 HStoreContextSlot::Mode mode = IsLexicalVariableMode(var->mode()) | 9282 HStoreContextSlot::Mode mode = IsLexicalVariableMode(var->mode()) |
| 9280 ? HStoreContextSlot::kCheckDeoptimize : HStoreContextSlot::kNoCheck; | 9283 ? HStoreContextSlot::kCheckDeoptimize : HStoreContextSlot::kNoCheck; |
| 9281 HStoreContextSlot* instr = | 9284 HStoreContextSlot* instr = |
| 9282 new(zone()) HStoreContextSlot(context, var->index(), mode, after); | 9285 new(zone()) HStoreContextSlot(context, var->index(), mode, after); |
| 9283 AddInstruction(instr); | 9286 AddInstruction(instr); |
| 9284 if (instr->HasObservableSideEffects()) { | 9287 if (instr->HasObservableSideEffects()) { |
| 9285 AddSimulate(expr->AssignmentId(), REMOVABLE_SIMULATE); | 9288 Add<HSimulate>(expr->AssignmentId(), REMOVABLE_SIMULATE); |
| 9286 } | 9289 } |
| 9287 break; | 9290 break; |
| 9288 } | 9291 } |
| 9289 | 9292 |
| 9290 case Variable::LOOKUP: | 9293 case Variable::LOOKUP: |
| 9291 return Bailout("lookup variable in count operation"); | 9294 return Bailout("lookup variable in count operation"); |
| 9292 } | 9295 } |
| 9293 | 9296 |
| 9294 } else { | 9297 } else { |
| 9295 // Argument of the count operation is a property. | 9298 // Argument of the count operation is a property. |
| (...skipping 22 matching lines...) Expand all Loading... |
| 9318 load = BuildCallGetter(object, map, getter, holder); | 9321 load = BuildCallGetter(object, map, getter, holder); |
| 9319 } else { | 9322 } else { |
| 9320 load = BuildLoadNamedMonomorphic(object, name, prop, map); | 9323 load = BuildLoadNamedMonomorphic(object, name, prop, map); |
| 9321 } | 9324 } |
| 9322 } else if (types != NULL && types->length() > 1) { | 9325 } else if (types != NULL && types->length() > 1) { |
| 9323 load = TryLoadPolymorphicAsMonomorphic(prop, object, types, name); | 9326 load = TryLoadPolymorphicAsMonomorphic(prop, object, types, name); |
| 9324 } | 9327 } |
| 9325 if (load == NULL) load = BuildLoadNamedGeneric(object, name, prop); | 9328 if (load == NULL) load = BuildLoadNamedGeneric(object, name, prop); |
| 9326 PushAndAdd(load); | 9329 PushAndAdd(load); |
| 9327 if (load->HasObservableSideEffects()) { | 9330 if (load->HasObservableSideEffects()) { |
| 9328 AddSimulate(prop->LoadId(), REMOVABLE_SIMULATE); | 9331 Add<HSimulate>(prop->LoadId(), REMOVABLE_SIMULATE); |
| 9329 } | 9332 } |
| 9330 | 9333 |
| 9331 after = BuildIncrement(returns_original_input, expr); | 9334 after = BuildIncrement(returns_original_input, expr); |
| 9332 input = Pop(); | 9335 input = Pop(); |
| 9333 | 9336 |
| 9334 HInstruction* store; | 9337 HInstruction* store; |
| 9335 if (!monomorphic || map->is_observed()) { | 9338 if (!monomorphic || map->is_observed()) { |
| 9336 // If we don't know the monomorphic type, do a generic store. | 9339 // If we don't know the monomorphic type, do a generic store. |
| 9337 CHECK_ALIVE(store = BuildStoreNamedGeneric(object, name, after)); | 9340 CHECK_ALIVE(store = BuildStoreNamedGeneric(object, name, after)); |
| 9338 } else { | 9341 } else { |
| 9339 Handle<JSFunction> setter; | 9342 Handle<JSFunction> setter; |
| 9340 Handle<JSObject> holder; | 9343 Handle<JSObject> holder; |
| 9341 if (LookupSetter(map, name, &setter, &holder)) { | 9344 if (LookupSetter(map, name, &setter, &holder)) { |
| 9342 store = BuildCallSetter(object, after, map, setter, holder); | 9345 store = BuildCallSetter(object, after, map, setter, holder); |
| 9343 } else { | 9346 } else { |
| 9344 CHECK_ALIVE(store = BuildStoreNamedMonomorphic(object, | 9347 CHECK_ALIVE(store = BuildStoreNamedMonomorphic(object, |
| 9345 name, | 9348 name, |
| 9346 after, | 9349 after, |
| 9347 map)); | 9350 map)); |
| 9348 } | 9351 } |
| 9349 } | 9352 } |
| 9350 AddInstruction(store); | 9353 AddInstruction(store); |
| 9351 | 9354 |
| 9352 // Overwrite the receiver in the bailout environment with the result | 9355 // Overwrite the receiver in the bailout environment with the result |
| 9353 // of the operation, and the placeholder with the original value if | 9356 // of the operation, and the placeholder with the original value if |
| 9354 // necessary. | 9357 // necessary. |
| 9355 environment()->SetExpressionStackAt(0, after); | 9358 environment()->SetExpressionStackAt(0, after); |
| 9356 if (returns_original_input) environment()->SetExpressionStackAt(1, input); | 9359 if (returns_original_input) environment()->SetExpressionStackAt(1, input); |
| 9357 if (store->HasObservableSideEffects()) { | 9360 if (store->HasObservableSideEffects()) { |
| 9358 AddSimulate(expr->AssignmentId(), REMOVABLE_SIMULATE); | 9361 Add<HSimulate>(expr->AssignmentId(), REMOVABLE_SIMULATE); |
| 9359 } | 9362 } |
| 9360 | 9363 |
| 9361 } else { | 9364 } else { |
| 9362 // Keyed property. | 9365 // Keyed property. |
| 9363 if (returns_original_input) Push(graph()->GetConstantUndefined()); | 9366 if (returns_original_input) Push(graph()->GetConstantUndefined()); |
| 9364 | 9367 |
| 9365 CHECK_ALIVE(VisitForValue(prop->obj())); | 9368 CHECK_ALIVE(VisitForValue(prop->obj())); |
| 9366 CHECK_ALIVE(VisitForValue(prop->key())); | 9369 CHECK_ALIVE(VisitForValue(prop->key())); |
| 9367 HValue* obj = environment()->ExpressionStackAt(1); | 9370 HValue* obj = environment()->ExpressionStackAt(1); |
| 9368 HValue* key = environment()->ExpressionStackAt(0); | 9371 HValue* key = environment()->ExpressionStackAt(0); |
| 9369 | 9372 |
| 9370 bool has_side_effects = false; | 9373 bool has_side_effects = false; |
| 9371 HValue* load = HandleKeyedElementAccess( | 9374 HValue* load = HandleKeyedElementAccess( |
| 9372 obj, key, NULL, prop, prop->LoadId(), RelocInfo::kNoPosition, | 9375 obj, key, NULL, prop, prop->LoadId(), RelocInfo::kNoPosition, |
| 9373 false, // is_store | 9376 false, // is_store |
| 9374 &has_side_effects); | 9377 &has_side_effects); |
| 9375 Push(load); | 9378 Push(load); |
| 9376 if (has_side_effects) AddSimulate(prop->LoadId(), REMOVABLE_SIMULATE); | 9379 if (has_side_effects) Add<HSimulate>(prop->LoadId(), REMOVABLE_SIMULATE); |
| 9377 | 9380 |
| 9378 after = BuildIncrement(returns_original_input, expr); | 9381 after = BuildIncrement(returns_original_input, expr); |
| 9379 input = environment()->ExpressionStackAt(0); | 9382 input = environment()->ExpressionStackAt(0); |
| 9380 | 9383 |
| 9381 HandleKeyedElementAccess(obj, key, after, expr, expr->AssignmentId(), | 9384 HandleKeyedElementAccess(obj, key, after, expr, expr->AssignmentId(), |
| 9382 RelocInfo::kNoPosition, | 9385 RelocInfo::kNoPosition, |
| 9383 true, // is_store | 9386 true, // is_store |
| 9384 &has_side_effects); | 9387 &has_side_effects); |
| 9385 | 9388 |
| 9386 // Drop the key and the original value from the bailout environment. | 9389 // Drop the key and the original value from the bailout environment. |
| 9387 // Overwrite the receiver with the result of the operation, and the | 9390 // Overwrite the receiver with the result of the operation, and the |
| 9388 // placeholder with the original value if necessary. | 9391 // placeholder with the original value if necessary. |
| 9389 Drop(2); | 9392 Drop(2); |
| 9390 environment()->SetExpressionStackAt(0, after); | 9393 environment()->SetExpressionStackAt(0, after); |
| 9391 if (returns_original_input) environment()->SetExpressionStackAt(1, input); | 9394 if (returns_original_input) environment()->SetExpressionStackAt(1, input); |
| 9392 ASSERT(has_side_effects); // Stores always have side effects. | 9395 ASSERT(has_side_effects); // Stores always have side effects. |
| 9393 AddSimulate(expr->AssignmentId(), REMOVABLE_SIMULATE); | 9396 Add<HSimulate>(expr->AssignmentId(), REMOVABLE_SIMULATE); |
| 9394 } | 9397 } |
| 9395 } | 9398 } |
| 9396 | 9399 |
| 9397 Drop(returns_original_input ? 2 : 1); | 9400 Drop(returns_original_input ? 2 : 1); |
| 9398 return ast_context()->ReturnValue(expr->is_postfix() ? input : after); | 9401 return ast_context()->ReturnValue(expr->is_postfix() ? input : after); |
| 9399 } | 9402 } |
| 9400 | 9403 |
| 9401 | 9404 |
| 9402 HInstruction* HOptimizedGraphBuilder::BuildStringCharCodeAt( | 9405 HInstruction* HOptimizedGraphBuilder::BuildStringCharCodeAt( |
| 9403 HValue* context, | 9406 HValue* context, |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9488 HValue* context = environment()->LookupContext(); | 9491 HValue* context = environment()->LookupContext(); |
| 9489 Handle<Type> left_type = expr->left_type(); | 9492 Handle<Type> left_type = expr->left_type(); |
| 9490 Handle<Type> right_type = expr->right_type(); | 9493 Handle<Type> right_type = expr->right_type(); |
| 9491 Handle<Type> result_type = expr->result_type(); | 9494 Handle<Type> result_type = expr->result_type(); |
| 9492 bool has_fixed_right_arg = expr->has_fixed_right_arg(); | 9495 bool has_fixed_right_arg = expr->has_fixed_right_arg(); |
| 9493 int fixed_right_arg_value = expr->fixed_right_arg_value(); | 9496 int fixed_right_arg_value = expr->fixed_right_arg_value(); |
| 9494 Representation left_rep = ToRepresentation(left_type); | 9497 Representation left_rep = ToRepresentation(left_type); |
| 9495 Representation right_rep = ToRepresentation(right_type); | 9498 Representation right_rep = ToRepresentation(right_type); |
| 9496 Representation result_rep = ToRepresentation(result_type); | 9499 Representation result_rep = ToRepresentation(result_type); |
| 9497 if (left_type->Is(Type::None())) { | 9500 if (left_type->Is(Type::None())) { |
| 9498 AddSoftDeoptimize(); | 9501 Add<HDeoptimize>(Deoptimizer::SOFT); |
| 9499 left_type = handle(Type::Any(), isolate()); | 9502 left_type = handle(Type::Any(), isolate()); |
| 9500 } | 9503 } |
| 9501 if (right_type->Is(Type::None())) { | 9504 if (right_type->Is(Type::None())) { |
| 9502 AddSoftDeoptimize(); | 9505 Add<HDeoptimize>(Deoptimizer::SOFT); |
| 9503 right_type = handle(Type::Any(), isolate()); | 9506 right_type = handle(Type::Any(), isolate()); |
| 9504 } | 9507 } |
| 9505 HInstruction* instr = NULL; | 9508 HInstruction* instr = NULL; |
| 9506 switch (expr->op()) { | 9509 switch (expr->op()) { |
| 9507 case Token::ADD: | 9510 case Token::ADD: |
| 9508 if (left_type->Is(Type::String()) && right_type->Is(Type::String())) { | 9511 if (left_type->Is(Type::String()) && right_type->Is(Type::String())) { |
| 9509 BuildCheckNonSmi(left); | 9512 BuildCheckNonSmi(left); |
| 9510 AddInstruction(HCheckInstanceType::NewIsString(left, zone())); | 9513 AddInstruction(HCheckInstanceType::NewIsString(left, zone())); |
| 9511 BuildCheckNonSmi(right); | 9514 BuildCheckNonSmi(right); |
| 9512 AddInstruction(HCheckInstanceType::NewIsString(right, zone())); | 9515 AddInstruction(HCheckInstanceType::NewIsString(right, zone())); |
| (...skipping 287 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9800 | 9803 |
| 9801 Handle<Type> left_type = expr->left_type(); | 9804 Handle<Type> left_type = expr->left_type(); |
| 9802 Handle<Type> right_type = expr->right_type(); | 9805 Handle<Type> right_type = expr->right_type(); |
| 9803 Handle<Type> overall_type = expr->overall_type(); | 9806 Handle<Type> overall_type = expr->overall_type(); |
| 9804 Representation combined_rep = ToRepresentation(overall_type); | 9807 Representation combined_rep = ToRepresentation(overall_type); |
| 9805 Representation left_rep = ToRepresentation(left_type); | 9808 Representation left_rep = ToRepresentation(left_type); |
| 9806 Representation right_rep = ToRepresentation(right_type); | 9809 Representation right_rep = ToRepresentation(right_type); |
| 9807 // Check if this expression was ever executed according to type feedback. | 9810 // Check if this expression was ever executed according to type feedback. |
| 9808 // Note that for the special typeof/null/undefined cases we get unknown here. | 9811 // Note that for the special typeof/null/undefined cases we get unknown here. |
| 9809 if (overall_type->Is(Type::None())) { | 9812 if (overall_type->Is(Type::None())) { |
| 9810 AddSoftDeoptimize(); | 9813 Add<HDeoptimize>(Deoptimizer::SOFT); |
| 9811 overall_type = left_type = right_type = handle(Type::Any(), isolate()); | 9814 overall_type = left_type = right_type = handle(Type::Any(), isolate()); |
| 9812 } | 9815 } |
| 9813 | 9816 |
| 9814 CHECK_ALIVE(VisitForValue(expr->left())); | 9817 CHECK_ALIVE(VisitForValue(expr->left())); |
| 9815 CHECK_ALIVE(VisitForValue(expr->right())); | 9818 CHECK_ALIVE(VisitForValue(expr->right())); |
| 9816 | 9819 |
| 9817 HValue* context = environment()->LookupContext(); | 9820 HValue* context = environment()->LookupContext(); |
| 9818 HValue* right = Pop(); | 9821 HValue* right = Pop(); |
| 9819 HValue* left = Pop(); | 9822 HValue* left = Pop(); |
| 9820 Token::Value op = expr->op(); | 9823 Token::Value op = expr->op(); |
| (...skipping 489 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10310 } | 10313 } |
| 10311 break; | 10314 break; |
| 10312 case Variable::CONTEXT: | 10315 case Variable::CONTEXT: |
| 10313 if (hole_init) { | 10316 if (hole_init) { |
| 10314 HValue* value = graph()->GetConstantHole(); | 10317 HValue* value = graph()->GetConstantHole(); |
| 10315 HValue* context = environment()->LookupContext(); | 10318 HValue* context = environment()->LookupContext(); |
| 10316 HStoreContextSlot* store = new(zone()) HStoreContextSlot( | 10319 HStoreContextSlot* store = new(zone()) HStoreContextSlot( |
| 10317 context, variable->index(), HStoreContextSlot::kNoCheck, value); | 10320 context, variable->index(), HStoreContextSlot::kNoCheck, value); |
| 10318 AddInstruction(store); | 10321 AddInstruction(store); |
| 10319 if (store->HasObservableSideEffects()) { | 10322 if (store->HasObservableSideEffects()) { |
| 10320 AddSimulate(proxy->id(), REMOVABLE_SIMULATE); | 10323 Add<HSimulate>(proxy->id(), REMOVABLE_SIMULATE); |
| 10321 } | 10324 } |
| 10322 } | 10325 } |
| 10323 break; | 10326 break; |
| 10324 case Variable::LOOKUP: | 10327 case Variable::LOOKUP: |
| 10325 return Bailout("unsupported lookup slot in declaration"); | 10328 return Bailout("unsupported lookup slot in declaration"); |
| 10326 } | 10329 } |
| 10327 } | 10330 } |
| 10328 | 10331 |
| 10329 | 10332 |
| 10330 void HOptimizedGraphBuilder::VisitFunctionDeclaration( | 10333 void HOptimizedGraphBuilder::VisitFunctionDeclaration( |
| (...skipping 18 matching lines...) Expand all Loading... |
| 10349 break; | 10352 break; |
| 10350 } | 10353 } |
| 10351 case Variable::CONTEXT: { | 10354 case Variable::CONTEXT: { |
| 10352 CHECK_ALIVE(VisitForValue(declaration->fun())); | 10355 CHECK_ALIVE(VisitForValue(declaration->fun())); |
| 10353 HValue* value = Pop(); | 10356 HValue* value = Pop(); |
| 10354 HValue* context = environment()->LookupContext(); | 10357 HValue* context = environment()->LookupContext(); |
| 10355 HStoreContextSlot* store = new(zone()) HStoreContextSlot( | 10358 HStoreContextSlot* store = new(zone()) HStoreContextSlot( |
| 10356 context, variable->index(), HStoreContextSlot::kNoCheck, value); | 10359 context, variable->index(), HStoreContextSlot::kNoCheck, value); |
| 10357 AddInstruction(store); | 10360 AddInstruction(store); |
| 10358 if (store->HasObservableSideEffects()) { | 10361 if (store->HasObservableSideEffects()) { |
| 10359 AddSimulate(proxy->id(), REMOVABLE_SIMULATE); | 10362 Add<HSimulate>(proxy->id(), REMOVABLE_SIMULATE); |
| 10360 } | 10363 } |
| 10361 break; | 10364 break; |
| 10362 } | 10365 } |
| 10363 case Variable::LOOKUP: | 10366 case Variable::LOOKUP: |
| 10364 return Bailout("unsupported lookup slot in declaration"); | 10367 return Bailout("unsupported lookup slot in declaration"); |
| 10365 } | 10368 } |
| 10366 } | 10369 } |
| 10367 | 10370 |
| 10368 | 10371 |
| 10369 void HOptimizedGraphBuilder::VisitModuleDeclaration( | 10372 void HOptimizedGraphBuilder::VisitModuleDeclaration( |
| (...skipping 1240 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11610 } | 11613 } |
| 11611 } | 11614 } |
| 11612 | 11615 |
| 11613 #ifdef DEBUG | 11616 #ifdef DEBUG |
| 11614 if (graph_ != NULL) graph_->Verify(false); // No full verify. | 11617 if (graph_ != NULL) graph_->Verify(false); // No full verify. |
| 11615 if (allocator_ != NULL) allocator_->Verify(); | 11618 if (allocator_ != NULL) allocator_->Verify(); |
| 11616 #endif | 11619 #endif |
| 11617 } | 11620 } |
| 11618 | 11621 |
| 11619 } } // namespace v8::internal | 11622 } } // namespace v8::internal |
| OLD | NEW |