Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(334)

Side by Side Diff: src/hydrogen.cc

Issue 131363008: A64: Synchronize with r15922. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/a64
Patch Set: Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/hydrogen.h ('k') | src/hydrogen-bce.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 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 16 matching lines...) Expand all
27 27
28 #include "hydrogen.h" 28 #include "hydrogen.h"
29 29
30 #include <algorithm> 30 #include <algorithm>
31 31
32 #include "v8.h" 32 #include "v8.h"
33 #include "codegen.h" 33 #include "codegen.h"
34 #include "full-codegen.h" 34 #include "full-codegen.h"
35 #include "hashmap.h" 35 #include "hashmap.h"
36 #include "hydrogen-bce.h" 36 #include "hydrogen-bce.h"
37 #include "hydrogen-bch.h"
37 #include "hydrogen-canonicalize.h" 38 #include "hydrogen-canonicalize.h"
38 #include "hydrogen-dce.h" 39 #include "hydrogen-dce.h"
39 #include "hydrogen-dehoist.h" 40 #include "hydrogen-dehoist.h"
40 #include "hydrogen-deoptimizing-mark.h" 41 #include "hydrogen-deoptimizing-mark.h"
41 #include "hydrogen-environment-liveness.h" 42 #include "hydrogen-environment-liveness.h"
42 #include "hydrogen-escape-analysis.h" 43 #include "hydrogen-escape-analysis.h"
43 #include "hydrogen-infer-representation.h" 44 #include "hydrogen-infer-representation.h"
44 #include "hydrogen-infer-types.h" 45 #include "hydrogen-infer-types.h"
45 #include "hydrogen-gvn.h" 46 #include "hydrogen-gvn.h"
46 #include "hydrogen-minus-zero.h" 47 #include "hydrogen-minus-zero.h"
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
141 ASSERT(last_environment() != NULL); 142 ASSERT(last_environment() != NULL);
142 ASSERT(!last_environment()->ast_id().IsNone()); 143 ASSERT(!last_environment()->ast_id().IsNone());
143 HBlockEntry* entry = new(zone()) HBlockEntry(); 144 HBlockEntry* entry = new(zone()) HBlockEntry();
144 entry->InitializeAsFirst(this); 145 entry->InitializeAsFirst(this);
145 first_ = last_ = entry; 146 first_ = last_ = entry;
146 } 147 }
147 instr->InsertAfter(last_); 148 instr->InsertAfter(last_);
148 } 149 }
149 150
150 151
151 HDeoptimize* HBasicBlock::CreateDeoptimize(
152 HDeoptimize::UseEnvironment has_uses) {
153 ASSERT(HasEnvironment());
154 if (has_uses == HDeoptimize::kNoUses)
155 return new(zone()) HDeoptimize(0, 0, 0, zone());
156
157 HEnvironment* environment = last_environment();
158 int first_local_index = environment->first_local_index();
159 int first_expression_index = environment->first_expression_index();
160 HDeoptimize* instr = new(zone()) HDeoptimize(
161 environment->length(), first_local_index, first_expression_index, zone());
162 for (int i = 0; i < environment->length(); i++) {
163 HValue* val = environment->values()->at(i);
164 instr->AddEnvironmentValue(val, zone());
165 }
166
167 return instr;
168 }
169
170
171 HSimulate* HBasicBlock::CreateSimulate(BailoutId ast_id, 152 HSimulate* HBasicBlock::CreateSimulate(BailoutId ast_id,
172 RemovableSimulate removable) { 153 RemovableSimulate removable) {
173 ASSERT(HasEnvironment()); 154 ASSERT(HasEnvironment());
174 HEnvironment* environment = last_environment(); 155 HEnvironment* environment = last_environment();
175 ASSERT(ast_id.IsNone() || 156 ASSERT(ast_id.IsNone() ||
176 ast_id == BailoutId::StubEntry() || 157 ast_id == BailoutId::StubEntry() ||
177 environment->closure()->shared()->VerifyBailoutId(ast_id)); 158 environment->closure()->shared()->VerifyBailoutId(ast_id));
178 159
179 int push_count = environment->push_count(); 160 int push_count = environment->push_count();
180 int pop_count = environment->pop_count(); 161 int pop_count = environment->pop_count();
(...skipping 514 matching lines...) Expand 10 before | Expand all | Expand 10 after
695 if (constant == GetConstantHole()) return true; 676 if (constant == GetConstantHole()) return true;
696 if (constant == GetConstantNull()) return true; 677 if (constant == GetConstantNull()) return true;
697 return false; 678 return false;
698 } 679 }
699 680
700 681
701 HGraphBuilder::IfBuilder::IfBuilder(HGraphBuilder* builder, int position) 682 HGraphBuilder::IfBuilder::IfBuilder(HGraphBuilder* builder, int position)
702 : builder_(builder), 683 : builder_(builder),
703 position_(position), 684 position_(position),
704 finished_(false), 685 finished_(false),
686 deopt_then_(false),
687 deopt_else_(false),
705 did_then_(false), 688 did_then_(false),
706 did_else_(false), 689 did_else_(false),
707 did_and_(false), 690 did_and_(false),
708 did_or_(false), 691 did_or_(false),
709 captured_(false), 692 captured_(false),
710 needs_compare_(true), 693 needs_compare_(true),
711 split_edge_merge_block_(NULL) { 694 split_edge_merge_block_(NULL),
695 merge_block_(NULL) {
712 HEnvironment* env = builder->environment(); 696 HEnvironment* env = builder->environment();
713 first_true_block_ = builder->CreateBasicBlock(env->Copy()); 697 first_true_block_ = builder->CreateBasicBlock(env->Copy());
714 last_true_block_ = NULL; 698 last_true_block_ = NULL;
715 first_false_block_ = builder->CreateBasicBlock(env->Copy()); 699 first_false_block_ = builder->CreateBasicBlock(env->Copy());
716 } 700 }
717 701
718 702
719 HGraphBuilder::IfBuilder::IfBuilder( 703 HGraphBuilder::IfBuilder::IfBuilder(
720 HGraphBuilder* builder, 704 HGraphBuilder* builder,
721 HIfContinuation* continuation) 705 HIfContinuation* continuation)
722 : builder_(builder), 706 : builder_(builder),
723 position_(RelocInfo::kNoPosition), 707 position_(RelocInfo::kNoPosition),
724 finished_(false), 708 finished_(false),
709 deopt_then_(false),
710 deopt_else_(false),
725 did_then_(false), 711 did_then_(false),
726 did_else_(false), 712 did_else_(false),
727 did_and_(false), 713 did_and_(false),
728 did_or_(false), 714 did_or_(false),
729 captured_(false), 715 captured_(false),
730 needs_compare_(false), 716 needs_compare_(false),
731 first_true_block_(NULL), 717 first_true_block_(NULL),
732 first_false_block_(NULL), 718 first_false_block_(NULL),
733 split_edge_merge_block_(NULL), 719 split_edge_merge_block_(NULL),
734 merge_block_(NULL) { 720 merge_block_(NULL) {
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
831 ASSERT(!captured_); 817 ASSERT(!captured_);
832 ASSERT(!finished_); 818 ASSERT(!finished_);
833 last_true_block_ = builder_->current_block(); 819 last_true_block_ = builder_->current_block();
834 ASSERT(first_true_block_ == NULL || !last_true_block_->IsFinished()); 820 ASSERT(first_true_block_ == NULL || !last_true_block_->IsFinished());
835 builder_->set_current_block(first_false_block_); 821 builder_->set_current_block(first_false_block_);
836 did_else_ = true; 822 did_else_ = true;
837 } 823 }
838 824
839 825
840 void HGraphBuilder::IfBuilder::Deopt() { 826 void HGraphBuilder::IfBuilder::Deopt() {
841 HBasicBlock* block = builder_->current_block(); 827 ASSERT(did_then_);
842 block->FinishExitWithDeoptimization(HDeoptimize::kUseAll);
843 builder_->set_current_block(NULL);
844 if (did_else_) { 828 if (did_else_) {
845 first_false_block_ = NULL; 829 deopt_else_ = true;
846 } else { 830 } else {
847 first_true_block_ = NULL; 831 deopt_then_ = true;
848 } 832 }
833 builder_->Add<HDeoptimize>(Deoptimizer::EAGER);
849 } 834 }
850 835
851 836
852 void HGraphBuilder::IfBuilder::Return(HValue* value) { 837 void HGraphBuilder::IfBuilder::Return(HValue* value) {
853 HBasicBlock* block = builder_->current_block(); 838 HBasicBlock* block = builder_->current_block();
854 HValue* context = builder_->environment()->LookupContext(); 839 HValue* context = builder_->environment()->LookupContext();
855 HValue* parameter_count = builder_->graph()->GetConstantMinus1(); 840 HValue* parameter_count = builder_->graph()->GetConstantMinus1();
856 block->FinishExit(new(zone()) HReturn(value, context, parameter_count)); 841 block->FinishExit(new(zone()) HReturn(value, context, parameter_count));
857 builder_->set_current_block(NULL); 842 builder_->set_current_block(NULL);
858 if (did_else_) { 843 if (did_else_) {
859 first_false_block_ = NULL; 844 first_false_block_ = NULL;
860 } else { 845 } else {
861 first_true_block_ = NULL; 846 first_true_block_ = NULL;
862 } 847 }
863 } 848 }
864 849
865 850
866 void HGraphBuilder::IfBuilder::End() { 851 void HGraphBuilder::IfBuilder::End() {
867 if (!captured_) { 852 if (!captured_) {
868 ASSERT(did_then_); 853 ASSERT(did_then_);
869 if (!did_else_) { 854 if (!did_else_) {
870 last_true_block_ = builder_->current_block(); 855 last_true_block_ = builder_->current_block();
871 } 856 }
872 if (first_true_block_ == NULL) { 857 if (first_true_block_ == NULL) {
873 // Deopt on true. Nothing to do, just continue the false block. 858 // Return on true. Nothing to do, just continue the false block.
874 } else if (first_false_block_ == NULL) { 859 } else if (first_false_block_ == NULL) {
875 // Deopt on false. Nothing to do except switching to the true block. 860 // Deopt on false. Nothing to do except switching to the true block.
876 builder_->set_current_block(last_true_block_); 861 builder_->set_current_block(last_true_block_);
877 } else { 862 } else {
878 HEnvironment* merge_env = last_true_block_->last_environment()->Copy(); 863 merge_block_ = builder_->graph()->CreateBasicBlock();
879 merge_block_ = builder_->CreateBasicBlock(merge_env);
880 ASSERT(!finished_); 864 ASSERT(!finished_);
881 if (!did_else_) Else(); 865 if (!did_else_) Else();
882 ASSERT(!last_true_block_->IsFinished()); 866 ASSERT(!last_true_block_->IsFinished());
883 HBasicBlock* last_false_block = builder_->current_block(); 867 HBasicBlock* last_false_block = builder_->current_block();
884 ASSERT(!last_false_block->IsFinished()); 868 ASSERT(!last_false_block->IsFinished());
885 last_true_block_->GotoNoSimulate(merge_block_); 869 if (deopt_then_) {
886 last_false_block->GotoNoSimulate(merge_block_); 870 last_false_block->GotoNoSimulate(merge_block_);
871 builder_->PadEnvironmentForContinuation(last_true_block_,
872 merge_block_);
873 last_true_block_->GotoNoSimulate(merge_block_);
874 } else {
875 last_true_block_->GotoNoSimulate(merge_block_);
876 if (deopt_else_) {
877 builder_->PadEnvironmentForContinuation(last_false_block,
878 merge_block_);
879 }
880 last_false_block->GotoNoSimulate(merge_block_);
881 }
887 builder_->set_current_block(merge_block_); 882 builder_->set_current_block(merge_block_);
888 } 883 }
889 } 884 }
890 finished_ = true; 885 finished_ = true;
891 } 886 }
892 887
893 888
894 HGraphBuilder::LoopBuilder::LoopBuilder(HGraphBuilder* builder, 889 HGraphBuilder::LoopBuilder::LoopBuilder(HGraphBuilder* builder,
895 HValue* context, 890 HValue* context,
896 LoopBuilder::Direction direction) 891 LoopBuilder::Direction direction)
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
986 HInstruction* HGraphBuilder::AddInstruction(HInstruction* instr) { 981 HInstruction* HGraphBuilder::AddInstruction(HInstruction* instr) {
987 ASSERT(current_block() != NULL); 982 ASSERT(current_block() != NULL);
988 current_block()->AddInstruction(instr); 983 current_block()->AddInstruction(instr);
989 if (no_side_effects_scope_count_ > 0) { 984 if (no_side_effects_scope_count_ > 0) {
990 instr->SetFlag(HValue::kHasNoObservableSideEffects); 985 instr->SetFlag(HValue::kHasNoObservableSideEffects);
991 } 986 }
992 return instr; 987 return instr;
993 } 988 }
994 989
995 990
996 void HGraphBuilder::AddSimulate(BailoutId id,
997 RemovableSimulate removable) {
998 ASSERT(current_block() != NULL);
999 ASSERT(no_side_effects_scope_count_ == 0);
1000 current_block()->AddSimulate(id, removable);
1001 }
1002
1003
1004 HReturn* HGraphBuilder::AddReturn(HValue* value) {
1005 HValue* context = environment()->LookupContext();
1006 int num_parameters = graph()->info()->num_parameters();
1007 HValue* params = Add<HConstant>(num_parameters);
1008 HReturn* return_instruction = new(graph()->zone())
1009 HReturn(value, context, params);
1010 current_block()->FinishExit(return_instruction);
1011 return return_instruction;
1012 }
1013
1014
1015 void HGraphBuilder::AddSoftDeoptimize(SoftDeoptimizeMode mode) {
1016 isolate()->counters()->soft_deopts_requested()->Increment();
1017 if (FLAG_always_opt && mode == CAN_OMIT_SOFT_DEOPT) return;
1018 if (current_block()->IsDeoptimizing()) return;
1019 Add<HSoftDeoptimize>();
1020 isolate()->counters()->soft_deopts_inserted()->Increment();
1021 current_block()->MarkAsDeoptimizing();
1022 graph()->set_has_soft_deoptimize(true);
1023 }
1024
1025
1026 HBasicBlock* HGraphBuilder::CreateBasicBlock(HEnvironment* env) { 991 HBasicBlock* HGraphBuilder::CreateBasicBlock(HEnvironment* env) {
1027 HBasicBlock* b = graph()->CreateBasicBlock(); 992 HBasicBlock* b = graph()->CreateBasicBlock();
1028 b->SetInitialEnvironment(env); 993 b->SetInitialEnvironment(env);
1029 return b; 994 return b;
1030 } 995 }
1031 996
1032 997
1033 HBasicBlock* HGraphBuilder::CreateLoopHeaderBlock() { 998 HBasicBlock* HGraphBuilder::CreateLoopHeaderBlock() {
1034 HBasicBlock* header = graph()->CreateBasicBlock(); 999 HBasicBlock* header = graph()->CreateBasicBlock();
1035 HEnvironment* entry_env = environment()->CopyAsLoopHeader(header); 1000 HEnvironment* entry_env = environment()->CopyAsLoopHeader(header);
1036 header->SetInitialEnvironment(entry_env); 1001 header->SetInitialEnvironment(entry_env);
1037 header->AttachLoopInformation(); 1002 header->AttachLoopInformation();
1038 return header; 1003 return header;
1039 } 1004 }
1040 1005
1041 1006
1042 HValue* HGraphBuilder::BuildCheckHeapObject(HValue* obj) { 1007 HValue* HGraphBuilder::BuildCheckHeapObject(HValue* obj) {
1043 if (obj->type().IsHeapObject()) return obj; 1008 if (obj->type().IsHeapObject()) return obj;
1044 return Add<HCheckHeapObject>(obj); 1009 return Add<HCheckHeapObject>(obj);
1045 } 1010 }
1046 1011
1047 1012
1048 HValue* HGraphBuilder::BuildCheckMap(HValue* obj, 1013 void HGraphBuilder::FinishExitWithHardDeoptimization(
1049 Handle<Map> map) { 1014 HBasicBlock* continuation) {
1050 HCheckMaps* check = HCheckMaps::New(obj, map, zone()); 1015 PadEnvironmentForContinuation(current_block(), continuation);
1016 Add<HDeoptimize>(Deoptimizer::EAGER);
1017 if (no_side_effects_scope_count_ > 0) {
1018 current_block()->GotoNoSimulate(continuation);
1019 } else {
1020 current_block()->Goto(continuation);
1021 }
1022 }
1023
1024
1025 void HGraphBuilder::PadEnvironmentForContinuation(
1026 HBasicBlock* from,
1027 HBasicBlock* continuation) {
1028 if (continuation->last_environment() != NULL) {
1029 // When merging from a deopt block to a continuation, resolve differences in
1030 // environment by pushing undefined and popping extra values so that the
1031 // environments match during the join.
1032 int continuation_env_length = continuation->last_environment()->length();
1033 while (continuation_env_length != from->last_environment()->length()) {
1034 if (continuation_env_length > from->last_environment()->length()) {
1035 from->last_environment()->Push(graph()->GetConstantUndefined());
1036 } else {
1037 from->last_environment()->Pop();
1038 }
1039 }
1040 } else {
1041 ASSERT(continuation->predecessors()->length() == 0);
1042 }
1043 }
1044
1045
1046 HValue* HGraphBuilder::BuildCheckMap(HValue* obj, Handle<Map> map) {
1047 HCheckMaps* check = HCheckMaps::New(obj, map, zone(), top_info());
1051 AddInstruction(check); 1048 AddInstruction(check);
1052 return check; 1049 return check;
1053 } 1050 }
1054 1051
1055 1052
1053 HValue* HGraphBuilder::BuildWrapReceiver(HValue* object, HValue* function) {
1054 if (object->type().IsJSObject()) return object;
1055 return Add<HWrapReceiver>(object, function);
1056 }
1057
1058
1056 HValue* HGraphBuilder::BuildCheckForCapacityGrow(HValue* object, 1059 HValue* HGraphBuilder::BuildCheckForCapacityGrow(HValue* object,
1057 HValue* elements, 1060 HValue* elements,
1058 ElementsKind kind, 1061 ElementsKind kind,
1059 HValue* length, 1062 HValue* length,
1060 HValue* key, 1063 HValue* key,
1061 bool is_js_array) { 1064 bool is_js_array) {
1062 Zone* zone = this->zone(); 1065 Zone* zone = this->zone();
1063 IfBuilder length_checker(this); 1066 IfBuilder length_checker(this);
1064 1067
1065 Token::Value token = IsHoleyElementsKind(kind) ? Token::GTE : Token::EQ; 1068 Token::Value token = IsHoleyElementsKind(kind) ? Token::GTE : Token::EQ;
(...skipping 21 matching lines...) Expand all
1087 capacity_checker.Else(); 1090 capacity_checker.Else();
1088 1091
1089 environment()->Push(elements); 1092 environment()->Push(elements);
1090 capacity_checker.End(); 1093 capacity_checker.End();
1091 1094
1092 if (is_js_array) { 1095 if (is_js_array) {
1093 HValue* new_length = AddInstruction( 1096 HValue* new_length = AddInstruction(
1094 HAdd::New(zone, context, key, graph_->GetConstant1())); 1097 HAdd::New(zone, context, key, graph_->GetConstant1()));
1095 new_length->ClearFlag(HValue::kCanOverflow); 1098 new_length->ClearFlag(HValue::kCanOverflow);
1096 1099
1097 Representation representation = IsFastElementsKind(kind) 1100 AddStore(object, HObjectAccess::ForArrayLength(kind), new_length);
1098 ? Representation::Smi() : Representation::Tagged();
1099 AddStore(object, HObjectAccess::ForArrayLength(), new_length,
1100 representation);
1101 } 1101 }
1102 1102
1103 length_checker.Else(); 1103 length_checker.Else();
1104 Add<HBoundsCheck>(key, length); 1104 Add<HBoundsCheck>(key, length);
1105 1105
1106 environment()->Push(elements); 1106 environment()->Push(elements);
1107 length_checker.End(); 1107 length_checker.End();
1108 1108
1109 return environment()->Pop(); 1109 return environment()->Pop();
1110 } 1110 }
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
1158 1158
1159 IfBuilder if_builder(this); 1159 IfBuilder if_builder(this);
1160 1160
1161 if_builder.IfNot<HCompareObjectEqAndBranch>(elements, empty_fixed_array); 1161 if_builder.IfNot<HCompareObjectEqAndBranch>(elements, empty_fixed_array);
1162 1162
1163 if_builder.Then(); 1163 if_builder.Then();
1164 1164
1165 HInstruction* elements_length = AddLoadFixedArrayLength(elements); 1165 HInstruction* elements_length = AddLoadFixedArrayLength(elements);
1166 1166
1167 HInstruction* array_length = is_jsarray 1167 HInstruction* array_length = is_jsarray
1168 ? AddLoad(object, HObjectAccess::ForArrayLength(), 1168 ? AddLoad(object, HObjectAccess::ForArrayLength(from_kind), NULL)
1169 NULL, Representation::Smi())
1170 : elements_length; 1169 : elements_length;
1171 array_length->set_type(HType::Smi());
1172 1170
1173 BuildGrowElementsCapacity(object, elements, from_kind, to_kind, 1171 BuildGrowElementsCapacity(object, elements, from_kind, to_kind,
1174 array_length, elements_length); 1172 array_length, elements_length);
1175 1173
1176 if_builder.End(); 1174 if_builder.End();
1177 } 1175 }
1178 1176
1179 AddStore(object, HObjectAccess::ForMap(), map); 1177 AddStore(object, HObjectAccess::ForMap(), map);
1180 } 1178 }
1181 1179
(...skipping 21 matching lines...) Expand all
1203 if (mapcheck != NULL) { 1201 if (mapcheck != NULL) {
1204 mapcheck->ClearGVNFlag(kDependsOnElementsKind); 1202 mapcheck->ClearGVNFlag(kDependsOnElementsKind);
1205 } 1203 }
1206 } 1204 }
1207 bool fast_smi_only_elements = IsFastSmiElementsKind(elements_kind); 1205 bool fast_smi_only_elements = IsFastSmiElementsKind(elements_kind);
1208 bool fast_elements = IsFastObjectElementsKind(elements_kind); 1206 bool fast_elements = IsFastObjectElementsKind(elements_kind);
1209 HValue* elements = AddLoadElements(object, mapcheck); 1207 HValue* elements = AddLoadElements(object, mapcheck);
1210 if (is_store && (fast_elements || fast_smi_only_elements) && 1208 if (is_store && (fast_elements || fast_smi_only_elements) &&
1211 store_mode != STORE_NO_TRANSITION_HANDLE_COW) { 1209 store_mode != STORE_NO_TRANSITION_HANDLE_COW) {
1212 HCheckMaps* check_cow_map = HCheckMaps::New( 1210 HCheckMaps* check_cow_map = HCheckMaps::New(
1213 elements, isolate()->factory()->fixed_array_map(), zone); 1211 elements, isolate()->factory()->fixed_array_map(), zone, top_info());
1214 check_cow_map->ClearGVNFlag(kDependsOnElementsKind); 1212 check_cow_map->ClearGVNFlag(kDependsOnElementsKind);
1215 AddInstruction(check_cow_map); 1213 AddInstruction(check_cow_map);
1216 } 1214 }
1217 HInstruction* length = NULL; 1215 HInstruction* length = NULL;
1218 if (is_js_array) { 1216 if (is_js_array) {
1219 length = AddLoad(object, HObjectAccess::ForArrayLength(), mapcheck, 1217 length = AddLoad(object, HObjectAccess::ForArrayLength(elements_kind),
1220 Representation::Smi()); 1218 mapcheck);
1221 } else { 1219 } else {
1222 length = AddLoadFixedArrayLength(elements); 1220 length = AddLoadFixedArrayLength(elements);
1223 } 1221 }
1224 length->set_type(HType::Smi()); 1222 length->set_type(HType::Smi());
1225 HValue* checked_key = NULL; 1223 HValue* checked_key = NULL;
1226 if (IsExternalArrayElementsKind(elements_kind)) { 1224 if (IsExternalArrayElementsKind(elements_kind)) {
1227 if (store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS) { 1225 if (store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS) {
1228 NoObservableSideEffectsScope no_effects(this); 1226 NoObservableSideEffectsScope no_effects(this);
1229 HLoadExternalArrayPointer* external_elements = 1227 HLoadExternalArrayPointer* external_elements =
1230 Add<HLoadExternalArrayPointer>(elements); 1228 Add<HLoadExternalArrayPointer>(elements);
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
1271 checked_key = Add<HBoundsCheck>(key, length); 1269 checked_key = Add<HBoundsCheck>(key, length);
1272 1270
1273 if (is_store && (fast_elements || fast_smi_only_elements)) { 1271 if (is_store && (fast_elements || fast_smi_only_elements)) {
1274 if (store_mode == STORE_NO_TRANSITION_HANDLE_COW) { 1272 if (store_mode == STORE_NO_TRANSITION_HANDLE_COW) {
1275 NoObservableSideEffectsScope no_effects(this); 1273 NoObservableSideEffectsScope no_effects(this);
1276 1274
1277 elements = BuildCopyElementsOnWrite(object, elements, elements_kind, 1275 elements = BuildCopyElementsOnWrite(object, elements, elements_kind,
1278 length); 1276 length);
1279 } else { 1277 } else {
1280 HCheckMaps* check_cow_map = HCheckMaps::New( 1278 HCheckMaps* check_cow_map = HCheckMaps::New(
1281 elements, isolate()->factory()->fixed_array_map(), zone); 1279 elements, isolate()->factory()->fixed_array_map(),
1280 zone, top_info());
1282 check_cow_map->ClearGVNFlag(kDependsOnElementsKind); 1281 check_cow_map->ClearGVNFlag(kDependsOnElementsKind);
1283 AddInstruction(check_cow_map); 1282 AddInstruction(check_cow_map);
1284 } 1283 }
1285 } 1284 }
1286 } 1285 }
1287 return AddFastElementAccess(elements, checked_key, val, mapcheck, 1286 return AddFastElementAccess(elements, checked_key, val, mapcheck,
1288 elements_kind, is_store, load_mode, store_mode); 1287 elements_kind, is_store, load_mode, store_mode);
1289 } 1288 }
1290 1289
1291 1290
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
1325 1324
1326 void HGraphBuilder::BuildInitializeElementsHeader(HValue* elements, 1325 void HGraphBuilder::BuildInitializeElementsHeader(HValue* elements,
1327 ElementsKind kind, 1326 ElementsKind kind,
1328 HValue* capacity) { 1327 HValue* capacity) {
1329 Factory* factory = isolate()->factory(); 1328 Factory* factory = isolate()->factory();
1330 Handle<Map> map = IsFastDoubleElementsKind(kind) 1329 Handle<Map> map = IsFastDoubleElementsKind(kind)
1331 ? factory->fixed_double_array_map() 1330 ? factory->fixed_double_array_map()
1332 : factory->fixed_array_map(); 1331 : factory->fixed_array_map();
1333 1332
1334 AddStoreMapConstant(elements, map); 1333 AddStoreMapConstant(elements, map);
1335 Representation representation = IsFastElementsKind(kind) 1334 AddStore(elements, HObjectAccess::ForFixedArrayLength(), capacity);
1336 ? Representation::Smi() : Representation::Tagged();
1337 AddStore(elements, HObjectAccess::ForFixedArrayLength(), capacity,
1338 representation);
1339 } 1335 }
1340 1336
1341 1337
1342 HValue* HGraphBuilder::BuildAllocateElementsAndInitializeElementsHeader( 1338 HValue* HGraphBuilder::BuildAllocateElementsAndInitializeElementsHeader(
1343 HValue* context, 1339 HValue* context,
1344 ElementsKind kind, 1340 ElementsKind kind,
1345 HValue* capacity) { 1341 HValue* capacity) {
1346 HValue* new_elements = BuildAllocateElements(context, kind, capacity); 1342 HValue* new_elements = BuildAllocateElements(context, kind, capacity);
1347 BuildInitializeElementsHeader(new_elements, kind, capacity); 1343 BuildInitializeElementsHeader(new_elements, kind, capacity);
1348 return new_elements; 1344 return new_elements;
1349 } 1345 }
1350 1346
1351 1347
1352 HInnerAllocatedObject* HGraphBuilder::BuildJSArrayHeader(HValue* array, 1348 HInnerAllocatedObject* HGraphBuilder::BuildJSArrayHeader(HValue* array,
1353 HValue* array_map, 1349 HValue* array_map,
1354 AllocationSiteMode mode, 1350 AllocationSiteMode mode,
1351 ElementsKind elements_kind,
1355 HValue* allocation_site_payload, 1352 HValue* allocation_site_payload,
1356 HValue* length_field) { 1353 HValue* length_field) {
1357 1354
1358 AddStore(array, HObjectAccess::ForMap(), array_map); 1355 AddStore(array, HObjectAccess::ForMap(), array_map);
1359 1356
1360 HConstant* empty_fixed_array = 1357 HConstant* empty_fixed_array =
1361 Add<HConstant>(isolate()->factory()->empty_fixed_array()); 1358 Add<HConstant>(isolate()->factory()->empty_fixed_array());
1362 1359
1363 HObjectAccess access = HObjectAccess::ForPropertiesPointer(); 1360 HObjectAccess access = HObjectAccess::ForPropertiesPointer();
1364 AddStore(array, access, empty_fixed_array); 1361 AddStore(array, access, empty_fixed_array);
1365 AddStore(array, HObjectAccess::ForArrayLength(), length_field); 1362 AddStore(array, HObjectAccess::ForArrayLength(elements_kind), length_field);
1366 1363
1367 if (mode == TRACK_ALLOCATION_SITE) { 1364 if (mode == TRACK_ALLOCATION_SITE) {
1368 BuildCreateAllocationMemento(array, 1365 BuildCreateAllocationMemento(array,
1369 JSArray::kSize, 1366 JSArray::kSize,
1370 allocation_site_payload); 1367 allocation_site_payload);
1371 } 1368 }
1372 1369
1373 int elements_location = JSArray::kSize; 1370 int elements_location = JSArray::kSize;
1374 if (mode == TRACK_ALLOCATION_SITE) { 1371 if (mode == TRACK_ALLOCATION_SITE) {
1375 elements_location += AllocationMemento::kSize; 1372 elements_location += AllocationMemento::kSize;
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
1462 } 1459 }
1463 1460
1464 1461
1465 HLoadNamedField* HGraphBuilder::AddLoadElements(HValue* object, 1462 HLoadNamedField* HGraphBuilder::AddLoadElements(HValue* object,
1466 HValue* typecheck) { 1463 HValue* typecheck) {
1467 return AddLoad(object, HObjectAccess::ForElementsPointer(), typecheck); 1464 return AddLoad(object, HObjectAccess::ForElementsPointer(), typecheck);
1468 } 1465 }
1469 1466
1470 1467
1471 HLoadNamedField* HGraphBuilder::AddLoadFixedArrayLength(HValue* object) { 1468 HLoadNamedField* HGraphBuilder::AddLoadFixedArrayLength(HValue* object) {
1472 HLoadNamedField* instr = AddLoad(object, HObjectAccess::ForFixedArrayLength(), 1469 return AddLoad(object, HObjectAccess::ForFixedArrayLength());
1473 NULL, Representation::Smi());
1474 instr->set_type(HType::Smi());
1475 return instr;
1476 } 1470 }
1477 1471
1478 1472
1479 HValue* HGraphBuilder::BuildNewElementsCapacity(HValue* context, 1473 HValue* HGraphBuilder::BuildNewElementsCapacity(HValue* context,
1480 HValue* old_capacity) { 1474 HValue* old_capacity) {
1481 Zone* zone = this->zone(); 1475 Zone* zone = this->zone();
1482 HValue* half_old_capacity = 1476 HValue* half_old_capacity =
1483 AddInstruction(HShr::New(zone, context, old_capacity, 1477 AddInstruction(HShr::New(zone, context, old_capacity,
1484 graph_->GetConstant1())); 1478 graph_->GetConstant1()));
1485 half_old_capacity->ClearFlag(HValue::kCanOverflow); 1479 half_old_capacity->ClearFlag(HValue::kCanOverflow);
(...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after
1714 1708
1715 switch (operation) { 1709 switch (operation) {
1716 default: 1710 default:
1717 UNREACHABLE(); 1711 UNREACHABLE();
1718 case Token::SUB: { 1712 case Token::SUB: {
1719 HInstruction* instr = 1713 HInstruction* instr =
1720 HMul::New(zone(), environment()->LookupContext(), 1714 HMul::New(zone(), environment()->LookupContext(),
1721 input, graph()->GetConstantMinus1()); 1715 input, graph()->GetConstantMinus1());
1722 Representation rep = Representation::FromType(type); 1716 Representation rep = Representation::FromType(type);
1723 if (type->Is(Type::None())) { 1717 if (type->Is(Type::None())) {
1724 AddSoftDeoptimize(); 1718 Add<HDeoptimize>(Deoptimizer::SOFT);
1725 } 1719 }
1726 if (instr->IsBinaryOperation()) { 1720 if (instr->IsBinaryOperation()) {
1727 HBinaryOperation* binop = HBinaryOperation::cast(instr); 1721 HBinaryOperation* binop = HBinaryOperation::cast(instr);
1728 binop->set_observed_input_representation(1, rep); 1722 binop->set_observed_input_representation(1, rep);
1729 binop->set_observed_input_representation(2, rep); 1723 binop->set_observed_input_representation(2, rep);
1730 } 1724 }
1731 return instr; 1725 return instr;
1732 } 1726 }
1733 case Token::BIT_NOT: 1727 case Token::BIT_NOT:
1734 if (type->Is(Type::None())) { 1728 if (type->Is(Type::None())) {
1735 AddSoftDeoptimize(); 1729 Add<HDeoptimize>(Deoptimizer::SOFT);
1736 } 1730 }
1737 return new(zone()) HBitNot(input); 1731 return new(zone()) HBitNot(input);
1738 } 1732 }
1739 } 1733 }
1740 1734
1741 1735
1742 void HGraphBuilder::BuildCompareNil( 1736 void HGraphBuilder::BuildCompareNil(
1743 HValue* value, 1737 HValue* value,
1744 Handle<Type> type, 1738 Handle<Type> type,
1745 int position, 1739 int position,
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
1836 allocation_site_payload_(NULL), 1830 allocation_site_payload_(NULL),
1837 constructor_function_(constructor_function) { 1831 constructor_function_(constructor_function) {
1838 } 1832 }
1839 1833
1840 1834
1841 HValue* HGraphBuilder::JSArrayBuilder::EmitMapCode(HValue* context) { 1835 HValue* HGraphBuilder::JSArrayBuilder::EmitMapCode(HValue* context) {
1842 if (kind_ == GetInitialFastElementsKind()) { 1836 if (kind_ == GetInitialFastElementsKind()) {
1843 // No need for a context lookup if the kind_ matches the initial 1837 // No need for a context lookup if the kind_ matches the initial
1844 // map, because we can just load the map in that case. 1838 // map, because we can just load the map in that case.
1845 HObjectAccess access = HObjectAccess::ForPrototypeOrInitialMap(); 1839 HObjectAccess access = HObjectAccess::ForPrototypeOrInitialMap();
1846 HInstruction* load = 1840 return builder()->AddInstruction(
1847 builder()->BuildLoadNamedField(constructor_function_, 1841 builder()->BuildLoadNamedField(constructor_function_, access));
1848 access,
1849 Representation::Tagged());
1850 return builder()->AddInstruction(load);
1851 } 1842 }
1852 1843
1853 HInstruction* native_context = builder()->BuildGetNativeContext(context); 1844 HInstruction* native_context = builder()->BuildGetNativeContext(context);
1854 HInstruction* index = builder()->Add<HConstant>( 1845 HInstruction* index = builder()->Add<HConstant>(
1855 static_cast<int32_t>(Context::JS_ARRAY_MAPS_INDEX)); 1846 static_cast<int32_t>(Context::JS_ARRAY_MAPS_INDEX));
1856 1847
1857 HInstruction* map_array = builder()->Add<HLoadKeyed>( 1848 HInstruction* map_array = builder()->Add<HLoadKeyed>(
1858 native_context, index, static_cast<HValue*>(NULL), FAST_ELEMENTS); 1849 native_context, index, static_cast<HValue*>(NULL), FAST_ELEMENTS);
1859 1850
1860 HInstruction* kind_index = builder()->Add<HConstant>(kind_); 1851 HInstruction* kind_index = builder()->Add<HConstant>(kind_);
1861 1852
1862 return builder()->Add<HLoadKeyed>( 1853 return builder()->Add<HLoadKeyed>(
1863 map_array, kind_index, static_cast<HValue*>(NULL), FAST_ELEMENTS); 1854 map_array, kind_index, static_cast<HValue*>(NULL), FAST_ELEMENTS);
1864 } 1855 }
1865 1856
1866 1857
1867 HValue* HGraphBuilder::JSArrayBuilder::EmitInternalMapCode() { 1858 HValue* HGraphBuilder::JSArrayBuilder::EmitInternalMapCode() {
1868 // Find the map near the constructor function 1859 // Find the map near the constructor function
1869 HObjectAccess access = HObjectAccess::ForPrototypeOrInitialMap(); 1860 HObjectAccess access = HObjectAccess::ForPrototypeOrInitialMap();
1870 return builder()->AddInstruction( 1861 return builder()->AddInstruction(
1871 builder()->BuildLoadNamedField(constructor_function_, 1862 builder()->BuildLoadNamedField(constructor_function_, access));
1872 access,
1873 Representation::Tagged()));
1874 } 1863 }
1875 1864
1876 1865
1877 HValue* HGraphBuilder::JSArrayBuilder::EstablishAllocationSize( 1866 HValue* HGraphBuilder::JSArrayBuilder::EstablishAllocationSize(
1878 HValue* length_node) { 1867 HValue* length_node) {
1879 HValue* context = builder()->environment()->LookupContext(); 1868 HValue* context = builder()->environment()->LookupContext();
1880 ASSERT(length_node != NULL); 1869 ASSERT(length_node != NULL);
1881 1870
1882 int base_size = JSArray::kSize; 1871 int base_size = JSArray::kSize;
1883 if (mode_ == TRACK_ALLOCATION_SITE) { 1872 if (mode_ == TRACK_ALLOCATION_SITE) {
1884 base_size += AllocationMemento::kSize; 1873 base_size += AllocationMemento::kSize;
1885 } 1874 }
1886 1875
1887 if (IsFastDoubleElementsKind(kind_)) { 1876 STATIC_ASSERT(FixedDoubleArray::kHeaderSize == FixedArray::kHeaderSize);
1888 base_size += FixedDoubleArray::kHeaderSize; 1877 base_size += FixedArray::kHeaderSize;
1889 } else {
1890 base_size += FixedArray::kHeaderSize;
1891 }
1892 1878
1893 HInstruction* elements_size_value = 1879 HInstruction* elements_size_value =
1894 builder()->Add<HConstant>(elements_size()); 1880 builder()->Add<HConstant>(elements_size());
1895 HInstruction* mul = HMul::New(zone(), context, length_node, 1881 HInstruction* mul = HMul::New(zone(), context, length_node,
1896 elements_size_value); 1882 elements_size_value);
1897 mul->ClearFlag(HValue::kCanOverflow); 1883 mul->ClearFlag(HValue::kCanOverflow);
1898 builder()->AddInstruction(mul); 1884 builder()->AddInstruction(mul);
1899 1885
1900 HInstruction* base = builder()->Add<HConstant>(base_size); 1886 HInstruction* base = builder()->Add<HConstant>(base_size);
1901 HInstruction* total_size = HAdd::New(zone(), context, base, mul); 1887 HInstruction* total_size = HAdd::New(zone(), context, base, mul);
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
1951 // Fill in the fields: map, properties, length 1937 // Fill in the fields: map, properties, length
1952 HValue* map; 1938 HValue* map;
1953 if (allocation_site_payload_ == NULL) { 1939 if (allocation_site_payload_ == NULL) {
1954 map = EmitInternalMapCode(); 1940 map = EmitInternalMapCode();
1955 } else { 1941 } else {
1956 map = EmitMapCode(context); 1942 map = EmitMapCode(context);
1957 } 1943 }
1958 elements_location_ = builder()->BuildJSArrayHeader(new_object, 1944 elements_location_ = builder()->BuildJSArrayHeader(new_object,
1959 map, 1945 map,
1960 mode_, 1946 mode_,
1947 kind_,
1961 allocation_site_payload_, 1948 allocation_site_payload_,
1962 length_field); 1949 length_field);
1963 1950
1964 // Initialize the elements 1951 // Initialize the elements
1965 builder()->BuildInitializeElementsHeader(elements_location_, kind_, capacity); 1952 builder()->BuildInitializeElementsHeader(elements_location_, kind_, capacity);
1966 1953
1967 if (fill_with_hole) { 1954 if (fill_with_hole) {
1968 builder()->BuildFillElementsWithHole(context, elements_location_, kind_, 1955 builder()->BuildFillElementsWithHole(context, elements_location_, kind_,
1969 graph()->GetConstant0(), capacity); 1956 graph()->GetConstant0(), capacity);
1970 } 1957 }
1971 1958
1972 return new_object; 1959 return new_object;
1973 } 1960 }
1974 1961
1975 1962
1976 HStoreNamedField* HGraphBuilder::AddStore(HValue *object, 1963 HStoreNamedField* HGraphBuilder::AddStore(HValue *object,
1977 HObjectAccess access, 1964 HObjectAccess access,
1978 HValue *val, 1965 HValue *val) {
1979 Representation representation) { 1966 return Add<HStoreNamedField>(object, access, val);
1980 return Add<HStoreNamedField>(object, access, val, representation);
1981 } 1967 }
1982 1968
1983 1969
1984 HLoadNamedField* HGraphBuilder::AddLoad(HValue *object, 1970 HLoadNamedField* HGraphBuilder::AddLoad(HValue *object,
1985 HObjectAccess access, 1971 HObjectAccess access,
1986 HValue *typecheck, 1972 HValue *typecheck) {
1987 Representation representation) { 1973 return Add<HLoadNamedField>(object, access, typecheck);
1988 return Add<HLoadNamedField>(object, access, typecheck, representation);
1989 } 1974 }
1990 1975
1991 1976
1992 HStoreNamedField* HGraphBuilder::AddStoreMapConstant(HValue *object, 1977 HStoreNamedField* HGraphBuilder::AddStoreMapConstant(HValue *object,
1993 Handle<Map> map) { 1978 Handle<Map> map) {
1994 return Add<HStoreNamedField>(object, HObjectAccess::ForMap(), 1979 return Add<HStoreNamedField>(object, HObjectAccess::ForMap(),
1995 Add<HConstant>(map)); 1980 Add<HConstant>(map));
1996 } 1981 }
1997 1982
1998 1983
(...skipping 634 matching lines...) Expand 10 before | Expand all | Expand 10 after
2633 2618
2634 void TestContext::ReturnValue(HValue* value) { 2619 void TestContext::ReturnValue(HValue* value) {
2635 BuildBranch(value); 2620 BuildBranch(value);
2636 } 2621 }
2637 2622
2638 2623
2639 void EffectContext::ReturnInstruction(HInstruction* instr, BailoutId ast_id) { 2624 void EffectContext::ReturnInstruction(HInstruction* instr, BailoutId ast_id) {
2640 ASSERT(!instr->IsControlInstruction()); 2625 ASSERT(!instr->IsControlInstruction());
2641 owner()->AddInstruction(instr); 2626 owner()->AddInstruction(instr);
2642 if (instr->HasObservableSideEffects()) { 2627 if (instr->HasObservableSideEffects()) {
2643 owner()->AddSimulate(ast_id, REMOVABLE_SIMULATE); 2628 owner()->Add<HSimulate>(ast_id, REMOVABLE_SIMULATE);
2644 } 2629 }
2645 } 2630 }
2646 2631
2647 2632
2648 void EffectContext::ReturnControl(HControlInstruction* instr, 2633 void EffectContext::ReturnControl(HControlInstruction* instr,
2649 BailoutId ast_id) { 2634 BailoutId ast_id) {
2650 ASSERT(!instr->HasObservableSideEffects()); 2635 ASSERT(!instr->HasObservableSideEffects());
2651 HBasicBlock* empty_true = owner()->graph()->CreateBasicBlock(); 2636 HBasicBlock* empty_true = owner()->graph()->CreateBasicBlock();
2652 HBasicBlock* empty_false = owner()->graph()->CreateBasicBlock(); 2637 HBasicBlock* empty_false = owner()->graph()->CreateBasicBlock();
2653 instr->SetSuccessorAt(0, empty_true); 2638 instr->SetSuccessorAt(0, empty_true);
(...skipping 21 matching lines...) Expand all
2675 2660
2676 2661
2677 void ValueContext::ReturnInstruction(HInstruction* instr, BailoutId ast_id) { 2662 void ValueContext::ReturnInstruction(HInstruction* instr, BailoutId ast_id) {
2678 ASSERT(!instr->IsControlInstruction()); 2663 ASSERT(!instr->IsControlInstruction());
2679 if (!arguments_allowed() && instr->CheckFlag(HValue::kIsArguments)) { 2664 if (!arguments_allowed() && instr->CheckFlag(HValue::kIsArguments)) {
2680 return owner()->Bailout("bad value context for arguments object value"); 2665 return owner()->Bailout("bad value context for arguments object value");
2681 } 2666 }
2682 owner()->AddInstruction(instr); 2667 owner()->AddInstruction(instr);
2683 owner()->Push(instr); 2668 owner()->Push(instr);
2684 if (instr->HasObservableSideEffects()) { 2669 if (instr->HasObservableSideEffects()) {
2685 owner()->AddSimulate(ast_id, REMOVABLE_SIMULATE); 2670 owner()->Add<HSimulate>(ast_id, REMOVABLE_SIMULATE);
2686 } 2671 }
2687 } 2672 }
2688 2673
2689 2674
2690 void ValueContext::ReturnControl(HControlInstruction* instr, BailoutId ast_id) { 2675 void ValueContext::ReturnControl(HControlInstruction* instr, BailoutId ast_id) {
2691 ASSERT(!instr->HasObservableSideEffects()); 2676 ASSERT(!instr->HasObservableSideEffects());
2692 if (!arguments_allowed() && instr->CheckFlag(HValue::kIsArguments)) { 2677 if (!arguments_allowed() && instr->CheckFlag(HValue::kIsArguments)) {
2693 return owner()->Bailout("bad value context for arguments object value"); 2678 return owner()->Bailout("bad value context for arguments object value");
2694 } 2679 }
2695 HBasicBlock* materialize_false = owner()->graph()->CreateBasicBlock(); 2680 HBasicBlock* materialize_false = owner()->graph()->CreateBasicBlock();
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
2731 2716
2732 2717
2733 void TestContext::ReturnInstruction(HInstruction* instr, BailoutId ast_id) { 2718 void TestContext::ReturnInstruction(HInstruction* instr, BailoutId ast_id) {
2734 ASSERT(!instr->IsControlInstruction()); 2719 ASSERT(!instr->IsControlInstruction());
2735 HOptimizedGraphBuilder* builder = owner(); 2720 HOptimizedGraphBuilder* builder = owner();
2736 builder->AddInstruction(instr); 2721 builder->AddInstruction(instr);
2737 // We expect a simulate after every expression with side effects, though 2722 // We expect a simulate after every expression with side effects, though
2738 // this one isn't actually needed (and wouldn't work if it were targeted). 2723 // this one isn't actually needed (and wouldn't work if it were targeted).
2739 if (instr->HasObservableSideEffects()) { 2724 if (instr->HasObservableSideEffects()) {
2740 builder->Push(instr); 2725 builder->Push(instr);
2741 builder->AddSimulate(ast_id, REMOVABLE_SIMULATE); 2726 builder->Add<HSimulate>(ast_id, REMOVABLE_SIMULATE);
2742 builder->Pop(); 2727 builder->Pop();
2743 } 2728 }
2744 BuildBranch(instr); 2729 BuildBranch(instr);
2745 } 2730 }
2746 2731
2747 2732
2748 void TestContext::ReturnControl(HControlInstruction* instr, BailoutId ast_id) { 2733 void TestContext::ReturnControl(HControlInstruction* instr, BailoutId ast_id) {
2749 ASSERT(!instr->HasObservableSideEffects()); 2734 ASSERT(!instr->HasObservableSideEffects());
2750 HBasicBlock* empty_true = owner()->graph()->CreateBasicBlock(); 2735 HBasicBlock* empty_true = owner()->graph()->CreateBasicBlock();
2751 HBasicBlock* empty_false = owner()->graph()->CreateBasicBlock(); 2736 HBasicBlock* empty_false = owner()->graph()->CreateBasicBlock();
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after
2919 current_block()->Goto(body_entry); 2904 current_block()->Goto(body_entry);
2920 body_entry->SetJoinId(BailoutId::FunctionEntry()); 2905 body_entry->SetJoinId(BailoutId::FunctionEntry());
2921 set_current_block(body_entry); 2906 set_current_block(body_entry);
2922 2907
2923 // Handle implicit declaration of the function name in named function 2908 // Handle implicit declaration of the function name in named function
2924 // expressions before other declarations. 2909 // expressions before other declarations.
2925 if (scope->is_function_scope() && scope->function() != NULL) { 2910 if (scope->is_function_scope() && scope->function() != NULL) {
2926 VisitVariableDeclaration(scope->function()); 2911 VisitVariableDeclaration(scope->function());
2927 } 2912 }
2928 VisitDeclarations(scope->declarations()); 2913 VisitDeclarations(scope->declarations());
2929 AddSimulate(BailoutId::Declarations()); 2914 Add<HSimulate>(BailoutId::Declarations());
2930 2915
2931 HValue* context = environment()->LookupContext(); 2916 HValue* context = environment()->LookupContext();
2932 Add<HStackCheck>(context, HStackCheck::kFunctionEntry); 2917 Add<HStackCheck>(context, HStackCheck::kFunctionEntry);
2933 2918
2934 VisitStatements(current_info()->function()->body()); 2919 VisitStatements(current_info()->function()->body());
2935 if (HasStackOverflow()) return false; 2920 if (HasStackOverflow()) return false;
2936 2921
2937 if (current_block() != NULL) { 2922 if (current_block() != NULL) {
2938 AddReturn(graph()->GetConstantUndefined()); 2923 Add<HReturn>(graph()->GetConstantUndefined());
2939 set_current_block(NULL); 2924 set_current_block(NULL);
2940 } 2925 }
2941 2926
2942 // If the checksum of the number of type info changes is the same as the 2927 // If the checksum of the number of type info changes is the same as the
2943 // last time this function was compiled, then this recompile is likely not 2928 // last time this function was compiled, then this recompile is likely not
2944 // due to missing/inadequate type feedback, but rather too aggressive 2929 // due to missing/inadequate type feedback, but rather too aggressive
2945 // optimization. Disable optimistic LICM in that case. 2930 // optimization. Disable optimistic LICM in that case.
2946 Handle<Code> unoptimized_code(current_info()->shared_info()->code()); 2931 Handle<Code> unoptimized_code(current_info()->shared_info()->code());
2947 ASSERT(unoptimized_code->kind() == Code::FUNCTION); 2932 ASSERT(unoptimized_code->kind() == Code::FUNCTION);
2948 Handle<TypeFeedbackInfo> type_info( 2933 Handle<TypeFeedbackInfo> type_info(
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
3026 3011
3027 Run<HComputeMinusZeroChecksPhase>(); 3012 Run<HComputeMinusZeroChecksPhase>();
3028 3013
3029 // Eliminate redundant stack checks on backwards branches. 3014 // Eliminate redundant stack checks on backwards branches.
3030 Run<HStackCheckEliminationPhase>(); 3015 Run<HStackCheckEliminationPhase>();
3031 3016
3032 if (FLAG_idefs) SetupInformativeDefinitions(); 3017 if (FLAG_idefs) SetupInformativeDefinitions();
3033 if (FLAG_array_bounds_checks_elimination && !FLAG_idefs) { 3018 if (FLAG_array_bounds_checks_elimination && !FLAG_idefs) {
3034 Run<HBoundsCheckEliminationPhase>(); 3019 Run<HBoundsCheckEliminationPhase>();
3035 } 3020 }
3021 if (FLAG_array_bounds_checks_hoisting && !FLAG_idefs) {
3022 Run<HBoundsCheckHoistingPhase>();
3023 }
3036 if (FLAG_array_index_dehoisting) Run<HDehoistIndexComputationsPhase>(); 3024 if (FLAG_array_index_dehoisting) Run<HDehoistIndexComputationsPhase>();
3037 if (FLAG_dead_code_elimination) Run<HDeadCodeEliminationPhase>(); 3025 if (FLAG_dead_code_elimination) Run<HDeadCodeEliminationPhase>();
3038 3026
3039 RestoreActualValues(); 3027 RestoreActualValues();
3040 3028
3041 return true; 3029 return true;
3042 } 3030 }
3043 3031
3044 3032
3045 void HGraph::SetupInformativeDefinitionsInBlock(HBasicBlock* block) { 3033 void HGraph::SetupInformativeDefinitionsInBlock(HBasicBlock* block) {
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
3107 instruction->DeleteAndReplaceWith(instruction->RedefinedOperand()); 3095 instruction->DeleteAndReplaceWith(instruction->RedefinedOperand());
3108 } else { 3096 } else {
3109 instruction->ReplaceAllUsesWith(instruction->ActualValue()); 3097 instruction->ReplaceAllUsesWith(instruction->ActualValue());
3110 } 3098 }
3111 } 3099 }
3112 } 3100 }
3113 } 3101 }
3114 } 3102 }
3115 3103
3116 3104
3117 void HOptimizedGraphBuilder::PushAndAdd(HInstruction* instr) { 3105 void HGraphBuilder::PushAndAdd(HInstruction* instr) {
3118 Push(instr); 3106 Push(instr);
3119 AddInstruction(instr); 3107 AddInstruction(instr);
3120 } 3108 }
3121 3109
3122 3110
3123 template <class Instruction> 3111 template <class Instruction>
3124 HInstruction* HOptimizedGraphBuilder::PreProcessCall(Instruction* call) { 3112 HInstruction* HOptimizedGraphBuilder::PreProcessCall(Instruction* call) {
3125 int count = call->argument_count(); 3113 int count = call->argument_count();
3126 ZoneList<HValue*> arguments(count, zone()); 3114 ZoneList<HValue*> arguments(count, zone());
3127 for (int i = 0; i < count; ++i) { 3115 for (int i = 0; i < count; ++i) {
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
3218 ASSERT(current_block() != NULL); 3206 ASSERT(current_block() != NULL);
3219 ASSERT(current_block()->HasPredecessor()); 3207 ASSERT(current_block()->HasPredecessor());
3220 } 3208 }
3221 3209
3222 3210
3223 void HOptimizedGraphBuilder::VisitIfStatement(IfStatement* stmt) { 3211 void HOptimizedGraphBuilder::VisitIfStatement(IfStatement* stmt) {
3224 ASSERT(!HasStackOverflow()); 3212 ASSERT(!HasStackOverflow());
3225 ASSERT(current_block() != NULL); 3213 ASSERT(current_block() != NULL);
3226 ASSERT(current_block()->HasPredecessor()); 3214 ASSERT(current_block()->HasPredecessor());
3227 if (stmt->condition()->ToBooleanIsTrue()) { 3215 if (stmt->condition()->ToBooleanIsTrue()) {
3228 AddSimulate(stmt->ThenId()); 3216 Add<HSimulate>(stmt->ThenId());
3229 Visit(stmt->then_statement()); 3217 Visit(stmt->then_statement());
3230 } else if (stmt->condition()->ToBooleanIsFalse()) { 3218 } else if (stmt->condition()->ToBooleanIsFalse()) {
3231 AddSimulate(stmt->ElseId()); 3219 Add<HSimulate>(stmt->ElseId());
3232 Visit(stmt->else_statement()); 3220 Visit(stmt->else_statement());
3233 } else { 3221 } else {
3234 HBasicBlock* cond_true = graph()->CreateBasicBlock(); 3222 HBasicBlock* cond_true = graph()->CreateBasicBlock();
3235 HBasicBlock* cond_false = graph()->CreateBasicBlock(); 3223 HBasicBlock* cond_false = graph()->CreateBasicBlock();
3236 CHECK_BAILOUT(VisitForControl(stmt->condition(), cond_true, cond_false)); 3224 CHECK_BAILOUT(VisitForControl(stmt->condition(), cond_true, cond_false));
3237 3225
3238 if (cond_true->HasPredecessor()) { 3226 if (cond_true->HasPredecessor()) {
3239 cond_true->SetJoinId(stmt->ThenId()); 3227 cond_true->SetJoinId(stmt->ThenId());
3240 set_current_block(cond_true); 3228 set_current_block(cond_true);
3241 CHECK_BAILOUT(Visit(stmt->then_statement())); 3229 CHECK_BAILOUT(Visit(stmt->then_statement()));
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
3328 void HOptimizedGraphBuilder::VisitReturnStatement(ReturnStatement* stmt) { 3316 void HOptimizedGraphBuilder::VisitReturnStatement(ReturnStatement* stmt) {
3329 ASSERT(!HasStackOverflow()); 3317 ASSERT(!HasStackOverflow());
3330 ASSERT(current_block() != NULL); 3318 ASSERT(current_block() != NULL);
3331 ASSERT(current_block()->HasPredecessor()); 3319 ASSERT(current_block()->HasPredecessor());
3332 FunctionState* state = function_state(); 3320 FunctionState* state = function_state();
3333 AstContext* context = call_context(); 3321 AstContext* context = call_context();
3334 if (context == NULL) { 3322 if (context == NULL) {
3335 // Not an inlined return, so an actual one. 3323 // Not an inlined return, so an actual one.
3336 CHECK_ALIVE(VisitForValue(stmt->expression())); 3324 CHECK_ALIVE(VisitForValue(stmt->expression()));
3337 HValue* result = environment()->Pop(); 3325 HValue* result = environment()->Pop();
3338 AddReturn(result); 3326 Add<HReturn>(result);
3339 } else if (state->inlining_kind() == CONSTRUCT_CALL_RETURN) { 3327 } else if (state->inlining_kind() == CONSTRUCT_CALL_RETURN) {
3340 // Return from an inlined construct call. In a test context the return value 3328 // Return from an inlined construct call. In a test context the return value
3341 // will always evaluate to true, in a value context the return value needs 3329 // will always evaluate to true, in a value context the return value needs
3342 // to be a JSObject. 3330 // to be a JSObject.
3343 if (context->IsTest()) { 3331 if (context->IsTest()) {
3344 TestContext* test = TestContext::cast(context); 3332 TestContext* test = TestContext::cast(context);
3345 CHECK_ALIVE(VisitForEffect(stmt->expression())); 3333 CHECK_ALIVE(VisitForEffect(stmt->expression()));
3346 current_block()->Goto(test->if_true(), state); 3334 current_block()->Goto(test->if_true(), state);
3347 } else if (context->IsEffect()) { 3335 } else if (context->IsEffect()) {
3348 CHECK_ALIVE(VisitForEffect(stmt->expression())); 3336 CHECK_ALIVE(VisitForEffect(stmt->expression()));
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
3420 } 3408 }
3421 3409
3422 ASSERT(stmt->switch_type() != SwitchStatement::UNKNOWN_SWITCH); 3410 ASSERT(stmt->switch_type() != SwitchStatement::UNKNOWN_SWITCH);
3423 if (stmt->switch_type() == SwitchStatement::GENERIC_SWITCH) { 3411 if (stmt->switch_type() == SwitchStatement::GENERIC_SWITCH) {
3424 return Bailout("SwitchStatement: mixed or non-literal switch labels"); 3412 return Bailout("SwitchStatement: mixed or non-literal switch labels");
3425 } 3413 }
3426 3414
3427 HValue* context = environment()->LookupContext(); 3415 HValue* context = environment()->LookupContext();
3428 3416
3429 CHECK_ALIVE(VisitForValue(stmt->tag())); 3417 CHECK_ALIVE(VisitForValue(stmt->tag()));
3430 AddSimulate(stmt->EntryId()); 3418 Add<HSimulate>(stmt->EntryId());
3431 HValue* tag_value = Pop(); 3419 HValue* tag_value = Pop();
3432 HBasicBlock* first_test_block = current_block(); 3420 HBasicBlock* first_test_block = current_block();
3433 3421
3434 HUnaryControlInstruction* string_check = NULL; 3422 HUnaryControlInstruction* string_check = NULL;
3435 HBasicBlock* not_string_block = NULL; 3423 HBasicBlock* not_string_block = NULL;
3436 3424
3437 // Test switch's tag value if all clauses are string literals 3425 // Test switch's tag value if all clauses are string literals
3438 if (stmt->switch_type() == SwitchStatement::STRING_SWITCH) { 3426 if (stmt->switch_type() == SwitchStatement::STRING_SWITCH) {
3439 string_check = new(zone()) HIsStringAndBranch(tag_value); 3427 string_check = new(zone()) HIsStringAndBranch(tag_value);
3440 first_test_block = graph()->CreateBasicBlock(); 3428 first_test_block = graph()->CreateBasicBlock();
(...skipping 19 matching lines...) Expand all
3460 CHECK_ALIVE(VisitForValue(clause->label())); 3448 CHECK_ALIVE(VisitForValue(clause->label()));
3461 HValue* label_value = Pop(); 3449 HValue* label_value = Pop();
3462 3450
3463 HBasicBlock* next_test_block = graph()->CreateBasicBlock(); 3451 HBasicBlock* next_test_block = graph()->CreateBasicBlock();
3464 HBasicBlock* body_block = graph()->CreateBasicBlock(); 3452 HBasicBlock* body_block = graph()->CreateBasicBlock();
3465 3453
3466 HControlInstruction* compare; 3454 HControlInstruction* compare;
3467 3455
3468 if (stmt->switch_type() == SwitchStatement::SMI_SWITCH) { 3456 if (stmt->switch_type() == SwitchStatement::SMI_SWITCH) {
3469 if (!clause->compare_type()->Is(Type::Smi())) { 3457 if (!clause->compare_type()->Is(Type::Smi())) {
3470 AddSoftDeoptimize(); 3458 Add<HDeoptimize>(Deoptimizer::SOFT);
3471 } 3459 }
3472 3460
3473 HCompareNumericAndBranch* compare_ = 3461 HCompareNumericAndBranch* compare_ =
3474 new(zone()) HCompareNumericAndBranch(tag_value, 3462 new(zone()) HCompareNumericAndBranch(tag_value,
3475 label_value, 3463 label_value,
3476 Token::EQ_STRICT); 3464 Token::EQ_STRICT);
3477 compare_->set_observed_input_representation( 3465 compare_->set_observed_input_representation(
3478 Representation::Smi(), Representation::Smi()); 3466 Representation::Smi(), Representation::Smi());
3479 compare = compare_; 3467 compare = compare_;
3480 } else { 3468 } else {
(...skipping 29 matching lines...) Expand all
3510 CaseClause* clause = clauses->at(i); 3498 CaseClause* clause = clauses->at(i);
3511 3499
3512 // Identify the block where normal (non-fall-through) control flow 3500 // Identify the block where normal (non-fall-through) control flow
3513 // goes to. 3501 // goes to.
3514 HBasicBlock* normal_block = NULL; 3502 HBasicBlock* normal_block = NULL;
3515 if (clause->is_default()) { 3503 if (clause->is_default()) {
3516 if (last_block != NULL) { 3504 if (last_block != NULL) {
3517 normal_block = last_block; 3505 normal_block = last_block;
3518 last_block = NULL; // Cleared to indicate we've handled it. 3506 last_block = NULL; // Cleared to indicate we've handled it.
3519 } 3507 }
3520 } else if (!curr_test_block->end()->IsDeoptimize()) { 3508 } else {
3521 normal_block = curr_test_block->end()->FirstSuccessor(); 3509 normal_block = curr_test_block->end()->FirstSuccessor();
3522 curr_test_block = curr_test_block->end()->SecondSuccessor(); 3510 curr_test_block = curr_test_block->end()->SecondSuccessor();
3523 } 3511 }
3524 3512
3525 // Identify a block to emit the body into. 3513 // Identify a block to emit the body into.
3526 if (normal_block == NULL) { 3514 if (normal_block == NULL) {
3527 if (fall_through_block == NULL) { 3515 if (fall_through_block == NULL) {
3528 // (a) Unreachable. 3516 // (a) Unreachable.
3529 if (clause->is_default()) { 3517 if (clause->is_default()) {
3530 continue; // Might still be reachable clause bodies. 3518 continue; // Might still be reachable clause bodies.
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
3564 break_block->SetJoinId(stmt->ExitId()); 3552 break_block->SetJoinId(stmt->ExitId());
3565 set_current_block(break_block); 3553 set_current_block(break_block);
3566 } 3554 }
3567 } 3555 }
3568 3556
3569 3557
3570 void HOptimizedGraphBuilder::VisitLoopBody(IterationStatement* stmt, 3558 void HOptimizedGraphBuilder::VisitLoopBody(IterationStatement* stmt,
3571 HBasicBlock* loop_entry, 3559 HBasicBlock* loop_entry,
3572 BreakAndContinueInfo* break_info) { 3560 BreakAndContinueInfo* break_info) {
3573 BreakAndContinueScope push(break_info, this); 3561 BreakAndContinueScope push(break_info, this);
3574 AddSimulate(stmt->StackCheckId()); 3562 Add<HSimulate>(stmt->StackCheckId());
3575 HValue* context = environment()->LookupContext(); 3563 HValue* context = environment()->LookupContext();
3576 HStackCheck* stack_check = Add<HStackCheck>( 3564 HStackCheck* stack_check = Add<HStackCheck>(
3577 context, HStackCheck::kBackwardsBranch); 3565 context, HStackCheck::kBackwardsBranch);
3578 ASSERT(loop_entry->IsLoopHeader()); 3566 ASSERT(loop_entry->IsLoopHeader());
3579 loop_entry->loop_information()->set_stack_check(stack_check); 3567 loop_entry->loop_information()->set_stack_check(stack_check);
3580 CHECK_BAILOUT(Visit(stmt->body())); 3568 CHECK_BAILOUT(Visit(stmt->body()));
3581 } 3569 }
3582 3570
3583 3571
3584 void HOptimizedGraphBuilder::VisitDoWhileStatement(DoWhileStatement* stmt) { 3572 void HOptimizedGraphBuilder::VisitDoWhileStatement(DoWhileStatement* stmt) {
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after
3725 return Bailout("ForInStatement with non-local each variable"); 3713 return Bailout("ForInStatement with non-local each variable");
3726 } 3714 }
3727 3715
3728 Variable* each_var = stmt->each()->AsVariableProxy()->var(); 3716 Variable* each_var = stmt->each()->AsVariableProxy()->var();
3729 3717
3730 CHECK_ALIVE(VisitForValue(stmt->enumerable())); 3718 CHECK_ALIVE(VisitForValue(stmt->enumerable()));
3731 HValue* enumerable = Top(); // Leave enumerable at the top. 3719 HValue* enumerable = Top(); // Leave enumerable at the top.
3732 3720
3733 HInstruction* map = Add<HForInPrepareMap>( 3721 HInstruction* map = Add<HForInPrepareMap>(
3734 environment()->LookupContext(), enumerable); 3722 environment()->LookupContext(), enumerable);
3735 AddSimulate(stmt->PrepareId()); 3723 Add<HSimulate>(stmt->PrepareId());
3736 3724
3737 HInstruction* array = Add<HForInCacheArray>( 3725 HInstruction* array = Add<HForInCacheArray>(
3738 enumerable, map, DescriptorArray::kEnumCacheBridgeCacheIndex); 3726 enumerable, map, DescriptorArray::kEnumCacheBridgeCacheIndex);
3739 3727
3740 HInstruction* enum_length = Add<HMapEnumLength>(map); 3728 HInstruction* enum_length = Add<HMapEnumLength>(map);
3741 3729
3742 HInstruction* start_index = Add<HConstant>(0); 3730 HInstruction* start_index = Add<HConstant>(0);
3743 3731
3744 Push(map); 3732 Push(map);
3745 Push(array); 3733 Push(array);
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
3794 JoinContinue(stmt, current_block(), break_info.continue_block()); 3782 JoinContinue(stmt, current_block(), break_info.continue_block());
3795 3783
3796 if (body_exit != NULL) { 3784 if (body_exit != NULL) {
3797 set_current_block(body_exit); 3785 set_current_block(body_exit);
3798 3786
3799 HValue* current_index = Pop(); 3787 HValue* current_index = Pop();
3800 HInstruction* new_index = HAdd::New(zone(), 3788 HInstruction* new_index = HAdd::New(zone(),
3801 environment()->LookupContext(), 3789 environment()->LookupContext(),
3802 current_index, 3790 current_index,
3803 graph()->GetConstant1()); 3791 graph()->GetConstant1());
3804 new_index->AssumeRepresentation(Representation::Integer32());
3805 PushAndAdd(new_index); 3792 PushAndAdd(new_index);
3806 body_exit = current_block(); 3793 body_exit = current_block();
3807 } 3794 }
3808 3795
3809 HBasicBlock* loop_exit = CreateLoop(stmt, 3796 HBasicBlock* loop_exit = CreateLoop(stmt,
3810 loop_entry, 3797 loop_entry,
3811 body_exit, 3798 body_exit,
3812 loop_successor, 3799 loop_successor,
3813 break_info.break_block()); 3800 break_info.break_block());
3814 3801
(...skipping 507 matching lines...) Expand 10 before | Expand all | Expand 10 after
4322 Handle<JSObject> holder; 4309 Handle<JSObject> holder;
4323 ASSERT(!LookupSetter(map, name, &setter, &holder)); 4310 ASSERT(!LookupSetter(map, name, &setter, &holder));
4324 #endif 4311 #endif
4325 CHECK_ALIVE(store = BuildStoreNamedMonomorphic(literal, 4312 CHECK_ALIVE(store = BuildStoreNamedMonomorphic(literal,
4326 name, 4313 name,
4327 value, 4314 value,
4328 map)); 4315 map));
4329 } 4316 }
4330 AddInstruction(store); 4317 AddInstruction(store);
4331 if (store->HasObservableSideEffects()) { 4318 if (store->HasObservableSideEffects()) {
4332 AddSimulate(key->id(), REMOVABLE_SIMULATE); 4319 Add<HSimulate>(key->id(), REMOVABLE_SIMULATE);
4333 } 4320 }
4334 } else { 4321 } else {
4335 CHECK_ALIVE(VisitForEffect(value)); 4322 CHECK_ALIVE(VisitForEffect(value));
4336 } 4323 }
4337 break; 4324 break;
4338 } 4325 }
4339 // Fall through. 4326 // Fall through.
4340 case ObjectLiteral::Property::PROTOTYPE: 4327 case ObjectLiteral::Property::PROTOTYPE:
4341 case ObjectLiteral::Property::SETTER: 4328 case ObjectLiteral::Property::SETTER:
4342 case ObjectLiteral::Property::GETTER: 4329 case ObjectLiteral::Property::GETTER:
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
4445 Runtime::FunctionId function_id = (expr->depth() > 1) 4432 Runtime::FunctionId function_id = (expr->depth() > 1)
4446 ? Runtime::kCreateArrayLiteral : Runtime::kCreateArrayLiteralShallow; 4433 ? Runtime::kCreateArrayLiteral : Runtime::kCreateArrayLiteralShallow;
4447 literal = Add<HCallRuntime>(context, 4434 literal = Add<HCallRuntime>(context,
4448 isolate()->factory()->empty_string(), 4435 isolate()->factory()->empty_string(),
4449 Runtime::FunctionForId(function_id), 4436 Runtime::FunctionForId(function_id),
4450 3); 4437 3);
4451 4438
4452 // De-opt if elements kind changed from boilerplate_elements_kind. 4439 // De-opt if elements kind changed from boilerplate_elements_kind.
4453 Handle<Map> map = Handle<Map>(original_boilerplate_object->map(), 4440 Handle<Map> map = Handle<Map>(original_boilerplate_object->map(),
4454 isolate()); 4441 isolate());
4455 AddInstruction(HCheckMaps::New(literal, map, zone())); 4442 AddInstruction(HCheckMaps::New(literal, map, zone(), top_info()));
4456 } 4443 }
4457 4444
4458 // The array is expected in the bailout environment during computation 4445 // The array is expected in the bailout environment during computation
4459 // of the property values and is the value of the entire expression. 4446 // of the property values and is the value of the entire expression.
4460 Push(literal); 4447 Push(literal);
4461 // The literal index is on the stack, too. 4448 // The literal index is on the stack, too.
4462 Push(Add<HConstant>(expr->literal_index())); 4449 Push(Add<HConstant>(expr->literal_index()));
4463 4450
4464 HInstruction* elements = NULL; 4451 HInstruction* elements = NULL;
4465 4452
(...skipping 21 matching lines...) Expand all
4487 HStoreKeyed* instr = Add<HStoreKeyed>(elements, key, value, 4474 HStoreKeyed* instr = Add<HStoreKeyed>(elements, key, value,
4488 boilerplate_elements_kind); 4475 boilerplate_elements_kind);
4489 instr->SetUninitialized(uninitialized); 4476 instr->SetUninitialized(uninitialized);
4490 break; 4477 break;
4491 } 4478 }
4492 default: 4479 default:
4493 UNREACHABLE(); 4480 UNREACHABLE();
4494 break; 4481 break;
4495 } 4482 }
4496 4483
4497 AddSimulate(expr->GetIdForElement(i)); 4484 Add<HSimulate>(expr->GetIdForElement(i));
4498 } 4485 }
4499 4486
4500 Drop(1); // array literal index 4487 Drop(1); // array literal index
4501 return ast_context()->ReturnValue(Pop()); 4488 return ast_context()->ReturnValue(Pop());
4502 } 4489 }
4503 4490
4504 4491
4505 // Sets the lookup result and returns true if the load/store can be inlined. 4492 // Sets the lookup result and returns true if the load/store can be inlined.
4506 static bool ComputeLoadStoreField(Handle<Map> type, 4493 static bool ComputeLoadStoreField(Handle<Map> type,
4507 Handle<String> name, 4494 Handle<String> name,
(...skipping 12 matching lines...) Expand all
4520 if (!is_store) return false; 4507 if (!is_store) return false;
4521 4508
4522 // 2nd chance: A store into a non-existent field can still be inlined if we 4509 // 2nd chance: A store into a non-existent field can still be inlined if we
4523 // have a matching transition and some room left in the object. 4510 // have a matching transition and some room left in the object.
4524 type->LookupTransition(NULL, *name, lookup); 4511 type->LookupTransition(NULL, *name, lookup);
4525 return lookup->IsTransitionToField(*type) && 4512 return lookup->IsTransitionToField(*type) &&
4526 (type->unused_property_fields() > 0); 4513 (type->unused_property_fields() > 0);
4527 } 4514 }
4528 4515
4529 4516
4530 static Representation ComputeLoadStoreRepresentation(Handle<Map> type,
4531 LookupResult* lookup) {
4532 if (lookup->IsField()) {
4533 return lookup->representation();
4534 } else {
4535 Map* transition = lookup->GetTransitionMapFromMap(*type);
4536 int descriptor = transition->LastAdded();
4537 PropertyDetails details =
4538 transition->instance_descriptors()->GetDetails(descriptor);
4539 return details.representation();
4540 }
4541 }
4542
4543
4544 void HOptimizedGraphBuilder::AddCheckMap(HValue* object, Handle<Map> map) { 4517 void HOptimizedGraphBuilder::AddCheckMap(HValue* object, Handle<Map> map) {
4545 BuildCheckHeapObject(object); 4518 BuildCheckHeapObject(object);
4546 AddInstruction(HCheckMaps::New(object, map, zone())); 4519 AddInstruction(HCheckMaps::New(object, map, zone(), top_info()));
4547 } 4520 }
4548 4521
4549 4522
4550 void HOptimizedGraphBuilder::AddCheckMapsWithTransitions(HValue* object, 4523 void HOptimizedGraphBuilder::AddCheckMapsWithTransitions(HValue* object,
4551 Handle<Map> map) { 4524 Handle<Map> map) {
4552 BuildCheckHeapObject(object); 4525 BuildCheckHeapObject(object);
4553 AddInstruction(HCheckMaps::NewWithTransitions(object, map, zone())); 4526 AddInstruction(HCheckMaps::NewWithTransitions(
4527 object, map, zone(), top_info()));
4554 } 4528 }
4555 4529
4556 4530
4557 HInstruction* HOptimizedGraphBuilder::BuildStoreNamedField( 4531 HInstruction* HOptimizedGraphBuilder::BuildStoreNamedField(
4558 HValue* object, 4532 HValue* object,
4559 Handle<String> name, 4533 Handle<String> name,
4560 HValue* value, 4534 HValue* value,
4561 Handle<Map> map, 4535 Handle<Map> map,
4562 LookupResult* lookup) { 4536 LookupResult* lookup) {
4563 ASSERT(lookup->IsFound()); 4537 ASSERT(lookup->IsFound());
(...skipping 20 matching lines...) Expand all
4584 } 4558 }
4585 ASSERT(proto->GetPrototype(isolate())->IsNull()); 4559 ASSERT(proto->GetPrototype(isolate())->IsNull());
4586 } 4560 }
4587 ASSERT(proto->IsJSObject()); 4561 ASSERT(proto->IsJSObject());
4588 Add<HCheckPrototypeMaps>(Handle<JSObject>(JSObject::cast(map->prototype())), 4562 Add<HCheckPrototypeMaps>(Handle<JSObject>(JSObject::cast(map->prototype())),
4589 Handle<JSObject>(JSObject::cast(proto)), 4563 Handle<JSObject>(JSObject::cast(proto)),
4590 zone(), top_info()); 4564 zone(), top_info());
4591 } 4565 }
4592 4566
4593 HObjectAccess field_access = HObjectAccess::ForField(map, lookup, name); 4567 HObjectAccess field_access = HObjectAccess::ForField(map, lookup, name);
4594 Representation representation = ComputeLoadStoreRepresentation(map, lookup);
4595 bool transition_to_field = lookup->IsTransitionToField(*map); 4568 bool transition_to_field = lookup->IsTransitionToField(*map);
4596 4569
4597 HStoreNamedField *instr; 4570 HStoreNamedField *instr;
4598 if (FLAG_track_double_fields && representation.IsDouble()) { 4571 if (FLAG_track_double_fields && field_access.representation().IsDouble()) {
4572 HObjectAccess heap_number_access =
4573 field_access.WithRepresentation(Representation::Tagged());
4599 if (transition_to_field) { 4574 if (transition_to_field) {
4600 // The store requires a mutable HeapNumber to be allocated. 4575 // The store requires a mutable HeapNumber to be allocated.
4601 NoObservableSideEffectsScope no_side_effects(this); 4576 NoObservableSideEffectsScope no_side_effects(this);
4602 HInstruction* heap_number_size = Add<HConstant>(HeapNumber::kSize); 4577 HInstruction* heap_number_size = Add<HConstant>(HeapNumber::kSize);
4603 HInstruction* double_box = Add<HAllocate>( 4578 HInstruction* heap_number = Add<HAllocate>(
4604 environment()->LookupContext(), heap_number_size, 4579 environment()->LookupContext(), heap_number_size,
4605 HType::HeapNumber(), HAllocate::CAN_ALLOCATE_IN_NEW_SPACE); 4580 HType::HeapNumber(), HAllocate::CAN_ALLOCATE_IN_NEW_SPACE);
4606 AddStoreMapConstant(double_box, isolate()->factory()->heap_number_map()); 4581 AddStoreMapConstant(heap_number, isolate()->factory()->heap_number_map());
4607 AddStore(double_box, HObjectAccess::ForHeapNumberValue(), 4582 AddStore(heap_number, HObjectAccess::ForHeapNumberValue(), value);
4608 value, Representation::Double()); 4583 instr = new(zone()) HStoreNamedField(
4609 instr = new(zone()) HStoreNamedField(object, field_access, double_box); 4584 object, heap_number_access, heap_number);
4610 } else { 4585 } else {
4611 // Already holds a HeapNumber; load the box and write its value field. 4586 // Already holds a HeapNumber; load the box and write its value field.
4612 HInstruction* double_box = AddLoad(object, field_access); 4587 HInstruction* heap_number = AddLoad(object, heap_number_access);
4613 double_box->set_type(HType::HeapNumber()); 4588 heap_number->set_type(HType::HeapNumber());
4614 instr = new(zone()) HStoreNamedField(double_box, 4589 instr = new(zone()) HStoreNamedField(heap_number,
4615 HObjectAccess::ForHeapNumberValue(), value, Representation::Double()); 4590 HObjectAccess::ForHeapNumberValue(), value);
4616 } 4591 }
4617 } else { 4592 } else {
4618 // This is a non-double store. 4593 // This is a normal store.
4619 instr = new(zone()) HStoreNamedField( 4594 instr = new(zone()) HStoreNamedField(object, field_access, value);
4620 object, field_access, value, representation);
4621 } 4595 }
4622 4596
4623 if (transition_to_field) { 4597 if (transition_to_field) {
4624 Handle<Map> transition(lookup->GetTransitionMapFromMap(*map)); 4598 Handle<Map> transition(lookup->GetTransitionMapFromMap(*map));
4625 instr->SetTransition(transition, top_info()); 4599 instr->SetTransition(transition, top_info());
4626 // TODO(fschneider): Record the new map type of the object in the IR to 4600 // TODO(fschneider): Record the new map type of the object in the IR to
4627 // enable elimination of redundant checks after the transition store. 4601 // enable elimination of redundant checks after the transition store.
4628 instr->SetGVNFlag(kChangesMaps); 4602 instr->SetGVNFlag(kChangesMaps);
4629 } 4603 }
4630 return instr; 4604 return instr;
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
4677 Property* expr, 4651 Property* expr,
4678 HValue* object, 4652 HValue* object,
4679 SmallMapList* types, 4653 SmallMapList* types,
4680 Handle<String> name) { 4654 Handle<String> name) {
4681 // Use monomorphic load if property lookup results in the same field index 4655 // Use monomorphic load if property lookup results in the same field index
4682 // for all maps. Requires special map check on the set of all handled maps. 4656 // for all maps. Requires special map check on the set of all handled maps.
4683 if (types->length() > kMaxLoadPolymorphism) return NULL; 4657 if (types->length() > kMaxLoadPolymorphism) return NULL;
4684 4658
4685 LookupResult lookup(isolate()); 4659 LookupResult lookup(isolate());
4686 int count; 4660 int count;
4687 Representation representation = Representation::None();
4688 HObjectAccess access = HObjectAccess::ForMap(); // initial value unused. 4661 HObjectAccess access = HObjectAccess::ForMap(); // initial value unused.
4689 for (count = 0; count < types->length(); ++count) { 4662 for (count = 0; count < types->length(); ++count) {
4690 Handle<Map> map = types->at(count); 4663 Handle<Map> map = types->at(count);
4691 if (!ComputeLoadStoreField(map, name, &lookup, false)) break; 4664 if (!ComputeLoadStoreField(map, name, &lookup, false)) break;
4692 4665
4693 HObjectAccess new_access = HObjectAccess::ForField(map, &lookup, name); 4666 HObjectAccess new_access = HObjectAccess::ForField(map, &lookup, name);
4694 Representation new_representation =
4695 ComputeLoadStoreRepresentation(map, &lookup);
4696 4667
4697 if (count == 0) { 4668 if (count == 0) {
4698 // First time through the loop; set access and representation. 4669 // First time through the loop; set access and representation.
4699 access = new_access; 4670 access = new_access;
4700 } else if (!representation.IsCompatibleForLoad(new_representation)) { 4671 } else if (!access.representation().IsCompatibleForLoad(
4672 new_access.representation())) {
4701 // Representations did not match. 4673 // Representations did not match.
4702 break; 4674 break;
4703 } else if (access.offset() != new_access.offset()) { 4675 } else if (access.offset() != new_access.offset()) {
4704 // Offsets did not match. 4676 // Offsets did not match.
4705 break; 4677 break;
4706 } else if (access.IsInobject() != new_access.IsInobject()) { 4678 } else if (access.IsInobject() != new_access.IsInobject()) {
4707 // In-objectness did not match. 4679 // In-objectness did not match.
4708 break; 4680 break;
4709 } 4681 }
4710 representation = representation.generalize(new_representation); 4682 access = access.WithRepresentation(
4683 access.representation().generalize(new_access.representation()));
4711 } 4684 }
4712 4685
4713 if (count == types->length()) { 4686 if (count == types->length()) {
4714 // Everything matched; can use monomorphic load. 4687 // Everything matched; can use monomorphic load.
4715 BuildCheckHeapObject(object); 4688 BuildCheckHeapObject(object);
4716 AddInstruction(HCheckMaps::New(object, types, zone())); 4689 AddInstruction(HCheckMaps::New(object, types, zone()));
4717 return BuildLoadNamedField(object, access, representation); 4690 return BuildLoadNamedField(object, access);
4718 } 4691 }
4719 4692
4720 if (count != 0) return NULL; 4693 if (count != 0) return NULL;
4721 4694
4722 // Second chance: the property is on the prototype and all maps have the 4695 // Second chance: the property is on the prototype and all maps have the
4723 // same prototype. 4696 // same prototype.
4724 Handle<Map> map(types->at(0)); 4697 Handle<Map> map(types->at(0));
4725 if (!CanLoadPropertyFromPrototype(map, name, &lookup)) return NULL; 4698 if (!CanLoadPropertyFromPrototype(map, name, &lookup)) return NULL;
4726 4699
4727 Handle<Object> prototype(map->prototype(), isolate()); 4700 Handle<Object> prototype(map->prototype(), isolate());
4728 for (count = 1; count < types->length(); ++count) { 4701 for (count = 1; count < types->length(); ++count) {
4729 Handle<Map> test_map(types->at(count)); 4702 Handle<Map> test_map(types->at(count));
4730 if (!CanLoadPropertyFromPrototype(test_map, name, &lookup)) return NULL; 4703 if (!CanLoadPropertyFromPrototype(test_map, name, &lookup)) return NULL;
4731 if (test_map->prototype() != *prototype) return NULL; 4704 if (test_map->prototype() != *prototype) return NULL;
4732 } 4705 }
4733 4706
4734 LookupInPrototypes(map, name, &lookup); 4707 LookupInPrototypes(map, name, &lookup);
4735 if (!lookup.IsField()) return NULL; 4708 if (!lookup.IsField()) return NULL;
4736 4709
4737 BuildCheckHeapObject(object); 4710 BuildCheckHeapObject(object);
4738 AddInstruction(HCheckMaps::New(object, types, zone())); 4711 AddInstruction(HCheckMaps::New(object, types, zone()));
4712
4739 Handle<JSObject> holder(lookup.holder()); 4713 Handle<JSObject> holder(lookup.holder());
4740 Handle<Map> holder_map(holder->map()); 4714 Handle<Map> holder_map(holder->map());
4741 AddInstruction(new(zone()) HCheckPrototypeMaps( 4715 AddInstruction(new(zone()) HCheckPrototypeMaps(
4742 Handle<JSObject>::cast(prototype), holder, zone(), top_info())); 4716 Handle<JSObject>::cast(prototype), holder, zone(), top_info()));
4743 HValue* holder_value = AddInstruction(new(zone()) HConstant(holder)); 4717 HValue* holder_value = AddInstruction(new(zone()) HConstant(holder));
4744 return BuildLoadNamedField(holder_value, 4718 return BuildLoadNamedField(holder_value,
4745 HObjectAccess::ForField(holder_map, &lookup, name), 4719 HObjectAccess::ForField(holder_map, &lookup, name));
4746 ComputeLoadStoreRepresentation(map, &lookup));
4747 } 4720 }
4748 4721
4749 4722
4750 void HOptimizedGraphBuilder::HandlePolymorphicLoadNamedField( 4723 void HOptimizedGraphBuilder::HandlePolymorphicLoadNamedField(
4751 Property* expr, 4724 Property* expr,
4752 HValue* object, 4725 HValue* object,
4753 SmallMapList* types, 4726 SmallMapList* types,
4754 Handle<String> name) { 4727 Handle<String> name) {
4755 HInstruction* instr = TryLoadPolymorphicAsMonomorphic( 4728 HInstruction* instr = TryLoadPolymorphicAsMonomorphic(
4756 expr, object, types, name); 4729 expr, object, types, name);
(...skipping 28 matching lines...) Expand all
4785 int count; 4758 int count;
4786 Representation representation = Representation::None(); 4759 Representation representation = Representation::None();
4787 HObjectAccess access = HObjectAccess::ForMap(); // initial value unused. 4760 HObjectAccess access = HObjectAccess::ForMap(); // initial value unused.
4788 for (count = 0; count < types->length(); ++count) { 4761 for (count = 0; count < types->length(); ++count) {
4789 Handle<Map> map = types->at(count); 4762 Handle<Map> map = types->at(count);
4790 // Pass false to ignore transitions. 4763 // Pass false to ignore transitions.
4791 if (!ComputeLoadStoreField(map, name, &lookup, false)) break; 4764 if (!ComputeLoadStoreField(map, name, &lookup, false)) break;
4792 ASSERT(!map->is_observed()); 4765 ASSERT(!map->is_observed());
4793 4766
4794 HObjectAccess new_access = HObjectAccess::ForField(map, &lookup, name); 4767 HObjectAccess new_access = HObjectAccess::ForField(map, &lookup, name);
4795 Representation new_representation = 4768 Representation new_representation = new_access.representation();
4796 ComputeLoadStoreRepresentation(map, &lookup);
4797 4769
4798 if (count == 0) { 4770 if (count == 0) {
4799 // First time through the loop; set access and representation. 4771 // First time through the loop; set access and representation.
4800 access = new_access; 4772 access = new_access;
4801 representation = new_representation; 4773 representation = new_representation;
4802 } else if (!representation.IsCompatibleForStore(new_representation)) { 4774 } else if (!representation.IsCompatibleForStore(new_representation)) {
4803 // Representations did not match. 4775 // Representations did not match.
4804 break; 4776 break;
4805 } else if (access.offset() != new_access.offset()) { 4777 } else if (access.offset() != new_access.offset()) {
4806 // Offsets did not match. 4778 // Offsets did not match.
(...skipping 10 matching lines...) Expand all
4817 BuildCheckHeapObject(object); 4789 BuildCheckHeapObject(object);
4818 AddInstruction(HCheckMaps::New(object, types, zone())); 4790 AddInstruction(HCheckMaps::New(object, types, zone()));
4819 HInstruction* store; 4791 HInstruction* store;
4820 CHECK_ALIVE_OR_RETURN( 4792 CHECK_ALIVE_OR_RETURN(
4821 store = BuildStoreNamedField( 4793 store = BuildStoreNamedField(
4822 object, name, store_value, types->at(count - 1), &lookup), 4794 object, name, store_value, types->at(count - 1), &lookup),
4823 true); 4795 true);
4824 if (!ast_context()->IsEffect()) Push(result_value); 4796 if (!ast_context()->IsEffect()) Push(result_value);
4825 store->set_position(position); 4797 store->set_position(position);
4826 AddInstruction(store); 4798 AddInstruction(store);
4827 AddSimulate(assignment_id); 4799 Add<HSimulate>(assignment_id);
4828 if (!ast_context()->IsEffect()) Drop(1); 4800 if (!ast_context()->IsEffect()) Drop(1);
4829 ast_context()->ReturnValue(result_value); 4801 ast_context()->ReturnValue(result_value);
4830 return true; 4802 return true;
4831 } 4803 }
4832 4804
4833 4805
4834 void HOptimizedGraphBuilder::HandlePolymorphicStoreNamedField( 4806 void HOptimizedGraphBuilder::HandlePolymorphicStoreNamedField(
4835 int position, 4807 int position,
4836 BailoutId assignment_id, 4808 BailoutId assignment_id,
4837 HValue* object, 4809 HValue* object,
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
4876 current_block()->Goto(join); 4848 current_block()->Goto(join);
4877 4849
4878 set_current_block(if_false); 4850 set_current_block(if_false);
4879 } 4851 }
4880 } 4852 }
4881 4853
4882 // Finish up. Unconditionally deoptimize if we've handled all the maps we 4854 // Finish up. Unconditionally deoptimize if we've handled all the maps we
4883 // know about and do not want to handle ones we've never seen. Otherwise 4855 // know about and do not want to handle ones we've never seen. Otherwise
4884 // use a generic IC. 4856 // use a generic IC.
4885 if (count == types->length() && FLAG_deoptimize_uncommon_cases) { 4857 if (count == types->length() && FLAG_deoptimize_uncommon_cases) {
4886 current_block()->FinishExitWithDeoptimization(HDeoptimize::kNoUses); 4858 FinishExitWithHardDeoptimization(join);
4887 } else { 4859 } else {
4888 HInstruction* instr = BuildStoreNamedGeneric(object, name, store_value); 4860 HInstruction* instr = BuildStoreNamedGeneric(object, name, store_value);
4889 instr->set_position(position); 4861 instr->set_position(position);
4890 AddInstruction(instr); 4862 AddInstruction(instr);
4891 4863
4892 if (join != NULL) { 4864 if (join != NULL) {
4893 if (!ast_context()->IsEffect()) { 4865 if (!ast_context()->IsEffect()) {
4894 Push(result_value); 4866 Push(result_value);
4895 } 4867 }
4896 current_block()->Goto(join); 4868 current_block()->Goto(join);
4897 } else { 4869 } else {
4898 // The HSimulate for the store should not see the stored value in 4870 // The HSimulate for the store should not see the stored value in
4899 // effect contexts (it is not materialized at expr->id() in the 4871 // effect contexts (it is not materialized at expr->id() in the
4900 // unoptimized code). 4872 // unoptimized code).
4901 if (instr->HasObservableSideEffects()) { 4873 if (instr->HasObservableSideEffects()) {
4902 if (ast_context()->IsEffect()) { 4874 if (ast_context()->IsEffect()) {
4903 AddSimulate(assignment_id, REMOVABLE_SIMULATE); 4875 Add<HSimulate>(assignment_id, REMOVABLE_SIMULATE);
4904 } else { 4876 } else {
4905 Push(result_value); 4877 Push(result_value);
4906 AddSimulate(assignment_id, REMOVABLE_SIMULATE); 4878 Add<HSimulate>(assignment_id, REMOVABLE_SIMULATE);
4907 Drop(1); 4879 Drop(1);
4908 } 4880 }
4909 } 4881 }
4910 return ast_context()->ReturnValue(result_value); 4882 return ast_context()->ReturnValue(result_value);
4911 } 4883 }
4912 } 4884 }
4913 4885
4914 ASSERT(join != NULL); 4886 ASSERT(join != NULL);
4915 join->SetJoinId(assignment_id); 4887 join->SetJoinId(assignment_id);
4916 set_current_block(join); 4888 set_current_block(join);
4917 if (!ast_context()->IsEffect()) { 4889 if (!ast_context()->IsEffect()) {
4918 ast_context()->ReturnValue(Pop()); 4890 ast_context()->ReturnValue(Pop());
4919 } 4891 }
4920 } 4892 }
4921 4893
4922 4894
4923 void HOptimizedGraphBuilder::HandlePropertyAssignment(Assignment* expr) { 4895 void HOptimizedGraphBuilder::HandlePropertyAssignment(Assignment* expr) {
4924 Property* prop = expr->target()->AsProperty(); 4896 Property* prop = expr->target()->AsProperty();
4925 ASSERT(prop != NULL); 4897 ASSERT(prop != NULL);
4926 CHECK_ALIVE(VisitForValue(prop->obj())); 4898 CHECK_ALIVE(VisitForValue(prop->obj()));
4927 4899
4928 if (prop->key()->IsPropertyName()) { 4900 if (prop->key()->IsPropertyName()) {
4929 // Named store. 4901 // Named store.
4930 CHECK_ALIVE(VisitForValue(expr->value())); 4902 CHECK_ALIVE(VisitForValue(expr->value()));
4931 HValue* value = environment()->ExpressionStackAt(0); 4903 HValue* value = environment()->ExpressionStackAt(0);
4932 HValue* object = environment()->ExpressionStackAt(1); 4904 HValue* object = environment()->ExpressionStackAt(1);
4933 4905
4934 if (expr->IsUninitialized()) AddSoftDeoptimize(); 4906 if (expr->IsUninitialized()) Add<HDeoptimize>(Deoptimizer::SOFT);
4935 return BuildStoreNamed(expr, expr->id(), expr->position(), 4907 return BuildStoreNamed(expr, expr->id(), expr->position(),
4936 expr->AssignmentId(), prop, object, value, value); 4908 expr->AssignmentId(), prop, object, value, value);
4937 } else { 4909 } else {
4938 // Keyed store. 4910 // Keyed store.
4939 CHECK_ALIVE(VisitForValue(prop->key())); 4911 CHECK_ALIVE(VisitForValue(prop->key()));
4940 CHECK_ALIVE(VisitForValue(expr->value())); 4912 CHECK_ALIVE(VisitForValue(expr->value()));
4941 HValue* value = environment()->ExpressionStackAt(0); 4913 HValue* value = environment()->ExpressionStackAt(0);
4942 HValue* key = environment()->ExpressionStackAt(1); 4914 HValue* key = environment()->ExpressionStackAt(1);
4943 HValue* object = environment()->ExpressionStackAt(2); 4915 HValue* object = environment()->ExpressionStackAt(2);
4944 bool has_side_effects = false; 4916 bool has_side_effects = false;
4945 HandleKeyedElementAccess(object, key, value, expr, expr->AssignmentId(), 4917 HandleKeyedElementAccess(object, key, value, expr, expr->AssignmentId(),
4946 expr->position(), 4918 expr->position(),
4947 true, // is_store 4919 true, // is_store
4948 &has_side_effects); 4920 &has_side_effects);
4949 Drop(3); 4921 Drop(3);
4950 Push(value); 4922 Push(value);
4951 AddSimulate(expr->AssignmentId(), REMOVABLE_SIMULATE); 4923 Add<HSimulate>(expr->AssignmentId(), REMOVABLE_SIMULATE);
4952 return ast_context()->ReturnValue(Pop()); 4924 return ast_context()->ReturnValue(Pop());
4953 } 4925 }
4954 } 4926 }
4955 4927
4956 4928
4957 // Because not every expression has a position and there is not common 4929 // Because not every expression has a position and there is not common
4958 // superclass of Assignment and CountOperation, we cannot just pass the 4930 // superclass of Assignment and CountOperation, we cannot just pass the
4959 // owning expression instead of position and ast_id separately. 4931 // owning expression instead of position and ast_id separately.
4960 void HOptimizedGraphBuilder::HandleGlobalVariableAssignment( 4932 void HOptimizedGraphBuilder::HandleGlobalVariableAssignment(
4961 Variable* var, 4933 Variable* var,
4962 HValue* value, 4934 HValue* value,
4963 int position, 4935 int position,
4964 BailoutId ast_id) { 4936 BailoutId ast_id) {
4965 LookupResult lookup(isolate()); 4937 LookupResult lookup(isolate());
4966 GlobalPropertyAccess type = LookupGlobalProperty(var, &lookup, true); 4938 GlobalPropertyAccess type = LookupGlobalProperty(var, &lookup, true);
4967 if (type == kUseCell) { 4939 if (type == kUseCell) {
4968 Handle<GlobalObject> global(current_info()->global_object()); 4940 Handle<GlobalObject> global(current_info()->global_object());
4969 Handle<PropertyCell> cell(global->GetPropertyCell(&lookup)); 4941 Handle<PropertyCell> cell(global->GetPropertyCell(&lookup));
4970 if (cell->type()->IsConstant()) { 4942 if (cell->type()->IsConstant()) {
4971 IfBuilder builder(this); 4943 IfBuilder builder(this);
4972 HValue* constant = Add<HConstant>(cell->type()->AsConstant()); 4944 HValue* constant = Add<HConstant>(cell->type()->AsConstant());
4973 if (cell->type()->AsConstant()->IsNumber()) { 4945 if (cell->type()->AsConstant()->IsNumber()) {
4974 builder.If<HCompareNumericAndBranch>(value, constant, Token::EQ); 4946 builder.If<HCompareNumericAndBranch>(value, constant, Token::EQ);
4975 } else { 4947 } else {
4976 builder.If<HCompareObjectEqAndBranch>(value, constant); 4948 builder.If<HCompareObjectEqAndBranch>(value, constant);
4977 } 4949 }
4978 builder.Then(); 4950 builder.Then();
4979 builder.Else(); 4951 builder.Else();
4980 AddSoftDeoptimize(MUST_EMIT_SOFT_DEOPT); 4952 Add<HDeoptimize>(Deoptimizer::EAGER);
4981 builder.End(); 4953 builder.End();
4982 } 4954 }
4983 HInstruction* instr = 4955 HInstruction* instr =
4984 Add<HStoreGlobalCell>(value, cell, lookup.GetPropertyDetails()); 4956 Add<HStoreGlobalCell>(value, cell, lookup.GetPropertyDetails());
4985 instr->set_position(position); 4957 instr->set_position(position);
4986 if (instr->HasObservableSideEffects()) { 4958 if (instr->HasObservableSideEffects()) {
4987 AddSimulate(ast_id, REMOVABLE_SIMULATE); 4959 Add<HSimulate>(ast_id, REMOVABLE_SIMULATE);
4988 } 4960 }
4989 } else { 4961 } else {
4990 HValue* context = environment()->LookupContext(); 4962 HValue* context = environment()->LookupContext();
4991 HGlobalObject* global_object = Add<HGlobalObject>(context); 4963 HGlobalObject* global_object = Add<HGlobalObject>(context);
4992 HStoreGlobalGeneric* instr = 4964 HStoreGlobalGeneric* instr =
4993 Add<HStoreGlobalGeneric>(context, global_object, var->name(), 4965 Add<HStoreGlobalGeneric>(context, global_object, var->name(),
4994 value, function_strict_mode_flag()); 4966 value, function_strict_mode_flag());
4995 instr->set_position(position); 4967 instr->set_position(position);
4996 ASSERT(instr->HasObservableSideEffects()); 4968 ASSERT(instr->HasObservableSideEffects());
4997 AddSimulate(ast_id, REMOVABLE_SIMULATE); 4969 Add<HSimulate>(ast_id, REMOVABLE_SIMULATE);
4998 } 4970 }
4999 } 4971 }
5000 4972
5001 4973
5002 void HOptimizedGraphBuilder::BuildStoreNamed(Expression* expr, 4974 void HOptimizedGraphBuilder::BuildStoreNamed(Expression* expr,
5003 BailoutId id, 4975 BailoutId id,
5004 int position, 4976 int position,
5005 BailoutId assignment_id, 4977 BailoutId assignment_id,
5006 Property* prop, 4978 Property* prop,
5007 HValue* object, 4979 HValue* object,
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
5049 store_value, result_value, types, name); 5021 store_value, result_value, types, name);
5050 } else { 5022 } else {
5051 Drop(2); 5023 Drop(2);
5052 instr = BuildStoreNamedGeneric(object, name, store_value); 5024 instr = BuildStoreNamedGeneric(object, name, store_value);
5053 } 5025 }
5054 5026
5055 if (!ast_context()->IsEffect()) Push(result_value); 5027 if (!ast_context()->IsEffect()) Push(result_value);
5056 instr->set_position(position); 5028 instr->set_position(position);
5057 AddInstruction(instr); 5029 AddInstruction(instr);
5058 if (instr->HasObservableSideEffects()) { 5030 if (instr->HasObservableSideEffects()) {
5059 AddSimulate(id, REMOVABLE_SIMULATE); 5031 Add<HSimulate>(id, REMOVABLE_SIMULATE);
5060 } 5032 }
5061 if (!ast_context()->IsEffect()) Drop(1); 5033 if (!ast_context()->IsEffect()) Drop(1);
5062 return ast_context()->ReturnValue(result_value); 5034 return ast_context()->ReturnValue(result_value);
5063 } 5035 }
5064 5036
5065 5037
5066 void HOptimizedGraphBuilder::HandleCompoundAssignment(Assignment* expr) { 5038 void HOptimizedGraphBuilder::HandleCompoundAssignment(Assignment* expr) {
5067 Expression* target = expr->target(); 5039 Expression* target = expr->target();
5068 VariableProxy* proxy = target->AsVariableProxy(); 5040 VariableProxy* proxy = target->AsVariableProxy();
5069 Property* prop = target->AsProperty(); 5041 Property* prop = target->AsProperty();
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
5127 // perform checks here 5099 // perform checks here
5128 UNREACHABLE(); 5100 UNREACHABLE();
5129 default: 5101 default:
5130 mode = HStoreContextSlot::kNoCheck; 5102 mode = HStoreContextSlot::kNoCheck;
5131 } 5103 }
5132 5104
5133 HValue* context = BuildContextChainWalk(var); 5105 HValue* context = BuildContextChainWalk(var);
5134 HStoreContextSlot* instr = Add<HStoreContextSlot>(context, var->index(), 5106 HStoreContextSlot* instr = Add<HStoreContextSlot>(context, var->index(),
5135 mode, Top()); 5107 mode, Top());
5136 if (instr->HasObservableSideEffects()) { 5108 if (instr->HasObservableSideEffects()) {
5137 AddSimulate(expr->AssignmentId(), REMOVABLE_SIMULATE); 5109 Add<HSimulate>(expr->AssignmentId(), REMOVABLE_SIMULATE);
5138 } 5110 }
5139 break; 5111 break;
5140 } 5112 }
5141 5113
5142 case Variable::LOOKUP: 5114 case Variable::LOOKUP:
5143 return Bailout("compound assignment to lookup slot"); 5115 return Bailout("compound assignment to lookup slot");
5144 } 5116 }
5145 return ast_context()->ReturnValue(Pop()); 5117 return ast_context()->ReturnValue(Pop());
5146 5118
5147 } else if (prop != NULL) { 5119 } else if (prop != NULL) {
(...skipping 20 matching lines...) Expand all
5168 load = BuildCallGetter(object, map, getter, holder); 5140 load = BuildCallGetter(object, map, getter, holder);
5169 } else { 5141 } else {
5170 load = BuildLoadNamedMonomorphic(object, name, prop, map); 5142 load = BuildLoadNamedMonomorphic(object, name, prop, map);
5171 } 5143 }
5172 } else if (types != NULL && types->length() > 1) { 5144 } else if (types != NULL && types->length() > 1) {
5173 load = TryLoadPolymorphicAsMonomorphic(prop, object, types, name); 5145 load = TryLoadPolymorphicAsMonomorphic(prop, object, types, name);
5174 } 5146 }
5175 if (load == NULL) load = BuildLoadNamedGeneric(object, name, prop); 5147 if (load == NULL) load = BuildLoadNamedGeneric(object, name, prop);
5176 PushAndAdd(load); 5148 PushAndAdd(load);
5177 if (load->HasObservableSideEffects()) { 5149 if (load->HasObservableSideEffects()) {
5178 AddSimulate(prop->LoadId(), REMOVABLE_SIMULATE); 5150 Add<HSimulate>(prop->LoadId(), REMOVABLE_SIMULATE);
5179 } 5151 }
5180 5152
5181 CHECK_ALIVE(VisitForValue(expr->value())); 5153 CHECK_ALIVE(VisitForValue(expr->value()));
5182 HValue* right = Pop(); 5154 HValue* right = Pop();
5183 HValue* left = Pop(); 5155 HValue* left = Pop();
5184 5156
5185 HInstruction* instr = BuildBinaryOperation(operation, left, right); 5157 HInstruction* instr = BuildBinaryOperation(operation, left, right);
5186 PushAndAdd(instr); 5158 PushAndAdd(instr);
5187 if (instr->HasObservableSideEffects()) { 5159 if (instr->HasObservableSideEffects()) {
5188 AddSimulate(operation->id(), REMOVABLE_SIMULATE); 5160 Add<HSimulate>(operation->id(), REMOVABLE_SIMULATE);
5189 } 5161 }
5190 5162
5191 return BuildStoreNamed(prop, expr->id(), expr->position(), 5163 return BuildStoreNamed(prop, expr->id(), expr->position(),
5192 expr->AssignmentId(), prop, object, instr, instr); 5164 expr->AssignmentId(), prop, object, instr, instr);
5193 } else { 5165 } else {
5194 // Keyed property. 5166 // Keyed property.
5195 CHECK_ALIVE(VisitForValue(prop->obj())); 5167 CHECK_ALIVE(VisitForValue(prop->obj()));
5196 CHECK_ALIVE(VisitForValue(prop->key())); 5168 CHECK_ALIVE(VisitForValue(prop->key()));
5197 HValue* obj = environment()->ExpressionStackAt(1); 5169 HValue* obj = environment()->ExpressionStackAt(1);
5198 HValue* key = environment()->ExpressionStackAt(0); 5170 HValue* key = environment()->ExpressionStackAt(0);
5199 5171
5200 bool has_side_effects = false; 5172 bool has_side_effects = false;
5201 HValue* load = HandleKeyedElementAccess( 5173 HValue* load = HandleKeyedElementAccess(
5202 obj, key, NULL, prop, prop->LoadId(), RelocInfo::kNoPosition, 5174 obj, key, NULL, prop, prop->LoadId(), RelocInfo::kNoPosition,
5203 false, // is_store 5175 false, // is_store
5204 &has_side_effects); 5176 &has_side_effects);
5205 Push(load); 5177 Push(load);
5206 if (has_side_effects) AddSimulate(prop->LoadId(), REMOVABLE_SIMULATE); 5178 if (has_side_effects) Add<HSimulate>(prop->LoadId(), REMOVABLE_SIMULATE);
5207 5179
5208 CHECK_ALIVE(VisitForValue(expr->value())); 5180 CHECK_ALIVE(VisitForValue(expr->value()));
5209 HValue* right = Pop(); 5181 HValue* right = Pop();
5210 HValue* left = Pop(); 5182 HValue* left = Pop();
5211 5183
5212 HInstruction* instr = BuildBinaryOperation(operation, left, right); 5184 HInstruction* instr = BuildBinaryOperation(operation, left, right);
5213 PushAndAdd(instr); 5185 PushAndAdd(instr);
5214 if (instr->HasObservableSideEffects()) { 5186 if (instr->HasObservableSideEffects()) {
5215 AddSimulate(operation->id(), REMOVABLE_SIMULATE); 5187 Add<HSimulate>(operation->id(), REMOVABLE_SIMULATE);
5216 } 5188 }
5217 5189
5218 HandleKeyedElementAccess(obj, key, instr, expr, expr->AssignmentId(), 5190 HandleKeyedElementAccess(obj, key, instr, expr, expr->AssignmentId(),
5219 RelocInfo::kNoPosition, 5191 RelocInfo::kNoPosition,
5220 true, // is_store 5192 true, // is_store
5221 &has_side_effects); 5193 &has_side_effects);
5222 5194
5223 // Drop the simulated receiver, key, and value. Return the value. 5195 // Drop the simulated receiver, key, and value. Return the value.
5224 Drop(3); 5196 Drop(3);
5225 Push(instr); 5197 Push(instr);
5226 ASSERT(has_side_effects); // Stores always have side effects. 5198 ASSERT(has_side_effects); // Stores always have side effects.
5227 AddSimulate(expr->AssignmentId(), REMOVABLE_SIMULATE); 5199 Add<HSimulate>(expr->AssignmentId(), REMOVABLE_SIMULATE);
5228 return ast_context()->ReturnValue(Pop()); 5200 return ast_context()->ReturnValue(Pop());
5229 } 5201 }
5230 5202
5231 } else { 5203 } else {
5232 return Bailout("invalid lhs in compound assignment"); 5204 return Bailout("invalid lhs in compound assignment");
5233 } 5205 }
5234 } 5206 }
5235 5207
5236 5208
5237 void HOptimizedGraphBuilder::VisitAssignment(Assignment* expr) { 5209 void HOptimizedGraphBuilder::VisitAssignment(Assignment* expr) {
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
5339 } else { 5311 } else {
5340 ASSERT(expr->op() == Token::INIT_CONST); 5312 ASSERT(expr->op() == Token::INIT_CONST);
5341 5313
5342 mode = HStoreContextSlot::kCheckIgnoreAssignment; 5314 mode = HStoreContextSlot::kCheckIgnoreAssignment;
5343 } 5315 }
5344 5316
5345 HValue* context = BuildContextChainWalk(var); 5317 HValue* context = BuildContextChainWalk(var);
5346 HStoreContextSlot* instr = Add<HStoreContextSlot>(context, var->index(), 5318 HStoreContextSlot* instr = Add<HStoreContextSlot>(context, var->index(),
5347 mode, Top()); 5319 mode, Top());
5348 if (instr->HasObservableSideEffects()) { 5320 if (instr->HasObservableSideEffects()) {
5349 AddSimulate(expr->AssignmentId(), REMOVABLE_SIMULATE); 5321 Add<HSimulate>(expr->AssignmentId(), REMOVABLE_SIMULATE);
5350 } 5322 }
5351 return ast_context()->ReturnValue(Pop()); 5323 return ast_context()->ReturnValue(Pop());
5352 } 5324 }
5353 5325
5354 case Variable::LOOKUP: 5326 case Variable::LOOKUP:
5355 return Bailout("assignment to LOOKUP variable"); 5327 return Bailout("assignment to LOOKUP variable");
5356 } 5328 }
5357 } else { 5329 } else {
5358 return Bailout("invalid left-hand side in assignment"); 5330 return Bailout("invalid left-hand side in assignment");
5359 } 5331 }
(...skipping 13 matching lines...) Expand all
5373 // We don't optimize functions with invalid left-hand sides in 5345 // We don't optimize functions with invalid left-hand sides in
5374 // assignments, count operations, or for-in. Consequently throw can 5346 // assignments, count operations, or for-in. Consequently throw can
5375 // currently only occur in an effect context. 5347 // currently only occur in an effect context.
5376 ASSERT(ast_context()->IsEffect()); 5348 ASSERT(ast_context()->IsEffect());
5377 CHECK_ALIVE(VisitForValue(expr->exception())); 5349 CHECK_ALIVE(VisitForValue(expr->exception()));
5378 5350
5379 HValue* context = environment()->LookupContext(); 5351 HValue* context = environment()->LookupContext();
5380 HValue* value = environment()->Pop(); 5352 HValue* value = environment()->Pop();
5381 HThrow* instr = Add<HThrow>(context, value); 5353 HThrow* instr = Add<HThrow>(context, value);
5382 instr->set_position(expr->position()); 5354 instr->set_position(expr->position());
5383 AddSimulate(expr->id()); 5355 Add<HSimulate>(expr->id());
5384 current_block()->FinishExit(new(zone()) HAbnormalExit); 5356 current_block()->FinishExit(new(zone()) HAbnormalExit);
5385 set_current_block(NULL); 5357 set_current_block(NULL);
5386 } 5358 }
5387 5359
5388 5360
5389 HLoadNamedField* HGraphBuilder::BuildLoadNamedField( 5361 HLoadNamedField* HGraphBuilder::BuildLoadNamedField(HValue* object,
5390 HValue* object, 5362 HObjectAccess access) {
5391 HObjectAccess access, 5363 if (FLAG_track_double_fields && access.representation().IsDouble()) {
5392 Representation representation) { 5364 // load the heap number
5393 bool load_double = false; 5365 HLoadNamedField* heap_number =
5394 if (representation.IsDouble()) { 5366 AddLoad(object, access.WithRepresentation(Representation::Tagged()));
5395 representation = Representation::Tagged(); 5367 heap_number->set_type(HType::HeapNumber());
5396 load_double = FLAG_track_double_fields; 5368 // load the double value from it
5369 return new(zone()) HLoadNamedField(heap_number,
5370 HObjectAccess::ForHeapNumberValue(), NULL);
5397 } 5371 }
5398 HLoadNamedField* field = 5372 return new(zone()) HLoadNamedField(object, access, NULL);
5399 new(zone()) HLoadNamedField(object, access, NULL, representation);
5400 if (load_double) {
5401 AddInstruction(field);
5402 field->set_type(HType::HeapNumber());
5403 return new(zone()) HLoadNamedField(field,
5404 HObjectAccess::ForHeapNumberValue(), NULL, Representation::Double());
5405 }
5406 return field;
5407 } 5373 }
5408 5374
5409 5375
5410 HInstruction* HOptimizedGraphBuilder::BuildLoadNamedGeneric( 5376 HInstruction* HOptimizedGraphBuilder::BuildLoadNamedGeneric(
5411 HValue* object, 5377 HValue* object,
5412 Handle<String> name, 5378 Handle<String> name,
5413 Property* expr) { 5379 Property* expr) {
5414 if (expr->IsUninitialized()) { 5380 if (expr->IsUninitialized()) {
5415 AddSoftDeoptimize(); 5381 Add<HDeoptimize>(Deoptimizer::SOFT);
5416 } 5382 }
5417 HValue* context = environment()->LookupContext(); 5383 HValue* context = environment()->LookupContext();
5418 return new(zone()) HLoadNamedGeneric(context, object, name); 5384 return new(zone()) HLoadNamedGeneric(context, object, name);
5419 } 5385 }
5420 5386
5421 5387
5422 HInstruction* HOptimizedGraphBuilder::BuildCallGetter( 5388 HInstruction* HOptimizedGraphBuilder::BuildCallGetter(
5423 HValue* object, 5389 HValue* object,
5424 Handle<Map> map, 5390 Handle<Map> map,
5425 Handle<JSFunction> getter, 5391 Handle<JSFunction> getter,
(...skipping 10 matching lines...) Expand all
5436 Property* expr, 5402 Property* expr,
5437 Handle<Map> map) { 5403 Handle<Map> map) {
5438 // Handle a load from a known field. 5404 // Handle a load from a known field.
5439 ASSERT(!map->is_dictionary_map()); 5405 ASSERT(!map->is_dictionary_map());
5440 5406
5441 // Handle access to various length properties 5407 // Handle access to various length properties
5442 if (name->Equals(isolate()->heap()->length_string())) { 5408 if (name->Equals(isolate()->heap()->length_string())) {
5443 if (map->instance_type() == JS_ARRAY_TYPE) { 5409 if (map->instance_type() == JS_ARRAY_TYPE) {
5444 AddCheckMapsWithTransitions(object, map); 5410 AddCheckMapsWithTransitions(object, map);
5445 return new(zone()) HLoadNamedField(object, 5411 return new(zone()) HLoadNamedField(object,
5446 HObjectAccess::ForArrayLength()); 5412 HObjectAccess::ForArrayLength(map->elements_kind()));
5447 } 5413 }
5448 } 5414 }
5449 5415
5450 LookupResult lookup(isolate()); 5416 LookupResult lookup(isolate());
5451 map->LookupDescriptor(NULL, *name, &lookup); 5417 map->LookupDescriptor(NULL, *name, &lookup);
5452 if (lookup.IsField()) { 5418 if (lookup.IsField()) {
5453 AddCheckMap(object, map); 5419 AddCheckMap(object, map);
5454 return BuildLoadNamedField(object, 5420 return BuildLoadNamedField(object,
5455 HObjectAccess::ForField(map, &lookup, name), 5421 HObjectAccess::ForField(map, &lookup, name));
5456 ComputeLoadStoreRepresentation(map, &lookup));
5457 } 5422 }
5458 5423
5459 // Handle a load of a constant known function. 5424 // Handle a load of a constant known function.
5460 if (lookup.IsConstantFunction()) { 5425 if (lookup.IsConstant()) {
5461 AddCheckMap(object, map); 5426 AddCheckMap(object, map);
5462 Handle<JSFunction> function(lookup.GetConstantFunctionFromMap(*map)); 5427 Handle<Object> constant(lookup.GetConstantFromMap(*map), isolate());
5463 return new(zone()) HConstant(function); 5428 return new(zone()) HConstant(constant);
5464 } 5429 }
5465 5430
5466 // Handle a load from a known field somewhere in the prototype chain. 5431 // Handle a load from a known field somewhere in the prototype chain.
5467 LookupInPrototypes(map, name, &lookup); 5432 LookupInPrototypes(map, name, &lookup);
5468 if (lookup.IsField()) { 5433 if (lookup.IsField()) {
5469 Handle<JSObject> prototype(JSObject::cast(map->prototype())); 5434 Handle<JSObject> prototype(JSObject::cast(map->prototype()));
5470 Handle<JSObject> holder(lookup.holder()); 5435 Handle<JSObject> holder(lookup.holder());
5471 Handle<Map> holder_map(holder->map()); 5436 Handle<Map> holder_map(holder->map());
5472 AddCheckMap(object, map); 5437 AddCheckMap(object, map);
5473 Add<HCheckPrototypeMaps>(prototype, holder, zone(), top_info()); 5438 Add<HCheckPrototypeMaps>(prototype, holder, zone(), top_info());
5474 HValue* holder_value = Add<HConstant>(holder); 5439 HValue* holder_value = Add<HConstant>(holder);
5475 return BuildLoadNamedField(holder_value, 5440 return BuildLoadNamedField(holder_value,
5476 HObjectAccess::ForField(holder_map, &lookup, name), 5441 HObjectAccess::ForField(holder_map, &lookup, name));
5477 ComputeLoadStoreRepresentation(map, &lookup));
5478 } 5442 }
5479 5443
5480 // Handle a load of a constant function somewhere in the prototype chain. 5444 // Handle a load of a constant function somewhere in the prototype chain.
5481 if (lookup.IsConstantFunction()) { 5445 if (lookup.IsConstant()) {
5482 Handle<JSObject> prototype(JSObject::cast(map->prototype())); 5446 Handle<JSObject> prototype(JSObject::cast(map->prototype()));
5483 Handle<JSObject> holder(lookup.holder()); 5447 Handle<JSObject> holder(lookup.holder());
5484 Handle<Map> holder_map(holder->map()); 5448 Handle<Map> holder_map(holder->map());
5485 AddCheckMap(object, map); 5449 AddCheckMap(object, map);
5486 Add<HCheckPrototypeMaps>(prototype, holder, zone(), top_info()); 5450 Add<HCheckPrototypeMaps>(prototype, holder, zone(), top_info());
5487 Handle<JSFunction> function(lookup.GetConstantFunctionFromMap(*holder_map)); 5451 Handle<Object> constant(lookup.GetConstantFromMap(*holder_map), isolate());
5488 return new(zone()) HConstant(function); 5452 return new(zone()) HConstant(constant);
5489 } 5453 }
5490 5454
5491 // No luck, do a generic load. 5455 // No luck, do a generic load.
5492 return BuildLoadNamedGeneric(object, name, expr); 5456 return BuildLoadNamedGeneric(object, name, expr);
5493 } 5457 }
5494 5458
5495 5459
5496 HInstruction* HOptimizedGraphBuilder::BuildLoadKeyedGeneric(HValue* object, 5460 HInstruction* HOptimizedGraphBuilder::BuildLoadKeyedGeneric(HValue* object,
5497 HValue* key) { 5461 HValue* key) {
5498 HValue* context = environment()->LookupContext(); 5462 HValue* context = environment()->LookupContext();
5499 return new(zone()) HLoadKeyedGeneric(context, object, key); 5463 return new(zone()) HLoadKeyedGeneric(context, object, key);
5500 } 5464 }
5501 5465
5502 5466
5503 HInstruction* HOptimizedGraphBuilder::BuildMonomorphicElementAccess( 5467 HInstruction* HOptimizedGraphBuilder::BuildMonomorphicElementAccess(
5504 HValue* object, 5468 HValue* object,
5505 HValue* key, 5469 HValue* key,
5506 HValue* val, 5470 HValue* val,
5507 HValue* dependency, 5471 HValue* dependency,
5508 Handle<Map> map, 5472 Handle<Map> map,
5509 bool is_store, 5473 bool is_store,
5510 KeyedAccessStoreMode store_mode) { 5474 KeyedAccessStoreMode store_mode) {
5511 HCheckMaps* mapcheck = HCheckMaps::New(object, map, zone(), dependency); 5475 HCheckMaps* mapcheck = HCheckMaps::New(
5476 object, map, zone(), top_info(), dependency);
5512 AddInstruction(mapcheck); 5477 AddInstruction(mapcheck);
5513 if (dependency) { 5478 if (dependency) {
5514 mapcheck->ClearGVNFlag(kDependsOnElementsKind); 5479 mapcheck->ClearGVNFlag(kDependsOnElementsKind);
5515 } 5480 }
5516 5481
5517 // Loads from a "stock" fast holey double arrays can elide the hole check. 5482 // Loads from a "stock" fast holey double arrays can elide the hole check.
5518 LoadKeyedHoleMode load_mode = NEVER_RETURN_HOLE; 5483 LoadKeyedHoleMode load_mode = NEVER_RETURN_HOLE;
5519 if (*map == isolate()->get_initial_js_array_map(FAST_HOLEY_DOUBLE_ELEMENTS) && 5484 if (*map == isolate()->get_initial_js_array_map(FAST_HOLEY_DOUBLE_ELEMENTS) &&
5520 isolate()->IsFastArrayConstructorPrototypeChainIntact()) { 5485 isolate()->IsFastArrayConstructorPrototypeChainIntact()) {
5521 Handle<JSObject> prototype(JSObject::cast(map->prototype()), isolate()); 5486 Handle<JSObject> prototype(JSObject::cast(map->prototype()), isolate());
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after
5685 new(zone()) HCompareMap(object, map, this_map, other_map); 5650 new(zone()) HCompareMap(object, map, this_map, other_map);
5686 current_block()->Finish(mapcompare); 5651 current_block()->Finish(mapcompare);
5687 5652
5688 set_current_block(this_map); 5653 set_current_block(this_map);
5689 HInstruction* checked_key = NULL; 5654 HInstruction* checked_key = NULL;
5690 HInstruction* access = NULL; 5655 HInstruction* access = NULL;
5691 if (IsFastElementsKind(elements_kind)) { 5656 if (IsFastElementsKind(elements_kind)) {
5692 if (is_store && !IsFastDoubleElementsKind(elements_kind)) { 5657 if (is_store && !IsFastDoubleElementsKind(elements_kind)) {
5693 AddInstruction(HCheckMaps::New( 5658 AddInstruction(HCheckMaps::New(
5694 elements, isolate()->factory()->fixed_array_map(), 5659 elements, isolate()->factory()->fixed_array_map(),
5695 zone(), mapcompare)); 5660 zone(), top_info(), mapcompare));
5696 } 5661 }
5697 if (map->IsJSArray()) { 5662 if (map->instance_type() == JS_ARRAY_TYPE) {
5698 HInstruction* length = AddLoad(object, HObjectAccess::ForArrayLength(), 5663 HInstruction* length = AddLoad(
5699 mapcompare, Representation::Smi()); 5664 object, HObjectAccess::ForArrayLength(elements_kind), mapcompare);
5700 length->set_type(HType::Smi());
5701 checked_key = Add<HBoundsCheck>(key, length); 5665 checked_key = Add<HBoundsCheck>(key, length);
5702 } else { 5666 } else {
5703 HInstruction* length = AddLoadFixedArrayLength(elements); 5667 HInstruction* length = AddLoadFixedArrayLength(elements);
5704 checked_key = Add<HBoundsCheck>(key, length); 5668 checked_key = Add<HBoundsCheck>(key, length);
5705 } 5669 }
5706 access = AddFastElementAccess( 5670 access = AddFastElementAccess(
5707 elements, checked_key, val, mapcompare, 5671 elements, checked_key, val, mapcompare,
5708 elements_kind, is_store, NEVER_RETURN_HOLE, STANDARD_STORE); 5672 elements_kind, is_store, NEVER_RETURN_HOLE, STANDARD_STORE);
5709 } else if (IsDictionaryElementsKind(elements_kind)) { 5673 } else if (IsDictionaryElementsKind(elements_kind)) {
5710 if (is_store) { 5674 if (is_store) {
(...skipping 16 matching lines...) Expand all
5727 access->SetFlag(HValue::kHasNoObservableSideEffects); 5691 access->SetFlag(HValue::kHasNoObservableSideEffects);
5728 if (position != RelocInfo::kNoPosition) access->set_position(position); 5692 if (position != RelocInfo::kNoPosition) access->set_position(position);
5729 if (!is_store) { 5693 if (!is_store) {
5730 Push(access); 5694 Push(access);
5731 } 5695 }
5732 current_block()->GotoNoSimulate(join); 5696 current_block()->GotoNoSimulate(join);
5733 set_current_block(other_map); 5697 set_current_block(other_map);
5734 } 5698 }
5735 5699
5736 // Deopt if none of the cases matched. 5700 // Deopt if none of the cases matched.
5737 current_block()->FinishExitWithDeoptimization(HDeoptimize::kNoUses); 5701 NoObservableSideEffectsScope scope(this);
5702 FinishExitWithHardDeoptimization(join);
5738 set_current_block(join); 5703 set_current_block(join);
5739 return is_store ? NULL : Pop(); 5704 return is_store ? NULL : Pop();
5740 } 5705 }
5741 5706
5742 5707
5743 HValue* HOptimizedGraphBuilder::HandleKeyedElementAccess( 5708 HValue* HOptimizedGraphBuilder::HandleKeyedElementAccess(
5744 HValue* obj, 5709 HValue* obj,
5745 HValue* key, 5710 HValue* key,
5746 HValue* val, 5711 HValue* val,
5747 Expression* expr, 5712 Expression* expr,
(...skipping 15 matching lines...) Expand all
5763 obj, key, val, NULL, map, is_store, expr->GetStoreMode()); 5728 obj, key, val, NULL, map, is_store, expr->GetStoreMode());
5764 } 5729 }
5765 } else if (expr->GetReceiverTypes() != NULL && 5730 } else if (expr->GetReceiverTypes() != NULL &&
5766 !expr->GetReceiverTypes()->is_empty()) { 5731 !expr->GetReceiverTypes()->is_empty()) {
5767 return HandlePolymorphicElementAccess( 5732 return HandlePolymorphicElementAccess(
5768 obj, key, val, expr, ast_id, position, is_store, 5733 obj, key, val, expr, ast_id, position, is_store,
5769 expr->GetStoreMode(), has_side_effects); 5734 expr->GetStoreMode(), has_side_effects);
5770 } else { 5735 } else {
5771 if (is_store) { 5736 if (is_store) {
5772 if (expr->IsAssignment() && expr->AsAssignment()->IsUninitialized()) { 5737 if (expr->IsAssignment() && expr->AsAssignment()->IsUninitialized()) {
5773 AddSoftDeoptimize(); 5738 Add<HDeoptimize>(Deoptimizer::SOFT);
5774 } 5739 }
5775 instr = BuildStoreKeyedGeneric(obj, key, val); 5740 instr = BuildStoreKeyedGeneric(obj, key, val);
5776 } else { 5741 } else {
5777 if (expr->AsProperty()->IsUninitialized()) { 5742 if (expr->AsProperty()->IsUninitialized()) {
5778 AddSoftDeoptimize(); 5743 Add<HDeoptimize>(Deoptimizer::SOFT);
5779 } 5744 }
5780 instr = BuildLoadKeyedGeneric(obj, key); 5745 instr = BuildLoadKeyedGeneric(obj, key);
5781 } 5746 }
5782 AddInstruction(instr); 5747 AddInstruction(instr);
5783 } 5748 }
5784 if (position != RelocInfo::kNoPosition) instr->set_position(position); 5749 if (position != RelocInfo::kNoPosition) instr->set_position(position);
5785 *has_side_effects = instr->HasObservableSideEffects(); 5750 *has_side_effects = instr->HasObservableSideEffects();
5786 return instr; 5751 return instr;
5787 } 5752 }
5788 5753
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after
5947 HValue* key = Pop(); 5912 HValue* key = Pop();
5948 HValue* obj = Pop(); 5913 HValue* obj = Pop();
5949 5914
5950 bool has_side_effects = false; 5915 bool has_side_effects = false;
5951 HValue* load = HandleKeyedElementAccess( 5916 HValue* load = HandleKeyedElementAccess(
5952 obj, key, NULL, expr, expr->id(), expr->position(), 5917 obj, key, NULL, expr, expr->id(), expr->position(),
5953 false, // is_store 5918 false, // is_store
5954 &has_side_effects); 5919 &has_side_effects);
5955 if (has_side_effects) { 5920 if (has_side_effects) {
5956 if (ast_context()->IsEffect()) { 5921 if (ast_context()->IsEffect()) {
5957 AddSimulate(expr->id(), REMOVABLE_SIMULATE); 5922 Add<HSimulate>(expr->id(), REMOVABLE_SIMULATE);
5958 } else { 5923 } else {
5959 Push(load); 5924 Push(load);
5960 AddSimulate(expr->id(), REMOVABLE_SIMULATE); 5925 Add<HSimulate>(expr->id(), REMOVABLE_SIMULATE);
5961 Drop(1); 5926 Drop(1);
5962 } 5927 }
5963 } 5928 }
5964 return ast_context()->ReturnValue(load); 5929 return ast_context()->ReturnValue(load);
5965 } 5930 }
5966 instr->set_position(expr->position()); 5931 instr->set_position(expr->position());
5967 return ast_context()->ReturnInstruction(instr, expr->id()); 5932 return ast_context()->ReturnInstruction(instr, expr->id());
5968 } 5933 }
5969 5934
5970 5935
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
6052 } 6017 }
6053 6018
6054 if (!TryInlineCall(expr)) { 6019 if (!TryInlineCall(expr)) {
6055 int argument_count = expr->arguments()->length() + 1; // Includes receiver. 6020 int argument_count = expr->arguments()->length() + 1; // Includes receiver.
6056 HCallConstantFunction* call = 6021 HCallConstantFunction* call =
6057 new(zone()) HCallConstantFunction(expr->target(), argument_count); 6022 new(zone()) HCallConstantFunction(expr->target(), argument_count);
6058 call->set_position(expr->position()); 6023 call->set_position(expr->position());
6059 PreProcessCall(call); 6024 PreProcessCall(call);
6060 AddInstruction(call); 6025 AddInstruction(call);
6061 if (!ast_context()->IsEffect()) Push(call); 6026 if (!ast_context()->IsEffect()) Push(call);
6062 AddSimulate(expr->id(), REMOVABLE_SIMULATE); 6027 Add<HSimulate>(expr->id(), REMOVABLE_SIMULATE);
6063 if (!ast_context()->IsEffect()) ast_context()->ReturnValue(Pop()); 6028 if (!ast_context()->IsEffect()) ast_context()->ReturnValue(Pop());
6064 } 6029 }
6065 6030
6066 return true; 6031 return true;
6067 } 6032 }
6068 6033
6069 6034
6070 void HOptimizedGraphBuilder::HandlePolymorphicCallNamed( 6035 void HOptimizedGraphBuilder::HandlePolymorphicCallNamed(
6071 Call* expr, 6036 Call* expr,
6072 HValue* receiver, 6037 HValue* receiver,
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
6184 } 6149 }
6185 6150
6186 if (current_block() != NULL) current_block()->Goto(join); 6151 if (current_block() != NULL) current_block()->Goto(join);
6187 set_current_block(if_false); 6152 set_current_block(if_false);
6188 } 6153 }
6189 6154
6190 // Finish up. Unconditionally deoptimize if we've handled all the maps we 6155 // Finish up. Unconditionally deoptimize if we've handled all the maps we
6191 // know about and do not want to handle ones we've never seen. Otherwise 6156 // know about and do not want to handle ones we've never seen. Otherwise
6192 // use a generic IC. 6157 // use a generic IC.
6193 if (ordered_functions == types->length() && FLAG_deoptimize_uncommon_cases) { 6158 if (ordered_functions == types->length() && FLAG_deoptimize_uncommon_cases) {
6194 current_block()->FinishExitWithDeoptimization(HDeoptimize::kNoUses); 6159 // Because the deopt may be the only path in the polymorphic call, make sure
6160 // that the environment stack matches the depth on deopt that it otherwise
6161 // would have had after a successful call.
6162 Drop(argument_count - (ast_context()->IsEffect() ? 0 : 1));
6163 FinishExitWithHardDeoptimization(join);
6195 } else { 6164 } else {
6196 HValue* context = environment()->LookupContext(); 6165 HValue* context = environment()->LookupContext();
6197 HCallNamed* call = new(zone()) HCallNamed(context, name, argument_count); 6166 HCallNamed* call = new(zone()) HCallNamed(context, name, argument_count);
6198 call->set_position(expr->position()); 6167 call->set_position(expr->position());
6199 PreProcessCall(call); 6168 PreProcessCall(call);
6200 6169
6201 if (join != NULL) { 6170 if (join != NULL) {
6202 AddInstruction(call); 6171 AddInstruction(call);
6203 if (!ast_context()->IsEffect()) Push(call); 6172 if (!ast_context()->IsEffect()) Push(call);
6204 current_block()->Goto(join); 6173 current_block()->Goto(join);
(...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after
6442 #if V8_TARGET_ARCH_IA32 6411 #if V8_TARGET_ARCH_IA32
6443 // IA32 only, overwrite the caller's context in the deoptimization 6412 // IA32 only, overwrite the caller's context in the deoptimization
6444 // environment with the correct one. 6413 // environment with the correct one.
6445 // 6414 //
6446 // TODO(kmillikin): implement the same inlining on other platforms so we 6415 // TODO(kmillikin): implement the same inlining on other platforms so we
6447 // can remove the unsightly ifdefs in this function. 6416 // can remove the unsightly ifdefs in this function.
6448 HConstant* context = Add<HConstant>(Handle<Context>(target->context())); 6417 HConstant* context = Add<HConstant>(Handle<Context>(target->context()));
6449 inner_env->BindContext(context); 6418 inner_env->BindContext(context);
6450 #endif 6419 #endif
6451 6420
6452 AddSimulate(return_id); 6421 Add<HSimulate>(return_id);
6453 current_block()->UpdateEnvironment(inner_env); 6422 current_block()->UpdateEnvironment(inner_env);
6454 HArgumentsObject* arguments_object = NULL; 6423 HArgumentsObject* arguments_object = NULL;
6455 6424
6456 // If the function uses arguments object create and bind one, also copy 6425 // If the function uses arguments object create and bind one, also copy
6457 // current arguments values to use them for materialization. 6426 // current arguments values to use them for materialization.
6458 if (function->scope()->arguments() != NULL) { 6427 if (function->scope()->arguments() != NULL) {
6459 ASSERT(function->scope()->arguments()->IsStackAllocated()); 6428 ASSERT(function->scope()->arguments()->IsStackAllocated());
6460 HEnvironment* arguments_env = inner_env->arguments_environment(); 6429 HEnvironment* arguments_env = inner_env->arguments_environment();
6461 int arguments_count = arguments_env->parameter_count(); 6430 int arguments_count = arguments_env->parameter_count();
6462 arguments_object = Add<HArgumentsObject>(arguments_count, zone()); 6431 arguments_object = Add<HArgumentsObject>(arguments_count, zone());
(...skipping 413 matching lines...) Expand 10 before | Expand all | Expand 10 after
6876 AddCheckConstantFunction(expr->holder(), function, function_map); 6845 AddCheckConstantFunction(expr->holder(), function, function_map);
6877 Drop(1); 6846 Drop(1);
6878 6847
6879 VisitForValue(args->at(0)); 6848 VisitForValue(args->at(0));
6880 if (HasStackOverflow() || current_block() == NULL) return true; 6849 if (HasStackOverflow() || current_block() == NULL) return true;
6881 HValue* receiver = Pop(); 6850 HValue* receiver = Pop();
6882 6851
6883 if (function_state()->outer() == NULL) { 6852 if (function_state()->outer() == NULL) {
6884 HInstruction* elements = Add<HArgumentsElements>(false); 6853 HInstruction* elements = Add<HArgumentsElements>(false);
6885 HInstruction* length = Add<HArgumentsLength>(elements); 6854 HInstruction* length = Add<HArgumentsLength>(elements);
6886 HValue* wrapped_receiver = Add<HWrapReceiver>(receiver, function); 6855 HValue* wrapped_receiver = BuildWrapReceiver(receiver, function);
6887 HInstruction* result = 6856 HInstruction* result =
6888 new(zone()) HApplyArguments(function, 6857 new(zone()) HApplyArguments(function,
6889 wrapped_receiver, 6858 wrapped_receiver,
6890 length, 6859 length,
6891 elements); 6860 elements);
6892 result->set_position(expr->position()); 6861 result->set_position(expr->position());
6893 ast_context()->ReturnInstruction(result, expr->id()); 6862 ast_context()->ReturnInstruction(result, expr->id());
6894 return true; 6863 return true;
6895 } else { 6864 } else {
6896 // We are inside inlined function and we know exactly what is inside 6865 // We are inside inlined function and we know exactly what is inside
6897 // arguments object. But we need to be able to materialize at deopt. 6866 // arguments object. But we need to be able to materialize at deopt.
6898 ASSERT_EQ(environment()->arguments_environment()->parameter_count(), 6867 ASSERT_EQ(environment()->arguments_environment()->parameter_count(),
6899 function_state()->entry()->arguments_object()->arguments_count()); 6868 function_state()->entry()->arguments_object()->arguments_count());
6900 HArgumentsObject* args = function_state()->entry()->arguments_object(); 6869 HArgumentsObject* args = function_state()->entry()->arguments_object();
6901 const ZoneList<HValue*>* arguments_values = args->arguments_values(); 6870 const ZoneList<HValue*>* arguments_values = args->arguments_values();
6902 int arguments_count = arguments_values->length(); 6871 int arguments_count = arguments_values->length();
6903 PushAndAdd(new(zone()) HWrapReceiver(receiver, function)); 6872 Push(BuildWrapReceiver(receiver, function));
6904 for (int i = 1; i < arguments_count; i++) { 6873 for (int i = 1; i < arguments_count; i++) {
6905 Push(arguments_values->at(i)); 6874 Push(arguments_values->at(i));
6906 } 6875 }
6907 6876
6908 Handle<JSFunction> known_function; 6877 Handle<JSFunction> known_function;
6909 if (function->IsConstant()) { 6878 if (function->IsConstant()) {
6910 HConstant* constant_function = HConstant::cast(function); 6879 HConstant* constant_function = HConstant::cast(function);
6911 known_function = Handle<JSFunction>::cast(constant_function->handle()); 6880 known_function = Handle<JSFunction>::cast(constant_function->handle());
6912 int args_count = arguments_count - 1; // Excluding receiver. 6881 int args_count = arguments_count - 1; // Excluding receiver.
6913 if (TryInlineApply(known_function, expr, args_count)) return true; 6882 if (TryInlineApply(known_function, expr, args_count)) return true;
(...skipping 541 matching lines...) Expand 10 before | Expand all | Expand 10 after
7455 CHECK_ALIVE(VisitForTypeOf(expr->expression())); 7424 CHECK_ALIVE(VisitForTypeOf(expr->expression()));
7456 HValue* value = Pop(); 7425 HValue* value = Pop();
7457 HValue* context = environment()->LookupContext(); 7426 HValue* context = environment()->LookupContext();
7458 HInstruction* instr = new(zone()) HTypeof(context, value); 7427 HInstruction* instr = new(zone()) HTypeof(context, value);
7459 return ast_context()->ReturnInstruction(instr, expr->id()); 7428 return ast_context()->ReturnInstruction(instr, expr->id());
7460 } 7429 }
7461 7430
7462 7431
7463 void HOptimizedGraphBuilder::VisitSub(UnaryOperation* expr) { 7432 void HOptimizedGraphBuilder::VisitSub(UnaryOperation* expr) {
7464 CHECK_ALIVE(VisitForValue(expr->expression())); 7433 CHECK_ALIVE(VisitForValue(expr->expression()));
7465 HValue* value = Pop();
7466 Handle<Type> operand_type = expr->expression()->bounds().lower; 7434 Handle<Type> operand_type = expr->expression()->bounds().lower;
7435 HValue* value = TruncateToNumber(Pop(), &operand_type);
7467 HInstruction* instr = BuildUnaryMathOp(value, operand_type, Token::SUB); 7436 HInstruction* instr = BuildUnaryMathOp(value, operand_type, Token::SUB);
7468 return ast_context()->ReturnInstruction(instr, expr->id()); 7437 return ast_context()->ReturnInstruction(instr, expr->id());
7469 } 7438 }
7470 7439
7471 7440
7472 void HOptimizedGraphBuilder::VisitBitNot(UnaryOperation* expr) { 7441 void HOptimizedGraphBuilder::VisitBitNot(UnaryOperation* expr) {
7473 CHECK_ALIVE(VisitForValue(expr->expression())); 7442 CHECK_ALIVE(VisitForValue(expr->expression()));
7474 HValue* value = Pop();
7475 Handle<Type> operand_type = expr->expression()->bounds().lower; 7443 Handle<Type> operand_type = expr->expression()->bounds().lower;
7444 HValue* value = TruncateToNumber(Pop(), &operand_type);
7476 HInstruction* instr = BuildUnaryMathOp(value, operand_type, Token::BIT_NOT); 7445 HInstruction* instr = BuildUnaryMathOp(value, operand_type, Token::BIT_NOT);
7477 return ast_context()->ReturnInstruction(instr, expr->id()); 7446 return ast_context()->ReturnInstruction(instr, expr->id());
7478 } 7447 }
7479 7448
7480 7449
7481 void HOptimizedGraphBuilder::VisitNot(UnaryOperation* expr) { 7450 void HOptimizedGraphBuilder::VisitNot(UnaryOperation* expr) {
7482 if (ast_context()->IsTest()) { 7451 if (ast_context()->IsTest()) {
7483 TestContext* context = TestContext::cast(ast_context()); 7452 TestContext* context = TestContext::cast(ast_context());
7484 VisitForControl(expr->expression(), 7453 VisitForControl(expr->expression(),
7485 context->if_false(), 7454 context->if_false(),
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after
7620 } 7589 }
7621 } 7590 }
7622 } 7591 }
7623 7592
7624 HValue* context = BuildContextChainWalk(var); 7593 HValue* context = BuildContextChainWalk(var);
7625 HStoreContextSlot::Mode mode = IsLexicalVariableMode(var->mode()) 7594 HStoreContextSlot::Mode mode = IsLexicalVariableMode(var->mode())
7626 ? HStoreContextSlot::kCheckDeoptimize : HStoreContextSlot::kNoCheck; 7595 ? HStoreContextSlot::kCheckDeoptimize : HStoreContextSlot::kNoCheck;
7627 HStoreContextSlot* instr = Add<HStoreContextSlot>(context, var->index(), 7596 HStoreContextSlot* instr = Add<HStoreContextSlot>(context, var->index(),
7628 mode, after); 7597 mode, after);
7629 if (instr->HasObservableSideEffects()) { 7598 if (instr->HasObservableSideEffects()) {
7630 AddSimulate(expr->AssignmentId(), REMOVABLE_SIMULATE); 7599 Add<HSimulate>(expr->AssignmentId(), REMOVABLE_SIMULATE);
7631 } 7600 }
7632 break; 7601 break;
7633 } 7602 }
7634 7603
7635 case Variable::LOOKUP: 7604 case Variable::LOOKUP:
7636 return Bailout("lookup variable in count operation"); 7605 return Bailout("lookup variable in count operation");
7637 } 7606 }
7638 7607
7639 } else { 7608 } else {
7640 // Argument of the count operation is a property. 7609 // Argument of the count operation is a property.
(...skipping 22 matching lines...) Expand all
7663 load = BuildCallGetter(object, map, getter, holder); 7632 load = BuildCallGetter(object, map, getter, holder);
7664 } else { 7633 } else {
7665 load = BuildLoadNamedMonomorphic(object, name, prop, map); 7634 load = BuildLoadNamedMonomorphic(object, name, prop, map);
7666 } 7635 }
7667 } else if (types != NULL && types->length() > 1) { 7636 } else if (types != NULL && types->length() > 1) {
7668 load = TryLoadPolymorphicAsMonomorphic(prop, object, types, name); 7637 load = TryLoadPolymorphicAsMonomorphic(prop, object, types, name);
7669 } 7638 }
7670 if (load == NULL) load = BuildLoadNamedGeneric(object, name, prop); 7639 if (load == NULL) load = BuildLoadNamedGeneric(object, name, prop);
7671 PushAndAdd(load); 7640 PushAndAdd(load);
7672 if (load->HasObservableSideEffects()) { 7641 if (load->HasObservableSideEffects()) {
7673 AddSimulate(prop->LoadId(), REMOVABLE_SIMULATE); 7642 Add<HSimulate>(prop->LoadId(), REMOVABLE_SIMULATE);
7674 } 7643 }
7675 7644
7676 after = BuildIncrement(returns_original_input, expr); 7645 after = BuildIncrement(returns_original_input, expr);
7677 HValue* result = returns_original_input ? Pop() : after; 7646 HValue* result = returns_original_input ? Pop() : after;
7678 7647
7679 return BuildStoreNamed(prop, expr->id(), expr->position(), 7648 return BuildStoreNamed(prop, expr->id(), expr->position(),
7680 expr->AssignmentId(), prop, object, after, result); 7649 expr->AssignmentId(), prop, object, after, result);
7681 } else { 7650 } else {
7682 // Keyed property. 7651 // Keyed property.
7683 if (returns_original_input) Push(graph()->GetConstantUndefined()); 7652 if (returns_original_input) Push(graph()->GetConstantUndefined());
7684 7653
7685 CHECK_ALIVE(VisitForValue(prop->obj())); 7654 CHECK_ALIVE(VisitForValue(prop->obj()));
7686 CHECK_ALIVE(VisitForValue(prop->key())); 7655 CHECK_ALIVE(VisitForValue(prop->key()));
7687 HValue* obj = environment()->ExpressionStackAt(1); 7656 HValue* obj = environment()->ExpressionStackAt(1);
7688 HValue* key = environment()->ExpressionStackAt(0); 7657 HValue* key = environment()->ExpressionStackAt(0);
7689 7658
7690 bool has_side_effects = false; 7659 bool has_side_effects = false;
7691 HValue* load = HandleKeyedElementAccess( 7660 HValue* load = HandleKeyedElementAccess(
7692 obj, key, NULL, prop, prop->LoadId(), RelocInfo::kNoPosition, 7661 obj, key, NULL, prop, prop->LoadId(), RelocInfo::kNoPosition,
7693 false, // is_store 7662 false, // is_store
7694 &has_side_effects); 7663 &has_side_effects);
7695 Push(load); 7664 Push(load);
7696 if (has_side_effects) AddSimulate(prop->LoadId(), REMOVABLE_SIMULATE); 7665 if (has_side_effects) Add<HSimulate>(prop->LoadId(), REMOVABLE_SIMULATE);
7697 7666
7698 after = BuildIncrement(returns_original_input, expr); 7667 after = BuildIncrement(returns_original_input, expr);
7699 input = environment()->ExpressionStackAt(0); 7668 input = environment()->ExpressionStackAt(0);
7700 7669
7701 HandleKeyedElementAccess(obj, key, after, expr, expr->AssignmentId(), 7670 HandleKeyedElementAccess(obj, key, after, expr, expr->AssignmentId(),
7702 RelocInfo::kNoPosition, 7671 RelocInfo::kNoPosition,
7703 true, // is_store 7672 true, // is_store
7704 &has_side_effects); 7673 &has_side_effects);
7705 7674
7706 // Drop the key and the original value from the bailout environment. 7675 // Drop the key and the original value from the bailout environment.
7707 // Overwrite the receiver with the result of the operation, and the 7676 // Overwrite the receiver with the result of the operation, and the
7708 // placeholder with the original value if necessary. 7677 // placeholder with the original value if necessary.
7709 Drop(2); 7678 Drop(2);
7710 environment()->SetExpressionStackAt(0, after); 7679 environment()->SetExpressionStackAt(0, after);
7711 if (returns_original_input) environment()->SetExpressionStackAt(1, input); 7680 if (returns_original_input) environment()->SetExpressionStackAt(1, input);
7712 ASSERT(has_side_effects); // Stores always have side effects. 7681 ASSERT(has_side_effects); // Stores always have side effects.
7713 AddSimulate(expr->AssignmentId(), REMOVABLE_SIMULATE); 7682 Add<HSimulate>(expr->AssignmentId(), REMOVABLE_SIMULATE);
7714 } 7683 }
7715 } 7684 }
7716 7685
7717 Drop(returns_original_input ? 2 : 1); 7686 Drop(returns_original_input ? 2 : 1);
7718 return ast_context()->ReturnValue(expr->is_postfix() ? input : after); 7687 return ast_context()->ReturnValue(expr->is_postfix() ? input : after);
7719 } 7688 }
7720 7689
7721 7690
7722 HInstruction* HOptimizedGraphBuilder::BuildStringCharCodeAt( 7691 HInstruction* HOptimizedGraphBuilder::BuildStringCharCodeAt(
7723 HValue* context, 7692 HValue* context,
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
7795 HConstant* right_const = HConstant::cast(right); 7764 HConstant* right_const = HConstant::cast(right);
7796 if (right_const->HasInteger32Value() && 7765 if (right_const->HasInteger32Value() &&
7797 (right_const->Integer32Value() & 0x1f) != 0) { 7766 (right_const->Integer32Value() & 0x1f) != 0) {
7798 return false; 7767 return false;
7799 } 7768 }
7800 } 7769 }
7801 return true; 7770 return true;
7802 } 7771 }
7803 7772
7804 7773
7774 HValue* HGraphBuilder::TruncateToNumber(HValue* value, Handle<Type>* expected) {
7775 if (value->IsConstant()) {
7776 HConstant* constant = HConstant::cast(value);
7777 Maybe<HConstant*> number = constant->CopyToTruncatedNumber(zone());
7778 if (number.has_value) {
7779 *expected = handle(Type::Number(), isolate());
7780 return AddInstruction(number.value);
7781 }
7782 return value;
7783 }
7784
7785 Handle<Type> expected_type = *expected;
7786 Representation rep = Representation::FromType(expected_type);
7787 if (!rep.IsTagged()) return value;
7788
7789 // If our type feedback suggests that we can non-observably truncate to number
7790 // we introduce the appropriate check here. This avoids 'value' having a
7791 // tagged representation later on.
7792 if (expected_type->Is(Type::Oddball())) {
7793 // TODO(olivf) The BinaryOpStub only records undefined. It might pay off to
7794 // also record booleans and convert them to 0/1 here.
7795 IfBuilder if_nan(this);
7796 if_nan.If<HCompareObjectEqAndBranch>(value,
7797 graph()->GetConstantUndefined());
7798 if_nan.Then();
7799 if_nan.ElseDeopt();
7800 if_nan.End();
7801 return Add<HConstant>(OS::nan_value(), Representation::Double());
7802 }
7803
7804 return value;
7805 }
7806
7807
7805 HInstruction* HOptimizedGraphBuilder::BuildBinaryOperation( 7808 HInstruction* HOptimizedGraphBuilder::BuildBinaryOperation(
7806 BinaryOperation* expr, 7809 BinaryOperation* expr,
7807 HValue* left, 7810 HValue* left,
7808 HValue* right) { 7811 HValue* right) {
7809 HValue* context = environment()->LookupContext(); 7812 HValue* context = environment()->LookupContext();
7810 Handle<Type> left_type = expr->left()->bounds().lower; 7813 Handle<Type> left_type = expr->left()->bounds().lower;
7811 Handle<Type> right_type = expr->right()->bounds().lower; 7814 Handle<Type> right_type = expr->right()->bounds().lower;
7812 Handle<Type> result_type = expr->bounds().lower; 7815 Handle<Type> result_type = expr->bounds().lower;
7813 Maybe<int> fixed_right_arg = expr->fixed_right_arg(); 7816 Maybe<int> fixed_right_arg = expr->fixed_right_arg();
7814 Representation left_rep = Representation::FromType(left_type); 7817 Representation left_rep = Representation::FromType(left_type);
7815 Representation right_rep = Representation::FromType(right_type); 7818 Representation right_rep = Representation::FromType(right_type);
7816 Representation result_rep = Representation::FromType(result_type); 7819 Representation result_rep = Representation::FromType(result_type);
7817 7820
7821 if (expr->op() != Token::ADD ||
7822 (left->type().IsNonString() && right->type().IsNonString())) {
7823 // For addition we can only truncate the arguments to number if we can
7824 // prove that we will not end up in string concatenation mode.
7825 left = TruncateToNumber(left, &left_type);
7826 right = TruncateToNumber(right, &right_type);
7827 }
7828
7818 if (left_type->Is(Type::None())) { 7829 if (left_type->Is(Type::None())) {
7819 AddSoftDeoptimize(); 7830 Add<HDeoptimize>(Deoptimizer::SOFT);
7820 // TODO(rossberg): we should be able to get rid of non-continuous defaults. 7831 // TODO(rossberg): we should be able to get rid of non-continuous defaults.
7821 left_type = handle(Type::Any(), isolate()); 7832 left_type = handle(Type::Any(), isolate());
7822 } 7833 }
7823 if (right_type->Is(Type::None())) { 7834 if (right_type->Is(Type::None())) {
7824 AddSoftDeoptimize(); 7835 Add<HDeoptimize>(Deoptimizer::SOFT);
7825 right_type = handle(Type::Any(), isolate()); 7836 right_type = handle(Type::Any(), isolate());
7826 } 7837 }
7827 HInstruction* instr = NULL; 7838 HInstruction* instr = NULL;
7828 switch (expr->op()) { 7839 switch (expr->op()) {
7829 case Token::ADD: 7840 case Token::ADD:
7830 if (left_type->Is(Type::String()) && right_type->Is(Type::String())) { 7841 if (left_type->Is(Type::String()) && right_type->Is(Type::String())) {
7831 BuildCheckHeapObject(left); 7842 BuildCheckHeapObject(left);
7832 AddInstruction(HCheckInstanceType::NewIsString(left, zone())); 7843 AddInstruction(HCheckInstanceType::NewIsString(left, zone()));
7833 BuildCheckHeapObject(right); 7844 BuildCheckHeapObject(right);
7834 AddInstruction(HCheckInstanceType::NewIsString(right, zone())); 7845 AddInstruction(HCheckInstanceType::NewIsString(right, zone()));
(...skipping 329 matching lines...) Expand 10 before | Expand all | Expand 10 after
8164 // TODO(olivf) InvokeFunction produces a check for the parameter count, 8175 // TODO(olivf) InvokeFunction produces a check for the parameter count,
8165 // even though we are certain to pass the correct number of arguments here. 8176 // even though we are certain to pass the correct number of arguments here.
8166 HInstruction* result = new(zone()) HInvokeFunction(context, function, 2); 8177 HInstruction* result = new(zone()) HInvokeFunction(context, function, 2);
8167 result->set_position(expr->position()); 8178 result->set_position(expr->position());
8168 return ast_context()->ReturnInstruction(result, expr->id()); 8179 return ast_context()->ReturnInstruction(result, expr->id());
8169 } 8180 }
8170 8181
8171 // Cases handled below depend on collected type feedback. They should 8182 // Cases handled below depend on collected type feedback. They should
8172 // soft deoptimize when there is no type feedback. 8183 // soft deoptimize when there is no type feedback.
8173 if (combined_type->Is(Type::None())) { 8184 if (combined_type->Is(Type::None())) {
8174 AddSoftDeoptimize(); 8185 Add<HDeoptimize>(Deoptimizer::SOFT);
8175 combined_type = left_type = right_type = handle(Type::Any(), isolate()); 8186 combined_type = left_type = right_type = handle(Type::Any(), isolate());
8176 } 8187 }
8177 8188
8178 if (combined_type->Is(Type::Receiver())) { 8189 if (combined_type->Is(Type::Receiver())) {
8179 switch (op) { 8190 switch (op) {
8180 case Token::EQ: 8191 case Token::EQ:
8181 case Token::EQ_STRICT: { 8192 case Token::EQ_STRICT: {
8182 // Can we get away with map check and not instance type check? 8193 // Can we get away with map check and not instance type check?
8183 if (combined_type->IsClass()) { 8194 if (combined_type->IsClass()) {
8184 Handle<Map> map = combined_type->AsClass(); 8195 Handle<Map> map = combined_type->AsClass();
(...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after
8440 AddStore(object_header, access, properties); 8451 AddStore(object_header, access, properties);
8441 8452
8442 if (boilerplate_object->IsJSArray()) { 8453 if (boilerplate_object->IsJSArray()) {
8443 Handle<JSArray> boilerplate_array = 8454 Handle<JSArray> boilerplate_array =
8444 Handle<JSArray>::cast(boilerplate_object); 8455 Handle<JSArray>::cast(boilerplate_object);
8445 Handle<Object> length_field = 8456 Handle<Object> length_field =
8446 Handle<Object>(boilerplate_array->length(), isolate()); 8457 Handle<Object>(boilerplate_array->length(), isolate());
8447 HInstruction* length = Add<HConstant>(length_field); 8458 HInstruction* length = Add<HConstant>(length_field);
8448 8459
8449 ASSERT(boilerplate_array->length()->IsSmi()); 8460 ASSERT(boilerplate_array->length()->IsSmi());
8450 Representation representation = 8461 AddStore(object_header, HObjectAccess::ForArrayLength(
8451 IsFastElementsKind(boilerplate_array->GetElementsKind()) 8462 boilerplate_array->GetElementsKind()), length);
8452 ? Representation::Smi() : Representation::Tagged();
8453 AddStore(object_header, HObjectAccess::ForArrayLength(),
8454 length, representation);
8455 } 8463 }
8456 8464
8457 return result; 8465 return result;
8458 } 8466 }
8459 8467
8460 8468
8461 void HOptimizedGraphBuilder::BuildEmitInObjectProperties( 8469 void HOptimizedGraphBuilder::BuildEmitInObjectProperties(
8462 Handle<JSObject> boilerplate_object, 8470 Handle<JSObject> boilerplate_object,
8463 Handle<JSObject> original_boilerplate_object, 8471 Handle<JSObject> original_boilerplate_object,
8464 HValue* object_properties, 8472 HValue* object_properties,
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
8510 if (data_target != NULL) { 8518 if (data_target != NULL) {
8511 double_box = Add<HInnerAllocatedObject>(data_target, *data_offset); 8519 double_box = Add<HInnerAllocatedObject>(data_target, *data_offset);
8512 *data_offset += HeapNumber::kSize; 8520 *data_offset += HeapNumber::kSize;
8513 } else { 8521 } else {
8514 double_box = Add<HInnerAllocatedObject>(target, *offset); 8522 double_box = Add<HInnerAllocatedObject>(target, *offset);
8515 *offset += HeapNumber::kSize; 8523 *offset += HeapNumber::kSize;
8516 } 8524 }
8517 AddStoreMapConstant(double_box, 8525 AddStoreMapConstant(double_box,
8518 isolate()->factory()->heap_number_map()); 8526 isolate()->factory()->heap_number_map());
8519 AddStore(double_box, HObjectAccess::ForHeapNumberValue(), 8527 AddStore(double_box, HObjectAccess::ForHeapNumberValue(),
8520 value_instruction, Representation::Double()); 8528 value_instruction);
8521 value_instruction = double_box; 8529 value_instruction = double_box;
8522 } 8530 }
8523 8531
8524 AddStore(object_properties, access, value_instruction); 8532 AddStore(object_properties, access, value_instruction);
8525 } 8533 }
8526 } 8534 }
8527 8535
8528 int inobject_properties = boilerplate_object->map()->inobject_properties(); 8536 int inobject_properties = boilerplate_object->map()->inobject_properties();
8529 HInstruction* value_instruction = 8537 HInstruction* value_instruction =
8530 Add<HConstant>(isolate()->factory()->one_pointer_filler_map()); 8538 Add<HConstant>(isolate()->factory()->one_pointer_filler_map());
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after
8667 environment()->Bind(variable, value); 8675 environment()->Bind(variable, value);
8668 } 8676 }
8669 break; 8677 break;
8670 case Variable::CONTEXT: 8678 case Variable::CONTEXT:
8671 if (hole_init) { 8679 if (hole_init) {
8672 HValue* value = graph()->GetConstantHole(); 8680 HValue* value = graph()->GetConstantHole();
8673 HValue* context = environment()->LookupContext(); 8681 HValue* context = environment()->LookupContext();
8674 HStoreContextSlot* store = Add<HStoreContextSlot>( 8682 HStoreContextSlot* store = Add<HStoreContextSlot>(
8675 context, variable->index(), HStoreContextSlot::kNoCheck, value); 8683 context, variable->index(), HStoreContextSlot::kNoCheck, value);
8676 if (store->HasObservableSideEffects()) { 8684 if (store->HasObservableSideEffects()) {
8677 AddSimulate(proxy->id(), REMOVABLE_SIMULATE); 8685 Add<HSimulate>(proxy->id(), REMOVABLE_SIMULATE);
8678 } 8686 }
8679 } 8687 }
8680 break; 8688 break;
8681 case Variable::LOOKUP: 8689 case Variable::LOOKUP:
8682 return Bailout("unsupported lookup slot in declaration"); 8690 return Bailout("unsupported lookup slot in declaration");
8683 } 8691 }
8684 } 8692 }
8685 8693
8686 8694
8687 void HOptimizedGraphBuilder::VisitFunctionDeclaration( 8695 void HOptimizedGraphBuilder::VisitFunctionDeclaration(
(...skipping 17 matching lines...) Expand all
8705 BindIfLive(variable, value); 8713 BindIfLive(variable, value);
8706 break; 8714 break;
8707 } 8715 }
8708 case Variable::CONTEXT: { 8716 case Variable::CONTEXT: {
8709 CHECK_ALIVE(VisitForValue(declaration->fun())); 8717 CHECK_ALIVE(VisitForValue(declaration->fun()));
8710 HValue* value = Pop(); 8718 HValue* value = Pop();
8711 HValue* context = environment()->LookupContext(); 8719 HValue* context = environment()->LookupContext();
8712 HStoreContextSlot* store = Add<HStoreContextSlot>( 8720 HStoreContextSlot* store = Add<HStoreContextSlot>(
8713 context, variable->index(), HStoreContextSlot::kNoCheck, value); 8721 context, variable->index(), HStoreContextSlot::kNoCheck, value);
8714 if (store->HasObservableSideEffects()) { 8722 if (store->HasObservableSideEffects()) {
8715 AddSimulate(proxy->id(), REMOVABLE_SIMULATE); 8723 Add<HSimulate>(proxy->id(), REMOVABLE_SIMULATE);
8716 } 8724 }
8717 break; 8725 break;
8718 } 8726 }
8719 case Variable::LOOKUP: 8727 case Variable::LOOKUP:
8720 return Bailout("unsupported lookup slot in declaration"); 8728 return Bailout("unsupported lookup slot in declaration");
8721 } 8729 }
8722 } 8730 }
8723 8731
8724 8732
8725 void HOptimizedGraphBuilder::VisitModuleDeclaration( 8733 void HOptimizedGraphBuilder::VisitModuleDeclaration(
(...skipping 1180 matching lines...) Expand 10 before | Expand all | Expand 10 after
9906 if (ShouldProduceTraceOutput()) { 9914 if (ShouldProduceTraceOutput()) {
9907 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); 9915 isolate()->GetHTracer()->TraceHydrogen(name(), graph_);
9908 } 9916 }
9909 9917
9910 #ifdef DEBUG 9918 #ifdef DEBUG
9911 graph_->Verify(false); // No full verify. 9919 graph_->Verify(false); // No full verify.
9912 #endif 9920 #endif
9913 } 9921 }
9914 9922
9915 } } // namespace v8::internal 9923 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/hydrogen.h ('k') | src/hydrogen-bce.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698