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

Side by Side Diff: src/hydrogen.cc

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

Powered by Google App Engine
This is Rietveld 408576698