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

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: 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
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 HConstant* constant = HConstant::New(zone(), NULL, value);
613 constant->InsertAfter(GetConstantUndefined()); 613 constant->InsertAfter(GetConstantUndefined());
614 pointer->set(constant); 614 pointer->set(constant);
615 } 615 }
616 return pointer->get(); 616 return pointer->get();
617 } 617 }
618 618
619 619
620 HConstant* HGraph::GetConstant0() { 620 HConstant* HGraph::GetConstant0() {
621 return GetConstant(&constant_0_, 0); 621 return GetConstant(&constant_0_, 0);
622 } 622 }
(...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after
828 deopt_else_ = true; 828 deopt_else_ = true;
829 } else { 829 } else {
830 deopt_then_ = true; 830 deopt_then_ = true;
831 } 831 }
832 builder_->Add<HDeoptimize>(Deoptimizer::EAGER); 832 builder_->Add<HDeoptimize>(Deoptimizer::EAGER);
833 } 833 }
834 834
835 835
836 void HGraphBuilder::IfBuilder::Return(HValue* value) { 836 void HGraphBuilder::IfBuilder::Return(HValue* value) {
837 HBasicBlock* block = builder_->current_block(); 837 HBasicBlock* block = builder_->current_block();
838 HValue* context = builder_->environment()->LookupContext();
839 HValue* parameter_count = builder_->graph()->GetConstantMinus1(); 838 HValue* parameter_count = builder_->graph()->GetConstantMinus1();
840 block->FinishExit(new(zone()) HReturn(value, context, parameter_count)); 839 block->FinishExit(builder_->NewAndCast<HReturn>(value,
840 parameter_count));
841 builder_->set_current_block(NULL); 841 builder_->set_current_block(NULL);
842 if (did_else_) { 842 if (did_else_) {
843 first_false_block_ = NULL; 843 first_false_block_ = NULL;
844 } else { 844 } else {
845 first_true_block_ = NULL; 845 first_true_block_ = NULL;
846 } 846 }
847 } 847 }
848 848
849 849
850 void HGraphBuilder::IfBuilder::End() { 850 void HGraphBuilder::IfBuilder::End() {
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
984 instr->SetFlag(HValue::kHasNoObservableSideEffects); 984 instr->SetFlag(HValue::kHasNoObservableSideEffects);
985 } 985 }
986 return instr; 986 return instr;
987 } 987 }
988 988
989 989
990 void HGraphBuilder::AddIncrementCounter(StatsCounter* counter, 990 void HGraphBuilder::AddIncrementCounter(StatsCounter* counter,
991 HValue* context) { 991 HValue* context) {
992 if (FLAG_native_code_counters && counter->Enabled()) { 992 if (FLAG_native_code_counters && counter->Enabled()) {
993 HValue* reference = Add<HConstant>(ExternalReference(counter)); 993 HValue* reference = Add<HConstant>(ExternalReference(counter));
994 HValue* old_value = AddLoad(reference, HObjectAccess::ForCounter(), NULL); 994 HValue* old_value = Add<HLoadNamedField>(reference,
995 HValue* new_value = AddInstruction( 995 HObjectAccess::ForCounter());
996 HAdd::New(zone(), context, old_value, graph()->GetConstant1())); 996 HValue* new_value = Add<HAdd>(old_value, graph()->GetConstant1());
997 new_value->ClearFlag(HValue::kCanOverflow); // Ignore counter overflow 997 new_value->ClearFlag(HValue::kCanOverflow); // Ignore counter overflow
998 AddStore(reference, HObjectAccess::ForCounter(), new_value); 998 Add<HStoreNamedField>(reference, HObjectAccess::ForCounter(),
999 new_value);
999 } 1000 }
1000 } 1001 }
1001 1002
1002 1003
1004 void HGraphBuilder::AddSimulate(BailoutId id,
1005 RemovableSimulate removable) {
1006 ASSERT(current_block() != NULL);
1007 ASSERT(no_side_effects_scope_count_ == 0);
1008 current_block()->AddSimulate(id, removable);
1009 }
1010
1011
1003 HBasicBlock* HGraphBuilder::CreateBasicBlock(HEnvironment* env) { 1012 HBasicBlock* HGraphBuilder::CreateBasicBlock(HEnvironment* env) {
1004 HBasicBlock* b = graph()->CreateBasicBlock(); 1013 HBasicBlock* b = graph()->CreateBasicBlock();
1005 b->SetInitialEnvironment(env); 1014 b->SetInitialEnvironment(env);
1006 return b; 1015 return b;
1007 } 1016 }
1008 1017
1009 1018
1010 HBasicBlock* HGraphBuilder::CreateLoopHeaderBlock() { 1019 HBasicBlock* HGraphBuilder::CreateLoopHeaderBlock() {
1011 HBasicBlock* header = graph()->CreateBasicBlock(); 1020 HBasicBlock* header = graph()->CreateBasicBlock();
1012 HEnvironment* entry_env = environment()->CopyAsLoopHeader(header); 1021 HEnvironment* entry_env = environment()->CopyAsLoopHeader(header);
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
1083 length_checker.Then(); 1092 length_checker.Then();
1084 1093
1085 HValue* current_capacity = AddLoadFixedArrayLength(elements); 1094 HValue* current_capacity = AddLoadFixedArrayLength(elements);
1086 1095
1087 IfBuilder capacity_checker(this); 1096 IfBuilder capacity_checker(this);
1088 1097
1089 capacity_checker.If<HCompareNumericAndBranch>(key, current_capacity, 1098 capacity_checker.If<HCompareNumericAndBranch>(key, current_capacity,
1090 Token::GTE); 1099 Token::GTE);
1091 capacity_checker.Then(); 1100 capacity_checker.Then();
1092 1101
1093 HValue* context = environment()->LookupContext(); 1102 HValue* context = environment()->context();
1094 1103
1095 HValue* max_gap = Add<HConstant>(static_cast<int32_t>(JSObject::kMaxGap)); 1104 HValue* max_gap = Add<HConstant>(static_cast<int32_t>(JSObject::kMaxGap));
1096 HValue* max_capacity = AddInstruction( 1105 HValue* max_capacity = Add<HAdd>(current_capacity, max_gap);
1097 HAdd::New(zone, context, current_capacity, max_gap));
1098 IfBuilder key_checker(this); 1106 IfBuilder key_checker(this);
1099 key_checker.If<HCompareNumericAndBranch>(key, max_capacity, Token::LT); 1107 key_checker.If<HCompareNumericAndBranch>(key, max_capacity, Token::LT);
1100 key_checker.Then(); 1108 key_checker.Then();
1101 key_checker.ElseDeopt(); 1109 key_checker.ElseDeopt();
1102 key_checker.End(); 1110 key_checker.End();
1103 1111
1104 HValue* new_capacity = BuildNewElementsCapacity(context, key); 1112 HValue* new_capacity = BuildNewElementsCapacity(key);
1105 HValue* new_elements = BuildGrowElementsCapacity(object, elements, 1113 HValue* new_elements = BuildGrowElementsCapacity(object, elements,
1106 kind, kind, length, 1114 kind, kind, length,
1107 new_capacity); 1115 new_capacity);
1108 1116
1109 environment()->Push(new_elements); 1117 environment()->Push(new_elements);
1110 capacity_checker.Else(); 1118 capacity_checker.Else();
1111 1119
1112 environment()->Push(elements); 1120 environment()->Push(elements);
1113 capacity_checker.End(); 1121 capacity_checker.End();
1114 1122
1115 if (is_js_array) { 1123 if (is_js_array) {
1116 HValue* new_length = AddInstruction( 1124 HValue* new_length = AddInstruction(
1117 HAdd::New(zone, context, key, graph_->GetConstant1())); 1125 HAdd::New(zone, context, key, graph_->GetConstant1()));
1118 new_length->ClearFlag(HValue::kCanOverflow); 1126 new_length->ClearFlag(HValue::kCanOverflow);
1119 1127
1120 AddStore(object, HObjectAccess::ForArrayLength(kind), new_length); 1128 Add<HStoreNamedField>(object, HObjectAccess::ForArrayLength(kind),
1129 new_length);
1121 } 1130 }
1122 1131
1123 length_checker.Else(); 1132 length_checker.Else();
1124 Add<HBoundsCheck>(key, length); 1133 Add<HBoundsCheck>(key, length);
1125 1134
1126 environment()->Push(elements); 1135 environment()->Push(elements);
1127 length_checker.End(); 1136 length_checker.End();
1128 1137
1129 return environment()->Pop(); 1138 return environment()->Pop();
1130 } 1139 }
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
1167 IsFastHoleyElementsKind(to_kind)); 1176 IsFastHoleyElementsKind(to_kind));
1168 1177
1169 if (AllocationSite::GetMode(from_kind, to_kind) == TRACK_ALLOCATION_SITE) { 1178 if (AllocationSite::GetMode(from_kind, to_kind) == TRACK_ALLOCATION_SITE) {
1170 Add<HTrapAllocationMemento>(object); 1179 Add<HTrapAllocationMemento>(object);
1171 } 1180 }
1172 1181
1173 if (!IsSimpleMapChangeTransition(from_kind, to_kind)) { 1182 if (!IsSimpleMapChangeTransition(from_kind, to_kind)) {
1174 HInstruction* elements = AddLoadElements(object); 1183 HInstruction* elements = AddLoadElements(object);
1175 1184
1176 HInstruction* empty_fixed_array = Add<HConstant>( 1185 HInstruction* empty_fixed_array = Add<HConstant>(
1177 isolate()->factory()->empty_fixed_array(), Representation::Tagged()); 1186 isolate()->factory()->empty_fixed_array());
1178 1187
1179 IfBuilder if_builder(this); 1188 IfBuilder if_builder(this);
1180 1189
1181 if_builder.IfNot<HCompareObjectEqAndBranch>(elements, empty_fixed_array); 1190 if_builder.IfNot<HCompareObjectEqAndBranch>(elements, empty_fixed_array);
1182 1191
1183 if_builder.Then(); 1192 if_builder.Then();
1184 1193
1185 HInstruction* elements_length = AddLoadFixedArrayLength(elements); 1194 HInstruction* elements_length = AddLoadFixedArrayLength(elements);
1186 1195
1187 HInstruction* array_length = is_jsarray 1196 HInstruction* array_length = is_jsarray
1188 ? AddLoad(object, HObjectAccess::ForArrayLength(from_kind), NULL) 1197 ? Add<HLoadNamedField>(object, HObjectAccess::ForArrayLength(from_kind))
1189 : elements_length; 1198 : elements_length;
1190 1199
1191 BuildGrowElementsCapacity(object, elements, from_kind, to_kind, 1200 BuildGrowElementsCapacity(object, elements, from_kind, to_kind,
1192 array_length, elements_length); 1201 array_length, elements_length);
1193 1202
1194 if_builder.End(); 1203 if_builder.End();
1195 } 1204 }
1196 1205
1197 AddStore(object, HObjectAccess::ForMap(), map); 1206 Add<HStoreNamedField>(object, HObjectAccess::ForMap(), map);
1198 } 1207 }
1199 1208
1200 1209
1201 HInstruction* HGraphBuilder::BuildUncheckedMonomorphicElementAccess( 1210 HInstruction* HGraphBuilder::BuildUncheckedMonomorphicElementAccess(
1202 HValue* object, 1211 HValue* object,
1203 HValue* key, 1212 HValue* key,
1204 HValue* val, 1213 HValue* val,
1205 HCheckMaps* mapcheck, 1214 HCheckMaps* mapcheck,
1206 bool is_js_array, 1215 bool is_js_array,
1207 ElementsKind elements_kind, 1216 ElementsKind elements_kind,
(...skipping 19 matching lines...) Expand all
1227 HValue* elements = AddLoadElements(object, mapcheck); 1236 HValue* elements = AddLoadElements(object, mapcheck);
1228 if (is_store && (fast_elements || fast_smi_only_elements) && 1237 if (is_store && (fast_elements || fast_smi_only_elements) &&
1229 store_mode != STORE_NO_TRANSITION_HANDLE_COW) { 1238 store_mode != STORE_NO_TRANSITION_HANDLE_COW) {
1230 HCheckMaps* check_cow_map = HCheckMaps::New( 1239 HCheckMaps* check_cow_map = HCheckMaps::New(
1231 elements, isolate()->factory()->fixed_array_map(), zone, top_info()); 1240 elements, isolate()->factory()->fixed_array_map(), zone, top_info());
1232 check_cow_map->ClearGVNFlag(kDependsOnElementsKind); 1241 check_cow_map->ClearGVNFlag(kDependsOnElementsKind);
1233 AddInstruction(check_cow_map); 1242 AddInstruction(check_cow_map);
1234 } 1243 }
1235 HInstruction* length = NULL; 1244 HInstruction* length = NULL;
1236 if (is_js_array) { 1245 if (is_js_array) {
1237 length = AddLoad(object, HObjectAccess::ForArrayLength(elements_kind), 1246 length = Add<HLoadNamedField>(object,
1238 mapcheck); 1247 HObjectAccess::ForArrayLength(elements_kind), mapcheck);
1239 } else { 1248 } else {
1240 length = AddLoadFixedArrayLength(elements); 1249 length = AddLoadFixedArrayLength(elements);
1241 } 1250 }
1242 length->set_type(HType::Smi()); 1251 length->set_type(HType::Smi());
1243 HValue* checked_key = NULL; 1252 HValue* checked_key = NULL;
1244 if (IsExternalArrayElementsKind(elements_kind)) { 1253 if (IsExternalArrayElementsKind(elements_kind)) {
1245 if (store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS) { 1254 if (store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS) {
1246 NoObservableSideEffectsScope no_effects(this); 1255 NoObservableSideEffectsScope no_effects(this);
1247 HLoadExternalArrayPointer* external_elements = 1256 HLoadExternalArrayPointer* external_elements =
1248 Add<HLoadExternalArrayPointer>(elements); 1257 AddAndCast<HLoadExternalArrayPointer>(elements);
1249 IfBuilder length_checker(this); 1258 IfBuilder length_checker(this);
1250 length_checker.If<HCompareNumericAndBranch>(key, length, Token::LT); 1259 length_checker.If<HCompareNumericAndBranch>(key, length, Token::LT);
1251 length_checker.Then(); 1260 length_checker.Then();
1252 IfBuilder negative_checker(this); 1261 IfBuilder negative_checker(this);
1253 HValue* bounds_check = negative_checker.If<HCompareNumericAndBranch>( 1262 HValue* bounds_check = negative_checker.If<HCompareNumericAndBranch>(
1254 key, graph()->GetConstant0(), Token::GTE); 1263 key, graph()->GetConstant0(), Token::GTE);
1255 negative_checker.Then(); 1264 negative_checker.Then();
1256 HInstruction* result = AddExternalArrayElementAccess( 1265 HInstruction* result = AddExternalArrayElementAccess(
1257 external_elements, key, val, bounds_check, elements_kind, is_store); 1266 external_elements, key, val, bounds_check, elements_kind, is_store);
1258 negative_checker.ElseDeopt(); 1267 negative_checker.ElseDeopt();
1259 length_checker.End(); 1268 length_checker.End();
1260 return result; 1269 return result;
1261 } else { 1270 } else {
1262 ASSERT(store_mode == STANDARD_STORE); 1271 ASSERT(store_mode == STANDARD_STORE);
1263 checked_key = Add<HBoundsCheck>(key, length); 1272 checked_key = Add<HBoundsCheck>(key, length);
1264 HLoadExternalArrayPointer* external_elements = 1273 HLoadExternalArrayPointer* external_elements =
1265 Add<HLoadExternalArrayPointer>(elements); 1274 AddAndCast<HLoadExternalArrayPointer>(elements);
1266 return AddExternalArrayElementAccess( 1275 return AddExternalArrayElementAccess(
1267 external_elements, checked_key, val, 1276 external_elements, checked_key, val,
1268 mapcheck, elements_kind, is_store); 1277 mapcheck, elements_kind, is_store);
1269 } 1278 }
1270 } 1279 }
1271 ASSERT(fast_smi_only_elements || 1280 ASSERT(fast_smi_only_elements ||
1272 fast_elements || 1281 fast_elements ||
1273 IsFastDoubleElementsKind(elements_kind)); 1282 IsFastDoubleElementsKind(elements_kind));
1274 1283
1275 // In case val is stored into a fast smi array, assure that the value is a smi 1284 // In case val is stored into a fast smi array, assure that the value is a smi
(...skipping 25 matching lines...) Expand all
1301 check_cow_map->ClearGVNFlag(kDependsOnElementsKind); 1310 check_cow_map->ClearGVNFlag(kDependsOnElementsKind);
1302 AddInstruction(check_cow_map); 1311 AddInstruction(check_cow_map);
1303 } 1312 }
1304 } 1313 }
1305 } 1314 }
1306 return AddFastElementAccess(elements, checked_key, val, mapcheck, 1315 return AddFastElementAccess(elements, checked_key, val, mapcheck,
1307 elements_kind, is_store, load_mode, store_mode); 1316 elements_kind, is_store, load_mode, store_mode);
1308 } 1317 }
1309 1318
1310 1319
1311 HValue* HGraphBuilder::BuildAllocateElements(HValue* context, 1320 HValue* HGraphBuilder::BuildAllocateElements(ElementsKind kind,
1312 ElementsKind kind,
1313 HValue* capacity) { 1321 HValue* capacity) {
1314 Zone* zone = this->zone();
1315
1316 int elements_size = IsFastDoubleElementsKind(kind) 1322 int elements_size = IsFastDoubleElementsKind(kind)
1317 ? kDoubleSize : kPointerSize; 1323 ? kDoubleSize : kPointerSize;
1318 HConstant* elements_size_value = Add<HConstant>(elements_size); 1324 HConstant* elements_size_value = AddAndCast<HConstant>(elements_size);
1319 HValue* mul = AddInstruction( 1325 HValue* mul = Add<HMul>(capacity, elements_size_value);
1320 HMul::New(zone, context, capacity, elements_size_value));
1321 mul->ClearFlag(HValue::kCanOverflow); 1326 mul->ClearFlag(HValue::kCanOverflow);
1322 1327
1323 HConstant* header_size = Add<HConstant>(FixedArray::kHeaderSize); 1328 HConstant* header_size = AddAndCast<HConstant>(FixedArray::kHeaderSize);
1324 HValue* total_size = AddInstruction( 1329 HValue* total_size = Add<HAdd>(mul, header_size);
1325 HAdd::New(zone, context, mul, header_size));
1326 total_size->ClearFlag(HValue::kCanOverflow); 1330 total_size->ClearFlag(HValue::kCanOverflow);
1327 1331
1328 HAllocate::Flags flags = HAllocate::DefaultFlags(kind); 1332 HAllocate::Flags flags = HAllocate::DefaultFlags(kind);
1329 if (isolate()->heap()->ShouldGloballyPretenure()) { 1333 if (isolate()->heap()->ShouldGloballyPretenure()) {
1330 // TODO(hpayer): When pretenuring can be internalized, flags can become 1334 // TODO(hpayer): When pretenuring can be internalized, flags can become
1331 // private to HAllocate. 1335 // private to HAllocate.
1332 if (IsFastDoubleElementsKind(kind)) { 1336 if (IsFastDoubleElementsKind(kind)) {
1333 flags = static_cast<HAllocate::Flags>( 1337 flags = static_cast<HAllocate::Flags>(
1334 flags | HAllocate::CAN_ALLOCATE_IN_OLD_DATA_SPACE); 1338 flags | HAllocate::CAN_ALLOCATE_IN_OLD_DATA_SPACE);
1335 } else { 1339 } else {
1336 flags = static_cast<HAllocate::Flags>( 1340 flags = static_cast<HAllocate::Flags>(
1337 flags | HAllocate::CAN_ALLOCATE_IN_OLD_POINTER_SPACE); 1341 flags | HAllocate::CAN_ALLOCATE_IN_OLD_POINTER_SPACE);
1338 } 1342 }
1339 } 1343 }
1340 1344
1341 return Add<HAllocate>(context, total_size, HType::JSArray(), flags); 1345 return Add<HAllocate>(total_size, HType::JSArray(), flags);
1342 } 1346 }
1343 1347
1344 1348
1345 void HGraphBuilder::BuildInitializeElementsHeader(HValue* elements, 1349 void HGraphBuilder::BuildInitializeElementsHeader(HValue* elements,
1346 ElementsKind kind, 1350 ElementsKind kind,
1347 HValue* capacity) { 1351 HValue* capacity) {
1348 Factory* factory = isolate()->factory(); 1352 Factory* factory = isolate()->factory();
1349 Handle<Map> map = IsFastDoubleElementsKind(kind) 1353 Handle<Map> map = IsFastDoubleElementsKind(kind)
1350 ? factory->fixed_double_array_map() 1354 ? factory->fixed_double_array_map()
1351 : factory->fixed_array_map(); 1355 : factory->fixed_array_map();
1352 1356
1353 AddStoreMapConstant(elements, map); 1357 AddStoreMapConstant(elements, map);
1354 AddStore(elements, HObjectAccess::ForFixedArrayLength(), capacity); 1358 Add<HStoreNamedField>(elements, HObjectAccess::ForFixedArrayLength(),
1359 capacity);
1355 } 1360 }
1356 1361
1357 1362
1358 HValue* HGraphBuilder::BuildAllocateElementsAndInitializeElementsHeader( 1363 HValue* HGraphBuilder::BuildAllocateElementsAndInitializeElementsHeader(
1359 HValue* context,
1360 ElementsKind kind, 1364 ElementsKind kind,
1361 HValue* capacity) { 1365 HValue* capacity) {
1362 // The HForceRepresentation is to prevent possible deopt on int-smi 1366 // The HForceRepresentation is to prevent possible deopt on int-smi
1363 // conversion after allocation but before the new object fields are set. 1367 // conversion after allocation but before the new object fields are set.
1364 capacity = Add<HForceRepresentation>(capacity, Representation::Smi()); 1368 capacity = Add<HForceRepresentation>(capacity, Representation::Smi());
1365 HValue* new_elements = BuildAllocateElements(context, kind, capacity); 1369 HValue* new_elements = BuildAllocateElements(kind, capacity);
1366 BuildInitializeElementsHeader(new_elements, kind, capacity); 1370 BuildInitializeElementsHeader(new_elements, kind, capacity);
1367 return new_elements; 1371 return new_elements;
1368 } 1372 }
1369 1373
1370 1374
1371 HInnerAllocatedObject* HGraphBuilder::BuildJSArrayHeader(HValue* array, 1375 HInnerAllocatedObject* HGraphBuilder::BuildJSArrayHeader(HValue* array,
1372 HValue* array_map, 1376 HValue* array_map,
1373 AllocationSiteMode mode, 1377 AllocationSiteMode mode,
1374 ElementsKind elements_kind, 1378 ElementsKind elements_kind,
1375 HValue* allocation_site_payload, 1379 HValue* allocation_site_payload,
1376 HValue* length_field) { 1380 HValue* length_field) {
1377 1381
1378 AddStore(array, HObjectAccess::ForMap(), array_map); 1382 Add<HStoreNamedField>(array, HObjectAccess::ForMap(), array_map);
1379 1383
1380 HConstant* empty_fixed_array = 1384 HConstant* empty_fixed_array =
1381 Add<HConstant>(isolate()->factory()->empty_fixed_array()); 1385 AddAndCast<HConstant>(isolate()->factory()->empty_fixed_array());
1382 1386
1383 HObjectAccess access = HObjectAccess::ForPropertiesPointer(); 1387 HObjectAccess access = HObjectAccess::ForPropertiesPointer();
1384 AddStore(array, access, empty_fixed_array); 1388 Add<HStoreNamedField>(array, access, empty_fixed_array);
1385 AddStore(array, HObjectAccess::ForArrayLength(elements_kind), length_field); 1389 Add<HStoreNamedField>(array, HObjectAccess::ForArrayLength(elements_kind),
1390 length_field);
1386 1391
1387 if (mode == TRACK_ALLOCATION_SITE) { 1392 if (mode == TRACK_ALLOCATION_SITE) {
1388 BuildCreateAllocationMemento(array, 1393 BuildCreateAllocationMemento(array,
1389 JSArray::kSize, 1394 JSArray::kSize,
1390 allocation_site_payload); 1395 allocation_site_payload);
1391 } 1396 }
1392 1397
1393 int elements_location = JSArray::kSize; 1398 int elements_location = JSArray::kSize;
1394 if (mode == TRACK_ALLOCATION_SITE) { 1399 if (mode == TRACK_ALLOCATION_SITE) {
1395 elements_location += AllocationMemento::kSize; 1400 elements_location += AllocationMemento::kSize;
1396 } 1401 }
1397 1402
1398 HInnerAllocatedObject* elements = 1403 HValue* elements =
1399 Add<HInnerAllocatedObject>(array, elements_location); 1404 Add<HInnerAllocatedObject>(array, elements_location);
1400 AddStore(array, HObjectAccess::ForElementsPointer(), elements); 1405 Add<HStoreNamedField>(array, HObjectAccess::ForElementsPointer(), elements);
1401 return elements; 1406 return static_cast<HInnerAllocatedObject*>(elements);
1402 } 1407 }
1403 1408
1404 1409
1405 HInstruction* HGraphBuilder::AddExternalArrayElementAccess( 1410 HInstruction* HGraphBuilder::AddExternalArrayElementAccess(
1406 HValue* external_elements, 1411 HValue* external_elements,
1407 HValue* checked_key, 1412 HValue* checked_key,
1408 HValue* val, 1413 HValue* val,
1409 HValue* dependency, 1414 HValue* dependency,
1410 ElementsKind elements_kind, 1415 ElementsKind elements_kind,
1411 bool is_store) { 1416 bool is_store) {
(...skipping 22 matching lines...) Expand all
1434 case FAST_HOLEY_ELEMENTS: 1439 case FAST_HOLEY_ELEMENTS:
1435 case FAST_HOLEY_DOUBLE_ELEMENTS: 1440 case FAST_HOLEY_DOUBLE_ELEMENTS:
1436 case DICTIONARY_ELEMENTS: 1441 case DICTIONARY_ELEMENTS:
1437 case NON_STRICT_ARGUMENTS_ELEMENTS: 1442 case NON_STRICT_ARGUMENTS_ELEMENTS:
1438 UNREACHABLE(); 1443 UNREACHABLE();
1439 break; 1444 break;
1440 } 1445 }
1441 return Add<HStoreKeyed>(external_elements, checked_key, val, elements_kind); 1446 return Add<HStoreKeyed>(external_elements, checked_key, val, elements_kind);
1442 } else { 1447 } else {
1443 ASSERT(val == NULL); 1448 ASSERT(val == NULL);
1444 HLoadKeyed* load = Add<HLoadKeyed>(external_elements, checked_key, 1449 HLoadKeyed* load = HLoadKeyed::cast(Add<HLoadKeyed>(external_elements,
1445 dependency, elements_kind); 1450 checked_key,
1451 dependency,
1452 elements_kind));
1446 if (FLAG_opt_safe_uint32_operations && 1453 if (FLAG_opt_safe_uint32_operations &&
1447 elements_kind == EXTERNAL_UNSIGNED_INT_ELEMENTS) { 1454 elements_kind == EXTERNAL_UNSIGNED_INT_ELEMENTS) {
1448 graph()->RecordUint32Instruction(load); 1455 graph()->RecordUint32Instruction(load);
1449 } 1456 }
1450 return load; 1457 return load;
1451 } 1458 }
1452 } 1459 }
1453 1460
1454 1461
1455 HInstruction* HGraphBuilder::AddFastElementAccess( 1462 HInstruction* HGraphBuilder::AddFastElementAccess(
(...skipping 21 matching lines...) Expand all
1477 } 1484 }
1478 } 1485 }
1479 // It's an element load (!is_store). 1486 // It's an element load (!is_store).
1480 return Add<HLoadKeyed>( 1487 return Add<HLoadKeyed>(
1481 elements, checked_key, load_dependency, elements_kind, load_mode); 1488 elements, checked_key, load_dependency, elements_kind, load_mode);
1482 } 1489 }
1483 1490
1484 1491
1485 HLoadNamedField* HGraphBuilder::AddLoadElements(HValue* object, 1492 HLoadNamedField* HGraphBuilder::AddLoadElements(HValue* object,
1486 HValue* typecheck) { 1493 HValue* typecheck) {
1487 return AddLoad(object, HObjectAccess::ForElementsPointer(), typecheck); 1494 return AddAndCast<HLoadNamedField>(object,
1495 HObjectAccess::ForElementsPointer(),
1496 typecheck);
1488 } 1497 }
1489 1498
1490 1499
1491 HLoadNamedField* HGraphBuilder::AddLoadFixedArrayLength(HValue* object) { 1500 HLoadNamedField* HGraphBuilder::AddLoadFixedArrayLength(HValue* object) {
1492 return AddLoad(object, HObjectAccess::ForFixedArrayLength()); 1501 return AddAndCast<HLoadNamedField>(object,
1502 HObjectAccess::ForFixedArrayLength());
1493 } 1503 }
1494 1504
1495 1505
1496 HValue* HGraphBuilder::BuildNewElementsCapacity(HValue* context, 1506 HValue* HGraphBuilder::BuildNewElementsCapacity(HValue* old_capacity) {
1497 HValue* old_capacity) { 1507 HValue* half_old_capacity = Add<HShr>(old_capacity, graph_->GetConstant1());
1498 Zone* zone = this->zone();
1499 HValue* half_old_capacity =
1500 AddInstruction(HShr::New(zone, context, old_capacity,
1501 graph_->GetConstant1()));
1502 1508
1503 HValue* new_capacity = AddInstruction( 1509 HValue* new_capacity = Add<HAdd>(half_old_capacity, old_capacity);
1504 HAdd::New(zone, context, half_old_capacity, old_capacity));
1505 new_capacity->ClearFlag(HValue::kCanOverflow); 1510 new_capacity->ClearFlag(HValue::kCanOverflow);
1506 1511
1507 HValue* min_growth = Add<HConstant>(16); 1512 HValue* min_growth = Add<HConstant>(16);
1508 1513
1509 new_capacity = AddInstruction( 1514 new_capacity = Add<HAdd>(new_capacity, min_growth);
1510 HAdd::New(zone, context, new_capacity, min_growth));
1511 new_capacity->ClearFlag(HValue::kCanOverflow); 1515 new_capacity->ClearFlag(HValue::kCanOverflow);
1512 1516
1513 return new_capacity; 1517 return new_capacity;
1514 } 1518 }
1515 1519
1516 1520
1517 void HGraphBuilder::BuildNewSpaceArrayCheck(HValue* length, ElementsKind kind) { 1521 void HGraphBuilder::BuildNewSpaceArrayCheck(HValue* length, ElementsKind kind) {
1518 Heap* heap = isolate()->heap(); 1522 Heap* heap = isolate()->heap();
1519 int element_size = IsFastDoubleElementsKind(kind) ? kDoubleSize 1523 int element_size = IsFastDoubleElementsKind(kind) ? kDoubleSize
1520 : kPointerSize; 1524 : kPointerSize;
1521 int max_size = heap->MaxRegularSpaceAllocationSize() / element_size; 1525 int max_size = heap->MaxRegularSpaceAllocationSize() / element_size;
1522 max_size -= JSArray::kSize / element_size; 1526 max_size -= JSArray::kSize / element_size;
1523 HConstant* max_size_constant = Add<HConstant>(max_size); 1527 HConstant* max_size_constant = AddAndCast<HConstant>(max_size);
1524 Add<HBoundsCheck>(length, max_size_constant); 1528 Add<HBoundsCheck>(length, max_size_constant);
1525 } 1529 }
1526 1530
1527 1531
1528 HValue* HGraphBuilder::BuildGrowElementsCapacity(HValue* object, 1532 HValue* HGraphBuilder::BuildGrowElementsCapacity(HValue* object,
1529 HValue* elements, 1533 HValue* elements,
1530 ElementsKind kind, 1534 ElementsKind kind,
1531 ElementsKind new_kind, 1535 ElementsKind new_kind,
1532 HValue* length, 1536 HValue* length,
1533 HValue* new_capacity) { 1537 HValue* new_capacity) {
1534 HValue* context = environment()->LookupContext();
1535
1536 BuildNewSpaceArrayCheck(new_capacity, new_kind); 1538 BuildNewSpaceArrayCheck(new_capacity, new_kind);
1537 1539
1538 HValue* new_elements = BuildAllocateElementsAndInitializeElementsHeader( 1540 HValue* new_elements = BuildAllocateElementsAndInitializeElementsHeader(
1539 context, new_kind, new_capacity); 1541 new_kind, new_capacity);
1540 1542
1541 BuildCopyElements(context, elements, kind, 1543 BuildCopyElements(elements, kind,
1542 new_elements, new_kind, 1544 new_elements, new_kind,
1543 length, new_capacity); 1545 length, new_capacity);
1544 1546
1545 AddStore(object, HObjectAccess::ForElementsPointer(), new_elements); 1547 Add<HStoreNamedField>(object, HObjectAccess::ForElementsPointer(),
1548 new_elements);
1546 1549
1547 return new_elements; 1550 return new_elements;
1548 } 1551 }
1549 1552
1550 1553
1551 void HGraphBuilder::BuildFillElementsWithHole(HValue* context, 1554 void HGraphBuilder::BuildFillElementsWithHole(HValue* elements,
1552 HValue* elements,
1553 ElementsKind elements_kind, 1555 ElementsKind elements_kind,
1554 HValue* from, 1556 HValue* from,
1555 HValue* to) { 1557 HValue* to) {
1556 // Fast elements kinds need to be initialized in case statements below cause 1558 // Fast elements kinds need to be initialized in case statements below cause
1557 // a garbage collection. 1559 // a garbage collection.
1558 Factory* factory = isolate()->factory(); 1560 Factory* factory = isolate()->factory();
1559 1561
1560 double nan_double = FixedDoubleArray::hole_nan_as_double(); 1562 double nan_double = FixedDoubleArray::hole_nan_as_double();
1561 HValue* hole = IsFastSmiOrObjectElementsKind(elements_kind) 1563 HValue* hole = IsFastSmiOrObjectElementsKind(elements_kind)
1562 ? Add<HConstant>(factory->the_hole_value()) 1564 ? Add<HConstant>(factory->the_hole_value())
(...skipping 21 matching lines...) Expand all
1584 if (IsFastSmiOrObjectElementsKind(elements_kind)) { 1586 if (IsFastSmiOrObjectElementsKind(elements_kind)) {
1585 elements_kind = FAST_HOLEY_ELEMENTS; 1587 elements_kind = FAST_HOLEY_ELEMENTS;
1586 } 1588 }
1587 1589
1588 if (unfold_loop) { 1590 if (unfold_loop) {
1589 for (int i = 0; i < initial_capacity; i++) { 1591 for (int i = 0; i < initial_capacity; i++) {
1590 HInstruction* key = Add<HConstant>(i); 1592 HInstruction* key = Add<HConstant>(i);
1591 Add<HStoreKeyed>(elements, key, hole, elements_kind); 1593 Add<HStoreKeyed>(elements, key, hole, elements_kind);
1592 } 1594 }
1593 } else { 1595 } else {
1594 LoopBuilder builder(this, context, LoopBuilder::kPostIncrement); 1596 LoopBuilder builder(this, context(), LoopBuilder::kPostIncrement);
1595 1597
1596 HValue* key = builder.BeginBody(from, to, Token::LT); 1598 HValue* key = builder.BeginBody(from, to, Token::LT);
1597 1599
1598 Add<HStoreKeyed>(elements, key, hole, elements_kind); 1600 Add<HStoreKeyed>(elements, key, hole, elements_kind);
1599 1601
1600 builder.EndBody(); 1602 builder.EndBody();
1601 } 1603 }
1602 } 1604 }
1603 1605
1604 1606
1605 void HGraphBuilder::BuildCopyElements(HValue* context, 1607 void HGraphBuilder::BuildCopyElements(HValue* from_elements,
1606 HValue* from_elements,
1607 ElementsKind from_elements_kind, 1608 ElementsKind from_elements_kind,
1608 HValue* to_elements, 1609 HValue* to_elements,
1609 ElementsKind to_elements_kind, 1610 ElementsKind to_elements_kind,
1610 HValue* length, 1611 HValue* length,
1611 HValue* capacity) { 1612 HValue* capacity) {
1612 bool pre_fill_with_holes = 1613 bool pre_fill_with_holes =
1613 IsFastDoubleElementsKind(from_elements_kind) && 1614 IsFastDoubleElementsKind(from_elements_kind) &&
1614 IsFastObjectElementsKind(to_elements_kind); 1615 IsFastObjectElementsKind(to_elements_kind);
1615 1616
1616 if (pre_fill_with_holes) { 1617 if (pre_fill_with_holes) {
1617 // If the copy might trigger a GC, make sure that the FixedArray is 1618 // If the copy might trigger a GC, make sure that the FixedArray is
1618 // pre-initialized with holes to make sure that it's always in a consistent 1619 // pre-initialized with holes to make sure that it's always in a consistent
1619 // state. 1620 // state.
1620 BuildFillElementsWithHole(context, to_elements, to_elements_kind, 1621 BuildFillElementsWithHole(to_elements, to_elements_kind,
1621 graph()->GetConstant0(), capacity); 1622 graph()->GetConstant0(), capacity);
1622 } 1623 }
1623 1624
1624 LoopBuilder builder(this, context, LoopBuilder::kPostIncrement); 1625 LoopBuilder builder(this, context(), LoopBuilder::kPostIncrement);
1625 1626
1626 HValue* key = builder.BeginBody(graph()->GetConstant0(), length, Token::LT); 1627 HValue* key = builder.BeginBody(graph()->GetConstant0(), length, Token::LT);
1627 1628
1628 HValue* element = Add<HLoadKeyed>(from_elements, key, 1629 HValue* element = Add<HLoadKeyed>(from_elements, key,
1629 static_cast<HValue*>(NULL), 1630 static_cast<HValue*>(NULL),
1630 from_elements_kind, 1631 from_elements_kind,
1631 ALLOW_RETURN_HOLE); 1632 ALLOW_RETURN_HOLE);
1632 1633
1633 ElementsKind holey_kind = IsFastSmiElementsKind(to_elements_kind) 1634 ElementsKind holey_kind = IsFastSmiElementsKind(to_elements_kind)
1634 ? FAST_HOLEY_ELEMENTS : to_elements_kind; 1635 ? FAST_HOLEY_ELEMENTS : to_elements_kind;
1635 HInstruction* holey_store = Add<HStoreKeyed>(to_elements, key, 1636 HInstruction* holey_store = Add<HStoreKeyed>(to_elements, key,
1636 element, holey_kind); 1637 element, holey_kind);
1637 // Allow NaN hole values to converted to their tagged counterparts. 1638 // Allow NaN hole values to converted to their tagged counterparts.
1638 if (IsFastHoleyElementsKind(to_elements_kind)) { 1639 if (IsFastHoleyElementsKind(to_elements_kind)) {
1639 holey_store->SetFlag(HValue::kAllowUndefinedAsNaN); 1640 holey_store->SetFlag(HValue::kAllowUndefinedAsNaN);
1640 } 1641 }
1641 1642
1642 builder.EndBody(); 1643 builder.EndBody();
1643 1644
1644 if (!pre_fill_with_holes && length != capacity) { 1645 if (!pre_fill_with_holes && length != capacity) {
1645 // Fill unused capacity with the hole. 1646 // Fill unused capacity with the hole.
1646 BuildFillElementsWithHole(context, to_elements, to_elements_kind, 1647 BuildFillElementsWithHole(to_elements, to_elements_kind,
1647 key, capacity); 1648 key, capacity);
1648 } 1649 }
1649 } 1650 }
1650 1651
1651 1652
1652 HValue* HGraphBuilder::BuildCloneShallowArray(HContext* context, 1653 HValue* HGraphBuilder::BuildCloneShallowArray(HValue* boilerplate,
1653 HValue* boilerplate,
1654 HValue* allocation_site, 1654 HValue* allocation_site,
1655 AllocationSiteMode mode, 1655 AllocationSiteMode mode,
1656 ElementsKind kind, 1656 ElementsKind kind,
1657 int length) { 1657 int length) {
1658 NoObservableSideEffectsScope no_effects(this); 1658 NoObservableSideEffectsScope no_effects(this);
1659 1659
1660 // All sizes here are multiples of kPointerSize. 1660 // All sizes here are multiples of kPointerSize.
1661 int size = JSArray::kSize; 1661 int size = JSArray::kSize;
1662 if (mode == TRACK_ALLOCATION_SITE) { 1662 if (mode == TRACK_ALLOCATION_SITE) {
1663 size += AllocationMemento::kSize; 1663 size += AllocationMemento::kSize;
1664 } 1664 }
1665 int elems_offset = size; 1665 int elems_offset = size;
1666 if (length > 0) { 1666 if (length > 0) {
1667 size += IsFastDoubleElementsKind(kind) 1667 size += IsFastDoubleElementsKind(kind)
1668 ? FixedDoubleArray::SizeFor(length) 1668 ? FixedDoubleArray::SizeFor(length)
1669 : FixedArray::SizeFor(length); 1669 : FixedArray::SizeFor(length);
1670 } 1670 }
1671 1671
1672 HAllocate::Flags allocate_flags = HAllocate::DefaultFlags(kind); 1672 HAllocate::Flags allocate_flags = HAllocate::DefaultFlags(kind);
1673 // Allocate both the JS array and the elements array in one big 1673 // Allocate both the JS array and the elements array in one big
1674 // allocation. This avoids multiple limit checks. 1674 // allocation. This avoids multiple limit checks.
1675 HValue* size_in_bytes = Add<HConstant>(size); 1675 HValue* size_in_bytes = Add<HConstant>(size);
1676 HInstruction* object = Add<HAllocate>(context, 1676 HInstruction* object = Add<HAllocate>(size_in_bytes,
1677 size_in_bytes,
1678 HType::JSObject(), 1677 HType::JSObject(),
1679 allocate_flags); 1678 allocate_flags);
1680 1679
1681 // Copy the JS array part. 1680 // Copy the JS array part.
1682 for (int i = 0; i < JSArray::kSize; i += kPointerSize) { 1681 for (int i = 0; i < JSArray::kSize; i += kPointerSize) {
1683 if ((i != JSArray::kElementsOffset) || (length == 0)) { 1682 if ((i != JSArray::kElementsOffset) || (length == 0)) {
1684 HObjectAccess access = HObjectAccess::ForJSArrayOffset(i); 1683 HObjectAccess access = HObjectAccess::ForJSArrayOffset(i);
1685 AddStore(object, access, AddLoad(boilerplate, access)); 1684 Add<HStoreNamedField>(object, access,
1685 Add<HLoadNamedField>(boilerplate, access));
1686 } 1686 }
1687 } 1687 }
1688 1688
1689 // Create an allocation site info if requested. 1689 // Create an allocation site info if requested.
1690 if (mode == TRACK_ALLOCATION_SITE) { 1690 if (mode == TRACK_ALLOCATION_SITE) {
1691 BuildCreateAllocationMemento(object, JSArray::kSize, allocation_site); 1691 BuildCreateAllocationMemento(object, JSArray::kSize, allocation_site);
1692 } 1692 }
1693 1693
1694 if (length > 0) { 1694 if (length > 0) {
1695 // Get hold of the elements array of the boilerplate and setup the 1695 // Get hold of the elements array of the boilerplate and setup the
1696 // elements pointer in the resulting object. 1696 // elements pointer in the resulting object.
1697 HValue* boilerplate_elements = AddLoadElements(boilerplate); 1697 HValue* boilerplate_elements = AddLoadElements(boilerplate);
1698 HValue* object_elements = Add<HInnerAllocatedObject>(object, elems_offset); 1698 HValue* object_elements = Add<HInnerAllocatedObject>(object, elems_offset);
1699 AddStore(object, HObjectAccess::ForElementsPointer(), object_elements); 1699 Add<HStoreNamedField>(object, HObjectAccess::ForElementsPointer(),
1700 object_elements);
1700 1701
1701 // Copy the elements array header. 1702 // Copy the elements array header.
1702 for (int i = 0; i < FixedArrayBase::kHeaderSize; i += kPointerSize) { 1703 for (int i = 0; i < FixedArrayBase::kHeaderSize; i += kPointerSize) {
1703 HObjectAccess access = HObjectAccess::ForFixedArrayHeader(i); 1704 HObjectAccess access = HObjectAccess::ForFixedArrayHeader(i);
1704 AddStore(object_elements, access, AddLoad(boilerplate_elements, access)); 1705 Add<HStoreNamedField>(object_elements, access,
1706 Add<HLoadNamedField>(boilerplate_elements, access));
1705 } 1707 }
1706 1708
1707 // Copy the elements array contents. 1709 // Copy the elements array contents.
1708 // TODO(mstarzinger): Teach HGraphBuilder::BuildCopyElements to unfold 1710 // TODO(mstarzinger): Teach HGraphBuilder::BuildCopyElements to unfold
1709 // copying loops with constant length up to a given boundary and use this 1711 // copying loops with constant length up to a given boundary and use this
1710 // helper here instead. 1712 // helper here instead.
1711 for (int i = 0; i < length; i++) { 1713 for (int i = 0; i < length; i++) {
1712 HValue* key_constant = Add<HConstant>(i); 1714 HValue* key_constant = Add<HConstant>(i);
1713 HInstruction* value = Add<HLoadKeyed>(boilerplate_elements, key_constant, 1715 HInstruction* value = Add<HLoadKeyed>(boilerplate_elements, key_constant,
1714 static_cast<HValue*>(NULL), kind); 1716 static_cast<HValue*>(NULL), kind);
1715 Add<HStoreKeyed>(object_elements, key_constant, value, kind); 1717 Add<HStoreKeyed>(object_elements, key_constant, value, kind);
1716 } 1718 }
1717 } 1719 }
1718 1720
1719 return object; 1721 return object;
1720 } 1722 }
1721 1723
1722 1724
1725 HValue* HGraphBuilder::BuildKeyHash(HValue* key) {
1726 int32_t seed_value = static_cast<uint32_t>(isolate()->heap()->HashSeed());
1727 HValue* seed = Add<HConstant>(seed_value);
1728 HValue* hash = Add<HBitwise>(Token::BIT_XOR, key, seed);
1729
1730 // hash = ~hash + (hash << 15);
1731 HValue* shifted_hash = Add<HShl>(hash, Add<HConstant>(15));
1732 hash = Add<HAdd>(shifted_hash, static_cast<HValue*>(Add<HBitNot>(hash)));
1733
1734 // hash = hash ^ (hash >> 12);
1735 shifted_hash = Add<HShr>(hash, Add<HConstant>(12));
1736 hash = Add<HBitwise>(Token::BIT_XOR, hash, shifted_hash);
1737
1738 // hash = hash + (hash << 2);
1739 shifted_hash = Add<HShl>(hash, Add<HConstant>(2));
1740 hash = Add<HAdd>(hash, shifted_hash);
1741
1742 // hash = hash ^ (hash >> 4);
1743 shifted_hash = Add<HShr>(hash, Add<HConstant>(4));
1744 hash = Add<HBitwise>(Token::BIT_XOR, hash, shifted_hash);
1745
1746 // hash = hash * 2057;
1747 hash = Add<HMul>(hash, Add<HConstant>(2057));
1748 hash->ClearFlag(HValue::kCanOverflow);
1749
1750 // hash = hash ^ (hash >> 16);
1751 shifted_hash = Add<HShr>(hash, Add<HConstant>(16));
1752 return Add<HBitwise>(Token::BIT_XOR, hash, shifted_hash);
1753 }
1754
1755
1723 HInstruction* HGraphBuilder::BuildUnaryMathOp( 1756 HInstruction* HGraphBuilder::BuildUnaryMathOp(
1724 HValue* input, Handle<Type> type, Token::Value operation) { 1757 HValue* input, Handle<Type> type, Token::Value operation) {
1725 // We only handle the numeric cases here 1758 // We only handle the numeric cases here
1726 type = handle( 1759 type = handle(
1727 Type::Intersect(type, handle(Type::Number(), isolate())), isolate()); 1760 Type::Intersect(type, handle(Type::Number(), isolate())), isolate());
1728 1761
1729 switch (operation) { 1762 switch (operation) {
1730 default: 1763 default:
1731 UNREACHABLE(); 1764 UNREACHABLE();
1732 case Token::SUB: { 1765 case Token::SUB: {
1733 HInstruction* instr = 1766 HInstruction* instr =
1734 HMul::New(zone(), environment()->LookupContext(), 1767 New<HMul>(input, graph()->GetConstantMinus1());
1735 input, graph()->GetConstantMinus1());
1736 Representation rep = Representation::FromType(type); 1768 Representation rep = Representation::FromType(type);
1737 if (type->Is(Type::None())) { 1769 if (type->Is(Type::None())) {
1738 Add<HDeoptimize>(Deoptimizer::SOFT); 1770 Add<HDeoptimize>(Deoptimizer::SOFT);
1739 } 1771 }
1740 if (instr->IsBinaryOperation()) { 1772 if (instr->IsBinaryOperation()) {
1741 HBinaryOperation* binop = HBinaryOperation::cast(instr); 1773 HBinaryOperation* binop = HBinaryOperation::cast(instr);
1742 binop->set_observed_input_representation(1, rep); 1774 binop->set_observed_input_representation(1, rep);
1743 binop->set_observed_input_representation(2, rep); 1775 binop->set_observed_input_representation(2, rep);
1744 } 1776 }
1745 return instr; 1777 return instr;
1746 } 1778 }
1747 case Token::BIT_NOT: 1779 case Token::BIT_NOT:
1748 if (type->Is(Type::None())) { 1780 if (type->Is(Type::None())) {
1749 Add<HDeoptimize>(Deoptimizer::SOFT); 1781 Add<HDeoptimize>(Deoptimizer::SOFT);
1750 } 1782 }
1751 return new(zone()) HBitNot(input); 1783 return New<HBitNot>(input);
1752 } 1784 }
1753 } 1785 }
1754 1786
1755 1787
1756 void HGraphBuilder::BuildCompareNil( 1788 void HGraphBuilder::BuildCompareNil(
1757 HValue* value, 1789 HValue* value,
1758 Handle<Type> type, 1790 Handle<Type> type,
1759 int position, 1791 int position,
1760 HIfContinuation* continuation) { 1792 HIfContinuation* continuation) {
1761 IfBuilder if_nil(this, position); 1793 IfBuilder if_nil(this, position);
(...skipping 28 matching lines...) Expand all
1790 } 1822 }
1791 1823
1792 if_nil.CaptureContinuation(continuation); 1824 if_nil.CaptureContinuation(continuation);
1793 } 1825 }
1794 1826
1795 1827
1796 HValue* HGraphBuilder::BuildCreateAllocationMemento(HValue* previous_object, 1828 HValue* HGraphBuilder::BuildCreateAllocationMemento(HValue* previous_object,
1797 int previous_object_size, 1829 int previous_object_size,
1798 HValue* alloc_site) { 1830 HValue* alloc_site) {
1799 ASSERT(alloc_site != NULL); 1831 ASSERT(alloc_site != NULL);
1800 HInnerAllocatedObject* alloc_memento = Add<HInnerAllocatedObject>( 1832 HInnerAllocatedObject* alloc_memento = AddAndCast<HInnerAllocatedObject>(
1801 previous_object, previous_object_size); 1833 previous_object, previous_object_size);
1802 Handle<Map> alloc_memento_map( 1834 Handle<Map> alloc_memento_map(
1803 isolate()->heap()->allocation_memento_map()); 1835 isolate()->heap()->allocation_memento_map());
1804 AddStoreMapConstant(alloc_memento, alloc_memento_map); 1836 AddStoreMapConstant(alloc_memento, alloc_memento_map);
1805 HObjectAccess access = HObjectAccess::ForAllocationMementoSite(); 1837 HObjectAccess access = HObjectAccess::ForAllocationMementoSite();
1806 AddStore(alloc_memento, access, alloc_site); 1838 Add<HStoreNamedField>(alloc_memento, access, alloc_site);
1807 return alloc_memento; 1839 return alloc_memento;
1808 } 1840 }
1809 1841
1810 1842
1811 HInstruction* HGraphBuilder::BuildGetNativeContext(HValue* context) { 1843 HInstruction* HGraphBuilder::BuildGetNativeContext() {
1812 // Get the global context, then the native context 1844 // Get the global context, then the native context
1813 HInstruction* global_object = Add<HGlobalObject>(context); 1845 HInstruction* global_object = Add<HGlobalObject>();
1814 HObjectAccess access = HObjectAccess::ForJSObjectOffset( 1846 HObjectAccess access = HObjectAccess::ForJSObjectOffset(
1815 GlobalObject::kNativeContextOffset); 1847 GlobalObject::kNativeContextOffset);
1816 return AddLoad(global_object, access); 1848 return Add<HLoadNamedField>(global_object, access);
1817 } 1849 }
1818 1850
1819 1851
1820 HInstruction* HGraphBuilder::BuildGetArrayFunction(HValue* context) { 1852 HInstruction* HGraphBuilder::BuildGetArrayFunction() {
1821 HInstruction* native_context = BuildGetNativeContext(context); 1853 HInstruction* native_context = BuildGetNativeContext();
1822 HInstruction* index = 1854 HInstruction* index =
1823 Add<HConstant>(static_cast<int32_t>(Context::ARRAY_FUNCTION_INDEX)); 1855 Add<HConstant>(static_cast<int32_t>(Context::ARRAY_FUNCTION_INDEX));
1824 return Add<HLoadKeyed>( 1856 return Add<HLoadKeyed>(
1825 native_context, index, static_cast<HValue*>(NULL), FAST_ELEMENTS); 1857 native_context, index, static_cast<HValue*>(NULL), FAST_ELEMENTS);
1826 } 1858 }
1827 1859
1828 1860
1829 HGraphBuilder::JSArrayBuilder::JSArrayBuilder(HGraphBuilder* builder, 1861 HGraphBuilder::JSArrayBuilder::JSArrayBuilder(HGraphBuilder* builder,
1830 ElementsKind kind, 1862 ElementsKind kind,
1831 HValue* allocation_site_payload, 1863 HValue* allocation_site_payload,
(...skipping 13 matching lines...) Expand all
1845 ElementsKind kind, 1877 ElementsKind kind,
1846 HValue* constructor_function) : 1878 HValue* constructor_function) :
1847 builder_(builder), 1879 builder_(builder),
1848 kind_(kind), 1880 kind_(kind),
1849 mode_(DONT_TRACK_ALLOCATION_SITE), 1881 mode_(DONT_TRACK_ALLOCATION_SITE),
1850 allocation_site_payload_(NULL), 1882 allocation_site_payload_(NULL),
1851 constructor_function_(constructor_function) { 1883 constructor_function_(constructor_function) {
1852 } 1884 }
1853 1885
1854 1886
1855 HValue* HGraphBuilder::JSArrayBuilder::EmitMapCode(HValue* context) { 1887 HValue* HGraphBuilder::JSArrayBuilder::EmitMapCode() {
1856 if (kind_ == GetInitialFastElementsKind()) { 1888 if (kind_ == GetInitialFastElementsKind()) {
1857 // No need for a context lookup if the kind_ matches the initial 1889 // No need for a context lookup if the kind_ matches the initial
1858 // map, because we can just load the map in that case. 1890 // map, because we can just load the map in that case.
1859 HObjectAccess access = HObjectAccess::ForPrototypeOrInitialMap(); 1891 HObjectAccess access = HObjectAccess::ForPrototypeOrInitialMap();
1860 return builder()->AddInstruction( 1892 return builder()->AddInstruction(
1861 builder()->BuildLoadNamedField(constructor_function_, access)); 1893 builder()->BuildLoadNamedField(constructor_function_, access));
1862 } 1894 }
1863 1895
1864 HInstruction* native_context = builder()->BuildGetNativeContext(context); 1896 HInstruction* native_context = builder()->BuildGetNativeContext();
1865 HInstruction* index = builder()->Add<HConstant>( 1897 HInstruction* index = builder()->Add<HConstant>(
1866 static_cast<int32_t>(Context::JS_ARRAY_MAPS_INDEX)); 1898 static_cast<int32_t>(Context::JS_ARRAY_MAPS_INDEX));
1867 1899
1868 HInstruction* map_array = builder()->Add<HLoadKeyed>( 1900 HInstruction* map_array = builder()->Add<HLoadKeyed>(
1869 native_context, index, static_cast<HValue*>(NULL), FAST_ELEMENTS); 1901 native_context, index, static_cast<HValue*>(NULL), FAST_ELEMENTS);
1870 1902
1871 HInstruction* kind_index = builder()->Add<HConstant>(kind_); 1903 HInstruction* kind_index = builder()->Add<HConstant>(kind_);
1872 1904
1873 return builder()->Add<HLoadKeyed>( 1905 return builder()->Add<HLoadKeyed>(
1874 map_array, kind_index, static_cast<HValue*>(NULL), FAST_ELEMENTS); 1906 map_array, kind_index, static_cast<HValue*>(NULL), FAST_ELEMENTS);
1875 } 1907 }
1876 1908
1877 1909
1878 HValue* HGraphBuilder::JSArrayBuilder::EmitInternalMapCode() { 1910 HValue* HGraphBuilder::JSArrayBuilder::EmitInternalMapCode() {
1879 // Find the map near the constructor function 1911 // Find the map near the constructor function
1880 HObjectAccess access = HObjectAccess::ForPrototypeOrInitialMap(); 1912 HObjectAccess access = HObjectAccess::ForPrototypeOrInitialMap();
1881 return builder()->AddInstruction( 1913 return builder()->AddInstruction(
1882 builder()->BuildLoadNamedField(constructor_function_, access)); 1914 builder()->BuildLoadNamedField(constructor_function_, access));
1883 } 1915 }
1884 1916
1885 1917
1886 HValue* HGraphBuilder::JSArrayBuilder::EstablishAllocationSize( 1918 HValue* HGraphBuilder::JSArrayBuilder::EstablishAllocationSize(
1887 HValue* length_node) { 1919 HValue* length_node) {
1888 HValue* context = builder()->environment()->LookupContext();
1889 ASSERT(length_node != NULL); 1920 ASSERT(length_node != NULL);
1890 1921
1891 int base_size = JSArray::kSize; 1922 int base_size = JSArray::kSize;
1892 if (mode_ == TRACK_ALLOCATION_SITE) { 1923 if (mode_ == TRACK_ALLOCATION_SITE) {
1893 base_size += AllocationMemento::kSize; 1924 base_size += AllocationMemento::kSize;
1894 } 1925 }
1895 1926
1896 STATIC_ASSERT(FixedDoubleArray::kHeaderSize == FixedArray::kHeaderSize); 1927 STATIC_ASSERT(FixedDoubleArray::kHeaderSize == FixedArray::kHeaderSize);
1897 base_size += FixedArray::kHeaderSize; 1928 base_size += FixedArray::kHeaderSize;
1898 1929
1899 HInstruction* elements_size_value = 1930 HInstruction* elements_size_value =
1900 builder()->Add<HConstant>(elements_size()); 1931 builder()->Add<HConstant>(elements_size());
1901 HInstruction* mul = HMul::New(zone(), context, length_node, 1932 HInstruction* mul = builder()->Add<HMul>(length_node, elements_size_value);
1902 elements_size_value);
1903 mul->ClearFlag(HValue::kCanOverflow); 1933 mul->ClearFlag(HValue::kCanOverflow);
1904 builder()->AddInstruction(mul);
1905 1934
1906 HInstruction* base = builder()->Add<HConstant>(base_size); 1935 HInstruction* base = builder()->Add<HConstant>(base_size);
1907 HInstruction* total_size = HAdd::New(zone(), context, base, mul); 1936 HInstruction* total_size = builder()->Add<HAdd>(base, mul);
1908 total_size->ClearFlag(HValue::kCanOverflow); 1937 total_size->ClearFlag(HValue::kCanOverflow);
1909 builder()->AddInstruction(total_size);
1910 return total_size; 1938 return total_size;
1911 } 1939 }
1912 1940
1913 1941
1914 HValue* HGraphBuilder::JSArrayBuilder::EstablishEmptyArrayAllocationSize() { 1942 HValue* HGraphBuilder::JSArrayBuilder::EstablishEmptyArrayAllocationSize() {
1915 int base_size = JSArray::kSize; 1943 int base_size = JSArray::kSize;
1916 if (mode_ == TRACK_ALLOCATION_SITE) { 1944 if (mode_ == TRACK_ALLOCATION_SITE) {
1917 base_size += AllocationMemento::kSize; 1945 base_size += AllocationMemento::kSize;
1918 } 1946 }
1919 1947
1920 base_size += IsFastDoubleElementsKind(kind_) 1948 base_size += IsFastDoubleElementsKind(kind_)
1921 ? FixedDoubleArray::SizeFor(initial_capacity()) 1949 ? FixedDoubleArray::SizeFor(initial_capacity())
1922 : FixedArray::SizeFor(initial_capacity()); 1950 : FixedArray::SizeFor(initial_capacity());
1923 1951
1924 return builder()->Add<HConstant>(base_size); 1952 return builder()->Add<HConstant>(base_size);
1925 } 1953 }
1926 1954
1927 1955
1928 HValue* HGraphBuilder::JSArrayBuilder::AllocateEmptyArray() { 1956 HValue* HGraphBuilder::JSArrayBuilder::AllocateEmptyArray() {
1929 HValue* size_in_bytes = EstablishEmptyArrayAllocationSize(); 1957 HValue* size_in_bytes = EstablishEmptyArrayAllocationSize();
1930 HConstant* capacity = builder()->Add<HConstant>(initial_capacity()); 1958 HConstant* capacity = builder()->AddAndCast<HConstant>(initial_capacity());
1931 return AllocateArray(size_in_bytes, 1959 return AllocateArray(size_in_bytes,
1932 capacity, 1960 capacity,
1933 builder()->graph()->GetConstant0(), 1961 builder()->graph()->GetConstant0(),
1934 true); 1962 true);
1935 } 1963 }
1936 1964
1937 1965
1938 HValue* HGraphBuilder::JSArrayBuilder::AllocateArray(HValue* capacity, 1966 HValue* HGraphBuilder::JSArrayBuilder::AllocateArray(HValue* capacity,
1939 HValue* length_field, 1967 HValue* length_field,
1940 bool fill_with_hole) { 1968 bool fill_with_hole) {
1941 HValue* size_in_bytes = EstablishAllocationSize(capacity); 1969 HValue* size_in_bytes = EstablishAllocationSize(capacity);
1942 return AllocateArray(size_in_bytes, capacity, length_field, fill_with_hole); 1970 return AllocateArray(size_in_bytes, capacity, length_field, fill_with_hole);
1943 } 1971 }
1944 1972
1945 1973
1946 HValue* HGraphBuilder::JSArrayBuilder::AllocateArray(HValue* size_in_bytes, 1974 HValue* HGraphBuilder::JSArrayBuilder::AllocateArray(HValue* size_in_bytes,
1947 HValue* capacity, 1975 HValue* capacity,
1948 HValue* length_field, 1976 HValue* length_field,
1949 bool fill_with_hole) { 1977 bool fill_with_hole) {
1950 HValue* context = builder()->environment()->LookupContext();
1951
1952 // These HForceRepresentations are because we store these as fields in the 1978 // These HForceRepresentations are because we store these as fields in the
1953 // objects we construct, and an int32-to-smi HChange could deopt. Accept 1979 // objects we construct, and an int32-to-smi HChange could deopt. Accept
1954 // the deopt possibility now, before allocation occurs. 1980 // the deopt possibility now, before allocation occurs.
1955 capacity = builder()->Add<HForceRepresentation>(capacity, 1981 capacity = builder()->Add<HForceRepresentation>(capacity,
1956 Representation::Smi()); 1982 Representation::Smi());
1957 length_field = builder()->Add<HForceRepresentation>(length_field, 1983 length_field = builder()->Add<HForceRepresentation>(length_field,
1958 Representation::Smi()); 1984 Representation::Smi());
1959
1960 // Allocate (dealing with failure appropriately) 1985 // Allocate (dealing with failure appropriately)
1961 HAllocate::Flags flags = HAllocate::DefaultFlags(kind_); 1986 HAllocate::Flags flags = HAllocate::DefaultFlags(kind_);
1962 HAllocate* new_object = builder()->Add<HAllocate>(context, size_in_bytes, 1987 HAllocate* new_object =
1963 HType::JSArray(), flags); 1988 builder()->AddAndCast<HAllocate>(size_in_bytes, HType::JSArray(), flags);
1964 1989
1965 // Fill in the fields: map, properties, length 1990 // Fill in the fields: map, properties, length
1966 HValue* map; 1991 HValue* map;
1967 if (allocation_site_payload_ == NULL) { 1992 if (allocation_site_payload_ == NULL) {
1968 map = EmitInternalMapCode(); 1993 map = EmitInternalMapCode();
1969 } else { 1994 } else {
1970 map = EmitMapCode(context); 1995 map = EmitMapCode();
1971 } 1996 }
1972 elements_location_ = builder()->BuildJSArrayHeader(new_object, 1997 elements_location_ = builder()->BuildJSArrayHeader(new_object,
1973 map, 1998 map,
1974 mode_, 1999 mode_,
1975 kind_, 2000 kind_,
1976 allocation_site_payload_, 2001 allocation_site_payload_,
1977 length_field); 2002 length_field);
1978 2003
1979 // Initialize the elements 2004 // Initialize the elements
1980 builder()->BuildInitializeElementsHeader(elements_location_, kind_, capacity); 2005 builder()->BuildInitializeElementsHeader(elements_location_, kind_, capacity);
1981 2006
1982 if (fill_with_hole) { 2007 if (fill_with_hole) {
1983 builder()->BuildFillElementsWithHole(context, elements_location_, kind_, 2008 builder()->BuildFillElementsWithHole(elements_location_, kind_,
1984 graph()->GetConstant0(), capacity); 2009 graph()->GetConstant0(), capacity);
1985 } 2010 }
1986 2011
1987 return new_object; 2012 return new_object;
1988 } 2013 }
1989 2014
1990 2015
1991 HStoreNamedField* HGraphBuilder::AddStore(HValue *object,
1992 HObjectAccess access,
1993 HValue *val) {
1994 return Add<HStoreNamedField>(object, access, val);
1995 }
1996
1997
1998 HLoadNamedField* HGraphBuilder::AddLoad(HValue *object,
1999 HObjectAccess access,
2000 HValue *typecheck) {
2001 return Add<HLoadNamedField>(object, access, typecheck);
2002 }
2003
2004
2005 HStoreNamedField* HGraphBuilder::AddStoreMapConstant(HValue *object, 2016 HStoreNamedField* HGraphBuilder::AddStoreMapConstant(HValue *object,
2006 Handle<Map> map) { 2017 Handle<Map> map) {
2007 return Add<HStoreNamedField>(object, HObjectAccess::ForMap(), 2018 return AddAndCast<HStoreNamedField>(object, HObjectAccess::ForMap(),
2008 Add<HConstant>(map)); 2019 Add<HConstant>(map));
2009 } 2020 }
2010 2021
2011 2022
2012 HValue* HGraphBuilder::AddLoadJSBuiltin(Builtins::JavaScript builtin, 2023 HValue* HGraphBuilder::AddLoadJSBuiltin(Builtins::JavaScript builtin) {
2013 HValue* context) { 2024 HGlobalObject* global_object = AddAndCast<HGlobalObject>();
2014 HGlobalObject* global_object = Add<HGlobalObject>(context);
2015 HObjectAccess access = HObjectAccess::ForJSObjectOffset( 2025 HObjectAccess access = HObjectAccess::ForJSObjectOffset(
2016 GlobalObject::kBuiltinsOffset); 2026 GlobalObject::kBuiltinsOffset);
2017 HValue* builtins = AddLoad(global_object, access); 2027 HValue* builtins = Add<HLoadNamedField>(global_object, access);
2018 HObjectAccess function_access = HObjectAccess::ForJSObjectOffset( 2028 HObjectAccess function_access = HObjectAccess::ForJSObjectOffset(
2019 JSBuiltinsObject::OffsetOfFunctionWithId(builtin)); 2029 JSBuiltinsObject::OffsetOfFunctionWithId(builtin));
2020 return AddLoad(builtins, function_access); 2030 return Add<HLoadNamedField>(builtins, function_access);
2021 } 2031 }
2022 2032
2023 2033
2024 HOptimizedGraphBuilder::HOptimizedGraphBuilder(CompilationInfo* info) 2034 HOptimizedGraphBuilder::HOptimizedGraphBuilder(CompilationInfo* info)
2025 : HGraphBuilder(info), 2035 : HGraphBuilder(info),
2026 function_state_(NULL), 2036 function_state_(NULL),
2027 initial_function_state_(this, info, NORMAL_RETURN), 2037 initial_function_state_(this, info, NORMAL_RETURN),
2028 ast_context_(NULL), 2038 ast_context_(NULL),
2029 break_scope_(NULL), 2039 break_scope_(NULL),
2030 inlined_count_(0), 2040 inlined_count_(0),
(...skipping 871 matching lines...) Expand 10 before | Expand all | Expand 10 after
2902 set_current_block(body_entry); 2912 set_current_block(body_entry);
2903 2913
2904 // Handle implicit declaration of the function name in named function 2914 // Handle implicit declaration of the function name in named function
2905 // expressions before other declarations. 2915 // expressions before other declarations.
2906 if (scope->is_function_scope() && scope->function() != NULL) { 2916 if (scope->is_function_scope() && scope->function() != NULL) {
2907 VisitVariableDeclaration(scope->function()); 2917 VisitVariableDeclaration(scope->function());
2908 } 2918 }
2909 VisitDeclarations(scope->declarations()); 2919 VisitDeclarations(scope->declarations());
2910 Add<HSimulate>(BailoutId::Declarations()); 2920 Add<HSimulate>(BailoutId::Declarations());
2911 2921
2912 HValue* context = environment()->LookupContext(); 2922 HValue* context = environment()->context();
2913 Add<HStackCheck>(context, HStackCheck::kFunctionEntry); 2923 Add<HStackCheck>(context, HStackCheck::kFunctionEntry);
2914 2924
2915 VisitStatements(current_info()->function()->body()); 2925 VisitStatements(current_info()->function()->body());
2916 if (HasStackOverflow()) return false; 2926 if (HasStackOverflow()) return false;
2917 2927
2918 if (current_block() != NULL) { 2928 if (current_block() != NULL) {
2919 Add<HReturn>(graph()->GetConstantUndefined()); 2929 Add<HReturn>(graph()->GetConstantUndefined());
2920 set_current_block(NULL); 2930 set_current_block(NULL);
2921 } 2931 }
2922 2932
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after
3113 } 3123 }
3114 3124
3115 while (!arguments.is_empty()) { 3125 while (!arguments.is_empty()) {
3116 Add<HPushArgument>(arguments.RemoveLast()); 3126 Add<HPushArgument>(arguments.RemoveLast());
3117 } 3127 }
3118 return call; 3128 return call;
3119 } 3129 }
3120 3130
3121 3131
3122 void HOptimizedGraphBuilder::SetUpScope(Scope* scope) { 3132 void HOptimizedGraphBuilder::SetUpScope(Scope* scope) {
3123 HConstant* undefined_constant = Add<HConstant>( 3133 // First special is HContext.
3124 isolate()->factory()->undefined_value()); 3134 HInstruction* context = Add<HContext>();
3135 environment()->BindContext(context);
3136
3137 HConstant* undefined_constant = HConstant::cast(Add<HConstant>(
3138 isolate()->factory()->undefined_value()));
3125 graph()->set_undefined_constant(undefined_constant); 3139 graph()->set_undefined_constant(undefined_constant);
3126 3140
3127 // Create an arguments object containing the initial parameters. Set the 3141 // Create an arguments object containing the initial parameters. Set the
3128 // initial values of parameters including "this" having parameter index 0. 3142 // initial values of parameters including "this" having parameter index 0.
3129 ASSERT_EQ(scope->num_parameters() + 1, environment()->parameter_count()); 3143 ASSERT_EQ(scope->num_parameters() + 1, environment()->parameter_count());
3130 HArgumentsObject* arguments_object = 3144 HArgumentsObject* arguments_object =
3131 new(zone()) HArgumentsObject(environment()->parameter_count(), zone()); 3145 NewAndCast<HArgumentsObject>(environment()->parameter_count());
3132 for (int i = 0; i < environment()->parameter_count(); ++i) { 3146 for (int i = 0; i < environment()->parameter_count(); ++i) {
3133 HInstruction* parameter = Add<HParameter>(i); 3147 HInstruction* parameter = Add<HParameter>(i);
3134 arguments_object->AddArgument(parameter, zone()); 3148 arguments_object->AddArgument(parameter, zone());
3135 environment()->Bind(i, parameter); 3149 environment()->Bind(i, parameter);
3136 } 3150 }
3137 AddInstruction(arguments_object); 3151 AddInstruction(arguments_object);
3138 graph()->SetArgumentsObject(arguments_object); 3152 graph()->SetArgumentsObject(arguments_object);
3139 3153
3140 // First special is HContext.
3141 HInstruction* context = Add<HContext>();
3142 environment()->BindContext(context);
3143
3144 // Initialize specials and locals to undefined. 3154 // Initialize specials and locals to undefined.
3145 for (int i = environment()->parameter_count() + 1; 3155 for (int i = environment()->parameter_count() + 1;
3146 i < environment()->length(); 3156 i < environment()->length();
3147 ++i) { 3157 ++i) {
3148 environment()->Bind(i, undefined_constant); 3158 environment()->Bind(i, undefined_constant);
3149 } 3159 }
3150 3160
3151 // Handle the arguments and arguments shadow variables specially (they do 3161 // Handle the arguments and arguments shadow variables specially (they do
3152 // not have declarations). 3162 // not have declarations).
3153 if (scope->arguments() != NULL) { 3163 if (scope->arguments() != NULL) {
(...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after
3401 int clause_count = clauses->length(); 3411 int clause_count = clauses->length();
3402 if (clause_count > kCaseClauseLimit) { 3412 if (clause_count > kCaseClauseLimit) {
3403 return Bailout("SwitchStatement: too many clauses"); 3413 return Bailout("SwitchStatement: too many clauses");
3404 } 3414 }
3405 3415
3406 ASSERT(stmt->switch_type() != SwitchStatement::UNKNOWN_SWITCH); 3416 ASSERT(stmt->switch_type() != SwitchStatement::UNKNOWN_SWITCH);
3407 if (stmt->switch_type() == SwitchStatement::GENERIC_SWITCH) { 3417 if (stmt->switch_type() == SwitchStatement::GENERIC_SWITCH) {
3408 return Bailout("SwitchStatement: mixed or non-literal switch labels"); 3418 return Bailout("SwitchStatement: mixed or non-literal switch labels");
3409 } 3419 }
3410 3420
3411 HValue* context = environment()->LookupContext(); 3421 HValue* context = environment()->context();
3412 3422
3413 CHECK_ALIVE(VisitForValue(stmt->tag())); 3423 CHECK_ALIVE(VisitForValue(stmt->tag()));
3414 Add<HSimulate>(stmt->EntryId()); 3424 Add<HSimulate>(stmt->EntryId());
3415 HValue* tag_value = Pop(); 3425 HValue* tag_value = Pop();
3416 HBasicBlock* first_test_block = current_block(); 3426 HBasicBlock* first_test_block = current_block();
3417 3427
3418 HUnaryControlInstruction* string_check = NULL; 3428 HUnaryControlInstruction* string_check = NULL;
3419 HBasicBlock* not_string_block = NULL; 3429 HBasicBlock* not_string_block = NULL;
3420 3430
3421 // Test switch's tag value if all clauses are string literals 3431 // Test switch's tag value if all clauses are string literals
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
3549 set_current_block(break_block); 3559 set_current_block(break_block);
3550 } 3560 }
3551 } 3561 }
3552 3562
3553 3563
3554 void HOptimizedGraphBuilder::VisitLoopBody(IterationStatement* stmt, 3564 void HOptimizedGraphBuilder::VisitLoopBody(IterationStatement* stmt,
3555 HBasicBlock* loop_entry, 3565 HBasicBlock* loop_entry,
3556 BreakAndContinueInfo* break_info) { 3566 BreakAndContinueInfo* break_info) {
3557 BreakAndContinueScope push(break_info, this); 3567 BreakAndContinueScope push(break_info, this);
3558 Add<HSimulate>(stmt->StackCheckId()); 3568 Add<HSimulate>(stmt->StackCheckId());
3559 HValue* context = environment()->LookupContext(); 3569 HValue* context = environment()->context();
3560 HStackCheck* stack_check = Add<HStackCheck>( 3570 HStackCheck* stack_check = HStackCheck::cast(Add<HStackCheck>(
3561 context, HStackCheck::kBackwardsBranch); 3571 context, HStackCheck::kBackwardsBranch));
3562 ASSERT(loop_entry->IsLoopHeader()); 3572 ASSERT(loop_entry->IsLoopHeader());
3563 loop_entry->loop_information()->set_stack_check(stack_check); 3573 loop_entry->loop_information()->set_stack_check(stack_check);
3564 CHECK_BAILOUT(Visit(stmt->body())); 3574 CHECK_BAILOUT(Visit(stmt->body()));
3565 } 3575 }
3566 3576
3567 3577
3568 void HOptimizedGraphBuilder::VisitDoWhileStatement(DoWhileStatement* stmt) { 3578 void HOptimizedGraphBuilder::VisitDoWhileStatement(DoWhileStatement* stmt) {
3569 ASSERT(!HasStackOverflow()); 3579 ASSERT(!HasStackOverflow());
3570 ASSERT(current_block() != NULL); 3580 ASSERT(current_block() != NULL);
3571 ASSERT(current_block()->HasPredecessor()); 3581 ASSERT(current_block()->HasPredecessor());
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after
3707 if (!stmt->each()->IsVariableProxy() || 3717 if (!stmt->each()->IsVariableProxy() ||
3708 !stmt->each()->AsVariableProxy()->var()->IsStackLocal()) { 3718 !stmt->each()->AsVariableProxy()->var()->IsStackLocal()) {
3709 return Bailout("ForInStatement with non-local each variable"); 3719 return Bailout("ForInStatement with non-local each variable");
3710 } 3720 }
3711 3721
3712 Variable* each_var = stmt->each()->AsVariableProxy()->var(); 3722 Variable* each_var = stmt->each()->AsVariableProxy()->var();
3713 3723
3714 CHECK_ALIVE(VisitForValue(stmt->enumerable())); 3724 CHECK_ALIVE(VisitForValue(stmt->enumerable()));
3715 HValue* enumerable = Top(); // Leave enumerable at the top. 3725 HValue* enumerable = Top(); // Leave enumerable at the top.
3716 3726
3717 HInstruction* map = Add<HForInPrepareMap>( 3727 HInstruction* map = Add<HForInPrepareMap>(enumerable);
3718 environment()->LookupContext(), enumerable);
3719 Add<HSimulate>(stmt->PrepareId()); 3728 Add<HSimulate>(stmt->PrepareId());
3720 3729
3721 HInstruction* array = Add<HForInCacheArray>( 3730 HInstruction* array = Add<HForInCacheArray>(
3722 enumerable, map, DescriptorArray::kEnumCacheBridgeCacheIndex); 3731 enumerable, map, DescriptorArray::kEnumCacheBridgeCacheIndex);
3723 3732
3724 HInstruction* enum_length = Add<HMapEnumLength>(map); 3733 HInstruction* enum_length = Add<HMapEnumLength>(map);
3725 3734
3726 HInstruction* start_index = Add<HConstant>(0); 3735 HInstruction* start_index = Add<HConstant>(0);
3727 3736
3728 Push(map); 3737 Push(map);
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
3774 BreakAndContinueInfo break_info(stmt, 5); 3783 BreakAndContinueInfo break_info(stmt, 5);
3775 CHECK_BAILOUT(VisitLoopBody(stmt, loop_entry, &break_info)); 3784 CHECK_BAILOUT(VisitLoopBody(stmt, loop_entry, &break_info));
3776 3785
3777 HBasicBlock* body_exit = 3786 HBasicBlock* body_exit =
3778 JoinContinue(stmt, current_block(), break_info.continue_block()); 3787 JoinContinue(stmt, current_block(), break_info.continue_block());
3779 3788
3780 if (body_exit != NULL) { 3789 if (body_exit != NULL) {
3781 set_current_block(body_exit); 3790 set_current_block(body_exit);
3782 3791
3783 HValue* current_index = Pop(); 3792 HValue* current_index = Pop();
3784 HInstruction* new_index = HAdd::New(zone(), 3793 HInstruction* new_index = New<HAdd>(current_index,
3785 environment()->LookupContext(),
3786 current_index,
3787 graph()->GetConstant1()); 3794 graph()->GetConstant1());
3788 PushAndAdd(new_index); 3795 PushAndAdd(new_index);
3789 body_exit = current_block(); 3796 body_exit = current_block();
3790 } 3797 }
3791 3798
3792 HBasicBlock* loop_exit = CreateLoop(stmt, 3799 HBasicBlock* loop_exit = CreateLoop(stmt,
3793 loop_entry, 3800 loop_entry,
3794 body_exit, 3801 body_exit,
3795 loop_successor, 3802 loop_successor,
3796 break_info.break_block()); 3803 break_info.break_block());
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
3855 ASSERT(!HasStackOverflow()); 3862 ASSERT(!HasStackOverflow());
3856 ASSERT(current_block() != NULL); 3863 ASSERT(current_block() != NULL);
3857 ASSERT(current_block()->HasPredecessor()); 3864 ASSERT(current_block()->HasPredecessor());
3858 Handle<SharedFunctionInfo> shared_info = 3865 Handle<SharedFunctionInfo> shared_info =
3859 SearchSharedFunctionInfo(current_info()->shared_info()->code(), expr); 3866 SearchSharedFunctionInfo(current_info()->shared_info()->code(), expr);
3860 if (shared_info.is_null()) { 3867 if (shared_info.is_null()) {
3861 shared_info = Compiler::BuildFunctionInfo(expr, current_info()->script()); 3868 shared_info = Compiler::BuildFunctionInfo(expr, current_info()->script());
3862 } 3869 }
3863 // We also have a stack overflow if the recursive compilation did. 3870 // We also have a stack overflow if the recursive compilation did.
3864 if (HasStackOverflow()) return; 3871 if (HasStackOverflow()) return;
3865 HValue* context = environment()->LookupContext(); 3872 HValue* context = environment()->context();
3866 HFunctionLiteral* instr = 3873 HFunctionLiteral* instr =
3867 new(zone()) HFunctionLiteral(context, shared_info, expr->pretenure()); 3874 new(zone()) HFunctionLiteral(context, shared_info, expr->pretenure());
3868 return ast_context()->ReturnInstruction(instr, expr->id()); 3875 return ast_context()->ReturnInstruction(instr, expr->id());
3869 } 3876 }
3870 3877
3871 3878
3872 void HOptimizedGraphBuilder::VisitSharedFunctionInfoLiteral( 3879 void HOptimizedGraphBuilder::VisitSharedFunctionInfoLiteral(
3873 SharedFunctionInfoLiteral* expr) { 3880 SharedFunctionInfoLiteral* expr) {
3874 ASSERT(!HasStackOverflow()); 3881 ASSERT(!HasStackOverflow());
3875 ASSERT(current_block() != NULL); 3882 ASSERT(current_block() != NULL);
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
3929 lookup->holder() != *global) { 3936 lookup->holder() != *global) {
3930 return kUseGeneric; 3937 return kUseGeneric;
3931 } 3938 }
3932 3939
3933 return kUseCell; 3940 return kUseCell;
3934 } 3941 }
3935 3942
3936 3943
3937 HValue* HOptimizedGraphBuilder::BuildContextChainWalk(Variable* var) { 3944 HValue* HOptimizedGraphBuilder::BuildContextChainWalk(Variable* var) {
3938 ASSERT(var->IsContextSlot()); 3945 ASSERT(var->IsContextSlot());
3939 HValue* context = environment()->LookupContext(); 3946 HValue* context = environment()->context();
3940 int length = current_info()->scope()->ContextChainLength(var->scope()); 3947 int length = current_info()->scope()->ContextChainLength(var->scope());
3941 while (length-- > 0) { 3948 while (length-- > 0) {
3942 context = Add<HOuterContext>(context); 3949 context = Add<HOuterContext>(context);
3943 } 3950 }
3944 return context; 3951 return context;
3945 } 3952 }
3946 3953
3947 3954
3948 void HOptimizedGraphBuilder::VisitVariableProxy(VariableProxy* expr) { 3955 void HOptimizedGraphBuilder::VisitVariableProxy(VariableProxy* expr) {
3949 ASSERT(!HasStackOverflow()); 3956 ASSERT(!HasStackOverflow());
3950 ASSERT(current_block() != NULL); 3957 ASSERT(current_block() != NULL);
3951 ASSERT(current_block()->HasPredecessor()); 3958 ASSERT(current_block()->HasPredecessor());
3952 Variable* variable = expr->var(); 3959 Variable* variable = expr->var();
3953 switch (variable->location()) { 3960 switch (variable->location()) {
3954 case Variable::UNALLOCATED: { 3961 case Variable::UNALLOCATED: {
3955 if (IsLexicalVariableMode(variable->mode())) { 3962 if (IsLexicalVariableMode(variable->mode())) {
3956 // TODO(rossberg): should this be an ASSERT? 3963 // TODO(rossberg): should this be an ASSERT?
3957 return Bailout("reference to global lexical variable"); 3964 return Bailout("reference to global lexical variable");
3958 } 3965 }
3959 // Handle known global constants like 'undefined' specially to avoid a 3966 // Handle known global constants like 'undefined' specially to avoid a
3960 // load from a global cell for them. 3967 // load from a global cell for them.
3961 Handle<Object> constant_value = 3968 Handle<Object> constant_value =
3962 isolate()->factory()->GlobalConstantFor(variable->name()); 3969 isolate()->factory()->GlobalConstantFor(variable->name());
3963 if (!constant_value.is_null()) { 3970 if (!constant_value.is_null()) {
3964 HConstant* instr = new(zone()) HConstant(constant_value); 3971 HConstant* instr = NewAndCast<HConstant>(constant_value);
3965 return ast_context()->ReturnInstruction(instr, expr->id()); 3972 return ast_context()->ReturnInstruction(instr, expr->id());
3966 } 3973 }
3967 3974
3968 LookupResult lookup(isolate()); 3975 LookupResult lookup(isolate());
3969 GlobalPropertyAccess type = 3976 GlobalPropertyAccess type =
3970 LookupGlobalProperty(variable, &lookup, false); 3977 LookupGlobalProperty(variable, &lookup, false);
3971 3978
3972 if (type == kUseCell && 3979 if (type == kUseCell &&
3973 current_info()->global_object()->IsAccessCheckNeeded()) { 3980 current_info()->global_object()->IsAccessCheckNeeded()) {
3974 type = kUseGeneric; 3981 type = kUseGeneric;
3975 } 3982 }
3976 3983
3977 if (type == kUseCell) { 3984 if (type == kUseCell) {
3978 Handle<GlobalObject> global(current_info()->global_object()); 3985 Handle<GlobalObject> global(current_info()->global_object());
3979 Handle<PropertyCell> cell(global->GetPropertyCell(&lookup)); 3986 Handle<PropertyCell> cell(global->GetPropertyCell(&lookup));
3980 if (cell->type()->IsConstant()) { 3987 if (cell->type()->IsConstant()) {
3981 cell->AddDependentCompilationInfo(top_info()); 3988 cell->AddDependentCompilationInfo(top_info());
3982 Handle<Object> constant_object = cell->type()->AsConstant(); 3989 Handle<Object> constant_object = cell->type()->AsConstant();
3983 if (constant_object->IsConsString()) { 3990 if (constant_object->IsConsString()) {
3984 constant_object = 3991 constant_object =
3985 FlattenGetString(Handle<String>::cast(constant_object)); 3992 FlattenGetString(Handle<String>::cast(constant_object));
3986 } 3993 }
3987 HConstant* constant = new(zone()) HConstant(constant_object); 3994 HConstant* constant = NewAndCast<HConstant>(constant_object);
3988 return ast_context()->ReturnInstruction(constant, expr->id()); 3995 return ast_context()->ReturnInstruction(constant, expr->id());
3989 } else { 3996 } else {
3990 HLoadGlobalCell* instr = 3997 HLoadGlobalCell* instr =
3991 new(zone()) HLoadGlobalCell(cell, lookup.GetPropertyDetails()); 3998 new(zone()) HLoadGlobalCell(cell, lookup.GetPropertyDetails());
3992 return ast_context()->ReturnInstruction(instr, expr->id()); 3999 return ast_context()->ReturnInstruction(instr, expr->id());
3993 } 4000 }
3994 } else { 4001 } else {
3995 HValue* context = environment()->LookupContext(); 4002 HValue* context = environment()->context();
3996 HGlobalObject* global_object = new(zone()) HGlobalObject(context); 4003 HGlobalObject* global_object = new(zone()) HGlobalObject(context);
3997 AddInstruction(global_object); 4004 AddInstruction(global_object);
3998 HLoadGlobalGeneric* instr = 4005 HLoadGlobalGeneric* instr =
3999 new(zone()) HLoadGlobalGeneric(context, 4006 new(zone()) HLoadGlobalGeneric(context,
4000 global_object, 4007 global_object,
4001 variable->name(), 4008 variable->name(),
4002 ast_context()->is_for_typeof()); 4009 ast_context()->is_for_typeof());
4003 instr->set_position(expr->position()); 4010 instr->set_position(expr->position());
4004 return ast_context()->ReturnInstruction(instr, expr->id()); 4011 return ast_context()->ReturnInstruction(instr, expr->id());
4005 } 4012 }
(...skipping 19 matching lines...) Expand all
4025 case Variable::LOOKUP: 4032 case Variable::LOOKUP:
4026 return Bailout("reference to a variable which requires dynamic lookup"); 4033 return Bailout("reference to a variable which requires dynamic lookup");
4027 } 4034 }
4028 } 4035 }
4029 4036
4030 4037
4031 void HOptimizedGraphBuilder::VisitLiteral(Literal* expr) { 4038 void HOptimizedGraphBuilder::VisitLiteral(Literal* expr) {
4032 ASSERT(!HasStackOverflow()); 4039 ASSERT(!HasStackOverflow());
4033 ASSERT(current_block() != NULL); 4040 ASSERT(current_block() != NULL);
4034 ASSERT(current_block()->HasPredecessor()); 4041 ASSERT(current_block()->HasPredecessor());
4035 HConstant* instr = new(zone()) HConstant(expr->value()); 4042 HConstant* instr = NewAndCast<HConstant>(expr->value());
4036 return ast_context()->ReturnInstruction(instr, expr->id()); 4043 return ast_context()->ReturnInstruction(instr, expr->id());
4037 } 4044 }
4038 4045
4039 4046
4040 void HOptimizedGraphBuilder::VisitRegExpLiteral(RegExpLiteral* expr) { 4047 void HOptimizedGraphBuilder::VisitRegExpLiteral(RegExpLiteral* expr) {
4041 ASSERT(!HasStackOverflow()); 4048 ASSERT(!HasStackOverflow());
4042 ASSERT(current_block() != NULL); 4049 ASSERT(current_block() != NULL);
4043 ASSERT(current_block()->HasPredecessor()); 4050 ASSERT(current_block()->HasPredecessor());
4044 Handle<JSFunction> closure = function_state()->compilation_info()->closure(); 4051 Handle<JSFunction> closure = function_state()->compilation_info()->closure();
4045 Handle<FixedArray> literals(closure->literals()); 4052 Handle<FixedArray> literals(closure->literals());
4046 HValue* context = environment()->LookupContext(); 4053 HValue* context = environment()->context();
4047 4054
4048 HRegExpLiteral* instr = new(zone()) HRegExpLiteral(context, 4055 HRegExpLiteral* instr = new(zone()) HRegExpLiteral(context,
4049 literals, 4056 literals,
4050 expr->pattern(), 4057 expr->pattern(),
4051 expr->flags(), 4058 expr->flags(),
4052 expr->literal_index()); 4059 expr->literal_index());
4053 return ast_context()->ReturnInstruction(instr, expr->id()); 4060 return ast_context()->ReturnInstruction(instr, expr->id());
4054 } 4061 }
4055 4062
4056 4063
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after
4213 *pointer_size += boilerplate->map()->instance_size(); 4220 *pointer_size += boilerplate->map()->instance_size();
4214 return true; 4221 return true;
4215 } 4222 }
4216 4223
4217 4224
4218 void HOptimizedGraphBuilder::VisitObjectLiteral(ObjectLiteral* expr) { 4225 void HOptimizedGraphBuilder::VisitObjectLiteral(ObjectLiteral* expr) {
4219 ASSERT(!HasStackOverflow()); 4226 ASSERT(!HasStackOverflow());
4220 ASSERT(current_block() != NULL); 4227 ASSERT(current_block() != NULL);
4221 ASSERT(current_block()->HasPredecessor()); 4228 ASSERT(current_block()->HasPredecessor());
4222 Handle<JSFunction> closure = function_state()->compilation_info()->closure(); 4229 Handle<JSFunction> closure = function_state()->compilation_info()->closure();
4223 HValue* context = environment()->LookupContext(); 4230 HValue* context = environment()->context();
4224 HInstruction* literal; 4231 HInstruction* literal;
4225 4232
4226 // Check whether to use fast or slow deep-copying for boilerplate. 4233 // Check whether to use fast or slow deep-copying for boilerplate.
4227 int data_size = 0; 4234 int data_size = 0;
4228 int pointer_size = 0; 4235 int pointer_size = 0;
4229 int max_properties = kMaxFastLiteralProperties; 4236 int max_properties = kMaxFastLiteralProperties;
4230 Handle<Object> original_boilerplate(closure->literals()->get( 4237 Handle<Object> original_boilerplate(closure->literals()->get(
4231 expr->literal_index()), isolate()); 4238 expr->literal_index()), isolate());
4232 if (original_boilerplate->IsJSObject() && 4239 if (original_boilerplate->IsJSObject() &&
4233 IsFastLiteral(Handle<JSObject>::cast(original_boilerplate), 4240 IsFastLiteral(Handle<JSObject>::cast(original_boilerplate),
(...skipping 24 matching lines...) Expand all
4258 ? ObjectLiteral::kHasFunction : ObjectLiteral::kNoFlags; 4265 ? ObjectLiteral::kHasFunction : ObjectLiteral::kNoFlags;
4259 4266
4260 Add<HPushArgument>(Add<HConstant>(closure_literals)); 4267 Add<HPushArgument>(Add<HConstant>(closure_literals));
4261 Add<HPushArgument>(Add<HConstant>(literal_index)); 4268 Add<HPushArgument>(Add<HConstant>(literal_index));
4262 Add<HPushArgument>(Add<HConstant>(constant_properties)); 4269 Add<HPushArgument>(Add<HConstant>(constant_properties));
4263 Add<HPushArgument>(Add<HConstant>(flags)); 4270 Add<HPushArgument>(Add<HConstant>(flags));
4264 4271
4265 Runtime::FunctionId function_id = 4272 Runtime::FunctionId function_id =
4266 (expr->depth() > 1 || expr->may_store_doubles()) 4273 (expr->depth() > 1 || expr->may_store_doubles())
4267 ? Runtime::kCreateObjectLiteral : Runtime::kCreateObjectLiteralShallow; 4274 ? Runtime::kCreateObjectLiteral : Runtime::kCreateObjectLiteralShallow;
4268 literal = Add<HCallRuntime>(context, 4275 literal = Add<HCallRuntime>(isolate()->factory()->empty_string(),
4269 isolate()->factory()->empty_string(),
4270 Runtime::FunctionForId(function_id), 4276 Runtime::FunctionForId(function_id),
4271 4); 4277 4);
4272 } 4278 }
4273 4279
4274 // The object is expected in the bailout environment during computation 4280 // The object is expected in the bailout environment during computation
4275 // of the property values and is the value of the entire expression. 4281 // of the property values and is the value of the entire expression.
4276 Push(literal); 4282 Push(literal);
4277 4283
4278 expr->CalculateEmitStore(zone()); 4284 expr->CalculateEmitStore(zone());
4279 4285
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
4327 default: UNREACHABLE(); 4333 default: UNREACHABLE();
4328 } 4334 }
4329 } 4335 }
4330 4336
4331 if (expr->has_function()) { 4337 if (expr->has_function()) {
4332 // Return the result of the transformation to fast properties 4338 // Return the result of the transformation to fast properties
4333 // instead of the original since this operation changes the map 4339 // instead of the original since this operation changes the map
4334 // of the object. This makes sure that the original object won't 4340 // of the object. This makes sure that the original object won't
4335 // be used by other optimized code before it is transformed 4341 // be used by other optimized code before it is transformed
4336 // (e.g. because of code motion). 4342 // (e.g. because of code motion).
4337 HToFastProperties* result = Add<HToFastProperties>(Pop()); 4343 HToFastProperties* result = AddAndCast<HToFastProperties>(Pop());
4338 return ast_context()->ReturnValue(result); 4344 return ast_context()->ReturnValue(result);
4339 } else { 4345 } else {
4340 return ast_context()->ReturnValue(Pop()); 4346 return ast_context()->ReturnValue(Pop());
4341 } 4347 }
4342 } 4348 }
4343 4349
4344 4350
4345 void HOptimizedGraphBuilder::VisitArrayLiteral(ArrayLiteral* expr) { 4351 void HOptimizedGraphBuilder::VisitArrayLiteral(ArrayLiteral* expr) {
4346 ASSERT(!HasStackOverflow()); 4352 ASSERT(!HasStackOverflow());
4347 ASSERT(current_block() != NULL); 4353 ASSERT(current_block() != NULL);
4348 ASSERT(current_block()->HasPredecessor()); 4354 ASSERT(current_block()->HasPredecessor());
4349 ZoneList<Expression*>* subexprs = expr->values(); 4355 ZoneList<Expression*>* subexprs = expr->values();
4350 int length = subexprs->length(); 4356 int length = subexprs->length();
4351 HValue* context = environment()->LookupContext(); 4357 HValue* context = environment()->context();
4352 HInstruction* literal; 4358 HInstruction* literal;
4353 4359
4354 Handle<AllocationSite> site; 4360 Handle<AllocationSite> site;
4355 Handle<FixedArray> literals(environment()->closure()->literals(), isolate()); 4361 Handle<FixedArray> literals(environment()->closure()->literals(), isolate());
4356 bool uninitialized = false; 4362 bool uninitialized = false;
4357 Handle<Object> literals_cell(literals->get(expr->literal_index()), 4363 Handle<Object> literals_cell(literals->get(expr->literal_index()),
4358 isolate()); 4364 isolate());
4359 Handle<Object> raw_boilerplate; 4365 Handle<Object> raw_boilerplate;
4360 if (literals_cell->IsUndefined()) { 4366 if (literals_cell->IsUndefined()) {
4361 uninitialized = true; 4367 uninitialized = true;
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
4420 // pass an empty fixed array to the runtime function instead. 4426 // pass an empty fixed array to the runtime function instead.
4421 Handle<FixedArray> constants = isolate()->factory()->empty_fixed_array(); 4427 Handle<FixedArray> constants = isolate()->factory()->empty_fixed_array();
4422 int literal_index = expr->literal_index(); 4428 int literal_index = expr->literal_index();
4423 4429
4424 Add<HPushArgument>(Add<HConstant>(literals)); 4430 Add<HPushArgument>(Add<HConstant>(literals));
4425 Add<HPushArgument>(Add<HConstant>(literal_index)); 4431 Add<HPushArgument>(Add<HConstant>(literal_index));
4426 Add<HPushArgument>(Add<HConstant>(constants)); 4432 Add<HPushArgument>(Add<HConstant>(constants));
4427 4433
4428 Runtime::FunctionId function_id = (expr->depth() > 1) 4434 Runtime::FunctionId function_id = (expr->depth() > 1)
4429 ? Runtime::kCreateArrayLiteral : Runtime::kCreateArrayLiteralShallow; 4435 ? Runtime::kCreateArrayLiteral : Runtime::kCreateArrayLiteralShallow;
4430 literal = Add<HCallRuntime>(context, 4436 literal = Add<HCallRuntime>(isolate()->factory()->empty_string(),
4431 isolate()->factory()->empty_string(),
4432 Runtime::FunctionForId(function_id), 4437 Runtime::FunctionForId(function_id),
4433 3); 4438 3);
4434 4439
4435 // De-opt if elements kind changed from boilerplate_elements_kind. 4440 // De-opt if elements kind changed from boilerplate_elements_kind.
4436 Handle<Map> map = Handle<Map>(original_boilerplate_object->map(), 4441 Handle<Map> map = Handle<Map>(original_boilerplate_object->map(),
4437 isolate()); 4442 isolate());
4438 AddInstruction(HCheckMaps::New(literal, map, zone(), top_info())); 4443 AddInstruction(HCheckMaps::New(literal, map, zone(), top_info()));
4439 } 4444 }
4440 4445
4441 // The array is expected in the bailout environment during computation 4446 // The array is expected in the bailout environment during computation
(...skipping 18 matching lines...) Expand all
4460 4465
4461 HValue* key = Add<HConstant>(i); 4466 HValue* key = Add<HConstant>(i);
4462 4467
4463 switch (boilerplate_elements_kind) { 4468 switch (boilerplate_elements_kind) {
4464 case FAST_SMI_ELEMENTS: 4469 case FAST_SMI_ELEMENTS:
4465 case FAST_HOLEY_SMI_ELEMENTS: 4470 case FAST_HOLEY_SMI_ELEMENTS:
4466 case FAST_ELEMENTS: 4471 case FAST_ELEMENTS:
4467 case FAST_HOLEY_ELEMENTS: 4472 case FAST_HOLEY_ELEMENTS:
4468 case FAST_DOUBLE_ELEMENTS: 4473 case FAST_DOUBLE_ELEMENTS:
4469 case FAST_HOLEY_DOUBLE_ELEMENTS: { 4474 case FAST_HOLEY_DOUBLE_ELEMENTS: {
4470 HStoreKeyed* instr = Add<HStoreKeyed>(elements, key, value, 4475 HStoreKeyed* instr = AddAndCast<HStoreKeyed>(elements, key, value,
4471 boilerplate_elements_kind); 4476 boilerplate_elements_kind);
4472 instr->SetUninitialized(uninitialized); 4477 instr->SetUninitialized(uninitialized);
4473 break; 4478 break;
4474 } 4479 }
4475 default: 4480 default:
4476 UNREACHABLE(); 4481 UNREACHABLE();
4477 break; 4482 break;
4478 } 4483 }
4479 4484
4480 Add<HSimulate>(expr->GetIdForElement(i)); 4485 Add<HSimulate>(expr->GetIdForElement(i));
4481 } 4486 }
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
4548 // We only need to check up to the preexisting property. 4553 // We only need to check up to the preexisting property.
4549 proto = proto_result.holder(); 4554 proto = proto_result.holder();
4550 } else { 4555 } else {
4551 // Otherwise, find the top prototype. 4556 // Otherwise, find the top prototype.
4552 while (proto->GetPrototype(isolate())->IsJSObject()) { 4557 while (proto->GetPrototype(isolate())->IsJSObject()) {
4553 proto = proto->GetPrototype(isolate()); 4558 proto = proto->GetPrototype(isolate());
4554 } 4559 }
4555 ASSERT(proto->GetPrototype(isolate())->IsNull()); 4560 ASSERT(proto->GetPrototype(isolate())->IsNull());
4556 } 4561 }
4557 ASSERT(proto->IsJSObject()); 4562 ASSERT(proto->IsJSObject());
4558 Add<HCheckPrototypeMaps>(Handle<JSObject>(JSObject::cast(map->prototype())), 4563 Add<HCheckPrototypeMaps>(
4559 Handle<JSObject>(JSObject::cast(proto)), 4564 Handle<JSObject>(JSObject::cast(map->prototype())),
4560 zone(), top_info()); 4565 Handle<JSObject>(JSObject::cast(proto)), top_info());
4561 } 4566 }
4562 4567
4563 HObjectAccess field_access = HObjectAccess::ForField(map, lookup, name); 4568 HObjectAccess field_access = HObjectAccess::ForField(map, lookup, name);
4564 bool transition_to_field = lookup->IsTransitionToField(*map); 4569 bool transition_to_field = lookup->IsTransitionToField(*map);
4565 4570
4566 HStoreNamedField *instr; 4571 HStoreNamedField *instr;
4567 if (FLAG_track_double_fields && field_access.representation().IsDouble()) { 4572 if (FLAG_track_double_fields && field_access.representation().IsDouble()) {
4568 HObjectAccess heap_number_access = 4573 HObjectAccess heap_number_access =
4569 field_access.WithRepresentation(Representation::Tagged()); 4574 field_access.WithRepresentation(Representation::Tagged());
4570 if (transition_to_field) { 4575 if (transition_to_field) {
4571 // The store requires a mutable HeapNumber to be allocated. 4576 // The store requires a mutable HeapNumber to be allocated.
4572 NoObservableSideEffectsScope no_side_effects(this); 4577 NoObservableSideEffectsScope no_side_effects(this);
4573 HInstruction* heap_number_size = Add<HConstant>(HeapNumber::kSize); 4578 HInstruction* heap_number_size = Add<HConstant>(HeapNumber::kSize);
4574 HInstruction* heap_number = Add<HAllocate>( 4579 HInstruction* heap_number = Add<HAllocate>(heap_number_size,
4575 environment()->LookupContext(), heap_number_size,
4576 HType::HeapNumber(), HAllocate::CAN_ALLOCATE_IN_NEW_SPACE); 4580 HType::HeapNumber(), HAllocate::CAN_ALLOCATE_IN_NEW_SPACE);
4577 AddStoreMapConstant(heap_number, isolate()->factory()->heap_number_map()); 4581 AddStoreMapConstant(heap_number, isolate()->factory()->heap_number_map());
4578 AddStore(heap_number, HObjectAccess::ForHeapNumberValue(), value); 4582 Add<HStoreNamedField>(heap_number, HObjectAccess::ForHeapNumberValue(),
4579 instr = new(zone()) HStoreNamedField( 4583 value);
4580 object, heap_number_access, heap_number); 4584 instr = NewAndCast<HStoreNamedField>(object, heap_number_access,
4585 heap_number);
4581 } else { 4586 } else {
4582 // Already holds a HeapNumber; load the box and write its value field. 4587 // Already holds a HeapNumber; load the box and write its value field.
4583 HInstruction* heap_number = AddLoad(object, heap_number_access); 4588 HInstruction* heap_number = Add<HLoadNamedField>(object,
4589 heap_number_access);
4584 heap_number->set_type(HType::HeapNumber()); 4590 heap_number->set_type(HType::HeapNumber());
4585 instr = new(zone()) HStoreNamedField(heap_number, 4591 instr = NewAndCast<HStoreNamedField>(heap_number,
4586 HObjectAccess::ForHeapNumberValue(), value); 4592 HObjectAccess::ForHeapNumberValue(),
4593 value);
4587 } 4594 }
4588 } else { 4595 } else {
4589 // This is a normal store. 4596 // This is a normal store.
4590 instr = new(zone()) HStoreNamedField(object, field_access, value); 4597 instr = NewAndCast<HStoreNamedField>(object, field_access, value);
4591 } 4598 }
4592 4599
4593 if (transition_to_field) { 4600 if (transition_to_field) {
4594 Handle<Map> transition(lookup->GetTransitionMapFromMap(*map)); 4601 Handle<Map> transition(lookup->GetTransitionMapFromMap(*map));
4595 instr->SetTransition(transition, top_info()); 4602 instr->SetTransition(transition, top_info());
4596 // TODO(fschneider): Record the new map type of the object in the IR to 4603 // TODO(fschneider): Record the new map type of the object in the IR to
4597 // enable elimination of redundant checks after the transition store. 4604 // enable elimination of redundant checks after the transition store.
4598 instr->SetGVNFlag(kChangesMaps); 4605 instr->SetGVNFlag(kChangesMaps);
4599 } 4606 }
4600 return instr; 4607 return instr;
4601 } 4608 }
4602 4609
4603 4610
4604 HInstruction* HOptimizedGraphBuilder::BuildStoreNamedGeneric( 4611 HInstruction* HOptimizedGraphBuilder::BuildStoreNamedGeneric(
4605 HValue* object, 4612 HValue* object,
4606 Handle<String> name, 4613 Handle<String> name,
4607 HValue* value) { 4614 HValue* value) {
4608 HValue* context = environment()->LookupContext(); 4615 HValue* context = environment()->context();
4609 return new(zone()) HStoreNamedGeneric( 4616 return new(zone()) HStoreNamedGeneric(
4610 context, 4617 context,
4611 object, 4618 object,
4612 name, 4619 name,
4613 value, 4620 value,
4614 function_strict_mode_flag()); 4621 function_strict_mode_flag());
4615 } 4622 }
4616 4623
4617 4624
4618 HInstruction* HOptimizedGraphBuilder::BuildStoreNamedMonomorphic( 4625 HInstruction* HOptimizedGraphBuilder::BuildStoreNamedMonomorphic(
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
4701 } 4708 }
4702 4709
4703 LookupInPrototypes(map, name, &lookup); 4710 LookupInPrototypes(map, name, &lookup);
4704 if (!lookup.IsField()) return NULL; 4711 if (!lookup.IsField()) return NULL;
4705 4712
4706 BuildCheckHeapObject(object); 4713 BuildCheckHeapObject(object);
4707 AddInstruction(HCheckMaps::New(object, types, zone())); 4714 AddInstruction(HCheckMaps::New(object, types, zone()));
4708 4715
4709 Handle<JSObject> holder(lookup.holder()); 4716 Handle<JSObject> holder(lookup.holder());
4710 Handle<Map> holder_map(holder->map()); 4717 Handle<Map> holder_map(holder->map());
4711 AddInstruction(new(zone()) HCheckPrototypeMaps( 4718 Add<HCheckPrototypeMaps>(
4712 Handle<JSObject>::cast(prototype), holder, zone(), top_info())); 4719 Handle<JSObject>::cast(prototype), holder, top_info());
4713 HValue* holder_value = AddInstruction(new(zone()) HConstant(holder)); 4720 HValue* holder_value = Add<HConstant>(holder);
4714 return BuildLoadNamedField(holder_value, 4721 return BuildLoadNamedField(holder_value,
4715 HObjectAccess::ForField(holder_map, &lookup, name)); 4722 HObjectAccess::ForField(holder_map, &lookup, name));
4716 } 4723 }
4717 4724
4718 4725
4719 void HOptimizedGraphBuilder::HandlePolymorphicLoadNamedField( 4726 void HOptimizedGraphBuilder::HandlePolymorphicLoadNamedField(
4720 Property* expr, 4727 Property* expr,
4721 HValue* object, 4728 HValue* object,
4722 SmallMapList* types, 4729 SmallMapList* types,
4723 Handle<String> name) { 4730 Handle<String> name) {
4724 HInstruction* instr = TryLoadPolymorphicAsMonomorphic( 4731 HInstruction* instr = TryLoadPolymorphicAsMonomorphic(
4725 expr, object, types, name); 4732 expr, object, types, name);
4726 if (instr == NULL) { 4733 if (instr == NULL) {
4727 // Something did not match; must use a polymorphic load. 4734 // Something did not match; must use a polymorphic load.
4728 BuildCheckHeapObject(object); 4735 BuildCheckHeapObject(object);
4729 HValue* context = environment()->LookupContext(); 4736 HValue* context = environment()->context();
4730 instr = new(zone()) HLoadNamedFieldPolymorphic( 4737 instr = new(zone()) HLoadNamedFieldPolymorphic(
4731 context, object, types, name, zone()); 4738 context, object, types, name, zone());
4732 } 4739 }
4733 4740
4734 instr->set_position(expr->position()); 4741 instr->set_position(expr->position());
4735 return ast_context()->ReturnInstruction(instr, expr->id()); 4742 return ast_context()->ReturnInstruction(instr, expr->id());
4736 } 4743 }
4737 4744
4738 4745
4739 bool HOptimizedGraphBuilder::TryStorePolymorphicAsMonomorphic( 4746 bool HOptimizedGraphBuilder::TryStorePolymorphicAsMonomorphic(
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after
4948 Add<HDeoptimize>(Deoptimizer::EAGER); 4955 Add<HDeoptimize>(Deoptimizer::EAGER);
4949 builder.End(); 4956 builder.End();
4950 } 4957 }
4951 HInstruction* instr = 4958 HInstruction* instr =
4952 Add<HStoreGlobalCell>(value, cell, lookup.GetPropertyDetails()); 4959 Add<HStoreGlobalCell>(value, cell, lookup.GetPropertyDetails());
4953 instr->set_position(position); 4960 instr->set_position(position);
4954 if (instr->HasObservableSideEffects()) { 4961 if (instr->HasObservableSideEffects()) {
4955 Add<HSimulate>(ast_id, REMOVABLE_SIMULATE); 4962 Add<HSimulate>(ast_id, REMOVABLE_SIMULATE);
4956 } 4963 }
4957 } else { 4964 } else {
4958 HValue* context = environment()->LookupContext(); 4965 HGlobalObject* global_object = AddAndCast<HGlobalObject>();
4959 HGlobalObject* global_object = Add<HGlobalObject>(context);
4960 HStoreGlobalGeneric* instr = 4966 HStoreGlobalGeneric* instr =
4961 Add<HStoreGlobalGeneric>(context, global_object, var->name(), 4967 AddAndCast<HStoreGlobalGeneric>(global_object, var->name(),
4962 value, function_strict_mode_flag()); 4968 value, function_strict_mode_flag());
4963 instr->set_position(position); 4969 instr->set_position(position);
4964 ASSERT(instr->HasObservableSideEffects()); 4970 ASSERT(instr->HasObservableSideEffects());
4965 Add<HSimulate>(ast_id, REMOVABLE_SIMULATE); 4971 Add<HSimulate>(ast_id, REMOVABLE_SIMULATE);
4966 } 4972 }
4967 } 4973 }
4968 4974
4969 4975
4970 void HOptimizedGraphBuilder::BuildStoreNamed(Expression* expr, 4976 void HOptimizedGraphBuilder::BuildStoreNamed(Expression* expr,
4971 BailoutId id, 4977 BailoutId id,
4972 int position, 4978 int position,
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
5092 return ast_context()->ReturnValue(Pop()); 5098 return ast_context()->ReturnValue(Pop());
5093 case CONST_HARMONY: 5099 case CONST_HARMONY:
5094 // This case is checked statically so no need to 5100 // This case is checked statically so no need to
5095 // perform checks here 5101 // perform checks here
5096 UNREACHABLE(); 5102 UNREACHABLE();
5097 default: 5103 default:
5098 mode = HStoreContextSlot::kNoCheck; 5104 mode = HStoreContextSlot::kNoCheck;
5099 } 5105 }
5100 5106
5101 HValue* context = BuildContextChainWalk(var); 5107 HValue* context = BuildContextChainWalk(var);
5102 HStoreContextSlot* instr = Add<HStoreContextSlot>(context, var->index(), 5108 HStoreContextSlot* instr = AddAndCast<HStoreContextSlot>(
5103 mode, Top()); 5109 context, var->index(), mode, Top());
5104 if (instr->HasObservableSideEffects()) { 5110 if (instr->HasObservableSideEffects()) {
5105 Add<HSimulate>(expr->AssignmentId(), REMOVABLE_SIMULATE); 5111 Add<HSimulate>(expr->AssignmentId(), REMOVABLE_SIMULATE);
5106 } 5112 }
5107 break; 5113 break;
5108 } 5114 }
5109 5115
5110 case Variable::LOOKUP: 5116 case Variable::LOOKUP:
5111 return Bailout("compound assignment to lookup slot"); 5117 return Bailout("compound assignment to lookup slot");
5112 } 5118 }
5113 return ast_context()->ReturnValue(Pop()); 5119 return ast_context()->ReturnValue(Pop());
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after
5304 expr->op() == Token::INIT_LET || 5310 expr->op() == Token::INIT_LET ||
5305 expr->op() == Token::INIT_CONST_HARMONY) { 5311 expr->op() == Token::INIT_CONST_HARMONY) {
5306 mode = HStoreContextSlot::kNoCheck; 5312 mode = HStoreContextSlot::kNoCheck;
5307 } else { 5313 } else {
5308 ASSERT(expr->op() == Token::INIT_CONST); 5314 ASSERT(expr->op() == Token::INIT_CONST);
5309 5315
5310 mode = HStoreContextSlot::kCheckIgnoreAssignment; 5316 mode = HStoreContextSlot::kCheckIgnoreAssignment;
5311 } 5317 }
5312 5318
5313 HValue* context = BuildContextChainWalk(var); 5319 HValue* context = BuildContextChainWalk(var);
5314 HStoreContextSlot* instr = Add<HStoreContextSlot>(context, var->index(), 5320 HStoreContextSlot* instr = AddAndCast<HStoreContextSlot>(
5315 mode, Top()); 5321 context, var->index(), mode, Top());
5316 if (instr->HasObservableSideEffects()) { 5322 if (instr->HasObservableSideEffects()) {
5317 Add<HSimulate>(expr->AssignmentId(), REMOVABLE_SIMULATE); 5323 Add<HSimulate>(expr->AssignmentId(), REMOVABLE_SIMULATE);
5318 } 5324 }
5319 return ast_context()->ReturnValue(Pop()); 5325 return ast_context()->ReturnValue(Pop());
5320 } 5326 }
5321 5327
5322 case Variable::LOOKUP: 5328 case Variable::LOOKUP:
5323 return Bailout("assignment to LOOKUP variable"); 5329 return Bailout("assignment to LOOKUP variable");
5324 } 5330 }
5325 } else { 5331 } else {
(...skipping 11 matching lines...) Expand all
5337 void HOptimizedGraphBuilder::VisitThrow(Throw* expr) { 5343 void HOptimizedGraphBuilder::VisitThrow(Throw* expr) {
5338 ASSERT(!HasStackOverflow()); 5344 ASSERT(!HasStackOverflow());
5339 ASSERT(current_block() != NULL); 5345 ASSERT(current_block() != NULL);
5340 ASSERT(current_block()->HasPredecessor()); 5346 ASSERT(current_block()->HasPredecessor());
5341 // We don't optimize functions with invalid left-hand sides in 5347 // We don't optimize functions with invalid left-hand sides in
5342 // assignments, count operations, or for-in. Consequently throw can 5348 // assignments, count operations, or for-in. Consequently throw can
5343 // currently only occur in an effect context. 5349 // currently only occur in an effect context.
5344 ASSERT(ast_context()->IsEffect()); 5350 ASSERT(ast_context()->IsEffect());
5345 CHECK_ALIVE(VisitForValue(expr->exception())); 5351 CHECK_ALIVE(VisitForValue(expr->exception()));
5346 5352
5347 HValue* context = environment()->LookupContext();
5348 HValue* value = environment()->Pop(); 5353 HValue* value = environment()->Pop();
5349 HThrow* instr = Add<HThrow>(context, value); 5354 HThrow* instr = AddAndCast<HThrow>(value);
5350 instr->set_position(expr->position()); 5355 instr->set_position(expr->position());
5351 Add<HSimulate>(expr->id()); 5356 Add<HSimulate>(expr->id());
5352 current_block()->FinishExit(new(zone()) HAbnormalExit); 5357 current_block()->FinishExit(new(zone()) HAbnormalExit);
5353 set_current_block(NULL); 5358 set_current_block(NULL);
5354 } 5359 }
5355 5360
5356 5361
5357 HLoadNamedField* HGraphBuilder::BuildLoadNamedField(HValue* object, 5362 HLoadNamedField* HGraphBuilder::BuildLoadNamedField(HValue* object,
5358 HObjectAccess access) { 5363 HObjectAccess access) {
5359 if (FLAG_track_double_fields && access.representation().IsDouble()) { 5364 if (FLAG_track_double_fields && access.representation().IsDouble()) {
5360 // load the heap number 5365 // load the heap number
5361 HLoadNamedField* heap_number = 5366 HLoadNamedField* heap_number = AddAndCast<HLoadNamedField>(
5362 AddLoad(object, access.WithRepresentation(Representation::Tagged())); 5367 object, access.WithRepresentation(Representation::Tagged()));
5363 heap_number->set_type(HType::HeapNumber()); 5368 heap_number->set_type(HType::HeapNumber());
5364 // load the double value from it 5369 // load the double value from it
5365 return new(zone()) HLoadNamedField(heap_number, 5370 return NewAndCast<HLoadNamedField>(heap_number,
5366 HObjectAccess::ForHeapNumberValue(), NULL); 5371 HObjectAccess::ForHeapNumberValue());
5367 } 5372 }
5368 return new(zone()) HLoadNamedField(object, access, NULL); 5373 return NewAndCast<HLoadNamedField>(object, access);
5369 } 5374 }
5370 5375
5371 5376
5372 HInstruction* HOptimizedGraphBuilder::BuildLoadNamedGeneric( 5377 HInstruction* HOptimizedGraphBuilder::BuildLoadNamedGeneric(
5373 HValue* object, 5378 HValue* object,
5374 Handle<String> name, 5379 Handle<String> name,
5375 Property* expr) { 5380 Property* expr) {
5376 if (expr->IsUninitialized()) { 5381 if (expr->IsUninitialized()) {
5377 Add<HDeoptimize>(Deoptimizer::SOFT); 5382 Add<HDeoptimize>(Deoptimizer::SOFT);
5378 } 5383 }
5379 HValue* context = environment()->LookupContext(); 5384 HValue* context = environment()->context();
5380 return new(zone()) HLoadNamedGeneric(context, object, name); 5385 return new(zone()) HLoadNamedGeneric(context, object, name);
5381 } 5386 }
5382 5387
5383 5388
5384 HInstruction* HOptimizedGraphBuilder::BuildCallGetter( 5389 HInstruction* HOptimizedGraphBuilder::BuildCallGetter(
5385 HValue* object, 5390 HValue* object,
5386 Handle<Map> map, 5391 Handle<Map> map,
5387 Handle<JSFunction> getter, 5392 Handle<JSFunction> getter,
5388 Handle<JSObject> holder) { 5393 Handle<JSObject> holder) {
5389 AddCheckConstantFunction(holder, object, map); 5394 AddCheckConstantFunction(holder, object, map);
5390 Add<HPushArgument>(object); 5395 Add<HPushArgument>(object);
5391 return new(zone()) HCallConstantFunction(getter, 1); 5396 return new(zone()) HCallConstantFunction(getter, 1);
5392 } 5397 }
5393 5398
5394 5399
5395 HInstruction* HOptimizedGraphBuilder::BuildLoadNamedMonomorphic( 5400 HInstruction* HOptimizedGraphBuilder::BuildLoadNamedMonomorphic(
5396 HValue* object, 5401 HValue* object,
5397 Handle<String> name, 5402 Handle<String> name,
5398 Property* expr, 5403 Property* expr,
5399 Handle<Map> map) { 5404 Handle<Map> map) {
5400 // Handle a load from a known field. 5405 // Handle a load from a known field.
5401 ASSERT(!map->is_dictionary_map()); 5406 ASSERT(!map->is_dictionary_map());
5402 5407
5403 // Handle access to various length properties 5408 // Handle access to various length properties
5404 if (name->Equals(isolate()->heap()->length_string())) { 5409 if (name->Equals(isolate()->heap()->length_string())) {
5405 if (map->instance_type() == JS_ARRAY_TYPE) { 5410 if (map->instance_type() == JS_ARRAY_TYPE) {
5406 AddCheckMapsWithTransitions(object, map); 5411 AddCheckMapsWithTransitions(object, map);
5407 return new(zone()) HLoadNamedField(object, 5412 return New<HLoadNamedField>(object,
5408 HObjectAccess::ForArrayLength(map->elements_kind())); 5413 HObjectAccess::ForArrayLength(map->elements_kind()));
5409 } 5414 }
5410 } 5415 }
5411 5416
5412 LookupResult lookup(isolate()); 5417 LookupResult lookup(isolate());
5413 map->LookupDescriptor(NULL, *name, &lookup); 5418 map->LookupDescriptor(NULL, *name, &lookup);
5414 if (lookup.IsField()) { 5419 if (lookup.IsField()) {
5415 AddCheckMap(object, map); 5420 AddCheckMap(object, map);
5416 return BuildLoadNamedField(object, 5421 return BuildLoadNamedField(object,
5417 HObjectAccess::ForField(map, &lookup, name)); 5422 HObjectAccess::ForField(map, &lookup, name));
5418 } 5423 }
5419 5424
5420 // Handle a load of a constant known function. 5425 // Handle a load of a constant known function.
5421 if (lookup.IsConstant()) { 5426 if (lookup.IsConstant()) {
5422 AddCheckMap(object, map); 5427 AddCheckMap(object, map);
5423 Handle<Object> constant(lookup.GetConstantFromMap(*map), isolate()); 5428 Handle<Object> constant(lookup.GetConstantFromMap(*map), isolate());
5424 return new(zone()) HConstant(constant); 5429 return New<HConstant>(constant);
5425 } 5430 }
5426 5431
5427 // Handle a load from a known field somewhere in the prototype chain. 5432 // Handle a load from a known field somewhere in the prototype chain.
5428 LookupInPrototypes(map, name, &lookup); 5433 LookupInPrototypes(map, name, &lookup);
5429 if (lookup.IsField()) { 5434 if (lookup.IsField()) {
5430 Handle<JSObject> prototype(JSObject::cast(map->prototype())); 5435 Handle<JSObject> prototype(JSObject::cast(map->prototype()));
5431 Handle<JSObject> holder(lookup.holder()); 5436 Handle<JSObject> holder(lookup.holder());
5432 Handle<Map> holder_map(holder->map()); 5437 Handle<Map> holder_map(holder->map());
5433 AddCheckMap(object, map); 5438 AddCheckMap(object, map);
5434 Add<HCheckPrototypeMaps>(prototype, holder, zone(), top_info()); 5439 Add<HCheckPrototypeMaps>(prototype, holder, top_info());
5435 HValue* holder_value = Add<HConstant>(holder); 5440 HValue* holder_value = Add<HConstant>(holder);
5436 return BuildLoadNamedField(holder_value, 5441 return BuildLoadNamedField(holder_value,
5437 HObjectAccess::ForField(holder_map, &lookup, name)); 5442 HObjectAccess::ForField(holder_map, &lookup, name));
5438 } 5443 }
5439 5444
5440 // Handle a load of a constant function somewhere in the prototype chain. 5445 // Handle a load of a constant function somewhere in the prototype chain.
5441 if (lookup.IsConstant()) { 5446 if (lookup.IsConstant()) {
5442 Handle<JSObject> prototype(JSObject::cast(map->prototype())); 5447 Handle<JSObject> prototype(JSObject::cast(map->prototype()));
5443 Handle<JSObject> holder(lookup.holder()); 5448 Handle<JSObject> holder(lookup.holder());
5444 Handle<Map> holder_map(holder->map()); 5449 Handle<Map> holder_map(holder->map());
5445 AddCheckMap(object, map); 5450 AddCheckMap(object, map);
5446 Add<HCheckPrototypeMaps>(prototype, holder, zone(), top_info()); 5451 Add<HCheckPrototypeMaps>(prototype, holder, top_info());
5447 Handle<Object> constant(lookup.GetConstantFromMap(*holder_map), isolate()); 5452 Handle<Object> constant(lookup.GetConstantFromMap(*holder_map), isolate());
5448 return new(zone()) HConstant(constant); 5453 return New<HConstant>(constant);
5449 } 5454 }
5450 5455
5451 // No luck, do a generic load. 5456 // No luck, do a generic load.
5452 return BuildLoadNamedGeneric(object, name, expr); 5457 return BuildLoadNamedGeneric(object, name, expr);
5453 } 5458 }
5454 5459
5455 5460
5456 HInstruction* HOptimizedGraphBuilder::BuildLoadKeyedGeneric(HValue* object, 5461 HInstruction* HOptimizedGraphBuilder::BuildLoadKeyedGeneric(HValue* object,
5457 HValue* key) { 5462 HValue* key) {
5458 HValue* context = environment()->LookupContext(); 5463 HValue* context = environment()->context();
5459 return new(zone()) HLoadKeyedGeneric(context, object, key); 5464 return new(zone()) HLoadKeyedGeneric(context, object, key);
5460 } 5465 }
5461 5466
5462 5467
5463 HInstruction* HOptimizedGraphBuilder::BuildMonomorphicElementAccess( 5468 HInstruction* HOptimizedGraphBuilder::BuildMonomorphicElementAccess(
5464 HValue* object, 5469 HValue* object,
5465 HValue* key, 5470 HValue* key,
5466 HValue* val, 5471 HValue* val,
5467 HValue* dependency, 5472 HValue* dependency,
5468 Handle<Map> map, 5473 Handle<Map> map,
5469 bool is_store, 5474 bool is_store,
5470 KeyedAccessStoreMode store_mode) { 5475 KeyedAccessStoreMode store_mode) {
5471 HCheckMaps* mapcheck = HCheckMaps::New( 5476 HCheckMaps* mapcheck = HCheckMaps::New(
5472 object, map, zone(), top_info(), dependency); 5477 object, map, zone(), top_info(), dependency);
5473 AddInstruction(mapcheck); 5478 AddInstruction(mapcheck);
5474 if (dependency) { 5479 if (dependency) {
5475 mapcheck->ClearGVNFlag(kDependsOnElementsKind); 5480 mapcheck->ClearGVNFlag(kDependsOnElementsKind);
5476 } 5481 }
5477 5482
5478 // Loads from a "stock" fast holey double arrays can elide the hole check. 5483 // Loads from a "stock" fast holey double arrays can elide the hole check.
5479 LoadKeyedHoleMode load_mode = NEVER_RETURN_HOLE; 5484 LoadKeyedHoleMode load_mode = NEVER_RETURN_HOLE;
5480 if (*map == isolate()->get_initial_js_array_map(FAST_HOLEY_DOUBLE_ELEMENTS) && 5485 if (*map == isolate()->get_initial_js_array_map(FAST_HOLEY_DOUBLE_ELEMENTS) &&
5481 isolate()->IsFastArrayConstructorPrototypeChainIntact()) { 5486 isolate()->IsFastArrayConstructorPrototypeChainIntact()) {
5482 Handle<JSObject> prototype(JSObject::cast(map->prototype()), isolate()); 5487 Handle<JSObject> prototype(JSObject::cast(map->prototype()), isolate());
5483 Handle<JSObject> object_prototype = isolate()->initial_object_prototype(); 5488 Handle<JSObject> object_prototype = isolate()->initial_object_prototype();
5484 Add<HCheckPrototypeMaps>(prototype, object_prototype, zone(), top_info()); 5489 Add<HCheckPrototypeMaps>(prototype, object_prototype, top_info());
5485 load_mode = ALLOW_RETURN_HOLE; 5490 load_mode = ALLOW_RETURN_HOLE;
5486 graph()->MarkDependsOnEmptyArrayProtoElements(); 5491 graph()->MarkDependsOnEmptyArrayProtoElements();
5487 } 5492 }
5488 5493
5489 return BuildUncheckedMonomorphicElementAccess( 5494 return BuildUncheckedMonomorphicElementAccess(
5490 object, key, val, 5495 object, key, val,
5491 mapcheck, map->instance_type() == JS_ARRAY_TYPE, 5496 mapcheck, map->instance_type() == JS_ARRAY_TYPE,
5492 map->elements_kind(), is_store, load_mode, store_mode); 5497 map->elements_kind(), is_store, load_mode, store_mode);
5493 } 5498 }
5494 5499
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
5597 5602
5598 MapHandleList untransitionable_maps(maps->length()); 5603 MapHandleList untransitionable_maps(maps->length());
5599 HTransitionElementsKind* transition = NULL; 5604 HTransitionElementsKind* transition = NULL;
5600 for (int i = 0; i < maps->length(); ++i) { 5605 for (int i = 0; i < maps->length(); ++i) {
5601 Handle<Map> map = maps->at(i); 5606 Handle<Map> map = maps->at(i);
5602 ASSERT(map->IsMap()); 5607 ASSERT(map->IsMap());
5603 if (!transition_target.at(i).is_null()) { 5608 if (!transition_target.at(i).is_null()) {
5604 ASSERT(Map::IsValidElementsTransition( 5609 ASSERT(Map::IsValidElementsTransition(
5605 map->elements_kind(), 5610 map->elements_kind(),
5606 transition_target.at(i)->elements_kind())); 5611 transition_target.at(i)->elements_kind()));
5607 HValue* context = environment()->LookupContext(); 5612 transition = AddAndCast<HTransitionElementsKind>(object, map,
5608 transition = Add<HTransitionElementsKind>(context, object, map, 5613 transition_target.at(i));
5609 transition_target.at(i));
5610 } else { 5614 } else {
5611 untransitionable_maps.Add(map); 5615 untransitionable_maps.Add(map);
5612 } 5616 }
5613 } 5617 }
5614 5618
5615 // If only one map is left after transitioning, handle this case 5619 // If only one map is left after transitioning, handle this case
5616 // monomorphically. 5620 // monomorphically.
5617 ASSERT(untransitionable_maps.length() >= 1); 5621 ASSERT(untransitionable_maps.length() >= 1);
5618 if (untransitionable_maps.length() == 1) { 5622 if (untransitionable_maps.length() == 1) {
5619 Handle<Map> untransitionable_map = untransitionable_maps[0]; 5623 Handle<Map> untransitionable_map = untransitionable_maps[0];
(...skipping 29 matching lines...) Expand all
5649 set_current_block(this_map); 5653 set_current_block(this_map);
5650 HInstruction* checked_key = NULL; 5654 HInstruction* checked_key = NULL;
5651 HInstruction* access = NULL; 5655 HInstruction* access = NULL;
5652 if (IsFastElementsKind(elements_kind)) { 5656 if (IsFastElementsKind(elements_kind)) {
5653 if (is_store && !IsFastDoubleElementsKind(elements_kind)) { 5657 if (is_store && !IsFastDoubleElementsKind(elements_kind)) {
5654 AddInstruction(HCheckMaps::New( 5658 AddInstruction(HCheckMaps::New(
5655 elements, isolate()->factory()->fixed_array_map(), 5659 elements, isolate()->factory()->fixed_array_map(),
5656 zone(), top_info(), mapcompare)); 5660 zone(), top_info(), mapcompare));
5657 } 5661 }
5658 if (map->instance_type() == JS_ARRAY_TYPE) { 5662 if (map->instance_type() == JS_ARRAY_TYPE) {
5659 HInstruction* length = AddLoad( 5663 HInstruction* length = Add<HLoadNamedField>(
5660 object, HObjectAccess::ForArrayLength(elements_kind), mapcompare); 5664 object, HObjectAccess::ForArrayLength(elements_kind), mapcompare);
5661 checked_key = Add<HBoundsCheck>(key, length); 5665 checked_key = Add<HBoundsCheck>(key, length);
5662 } else { 5666 } else {
5663 HInstruction* length = AddLoadFixedArrayLength(elements); 5667 HInstruction* length = AddLoadFixedArrayLength(elements);
5664 checked_key = Add<HBoundsCheck>(key, length); 5668 checked_key = Add<HBoundsCheck>(key, length);
5665 } 5669 }
5666 access = AddFastElementAccess( 5670 access = AddFastElementAccess(
5667 elements, checked_key, val, mapcompare, 5671 elements, checked_key, val, mapcompare,
5668 elements_kind, is_store, NEVER_RETURN_HOLE, STANDARD_STORE); 5672 elements_kind, is_store, NEVER_RETURN_HOLE, STANDARD_STORE);
5669 } else if (IsDictionaryElementsKind(elements_kind)) { 5673 } else if (IsDictionaryElementsKind(elements_kind)) {
5670 if (is_store) { 5674 if (is_store) {
5671 access = AddInstruction(BuildStoreKeyedGeneric(object, key, val)); 5675 access = AddInstruction(BuildStoreKeyedGeneric(object, key, val));
5672 } else { 5676 } else {
5673 access = AddInstruction(BuildLoadKeyedGeneric(object, key)); 5677 access = AddInstruction(BuildLoadKeyedGeneric(object, key));
5674 } 5678 }
5675 } else { 5679 } else {
5676 ASSERT(IsExternalArrayElementsKind(elements_kind)); 5680 ASSERT(IsExternalArrayElementsKind(elements_kind));
5677 HInstruction* length = AddLoadFixedArrayLength(elements); 5681 HInstruction* length = AddLoadFixedArrayLength(elements);
5678 checked_key = Add<HBoundsCheck>(key, length); 5682 checked_key = Add<HBoundsCheck>(key, length);
5679 HLoadExternalArrayPointer* external_elements = 5683 HLoadExternalArrayPointer* external_elements =
5680 Add<HLoadExternalArrayPointer>(elements); 5684 AddAndCast<HLoadExternalArrayPointer>(elements);
5681 access = AddExternalArrayElementAccess( 5685 access = AddExternalArrayElementAccess(
5682 external_elements, checked_key, val, 5686 external_elements, checked_key, val,
5683 mapcompare, elements_kind, is_store); 5687 mapcompare, elements_kind, is_store);
5684 } 5688 }
5685 *has_side_effects |= access->HasObservableSideEffects(); 5689 *has_side_effects |= access->HasObservableSideEffects();
5686 // The caller will use has_side_effects and add a correct Simulate. 5690 // The caller will use has_side_effects and add a correct Simulate.
5687 access->SetFlag(HValue::kHasNoObservableSideEffects); 5691 access->SetFlag(HValue::kHasNoObservableSideEffects);
5688 if (position != RelocInfo::kNoPosition) access->set_position(position); 5692 if (position != RelocInfo::kNoPosition) access->set_position(position);
5689 if (!is_store) { 5693 if (!is_store) {
5690 Push(access); 5694 Push(access);
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
5745 if (position != RelocInfo::kNoPosition) instr->set_position(position); 5749 if (position != RelocInfo::kNoPosition) instr->set_position(position);
5746 *has_side_effects = instr->HasObservableSideEffects(); 5750 *has_side_effects = instr->HasObservableSideEffects();
5747 return instr; 5751 return instr;
5748 } 5752 }
5749 5753
5750 5754
5751 HInstruction* HOptimizedGraphBuilder::BuildStoreKeyedGeneric( 5755 HInstruction* HOptimizedGraphBuilder::BuildStoreKeyedGeneric(
5752 HValue* object, 5756 HValue* object,
5753 HValue* key, 5757 HValue* key,
5754 HValue* value) { 5758 HValue* value) {
5755 HValue* context = environment()->LookupContext(); 5759 HValue* context = environment()->context();
5756 return new(zone()) HStoreKeyedGeneric( 5760 return new(zone()) HStoreKeyedGeneric(
5757 context, 5761 context,
5758 object, 5762 object,
5759 key, 5763 key,
5760 value, 5764 value,
5761 function_strict_mode_flag()); 5765 function_strict_mode_flag());
5762 } 5766 }
5763 5767
5764 5768
5765 void HOptimizedGraphBuilder::EnsureArgumentsArePushedForAccess() { 5769 void HOptimizedGraphBuilder::EnsureArgumentsArePushedForAccess() {
5766 // Outermost function already has arguments on the stack. 5770 // Outermost function already has arguments on the stack.
5767 if (function_state()->outer() == NULL) return; 5771 if (function_state()->outer() == NULL) return;
5768 5772
5769 if (function_state()->arguments_pushed()) return; 5773 if (function_state()->arguments_pushed()) return;
5770 5774
5771 // Push arguments when entering inlined function. 5775 // Push arguments when entering inlined function.
5772 HEnterInlined* entry = function_state()->entry(); 5776 HEnterInlined* entry = function_state()->entry();
5773 entry->set_arguments_pushed(); 5777 entry->set_arguments_pushed();
5774 5778
5775 HArgumentsObject* arguments = entry->arguments_object(); 5779 HArgumentsObject* arguments = entry->arguments_object();
5776 const ZoneList<HValue*>* arguments_values = arguments->arguments_values(); 5780 const ZoneList<HValue*>* arguments_values = arguments->arguments_values();
5777 5781
5778 HInstruction* insert_after = entry; 5782 HInstruction* insert_after = entry;
5779 for (int i = 0; i < arguments_values->length(); i++) { 5783 for (int i = 0; i < arguments_values->length(); i++) {
5780 HValue* argument = arguments_values->at(i); 5784 HValue* argument = arguments_values->at(i);
5781 HInstruction* push_argument = new(zone()) HPushArgument(argument); 5785 HInstruction* push_argument = New<HPushArgument>(argument);
5782 push_argument->InsertAfter(insert_after); 5786 push_argument->InsertAfter(insert_after);
5783 insert_after = push_argument; 5787 insert_after = push_argument;
5784 } 5788 }
5785 5789
5786 HArgumentsElements* arguments_elements = 5790 HArgumentsElements* arguments_elements = NewAndCast<HArgumentsElements>(true);
5787 new(zone()) HArgumentsElements(true);
5788 arguments_elements->ClearFlag(HValue::kUseGVN); 5791 arguments_elements->ClearFlag(HValue::kUseGVN);
5789 arguments_elements->InsertAfter(insert_after); 5792 arguments_elements->InsertAfter(insert_after);
5790 function_state()->set_arguments_elements(arguments_elements); 5793 function_state()->set_arguments_elements(arguments_elements);
5791 } 5794 }
5792 5795
5793 5796
5794 bool HOptimizedGraphBuilder::TryArgumentsAccess(Property* expr) { 5797 bool HOptimizedGraphBuilder::TryArgumentsAccess(Property* expr) {
5795 VariableProxy* proxy = expr->obj()->AsVariableProxy(); 5798 VariableProxy* proxy = expr->obj()->AsVariableProxy();
5796 if (proxy == NULL) return false; 5799 if (proxy == NULL) return false;
5797 if (!proxy->var()->IsStackAllocated()) return false; 5800 if (!proxy->var()->IsStackAllocated()) return false;
5798 if (!environment()->Lookup(proxy->var())->CheckFlag(HValue::kIsArguments)) { 5801 if (!environment()->Lookup(proxy->var())->CheckFlag(HValue::kIsArguments)) {
5799 return false; 5802 return false;
5800 } 5803 }
5801 5804
5802 HInstruction* result = NULL; 5805 HInstruction* result = NULL;
5803 if (expr->key()->IsPropertyName()) { 5806 if (expr->key()->IsPropertyName()) {
5804 Handle<String> name = expr->key()->AsLiteral()->AsPropertyName(); 5807 Handle<String> name = expr->key()->AsLiteral()->AsPropertyName();
5805 if (!name->IsOneByteEqualTo(STATIC_ASCII_VECTOR("length"))) return false; 5808 if (!name->IsOneByteEqualTo(STATIC_ASCII_VECTOR("length"))) return false;
5806 5809
5807 if (function_state()->outer() == NULL) { 5810 if (function_state()->outer() == NULL) {
5808 HInstruction* elements = Add<HArgumentsElements>(false); 5811 HInstruction* elements = Add<HArgumentsElements>(false);
5809 result = new(zone()) HArgumentsLength(elements); 5812 result = New<HArgumentsLength>(elements);
5810 } else { 5813 } else {
5811 // Number of arguments without receiver. 5814 // Number of arguments without receiver.
5812 int argument_count = environment()-> 5815 int argument_count = environment()->
5813 arguments_environment()->parameter_count() - 1; 5816 arguments_environment()->parameter_count() - 1;
5814 result = new(zone()) HConstant(argument_count); 5817 result = New<HConstant>(argument_count);
5815 } 5818 }
5816 } else { 5819 } else {
5817 Push(graph()->GetArgumentsObject()); 5820 Push(graph()->GetArgumentsObject());
5818 VisitForValue(expr->key()); 5821 VisitForValue(expr->key());
5819 if (HasStackOverflow() || current_block() == NULL) return true; 5822 if (HasStackOverflow() || current_block() == NULL) return true;
5820 HValue* key = Pop(); 5823 HValue* key = Pop();
5821 Drop(1); // Arguments object. 5824 Drop(1); // Arguments object.
5822 if (function_state()->outer() == NULL) { 5825 if (function_state()->outer() == NULL) {
5823 HInstruction* elements = Add<HArgumentsElements>(false); 5826 HInstruction* elements = Add<HArgumentsElements>(false);
5824 HInstruction* length = Add<HArgumentsLength>(elements); 5827 HInstruction* length = Add<HArgumentsLength>(elements);
(...skipping 23 matching lines...) Expand all
5848 5851
5849 if (TryArgumentsAccess(expr)) return; 5852 if (TryArgumentsAccess(expr)) return;
5850 5853
5851 CHECK_ALIVE(VisitForValue(expr->obj())); 5854 CHECK_ALIVE(VisitForValue(expr->obj()));
5852 5855
5853 HInstruction* instr = NULL; 5856 HInstruction* instr = NULL;
5854 if (expr->IsStringLength()) { 5857 if (expr->IsStringLength()) {
5855 HValue* string = Pop(); 5858 HValue* string = Pop();
5856 BuildCheckHeapObject(string); 5859 BuildCheckHeapObject(string);
5857 AddInstruction(HCheckInstanceType::NewIsString(string, zone())); 5860 AddInstruction(HCheckInstanceType::NewIsString(string, zone()));
5858 instr = HStringLength::New(zone(), string); 5861 instr = HStringLength::New(zone(), context(), string);
5859 } else if (expr->IsStringAccess()) { 5862 } else if (expr->IsStringAccess()) {
5860 CHECK_ALIVE(VisitForValue(expr->key())); 5863 CHECK_ALIVE(VisitForValue(expr->key()));
5861 HValue* index = Pop(); 5864 HValue* index = Pop();
5862 HValue* string = Pop(); 5865 HValue* string = Pop();
5863 HValue* context = environment()->LookupContext(); 5866 HValue* context = environment()->context();
5864 HInstruction* char_code = 5867 HInstruction* char_code =
5865 BuildStringCharCodeAt(context, string, index); 5868 BuildStringCharCodeAt(string, index);
5866 AddInstruction(char_code); 5869 AddInstruction(char_code);
5867 instr = HStringCharFromCode::New(zone(), context, char_code); 5870 instr = HStringCharFromCode::New(zone(), context, char_code);
5868 5871
5869 } else if (expr->IsFunctionPrototype()) { 5872 } else if (expr->IsFunctionPrototype()) {
5870 HValue* function = Pop(); 5873 HValue* function = Pop();
5871 BuildCheckHeapObject(function); 5874 BuildCheckHeapObject(function);
5872 instr = new(zone()) HLoadFunctionPrototype(function); 5875 instr = new(zone()) HLoadFunctionPrototype(function);
5873 5876
5874 } else if (expr->key()->IsPropertyName()) { 5877 } else if (expr->key()->IsPropertyName()) {
5875 Handle<String> name = expr->key()->AsLiteral()->AsPropertyName(); 5878 Handle<String> name = expr->key()->AsLiteral()->AsPropertyName();
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
5926 } 5929 }
5927 instr->set_position(expr->position()); 5930 instr->set_position(expr->position());
5928 return ast_context()->ReturnInstruction(instr, expr->id()); 5931 return ast_context()->ReturnInstruction(instr, expr->id());
5929 } 5932 }
5930 5933
5931 5934
5932 void HOptimizedGraphBuilder::AddCheckPrototypeMaps(Handle<JSObject> holder, 5935 void HOptimizedGraphBuilder::AddCheckPrototypeMaps(Handle<JSObject> holder,
5933 Handle<Map> receiver_map) { 5936 Handle<Map> receiver_map) {
5934 if (!holder.is_null()) { 5937 if (!holder.is_null()) {
5935 Handle<JSObject> prototype(JSObject::cast(receiver_map->prototype())); 5938 Handle<JSObject> prototype(JSObject::cast(receiver_map->prototype()));
5936 Add<HCheckPrototypeMaps>(prototype, holder, zone(), top_info()); 5939 Add<HCheckPrototypeMaps>(prototype, holder, top_info());
5937 } 5940 }
5938 } 5941 }
5939 5942
5940 5943
5941 void HOptimizedGraphBuilder::AddCheckConstantFunction( 5944 void HOptimizedGraphBuilder::AddCheckConstantFunction(
5942 Handle<JSObject> holder, 5945 Handle<JSObject> holder,
5943 HValue* receiver, 5946 HValue* receiver,
5944 Handle<Map> receiver_map) { 5947 Handle<Map> receiver_map) {
5945 // Constant functions have the nice property that the map will change if they 5948 // Constant functions have the nice property that the map will change if they
5946 // are overwritten. Therefore it is enough to check the map of the holder and 5949 // are overwritten. Therefore it is enough to check the map of the holder and
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after
6151 // Finish up. Unconditionally deoptimize if we've handled all the maps we 6154 // Finish up. Unconditionally deoptimize if we've handled all the maps we
6152 // know about and do not want to handle ones we've never seen. Otherwise 6155 // know about and do not want to handle ones we've never seen. Otherwise
6153 // use a generic IC. 6156 // use a generic IC.
6154 if (ordered_functions == types->length() && FLAG_deoptimize_uncommon_cases) { 6157 if (ordered_functions == types->length() && FLAG_deoptimize_uncommon_cases) {
6155 // Because the deopt may be the only path in the polymorphic call, make sure 6158 // Because the deopt may be the only path in the polymorphic call, make sure
6156 // that the environment stack matches the depth on deopt that it otherwise 6159 // that the environment stack matches the depth on deopt that it otherwise
6157 // would have had after a successful call. 6160 // would have had after a successful call.
6158 Drop(argument_count - (ast_context()->IsEffect() ? 0 : 1)); 6161 Drop(argument_count - (ast_context()->IsEffect() ? 0 : 1));
6159 FinishExitWithHardDeoptimization(join); 6162 FinishExitWithHardDeoptimization(join);
6160 } else { 6163 } else {
6161 HValue* context = environment()->LookupContext(); 6164 HValue* context = environment()->context();
6162 HCallNamed* call = new(zone()) HCallNamed(context, name, argument_count); 6165 HCallNamed* call = new(zone()) HCallNamed(context, name, argument_count);
6163 call->set_position(expr->position()); 6166 call->set_position(expr->position());
6164 PreProcessCall(call); 6167 PreProcessCall(call);
6165 6168
6166 if (join != NULL) { 6169 if (join != NULL) {
6167 AddInstruction(call); 6170 AddInstruction(call);
6168 if (!ast_context()->IsEffect()) Push(call); 6171 if (!ast_context()->IsEffect()) Push(call);
6169 current_block()->Goto(join); 6172 current_block()->Goto(join);
6170 } else { 6173 } else {
6171 return ast_context()->ReturnInstruction(call, expr->id()); 6174 return ast_context()->ReturnInstruction(call, expr->id());
(...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after
6403 function, 6406 function,
6404 undefined, 6407 undefined,
6405 function_state()->inlining_kind(), 6408 function_state()->inlining_kind(),
6406 undefined_receiver); 6409 undefined_receiver);
6407 #if V8_TARGET_ARCH_IA32 6410 #if V8_TARGET_ARCH_IA32
6408 // IA32 only, overwrite the caller's context in the deoptimization 6411 // IA32 only, overwrite the caller's context in the deoptimization
6409 // environment with the correct one. 6412 // environment with the correct one.
6410 // 6413 //
6411 // TODO(kmillikin): implement the same inlining on other platforms so we 6414 // TODO(kmillikin): implement the same inlining on other platforms so we
6412 // can remove the unsightly ifdefs in this function. 6415 // can remove the unsightly ifdefs in this function.
6413 HConstant* context = Add<HConstant>(Handle<Context>(target->context())); 6416 HConstant* context =
6417 AddAndCast<HConstant>(Handle<Context>(target->context()));
6414 inner_env->BindContext(context); 6418 inner_env->BindContext(context);
6415 #endif 6419 #endif
6416 6420
6417 Add<HSimulate>(return_id); 6421 Add<HSimulate>(return_id);
6418 current_block()->UpdateEnvironment(inner_env); 6422 current_block()->UpdateEnvironment(inner_env);
6419 HArgumentsObject* arguments_object = NULL; 6423 HArgumentsObject* arguments_object = NULL;
6420 6424
6421 // If the function uses arguments object create and bind one, also copy 6425 // If the function uses arguments object create and bind one, also copy
6422 // current arguments values to use them for materialization. 6426 // current arguments values to use them for materialization.
6423 if (function->scope()->arguments() != NULL) { 6427 if (function->scope()->arguments() != NULL) {
6424 ASSERT(function->scope()->arguments()->IsStackAllocated()); 6428 ASSERT(function->scope()->arguments()->IsStackAllocated());
6425 HEnvironment* arguments_env = inner_env->arguments_environment(); 6429 HEnvironment* arguments_env = inner_env->arguments_environment();
6426 int arguments_count = arguments_env->parameter_count(); 6430 int arguments_count = arguments_env->parameter_count();
6427 arguments_object = Add<HArgumentsObject>(arguments_count, zone()); 6431 arguments_object = AddAndCast<HArgumentsObject>(arguments_count);
6428 inner_env->Bind(function->scope()->arguments(), arguments_object); 6432 inner_env->Bind(function->scope()->arguments(), arguments_object);
6429 for (int i = 0; i < arguments_count; i++) { 6433 for (int i = 0; i < arguments_count; i++) {
6430 arguments_object->AddArgument(arguments_env->Lookup(i), zone()); 6434 arguments_object->AddArgument(arguments_env->Lookup(i), zone());
6431 } 6435 }
6432 } 6436 }
6433 6437
6434 HEnterInlined* enter_inlined = 6438 HEnterInlined* enter_inlined =
6435 Add<HEnterInlined>(target, arguments_count, function, 6439 AddAndCast<HEnterInlined>(target, arguments_count, function,
6436 function_state()->inlining_kind(), 6440 function_state()->inlining_kind(),
6437 function->scope()->arguments(), 6441 function->scope()->arguments(),
6438 arguments_object, undefined_receiver, zone()); 6442 arguments_object, undefined_receiver, zone());
6439 function_state()->set_entry(enter_inlined); 6443 function_state()->set_entry(enter_inlined);
6440 6444
6441 VisitDeclarations(target_info.scope()->declarations()); 6445 VisitDeclarations(target_info.scope()->declarations());
6442 VisitStatements(function->body()); 6446 VisitStatements(function->body());
6443 if (HasStackOverflow()) { 6447 if (HasStackOverflow()) {
6444 // Bail out if the inline function did, as we cannot residualize a call 6448 // Bail out if the inline function did, as we cannot residualize a call
6445 // instead. 6449 // instead.
6446 TraceInline(target, caller, "inline graph construction failed"); 6450 TraceInline(target, caller, "inline graph construction failed");
6447 target_shared->DisableOptimization("inlining bailed out"); 6451 target_shared->DisableOptimization("inlining bailed out");
6448 inline_bailout_ = true; 6452 inline_bailout_ = true;
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after
6619 case kMathRound: 6623 case kMathRound:
6620 case kMathFloor: 6624 case kMathFloor:
6621 case kMathAbs: 6625 case kMathAbs:
6622 case kMathSqrt: 6626 case kMathSqrt:
6623 case kMathLog: 6627 case kMathLog:
6624 case kMathSin: 6628 case kMathSin:
6625 case kMathCos: 6629 case kMathCos:
6626 case kMathTan: 6630 case kMathTan:
6627 if (expr->arguments()->length() == 1) { 6631 if (expr->arguments()->length() == 1) {
6628 HValue* argument = Pop(); 6632 HValue* argument = Pop();
6629 HValue* context = environment()->LookupContext(); 6633 HValue* context = environment()->context();
6630 Drop(1); // Receiver. 6634 Drop(1); // Receiver.
6631 HInstruction* op = 6635 HInstruction* op =
6632 HUnaryMathOperation::New(zone(), context, argument, id); 6636 HUnaryMathOperation::New(zone(), context, argument, id);
6633 op->set_position(expr->position()); 6637 op->set_position(expr->position());
6634 if (drop_extra) Drop(1); // Optionally drop the function. 6638 if (drop_extra) Drop(1); // Optionally drop the function.
6635 ast_context()->ReturnInstruction(op, expr->id()); 6639 ast_context()->ReturnInstruction(op, expr->id());
6636 return true; 6640 return true;
6637 } 6641 }
6638 break; 6642 break;
6639 case kMathImul: 6643 case kMathImul:
6640 if (expr->arguments()->length() == 2) { 6644 if (expr->arguments()->length() == 2) {
6641 HValue* right = Pop(); 6645 HValue* right = Pop();
6642 HValue* left = Pop(); 6646 HValue* left = Pop();
6643 Drop(1); // Receiver. 6647 Drop(1); // Receiver.
6644 HValue* context = environment()->LookupContext(); 6648 HValue* context = environment()->context();
6645 HInstruction* op = HMul::NewImul(zone(), context, left, right); 6649 HInstruction* op = HMul::NewImul(zone(), context, left, right);
6646 if (drop_extra) Drop(1); // Optionally drop the function. 6650 if (drop_extra) Drop(1); // Optionally drop the function.
6647 ast_context()->ReturnInstruction(op, expr->id()); 6651 ast_context()->ReturnInstruction(op, expr->id());
6648 return true; 6652 return true;
6649 } 6653 }
6650 break; 6654 break;
6651 default: 6655 default:
6652 // Not supported for inlining yet. 6656 // Not supported for inlining yet.
6653 break; 6657 break;
6654 } 6658 }
(...skipping 10 matching lines...) Expand all
6665 // Try to inline calls like Math.* as operations in the calling function. 6669 // Try to inline calls like Math.* as operations in the calling function.
6666 if (!expr->target()->shared()->HasBuiltinFunctionId()) return false; 6670 if (!expr->target()->shared()->HasBuiltinFunctionId()) return false;
6667 BuiltinFunctionId id = expr->target()->shared()->builtin_function_id(); 6671 BuiltinFunctionId id = expr->target()->shared()->builtin_function_id();
6668 int argument_count = expr->arguments()->length() + 1; // Plus receiver. 6672 int argument_count = expr->arguments()->length() + 1; // Plus receiver.
6669 switch (id) { 6673 switch (id) {
6670 case kStringCharCodeAt: 6674 case kStringCharCodeAt:
6671 case kStringCharAt: 6675 case kStringCharAt:
6672 if (argument_count == 2 && check_type == STRING_CHECK) { 6676 if (argument_count == 2 && check_type == STRING_CHECK) {
6673 HValue* index = Pop(); 6677 HValue* index = Pop();
6674 HValue* string = Pop(); 6678 HValue* string = Pop();
6675 HValue* context = environment()->LookupContext(); 6679 HValue* context = environment()->context();
6676 ASSERT(!expr->holder().is_null()); 6680 ASSERT(!expr->holder().is_null());
6677 Add<HCheckPrototypeMaps>(Call::GetPrototypeForPrimitiveCheck( 6681 Add<HCheckPrototypeMaps>(Call::GetPrototypeForPrimitiveCheck(
6678 STRING_CHECK, expr->holder()->GetIsolate()), 6682 STRING_CHECK, expr->holder()->GetIsolate()),
6679 expr->holder(), zone(), top_info()); 6683 expr->holder(), top_info());
6680 HInstruction* char_code = 6684 HInstruction* char_code =
6681 BuildStringCharCodeAt(context, string, index); 6685 BuildStringCharCodeAt(string, index);
6682 if (id == kStringCharCodeAt) { 6686 if (id == kStringCharCodeAt) {
6683 ast_context()->ReturnInstruction(char_code, expr->id()); 6687 ast_context()->ReturnInstruction(char_code, expr->id());
6684 return true; 6688 return true;
6685 } 6689 }
6686 AddInstruction(char_code); 6690 AddInstruction(char_code);
6687 HInstruction* result = 6691 HInstruction* result =
6688 HStringCharFromCode::New(zone(), context, char_code); 6692 HStringCharFromCode::New(zone(), context, char_code);
6689 ast_context()->ReturnInstruction(result, expr->id()); 6693 ast_context()->ReturnInstruction(result, expr->id());
6690 return true; 6694 return true;
6691 } 6695 }
6692 break; 6696 break;
6693 case kStringFromCharCode: 6697 case kStringFromCharCode:
6694 if (argument_count == 2 && check_type == RECEIVER_MAP_CHECK) { 6698 if (argument_count == 2 && check_type == RECEIVER_MAP_CHECK) {
6695 AddCheckConstantFunction(expr->holder(), receiver, receiver_map); 6699 AddCheckConstantFunction(expr->holder(), receiver, receiver_map);
6696 HValue* argument = Pop(); 6700 HValue* argument = Pop();
6697 HValue* context = environment()->LookupContext(); 6701 HValue* context = environment()->context();
6698 Drop(1); // Receiver. 6702 Drop(1); // Receiver.
6699 HInstruction* result = 6703 HInstruction* result =
6700 HStringCharFromCode::New(zone(), context, argument); 6704 HStringCharFromCode::New(zone(), context, argument);
6701 ast_context()->ReturnInstruction(result, expr->id()); 6705 ast_context()->ReturnInstruction(result, expr->id());
6702 return true; 6706 return true;
6703 } 6707 }
6704 break; 6708 break;
6705 case kMathExp: 6709 case kMathExp:
6706 if (!FLAG_fast_math) break; 6710 if (!FLAG_fast_math) break;
6707 // Fall through if FLAG_fast_math. 6711 // Fall through if FLAG_fast_math.
6708 case kMathRound: 6712 case kMathRound:
6709 case kMathFloor: 6713 case kMathFloor:
6710 case kMathAbs: 6714 case kMathAbs:
6711 case kMathSqrt: 6715 case kMathSqrt:
6712 case kMathLog: 6716 case kMathLog:
6713 case kMathSin: 6717 case kMathSin:
6714 case kMathCos: 6718 case kMathCos:
6715 case kMathTan: 6719 case kMathTan:
6716 if (argument_count == 2 && check_type == RECEIVER_MAP_CHECK) { 6720 if (argument_count == 2 && check_type == RECEIVER_MAP_CHECK) {
6717 AddCheckConstantFunction(expr->holder(), receiver, receiver_map); 6721 AddCheckConstantFunction(expr->holder(), receiver, receiver_map);
6718 HValue* argument = Pop(); 6722 HValue* argument = Pop();
6719 HValue* context = environment()->LookupContext(); 6723 HValue* context = environment()->context();
6720 Drop(1); // Receiver. 6724 Drop(1); // Receiver.
6721 HInstruction* op = 6725 HInstruction* op =
6722 HUnaryMathOperation::New(zone(), context, argument, id); 6726 HUnaryMathOperation::New(zone(), context, argument, id);
6723 op->set_position(expr->position()); 6727 op->set_position(expr->position());
6724 ast_context()->ReturnInstruction(op, expr->id()); 6728 ast_context()->ReturnInstruction(op, expr->id());
6725 return true; 6729 return true;
6726 } 6730 }
6727 break; 6731 break;
6728 case kMathPow: 6732 case kMathPow:
6729 if (argument_count == 3 && check_type == RECEIVER_MAP_CHECK) { 6733 if (argument_count == 3 && check_type == RECEIVER_MAP_CHECK) {
6730 AddCheckConstantFunction(expr->holder(), receiver, receiver_map); 6734 AddCheckConstantFunction(expr->holder(), receiver, receiver_map);
6731 HValue* right = Pop(); 6735 HValue* right = Pop();
6732 HValue* left = Pop(); 6736 HValue* left = Pop();
6733 Pop(); // Pop receiver. 6737 Pop(); // Pop receiver.
6734 HValue* context = environment()->LookupContext(); 6738 HValue* context = environment()->context();
6735 HInstruction* result = NULL; 6739 HInstruction* result = NULL;
6736 // Use sqrt() if exponent is 0.5 or -0.5. 6740 // Use sqrt() if exponent is 0.5 or -0.5.
6737 if (right->IsConstant() && HConstant::cast(right)->HasDoubleValue()) { 6741 if (right->IsConstant() && HConstant::cast(right)->HasDoubleValue()) {
6738 double exponent = HConstant::cast(right)->DoubleValue(); 6742 double exponent = HConstant::cast(right)->DoubleValue();
6739 if (exponent == 0.5) { 6743 if (exponent == 0.5) {
6740 result = 6744 result =
6741 HUnaryMathOperation::New(zone(), context, left, kMathPowHalf); 6745 HUnaryMathOperation::New(zone(), context, left, kMathPowHalf);
6742 } else if (exponent == -0.5) { 6746 } else if (exponent == -0.5) {
6743 HValue* one = graph()->GetConstant1(); 6747 HValue* one = graph()->GetConstant1();
6744 HInstruction* sqrt = 6748 HInstruction* sqrt =
6745 HUnaryMathOperation::New(zone(), context, left, kMathPowHalf); 6749 HUnaryMathOperation::New(zone(), context, left, kMathPowHalf);
6746 AddInstruction(sqrt); 6750 AddInstruction(sqrt);
6747 // MathPowHalf doesn't have side effects so there's no need for 6751 // MathPowHalf doesn't have side effects so there's no need for
6748 // an environment simulation here. 6752 // an environment simulation here.
6749 ASSERT(!sqrt->HasObservableSideEffects()); 6753 ASSERT(!sqrt->HasObservableSideEffects());
6750 result = HDiv::New(zone(), context, one, sqrt); 6754 result = HDiv::New(zone(), context, one, sqrt);
6751 } else if (exponent == 2.0) { 6755 } else if (exponent == 2.0) {
6752 result = HMul::New(zone(), context, left, left); 6756 result = HMul::New(zone(), context, left, left);
6753 } 6757 }
6754 } else if (right->EqualsInteger32Constant(2)) { 6758 } else if (right->EqualsInteger32Constant(2)) {
6755 result = HMul::New(zone(), context, left, left); 6759 result = HMul::New(zone(), context, left, left);
6756 } 6760 }
6757 6761
6758 if (result == NULL) { 6762 if (result == NULL) {
6759 result = HPower::New(zone(), left, right); 6763 result = HPower::New(zone(), context, left, right);
6760 } 6764 }
6761 ast_context()->ReturnInstruction(result, expr->id()); 6765 ast_context()->ReturnInstruction(result, expr->id());
6762 return true; 6766 return true;
6763 } 6767 }
6764 break; 6768 break;
6765 case kMathRandom: 6769 case kMathRandom:
6766 if (argument_count == 1 && check_type == RECEIVER_MAP_CHECK) { 6770 if (argument_count == 1 && check_type == RECEIVER_MAP_CHECK) {
6767 AddCheckConstantFunction(expr->holder(), receiver, receiver_map); 6771 AddCheckConstantFunction(expr->holder(), receiver, receiver_map);
6768 Drop(1); // Receiver. 6772 Drop(1); // Receiver.
6769 HValue* context = environment()->LookupContext(); 6773 HGlobalObject* global_object = AddAndCast<HGlobalObject>();
6770 HGlobalObject* global_object = Add<HGlobalObject>(context);
6771 HRandom* result = new(zone()) HRandom(global_object); 6774 HRandom* result = new(zone()) HRandom(global_object);
6772 ast_context()->ReturnInstruction(result, expr->id()); 6775 ast_context()->ReturnInstruction(result, expr->id());
6773 return true; 6776 return true;
6774 } 6777 }
6775 break; 6778 break;
6776 case kMathMax: 6779 case kMathMax:
6777 case kMathMin: 6780 case kMathMin:
6778 if (argument_count == 3 && check_type == RECEIVER_MAP_CHECK) { 6781 if (argument_count == 3 && check_type == RECEIVER_MAP_CHECK) {
6779 AddCheckConstantFunction(expr->holder(), receiver, receiver_map); 6782 AddCheckConstantFunction(expr->holder(), receiver, receiver_map);
6780 HValue* right = Pop(); 6783 HValue* right = Pop();
6781 HValue* left = Pop(); 6784 HValue* left = Pop();
6782 Drop(1); // Receiver. 6785 Drop(1); // Receiver.
6783 HValue* context = environment()->LookupContext(); 6786 HValue* context = environment()->context();
6784 HMathMinMax::Operation op = (id == kMathMin) ? HMathMinMax::kMathMin 6787 HMathMinMax::Operation op = (id == kMathMin) ? HMathMinMax::kMathMin
6785 : HMathMinMax::kMathMax; 6788 : HMathMinMax::kMathMax;
6786 HInstruction* result = 6789 HInstruction* result =
6787 HMathMinMax::New(zone(), context, left, right, op); 6790 HMathMinMax::New(zone(), context, left, right, op);
6788 ast_context()->ReturnInstruction(result, expr->id()); 6791 ast_context()->ReturnInstruction(result, expr->id());
6789 return true; 6792 return true;
6790 } 6793 }
6791 break; 6794 break;
6792 case kMathImul: 6795 case kMathImul:
6793 if (argument_count == 3 && check_type == RECEIVER_MAP_CHECK) { 6796 if (argument_count == 3 && check_type == RECEIVER_MAP_CHECK) {
6794 AddCheckConstantFunction(expr->holder(), receiver, receiver_map); 6797 AddCheckConstantFunction(expr->holder(), receiver, receiver_map);
6795 HValue* right = Pop(); 6798 HValue* right = Pop();
6796 HValue* left = Pop(); 6799 HValue* left = Pop();
6797 Drop(1); // Receiver. 6800 Drop(1); // Receiver.
6798 HValue* context = environment()->LookupContext(); 6801 HValue* context = environment()->context();
6799 HInstruction* result = HMul::NewImul(zone(), context, left, right); 6802 HInstruction* result = HMul::NewImul(zone(), context, left, right);
6800 ast_context()->ReturnInstruction(result, expr->id()); 6803 ast_context()->ReturnInstruction(result, expr->id());
6801 return true; 6804 return true;
6802 } 6805 }
6803 break; 6806 break;
6804 default: 6807 default:
6805 // Not yet supported for inlining. 6808 // Not yet supported for inlining.
6806 break; 6809 break;
6807 } 6810 }
6808 return false; 6811 return false;
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
6872 6875
6873 Handle<JSFunction> known_function; 6876 Handle<JSFunction> known_function;
6874 if (function->IsConstant()) { 6877 if (function->IsConstant()) {
6875 HConstant* constant_function = HConstant::cast(function); 6878 HConstant* constant_function = HConstant::cast(function);
6876 known_function = Handle<JSFunction>::cast(constant_function->handle()); 6879 known_function = Handle<JSFunction>::cast(constant_function->handle());
6877 int args_count = arguments_count - 1; // Excluding receiver. 6880 int args_count = arguments_count - 1; // Excluding receiver.
6878 if (TryInlineApply(known_function, expr, args_count)) return true; 6881 if (TryInlineApply(known_function, expr, args_count)) return true;
6879 } 6882 }
6880 6883
6881 Drop(arguments_count - 1); 6884 Drop(arguments_count - 1);
6882 PushAndAdd(new(zone()) HPushArgument(Pop())); 6885 PushAndAdd(New<HPushArgument>(Pop()));
6883 for (int i = 1; i < arguments_count; i++) { 6886 for (int i = 1; i < arguments_count; i++) {
6884 PushAndAdd(new(zone()) HPushArgument(arguments_values->at(i))); 6887 PushAndAdd(New<HPushArgument>(arguments_values->at(i)));
6885 } 6888 }
6886 6889
6887 HValue* context = environment()->LookupContext(); 6890 HValue* context = environment()->context();
6888 HInvokeFunction* call = new(zone()) HInvokeFunction( 6891 HInvokeFunction* call = new(zone()) HInvokeFunction(
6889 context, 6892 context,
6890 function, 6893 function,
6891 known_function, 6894 known_function,
6892 arguments_count); 6895 arguments_count);
6893 Drop(arguments_count); 6896 Drop(arguments_count);
6894 call->set_position(expr->position()); 6897 call->set_position(expr->position());
6895 ast_context()->ReturnInstruction(call, expr->id()); 6898 ast_context()->ReturnInstruction(call, expr->id());
6896 return true; 6899 return true;
6897 } 6900 }
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
6963 6966
6964 CHECK_ALIVE(VisitForValue(prop->key())); 6967 CHECK_ALIVE(VisitForValue(prop->key()));
6965 // Push receiver and key like the non-optimized code generator expects it. 6968 // Push receiver and key like the non-optimized code generator expects it.
6966 HValue* key = Pop(); 6969 HValue* key = Pop();
6967 HValue* receiver = Pop(); 6970 HValue* receiver = Pop();
6968 Push(key); 6971 Push(key);
6969 Push(receiver); 6972 Push(receiver);
6970 6973
6971 CHECK_ALIVE(VisitArgumentList(expr->arguments())); 6974 CHECK_ALIVE(VisitArgumentList(expr->arguments()));
6972 6975
6973 HValue* context = environment()->LookupContext(); 6976 HValue* context = environment()->context();
6974 call = new(zone()) HCallKeyed(context, key, argument_count); 6977 call = new(zone()) HCallKeyed(context, key, argument_count);
6975 call->set_position(expr->position()); 6978 call->set_position(expr->position());
6976 Drop(argument_count + 1); // 1 is the key. 6979 Drop(argument_count + 1); // 1 is the key.
6977 return ast_context()->ReturnInstruction(call, expr->id()); 6980 return ast_context()->ReturnInstruction(call, expr->id());
6978 } 6981 }
6979 6982
6980 // Named function call. 6983 // Named function call.
6981 if (TryCallApply(expr)) return; 6984 if (TryCallApply(expr)) return;
6982 6985
6983 CHECK_ALIVE(VisitForValue(prop->obj())); 6986 CHECK_ALIVE(VisitForValue(prop->obj()));
(...skipping 29 matching lines...) Expand all
7013 PrintF("\n"); 7016 PrintF("\n");
7014 } 7017 }
7015 return; 7018 return;
7016 } 7019 }
7017 7020
7018 if (CallStubCompiler::HasCustomCallGenerator(expr->target()) || 7021 if (CallStubCompiler::HasCustomCallGenerator(expr->target()) ||
7019 expr->check_type() != RECEIVER_MAP_CHECK) { 7022 expr->check_type() != RECEIVER_MAP_CHECK) {
7020 // When the target has a custom call IC generator, use the IC, 7023 // When the target has a custom call IC generator, use the IC,
7021 // because it is likely to generate better code. Also use the IC 7024 // because it is likely to generate better code. Also use the IC
7022 // when a primitive receiver check is required. 7025 // when a primitive receiver check is required.
7023 HValue* context = environment()->LookupContext(); 7026 HValue* context = environment()->context();
7024 call = PreProcessCall( 7027 call = PreProcessCall(
7025 new(zone()) HCallNamed(context, name, argument_count)); 7028 new(zone()) HCallNamed(context, name, argument_count));
7026 } else { 7029 } else {
7027 AddCheckConstantFunction(expr->holder(), receiver, receiver_map); 7030 AddCheckConstantFunction(expr->holder(), receiver, receiver_map);
7028 7031
7029 if (TryInlineCall(expr)) return; 7032 if (TryInlineCall(expr)) return;
7030 call = PreProcessCall( 7033 call = PreProcessCall(
7031 new(zone()) HCallConstantFunction(expr->target(), 7034 new(zone()) HCallConstantFunction(expr->target(),
7032 argument_count)); 7035 argument_count));
7033 } 7036 }
7034 } else if (types != NULL && types->length() > 1) { 7037 } else if (types != NULL && types->length() > 1) {
7035 ASSERT(expr->check_type() == RECEIVER_MAP_CHECK); 7038 ASSERT(expr->check_type() == RECEIVER_MAP_CHECK);
7036 HandlePolymorphicCallNamed(expr, receiver, types, name); 7039 HandlePolymorphicCallNamed(expr, receiver, types, name);
7037 return; 7040 return;
7038 7041
7039 } else { 7042 } else {
7040 HValue* context = environment()->LookupContext(); 7043 HValue* context = environment()->context();
7041 call = PreProcessCall( 7044 call = PreProcessCall(
7042 new(zone()) HCallNamed(context, name, argument_count)); 7045 new(zone()) HCallNamed(context, name, argument_count));
7043 } 7046 }
7044 7047
7045 } else { 7048 } else {
7046 VariableProxy* proxy = expr->expression()->AsVariableProxy(); 7049 VariableProxy* proxy = expr->expression()->AsVariableProxy();
7047 if (proxy != NULL && proxy->var()->is_possibly_eval(isolate())) { 7050 if (proxy != NULL && proxy->var()->is_possibly_eval(isolate())) {
7048 return Bailout("possible direct call to eval"); 7051 return Bailout("possible direct call to eval");
7049 } 7052 }
7050 7053
7051 bool global_call = proxy != NULL && proxy->var()->IsUnallocated(); 7054 bool global_call = proxy != NULL && proxy->var()->IsUnallocated();
7052 if (global_call) { 7055 if (global_call) {
7053 Variable* var = proxy->var(); 7056 Variable* var = proxy->var();
7054 bool known_global_function = false; 7057 bool known_global_function = false;
7055 // If there is a global property cell for the name at compile time and 7058 // If there is a global property cell for the name at compile time and
7056 // access check is not enabled we assume that the function will not change 7059 // access check is not enabled we assume that the function will not change
7057 // and generate optimized code for calling the function. 7060 // and generate optimized code for calling the function.
7058 LookupResult lookup(isolate()); 7061 LookupResult lookup(isolate());
7059 GlobalPropertyAccess type = LookupGlobalProperty(var, &lookup, false); 7062 GlobalPropertyAccess type = LookupGlobalProperty(var, &lookup, false);
7060 if (type == kUseCell && 7063 if (type == kUseCell &&
7061 !current_info()->global_object()->IsAccessCheckNeeded()) { 7064 !current_info()->global_object()->IsAccessCheckNeeded()) {
7062 Handle<GlobalObject> global(current_info()->global_object()); 7065 Handle<GlobalObject> global(current_info()->global_object());
7063 known_global_function = expr->ComputeGlobalTarget(global, &lookup); 7066 known_global_function = expr->ComputeGlobalTarget(global, &lookup);
7064 } 7067 }
7065 if (known_global_function) { 7068 if (known_global_function) {
7066 // Push the global object instead of the global receiver because 7069 // Push the global object instead of the global receiver because
7067 // code generated by the full code generator expects it. 7070 // code generated by the full code generator expects it.
7068 HValue* context = environment()->LookupContext(); 7071 HValue* context = environment()->context();
7069 HGlobalObject* global_object = new(zone()) HGlobalObject(context); 7072 HGlobalObject* global_object = new(zone()) HGlobalObject(context);
7070 PushAndAdd(global_object); 7073 PushAndAdd(global_object);
7071 CHECK_ALIVE(VisitExpressions(expr->arguments())); 7074 CHECK_ALIVE(VisitExpressions(expr->arguments()));
7072 7075
7073 CHECK_ALIVE(VisitForValue(expr->expression())); 7076 CHECK_ALIVE(VisitForValue(expr->expression()));
7074 HValue* function = Pop(); 7077 HValue* function = Pop();
7075 Add<HCheckFunction>(function, expr->target()); 7078 Add<HCheckFunction>(function, expr->target());
7076 7079
7077 // Replace the global object with the global receiver. 7080 // Replace the global object with the global receiver.
7078 HGlobalReceiver* global_receiver = Add<HGlobalReceiver>(global_object); 7081 HGlobalReceiver* global_receiver =
7082 AddAndCast<HGlobalReceiver>(global_object);
7079 // Index of the receiver from the top of the expression stack. 7083 // Index of the receiver from the top of the expression stack.
7080 const int receiver_index = argument_count - 1; 7084 const int receiver_index = argument_count - 1;
7081 ASSERT(environment()->ExpressionStackAt(receiver_index)-> 7085 ASSERT(environment()->ExpressionStackAt(receiver_index)->
7082 IsGlobalObject()); 7086 IsGlobalObject());
7083 environment()->SetExpressionStackAt(receiver_index, global_receiver); 7087 environment()->SetExpressionStackAt(receiver_index, global_receiver);
7084 7088
7085 if (TryInlineBuiltinFunctionCall(expr, false)) { // Nothing to drop. 7089 if (TryInlineBuiltinFunctionCall(expr, false)) { // Nothing to drop.
7086 if (FLAG_trace_inlining) { 7090 if (FLAG_trace_inlining) {
7087 PrintF("Inlining builtin "); 7091 PrintF("Inlining builtin ");
7088 expr->target()->ShortPrint(); 7092 expr->target()->ShortPrint();
7089 PrintF("\n"); 7093 PrintF("\n");
7090 } 7094 }
7091 return; 7095 return;
7092 } 7096 }
7093 if (TryInlineCall(expr)) return; 7097 if (TryInlineCall(expr)) return;
7094 7098
7095 if (expr->target().is_identical_to(current_info()->closure())) { 7099 if (expr->target().is_identical_to(current_info()->closure())) {
7096 graph()->MarkRecursive(); 7100 graph()->MarkRecursive();
7097 } 7101 }
7098 7102
7099 if (CallStubCompiler::HasCustomCallGenerator(expr->target())) { 7103 if (CallStubCompiler::HasCustomCallGenerator(expr->target())) {
7100 // When the target has a custom call IC generator, use the IC, 7104 // When the target has a custom call IC generator, use the IC,
7101 // because it is likely to generate better code. 7105 // because it is likely to generate better code.
7102 HValue* context = environment()->LookupContext(); 7106 HValue* context = environment()->context();
7103 call = PreProcessCall( 7107 call = PreProcessCall(
7104 new(zone()) HCallNamed(context, var->name(), argument_count)); 7108 new(zone()) HCallNamed(context, var->name(), argument_count));
7105 } else { 7109 } else {
7106 call = PreProcessCall(new(zone()) HCallKnownGlobal(expr->target(), 7110 call = PreProcessCall(new(zone()) HCallKnownGlobal(expr->target(),
7107 argument_count)); 7111 argument_count));
7108 } 7112 }
7109 } else { 7113 } else {
7110 HValue* context = environment()->LookupContext(); 7114 HGlobalObject* receiver = AddAndCast<HGlobalObject>();
7111 HGlobalObject* receiver = Add<HGlobalObject>(context); 7115 PushAndAdd(New<HPushArgument>(receiver));
7112 PushAndAdd(new(zone()) HPushArgument(receiver));
7113 CHECK_ALIVE(VisitArgumentList(expr->arguments())); 7116 CHECK_ALIVE(VisitArgumentList(expr->arguments()));
7114 7117
7115 call = new(zone()) HCallGlobal(context, var->name(), argument_count); 7118 call = New<HCallGlobal>(var->name(), argument_count);
7116 Drop(argument_count); 7119 Drop(argument_count);
7117 } 7120 }
7118 7121
7119 } else if (expr->IsMonomorphic()) { 7122 } else if (expr->IsMonomorphic()) {
7120 // The function is on the stack in the unoptimized code during 7123 // The function is on the stack in the unoptimized code during
7121 // evaluation of the arguments. 7124 // evaluation of the arguments.
7122 CHECK_ALIVE(VisitForValue(expr->expression())); 7125 CHECK_ALIVE(VisitForValue(expr->expression()));
7123 HValue* function = Top(); 7126 HValue* function = Top();
7124 HValue* context = environment()->LookupContext(); 7127 HGlobalObject* global = AddAndCast<HGlobalObject>();
7125 HGlobalObject* global = Add<HGlobalObject>(context); 7128 HGlobalReceiver* receiver = NewAndCast<HGlobalReceiver>(global);
7126 HGlobalReceiver* receiver = new(zone()) HGlobalReceiver(global);
7127 PushAndAdd(receiver); 7129 PushAndAdd(receiver);
7128 CHECK_ALIVE(VisitExpressions(expr->arguments())); 7130 CHECK_ALIVE(VisitExpressions(expr->arguments()));
7129 Add<HCheckFunction>(function, expr->target()); 7131 Add<HCheckFunction>(function, expr->target());
7130 7132
7131 if (TryInlineBuiltinFunctionCall(expr, true)) { // Drop the function. 7133 if (TryInlineBuiltinFunctionCall(expr, true)) { // Drop the function.
7132 if (FLAG_trace_inlining) { 7134 if (FLAG_trace_inlining) {
7133 PrintF("Inlining builtin "); 7135 PrintF("Inlining builtin ");
7134 expr->target()->ShortPrint(); 7136 expr->target()->ShortPrint();
7135 PrintF("\n"); 7137 PrintF("\n");
7136 } 7138 }
7137 return; 7139 return;
7138 } 7140 }
7139 7141
7140 if (TryInlineCall(expr, true)) { // Drop function from environment. 7142 if (TryInlineCall(expr, true)) { // Drop function from environment.
7141 return; 7143 return;
7142 } else { 7144 } else {
7143 call = PreProcessCall( 7145 call = PreProcessCall(
7144 new(zone()) HInvokeFunction(context, 7146 NewAndCast<HInvokeFunction>(function, expr->target(),
7145 function, 7147 argument_count));
7146 expr->target(),
7147 argument_count));
7148 Drop(1); // The function. 7148 Drop(1); // The function.
7149 } 7149 }
7150 7150
7151 } else { 7151 } else {
7152 CHECK_ALIVE(VisitForValue(expr->expression())); 7152 CHECK_ALIVE(VisitForValue(expr->expression()));
7153 HValue* function = Top(); 7153 HValue* function = Top();
7154 HValue* context = environment()->LookupContext(); 7154 HGlobalObject* global_object = AddAndCast<HGlobalObject>();
7155 HGlobalObject* global_object = Add<HGlobalObject>(context); 7155 HGlobalReceiver* receiver = AddAndCast<HGlobalReceiver>(global_object);
7156 HGlobalReceiver* receiver = Add<HGlobalReceiver>(global_object); 7156 PushAndAdd(New<HPushArgument>(receiver));
7157 PushAndAdd(new(zone()) HPushArgument(receiver));
7158 CHECK_ALIVE(VisitArgumentList(expr->arguments())); 7157 CHECK_ALIVE(VisitArgumentList(expr->arguments()));
7159 7158
7160 call = new(zone()) HCallFunction(context, function, argument_count); 7159 call = New<HCallFunction>(function, argument_count);
7161 Drop(argument_count + 1); 7160 Drop(argument_count + 1);
7162 } 7161 }
7163 } 7162 }
7164 7163
7165 call->set_position(expr->position()); 7164 call->set_position(expr->position());
7166 return ast_context()->ReturnInstruction(call, expr->id()); 7165 return ast_context()->ReturnInstruction(call, expr->id());
7167 } 7166 }
7168 7167
7169 7168
7170 // Checks whether allocation using the given constructor can be inlined. 7169 // Checks whether allocation using the given constructor can be inlined.
7171 static bool IsAllocationInlineable(Handle<JSFunction> constructor) { 7170 static bool IsAllocationInlineable(Handle<JSFunction> constructor) {
7172 return constructor->has_initial_map() && 7171 return constructor->has_initial_map() &&
7173 constructor->initial_map()->instance_type() == JS_OBJECT_TYPE && 7172 constructor->initial_map()->instance_type() == JS_OBJECT_TYPE &&
7174 constructor->initial_map()->instance_size() < HAllocate::kMaxInlineSize && 7173 constructor->initial_map()->instance_size() < HAllocate::kMaxInlineSize &&
7175 constructor->initial_map()->InitialPropertiesLength() == 0; 7174 constructor->initial_map()->InitialPropertiesLength() == 0;
7176 } 7175 }
7177 7176
7178 7177
7179 void HOptimizedGraphBuilder::VisitCallNew(CallNew* expr) { 7178 void HOptimizedGraphBuilder::VisitCallNew(CallNew* expr) {
7180 ASSERT(!HasStackOverflow()); 7179 ASSERT(!HasStackOverflow());
7181 ASSERT(current_block() != NULL); 7180 ASSERT(current_block() != NULL);
7182 ASSERT(current_block()->HasPredecessor()); 7181 ASSERT(current_block()->HasPredecessor());
7183 int argument_count = expr->arguments()->length() + 1; // Plus constructor. 7182 int argument_count = expr->arguments()->length() + 1; // Plus constructor.
7184 HValue* context = environment()->LookupContext(); 7183 HValue* context = environment()->context();
7185 Factory* factory = isolate()->factory(); 7184 Factory* factory = isolate()->factory();
7186 7185
7187 if (FLAG_inline_construct && 7186 if (FLAG_inline_construct &&
7188 expr->IsMonomorphic() && 7187 expr->IsMonomorphic() &&
7189 IsAllocationInlineable(expr->target())) { 7188 IsAllocationInlineable(expr->target())) {
7190 // The constructor function is on the stack in the unoptimized code 7189 // The constructor function is on the stack in the unoptimized code
7191 // during evaluation of the arguments. 7190 // during evaluation of the arguments.
7192 CHECK_ALIVE(VisitForValue(expr->expression())); 7191 CHECK_ALIVE(VisitForValue(expr->expression()));
7193 HValue* function = Top(); 7192 HValue* function = Top();
7194 CHECK_ALIVE(VisitExpressions(expr->arguments())); 7193 CHECK_ALIVE(VisitExpressions(expr->arguments()));
(...skipping 14 matching lines...) Expand all
7209 7208
7210 // Allocate an instance of the implicit receiver object. 7209 // Allocate an instance of the implicit receiver object.
7211 HValue* size_in_bytes = Add<HConstant>(instance_size); 7210 HValue* size_in_bytes = Add<HConstant>(instance_size);
7212 HAllocate::Flags flags = HAllocate::DefaultFlags(); 7211 HAllocate::Flags flags = HAllocate::DefaultFlags();
7213 if (FLAG_pretenuring_call_new && 7212 if (FLAG_pretenuring_call_new &&
7214 isolate()->heap()->ShouldGloballyPretenure()) { 7213 isolate()->heap()->ShouldGloballyPretenure()) {
7215 flags = static_cast<HAllocate::Flags>( 7214 flags = static_cast<HAllocate::Flags>(
7216 flags | HAllocate::CAN_ALLOCATE_IN_OLD_POINTER_SPACE); 7215 flags | HAllocate::CAN_ALLOCATE_IN_OLD_POINTER_SPACE);
7217 } 7216 }
7218 HAllocate* receiver = 7217 HAllocate* receiver =
7219 Add<HAllocate>(context, size_in_bytes, HType::JSObject(), flags); 7218 AddAndCast<HAllocate>(size_in_bytes, HType::JSObject(), flags);
7220 receiver->set_known_initial_map(initial_map); 7219 receiver->set_known_initial_map(initial_map);
7221 7220
7222 // Load the initial map from the constructor. 7221 // Load the initial map from the constructor.
7223 HValue* constructor_value = Add<HConstant>(constructor); 7222 HValue* constructor_value = Add<HConstant>(constructor);
7224 HValue* initial_map_value = 7223 HValue* initial_map_value =
7225 AddLoad(constructor_value, HObjectAccess::ForJSObjectOffset( 7224 Add<HLoadNamedField>(constructor_value, HObjectAccess::ForJSObjectOffset(
7226 JSFunction::kPrototypeOrInitialMapOffset)); 7225 JSFunction::kPrototypeOrInitialMapOffset));
7227 7226
7228 // Initialize map and fields of the newly allocated object. 7227 // Initialize map and fields of the newly allocated object.
7229 { NoObservableSideEffectsScope no_effects(this); 7228 { NoObservableSideEffectsScope no_effects(this);
7230 ASSERT(initial_map->instance_type() == JS_OBJECT_TYPE); 7229 ASSERT(initial_map->instance_type() == JS_OBJECT_TYPE);
7231 AddStore(receiver, 7230 Add<HStoreNamedField>(receiver,
7232 HObjectAccess::ForJSObjectOffset(JSObject::kMapOffset), 7231 HObjectAccess::ForJSObjectOffset(JSObject::kMapOffset),
7233 initial_map_value); 7232 initial_map_value);
7234 HValue* empty_fixed_array = Add<HConstant>(factory->empty_fixed_array()); 7233 HValue* empty_fixed_array = Add<HConstant>(factory->empty_fixed_array());
7235 AddStore(receiver, 7234 Add<HStoreNamedField>(receiver,
7236 HObjectAccess::ForJSObjectOffset(JSObject::kPropertiesOffset), 7235 HObjectAccess::ForJSObjectOffset(JSObject::kPropertiesOffset),
7237 empty_fixed_array); 7236 empty_fixed_array);
7238 AddStore(receiver, 7237 Add<HStoreNamedField>(receiver,
7239 HObjectAccess::ForJSObjectOffset(JSObject::kElementsOffset), 7238 HObjectAccess::ForJSObjectOffset(JSObject::kElementsOffset),
7240 empty_fixed_array); 7239 empty_fixed_array);
7241 if (initial_map->inobject_properties() != 0) { 7240 if (initial_map->inobject_properties() != 0) {
7242 HConstant* undefined = graph()->GetConstantUndefined(); 7241 HConstant* undefined = graph()->GetConstantUndefined();
7243 for (int i = 0; i < initial_map->inobject_properties(); i++) { 7242 for (int i = 0; i < initial_map->inobject_properties(); i++) {
7244 int property_offset = JSObject::kHeaderSize + i * kPointerSize; 7243 int property_offset = JSObject::kHeaderSize + i * kPointerSize;
7245 AddStore(receiver, 7244 Add<HStoreNamedField>(receiver,
7246 HObjectAccess::ForJSObjectOffset(property_offset), 7245 HObjectAccess::ForJSObjectOffset(property_offset),
7247 undefined); 7246 undefined);
7248 } 7247 }
7249 } 7248 }
7250 } 7249 }
7251 7250
7252 // Replace the constructor function with a newly allocated receiver using 7251 // Replace the constructor function with a newly allocated receiver using
7253 // the index of the receiver from the top of the expression stack. 7252 // the index of the receiver from the top of the expression stack.
7254 const int receiver_index = argument_count - 1; 7253 const int receiver_index = argument_count - 1;
7255 ASSERT(environment()->ExpressionStackAt(receiver_index) == function); 7254 ASSERT(environment()->ExpressionStackAt(receiver_index) == function);
7256 environment()->SetExpressionStackAt(receiver_index, receiver); 7255 environment()->SetExpressionStackAt(receiver_index, receiver);
7257 7256
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
7335 ASSERT(static_cast<size_t>(lookup_index) < 7334 ASSERT(static_cast<size_t>(lookup_index) <
7336 ARRAY_SIZE(kInlineFunctionGenerators)); 7335 ARRAY_SIZE(kInlineFunctionGenerators));
7337 InlineFunctionGenerator generator = kInlineFunctionGenerators[lookup_index]; 7336 InlineFunctionGenerator generator = kInlineFunctionGenerators[lookup_index];
7338 7337
7339 // Call the inline code generator using the pointer-to-member. 7338 // Call the inline code generator using the pointer-to-member.
7340 (this->*generator)(expr); 7339 (this->*generator)(expr);
7341 } else { 7340 } else {
7342 ASSERT(function->intrinsic_type == Runtime::RUNTIME); 7341 ASSERT(function->intrinsic_type == Runtime::RUNTIME);
7343 CHECK_ALIVE(VisitArgumentList(expr->arguments())); 7342 CHECK_ALIVE(VisitArgumentList(expr->arguments()));
7344 7343
7345 HValue* context = environment()->LookupContext();
7346 Handle<String> name = expr->name(); 7344 Handle<String> name = expr->name();
7347 int argument_count = expr->arguments()->length(); 7345 int argument_count = expr->arguments()->length();
7348 HCallRuntime* call = 7346 HCallRuntime* call = NewAndCast<HCallRuntime>(name, function,
7349 new(zone()) HCallRuntime(context, name, function, argument_count); 7347 argument_count);
7350 Drop(argument_count); 7348 Drop(argument_count);
7351 return ast_context()->ReturnInstruction(call, expr->id()); 7349 return ast_context()->ReturnInstruction(call, expr->id());
7352 } 7350 }
7353 } 7351 }
7354 7352
7355 7353
7356 void HOptimizedGraphBuilder::VisitUnaryOperation(UnaryOperation* expr) { 7354 void HOptimizedGraphBuilder::VisitUnaryOperation(UnaryOperation* expr) {
7357 ASSERT(!HasStackOverflow()); 7355 ASSERT(!HasStackOverflow());
7358 ASSERT(current_block() != NULL); 7356 ASSERT(current_block() != NULL);
7359 ASSERT(current_block()->HasPredecessor()); 7357 ASSERT(current_block()->HasPredecessor());
(...skipping 10 matching lines...) Expand all
7370 7368
7371 7369
7372 void HOptimizedGraphBuilder::VisitDelete(UnaryOperation* expr) { 7370 void HOptimizedGraphBuilder::VisitDelete(UnaryOperation* expr) {
7373 Property* prop = expr->expression()->AsProperty(); 7371 Property* prop = expr->expression()->AsProperty();
7374 VariableProxy* proxy = expr->expression()->AsVariableProxy(); 7372 VariableProxy* proxy = expr->expression()->AsVariableProxy();
7375 if (prop != NULL) { 7373 if (prop != NULL) {
7376 CHECK_ALIVE(VisitForValue(prop->obj())); 7374 CHECK_ALIVE(VisitForValue(prop->obj()));
7377 CHECK_ALIVE(VisitForValue(prop->key())); 7375 CHECK_ALIVE(VisitForValue(prop->key()));
7378 HValue* key = Pop(); 7376 HValue* key = Pop();
7379 HValue* obj = Pop(); 7377 HValue* obj = Pop();
7380 HValue* context = environment()->LookupContext(); 7378 HValue* function = AddLoadJSBuiltin(Builtins::DELETE);
7381 HValue* function = AddLoadJSBuiltin(Builtins::DELETE, context);
7382 Add<HPushArgument>(obj); 7379 Add<HPushArgument>(obj);
7383 Add<HPushArgument>(key); 7380 Add<HPushArgument>(key);
7384 Add<HPushArgument>(Add<HConstant>(function_strict_mode_flag())); 7381 Add<HPushArgument>(Add<HConstant>(function_strict_mode_flag()));
7385 // TODO(olivf) InvokeFunction produces a check for the parameter count, 7382 // TODO(olivf) InvokeFunction produces a check for the parameter count,
7386 // even though we are certain to pass the correct number of arguments here. 7383 // even though we are certain to pass the correct number of arguments here.
7387 HInstruction* instr = new(zone()) HInvokeFunction(context, function, 3); 7384 HInstruction* instr = New<HInvokeFunction>(function, 3);
7388 return ast_context()->ReturnInstruction(instr, expr->id()); 7385 return ast_context()->ReturnInstruction(instr, expr->id());
7389 } else if (proxy != NULL) { 7386 } else if (proxy != NULL) {
7390 Variable* var = proxy->var(); 7387 Variable* var = proxy->var();
7391 if (var->IsUnallocated()) { 7388 if (var->IsUnallocated()) {
7392 Bailout("delete with global variable"); 7389 Bailout("delete with global variable");
7393 } else if (var->IsStackAllocated() || var->IsContextSlot()) { 7390 } else if (var->IsStackAllocated() || var->IsContextSlot()) {
7394 // Result of deleting non-global variables is false. 'this' is not 7391 // Result of deleting non-global variables is false. 'this' is not
7395 // really a variable, though we implement it as one. The 7392 // really a variable, though we implement it as one. The
7396 // subexpression does not have side effects. 7393 // subexpression does not have side effects.
7397 HValue* value = var->is_this() 7394 HValue* value = var->is_this()
(...skipping 14 matching lines...) Expand all
7412 7409
7413 void HOptimizedGraphBuilder::VisitVoid(UnaryOperation* expr) { 7410 void HOptimizedGraphBuilder::VisitVoid(UnaryOperation* expr) {
7414 CHECK_ALIVE(VisitForEffect(expr->expression())); 7411 CHECK_ALIVE(VisitForEffect(expr->expression()));
7415 return ast_context()->ReturnValue(graph()->GetConstantUndefined()); 7412 return ast_context()->ReturnValue(graph()->GetConstantUndefined());
7416 } 7413 }
7417 7414
7418 7415
7419 void HOptimizedGraphBuilder::VisitTypeof(UnaryOperation* expr) { 7416 void HOptimizedGraphBuilder::VisitTypeof(UnaryOperation* expr) {
7420 CHECK_ALIVE(VisitForTypeOf(expr->expression())); 7417 CHECK_ALIVE(VisitForTypeOf(expr->expression()));
7421 HValue* value = Pop(); 7418 HValue* value = Pop();
7422 HValue* context = environment()->LookupContext(); 7419 HValue* context = environment()->context();
7423 HInstruction* instr = new(zone()) HTypeof(context, value); 7420 HInstruction* instr = new(zone()) HTypeof(context, value);
7424 return ast_context()->ReturnInstruction(instr, expr->id()); 7421 return ast_context()->ReturnInstruction(instr, expr->id());
7425 } 7422 }
7426 7423
7427 7424
7428 void HOptimizedGraphBuilder::VisitSub(UnaryOperation* expr) { 7425 void HOptimizedGraphBuilder::VisitSub(UnaryOperation* expr) {
7429 CHECK_ALIVE(VisitForValue(expr->expression())); 7426 CHECK_ALIVE(VisitForValue(expr->expression()));
7430 Handle<Type> operand_type = expr->expression()->bounds().lower; 7427 Handle<Type> operand_type = expr->expression()->bounds().lower;
7431 HValue* value = TruncateToNumber(Pop(), &operand_type); 7428 HValue* value = TruncateToNumber(Pop(), &operand_type);
7432 HInstruction* instr = BuildUnaryMathOp(value, operand_type, Token::SUB); 7429 HInstruction* instr = BuildUnaryMathOp(value, operand_type, Token::SUB);
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
7509 } 7506 }
7510 Push(number_input); 7507 Push(number_input);
7511 } 7508 }
7512 7509
7513 // The addition has no side effects, so we do not need 7510 // The addition has no side effects, so we do not need
7514 // to simulate the expression stack after this instruction. 7511 // to simulate the expression stack after this instruction.
7515 // Any later failures deopt to the load of the input or earlier. 7512 // Any later failures deopt to the load of the input or earlier.
7516 HConstant* delta = (expr->op() == Token::INC) 7513 HConstant* delta = (expr->op() == Token::INC)
7517 ? graph()->GetConstant1() 7514 ? graph()->GetConstant1()
7518 : graph()->GetConstantMinus1(); 7515 : graph()->GetConstantMinus1();
7519 HValue* context = environment()->LookupContext(); 7516 HInstruction* instr = Add<HAdd>(Top(), delta);
7520 HInstruction* instr = HAdd::New(zone(), context, Top(), delta);
7521 instr->SetFlag(HInstruction::kCannotBeTagged); 7517 instr->SetFlag(HInstruction::kCannotBeTagged);
7522 instr->ClearAllSideEffects(); 7518 instr->ClearAllSideEffects();
7523 AddInstruction(instr);
7524 return instr; 7519 return instr;
7525 } 7520 }
7526 7521
7527 7522
7528 void HOptimizedGraphBuilder::VisitCountOperation(CountOperation* expr) { 7523 void HOptimizedGraphBuilder::VisitCountOperation(CountOperation* expr) {
7529 ASSERT(!HasStackOverflow()); 7524 ASSERT(!HasStackOverflow());
7530 ASSERT(current_block() != NULL); 7525 ASSERT(current_block() != NULL);
7531 ASSERT(current_block()->HasPredecessor()); 7526 ASSERT(current_block()->HasPredecessor());
7532 Expression* target = expr->expression(); 7527 Expression* target = expr->expression();
7533 VariableProxy* proxy = target->AsVariableProxy(); 7528 VariableProxy* proxy = target->AsVariableProxy();
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
7582 for (int i = 0; i < count; ++i) { 7577 for (int i = 0; i < count; ++i) {
7583 if (var == current_info()->scope()->parameter(i)) { 7578 if (var == current_info()->scope()->parameter(i)) {
7584 return Bailout("assignment to parameter in arguments object"); 7579 return Bailout("assignment to parameter in arguments object");
7585 } 7580 }
7586 } 7581 }
7587 } 7582 }
7588 7583
7589 HValue* context = BuildContextChainWalk(var); 7584 HValue* context = BuildContextChainWalk(var);
7590 HStoreContextSlot::Mode mode = IsLexicalVariableMode(var->mode()) 7585 HStoreContextSlot::Mode mode = IsLexicalVariableMode(var->mode())
7591 ? HStoreContextSlot::kCheckDeoptimize : HStoreContextSlot::kNoCheck; 7586 ? HStoreContextSlot::kCheckDeoptimize : HStoreContextSlot::kNoCheck;
7592 HStoreContextSlot* instr = Add<HStoreContextSlot>(context, var->index(), 7587 HStoreContextSlot* instr =
7593 mode, after); 7588 AddAndCast<HStoreContextSlot>(context, var->index(),
7589 mode, after);
7594 if (instr->HasObservableSideEffects()) { 7590 if (instr->HasObservableSideEffects()) {
7595 Add<HSimulate>(expr->AssignmentId(), REMOVABLE_SIMULATE); 7591 Add<HSimulate>(expr->AssignmentId(), REMOVABLE_SIMULATE);
7596 } 7592 }
7597 break; 7593 break;
7598 } 7594 }
7599 7595
7600 case Variable::LOOKUP: 7596 case Variable::LOOKUP:
7601 return Bailout("lookup variable in count operation"); 7597 return Bailout("lookup variable in count operation");
7602 } 7598 }
7603 7599
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
7678 Add<HSimulate>(expr->AssignmentId(), REMOVABLE_SIMULATE); 7674 Add<HSimulate>(expr->AssignmentId(), REMOVABLE_SIMULATE);
7679 } 7675 }
7680 } 7676 }
7681 7677
7682 Drop(returns_original_input ? 2 : 1); 7678 Drop(returns_original_input ? 2 : 1);
7683 return ast_context()->ReturnValue(expr->is_postfix() ? input : after); 7679 return ast_context()->ReturnValue(expr->is_postfix() ? input : after);
7684 } 7680 }
7685 7681
7686 7682
7687 HInstruction* HOptimizedGraphBuilder::BuildStringCharCodeAt( 7683 HInstruction* HOptimizedGraphBuilder::BuildStringCharCodeAt(
7688 HValue* context,
7689 HValue* string, 7684 HValue* string,
7690 HValue* index) { 7685 HValue* index) {
7691 if (string->IsConstant() && index->IsConstant()) { 7686 if (string->IsConstant() && index->IsConstant()) {
7692 HConstant* c_string = HConstant::cast(string); 7687 HConstant* c_string = HConstant::cast(string);
7693 HConstant* c_index = HConstant::cast(index); 7688 HConstant* c_index = HConstant::cast(index);
7694 if (c_string->HasStringValue() && c_index->HasNumberValue()) { 7689 if (c_string->HasStringValue() && c_index->HasNumberValue()) {
7695 int32_t i = c_index->NumberValueAsInteger32(); 7690 int32_t i = c_index->NumberValueAsInteger32();
7696 Handle<String> s = c_string->StringValue(); 7691 Handle<String> s = c_string->StringValue();
7697 if (i < 0 || i >= s->length()) { 7692 if (i < 0 || i >= s->length()) {
7698 return new(zone()) HConstant(OS::nan_value()); 7693 return New<HConstant>(OS::nan_value());
7699 } 7694 }
7700 return new(zone()) HConstant(s->Get(i)); 7695 return New<HConstant>(s->Get(i));
7701 } 7696 }
7702 } 7697 }
7703 BuildCheckHeapObject(string); 7698 BuildCheckHeapObject(string);
7704 AddInstruction(HCheckInstanceType::NewIsString(string, zone())); 7699 AddInstruction(HCheckInstanceType::NewIsString(string, zone()));
7705 HInstruction* length = HStringLength::New(zone(), string); 7700 HInstruction* length = Add<HStringLength>(string);
7706 AddInstruction(length);
7707 HInstruction* checked_index = Add<HBoundsCheck>(index, length); 7701 HInstruction* checked_index = Add<HBoundsCheck>(index, length);
7708 return new(zone()) HStringCharCodeAt(context, string, checked_index); 7702 return New<HStringCharCodeAt>(string, checked_index);
7709 } 7703 }
7710 7704
7711 7705
7712 // Checks if the given shift amounts have form: (sa) and (32 - sa). 7706 // Checks if the given shift amounts have form: (sa) and (32 - sa).
7713 static bool ShiftAmountsAllowReplaceByRotate(HValue* sa, 7707 static bool ShiftAmountsAllowReplaceByRotate(HValue* sa,
7714 HValue* const32_minus_sa) { 7708 HValue* const32_minus_sa) {
7715 if (!const32_minus_sa->IsSub()) return false; 7709 if (!const32_minus_sa->IsSub()) return false;
7716 HSub* sub = HSub::cast(const32_minus_sa); 7710 HSub* sub = HSub::cast(const32_minus_sa);
7717 if (sa != sub->right()) return false; 7711 if (sa != sub->right()) return false;
7718 HValue* const32 = sub->left(); 7712 HValue* const32 = sub->left();
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
7787 // tagged representation later on. 7781 // tagged representation later on.
7788 if (expected_type->Is(Type::Oddball())) { 7782 if (expected_type->Is(Type::Oddball())) {
7789 // TODO(olivf) The BinaryOpStub only records undefined. It might pay off to 7783 // TODO(olivf) The BinaryOpStub only records undefined. It might pay off to
7790 // also record booleans and convert them to 0/1 here. 7784 // also record booleans and convert them to 0/1 here.
7791 IfBuilder if_nan(this); 7785 IfBuilder if_nan(this);
7792 if_nan.If<HCompareObjectEqAndBranch>(value, 7786 if_nan.If<HCompareObjectEqAndBranch>(value,
7793 graph()->GetConstantUndefined()); 7787 graph()->GetConstantUndefined());
7794 if_nan.Then(); 7788 if_nan.Then();
7795 if_nan.ElseDeopt(); 7789 if_nan.ElseDeopt();
7796 if_nan.End(); 7790 if_nan.End();
7797 return Add<HConstant>(OS::nan_value(), Representation::Double()); 7791 return Add<HConstant>(OS::nan_value());
7798 } 7792 }
7799 7793
7800 return value; 7794 return value;
7801 } 7795 }
7802 7796
7803 7797
7804 HInstruction* HOptimizedGraphBuilder::BuildBinaryOperation( 7798 HInstruction* HOptimizedGraphBuilder::BuildBinaryOperation(
7805 BinaryOperation* expr, 7799 BinaryOperation* expr,
7806 HValue* left, 7800 HValue* left,
7807 HValue* right) { 7801 HValue* right) {
7808 HValue* context = environment()->LookupContext(); 7802 HValue* context = environment()->context();
7809 Handle<Type> left_type = expr->left()->bounds().lower; 7803 Handle<Type> left_type = expr->left()->bounds().lower;
7810 Handle<Type> right_type = expr->right()->bounds().lower; 7804 Handle<Type> right_type = expr->right()->bounds().lower;
7811 Handle<Type> result_type = expr->bounds().lower; 7805 Handle<Type> result_type = expr->bounds().lower;
7812 Maybe<int> fixed_right_arg = expr->fixed_right_arg(); 7806 Maybe<int> fixed_right_arg = expr->fixed_right_arg();
7813 Representation left_rep = Representation::FromType(left_type); 7807 Representation left_rep = Representation::FromType(left_type);
7814 Representation right_rep = Representation::FromType(right_type); 7808 Representation right_rep = Representation::FromType(right_type);
7815 Representation result_rep = Representation::FromType(result_type); 7809 Representation result_rep = Representation::FromType(result_type);
7816 7810
7817 if (expr->op() != Token::ADD || 7811 if (expr->op() != Token::ADD ||
7818 (left->type().IsNonString() && right->type().IsNonString())) { 7812 (left->type().IsNonString() && right->type().IsNonString())) {
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
7851 instr = HMul::New(zone(), context, left, right); 7845 instr = HMul::New(zone(), context, left, right);
7852 break; 7846 break;
7853 case Token::MOD: 7847 case Token::MOD:
7854 instr = HMod::New(zone(), context, left, right, fixed_right_arg); 7848 instr = HMod::New(zone(), context, left, right, fixed_right_arg);
7855 break; 7849 break;
7856 case Token::DIV: 7850 case Token::DIV:
7857 instr = HDiv::New(zone(), context, left, right); 7851 instr = HDiv::New(zone(), context, left, right);
7858 break; 7852 break;
7859 case Token::BIT_XOR: 7853 case Token::BIT_XOR:
7860 case Token::BIT_AND: 7854 case Token::BIT_AND:
7861 instr = HBitwise::New(zone(), expr->op(), context, left, right); 7855 instr = New<HBitwise>(expr->op(), left, right);
7862 break; 7856 break;
7863 case Token::BIT_OR: { 7857 case Token::BIT_OR: {
7864 HValue* operand, *shift_amount; 7858 HValue* operand, *shift_amount;
7865 if (left_type->Is(Type::Signed32()) && 7859 if (left_type->Is(Type::Signed32()) &&
7866 right_type->Is(Type::Signed32()) && 7860 right_type->Is(Type::Signed32()) &&
7867 MatchRotateRight(left, right, &operand, &shift_amount)) { 7861 MatchRotateRight(left, right, &operand, &shift_amount)) {
7868 instr = new(zone()) HRor(context, operand, shift_amount); 7862 instr = new(zone()) HRor(context, operand, shift_amount);
7869 } else { 7863 } else {
7870 instr = HBitwise::New(zone(), expr->op(), context, left, right); 7864 instr = New<HBitwise>(expr->op(), left, right);
7871 } 7865 }
7872 break; 7866 break;
7873 } 7867 }
7874 case Token::SAR: 7868 case Token::SAR:
7875 instr = HSar::New(zone(), context, left, right); 7869 instr = HSar::New(zone(), context, left, right);
7876 break; 7870 break;
7877 case Token::SHR: 7871 case Token::SHR:
7878 instr = HShr::New(zone(), context, left, right); 7872 instr = HShr::New(zone(), context, left, right);
7879 if (FLAG_opt_safe_uint32_operations && instr->IsShr() && 7873 if (FLAG_opt_safe_uint32_operations && instr->IsShr() &&
7880 CanBeZero(right)) { 7874 CanBeZero(right)) {
(...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after
8105 Handle<Type> left_type = expr->left()->bounds().lower; 8099 Handle<Type> left_type = expr->left()->bounds().lower;
8106 Handle<Type> right_type = expr->right()->bounds().lower; 8100 Handle<Type> right_type = expr->right()->bounds().lower;
8107 Handle<Type> combined_type = expr->combined_type(); 8101 Handle<Type> combined_type = expr->combined_type();
8108 Representation combined_rep = Representation::FromType(combined_type); 8102 Representation combined_rep = Representation::FromType(combined_type);
8109 Representation left_rep = Representation::FromType(left_type); 8103 Representation left_rep = Representation::FromType(left_type);
8110 Representation right_rep = Representation::FromType(right_type); 8104 Representation right_rep = Representation::FromType(right_type);
8111 8105
8112 CHECK_ALIVE(VisitForValue(expr->left())); 8106 CHECK_ALIVE(VisitForValue(expr->left()));
8113 CHECK_ALIVE(VisitForValue(expr->right())); 8107 CHECK_ALIVE(VisitForValue(expr->right()));
8114 8108
8115 HValue* context = environment()->LookupContext(); 8109 HValue* context = environment()->context();
8116 HValue* right = Pop(); 8110 HValue* right = Pop();
8117 HValue* left = Pop(); 8111 HValue* left = Pop();
8118 Token::Value op = expr->op(); 8112 Token::Value op = expr->op();
8119 8113
8120 if (IsLiteralCompareBool(left, op, right)) { 8114 if (IsLiteralCompareBool(left, op, right)) {
8121 HCompareObjectEqAndBranch* result = 8115 HCompareObjectEqAndBranch* result =
8122 new(zone()) HCompareObjectEqAndBranch(left, right); 8116 NewAndCast<HCompareObjectEqAndBranch>(left, right);
8123 result->set_position(expr->position()); 8117 result->set_position(expr->position());
8124 return ast_context()->ReturnControl(result, expr->id()); 8118 return ast_context()->ReturnControl(result, expr->id());
8125 } 8119 }
8126 8120
8127 if (op == Token::INSTANCEOF) { 8121 if (op == Token::INSTANCEOF) {
8128 // Check to see if the rhs of the instanceof is a global function not 8122 // Check to see if the rhs of the instanceof is a global function not
8129 // residing in new space. If it is we assume that the function will stay the 8123 // residing in new space. If it is we assume that the function will stay the
8130 // same. 8124 // same.
8131 Handle<JSFunction> target = Handle<JSFunction>::null(); 8125 Handle<JSFunction> target = Handle<JSFunction>::null();
8132 VariableProxy* proxy = expr->right()->AsVariableProxy(); 8126 VariableProxy* proxy = expr->right()->AsVariableProxy();
(...skipping 25 matching lines...) Expand all
8158 Add<HCheckFunction>(right, target); 8152 Add<HCheckFunction>(right, target);
8159 HInstanceOfKnownGlobal* result = 8153 HInstanceOfKnownGlobal* result =
8160 new(zone()) HInstanceOfKnownGlobal(context, left, target); 8154 new(zone()) HInstanceOfKnownGlobal(context, left, target);
8161 result->set_position(expr->position()); 8155 result->set_position(expr->position());
8162 return ast_context()->ReturnInstruction(result, expr->id()); 8156 return ast_context()->ReturnInstruction(result, expr->id());
8163 } 8157 }
8164 8158
8165 // Code below assumes that we don't fall through. 8159 // Code below assumes that we don't fall through.
8166 UNREACHABLE(); 8160 UNREACHABLE();
8167 } else if (op == Token::IN) { 8161 } else if (op == Token::IN) {
8168 HValue* function = AddLoadJSBuiltin(Builtins::IN, context); 8162 HValue* function = AddLoadJSBuiltin(Builtins::IN);
8169 Add<HPushArgument>(left); 8163 Add<HPushArgument>(left);
8170 Add<HPushArgument>(right); 8164 Add<HPushArgument>(right);
8171 // TODO(olivf) InvokeFunction produces a check for the parameter count, 8165 // TODO(olivf) InvokeFunction produces a check for the parameter count,
8172 // even though we are certain to pass the correct number of arguments here. 8166 // even though we are certain to pass the correct number of arguments here.
8173 HInstruction* result = new(zone()) HInvokeFunction(context, function, 2); 8167 HInstruction* result = new(zone()) HInvokeFunction(context, function, 2);
8174 result->set_position(expr->position()); 8168 result->set_position(expr->position());
8175 return ast_context()->ReturnInstruction(result, expr->id()); 8169 return ast_context()->ReturnInstruction(result, expr->id());
8176 } 8170 }
8177 8171
8178 // Cases handled below depend on collected type feedback. They should 8172 // Cases handled below depend on collected type feedback. They should
8179 // soft deoptimize when there is no type feedback. 8173 // soft deoptimize when there is no type feedback.
8180 if (combined_type->Is(Type::None())) { 8174 if (combined_type->Is(Type::None())) {
8181 Add<HDeoptimize>(Deoptimizer::SOFT); 8175 Add<HDeoptimize>(Deoptimizer::SOFT);
8182 combined_type = left_type = right_type = handle(Type::Any(), isolate()); 8176 combined_type = left_type = right_type = handle(Type::Any(), isolate());
8183 } 8177 }
8184 8178
8185 if (combined_type->Is(Type::Receiver())) { 8179 if (combined_type->Is(Type::Receiver())) {
8186 switch (op) { 8180 switch (op) {
8187 case Token::EQ: 8181 case Token::EQ:
8188 case Token::EQ_STRICT: { 8182 case Token::EQ_STRICT: {
8189 // Can we get away with map check and not instance type check? 8183 // Can we get away with map check and not instance type check?
8190 if (combined_type->IsClass()) { 8184 if (combined_type->IsClass()) {
8191 Handle<Map> map = combined_type->AsClass(); 8185 Handle<Map> map = combined_type->AsClass();
8192 AddCheckMapsWithTransitions(left, map); 8186 AddCheckMapsWithTransitions(left, map);
8193 AddCheckMapsWithTransitions(right, map); 8187 AddCheckMapsWithTransitions(right, map);
8194 HCompareObjectEqAndBranch* result = 8188 HCompareObjectEqAndBranch* result =
8195 new(zone()) HCompareObjectEqAndBranch(left, right); 8189 NewAndCast<HCompareObjectEqAndBranch>(left, right);
8196 result->set_position(expr->position()); 8190 result->set_position(expr->position());
8197 return ast_context()->ReturnControl(result, expr->id()); 8191 return ast_context()->ReturnControl(result, expr->id());
8198 } else { 8192 } else {
8199 BuildCheckHeapObject(left); 8193 BuildCheckHeapObject(left);
8200 AddInstruction(HCheckInstanceType::NewIsSpecObject(left, zone())); 8194 AddInstruction(HCheckInstanceType::NewIsSpecObject(left, zone()));
8201 BuildCheckHeapObject(right); 8195 BuildCheckHeapObject(right);
8202 AddInstruction(HCheckInstanceType::NewIsSpecObject(right, zone())); 8196 AddInstruction(HCheckInstanceType::NewIsSpecObject(right, zone()));
8203 HCompareObjectEqAndBranch* result = 8197 HCompareObjectEqAndBranch* result =
8204 new(zone()) HCompareObjectEqAndBranch(left, right); 8198 new(zone()) HCompareObjectEqAndBranch(left, right);
8205 result->set_position(expr->position()); 8199 result->set_position(expr->position());
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
8266 ? handle(Type::Any(), isolate_) : expr->combined_type(); 8260 ? handle(Type::Any(), isolate_) : expr->combined_type();
8267 BuildCompareNil(value, type, expr->position(), &continuation); 8261 BuildCompareNil(value, type, expr->position(), &continuation);
8268 return ast_context()->ReturnContinuation(&continuation, expr->id()); 8262 return ast_context()->ReturnContinuation(&continuation, expr->id());
8269 } 8263 }
8270 8264
8271 8265
8272 HInstruction* HOptimizedGraphBuilder::BuildThisFunction() { 8266 HInstruction* HOptimizedGraphBuilder::BuildThisFunction() {
8273 // If we share optimized code between different closures, the 8267 // If we share optimized code between different closures, the
8274 // this-function is not a constant, except inside an inlined body. 8268 // this-function is not a constant, except inside an inlined body.
8275 if (function_state()->outer() != NULL) { 8269 if (function_state()->outer() != NULL) {
8276 return new(zone()) HConstant( 8270 return New<HConstant>(
8277 function_state()->compilation_info()->closure()); 8271 function_state()->compilation_info()->closure());
8278 } else { 8272 } else {
8279 return new(zone()) HThisFunction; 8273 return new(zone()) HThisFunction;
8280 } 8274 }
8281 } 8275 }
8282 8276
8283 8277
8284 HInstruction* HOptimizedGraphBuilder::BuildFastLiteral( 8278 HInstruction* HOptimizedGraphBuilder::BuildFastLiteral(
8285 HValue* context, 8279 HValue* context,
8286 Handle<JSObject> boilerplate_object, 8280 Handle<JSObject> boilerplate_object,
8287 Handle<JSObject> original_boilerplate_object, 8281 Handle<JSObject> original_boilerplate_object,
8288 Handle<Object> allocation_site, 8282 Handle<Object> allocation_site,
8289 int data_size, 8283 int data_size,
8290 int pointer_size, 8284 int pointer_size,
8291 AllocationSiteMode mode) { 8285 AllocationSiteMode mode) {
8292 NoObservableSideEffectsScope no_effects(this); 8286 NoObservableSideEffectsScope no_effects(this);
8293 8287
8294 HInstruction* target = NULL; 8288 HInstruction* target = NULL;
8295 HInstruction* data_target = NULL; 8289 HInstruction* data_target = NULL;
8296 8290
8297 ElementsKind kind = boilerplate_object->map()->elements_kind(); 8291 ElementsKind kind = boilerplate_object->map()->elements_kind();
8298 8292
8299 if (isolate()->heap()->ShouldGloballyPretenure()) { 8293 if (isolate()->heap()->ShouldGloballyPretenure()) {
8300 if (data_size != 0) { 8294 if (data_size != 0) {
8301 HAllocate::Flags data_flags = 8295 HAllocate::Flags data_flags =
8302 static_cast<HAllocate::Flags>(HAllocate::DefaultFlags(kind) | 8296 static_cast<HAllocate::Flags>(HAllocate::DefaultFlags(kind) |
8303 HAllocate::CAN_ALLOCATE_IN_OLD_DATA_SPACE); 8297 HAllocate::CAN_ALLOCATE_IN_OLD_DATA_SPACE);
8304 HValue* size_in_bytes = Add<HConstant>(data_size); 8298 HValue* size_in_bytes = Add<HConstant>(data_size);
8305 data_target = Add<HAllocate>(context, size_in_bytes, HType::JSObject(), 8299 data_target = Add<HAllocate>(size_in_bytes, HType::JSObject(),
8306 data_flags); 8300 data_flags);
8307 Handle<Map> free_space_map = isolate()->factory()->free_space_map(); 8301 Handle<Map> free_space_map = isolate()->factory()->free_space_map();
8308 AddStoreMapConstant(data_target, free_space_map); 8302 AddStoreMapConstant(data_target, free_space_map);
8309 HObjectAccess access = 8303 HObjectAccess access =
8310 HObjectAccess::ForJSObjectOffset(FreeSpace::kSizeOffset); 8304 HObjectAccess::ForJSObjectOffset(FreeSpace::kSizeOffset);
8311 AddStore(data_target, access, size_in_bytes); 8305 Add<HStoreNamedField>(data_target, access, size_in_bytes);
8312 } 8306 }
8313 if (pointer_size != 0) { 8307 if (pointer_size != 0) {
8314 HAllocate::Flags pointer_flags = 8308 HAllocate::Flags pointer_flags =
8315 static_cast<HAllocate::Flags>(HAllocate::DefaultFlags() | 8309 static_cast<HAllocate::Flags>(HAllocate::DefaultFlags() |
8316 HAllocate::CAN_ALLOCATE_IN_OLD_POINTER_SPACE); 8310 HAllocate::CAN_ALLOCATE_IN_OLD_POINTER_SPACE);
8317 HValue* size_in_bytes = Add<HConstant>(pointer_size); 8311 HValue* size_in_bytes = Add<HConstant>(pointer_size);
8318 target = Add<HAllocate>(context, size_in_bytes, HType::JSObject(), 8312 target = Add<HAllocate>(size_in_bytes, HType::JSObject(),
8319 pointer_flags); 8313 pointer_flags);
8320 } 8314 }
8321 } else { 8315 } else {
8322 HAllocate::Flags flags = HAllocate::DefaultFlags(kind); 8316 HAllocate::Flags flags = HAllocate::DefaultFlags(kind);
8323 HValue* size_in_bytes = Add<HConstant>(data_size + pointer_size); 8317 HValue* size_in_bytes = Add<HConstant>(data_size + pointer_size);
8324 target = Add<HAllocate>(context, size_in_bytes, HType::JSObject(), flags); 8318 target = Add<HAllocate>(size_in_bytes, HType::JSObject(), flags);
8325 } 8319 }
8326 8320
8327 int offset = 0; 8321 int offset = 0;
8328 int data_offset = 0; 8322 int data_offset = 0;
8329 BuildEmitDeepCopy(boilerplate_object, original_boilerplate_object, 8323 BuildEmitDeepCopy(boilerplate_object, original_boilerplate_object,
8330 allocation_site, target, &offset, data_target, 8324 allocation_site, target, &offset, data_target,
8331 &data_offset, mode); 8325 &data_offset, mode);
8332 return target; 8326 return target;
8333 } 8327 }
8334 8328
8335 8329
8336 void HOptimizedGraphBuilder::BuildEmitDeepCopy( 8330 void HOptimizedGraphBuilder::BuildEmitDeepCopy(
8337 Handle<JSObject> boilerplate_object, 8331 Handle<JSObject> boilerplate_object,
8338 Handle<JSObject> original_boilerplate_object, 8332 Handle<JSObject> original_boilerplate_object,
8339 Handle<Object> allocation_site_object, 8333 Handle<Object> allocation_site_object,
8340 HInstruction* target, 8334 HInstruction* target,
8341 int* offset, 8335 int* offset,
8342 HInstruction* data_target, 8336 HInstruction* data_target,
8343 int* data_offset, 8337 int* data_offset,
8344 AllocationSiteMode mode) { 8338 AllocationSiteMode mode) {
8345 Zone* zone = this->zone();
8346
8347 bool create_allocation_site_info = mode == TRACK_ALLOCATION_SITE && 8339 bool create_allocation_site_info = mode == TRACK_ALLOCATION_SITE &&
8348 boilerplate_object->map()->CanTrackAllocationSite(); 8340 boilerplate_object->map()->CanTrackAllocationSite();
8349 8341
8350 // If using allocation sites, then the payload on the site should already 8342 // If using allocation sites, then the payload on the site should already
8351 // be filled in as a valid (boilerplate) array. 8343 // be filled in as a valid (boilerplate) array.
8352 ASSERT(!create_allocation_site_info || 8344 ASSERT(!create_allocation_site_info ||
8353 AllocationSite::cast(*allocation_site_object)->IsLiteralSite()); 8345 AllocationSite::cast(*allocation_site_object)->IsLiteralSite());
8354 8346
8355 HInstruction* allocation_site = NULL; 8347 HInstruction* allocation_site = NULL;
8356 8348
8357 if (create_allocation_site_info) { 8349 if (create_allocation_site_info) {
8358 allocation_site = AddInstruction(new(zone) HConstant( 8350 allocation_site = Add<HConstant>(allocation_site_object);
8359 allocation_site_object, Representation::Tagged()));
8360 } 8351 }
8361 8352
8362 // Only elements backing stores for non-COW arrays need to be copied. 8353 // Only elements backing stores for non-COW arrays need to be copied.
8363 Handle<FixedArrayBase> elements(boilerplate_object->elements()); 8354 Handle<FixedArrayBase> elements(boilerplate_object->elements());
8364 Handle<FixedArrayBase> original_elements( 8355 Handle<FixedArrayBase> original_elements(
8365 original_boilerplate_object->elements()); 8356 original_boilerplate_object->elements());
8366 ElementsKind kind = boilerplate_object->map()->elements_kind(); 8357 ElementsKind kind = boilerplate_object->map()->elements_kind();
8367 8358
8368 int object_offset = *offset; 8359 int object_offset = *offset;
8369 int object_size = boilerplate_object->map()->instance_size(); 8360 int object_size = boilerplate_object->map()->instance_size();
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
8430 Handle<Object>(boilerplate_object->elements(), isolate()); 8421 Handle<Object>(boilerplate_object->elements(), isolate());
8431 elements = Add<HConstant>(elements_field); 8422 elements = Add<HConstant>(elements_field);
8432 } else { 8423 } else {
8433 if (data_target != NULL && boilerplate_object->HasFastDoubleElements()) { 8424 if (data_target != NULL && boilerplate_object->HasFastDoubleElements()) {
8434 elements = Add<HInnerAllocatedObject>(data_target, elements_offset); 8425 elements = Add<HInnerAllocatedObject>(data_target, elements_offset);
8435 } else { 8426 } else {
8436 elements = Add<HInnerAllocatedObject>(target, elements_offset); 8427 elements = Add<HInnerAllocatedObject>(target, elements_offset);
8437 } 8428 }
8438 result = elements; 8429 result = elements;
8439 } 8430 }
8440 AddStore(object_header, HObjectAccess::ForElementsPointer(), elements); 8431 Add<HStoreNamedField>(object_header, HObjectAccess::ForElementsPointer(),
8432 elements);
8441 8433
8442 Handle<Object> properties_field = 8434 Handle<Object> properties_field =
8443 Handle<Object>(boilerplate_object->properties(), isolate()); 8435 Handle<Object>(boilerplate_object->properties(), isolate());
8444 ASSERT(*properties_field == isolate()->heap()->empty_fixed_array()); 8436 ASSERT(*properties_field == isolate()->heap()->empty_fixed_array());
8445 HInstruction* properties = Add<HConstant>(properties_field); 8437 HInstruction* properties = Add<HConstant>(properties_field);
8446 HObjectAccess access = HObjectAccess::ForPropertiesPointer(); 8438 HObjectAccess access = HObjectAccess::ForPropertiesPointer();
8447 AddStore(object_header, access, properties); 8439 Add<HStoreNamedField>(object_header, access, properties);
8448 8440
8449 if (boilerplate_object->IsJSArray()) { 8441 if (boilerplate_object->IsJSArray()) {
8450 Handle<JSArray> boilerplate_array = 8442 Handle<JSArray> boilerplate_array =
8451 Handle<JSArray>::cast(boilerplate_object); 8443 Handle<JSArray>::cast(boilerplate_object);
8452 Handle<Object> length_field = 8444 Handle<Object> length_field =
8453 Handle<Object>(boilerplate_array->length(), isolate()); 8445 Handle<Object>(boilerplate_array->length(), isolate());
8454 HInstruction* length = Add<HConstant>(length_field); 8446 HInstruction* length = Add<HConstant>(length_field);
8455 8447
8456 ASSERT(boilerplate_array->length()->IsSmi()); 8448 ASSERT(boilerplate_array->length()->IsSmi());
8457 AddStore(object_header, HObjectAccess::ForArrayLength( 8449 Add<HStoreNamedField>(object_header, HObjectAccess::ForArrayLength(
8458 boilerplate_array->GetElementsKind()), length); 8450 boilerplate_array->GetElementsKind()), length);
8459 } 8451 }
8460 8452
8461 return result; 8453 return result;
8462 } 8454 }
8463 8455
8464 8456
8465 void HOptimizedGraphBuilder::BuildEmitInObjectProperties( 8457 void HOptimizedGraphBuilder::BuildEmitInObjectProperties(
8466 Handle<JSObject> boilerplate_object, 8458 Handle<JSObject> boilerplate_object,
8467 Handle<JSObject> original_boilerplate_object, 8459 Handle<JSObject> original_boilerplate_object,
(...skipping 24 matching lines...) Expand all
8492 HObjectAccess::ForJSObjectOffset(property_offset); 8484 HObjectAccess::ForJSObjectOffset(property_offset);
8493 8485
8494 if (value->IsJSObject()) { 8486 if (value->IsJSObject()) {
8495 Handle<JSObject> value_object = Handle<JSObject>::cast(value); 8487 Handle<JSObject> value_object = Handle<JSObject>::cast(value);
8496 Handle<JSObject> original_value_object = Handle<JSObject>::cast( 8488 Handle<JSObject> original_value_object = Handle<JSObject>::cast(
8497 Handle<Object>(original_boilerplate_object->InObjectPropertyAt(index), 8489 Handle<Object>(original_boilerplate_object->InObjectPropertyAt(index),
8498 isolate())); 8490 isolate()));
8499 HInstruction* value_instruction = Add<HInnerAllocatedObject>(target, 8491 HInstruction* value_instruction = Add<HInnerAllocatedObject>(target,
8500 *offset); 8492 *offset);
8501 8493
8502 AddStore(object_properties, access, value_instruction); 8494 Add<HStoreNamedField>(object_properties, access, value_instruction);
8503 BuildEmitDeepCopy(value_object, original_value_object, 8495 BuildEmitDeepCopy(value_object, original_value_object,
8504 Handle<Object>::null(), target, 8496 Handle<Object>::null(), target,
8505 offset, data_target, data_offset, 8497 offset, data_target, data_offset,
8506 DONT_TRACK_ALLOCATION_SITE); 8498 DONT_TRACK_ALLOCATION_SITE);
8507 } else { 8499 } else {
8508 Representation representation = details.representation(); 8500 Representation representation = details.representation();
8509 HInstruction* value_instruction = Add<HConstant>(value); 8501 HInstruction* value_instruction = Add<HConstant>(value);
8510 8502
8511 if (representation.IsDouble()) { 8503 if (representation.IsDouble()) {
8512 // Allocate a HeapNumber box and store the value into it. 8504 // Allocate a HeapNumber box and store the value into it.
8513 HInstruction* double_box; 8505 HInstruction* double_box;
8514 if (data_target != NULL) { 8506 if (data_target != NULL) {
8515 double_box = Add<HInnerAllocatedObject>(data_target, *data_offset); 8507 double_box = Add<HInnerAllocatedObject>(data_target, *data_offset);
8516 *data_offset += HeapNumber::kSize; 8508 *data_offset += HeapNumber::kSize;
8517 } else { 8509 } else {
8518 double_box = Add<HInnerAllocatedObject>(target, *offset); 8510 double_box = Add<HInnerAllocatedObject>(target, *offset);
8519 *offset += HeapNumber::kSize; 8511 *offset += HeapNumber::kSize;
8520 } 8512 }
8521 AddStoreMapConstant(double_box, 8513 AddStoreMapConstant(double_box,
8522 isolate()->factory()->heap_number_map()); 8514 isolate()->factory()->heap_number_map());
8523 AddStore(double_box, HObjectAccess::ForHeapNumberValue(), 8515 Add<HStoreNamedField>(double_box, HObjectAccess::ForHeapNumberValue(),
8524 value_instruction); 8516 value_instruction);
8525 value_instruction = double_box; 8517 value_instruction = double_box;
8526 } 8518 }
8527 8519
8528 AddStore(object_properties, access, value_instruction); 8520 Add<HStoreNamedField>(object_properties, access, value_instruction);
8529 } 8521 }
8530 } 8522 }
8531 8523
8532 int inobject_properties = boilerplate_object->map()->inobject_properties(); 8524 int inobject_properties = boilerplate_object->map()->inobject_properties();
8533 HInstruction* value_instruction = 8525 HInstruction* value_instruction =
8534 Add<HConstant>(isolate()->factory()->one_pointer_filler_map()); 8526 Add<HConstant>(isolate()->factory()->one_pointer_filler_map());
8535 for (int i = copied_fields; i < inobject_properties; i++) { 8527 for (int i = copied_fields; i < inobject_properties; i++) {
8536 ASSERT(boilerplate_object->IsJSObject()); 8528 ASSERT(boilerplate_object->IsJSObject());
8537 int property_offset = boilerplate_object->GetInObjectPropertyOffset(i); 8529 int property_offset = boilerplate_object->GetInObjectPropertyOffset(i);
8538 HObjectAccess access = HObjectAccess::ForJSObjectOffset(property_offset); 8530 HObjectAccess access = HObjectAccess::ForJSObjectOffset(property_offset);
8539 AddStore(object_properties, access, value_instruction); 8531 Add<HStoreNamedField>(object_properties, access, value_instruction);
8540 } 8532 }
8541 } 8533 }
8542 8534
8543 8535
8544 void HOptimizedGraphBuilder::BuildEmitElements( 8536 void HOptimizedGraphBuilder::BuildEmitElements(
8545 Handle<FixedArrayBase> elements, 8537 Handle<FixedArrayBase> elements,
8546 Handle<FixedArrayBase> original_elements, 8538 Handle<FixedArrayBase> original_elements,
8547 ElementsKind kind, 8539 ElementsKind kind,
8548 HValue* object_elements, 8540 HValue* object_elements,
8549 HInstruction* target, 8541 HInstruction* target,
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
8638 ZoneList<Declaration*>* declarations) { 8630 ZoneList<Declaration*>* declarations) {
8639 ASSERT(globals_.is_empty()); 8631 ASSERT(globals_.is_empty());
8640 AstVisitor::VisitDeclarations(declarations); 8632 AstVisitor::VisitDeclarations(declarations);
8641 if (!globals_.is_empty()) { 8633 if (!globals_.is_empty()) {
8642 Handle<FixedArray> array = 8634 Handle<FixedArray> array =
8643 isolate()->factory()->NewFixedArray(globals_.length(), TENURED); 8635 isolate()->factory()->NewFixedArray(globals_.length(), TENURED);
8644 for (int i = 0; i < globals_.length(); ++i) array->set(i, *globals_.at(i)); 8636 for (int i = 0; i < globals_.length(); ++i) array->set(i, *globals_.at(i));
8645 int flags = DeclareGlobalsEvalFlag::encode(current_info()->is_eval()) | 8637 int flags = DeclareGlobalsEvalFlag::encode(current_info()->is_eval()) |
8646 DeclareGlobalsNativeFlag::encode(current_info()->is_native()) | 8638 DeclareGlobalsNativeFlag::encode(current_info()->is_native()) |
8647 DeclareGlobalsLanguageMode::encode(current_info()->language_mode()); 8639 DeclareGlobalsLanguageMode::encode(current_info()->language_mode());
8648 Add<HDeclareGlobals>(environment()->LookupContext(), array, flags); 8640 Add<HDeclareGlobals>(array, flags);
8649 globals_.Clear(); 8641 globals_.Clear();
8650 } 8642 }
8651 } 8643 }
8652 8644
8653 8645
8654 void HOptimizedGraphBuilder::VisitVariableDeclaration( 8646 void HOptimizedGraphBuilder::VisitVariableDeclaration(
8655 VariableDeclaration* declaration) { 8647 VariableDeclaration* declaration) {
8656 VariableProxy* proxy = declaration->proxy(); 8648 VariableProxy* proxy = declaration->proxy();
8657 VariableMode mode = declaration->mode(); 8649 VariableMode mode = declaration->mode();
8658 Variable* variable = proxy->var(); 8650 Variable* variable = proxy->var();
8659 bool hole_init = mode == CONST || mode == CONST_HARMONY || mode == LET; 8651 bool hole_init = mode == CONST || mode == CONST_HARMONY || mode == LET;
8660 switch (variable->location()) { 8652 switch (variable->location()) {
8661 case Variable::UNALLOCATED: 8653 case Variable::UNALLOCATED:
8662 globals_.Add(variable->name(), zone()); 8654 globals_.Add(variable->name(), zone());
8663 globals_.Add(variable->binding_needs_init() 8655 globals_.Add(variable->binding_needs_init()
8664 ? isolate()->factory()->the_hole_value() 8656 ? isolate()->factory()->the_hole_value()
8665 : isolate()->factory()->undefined_value(), zone()); 8657 : isolate()->factory()->undefined_value(), zone());
8666 return; 8658 return;
8667 case Variable::PARAMETER: 8659 case Variable::PARAMETER:
8668 case Variable::LOCAL: 8660 case Variable::LOCAL:
8669 if (hole_init) { 8661 if (hole_init) {
8670 HValue* value = graph()->GetConstantHole(); 8662 HValue* value = graph()->GetConstantHole();
8671 environment()->Bind(variable, value); 8663 environment()->Bind(variable, value);
8672 } 8664 }
8673 break; 8665 break;
8674 case Variable::CONTEXT: 8666 case Variable::CONTEXT:
8675 if (hole_init) { 8667 if (hole_init) {
8676 HValue* value = graph()->GetConstantHole(); 8668 HValue* value = graph()->GetConstantHole();
8677 HValue* context = environment()->LookupContext(); 8669 HValue* context = environment()->context();
8678 HStoreContextSlot* store = Add<HStoreContextSlot>( 8670 HStoreContextSlot* store = AddAndCast<HStoreContextSlot>(
8679 context, variable->index(), HStoreContextSlot::kNoCheck, value); 8671 context, variable->index(), HStoreContextSlot::kNoCheck, value);
8680 if (store->HasObservableSideEffects()) { 8672 if (store->HasObservableSideEffects()) {
8681 Add<HSimulate>(proxy->id(), REMOVABLE_SIMULATE); 8673 Add<HSimulate>(proxy->id(), REMOVABLE_SIMULATE);
8682 } 8674 }
8683 } 8675 }
8684 break; 8676 break;
8685 case Variable::LOOKUP: 8677 case Variable::LOOKUP:
8686 return Bailout("unsupported lookup slot in declaration"); 8678 return Bailout("unsupported lookup slot in declaration");
8687 } 8679 }
8688 } 8680 }
(...skipping 16 matching lines...) Expand all
8705 case Variable::PARAMETER: 8697 case Variable::PARAMETER:
8706 case Variable::LOCAL: { 8698 case Variable::LOCAL: {
8707 CHECK_ALIVE(VisitForValue(declaration->fun())); 8699 CHECK_ALIVE(VisitForValue(declaration->fun()));
8708 HValue* value = Pop(); 8700 HValue* value = Pop();
8709 BindIfLive(variable, value); 8701 BindIfLive(variable, value);
8710 break; 8702 break;
8711 } 8703 }
8712 case Variable::CONTEXT: { 8704 case Variable::CONTEXT: {
8713 CHECK_ALIVE(VisitForValue(declaration->fun())); 8705 CHECK_ALIVE(VisitForValue(declaration->fun()));
8714 HValue* value = Pop(); 8706 HValue* value = Pop();
8715 HValue* context = environment()->LookupContext(); 8707 HValue* context = environment()->context();
8716 HStoreContextSlot* store = Add<HStoreContextSlot>( 8708 HStoreContextSlot* store = AddAndCast<HStoreContextSlot>(
8717 context, variable->index(), HStoreContextSlot::kNoCheck, value); 8709 context, variable->index(), HStoreContextSlot::kNoCheck, value);
8718 if (store->HasObservableSideEffects()) { 8710 if (store->HasObservableSideEffects()) {
8719 Add<HSimulate>(proxy->id(), REMOVABLE_SIMULATE); 8711 Add<HSimulate>(proxy->id(), REMOVABLE_SIMULATE);
8720 } 8712 }
8721 break; 8713 break;
8722 } 8714 }
8723 case Variable::LOOKUP: 8715 case Variable::LOOKUP:
8724 return Bailout("unsupported lookup slot in declaration"); 8716 return Bailout("unsupported lookup slot in declaration");
8725 } 8717 }
8726 } 8718 }
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after
8880 8872
8881 8873
8882 // Support for arguments.length and arguments[?]. 8874 // Support for arguments.length and arguments[?].
8883 void HOptimizedGraphBuilder::GenerateArgumentsLength(CallRuntime* call) { 8875 void HOptimizedGraphBuilder::GenerateArgumentsLength(CallRuntime* call) {
8884 // Our implementation of arguments (based on this stack frame or an 8876 // Our implementation of arguments (based on this stack frame or an
8885 // adapter below it) does not work for inlined functions. This runtime 8877 // adapter below it) does not work for inlined functions. This runtime
8886 // function is blacklisted by AstNode::IsInlineable. 8878 // function is blacklisted by AstNode::IsInlineable.
8887 ASSERT(function_state()->outer() == NULL); 8879 ASSERT(function_state()->outer() == NULL);
8888 ASSERT(call->arguments()->length() == 0); 8880 ASSERT(call->arguments()->length() == 0);
8889 HInstruction* elements = Add<HArgumentsElements>(false); 8881 HInstruction* elements = Add<HArgumentsElements>(false);
8890 HArgumentsLength* result = new(zone()) HArgumentsLength(elements); 8882 HArgumentsLength* result = NewAndCast<HArgumentsLength>(elements);
8891 return ast_context()->ReturnInstruction(result, call->id()); 8883 return ast_context()->ReturnInstruction(result, call->id());
8892 } 8884 }
8893 8885
8894 8886
8895 void HOptimizedGraphBuilder::GenerateArguments(CallRuntime* call) { 8887 void HOptimizedGraphBuilder::GenerateArguments(CallRuntime* call) {
8896 // Our implementation of arguments (based on this stack frame or an 8888 // Our implementation of arguments (based on this stack frame or an
8897 // adapter below it) does not work for inlined functions. This runtime 8889 // adapter below it) does not work for inlined functions. This runtime
8898 // function is blacklisted by AstNode::IsInlineable. 8890 // function is blacklisted by AstNode::IsInlineable.
8899 ASSERT(function_state()->outer() == NULL); 8891 ASSERT(function_state()->outer() == NULL);
8900 ASSERT(call->arguments()->length() == 1); 8892 ASSERT(call->arguments()->length() == 1);
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
8989 new(zone()) HHasInstanceTypeAndBranch(object, JS_VALUE_TYPE); 8981 new(zone()) HHasInstanceTypeAndBranch(object, JS_VALUE_TYPE);
8990 HBasicBlock* if_js_value = graph()->CreateBasicBlock(); 8982 HBasicBlock* if_js_value = graph()->CreateBasicBlock();
8991 HBasicBlock* not_js_value = graph()->CreateBasicBlock(); 8983 HBasicBlock* not_js_value = graph()->CreateBasicBlock();
8992 typecheck->SetSuccessorAt(0, if_js_value); 8984 typecheck->SetSuccessorAt(0, if_js_value);
8993 typecheck->SetSuccessorAt(1, not_js_value); 8985 typecheck->SetSuccessorAt(1, not_js_value);
8994 current_block()->Finish(typecheck); 8986 current_block()->Finish(typecheck);
8995 not_js_value->Goto(join); 8987 not_js_value->Goto(join);
8996 8988
8997 // Create in-object property store to kValueOffset. 8989 // Create in-object property store to kValueOffset.
8998 set_current_block(if_js_value); 8990 set_current_block(if_js_value);
8999 AddStore(object, 8991 Add<HStoreNamedField>(object,
9000 HObjectAccess::ForJSObjectOffset(JSValue::kValueOffset), value); 8992 HObjectAccess::ForJSObjectOffset(JSValue::kValueOffset), value);
9001 if_js_value->Goto(join); 8993 if_js_value->Goto(join);
9002 join->SetJoinId(call->id()); 8994 join->SetJoinId(call->id());
9003 set_current_block(join); 8995 set_current_block(join);
9004 return ast_context()->ReturnValue(value); 8996 return ast_context()->ReturnValue(value);
9005 } 8997 }
9006 8998
9007 8999
9008 // Fast support for charCodeAt(n). 9000 // Fast support for charCodeAt(n).
9009 void HOptimizedGraphBuilder::GenerateStringCharCodeAt(CallRuntime* call) { 9001 void HOptimizedGraphBuilder::GenerateStringCharCodeAt(CallRuntime* call) {
9010 ASSERT(call->arguments()->length() == 2); 9002 ASSERT(call->arguments()->length() == 2);
9011 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 9003 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
9012 CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); 9004 CHECK_ALIVE(VisitForValue(call->arguments()->at(1)));
9013 HValue* index = Pop(); 9005 HValue* index = Pop();
9014 HValue* string = Pop(); 9006 HValue* string = Pop();
9015 HValue* context = environment()->LookupContext(); 9007 HInstruction* result = BuildStringCharCodeAt(string, index);
9016 HInstruction* result = BuildStringCharCodeAt(context, string, index);
9017 return ast_context()->ReturnInstruction(result, call->id()); 9008 return ast_context()->ReturnInstruction(result, call->id());
9018 } 9009 }
9019 9010
9020 9011
9021 // Fast support for string.charAt(n) and string[n]. 9012 // Fast support for string.charAt(n) and string[n].
9022 void HOptimizedGraphBuilder::GenerateStringCharFromCode(CallRuntime* call) { 9013 void HOptimizedGraphBuilder::GenerateStringCharFromCode(CallRuntime* call) {
9023 ASSERT(call->arguments()->length() == 1); 9014 ASSERT(call->arguments()->length() == 1);
9024 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 9015 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
9025 HValue* char_code = Pop(); 9016 HValue* char_code = Pop();
9026 HValue* context = environment()->LookupContext(); 9017 HInstruction* result = New<HStringCharFromCode>(char_code);
9027 HInstruction* result = HStringCharFromCode::New(zone(), context, char_code);
9028 return ast_context()->ReturnInstruction(result, call->id()); 9018 return ast_context()->ReturnInstruction(result, call->id());
9029 } 9019 }
9030 9020
9031 9021
9032 // Fast support for string.charAt(n) and string[n]. 9022 // Fast support for string.charAt(n) and string[n].
9033 void HOptimizedGraphBuilder::GenerateStringCharAt(CallRuntime* call) { 9023 void HOptimizedGraphBuilder::GenerateStringCharAt(CallRuntime* call) {
9034 ASSERT(call->arguments()->length() == 2); 9024 ASSERT(call->arguments()->length() == 2);
9035 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 9025 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
9036 CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); 9026 CHECK_ALIVE(VisitForValue(call->arguments()->at(1)));
9037 HValue* index = Pop(); 9027 HValue* index = Pop();
9038 HValue* string = Pop(); 9028 HValue* string = Pop();
9039 HValue* context = environment()->LookupContext(); 9029 HInstruction* char_code = BuildStringCharCodeAt(string, index);
9040 HInstruction* char_code = BuildStringCharCodeAt(context, string, index);
9041 AddInstruction(char_code); 9030 AddInstruction(char_code);
9042 HInstruction* result = HStringCharFromCode::New(zone(), context, char_code); 9031 HInstruction* result = New<HStringCharFromCode>(char_code);
9043 return ast_context()->ReturnInstruction(result, call->id()); 9032 return ast_context()->ReturnInstruction(result, call->id());
9044 } 9033 }
9045 9034
9046 9035
9047 // Fast support for object equality testing. 9036 // Fast support for object equality testing.
9048 void HOptimizedGraphBuilder::GenerateObjectEquals(CallRuntime* call) { 9037 void HOptimizedGraphBuilder::GenerateObjectEquals(CallRuntime* call) {
9049 ASSERT(call->arguments()->length() == 2); 9038 ASSERT(call->arguments()->length() == 2);
9050 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 9039 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
9051 CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); 9040 CHECK_ALIVE(VisitForValue(call->arguments()->at(1)));
9052 HValue* right = Pop(); 9041 HValue* right = Pop();
9053 HValue* left = Pop(); 9042 HValue* left = Pop();
9054 HCompareObjectEqAndBranch* result = 9043 HCompareObjectEqAndBranch* result =
9055 new(zone()) HCompareObjectEqAndBranch(left, right); 9044 NewAndCast<HCompareObjectEqAndBranch>(left, right);
9056 return ast_context()->ReturnControl(result, call->id()); 9045 return ast_context()->ReturnControl(result, call->id());
9057 } 9046 }
9058 9047
9059 9048
9060 void HOptimizedGraphBuilder::GenerateLog(CallRuntime* call) { 9049 void HOptimizedGraphBuilder::GenerateLog(CallRuntime* call) {
9061 // %_Log is ignored in optimized code. 9050 // %_Log is ignored in optimized code.
9062 return ast_context()->ReturnValue(graph()->GetConstantUndefined()); 9051 return ast_context()->ReturnValue(graph()->GetConstantUndefined());
9063 } 9052 }
9064 9053
9065 9054
9066 // Fast support for Math.random(). 9055 // Fast support for Math.random().
9067 void HOptimizedGraphBuilder::GenerateRandomHeapNumber(CallRuntime* call) { 9056 void HOptimizedGraphBuilder::GenerateRandomHeapNumber(CallRuntime* call) {
9068 HValue* context = environment()->LookupContext(); 9057 HGlobalObject* global_object = AddAndCast<HGlobalObject>();
9069 HGlobalObject* global_object = Add<HGlobalObject>(context);
9070 HRandom* result = new(zone()) HRandom(global_object); 9058 HRandom* result = new(zone()) HRandom(global_object);
9071 return ast_context()->ReturnInstruction(result, call->id()); 9059 return ast_context()->ReturnInstruction(result, call->id());
9072 } 9060 }
9073 9061
9074 9062
9075 // Fast support for StringAdd. 9063 // Fast support for StringAdd.
9076 void HOptimizedGraphBuilder::GenerateStringAdd(CallRuntime* call) { 9064 void HOptimizedGraphBuilder::GenerateStringAdd(CallRuntime* call) {
9077 ASSERT_EQ(2, call->arguments()->length()); 9065 ASSERT_EQ(2, call->arguments()->length());
9078 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 9066 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
9079 CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); 9067 CHECK_ALIVE(VisitForValue(call->arguments()->at(1)));
9080 HValue* right = Pop(); 9068 HValue* right = Pop();
9081 HValue* left = Pop(); 9069 HValue* left = Pop();
9082 HValue* context = environment()->LookupContext(); 9070 HValue* context = environment()->context();
9083 HInstruction* result = HStringAdd::New( 9071 HInstruction* result = HStringAdd::New(
9084 zone(), context, left, right, STRING_ADD_CHECK_BOTH); 9072 zone(), context, left, right, STRING_ADD_CHECK_BOTH);
9085 return ast_context()->ReturnInstruction(result, call->id()); 9073 return ast_context()->ReturnInstruction(result, call->id());
9086 } 9074 }
9087 9075
9088 9076
9089 // Fast support for SubString. 9077 // Fast support for SubString.
9090 void HOptimizedGraphBuilder::GenerateSubString(CallRuntime* call) { 9078 void HOptimizedGraphBuilder::GenerateSubString(CallRuntime* call) {
9091 ASSERT_EQ(3, call->arguments()->length()); 9079 ASSERT_EQ(3, call->arguments()->length());
9092 CHECK_ALIVE(VisitArgumentList(call->arguments())); 9080 CHECK_ALIVE(VisitArgumentList(call->arguments()));
9093 HValue* context = environment()->LookupContext(); 9081 HValue* context = environment()->context();
9094 HCallStub* result = new(zone()) HCallStub(context, CodeStub::SubString, 3); 9082 HCallStub* result = new(zone()) HCallStub(context, CodeStub::SubString, 3);
9095 Drop(3); 9083 Drop(3);
9096 return ast_context()->ReturnInstruction(result, call->id()); 9084 return ast_context()->ReturnInstruction(result, call->id());
9097 } 9085 }
9098 9086
9099 9087
9100 // Fast support for StringCompare. 9088 // Fast support for StringCompare.
9101 void HOptimizedGraphBuilder::GenerateStringCompare(CallRuntime* call) { 9089 void HOptimizedGraphBuilder::GenerateStringCompare(CallRuntime* call) {
9102 ASSERT_EQ(2, call->arguments()->length()); 9090 ASSERT_EQ(2, call->arguments()->length());
9103 CHECK_ALIVE(VisitArgumentList(call->arguments())); 9091 CHECK_ALIVE(VisitArgumentList(call->arguments()));
9104 HValue* context = environment()->LookupContext(); 9092 HValue* context = environment()->context();
9105 HCallStub* result = 9093 HCallStub* result =
9106 new(zone()) HCallStub(context, CodeStub::StringCompare, 2); 9094 new(zone()) HCallStub(context, CodeStub::StringCompare, 2);
9107 Drop(2); 9095 Drop(2);
9108 return ast_context()->ReturnInstruction(result, call->id()); 9096 return ast_context()->ReturnInstruction(result, call->id());
9109 } 9097 }
9110 9098
9111 9099
9112 // Support for direct calls from JavaScript to native RegExp code. 9100 // Support for direct calls from JavaScript to native RegExp code.
9113 void HOptimizedGraphBuilder::GenerateRegExpExec(CallRuntime* call) { 9101 void HOptimizedGraphBuilder::GenerateRegExpExec(CallRuntime* call) {
9114 ASSERT_EQ(4, call->arguments()->length()); 9102 ASSERT_EQ(4, call->arguments()->length());
9115 CHECK_ALIVE(VisitArgumentList(call->arguments())); 9103 CHECK_ALIVE(VisitArgumentList(call->arguments()));
9116 HValue* context = environment()->LookupContext(); 9104 HValue* context = environment()->context();
9117 HCallStub* result = new(zone()) HCallStub(context, CodeStub::RegExpExec, 4); 9105 HCallStub* result = new(zone()) HCallStub(context, CodeStub::RegExpExec, 4);
9118 Drop(4); 9106 Drop(4);
9119 return ast_context()->ReturnInstruction(result, call->id()); 9107 return ast_context()->ReturnInstruction(result, call->id());
9120 } 9108 }
9121 9109
9122 9110
9123 // Construct a RegExp exec result with two in-object properties. 9111 // Construct a RegExp exec result with two in-object properties.
9124 void HOptimizedGraphBuilder::GenerateRegExpConstructResult(CallRuntime* call) { 9112 void HOptimizedGraphBuilder::GenerateRegExpConstructResult(CallRuntime* call) {
9125 ASSERT_EQ(3, call->arguments()->length()); 9113 ASSERT_EQ(3, call->arguments()->length());
9126 CHECK_ALIVE(VisitArgumentList(call->arguments())); 9114 CHECK_ALIVE(VisitArgumentList(call->arguments()));
9127 HValue* context = environment()->LookupContext(); 9115 HValue* context = environment()->context();
9128 HCallStub* result = 9116 HCallStub* result =
9129 new(zone()) HCallStub(context, CodeStub::RegExpConstructResult, 3); 9117 new(zone()) HCallStub(context, CodeStub::RegExpConstructResult, 3);
9130 Drop(3); 9118 Drop(3);
9131 return ast_context()->ReturnInstruction(result, call->id()); 9119 return ast_context()->ReturnInstruction(result, call->id());
9132 } 9120 }
9133 9121
9134 9122
9135 // Support for fast native caches. 9123 // Support for fast native caches.
9136 void HOptimizedGraphBuilder::GenerateGetFromCache(CallRuntime* call) { 9124 void HOptimizedGraphBuilder::GenerateGetFromCache(CallRuntime* call) {
9137 return Bailout("inlined runtime function: GetFromCache"); 9125 return Bailout("inlined runtime function: GetFromCache");
9138 } 9126 }
9139 9127
9140 9128
9141 // Fast support for number to string. 9129 // Fast support for number to string.
9142 void HOptimizedGraphBuilder::GenerateNumberToString(CallRuntime* call) { 9130 void HOptimizedGraphBuilder::GenerateNumberToString(CallRuntime* call) {
9143 ASSERT_EQ(1, call->arguments()->length()); 9131 ASSERT_EQ(1, call->arguments()->length());
9144 CHECK_ALIVE(VisitArgumentList(call->arguments())); 9132 CHECK_ALIVE(VisitArgumentList(call->arguments()));
9145 HValue* context = environment()->LookupContext(); 9133 HValue* context = environment()->context();
9146 HCallStub* result = 9134 HCallStub* result =
9147 new(zone()) HCallStub(context, CodeStub::NumberToString, 1); 9135 new(zone()) HCallStub(context, CodeStub::NumberToString, 1);
9148 Drop(1); 9136 Drop(1);
9149 return ast_context()->ReturnInstruction(result, call->id()); 9137 return ast_context()->ReturnInstruction(result, call->id());
9150 } 9138 }
9151 9139
9152 9140
9153 // Fast call for custom callbacks. 9141 // Fast call for custom callbacks.
9154 void HOptimizedGraphBuilder::GenerateCallFunction(CallRuntime* call) { 9142 void HOptimizedGraphBuilder::GenerateCallFunction(CallRuntime* call) {
9155 // 1 ~ The function to call is not itself an argument to the call. 9143 // 1 ~ The function to call is not itself an argument to the call.
9156 int arg_count = call->arguments()->length() - 1; 9144 int arg_count = call->arguments()->length() - 1;
9157 ASSERT(arg_count >= 1); // There's always at least a receiver. 9145 ASSERT(arg_count >= 1); // There's always at least a receiver.
9158 9146
9159 for (int i = 0; i < arg_count; ++i) { 9147 for (int i = 0; i < arg_count; ++i) {
9160 CHECK_ALIVE(VisitArgument(call->arguments()->at(i))); 9148 CHECK_ALIVE(VisitArgument(call->arguments()->at(i)));
9161 } 9149 }
9162 CHECK_ALIVE(VisitForValue(call->arguments()->last())); 9150 CHECK_ALIVE(VisitForValue(call->arguments()->last()));
9163 9151
9164 HValue* function = Pop(); 9152 HValue* function = Pop();
9165 HValue* context = environment()->LookupContext();
9166 9153
9167 // Branch for function proxies, or other non-functions. 9154 // Branch for function proxies, or other non-functions.
9168 HHasInstanceTypeAndBranch* typecheck = 9155 HHasInstanceTypeAndBranch* typecheck =
9169 new(zone()) HHasInstanceTypeAndBranch(function, JS_FUNCTION_TYPE); 9156 new(zone()) HHasInstanceTypeAndBranch(function, JS_FUNCTION_TYPE);
9170 HBasicBlock* if_jsfunction = graph()->CreateBasicBlock(); 9157 HBasicBlock* if_jsfunction = graph()->CreateBasicBlock();
9171 HBasicBlock* if_nonfunction = graph()->CreateBasicBlock(); 9158 HBasicBlock* if_nonfunction = graph()->CreateBasicBlock();
9172 HBasicBlock* join = graph()->CreateBasicBlock(); 9159 HBasicBlock* join = graph()->CreateBasicBlock();
9173 typecheck->SetSuccessorAt(0, if_jsfunction); 9160 typecheck->SetSuccessorAt(0, if_jsfunction);
9174 typecheck->SetSuccessorAt(1, if_nonfunction); 9161 typecheck->SetSuccessorAt(1, if_nonfunction);
9175 current_block()->Finish(typecheck); 9162 current_block()->Finish(typecheck);
9176 9163
9177 set_current_block(if_jsfunction); 9164 set_current_block(if_jsfunction);
9178 HInstruction* invoke_result = 9165 HInstruction* invoke_result = Add<HInvokeFunction>(function, arg_count);
9179 Add<HInvokeFunction>(context, function, arg_count);
9180 Drop(arg_count); 9166 Drop(arg_count);
9181 Push(invoke_result); 9167 Push(invoke_result);
9182 if_jsfunction->Goto(join); 9168 if_jsfunction->Goto(join);
9183 9169
9184 set_current_block(if_nonfunction); 9170 set_current_block(if_nonfunction);
9185 HInstruction* call_result = Add<HCallFunction>(context, function, arg_count); 9171 HInstruction* call_result = Add<HCallFunction>(function, arg_count);
9186 Drop(arg_count); 9172 Drop(arg_count);
9187 Push(call_result); 9173 Push(call_result);
9188 if_nonfunction->Goto(join); 9174 if_nonfunction->Goto(join);
9189 9175
9190 set_current_block(join); 9176 set_current_block(join);
9191 join->SetJoinId(call->id()); 9177 join->SetJoinId(call->id());
9192 return ast_context()->ReturnValue(Pop()); 9178 return ast_context()->ReturnValue(Pop());
9193 } 9179 }
9194 9180
9195 9181
9196 // Fast call to math functions. 9182 // Fast call to math functions.
9197 void HOptimizedGraphBuilder::GenerateMathPow(CallRuntime* call) { 9183 void HOptimizedGraphBuilder::GenerateMathPow(CallRuntime* call) {
9198 ASSERT_EQ(2, call->arguments()->length()); 9184 ASSERT_EQ(2, call->arguments()->length());
9199 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 9185 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
9200 CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); 9186 CHECK_ALIVE(VisitForValue(call->arguments()->at(1)));
9201 HValue* right = Pop(); 9187 HValue* right = Pop();
9202 HValue* left = Pop(); 9188 HValue* left = Pop();
9203 HInstruction* result = HPower::New(zone(), left, right); 9189 HInstruction* result = HPower::New(zone(), context(), left, right);
9204 return ast_context()->ReturnInstruction(result, call->id()); 9190 return ast_context()->ReturnInstruction(result, call->id());
9205 } 9191 }
9206 9192
9207 9193
9208 void HOptimizedGraphBuilder::GenerateMathSin(CallRuntime* call) { 9194 void HOptimizedGraphBuilder::GenerateMathSin(CallRuntime* call) {
9209 ASSERT_EQ(1, call->arguments()->length()); 9195 ASSERT_EQ(1, call->arguments()->length());
9210 CHECK_ALIVE(VisitArgumentList(call->arguments())); 9196 CHECK_ALIVE(VisitArgumentList(call->arguments()));
9211 HValue* context = environment()->LookupContext(); 9197 HValue* context = environment()->context();
9212 HCallStub* result = 9198 HCallStub* result =
9213 new(zone()) HCallStub(context, CodeStub::TranscendentalCache, 1); 9199 new(zone()) HCallStub(context, CodeStub::TranscendentalCache, 1);
9214 result->set_transcendental_type(TranscendentalCache::SIN); 9200 result->set_transcendental_type(TranscendentalCache::SIN);
9215 Drop(1); 9201 Drop(1);
9216 return ast_context()->ReturnInstruction(result, call->id()); 9202 return ast_context()->ReturnInstruction(result, call->id());
9217 } 9203 }
9218 9204
9219 9205
9220 void HOptimizedGraphBuilder::GenerateMathCos(CallRuntime* call) { 9206 void HOptimizedGraphBuilder::GenerateMathCos(CallRuntime* call) {
9221 ASSERT_EQ(1, call->arguments()->length()); 9207 ASSERT_EQ(1, call->arguments()->length());
9222 CHECK_ALIVE(VisitArgumentList(call->arguments())); 9208 CHECK_ALIVE(VisitArgumentList(call->arguments()));
9223 HValue* context = environment()->LookupContext(); 9209 HValue* context = environment()->context();
9224 HCallStub* result = 9210 HCallStub* result =
9225 new(zone()) HCallStub(context, CodeStub::TranscendentalCache, 1); 9211 new(zone()) HCallStub(context, CodeStub::TranscendentalCache, 1);
9226 result->set_transcendental_type(TranscendentalCache::COS); 9212 result->set_transcendental_type(TranscendentalCache::COS);
9227 Drop(1); 9213 Drop(1);
9228 return ast_context()->ReturnInstruction(result, call->id()); 9214 return ast_context()->ReturnInstruction(result, call->id());
9229 } 9215 }
9230 9216
9231 9217
9232 void HOptimizedGraphBuilder::GenerateMathTan(CallRuntime* call) { 9218 void HOptimizedGraphBuilder::GenerateMathTan(CallRuntime* call) {
9233 ASSERT_EQ(1, call->arguments()->length()); 9219 ASSERT_EQ(1, call->arguments()->length());
9234 CHECK_ALIVE(VisitArgumentList(call->arguments())); 9220 CHECK_ALIVE(VisitArgumentList(call->arguments()));
9235 HValue* context = environment()->LookupContext(); 9221 HValue* context = environment()->context();
9236 HCallStub* result = 9222 HCallStub* result =
9237 new(zone()) HCallStub(context, CodeStub::TranscendentalCache, 1); 9223 new(zone()) HCallStub(context, CodeStub::TranscendentalCache, 1);
9238 result->set_transcendental_type(TranscendentalCache::TAN); 9224 result->set_transcendental_type(TranscendentalCache::TAN);
9239 Drop(1); 9225 Drop(1);
9240 return ast_context()->ReturnInstruction(result, call->id()); 9226 return ast_context()->ReturnInstruction(result, call->id());
9241 } 9227 }
9242 9228
9243 9229
9244 void HOptimizedGraphBuilder::GenerateMathLog(CallRuntime* call) { 9230 void HOptimizedGraphBuilder::GenerateMathLog(CallRuntime* call) {
9245 ASSERT_EQ(1, call->arguments()->length()); 9231 ASSERT_EQ(1, call->arguments()->length());
9246 CHECK_ALIVE(VisitArgumentList(call->arguments())); 9232 CHECK_ALIVE(VisitArgumentList(call->arguments()));
9247 HValue* context = environment()->LookupContext(); 9233 HValue* context = environment()->context();
9248 HCallStub* result = 9234 HCallStub* result =
9249 new(zone()) HCallStub(context, CodeStub::TranscendentalCache, 1); 9235 new(zone()) HCallStub(context, CodeStub::TranscendentalCache, 1);
9250 result->set_transcendental_type(TranscendentalCache::LOG); 9236 result->set_transcendental_type(TranscendentalCache::LOG);
9251 Drop(1); 9237 Drop(1);
9252 return ast_context()->ReturnInstruction(result, call->id()); 9238 return ast_context()->ReturnInstruction(result, call->id());
9253 } 9239 }
9254 9240
9255 9241
9256 void HOptimizedGraphBuilder::GenerateMathSqrt(CallRuntime* call) { 9242 void HOptimizedGraphBuilder::GenerateMathSqrt(CallRuntime* call) {
9257 ASSERT(call->arguments()->length() == 1); 9243 ASSERT(call->arguments()->length() == 1);
9258 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 9244 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
9259 HValue* value = Pop(); 9245 HValue* value = Pop();
9260 HValue* context = environment()->LookupContext(); 9246 HValue* context = environment()->context();
9261 HInstruction* result = 9247 HInstruction* result =
9262 HUnaryMathOperation::New(zone(), context, value, kMathSqrt); 9248 HUnaryMathOperation::New(zone(), context, value, kMathSqrt);
9263 return ast_context()->ReturnInstruction(result, call->id()); 9249 return ast_context()->ReturnInstruction(result, call->id());
9264 } 9250 }
9265 9251
9266 9252
9267 // Check whether two RegExps are equivalent 9253 // Check whether two RegExps are equivalent
9268 void HOptimizedGraphBuilder::GenerateIsRegExpEquivalent(CallRuntime* call) { 9254 void HOptimizedGraphBuilder::GenerateIsRegExpEquivalent(CallRuntime* call) {
9269 return Bailout("inlined runtime function: IsRegExpEquivalent"); 9255 return Bailout("inlined runtime function: IsRegExpEquivalent");
9270 } 9256 }
(...skipping 289 matching lines...) Expand 10 before | Expand all | Expand 10 after
9560 HValue* push = (i <= arguments) ? 9546 HValue* push = (i <= arguments) ?
9561 ExpressionStackAt(arguments - i) : undefined; 9547 ExpressionStackAt(arguments - i) : undefined;
9562 inner->SetValueAt(i, push); 9548 inner->SetValueAt(i, push);
9563 } 9549 }
9564 // If the function we are inlining is a strict mode function or a 9550 // If the function we are inlining is a strict mode function or a
9565 // builtin function, pass undefined as the receiver for function 9551 // builtin function, pass undefined as the receiver for function
9566 // calls (instead of the global receiver). 9552 // calls (instead of the global receiver).
9567 if (undefined_receiver) { 9553 if (undefined_receiver) {
9568 inner->SetValueAt(0, undefined); 9554 inner->SetValueAt(0, undefined);
9569 } 9555 }
9570 inner->SetValueAt(arity + 1, LookupContext()); 9556 inner->SetValueAt(arity + 1, context());
9571 for (int i = arity + 2; i < inner->length(); ++i) { 9557 for (int i = arity + 2; i < inner->length(); ++i) {
9572 inner->SetValueAt(i, undefined); 9558 inner->SetValueAt(i, undefined);
9573 } 9559 }
9574 9560
9575 inner->set_ast_id(BailoutId::FunctionEntry()); 9561 inner->set_ast_id(BailoutId::FunctionEntry());
9576 return inner; 9562 return inner;
9577 } 9563 }
9578 9564
9579 9565
9580 void HEnvironment::PrintTo(StringStream* stream) { 9566 void HEnvironment::PrintTo(StringStream* stream) {
(...skipping 329 matching lines...) Expand 10 before | Expand all | Expand 10 after
9910 if (ShouldProduceTraceOutput()) { 9896 if (ShouldProduceTraceOutput()) {
9911 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); 9897 isolate()->GetHTracer()->TraceHydrogen(name(), graph_);
9912 } 9898 }
9913 9899
9914 #ifdef DEBUG 9900 #ifdef DEBUG
9915 graph_->Verify(false); // No full verify. 9901 graph_->Verify(false); // No full verify.
9916 #endif 9902 #endif
9917 } 9903 }
9918 9904
9919 } } // namespace v8::internal 9905 } } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698