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

Side by Side Diff: src/hydrogen.cc

Issue 21356002: Improve instruction creating/adding shorthand in HGraphBuilder (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Review feedback Created 7 years, 4 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 591 matching lines...) Expand 10 before | Expand all | Expand 10 after
602 } 602 }
603 } 603 }
604 } 604 }
605 605
606 #endif 606 #endif
607 607
608 608
609 HConstant* HGraph::GetConstant(SetOncePointer<HConstant>* pointer, 609 HConstant* HGraph::GetConstant(SetOncePointer<HConstant>* pointer,
610 int32_t value) { 610 int32_t value) {
611 if (!pointer->is_set()) { 611 if (!pointer->is_set()) {
612 HConstant* constant = new(zone()) HConstant(value); 612 // Can't pass GetInvalidContext() to HConstant::New, because that will
613 // recursively call GetConstant
614 HConstant* constant = HConstant::New(zone(), NULL, value);
613 constant->InsertAfter(GetConstantUndefined()); 615 constant->InsertAfter(GetConstantUndefined());
614 pointer->set(constant); 616 pointer->set(constant);
615 } 617 }
616 return pointer->get(); 618 return pointer->get();
617 } 619 }
618 620
619 621
620 HConstant* HGraph::GetConstant0() { 622 HConstant* HGraph::GetConstant0() {
621 return GetConstant(&constant_0_, 0); 623 return GetConstant(&constant_0_, 0);
622 } 624 }
(...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after
828 deopt_else_ = true; 830 deopt_else_ = true;
829 } else { 831 } else {
830 deopt_then_ = true; 832 deopt_then_ = true;
831 } 833 }
832 builder_->Add<HDeoptimize>(Deoptimizer::EAGER); 834 builder_->Add<HDeoptimize>(Deoptimizer::EAGER);
833 } 835 }
834 836
835 837
836 void HGraphBuilder::IfBuilder::Return(HValue* value) { 838 void HGraphBuilder::IfBuilder::Return(HValue* value) {
837 HBasicBlock* block = builder_->current_block(); 839 HBasicBlock* block = builder_->current_block();
838 HValue* context = builder_->environment()->LookupContext();
839 HValue* parameter_count = builder_->graph()->GetConstantMinus1(); 840 HValue* parameter_count = builder_->graph()->GetConstantMinus1();
840 block->FinishExit(new(zone()) HReturn(value, context, parameter_count)); 841 block->FinishExit(builder_->New<HReturn>(value, parameter_count));
841 builder_->set_current_block(NULL); 842 builder_->set_current_block(NULL);
842 if (did_else_) { 843 if (did_else_) {
843 first_false_block_ = NULL; 844 first_false_block_ = NULL;
844 } else { 845 } else {
845 first_true_block_ = NULL; 846 first_true_block_ = NULL;
846 } 847 }
847 } 848 }
848 849
849 850
850 void HGraphBuilder::IfBuilder::End() { 851 void HGraphBuilder::IfBuilder::End() {
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
984 instr->SetFlag(HValue::kHasNoObservableSideEffects); 985 instr->SetFlag(HValue::kHasNoObservableSideEffects);
985 } 986 }
986 return instr; 987 return instr;
987 } 988 }
988 989
989 990
990 void HGraphBuilder::AddIncrementCounter(StatsCounter* counter, 991 void HGraphBuilder::AddIncrementCounter(StatsCounter* counter,
991 HValue* context) { 992 HValue* context) {
992 if (FLAG_native_code_counters && counter->Enabled()) { 993 if (FLAG_native_code_counters && counter->Enabled()) {
993 HValue* reference = Add<HConstant>(ExternalReference(counter)); 994 HValue* reference = Add<HConstant>(ExternalReference(counter));
994 HValue* old_value = AddLoad(reference, HObjectAccess::ForCounter(), NULL); 995 HValue* old_value = Add<HLoadNamedField>(reference,
995 HValue* new_value = AddInstruction( 996 HObjectAccess::ForCounter());
996 HAdd::New(zone(), context, old_value, graph()->GetConstant1())); 997 HValue* new_value = Add<HAdd>(old_value, graph()->GetConstant1());
997 new_value->ClearFlag(HValue::kCanOverflow); // Ignore counter overflow 998 new_value->ClearFlag(HValue::kCanOverflow); // Ignore counter overflow
998 AddStore(reference, HObjectAccess::ForCounter(), new_value); 999 Add<HStoreNamedField>(reference, HObjectAccess::ForCounter(),
1000 new_value);
999 } 1001 }
1000 } 1002 }
1001 1003
1002 1004
1005 void HGraphBuilder::AddSimulate(BailoutId id,
1006 RemovableSimulate removable) {
1007 ASSERT(current_block() != NULL);
1008 ASSERT(no_side_effects_scope_count_ == 0);
1009 current_block()->AddSimulate(id, removable);
1010 }
1011
1012
1003 HBasicBlock* HGraphBuilder::CreateBasicBlock(HEnvironment* env) { 1013 HBasicBlock* HGraphBuilder::CreateBasicBlock(HEnvironment* env) {
1004 HBasicBlock* b = graph()->CreateBasicBlock(); 1014 HBasicBlock* b = graph()->CreateBasicBlock();
1005 b->SetInitialEnvironment(env); 1015 b->SetInitialEnvironment(env);
1006 return b; 1016 return b;
1007 } 1017 }
1008 1018
1009 1019
1010 HBasicBlock* HGraphBuilder::CreateLoopHeaderBlock() { 1020 HBasicBlock* HGraphBuilder::CreateLoopHeaderBlock() {
1011 HBasicBlock* header = graph()->CreateBasicBlock(); 1021 HBasicBlock* header = graph()->CreateBasicBlock();
1012 HEnvironment* entry_env = environment()->CopyAsLoopHeader(header); 1022 HEnvironment* entry_env = environment()->CopyAsLoopHeader(header);
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
1049 from->last_environment()->Pop(); 1059 from->last_environment()->Pop();
1050 } 1060 }
1051 } 1061 }
1052 } else { 1062 } else {
1053 ASSERT(continuation->predecessors()->length() == 0); 1063 ASSERT(continuation->predecessors()->length() == 0);
1054 } 1064 }
1055 } 1065 }
1056 1066
1057 1067
1058 HValue* HGraphBuilder::BuildCheckMap(HValue* obj, Handle<Map> map) { 1068 HValue* HGraphBuilder::BuildCheckMap(HValue* obj, Handle<Map> map) {
1059 HCheckMaps* check = HCheckMaps::New(obj, map, zone(), top_info()); 1069 return Add<HCheckMaps>(obj, map, top_info());
1060 AddInstruction(check);
1061 return check;
1062 } 1070 }
1063 1071
1064 1072
1065 HValue* HGraphBuilder::BuildWrapReceiver(HValue* object, HValue* function) { 1073 HValue* HGraphBuilder::BuildWrapReceiver(HValue* object, HValue* function) {
1066 if (object->type().IsJSObject()) return object; 1074 if (object->type().IsJSObject()) return object;
1067 return Add<HWrapReceiver>(object, function); 1075 return Add<HWrapReceiver>(object, function);
1068 } 1076 }
1069 1077
1070 1078
1071 HValue* HGraphBuilder::BuildCheckForCapacityGrow(HValue* object, 1079 HValue* HGraphBuilder::BuildCheckForCapacityGrow(HValue* object,
(...skipping 11 matching lines...) Expand all
1083 length_checker.Then(); 1091 length_checker.Then();
1084 1092
1085 HValue* current_capacity = AddLoadFixedArrayLength(elements); 1093 HValue* current_capacity = AddLoadFixedArrayLength(elements);
1086 1094
1087 IfBuilder capacity_checker(this); 1095 IfBuilder capacity_checker(this);
1088 1096
1089 capacity_checker.If<HCompareNumericAndBranch>(key, current_capacity, 1097 capacity_checker.If<HCompareNumericAndBranch>(key, current_capacity,
1090 Token::GTE); 1098 Token::GTE);
1091 capacity_checker.Then(); 1099 capacity_checker.Then();
1092 1100
1093 HValue* context = environment()->LookupContext(); 1101 HValue* context = environment()->context();
1094 1102
1095 HValue* max_gap = Add<HConstant>(static_cast<int32_t>(JSObject::kMaxGap)); 1103 HValue* max_gap = Add<HConstant>(static_cast<int32_t>(JSObject::kMaxGap));
1096 HValue* max_capacity = AddInstruction( 1104 HValue* max_capacity = Add<HAdd>(current_capacity, max_gap);
1097 HAdd::New(zone, context, current_capacity, max_gap));
1098 IfBuilder key_checker(this); 1105 IfBuilder key_checker(this);
1099 key_checker.If<HCompareNumericAndBranch>(key, max_capacity, Token::LT); 1106 key_checker.If<HCompareNumericAndBranch>(key, max_capacity, Token::LT);
1100 key_checker.Then(); 1107 key_checker.Then();
1101 key_checker.ElseDeopt(); 1108 key_checker.ElseDeopt();
1102 key_checker.End(); 1109 key_checker.End();
1103 1110
1104 HValue* new_capacity = BuildNewElementsCapacity(context, key); 1111 HValue* new_capacity = BuildNewElementsCapacity(key);
1105 HValue* new_elements = BuildGrowElementsCapacity(object, elements, 1112 HValue* new_elements = BuildGrowElementsCapacity(object, elements,
1106 kind, kind, length, 1113 kind, kind, length,
1107 new_capacity); 1114 new_capacity);
1108 1115
1109 environment()->Push(new_elements); 1116 environment()->Push(new_elements);
1110 capacity_checker.Else(); 1117 capacity_checker.Else();
1111 1118
1112 environment()->Push(elements); 1119 environment()->Push(elements);
1113 capacity_checker.End(); 1120 capacity_checker.End();
1114 1121
1115 if (is_js_array) { 1122 if (is_js_array) {
1116 HValue* new_length = AddInstruction( 1123 HValue* new_length = AddInstruction(
1117 HAdd::New(zone, context, key, graph_->GetConstant1())); 1124 HAdd::New(zone, context, key, graph_->GetConstant1()));
1118 new_length->ClearFlag(HValue::kCanOverflow); 1125 new_length->ClearFlag(HValue::kCanOverflow);
1119 1126
1120 AddStore(object, HObjectAccess::ForArrayLength(kind), new_length); 1127 Add<HStoreNamedField>(object, HObjectAccess::ForArrayLength(kind),
1128 new_length);
1121 } 1129 }
1122 1130
1123 length_checker.Else(); 1131 length_checker.Else();
1124 Add<HBoundsCheck>(key, length); 1132 Add<HBoundsCheck>(key, length);
1125 1133
1126 environment()->Push(elements); 1134 environment()->Push(elements);
1127 length_checker.End(); 1135 length_checker.End();
1128 1136
1129 return environment()->Pop(); 1137 return environment()->Pop();
1130 } 1138 }
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
1167 IsFastHoleyElementsKind(to_kind)); 1175 IsFastHoleyElementsKind(to_kind));
1168 1176
1169 if (AllocationSite::GetMode(from_kind, to_kind) == TRACK_ALLOCATION_SITE) { 1177 if (AllocationSite::GetMode(from_kind, to_kind) == TRACK_ALLOCATION_SITE) {
1170 Add<HTrapAllocationMemento>(object); 1178 Add<HTrapAllocationMemento>(object);
1171 } 1179 }
1172 1180
1173 if (!IsSimpleMapChangeTransition(from_kind, to_kind)) { 1181 if (!IsSimpleMapChangeTransition(from_kind, to_kind)) {
1174 HInstruction* elements = AddLoadElements(object); 1182 HInstruction* elements = AddLoadElements(object);
1175 1183
1176 HInstruction* empty_fixed_array = Add<HConstant>( 1184 HInstruction* empty_fixed_array = Add<HConstant>(
1177 isolate()->factory()->empty_fixed_array(), Representation::Tagged()); 1185 isolate()->factory()->empty_fixed_array());
1178 1186
1179 IfBuilder if_builder(this); 1187 IfBuilder if_builder(this);
1180 1188
1181 if_builder.IfNot<HCompareObjectEqAndBranch>(elements, empty_fixed_array); 1189 if_builder.IfNot<HCompareObjectEqAndBranch>(elements, empty_fixed_array);
1182 1190
1183 if_builder.Then(); 1191 if_builder.Then();
1184 1192
1185 HInstruction* elements_length = AddLoadFixedArrayLength(elements); 1193 HInstruction* elements_length = AddLoadFixedArrayLength(elements);
1186 1194
1187 HInstruction* array_length = is_jsarray 1195 HInstruction* array_length = is_jsarray
1188 ? AddLoad(object, HObjectAccess::ForArrayLength(from_kind), NULL) 1196 ? Add<HLoadNamedField>(object, HObjectAccess::ForArrayLength(from_kind))
1189 : elements_length; 1197 : elements_length;
1190 1198
1191 BuildGrowElementsCapacity(object, elements, from_kind, to_kind, 1199 BuildGrowElementsCapacity(object, elements, from_kind, to_kind,
1192 array_length, elements_length); 1200 array_length, elements_length);
1193 1201
1194 if_builder.End(); 1202 if_builder.End();
1195 } 1203 }
1196 1204
1197 AddStore(object, HObjectAccess::ForMap(), map); 1205 Add<HStoreNamedField>(object, HObjectAccess::ForMap(), map);
1198 } 1206 }
1199 1207
1200 1208
1201 HInstruction* HGraphBuilder::BuildUncheckedMonomorphicElementAccess( 1209 HInstruction* HGraphBuilder::BuildUncheckedMonomorphicElementAccess(
1202 HValue* object, 1210 HValue* object,
1203 HValue* key, 1211 HValue* key,
1204 HValue* val, 1212 HValue* val,
1205 HCheckMaps* mapcheck, 1213 HCheckMaps* mapcheck,
1206 bool is_js_array, 1214 bool is_js_array,
1207 ElementsKind elements_kind, 1215 ElementsKind elements_kind,
1208 bool is_store, 1216 bool is_store,
1209 LoadKeyedHoleMode load_mode, 1217 LoadKeyedHoleMode load_mode,
1210 KeyedAccessStoreMode store_mode) { 1218 KeyedAccessStoreMode store_mode) {
1211 ASSERT(!IsExternalArrayElementsKind(elements_kind) || !is_js_array); 1219 ASSERT(!IsExternalArrayElementsKind(elements_kind) || !is_js_array);
1212 Zone* zone = this->zone();
1213 // No GVNFlag is necessary for ElementsKind if there is an explicit dependency 1220 // No GVNFlag is necessary for ElementsKind if there is an explicit dependency
1214 // on a HElementsTransition instruction. The flag can also be removed if the 1221 // on a HElementsTransition instruction. The flag can also be removed if the
1215 // map to check has FAST_HOLEY_ELEMENTS, since there can be no further 1222 // map to check has FAST_HOLEY_ELEMENTS, since there can be no further
1216 // ElementsKind transitions. Finally, the dependency can be removed for stores 1223 // ElementsKind transitions. Finally, the dependency can be removed for stores
1217 // for FAST_ELEMENTS, since a transition to HOLEY elements won't change the 1224 // for FAST_ELEMENTS, since a transition to HOLEY elements won't change the
1218 // generated store code. 1225 // generated store code.
1219 if ((elements_kind == FAST_HOLEY_ELEMENTS) || 1226 if ((elements_kind == FAST_HOLEY_ELEMENTS) ||
1220 (elements_kind == FAST_ELEMENTS && is_store)) { 1227 (elements_kind == FAST_ELEMENTS && is_store)) {
1221 if (mapcheck != NULL) { 1228 if (mapcheck != NULL) {
1222 mapcheck->ClearGVNFlag(kDependsOnElementsKind); 1229 mapcheck->ClearGVNFlag(kDependsOnElementsKind);
1223 } 1230 }
1224 } 1231 }
1225 bool fast_smi_only_elements = IsFastSmiElementsKind(elements_kind); 1232 bool fast_smi_only_elements = IsFastSmiElementsKind(elements_kind);
1226 bool fast_elements = IsFastObjectElementsKind(elements_kind); 1233 bool fast_elements = IsFastObjectElementsKind(elements_kind);
1227 HValue* elements = AddLoadElements(object, mapcheck); 1234 HValue* elements = AddLoadElements(object, mapcheck);
1228 if (is_store && (fast_elements || fast_smi_only_elements) && 1235 if (is_store && (fast_elements || fast_smi_only_elements) &&
1229 store_mode != STORE_NO_TRANSITION_HANDLE_COW) { 1236 store_mode != STORE_NO_TRANSITION_HANDLE_COW) {
1230 HCheckMaps* check_cow_map = HCheckMaps::New( 1237 HCheckMaps* check_cow_map = Add<HCheckMaps>(
1231 elements, isolate()->factory()->fixed_array_map(), zone, top_info()); 1238 elements, isolate()->factory()->fixed_array_map(), top_info());
1232 check_cow_map->ClearGVNFlag(kDependsOnElementsKind); 1239 check_cow_map->ClearGVNFlag(kDependsOnElementsKind);
1233 AddInstruction(check_cow_map);
1234 } 1240 }
1235 HInstruction* length = NULL; 1241 HInstruction* length = NULL;
1236 if (is_js_array) { 1242 if (is_js_array) {
1237 length = AddLoad(object, HObjectAccess::ForArrayLength(elements_kind), 1243 length = Add<HLoadNamedField>(object,
1238 mapcheck); 1244 HObjectAccess::ForArrayLength(elements_kind), mapcheck);
1239 } else { 1245 } else {
1240 length = AddLoadFixedArrayLength(elements); 1246 length = AddLoadFixedArrayLength(elements);
1241 } 1247 }
1242 length->set_type(HType::Smi()); 1248 length->set_type(HType::Smi());
1243 HValue* checked_key = NULL; 1249 HValue* checked_key = NULL;
1244 if (IsExternalArrayElementsKind(elements_kind)) { 1250 if (IsExternalArrayElementsKind(elements_kind)) {
1245 if (store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS) { 1251 if (store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS) {
1246 NoObservableSideEffectsScope no_effects(this); 1252 NoObservableSideEffectsScope no_effects(this);
1247 HLoadExternalArrayPointer* external_elements = 1253 HLoadExternalArrayPointer* external_elements =
1248 Add<HLoadExternalArrayPointer>(elements); 1254 Add<HLoadExternalArrayPointer>(elements);
1249 IfBuilder length_checker(this); 1255 IfBuilder length_checker(this);
1250 length_checker.If<HCompareNumericAndBranch>(key, length, Token::LT); 1256 length_checker.If<HCompareNumericAndBranch>(key, length, Token::LT);
1251 length_checker.Then(); 1257 length_checker.Then();
1252 IfBuilder negative_checker(this); 1258 IfBuilder negative_checker(this);
1253 HValue* bounds_check = negative_checker.If<HCompareNumericAndBranch>( 1259 HValue* bounds_check = negative_checker.If<HCompareNumericAndBranch>(
1254 key, graph()->GetConstant0(), Token::GTE); 1260 key, graph()->GetConstant0(), Token::GTE);
1255 negative_checker.Then(); 1261 negative_checker.Then();
1256 HInstruction* result = AddExternalArrayElementAccess( 1262 HInstruction* result = AddExternalArrayElementAccess(
1257 external_elements, key, val, bounds_check, elements_kind, is_store); 1263 external_elements, key, val, bounds_check, elements_kind, is_store);
1258 negative_checker.ElseDeopt(); 1264 negative_checker.ElseDeopt();
(...skipping 29 matching lines...) Expand all
1288 } else { 1294 } else {
1289 checked_key = Add<HBoundsCheck>(key, length); 1295 checked_key = Add<HBoundsCheck>(key, length);
1290 1296
1291 if (is_store && (fast_elements || fast_smi_only_elements)) { 1297 if (is_store && (fast_elements || fast_smi_only_elements)) {
1292 if (store_mode == STORE_NO_TRANSITION_HANDLE_COW) { 1298 if (store_mode == STORE_NO_TRANSITION_HANDLE_COW) {
1293 NoObservableSideEffectsScope no_effects(this); 1299 NoObservableSideEffectsScope no_effects(this);
1294 1300
1295 elements = BuildCopyElementsOnWrite(object, elements, elements_kind, 1301 elements = BuildCopyElementsOnWrite(object, elements, elements_kind,
1296 length); 1302 length);
1297 } else { 1303 } else {
1298 HCheckMaps* check_cow_map = HCheckMaps::New( 1304 HCheckMaps* check_cow_map = Add<HCheckMaps>(
1299 elements, isolate()->factory()->fixed_array_map(), 1305 elements, isolate()->factory()->fixed_array_map(),
1300 zone, top_info()); 1306 top_info());
1301 check_cow_map->ClearGVNFlag(kDependsOnElementsKind); 1307 check_cow_map->ClearGVNFlag(kDependsOnElementsKind);
1302 AddInstruction(check_cow_map);
1303 } 1308 }
1304 } 1309 }
1305 } 1310 }
1306 return AddFastElementAccess(elements, checked_key, val, mapcheck, 1311 return AddFastElementAccess(elements, checked_key, val, mapcheck,
1307 elements_kind, is_store, load_mode, store_mode); 1312 elements_kind, is_store, load_mode, store_mode);
1308 } 1313 }
1309 1314
1310 1315
1311 HValue* HGraphBuilder::BuildAllocateElements(HValue* context, 1316 HValue* HGraphBuilder::BuildAllocateElements(ElementsKind kind,
1312 ElementsKind kind,
1313 HValue* capacity) { 1317 HValue* capacity) {
1314 Zone* zone = this->zone();
1315
1316 int elements_size = IsFastDoubleElementsKind(kind) 1318 int elements_size = IsFastDoubleElementsKind(kind)
1317 ? kDoubleSize : kPointerSize; 1319 ? kDoubleSize : kPointerSize;
1318 HConstant* elements_size_value = Add<HConstant>(elements_size); 1320 HConstant* elements_size_value = Add<HConstant>(elements_size);
1319 HValue* mul = AddInstruction( 1321 HValue* mul = Add<HMul>(capacity, elements_size_value);
1320 HMul::New(zone, context, capacity, elements_size_value));
1321 mul->ClearFlag(HValue::kCanOverflow); 1322 mul->ClearFlag(HValue::kCanOverflow);
1322 1323
1323 HConstant* header_size = Add<HConstant>(FixedArray::kHeaderSize); 1324 HConstant* header_size = Add<HConstant>(FixedArray::kHeaderSize);
1324 HValue* total_size = AddInstruction( 1325 HValue* total_size = Add<HAdd>(mul, header_size);
1325 HAdd::New(zone, context, mul, header_size));
1326 total_size->ClearFlag(HValue::kCanOverflow); 1326 total_size->ClearFlag(HValue::kCanOverflow);
1327 1327
1328 return Add<HAllocate>(context, total_size, HType::JSArray(), 1328 return Add<HAllocate>(total_size, HType::JSArray(),
1329 isolate()->heap()->ShouldGloballyPretenure(), kind); 1329 isolate()->heap()->ShouldGloballyPretenure(), kind);
1330 } 1330 }
1331 1331
1332 1332
1333 void HGraphBuilder::BuildInitializeElementsHeader(HValue* elements, 1333 void HGraphBuilder::BuildInitializeElementsHeader(HValue* elements,
1334 ElementsKind kind, 1334 ElementsKind kind,
1335 HValue* capacity) { 1335 HValue* capacity) {
1336 Factory* factory = isolate()->factory(); 1336 Factory* factory = isolate()->factory();
1337 Handle<Map> map = IsFastDoubleElementsKind(kind) 1337 Handle<Map> map = IsFastDoubleElementsKind(kind)
1338 ? factory->fixed_double_array_map() 1338 ? factory->fixed_double_array_map()
1339 : factory->fixed_array_map(); 1339 : factory->fixed_array_map();
1340 1340
1341 AddStoreMapConstant(elements, map); 1341 AddStoreMapConstant(elements, map);
1342 AddStore(elements, HObjectAccess::ForFixedArrayLength(), capacity); 1342 Add<HStoreNamedField>(elements, HObjectAccess::ForFixedArrayLength(),
1343 capacity);
1343 } 1344 }
1344 1345
1345 1346
1346 HValue* HGraphBuilder::BuildAllocateElementsAndInitializeElementsHeader( 1347 HValue* HGraphBuilder::BuildAllocateElementsAndInitializeElementsHeader(
1347 HValue* context,
1348 ElementsKind kind, 1348 ElementsKind kind,
1349 HValue* capacity) { 1349 HValue* capacity) {
1350 // The HForceRepresentation is to prevent possible deopt on int-smi 1350 // The HForceRepresentation is to prevent possible deopt on int-smi
1351 // conversion after allocation but before the new object fields are set. 1351 // conversion after allocation but before the new object fields are set.
1352 capacity = Add<HForceRepresentation>(capacity, Representation::Smi()); 1352 capacity = Add<HForceRepresentation>(capacity, Representation::Smi());
1353 HValue* new_elements = BuildAllocateElements(context, kind, capacity); 1353 HValue* new_elements = BuildAllocateElements(kind, capacity);
1354 BuildInitializeElementsHeader(new_elements, kind, capacity); 1354 BuildInitializeElementsHeader(new_elements, kind, capacity);
1355 return new_elements; 1355 return new_elements;
1356 } 1356 }
1357 1357
1358 1358
1359 HInnerAllocatedObject* HGraphBuilder::BuildJSArrayHeader(HValue* array, 1359 HInnerAllocatedObject* HGraphBuilder::BuildJSArrayHeader(HValue* array,
1360 HValue* array_map, 1360 HValue* array_map,
1361 AllocationSiteMode mode, 1361 AllocationSiteMode mode,
1362 ElementsKind elements_kind, 1362 ElementsKind elements_kind,
1363 HValue* allocation_site_payload, 1363 HValue* allocation_site_payload,
1364 HValue* length_field) { 1364 HValue* length_field) {
1365 1365
1366 AddStore(array, HObjectAccess::ForMap(), array_map); 1366 Add<HStoreNamedField>(array, HObjectAccess::ForMap(), array_map);
1367 1367
1368 HConstant* empty_fixed_array = 1368 HConstant* empty_fixed_array =
1369 Add<HConstant>(isolate()->factory()->empty_fixed_array()); 1369 Add<HConstant>(isolate()->factory()->empty_fixed_array());
1370 1370
1371 HObjectAccess access = HObjectAccess::ForPropertiesPointer(); 1371 HObjectAccess access = HObjectAccess::ForPropertiesPointer();
1372 AddStore(array, access, empty_fixed_array); 1372 Add<HStoreNamedField>(array, access, empty_fixed_array);
1373 AddStore(array, HObjectAccess::ForArrayLength(elements_kind), length_field); 1373 Add<HStoreNamedField>(array, HObjectAccess::ForArrayLength(elements_kind),
1374 length_field);
1374 1375
1375 if (mode == TRACK_ALLOCATION_SITE) { 1376 if (mode == TRACK_ALLOCATION_SITE) {
1376 BuildCreateAllocationMemento(array, 1377 BuildCreateAllocationMemento(array,
1377 JSArray::kSize, 1378 JSArray::kSize,
1378 allocation_site_payload); 1379 allocation_site_payload);
1379 } 1380 }
1380 1381
1381 int elements_location = JSArray::kSize; 1382 int elements_location = JSArray::kSize;
1382 if (mode == TRACK_ALLOCATION_SITE) { 1383 if (mode == TRACK_ALLOCATION_SITE) {
1383 elements_location += AllocationMemento::kSize; 1384 elements_location += AllocationMemento::kSize;
1384 } 1385 }
1385 1386
1386 HInnerAllocatedObject* elements = 1387 HValue* elements = Add<HInnerAllocatedObject>(array, elements_location);
1387 Add<HInnerAllocatedObject>(array, elements_location); 1388 Add<HStoreNamedField>(array, HObjectAccess::ForElementsPointer(), elements);
1388 AddStore(array, HObjectAccess::ForElementsPointer(), elements); 1389 return static_cast<HInnerAllocatedObject*>(elements);
1389 return elements;
1390 } 1390 }
1391 1391
1392 1392
1393 HInstruction* HGraphBuilder::AddExternalArrayElementAccess( 1393 HInstruction* HGraphBuilder::AddExternalArrayElementAccess(
1394 HValue* external_elements, 1394 HValue* external_elements,
1395 HValue* checked_key, 1395 HValue* checked_key,
1396 HValue* val, 1396 HValue* val,
1397 HValue* dependency, 1397 HValue* dependency,
1398 ElementsKind elements_kind, 1398 ElementsKind elements_kind,
1399 bool is_store) { 1399 bool is_store) {
(...skipping 22 matching lines...) Expand all
1422 case FAST_HOLEY_ELEMENTS: 1422 case FAST_HOLEY_ELEMENTS:
1423 case FAST_HOLEY_DOUBLE_ELEMENTS: 1423 case FAST_HOLEY_DOUBLE_ELEMENTS:
1424 case DICTIONARY_ELEMENTS: 1424 case DICTIONARY_ELEMENTS:
1425 case NON_STRICT_ARGUMENTS_ELEMENTS: 1425 case NON_STRICT_ARGUMENTS_ELEMENTS:
1426 UNREACHABLE(); 1426 UNREACHABLE();
1427 break; 1427 break;
1428 } 1428 }
1429 return Add<HStoreKeyed>(external_elements, checked_key, val, elements_kind); 1429 return Add<HStoreKeyed>(external_elements, checked_key, val, elements_kind);
1430 } else { 1430 } else {
1431 ASSERT(val == NULL); 1431 ASSERT(val == NULL);
1432 HLoadKeyed* load = Add<HLoadKeyed>(external_elements, checked_key, 1432 HLoadKeyed* load = Add<HLoadKeyed>(external_elements,
1433 dependency, elements_kind); 1433 checked_key,
1434 dependency,
1435 elements_kind);
1434 if (FLAG_opt_safe_uint32_operations && 1436 if (FLAG_opt_safe_uint32_operations &&
1435 elements_kind == EXTERNAL_UNSIGNED_INT_ELEMENTS) { 1437 elements_kind == EXTERNAL_UNSIGNED_INT_ELEMENTS) {
1436 graph()->RecordUint32Instruction(load); 1438 graph()->RecordUint32Instruction(load);
1437 } 1439 }
1438 return load; 1440 return load;
1439 } 1441 }
1440 } 1442 }
1441 1443
1442 1444
1443 HInstruction* HGraphBuilder::AddFastElementAccess( 1445 HInstruction* HGraphBuilder::AddFastElementAccess(
(...skipping 21 matching lines...) Expand all
1465 } 1467 }
1466 } 1468 }
1467 // It's an element load (!is_store). 1469 // It's an element load (!is_store).
1468 return Add<HLoadKeyed>( 1470 return Add<HLoadKeyed>(
1469 elements, checked_key, load_dependency, elements_kind, load_mode); 1471 elements, checked_key, load_dependency, elements_kind, load_mode);
1470 } 1472 }
1471 1473
1472 1474
1473 HLoadNamedField* HGraphBuilder::AddLoadElements(HValue* object, 1475 HLoadNamedField* HGraphBuilder::AddLoadElements(HValue* object,
1474 HValue* typecheck) { 1476 HValue* typecheck) {
1475 return AddLoad(object, HObjectAccess::ForElementsPointer(), typecheck); 1477 return Add<HLoadNamedField>(object,
1478 HObjectAccess::ForElementsPointer(),
1479 typecheck);
1476 } 1480 }
1477 1481
1478 1482
1479 HLoadNamedField* HGraphBuilder::AddLoadFixedArrayLength(HValue* object) { 1483 HLoadNamedField* HGraphBuilder::AddLoadFixedArrayLength(HValue* object) {
1480 return AddLoad(object, HObjectAccess::ForFixedArrayLength()); 1484 return Add<HLoadNamedField>(object,
1485 HObjectAccess::ForFixedArrayLength());
1481 } 1486 }
1482 1487
1483 1488
1484 HValue* HGraphBuilder::BuildNewElementsCapacity(HValue* context, 1489 HValue* HGraphBuilder::BuildNewElementsCapacity(HValue* old_capacity) {
1485 HValue* old_capacity) { 1490 HValue* half_old_capacity = Add<HShr>(old_capacity, graph_->GetConstant1());
1486 Zone* zone = this->zone();
1487 HValue* half_old_capacity =
1488 AddInstruction(HShr::New(zone, context, old_capacity,
1489 graph_->GetConstant1()));
1490 1491
1491 HValue* new_capacity = AddInstruction( 1492 HValue* new_capacity = Add<HAdd>(half_old_capacity, old_capacity);
1492 HAdd::New(zone, context, half_old_capacity, old_capacity));
1493 new_capacity->ClearFlag(HValue::kCanOverflow); 1493 new_capacity->ClearFlag(HValue::kCanOverflow);
1494 1494
1495 HValue* min_growth = Add<HConstant>(16); 1495 HValue* min_growth = Add<HConstant>(16);
1496 1496
1497 new_capacity = AddInstruction( 1497 new_capacity = Add<HAdd>(new_capacity, min_growth);
1498 HAdd::New(zone, context, new_capacity, min_growth));
1499 new_capacity->ClearFlag(HValue::kCanOverflow); 1498 new_capacity->ClearFlag(HValue::kCanOverflow);
1500 1499
1501 return new_capacity; 1500 return new_capacity;
1502 } 1501 }
1503 1502
1504 1503
1505 void HGraphBuilder::BuildNewSpaceArrayCheck(HValue* length, ElementsKind kind) { 1504 void HGraphBuilder::BuildNewSpaceArrayCheck(HValue* length, ElementsKind kind) {
1506 Heap* heap = isolate()->heap(); 1505 Heap* heap = isolate()->heap();
1507 int element_size = IsFastDoubleElementsKind(kind) ? kDoubleSize 1506 int element_size = IsFastDoubleElementsKind(kind) ? kDoubleSize
1508 : kPointerSize; 1507 : kPointerSize;
1509 int max_size = heap->MaxRegularSpaceAllocationSize() / element_size; 1508 int max_size = heap->MaxRegularSpaceAllocationSize() / element_size;
1510 max_size -= JSArray::kSize / element_size; 1509 max_size -= JSArray::kSize / element_size;
1511 HConstant* max_size_constant = Add<HConstant>(max_size); 1510 HConstant* max_size_constant = Add<HConstant>(max_size);
1512 Add<HBoundsCheck>(length, max_size_constant); 1511 Add<HBoundsCheck>(length, max_size_constant);
1513 } 1512 }
1514 1513
1515 1514
1516 HValue* HGraphBuilder::BuildGrowElementsCapacity(HValue* object, 1515 HValue* HGraphBuilder::BuildGrowElementsCapacity(HValue* object,
1517 HValue* elements, 1516 HValue* elements,
1518 ElementsKind kind, 1517 ElementsKind kind,
1519 ElementsKind new_kind, 1518 ElementsKind new_kind,
1520 HValue* length, 1519 HValue* length,
1521 HValue* new_capacity) { 1520 HValue* new_capacity) {
1522 HValue* context = environment()->LookupContext();
1523
1524 BuildNewSpaceArrayCheck(new_capacity, new_kind); 1521 BuildNewSpaceArrayCheck(new_capacity, new_kind);
1525 1522
1526 HValue* new_elements = BuildAllocateElementsAndInitializeElementsHeader( 1523 HValue* new_elements = BuildAllocateElementsAndInitializeElementsHeader(
1527 context, new_kind, new_capacity); 1524 new_kind, new_capacity);
1528 1525
1529 BuildCopyElements(context, elements, kind, 1526 BuildCopyElements(elements, kind,
1530 new_elements, new_kind, 1527 new_elements, new_kind,
1531 length, new_capacity); 1528 length, new_capacity);
1532 1529
1533 AddStore(object, HObjectAccess::ForElementsPointer(), new_elements); 1530 Add<HStoreNamedField>(object, HObjectAccess::ForElementsPointer(),
1531 new_elements);
1534 1532
1535 return new_elements; 1533 return new_elements;
1536 } 1534 }
1537 1535
1538 1536
1539 void HGraphBuilder::BuildFillElementsWithHole(HValue* context, 1537 void HGraphBuilder::BuildFillElementsWithHole(HValue* elements,
1540 HValue* elements,
1541 ElementsKind elements_kind, 1538 ElementsKind elements_kind,
1542 HValue* from, 1539 HValue* from,
1543 HValue* to) { 1540 HValue* to) {
1544 // Fast elements kinds need to be initialized in case statements below cause 1541 // Fast elements kinds need to be initialized in case statements below cause
1545 // a garbage collection. 1542 // a garbage collection.
1546 Factory* factory = isolate()->factory(); 1543 Factory* factory = isolate()->factory();
1547 1544
1548 double nan_double = FixedDoubleArray::hole_nan_as_double(); 1545 double nan_double = FixedDoubleArray::hole_nan_as_double();
1549 HValue* hole = IsFastSmiOrObjectElementsKind(elements_kind) 1546 HValue* hole = IsFastSmiOrObjectElementsKind(elements_kind)
1550 ? Add<HConstant>(factory->the_hole_value()) 1547 ? Add<HConstant>(factory->the_hole_value())
(...skipping 21 matching lines...) Expand all
1572 if (IsFastSmiOrObjectElementsKind(elements_kind)) { 1569 if (IsFastSmiOrObjectElementsKind(elements_kind)) {
1573 elements_kind = FAST_HOLEY_ELEMENTS; 1570 elements_kind = FAST_HOLEY_ELEMENTS;
1574 } 1571 }
1575 1572
1576 if (unfold_loop) { 1573 if (unfold_loop) {
1577 for (int i = 0; i < initial_capacity; i++) { 1574 for (int i = 0; i < initial_capacity; i++) {
1578 HInstruction* key = Add<HConstant>(i); 1575 HInstruction* key = Add<HConstant>(i);
1579 Add<HStoreKeyed>(elements, key, hole, elements_kind); 1576 Add<HStoreKeyed>(elements, key, hole, elements_kind);
1580 } 1577 }
1581 } else { 1578 } else {
1582 LoopBuilder builder(this, context, LoopBuilder::kPostIncrement); 1579 LoopBuilder builder(this, context(), LoopBuilder::kPostIncrement);
1583 1580
1584 HValue* key = builder.BeginBody(from, to, Token::LT); 1581 HValue* key = builder.BeginBody(from, to, Token::LT);
1585 1582
1586 Add<HStoreKeyed>(elements, key, hole, elements_kind); 1583 Add<HStoreKeyed>(elements, key, hole, elements_kind);
1587 1584
1588 builder.EndBody(); 1585 builder.EndBody();
1589 } 1586 }
1590 } 1587 }
1591 1588
1592 1589
1593 void HGraphBuilder::BuildCopyElements(HValue* context, 1590 void HGraphBuilder::BuildCopyElements(HValue* from_elements,
1594 HValue* from_elements,
1595 ElementsKind from_elements_kind, 1591 ElementsKind from_elements_kind,
1596 HValue* to_elements, 1592 HValue* to_elements,
1597 ElementsKind to_elements_kind, 1593 ElementsKind to_elements_kind,
1598 HValue* length, 1594 HValue* length,
1599 HValue* capacity) { 1595 HValue* capacity) {
1600 bool pre_fill_with_holes = 1596 bool pre_fill_with_holes =
1601 IsFastDoubleElementsKind(from_elements_kind) && 1597 IsFastDoubleElementsKind(from_elements_kind) &&
1602 IsFastObjectElementsKind(to_elements_kind); 1598 IsFastObjectElementsKind(to_elements_kind);
1603 1599
1604 if (pre_fill_with_holes) { 1600 if (pre_fill_with_holes) {
1605 // If the copy might trigger a GC, make sure that the FixedArray is 1601 // If the copy might trigger a GC, make sure that the FixedArray is
1606 // pre-initialized with holes to make sure that it's always in a consistent 1602 // pre-initialized with holes to make sure that it's always in a consistent
1607 // state. 1603 // state.
1608 BuildFillElementsWithHole(context, to_elements, to_elements_kind, 1604 BuildFillElementsWithHole(to_elements, to_elements_kind,
1609 graph()->GetConstant0(), capacity); 1605 graph()->GetConstant0(), capacity);
1610 } 1606 }
1611 1607
1612 LoopBuilder builder(this, context, LoopBuilder::kPostIncrement); 1608 LoopBuilder builder(this, context(), LoopBuilder::kPostIncrement);
1613 1609
1614 HValue* key = builder.BeginBody(graph()->GetConstant0(), length, Token::LT); 1610 HValue* key = builder.BeginBody(graph()->GetConstant0(), length, Token::LT);
1615 1611
1616 HValue* element = Add<HLoadKeyed>(from_elements, key, 1612 HValue* element = Add<HLoadKeyed>(from_elements, key,
1617 static_cast<HValue*>(NULL), 1613 static_cast<HValue*>(NULL),
1618 from_elements_kind, 1614 from_elements_kind,
1619 ALLOW_RETURN_HOLE); 1615 ALLOW_RETURN_HOLE);
1620 1616
1621 ElementsKind holey_kind = IsFastSmiElementsKind(to_elements_kind) 1617 ElementsKind holey_kind = IsFastSmiElementsKind(to_elements_kind)
1622 ? FAST_HOLEY_ELEMENTS : to_elements_kind; 1618 ? FAST_HOLEY_ELEMENTS : to_elements_kind;
1623 HInstruction* holey_store = Add<HStoreKeyed>(to_elements, key, 1619 HInstruction* holey_store = Add<HStoreKeyed>(to_elements, key,
1624 element, holey_kind); 1620 element, holey_kind);
1625 // Allow NaN hole values to converted to their tagged counterparts. 1621 // Allow NaN hole values to converted to their tagged counterparts.
1626 if (IsFastHoleyElementsKind(to_elements_kind)) { 1622 if (IsFastHoleyElementsKind(to_elements_kind)) {
1627 holey_store->SetFlag(HValue::kAllowUndefinedAsNaN); 1623 holey_store->SetFlag(HValue::kAllowUndefinedAsNaN);
1628 } 1624 }
1629 1625
1630 builder.EndBody(); 1626 builder.EndBody();
1631 1627
1632 if (!pre_fill_with_holes && length != capacity) { 1628 if (!pre_fill_with_holes && length != capacity) {
1633 // Fill unused capacity with the hole. 1629 // Fill unused capacity with the hole.
1634 BuildFillElementsWithHole(context, to_elements, to_elements_kind, 1630 BuildFillElementsWithHole(to_elements, to_elements_kind,
1635 key, capacity); 1631 key, capacity);
1636 } 1632 }
1637 } 1633 }
1638 1634
1639 1635
1640 HValue* HGraphBuilder::BuildCloneShallowArray(HContext* context, 1636 HValue* HGraphBuilder::BuildCloneShallowArray(HValue* boilerplate,
1641 HValue* boilerplate,
1642 HValue* allocation_site, 1637 HValue* allocation_site,
1643 AllocationSiteMode mode, 1638 AllocationSiteMode mode,
1644 ElementsKind kind, 1639 ElementsKind kind,
1645 int length) { 1640 int length) {
1646 NoObservableSideEffectsScope no_effects(this); 1641 NoObservableSideEffectsScope no_effects(this);
1647 1642
1648 // All sizes here are multiples of kPointerSize. 1643 // All sizes here are multiples of kPointerSize.
1649 int size = JSArray::kSize; 1644 int size = JSArray::kSize;
1650 if (mode == TRACK_ALLOCATION_SITE) { 1645 if (mode == TRACK_ALLOCATION_SITE) {
1651 size += AllocationMemento::kSize; 1646 size += AllocationMemento::kSize;
1652 } 1647 }
1653 int elems_offset = size; 1648 int elems_offset = size;
1654 if (length > 0) { 1649 if (length > 0) {
1655 size += IsFastDoubleElementsKind(kind) 1650 size += IsFastDoubleElementsKind(kind)
1656 ? FixedDoubleArray::SizeFor(length) 1651 ? FixedDoubleArray::SizeFor(length)
1657 : FixedArray::SizeFor(length); 1652 : FixedArray::SizeFor(length);
1658 } 1653 }
1659 1654
1660 // Allocate both the JS array and the elements array in one big 1655 // Allocate both the JS array and the elements array in one big
1661 // allocation. This avoids multiple limit checks. 1656 // allocation. This avoids multiple limit checks.
1662 HValue* size_in_bytes = Add<HConstant>(size); 1657 HValue* size_in_bytes = Add<HConstant>(size);
1663 HInstruction* object = Add<HAllocate>(context, 1658 HInstruction* object = Add<HAllocate>(size_in_bytes,
1664 size_in_bytes,
1665 HType::JSObject(), 1659 HType::JSObject(),
1666 false, 1660 false,
1667 kind); 1661 kind);
1668 1662
1669 // Copy the JS array part. 1663 // Copy the JS array part.
1670 for (int i = 0; i < JSArray::kSize; i += kPointerSize) { 1664 for (int i = 0; i < JSArray::kSize; i += kPointerSize) {
1671 if ((i != JSArray::kElementsOffset) || (length == 0)) { 1665 if ((i != JSArray::kElementsOffset) || (length == 0)) {
1672 HObjectAccess access = HObjectAccess::ForJSArrayOffset(i); 1666 HObjectAccess access = HObjectAccess::ForJSArrayOffset(i);
1673 AddStore(object, access, AddLoad(boilerplate, access)); 1667 Add<HStoreNamedField>(object, access,
1668 Add<HLoadNamedField>(boilerplate, access));
1674 } 1669 }
1675 } 1670 }
1676 1671
1677 // Create an allocation site info if requested. 1672 // Create an allocation site info if requested.
1678 if (mode == TRACK_ALLOCATION_SITE) { 1673 if (mode == TRACK_ALLOCATION_SITE) {
1679 BuildCreateAllocationMemento(object, JSArray::kSize, allocation_site); 1674 BuildCreateAllocationMemento(object, JSArray::kSize, allocation_site);
1680 } 1675 }
1681 1676
1682 if (length > 0) { 1677 if (length > 0) {
1683 // Get hold of the elements array of the boilerplate and setup the 1678 // Get hold of the elements array of the boilerplate and setup the
1684 // elements pointer in the resulting object. 1679 // elements pointer in the resulting object.
1685 HValue* boilerplate_elements = AddLoadElements(boilerplate); 1680 HValue* boilerplate_elements = AddLoadElements(boilerplate);
1686 HValue* object_elements = Add<HInnerAllocatedObject>(object, elems_offset); 1681 HValue* object_elements = Add<HInnerAllocatedObject>(object, elems_offset);
1687 AddStore(object, HObjectAccess::ForElementsPointer(), object_elements); 1682 Add<HStoreNamedField>(object, HObjectAccess::ForElementsPointer(),
1683 object_elements);
1688 1684
1689 // Copy the elements array header. 1685 // Copy the elements array header.
1690 for (int i = 0; i < FixedArrayBase::kHeaderSize; i += kPointerSize) { 1686 for (int i = 0; i < FixedArrayBase::kHeaderSize; i += kPointerSize) {
1691 HObjectAccess access = HObjectAccess::ForFixedArrayHeader(i); 1687 HObjectAccess access = HObjectAccess::ForFixedArrayHeader(i);
1692 AddStore(object_elements, access, AddLoad(boilerplate_elements, access)); 1688 Add<HStoreNamedField>(object_elements, access,
1689 Add<HLoadNamedField>(boilerplate_elements, access));
1693 } 1690 }
1694 1691
1695 // Copy the elements array contents. 1692 // Copy the elements array contents.
1696 // TODO(mstarzinger): Teach HGraphBuilder::BuildCopyElements to unfold 1693 // TODO(mstarzinger): Teach HGraphBuilder::BuildCopyElements to unfold
1697 // copying loops with constant length up to a given boundary and use this 1694 // copying loops with constant length up to a given boundary and use this
1698 // helper here instead. 1695 // helper here instead.
1699 for (int i = 0; i < length; i++) { 1696 for (int i = 0; i < length; i++) {
1700 HValue* key_constant = Add<HConstant>(i); 1697 HValue* key_constant = Add<HConstant>(i);
1701 HInstruction* value = Add<HLoadKeyed>(boilerplate_elements, key_constant, 1698 HInstruction* value = Add<HLoadKeyed>(boilerplate_elements, key_constant,
1702 static_cast<HValue*>(NULL), kind); 1699 static_cast<HValue*>(NULL), kind);
1703 Add<HStoreKeyed>(object_elements, key_constant, value, kind); 1700 Add<HStoreKeyed>(object_elements, key_constant, value, kind);
1704 } 1701 }
1705 } 1702 }
1706 1703
1707 return object; 1704 return object;
1708 } 1705 }
1709 1706
1710 1707
1711 HInstruction* HGraphBuilder::BuildUnaryMathOp( 1708 HInstruction* HGraphBuilder::BuildUnaryMathOp(
1712 HValue* input, Handle<Type> type, Token::Value operation) { 1709 HValue* input, Handle<Type> type, Token::Value operation) {
1713 // We only handle the numeric cases here 1710 // We only handle the numeric cases here
1714 type = handle( 1711 type = handle(
1715 Type::Intersect(type, handle(Type::Number(), isolate())), isolate()); 1712 Type::Intersect(type, handle(Type::Number(), isolate())), isolate());
1716 1713
1717 switch (operation) { 1714 switch (operation) {
1718 default: 1715 default:
1719 UNREACHABLE(); 1716 UNREACHABLE();
1720 case Token::SUB: { 1717 case Token::SUB: {
1721 HInstruction* instr = 1718 HInstruction* instr =
1722 HMul::New(zone(), environment()->LookupContext(), 1719 NewUncasted<HMul>(input, graph()->GetConstantMinus1());
1723 input, graph()->GetConstantMinus1());
1724 Representation rep = Representation::FromType(type); 1720 Representation rep = Representation::FromType(type);
1725 if (type->Is(Type::None())) { 1721 if (type->Is(Type::None())) {
1726 Add<HDeoptimize>(Deoptimizer::SOFT); 1722 Add<HDeoptimize>(Deoptimizer::SOFT);
1727 } 1723 }
1728 if (instr->IsBinaryOperation()) { 1724 if (instr->IsBinaryOperation()) {
1729 HBinaryOperation* binop = HBinaryOperation::cast(instr); 1725 HBinaryOperation* binop = HBinaryOperation::cast(instr);
1730 binop->set_observed_input_representation(1, rep); 1726 binop->set_observed_input_representation(1, rep);
1731 binop->set_observed_input_representation(2, rep); 1727 binop->set_observed_input_representation(2, rep);
1732 } 1728 }
1733 return instr; 1729 return instr;
1734 } 1730 }
1735 case Token::BIT_NOT: 1731 case Token::BIT_NOT:
1736 if (type->Is(Type::None())) { 1732 if (type->Is(Type::None())) {
1737 Add<HDeoptimize>(Deoptimizer::SOFT); 1733 Add<HDeoptimize>(Deoptimizer::SOFT);
1738 } 1734 }
1739 return new(zone()) HBitNot(input); 1735 return New<HBitNot>(input);
1740 } 1736 }
1741 } 1737 }
1742 1738
1743 1739
1744 void HGraphBuilder::BuildCompareNil( 1740 void HGraphBuilder::BuildCompareNil(
1745 HValue* value, 1741 HValue* value,
1746 Handle<Type> type, 1742 Handle<Type> type,
1747 int position, 1743 int position,
1748 HIfContinuation* continuation) { 1744 HIfContinuation* continuation) {
1749 IfBuilder if_nil(this, position); 1745 IfBuilder if_nil(this, position);
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
1784 HValue* HGraphBuilder::BuildCreateAllocationMemento(HValue* previous_object, 1780 HValue* HGraphBuilder::BuildCreateAllocationMemento(HValue* previous_object,
1785 int previous_object_size, 1781 int previous_object_size,
1786 HValue* alloc_site) { 1782 HValue* alloc_site) {
1787 ASSERT(alloc_site != NULL); 1783 ASSERT(alloc_site != NULL);
1788 HInnerAllocatedObject* alloc_memento = Add<HInnerAllocatedObject>( 1784 HInnerAllocatedObject* alloc_memento = Add<HInnerAllocatedObject>(
1789 previous_object, previous_object_size); 1785 previous_object, previous_object_size);
1790 Handle<Map> alloc_memento_map( 1786 Handle<Map> alloc_memento_map(
1791 isolate()->heap()->allocation_memento_map()); 1787 isolate()->heap()->allocation_memento_map());
1792 AddStoreMapConstant(alloc_memento, alloc_memento_map); 1788 AddStoreMapConstant(alloc_memento, alloc_memento_map);
1793 HObjectAccess access = HObjectAccess::ForAllocationMementoSite(); 1789 HObjectAccess access = HObjectAccess::ForAllocationMementoSite();
1794 AddStore(alloc_memento, access, alloc_site); 1790 Add<HStoreNamedField>(alloc_memento, access, alloc_site);
1795 return alloc_memento; 1791 return alloc_memento;
1796 } 1792 }
1797 1793
1798 1794
1799 HInstruction* HGraphBuilder::BuildGetNativeContext(HValue* context) { 1795 HInstruction* HGraphBuilder::BuildGetNativeContext() {
1800 // Get the global context, then the native context 1796 // Get the global context, then the native context
1801 HInstruction* global_object = Add<HGlobalObject>(context); 1797 HInstruction* global_object = Add<HGlobalObject>();
1802 HObjectAccess access = HObjectAccess::ForJSObjectOffset( 1798 HObjectAccess access = HObjectAccess::ForJSObjectOffset(
1803 GlobalObject::kNativeContextOffset); 1799 GlobalObject::kNativeContextOffset);
1804 return AddLoad(global_object, access); 1800 return Add<HLoadNamedField>(global_object, access);
1805 } 1801 }
1806 1802
1807 1803
1808 HInstruction* HGraphBuilder::BuildGetArrayFunction(HValue* context) { 1804 HInstruction* HGraphBuilder::BuildGetArrayFunction() {
1809 HInstruction* native_context = BuildGetNativeContext(context); 1805 HInstruction* native_context = BuildGetNativeContext();
1810 HInstruction* index = 1806 HInstruction* index =
1811 Add<HConstant>(static_cast<int32_t>(Context::ARRAY_FUNCTION_INDEX)); 1807 Add<HConstant>(static_cast<int32_t>(Context::ARRAY_FUNCTION_INDEX));
1812 return Add<HLoadKeyed>( 1808 return Add<HLoadKeyed>(
1813 native_context, index, static_cast<HValue*>(NULL), FAST_ELEMENTS); 1809 native_context, index, static_cast<HValue*>(NULL), FAST_ELEMENTS);
1814 } 1810 }
1815 1811
1816 1812
1817 HGraphBuilder::JSArrayBuilder::JSArrayBuilder(HGraphBuilder* builder, 1813 HGraphBuilder::JSArrayBuilder::JSArrayBuilder(HGraphBuilder* builder,
1818 ElementsKind kind, 1814 ElementsKind kind,
1819 HValue* allocation_site_payload, 1815 HValue* allocation_site_payload,
(...skipping 13 matching lines...) Expand all
1833 ElementsKind kind, 1829 ElementsKind kind,
1834 HValue* constructor_function) : 1830 HValue* constructor_function) :
1835 builder_(builder), 1831 builder_(builder),
1836 kind_(kind), 1832 kind_(kind),
1837 mode_(DONT_TRACK_ALLOCATION_SITE), 1833 mode_(DONT_TRACK_ALLOCATION_SITE),
1838 allocation_site_payload_(NULL), 1834 allocation_site_payload_(NULL),
1839 constructor_function_(constructor_function) { 1835 constructor_function_(constructor_function) {
1840 } 1836 }
1841 1837
1842 1838
1843 HValue* HGraphBuilder::JSArrayBuilder::EmitMapCode(HValue* context) { 1839 HValue* HGraphBuilder::JSArrayBuilder::EmitMapCode() {
1844 if (kind_ == GetInitialFastElementsKind()) { 1840 if (kind_ == GetInitialFastElementsKind()) {
1845 // No need for a context lookup if the kind_ matches the initial 1841 // No need for a context lookup if the kind_ matches the initial
1846 // map, because we can just load the map in that case. 1842 // map, because we can just load the map in that case.
1847 HObjectAccess access = HObjectAccess::ForPrototypeOrInitialMap(); 1843 HObjectAccess access = HObjectAccess::ForPrototypeOrInitialMap();
1848 return builder()->AddInstruction( 1844 return builder()->AddInstruction(
1849 builder()->BuildLoadNamedField(constructor_function_, access)); 1845 builder()->BuildLoadNamedField(constructor_function_, access));
1850 } 1846 }
1851 1847
1852 HInstruction* native_context = builder()->BuildGetNativeContext(context); 1848 HInstruction* native_context = builder()->BuildGetNativeContext();
1853 HInstruction* index = builder()->Add<HConstant>( 1849 HInstruction* index = builder()->Add<HConstant>(
1854 static_cast<int32_t>(Context::JS_ARRAY_MAPS_INDEX)); 1850 static_cast<int32_t>(Context::JS_ARRAY_MAPS_INDEX));
1855 1851
1856 HInstruction* map_array = builder()->Add<HLoadKeyed>( 1852 HInstruction* map_array = builder()->Add<HLoadKeyed>(
1857 native_context, index, static_cast<HValue*>(NULL), FAST_ELEMENTS); 1853 native_context, index, static_cast<HValue*>(NULL), FAST_ELEMENTS);
1858 1854
1859 HInstruction* kind_index = builder()->Add<HConstant>(kind_); 1855 HInstruction* kind_index = builder()->Add<HConstant>(kind_);
1860 1856
1861 return builder()->Add<HLoadKeyed>( 1857 return builder()->Add<HLoadKeyed>(
1862 map_array, kind_index, static_cast<HValue*>(NULL), FAST_ELEMENTS); 1858 map_array, kind_index, static_cast<HValue*>(NULL), FAST_ELEMENTS);
1863 } 1859 }
1864 1860
1865 1861
1866 HValue* HGraphBuilder::JSArrayBuilder::EmitInternalMapCode() { 1862 HValue* HGraphBuilder::JSArrayBuilder::EmitInternalMapCode() {
1867 // Find the map near the constructor function 1863 // Find the map near the constructor function
1868 HObjectAccess access = HObjectAccess::ForPrototypeOrInitialMap(); 1864 HObjectAccess access = HObjectAccess::ForPrototypeOrInitialMap();
1869 return builder()->AddInstruction( 1865 return builder()->AddInstruction(
1870 builder()->BuildLoadNamedField(constructor_function_, access)); 1866 builder()->BuildLoadNamedField(constructor_function_, access));
1871 } 1867 }
1872 1868
1873 1869
1874 HValue* HGraphBuilder::JSArrayBuilder::EstablishAllocationSize( 1870 HValue* HGraphBuilder::JSArrayBuilder::EstablishAllocationSize(
1875 HValue* length_node) { 1871 HValue* length_node) {
1876 HValue* context = builder()->environment()->LookupContext();
1877 ASSERT(length_node != NULL); 1872 ASSERT(length_node != NULL);
1878 1873
1879 int base_size = JSArray::kSize; 1874 int base_size = JSArray::kSize;
1880 if (mode_ == TRACK_ALLOCATION_SITE) { 1875 if (mode_ == TRACK_ALLOCATION_SITE) {
1881 base_size += AllocationMemento::kSize; 1876 base_size += AllocationMemento::kSize;
1882 } 1877 }
1883 1878
1884 STATIC_ASSERT(FixedDoubleArray::kHeaderSize == FixedArray::kHeaderSize); 1879 STATIC_ASSERT(FixedDoubleArray::kHeaderSize == FixedArray::kHeaderSize);
1885 base_size += FixedArray::kHeaderSize; 1880 base_size += FixedArray::kHeaderSize;
1886 1881
1887 HInstruction* elements_size_value = 1882 HInstruction* elements_size_value =
1888 builder()->Add<HConstant>(elements_size()); 1883 builder()->Add<HConstant>(elements_size());
1889 HInstruction* mul = HMul::New(zone(), context, length_node, 1884 HInstruction* mul = builder()->Add<HMul>(length_node, elements_size_value);
1890 elements_size_value);
1891 mul->ClearFlag(HValue::kCanOverflow); 1885 mul->ClearFlag(HValue::kCanOverflow);
1892 builder()->AddInstruction(mul);
1893 1886
1894 HInstruction* base = builder()->Add<HConstant>(base_size); 1887 HInstruction* base = builder()->Add<HConstant>(base_size);
1895 HInstruction* total_size = HAdd::New(zone(), context, base, mul); 1888 HInstruction* total_size = builder()->Add<HAdd>(base, mul);
1896 total_size->ClearFlag(HValue::kCanOverflow); 1889 total_size->ClearFlag(HValue::kCanOverflow);
1897 builder()->AddInstruction(total_size);
1898 return total_size; 1890 return total_size;
1899 } 1891 }
1900 1892
1901 1893
1902 HValue* HGraphBuilder::JSArrayBuilder::EstablishEmptyArrayAllocationSize() { 1894 HValue* HGraphBuilder::JSArrayBuilder::EstablishEmptyArrayAllocationSize() {
1903 int base_size = JSArray::kSize; 1895 int base_size = JSArray::kSize;
1904 if (mode_ == TRACK_ALLOCATION_SITE) { 1896 if (mode_ == TRACK_ALLOCATION_SITE) {
1905 base_size += AllocationMemento::kSize; 1897 base_size += AllocationMemento::kSize;
1906 } 1898 }
1907 1899
(...skipping 20 matching lines...) Expand all
1928 bool fill_with_hole) { 1920 bool fill_with_hole) {
1929 HValue* size_in_bytes = EstablishAllocationSize(capacity); 1921 HValue* size_in_bytes = EstablishAllocationSize(capacity);
1930 return AllocateArray(size_in_bytes, capacity, length_field, fill_with_hole); 1922 return AllocateArray(size_in_bytes, capacity, length_field, fill_with_hole);
1931 } 1923 }
1932 1924
1933 1925
1934 HValue* HGraphBuilder::JSArrayBuilder::AllocateArray(HValue* size_in_bytes, 1926 HValue* HGraphBuilder::JSArrayBuilder::AllocateArray(HValue* size_in_bytes,
1935 HValue* capacity, 1927 HValue* capacity,
1936 HValue* length_field, 1928 HValue* length_field,
1937 bool fill_with_hole) { 1929 bool fill_with_hole) {
1938 HValue* context = builder()->environment()->LookupContext();
1939
1940 // These HForceRepresentations are because we store these as fields in the 1930 // These HForceRepresentations are because we store these as fields in the
1941 // objects we construct, and an int32-to-smi HChange could deopt. Accept 1931 // objects we construct, and an int32-to-smi HChange could deopt. Accept
1942 // the deopt possibility now, before allocation occurs. 1932 // the deopt possibility now, before allocation occurs.
1943 capacity = builder()->Add<HForceRepresentation>(capacity, 1933 capacity = builder()->Add<HForceRepresentation>(capacity,
1944 Representation::Smi()); 1934 Representation::Smi());
1945 length_field = builder()->Add<HForceRepresentation>(length_field, 1935 length_field = builder()->Add<HForceRepresentation>(length_field,
1946 Representation::Smi()); 1936 Representation::Smi());
1947
1948 // Allocate (dealing with failure appropriately) 1937 // Allocate (dealing with failure appropriately)
1949 HAllocate* new_object = builder()->Add<HAllocate>(context, size_in_bytes, 1938 HAllocate* new_object = builder()->Add<HAllocate>(size_in_bytes,
1950 HType::JSArray(), false, kind_); 1939 HType::JSArray(), false, kind_);
1951 1940
1952 // Fill in the fields: map, properties, length 1941 // Fill in the fields: map, properties, length
1953 HValue* map; 1942 HValue* map;
1954 if (allocation_site_payload_ == NULL) { 1943 if (allocation_site_payload_ == NULL) {
1955 map = EmitInternalMapCode(); 1944 map = EmitInternalMapCode();
1956 } else { 1945 } else {
1957 map = EmitMapCode(context); 1946 map = EmitMapCode();
1958 } 1947 }
1959 elements_location_ = builder()->BuildJSArrayHeader(new_object, 1948 elements_location_ = builder()->BuildJSArrayHeader(new_object,
1960 map, 1949 map,
1961 mode_, 1950 mode_,
1962 kind_, 1951 kind_,
1963 allocation_site_payload_, 1952 allocation_site_payload_,
1964 length_field); 1953 length_field);
1965 1954
1966 // Initialize the elements 1955 // Initialize the elements
1967 builder()->BuildInitializeElementsHeader(elements_location_, kind_, capacity); 1956 builder()->BuildInitializeElementsHeader(elements_location_, kind_, capacity);
1968 1957
1969 if (fill_with_hole) { 1958 if (fill_with_hole) {
1970 builder()->BuildFillElementsWithHole(context, elements_location_, kind_, 1959 builder()->BuildFillElementsWithHole(elements_location_, kind_,
1971 graph()->GetConstant0(), capacity); 1960 graph()->GetConstant0(), capacity);
1972 } 1961 }
1973 1962
1974 return new_object; 1963 return new_object;
1975 } 1964 }
1976 1965
1977 1966
1978 HStoreNamedField* HGraphBuilder::AddStore(HValue *object,
1979 HObjectAccess access,
1980 HValue *val) {
1981 return Add<HStoreNamedField>(object, access, val);
1982 }
1983
1984
1985 HLoadNamedField* HGraphBuilder::AddLoad(HValue *object,
1986 HObjectAccess access,
1987 HValue *typecheck) {
1988 return Add<HLoadNamedField>(object, access, typecheck);
1989 }
1990
1991
1992 HStoreNamedField* HGraphBuilder::AddStoreMapConstant(HValue *object, 1967 HStoreNamedField* HGraphBuilder::AddStoreMapConstant(HValue *object,
1993 Handle<Map> map) { 1968 Handle<Map> map) {
1994 return Add<HStoreNamedField>(object, HObjectAccess::ForMap(), 1969 return Add<HStoreNamedField>(object, HObjectAccess::ForMap(),
1995 Add<HConstant>(map)); 1970 Add<HConstant>(map));
1996 } 1971 }
1997 1972
1998 1973
1999 HValue* HGraphBuilder::AddLoadJSBuiltin(Builtins::JavaScript builtin, 1974 HValue* HGraphBuilder::AddLoadJSBuiltin(Builtins::JavaScript builtin) {
2000 HValue* context) { 1975 HGlobalObject* global_object = Add<HGlobalObject>();
2001 HGlobalObject* global_object = Add<HGlobalObject>(context);
2002 HObjectAccess access = HObjectAccess::ForJSObjectOffset( 1976 HObjectAccess access = HObjectAccess::ForJSObjectOffset(
2003 GlobalObject::kBuiltinsOffset); 1977 GlobalObject::kBuiltinsOffset);
2004 HValue* builtins = AddLoad(global_object, access); 1978 HValue* builtins = Add<HLoadNamedField>(global_object, access);
2005 HObjectAccess function_access = HObjectAccess::ForJSObjectOffset( 1979 HObjectAccess function_access = HObjectAccess::ForJSObjectOffset(
2006 JSBuiltinsObject::OffsetOfFunctionWithId(builtin)); 1980 JSBuiltinsObject::OffsetOfFunctionWithId(builtin));
2007 return AddLoad(builtins, function_access); 1981 return Add<HLoadNamedField>(builtins, function_access);
2008 } 1982 }
2009 1983
2010 1984
2011 HOptimizedGraphBuilder::HOptimizedGraphBuilder(CompilationInfo* info) 1985 HOptimizedGraphBuilder::HOptimizedGraphBuilder(CompilationInfo* info)
2012 : HGraphBuilder(info), 1986 : HGraphBuilder(info),
2013 function_state_(NULL), 1987 function_state_(NULL),
2014 initial_function_state_(this, info, NORMAL_RETURN), 1988 initial_function_state_(this, info, NORMAL_RETURN),
2015 ast_context_(NULL), 1989 ast_context_(NULL),
2016 break_scope_(NULL), 1990 break_scope_(NULL),
2017 inlined_count_(0), 1991 inlined_count_(0),
(...skipping 871 matching lines...) Expand 10 before | Expand all | Expand 10 after
2889 set_current_block(body_entry); 2863 set_current_block(body_entry);
2890 2864
2891 // Handle implicit declaration of the function name in named function 2865 // Handle implicit declaration of the function name in named function
2892 // expressions before other declarations. 2866 // expressions before other declarations.
2893 if (scope->is_function_scope() && scope->function() != NULL) { 2867 if (scope->is_function_scope() && scope->function() != NULL) {
2894 VisitVariableDeclaration(scope->function()); 2868 VisitVariableDeclaration(scope->function());
2895 } 2869 }
2896 VisitDeclarations(scope->declarations()); 2870 VisitDeclarations(scope->declarations());
2897 Add<HSimulate>(BailoutId::Declarations()); 2871 Add<HSimulate>(BailoutId::Declarations());
2898 2872
2899 HValue* context = environment()->LookupContext(); 2873 HValue* context = environment()->context();
2900 Add<HStackCheck>(context, HStackCheck::kFunctionEntry); 2874 Add<HStackCheck>(context, HStackCheck::kFunctionEntry);
2901 2875
2902 VisitStatements(current_info()->function()->body()); 2876 VisitStatements(current_info()->function()->body());
2903 if (HasStackOverflow()) return false; 2877 if (HasStackOverflow()) return false;
2904 2878
2905 if (current_block() != NULL) { 2879 if (current_block() != NULL) {
2906 Add<HReturn>(graph()->GetConstantUndefined()); 2880 Add<HReturn>(graph()->GetConstantUndefined());
2907 set_current_block(NULL); 2881 set_current_block(NULL);
2908 } 2882 }
2909 2883
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after
3100 } 3074 }
3101 3075
3102 while (!arguments.is_empty()) { 3076 while (!arguments.is_empty()) {
3103 Add<HPushArgument>(arguments.RemoveLast()); 3077 Add<HPushArgument>(arguments.RemoveLast());
3104 } 3078 }
3105 return call; 3079 return call;
3106 } 3080 }
3107 3081
3108 3082
3109 void HOptimizedGraphBuilder::SetUpScope(Scope* scope) { 3083 void HOptimizedGraphBuilder::SetUpScope(Scope* scope) {
3110 HConstant* undefined_constant = Add<HConstant>( 3084 // First special is HContext.
3111 isolate()->factory()->undefined_value()); 3085 HInstruction* context = Add<HContext>();
3086 environment()->BindContext(context);
3087
3088 HConstant* undefined_constant = HConstant::cast(Add<HConstant>(
3089 isolate()->factory()->undefined_value()));
3112 graph()->set_undefined_constant(undefined_constant); 3090 graph()->set_undefined_constant(undefined_constant);
3113 3091
3114 // Create an arguments object containing the initial parameters. Set the 3092 // Create an arguments object containing the initial parameters. Set the
3115 // initial values of parameters including "this" having parameter index 0. 3093 // initial values of parameters including "this" having parameter index 0.
3116 ASSERT_EQ(scope->num_parameters() + 1, environment()->parameter_count()); 3094 ASSERT_EQ(scope->num_parameters() + 1, environment()->parameter_count());
3117 HArgumentsObject* arguments_object = 3095 HArgumentsObject* arguments_object =
3118 new(zone()) HArgumentsObject(environment()->parameter_count(), zone()); 3096 New<HArgumentsObject>(environment()->parameter_count());
3119 for (int i = 0; i < environment()->parameter_count(); ++i) { 3097 for (int i = 0; i < environment()->parameter_count(); ++i) {
3120 HInstruction* parameter = Add<HParameter>(i); 3098 HInstruction* parameter = Add<HParameter>(i);
3121 arguments_object->AddArgument(parameter, zone()); 3099 arguments_object->AddArgument(parameter, zone());
3122 environment()->Bind(i, parameter); 3100 environment()->Bind(i, parameter);
3123 } 3101 }
3124 AddInstruction(arguments_object); 3102 AddInstruction(arguments_object);
3125 graph()->SetArgumentsObject(arguments_object); 3103 graph()->SetArgumentsObject(arguments_object);
3126 3104
3127 // First special is HContext.
3128 HInstruction* context = Add<HContext>();
3129 environment()->BindContext(context);
3130
3131 // Initialize specials and locals to undefined. 3105 // Initialize specials and locals to undefined.
3132 for (int i = environment()->parameter_count() + 1; 3106 for (int i = environment()->parameter_count() + 1;
3133 i < environment()->length(); 3107 i < environment()->length();
3134 ++i) { 3108 ++i) {
3135 environment()->Bind(i, undefined_constant); 3109 environment()->Bind(i, undefined_constant);
3136 } 3110 }
3137 3111
3138 // Handle the arguments and arguments shadow variables specially (they do 3112 // Handle the arguments and arguments shadow variables specially (they do
3139 // not have declarations). 3113 // not have declarations).
3140 if (scope->arguments() != NULL) { 3114 if (scope->arguments() != NULL) {
(...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after
3388 int clause_count = clauses->length(); 3362 int clause_count = clauses->length();
3389 if (clause_count > kCaseClauseLimit) { 3363 if (clause_count > kCaseClauseLimit) {
3390 return Bailout("SwitchStatement: too many clauses"); 3364 return Bailout("SwitchStatement: too many clauses");
3391 } 3365 }
3392 3366
3393 ASSERT(stmt->switch_type() != SwitchStatement::UNKNOWN_SWITCH); 3367 ASSERT(stmt->switch_type() != SwitchStatement::UNKNOWN_SWITCH);
3394 if (stmt->switch_type() == SwitchStatement::GENERIC_SWITCH) { 3368 if (stmt->switch_type() == SwitchStatement::GENERIC_SWITCH) {
3395 return Bailout("SwitchStatement: mixed or non-literal switch labels"); 3369 return Bailout("SwitchStatement: mixed or non-literal switch labels");
3396 } 3370 }
3397 3371
3398 HValue* context = environment()->LookupContext(); 3372 HValue* context = environment()->context();
3399 3373
3400 CHECK_ALIVE(VisitForValue(stmt->tag())); 3374 CHECK_ALIVE(VisitForValue(stmt->tag()));
3401 Add<HSimulate>(stmt->EntryId()); 3375 Add<HSimulate>(stmt->EntryId());
3402 HValue* tag_value = Pop(); 3376 HValue* tag_value = Pop();
3403 HBasicBlock* first_test_block = current_block(); 3377 HBasicBlock* first_test_block = current_block();
3404 3378
3405 HUnaryControlInstruction* string_check = NULL; 3379 HUnaryControlInstruction* string_check = NULL;
3406 HBasicBlock* not_string_block = NULL; 3380 HBasicBlock* not_string_block = NULL;
3407 3381
3408 // Test switch's tag value if all clauses are string literals 3382 // Test switch's tag value if all clauses are string literals
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
3536 set_current_block(break_block); 3510 set_current_block(break_block);
3537 } 3511 }
3538 } 3512 }
3539 3513
3540 3514
3541 void HOptimizedGraphBuilder::VisitLoopBody(IterationStatement* stmt, 3515 void HOptimizedGraphBuilder::VisitLoopBody(IterationStatement* stmt,
3542 HBasicBlock* loop_entry, 3516 HBasicBlock* loop_entry,
3543 BreakAndContinueInfo* break_info) { 3517 BreakAndContinueInfo* break_info) {
3544 BreakAndContinueScope push(break_info, this); 3518 BreakAndContinueScope push(break_info, this);
3545 Add<HSimulate>(stmt->StackCheckId()); 3519 Add<HSimulate>(stmt->StackCheckId());
3546 HValue* context = environment()->LookupContext(); 3520 HValue* context = environment()->context();
3547 HStackCheck* stack_check = Add<HStackCheck>( 3521 HStackCheck* stack_check = HStackCheck::cast(Add<HStackCheck>(
3548 context, HStackCheck::kBackwardsBranch); 3522 context, HStackCheck::kBackwardsBranch));
3549 ASSERT(loop_entry->IsLoopHeader()); 3523 ASSERT(loop_entry->IsLoopHeader());
3550 loop_entry->loop_information()->set_stack_check(stack_check); 3524 loop_entry->loop_information()->set_stack_check(stack_check);
3551 CHECK_BAILOUT(Visit(stmt->body())); 3525 CHECK_BAILOUT(Visit(stmt->body()));
3552 } 3526 }
3553 3527
3554 3528
3555 void HOptimizedGraphBuilder::VisitDoWhileStatement(DoWhileStatement* stmt) { 3529 void HOptimizedGraphBuilder::VisitDoWhileStatement(DoWhileStatement* stmt) {
3556 ASSERT(!HasStackOverflow()); 3530 ASSERT(!HasStackOverflow());
3557 ASSERT(current_block() != NULL); 3531 ASSERT(current_block() != NULL);
3558 ASSERT(current_block()->HasPredecessor()); 3532 ASSERT(current_block()->HasPredecessor());
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after
3694 if (!stmt->each()->IsVariableProxy() || 3668 if (!stmt->each()->IsVariableProxy() ||
3695 !stmt->each()->AsVariableProxy()->var()->IsStackLocal()) { 3669 !stmt->each()->AsVariableProxy()->var()->IsStackLocal()) {
3696 return Bailout("ForInStatement with non-local each variable"); 3670 return Bailout("ForInStatement with non-local each variable");
3697 } 3671 }
3698 3672
3699 Variable* each_var = stmt->each()->AsVariableProxy()->var(); 3673 Variable* each_var = stmt->each()->AsVariableProxy()->var();
3700 3674
3701 CHECK_ALIVE(VisitForValue(stmt->enumerable())); 3675 CHECK_ALIVE(VisitForValue(stmt->enumerable()));
3702 HValue* enumerable = Top(); // Leave enumerable at the top. 3676 HValue* enumerable = Top(); // Leave enumerable at the top.
3703 3677
3704 HInstruction* map = Add<HForInPrepareMap>( 3678 HInstruction* map = Add<HForInPrepareMap>(enumerable);
3705 environment()->LookupContext(), enumerable);
3706 Add<HSimulate>(stmt->PrepareId()); 3679 Add<HSimulate>(stmt->PrepareId());
3707 3680
3708 HInstruction* array = Add<HForInCacheArray>( 3681 HInstruction* array = Add<HForInCacheArray>(
3709 enumerable, map, DescriptorArray::kEnumCacheBridgeCacheIndex); 3682 enumerable, map, DescriptorArray::kEnumCacheBridgeCacheIndex);
3710 3683
3711 HInstruction* enum_length = Add<HMapEnumLength>(map); 3684 HInstruction* enum_length = Add<HMapEnumLength>(map);
3712 3685
3713 HInstruction* start_index = Add<HConstant>(0); 3686 HInstruction* start_index = Add<HConstant>(0);
3714 3687
3715 Push(map); 3688 Push(map);
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
3761 BreakAndContinueInfo break_info(stmt, 5); 3734 BreakAndContinueInfo break_info(stmt, 5);
3762 CHECK_BAILOUT(VisitLoopBody(stmt, loop_entry, &break_info)); 3735 CHECK_BAILOUT(VisitLoopBody(stmt, loop_entry, &break_info));
3763 3736
3764 HBasicBlock* body_exit = 3737 HBasicBlock* body_exit =
3765 JoinContinue(stmt, current_block(), break_info.continue_block()); 3738 JoinContinue(stmt, current_block(), break_info.continue_block());
3766 3739
3767 if (body_exit != NULL) { 3740 if (body_exit != NULL) {
3768 set_current_block(body_exit); 3741 set_current_block(body_exit);
3769 3742
3770 HValue* current_index = Pop(); 3743 HValue* current_index = Pop();
3771 HInstruction* new_index = HAdd::New(zone(), 3744 HInstruction* new_index = New<HAdd>(current_index,
3772 environment()->LookupContext(),
3773 current_index,
3774 graph()->GetConstant1()); 3745 graph()->GetConstant1());
3775 PushAndAdd(new_index); 3746 PushAndAdd(new_index);
3776 body_exit = current_block(); 3747 body_exit = current_block();
3777 } 3748 }
3778 3749
3779 HBasicBlock* loop_exit = CreateLoop(stmt, 3750 HBasicBlock* loop_exit = CreateLoop(stmt,
3780 loop_entry, 3751 loop_entry,
3781 body_exit, 3752 body_exit,
3782 loop_successor, 3753 loop_successor,
3783 break_info.break_block()); 3754 break_info.break_block());
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
3842 ASSERT(!HasStackOverflow()); 3813 ASSERT(!HasStackOverflow());
3843 ASSERT(current_block() != NULL); 3814 ASSERT(current_block() != NULL);
3844 ASSERT(current_block()->HasPredecessor()); 3815 ASSERT(current_block()->HasPredecessor());
3845 Handle<SharedFunctionInfo> shared_info = 3816 Handle<SharedFunctionInfo> shared_info =
3846 SearchSharedFunctionInfo(current_info()->shared_info()->code(), expr); 3817 SearchSharedFunctionInfo(current_info()->shared_info()->code(), expr);
3847 if (shared_info.is_null()) { 3818 if (shared_info.is_null()) {
3848 shared_info = Compiler::BuildFunctionInfo(expr, current_info()->script()); 3819 shared_info = Compiler::BuildFunctionInfo(expr, current_info()->script());
3849 } 3820 }
3850 // We also have a stack overflow if the recursive compilation did. 3821 // We also have a stack overflow if the recursive compilation did.
3851 if (HasStackOverflow()) return; 3822 if (HasStackOverflow()) return;
3852 HValue* context = environment()->LookupContext(); 3823 HValue* context = environment()->context();
3853 HFunctionLiteral* instr = 3824 HFunctionLiteral* instr =
3854 new(zone()) HFunctionLiteral(context, shared_info, expr->pretenure()); 3825 new(zone()) HFunctionLiteral(context, shared_info, expr->pretenure());
3855 return ast_context()->ReturnInstruction(instr, expr->id()); 3826 return ast_context()->ReturnInstruction(instr, expr->id());
3856 } 3827 }
3857 3828
3858 3829
3859 void HOptimizedGraphBuilder::VisitSharedFunctionInfoLiteral( 3830 void HOptimizedGraphBuilder::VisitSharedFunctionInfoLiteral(
3860 SharedFunctionInfoLiteral* expr) { 3831 SharedFunctionInfoLiteral* expr) {
3861 ASSERT(!HasStackOverflow()); 3832 ASSERT(!HasStackOverflow());
3862 ASSERT(current_block() != NULL); 3833 ASSERT(current_block() != NULL);
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
3916 lookup->holder() != *global) { 3887 lookup->holder() != *global) {
3917 return kUseGeneric; 3888 return kUseGeneric;
3918 } 3889 }
3919 3890
3920 return kUseCell; 3891 return kUseCell;
3921 } 3892 }
3922 3893
3923 3894
3924 HValue* HOptimizedGraphBuilder::BuildContextChainWalk(Variable* var) { 3895 HValue* HOptimizedGraphBuilder::BuildContextChainWalk(Variable* var) {
3925 ASSERT(var->IsContextSlot()); 3896 ASSERT(var->IsContextSlot());
3926 HValue* context = environment()->LookupContext(); 3897 HValue* context = environment()->context();
3927 int length = current_info()->scope()->ContextChainLength(var->scope()); 3898 int length = current_info()->scope()->ContextChainLength(var->scope());
3928 while (length-- > 0) { 3899 while (length-- > 0) {
3929 context = Add<HOuterContext>(context); 3900 context = Add<HOuterContext>(context);
3930 } 3901 }
3931 return context; 3902 return context;
3932 } 3903 }
3933 3904
3934 3905
3935 void HOptimizedGraphBuilder::VisitVariableProxy(VariableProxy* expr) { 3906 void HOptimizedGraphBuilder::VisitVariableProxy(VariableProxy* expr) {
3936 ASSERT(!HasStackOverflow()); 3907 ASSERT(!HasStackOverflow());
3937 ASSERT(current_block() != NULL); 3908 ASSERT(current_block() != NULL);
3938 ASSERT(current_block()->HasPredecessor()); 3909 ASSERT(current_block()->HasPredecessor());
3939 Variable* variable = expr->var(); 3910 Variable* variable = expr->var();
3940 switch (variable->location()) { 3911 switch (variable->location()) {
3941 case Variable::UNALLOCATED: { 3912 case Variable::UNALLOCATED: {
3942 if (IsLexicalVariableMode(variable->mode())) { 3913 if (IsLexicalVariableMode(variable->mode())) {
3943 // TODO(rossberg): should this be an ASSERT? 3914 // TODO(rossberg): should this be an ASSERT?
3944 return Bailout("reference to global lexical variable"); 3915 return Bailout("reference to global lexical variable");
3945 } 3916 }
3946 // Handle known global constants like 'undefined' specially to avoid a 3917 // Handle known global constants like 'undefined' specially to avoid a
3947 // load from a global cell for them. 3918 // load from a global cell for them.
3948 Handle<Object> constant_value = 3919 Handle<Object> constant_value =
3949 isolate()->factory()->GlobalConstantFor(variable->name()); 3920 isolate()->factory()->GlobalConstantFor(variable->name());
3950 if (!constant_value.is_null()) { 3921 if (!constant_value.is_null()) {
3951 HConstant* instr = new(zone()) HConstant(constant_value); 3922 HConstant* instr = New<HConstant>(constant_value);
3952 return ast_context()->ReturnInstruction(instr, expr->id()); 3923 return ast_context()->ReturnInstruction(instr, expr->id());
3953 } 3924 }
3954 3925
3955 LookupResult lookup(isolate()); 3926 LookupResult lookup(isolate());
3956 GlobalPropertyAccess type = 3927 GlobalPropertyAccess type =
3957 LookupGlobalProperty(variable, &lookup, false); 3928 LookupGlobalProperty(variable, &lookup, false);
3958 3929
3959 if (type == kUseCell && 3930 if (type == kUseCell &&
3960 current_info()->global_object()->IsAccessCheckNeeded()) { 3931 current_info()->global_object()->IsAccessCheckNeeded()) {
3961 type = kUseGeneric; 3932 type = kUseGeneric;
3962 } 3933 }
3963 3934
3964 if (type == kUseCell) { 3935 if (type == kUseCell) {
3965 Handle<GlobalObject> global(current_info()->global_object()); 3936 Handle<GlobalObject> global(current_info()->global_object());
3966 Handle<PropertyCell> cell(global->GetPropertyCell(&lookup)); 3937 Handle<PropertyCell> cell(global->GetPropertyCell(&lookup));
3967 if (cell->type()->IsConstant()) { 3938 if (cell->type()->IsConstant()) {
3968 cell->AddDependentCompilationInfo(top_info()); 3939 cell->AddDependentCompilationInfo(top_info());
3969 Handle<Object> constant_object = cell->type()->AsConstant(); 3940 Handle<Object> constant_object = cell->type()->AsConstant();
3970 if (constant_object->IsConsString()) { 3941 if (constant_object->IsConsString()) {
3971 constant_object = 3942 constant_object =
3972 FlattenGetString(Handle<String>::cast(constant_object)); 3943 FlattenGetString(Handle<String>::cast(constant_object));
3973 } 3944 }
3974 HConstant* constant = new(zone()) HConstant(constant_object); 3945 HConstant* constant = New<HConstant>(constant_object);
3975 return ast_context()->ReturnInstruction(constant, expr->id()); 3946 return ast_context()->ReturnInstruction(constant, expr->id());
3976 } else { 3947 } else {
3977 HLoadGlobalCell* instr = 3948 HLoadGlobalCell* instr =
3978 new(zone()) HLoadGlobalCell(cell, lookup.GetPropertyDetails()); 3949 new(zone()) HLoadGlobalCell(cell, lookup.GetPropertyDetails());
3979 return ast_context()->ReturnInstruction(instr, expr->id()); 3950 return ast_context()->ReturnInstruction(instr, expr->id());
3980 } 3951 }
3981 } else { 3952 } else {
3982 HValue* context = environment()->LookupContext(); 3953 HValue* context = environment()->context();
3983 HGlobalObject* global_object = new(zone()) HGlobalObject(context); 3954 HGlobalObject* global_object = new(zone()) HGlobalObject(context);
3984 AddInstruction(global_object); 3955 AddInstruction(global_object);
3985 HLoadGlobalGeneric* instr = 3956 HLoadGlobalGeneric* instr =
3986 new(zone()) HLoadGlobalGeneric(context, 3957 new(zone()) HLoadGlobalGeneric(context,
3987 global_object, 3958 global_object,
3988 variable->name(), 3959 variable->name(),
3989 ast_context()->is_for_typeof()); 3960 ast_context()->is_for_typeof());
3990 instr->set_position(expr->position()); 3961 instr->set_position(expr->position());
3991 return ast_context()->ReturnInstruction(instr, expr->id()); 3962 return ast_context()->ReturnInstruction(instr, expr->id());
3992 } 3963 }
(...skipping 19 matching lines...) Expand all
4012 case Variable::LOOKUP: 3983 case Variable::LOOKUP:
4013 return Bailout("reference to a variable which requires dynamic lookup"); 3984 return Bailout("reference to a variable which requires dynamic lookup");
4014 } 3985 }
4015 } 3986 }
4016 3987
4017 3988
4018 void HOptimizedGraphBuilder::VisitLiteral(Literal* expr) { 3989 void HOptimizedGraphBuilder::VisitLiteral(Literal* expr) {
4019 ASSERT(!HasStackOverflow()); 3990 ASSERT(!HasStackOverflow());
4020 ASSERT(current_block() != NULL); 3991 ASSERT(current_block() != NULL);
4021 ASSERT(current_block()->HasPredecessor()); 3992 ASSERT(current_block()->HasPredecessor());
4022 HConstant* instr = new(zone()) HConstant(expr->value()); 3993 HConstant* instr = New<HConstant>(expr->value());
4023 return ast_context()->ReturnInstruction(instr, expr->id()); 3994 return ast_context()->ReturnInstruction(instr, expr->id());
4024 } 3995 }
4025 3996
4026 3997
4027 void HOptimizedGraphBuilder::VisitRegExpLiteral(RegExpLiteral* expr) { 3998 void HOptimizedGraphBuilder::VisitRegExpLiteral(RegExpLiteral* expr) {
4028 ASSERT(!HasStackOverflow()); 3999 ASSERT(!HasStackOverflow());
4029 ASSERT(current_block() != NULL); 4000 ASSERT(current_block() != NULL);
4030 ASSERT(current_block()->HasPredecessor()); 4001 ASSERT(current_block()->HasPredecessor());
4031 Handle<JSFunction> closure = function_state()->compilation_info()->closure(); 4002 Handle<JSFunction> closure = function_state()->compilation_info()->closure();
4032 Handle<FixedArray> literals(closure->literals()); 4003 Handle<FixedArray> literals(closure->literals());
4033 HValue* context = environment()->LookupContext(); 4004 HValue* context = environment()->context();
4034 4005
4035 HRegExpLiteral* instr = new(zone()) HRegExpLiteral(context, 4006 HRegExpLiteral* instr = new(zone()) HRegExpLiteral(context,
4036 literals, 4007 literals,
4037 expr->pattern(), 4008 expr->pattern(),
4038 expr->flags(), 4009 expr->flags(),
4039 expr->literal_index()); 4010 expr->literal_index());
4040 return ast_context()->ReturnInstruction(instr, expr->id()); 4011 return ast_context()->ReturnInstruction(instr, expr->id());
4041 } 4012 }
4042 4013
4043 4014
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after
4200 *pointer_size += boilerplate->map()->instance_size(); 4171 *pointer_size += boilerplate->map()->instance_size();
4201 return true; 4172 return true;
4202 } 4173 }
4203 4174
4204 4175
4205 void HOptimizedGraphBuilder::VisitObjectLiteral(ObjectLiteral* expr) { 4176 void HOptimizedGraphBuilder::VisitObjectLiteral(ObjectLiteral* expr) {
4206 ASSERT(!HasStackOverflow()); 4177 ASSERT(!HasStackOverflow());
4207 ASSERT(current_block() != NULL); 4178 ASSERT(current_block() != NULL);
4208 ASSERT(current_block()->HasPredecessor()); 4179 ASSERT(current_block()->HasPredecessor());
4209 Handle<JSFunction> closure = function_state()->compilation_info()->closure(); 4180 Handle<JSFunction> closure = function_state()->compilation_info()->closure();
4210 HValue* context = environment()->LookupContext(); 4181 HValue* context = environment()->context();
4211 HInstruction* literal; 4182 HInstruction* literal;
4212 4183
4213 // Check whether to use fast or slow deep-copying for boilerplate. 4184 // Check whether to use fast or slow deep-copying for boilerplate.
4214 int data_size = 0; 4185 int data_size = 0;
4215 int pointer_size = 0; 4186 int pointer_size = 0;
4216 int max_properties = kMaxFastLiteralProperties; 4187 int max_properties = kMaxFastLiteralProperties;
4217 Handle<Object> original_boilerplate(closure->literals()->get( 4188 Handle<Object> original_boilerplate(closure->literals()->get(
4218 expr->literal_index()), isolate()); 4189 expr->literal_index()), isolate());
4219 if (original_boilerplate->IsJSObject() && 4190 if (original_boilerplate->IsJSObject() &&
4220 IsFastLiteral(Handle<JSObject>::cast(original_boilerplate), 4191 IsFastLiteral(Handle<JSObject>::cast(original_boilerplate),
(...skipping 24 matching lines...) Expand all
4245 ? ObjectLiteral::kHasFunction : ObjectLiteral::kNoFlags; 4216 ? ObjectLiteral::kHasFunction : ObjectLiteral::kNoFlags;
4246 4217
4247 Add<HPushArgument>(Add<HConstant>(closure_literals)); 4218 Add<HPushArgument>(Add<HConstant>(closure_literals));
4248 Add<HPushArgument>(Add<HConstant>(literal_index)); 4219 Add<HPushArgument>(Add<HConstant>(literal_index));
4249 Add<HPushArgument>(Add<HConstant>(constant_properties)); 4220 Add<HPushArgument>(Add<HConstant>(constant_properties));
4250 Add<HPushArgument>(Add<HConstant>(flags)); 4221 Add<HPushArgument>(Add<HConstant>(flags));
4251 4222
4252 Runtime::FunctionId function_id = 4223 Runtime::FunctionId function_id =
4253 (expr->depth() > 1 || expr->may_store_doubles()) 4224 (expr->depth() > 1 || expr->may_store_doubles())
4254 ? Runtime::kCreateObjectLiteral : Runtime::kCreateObjectLiteralShallow; 4225 ? Runtime::kCreateObjectLiteral : Runtime::kCreateObjectLiteralShallow;
4255 literal = Add<HCallRuntime>(context, 4226 literal = Add<HCallRuntime>(isolate()->factory()->empty_string(),
4256 isolate()->factory()->empty_string(),
4257 Runtime::FunctionForId(function_id), 4227 Runtime::FunctionForId(function_id),
4258 4); 4228 4);
4259 } 4229 }
4260 4230
4261 // The object is expected in the bailout environment during computation 4231 // The object is expected in the bailout environment during computation
4262 // of the property values and is the value of the entire expression. 4232 // of the property values and is the value of the entire expression.
4263 Push(literal); 4233 Push(literal);
4264 4234
4265 expr->CalculateEmitStore(zone()); 4235 expr->CalculateEmitStore(zone());
4266 4236
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
4328 } 4298 }
4329 } 4299 }
4330 4300
4331 4301
4332 void HOptimizedGraphBuilder::VisitArrayLiteral(ArrayLiteral* expr) { 4302 void HOptimizedGraphBuilder::VisitArrayLiteral(ArrayLiteral* expr) {
4333 ASSERT(!HasStackOverflow()); 4303 ASSERT(!HasStackOverflow());
4334 ASSERT(current_block() != NULL); 4304 ASSERT(current_block() != NULL);
4335 ASSERT(current_block()->HasPredecessor()); 4305 ASSERT(current_block()->HasPredecessor());
4336 ZoneList<Expression*>* subexprs = expr->values(); 4306 ZoneList<Expression*>* subexprs = expr->values();
4337 int length = subexprs->length(); 4307 int length = subexprs->length();
4338 HValue* context = environment()->LookupContext(); 4308 HValue* context = environment()->context();
4339 HInstruction* literal; 4309 HInstruction* literal;
4340 4310
4341 Handle<AllocationSite> site; 4311 Handle<AllocationSite> site;
4342 Handle<FixedArray> literals(environment()->closure()->literals(), isolate()); 4312 Handle<FixedArray> literals(environment()->closure()->literals(), isolate());
4343 bool uninitialized = false; 4313 bool uninitialized = false;
4344 Handle<Object> literals_cell(literals->get(expr->literal_index()), 4314 Handle<Object> literals_cell(literals->get(expr->literal_index()),
4345 isolate()); 4315 isolate());
4346 Handle<Object> raw_boilerplate; 4316 Handle<Object> raw_boilerplate;
4347 if (literals_cell->IsUndefined()) { 4317 if (literals_cell->IsUndefined()) {
4348 uninitialized = true; 4318 uninitialized = true;
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
4407 // pass an empty fixed array to the runtime function instead. 4377 // pass an empty fixed array to the runtime function instead.
4408 Handle<FixedArray> constants = isolate()->factory()->empty_fixed_array(); 4378 Handle<FixedArray> constants = isolate()->factory()->empty_fixed_array();
4409 int literal_index = expr->literal_index(); 4379 int literal_index = expr->literal_index();
4410 4380
4411 Add<HPushArgument>(Add<HConstant>(literals)); 4381 Add<HPushArgument>(Add<HConstant>(literals));
4412 Add<HPushArgument>(Add<HConstant>(literal_index)); 4382 Add<HPushArgument>(Add<HConstant>(literal_index));
4413 Add<HPushArgument>(Add<HConstant>(constants)); 4383 Add<HPushArgument>(Add<HConstant>(constants));
4414 4384
4415 Runtime::FunctionId function_id = (expr->depth() > 1) 4385 Runtime::FunctionId function_id = (expr->depth() > 1)
4416 ? Runtime::kCreateArrayLiteral : Runtime::kCreateArrayLiteralShallow; 4386 ? Runtime::kCreateArrayLiteral : Runtime::kCreateArrayLiteralShallow;
4417 literal = Add<HCallRuntime>(context, 4387 literal = Add<HCallRuntime>(isolate()->factory()->empty_string(),
4418 isolate()->factory()->empty_string(),
4419 Runtime::FunctionForId(function_id), 4388 Runtime::FunctionForId(function_id),
4420 3); 4389 3);
4421 4390
4422 // De-opt if elements kind changed from boilerplate_elements_kind. 4391 // De-opt if elements kind changed from boilerplate_elements_kind.
4423 Handle<Map> map = Handle<Map>(original_boilerplate_object->map(), 4392 Handle<Map> map = Handle<Map>(original_boilerplate_object->map(),
4424 isolate()); 4393 isolate());
4425 AddInstruction(HCheckMaps::New(literal, map, zone(), top_info())); 4394 Add<HCheckMaps>(literal, map, top_info());
4426 } 4395 }
4427 4396
4428 // The array is expected in the bailout environment during computation 4397 // The array is expected in the bailout environment during computation
4429 // of the property values and is the value of the entire expression. 4398 // of the property values and is the value of the entire expression.
4430 Push(literal); 4399 Push(literal);
4431 // The literal index is on the stack, too. 4400 // The literal index is on the stack, too.
4432 Push(Add<HConstant>(expr->literal_index())); 4401 Push(Add<HConstant>(expr->literal_index()));
4433 4402
4434 HInstruction* elements = NULL; 4403 HInstruction* elements = NULL;
4435 4404
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
4492 // 2nd chance: A store into a non-existent field can still be inlined if we 4461 // 2nd chance: A store into a non-existent field can still be inlined if we
4493 // have a matching transition and some room left in the object. 4462 // have a matching transition and some room left in the object.
4494 type->LookupTransition(NULL, *name, lookup); 4463 type->LookupTransition(NULL, *name, lookup);
4495 return lookup->IsTransitionToField(*type) && 4464 return lookup->IsTransitionToField(*type) &&
4496 (type->unused_property_fields() > 0); 4465 (type->unused_property_fields() > 0);
4497 } 4466 }
4498 4467
4499 4468
4500 void HOptimizedGraphBuilder::AddCheckMap(HValue* object, Handle<Map> map) { 4469 void HOptimizedGraphBuilder::AddCheckMap(HValue* object, Handle<Map> map) {
4501 BuildCheckHeapObject(object); 4470 BuildCheckHeapObject(object);
4502 AddInstruction(HCheckMaps::New(object, map, zone(), top_info())); 4471 Add<HCheckMaps>(object, map, top_info());
4503 } 4472 }
4504 4473
4505 4474
4506 HInstruction* HOptimizedGraphBuilder::BuildStoreNamedField( 4475 HInstruction* HOptimizedGraphBuilder::BuildStoreNamedField(
4507 HValue* object, 4476 HValue* object,
4508 Handle<String> name, 4477 Handle<String> name,
4509 HValue* value, 4478 HValue* value,
4510 Handle<Map> map, 4479 Handle<Map> map,
4511 LookupResult* lookup) { 4480 LookupResult* lookup) {
4512 ASSERT(lookup->IsFound()); 4481 ASSERT(lookup->IsFound());
(...skipping 14 matching lines...) Expand all
4527 // We only need to check up to the preexisting property. 4496 // We only need to check up to the preexisting property.
4528 proto = proto_result.holder(); 4497 proto = proto_result.holder();
4529 } else { 4498 } else {
4530 // Otherwise, find the top prototype. 4499 // Otherwise, find the top prototype.
4531 while (proto->GetPrototype(isolate())->IsJSObject()) { 4500 while (proto->GetPrototype(isolate())->IsJSObject()) {
4532 proto = proto->GetPrototype(isolate()); 4501 proto = proto->GetPrototype(isolate());
4533 } 4502 }
4534 ASSERT(proto->GetPrototype(isolate())->IsNull()); 4503 ASSERT(proto->GetPrototype(isolate())->IsNull());
4535 } 4504 }
4536 ASSERT(proto->IsJSObject()); 4505 ASSERT(proto->IsJSObject());
4537 Add<HCheckPrototypeMaps>(Handle<JSObject>(JSObject::cast(map->prototype())), 4506 Add<HCheckPrototypeMaps>(
4538 Handle<JSObject>(JSObject::cast(proto)), 4507 Handle<JSObject>(JSObject::cast(map->prototype())),
4539 zone(), top_info()); 4508 Handle<JSObject>(JSObject::cast(proto)), top_info());
4540 } 4509 }
4541 4510
4542 HObjectAccess field_access = HObjectAccess::ForField(map, lookup, name); 4511 HObjectAccess field_access = HObjectAccess::ForField(map, lookup, name);
4543 bool transition_to_field = lookup->IsTransitionToField(*map); 4512 bool transition_to_field = lookup->IsTransitionToField(*map);
4544 4513
4545 HStoreNamedField *instr; 4514 HStoreNamedField *instr;
4546 if (FLAG_track_double_fields && field_access.representation().IsDouble()) { 4515 if (FLAG_track_double_fields && field_access.representation().IsDouble()) {
4547 HObjectAccess heap_number_access = 4516 HObjectAccess heap_number_access =
4548 field_access.WithRepresentation(Representation::Tagged()); 4517 field_access.WithRepresentation(Representation::Tagged());
4549 if (transition_to_field) { 4518 if (transition_to_field) {
4550 // The store requires a mutable HeapNumber to be allocated. 4519 // The store requires a mutable HeapNumber to be allocated.
4551 NoObservableSideEffectsScope no_side_effects(this); 4520 NoObservableSideEffectsScope no_side_effects(this);
4552 HInstruction* heap_number_size = Add<HConstant>(HeapNumber::kSize); 4521 HInstruction* heap_number_size = Add<HConstant>(HeapNumber::kSize);
4553 HInstruction* heap_number = Add<HAllocate>( 4522 HInstruction* heap_number = Add<HAllocate>(heap_number_size,
4554 environment()->LookupContext(), heap_number_size,
4555 HType::HeapNumber(), false); 4523 HType::HeapNumber(), false);
4556 AddStoreMapConstant(heap_number, isolate()->factory()->heap_number_map()); 4524 AddStoreMapConstant(heap_number, isolate()->factory()->heap_number_map());
4557 AddStore(heap_number, HObjectAccess::ForHeapNumberValue(), value); 4525 Add<HStoreNamedField>(heap_number, HObjectAccess::ForHeapNumberValue(),
4558 instr = new(zone()) HStoreNamedField( 4526 value);
4559 object, heap_number_access, heap_number); 4527 instr = New<HStoreNamedField>(object, heap_number_access,
4528 heap_number);
4560 } else { 4529 } else {
4561 // Already holds a HeapNumber; load the box and write its value field. 4530 // Already holds a HeapNumber; load the box and write its value field.
4562 HInstruction* heap_number = AddLoad(object, heap_number_access); 4531 HInstruction* heap_number = Add<HLoadNamedField>(object,
4532 heap_number_access);
4563 heap_number->set_type(HType::HeapNumber()); 4533 heap_number->set_type(HType::HeapNumber());
4564 instr = new(zone()) HStoreNamedField(heap_number, 4534 instr = New<HStoreNamedField>(heap_number,
4565 HObjectAccess::ForHeapNumberValue(), value); 4535 HObjectAccess::ForHeapNumberValue(),
4536 value);
4566 } 4537 }
4567 } else { 4538 } else {
4568 // This is a normal store. 4539 // This is a normal store.
4569 instr = new(zone()) HStoreNamedField(object, field_access, value); 4540 instr = New<HStoreNamedField>(object, field_access, value);
4570 } 4541 }
4571 4542
4572 if (transition_to_field) { 4543 if (transition_to_field) {
4573 Handle<Map> transition(lookup->GetTransitionMapFromMap(*map)); 4544 Handle<Map> transition(lookup->GetTransitionMapFromMap(*map));
4574 instr->SetTransition(transition, top_info()); 4545 instr->SetTransition(transition, top_info());
4575 // TODO(fschneider): Record the new map type of the object in the IR to 4546 // TODO(fschneider): Record the new map type of the object in the IR to
4576 // enable elimination of redundant checks after the transition store. 4547 // enable elimination of redundant checks after the transition store.
4577 instr->SetGVNFlag(kChangesMaps); 4548 instr->SetGVNFlag(kChangesMaps);
4578 } 4549 }
4579 return instr; 4550 return instr;
4580 } 4551 }
4581 4552
4582 4553
4583 HInstruction* HOptimizedGraphBuilder::BuildStoreNamedGeneric( 4554 HInstruction* HOptimizedGraphBuilder::BuildStoreNamedGeneric(
4584 HValue* object, 4555 HValue* object,
4585 Handle<String> name, 4556 Handle<String> name,
4586 HValue* value) { 4557 HValue* value) {
4587 HValue* context = environment()->LookupContext(); 4558 HValue* context = environment()->context();
4588 return new(zone()) HStoreNamedGeneric( 4559 return new(zone()) HStoreNamedGeneric(
4589 context, 4560 context,
4590 object, 4561 object,
4591 name, 4562 name,
4592 value, 4563 value,
4593 function_strict_mode_flag()); 4564 function_strict_mode_flag());
4594 } 4565 }
4595 4566
4596 4567
4597 HInstruction* HOptimizedGraphBuilder::BuildStoreNamedMonomorphic( 4568 HInstruction* HOptimizedGraphBuilder::BuildStoreNamedMonomorphic(
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
4654 // In-objectness did not match. 4625 // In-objectness did not match.
4655 break; 4626 break;
4656 } 4627 }
4657 access = access.WithRepresentation( 4628 access = access.WithRepresentation(
4658 access.representation().generalize(new_access.representation())); 4629 access.representation().generalize(new_access.representation()));
4659 } 4630 }
4660 4631
4661 if (count == types->length()) { 4632 if (count == types->length()) {
4662 // Everything matched; can use monomorphic load. 4633 // Everything matched; can use monomorphic load.
4663 BuildCheckHeapObject(object); 4634 BuildCheckHeapObject(object);
4664 AddInstruction(HCheckMaps::New(object, types, zone())); 4635 Add<HCheckMaps>(object, types);
4665 return BuildLoadNamedField(object, access); 4636 return BuildLoadNamedField(object, access);
4666 } 4637 }
4667 4638
4668 if (count != 0) return NULL; 4639 if (count != 0) return NULL;
4669 4640
4670 // Second chance: the property is on the prototype and all maps have the 4641 // Second chance: the property is on the prototype and all maps have the
4671 // same prototype. 4642 // same prototype.
4672 Handle<Map> map(types->at(0)); 4643 Handle<Map> map(types->at(0));
4673 if (!CanLoadPropertyFromPrototype(map, name, &lookup)) return NULL; 4644 if (!CanLoadPropertyFromPrototype(map, name, &lookup)) return NULL;
4674 4645
4675 Handle<Object> prototype(map->prototype(), isolate()); 4646 Handle<Object> prototype(map->prototype(), isolate());
4676 for (count = 1; count < types->length(); ++count) { 4647 for (count = 1; count < types->length(); ++count) {
4677 Handle<Map> test_map(types->at(count)); 4648 Handle<Map> test_map(types->at(count));
4678 if (!CanLoadPropertyFromPrototype(test_map, name, &lookup)) return NULL; 4649 if (!CanLoadPropertyFromPrototype(test_map, name, &lookup)) return NULL;
4679 if (test_map->prototype() != *prototype) return NULL; 4650 if (test_map->prototype() != *prototype) return NULL;
4680 } 4651 }
4681 4652
4682 LookupInPrototypes(map, name, &lookup); 4653 LookupInPrototypes(map, name, &lookup);
4683 if (!lookup.IsField()) return NULL; 4654 if (!lookup.IsField()) return NULL;
4684 4655
4685 BuildCheckHeapObject(object); 4656 BuildCheckHeapObject(object);
4686 AddInstruction(HCheckMaps::New(object, types, zone())); 4657 Add<HCheckMaps>(object, types);
4687 4658
4688 Handle<JSObject> holder(lookup.holder()); 4659 Handle<JSObject> holder(lookup.holder());
4689 Handle<Map> holder_map(holder->map()); 4660 Handle<Map> holder_map(holder->map());
4690 AddInstruction(new(zone()) HCheckPrototypeMaps( 4661 Add<HCheckPrototypeMaps>(
4691 Handle<JSObject>::cast(prototype), holder, zone(), top_info())); 4662 Handle<JSObject>::cast(prototype), holder, top_info());
4692 HValue* holder_value = AddInstruction(new(zone()) HConstant(holder)); 4663 HValue* holder_value = Add<HConstant>(holder);
4693 return BuildLoadNamedField(holder_value, 4664 return BuildLoadNamedField(holder_value,
4694 HObjectAccess::ForField(holder_map, &lookup, name)); 4665 HObjectAccess::ForField(holder_map, &lookup, name));
4695 } 4666 }
4696 4667
4697 4668
4698 void HOptimizedGraphBuilder::HandlePolymorphicLoadNamedField( 4669 void HOptimizedGraphBuilder::HandlePolymorphicLoadNamedField(
4699 Property* expr, 4670 Property* expr,
4700 HValue* object, 4671 HValue* object,
4701 SmallMapList* types, 4672 SmallMapList* types,
4702 Handle<String> name) { 4673 Handle<String> name) {
4703 HInstruction* instr = TryLoadPolymorphicAsMonomorphic( 4674 HInstruction* instr = TryLoadPolymorphicAsMonomorphic(
4704 expr, object, types, name); 4675 expr, object, types, name);
4705 if (instr == NULL) { 4676 if (instr == NULL) {
4706 // Something did not match; must use a polymorphic load. 4677 // Something did not match; must use a polymorphic load.
4707 BuildCheckHeapObject(object); 4678 BuildCheckHeapObject(object);
4708 HValue* context = environment()->LookupContext(); 4679 HValue* context = environment()->context();
4709 instr = new(zone()) HLoadNamedFieldPolymorphic( 4680 instr = new(zone()) HLoadNamedFieldPolymorphic(
4710 context, object, types, name, zone()); 4681 context, object, types, name, zone());
4711 } 4682 }
4712 4683
4713 instr->set_position(expr->position()); 4684 instr->set_position(expr->position());
4714 return ast_context()->ReturnInstruction(instr, expr->id()); 4685 return ast_context()->ReturnInstruction(instr, expr->id());
4715 } 4686 }
4716 4687
4717 4688
4718 bool HOptimizedGraphBuilder::TryStorePolymorphicAsMonomorphic( 4689 bool HOptimizedGraphBuilder::TryStorePolymorphicAsMonomorphic(
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
4755 } else if (access.IsInobject() != new_access.IsInobject()) { 4726 } else if (access.IsInobject() != new_access.IsInobject()) {
4756 // In-objectness did not match. 4727 // In-objectness did not match.
4757 break; 4728 break;
4758 } 4729 }
4759 } 4730 }
4760 4731
4761 if (count != types->length()) return false; 4732 if (count != types->length()) return false;
4762 4733
4763 // Everything matched; can use monomorphic store. 4734 // Everything matched; can use monomorphic store.
4764 BuildCheckHeapObject(object); 4735 BuildCheckHeapObject(object);
4765 AddInstruction(HCheckMaps::New(object, types, zone())); 4736 Add<HCheckMaps>(object, types);
4766 HInstruction* store; 4737 HInstruction* store;
4767 CHECK_ALIVE_OR_RETURN( 4738 CHECK_ALIVE_OR_RETURN(
4768 store = BuildStoreNamedField( 4739 store = BuildStoreNamedField(
4769 object, name, store_value, types->at(count - 1), &lookup), 4740 object, name, store_value, types->at(count - 1), &lookup),
4770 true); 4741 true);
4771 if (!ast_context()->IsEffect()) Push(result_value); 4742 if (!ast_context()->IsEffect()) Push(result_value);
4772 store->set_position(position); 4743 store->set_position(position);
4773 AddInstruction(store); 4744 AddInstruction(store);
4774 Add<HSimulate>(assignment_id); 4745 Add<HSimulate>(assignment_id);
4775 if (!ast_context()->IsEffect()) Drop(1); 4746 if (!ast_context()->IsEffect()) Drop(1);
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after
4927 Add<HDeoptimize>(Deoptimizer::EAGER); 4898 Add<HDeoptimize>(Deoptimizer::EAGER);
4928 builder.End(); 4899 builder.End();
4929 } 4900 }
4930 HInstruction* instr = 4901 HInstruction* instr =
4931 Add<HStoreGlobalCell>(value, cell, lookup.GetPropertyDetails()); 4902 Add<HStoreGlobalCell>(value, cell, lookup.GetPropertyDetails());
4932 instr->set_position(position); 4903 instr->set_position(position);
4933 if (instr->HasObservableSideEffects()) { 4904 if (instr->HasObservableSideEffects()) {
4934 Add<HSimulate>(ast_id, REMOVABLE_SIMULATE); 4905 Add<HSimulate>(ast_id, REMOVABLE_SIMULATE);
4935 } 4906 }
4936 } else { 4907 } else {
4937 HValue* context = environment()->LookupContext(); 4908 HGlobalObject* global_object = Add<HGlobalObject>();
4938 HGlobalObject* global_object = Add<HGlobalObject>(context);
4939 HStoreGlobalGeneric* instr = 4909 HStoreGlobalGeneric* instr =
4940 Add<HStoreGlobalGeneric>(context, global_object, var->name(), 4910 Add<HStoreGlobalGeneric>(global_object, var->name(),
4941 value, function_strict_mode_flag()); 4911 value, function_strict_mode_flag());
4942 instr->set_position(position); 4912 instr->set_position(position);
4943 ASSERT(instr->HasObservableSideEffects()); 4913 ASSERT(instr->HasObservableSideEffects());
4944 Add<HSimulate>(ast_id, REMOVABLE_SIMULATE); 4914 Add<HSimulate>(ast_id, REMOVABLE_SIMULATE);
4945 } 4915 }
4946 } 4916 }
4947 4917
4948 4918
4949 void HOptimizedGraphBuilder::BuildStoreNamed(Expression* expr, 4919 void HOptimizedGraphBuilder::BuildStoreNamed(Expression* expr,
4950 BailoutId id, 4920 BailoutId id,
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
5071 return ast_context()->ReturnValue(Pop()); 5041 return ast_context()->ReturnValue(Pop());
5072 case CONST_HARMONY: 5042 case CONST_HARMONY:
5073 // This case is checked statically so no need to 5043 // This case is checked statically so no need to
5074 // perform checks here 5044 // perform checks here
5075 UNREACHABLE(); 5045 UNREACHABLE();
5076 default: 5046 default:
5077 mode = HStoreContextSlot::kNoCheck; 5047 mode = HStoreContextSlot::kNoCheck;
5078 } 5048 }
5079 5049
5080 HValue* context = BuildContextChainWalk(var); 5050 HValue* context = BuildContextChainWalk(var);
5081 HStoreContextSlot* instr = Add<HStoreContextSlot>(context, var->index(), 5051 HStoreContextSlot* instr = Add<HStoreContextSlot>(
5082 mode, Top()); 5052 context, var->index(), mode, Top());
5083 if (instr->HasObservableSideEffects()) { 5053 if (instr->HasObservableSideEffects()) {
5084 Add<HSimulate>(expr->AssignmentId(), REMOVABLE_SIMULATE); 5054 Add<HSimulate>(expr->AssignmentId(), REMOVABLE_SIMULATE);
5085 } 5055 }
5086 break; 5056 break;
5087 } 5057 }
5088 5058
5089 case Variable::LOOKUP: 5059 case Variable::LOOKUP:
5090 return Bailout("compound assignment to lookup slot"); 5060 return Bailout("compound assignment to lookup slot");
5091 } 5061 }
5092 return ast_context()->ReturnValue(Pop()); 5062 return ast_context()->ReturnValue(Pop());
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after
5283 expr->op() == Token::INIT_LET || 5253 expr->op() == Token::INIT_LET ||
5284 expr->op() == Token::INIT_CONST_HARMONY) { 5254 expr->op() == Token::INIT_CONST_HARMONY) {
5285 mode = HStoreContextSlot::kNoCheck; 5255 mode = HStoreContextSlot::kNoCheck;
5286 } else { 5256 } else {
5287 ASSERT(expr->op() == Token::INIT_CONST); 5257 ASSERT(expr->op() == Token::INIT_CONST);
5288 5258
5289 mode = HStoreContextSlot::kCheckIgnoreAssignment; 5259 mode = HStoreContextSlot::kCheckIgnoreAssignment;
5290 } 5260 }
5291 5261
5292 HValue* context = BuildContextChainWalk(var); 5262 HValue* context = BuildContextChainWalk(var);
5293 HStoreContextSlot* instr = Add<HStoreContextSlot>(context, var->index(), 5263 HStoreContextSlot* instr = Add<HStoreContextSlot>(
5294 mode, Top()); 5264 context, var->index(), mode, Top());
5295 if (instr->HasObservableSideEffects()) { 5265 if (instr->HasObservableSideEffects()) {
5296 Add<HSimulate>(expr->AssignmentId(), REMOVABLE_SIMULATE); 5266 Add<HSimulate>(expr->AssignmentId(), REMOVABLE_SIMULATE);
5297 } 5267 }
5298 return ast_context()->ReturnValue(Pop()); 5268 return ast_context()->ReturnValue(Pop());
5299 } 5269 }
5300 5270
5301 case Variable::LOOKUP: 5271 case Variable::LOOKUP:
5302 return Bailout("assignment to LOOKUP variable"); 5272 return Bailout("assignment to LOOKUP variable");
5303 } 5273 }
5304 } else { 5274 } else {
(...skipping 11 matching lines...) Expand all
5316 void HOptimizedGraphBuilder::VisitThrow(Throw* expr) { 5286 void HOptimizedGraphBuilder::VisitThrow(Throw* expr) {
5317 ASSERT(!HasStackOverflow()); 5287 ASSERT(!HasStackOverflow());
5318 ASSERT(current_block() != NULL); 5288 ASSERT(current_block() != NULL);
5319 ASSERT(current_block()->HasPredecessor()); 5289 ASSERT(current_block()->HasPredecessor());
5320 // We don't optimize functions with invalid left-hand sides in 5290 // We don't optimize functions with invalid left-hand sides in
5321 // assignments, count operations, or for-in. Consequently throw can 5291 // assignments, count operations, or for-in. Consequently throw can
5322 // currently only occur in an effect context. 5292 // currently only occur in an effect context.
5323 ASSERT(ast_context()->IsEffect()); 5293 ASSERT(ast_context()->IsEffect());
5324 CHECK_ALIVE(VisitForValue(expr->exception())); 5294 CHECK_ALIVE(VisitForValue(expr->exception()));
5325 5295
5326 HValue* context = environment()->LookupContext();
5327 HValue* value = environment()->Pop(); 5296 HValue* value = environment()->Pop();
5328 HThrow* instr = Add<HThrow>(context, value); 5297 HThrow* instr = Add<HThrow>(value);
5329 instr->set_position(expr->position()); 5298 instr->set_position(expr->position());
5330 Add<HSimulate>(expr->id()); 5299 Add<HSimulate>(expr->id());
5331 current_block()->FinishExit(new(zone()) HAbnormalExit); 5300 current_block()->FinishExit(new(zone()) HAbnormalExit);
5332 set_current_block(NULL); 5301 set_current_block(NULL);
5333 } 5302 }
5334 5303
5335 5304
5336 HLoadNamedField* HGraphBuilder::BuildLoadNamedField(HValue* object, 5305 HLoadNamedField* HGraphBuilder::BuildLoadNamedField(HValue* object,
5337 HObjectAccess access) { 5306 HObjectAccess access) {
5338 if (FLAG_track_double_fields && access.representation().IsDouble()) { 5307 if (FLAG_track_double_fields && access.representation().IsDouble()) {
5339 // load the heap number 5308 // load the heap number
5340 HLoadNamedField* heap_number = 5309 HLoadNamedField* heap_number = Add<HLoadNamedField>(
5341 AddLoad(object, access.WithRepresentation(Representation::Tagged())); 5310 object, access.WithRepresentation(Representation::Tagged()));
5342 heap_number->set_type(HType::HeapNumber()); 5311 heap_number->set_type(HType::HeapNumber());
5343 // load the double value from it 5312 // load the double value from it
5344 return new(zone()) HLoadNamedField(heap_number, 5313 return New<HLoadNamedField>(heap_number,
5345 HObjectAccess::ForHeapNumberValue(), NULL); 5314 HObjectAccess::ForHeapNumberValue());
5346 } 5315 }
5347 return new(zone()) HLoadNamedField(object, access, NULL); 5316 return New<HLoadNamedField>(object, access);
5348 } 5317 }
5349 5318
5350 5319
5351 HInstruction* HOptimizedGraphBuilder::BuildLoadNamedGeneric( 5320 HInstruction* HOptimizedGraphBuilder::BuildLoadNamedGeneric(
5352 HValue* object, 5321 HValue* object,
5353 Handle<String> name, 5322 Handle<String> name,
5354 Property* expr) { 5323 Property* expr) {
5355 if (expr->IsUninitialized()) { 5324 if (expr->IsUninitialized()) {
5356 Add<HDeoptimize>(Deoptimizer::SOFT); 5325 Add<HDeoptimize>(Deoptimizer::SOFT);
5357 } 5326 }
5358 HValue* context = environment()->LookupContext(); 5327 HValue* context = environment()->context();
5359 return new(zone()) HLoadNamedGeneric(context, object, name); 5328 return new(zone()) HLoadNamedGeneric(context, object, name);
5360 } 5329 }
5361 5330
5362 5331
5363 HInstruction* HOptimizedGraphBuilder::BuildCallGetter( 5332 HInstruction* HOptimizedGraphBuilder::BuildCallGetter(
5364 HValue* object, 5333 HValue* object,
5365 Handle<Map> map, 5334 Handle<Map> map,
5366 Handle<JSFunction> getter, 5335 Handle<JSFunction> getter,
5367 Handle<JSObject> holder) { 5336 Handle<JSObject> holder) {
5368 AddCheckConstantFunction(holder, object, map); 5337 AddCheckConstantFunction(holder, object, map);
5369 Add<HPushArgument>(object); 5338 Add<HPushArgument>(object);
5370 return new(zone()) HCallConstantFunction(getter, 1); 5339 return new(zone()) HCallConstantFunction(getter, 1);
5371 } 5340 }
5372 5341
5373 5342
5374 HInstruction* HOptimizedGraphBuilder::BuildLoadNamedMonomorphic( 5343 HInstruction* HOptimizedGraphBuilder::BuildLoadNamedMonomorphic(
5375 HValue* object, 5344 HValue* object,
5376 Handle<String> name, 5345 Handle<String> name,
5377 Property* expr, 5346 Property* expr,
5378 Handle<Map> map) { 5347 Handle<Map> map) {
5379 // Handle a load from a known field. 5348 // Handle a load from a known field.
5380 ASSERT(!map->is_dictionary_map()); 5349 ASSERT(!map->is_dictionary_map());
5381 5350
5382 // Handle access to various length properties 5351 // Handle access to various length properties
5383 if (name->Equals(isolate()->heap()->length_string())) { 5352 if (name->Equals(isolate()->heap()->length_string())) {
5384 if (map->instance_type() == JS_ARRAY_TYPE) { 5353 if (map->instance_type() == JS_ARRAY_TYPE) {
5385 AddCheckMap(object, map); 5354 AddCheckMap(object, map);
5386 return new(zone()) HLoadNamedField(object, 5355 return New<HLoadNamedField>(object,
5387 HObjectAccess::ForArrayLength(map->elements_kind())); 5356 HObjectAccess::ForArrayLength(map->elements_kind()));
5388 } 5357 }
5389 } 5358 }
5390 5359
5391 LookupResult lookup(isolate()); 5360 LookupResult lookup(isolate());
5392 map->LookupDescriptor(NULL, *name, &lookup); 5361 map->LookupDescriptor(NULL, *name, &lookup);
5393 if (lookup.IsField()) { 5362 if (lookup.IsField()) {
5394 AddCheckMap(object, map); 5363 AddCheckMap(object, map);
5395 return BuildLoadNamedField(object, 5364 return BuildLoadNamedField(object,
5396 HObjectAccess::ForField(map, &lookup, name)); 5365 HObjectAccess::ForField(map, &lookup, name));
5397 } 5366 }
5398 5367
5399 // Handle a load of a constant known function. 5368 // Handle a load of a constant known function.
5400 if (lookup.IsConstant()) { 5369 if (lookup.IsConstant()) {
5401 AddCheckMap(object, map); 5370 AddCheckMap(object, map);
5402 Handle<Object> constant(lookup.GetConstantFromMap(*map), isolate()); 5371 Handle<Object> constant(lookup.GetConstantFromMap(*map), isolate());
5403 return new(zone()) HConstant(constant); 5372 return New<HConstant>(constant);
5404 } 5373 }
5405 5374
5406 // Handle a load from a known field somewhere in the prototype chain. 5375 // Handle a load from a known field somewhere in the prototype chain.
5407 LookupInPrototypes(map, name, &lookup); 5376 LookupInPrototypes(map, name, &lookup);
5408 if (lookup.IsField()) { 5377 if (lookup.IsField()) {
5409 Handle<JSObject> prototype(JSObject::cast(map->prototype())); 5378 Handle<JSObject> prototype(JSObject::cast(map->prototype()));
5410 Handle<JSObject> holder(lookup.holder()); 5379 Handle<JSObject> holder(lookup.holder());
5411 Handle<Map> holder_map(holder->map()); 5380 Handle<Map> holder_map(holder->map());
5412 AddCheckMap(object, map); 5381 AddCheckMap(object, map);
5413 Add<HCheckPrototypeMaps>(prototype, holder, zone(), top_info()); 5382 Add<HCheckPrototypeMaps>(prototype, holder, top_info());
5414 HValue* holder_value = Add<HConstant>(holder); 5383 HValue* holder_value = Add<HConstant>(holder);
5415 return BuildLoadNamedField(holder_value, 5384 return BuildLoadNamedField(holder_value,
5416 HObjectAccess::ForField(holder_map, &lookup, name)); 5385 HObjectAccess::ForField(holder_map, &lookup, name));
5417 } 5386 }
5418 5387
5419 // Handle a load of a constant function somewhere in the prototype chain. 5388 // Handle a load of a constant function somewhere in the prototype chain.
5420 if (lookup.IsConstant()) { 5389 if (lookup.IsConstant()) {
5421 Handle<JSObject> prototype(JSObject::cast(map->prototype())); 5390 Handle<JSObject> prototype(JSObject::cast(map->prototype()));
5422 Handle<JSObject> holder(lookup.holder()); 5391 Handle<JSObject> holder(lookup.holder());
5423 Handle<Map> holder_map(holder->map()); 5392 Handle<Map> holder_map(holder->map());
5424 AddCheckMap(object, map); 5393 AddCheckMap(object, map);
5425 Add<HCheckPrototypeMaps>(prototype, holder, zone(), top_info()); 5394 Add<HCheckPrototypeMaps>(prototype, holder, top_info());
5426 Handle<Object> constant(lookup.GetConstantFromMap(*holder_map), isolate()); 5395 Handle<Object> constant(lookup.GetConstantFromMap(*holder_map), isolate());
5427 return new(zone()) HConstant(constant); 5396 return New<HConstant>(constant);
5428 } 5397 }
5429 5398
5430 // No luck, do a generic load. 5399 // No luck, do a generic load.
5431 return BuildLoadNamedGeneric(object, name, expr); 5400 return BuildLoadNamedGeneric(object, name, expr);
5432 } 5401 }
5433 5402
5434 5403
5435 HInstruction* HOptimizedGraphBuilder::BuildLoadKeyedGeneric(HValue* object, 5404 HInstruction* HOptimizedGraphBuilder::BuildLoadKeyedGeneric(HValue* object,
5436 HValue* key) { 5405 HValue* key) {
5437 HValue* context = environment()->LookupContext(); 5406 HValue* context = environment()->context();
5438 return new(zone()) HLoadKeyedGeneric(context, object, key); 5407 return new(zone()) HLoadKeyedGeneric(context, object, key);
5439 } 5408 }
5440 5409
5441 5410
5442 HInstruction* HOptimizedGraphBuilder::BuildMonomorphicElementAccess( 5411 HInstruction* HOptimizedGraphBuilder::BuildMonomorphicElementAccess(
5443 HValue* object, 5412 HValue* object,
5444 HValue* key, 5413 HValue* key,
5445 HValue* val, 5414 HValue* val,
5446 HValue* dependency, 5415 HValue* dependency,
5447 Handle<Map> map, 5416 Handle<Map> map,
5448 bool is_store, 5417 bool is_store,
5449 KeyedAccessStoreMode store_mode) { 5418 KeyedAccessStoreMode store_mode) {
5450 HCheckMaps* mapcheck = HCheckMaps::New( 5419 HCheckMaps* mapcheck = Add<HCheckMaps>(object, map, top_info(), dependency);
5451 object, map, zone(), top_info(), dependency);
5452 AddInstruction(mapcheck);
5453 if (dependency) { 5420 if (dependency) {
5454 mapcheck->ClearGVNFlag(kDependsOnElementsKind); 5421 mapcheck->ClearGVNFlag(kDependsOnElementsKind);
5455 } 5422 }
5456 5423
5457 // Loads from a "stock" fast holey double arrays can elide the hole check. 5424 // Loads from a "stock" fast holey double arrays can elide the hole check.
5458 LoadKeyedHoleMode load_mode = NEVER_RETURN_HOLE; 5425 LoadKeyedHoleMode load_mode = NEVER_RETURN_HOLE;
5459 if (*map == isolate()->get_initial_js_array_map(FAST_HOLEY_DOUBLE_ELEMENTS) && 5426 if (*map == isolate()->get_initial_js_array_map(FAST_HOLEY_DOUBLE_ELEMENTS) &&
5460 isolate()->IsFastArrayConstructorPrototypeChainIntact()) { 5427 isolate()->IsFastArrayConstructorPrototypeChainIntact()) {
5461 Handle<JSObject> prototype(JSObject::cast(map->prototype()), isolate()); 5428 Handle<JSObject> prototype(JSObject::cast(map->prototype()), isolate());
5462 Handle<JSObject> object_prototype = isolate()->initial_object_prototype(); 5429 Handle<JSObject> object_prototype = isolate()->initial_object_prototype();
5463 Add<HCheckPrototypeMaps>(prototype, object_prototype, zone(), top_info()); 5430 Add<HCheckPrototypeMaps>(prototype, object_prototype, top_info());
5464 load_mode = ALLOW_RETURN_HOLE; 5431 load_mode = ALLOW_RETURN_HOLE;
5465 graph()->MarkDependsOnEmptyArrayProtoElements(); 5432 graph()->MarkDependsOnEmptyArrayProtoElements();
5466 } 5433 }
5467 5434
5468 return BuildUncheckedMonomorphicElementAccess( 5435 return BuildUncheckedMonomorphicElementAccess(
5469 object, key, val, 5436 object, key, val,
5470 mapcheck, map->instance_type() == JS_ARRAY_TYPE, 5437 mapcheck, map->instance_type() == JS_ARRAY_TYPE,
5471 map->elements_kind(), is_store, load_mode, store_mode); 5438 map->elements_kind(), is_store, load_mode, store_mode);
5472 } 5439 }
5473 5440
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
5510 // Remember the most general elements kind, the code for its load will 5477 // Remember the most general elements kind, the code for its load will
5511 // properly handle all of the more specific cases. 5478 // properly handle all of the more specific cases.
5512 if ((i == 0) || IsMoreGeneralElementsKindTransition( 5479 if ((i == 0) || IsMoreGeneralElementsKindTransition(
5513 most_general_consolidated_map->elements_kind(), 5480 most_general_consolidated_map->elements_kind(),
5514 map->elements_kind())) { 5481 map->elements_kind())) {
5515 most_general_consolidated_map = map; 5482 most_general_consolidated_map = map;
5516 } 5483 }
5517 } 5484 }
5518 if (!has_double_maps && !has_smi_or_object_maps) return NULL; 5485 if (!has_double_maps && !has_smi_or_object_maps) return NULL;
5519 5486
5520 HCheckMaps* check_maps = HCheckMaps::New(object, maps, zone()); 5487 HCheckMaps* check_maps = Add<HCheckMaps>(object, maps);
5521 AddInstruction(check_maps);
5522 HInstruction* instr = BuildUncheckedMonomorphicElementAccess( 5488 HInstruction* instr = BuildUncheckedMonomorphicElementAccess(
5523 object, key, val, check_maps, 5489 object, key, val, check_maps,
5524 most_general_consolidated_map->instance_type() == JS_ARRAY_TYPE, 5490 most_general_consolidated_map->instance_type() == JS_ARRAY_TYPE,
5525 most_general_consolidated_map->elements_kind(), 5491 most_general_consolidated_map->elements_kind(),
5526 false, NEVER_RETURN_HOLE, STANDARD_STORE); 5492 false, NEVER_RETURN_HOLE, STANDARD_STORE);
5527 return instr; 5493 return instr;
5528 } 5494 }
5529 5495
5530 5496
5531 HValue* HOptimizedGraphBuilder::HandlePolymorphicElementAccess( 5497 HValue* HOptimizedGraphBuilder::HandlePolymorphicElementAccess(
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
5576 5542
5577 MapHandleList untransitionable_maps(maps->length()); 5543 MapHandleList untransitionable_maps(maps->length());
5578 HTransitionElementsKind* transition = NULL; 5544 HTransitionElementsKind* transition = NULL;
5579 for (int i = 0; i < maps->length(); ++i) { 5545 for (int i = 0; i < maps->length(); ++i) {
5580 Handle<Map> map = maps->at(i); 5546 Handle<Map> map = maps->at(i);
5581 ASSERT(map->IsMap()); 5547 ASSERT(map->IsMap());
5582 if (!transition_target.at(i).is_null()) { 5548 if (!transition_target.at(i).is_null()) {
5583 ASSERT(Map::IsValidElementsTransition( 5549 ASSERT(Map::IsValidElementsTransition(
5584 map->elements_kind(), 5550 map->elements_kind(),
5585 transition_target.at(i)->elements_kind())); 5551 transition_target.at(i)->elements_kind()));
5586 HValue* context = environment()->LookupContext(); 5552 transition = Add<HTransitionElementsKind>(object, map,
5587 transition = Add<HTransitionElementsKind>(context, object, map,
5588 transition_target.at(i)); 5553 transition_target.at(i));
5589 } else { 5554 } else {
5590 untransitionable_maps.Add(map); 5555 untransitionable_maps.Add(map);
5591 } 5556 }
5592 } 5557 }
5593 5558
5594 // If only one map is left after transitioning, handle this case 5559 // If only one map is left after transitioning, handle this case
5595 // monomorphically. 5560 // monomorphically.
5596 ASSERT(untransitionable_maps.length() >= 1); 5561 ASSERT(untransitionable_maps.length() >= 1);
5597 if (untransitionable_maps.length() == 1) { 5562 if (untransitionable_maps.length() == 1) {
(...skipping 25 matching lines...) Expand all
5623 HBasicBlock* other_map = graph()->CreateBasicBlock(); 5588 HBasicBlock* other_map = graph()->CreateBasicBlock();
5624 HCompareMap* mapcompare = 5589 HCompareMap* mapcompare =
5625 new(zone()) HCompareMap(object, map, this_map, other_map); 5590 new(zone()) HCompareMap(object, map, this_map, other_map);
5626 current_block()->Finish(mapcompare); 5591 current_block()->Finish(mapcompare);
5627 5592
5628 set_current_block(this_map); 5593 set_current_block(this_map);
5629 HInstruction* checked_key = NULL; 5594 HInstruction* checked_key = NULL;
5630 HInstruction* access = NULL; 5595 HInstruction* access = NULL;
5631 if (IsFastElementsKind(elements_kind)) { 5596 if (IsFastElementsKind(elements_kind)) {
5632 if (is_store && !IsFastDoubleElementsKind(elements_kind)) { 5597 if (is_store && !IsFastDoubleElementsKind(elements_kind)) {
5633 AddInstruction(HCheckMaps::New( 5598 Add<HCheckMaps>(
5634 elements, isolate()->factory()->fixed_array_map(), 5599 elements, isolate()->factory()->fixed_array_map(),
5635 zone(), top_info(), mapcompare)); 5600 top_info(), mapcompare);
5636 } 5601 }
5637 if (map->instance_type() == JS_ARRAY_TYPE) { 5602 if (map->instance_type() == JS_ARRAY_TYPE) {
5638 HInstruction* length = AddLoad( 5603 HInstruction* length = Add<HLoadNamedField>(
5639 object, HObjectAccess::ForArrayLength(elements_kind), mapcompare); 5604 object, HObjectAccess::ForArrayLength(elements_kind), mapcompare);
5640 checked_key = Add<HBoundsCheck>(key, length); 5605 checked_key = Add<HBoundsCheck>(key, length);
5641 } else { 5606 } else {
5642 HInstruction* length = AddLoadFixedArrayLength(elements); 5607 HInstruction* length = AddLoadFixedArrayLength(elements);
5643 checked_key = Add<HBoundsCheck>(key, length); 5608 checked_key = Add<HBoundsCheck>(key, length);
5644 } 5609 }
5645 access = AddFastElementAccess( 5610 access = AddFastElementAccess(
5646 elements, checked_key, val, mapcompare, 5611 elements, checked_key, val, mapcompare,
5647 elements_kind, is_store, NEVER_RETURN_HOLE, STANDARD_STORE); 5612 elements_kind, is_store, NEVER_RETURN_HOLE, STANDARD_STORE);
5648 } else if (IsDictionaryElementsKind(elements_kind)) { 5613 } else if (IsDictionaryElementsKind(elements_kind)) {
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
5724 if (position != RelocInfo::kNoPosition) instr->set_position(position); 5689 if (position != RelocInfo::kNoPosition) instr->set_position(position);
5725 *has_side_effects = instr->HasObservableSideEffects(); 5690 *has_side_effects = instr->HasObservableSideEffects();
5726 return instr; 5691 return instr;
5727 } 5692 }
5728 5693
5729 5694
5730 HInstruction* HOptimizedGraphBuilder::BuildStoreKeyedGeneric( 5695 HInstruction* HOptimizedGraphBuilder::BuildStoreKeyedGeneric(
5731 HValue* object, 5696 HValue* object,
5732 HValue* key, 5697 HValue* key,
5733 HValue* value) { 5698 HValue* value) {
5734 HValue* context = environment()->LookupContext(); 5699 HValue* context = environment()->context();
5735 return new(zone()) HStoreKeyedGeneric( 5700 return new(zone()) HStoreKeyedGeneric(
5736 context, 5701 context,
5737 object, 5702 object,
5738 key, 5703 key,
5739 value, 5704 value,
5740 function_strict_mode_flag()); 5705 function_strict_mode_flag());
5741 } 5706 }
5742 5707
5743 5708
5744 void HOptimizedGraphBuilder::EnsureArgumentsArePushedForAccess() { 5709 void HOptimizedGraphBuilder::EnsureArgumentsArePushedForAccess() {
5745 // Outermost function already has arguments on the stack. 5710 // Outermost function already has arguments on the stack.
5746 if (function_state()->outer() == NULL) return; 5711 if (function_state()->outer() == NULL) return;
5747 5712
5748 if (function_state()->arguments_pushed()) return; 5713 if (function_state()->arguments_pushed()) return;
5749 5714
5750 // Push arguments when entering inlined function. 5715 // Push arguments when entering inlined function.
5751 HEnterInlined* entry = function_state()->entry(); 5716 HEnterInlined* entry = function_state()->entry();
5752 entry->set_arguments_pushed(); 5717 entry->set_arguments_pushed();
5753 5718
5754 HArgumentsObject* arguments = entry->arguments_object(); 5719 HArgumentsObject* arguments = entry->arguments_object();
5755 const ZoneList<HValue*>* arguments_values = arguments->arguments_values(); 5720 const ZoneList<HValue*>* arguments_values = arguments->arguments_values();
5756 5721
5757 HInstruction* insert_after = entry; 5722 HInstruction* insert_after = entry;
5758 for (int i = 0; i < arguments_values->length(); i++) { 5723 for (int i = 0; i < arguments_values->length(); i++) {
5759 HValue* argument = arguments_values->at(i); 5724 HValue* argument = arguments_values->at(i);
5760 HInstruction* push_argument = new(zone()) HPushArgument(argument); 5725 HInstruction* push_argument = New<HPushArgument>(argument);
5761 push_argument->InsertAfter(insert_after); 5726 push_argument->InsertAfter(insert_after);
5762 insert_after = push_argument; 5727 insert_after = push_argument;
5763 } 5728 }
5764 5729
5765 HArgumentsElements* arguments_elements = 5730 HArgumentsElements* arguments_elements = New<HArgumentsElements>(true);
5766 new(zone()) HArgumentsElements(true);
5767 arguments_elements->ClearFlag(HValue::kUseGVN); 5731 arguments_elements->ClearFlag(HValue::kUseGVN);
5768 arguments_elements->InsertAfter(insert_after); 5732 arguments_elements->InsertAfter(insert_after);
5769 function_state()->set_arguments_elements(arguments_elements); 5733 function_state()->set_arguments_elements(arguments_elements);
5770 } 5734 }
5771 5735
5772 5736
5773 bool HOptimizedGraphBuilder::TryArgumentsAccess(Property* expr) { 5737 bool HOptimizedGraphBuilder::TryArgumentsAccess(Property* expr) {
5774 VariableProxy* proxy = expr->obj()->AsVariableProxy(); 5738 VariableProxy* proxy = expr->obj()->AsVariableProxy();
5775 if (proxy == NULL) return false; 5739 if (proxy == NULL) return false;
5776 if (!proxy->var()->IsStackAllocated()) return false; 5740 if (!proxy->var()->IsStackAllocated()) return false;
5777 if (!environment()->Lookup(proxy->var())->CheckFlag(HValue::kIsArguments)) { 5741 if (!environment()->Lookup(proxy->var())->CheckFlag(HValue::kIsArguments)) {
5778 return false; 5742 return false;
5779 } 5743 }
5780 5744
5781 HInstruction* result = NULL; 5745 HInstruction* result = NULL;
5782 if (expr->key()->IsPropertyName()) { 5746 if (expr->key()->IsPropertyName()) {
5783 Handle<String> name = expr->key()->AsLiteral()->AsPropertyName(); 5747 Handle<String> name = expr->key()->AsLiteral()->AsPropertyName();
5784 if (!name->IsOneByteEqualTo(STATIC_ASCII_VECTOR("length"))) return false; 5748 if (!name->IsOneByteEqualTo(STATIC_ASCII_VECTOR("length"))) return false;
5785 5749
5786 if (function_state()->outer() == NULL) { 5750 if (function_state()->outer() == NULL) {
5787 HInstruction* elements = Add<HArgumentsElements>(false); 5751 HInstruction* elements = Add<HArgumentsElements>(false);
5788 result = new(zone()) HArgumentsLength(elements); 5752 result = New<HArgumentsLength>(elements);
5789 } else { 5753 } else {
5790 // Number of arguments without receiver. 5754 // Number of arguments without receiver.
5791 int argument_count = environment()-> 5755 int argument_count = environment()->
5792 arguments_environment()->parameter_count() - 1; 5756 arguments_environment()->parameter_count() - 1;
5793 result = new(zone()) HConstant(argument_count); 5757 result = New<HConstant>(argument_count);
5794 } 5758 }
5795 } else { 5759 } else {
5796 Push(graph()->GetArgumentsObject()); 5760 Push(graph()->GetArgumentsObject());
5797 VisitForValue(expr->key()); 5761 VisitForValue(expr->key());
5798 if (HasStackOverflow() || current_block() == NULL) return true; 5762 if (HasStackOverflow() || current_block() == NULL) return true;
5799 HValue* key = Pop(); 5763 HValue* key = Pop();
5800 Drop(1); // Arguments object. 5764 Drop(1); // Arguments object.
5801 if (function_state()->outer() == NULL) { 5765 if (function_state()->outer() == NULL) {
5802 HInstruction* elements = Add<HArgumentsElements>(false); 5766 HInstruction* elements = Add<HArgumentsElements>(false);
5803 HInstruction* length = Add<HArgumentsLength>(elements); 5767 HInstruction* length = Add<HArgumentsLength>(elements);
(...skipping 23 matching lines...) Expand all
5827 5791
5828 if (TryArgumentsAccess(expr)) return; 5792 if (TryArgumentsAccess(expr)) return;
5829 5793
5830 CHECK_ALIVE(VisitForValue(expr->obj())); 5794 CHECK_ALIVE(VisitForValue(expr->obj()));
5831 5795
5832 HInstruction* instr = NULL; 5796 HInstruction* instr = NULL;
5833 if (expr->IsStringLength()) { 5797 if (expr->IsStringLength()) {
5834 HValue* string = Pop(); 5798 HValue* string = Pop();
5835 BuildCheckHeapObject(string); 5799 BuildCheckHeapObject(string);
5836 AddInstruction(HCheckInstanceType::NewIsString(string, zone())); 5800 AddInstruction(HCheckInstanceType::NewIsString(string, zone()));
5837 instr = HStringLength::New(zone(), string); 5801 instr = NewUncasted<HStringLength>(string);
5838 } else if (expr->IsStringAccess()) { 5802 } else if (expr->IsStringAccess()) {
5839 CHECK_ALIVE(VisitForValue(expr->key())); 5803 CHECK_ALIVE(VisitForValue(expr->key()));
5840 HValue* index = Pop(); 5804 HValue* index = Pop();
5841 HValue* string = Pop(); 5805 HValue* string = Pop();
5842 HValue* context = environment()->LookupContext(); 5806 HValue* context = environment()->context();
5843 HInstruction* char_code = 5807 HInstruction* char_code =
5844 BuildStringCharCodeAt(context, string, index); 5808 BuildStringCharCodeAt(string, index);
5845 AddInstruction(char_code); 5809 AddInstruction(char_code);
5846 instr = HStringCharFromCode::New(zone(), context, char_code); 5810 instr = HStringCharFromCode::New(zone(), context, char_code);
5847 5811
5848 } else if (expr->IsFunctionPrototype()) { 5812 } else if (expr->IsFunctionPrototype()) {
5849 HValue* function = Pop(); 5813 HValue* function = Pop();
5850 BuildCheckHeapObject(function); 5814 BuildCheckHeapObject(function);
5851 instr = new(zone()) HLoadFunctionPrototype(function); 5815 instr = new(zone()) HLoadFunctionPrototype(function);
5852 5816
5853 } else if (expr->key()->IsPropertyName()) { 5817 } else if (expr->key()->IsPropertyName()) {
5854 Handle<String> name = expr->key()->AsLiteral()->AsPropertyName(); 5818 Handle<String> name = expr->key()->AsLiteral()->AsPropertyName();
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
5905 } 5869 }
5906 instr->set_position(expr->position()); 5870 instr->set_position(expr->position());
5907 return ast_context()->ReturnInstruction(instr, expr->id()); 5871 return ast_context()->ReturnInstruction(instr, expr->id());
5908 } 5872 }
5909 5873
5910 5874
5911 void HOptimizedGraphBuilder::AddCheckPrototypeMaps(Handle<JSObject> holder, 5875 void HOptimizedGraphBuilder::AddCheckPrototypeMaps(Handle<JSObject> holder,
5912 Handle<Map> receiver_map) { 5876 Handle<Map> receiver_map) {
5913 if (!holder.is_null()) { 5877 if (!holder.is_null()) {
5914 Handle<JSObject> prototype(JSObject::cast(receiver_map->prototype())); 5878 Handle<JSObject> prototype(JSObject::cast(receiver_map->prototype()));
5915 Add<HCheckPrototypeMaps>(prototype, holder, zone(), top_info()); 5879 Add<HCheckPrototypeMaps>(prototype, holder, top_info());
5916 } 5880 }
5917 } 5881 }
5918 5882
5919 5883
5920 void HOptimizedGraphBuilder::AddCheckConstantFunction( 5884 void HOptimizedGraphBuilder::AddCheckConstantFunction(
5921 Handle<JSObject> holder, 5885 Handle<JSObject> holder,
5922 HValue* receiver, 5886 HValue* receiver,
5923 Handle<Map> receiver_map) { 5887 Handle<Map> receiver_map) {
5924 // Constant functions have the nice property that the map will change if they 5888 // Constant functions have the nice property that the map will change if they
5925 // are overwritten. Therefore it is enough to check the map of the holder and 5889 // are overwritten. Therefore it is enough to check the map of the holder and
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
5974 Handle<Object> prototype(map->prototype(), isolate()); 5938 Handle<Object> prototype(map->prototype(), isolate());
5975 for (int count = 1; count < types->length(); ++count) { 5939 for (int count = 1; count < types->length(); ++count) {
5976 Handle<Map> test_map(types->at(count)); 5940 Handle<Map> test_map(types->at(count));
5977 if (!CanLoadPropertyFromPrototype(test_map, name, &lookup)) return false; 5941 if (!CanLoadPropertyFromPrototype(test_map, name, &lookup)) return false;
5978 if (test_map->prototype() != *prototype) return false; 5942 if (test_map->prototype() != *prototype) return false;
5979 } 5943 }
5980 5944
5981 if (!expr->ComputeTarget(map, name)) return false; 5945 if (!expr->ComputeTarget(map, name)) return false;
5982 5946
5983 BuildCheckHeapObject(receiver); 5947 BuildCheckHeapObject(receiver);
5984 AddInstruction(HCheckMaps::New(receiver, types, zone())); 5948 Add<HCheckMaps>(receiver, types);
5985 AddCheckPrototypeMaps(expr->holder(), map); 5949 AddCheckPrototypeMaps(expr->holder(), map);
5986 if (FLAG_trace_inlining) { 5950 if (FLAG_trace_inlining) {
5987 Handle<JSFunction> caller = current_info()->closure(); 5951 Handle<JSFunction> caller = current_info()->closure();
5988 SmartArrayPointer<char> caller_name = 5952 SmartArrayPointer<char> caller_name =
5989 caller->shared()->DebugName()->ToCString(); 5953 caller->shared()->DebugName()->ToCString();
5990 PrintF("Trying to inline the polymorphic call to %s from %s\n", 5954 PrintF("Trying to inline the polymorphic call to %s from %s\n",
5991 *name->ToCString(), *caller_name); 5955 *name->ToCString(), *caller_name);
5992 } 5956 }
5993 5957
5994 if (!TryInlineCall(expr)) { 5958 if (!TryInlineCall(expr)) {
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after
6130 // Finish up. Unconditionally deoptimize if we've handled all the maps we 6094 // Finish up. Unconditionally deoptimize if we've handled all the maps we
6131 // know about and do not want to handle ones we've never seen. Otherwise 6095 // know about and do not want to handle ones we've never seen. Otherwise
6132 // use a generic IC. 6096 // use a generic IC.
6133 if (ordered_functions == types->length() && FLAG_deoptimize_uncommon_cases) { 6097 if (ordered_functions == types->length() && FLAG_deoptimize_uncommon_cases) {
6134 // Because the deopt may be the only path in the polymorphic call, make sure 6098 // Because the deopt may be the only path in the polymorphic call, make sure
6135 // that the environment stack matches the depth on deopt that it otherwise 6099 // that the environment stack matches the depth on deopt that it otherwise
6136 // would have had after a successful call. 6100 // would have had after a successful call.
6137 Drop(argument_count - (ast_context()->IsEffect() ? 0 : 1)); 6101 Drop(argument_count - (ast_context()->IsEffect() ? 0 : 1));
6138 FinishExitWithHardDeoptimization(join); 6102 FinishExitWithHardDeoptimization(join);
6139 } else { 6103 } else {
6140 HValue* context = environment()->LookupContext(); 6104 HValue* context = environment()->context();
6141 HCallNamed* call = new(zone()) HCallNamed(context, name, argument_count); 6105 HCallNamed* call = new(zone()) HCallNamed(context, name, argument_count);
6142 call->set_position(expr->position()); 6106 call->set_position(expr->position());
6143 PreProcessCall(call); 6107 PreProcessCall(call);
6144 6108
6145 if (join != NULL) { 6109 if (join != NULL) {
6146 AddInstruction(call); 6110 AddInstruction(call);
6147 if (!ast_context()->IsEffect()) Push(call); 6111 if (!ast_context()->IsEffect()) Push(call);
6148 current_block()->Goto(join); 6112 current_block()->Goto(join);
6149 } else { 6113 } else {
6150 return ast_context()->ReturnInstruction(call, expr->id()); 6114 return ast_context()->ReturnInstruction(call, expr->id());
(...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after
6396 Add<HSimulate>(return_id); 6360 Add<HSimulate>(return_id);
6397 current_block()->UpdateEnvironment(inner_env); 6361 current_block()->UpdateEnvironment(inner_env);
6398 HArgumentsObject* arguments_object = NULL; 6362 HArgumentsObject* arguments_object = NULL;
6399 6363
6400 // If the function uses arguments object create and bind one, also copy 6364 // If the function uses arguments object create and bind one, also copy
6401 // current arguments values to use them for materialization. 6365 // current arguments values to use them for materialization.
6402 if (function->scope()->arguments() != NULL) { 6366 if (function->scope()->arguments() != NULL) {
6403 ASSERT(function->scope()->arguments()->IsStackAllocated()); 6367 ASSERT(function->scope()->arguments()->IsStackAllocated());
6404 HEnvironment* arguments_env = inner_env->arguments_environment(); 6368 HEnvironment* arguments_env = inner_env->arguments_environment();
6405 int arguments_count = arguments_env->parameter_count(); 6369 int arguments_count = arguments_env->parameter_count();
6406 arguments_object = Add<HArgumentsObject>(arguments_count, zone()); 6370 arguments_object = Add<HArgumentsObject>(arguments_count);
6407 inner_env->Bind(function->scope()->arguments(), arguments_object); 6371 inner_env->Bind(function->scope()->arguments(), arguments_object);
6408 for (int i = 0; i < arguments_count; i++) { 6372 for (int i = 0; i < arguments_count; i++) {
6409 arguments_object->AddArgument(arguments_env->Lookup(i), zone()); 6373 arguments_object->AddArgument(arguments_env->Lookup(i), zone());
6410 } 6374 }
6411 } 6375 }
6412 6376
6413 HEnterInlined* enter_inlined = 6377 HEnterInlined* enter_inlined =
6414 Add<HEnterInlined>(target, arguments_count, function, 6378 Add<HEnterInlined>(target, arguments_count, function,
6415 function_state()->inlining_kind(), 6379 function_state()->inlining_kind(),
6416 function->scope()->arguments(), 6380 function->scope()->arguments(),
6417 arguments_object, undefined_receiver, zone()); 6381 arguments_object, undefined_receiver);
6418 function_state()->set_entry(enter_inlined); 6382 function_state()->set_entry(enter_inlined);
6419 6383
6420 VisitDeclarations(target_info.scope()->declarations()); 6384 VisitDeclarations(target_info.scope()->declarations());
6421 VisitStatements(function->body()); 6385 VisitStatements(function->body());
6422 if (HasStackOverflow()) { 6386 if (HasStackOverflow()) {
6423 // Bail out if the inline function did, as we cannot residualize a call 6387 // Bail out if the inline function did, as we cannot residualize a call
6424 // instead. 6388 // instead.
6425 TraceInline(target, caller, "inline graph construction failed"); 6389 TraceInline(target, caller, "inline graph construction failed");
6426 target_shared->DisableOptimization("inlining bailed out"); 6390 target_shared->DisableOptimization("inlining bailed out");
6427 inline_bailout_ = true; 6391 inline_bailout_ = true;
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after
6598 case kMathRound: 6562 case kMathRound:
6599 case kMathFloor: 6563 case kMathFloor:
6600 case kMathAbs: 6564 case kMathAbs:
6601 case kMathSqrt: 6565 case kMathSqrt:
6602 case kMathLog: 6566 case kMathLog:
6603 case kMathSin: 6567 case kMathSin:
6604 case kMathCos: 6568 case kMathCos:
6605 case kMathTan: 6569 case kMathTan:
6606 if (expr->arguments()->length() == 1) { 6570 if (expr->arguments()->length() == 1) {
6607 HValue* argument = Pop(); 6571 HValue* argument = Pop();
6608 HValue* context = environment()->LookupContext(); 6572 HValue* context = environment()->context();
6609 Drop(1); // Receiver. 6573 Drop(1); // Receiver.
6610 HInstruction* op = 6574 HInstruction* op =
6611 HUnaryMathOperation::New(zone(), context, argument, id); 6575 HUnaryMathOperation::New(zone(), context, argument, id);
6612 op->set_position(expr->position()); 6576 op->set_position(expr->position());
6613 if (drop_extra) Drop(1); // Optionally drop the function. 6577 if (drop_extra) Drop(1); // Optionally drop the function.
6614 ast_context()->ReturnInstruction(op, expr->id()); 6578 ast_context()->ReturnInstruction(op, expr->id());
6615 return true; 6579 return true;
6616 } 6580 }
6617 break; 6581 break;
6618 case kMathImul: 6582 case kMathImul:
6619 if (expr->arguments()->length() == 2) { 6583 if (expr->arguments()->length() == 2) {
6620 HValue* right = Pop(); 6584 HValue* right = Pop();
6621 HValue* left = Pop(); 6585 HValue* left = Pop();
6622 Drop(1); // Receiver. 6586 Drop(1); // Receiver.
6623 HValue* context = environment()->LookupContext(); 6587 HValue* context = environment()->context();
6624 HInstruction* op = HMul::NewImul(zone(), context, left, right); 6588 HInstruction* op = HMul::NewImul(zone(), context, left, right);
6625 if (drop_extra) Drop(1); // Optionally drop the function. 6589 if (drop_extra) Drop(1); // Optionally drop the function.
6626 ast_context()->ReturnInstruction(op, expr->id()); 6590 ast_context()->ReturnInstruction(op, expr->id());
6627 return true; 6591 return true;
6628 } 6592 }
6629 break; 6593 break;
6630 default: 6594 default:
6631 // Not supported for inlining yet. 6595 // Not supported for inlining yet.
6632 break; 6596 break;
6633 } 6597 }
(...skipping 10 matching lines...) Expand all
6644 // Try to inline calls like Math.* as operations in the calling function. 6608 // Try to inline calls like Math.* as operations in the calling function.
6645 if (!expr->target()->shared()->HasBuiltinFunctionId()) return false; 6609 if (!expr->target()->shared()->HasBuiltinFunctionId()) return false;
6646 BuiltinFunctionId id = expr->target()->shared()->builtin_function_id(); 6610 BuiltinFunctionId id = expr->target()->shared()->builtin_function_id();
6647 int argument_count = expr->arguments()->length() + 1; // Plus receiver. 6611 int argument_count = expr->arguments()->length() + 1; // Plus receiver.
6648 switch (id) { 6612 switch (id) {
6649 case kStringCharCodeAt: 6613 case kStringCharCodeAt:
6650 case kStringCharAt: 6614 case kStringCharAt:
6651 if (argument_count == 2 && check_type == STRING_CHECK) { 6615 if (argument_count == 2 && check_type == STRING_CHECK) {
6652 HValue* index = Pop(); 6616 HValue* index = Pop();
6653 HValue* string = Pop(); 6617 HValue* string = Pop();
6654 HValue* context = environment()->LookupContext(); 6618 HValue* context = environment()->context();
6655 ASSERT(!expr->holder().is_null()); 6619 ASSERT(!expr->holder().is_null());
6656 Add<HCheckPrototypeMaps>(Call::GetPrototypeForPrimitiveCheck( 6620 Add<HCheckPrototypeMaps>(Call::GetPrototypeForPrimitiveCheck(
6657 STRING_CHECK, expr->holder()->GetIsolate()), 6621 STRING_CHECK, expr->holder()->GetIsolate()),
6658 expr->holder(), zone(), top_info()); 6622 expr->holder(), top_info());
6659 HInstruction* char_code = 6623 HInstruction* char_code =
6660 BuildStringCharCodeAt(context, string, index); 6624 BuildStringCharCodeAt(string, index);
6661 if (id == kStringCharCodeAt) { 6625 if (id == kStringCharCodeAt) {
6662 ast_context()->ReturnInstruction(char_code, expr->id()); 6626 ast_context()->ReturnInstruction(char_code, expr->id());
6663 return true; 6627 return true;
6664 } 6628 }
6665 AddInstruction(char_code); 6629 AddInstruction(char_code);
6666 HInstruction* result = 6630 HInstruction* result =
6667 HStringCharFromCode::New(zone(), context, char_code); 6631 HStringCharFromCode::New(zone(), context, char_code);
6668 ast_context()->ReturnInstruction(result, expr->id()); 6632 ast_context()->ReturnInstruction(result, expr->id());
6669 return true; 6633 return true;
6670 } 6634 }
6671 break; 6635 break;
6672 case kStringFromCharCode: 6636 case kStringFromCharCode:
6673 if (argument_count == 2 && check_type == RECEIVER_MAP_CHECK) { 6637 if (argument_count == 2 && check_type == RECEIVER_MAP_CHECK) {
6674 AddCheckConstantFunction(expr->holder(), receiver, receiver_map); 6638 AddCheckConstantFunction(expr->holder(), receiver, receiver_map);
6675 HValue* argument = Pop(); 6639 HValue* argument = Pop();
6676 HValue* context = environment()->LookupContext(); 6640 HValue* context = environment()->context();
6677 Drop(1); // Receiver. 6641 Drop(1); // Receiver.
6678 HInstruction* result = 6642 HInstruction* result =
6679 HStringCharFromCode::New(zone(), context, argument); 6643 HStringCharFromCode::New(zone(), context, argument);
6680 ast_context()->ReturnInstruction(result, expr->id()); 6644 ast_context()->ReturnInstruction(result, expr->id());
6681 return true; 6645 return true;
6682 } 6646 }
6683 break; 6647 break;
6684 case kMathExp: 6648 case kMathExp:
6685 if (!FLAG_fast_math) break; 6649 if (!FLAG_fast_math) break;
6686 // Fall through if FLAG_fast_math. 6650 // Fall through if FLAG_fast_math.
6687 case kMathRound: 6651 case kMathRound:
6688 case kMathFloor: 6652 case kMathFloor:
6689 case kMathAbs: 6653 case kMathAbs:
6690 case kMathSqrt: 6654 case kMathSqrt:
6691 case kMathLog: 6655 case kMathLog:
6692 case kMathSin: 6656 case kMathSin:
6693 case kMathCos: 6657 case kMathCos:
6694 case kMathTan: 6658 case kMathTan:
6695 if (argument_count == 2 && check_type == RECEIVER_MAP_CHECK) { 6659 if (argument_count == 2 && check_type == RECEIVER_MAP_CHECK) {
6696 AddCheckConstantFunction(expr->holder(), receiver, receiver_map); 6660 AddCheckConstantFunction(expr->holder(), receiver, receiver_map);
6697 HValue* argument = Pop(); 6661 HValue* argument = Pop();
6698 HValue* context = environment()->LookupContext(); 6662 HValue* context = environment()->context();
6699 Drop(1); // Receiver. 6663 Drop(1); // Receiver.
6700 HInstruction* op = 6664 HInstruction* op =
6701 HUnaryMathOperation::New(zone(), context, argument, id); 6665 HUnaryMathOperation::New(zone(), context, argument, id);
6702 op->set_position(expr->position()); 6666 op->set_position(expr->position());
6703 ast_context()->ReturnInstruction(op, expr->id()); 6667 ast_context()->ReturnInstruction(op, expr->id());
6704 return true; 6668 return true;
6705 } 6669 }
6706 break; 6670 break;
6707 case kMathPow: 6671 case kMathPow:
6708 if (argument_count == 3 && check_type == RECEIVER_MAP_CHECK) { 6672 if (argument_count == 3 && check_type == RECEIVER_MAP_CHECK) {
6709 AddCheckConstantFunction(expr->holder(), receiver, receiver_map); 6673 AddCheckConstantFunction(expr->holder(), receiver, receiver_map);
6710 HValue* right = Pop(); 6674 HValue* right = Pop();
6711 HValue* left = Pop(); 6675 HValue* left = Pop();
6712 Pop(); // Pop receiver. 6676 Pop(); // Pop receiver.
6713 HValue* context = environment()->LookupContext(); 6677 HValue* context = environment()->context();
6714 HInstruction* result = NULL; 6678 HInstruction* result = NULL;
6715 // Use sqrt() if exponent is 0.5 or -0.5. 6679 // Use sqrt() if exponent is 0.5 or -0.5.
6716 if (right->IsConstant() && HConstant::cast(right)->HasDoubleValue()) { 6680 if (right->IsConstant() && HConstant::cast(right)->HasDoubleValue()) {
6717 double exponent = HConstant::cast(right)->DoubleValue(); 6681 double exponent = HConstant::cast(right)->DoubleValue();
6718 if (exponent == 0.5) { 6682 if (exponent == 0.5) {
6719 result = 6683 result =
6720 HUnaryMathOperation::New(zone(), context, left, kMathPowHalf); 6684 HUnaryMathOperation::New(zone(), context, left, kMathPowHalf);
6721 } else if (exponent == -0.5) { 6685 } else if (exponent == -0.5) {
6722 HValue* one = graph()->GetConstant1(); 6686 HValue* one = graph()->GetConstant1();
6723 HInstruction* sqrt = 6687 HInstruction* sqrt =
6724 HUnaryMathOperation::New(zone(), context, left, kMathPowHalf); 6688 HUnaryMathOperation::New(zone(), context, left, kMathPowHalf);
6725 AddInstruction(sqrt); 6689 AddInstruction(sqrt);
6726 // MathPowHalf doesn't have side effects so there's no need for 6690 // MathPowHalf doesn't have side effects so there's no need for
6727 // an environment simulation here. 6691 // an environment simulation here.
6728 ASSERT(!sqrt->HasObservableSideEffects()); 6692 ASSERT(!sqrt->HasObservableSideEffects());
6729 result = HDiv::New(zone(), context, one, sqrt); 6693 result = HDiv::New(zone(), context, one, sqrt);
6730 } else if (exponent == 2.0) { 6694 } else if (exponent == 2.0) {
6731 result = HMul::New(zone(), context, left, left); 6695 result = HMul::New(zone(), context, left, left);
6732 } 6696 }
6733 } else if (right->EqualsInteger32Constant(2)) { 6697 } else if (right->EqualsInteger32Constant(2)) {
6734 result = HMul::New(zone(), context, left, left); 6698 result = HMul::New(zone(), context, left, left);
6735 } 6699 }
6736 6700
6737 if (result == NULL) { 6701 if (result == NULL) {
6738 result = HPower::New(zone(), left, right); 6702 result = HPower::New(zone(), context, left, right);
6739 } 6703 }
6740 ast_context()->ReturnInstruction(result, expr->id()); 6704 ast_context()->ReturnInstruction(result, expr->id());
6741 return true; 6705 return true;
6742 } 6706 }
6743 break; 6707 break;
6744 case kMathRandom: 6708 case kMathRandom:
6745 if (argument_count == 1 && check_type == RECEIVER_MAP_CHECK) { 6709 if (argument_count == 1 && check_type == RECEIVER_MAP_CHECK) {
6746 AddCheckConstantFunction(expr->holder(), receiver, receiver_map); 6710 AddCheckConstantFunction(expr->holder(), receiver, receiver_map);
6747 Drop(1); // Receiver. 6711 Drop(1); // Receiver.
6748 HValue* context = environment()->LookupContext(); 6712 HGlobalObject* global_object = Add<HGlobalObject>();
6749 HGlobalObject* global_object = Add<HGlobalObject>(context);
6750 HRandom* result = new(zone()) HRandom(global_object); 6713 HRandom* result = new(zone()) HRandom(global_object);
6751 ast_context()->ReturnInstruction(result, expr->id()); 6714 ast_context()->ReturnInstruction(result, expr->id());
6752 return true; 6715 return true;
6753 } 6716 }
6754 break; 6717 break;
6755 case kMathMax: 6718 case kMathMax:
6756 case kMathMin: 6719 case kMathMin:
6757 if (argument_count == 3 && check_type == RECEIVER_MAP_CHECK) { 6720 if (argument_count == 3 && check_type == RECEIVER_MAP_CHECK) {
6758 AddCheckConstantFunction(expr->holder(), receiver, receiver_map); 6721 AddCheckConstantFunction(expr->holder(), receiver, receiver_map);
6759 HValue* right = Pop(); 6722 HValue* right = Pop();
6760 HValue* left = Pop(); 6723 HValue* left = Pop();
6761 Drop(1); // Receiver. 6724 Drop(1); // Receiver.
6762 HValue* context = environment()->LookupContext(); 6725 HValue* context = environment()->context();
6763 HMathMinMax::Operation op = (id == kMathMin) ? HMathMinMax::kMathMin 6726 HMathMinMax::Operation op = (id == kMathMin) ? HMathMinMax::kMathMin
6764 : HMathMinMax::kMathMax; 6727 : HMathMinMax::kMathMax;
6765 HInstruction* result = 6728 HInstruction* result =
6766 HMathMinMax::New(zone(), context, left, right, op); 6729 HMathMinMax::New(zone(), context, left, right, op);
6767 ast_context()->ReturnInstruction(result, expr->id()); 6730 ast_context()->ReturnInstruction(result, expr->id());
6768 return true; 6731 return true;
6769 } 6732 }
6770 break; 6733 break;
6771 case kMathImul: 6734 case kMathImul:
6772 if (argument_count == 3 && check_type == RECEIVER_MAP_CHECK) { 6735 if (argument_count == 3 && check_type == RECEIVER_MAP_CHECK) {
6773 AddCheckConstantFunction(expr->holder(), receiver, receiver_map); 6736 AddCheckConstantFunction(expr->holder(), receiver, receiver_map);
6774 HValue* right = Pop(); 6737 HValue* right = Pop();
6775 HValue* left = Pop(); 6738 HValue* left = Pop();
6776 Drop(1); // Receiver. 6739 Drop(1); // Receiver.
6777 HValue* context = environment()->LookupContext(); 6740 HValue* context = environment()->context();
6778 HInstruction* result = HMul::NewImul(zone(), context, left, right); 6741 HInstruction* result = HMul::NewImul(zone(), context, left, right);
6779 ast_context()->ReturnInstruction(result, expr->id()); 6742 ast_context()->ReturnInstruction(result, expr->id());
6780 return true; 6743 return true;
6781 } 6744 }
6782 break; 6745 break;
6783 default: 6746 default:
6784 // Not yet supported for inlining. 6747 // Not yet supported for inlining.
6785 break; 6748 break;
6786 } 6749 }
6787 return false; 6750 return false;
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
6851 6814
6852 Handle<JSFunction> known_function; 6815 Handle<JSFunction> known_function;
6853 if (function->IsConstant()) { 6816 if (function->IsConstant()) {
6854 HConstant* constant_function = HConstant::cast(function); 6817 HConstant* constant_function = HConstant::cast(function);
6855 known_function = Handle<JSFunction>::cast(constant_function->handle()); 6818 known_function = Handle<JSFunction>::cast(constant_function->handle());
6856 int args_count = arguments_count - 1; // Excluding receiver. 6819 int args_count = arguments_count - 1; // Excluding receiver.
6857 if (TryInlineApply(known_function, expr, args_count)) return true; 6820 if (TryInlineApply(known_function, expr, args_count)) return true;
6858 } 6821 }
6859 6822
6860 Drop(arguments_count - 1); 6823 Drop(arguments_count - 1);
6861 PushAndAdd(new(zone()) HPushArgument(Pop())); 6824 PushAndAdd(New<HPushArgument>(Pop()));
6862 for (int i = 1; i < arguments_count; i++) { 6825 for (int i = 1; i < arguments_count; i++) {
6863 PushAndAdd(new(zone()) HPushArgument(arguments_values->at(i))); 6826 PushAndAdd(New<HPushArgument>(arguments_values->at(i)));
6864 } 6827 }
6865 6828
6866 HValue* context = environment()->LookupContext(); 6829 HValue* context = environment()->context();
6867 HInvokeFunction* call = new(zone()) HInvokeFunction( 6830 HInvokeFunction* call = new(zone()) HInvokeFunction(
6868 context, 6831 context,
6869 function, 6832 function,
6870 known_function, 6833 known_function,
6871 arguments_count); 6834 arguments_count);
6872 Drop(arguments_count); 6835 Drop(arguments_count);
6873 call->set_position(expr->position()); 6836 call->set_position(expr->position());
6874 ast_context()->ReturnInstruction(call, expr->id()); 6837 ast_context()->ReturnInstruction(call, expr->id());
6875 return true; 6838 return true;
6876 } 6839 }
(...skipping 16 matching lines...) Expand all
6893 6856
6894 CHECK_ALIVE(VisitForValue(prop->key())); 6857 CHECK_ALIVE(VisitForValue(prop->key()));
6895 // Push receiver and key like the non-optimized code generator expects it. 6858 // Push receiver and key like the non-optimized code generator expects it.
6896 HValue* key = Pop(); 6859 HValue* key = Pop();
6897 HValue* receiver = Pop(); 6860 HValue* receiver = Pop();
6898 Push(key); 6861 Push(key);
6899 Push(receiver); 6862 Push(receiver);
6900 6863
6901 CHECK_ALIVE(VisitArgumentList(expr->arguments())); 6864 CHECK_ALIVE(VisitArgumentList(expr->arguments()));
6902 6865
6903 HValue* context = environment()->LookupContext(); 6866 HValue* context = environment()->context();
6904 call = new(zone()) HCallKeyed(context, key, argument_count); 6867 call = new(zone()) HCallKeyed(context, key, argument_count);
6905 call->set_position(expr->position()); 6868 call->set_position(expr->position());
6906 Drop(argument_count + 1); // 1 is the key. 6869 Drop(argument_count + 1); // 1 is the key.
6907 return ast_context()->ReturnInstruction(call, expr->id()); 6870 return ast_context()->ReturnInstruction(call, expr->id());
6908 } 6871 }
6909 6872
6910 // Named function call. 6873 // Named function call.
6911 if (TryCallApply(expr)) return; 6874 if (TryCallApply(expr)) return;
6912 6875
6913 CHECK_ALIVE(VisitForValue(prop->obj())); 6876 CHECK_ALIVE(VisitForValue(prop->obj()));
(...skipping 23 matching lines...) Expand all
6937 PrintF("\n"); 6900 PrintF("\n");
6938 } 6901 }
6939 return; 6902 return;
6940 } 6903 }
6941 6904
6942 if (CallStubCompiler::HasCustomCallGenerator(expr->target()) || 6905 if (CallStubCompiler::HasCustomCallGenerator(expr->target()) ||
6943 expr->check_type() != RECEIVER_MAP_CHECK) { 6906 expr->check_type() != RECEIVER_MAP_CHECK) {
6944 // When the target has a custom call IC generator, use the IC, 6907 // When the target has a custom call IC generator, use the IC,
6945 // because it is likely to generate better code. Also use the IC 6908 // because it is likely to generate better code. Also use the IC
6946 // when a primitive receiver check is required. 6909 // when a primitive receiver check is required.
6947 HValue* context = environment()->LookupContext(); 6910 HValue* context = environment()->context();
6948 call = PreProcessCall( 6911 call = PreProcessCall(
6949 new(zone()) HCallNamed(context, name, argument_count)); 6912 new(zone()) HCallNamed(context, name, argument_count));
6950 } else { 6913 } else {
6951 AddCheckConstantFunction(expr->holder(), receiver, receiver_map); 6914 AddCheckConstantFunction(expr->holder(), receiver, receiver_map);
6952 6915
6953 if (TryInlineCall(expr)) return; 6916 if (TryInlineCall(expr)) return;
6954 call = PreProcessCall( 6917 call = PreProcessCall(
6955 new(zone()) HCallConstantFunction(expr->target(), 6918 new(zone()) HCallConstantFunction(expr->target(),
6956 argument_count)); 6919 argument_count));
6957 } 6920 }
6958 } else if (types != NULL && types->length() > 1) { 6921 } else if (types != NULL && types->length() > 1) {
6959 ASSERT(expr->check_type() == RECEIVER_MAP_CHECK); 6922 ASSERT(expr->check_type() == RECEIVER_MAP_CHECK);
6960 HandlePolymorphicCallNamed(expr, receiver, types, name); 6923 HandlePolymorphicCallNamed(expr, receiver, types, name);
6961 return; 6924 return;
6962 6925
6963 } else { 6926 } else {
6964 HValue* context = environment()->LookupContext(); 6927 HValue* context = environment()->context();
6965 call = PreProcessCall( 6928 call = PreProcessCall(
6966 new(zone()) HCallNamed(context, name, argument_count)); 6929 new(zone()) HCallNamed(context, name, argument_count));
6967 } 6930 }
6968 6931
6969 } else { 6932 } else {
6970 VariableProxy* proxy = expr->expression()->AsVariableProxy(); 6933 VariableProxy* proxy = expr->expression()->AsVariableProxy();
6971 if (proxy != NULL && proxy->var()->is_possibly_eval(isolate())) { 6934 if (proxy != NULL && proxy->var()->is_possibly_eval(isolate())) {
6972 return Bailout("possible direct call to eval"); 6935 return Bailout("possible direct call to eval");
6973 } 6936 }
6974 6937
6975 bool global_call = proxy != NULL && proxy->var()->IsUnallocated(); 6938 bool global_call = proxy != NULL && proxy->var()->IsUnallocated();
6976 if (global_call) { 6939 if (global_call) {
6977 Variable* var = proxy->var(); 6940 Variable* var = proxy->var();
6978 bool known_global_function = false; 6941 bool known_global_function = false;
6979 // If there is a global property cell for the name at compile time and 6942 // If there is a global property cell for the name at compile time and
6980 // access check is not enabled we assume that the function will not change 6943 // access check is not enabled we assume that the function will not change
6981 // and generate optimized code for calling the function. 6944 // and generate optimized code for calling the function.
6982 LookupResult lookup(isolate()); 6945 LookupResult lookup(isolate());
6983 GlobalPropertyAccess type = LookupGlobalProperty(var, &lookup, false); 6946 GlobalPropertyAccess type = LookupGlobalProperty(var, &lookup, false);
6984 if (type == kUseCell && 6947 if (type == kUseCell &&
6985 !current_info()->global_object()->IsAccessCheckNeeded()) { 6948 !current_info()->global_object()->IsAccessCheckNeeded()) {
6986 Handle<GlobalObject> global(current_info()->global_object()); 6949 Handle<GlobalObject> global(current_info()->global_object());
6987 known_global_function = expr->ComputeGlobalTarget(global, &lookup); 6950 known_global_function = expr->ComputeGlobalTarget(global, &lookup);
6988 } 6951 }
6989 if (known_global_function) { 6952 if (known_global_function) {
6990 // Push the global object instead of the global receiver because 6953 // Push the global object instead of the global receiver because
6991 // code generated by the full code generator expects it. 6954 // code generated by the full code generator expects it.
6992 HValue* context = environment()->LookupContext(); 6955 HValue* context = environment()->context();
6993 HGlobalObject* global_object = new(zone()) HGlobalObject(context); 6956 HGlobalObject* global_object = new(zone()) HGlobalObject(context);
6994 PushAndAdd(global_object); 6957 PushAndAdd(global_object);
6995 CHECK_ALIVE(VisitExpressions(expr->arguments())); 6958 CHECK_ALIVE(VisitExpressions(expr->arguments()));
6996 6959
6997 CHECK_ALIVE(VisitForValue(expr->expression())); 6960 CHECK_ALIVE(VisitForValue(expr->expression()));
6998 HValue* function = Pop(); 6961 HValue* function = Pop();
6999 Add<HCheckFunction>(function, expr->target()); 6962 Add<HCheckFunction>(function, expr->target());
7000 6963
7001 // Replace the global object with the global receiver. 6964 // Replace the global object with the global receiver.
7002 HGlobalReceiver* global_receiver = Add<HGlobalReceiver>(global_object); 6965 HGlobalReceiver* global_receiver = Add<HGlobalReceiver>(global_object);
(...skipping 13 matching lines...) Expand all
7016 } 6979 }
7017 if (TryInlineCall(expr)) return; 6980 if (TryInlineCall(expr)) return;
7018 6981
7019 if (expr->target().is_identical_to(current_info()->closure())) { 6982 if (expr->target().is_identical_to(current_info()->closure())) {
7020 graph()->MarkRecursive(); 6983 graph()->MarkRecursive();
7021 } 6984 }
7022 6985
7023 if (CallStubCompiler::HasCustomCallGenerator(expr->target())) { 6986 if (CallStubCompiler::HasCustomCallGenerator(expr->target())) {
7024 // When the target has a custom call IC generator, use the IC, 6987 // When the target has a custom call IC generator, use the IC,
7025 // because it is likely to generate better code. 6988 // because it is likely to generate better code.
7026 HValue* context = environment()->LookupContext(); 6989 HValue* context = environment()->context();
7027 call = PreProcessCall( 6990 call = PreProcessCall(
7028 new(zone()) HCallNamed(context, var->name(), argument_count)); 6991 new(zone()) HCallNamed(context, var->name(), argument_count));
7029 } else { 6992 } else {
7030 call = PreProcessCall(new(zone()) HCallKnownGlobal(expr->target(), 6993 call = PreProcessCall(new(zone()) HCallKnownGlobal(expr->target(),
7031 argument_count)); 6994 argument_count));
7032 } 6995 }
7033 } else { 6996 } else {
7034 HValue* context = environment()->LookupContext(); 6997 HGlobalObject* receiver = Add<HGlobalObject>();
7035 HGlobalObject* receiver = Add<HGlobalObject>(context); 6998 PushAndAdd(New<HPushArgument>(receiver));
7036 PushAndAdd(new(zone()) HPushArgument(receiver));
7037 CHECK_ALIVE(VisitArgumentList(expr->arguments())); 6999 CHECK_ALIVE(VisitArgumentList(expr->arguments()));
7038 7000
7039 call = new(zone()) HCallGlobal(context, var->name(), argument_count); 7001 call = New<HCallGlobal>(var->name(), argument_count);
7040 Drop(argument_count); 7002 Drop(argument_count);
7041 } 7003 }
7042 7004
7043 } else if (expr->IsMonomorphic()) { 7005 } else if (expr->IsMonomorphic()) {
7044 // The function is on the stack in the unoptimized code during 7006 // The function is on the stack in the unoptimized code during
7045 // evaluation of the arguments. 7007 // evaluation of the arguments.
7046 CHECK_ALIVE(VisitForValue(expr->expression())); 7008 CHECK_ALIVE(VisitForValue(expr->expression()));
7047 HValue* function = Top(); 7009 HValue* function = Top();
7048 HValue* context = environment()->LookupContext(); 7010 HGlobalObject* global = Add<HGlobalObject>();
7049 HGlobalObject* global = Add<HGlobalObject>(context); 7011 HGlobalReceiver* receiver = New<HGlobalReceiver>(global);
7050 HGlobalReceiver* receiver = new(zone()) HGlobalReceiver(global);
7051 PushAndAdd(receiver); 7012 PushAndAdd(receiver);
7052 CHECK_ALIVE(VisitExpressions(expr->arguments())); 7013 CHECK_ALIVE(VisitExpressions(expr->arguments()));
7053 Add<HCheckFunction>(function, expr->target()); 7014 Add<HCheckFunction>(function, expr->target());
7054 7015
7055 if (TryInlineBuiltinFunctionCall(expr, true)) { // Drop the function. 7016 if (TryInlineBuiltinFunctionCall(expr, true)) { // Drop the function.
7056 if (FLAG_trace_inlining) { 7017 if (FLAG_trace_inlining) {
7057 PrintF("Inlining builtin "); 7018 PrintF("Inlining builtin ");
7058 expr->target()->ShortPrint(); 7019 expr->target()->ShortPrint();
7059 PrintF("\n"); 7020 PrintF("\n");
7060 } 7021 }
7061 return; 7022 return;
7062 } 7023 }
7063 7024
7064 if (TryInlineCall(expr, true)) { // Drop function from environment. 7025 if (TryInlineCall(expr, true)) { // Drop function from environment.
7065 return; 7026 return;
7066 } else { 7027 } else {
7067 call = PreProcessCall( 7028 call = PreProcessCall(New<HInvokeFunction>(function, expr->target(),
7068 new(zone()) HInvokeFunction(context, 7029 argument_count));
7069 function,
7070 expr->target(),
7071 argument_count));
7072 Drop(1); // The function. 7030 Drop(1); // The function.
7073 } 7031 }
7074 7032
7075 } else { 7033 } else {
7076 CHECK_ALIVE(VisitForValue(expr->expression())); 7034 CHECK_ALIVE(VisitForValue(expr->expression()));
7077 HValue* function = Top(); 7035 HValue* function = Top();
7078 HValue* context = environment()->LookupContext(); 7036 HGlobalObject* global_object = Add<HGlobalObject>();
7079 HGlobalObject* global_object = Add<HGlobalObject>(context);
7080 HGlobalReceiver* receiver = Add<HGlobalReceiver>(global_object); 7037 HGlobalReceiver* receiver = Add<HGlobalReceiver>(global_object);
7081 PushAndAdd(new(zone()) HPushArgument(receiver)); 7038 PushAndAdd(New<HPushArgument>(receiver));
7082 CHECK_ALIVE(VisitArgumentList(expr->arguments())); 7039 CHECK_ALIVE(VisitArgumentList(expr->arguments()));
7083 7040
7084 call = new(zone()) HCallFunction(context, function, argument_count); 7041 call = New<HCallFunction>(function, argument_count);
7085 Drop(argument_count + 1); 7042 Drop(argument_count + 1);
7086 } 7043 }
7087 } 7044 }
7088 7045
7089 call->set_position(expr->position()); 7046 call->set_position(expr->position());
7090 return ast_context()->ReturnInstruction(call, expr->id()); 7047 return ast_context()->ReturnInstruction(call, expr->id());
7091 } 7048 }
7092 7049
7093 7050
7094 // Checks whether allocation using the given constructor can be inlined. 7051 // Checks whether allocation using the given constructor can be inlined.
7095 static bool IsAllocationInlineable(Handle<JSFunction> constructor) { 7052 static bool IsAllocationInlineable(Handle<JSFunction> constructor) {
7096 return constructor->has_initial_map() && 7053 return constructor->has_initial_map() &&
7097 constructor->initial_map()->instance_type() == JS_OBJECT_TYPE && 7054 constructor->initial_map()->instance_type() == JS_OBJECT_TYPE &&
7098 constructor->initial_map()->instance_size() < HAllocate::kMaxInlineSize && 7055 constructor->initial_map()->instance_size() < HAllocate::kMaxInlineSize &&
7099 constructor->initial_map()->InitialPropertiesLength() == 0; 7056 constructor->initial_map()->InitialPropertiesLength() == 0;
7100 } 7057 }
7101 7058
7102 7059
7103 void HOptimizedGraphBuilder::VisitCallNew(CallNew* expr) { 7060 void HOptimizedGraphBuilder::VisitCallNew(CallNew* expr) {
7104 ASSERT(!HasStackOverflow()); 7061 ASSERT(!HasStackOverflow());
7105 ASSERT(current_block() != NULL); 7062 ASSERT(current_block() != NULL);
7106 ASSERT(current_block()->HasPredecessor()); 7063 ASSERT(current_block()->HasPredecessor());
7107 int argument_count = expr->arguments()->length() + 1; // Plus constructor. 7064 int argument_count = expr->arguments()->length() + 1; // Plus constructor.
7108 HValue* context = environment()->LookupContext(); 7065 HValue* context = environment()->context();
7109 Factory* factory = isolate()->factory(); 7066 Factory* factory = isolate()->factory();
7110 7067
7111 if (FLAG_inline_construct && 7068 if (FLAG_inline_construct &&
7112 expr->IsMonomorphic() && 7069 expr->IsMonomorphic() &&
7113 IsAllocationInlineable(expr->target())) { 7070 IsAllocationInlineable(expr->target())) {
7114 // The constructor function is on the stack in the unoptimized code 7071 // The constructor function is on the stack in the unoptimized code
7115 // during evaluation of the arguments. 7072 // during evaluation of the arguments.
7116 CHECK_ALIVE(VisitForValue(expr->expression())); 7073 CHECK_ALIVE(VisitForValue(expr->expression()));
7117 HValue* function = Top(); 7074 HValue* function = Top();
7118 CHECK_ALIVE(VisitExpressions(expr->arguments())); 7075 CHECK_ALIVE(VisitExpressions(expr->arguments()));
(...skipping 10 matching lines...) Expand all
7129 ASSERT(constructor->has_initial_map()); 7086 ASSERT(constructor->has_initial_map());
7130 Handle<Map> initial_map(constructor->initial_map()); 7087 Handle<Map> initial_map(constructor->initial_map());
7131 int instance_size = initial_map->instance_size(); 7088 int instance_size = initial_map->instance_size();
7132 ASSERT(initial_map->InitialPropertiesLength() == 0); 7089 ASSERT(initial_map->InitialPropertiesLength() == 0);
7133 7090
7134 // Allocate an instance of the implicit receiver object. 7091 // Allocate an instance of the implicit receiver object.
7135 HValue* size_in_bytes = Add<HConstant>(instance_size); 7092 HValue* size_in_bytes = Add<HConstant>(instance_size);
7136 bool pretenure = FLAG_pretenuring_call_new && 7093 bool pretenure = FLAG_pretenuring_call_new &&
7137 isolate()->heap()->ShouldGloballyPretenure(); 7094 isolate()->heap()->ShouldGloballyPretenure();
7138 HAllocate* receiver = 7095 HAllocate* receiver =
7139 Add<HAllocate>(context, size_in_bytes, HType::JSObject(), pretenure); 7096 Add<HAllocate>(size_in_bytes, HType::JSObject(), pretenure);
7140 receiver->set_known_initial_map(initial_map); 7097 receiver->set_known_initial_map(initial_map);
7141 7098
7142 // Load the initial map from the constructor. 7099 // Load the initial map from the constructor.
7143 HValue* constructor_value = Add<HConstant>(constructor); 7100 HValue* constructor_value = Add<HConstant>(constructor);
7144 HValue* initial_map_value = 7101 HValue* initial_map_value =
7145 AddLoad(constructor_value, HObjectAccess::ForJSObjectOffset( 7102 Add<HLoadNamedField>(constructor_value, HObjectAccess::ForJSObjectOffset(
7146 JSFunction::kPrototypeOrInitialMapOffset)); 7103 JSFunction::kPrototypeOrInitialMapOffset));
7147 7104
7148 // Initialize map and fields of the newly allocated object. 7105 // Initialize map and fields of the newly allocated object.
7149 { NoObservableSideEffectsScope no_effects(this); 7106 { NoObservableSideEffectsScope no_effects(this);
7150 ASSERT(initial_map->instance_type() == JS_OBJECT_TYPE); 7107 ASSERT(initial_map->instance_type() == JS_OBJECT_TYPE);
7151 AddStore(receiver, 7108 Add<HStoreNamedField>(receiver,
7152 HObjectAccess::ForJSObjectOffset(JSObject::kMapOffset), 7109 HObjectAccess::ForJSObjectOffset(JSObject::kMapOffset),
7153 initial_map_value); 7110 initial_map_value);
7154 HValue* empty_fixed_array = Add<HConstant>(factory->empty_fixed_array()); 7111 HValue* empty_fixed_array = Add<HConstant>(factory->empty_fixed_array());
7155 AddStore(receiver, 7112 Add<HStoreNamedField>(receiver,
7156 HObjectAccess::ForJSObjectOffset(JSObject::kPropertiesOffset), 7113 HObjectAccess::ForJSObjectOffset(JSObject::kPropertiesOffset),
7157 empty_fixed_array); 7114 empty_fixed_array);
7158 AddStore(receiver, 7115 Add<HStoreNamedField>(receiver,
7159 HObjectAccess::ForJSObjectOffset(JSObject::kElementsOffset), 7116 HObjectAccess::ForJSObjectOffset(JSObject::kElementsOffset),
7160 empty_fixed_array); 7117 empty_fixed_array);
7161 if (initial_map->inobject_properties() != 0) { 7118 if (initial_map->inobject_properties() != 0) {
7162 HConstant* undefined = graph()->GetConstantUndefined(); 7119 HConstant* undefined = graph()->GetConstantUndefined();
7163 for (int i = 0; i < initial_map->inobject_properties(); i++) { 7120 for (int i = 0; i < initial_map->inobject_properties(); i++) {
7164 int property_offset = JSObject::kHeaderSize + i * kPointerSize; 7121 int property_offset = JSObject::kHeaderSize + i * kPointerSize;
7165 AddStore(receiver, 7122 Add<HStoreNamedField>(receiver,
7166 HObjectAccess::ForJSObjectOffset(property_offset), 7123 HObjectAccess::ForJSObjectOffset(property_offset),
7167 undefined); 7124 undefined);
7168 } 7125 }
7169 } 7126 }
7170 } 7127 }
7171 7128
7172 // Replace the constructor function with a newly allocated receiver using 7129 // Replace the constructor function with a newly allocated receiver using
7173 // the index of the receiver from the top of the expression stack. 7130 // the index of the receiver from the top of the expression stack.
7174 const int receiver_index = argument_count - 1; 7131 const int receiver_index = argument_count - 1;
7175 ASSERT(environment()->ExpressionStackAt(receiver_index) == function); 7132 ASSERT(environment()->ExpressionStackAt(receiver_index) == function);
7176 environment()->SetExpressionStackAt(receiver_index, receiver); 7133 environment()->SetExpressionStackAt(receiver_index, receiver);
7177 7134
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
7255 ASSERT(static_cast<size_t>(lookup_index) < 7212 ASSERT(static_cast<size_t>(lookup_index) <
7256 ARRAY_SIZE(kInlineFunctionGenerators)); 7213 ARRAY_SIZE(kInlineFunctionGenerators));
7257 InlineFunctionGenerator generator = kInlineFunctionGenerators[lookup_index]; 7214 InlineFunctionGenerator generator = kInlineFunctionGenerators[lookup_index];
7258 7215
7259 // Call the inline code generator using the pointer-to-member. 7216 // Call the inline code generator using the pointer-to-member.
7260 (this->*generator)(expr); 7217 (this->*generator)(expr);
7261 } else { 7218 } else {
7262 ASSERT(function->intrinsic_type == Runtime::RUNTIME); 7219 ASSERT(function->intrinsic_type == Runtime::RUNTIME);
7263 CHECK_ALIVE(VisitArgumentList(expr->arguments())); 7220 CHECK_ALIVE(VisitArgumentList(expr->arguments()));
7264 7221
7265 HValue* context = environment()->LookupContext();
7266 Handle<String> name = expr->name(); 7222 Handle<String> name = expr->name();
7267 int argument_count = expr->arguments()->length(); 7223 int argument_count = expr->arguments()->length();
7268 HCallRuntime* call = 7224 HCallRuntime* call = New<HCallRuntime>(name, function,
7269 new(zone()) HCallRuntime(context, name, function, argument_count); 7225 argument_count);
7270 Drop(argument_count); 7226 Drop(argument_count);
7271 return ast_context()->ReturnInstruction(call, expr->id()); 7227 return ast_context()->ReturnInstruction(call, expr->id());
7272 } 7228 }
7273 } 7229 }
7274 7230
7275 7231
7276 void HOptimizedGraphBuilder::VisitUnaryOperation(UnaryOperation* expr) { 7232 void HOptimizedGraphBuilder::VisitUnaryOperation(UnaryOperation* expr) {
7277 ASSERT(!HasStackOverflow()); 7233 ASSERT(!HasStackOverflow());
7278 ASSERT(current_block() != NULL); 7234 ASSERT(current_block() != NULL);
7279 ASSERT(current_block()->HasPredecessor()); 7235 ASSERT(current_block()->HasPredecessor());
(...skipping 10 matching lines...) Expand all
7290 7246
7291 7247
7292 void HOptimizedGraphBuilder::VisitDelete(UnaryOperation* expr) { 7248 void HOptimizedGraphBuilder::VisitDelete(UnaryOperation* expr) {
7293 Property* prop = expr->expression()->AsProperty(); 7249 Property* prop = expr->expression()->AsProperty();
7294 VariableProxy* proxy = expr->expression()->AsVariableProxy(); 7250 VariableProxy* proxy = expr->expression()->AsVariableProxy();
7295 if (prop != NULL) { 7251 if (prop != NULL) {
7296 CHECK_ALIVE(VisitForValue(prop->obj())); 7252 CHECK_ALIVE(VisitForValue(prop->obj()));
7297 CHECK_ALIVE(VisitForValue(prop->key())); 7253 CHECK_ALIVE(VisitForValue(prop->key()));
7298 HValue* key = Pop(); 7254 HValue* key = Pop();
7299 HValue* obj = Pop(); 7255 HValue* obj = Pop();
7300 HValue* context = environment()->LookupContext(); 7256 HValue* function = AddLoadJSBuiltin(Builtins::DELETE);
7301 HValue* function = AddLoadJSBuiltin(Builtins::DELETE, context);
7302 Add<HPushArgument>(obj); 7257 Add<HPushArgument>(obj);
7303 Add<HPushArgument>(key); 7258 Add<HPushArgument>(key);
7304 Add<HPushArgument>(Add<HConstant>(function_strict_mode_flag())); 7259 Add<HPushArgument>(Add<HConstant>(function_strict_mode_flag()));
7305 // TODO(olivf) InvokeFunction produces a check for the parameter count, 7260 // TODO(olivf) InvokeFunction produces a check for the parameter count,
7306 // even though we are certain to pass the correct number of arguments here. 7261 // even though we are certain to pass the correct number of arguments here.
7307 HInstruction* instr = new(zone()) HInvokeFunction(context, function, 3); 7262 HInstruction* instr = New<HInvokeFunction>(function, 3);
7308 return ast_context()->ReturnInstruction(instr, expr->id()); 7263 return ast_context()->ReturnInstruction(instr, expr->id());
7309 } else if (proxy != NULL) { 7264 } else if (proxy != NULL) {
7310 Variable* var = proxy->var(); 7265 Variable* var = proxy->var();
7311 if (var->IsUnallocated()) { 7266 if (var->IsUnallocated()) {
7312 Bailout("delete with global variable"); 7267 Bailout("delete with global variable");
7313 } else if (var->IsStackAllocated() || var->IsContextSlot()) { 7268 } else if (var->IsStackAllocated() || var->IsContextSlot()) {
7314 // Result of deleting non-global variables is false. 'this' is not 7269 // Result of deleting non-global variables is false. 'this' is not
7315 // really a variable, though we implement it as one. The 7270 // really a variable, though we implement it as one. The
7316 // subexpression does not have side effects. 7271 // subexpression does not have side effects.
7317 HValue* value = var->is_this() 7272 HValue* value = var->is_this()
(...skipping 14 matching lines...) Expand all
7332 7287
7333 void HOptimizedGraphBuilder::VisitVoid(UnaryOperation* expr) { 7288 void HOptimizedGraphBuilder::VisitVoid(UnaryOperation* expr) {
7334 CHECK_ALIVE(VisitForEffect(expr->expression())); 7289 CHECK_ALIVE(VisitForEffect(expr->expression()));
7335 return ast_context()->ReturnValue(graph()->GetConstantUndefined()); 7290 return ast_context()->ReturnValue(graph()->GetConstantUndefined());
7336 } 7291 }
7337 7292
7338 7293
7339 void HOptimizedGraphBuilder::VisitTypeof(UnaryOperation* expr) { 7294 void HOptimizedGraphBuilder::VisitTypeof(UnaryOperation* expr) {
7340 CHECK_ALIVE(VisitForTypeOf(expr->expression())); 7295 CHECK_ALIVE(VisitForTypeOf(expr->expression()));
7341 HValue* value = Pop(); 7296 HValue* value = Pop();
7342 HValue* context = environment()->LookupContext(); 7297 HValue* context = environment()->context();
7343 HInstruction* instr = new(zone()) HTypeof(context, value); 7298 HInstruction* instr = new(zone()) HTypeof(context, value);
7344 return ast_context()->ReturnInstruction(instr, expr->id()); 7299 return ast_context()->ReturnInstruction(instr, expr->id());
7345 } 7300 }
7346 7301
7347 7302
7348 void HOptimizedGraphBuilder::VisitSub(UnaryOperation* expr) { 7303 void HOptimizedGraphBuilder::VisitSub(UnaryOperation* expr) {
7349 CHECK_ALIVE(VisitForValue(expr->expression())); 7304 CHECK_ALIVE(VisitForValue(expr->expression()));
7350 Handle<Type> operand_type = expr->expression()->bounds().lower; 7305 Handle<Type> operand_type = expr->expression()->bounds().lower;
7351 HValue* value = TruncateToNumber(Pop(), &operand_type); 7306 HValue* value = TruncateToNumber(Pop(), &operand_type);
7352 HInstruction* instr = BuildUnaryMathOp(value, operand_type, Token::SUB); 7307 HInstruction* instr = BuildUnaryMathOp(value, operand_type, Token::SUB);
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
7429 } 7384 }
7430 Push(number_input); 7385 Push(number_input);
7431 } 7386 }
7432 7387
7433 // The addition has no side effects, so we do not need 7388 // The addition has no side effects, so we do not need
7434 // to simulate the expression stack after this instruction. 7389 // to simulate the expression stack after this instruction.
7435 // Any later failures deopt to the load of the input or earlier. 7390 // Any later failures deopt to the load of the input or earlier.
7436 HConstant* delta = (expr->op() == Token::INC) 7391 HConstant* delta = (expr->op() == Token::INC)
7437 ? graph()->GetConstant1() 7392 ? graph()->GetConstant1()
7438 : graph()->GetConstantMinus1(); 7393 : graph()->GetConstantMinus1();
7439 HValue* context = environment()->LookupContext(); 7394 HInstruction* instr = Add<HAdd>(Top(), delta);
7440 HInstruction* instr = HAdd::New(zone(), context, Top(), delta);
7441 instr->SetFlag(HInstruction::kCannotBeTagged); 7395 instr->SetFlag(HInstruction::kCannotBeTagged);
7442 instr->ClearAllSideEffects(); 7396 instr->ClearAllSideEffects();
7443 AddInstruction(instr);
7444 return instr; 7397 return instr;
7445 } 7398 }
7446 7399
7447 7400
7448 void HOptimizedGraphBuilder::VisitCountOperation(CountOperation* expr) { 7401 void HOptimizedGraphBuilder::VisitCountOperation(CountOperation* expr) {
7449 ASSERT(!HasStackOverflow()); 7402 ASSERT(!HasStackOverflow());
7450 ASSERT(current_block() != NULL); 7403 ASSERT(current_block() != NULL);
7451 ASSERT(current_block()->HasPredecessor()); 7404 ASSERT(current_block()->HasPredecessor());
7452 Expression* target = expr->expression(); 7405 Expression* target = expr->expression();
7453 VariableProxy* proxy = target->AsVariableProxy(); 7406 VariableProxy* proxy = target->AsVariableProxy();
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
7598 Add<HSimulate>(expr->AssignmentId(), REMOVABLE_SIMULATE); 7551 Add<HSimulate>(expr->AssignmentId(), REMOVABLE_SIMULATE);
7599 } 7552 }
7600 } 7553 }
7601 7554
7602 Drop(returns_original_input ? 2 : 1); 7555 Drop(returns_original_input ? 2 : 1);
7603 return ast_context()->ReturnValue(expr->is_postfix() ? input : after); 7556 return ast_context()->ReturnValue(expr->is_postfix() ? input : after);
7604 } 7557 }
7605 7558
7606 7559
7607 HInstruction* HOptimizedGraphBuilder::BuildStringCharCodeAt( 7560 HInstruction* HOptimizedGraphBuilder::BuildStringCharCodeAt(
7608 HValue* context,
7609 HValue* string, 7561 HValue* string,
7610 HValue* index) { 7562 HValue* index) {
7611 if (string->IsConstant() && index->IsConstant()) { 7563 if (string->IsConstant() && index->IsConstant()) {
7612 HConstant* c_string = HConstant::cast(string); 7564 HConstant* c_string = HConstant::cast(string);
7613 HConstant* c_index = HConstant::cast(index); 7565 HConstant* c_index = HConstant::cast(index);
7614 if (c_string->HasStringValue() && c_index->HasNumberValue()) { 7566 if (c_string->HasStringValue() && c_index->HasNumberValue()) {
7615 int32_t i = c_index->NumberValueAsInteger32(); 7567 int32_t i = c_index->NumberValueAsInteger32();
7616 Handle<String> s = c_string->StringValue(); 7568 Handle<String> s = c_string->StringValue();
7617 if (i < 0 || i >= s->length()) { 7569 if (i < 0 || i >= s->length()) {
7618 return new(zone()) HConstant(OS::nan_value()); 7570 return New<HConstant>(OS::nan_value());
7619 } 7571 }
7620 return new(zone()) HConstant(s->Get(i)); 7572 return New<HConstant>(s->Get(i));
7621 } 7573 }
7622 } 7574 }
7623 BuildCheckHeapObject(string); 7575 BuildCheckHeapObject(string);
7624 AddInstruction(HCheckInstanceType::NewIsString(string, zone())); 7576 AddInstruction(HCheckInstanceType::NewIsString(string, zone()));
7625 HInstruction* length = HStringLength::New(zone(), string); 7577 HInstruction* length = Add<HStringLength>(string);
7626 AddInstruction(length);
7627 HInstruction* checked_index = Add<HBoundsCheck>(index, length); 7578 HInstruction* checked_index = Add<HBoundsCheck>(index, length);
7628 return new(zone()) HStringCharCodeAt(context, string, checked_index); 7579 return New<HStringCharCodeAt>(string, checked_index);
7629 } 7580 }
7630 7581
7631 7582
7632 // Checks if the given shift amounts have form: (sa) and (32 - sa). 7583 // Checks if the given shift amounts have form: (sa) and (32 - sa).
7633 static bool ShiftAmountsAllowReplaceByRotate(HValue* sa, 7584 static bool ShiftAmountsAllowReplaceByRotate(HValue* sa,
7634 HValue* const32_minus_sa) { 7585 HValue* const32_minus_sa) {
7635 if (!const32_minus_sa->IsSub()) return false; 7586 if (!const32_minus_sa->IsSub()) return false;
7636 HSub* sub = HSub::cast(const32_minus_sa); 7587 HSub* sub = HSub::cast(const32_minus_sa);
7637 if (sa != sub->right()) return false; 7588 if (sa != sub->right()) return false;
7638 HValue* const32 = sub->left(); 7589 HValue* const32 = sub->left();
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
7707 // tagged representation later on. 7658 // tagged representation later on.
7708 if (expected_type->Is(Type::Oddball())) { 7659 if (expected_type->Is(Type::Oddball())) {
7709 // TODO(olivf) The BinaryOpStub only records undefined. It might pay off to 7660 // TODO(olivf) The BinaryOpStub only records undefined. It might pay off to
7710 // also record booleans and convert them to 0/1 here. 7661 // also record booleans and convert them to 0/1 here.
7711 IfBuilder if_nan(this); 7662 IfBuilder if_nan(this);
7712 if_nan.If<HCompareObjectEqAndBranch>(value, 7663 if_nan.If<HCompareObjectEqAndBranch>(value,
7713 graph()->GetConstantUndefined()); 7664 graph()->GetConstantUndefined());
7714 if_nan.Then(); 7665 if_nan.Then();
7715 if_nan.ElseDeopt(); 7666 if_nan.ElseDeopt();
7716 if_nan.End(); 7667 if_nan.End();
7717 return Add<HConstant>(OS::nan_value(), Representation::Double()); 7668 return Add<HConstant>(OS::nan_value());
7718 } 7669 }
7719 7670
7720 return value; 7671 return value;
7721 } 7672 }
7722 7673
7723 7674
7724 HInstruction* HOptimizedGraphBuilder::BuildBinaryOperation( 7675 HInstruction* HOptimizedGraphBuilder::BuildBinaryOperation(
7725 BinaryOperation* expr, 7676 BinaryOperation* expr,
7726 HValue* left, 7677 HValue* left,
7727 HValue* right) { 7678 HValue* right) {
7728 HValue* context = environment()->LookupContext(); 7679 HValue* context = environment()->context();
7729 Handle<Type> left_type = expr->left()->bounds().lower; 7680 Handle<Type> left_type = expr->left()->bounds().lower;
7730 Handle<Type> right_type = expr->right()->bounds().lower; 7681 Handle<Type> right_type = expr->right()->bounds().lower;
7731 Handle<Type> result_type = expr->bounds().lower; 7682 Handle<Type> result_type = expr->bounds().lower;
7732 Maybe<int> fixed_right_arg = expr->fixed_right_arg(); 7683 Maybe<int> fixed_right_arg = expr->fixed_right_arg();
7733 Representation left_rep = Representation::FromType(left_type); 7684 Representation left_rep = Representation::FromType(left_type);
7734 Representation right_rep = Representation::FromType(right_type); 7685 Representation right_rep = Representation::FromType(right_type);
7735 Representation result_rep = Representation::FromType(result_type); 7686 Representation result_rep = Representation::FromType(result_type);
7736 7687
7737 if (expr->op() != Token::ADD || 7688 if (expr->op() != Token::ADD ||
7738 (left->type().IsNonString() && right->type().IsNonString())) { 7689 (left->type().IsNonString() && right->type().IsNonString())) {
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
7771 instr = HMul::New(zone(), context, left, right); 7722 instr = HMul::New(zone(), context, left, right);
7772 break; 7723 break;
7773 case Token::MOD: 7724 case Token::MOD:
7774 instr = HMod::New(zone(), context, left, right, fixed_right_arg); 7725 instr = HMod::New(zone(), context, left, right, fixed_right_arg);
7775 break; 7726 break;
7776 case Token::DIV: 7727 case Token::DIV:
7777 instr = HDiv::New(zone(), context, left, right); 7728 instr = HDiv::New(zone(), context, left, right);
7778 break; 7729 break;
7779 case Token::BIT_XOR: 7730 case Token::BIT_XOR:
7780 case Token::BIT_AND: 7731 case Token::BIT_AND:
7781 instr = HBitwise::New(zone(), expr->op(), context, left, right); 7732 instr = New<HBitwise>(expr->op(), left, right);
7782 break; 7733 break;
7783 case Token::BIT_OR: { 7734 case Token::BIT_OR: {
7784 HValue* operand, *shift_amount; 7735 HValue* operand, *shift_amount;
7785 if (left_type->Is(Type::Signed32()) && 7736 if (left_type->Is(Type::Signed32()) &&
7786 right_type->Is(Type::Signed32()) && 7737 right_type->Is(Type::Signed32()) &&
7787 MatchRotateRight(left, right, &operand, &shift_amount)) { 7738 MatchRotateRight(left, right, &operand, &shift_amount)) {
7788 instr = new(zone()) HRor(context, operand, shift_amount); 7739 instr = new(zone()) HRor(context, operand, shift_amount);
7789 } else { 7740 } else {
7790 instr = HBitwise::New(zone(), expr->op(), context, left, right); 7741 instr = New<HBitwise>(expr->op(), left, right);
7791 } 7742 }
7792 break; 7743 break;
7793 } 7744 }
7794 case Token::SAR: 7745 case Token::SAR:
7795 instr = HSar::New(zone(), context, left, right); 7746 instr = HSar::New(zone(), context, left, right);
7796 break; 7747 break;
7797 case Token::SHR: 7748 case Token::SHR:
7798 instr = HShr::New(zone(), context, left, right); 7749 instr = HShr::New(zone(), context, left, right);
7799 if (FLAG_opt_safe_uint32_operations && instr->IsShr() && 7750 if (FLAG_opt_safe_uint32_operations && instr->IsShr() &&
7800 CanBeZero(right)) { 7751 CanBeZero(right)) {
(...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after
8025 Handle<Type> left_type = expr->left()->bounds().lower; 7976 Handle<Type> left_type = expr->left()->bounds().lower;
8026 Handle<Type> right_type = expr->right()->bounds().lower; 7977 Handle<Type> right_type = expr->right()->bounds().lower;
8027 Handle<Type> combined_type = expr->combined_type(); 7978 Handle<Type> combined_type = expr->combined_type();
8028 Representation combined_rep = Representation::FromType(combined_type); 7979 Representation combined_rep = Representation::FromType(combined_type);
8029 Representation left_rep = Representation::FromType(left_type); 7980 Representation left_rep = Representation::FromType(left_type);
8030 Representation right_rep = Representation::FromType(right_type); 7981 Representation right_rep = Representation::FromType(right_type);
8031 7982
8032 CHECK_ALIVE(VisitForValue(expr->left())); 7983 CHECK_ALIVE(VisitForValue(expr->left()));
8033 CHECK_ALIVE(VisitForValue(expr->right())); 7984 CHECK_ALIVE(VisitForValue(expr->right()));
8034 7985
8035 HValue* context = environment()->LookupContext(); 7986 HValue* context = environment()->context();
8036 HValue* right = Pop(); 7987 HValue* right = Pop();
8037 HValue* left = Pop(); 7988 HValue* left = Pop();
8038 Token::Value op = expr->op(); 7989 Token::Value op = expr->op();
8039 7990
8040 if (IsLiteralCompareBool(left, op, right)) { 7991 if (IsLiteralCompareBool(left, op, right)) {
8041 HCompareObjectEqAndBranch* result = 7992 HCompareObjectEqAndBranch* result =
8042 new(zone()) HCompareObjectEqAndBranch(left, right); 7993 New<HCompareObjectEqAndBranch>(left, right);
8043 result->set_position(expr->position()); 7994 result->set_position(expr->position());
8044 return ast_context()->ReturnControl(result, expr->id()); 7995 return ast_context()->ReturnControl(result, expr->id());
8045 } 7996 }
8046 7997
8047 if (op == Token::INSTANCEOF) { 7998 if (op == Token::INSTANCEOF) {
8048 // Check to see if the rhs of the instanceof is a global function not 7999 // Check to see if the rhs of the instanceof is a global function not
8049 // residing in new space. If it is we assume that the function will stay the 8000 // residing in new space. If it is we assume that the function will stay the
8050 // same. 8001 // same.
8051 Handle<JSFunction> target = Handle<JSFunction>::null(); 8002 Handle<JSFunction> target = Handle<JSFunction>::null();
8052 VariableProxy* proxy = expr->right()->AsVariableProxy(); 8003 VariableProxy* proxy = expr->right()->AsVariableProxy();
(...skipping 25 matching lines...) Expand all
8078 Add<HCheckFunction>(right, target); 8029 Add<HCheckFunction>(right, target);
8079 HInstanceOfKnownGlobal* result = 8030 HInstanceOfKnownGlobal* result =
8080 new(zone()) HInstanceOfKnownGlobal(context, left, target); 8031 new(zone()) HInstanceOfKnownGlobal(context, left, target);
8081 result->set_position(expr->position()); 8032 result->set_position(expr->position());
8082 return ast_context()->ReturnInstruction(result, expr->id()); 8033 return ast_context()->ReturnInstruction(result, expr->id());
8083 } 8034 }
8084 8035
8085 // Code below assumes that we don't fall through. 8036 // Code below assumes that we don't fall through.
8086 UNREACHABLE(); 8037 UNREACHABLE();
8087 } else if (op == Token::IN) { 8038 } else if (op == Token::IN) {
8088 HValue* function = AddLoadJSBuiltin(Builtins::IN, context); 8039 HValue* function = AddLoadJSBuiltin(Builtins::IN);
8089 Add<HPushArgument>(left); 8040 Add<HPushArgument>(left);
8090 Add<HPushArgument>(right); 8041 Add<HPushArgument>(right);
8091 // TODO(olivf) InvokeFunction produces a check for the parameter count, 8042 // TODO(olivf) InvokeFunction produces a check for the parameter count,
8092 // even though we are certain to pass the correct number of arguments here. 8043 // even though we are certain to pass the correct number of arguments here.
8093 HInstruction* result = new(zone()) HInvokeFunction(context, function, 2); 8044 HInstruction* result = new(zone()) HInvokeFunction(context, function, 2);
8094 result->set_position(expr->position()); 8045 result->set_position(expr->position());
8095 return ast_context()->ReturnInstruction(result, expr->id()); 8046 return ast_context()->ReturnInstruction(result, expr->id());
8096 } 8047 }
8097 8048
8098 // Cases handled below depend on collected type feedback. They should 8049 // Cases handled below depend on collected type feedback. They should
8099 // soft deoptimize when there is no type feedback. 8050 // soft deoptimize when there is no type feedback.
8100 if (combined_type->Is(Type::None())) { 8051 if (combined_type->Is(Type::None())) {
8101 Add<HDeoptimize>(Deoptimizer::SOFT); 8052 Add<HDeoptimize>(Deoptimizer::SOFT);
8102 combined_type = left_type = right_type = handle(Type::Any(), isolate()); 8053 combined_type = left_type = right_type = handle(Type::Any(), isolate());
8103 } 8054 }
8104 8055
8105 if (combined_type->Is(Type::Receiver())) { 8056 if (combined_type->Is(Type::Receiver())) {
8106 switch (op) { 8057 switch (op) {
8107 case Token::EQ: 8058 case Token::EQ:
8108 case Token::EQ_STRICT: { 8059 case Token::EQ_STRICT: {
8109 // Can we get away with map check and not instance type check? 8060 // Can we get away with map check and not instance type check?
8110 if (combined_type->IsClass()) { 8061 if (combined_type->IsClass()) {
8111 Handle<Map> map = combined_type->AsClass(); 8062 Handle<Map> map = combined_type->AsClass();
8112 AddCheckMap(left, map); 8063 AddCheckMap(left, map);
8113 AddCheckMap(right, map); 8064 AddCheckMap(right, map);
8114 HCompareObjectEqAndBranch* result = 8065 HCompareObjectEqAndBranch* result =
8115 new(zone()) HCompareObjectEqAndBranch(left, right); 8066 New<HCompareObjectEqAndBranch>(left, right);
8116 result->set_position(expr->position()); 8067 result->set_position(expr->position());
8117 return ast_context()->ReturnControl(result, expr->id()); 8068 return ast_context()->ReturnControl(result, expr->id());
8118 } else { 8069 } else {
8119 BuildCheckHeapObject(left); 8070 BuildCheckHeapObject(left);
8120 AddInstruction(HCheckInstanceType::NewIsSpecObject(left, zone())); 8071 AddInstruction(HCheckInstanceType::NewIsSpecObject(left, zone()));
8121 BuildCheckHeapObject(right); 8072 BuildCheckHeapObject(right);
8122 AddInstruction(HCheckInstanceType::NewIsSpecObject(right, zone())); 8073 AddInstruction(HCheckInstanceType::NewIsSpecObject(right, zone()));
8123 HCompareObjectEqAndBranch* result = 8074 HCompareObjectEqAndBranch* result =
8124 new(zone()) HCompareObjectEqAndBranch(left, right); 8075 new(zone()) HCompareObjectEqAndBranch(left, right);
8125 result->set_position(expr->position()); 8076 result->set_position(expr->position());
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
8186 ? handle(Type::Any(), isolate_) : expr->combined_type(); 8137 ? handle(Type::Any(), isolate_) : expr->combined_type();
8187 BuildCompareNil(value, type, expr->position(), &continuation); 8138 BuildCompareNil(value, type, expr->position(), &continuation);
8188 return ast_context()->ReturnContinuation(&continuation, expr->id()); 8139 return ast_context()->ReturnContinuation(&continuation, expr->id());
8189 } 8140 }
8190 8141
8191 8142
8192 HInstruction* HOptimizedGraphBuilder::BuildThisFunction() { 8143 HInstruction* HOptimizedGraphBuilder::BuildThisFunction() {
8193 // If we share optimized code between different closures, the 8144 // If we share optimized code between different closures, the
8194 // this-function is not a constant, except inside an inlined body. 8145 // this-function is not a constant, except inside an inlined body.
8195 if (function_state()->outer() != NULL) { 8146 if (function_state()->outer() != NULL) {
8196 return new(zone()) HConstant( 8147 return New<HConstant>(
8197 function_state()->compilation_info()->closure()); 8148 function_state()->compilation_info()->closure());
8198 } else { 8149 } else {
8199 return new(zone()) HThisFunction; 8150 return new(zone()) HThisFunction;
8200 } 8151 }
8201 } 8152 }
8202 8153
8203 8154
8204 HInstruction* HOptimizedGraphBuilder::BuildFastLiteral( 8155 HInstruction* HOptimizedGraphBuilder::BuildFastLiteral(
8205 HValue* context, 8156 HValue* context,
8206 Handle<JSObject> boilerplate_object, 8157 Handle<JSObject> boilerplate_object,
8207 Handle<JSObject> original_boilerplate_object, 8158 Handle<JSObject> original_boilerplate_object,
8208 Handle<Object> allocation_site, 8159 Handle<Object> allocation_site,
8209 int data_size, 8160 int data_size,
8210 int pointer_size, 8161 int pointer_size,
8211 AllocationSiteMode mode) { 8162 AllocationSiteMode mode) {
8212 NoObservableSideEffectsScope no_effects(this); 8163 NoObservableSideEffectsScope no_effects(this);
8213 8164
8214 HInstruction* target = NULL; 8165 HInstruction* target = NULL;
8215 HInstruction* data_target = NULL; 8166 HInstruction* data_target = NULL;
8216 8167
8217 ElementsKind kind = boilerplate_object->map()->elements_kind(); 8168 ElementsKind kind = boilerplate_object->map()->elements_kind();
8218 8169
8219 if (isolate()->heap()->ShouldGloballyPretenure()) { 8170 if (isolate()->heap()->ShouldGloballyPretenure()) {
8220 if (data_size != 0) { 8171 if (data_size != 0) {
8221 HValue* size_in_bytes = Add<HConstant>(data_size); 8172 HValue* size_in_bytes = Add<HConstant>(data_size);
8222 data_target = Add<HAllocate>(context, size_in_bytes, HType::JSObject(), 8173 data_target = Add<HAllocate>(size_in_bytes, HType::JSObject(),
8223 true, FAST_DOUBLE_ELEMENTS); 8174 true, FAST_DOUBLE_ELEMENTS);
8224 Handle<Map> free_space_map = isolate()->factory()->free_space_map(); 8175 Handle<Map> free_space_map = isolate()->factory()->free_space_map();
8225 AddStoreMapConstant(data_target, free_space_map); 8176 AddStoreMapConstant(data_target, free_space_map);
8226 HObjectAccess access = 8177 HObjectAccess access =
8227 HObjectAccess::ForJSObjectOffset(FreeSpace::kSizeOffset); 8178 HObjectAccess::ForJSObjectOffset(FreeSpace::kSizeOffset);
8228 AddStore(data_target, access, size_in_bytes); 8179 Add<HStoreNamedField>(data_target, access, size_in_bytes);
8229 } 8180 }
8230 if (pointer_size != 0) { 8181 if (pointer_size != 0) {
8231 HValue* size_in_bytes = Add<HConstant>(pointer_size); 8182 HValue* size_in_bytes = Add<HConstant>(pointer_size);
8232 target = Add<HAllocate>(context, size_in_bytes, HType::JSObject(), 8183 target = Add<HAllocate>(size_in_bytes, HType::JSObject(), true);
8233 true);
8234 } 8184 }
8235 } else { 8185 } else {
8236 HValue* size_in_bytes = Add<HConstant>(data_size + pointer_size); 8186 HValue* size_in_bytes = Add<HConstant>(data_size + pointer_size);
8237 target = Add<HAllocate>(context, size_in_bytes, HType::JSObject(), false, 8187 target = Add<HAllocate>(size_in_bytes, HType::JSObject(), false, kind);
8238 kind);
8239 } 8188 }
8240 8189
8241 int offset = 0; 8190 int offset = 0;
8242 int data_offset = 0; 8191 int data_offset = 0;
8243 BuildEmitDeepCopy(boilerplate_object, original_boilerplate_object, 8192 BuildEmitDeepCopy(boilerplate_object, original_boilerplate_object,
8244 allocation_site, target, &offset, data_target, 8193 allocation_site, target, &offset, data_target,
8245 &data_offset, mode); 8194 &data_offset, mode);
8246 return target; 8195 return target;
8247 } 8196 }
8248 8197
8249 8198
8250 void HOptimizedGraphBuilder::BuildEmitDeepCopy( 8199 void HOptimizedGraphBuilder::BuildEmitDeepCopy(
8251 Handle<JSObject> boilerplate_object, 8200 Handle<JSObject> boilerplate_object,
8252 Handle<JSObject> original_boilerplate_object, 8201 Handle<JSObject> original_boilerplate_object,
8253 Handle<Object> allocation_site_object, 8202 Handle<Object> allocation_site_object,
8254 HInstruction* target, 8203 HInstruction* target,
8255 int* offset, 8204 int* offset,
8256 HInstruction* data_target, 8205 HInstruction* data_target,
8257 int* data_offset, 8206 int* data_offset,
8258 AllocationSiteMode mode) { 8207 AllocationSiteMode mode) {
8259 Zone* zone = this->zone();
8260
8261 bool create_allocation_site_info = mode == TRACK_ALLOCATION_SITE && 8208 bool create_allocation_site_info = mode == TRACK_ALLOCATION_SITE &&
8262 boilerplate_object->map()->CanTrackAllocationSite(); 8209 boilerplate_object->map()->CanTrackAllocationSite();
8263 8210
8264 // If using allocation sites, then the payload on the site should already 8211 // If using allocation sites, then the payload on the site should already
8265 // be filled in as a valid (boilerplate) array. 8212 // be filled in as a valid (boilerplate) array.
8266 ASSERT(!create_allocation_site_info || 8213 ASSERT(!create_allocation_site_info ||
8267 AllocationSite::cast(*allocation_site_object)->IsLiteralSite()); 8214 AllocationSite::cast(*allocation_site_object)->IsLiteralSite());
8268 8215
8269 HInstruction* allocation_site = NULL; 8216 HInstruction* allocation_site = NULL;
8270 8217
8271 if (create_allocation_site_info) { 8218 if (create_allocation_site_info) {
8272 allocation_site = AddInstruction(new(zone) HConstant( 8219 allocation_site = Add<HConstant>(allocation_site_object);
8273 allocation_site_object, Representation::Tagged()));
8274 } 8220 }
8275 8221
8276 // Only elements backing stores for non-COW arrays need to be copied. 8222 // Only elements backing stores for non-COW arrays need to be copied.
8277 Handle<FixedArrayBase> elements(boilerplate_object->elements()); 8223 Handle<FixedArrayBase> elements(boilerplate_object->elements());
8278 Handle<FixedArrayBase> original_elements( 8224 Handle<FixedArrayBase> original_elements(
8279 original_boilerplate_object->elements()); 8225 original_boilerplate_object->elements());
8280 ElementsKind kind = boilerplate_object->map()->elements_kind(); 8226 ElementsKind kind = boilerplate_object->map()->elements_kind();
8281 8227
8282 int object_offset = *offset; 8228 int object_offset = *offset;
8283 int object_size = boilerplate_object->map()->instance_size(); 8229 int object_size = boilerplate_object->map()->instance_size();
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
8344 Handle<Object>(boilerplate_object->elements(), isolate()); 8290 Handle<Object>(boilerplate_object->elements(), isolate());
8345 elements = Add<HConstant>(elements_field); 8291 elements = Add<HConstant>(elements_field);
8346 } else { 8292 } else {
8347 if (data_target != NULL && boilerplate_object->HasFastDoubleElements()) { 8293 if (data_target != NULL && boilerplate_object->HasFastDoubleElements()) {
8348 elements = Add<HInnerAllocatedObject>(data_target, elements_offset); 8294 elements = Add<HInnerAllocatedObject>(data_target, elements_offset);
8349 } else { 8295 } else {
8350 elements = Add<HInnerAllocatedObject>(target, elements_offset); 8296 elements = Add<HInnerAllocatedObject>(target, elements_offset);
8351 } 8297 }
8352 result = elements; 8298 result = elements;
8353 } 8299 }
8354 AddStore(object_header, HObjectAccess::ForElementsPointer(), elements); 8300 Add<HStoreNamedField>(object_header, HObjectAccess::ForElementsPointer(),
8301 elements);
8355 8302
8356 Handle<Object> properties_field = 8303 Handle<Object> properties_field =
8357 Handle<Object>(boilerplate_object->properties(), isolate()); 8304 Handle<Object>(boilerplate_object->properties(), isolate());
8358 ASSERT(*properties_field == isolate()->heap()->empty_fixed_array()); 8305 ASSERT(*properties_field == isolate()->heap()->empty_fixed_array());
8359 HInstruction* properties = Add<HConstant>(properties_field); 8306 HInstruction* properties = Add<HConstant>(properties_field);
8360 HObjectAccess access = HObjectAccess::ForPropertiesPointer(); 8307 HObjectAccess access = HObjectAccess::ForPropertiesPointer();
8361 AddStore(object_header, access, properties); 8308 Add<HStoreNamedField>(object_header, access, properties);
8362 8309
8363 if (boilerplate_object->IsJSArray()) { 8310 if (boilerplate_object->IsJSArray()) {
8364 Handle<JSArray> boilerplate_array = 8311 Handle<JSArray> boilerplate_array =
8365 Handle<JSArray>::cast(boilerplate_object); 8312 Handle<JSArray>::cast(boilerplate_object);
8366 Handle<Object> length_field = 8313 Handle<Object> length_field =
8367 Handle<Object>(boilerplate_array->length(), isolate()); 8314 Handle<Object>(boilerplate_array->length(), isolate());
8368 HInstruction* length = Add<HConstant>(length_field); 8315 HInstruction* length = Add<HConstant>(length_field);
8369 8316
8370 ASSERT(boilerplate_array->length()->IsSmi()); 8317 ASSERT(boilerplate_array->length()->IsSmi());
8371 AddStore(object_header, HObjectAccess::ForArrayLength( 8318 Add<HStoreNamedField>(object_header, HObjectAccess::ForArrayLength(
8372 boilerplate_array->GetElementsKind()), length); 8319 boilerplate_array->GetElementsKind()), length);
8373 } 8320 }
8374 8321
8375 return result; 8322 return result;
8376 } 8323 }
8377 8324
8378 8325
8379 void HOptimizedGraphBuilder::BuildEmitInObjectProperties( 8326 void HOptimizedGraphBuilder::BuildEmitInObjectProperties(
8380 Handle<JSObject> boilerplate_object, 8327 Handle<JSObject> boilerplate_object,
8381 Handle<JSObject> original_boilerplate_object, 8328 Handle<JSObject> original_boilerplate_object,
(...skipping 24 matching lines...) Expand all
8406 HObjectAccess::ForJSObjectOffset(property_offset); 8353 HObjectAccess::ForJSObjectOffset(property_offset);
8407 8354
8408 if (value->IsJSObject()) { 8355 if (value->IsJSObject()) {
8409 Handle<JSObject> value_object = Handle<JSObject>::cast(value); 8356 Handle<JSObject> value_object = Handle<JSObject>::cast(value);
8410 Handle<JSObject> original_value_object = Handle<JSObject>::cast( 8357 Handle<JSObject> original_value_object = Handle<JSObject>::cast(
8411 Handle<Object>(original_boilerplate_object->InObjectPropertyAt(index), 8358 Handle<Object>(original_boilerplate_object->InObjectPropertyAt(index),
8412 isolate())); 8359 isolate()));
8413 HInstruction* value_instruction = Add<HInnerAllocatedObject>(target, 8360 HInstruction* value_instruction = Add<HInnerAllocatedObject>(target,
8414 *offset); 8361 *offset);
8415 8362
8416 AddStore(object_properties, access, value_instruction); 8363 Add<HStoreNamedField>(object_properties, access, value_instruction);
8417 BuildEmitDeepCopy(value_object, original_value_object, 8364 BuildEmitDeepCopy(value_object, original_value_object,
8418 Handle<Object>::null(), target, 8365 Handle<Object>::null(), target,
8419 offset, data_target, data_offset, 8366 offset, data_target, data_offset,
8420 DONT_TRACK_ALLOCATION_SITE); 8367 DONT_TRACK_ALLOCATION_SITE);
8421 } else { 8368 } else {
8422 Representation representation = details.representation(); 8369 Representation representation = details.representation();
8423 HInstruction* value_instruction = Add<HConstant>(value); 8370 HInstruction* value_instruction = Add<HConstant>(value);
8424 8371
8425 if (representation.IsDouble()) { 8372 if (representation.IsDouble()) {
8426 // Allocate a HeapNumber box and store the value into it. 8373 // Allocate a HeapNumber box and store the value into it.
8427 HInstruction* double_box; 8374 HInstruction* double_box;
8428 if (data_target != NULL) { 8375 if (data_target != NULL) {
8429 double_box = Add<HInnerAllocatedObject>(data_target, *data_offset); 8376 double_box = Add<HInnerAllocatedObject>(data_target, *data_offset);
8430 *data_offset += HeapNumber::kSize; 8377 *data_offset += HeapNumber::kSize;
8431 } else { 8378 } else {
8432 double_box = Add<HInnerAllocatedObject>(target, *offset); 8379 double_box = Add<HInnerAllocatedObject>(target, *offset);
8433 *offset += HeapNumber::kSize; 8380 *offset += HeapNumber::kSize;
8434 } 8381 }
8435 AddStoreMapConstant(double_box, 8382 AddStoreMapConstant(double_box,
8436 isolate()->factory()->heap_number_map()); 8383 isolate()->factory()->heap_number_map());
8437 AddStore(double_box, HObjectAccess::ForHeapNumberValue(), 8384 Add<HStoreNamedField>(double_box, HObjectAccess::ForHeapNumberValue(),
8438 value_instruction); 8385 value_instruction);
8439 value_instruction = double_box; 8386 value_instruction = double_box;
8440 } 8387 }
8441 8388
8442 AddStore(object_properties, access, value_instruction); 8389 Add<HStoreNamedField>(object_properties, access, value_instruction);
8443 } 8390 }
8444 } 8391 }
8445 8392
8446 int inobject_properties = boilerplate_object->map()->inobject_properties(); 8393 int inobject_properties = boilerplate_object->map()->inobject_properties();
8447 HInstruction* value_instruction = 8394 HInstruction* value_instruction =
8448 Add<HConstant>(isolate()->factory()->one_pointer_filler_map()); 8395 Add<HConstant>(isolate()->factory()->one_pointer_filler_map());
8449 for (int i = copied_fields; i < inobject_properties; i++) { 8396 for (int i = copied_fields; i < inobject_properties; i++) {
8450 ASSERT(boilerplate_object->IsJSObject()); 8397 ASSERT(boilerplate_object->IsJSObject());
8451 int property_offset = boilerplate_object->GetInObjectPropertyOffset(i); 8398 int property_offset = boilerplate_object->GetInObjectPropertyOffset(i);
8452 HObjectAccess access = HObjectAccess::ForJSObjectOffset(property_offset); 8399 HObjectAccess access = HObjectAccess::ForJSObjectOffset(property_offset);
8453 AddStore(object_properties, access, value_instruction); 8400 Add<HStoreNamedField>(object_properties, access, value_instruction);
8454 } 8401 }
8455 } 8402 }
8456 8403
8457 8404
8458 void HOptimizedGraphBuilder::BuildEmitElements( 8405 void HOptimizedGraphBuilder::BuildEmitElements(
8459 Handle<FixedArrayBase> elements, 8406 Handle<FixedArrayBase> elements,
8460 Handle<FixedArrayBase> original_elements, 8407 Handle<FixedArrayBase> original_elements,
8461 ElementsKind kind, 8408 ElementsKind kind,
8462 HValue* object_elements, 8409 HValue* object_elements,
8463 HInstruction* target, 8410 HInstruction* target,
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
8552 ZoneList<Declaration*>* declarations) { 8499 ZoneList<Declaration*>* declarations) {
8553 ASSERT(globals_.is_empty()); 8500 ASSERT(globals_.is_empty());
8554 AstVisitor::VisitDeclarations(declarations); 8501 AstVisitor::VisitDeclarations(declarations);
8555 if (!globals_.is_empty()) { 8502 if (!globals_.is_empty()) {
8556 Handle<FixedArray> array = 8503 Handle<FixedArray> array =
8557 isolate()->factory()->NewFixedArray(globals_.length(), TENURED); 8504 isolate()->factory()->NewFixedArray(globals_.length(), TENURED);
8558 for (int i = 0; i < globals_.length(); ++i) array->set(i, *globals_.at(i)); 8505 for (int i = 0; i < globals_.length(); ++i) array->set(i, *globals_.at(i));
8559 int flags = DeclareGlobalsEvalFlag::encode(current_info()->is_eval()) | 8506 int flags = DeclareGlobalsEvalFlag::encode(current_info()->is_eval()) |
8560 DeclareGlobalsNativeFlag::encode(current_info()->is_native()) | 8507 DeclareGlobalsNativeFlag::encode(current_info()->is_native()) |
8561 DeclareGlobalsLanguageMode::encode(current_info()->language_mode()); 8508 DeclareGlobalsLanguageMode::encode(current_info()->language_mode());
8562 Add<HDeclareGlobals>(environment()->LookupContext(), array, flags); 8509 Add<HDeclareGlobals>(array, flags);
8563 globals_.Clear(); 8510 globals_.Clear();
8564 } 8511 }
8565 } 8512 }
8566 8513
8567 8514
8568 void HOptimizedGraphBuilder::VisitVariableDeclaration( 8515 void HOptimizedGraphBuilder::VisitVariableDeclaration(
8569 VariableDeclaration* declaration) { 8516 VariableDeclaration* declaration) {
8570 VariableProxy* proxy = declaration->proxy(); 8517 VariableProxy* proxy = declaration->proxy();
8571 VariableMode mode = declaration->mode(); 8518 VariableMode mode = declaration->mode();
8572 Variable* variable = proxy->var(); 8519 Variable* variable = proxy->var();
8573 bool hole_init = mode == CONST || mode == CONST_HARMONY || mode == LET; 8520 bool hole_init = mode == CONST || mode == CONST_HARMONY || mode == LET;
8574 switch (variable->location()) { 8521 switch (variable->location()) {
8575 case Variable::UNALLOCATED: 8522 case Variable::UNALLOCATED:
8576 globals_.Add(variable->name(), zone()); 8523 globals_.Add(variable->name(), zone());
8577 globals_.Add(variable->binding_needs_init() 8524 globals_.Add(variable->binding_needs_init()
8578 ? isolate()->factory()->the_hole_value() 8525 ? isolate()->factory()->the_hole_value()
8579 : isolate()->factory()->undefined_value(), zone()); 8526 : isolate()->factory()->undefined_value(), zone());
8580 return; 8527 return;
8581 case Variable::PARAMETER: 8528 case Variable::PARAMETER:
8582 case Variable::LOCAL: 8529 case Variable::LOCAL:
8583 if (hole_init) { 8530 if (hole_init) {
8584 HValue* value = graph()->GetConstantHole(); 8531 HValue* value = graph()->GetConstantHole();
8585 environment()->Bind(variable, value); 8532 environment()->Bind(variable, value);
8586 } 8533 }
8587 break; 8534 break;
8588 case Variable::CONTEXT: 8535 case Variable::CONTEXT:
8589 if (hole_init) { 8536 if (hole_init) {
8590 HValue* value = graph()->GetConstantHole(); 8537 HValue* value = graph()->GetConstantHole();
8591 HValue* context = environment()->LookupContext(); 8538 HValue* context = environment()->context();
8592 HStoreContextSlot* store = Add<HStoreContextSlot>( 8539 HStoreContextSlot* store = Add<HStoreContextSlot>(
8593 context, variable->index(), HStoreContextSlot::kNoCheck, value); 8540 context, variable->index(), HStoreContextSlot::kNoCheck, value);
8594 if (store->HasObservableSideEffects()) { 8541 if (store->HasObservableSideEffects()) {
8595 Add<HSimulate>(proxy->id(), REMOVABLE_SIMULATE); 8542 Add<HSimulate>(proxy->id(), REMOVABLE_SIMULATE);
8596 } 8543 }
8597 } 8544 }
8598 break; 8545 break;
8599 case Variable::LOOKUP: 8546 case Variable::LOOKUP:
8600 return Bailout("unsupported lookup slot in declaration"); 8547 return Bailout("unsupported lookup slot in declaration");
8601 } 8548 }
(...skipping 17 matching lines...) Expand all
8619 case Variable::PARAMETER: 8566 case Variable::PARAMETER:
8620 case Variable::LOCAL: { 8567 case Variable::LOCAL: {
8621 CHECK_ALIVE(VisitForValue(declaration->fun())); 8568 CHECK_ALIVE(VisitForValue(declaration->fun()));
8622 HValue* value = Pop(); 8569 HValue* value = Pop();
8623 BindIfLive(variable, value); 8570 BindIfLive(variable, value);
8624 break; 8571 break;
8625 } 8572 }
8626 case Variable::CONTEXT: { 8573 case Variable::CONTEXT: {
8627 CHECK_ALIVE(VisitForValue(declaration->fun())); 8574 CHECK_ALIVE(VisitForValue(declaration->fun()));
8628 HValue* value = Pop(); 8575 HValue* value = Pop();
8629 HValue* context = environment()->LookupContext(); 8576 HValue* context = environment()->context();
8630 HStoreContextSlot* store = Add<HStoreContextSlot>( 8577 HStoreContextSlot* store = Add<HStoreContextSlot>(
8631 context, variable->index(), HStoreContextSlot::kNoCheck, value); 8578 context, variable->index(), HStoreContextSlot::kNoCheck, value);
8632 if (store->HasObservableSideEffects()) { 8579 if (store->HasObservableSideEffects()) {
8633 Add<HSimulate>(proxy->id(), REMOVABLE_SIMULATE); 8580 Add<HSimulate>(proxy->id(), REMOVABLE_SIMULATE);
8634 } 8581 }
8635 break; 8582 break;
8636 } 8583 }
8637 case Variable::LOOKUP: 8584 case Variable::LOOKUP:
8638 return Bailout("unsupported lookup slot in declaration"); 8585 return Bailout("unsupported lookup slot in declaration");
8639 } 8586 }
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after
8794 8741
8795 8742
8796 // Support for arguments.length and arguments[?]. 8743 // Support for arguments.length and arguments[?].
8797 void HOptimizedGraphBuilder::GenerateArgumentsLength(CallRuntime* call) { 8744 void HOptimizedGraphBuilder::GenerateArgumentsLength(CallRuntime* call) {
8798 // Our implementation of arguments (based on this stack frame or an 8745 // Our implementation of arguments (based on this stack frame or an
8799 // adapter below it) does not work for inlined functions. This runtime 8746 // adapter below it) does not work for inlined functions. This runtime
8800 // function is blacklisted by AstNode::IsInlineable. 8747 // function is blacklisted by AstNode::IsInlineable.
8801 ASSERT(function_state()->outer() == NULL); 8748 ASSERT(function_state()->outer() == NULL);
8802 ASSERT(call->arguments()->length() == 0); 8749 ASSERT(call->arguments()->length() == 0);
8803 HInstruction* elements = Add<HArgumentsElements>(false); 8750 HInstruction* elements = Add<HArgumentsElements>(false);
8804 HArgumentsLength* result = new(zone()) HArgumentsLength(elements); 8751 HArgumentsLength* result = New<HArgumentsLength>(elements);
8805 return ast_context()->ReturnInstruction(result, call->id()); 8752 return ast_context()->ReturnInstruction(result, call->id());
8806 } 8753 }
8807 8754
8808 8755
8809 void HOptimizedGraphBuilder::GenerateArguments(CallRuntime* call) { 8756 void HOptimizedGraphBuilder::GenerateArguments(CallRuntime* call) {
8810 // Our implementation of arguments (based on this stack frame or an 8757 // Our implementation of arguments (based on this stack frame or an
8811 // adapter below it) does not work for inlined functions. This runtime 8758 // adapter below it) does not work for inlined functions. This runtime
8812 // function is blacklisted by AstNode::IsInlineable. 8759 // function is blacklisted by AstNode::IsInlineable.
8813 ASSERT(function_state()->outer() == NULL); 8760 ASSERT(function_state()->outer() == NULL);
8814 ASSERT(call->arguments()->length() == 1); 8761 ASSERT(call->arguments()->length() == 1);
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
8903 new(zone()) HHasInstanceTypeAndBranch(object, JS_VALUE_TYPE); 8850 new(zone()) HHasInstanceTypeAndBranch(object, JS_VALUE_TYPE);
8904 HBasicBlock* if_js_value = graph()->CreateBasicBlock(); 8851 HBasicBlock* if_js_value = graph()->CreateBasicBlock();
8905 HBasicBlock* not_js_value = graph()->CreateBasicBlock(); 8852 HBasicBlock* not_js_value = graph()->CreateBasicBlock();
8906 typecheck->SetSuccessorAt(0, if_js_value); 8853 typecheck->SetSuccessorAt(0, if_js_value);
8907 typecheck->SetSuccessorAt(1, not_js_value); 8854 typecheck->SetSuccessorAt(1, not_js_value);
8908 current_block()->Finish(typecheck); 8855 current_block()->Finish(typecheck);
8909 not_js_value->Goto(join); 8856 not_js_value->Goto(join);
8910 8857
8911 // Create in-object property store to kValueOffset. 8858 // Create in-object property store to kValueOffset.
8912 set_current_block(if_js_value); 8859 set_current_block(if_js_value);
8913 AddStore(object, 8860 Add<HStoreNamedField>(object,
8914 HObjectAccess::ForJSObjectOffset(JSValue::kValueOffset), value); 8861 HObjectAccess::ForJSObjectOffset(JSValue::kValueOffset), value);
8915 if_js_value->Goto(join); 8862 if_js_value->Goto(join);
8916 join->SetJoinId(call->id()); 8863 join->SetJoinId(call->id());
8917 set_current_block(join); 8864 set_current_block(join);
8918 return ast_context()->ReturnValue(value); 8865 return ast_context()->ReturnValue(value);
8919 } 8866 }
8920 8867
8921 8868
8922 // Fast support for charCodeAt(n). 8869 // Fast support for charCodeAt(n).
8923 void HOptimizedGraphBuilder::GenerateStringCharCodeAt(CallRuntime* call) { 8870 void HOptimizedGraphBuilder::GenerateStringCharCodeAt(CallRuntime* call) {
8924 ASSERT(call->arguments()->length() == 2); 8871 ASSERT(call->arguments()->length() == 2);
8925 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 8872 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
8926 CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); 8873 CHECK_ALIVE(VisitForValue(call->arguments()->at(1)));
8927 HValue* index = Pop(); 8874 HValue* index = Pop();
8928 HValue* string = Pop(); 8875 HValue* string = Pop();
8929 HValue* context = environment()->LookupContext(); 8876 HInstruction* result = BuildStringCharCodeAt(string, index);
8930 HInstruction* result = BuildStringCharCodeAt(context, string, index);
8931 return ast_context()->ReturnInstruction(result, call->id()); 8877 return ast_context()->ReturnInstruction(result, call->id());
8932 } 8878 }
8933 8879
8934 8880
8935 // Fast support for string.charAt(n) and string[n]. 8881 // Fast support for string.charAt(n) and string[n].
8936 void HOptimizedGraphBuilder::GenerateStringCharFromCode(CallRuntime* call) { 8882 void HOptimizedGraphBuilder::GenerateStringCharFromCode(CallRuntime* call) {
8937 ASSERT(call->arguments()->length() == 1); 8883 ASSERT(call->arguments()->length() == 1);
8938 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 8884 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
8939 HValue* char_code = Pop(); 8885 HValue* char_code = Pop();
8940 HValue* context = environment()->LookupContext(); 8886 HInstruction* result = New<HStringCharFromCode>(char_code);
8941 HInstruction* result = HStringCharFromCode::New(zone(), context, char_code);
8942 return ast_context()->ReturnInstruction(result, call->id()); 8887 return ast_context()->ReturnInstruction(result, call->id());
8943 } 8888 }
8944 8889
8945 8890
8946 // Fast support for string.charAt(n) and string[n]. 8891 // Fast support for string.charAt(n) and string[n].
8947 void HOptimizedGraphBuilder::GenerateStringCharAt(CallRuntime* call) { 8892 void HOptimizedGraphBuilder::GenerateStringCharAt(CallRuntime* call) {
8948 ASSERT(call->arguments()->length() == 2); 8893 ASSERT(call->arguments()->length() == 2);
8949 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 8894 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
8950 CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); 8895 CHECK_ALIVE(VisitForValue(call->arguments()->at(1)));
8951 HValue* index = Pop(); 8896 HValue* index = Pop();
8952 HValue* string = Pop(); 8897 HValue* string = Pop();
8953 HValue* context = environment()->LookupContext(); 8898 HInstruction* char_code = BuildStringCharCodeAt(string, index);
8954 HInstruction* char_code = BuildStringCharCodeAt(context, string, index);
8955 AddInstruction(char_code); 8899 AddInstruction(char_code);
8956 HInstruction* result = HStringCharFromCode::New(zone(), context, char_code); 8900 HInstruction* result = New<HStringCharFromCode>(char_code);
8957 return ast_context()->ReturnInstruction(result, call->id()); 8901 return ast_context()->ReturnInstruction(result, call->id());
8958 } 8902 }
8959 8903
8960 8904
8961 // Fast support for object equality testing. 8905 // Fast support for object equality testing.
8962 void HOptimizedGraphBuilder::GenerateObjectEquals(CallRuntime* call) { 8906 void HOptimizedGraphBuilder::GenerateObjectEquals(CallRuntime* call) {
8963 ASSERT(call->arguments()->length() == 2); 8907 ASSERT(call->arguments()->length() == 2);
8964 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 8908 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
8965 CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); 8909 CHECK_ALIVE(VisitForValue(call->arguments()->at(1)));
8966 HValue* right = Pop(); 8910 HValue* right = Pop();
8967 HValue* left = Pop(); 8911 HValue* left = Pop();
8968 HCompareObjectEqAndBranch* result = 8912 HCompareObjectEqAndBranch* result =
8969 new(zone()) HCompareObjectEqAndBranch(left, right); 8913 New<HCompareObjectEqAndBranch>(left, right);
8970 return ast_context()->ReturnControl(result, call->id()); 8914 return ast_context()->ReturnControl(result, call->id());
8971 } 8915 }
8972 8916
8973 8917
8974 void HOptimizedGraphBuilder::GenerateLog(CallRuntime* call) { 8918 void HOptimizedGraphBuilder::GenerateLog(CallRuntime* call) {
8975 // %_Log is ignored in optimized code. 8919 // %_Log is ignored in optimized code.
8976 return ast_context()->ReturnValue(graph()->GetConstantUndefined()); 8920 return ast_context()->ReturnValue(graph()->GetConstantUndefined());
8977 } 8921 }
8978 8922
8979 8923
8980 // Fast support for Math.random(). 8924 // Fast support for Math.random().
8981 void HOptimizedGraphBuilder::GenerateRandomHeapNumber(CallRuntime* call) { 8925 void HOptimizedGraphBuilder::GenerateRandomHeapNumber(CallRuntime* call) {
8982 HValue* context = environment()->LookupContext(); 8926 HGlobalObject* global_object = Add<HGlobalObject>();
8983 HGlobalObject* global_object = Add<HGlobalObject>(context);
8984 HRandom* result = new(zone()) HRandom(global_object); 8927 HRandom* result = new(zone()) HRandom(global_object);
8985 return ast_context()->ReturnInstruction(result, call->id()); 8928 return ast_context()->ReturnInstruction(result, call->id());
8986 } 8929 }
8987 8930
8988 8931
8989 // Fast support for StringAdd. 8932 // Fast support for StringAdd.
8990 void HOptimizedGraphBuilder::GenerateStringAdd(CallRuntime* call) { 8933 void HOptimizedGraphBuilder::GenerateStringAdd(CallRuntime* call) {
8991 ASSERT_EQ(2, call->arguments()->length()); 8934 ASSERT_EQ(2, call->arguments()->length());
8992 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 8935 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
8993 CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); 8936 CHECK_ALIVE(VisitForValue(call->arguments()->at(1)));
8994 HValue* right = Pop(); 8937 HValue* right = Pop();
8995 HValue* left = Pop(); 8938 HValue* left = Pop();
8996 HValue* context = environment()->LookupContext(); 8939 HValue* context = environment()->context();
8997 HInstruction* result = HStringAdd::New( 8940 HInstruction* result = HStringAdd::New(
8998 zone(), context, left, right, STRING_ADD_CHECK_BOTH); 8941 zone(), context, left, right, STRING_ADD_CHECK_BOTH);
8999 return ast_context()->ReturnInstruction(result, call->id()); 8942 return ast_context()->ReturnInstruction(result, call->id());
9000 } 8943 }
9001 8944
9002 8945
9003 // Fast support for SubString. 8946 // Fast support for SubString.
9004 void HOptimizedGraphBuilder::GenerateSubString(CallRuntime* call) { 8947 void HOptimizedGraphBuilder::GenerateSubString(CallRuntime* call) {
9005 ASSERT_EQ(3, call->arguments()->length()); 8948 ASSERT_EQ(3, call->arguments()->length());
9006 CHECK_ALIVE(VisitArgumentList(call->arguments())); 8949 CHECK_ALIVE(VisitArgumentList(call->arguments()));
9007 HValue* context = environment()->LookupContext(); 8950 HValue* context = environment()->context();
9008 HCallStub* result = new(zone()) HCallStub(context, CodeStub::SubString, 3); 8951 HCallStub* result = new(zone()) HCallStub(context, CodeStub::SubString, 3);
9009 Drop(3); 8952 Drop(3);
9010 return ast_context()->ReturnInstruction(result, call->id()); 8953 return ast_context()->ReturnInstruction(result, call->id());
9011 } 8954 }
9012 8955
9013 8956
9014 // Fast support for StringCompare. 8957 // Fast support for StringCompare.
9015 void HOptimizedGraphBuilder::GenerateStringCompare(CallRuntime* call) { 8958 void HOptimizedGraphBuilder::GenerateStringCompare(CallRuntime* call) {
9016 ASSERT_EQ(2, call->arguments()->length()); 8959 ASSERT_EQ(2, call->arguments()->length());
9017 CHECK_ALIVE(VisitArgumentList(call->arguments())); 8960 CHECK_ALIVE(VisitArgumentList(call->arguments()));
9018 HValue* context = environment()->LookupContext(); 8961 HValue* context = environment()->context();
9019 HCallStub* result = 8962 HCallStub* result =
9020 new(zone()) HCallStub(context, CodeStub::StringCompare, 2); 8963 new(zone()) HCallStub(context, CodeStub::StringCompare, 2);
9021 Drop(2); 8964 Drop(2);
9022 return ast_context()->ReturnInstruction(result, call->id()); 8965 return ast_context()->ReturnInstruction(result, call->id());
9023 } 8966 }
9024 8967
9025 8968
9026 // Support for direct calls from JavaScript to native RegExp code. 8969 // Support for direct calls from JavaScript to native RegExp code.
9027 void HOptimizedGraphBuilder::GenerateRegExpExec(CallRuntime* call) { 8970 void HOptimizedGraphBuilder::GenerateRegExpExec(CallRuntime* call) {
9028 ASSERT_EQ(4, call->arguments()->length()); 8971 ASSERT_EQ(4, call->arguments()->length());
9029 CHECK_ALIVE(VisitArgumentList(call->arguments())); 8972 CHECK_ALIVE(VisitArgumentList(call->arguments()));
9030 HValue* context = environment()->LookupContext(); 8973 HValue* context = environment()->context();
9031 HCallStub* result = new(zone()) HCallStub(context, CodeStub::RegExpExec, 4); 8974 HCallStub* result = new(zone()) HCallStub(context, CodeStub::RegExpExec, 4);
9032 Drop(4); 8975 Drop(4);
9033 return ast_context()->ReturnInstruction(result, call->id()); 8976 return ast_context()->ReturnInstruction(result, call->id());
9034 } 8977 }
9035 8978
9036 8979
9037 // Construct a RegExp exec result with two in-object properties. 8980 // Construct a RegExp exec result with two in-object properties.
9038 void HOptimizedGraphBuilder::GenerateRegExpConstructResult(CallRuntime* call) { 8981 void HOptimizedGraphBuilder::GenerateRegExpConstructResult(CallRuntime* call) {
9039 ASSERT_EQ(3, call->arguments()->length()); 8982 ASSERT_EQ(3, call->arguments()->length());
9040 CHECK_ALIVE(VisitArgumentList(call->arguments())); 8983 CHECK_ALIVE(VisitArgumentList(call->arguments()));
9041 HValue* context = environment()->LookupContext(); 8984 HValue* context = environment()->context();
9042 HCallStub* result = 8985 HCallStub* result =
9043 new(zone()) HCallStub(context, CodeStub::RegExpConstructResult, 3); 8986 new(zone()) HCallStub(context, CodeStub::RegExpConstructResult, 3);
9044 Drop(3); 8987 Drop(3);
9045 return ast_context()->ReturnInstruction(result, call->id()); 8988 return ast_context()->ReturnInstruction(result, call->id());
9046 } 8989 }
9047 8990
9048 8991
9049 // Support for fast native caches. 8992 // Support for fast native caches.
9050 void HOptimizedGraphBuilder::GenerateGetFromCache(CallRuntime* call) { 8993 void HOptimizedGraphBuilder::GenerateGetFromCache(CallRuntime* call) {
9051 return Bailout("inlined runtime function: GetFromCache"); 8994 return Bailout("inlined runtime function: GetFromCache");
9052 } 8995 }
9053 8996
9054 8997
9055 // Fast support for number to string. 8998 // Fast support for number to string.
9056 void HOptimizedGraphBuilder::GenerateNumberToString(CallRuntime* call) { 8999 void HOptimizedGraphBuilder::GenerateNumberToString(CallRuntime* call) {
9057 ASSERT_EQ(1, call->arguments()->length()); 9000 ASSERT_EQ(1, call->arguments()->length());
9058 CHECK_ALIVE(VisitArgumentList(call->arguments())); 9001 CHECK_ALIVE(VisitArgumentList(call->arguments()));
9059 HValue* context = environment()->LookupContext(); 9002 HValue* context = environment()->context();
9060 HCallStub* result = 9003 HCallStub* result =
9061 new(zone()) HCallStub(context, CodeStub::NumberToString, 1); 9004 new(zone()) HCallStub(context, CodeStub::NumberToString, 1);
9062 Drop(1); 9005 Drop(1);
9063 return ast_context()->ReturnInstruction(result, call->id()); 9006 return ast_context()->ReturnInstruction(result, call->id());
9064 } 9007 }
9065 9008
9066 9009
9067 // Fast call for custom callbacks. 9010 // Fast call for custom callbacks.
9068 void HOptimizedGraphBuilder::GenerateCallFunction(CallRuntime* call) { 9011 void HOptimizedGraphBuilder::GenerateCallFunction(CallRuntime* call) {
9069 // 1 ~ The function to call is not itself an argument to the call. 9012 // 1 ~ The function to call is not itself an argument to the call.
9070 int arg_count = call->arguments()->length() - 1; 9013 int arg_count = call->arguments()->length() - 1;
9071 ASSERT(arg_count >= 1); // There's always at least a receiver. 9014 ASSERT(arg_count >= 1); // There's always at least a receiver.
9072 9015
9073 for (int i = 0; i < arg_count; ++i) { 9016 for (int i = 0; i < arg_count; ++i) {
9074 CHECK_ALIVE(VisitArgument(call->arguments()->at(i))); 9017 CHECK_ALIVE(VisitArgument(call->arguments()->at(i)));
9075 } 9018 }
9076 CHECK_ALIVE(VisitForValue(call->arguments()->last())); 9019 CHECK_ALIVE(VisitForValue(call->arguments()->last()));
9077 9020
9078 HValue* function = Pop(); 9021 HValue* function = Pop();
9079 HValue* context = environment()->LookupContext();
9080 9022
9081 // Branch for function proxies, or other non-functions. 9023 // Branch for function proxies, or other non-functions.
9082 HHasInstanceTypeAndBranch* typecheck = 9024 HHasInstanceTypeAndBranch* typecheck =
9083 new(zone()) HHasInstanceTypeAndBranch(function, JS_FUNCTION_TYPE); 9025 new(zone()) HHasInstanceTypeAndBranch(function, JS_FUNCTION_TYPE);
9084 HBasicBlock* if_jsfunction = graph()->CreateBasicBlock(); 9026 HBasicBlock* if_jsfunction = graph()->CreateBasicBlock();
9085 HBasicBlock* if_nonfunction = graph()->CreateBasicBlock(); 9027 HBasicBlock* if_nonfunction = graph()->CreateBasicBlock();
9086 HBasicBlock* join = graph()->CreateBasicBlock(); 9028 HBasicBlock* join = graph()->CreateBasicBlock();
9087 typecheck->SetSuccessorAt(0, if_jsfunction); 9029 typecheck->SetSuccessorAt(0, if_jsfunction);
9088 typecheck->SetSuccessorAt(1, if_nonfunction); 9030 typecheck->SetSuccessorAt(1, if_nonfunction);
9089 current_block()->Finish(typecheck); 9031 current_block()->Finish(typecheck);
9090 9032
9091 set_current_block(if_jsfunction); 9033 set_current_block(if_jsfunction);
9092 HInstruction* invoke_result = 9034 HInstruction* invoke_result = Add<HInvokeFunction>(function, arg_count);
9093 Add<HInvokeFunction>(context, function, arg_count);
9094 Drop(arg_count); 9035 Drop(arg_count);
9095 Push(invoke_result); 9036 Push(invoke_result);
9096 if_jsfunction->Goto(join); 9037 if_jsfunction->Goto(join);
9097 9038
9098 set_current_block(if_nonfunction); 9039 set_current_block(if_nonfunction);
9099 HInstruction* call_result = Add<HCallFunction>(context, function, arg_count); 9040 HInstruction* call_result = Add<HCallFunction>(function, arg_count);
9100 Drop(arg_count); 9041 Drop(arg_count);
9101 Push(call_result); 9042 Push(call_result);
9102 if_nonfunction->Goto(join); 9043 if_nonfunction->Goto(join);
9103 9044
9104 set_current_block(join); 9045 set_current_block(join);
9105 join->SetJoinId(call->id()); 9046 join->SetJoinId(call->id());
9106 return ast_context()->ReturnValue(Pop()); 9047 return ast_context()->ReturnValue(Pop());
9107 } 9048 }
9108 9049
9109 9050
9110 // Fast call to math functions. 9051 // Fast call to math functions.
9111 void HOptimizedGraphBuilder::GenerateMathPow(CallRuntime* call) { 9052 void HOptimizedGraphBuilder::GenerateMathPow(CallRuntime* call) {
9112 ASSERT_EQ(2, call->arguments()->length()); 9053 ASSERT_EQ(2, call->arguments()->length());
9113 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 9054 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
9114 CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); 9055 CHECK_ALIVE(VisitForValue(call->arguments()->at(1)));
9115 HValue* right = Pop(); 9056 HValue* right = Pop();
9116 HValue* left = Pop(); 9057 HValue* left = Pop();
9117 HInstruction* result = HPower::New(zone(), left, right); 9058 HInstruction* result = HPower::New(zone(), context(), left, right);
9118 return ast_context()->ReturnInstruction(result, call->id()); 9059 return ast_context()->ReturnInstruction(result, call->id());
9119 } 9060 }
9120 9061
9121 9062
9122 void HOptimizedGraphBuilder::GenerateMathSin(CallRuntime* call) { 9063 void HOptimizedGraphBuilder::GenerateMathSin(CallRuntime* call) {
9123 ASSERT_EQ(1, call->arguments()->length()); 9064 ASSERT_EQ(1, call->arguments()->length());
9124 CHECK_ALIVE(VisitArgumentList(call->arguments())); 9065 CHECK_ALIVE(VisitArgumentList(call->arguments()));
9125 HValue* context = environment()->LookupContext(); 9066 HValue* context = environment()->context();
9126 HCallStub* result = 9067 HCallStub* result =
9127 new(zone()) HCallStub(context, CodeStub::TranscendentalCache, 1); 9068 new(zone()) HCallStub(context, CodeStub::TranscendentalCache, 1);
9128 result->set_transcendental_type(TranscendentalCache::SIN); 9069 result->set_transcendental_type(TranscendentalCache::SIN);
9129 Drop(1); 9070 Drop(1);
9130 return ast_context()->ReturnInstruction(result, call->id()); 9071 return ast_context()->ReturnInstruction(result, call->id());
9131 } 9072 }
9132 9073
9133 9074
9134 void HOptimizedGraphBuilder::GenerateMathCos(CallRuntime* call) { 9075 void HOptimizedGraphBuilder::GenerateMathCos(CallRuntime* call) {
9135 ASSERT_EQ(1, call->arguments()->length()); 9076 ASSERT_EQ(1, call->arguments()->length());
9136 CHECK_ALIVE(VisitArgumentList(call->arguments())); 9077 CHECK_ALIVE(VisitArgumentList(call->arguments()));
9137 HValue* context = environment()->LookupContext(); 9078 HValue* context = environment()->context();
9138 HCallStub* result = 9079 HCallStub* result =
9139 new(zone()) HCallStub(context, CodeStub::TranscendentalCache, 1); 9080 new(zone()) HCallStub(context, CodeStub::TranscendentalCache, 1);
9140 result->set_transcendental_type(TranscendentalCache::COS); 9081 result->set_transcendental_type(TranscendentalCache::COS);
9141 Drop(1); 9082 Drop(1);
9142 return ast_context()->ReturnInstruction(result, call->id()); 9083 return ast_context()->ReturnInstruction(result, call->id());
9143 } 9084 }
9144 9085
9145 9086
9146 void HOptimizedGraphBuilder::GenerateMathTan(CallRuntime* call) { 9087 void HOptimizedGraphBuilder::GenerateMathTan(CallRuntime* call) {
9147 ASSERT_EQ(1, call->arguments()->length()); 9088 ASSERT_EQ(1, call->arguments()->length());
9148 CHECK_ALIVE(VisitArgumentList(call->arguments())); 9089 CHECK_ALIVE(VisitArgumentList(call->arguments()));
9149 HValue* context = environment()->LookupContext(); 9090 HValue* context = environment()->context();
9150 HCallStub* result = 9091 HCallStub* result =
9151 new(zone()) HCallStub(context, CodeStub::TranscendentalCache, 1); 9092 new(zone()) HCallStub(context, CodeStub::TranscendentalCache, 1);
9152 result->set_transcendental_type(TranscendentalCache::TAN); 9093 result->set_transcendental_type(TranscendentalCache::TAN);
9153 Drop(1); 9094 Drop(1);
9154 return ast_context()->ReturnInstruction(result, call->id()); 9095 return ast_context()->ReturnInstruction(result, call->id());
9155 } 9096 }
9156 9097
9157 9098
9158 void HOptimizedGraphBuilder::GenerateMathLog(CallRuntime* call) { 9099 void HOptimizedGraphBuilder::GenerateMathLog(CallRuntime* call) {
9159 ASSERT_EQ(1, call->arguments()->length()); 9100 ASSERT_EQ(1, call->arguments()->length());
9160 CHECK_ALIVE(VisitArgumentList(call->arguments())); 9101 CHECK_ALIVE(VisitArgumentList(call->arguments()));
9161 HValue* context = environment()->LookupContext(); 9102 HValue* context = environment()->context();
9162 HCallStub* result = 9103 HCallStub* result =
9163 new(zone()) HCallStub(context, CodeStub::TranscendentalCache, 1); 9104 new(zone()) HCallStub(context, CodeStub::TranscendentalCache, 1);
9164 result->set_transcendental_type(TranscendentalCache::LOG); 9105 result->set_transcendental_type(TranscendentalCache::LOG);
9165 Drop(1); 9106 Drop(1);
9166 return ast_context()->ReturnInstruction(result, call->id()); 9107 return ast_context()->ReturnInstruction(result, call->id());
9167 } 9108 }
9168 9109
9169 9110
9170 void HOptimizedGraphBuilder::GenerateMathSqrt(CallRuntime* call) { 9111 void HOptimizedGraphBuilder::GenerateMathSqrt(CallRuntime* call) {
9171 ASSERT(call->arguments()->length() == 1); 9112 ASSERT(call->arguments()->length() == 1);
9172 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 9113 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
9173 HValue* value = Pop(); 9114 HValue* value = Pop();
9174 HValue* context = environment()->LookupContext(); 9115 HValue* context = environment()->context();
9175 HInstruction* result = 9116 HInstruction* result =
9176 HUnaryMathOperation::New(zone(), context, value, kMathSqrt); 9117 HUnaryMathOperation::New(zone(), context, value, kMathSqrt);
9177 return ast_context()->ReturnInstruction(result, call->id()); 9118 return ast_context()->ReturnInstruction(result, call->id());
9178 } 9119 }
9179 9120
9180 9121
9181 // Check whether two RegExps are equivalent 9122 // Check whether two RegExps are equivalent
9182 void HOptimizedGraphBuilder::GenerateIsRegExpEquivalent(CallRuntime* call) { 9123 void HOptimizedGraphBuilder::GenerateIsRegExpEquivalent(CallRuntime* call) {
9183 return Bailout("inlined runtime function: IsRegExpEquivalent"); 9124 return Bailout("inlined runtime function: IsRegExpEquivalent");
9184 } 9125 }
(...skipping 289 matching lines...) Expand 10 before | Expand all | Expand 10 after
9474 HValue* push = (i <= arguments) ? 9415 HValue* push = (i <= arguments) ?
9475 ExpressionStackAt(arguments - i) : undefined; 9416 ExpressionStackAt(arguments - i) : undefined;
9476 inner->SetValueAt(i, push); 9417 inner->SetValueAt(i, push);
9477 } 9418 }
9478 // If the function we are inlining is a strict mode function or a 9419 // If the function we are inlining is a strict mode function or a
9479 // builtin function, pass undefined as the receiver for function 9420 // builtin function, pass undefined as the receiver for function
9480 // calls (instead of the global receiver). 9421 // calls (instead of the global receiver).
9481 if (undefined_receiver) { 9422 if (undefined_receiver) {
9482 inner->SetValueAt(0, undefined); 9423 inner->SetValueAt(0, undefined);
9483 } 9424 }
9484 inner->SetValueAt(arity + 1, LookupContext()); 9425 inner->SetValueAt(arity + 1, context());
9485 for (int i = arity + 2; i < inner->length(); ++i) { 9426 for (int i = arity + 2; i < inner->length(); ++i) {
9486 inner->SetValueAt(i, undefined); 9427 inner->SetValueAt(i, undefined);
9487 } 9428 }
9488 9429
9489 inner->set_ast_id(BailoutId::FunctionEntry()); 9430 inner->set_ast_id(BailoutId::FunctionEntry());
9490 return inner; 9431 return inner;
9491 } 9432 }
9492 9433
9493 9434
9494 void HEnvironment::PrintTo(StringStream* stream) { 9435 void HEnvironment::PrintTo(StringStream* stream) {
(...skipping 329 matching lines...) Expand 10 before | Expand all | Expand 10 after
9824 if (ShouldProduceTraceOutput()) { 9765 if (ShouldProduceTraceOutput()) {
9825 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); 9766 isolate()->GetHTracer()->TraceHydrogen(name(), graph_);
9826 } 9767 }
9827 9768
9828 #ifdef DEBUG 9769 #ifdef DEBUG
9829 graph_->Verify(false); // No full verify. 9770 graph_->Verify(false); // No full verify.
9830 #endif 9771 #endif
9831 } 9772 }
9832 9773
9833 } } // namespace v8::internal 9774 } } // 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