OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 975 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
986 RemovableSimulate removable) { | 986 RemovableSimulate removable) { |
987 ASSERT(current_block() != NULL); | 987 ASSERT(current_block() != NULL); |
988 ASSERT(no_side_effects_scope_count_ == 0); | 988 ASSERT(no_side_effects_scope_count_ == 0); |
989 current_block()->AddSimulate(id, removable); | 989 current_block()->AddSimulate(id, removable); |
990 } | 990 } |
991 | 991 |
992 | 992 |
993 HReturn* HGraphBuilder::AddReturn(HValue* value) { | 993 HReturn* HGraphBuilder::AddReturn(HValue* value) { |
994 HValue* context = environment()->LookupContext(); | 994 HValue* context = environment()->LookupContext(); |
995 int num_parameters = graph()->info()->num_parameters(); | 995 int num_parameters = graph()->info()->num_parameters(); |
996 HValue* params = AddInstruction(new(graph()->zone()) | 996 HValue* params = Add<HConstant>(num_parameters); |
997 HConstant(num_parameters)); | |
998 HReturn* return_instruction = new(graph()->zone()) | 997 HReturn* return_instruction = new(graph()->zone()) |
999 HReturn(value, context, params); | 998 HReturn(value, context, params); |
1000 current_block()->FinishExit(return_instruction); | 999 current_block()->FinishExit(return_instruction); |
1001 return return_instruction; | 1000 return return_instruction; |
1002 } | 1001 } |
1003 | 1002 |
1004 | 1003 |
1005 HBasicBlock* HGraphBuilder::CreateBasicBlock(HEnvironment* env) { | 1004 HBasicBlock* HGraphBuilder::CreateBasicBlock(HEnvironment* env) { |
1006 HBasicBlock* b = graph()->CreateBasicBlock(); | 1005 HBasicBlock* b = graph()->CreateBasicBlock(); |
1007 b->SetInitialEnvironment(env); | 1006 b->SetInitialEnvironment(env); |
1008 return b; | 1007 return b; |
1009 } | 1008 } |
1010 | 1009 |
1011 | 1010 |
1012 HBasicBlock* HGraphBuilder::CreateLoopHeaderBlock() { | 1011 HBasicBlock* HGraphBuilder::CreateLoopHeaderBlock() { |
1013 HBasicBlock* header = graph()->CreateBasicBlock(); | 1012 HBasicBlock* header = graph()->CreateBasicBlock(); |
1014 HEnvironment* entry_env = environment()->CopyAsLoopHeader(header); | 1013 HEnvironment* entry_env = environment()->CopyAsLoopHeader(header); |
1015 header->SetInitialEnvironment(entry_env); | 1014 header->SetInitialEnvironment(entry_env); |
1016 header->AttachLoopInformation(); | 1015 header->AttachLoopInformation(); |
1017 return header; | 1016 return header; |
1018 } | 1017 } |
1019 | 1018 |
1020 | 1019 |
1021 HValue* HGraphBuilder::BuildCheckHeapObject(HValue* obj) { | 1020 HValue* HGraphBuilder::BuildCheckHeapObject(HValue* obj) { |
1022 if (obj->type().IsHeapObject()) return obj; | 1021 if (obj->type().IsHeapObject()) return obj; |
1023 HCheckHeapObject* check = new(zone()) HCheckHeapObject(obj); | 1022 return Add<HCheckHeapObject>(obj); |
1024 AddInstruction(check); | |
1025 return check; | |
1026 } | 1023 } |
1027 | 1024 |
1028 | 1025 |
1029 HValue* HGraphBuilder::BuildCheckMap(HValue* obj, | 1026 HValue* HGraphBuilder::BuildCheckMap(HValue* obj, |
1030 Handle<Map> map) { | 1027 Handle<Map> map) { |
1031 HCheckMaps* check = HCheckMaps::New(obj, map, zone()); | 1028 HCheckMaps* check = HCheckMaps::New(obj, map, zone()); |
1032 AddInstruction(check); | 1029 AddInstruction(check); |
1033 return check; | 1030 return check; |
1034 } | 1031 } |
1035 | 1032 |
1036 | 1033 |
1037 HInstruction* HGraphBuilder::BuildExternalArrayElementAccess( | 1034 HInstruction* HGraphBuilder::BuildExternalArrayElementAccess( |
1038 HValue* external_elements, | 1035 HValue* external_elements, |
1039 HValue* checked_key, | 1036 HValue* checked_key, |
1040 HValue* val, | 1037 HValue* val, |
1041 HValue* dependency, | 1038 HValue* dependency, |
1042 ElementsKind elements_kind, | 1039 ElementsKind elements_kind, |
1043 bool is_store) { | 1040 bool is_store) { |
1044 Zone* zone = this->zone(); | 1041 Zone* zone = this->zone(); |
1045 if (is_store) { | 1042 if (is_store) { |
1046 ASSERT(val != NULL); | 1043 ASSERT(val != NULL); |
1047 switch (elements_kind) { | 1044 switch (elements_kind) { |
1048 case EXTERNAL_PIXEL_ELEMENTS: { | 1045 case EXTERNAL_PIXEL_ELEMENTS: { |
1049 val = AddInstruction(new(zone) HClampToUint8(val)); | 1046 val = Add<HClampToUint8>(val); |
1050 break; | 1047 break; |
1051 } | 1048 } |
1052 case EXTERNAL_BYTE_ELEMENTS: | 1049 case EXTERNAL_BYTE_ELEMENTS: |
1053 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: | 1050 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: |
1054 case EXTERNAL_SHORT_ELEMENTS: | 1051 case EXTERNAL_SHORT_ELEMENTS: |
1055 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: | 1052 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: |
1056 case EXTERNAL_INT_ELEMENTS: | 1053 case EXTERNAL_INT_ELEMENTS: |
1057 case EXTERNAL_UNSIGNED_INT_ELEMENTS: { | 1054 case EXTERNAL_UNSIGNED_INT_ELEMENTS: { |
1058 break; | 1055 break; |
1059 } | 1056 } |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1126 ElementsKind kind, | 1123 ElementsKind kind, |
1127 HValue* length, | 1124 HValue* length, |
1128 HValue* key, | 1125 HValue* key, |
1129 bool is_js_array) { | 1126 bool is_js_array) { |
1130 Zone* zone = this->zone(); | 1127 Zone* zone = this->zone(); |
1131 IfBuilder length_checker(this); | 1128 IfBuilder length_checker(this); |
1132 | 1129 |
1133 length_checker.IfCompare(length, key, Token::EQ); | 1130 length_checker.IfCompare(length, key, Token::EQ); |
1134 length_checker.Then(); | 1131 length_checker.Then(); |
1135 | 1132 |
1136 HValue* current_capacity = | 1133 HValue* current_capacity = Add<HFixedArrayBaseLength>(elements); |
1137 AddInstruction(new(zone) HFixedArrayBaseLength(elements)); | |
1138 | 1134 |
1139 IfBuilder capacity_checker(this); | 1135 IfBuilder capacity_checker(this); |
1140 | 1136 |
1141 capacity_checker.IfCompare(length, current_capacity, Token::EQ); | 1137 capacity_checker.IfCompare(length, current_capacity, Token::EQ); |
1142 capacity_checker.Then(); | 1138 capacity_checker.Then(); |
1143 | 1139 |
1144 HValue* context = environment()->LookupContext(); | 1140 HValue* context = environment()->LookupContext(); |
1145 | 1141 |
1146 HValue* new_capacity = | 1142 HValue* new_capacity = |
1147 BuildNewElementsCapacity(context, current_capacity); | 1143 BuildNewElementsCapacity(context, current_capacity); |
(...skipping 27 matching lines...) Expand all Loading... |
1175 length_checker.End(); | 1171 length_checker.End(); |
1176 | 1172 |
1177 return environment()->Pop(); | 1173 return environment()->Pop(); |
1178 } | 1174 } |
1179 | 1175 |
1180 | 1176 |
1181 HValue* HGraphBuilder::BuildCopyElementsOnWrite(HValue* object, | 1177 HValue* HGraphBuilder::BuildCopyElementsOnWrite(HValue* object, |
1182 HValue* elements, | 1178 HValue* elements, |
1183 ElementsKind kind, | 1179 ElementsKind kind, |
1184 HValue* length) { | 1180 HValue* length) { |
1185 Zone* zone = this->zone(); | |
1186 Heap* heap = isolate()->heap(); | 1181 Heap* heap = isolate()->heap(); |
1187 | 1182 |
1188 IfBuilder cow_checker(this); | 1183 IfBuilder cow_checker(this); |
1189 | 1184 |
1190 cow_checker.IfCompareMap(elements, | 1185 cow_checker.IfCompareMap(elements, |
1191 Handle<Map>(heap->fixed_cow_array_map())); | 1186 Handle<Map>(heap->fixed_cow_array_map())); |
1192 cow_checker.Then(); | 1187 cow_checker.Then(); |
1193 | 1188 |
1194 HValue* capacity = | 1189 HValue* capacity = Add<HFixedArrayBaseLength>(elements); |
1195 AddInstruction(new(zone) HFixedArrayBaseLength(elements)); | |
1196 | 1190 |
1197 HValue* new_elements = BuildGrowElementsCapacity(object, elements, | 1191 HValue* new_elements = BuildGrowElementsCapacity(object, elements, |
1198 kind, length, capacity); | 1192 kind, length, capacity); |
1199 | 1193 |
1200 environment()->Push(new_elements); | 1194 environment()->Push(new_elements); |
1201 | 1195 |
1202 cow_checker.Else(); | 1196 cow_checker.Else(); |
1203 | 1197 |
1204 environment()->Push(elements); | 1198 environment()->Push(elements); |
1205 | 1199 |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1242 elements, isolate()->factory()->fixed_array_map(), zone); | 1236 elements, isolate()->factory()->fixed_array_map(), zone); |
1243 check_cow_map->ClearGVNFlag(kDependsOnElementsKind); | 1237 check_cow_map->ClearGVNFlag(kDependsOnElementsKind); |
1244 AddInstruction(check_cow_map); | 1238 AddInstruction(check_cow_map); |
1245 } | 1239 } |
1246 HInstruction* length = NULL; | 1240 HInstruction* length = NULL; |
1247 if (is_js_array) { | 1241 if (is_js_array) { |
1248 length = AddLoad(object, HObjectAccess::ForArrayLength(), mapcheck, | 1242 length = AddLoad(object, HObjectAccess::ForArrayLength(), mapcheck, |
1249 Representation::Smi()); | 1243 Representation::Smi()); |
1250 length->set_type(HType::Smi()); | 1244 length->set_type(HType::Smi()); |
1251 } else { | 1245 } else { |
1252 length = AddInstruction(new(zone) HFixedArrayBaseLength(elements)); | 1246 length = Add<HFixedArrayBaseLength>(elements); |
1253 } | 1247 } |
1254 HValue* checked_key = NULL; | 1248 HValue* checked_key = NULL; |
1255 if (IsExternalArrayElementsKind(elements_kind)) { | 1249 if (IsExternalArrayElementsKind(elements_kind)) { |
1256 if (store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS) { | 1250 if (store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS) { |
1257 NoObservableSideEffectsScope no_effects(this); | 1251 NoObservableSideEffectsScope no_effects(this); |
1258 HLoadExternalArrayPointer* external_elements = | 1252 HLoadExternalArrayPointer* external_elements = |
1259 new(zone) HLoadExternalArrayPointer(elements); | 1253 Add<HLoadExternalArrayPointer>(elements); |
1260 AddInstruction(external_elements); | |
1261 IfBuilder length_checker(this); | 1254 IfBuilder length_checker(this); |
1262 length_checker.IfCompare(key, length, Token::LT); | 1255 length_checker.IfCompare(key, length, Token::LT); |
1263 length_checker.Then(); | 1256 length_checker.Then(); |
1264 IfBuilder negative_checker(this); | 1257 IfBuilder negative_checker(this); |
1265 HValue* bounds_check = negative_checker.IfCompare( | 1258 HValue* bounds_check = negative_checker.IfCompare( |
1266 key, graph()->GetConstant0(), Token::GTE); | 1259 key, graph()->GetConstant0(), Token::GTE); |
1267 negative_checker.Then(); | 1260 negative_checker.Then(); |
1268 HInstruction* result = BuildExternalArrayElementAccess( | 1261 HInstruction* result = BuildExternalArrayElementAccess( |
1269 external_elements, key, val, bounds_check, | 1262 external_elements, key, val, bounds_check, |
1270 elements_kind, is_store); | 1263 elements_kind, is_store); |
1271 AddInstruction(result); | 1264 AddInstruction(result); |
1272 negative_checker.ElseDeopt(); | 1265 negative_checker.ElseDeopt(); |
1273 length_checker.End(); | 1266 length_checker.End(); |
1274 return result; | 1267 return result; |
1275 } else { | 1268 } else { |
1276 ASSERT(store_mode == STANDARD_STORE); | 1269 ASSERT(store_mode == STANDARD_STORE); |
1277 checked_key = Add<HBoundsCheck>(key, length); | 1270 checked_key = Add<HBoundsCheck>(key, length); |
1278 HLoadExternalArrayPointer* external_elements = | 1271 HLoadExternalArrayPointer* external_elements = |
1279 new(zone) HLoadExternalArrayPointer(elements); | 1272 Add<HLoadExternalArrayPointer>(elements); |
1280 AddInstruction(external_elements); | |
1281 return AddInstruction(BuildExternalArrayElementAccess( | 1273 return AddInstruction(BuildExternalArrayElementAccess( |
1282 external_elements, checked_key, val, mapcheck, | 1274 external_elements, checked_key, val, mapcheck, |
1283 elements_kind, is_store)); | 1275 elements_kind, is_store)); |
1284 } | 1276 } |
1285 } | 1277 } |
1286 ASSERT(fast_smi_only_elements || | 1278 ASSERT(fast_smi_only_elements || |
1287 fast_elements || | 1279 fast_elements || |
1288 IsFastDoubleElementsKind(elements_kind)); | 1280 IsFastDoubleElementsKind(elements_kind)); |
1289 | 1281 |
1290 // In case val is stored into a fast smi array, assure that the value is a smi | 1282 // In case val is stored into a fast smi array, assure that the value is a smi |
1291 // before manipulating the backing store. Otherwise the actual store may | 1283 // before manipulating the backing store. Otherwise the actual store may |
1292 // deopt, leaving the backing store in an invalid state. | 1284 // deopt, leaving the backing store in an invalid state. |
1293 if (is_store && IsFastSmiElementsKind(elements_kind) && | 1285 if (is_store && IsFastSmiElementsKind(elements_kind) && |
1294 !val->type().IsSmi()) { | 1286 !val->type().IsSmi()) { |
1295 val = AddInstruction(new(zone) HForceRepresentation( | 1287 val = Add<HForceRepresentation>(val, Representation::Smi()); |
1296 val, Representation::Smi())); | |
1297 } | 1288 } |
1298 | 1289 |
1299 if (IsGrowStoreMode(store_mode)) { | 1290 if (IsGrowStoreMode(store_mode)) { |
1300 NoObservableSideEffectsScope no_effects(this); | 1291 NoObservableSideEffectsScope no_effects(this); |
1301 elements = BuildCheckForCapacityGrow(object, elements, elements_kind, | 1292 elements = BuildCheckForCapacityGrow(object, elements, elements_kind, |
1302 length, key, is_js_array); | 1293 length, key, is_js_array); |
1303 checked_key = key; | 1294 checked_key = key; |
1304 } else { | 1295 } else { |
1305 checked_key = Add<HBoundsCheck>(key, length); | 1296 checked_key = Add<HBoundsCheck>(key, length); |
1306 | 1297 |
(...skipping 17 matching lines...) Expand all Loading... |
1324 } | 1315 } |
1325 | 1316 |
1326 | 1317 |
1327 HValue* HGraphBuilder::BuildAllocateElements(HValue* context, | 1318 HValue* HGraphBuilder::BuildAllocateElements(HValue* context, |
1328 ElementsKind kind, | 1319 ElementsKind kind, |
1329 HValue* capacity) { | 1320 HValue* capacity) { |
1330 Zone* zone = this->zone(); | 1321 Zone* zone = this->zone(); |
1331 | 1322 |
1332 int elements_size = IsFastDoubleElementsKind(kind) | 1323 int elements_size = IsFastDoubleElementsKind(kind) |
1333 ? kDoubleSize : kPointerSize; | 1324 ? kDoubleSize : kPointerSize; |
1334 HConstant* elements_size_value = new(zone) HConstant(elements_size); | 1325 HConstant* elements_size_value = Add<HConstant>(elements_size); |
1335 AddInstruction(elements_size_value); | |
1336 HValue* mul = AddInstruction( | 1326 HValue* mul = AddInstruction( |
1337 HMul::New(zone, context, capacity, elements_size_value)); | 1327 HMul::New(zone, context, capacity, elements_size_value)); |
1338 mul->ClearFlag(HValue::kCanOverflow); | 1328 mul->ClearFlag(HValue::kCanOverflow); |
1339 | 1329 |
1340 HConstant* header_size = new(zone) HConstant(FixedArray::kHeaderSize); | 1330 HConstant* header_size = Add<HConstant>(FixedArray::kHeaderSize); |
1341 AddInstruction(header_size); | |
1342 HValue* total_size = AddInstruction( | 1331 HValue* total_size = AddInstruction( |
1343 HAdd::New(zone, context, mul, header_size)); | 1332 HAdd::New(zone, context, mul, header_size)); |
1344 total_size->ClearFlag(HValue::kCanOverflow); | 1333 total_size->ClearFlag(HValue::kCanOverflow); |
1345 | 1334 |
1346 HAllocate::Flags flags = HAllocate::DefaultFlags(kind); | 1335 HAllocate::Flags flags = HAllocate::DefaultFlags(kind); |
1347 if (isolate()->heap()->ShouldGloballyPretenure()) { | 1336 if (isolate()->heap()->ShouldGloballyPretenure()) { |
1348 // TODO(hpayer): When pretenuring can be internalized, flags can become | 1337 // TODO(hpayer): When pretenuring can be internalized, flags can become |
1349 // private to HAllocate. | 1338 // private to HAllocate. |
1350 if (IsFastDoubleElementsKind(kind)) { | 1339 if (IsFastDoubleElementsKind(kind)) { |
1351 flags = static_cast<HAllocate::Flags>( | 1340 flags = static_cast<HAllocate::Flags>( |
1352 flags | HAllocate::CAN_ALLOCATE_IN_OLD_DATA_SPACE); | 1341 flags | HAllocate::CAN_ALLOCATE_IN_OLD_DATA_SPACE); |
1353 } else { | 1342 } else { |
1354 flags = static_cast<HAllocate::Flags>( | 1343 flags = static_cast<HAllocate::Flags>( |
1355 flags | HAllocate::CAN_ALLOCATE_IN_OLD_POINTER_SPACE); | 1344 flags | HAllocate::CAN_ALLOCATE_IN_OLD_POINTER_SPACE); |
1356 } | 1345 } |
1357 } | 1346 } |
1358 | 1347 |
1359 HValue* elements = | 1348 return Add<HAllocate>(context, total_size, HType::JSArray(), flags); |
1360 AddInstruction(new(zone) HAllocate(context, total_size, | |
1361 HType::JSArray(), flags)); | |
1362 return elements; | |
1363 } | 1349 } |
1364 | 1350 |
1365 | 1351 |
1366 void HGraphBuilder::BuildInitializeElementsHeader(HValue* elements, | 1352 void HGraphBuilder::BuildInitializeElementsHeader(HValue* elements, |
1367 ElementsKind kind, | 1353 ElementsKind kind, |
1368 HValue* capacity) { | 1354 HValue* capacity) { |
1369 Factory* factory = isolate()->factory(); | 1355 Factory* factory = isolate()->factory(); |
1370 Handle<Map> map = IsFastDoubleElementsKind(kind) | 1356 Handle<Map> map = IsFastDoubleElementsKind(kind) |
1371 ? factory->fixed_double_array_map() | 1357 ? factory->fixed_double_array_map() |
1372 : factory->fixed_array_map(); | 1358 : factory->fixed_array_map(); |
(...skipping 18 matching lines...) Expand all Loading... |
1391 | 1377 |
1392 HInnerAllocatedObject* HGraphBuilder::BuildJSArrayHeader(HValue* array, | 1378 HInnerAllocatedObject* HGraphBuilder::BuildJSArrayHeader(HValue* array, |
1393 HValue* array_map, | 1379 HValue* array_map, |
1394 AllocationSiteMode mode, | 1380 AllocationSiteMode mode, |
1395 HValue* allocation_site_payload, | 1381 HValue* allocation_site_payload, |
1396 HValue* length_field) { | 1382 HValue* length_field) { |
1397 | 1383 |
1398 AddStore(array, HObjectAccess::ForMap(), array_map); | 1384 AddStore(array, HObjectAccess::ForMap(), array_map); |
1399 | 1385 |
1400 HConstant* empty_fixed_array = | 1386 HConstant* empty_fixed_array = |
1401 new(zone()) HConstant(isolate()->factory()->empty_fixed_array()); | 1387 Add<HConstant>(isolate()->factory()->empty_fixed_array()); |
1402 AddInstruction(empty_fixed_array); | |
1403 | 1388 |
1404 HObjectAccess access = HObjectAccess::ForPropertiesPointer(); | 1389 HObjectAccess access = HObjectAccess::ForPropertiesPointer(); |
1405 AddStore(array, access, empty_fixed_array); | 1390 AddStore(array, access, empty_fixed_array); |
1406 AddStore(array, HObjectAccess::ForArrayLength(), length_field); | 1391 AddStore(array, HObjectAccess::ForArrayLength(), length_field); |
1407 | 1392 |
1408 if (mode == TRACK_ALLOCATION_SITE) { | 1393 if (mode == TRACK_ALLOCATION_SITE) { |
1409 BuildCreateAllocationSiteInfo(array, | 1394 BuildCreateAllocationSiteInfo(array, |
1410 JSArray::kSize, | 1395 JSArray::kSize, |
1411 allocation_site_payload); | 1396 allocation_site_payload); |
1412 } | 1397 } |
1413 | 1398 |
1414 int elements_location = JSArray::kSize; | 1399 int elements_location = JSArray::kSize; |
1415 if (mode == TRACK_ALLOCATION_SITE) { | 1400 if (mode == TRACK_ALLOCATION_SITE) { |
1416 elements_location += AllocationSiteInfo::kSize; | 1401 elements_location += AllocationSiteInfo::kSize; |
1417 } | 1402 } |
1418 | 1403 |
1419 HInnerAllocatedObject* elements = new(zone()) HInnerAllocatedObject( | 1404 HInnerAllocatedObject* elements = |
1420 array, elements_location); | 1405 Add<HInnerAllocatedObject>(array, elements_location); |
1421 AddInstruction(elements); | |
1422 | |
1423 AddStore(array, HObjectAccess::ForElementsPointer(), elements); | 1406 AddStore(array, HObjectAccess::ForElementsPointer(), elements); |
1424 return elements; | 1407 return elements; |
1425 } | 1408 } |
1426 | 1409 |
1427 | 1410 |
1428 HLoadNamedField* HGraphBuilder::AddLoadElements(HValue* object, | 1411 HLoadNamedField* HGraphBuilder::AddLoadElements(HValue* object, |
1429 HValue* typecheck) { | 1412 HValue* typecheck) { |
1430 return AddLoad(object, HObjectAccess::ForElementsPointer(), typecheck); | 1413 return AddLoad(object, HObjectAccess::ForElementsPointer(), typecheck); |
1431 } | 1414 } |
1432 | 1415 |
1433 | 1416 |
1434 HValue* HGraphBuilder::BuildNewElementsCapacity(HValue* context, | 1417 HValue* HGraphBuilder::BuildNewElementsCapacity(HValue* context, |
1435 HValue* old_capacity) { | 1418 HValue* old_capacity) { |
1436 Zone* zone = this->zone(); | 1419 Zone* zone = this->zone(); |
1437 HValue* half_old_capacity = | 1420 HValue* half_old_capacity = |
1438 AddInstruction(HShr::New(zone, context, old_capacity, | 1421 AddInstruction(HShr::New(zone, context, old_capacity, |
1439 graph_->GetConstant1())); | 1422 graph_->GetConstant1())); |
1440 half_old_capacity->ClearFlag(HValue::kCanOverflow); | 1423 half_old_capacity->ClearFlag(HValue::kCanOverflow); |
1441 | 1424 |
1442 HValue* new_capacity = AddInstruction( | 1425 HValue* new_capacity = AddInstruction( |
1443 HAdd::New(zone, context, half_old_capacity, old_capacity)); | 1426 HAdd::New(zone, context, half_old_capacity, old_capacity)); |
1444 new_capacity->ClearFlag(HValue::kCanOverflow); | 1427 new_capacity->ClearFlag(HValue::kCanOverflow); |
1445 | 1428 |
1446 HValue* min_growth = AddInstruction(new(zone) HConstant(16)); | 1429 HValue* min_growth = Add<HConstant>(16); |
1447 | 1430 |
1448 new_capacity = AddInstruction( | 1431 new_capacity = AddInstruction( |
1449 HAdd::New(zone, context, new_capacity, min_growth)); | 1432 HAdd::New(zone, context, new_capacity, min_growth)); |
1450 new_capacity->ClearFlag(HValue::kCanOverflow); | 1433 new_capacity->ClearFlag(HValue::kCanOverflow); |
1451 | 1434 |
1452 return new_capacity; | 1435 return new_capacity; |
1453 } | 1436 } |
1454 | 1437 |
1455 | 1438 |
1456 void HGraphBuilder::BuildNewSpaceArrayCheck(HValue* length, ElementsKind kind) { | 1439 void HGraphBuilder::BuildNewSpaceArrayCheck(HValue* length, ElementsKind kind) { |
1457 Zone* zone = this->zone(); | |
1458 Heap* heap = isolate()->heap(); | 1440 Heap* heap = isolate()->heap(); |
1459 int element_size = IsFastDoubleElementsKind(kind) ? kDoubleSize | 1441 int element_size = IsFastDoubleElementsKind(kind) ? kDoubleSize |
1460 : kPointerSize; | 1442 : kPointerSize; |
1461 int max_size = heap->MaxRegularSpaceAllocationSize() / element_size; | 1443 int max_size = heap->MaxRegularSpaceAllocationSize() / element_size; |
1462 max_size -= JSArray::kSize / element_size; | 1444 max_size -= JSArray::kSize / element_size; |
1463 HConstant* max_size_constant = new(zone) HConstant(max_size); | 1445 HConstant* max_size_constant = Add<HConstant>(max_size); |
1464 AddInstruction(max_size_constant); | |
1465 // Since we're forcing Integer32 representation for this HBoundsCheck, | 1446 // Since we're forcing Integer32 representation for this HBoundsCheck, |
1466 // there's no need to Smi-check the index. | 1447 // there's no need to Smi-check the index. |
1467 AddInstruction(new(zone) HBoundsCheck(length, max_size_constant)); | 1448 Add<HBoundsCheck>(length, max_size_constant); |
1468 } | 1449 } |
1469 | 1450 |
1470 | 1451 |
1471 HValue* HGraphBuilder::BuildGrowElementsCapacity(HValue* object, | 1452 HValue* HGraphBuilder::BuildGrowElementsCapacity(HValue* object, |
1472 HValue* elements, | 1453 HValue* elements, |
1473 ElementsKind kind, | 1454 ElementsKind kind, |
1474 HValue* length, | 1455 HValue* length, |
1475 HValue* new_capacity) { | 1456 HValue* new_capacity) { |
1476 HValue* context = environment()->LookupContext(); | 1457 HValue* context = environment()->LookupContext(); |
1477 | 1458 |
(...skipping 15 matching lines...) Expand all Loading... |
1493 void HGraphBuilder::BuildFillElementsWithHole(HValue* context, | 1474 void HGraphBuilder::BuildFillElementsWithHole(HValue* context, |
1494 HValue* elements, | 1475 HValue* elements, |
1495 ElementsKind elements_kind, | 1476 ElementsKind elements_kind, |
1496 HValue* from, | 1477 HValue* from, |
1497 HValue* to) { | 1478 HValue* to) { |
1498 // Fast elements kinds need to be initialized in case statements below cause | 1479 // Fast elements kinds need to be initialized in case statements below cause |
1499 // a garbage collection. | 1480 // a garbage collection. |
1500 Factory* factory = isolate()->factory(); | 1481 Factory* factory = isolate()->factory(); |
1501 | 1482 |
1502 double nan_double = FixedDoubleArray::hole_nan_as_double(); | 1483 double nan_double = FixedDoubleArray::hole_nan_as_double(); |
1503 Zone* zone = this->zone(); | |
1504 HValue* hole = IsFastSmiOrObjectElementsKind(elements_kind) | 1484 HValue* hole = IsFastSmiOrObjectElementsKind(elements_kind) |
1505 ? AddInstruction(new(zone) HConstant(factory->the_hole_value())) | 1485 ? Add<HConstant>(factory->the_hole_value()) |
1506 : AddInstruction(new(zone) HConstant(nan_double)); | 1486 : Add<HConstant>(nan_double); |
1507 | 1487 |
1508 // Special loop unfolding case | 1488 // Special loop unfolding case |
1509 static const int kLoopUnfoldLimit = 4; | 1489 static const int kLoopUnfoldLimit = 4; |
1510 bool unfold_loop = false; | 1490 bool unfold_loop = false; |
1511 int initial_capacity = JSArray::kPreallocatedArrayElements; | 1491 int initial_capacity = JSArray::kPreallocatedArrayElements; |
1512 if (from->IsConstant() && to->IsConstant() && | 1492 if (from->IsConstant() && to->IsConstant() && |
1513 initial_capacity <= kLoopUnfoldLimit) { | 1493 initial_capacity <= kLoopUnfoldLimit) { |
1514 HConstant* constant_from = HConstant::cast(from); | 1494 HConstant* constant_from = HConstant::cast(from); |
1515 HConstant* constant_to = HConstant::cast(to); | 1495 HConstant* constant_to = HConstant::cast(to); |
1516 | 1496 |
1517 if (constant_from->HasInteger32Value() && | 1497 if (constant_from->HasInteger32Value() && |
1518 constant_from->Integer32Value() == 0 && | 1498 constant_from->Integer32Value() == 0 && |
1519 constant_to->HasInteger32Value() && | 1499 constant_to->HasInteger32Value() && |
1520 constant_to->Integer32Value() == initial_capacity) { | 1500 constant_to->Integer32Value() == initial_capacity) { |
1521 unfold_loop = true; | 1501 unfold_loop = true; |
1522 } | 1502 } |
1523 } | 1503 } |
1524 | 1504 |
1525 // Since we're about to store a hole value, the store instruction below must | 1505 // Since we're about to store a hole value, the store instruction below must |
1526 // assume an elements kind that supports heap object values. | 1506 // assume an elements kind that supports heap object values. |
1527 if (IsFastSmiOrObjectElementsKind(elements_kind)) { | 1507 if (IsFastSmiOrObjectElementsKind(elements_kind)) { |
1528 elements_kind = FAST_HOLEY_ELEMENTS; | 1508 elements_kind = FAST_HOLEY_ELEMENTS; |
1529 } | 1509 } |
1530 | 1510 |
1531 if (unfold_loop) { | 1511 if (unfold_loop) { |
1532 for (int i = 0; i < initial_capacity; i++) { | 1512 for (int i = 0; i < initial_capacity; i++) { |
1533 HInstruction* key = AddInstruction(new(zone) HConstant(i)); | 1513 HInstruction* key = Add<HConstant>(i); |
1534 AddInstruction(new(zone) HStoreKeyed(elements, key, hole, elements_kind)); | 1514 Add<HStoreKeyed>(elements, key, hole, elements_kind); |
1535 } | 1515 } |
1536 } else { | 1516 } else { |
1537 LoopBuilder builder(this, context, LoopBuilder::kPostIncrement); | 1517 LoopBuilder builder(this, context, LoopBuilder::kPostIncrement); |
1538 | 1518 |
1539 HValue* key = builder.BeginBody(from, to, Token::LT); | 1519 HValue* key = builder.BeginBody(from, to, Token::LT); |
1540 | 1520 |
1541 AddInstruction(new(zone) HStoreKeyed(elements, key, hole, elements_kind)); | 1521 Add<HStoreKeyed>(elements, key, hole, elements_kind); |
1542 | 1522 |
1543 builder.EndBody(); | 1523 builder.EndBody(); |
1544 } | 1524 } |
1545 } | 1525 } |
1546 | 1526 |
1547 | 1527 |
1548 void HGraphBuilder::BuildCopyElements(HValue* context, | 1528 void HGraphBuilder::BuildCopyElements(HValue* context, |
1549 HValue* from_elements, | 1529 HValue* from_elements, |
1550 ElementsKind from_elements_kind, | 1530 ElementsKind from_elements_kind, |
1551 HValue* to_elements, | 1531 HValue* to_elements, |
1552 ElementsKind to_elements_kind, | 1532 ElementsKind to_elements_kind, |
1553 HValue* length, | 1533 HValue* length, |
1554 HValue* capacity) { | 1534 HValue* capacity) { |
1555 bool pre_fill_with_holes = | 1535 bool pre_fill_with_holes = |
1556 IsFastDoubleElementsKind(from_elements_kind) && | 1536 IsFastDoubleElementsKind(from_elements_kind) && |
1557 IsFastObjectElementsKind(to_elements_kind); | 1537 IsFastObjectElementsKind(to_elements_kind); |
1558 | 1538 |
1559 if (pre_fill_with_holes) { | 1539 if (pre_fill_with_holes) { |
1560 // If the copy might trigger a GC, make sure that the FixedArray is | 1540 // If the copy might trigger a GC, make sure that the FixedArray is |
1561 // pre-initialized with holes to make sure that it's always in a consistent | 1541 // pre-initialized with holes to make sure that it's always in a consistent |
1562 // state. | 1542 // state. |
1563 BuildFillElementsWithHole(context, to_elements, to_elements_kind, | 1543 BuildFillElementsWithHole(context, to_elements, to_elements_kind, |
1564 graph()->GetConstant0(), capacity); | 1544 graph()->GetConstant0(), capacity); |
1565 } | 1545 } |
1566 | 1546 |
1567 LoopBuilder builder(this, context, LoopBuilder::kPostIncrement); | 1547 LoopBuilder builder(this, context, LoopBuilder::kPostIncrement); |
1568 | 1548 |
1569 HValue* key = builder.BeginBody(graph()->GetConstant0(), length, Token::LT); | 1549 HValue* key = builder.BeginBody(graph()->GetConstant0(), length, Token::LT); |
1570 | 1550 |
1571 HValue* element = | 1551 HValue* element = Add<HLoadKeyed>(from_elements, key, |
1572 AddInstruction(new(zone()) HLoadKeyed(from_elements, key, NULL, | 1552 static_cast<HValue*>(NULL), |
1573 from_elements_kind, | 1553 from_elements_kind, |
1574 ALLOW_RETURN_HOLE)); | 1554 ALLOW_RETURN_HOLE); |
1575 | 1555 |
1576 ElementsKind holey_kind = IsFastSmiElementsKind(to_elements_kind) | 1556 ElementsKind holey_kind = IsFastSmiElementsKind(to_elements_kind) |
1577 ? FAST_HOLEY_ELEMENTS : to_elements_kind; | 1557 ? FAST_HOLEY_ELEMENTS : to_elements_kind; |
1578 HInstruction* holey_store = AddInstruction( | 1558 HInstruction* holey_store = Add<HStoreKeyed>(to_elements, key, |
1579 new(zone()) HStoreKeyed(to_elements, key, element, holey_kind)); | 1559 element, holey_kind); |
1580 // Allow NaN hole values to converted to their tagged counterparts. | 1560 // Allow NaN hole values to converted to their tagged counterparts. |
1581 if (IsFastHoleyElementsKind(to_elements_kind)) { | 1561 if (IsFastHoleyElementsKind(to_elements_kind)) { |
1582 holey_store->SetFlag(HValue::kAllowUndefinedAsNaN); | 1562 holey_store->SetFlag(HValue::kAllowUndefinedAsNaN); |
1583 } | 1563 } |
1584 | 1564 |
1585 builder.EndBody(); | 1565 builder.EndBody(); |
1586 | 1566 |
1587 if (!pre_fill_with_holes && length != capacity) { | 1567 if (!pre_fill_with_holes && length != capacity) { |
1588 // Fill unused capacity with the hole. | 1568 // Fill unused capacity with the hole. |
1589 BuildFillElementsWithHole(context, to_elements, to_elements_kind, | 1569 BuildFillElementsWithHole(context, to_elements, to_elements_kind, |
1590 key, capacity); | 1570 key, capacity); |
1591 } | 1571 } |
1592 } | 1572 } |
1593 | 1573 |
1594 | 1574 |
1595 HValue* HGraphBuilder::BuildCloneShallowArray(HContext* context, | 1575 HValue* HGraphBuilder::BuildCloneShallowArray(HContext* context, |
1596 HValue* boilerplate, | 1576 HValue* boilerplate, |
1597 AllocationSiteMode mode, | 1577 AllocationSiteMode mode, |
1598 ElementsKind kind, | 1578 ElementsKind kind, |
1599 int length) { | 1579 int length) { |
1600 Zone* zone = this->zone(); | |
1601 | |
1602 NoObservableSideEffectsScope no_effects(this); | 1580 NoObservableSideEffectsScope no_effects(this); |
1603 | 1581 |
1604 // All sizes here are multiples of kPointerSize. | 1582 // All sizes here are multiples of kPointerSize. |
1605 int size = JSArray::kSize; | 1583 int size = JSArray::kSize; |
1606 if (mode == TRACK_ALLOCATION_SITE) { | 1584 if (mode == TRACK_ALLOCATION_SITE) { |
1607 size += AllocationSiteInfo::kSize; | 1585 size += AllocationSiteInfo::kSize; |
1608 } | 1586 } |
1609 int elems_offset = size; | 1587 int elems_offset = size; |
1610 if (length > 0) { | 1588 if (length > 0) { |
1611 size += IsFastDoubleElementsKind(kind) | 1589 size += IsFastDoubleElementsKind(kind) |
1612 ? FixedDoubleArray::SizeFor(length) | 1590 ? FixedDoubleArray::SizeFor(length) |
1613 : FixedArray::SizeFor(length); | 1591 : FixedArray::SizeFor(length); |
1614 } | 1592 } |
1615 | 1593 |
1616 HAllocate::Flags allocate_flags = HAllocate::DefaultFlags(kind); | 1594 HAllocate::Flags allocate_flags = HAllocate::DefaultFlags(kind); |
1617 // Allocate both the JS array and the elements array in one big | 1595 // Allocate both the JS array and the elements array in one big |
1618 // allocation. This avoids multiple limit checks. | 1596 // allocation. This avoids multiple limit checks. |
1619 HValue* size_in_bytes = AddInstruction(new(zone) HConstant(size)); | 1597 HValue* size_in_bytes = Add<HConstant>(size); |
1620 HInstruction* object = | 1598 HInstruction* object = Add<HAllocate>(context, |
1621 AddInstruction(new(zone) HAllocate(context, | 1599 size_in_bytes, |
1622 size_in_bytes, | 1600 HType::JSObject(), |
1623 HType::JSObject(), | 1601 allocate_flags); |
1624 allocate_flags)); | |
1625 | 1602 |
1626 // Copy the JS array part. | 1603 // Copy the JS array part. |
1627 for (int i = 0; i < JSArray::kSize; i += kPointerSize) { | 1604 for (int i = 0; i < JSArray::kSize; i += kPointerSize) { |
1628 if ((i != JSArray::kElementsOffset) || (length == 0)) { | 1605 if ((i != JSArray::kElementsOffset) || (length == 0)) { |
1629 HObjectAccess access = HObjectAccess::ForJSArrayOffset(i); | 1606 HObjectAccess access = HObjectAccess::ForJSArrayOffset(i); |
1630 AddStore(object, access, AddLoad(boilerplate, access)); | 1607 AddStore(object, access, AddLoad(boilerplate, access)); |
1631 } | 1608 } |
1632 } | 1609 } |
1633 | 1610 |
1634 // Create an allocation site info if requested. | 1611 // Create an allocation site info if requested. |
1635 if (mode == TRACK_ALLOCATION_SITE) { | 1612 if (mode == TRACK_ALLOCATION_SITE) { |
1636 BuildCreateAllocationSiteInfo(object, JSArray::kSize, boilerplate); | 1613 BuildCreateAllocationSiteInfo(object, JSArray::kSize, boilerplate); |
1637 } | 1614 } |
1638 | 1615 |
1639 if (length > 0) { | 1616 if (length > 0) { |
1640 // Get hold of the elements array of the boilerplate and setup the | 1617 // Get hold of the elements array of the boilerplate and setup the |
1641 // elements pointer in the resulting object. | 1618 // elements pointer in the resulting object. |
1642 HValue* boilerplate_elements = AddLoadElements(boilerplate); | 1619 HValue* boilerplate_elements = AddLoadElements(boilerplate); |
1643 HValue* object_elements = | 1620 HValue* object_elements = Add<HInnerAllocatedObject>(object, elems_offset); |
1644 AddInstruction(new(zone) HInnerAllocatedObject(object, elems_offset)); | |
1645 AddStore(object, HObjectAccess::ForElementsPointer(), object_elements); | 1621 AddStore(object, HObjectAccess::ForElementsPointer(), object_elements); |
1646 | 1622 |
1647 // Copy the elements array header. | 1623 // Copy the elements array header. |
1648 for (int i = 0; i < FixedArrayBase::kHeaderSize; i += kPointerSize) { | 1624 for (int i = 0; i < FixedArrayBase::kHeaderSize; i += kPointerSize) { |
1649 HObjectAccess access = HObjectAccess::ForFixedArrayHeader(i); | 1625 HObjectAccess access = HObjectAccess::ForFixedArrayHeader(i); |
1650 AddStore(object_elements, access, AddLoad(boilerplate_elements, access)); | 1626 AddStore(object_elements, access, AddLoad(boilerplate_elements, access)); |
1651 } | 1627 } |
1652 | 1628 |
1653 // Copy the elements array contents. | 1629 // Copy the elements array contents. |
1654 // TODO(mstarzinger): Teach HGraphBuilder::BuildCopyElements to unfold | 1630 // TODO(mstarzinger): Teach HGraphBuilder::BuildCopyElements to unfold |
1655 // copying loops with constant length up to a given boundary and use this | 1631 // copying loops with constant length up to a given boundary and use this |
1656 // helper here instead. | 1632 // helper here instead. |
1657 for (int i = 0; i < length; i++) { | 1633 for (int i = 0; i < length; i++) { |
1658 HValue* key_constant = AddInstruction(new(zone) HConstant(i)); | 1634 HValue* key_constant = Add<HConstant>(i); |
1659 HInstruction* value = | 1635 HInstruction* value = Add<HLoadKeyed>(boilerplate_elements, key_constant, |
1660 AddInstruction(new(zone) HLoadKeyed(boilerplate_elements, | 1636 static_cast<HValue*>(NULL), kind); |
1661 key_constant, | 1637 Add<HStoreKeyed>(object_elements, key_constant, value, kind); |
1662 NULL, | |
1663 kind)); | |
1664 AddInstruction(new(zone) HStoreKeyed(object_elements, | |
1665 key_constant, | |
1666 value, | |
1667 kind)); | |
1668 } | 1638 } |
1669 } | 1639 } |
1670 | 1640 |
1671 return object; | 1641 return object; |
1672 } | 1642 } |
1673 | 1643 |
1674 | 1644 |
1675 void HGraphBuilder::BuildCompareNil( | 1645 void HGraphBuilder::BuildCompareNil( |
1676 HValue* value, | 1646 HValue* value, |
1677 Handle<Type> type, | 1647 Handle<Type> type, |
(...skipping 30 matching lines...) Expand all Loading... |
1708 } | 1678 } |
1709 } | 1679 } |
1710 | 1680 |
1711 if_nil.CaptureContinuation(continuation); | 1681 if_nil.CaptureContinuation(continuation); |
1712 } | 1682 } |
1713 | 1683 |
1714 | 1684 |
1715 HValue* HGraphBuilder::BuildCreateAllocationSiteInfo(HValue* previous_object, | 1685 HValue* HGraphBuilder::BuildCreateAllocationSiteInfo(HValue* previous_object, |
1716 int previous_object_size, | 1686 int previous_object_size, |
1717 HValue* payload) { | 1687 HValue* payload) { |
1718 HInnerAllocatedObject* alloc_site = new(zone()) | 1688 HInnerAllocatedObject* alloc_site = Add<HInnerAllocatedObject>( |
1719 HInnerAllocatedObject(previous_object, previous_object_size); | 1689 previous_object, previous_object_size); |
1720 AddInstruction(alloc_site); | |
1721 Handle<Map> alloc_site_map(isolate()->heap()->allocation_site_info_map()); | 1690 Handle<Map> alloc_site_map(isolate()->heap()->allocation_site_info_map()); |
1722 AddStoreMapConstant(alloc_site, alloc_site_map); | 1691 AddStoreMapConstant(alloc_site, alloc_site_map); |
1723 HObjectAccess access = HObjectAccess::ForAllocationSitePayload(); | 1692 HObjectAccess access = HObjectAccess::ForAllocationSitePayload(); |
1724 AddStore(alloc_site, access, payload); | 1693 AddStore(alloc_site, access, payload); |
1725 return alloc_site; | 1694 return alloc_site; |
1726 } | 1695 } |
1727 | 1696 |
1728 | 1697 |
1729 HInstruction* HGraphBuilder::BuildGetNativeContext(HValue* context) { | 1698 HInstruction* HGraphBuilder::BuildGetNativeContext(HValue* context) { |
1730 // Get the global context, then the native context | 1699 // Get the global context, then the native context |
1731 HInstruction* global_object = AddInstruction(new(zone()) | 1700 HInstruction* global_object = Add<HGlobalObject>(context); |
1732 HGlobalObject(context)); | |
1733 HObjectAccess access = HObjectAccess::ForJSObjectOffset( | 1701 HObjectAccess access = HObjectAccess::ForJSObjectOffset( |
1734 GlobalObject::kNativeContextOffset); | 1702 GlobalObject::kNativeContextOffset); |
1735 return AddLoad(global_object, access); | 1703 return AddLoad(global_object, access); |
1736 } | 1704 } |
1737 | 1705 |
1738 | 1706 |
1739 HInstruction* HGraphBuilder::BuildGetArrayFunction(HValue* context) { | 1707 HInstruction* HGraphBuilder::BuildGetArrayFunction(HValue* context) { |
1740 HInstruction* native_context = BuildGetNativeContext(context); | 1708 HInstruction* native_context = BuildGetNativeContext(context); |
1741 HInstruction* index = AddInstruction(new(zone()) | 1709 HInstruction* index = Add<HConstant>(Context::ARRAY_FUNCTION_INDEX); |
1742 HConstant(Context::ARRAY_FUNCTION_INDEX)); | 1710 return Add<HLoadKeyed>( |
1743 | 1711 native_context, index, static_cast<HValue*>(NULL), FAST_ELEMENTS); |
1744 return AddInstruction(new (zone()) | |
1745 HLoadKeyed(native_context, index, NULL, FAST_ELEMENTS)); | |
1746 } | 1712 } |
1747 | 1713 |
1748 | 1714 |
1749 HGraphBuilder::JSArrayBuilder::JSArrayBuilder(HGraphBuilder* builder, | 1715 HGraphBuilder::JSArrayBuilder::JSArrayBuilder(HGraphBuilder* builder, |
1750 ElementsKind kind, | 1716 ElementsKind kind, |
1751 HValue* allocation_site_payload, | 1717 HValue* allocation_site_payload, |
1752 bool disable_allocation_sites) : | 1718 bool disable_allocation_sites) : |
1753 builder_(builder), | 1719 builder_(builder), |
1754 kind_(kind), | 1720 kind_(kind), |
1755 allocation_site_payload_(allocation_site_payload), | 1721 allocation_site_payload_(allocation_site_payload), |
(...skipping 11 matching lines...) Expand all Loading... |
1767 kind_(kind), | 1733 kind_(kind), |
1768 mode_(DONT_TRACK_ALLOCATION_SITE), | 1734 mode_(DONT_TRACK_ALLOCATION_SITE), |
1769 allocation_site_payload_(NULL), | 1735 allocation_site_payload_(NULL), |
1770 constructor_function_(constructor_function) { | 1736 constructor_function_(constructor_function) { |
1771 } | 1737 } |
1772 | 1738 |
1773 | 1739 |
1774 HValue* HGraphBuilder::JSArrayBuilder::EmitMapCode(HValue* context) { | 1740 HValue* HGraphBuilder::JSArrayBuilder::EmitMapCode(HValue* context) { |
1775 HInstruction* native_context = builder()->BuildGetNativeContext(context); | 1741 HInstruction* native_context = builder()->BuildGetNativeContext(context); |
1776 | 1742 |
1777 HInstruction* index = builder()->AddInstruction(new(zone()) | 1743 HInstruction* index = builder()->Add<HConstant>(Context::JS_ARRAY_MAPS_INDEX); |
1778 HConstant(Context::JS_ARRAY_MAPS_INDEX)); | |
1779 | 1744 |
1780 HInstruction* map_array = builder()->AddInstruction(new(zone()) | 1745 HInstruction* map_array = builder()->Add<HLoadKeyed>( |
1781 HLoadKeyed(native_context, index, NULL, FAST_ELEMENTS)); | 1746 native_context, index, static_cast<HValue*>(NULL), FAST_ELEMENTS); |
1782 | 1747 |
1783 HInstruction* kind_index = builder()->AddInstruction(new(zone()) | 1748 HInstruction* kind_index = builder()->Add<HConstant>(kind_); |
1784 HConstant(kind_)); | |
1785 | 1749 |
1786 return builder()->AddInstruction(new(zone()) | 1750 return builder()->Add<HLoadKeyed>( |
1787 HLoadKeyed(map_array, kind_index, NULL, FAST_ELEMENTS)); | 1751 map_array, kind_index, static_cast<HValue*>(NULL), FAST_ELEMENTS); |
1788 } | 1752 } |
1789 | 1753 |
1790 | 1754 |
1791 HValue* HGraphBuilder::JSArrayBuilder::EmitInternalMapCode() { | 1755 HValue* HGraphBuilder::JSArrayBuilder::EmitInternalMapCode() { |
1792 // Find the map near the constructor function | 1756 // Find the map near the constructor function |
1793 HObjectAccess access = HObjectAccess::ForPrototypeOrInitialMap(); | 1757 HObjectAccess access = HObjectAccess::ForPrototypeOrInitialMap(); |
1794 return AddInstruction( | 1758 return builder()->AddInstruction( |
1795 builder()->BuildLoadNamedField(constructor_function_, | 1759 builder()->BuildLoadNamedField(constructor_function_, |
1796 access, | 1760 access, |
1797 Representation::Tagged())); | 1761 Representation::Tagged())); |
1798 } | 1762 } |
1799 | 1763 |
1800 | 1764 |
1801 HValue* HGraphBuilder::JSArrayBuilder::EstablishAllocationSize( | 1765 HValue* HGraphBuilder::JSArrayBuilder::EstablishAllocationSize( |
1802 HValue* length_node) { | 1766 HValue* length_node) { |
1803 HValue* context = builder()->environment()->LookupContext(); | 1767 HValue* context = builder()->environment()->LookupContext(); |
1804 ASSERT(length_node != NULL); | 1768 ASSERT(length_node != NULL); |
1805 | 1769 |
1806 int base_size = JSArray::kSize; | 1770 int base_size = JSArray::kSize; |
1807 if (mode_ == TRACK_ALLOCATION_SITE) { | 1771 if (mode_ == TRACK_ALLOCATION_SITE) { |
1808 base_size += AllocationSiteInfo::kSize; | 1772 base_size += AllocationSiteInfo::kSize; |
1809 } | 1773 } |
1810 | 1774 |
1811 if (IsFastDoubleElementsKind(kind_)) { | 1775 if (IsFastDoubleElementsKind(kind_)) { |
1812 base_size += FixedDoubleArray::kHeaderSize; | 1776 base_size += FixedDoubleArray::kHeaderSize; |
1813 } else { | 1777 } else { |
1814 base_size += FixedArray::kHeaderSize; | 1778 base_size += FixedArray::kHeaderSize; |
1815 } | 1779 } |
1816 | 1780 |
1817 HInstruction* elements_size_value = new(zone()) HConstant(elements_size()); | 1781 HInstruction* elements_size_value = |
1818 AddInstruction(elements_size_value); | 1782 builder()->Add<HConstant>(elements_size()); |
1819 HInstruction* mul = HMul::New(zone(), context, length_node, | 1783 HInstruction* mul = HMul::New(zone(), context, length_node, |
1820 elements_size_value); | 1784 elements_size_value); |
1821 mul->ClearFlag(HValue::kCanOverflow); | 1785 mul->ClearFlag(HValue::kCanOverflow); |
1822 AddInstruction(mul); | 1786 builder()->AddInstruction(mul); |
1823 | 1787 |
1824 HInstruction* base = new(zone()) HConstant(base_size); | 1788 HInstruction* base = builder()->Add<HConstant>(base_size); |
1825 AddInstruction(base); | |
1826 HInstruction* total_size = HAdd::New(zone(), context, base, mul); | 1789 HInstruction* total_size = HAdd::New(zone(), context, base, mul); |
1827 total_size->ClearFlag(HValue::kCanOverflow); | 1790 total_size->ClearFlag(HValue::kCanOverflow); |
1828 AddInstruction(total_size); | 1791 builder()->AddInstruction(total_size); |
1829 return total_size; | 1792 return total_size; |
1830 } | 1793 } |
1831 | 1794 |
1832 | 1795 |
1833 HValue* HGraphBuilder::JSArrayBuilder::EstablishEmptyArrayAllocationSize() { | 1796 HValue* HGraphBuilder::JSArrayBuilder::EstablishEmptyArrayAllocationSize() { |
1834 int base_size = JSArray::kSize; | 1797 int base_size = JSArray::kSize; |
1835 if (mode_ == TRACK_ALLOCATION_SITE) { | 1798 if (mode_ == TRACK_ALLOCATION_SITE) { |
1836 base_size += AllocationSiteInfo::kSize; | 1799 base_size += AllocationSiteInfo::kSize; |
1837 } | 1800 } |
1838 | 1801 |
1839 base_size += IsFastDoubleElementsKind(kind_) | 1802 base_size += IsFastDoubleElementsKind(kind_) |
1840 ? FixedDoubleArray::SizeFor(initial_capacity()) | 1803 ? FixedDoubleArray::SizeFor(initial_capacity()) |
1841 : FixedArray::SizeFor(initial_capacity()); | 1804 : FixedArray::SizeFor(initial_capacity()); |
1842 | 1805 |
1843 HConstant* array_size = new(zone()) HConstant(base_size); | 1806 return builder()->Add<HConstant>(base_size); |
1844 AddInstruction(array_size); | |
1845 return array_size; | |
1846 } | 1807 } |
1847 | 1808 |
1848 | 1809 |
1849 HValue* HGraphBuilder::JSArrayBuilder::AllocateEmptyArray() { | 1810 HValue* HGraphBuilder::JSArrayBuilder::AllocateEmptyArray() { |
1850 HValue* size_in_bytes = EstablishEmptyArrayAllocationSize(); | 1811 HValue* size_in_bytes = EstablishEmptyArrayAllocationSize(); |
1851 HConstant* capacity = new(zone()) HConstant(initial_capacity()); | 1812 HConstant* capacity = builder()->Add<HConstant>(initial_capacity()); |
1852 AddInstruction(capacity); | |
1853 return AllocateArray(size_in_bytes, | 1813 return AllocateArray(size_in_bytes, |
1854 capacity, | 1814 capacity, |
1855 builder()->graph()->GetConstant0(), | 1815 builder()->graph()->GetConstant0(), |
1856 true); | 1816 true); |
1857 } | 1817 } |
1858 | 1818 |
1859 | 1819 |
1860 HValue* HGraphBuilder::JSArrayBuilder::AllocateArray(HValue* capacity, | 1820 HValue* HGraphBuilder::JSArrayBuilder::AllocateArray(HValue* capacity, |
1861 HValue* length_field, | 1821 HValue* length_field, |
1862 bool fill_with_hole) { | 1822 bool fill_with_hole) { |
1863 HValue* size_in_bytes = EstablishAllocationSize(capacity); | 1823 HValue* size_in_bytes = EstablishAllocationSize(capacity); |
1864 return AllocateArray(size_in_bytes, capacity, length_field, fill_with_hole); | 1824 return AllocateArray(size_in_bytes, capacity, length_field, fill_with_hole); |
1865 } | 1825 } |
1866 | 1826 |
1867 | 1827 |
1868 HValue* HGraphBuilder::JSArrayBuilder::AllocateArray(HValue* size_in_bytes, | 1828 HValue* HGraphBuilder::JSArrayBuilder::AllocateArray(HValue* size_in_bytes, |
1869 HValue* capacity, | 1829 HValue* capacity, |
1870 HValue* length_field, | 1830 HValue* length_field, |
1871 bool fill_with_hole) { | 1831 bool fill_with_hole) { |
1872 HValue* context = builder()->environment()->LookupContext(); | 1832 HValue* context = builder()->environment()->LookupContext(); |
1873 | 1833 |
1874 // Allocate (dealing with failure appropriately) | 1834 // Allocate (dealing with failure appropriately) |
1875 HAllocate::Flags flags = HAllocate::DefaultFlags(kind_); | 1835 HAllocate::Flags flags = HAllocate::DefaultFlags(kind_); |
1876 HAllocate* new_object = new(zone()) HAllocate(context, size_in_bytes, | 1836 HAllocate* new_object = builder()->Add<HAllocate>(context, size_in_bytes, |
1877 HType::JSArray(), flags); | 1837 HType::JSArray(), flags); |
1878 AddInstruction(new_object); | |
1879 | 1838 |
1880 // Fill in the fields: map, properties, length | 1839 // Fill in the fields: map, properties, length |
1881 HValue* map; | 1840 HValue* map; |
1882 if (constructor_function_ != NULL) { | 1841 if (constructor_function_ != NULL) { |
1883 map = EmitInternalMapCode(); | 1842 map = EmitInternalMapCode(); |
1884 } else { | 1843 } else { |
1885 map = EmitMapCode(context); | 1844 map = EmitMapCode(context); |
1886 } | 1845 } |
1887 elements_location_ = builder()->BuildJSArrayHeader(new_object, | 1846 elements_location_ = builder()->BuildJSArrayHeader(new_object, |
1888 map, | 1847 map, |
(...skipping 10 matching lines...) Expand all Loading... |
1899 } | 1858 } |
1900 | 1859 |
1901 return new_object; | 1860 return new_object; |
1902 } | 1861 } |
1903 | 1862 |
1904 | 1863 |
1905 HStoreNamedField* HGraphBuilder::AddStore(HValue *object, | 1864 HStoreNamedField* HGraphBuilder::AddStore(HValue *object, |
1906 HObjectAccess access, | 1865 HObjectAccess access, |
1907 HValue *val, | 1866 HValue *val, |
1908 Representation representation) { | 1867 Representation representation) { |
1909 HStoreNamedField *instr = new(zone()) | 1868 return Add<HStoreNamedField>(object, access, val, representation); |
1910 HStoreNamedField(object, access, val, representation); | |
1911 AddInstruction(instr); | |
1912 return instr; | |
1913 } | 1869 } |
1914 | 1870 |
1915 | 1871 |
1916 HLoadNamedField* HGraphBuilder::AddLoad(HValue *object, | 1872 HLoadNamedField* HGraphBuilder::AddLoad(HValue *object, |
1917 HObjectAccess access, | 1873 HObjectAccess access, |
1918 HValue *typecheck, | 1874 HValue *typecheck, |
1919 Representation representation) { | 1875 Representation representation) { |
1920 HLoadNamedField *instr = | 1876 return Add<HLoadNamedField>(object, access, typecheck, representation); |
1921 new(zone()) HLoadNamedField(object, access, typecheck, representation); | |
1922 AddInstruction(instr); | |
1923 return instr; | |
1924 } | 1877 } |
1925 | 1878 |
1926 | 1879 |
1927 HStoreNamedField* HGraphBuilder::AddStoreMapConstant(HValue *object, | 1880 HStoreNamedField* HGraphBuilder::AddStoreMapConstant(HValue *object, |
1928 Handle<Map> map) { | 1881 Handle<Map> map) { |
1929 HValue* constant = AddInstruction(new(zone()) HConstant(map)); | 1882 return Add<HStoreNamedField>(object, HObjectAccess::ForMap(), |
1930 HStoreNamedField *instr = | 1883 Add<HConstant>(map)); |
1931 new(zone()) HStoreNamedField(object, HObjectAccess::ForMap(), constant); | |
1932 AddInstruction(instr); | |
1933 return instr; | |
1934 } | 1884 } |
1935 | 1885 |
1936 | 1886 |
1937 HOptimizedGraphBuilder::HOptimizedGraphBuilder(CompilationInfo* info) | 1887 HOptimizedGraphBuilder::HOptimizedGraphBuilder(CompilationInfo* info) |
1938 : HGraphBuilder(info), | 1888 : HGraphBuilder(info), |
1939 function_state_(NULL), | 1889 function_state_(NULL), |
1940 initial_function_state_(this, info, NORMAL_RETURN), | 1890 initial_function_state_(this, info, NORMAL_RETURN), |
1941 ast_context_(NULL), | 1891 ast_context_(NULL), |
1942 break_scope_(NULL), | 1892 break_scope_(NULL), |
1943 inlined_count_(0), | 1893 inlined_count_(0), |
(...skipping 1751 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3695 void HOptimizedGraphBuilder::VisitForControl(Expression* expr, | 3645 void HOptimizedGraphBuilder::VisitForControl(Expression* expr, |
3696 HBasicBlock* true_block, | 3646 HBasicBlock* true_block, |
3697 HBasicBlock* false_block) { | 3647 HBasicBlock* false_block) { |
3698 TestContext for_test(this, expr, true_block, false_block); | 3648 TestContext for_test(this, expr, true_block, false_block); |
3699 Visit(expr); | 3649 Visit(expr); |
3700 } | 3650 } |
3701 | 3651 |
3702 | 3652 |
3703 void HOptimizedGraphBuilder::VisitArgument(Expression* expr) { | 3653 void HOptimizedGraphBuilder::VisitArgument(Expression* expr) { |
3704 CHECK_ALIVE(VisitForValue(expr)); | 3654 CHECK_ALIVE(VisitForValue(expr)); |
3705 Push(AddInstruction(new(zone()) HPushArgument(Pop()))); | 3655 Push(Add<HPushArgument>(Pop())); |
3706 } | 3656 } |
3707 | 3657 |
3708 | 3658 |
3709 void HOptimizedGraphBuilder::VisitArgumentList( | 3659 void HOptimizedGraphBuilder::VisitArgumentList( |
3710 ZoneList<Expression*>* arguments) { | 3660 ZoneList<Expression*>* arguments) { |
3711 for (int i = 0; i < arguments->length(); i++) { | 3661 for (int i = 0; i < arguments->length(); i++) { |
3712 CHECK_ALIVE(VisitArgument(arguments->at(i))); | 3662 CHECK_ALIVE(VisitArgument(arguments->at(i))); |
3713 } | 3663 } |
3714 } | 3664 } |
3715 | 3665 |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3761 | 3711 |
3762 // Handle implicit declaration of the function name in named function | 3712 // Handle implicit declaration of the function name in named function |
3763 // expressions before other declarations. | 3713 // expressions before other declarations. |
3764 if (scope->is_function_scope() && scope->function() != NULL) { | 3714 if (scope->is_function_scope() && scope->function() != NULL) { |
3765 VisitVariableDeclaration(scope->function()); | 3715 VisitVariableDeclaration(scope->function()); |
3766 } | 3716 } |
3767 VisitDeclarations(scope->declarations()); | 3717 VisitDeclarations(scope->declarations()); |
3768 AddSimulate(BailoutId::Declarations()); | 3718 AddSimulate(BailoutId::Declarations()); |
3769 | 3719 |
3770 HValue* context = environment()->LookupContext(); | 3720 HValue* context = environment()->LookupContext(); |
3771 AddInstruction( | 3721 Add<HStackCheck>(context, HStackCheck::kFunctionEntry); |
3772 new(zone()) HStackCheck(context, HStackCheck::kFunctionEntry)); | |
3773 | 3722 |
3774 VisitStatements(current_info()->function()->body()); | 3723 VisitStatements(current_info()->function()->body()); |
3775 if (HasStackOverflow()) return false; | 3724 if (HasStackOverflow()) return false; |
3776 | 3725 |
3777 if (current_block() != NULL) { | 3726 if (current_block() != NULL) { |
3778 AddReturn(graph()->GetConstantUndefined()); | 3727 AddReturn(graph()->GetConstantUndefined()); |
3779 set_current_block(NULL); | 3728 set_current_block(NULL); |
3780 } | 3729 } |
3781 | 3730 |
3782 // If the checksum of the number of type info changes is the same as the | 3731 // If the checksum of the number of type info changes is the same as the |
(...skipping 705 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4488 void HOptimizedGraphBuilder::PushAndAdd(HInstruction* instr) { | 4437 void HOptimizedGraphBuilder::PushAndAdd(HInstruction* instr) { |
4489 Push(instr); | 4438 Push(instr); |
4490 AddInstruction(instr); | 4439 AddInstruction(instr); |
4491 } | 4440 } |
4492 | 4441 |
4493 | 4442 |
4494 void HOptimizedGraphBuilder::AddSoftDeoptimize() { | 4443 void HOptimizedGraphBuilder::AddSoftDeoptimize() { |
4495 isolate()->counters()->soft_deopts_requested()->Increment(); | 4444 isolate()->counters()->soft_deopts_requested()->Increment(); |
4496 if (FLAG_always_opt) return; | 4445 if (FLAG_always_opt) return; |
4497 if (current_block()->IsDeoptimizing()) return; | 4446 if (current_block()->IsDeoptimizing()) return; |
4498 AddInstruction(new(zone()) HSoftDeoptimize()); | 4447 Add<HSoftDeoptimize>(); |
4499 isolate()->counters()->soft_deopts_inserted()->Increment(); | 4448 isolate()->counters()->soft_deopts_inserted()->Increment(); |
4500 current_block()->MarkAsDeoptimizing(); | 4449 current_block()->MarkAsDeoptimizing(); |
4501 graph()->set_has_soft_deoptimize(true); | 4450 graph()->set_has_soft_deoptimize(true); |
4502 } | 4451 } |
4503 | 4452 |
4504 | 4453 |
4505 template <class Instruction> | 4454 template <class Instruction> |
4506 HInstruction* HOptimizedGraphBuilder::PreProcessCall(Instruction* call) { | 4455 HInstruction* HOptimizedGraphBuilder::PreProcessCall(Instruction* call) { |
4507 int count = call->argument_count(); | 4456 int count = call->argument_count(); |
4508 ZoneList<HValue*> arguments(count, zone()); | 4457 ZoneList<HValue*> arguments(count, zone()); |
4509 for (int i = 0; i < count; ++i) { | 4458 for (int i = 0; i < count; ++i) { |
4510 arguments.Add(Pop(), zone()); | 4459 arguments.Add(Pop(), zone()); |
4511 } | 4460 } |
4512 | 4461 |
4513 while (!arguments.is_empty()) { | 4462 while (!arguments.is_empty()) { |
4514 AddInstruction(new(zone()) HPushArgument(arguments.RemoveLast())); | 4463 Add<HPushArgument>(arguments.RemoveLast()); |
4515 } | 4464 } |
4516 return call; | 4465 return call; |
4517 } | 4466 } |
4518 | 4467 |
4519 | 4468 |
4520 void HOptimizedGraphBuilder::SetUpScope(Scope* scope) { | 4469 void HOptimizedGraphBuilder::SetUpScope(Scope* scope) { |
4521 HConstant* undefined_constant = new(zone()) HConstant( | 4470 HConstant* undefined_constant = Add<HConstant>( |
4522 isolate()->factory()->undefined_value()); | 4471 isolate()->factory()->undefined_value()); |
4523 AddInstruction(undefined_constant); | |
4524 graph()->set_undefined_constant(undefined_constant); | 4472 graph()->set_undefined_constant(undefined_constant); |
4525 | 4473 |
4526 // Create an arguments object containing the initial parameters. Set the | 4474 // Create an arguments object containing the initial parameters. Set the |
4527 // initial values of parameters including "this" having parameter index 0. | 4475 // initial values of parameters including "this" having parameter index 0. |
4528 ASSERT_EQ(scope->num_parameters() + 1, environment()->parameter_count()); | 4476 ASSERT_EQ(scope->num_parameters() + 1, environment()->parameter_count()); |
4529 HArgumentsObject* arguments_object = | 4477 HArgumentsObject* arguments_object = |
4530 new(zone()) HArgumentsObject(environment()->parameter_count(), zone()); | 4478 new(zone()) HArgumentsObject(environment()->parameter_count(), zone()); |
4531 for (int i = 0; i < environment()->parameter_count(); ++i) { | 4479 for (int i = 0; i < environment()->parameter_count(); ++i) { |
4532 HInstruction* parameter = AddInstruction(new(zone()) HParameter(i)); | 4480 HInstruction* parameter = Add<HParameter>(i); |
4533 arguments_object->AddArgument(parameter, zone()); | 4481 arguments_object->AddArgument(parameter, zone()); |
4534 environment()->Bind(i, parameter); | 4482 environment()->Bind(i, parameter); |
4535 } | 4483 } |
4536 AddInstruction(arguments_object); | 4484 AddInstruction(arguments_object); |
4537 graph()->SetArgumentsObject(arguments_object); | 4485 graph()->SetArgumentsObject(arguments_object); |
4538 | 4486 |
4539 // First special is HContext. | 4487 // First special is HContext. |
4540 HInstruction* context = AddInstruction(new(zone()) HContext); | 4488 HInstruction* context = Add<HContext>(); |
4541 environment()->BindContext(context); | 4489 environment()->BindContext(context); |
4542 | 4490 |
4543 // Initialize specials and locals to undefined. | 4491 // Initialize specials and locals to undefined. |
4544 for (int i = environment()->parameter_count() + 1; | 4492 for (int i = environment()->parameter_count() + 1; |
4545 i < environment()->length(); | 4493 i < environment()->length(); |
4546 ++i) { | 4494 ++i) { |
4547 environment()->Bind(i, undefined_constant); | 4495 environment()->Bind(i, undefined_constant); |
4548 } | 4496 } |
4549 | 4497 |
4550 // Handle the arguments and arguments shadow variables specially (they do | 4498 // Handle the arguments and arguments shadow variables specially (they do |
(...skipping 418 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4969 | 4917 |
4970 set_current_block(osr_entry); | 4918 set_current_block(osr_entry); |
4971 osr_entry->set_osr_entry(); | 4919 osr_entry->set_osr_entry(); |
4972 BailoutId osr_entry_id = statement->OsrEntryId(); | 4920 BailoutId osr_entry_id = statement->OsrEntryId(); |
4973 int first_expression_index = environment()->first_expression_index(); | 4921 int first_expression_index = environment()->first_expression_index(); |
4974 int length = environment()->length(); | 4922 int length = environment()->length(); |
4975 ZoneList<HUnknownOSRValue*>* osr_values = | 4923 ZoneList<HUnknownOSRValue*>* osr_values = |
4976 new(zone()) ZoneList<HUnknownOSRValue*>(length, zone()); | 4924 new(zone()) ZoneList<HUnknownOSRValue*>(length, zone()); |
4977 | 4925 |
4978 for (int i = 0; i < first_expression_index; ++i) { | 4926 for (int i = 0; i < first_expression_index; ++i) { |
4979 HUnknownOSRValue* osr_value = new(zone()) HUnknownOSRValue; | 4927 HUnknownOSRValue* osr_value = Add<HUnknownOSRValue>(); |
4980 AddInstruction(osr_value); | |
4981 environment()->Bind(i, osr_value); | 4928 environment()->Bind(i, osr_value); |
4982 osr_values->Add(osr_value, zone()); | 4929 osr_values->Add(osr_value, zone()); |
4983 } | 4930 } |
4984 | 4931 |
4985 if (first_expression_index != length) { | 4932 if (first_expression_index != length) { |
4986 environment()->Drop(length - first_expression_index); | 4933 environment()->Drop(length - first_expression_index); |
4987 for (int i = first_expression_index; i < length; ++i) { | 4934 for (int i = first_expression_index; i < length; ++i) { |
4988 HUnknownOSRValue* osr_value = new(zone()) HUnknownOSRValue; | 4935 HUnknownOSRValue* osr_value = Add<HUnknownOSRValue>(); |
4989 AddInstruction(osr_value); | |
4990 environment()->Push(osr_value); | 4936 environment()->Push(osr_value); |
4991 osr_values->Add(osr_value, zone()); | 4937 osr_values->Add(osr_value, zone()); |
4992 } | 4938 } |
4993 } | 4939 } |
4994 | 4940 |
4995 graph()->set_osr_values(osr_values); | 4941 graph()->set_osr_values(osr_values); |
4996 | 4942 |
4997 AddSimulate(osr_entry_id); | 4943 AddSimulate(osr_entry_id); |
4998 AddInstruction(new(zone()) HOsrEntry(osr_entry_id)); | 4944 Add<HOsrEntry>(osr_entry_id); |
4999 HContext* context = new(zone()) HContext; | 4945 HContext* context = Add<HContext>(); |
5000 AddInstruction(context); | |
5001 environment()->BindContext(context); | 4946 environment()->BindContext(context); |
5002 current_block()->Goto(loop_predecessor); | 4947 current_block()->Goto(loop_predecessor); |
5003 loop_predecessor->SetJoinId(statement->EntryId()); | 4948 loop_predecessor->SetJoinId(statement->EntryId()); |
5004 set_current_block(loop_predecessor); | 4949 set_current_block(loop_predecessor); |
5005 return true; | 4950 return true; |
5006 } | 4951 } |
5007 | 4952 |
5008 | 4953 |
5009 void HOptimizedGraphBuilder::VisitLoopBody(IterationStatement* stmt, | 4954 void HOptimizedGraphBuilder::VisitLoopBody(IterationStatement* stmt, |
5010 HBasicBlock* loop_entry, | 4955 HBasicBlock* loop_entry, |
5011 BreakAndContinueInfo* break_info) { | 4956 BreakAndContinueInfo* break_info) { |
5012 BreakAndContinueScope push(break_info, this); | 4957 BreakAndContinueScope push(break_info, this); |
5013 AddSimulate(stmt->StackCheckId()); | 4958 AddSimulate(stmt->StackCheckId()); |
5014 HValue* context = environment()->LookupContext(); | 4959 HValue* context = environment()->LookupContext(); |
5015 HStackCheck* stack_check = | 4960 HStackCheck* stack_check = Add<HStackCheck>( |
5016 new(zone()) HStackCheck(context, HStackCheck::kBackwardsBranch); | 4961 context, HStackCheck::kBackwardsBranch); |
5017 AddInstruction(stack_check); | |
5018 ASSERT(loop_entry->IsLoopHeader()); | 4962 ASSERT(loop_entry->IsLoopHeader()); |
5019 loop_entry->loop_information()->set_stack_check(stack_check); | 4963 loop_entry->loop_information()->set_stack_check(stack_check); |
5020 CHECK_BAILOUT(Visit(stmt->body())); | 4964 CHECK_BAILOUT(Visit(stmt->body())); |
5021 } | 4965 } |
5022 | 4966 |
5023 | 4967 |
5024 void HOptimizedGraphBuilder::VisitDoWhileStatement(DoWhileStatement* stmt) { | 4968 void HOptimizedGraphBuilder::VisitDoWhileStatement(DoWhileStatement* stmt) { |
5025 ASSERT(!HasStackOverflow()); | 4969 ASSERT(!HasStackOverflow()); |
5026 ASSERT(current_block() != NULL); | 4970 ASSERT(current_block() != NULL); |
5027 ASSERT(current_block()->HasPredecessor()); | 4971 ASSERT(current_block()->HasPredecessor()); |
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5176 if (!stmt->each()->IsVariableProxy() || | 5120 if (!stmt->each()->IsVariableProxy() || |
5177 !stmt->each()->AsVariableProxy()->var()->IsStackLocal()) { | 5121 !stmt->each()->AsVariableProxy()->var()->IsStackLocal()) { |
5178 return Bailout("ForInStatement with non-local each variable"); | 5122 return Bailout("ForInStatement with non-local each variable"); |
5179 } | 5123 } |
5180 | 5124 |
5181 Variable* each_var = stmt->each()->AsVariableProxy()->var(); | 5125 Variable* each_var = stmt->each()->AsVariableProxy()->var(); |
5182 | 5126 |
5183 CHECK_ALIVE(VisitForValue(stmt->enumerable())); | 5127 CHECK_ALIVE(VisitForValue(stmt->enumerable())); |
5184 HValue* enumerable = Top(); // Leave enumerable at the top. | 5128 HValue* enumerable = Top(); // Leave enumerable at the top. |
5185 | 5129 |
5186 HInstruction* map = AddInstruction(new(zone()) HForInPrepareMap( | 5130 HInstruction* map = Add<HForInPrepareMap>( |
5187 environment()->LookupContext(), enumerable)); | 5131 environment()->LookupContext(), enumerable); |
5188 AddSimulate(stmt->PrepareId()); | 5132 AddSimulate(stmt->PrepareId()); |
5189 | 5133 |
5190 HInstruction* array = AddInstruction( | 5134 HInstruction* array = Add<HForInCacheArray>( |
5191 new(zone()) HForInCacheArray( | 5135 enumerable, map, DescriptorArray::kEnumCacheBridgeCacheIndex); |
5192 enumerable, | |
5193 map, | |
5194 DescriptorArray::kEnumCacheBridgeCacheIndex)); | |
5195 | 5136 |
5196 HInstruction* enum_length = AddInstruction(new(zone()) HMapEnumLength(map)); | 5137 HInstruction* enum_length = Add<HMapEnumLength>(map); |
5197 | 5138 |
5198 HInstruction* start_index = AddInstruction(new(zone()) HConstant(0)); | 5139 HInstruction* start_index = Add<HConstant>(0); |
5199 | 5140 |
5200 Push(map); | 5141 Push(map); |
5201 Push(array); | 5142 Push(array); |
5202 Push(enum_length); | 5143 Push(enum_length); |
5203 Push(start_index); | 5144 Push(start_index); |
5204 | 5145 |
5205 HInstruction* index_cache = AddInstruction( | 5146 HInstruction* index_cache = Add<HForInCacheArray>( |
5206 new(zone()) HForInCacheArray( | 5147 enumerable, map, DescriptorArray::kEnumCacheBridgeIndicesCacheIndex); |
5207 enumerable, | |
5208 map, | |
5209 DescriptorArray::kEnumCacheBridgeIndicesCacheIndex)); | |
5210 HForInCacheArray::cast(array)->set_index_cache( | 5148 HForInCacheArray::cast(array)->set_index_cache( |
5211 HForInCacheArray::cast(index_cache)); | 5149 HForInCacheArray::cast(index_cache)); |
5212 | 5150 |
5213 bool osr_entry = PreProcessOsrEntry(stmt); | 5151 bool osr_entry = PreProcessOsrEntry(stmt); |
5214 HBasicBlock* loop_entry = CreateLoopHeaderBlock(); | 5152 HBasicBlock* loop_entry = CreateLoopHeaderBlock(); |
5215 current_block()->Goto(loop_entry); | 5153 current_block()->Goto(loop_entry); |
5216 set_current_block(loop_entry); | 5154 set_current_block(loop_entry); |
5217 if (osr_entry) graph()->set_osr_loop_entry(loop_entry); | 5155 if (osr_entry) graph()->set_osr_loop_entry(loop_entry); |
5218 | 5156 |
5219 HValue* index = environment()->ExpressionStackAt(0); | 5157 HValue* index = environment()->ExpressionStackAt(0); |
(...skipping 10 matching lines...) Expand all Loading... |
5230 | 5168 |
5231 compare_index->SetSuccessorAt(0, loop_body); | 5169 compare_index->SetSuccessorAt(0, loop_body); |
5232 compare_index->SetSuccessorAt(1, loop_successor); | 5170 compare_index->SetSuccessorAt(1, loop_successor); |
5233 current_block()->Finish(compare_index); | 5171 current_block()->Finish(compare_index); |
5234 | 5172 |
5235 set_current_block(loop_successor); | 5173 set_current_block(loop_successor); |
5236 Drop(5); | 5174 Drop(5); |
5237 | 5175 |
5238 set_current_block(loop_body); | 5176 set_current_block(loop_body); |
5239 | 5177 |
5240 HValue* key = AddInstruction( | 5178 HValue* key = Add<HLoadKeyed>( |
5241 new(zone()) HLoadKeyed( | 5179 environment()->ExpressionStackAt(2), // Enum cache. |
5242 environment()->ExpressionStackAt(2), // Enum cache. | 5180 environment()->ExpressionStackAt(0), // Iteration index. |
5243 environment()->ExpressionStackAt(0), // Iteration index. | 5181 environment()->ExpressionStackAt(0), |
5244 environment()->ExpressionStackAt(0), | 5182 FAST_ELEMENTS); |
5245 FAST_ELEMENTS)); | |
5246 | 5183 |
5247 // Check if the expected map still matches that of the enumerable. | 5184 // Check if the expected map still matches that of the enumerable. |
5248 // If not just deoptimize. | 5185 // If not just deoptimize. |
5249 AddInstruction(new(zone()) HCheckMapValue( | 5186 Add<HCheckMapValue>(environment()->ExpressionStackAt(4), |
5250 environment()->ExpressionStackAt(4), | 5187 environment()->ExpressionStackAt(3)); |
5251 environment()->ExpressionStackAt(3))); | |
5252 | 5188 |
5253 Bind(each_var, key); | 5189 Bind(each_var, key); |
5254 | 5190 |
5255 BreakAndContinueInfo break_info(stmt, 5); | 5191 BreakAndContinueInfo break_info(stmt, 5); |
5256 CHECK_BAILOUT(VisitLoopBody(stmt, loop_entry, &break_info)); | 5192 CHECK_BAILOUT(VisitLoopBody(stmt, loop_entry, &break_info)); |
5257 | 5193 |
5258 HBasicBlock* body_exit = | 5194 HBasicBlock* body_exit = |
5259 JoinContinue(stmt, current_block(), break_info.continue_block()); | 5195 JoinContinue(stmt, current_block(), break_info.continue_block()); |
5260 | 5196 |
5261 if (body_exit != NULL) { | 5197 if (body_exit != NULL) { |
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5414 | 5350 |
5415 return kUseCell; | 5351 return kUseCell; |
5416 } | 5352 } |
5417 | 5353 |
5418 | 5354 |
5419 HValue* HOptimizedGraphBuilder::BuildContextChainWalk(Variable* var) { | 5355 HValue* HOptimizedGraphBuilder::BuildContextChainWalk(Variable* var) { |
5420 ASSERT(var->IsContextSlot()); | 5356 ASSERT(var->IsContextSlot()); |
5421 HValue* context = environment()->LookupContext(); | 5357 HValue* context = environment()->LookupContext(); |
5422 int length = current_info()->scope()->ContextChainLength(var->scope()); | 5358 int length = current_info()->scope()->ContextChainLength(var->scope()); |
5423 while (length-- > 0) { | 5359 while (length-- > 0) { |
5424 HInstruction* context_instruction = new(zone()) HOuterContext(context); | 5360 context = Add<HOuterContext>(context); |
5425 AddInstruction(context_instruction); | |
5426 context = context_instruction; | |
5427 } | 5361 } |
5428 return context; | 5362 return context; |
5429 } | 5363 } |
5430 | 5364 |
5431 | 5365 |
5432 void HOptimizedGraphBuilder::VisitVariableProxy(VariableProxy* expr) { | 5366 void HOptimizedGraphBuilder::VisitVariableProxy(VariableProxy* expr) { |
5433 ASSERT(!HasStackOverflow()); | 5367 ASSERT(!HasStackOverflow()); |
5434 ASSERT(current_block() != NULL); | 5368 ASSERT(current_block() != NULL); |
5435 ASSERT(current_block()->HasPredecessor()); | 5369 ASSERT(current_block()->HasPredecessor()); |
5436 Variable* variable = expr->var(); | 5370 Variable* variable = expr->var(); |
(...skipping 285 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5722 } else { | 5656 } else { |
5723 NoObservableSideEffectsScope no_effects(this); | 5657 NoObservableSideEffectsScope no_effects(this); |
5724 Handle<FixedArray> closure_literals(closure->literals(), isolate()); | 5658 Handle<FixedArray> closure_literals(closure->literals(), isolate()); |
5725 Handle<FixedArray> constant_properties = expr->constant_properties(); | 5659 Handle<FixedArray> constant_properties = expr->constant_properties(); |
5726 int literal_index = expr->literal_index(); | 5660 int literal_index = expr->literal_index(); |
5727 int flags = expr->fast_elements() | 5661 int flags = expr->fast_elements() |
5728 ? ObjectLiteral::kFastElements : ObjectLiteral::kNoFlags; | 5662 ? ObjectLiteral::kFastElements : ObjectLiteral::kNoFlags; |
5729 flags |= expr->has_function() | 5663 flags |= expr->has_function() |
5730 ? ObjectLiteral::kHasFunction : ObjectLiteral::kNoFlags; | 5664 ? ObjectLiteral::kHasFunction : ObjectLiteral::kNoFlags; |
5731 | 5665 |
5732 AddInstruction(new(zone()) HPushArgument(AddInstruction( | 5666 Add<HPushArgument>(Add<HConstant>(closure_literals)); |
5733 new(zone()) HConstant(closure_literals)))); | 5667 Add<HPushArgument>(Add<HConstant>(literal_index)); |
5734 AddInstruction(new(zone()) HPushArgument(AddInstruction( | 5668 Add<HPushArgument>(Add<HConstant>(constant_properties)); |
5735 new(zone()) HConstant(literal_index)))); | 5669 Add<HPushArgument>(Add<HConstant>(flags)); |
5736 AddInstruction(new(zone()) HPushArgument(AddInstruction( | |
5737 new(zone()) HConstant(constant_properties)))); | |
5738 AddInstruction(new(zone()) HPushArgument(AddInstruction( | |
5739 new(zone()) HConstant(flags)))); | |
5740 | 5670 |
5741 Runtime::FunctionId function_id = | 5671 Runtime::FunctionId function_id = |
5742 (expr->depth() > 1 || expr->may_store_doubles()) | 5672 (expr->depth() > 1 || expr->may_store_doubles()) |
5743 ? Runtime::kCreateObjectLiteral : Runtime::kCreateObjectLiteralShallow; | 5673 ? Runtime::kCreateObjectLiteral : Runtime::kCreateObjectLiteralShallow; |
5744 literal = AddInstruction( | 5674 literal = Add<HCallRuntime>(context, |
5745 new(zone()) HCallRuntime(context, | 5675 isolate()->factory()->empty_string(), |
5746 isolate()->factory()->empty_string(), | 5676 Runtime::FunctionForId(function_id), |
5747 Runtime::FunctionForId(function_id), | 5677 4); |
5748 4)); | |
5749 } | 5678 } |
5750 | 5679 |
5751 // The object is expected in the bailout environment during computation | 5680 // The object is expected in the bailout environment during computation |
5752 // of the property values and is the value of the entire expression. | 5681 // of the property values and is the value of the entire expression. |
5753 Push(literal); | 5682 Push(literal); |
5754 | 5683 |
5755 expr->CalculateEmitStore(zone()); | 5684 expr->CalculateEmitStore(zone()); |
5756 | 5685 |
5757 for (int i = 0; i < expr->properties()->length(); i++) { | 5686 for (int i = 0; i < expr->properties()->length(); i++) { |
5758 ObjectLiteral::Property* property = expr->properties()->at(i); | 5687 ObjectLiteral::Property* property = expr->properties()->at(i); |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5804 default: UNREACHABLE(); | 5733 default: UNREACHABLE(); |
5805 } | 5734 } |
5806 } | 5735 } |
5807 | 5736 |
5808 if (expr->has_function()) { | 5737 if (expr->has_function()) { |
5809 // Return the result of the transformation to fast properties | 5738 // Return the result of the transformation to fast properties |
5810 // instead of the original since this operation changes the map | 5739 // instead of the original since this operation changes the map |
5811 // of the object. This makes sure that the original object won't | 5740 // of the object. This makes sure that the original object won't |
5812 // be used by other optimized code before it is transformed | 5741 // be used by other optimized code before it is transformed |
5813 // (e.g. because of code motion). | 5742 // (e.g. because of code motion). |
5814 HToFastProperties* result = new(zone()) HToFastProperties(Pop()); | 5743 HToFastProperties* result = Add<HToFastProperties>(Pop()); |
5815 AddInstruction(result); | |
5816 return ast_context()->ReturnValue(result); | 5744 return ast_context()->ReturnValue(result); |
5817 } else { | 5745 } else { |
5818 return ast_context()->ReturnValue(Pop()); | 5746 return ast_context()->ReturnValue(Pop()); |
5819 } | 5747 } |
5820 } | 5748 } |
5821 | 5749 |
5822 | 5750 |
5823 void HOptimizedGraphBuilder::VisitArrayLiteral(ArrayLiteral* expr) { | 5751 void HOptimizedGraphBuilder::VisitArrayLiteral(ArrayLiteral* expr) { |
5824 ASSERT(!HasStackOverflow()); | 5752 ASSERT(!HasStackOverflow()); |
5825 ASSERT(current_block() != NULL); | 5753 ASSERT(current_block() != NULL); |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5877 data_size, | 5805 data_size, |
5878 pointer_size, | 5806 pointer_size, |
5879 mode); | 5807 mode); |
5880 } else { | 5808 } else { |
5881 NoObservableSideEffectsScope no_effects(this); | 5809 NoObservableSideEffectsScope no_effects(this); |
5882 // Boilerplate already exists and constant elements are never accessed, | 5810 // Boilerplate already exists and constant elements are never accessed, |
5883 // pass an empty fixed array to the runtime function instead. | 5811 // pass an empty fixed array to the runtime function instead. |
5884 Handle<FixedArray> constants = isolate()->factory()->empty_fixed_array(); | 5812 Handle<FixedArray> constants = isolate()->factory()->empty_fixed_array(); |
5885 int literal_index = expr->literal_index(); | 5813 int literal_index = expr->literal_index(); |
5886 | 5814 |
5887 AddInstruction(new(zone()) HPushArgument(AddInstruction( | 5815 Add<HPushArgument>(Add<HConstant>(literals)); |
5888 new(zone()) HConstant(literals)))); | 5816 Add<HPushArgument>(Add<HConstant>(literal_index)); |
5889 AddInstruction(new(zone()) HPushArgument(AddInstruction( | 5817 Add<HPushArgument>(Add<HConstant>(constants)); |
5890 new(zone()) HConstant(literal_index)))); | |
5891 AddInstruction(new(zone()) HPushArgument(AddInstruction( | |
5892 new(zone()) HConstant(constants)))); | |
5893 | 5818 |
5894 Runtime::FunctionId function_id = (expr->depth() > 1) | 5819 Runtime::FunctionId function_id = (expr->depth() > 1) |
5895 ? Runtime::kCreateArrayLiteral : Runtime::kCreateArrayLiteralShallow; | 5820 ? Runtime::kCreateArrayLiteral : Runtime::kCreateArrayLiteralShallow; |
5896 literal = AddInstruction( | 5821 literal = Add<HCallRuntime>(context, |
5897 new(zone()) HCallRuntime(context, | 5822 isolate()->factory()->empty_string(), |
5898 isolate()->factory()->empty_string(), | 5823 Runtime::FunctionForId(function_id), |
5899 Runtime::FunctionForId(function_id), | 5824 3); |
5900 3)); | |
5901 | 5825 |
5902 // De-opt if elements kind changed from boilerplate_elements_kind. | 5826 // De-opt if elements kind changed from boilerplate_elements_kind. |
5903 Handle<Map> map = Handle<Map>(original_boilerplate_object->map(), | 5827 Handle<Map> map = Handle<Map>(original_boilerplate_object->map(), |
5904 isolate()); | 5828 isolate()); |
5905 AddInstruction(HCheckMaps::New(literal, map, zone())); | 5829 AddInstruction(HCheckMaps::New(literal, map, zone())); |
5906 } | 5830 } |
5907 | 5831 |
5908 // The array is expected in the bailout environment during computation | 5832 // The array is expected in the bailout environment during computation |
5909 // of the property values and is the value of the entire expression. | 5833 // of the property values and is the value of the entire expression. |
5910 Push(literal); | 5834 Push(literal); |
5911 // The literal index is on the stack, too. | 5835 // The literal index is on the stack, too. |
5912 Push(AddInstruction(new(zone()) HConstant(expr->literal_index()))); | 5836 Push(Add<HConstant>(expr->literal_index())); |
5913 | 5837 |
5914 HInstruction* elements = NULL; | 5838 HInstruction* elements = NULL; |
5915 | 5839 |
5916 for (int i = 0; i < length; i++) { | 5840 for (int i = 0; i < length; i++) { |
5917 Expression* subexpr = subexprs->at(i); | 5841 Expression* subexpr = subexprs->at(i); |
5918 // If the subexpression is a literal or a simple materialized literal it | 5842 // If the subexpression is a literal or a simple materialized literal it |
5919 // is already set in the cloned array. | 5843 // is already set in the cloned array. |
5920 if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue; | 5844 if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue; |
5921 | 5845 |
5922 CHECK_ALIVE(VisitForValue(subexpr)); | 5846 CHECK_ALIVE(VisitForValue(subexpr)); |
5923 HValue* value = Pop(); | 5847 HValue* value = Pop(); |
5924 if (!Smi::IsValid(i)) return Bailout("Non-smi key in array literal"); | 5848 if (!Smi::IsValid(i)) return Bailout("Non-smi key in array literal"); |
5925 | 5849 |
5926 elements = AddLoadElements(literal); | 5850 elements = AddLoadElements(literal); |
5927 | 5851 |
5928 HValue* key = AddInstruction(new(zone()) HConstant(i)); | 5852 HValue* key = Add<HConstant>(i); |
5929 | 5853 |
5930 switch (boilerplate_elements_kind) { | 5854 switch (boilerplate_elements_kind) { |
5931 case FAST_SMI_ELEMENTS: | 5855 case FAST_SMI_ELEMENTS: |
5932 case FAST_HOLEY_SMI_ELEMENTS: | 5856 case FAST_HOLEY_SMI_ELEMENTS: |
5933 case FAST_ELEMENTS: | 5857 case FAST_ELEMENTS: |
5934 case FAST_HOLEY_ELEMENTS: | 5858 case FAST_HOLEY_ELEMENTS: |
5935 case FAST_DOUBLE_ELEMENTS: | 5859 case FAST_DOUBLE_ELEMENTS: |
5936 case FAST_HOLEY_DOUBLE_ELEMENTS: | 5860 case FAST_HOLEY_DOUBLE_ELEMENTS: |
5937 AddInstruction(new(zone()) HStoreKeyed( | 5861 Add<HStoreKeyed>(elements, key, value, |
5938 elements, | 5862 boilerplate_elements_kind); |
5939 key, | |
5940 value, | |
5941 boilerplate_elements_kind)); | |
5942 break; | 5863 break; |
5943 default: | 5864 default: |
5944 UNREACHABLE(); | 5865 UNREACHABLE(); |
5945 break; | 5866 break; |
5946 } | 5867 } |
5947 | 5868 |
5948 AddSimulate(expr->GetIdForElement(i)); | 5869 AddSimulate(expr->GetIdForElement(i)); |
5949 } | 5870 } |
5950 | 5871 |
5951 Drop(1); // array literal index | 5872 Drop(1); // array literal index |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6028 // We only need to check up to the preexisting property. | 5949 // We only need to check up to the preexisting property. |
6029 proto = proto_result.holder(); | 5950 proto = proto_result.holder(); |
6030 } else { | 5951 } else { |
6031 // Otherwise, find the top prototype. | 5952 // Otherwise, find the top prototype. |
6032 while (proto->GetPrototype(isolate())->IsJSObject()) { | 5953 while (proto->GetPrototype(isolate())->IsJSObject()) { |
6033 proto = proto->GetPrototype(isolate()); | 5954 proto = proto->GetPrototype(isolate()); |
6034 } | 5955 } |
6035 ASSERT(proto->GetPrototype(isolate())->IsNull()); | 5956 ASSERT(proto->GetPrototype(isolate())->IsNull()); |
6036 } | 5957 } |
6037 ASSERT(proto->IsJSObject()); | 5958 ASSERT(proto->IsJSObject()); |
6038 AddInstruction(new(zone()) HCheckPrototypeMaps( | 5959 Add<HCheckPrototypeMaps>(Handle<JSObject>(JSObject::cast(map->prototype())), |
6039 Handle<JSObject>(JSObject::cast(map->prototype())), | 5960 Handle<JSObject>(JSObject::cast(proto)), |
6040 Handle<JSObject>(JSObject::cast(proto)), | 5961 zone(), top_info()); |
6041 zone(), | |
6042 top_info())); | |
6043 } | 5962 } |
6044 | 5963 |
6045 HObjectAccess field_access = HObjectAccess::ForField(map, lookup, name); | 5964 HObjectAccess field_access = HObjectAccess::ForField(map, lookup, name); |
6046 Representation representation = ComputeLoadStoreRepresentation(map, lookup); | 5965 Representation representation = ComputeLoadStoreRepresentation(map, lookup); |
6047 bool transition_to_field = lookup->IsTransitionToField(*map); | 5966 bool transition_to_field = lookup->IsTransitionToField(*map); |
6048 | 5967 |
6049 HStoreNamedField *instr; | 5968 HStoreNamedField *instr; |
6050 if (FLAG_track_double_fields && representation.IsDouble()) { | 5969 if (FLAG_track_double_fields && representation.IsDouble()) { |
6051 if (transition_to_field) { | 5970 if (transition_to_field) { |
6052 // The store requires a mutable HeapNumber to be allocated. | 5971 // The store requires a mutable HeapNumber to be allocated. |
6053 NoObservableSideEffectsScope no_side_effects(this); | 5972 NoObservableSideEffectsScope no_side_effects(this); |
6054 HInstruction* heap_number_size = AddInstruction(new(zone()) HConstant( | 5973 HInstruction* heap_number_size = Add<HConstant>(HeapNumber::kSize); |
6055 HeapNumber::kSize)); | 5974 HInstruction* double_box = Add<HAllocate>( |
6056 HInstruction* double_box = AddInstruction(new(zone()) HAllocate( | |
6057 environment()->LookupContext(), heap_number_size, | 5975 environment()->LookupContext(), heap_number_size, |
6058 HType::HeapNumber(), HAllocate::CAN_ALLOCATE_IN_NEW_SPACE)); | 5976 HType::HeapNumber(), HAllocate::CAN_ALLOCATE_IN_NEW_SPACE); |
6059 AddStoreMapConstant(double_box, isolate()->factory()->heap_number_map()); | 5977 AddStoreMapConstant(double_box, isolate()->factory()->heap_number_map()); |
6060 AddStore(double_box, HObjectAccess::ForHeapNumberValue(), | 5978 AddStore(double_box, HObjectAccess::ForHeapNumberValue(), |
6061 value, Representation::Double()); | 5979 value, Representation::Double()); |
6062 instr = new(zone()) HStoreNamedField(object, field_access, double_box); | 5980 instr = new(zone()) HStoreNamedField(object, field_access, double_box); |
6063 } else { | 5981 } else { |
6064 // Already holds a HeapNumber; load the box and write its value field. | 5982 // Already holds a HeapNumber; load the box and write its value field. |
6065 HInstruction* double_box = AddLoad(object, field_access); | 5983 HInstruction* double_box = AddLoad(object, field_access); |
6066 double_box->set_type(HType::HeapNumber()); | 5984 double_box->set_type(HType::HeapNumber()); |
6067 instr = new(zone()) HStoreNamedField(double_box, | 5985 instr = new(zone()) HStoreNamedField(double_box, |
6068 HObjectAccess::ForHeapNumberValue(), value, Representation::Double()); | 5986 HObjectAccess::ForHeapNumberValue(), value, Representation::Double()); |
(...skipping 29 matching lines...) Expand all Loading... |
6098 } | 6016 } |
6099 | 6017 |
6100 | 6018 |
6101 HInstruction* HOptimizedGraphBuilder::BuildCallSetter( | 6019 HInstruction* HOptimizedGraphBuilder::BuildCallSetter( |
6102 HValue* object, | 6020 HValue* object, |
6103 HValue* value, | 6021 HValue* value, |
6104 Handle<Map> map, | 6022 Handle<Map> map, |
6105 Handle<JSFunction> setter, | 6023 Handle<JSFunction> setter, |
6106 Handle<JSObject> holder) { | 6024 Handle<JSObject> holder) { |
6107 AddCheckConstantFunction(holder, object, map); | 6025 AddCheckConstantFunction(holder, object, map); |
6108 AddInstruction(new(zone()) HPushArgument(object)); | 6026 Add<HPushArgument>(object); |
6109 AddInstruction(new(zone()) HPushArgument(value)); | 6027 Add<HPushArgument>(value); |
6110 return new(zone()) HCallConstantFunction(setter, 2); | 6028 return new(zone()) HCallConstantFunction(setter, 2); |
6111 } | 6029 } |
6112 | 6030 |
6113 | 6031 |
6114 HInstruction* HOptimizedGraphBuilder::BuildStoreNamedMonomorphic( | 6032 HInstruction* HOptimizedGraphBuilder::BuildStoreNamedMonomorphic( |
6115 HValue* object, | 6033 HValue* object, |
6116 Handle<String> name, | 6034 Handle<String> name, |
6117 HValue* value, | 6035 HValue* value, |
6118 Handle<Map> map) { | 6036 Handle<Map> map) { |
6119 // Handle a store to a known field. | 6037 // Handle a store to a known field. |
(...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6379 void HOptimizedGraphBuilder::HandleGlobalVariableAssignment( | 6297 void HOptimizedGraphBuilder::HandleGlobalVariableAssignment( |
6380 Variable* var, | 6298 Variable* var, |
6381 HValue* value, | 6299 HValue* value, |
6382 int position, | 6300 int position, |
6383 BailoutId ast_id) { | 6301 BailoutId ast_id) { |
6384 LookupResult lookup(isolate()); | 6302 LookupResult lookup(isolate()); |
6385 GlobalPropertyAccess type = LookupGlobalProperty(var, &lookup, true); | 6303 GlobalPropertyAccess type = LookupGlobalProperty(var, &lookup, true); |
6386 if (type == kUseCell) { | 6304 if (type == kUseCell) { |
6387 Handle<GlobalObject> global(current_info()->global_object()); | 6305 Handle<GlobalObject> global(current_info()->global_object()); |
6388 Handle<PropertyCell> cell(global->GetPropertyCell(&lookup)); | 6306 Handle<PropertyCell> cell(global->GetPropertyCell(&lookup)); |
6389 HInstruction* instr = | 6307 HInstruction* instr = Add<HStoreGlobalCell>(value, cell, |
6390 new(zone()) HStoreGlobalCell(value, cell, lookup.GetPropertyDetails()); | 6308 lookup.GetPropertyDetails()); |
6391 instr->set_position(position); | 6309 instr->set_position(position); |
6392 AddInstruction(instr); | |
6393 if (instr->HasObservableSideEffects()) { | 6310 if (instr->HasObservableSideEffects()) { |
6394 AddSimulate(ast_id, REMOVABLE_SIMULATE); | 6311 AddSimulate(ast_id, REMOVABLE_SIMULATE); |
6395 } | 6312 } |
6396 } else { | 6313 } else { |
6397 HValue* context = environment()->LookupContext(); | 6314 HValue* context = environment()->LookupContext(); |
6398 HGlobalObject* global_object = new(zone()) HGlobalObject(context); | 6315 HGlobalObject* global_object = Add<HGlobalObject>(context); |
6399 AddInstruction(global_object); | |
6400 HStoreGlobalGeneric* instr = | 6316 HStoreGlobalGeneric* instr = |
6401 new(zone()) HStoreGlobalGeneric(context, | 6317 Add<HStoreGlobalGeneric>(context, global_object, var->name(), |
6402 global_object, | 6318 value, function_strict_mode_flag()); |
6403 var->name(), | |
6404 value, | |
6405 function_strict_mode_flag()); | |
6406 instr->set_position(position); | 6319 instr->set_position(position); |
6407 AddInstruction(instr); | |
6408 ASSERT(instr->HasObservableSideEffects()); | 6320 ASSERT(instr->HasObservableSideEffects()); |
6409 AddSimulate(ast_id, REMOVABLE_SIMULATE); | 6321 AddSimulate(ast_id, REMOVABLE_SIMULATE); |
6410 } | 6322 } |
6411 } | 6323 } |
6412 | 6324 |
6413 | 6325 |
6414 void HOptimizedGraphBuilder::BuildStoreNamed(Expression* expr, | 6326 void HOptimizedGraphBuilder::BuildStoreNamed(Expression* expr, |
6415 BailoutId id, | 6327 BailoutId id, |
6416 int position, | 6328 int position, |
6417 BailoutId assignment_id, | 6329 BailoutId assignment_id, |
(...skipping 15 matching lines...) Expand all Loading... |
6433 if (monomorphic) { | 6345 if (monomorphic) { |
6434 Handle<JSFunction> setter; | 6346 Handle<JSFunction> setter; |
6435 Handle<JSObject> holder; | 6347 Handle<JSObject> holder; |
6436 if (LookupSetter(map, name, &setter, &holder)) { | 6348 if (LookupSetter(map, name, &setter, &holder)) { |
6437 AddCheckConstantFunction(holder, object, map); | 6349 AddCheckConstantFunction(holder, object, map); |
6438 if (FLAG_inline_accessors && | 6350 if (FLAG_inline_accessors && |
6439 TryInlineSetter(setter, id, assignment_id, value)) { | 6351 TryInlineSetter(setter, id, assignment_id, value)) { |
6440 return; | 6352 return; |
6441 } | 6353 } |
6442 Drop(2); | 6354 Drop(2); |
6443 AddInstruction(new(zone()) HPushArgument(object)); | 6355 Add<HPushArgument>(object); |
6444 AddInstruction(new(zone()) HPushArgument(value)); | 6356 Add<HPushArgument>(value); |
6445 instr = new(zone()) HCallConstantFunction(setter, 2); | 6357 instr = new(zone()) HCallConstantFunction(setter, 2); |
6446 } else { | 6358 } else { |
6447 Drop(2); | 6359 Drop(2); |
6448 CHECK_ALIVE(instr = BuildStoreNamedMonomorphic(object, | 6360 CHECK_ALIVE(instr = BuildStoreNamedMonomorphic(object, |
6449 name, | 6361 name, |
6450 value, | 6362 value, |
6451 map)); | 6363 map)); |
6452 } | 6364 } |
6453 | 6365 |
6454 } else if (types != NULL && types->length() > 1) { | 6366 } else if (types != NULL && types->length() > 1) { |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6531 return ast_context()->ReturnValue(Pop()); | 6443 return ast_context()->ReturnValue(Pop()); |
6532 case CONST_HARMONY: | 6444 case CONST_HARMONY: |
6533 // This case is checked statically so no need to | 6445 // This case is checked statically so no need to |
6534 // perform checks here | 6446 // perform checks here |
6535 UNREACHABLE(); | 6447 UNREACHABLE(); |
6536 default: | 6448 default: |
6537 mode = HStoreContextSlot::kNoCheck; | 6449 mode = HStoreContextSlot::kNoCheck; |
6538 } | 6450 } |
6539 | 6451 |
6540 HValue* context = BuildContextChainWalk(var); | 6452 HValue* context = BuildContextChainWalk(var); |
6541 HStoreContextSlot* instr = | 6453 HStoreContextSlot* instr = Add<HStoreContextSlot>(context, var->index(), |
6542 new(zone()) HStoreContextSlot(context, var->index(), mode, Top()); | 6454 mode, Top()); |
6543 AddInstruction(instr); | |
6544 if (instr->HasObservableSideEffects()) { | 6455 if (instr->HasObservableSideEffects()) { |
6545 AddSimulate(expr->AssignmentId(), REMOVABLE_SIMULATE); | 6456 AddSimulate(expr->AssignmentId(), REMOVABLE_SIMULATE); |
6546 } | 6457 } |
6547 break; | 6458 break; |
6548 } | 6459 } |
6549 | 6460 |
6550 case Variable::LOOKUP: | 6461 case Variable::LOOKUP: |
6551 return Bailout("compound assignment to lookup slot"); | 6462 return Bailout("compound assignment to lookup slot"); |
6552 } | 6463 } |
6553 return ast_context()->ReturnValue(Pop()); | 6464 return ast_context()->ReturnValue(Pop()); |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6663 if (var->mode() == CONST) { | 6574 if (var->mode() == CONST) { |
6664 if (expr->op() != Token::INIT_CONST) { | 6575 if (expr->op() != Token::INIT_CONST) { |
6665 CHECK_ALIVE(VisitForValue(expr->value())); | 6576 CHECK_ALIVE(VisitForValue(expr->value())); |
6666 return ast_context()->ReturnValue(Pop()); | 6577 return ast_context()->ReturnValue(Pop()); |
6667 } | 6578 } |
6668 | 6579 |
6669 if (var->IsStackAllocated()) { | 6580 if (var->IsStackAllocated()) { |
6670 // We insert a use of the old value to detect unsupported uses of const | 6581 // We insert a use of the old value to detect unsupported uses of const |
6671 // variables (e.g. initialization inside a loop). | 6582 // variables (e.g. initialization inside a loop). |
6672 HValue* old_value = environment()->Lookup(var); | 6583 HValue* old_value = environment()->Lookup(var); |
6673 AddInstruction(new(zone()) HUseConst(old_value)); | 6584 Add<HUseConst>(old_value); |
6674 } | 6585 } |
6675 } else if (var->mode() == CONST_HARMONY) { | 6586 } else if (var->mode() == CONST_HARMONY) { |
6676 if (expr->op() != Token::INIT_CONST_HARMONY) { | 6587 if (expr->op() != Token::INIT_CONST_HARMONY) { |
6677 return Bailout("non-initializer assignment to const"); | 6588 return Bailout("non-initializer assignment to const"); |
6678 } | 6589 } |
6679 } | 6590 } |
6680 | 6591 |
6681 if (proxy->IsArguments()) return Bailout("assignment to arguments"); | 6592 if (proxy->IsArguments()) return Bailout("assignment to arguments"); |
6682 | 6593 |
6683 // Handle the assignment. | 6594 // Handle the assignment. |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6744 expr->op() == Token::INIT_LET || | 6655 expr->op() == Token::INIT_LET || |
6745 expr->op() == Token::INIT_CONST_HARMONY) { | 6656 expr->op() == Token::INIT_CONST_HARMONY) { |
6746 mode = HStoreContextSlot::kNoCheck; | 6657 mode = HStoreContextSlot::kNoCheck; |
6747 } else { | 6658 } else { |
6748 ASSERT(expr->op() == Token::INIT_CONST); | 6659 ASSERT(expr->op() == Token::INIT_CONST); |
6749 | 6660 |
6750 mode = HStoreContextSlot::kCheckIgnoreAssignment; | 6661 mode = HStoreContextSlot::kCheckIgnoreAssignment; |
6751 } | 6662 } |
6752 | 6663 |
6753 HValue* context = BuildContextChainWalk(var); | 6664 HValue* context = BuildContextChainWalk(var); |
6754 HStoreContextSlot* instr = new(zone()) HStoreContextSlot( | 6665 HStoreContextSlot* instr = Add<HStoreContextSlot>(context, var->index(), |
6755 context, var->index(), mode, Top()); | 6666 mode, Top()); |
6756 AddInstruction(instr); | |
6757 if (instr->HasObservableSideEffects()) { | 6667 if (instr->HasObservableSideEffects()) { |
6758 AddSimulate(expr->AssignmentId(), REMOVABLE_SIMULATE); | 6668 AddSimulate(expr->AssignmentId(), REMOVABLE_SIMULATE); |
6759 } | 6669 } |
6760 return ast_context()->ReturnValue(Pop()); | 6670 return ast_context()->ReturnValue(Pop()); |
6761 } | 6671 } |
6762 | 6672 |
6763 case Variable::LOOKUP: | 6673 case Variable::LOOKUP: |
6764 return Bailout("assignment to LOOKUP variable"); | 6674 return Bailout("assignment to LOOKUP variable"); |
6765 } | 6675 } |
6766 } else { | 6676 } else { |
(...skipping 13 matching lines...) Expand all Loading... |
6780 ASSERT(current_block() != NULL); | 6690 ASSERT(current_block() != NULL); |
6781 ASSERT(current_block()->HasPredecessor()); | 6691 ASSERT(current_block()->HasPredecessor()); |
6782 // We don't optimize functions with invalid left-hand sides in | 6692 // We don't optimize functions with invalid left-hand sides in |
6783 // assignments, count operations, or for-in. Consequently throw can | 6693 // assignments, count operations, or for-in. Consequently throw can |
6784 // currently only occur in an effect context. | 6694 // currently only occur in an effect context. |
6785 ASSERT(ast_context()->IsEffect()); | 6695 ASSERT(ast_context()->IsEffect()); |
6786 CHECK_ALIVE(VisitForValue(expr->exception())); | 6696 CHECK_ALIVE(VisitForValue(expr->exception())); |
6787 | 6697 |
6788 HValue* context = environment()->LookupContext(); | 6698 HValue* context = environment()->LookupContext(); |
6789 HValue* value = environment()->Pop(); | 6699 HValue* value = environment()->Pop(); |
6790 HThrow* instr = new(zone()) HThrow(context, value); | 6700 HThrow* instr = Add<HThrow>(context, value); |
6791 instr->set_position(expr->position()); | 6701 instr->set_position(expr->position()); |
6792 AddInstruction(instr); | |
6793 AddSimulate(expr->id()); | 6702 AddSimulate(expr->id()); |
6794 current_block()->FinishExit(new(zone()) HAbnormalExit); | 6703 current_block()->FinishExit(new(zone()) HAbnormalExit); |
6795 set_current_block(NULL); | 6704 set_current_block(NULL); |
6796 } | 6705 } |
6797 | 6706 |
6798 | 6707 |
6799 HLoadNamedField* HGraphBuilder::BuildLoadNamedField( | 6708 HLoadNamedField* HGraphBuilder::BuildLoadNamedField( |
6800 HValue* object, | 6709 HValue* object, |
6801 HObjectAccess access, | 6710 HObjectAccess access, |
6802 Representation representation) { | 6711 Representation representation) { |
(...skipping 25 matching lines...) Expand all Loading... |
6828 return new(zone()) HLoadNamedGeneric(context, object, name); | 6737 return new(zone()) HLoadNamedGeneric(context, object, name); |
6829 } | 6738 } |
6830 | 6739 |
6831 | 6740 |
6832 HInstruction* HOptimizedGraphBuilder::BuildCallGetter( | 6741 HInstruction* HOptimizedGraphBuilder::BuildCallGetter( |
6833 HValue* object, | 6742 HValue* object, |
6834 Handle<Map> map, | 6743 Handle<Map> map, |
6835 Handle<JSFunction> getter, | 6744 Handle<JSFunction> getter, |
6836 Handle<JSObject> holder) { | 6745 Handle<JSObject> holder) { |
6837 AddCheckConstantFunction(holder, object, map); | 6746 AddCheckConstantFunction(holder, object, map); |
6838 AddInstruction(new(zone()) HPushArgument(object)); | 6747 Add<HPushArgument>(object); |
6839 return new(zone()) HCallConstantFunction(getter, 1); | 6748 return new(zone()) HCallConstantFunction(getter, 1); |
6840 } | 6749 } |
6841 | 6750 |
6842 | 6751 |
6843 HInstruction* HOptimizedGraphBuilder::BuildLoadNamedMonomorphic( | 6752 HInstruction* HOptimizedGraphBuilder::BuildLoadNamedMonomorphic( |
6844 HValue* object, | 6753 HValue* object, |
6845 Handle<String> name, | 6754 Handle<String> name, |
6846 Property* expr, | 6755 Property* expr, |
6847 Handle<Map> map) { | 6756 Handle<Map> map) { |
6848 // Handle a load from a known field. | 6757 // Handle a load from a known field. |
(...skipping 24 matching lines...) Expand all Loading... |
6873 return new(zone()) HConstant(function); | 6782 return new(zone()) HConstant(function); |
6874 } | 6783 } |
6875 | 6784 |
6876 // Handle a load from a known field somewhere in the prototype chain. | 6785 // Handle a load from a known field somewhere in the prototype chain. |
6877 LookupInPrototypes(map, name, &lookup); | 6786 LookupInPrototypes(map, name, &lookup); |
6878 if (lookup.IsField()) { | 6787 if (lookup.IsField()) { |
6879 Handle<JSObject> prototype(JSObject::cast(map->prototype())); | 6788 Handle<JSObject> prototype(JSObject::cast(map->prototype())); |
6880 Handle<JSObject> holder(lookup.holder()); | 6789 Handle<JSObject> holder(lookup.holder()); |
6881 Handle<Map> holder_map(holder->map()); | 6790 Handle<Map> holder_map(holder->map()); |
6882 AddCheckMap(object, map); | 6791 AddCheckMap(object, map); |
6883 AddInstruction(new(zone()) HCheckPrototypeMaps( | 6792 Add<HCheckPrototypeMaps>(prototype, holder, zone(), top_info()); |
6884 prototype, holder, zone(), top_info())); | 6793 HValue* holder_value = Add<HConstant>(holder); |
6885 HValue* holder_value = AddInstruction(new(zone()) HConstant(holder)); | |
6886 return BuildLoadNamedField(holder_value, | 6794 return BuildLoadNamedField(holder_value, |
6887 HObjectAccess::ForField(holder_map, &lookup, name), | 6795 HObjectAccess::ForField(holder_map, &lookup, name), |
6888 ComputeLoadStoreRepresentation(map, &lookup)); | 6796 ComputeLoadStoreRepresentation(map, &lookup)); |
6889 } | 6797 } |
6890 | 6798 |
6891 // Handle a load of a constant function somewhere in the prototype chain. | 6799 // Handle a load of a constant function somewhere in the prototype chain. |
6892 if (lookup.IsConstantFunction()) { | 6800 if (lookup.IsConstantFunction()) { |
6893 Handle<JSObject> prototype(JSObject::cast(map->prototype())); | 6801 Handle<JSObject> prototype(JSObject::cast(map->prototype())); |
6894 Handle<JSObject> holder(lookup.holder()); | 6802 Handle<JSObject> holder(lookup.holder()); |
6895 Handle<Map> holder_map(holder->map()); | 6803 Handle<Map> holder_map(holder->map()); |
6896 AddCheckMap(object, map); | 6804 AddCheckMap(object, map); |
6897 AddInstruction(new(zone()) HCheckPrototypeMaps( | 6805 Add<HCheckPrototypeMaps>(prototype, holder, zone(), top_info()); |
6898 prototype, holder, zone(), top_info())); | |
6899 Handle<JSFunction> function(lookup.GetConstantFunctionFromMap(*holder_map)); | 6806 Handle<JSFunction> function(lookup.GetConstantFunctionFromMap(*holder_map)); |
6900 return new(zone()) HConstant(function); | 6807 return new(zone()) HConstant(function); |
6901 } | 6808 } |
6902 | 6809 |
6903 // No luck, do a generic load. | 6810 // No luck, do a generic load. |
6904 return BuildLoadNamedGeneric(object, name, expr); | 6811 return BuildLoadNamedGeneric(object, name, expr); |
6905 } | 6812 } |
6906 | 6813 |
6907 | 6814 |
6908 HInstruction* HOptimizedGraphBuilder::BuildLoadKeyedGeneric(HValue* object, | 6815 HInstruction* HOptimizedGraphBuilder::BuildLoadKeyedGeneric(HValue* object, |
(...skipping 16 matching lines...) Expand all Loading... |
6925 if (dependency) { | 6832 if (dependency) { |
6926 mapcheck->ClearGVNFlag(kDependsOnElementsKind); | 6833 mapcheck->ClearGVNFlag(kDependsOnElementsKind); |
6927 } | 6834 } |
6928 | 6835 |
6929 // Loads from a "stock" fast holey double arrays can elide the hole check. | 6836 // Loads from a "stock" fast holey double arrays can elide the hole check. |
6930 LoadKeyedHoleMode load_mode = NEVER_RETURN_HOLE; | 6837 LoadKeyedHoleMode load_mode = NEVER_RETURN_HOLE; |
6931 if (*map == isolate()->get_initial_js_array_map(FAST_HOLEY_DOUBLE_ELEMENTS) && | 6838 if (*map == isolate()->get_initial_js_array_map(FAST_HOLEY_DOUBLE_ELEMENTS) && |
6932 isolate()->IsFastArrayConstructorPrototypeChainIntact()) { | 6839 isolate()->IsFastArrayConstructorPrototypeChainIntact()) { |
6933 Handle<JSObject> prototype(JSObject::cast(map->prototype()), isolate()); | 6840 Handle<JSObject> prototype(JSObject::cast(map->prototype()), isolate()); |
6934 Handle<JSObject> object_prototype = isolate()->initial_object_prototype(); | 6841 Handle<JSObject> object_prototype = isolate()->initial_object_prototype(); |
6935 AddInstruction(new(zone()) HCheckPrototypeMaps( | 6842 Add<HCheckPrototypeMaps>(prototype, object_prototype, zone(), top_info()); |
6936 prototype, object_prototype, zone(), top_info())); | |
6937 load_mode = ALLOW_RETURN_HOLE; | 6843 load_mode = ALLOW_RETURN_HOLE; |
6938 graph()->MarkDependsOnEmptyArrayProtoElements(); | 6844 graph()->MarkDependsOnEmptyArrayProtoElements(); |
6939 } | 6845 } |
6940 | 6846 |
6941 return BuildUncheckedMonomorphicElementAccess( | 6847 return BuildUncheckedMonomorphicElementAccess( |
6942 object, key, val, | 6848 object, key, val, |
6943 mapcheck, map->instance_type() == JS_ARRAY_TYPE, | 6849 mapcheck, map->instance_type() == JS_ARRAY_TYPE, |
6944 map->elements_kind(), is_store, load_mode, store_mode); | 6850 map->elements_kind(), is_store, load_mode, store_mode); |
6945 } | 6851 } |
6946 | 6852 |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7058 Handle<Map> untransitionable_map; | 6964 Handle<Map> untransitionable_map; |
7059 HTransitionElementsKind* transition = NULL; | 6965 HTransitionElementsKind* transition = NULL; |
7060 for (int i = 0; i < maps->length(); ++i) { | 6966 for (int i = 0; i < maps->length(); ++i) { |
7061 Handle<Map> map = maps->at(i); | 6967 Handle<Map> map = maps->at(i); |
7062 ASSERT(map->IsMap()); | 6968 ASSERT(map->IsMap()); |
7063 if (!transition_target.at(i).is_null()) { | 6969 if (!transition_target.at(i).is_null()) { |
7064 ASSERT(Map::IsValidElementsTransition( | 6970 ASSERT(Map::IsValidElementsTransition( |
7065 map->elements_kind(), | 6971 map->elements_kind(), |
7066 transition_target.at(i)->elements_kind())); | 6972 transition_target.at(i)->elements_kind())); |
7067 HValue* context = environment()->LookupContext(); | 6973 HValue* context = environment()->LookupContext(); |
7068 transition = new(zone()) HTransitionElementsKind( | 6974 transition = Add<HTransitionElementsKind>(context, object, map, |
7069 context, object, map, transition_target.at(i)); | 6975 transition_target.at(i)); |
7070 AddInstruction(transition); | |
7071 } else { | 6976 } else { |
7072 type_todo[map->elements_kind()] = true; | 6977 type_todo[map->elements_kind()] = true; |
7073 if (IsExternalArrayElementsKind(map->elements_kind())) { | 6978 if (IsExternalArrayElementsKind(map->elements_kind())) { |
7074 todo_external_array = true; | 6979 todo_external_array = true; |
7075 } | 6980 } |
7076 num_untransitionable_maps++; | 6981 num_untransitionable_maps++; |
7077 untransitionable_map = map; | 6982 untransitionable_map = map; |
7078 } | 6983 } |
7079 } | 6984 } |
7080 | 6985 |
(...skipping 12 matching lines...) Expand all Loading... |
7093 } | 6998 } |
7094 *has_side_effects |= instr->HasObservableSideEffects(); | 6999 *has_side_effects |= instr->HasObservableSideEffects(); |
7095 if (position != RelocInfo::kNoPosition) instr->set_position(position); | 7000 if (position != RelocInfo::kNoPosition) instr->set_position(position); |
7096 return is_store ? NULL : instr; | 7001 return is_store ? NULL : instr; |
7097 } | 7002 } |
7098 | 7003 |
7099 HInstruction* checkspec = | 7004 HInstruction* checkspec = |
7100 AddInstruction(HCheckInstanceType::NewIsSpecObject(object, zone())); | 7005 AddInstruction(HCheckInstanceType::NewIsSpecObject(object, zone())); |
7101 HBasicBlock* join = graph()->CreateBasicBlock(); | 7006 HBasicBlock* join = graph()->CreateBasicBlock(); |
7102 | 7007 |
7103 HInstruction* elements_kind_instr = | 7008 HInstruction* elements_kind_instr = Add<HElementsKind>(object); |
7104 AddInstruction(new(zone()) HElementsKind(object)); | |
7105 HInstruction* elements = AddLoadElements(object, checkspec); | 7009 HInstruction* elements = AddLoadElements(object, checkspec); |
7106 HLoadExternalArrayPointer* external_elements = NULL; | 7010 HLoadExternalArrayPointer* external_elements = NULL; |
7107 HInstruction* checked_key = NULL; | 7011 HInstruction* checked_key = NULL; |
7108 | 7012 |
7109 // Generated code assumes that FAST_* and DICTIONARY_ELEMENTS ElementsKinds | 7013 // Generated code assumes that FAST_* and DICTIONARY_ELEMENTS ElementsKinds |
7110 // are handled before external arrays. | 7014 // are handled before external arrays. |
7111 STATIC_ASSERT(FAST_SMI_ELEMENTS < FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND); | 7015 STATIC_ASSERT(FAST_SMI_ELEMENTS < FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND); |
7112 STATIC_ASSERT(FAST_HOLEY_ELEMENTS < FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND); | 7016 STATIC_ASSERT(FAST_HOLEY_ELEMENTS < FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND); |
7113 STATIC_ASSERT(FAST_DOUBLE_ELEMENTS < FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND); | 7017 STATIC_ASSERT(FAST_DOUBLE_ELEMENTS < FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND); |
7114 STATIC_ASSERT(DICTIONARY_ELEMENTS < FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND); | 7018 STATIC_ASSERT(DICTIONARY_ELEMENTS < FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND); |
7115 | 7019 |
7116 for (ElementsKind elements_kind = FIRST_ELEMENTS_KIND; | 7020 for (ElementsKind elements_kind = FIRST_ELEMENTS_KIND; |
7117 elements_kind <= LAST_ELEMENTS_KIND; | 7021 elements_kind <= LAST_ELEMENTS_KIND; |
7118 elements_kind = ElementsKind(elements_kind + 1)) { | 7022 elements_kind = ElementsKind(elements_kind + 1)) { |
7119 // After having handled FAST_* and DICTIONARY_ELEMENTS, we need to add some | 7023 // After having handled FAST_* and DICTIONARY_ELEMENTS, we need to add some |
7120 // code that's executed for all external array cases. | 7024 // code that's executed for all external array cases. |
7121 STATIC_ASSERT(LAST_EXTERNAL_ARRAY_ELEMENTS_KIND == | 7025 STATIC_ASSERT(LAST_EXTERNAL_ARRAY_ELEMENTS_KIND == |
7122 LAST_ELEMENTS_KIND); | 7026 LAST_ELEMENTS_KIND); |
7123 if (elements_kind == FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND | 7027 if (elements_kind == FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND |
7124 && todo_external_array) { | 7028 && todo_external_array) { |
7125 HInstruction* length = | 7029 HInstruction* length = Add<HFixedArrayBaseLength>(elements); |
7126 AddInstruction(new(zone()) HFixedArrayBaseLength(elements)); | |
7127 checked_key = Add<HBoundsCheck>(key, length); | 7030 checked_key = Add<HBoundsCheck>(key, length); |
7128 external_elements = new(zone()) HLoadExternalArrayPointer(elements); | 7031 external_elements = Add<HLoadExternalArrayPointer>(elements); |
7129 AddInstruction(external_elements); | |
7130 } | 7032 } |
7131 if (type_todo[elements_kind]) { | 7033 if (type_todo[elements_kind]) { |
7132 HBasicBlock* if_true = graph()->CreateBasicBlock(); | 7034 HBasicBlock* if_true = graph()->CreateBasicBlock(); |
7133 HBasicBlock* if_false = graph()->CreateBasicBlock(); | 7035 HBasicBlock* if_false = graph()->CreateBasicBlock(); |
7134 HCompareConstantEqAndBranch* elements_kind_branch = | 7036 HCompareConstantEqAndBranch* elements_kind_branch = |
7135 new(zone()) HCompareConstantEqAndBranch( | 7037 new(zone()) HCompareConstantEqAndBranch( |
7136 elements_kind_instr, elements_kind, Token::EQ_STRICT); | 7038 elements_kind_instr, elements_kind, Token::EQ_STRICT); |
7137 elements_kind_branch->SetSuccessorAt(0, if_true); | 7039 elements_kind_branch->SetSuccessorAt(0, if_true); |
7138 elements_kind_branch->SetSuccessorAt(1, if_false); | 7040 elements_kind_branch->SetSuccessorAt(1, if_false); |
7139 current_block()->Finish(elements_kind_branch); | 7041 current_block()->Finish(elements_kind_branch); |
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7310 if (!environment()->Lookup(proxy->var())->CheckFlag(HValue::kIsArguments)) { | 7212 if (!environment()->Lookup(proxy->var())->CheckFlag(HValue::kIsArguments)) { |
7311 return false; | 7213 return false; |
7312 } | 7214 } |
7313 | 7215 |
7314 HInstruction* result = NULL; | 7216 HInstruction* result = NULL; |
7315 if (expr->key()->IsPropertyName()) { | 7217 if (expr->key()->IsPropertyName()) { |
7316 Handle<String> name = expr->key()->AsLiteral()->AsPropertyName(); | 7218 Handle<String> name = expr->key()->AsLiteral()->AsPropertyName(); |
7317 if (!name->IsOneByteEqualTo(STATIC_ASCII_VECTOR("length"))) return false; | 7219 if (!name->IsOneByteEqualTo(STATIC_ASCII_VECTOR("length"))) return false; |
7318 | 7220 |
7319 if (function_state()->outer() == NULL) { | 7221 if (function_state()->outer() == NULL) { |
7320 HInstruction* elements = AddInstruction( | 7222 HInstruction* elements = Add<HArgumentsElements>(false); |
7321 new(zone()) HArgumentsElements(false)); | |
7322 result = new(zone()) HArgumentsLength(elements); | 7223 result = new(zone()) HArgumentsLength(elements); |
7323 } else { | 7224 } else { |
7324 // Number of arguments without receiver. | 7225 // Number of arguments without receiver. |
7325 int argument_count = environment()-> | 7226 int argument_count = environment()-> |
7326 arguments_environment()->parameter_count() - 1; | 7227 arguments_environment()->parameter_count() - 1; |
7327 result = new(zone()) HConstant(argument_count); | 7228 result = new(zone()) HConstant(argument_count); |
7328 } | 7229 } |
7329 } else { | 7230 } else { |
7330 Push(graph()->GetArgumentsObject()); | 7231 Push(graph()->GetArgumentsObject()); |
7331 VisitForValue(expr->key()); | 7232 VisitForValue(expr->key()); |
7332 if (HasStackOverflow() || current_block() == NULL) return true; | 7233 if (HasStackOverflow() || current_block() == NULL) return true; |
7333 HValue* key = Pop(); | 7234 HValue* key = Pop(); |
7334 Drop(1); // Arguments object. | 7235 Drop(1); // Arguments object. |
7335 if (function_state()->outer() == NULL) { | 7236 if (function_state()->outer() == NULL) { |
7336 HInstruction* elements = AddInstruction( | 7237 HInstruction* elements = Add<HArgumentsElements>(false); |
7337 new(zone()) HArgumentsElements(false)); | 7238 HInstruction* length = Add<HArgumentsLength>(elements); |
7338 HInstruction* length = AddInstruction( | |
7339 new(zone()) HArgumentsLength(elements)); | |
7340 HInstruction* checked_key = Add<HBoundsCheck>(key, length); | 7239 HInstruction* checked_key = Add<HBoundsCheck>(key, length); |
7341 result = new(zone()) HAccessArgumentsAt(elements, length, checked_key); | 7240 result = new(zone()) HAccessArgumentsAt(elements, length, checked_key); |
7342 } else { | 7241 } else { |
7343 EnsureArgumentsArePushedForAccess(); | 7242 EnsureArgumentsArePushedForAccess(); |
7344 | 7243 |
7345 // Number of arguments without receiver. | 7244 // Number of arguments without receiver. |
7346 HInstruction* elements = function_state()->arguments_elements(); | 7245 HInstruction* elements = function_state()->arguments_elements(); |
7347 int argument_count = environment()-> | 7246 int argument_count = environment()-> |
7348 arguments_environment()->parameter_count() - 1; | 7247 arguments_environment()->parameter_count() - 1; |
7349 HInstruction* length = AddInstruction(new(zone()) HConstant( | 7248 HInstruction* length = Add<HConstant>(argument_count); |
7350 argument_count)); | |
7351 HInstruction* checked_key = Add<HBoundsCheck>(key, length); | 7249 HInstruction* checked_key = Add<HBoundsCheck>(key, length); |
7352 result = new(zone()) HAccessArgumentsAt(elements, length, checked_key); | 7250 result = new(zone()) HAccessArgumentsAt(elements, length, checked_key); |
7353 } | 7251 } |
7354 } | 7252 } |
7355 ast_context()->ReturnInstruction(result, expr->id()); | 7253 ast_context()->ReturnInstruction(result, expr->id()); |
7356 return true; | 7254 return true; |
7357 } | 7255 } |
7358 | 7256 |
7359 | 7257 |
7360 void HOptimizedGraphBuilder::VisitProperty(Property* expr) { | 7258 void HOptimizedGraphBuilder::VisitProperty(Property* expr) { |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7400 } else if (object->HasMonomorphicJSObjectType()) { | 7298 } else if (object->HasMonomorphicJSObjectType()) { |
7401 map = object->GetMonomorphicJSObjectMap(); | 7299 map = object->GetMonomorphicJSObjectMap(); |
7402 monomorphic = !map->is_dictionary_map(); | 7300 monomorphic = !map->is_dictionary_map(); |
7403 } | 7301 } |
7404 if (monomorphic) { | 7302 if (monomorphic) { |
7405 Handle<JSFunction> getter; | 7303 Handle<JSFunction> getter; |
7406 Handle<JSObject> holder; | 7304 Handle<JSObject> holder; |
7407 if (LookupGetter(map, name, &getter, &holder)) { | 7305 if (LookupGetter(map, name, &getter, &holder)) { |
7408 AddCheckConstantFunction(holder, Top(), map); | 7306 AddCheckConstantFunction(holder, Top(), map); |
7409 if (FLAG_inline_accessors && TryInlineGetter(getter, expr)) return; | 7307 if (FLAG_inline_accessors && TryInlineGetter(getter, expr)) return; |
7410 AddInstruction(new(zone()) HPushArgument(Pop())); | 7308 Add<HPushArgument>(Pop()); |
7411 instr = new(zone()) HCallConstantFunction(getter, 1); | 7309 instr = new(zone()) HCallConstantFunction(getter, 1); |
7412 } else { | 7310 } else { |
7413 instr = BuildLoadNamedMonomorphic(Pop(), name, expr, map); | 7311 instr = BuildLoadNamedMonomorphic(Pop(), name, expr, map); |
7414 } | 7312 } |
7415 } else if (types != NULL && types->length() > 1) { | 7313 } else if (types != NULL && types->length() > 1) { |
7416 return HandlePolymorphicLoadNamedField(expr, Pop(), types, name); | 7314 return HandlePolymorphicLoadNamedField(expr, Pop(), types, name); |
7417 } else { | 7315 } else { |
7418 instr = BuildLoadNamedGeneric(Pop(), name, expr); | 7316 instr = BuildLoadNamedGeneric(Pop(), name, expr); |
7419 } | 7317 } |
7420 | 7318 |
(...skipping 21 matching lines...) Expand all Loading... |
7442 } | 7340 } |
7443 instr->set_position(expr->position()); | 7341 instr->set_position(expr->position()); |
7444 return ast_context()->ReturnInstruction(instr, expr->id()); | 7342 return ast_context()->ReturnInstruction(instr, expr->id()); |
7445 } | 7343 } |
7446 | 7344 |
7447 | 7345 |
7448 void HOptimizedGraphBuilder::AddCheckPrototypeMaps(Handle<JSObject> holder, | 7346 void HOptimizedGraphBuilder::AddCheckPrototypeMaps(Handle<JSObject> holder, |
7449 Handle<Map> receiver_map) { | 7347 Handle<Map> receiver_map) { |
7450 if (!holder.is_null()) { | 7348 if (!holder.is_null()) { |
7451 Handle<JSObject> prototype(JSObject::cast(receiver_map->prototype())); | 7349 Handle<JSObject> prototype(JSObject::cast(receiver_map->prototype())); |
7452 AddInstruction(new(zone()) HCheckPrototypeMaps( | 7350 Add<HCheckPrototypeMaps>(prototype, holder, zone(), top_info()); |
7453 prototype, holder, zone(), top_info())); | |
7454 } | 7351 } |
7455 } | 7352 } |
7456 | 7353 |
7457 | 7354 |
7458 void HOptimizedGraphBuilder::AddCheckConstantFunction( | 7355 void HOptimizedGraphBuilder::AddCheckConstantFunction( |
7459 Handle<JSObject> holder, | 7356 Handle<JSObject> holder, |
7460 HValue* receiver, | 7357 HValue* receiver, |
7461 Handle<Map> receiver_map) { | 7358 Handle<Map> receiver_map) { |
7462 // Constant functions have the nice property that the map will change if they | 7359 // Constant functions have the nice property that the map will change if they |
7463 // are overwritten. Therefore it is enough to check the map of the holder and | 7360 // are overwritten. Therefore it is enough to check the map of the holder and |
(...skipping 406 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7870 function, | 7767 function, |
7871 undefined, | 7768 undefined, |
7872 function_state()->inlining_kind(), | 7769 function_state()->inlining_kind(), |
7873 undefined_receiver); | 7770 undefined_receiver); |
7874 #ifdef V8_TARGET_ARCH_IA32 | 7771 #ifdef V8_TARGET_ARCH_IA32 |
7875 // IA32 only, overwrite the caller's context in the deoptimization | 7772 // IA32 only, overwrite the caller's context in the deoptimization |
7876 // environment with the correct one. | 7773 // environment with the correct one. |
7877 // | 7774 // |
7878 // TODO(kmillikin): implement the same inlining on other platforms so we | 7775 // TODO(kmillikin): implement the same inlining on other platforms so we |
7879 // can remove the unsightly ifdefs in this function. | 7776 // can remove the unsightly ifdefs in this function. |
7880 HConstant* context = | 7777 HConstant* context = Add<HConstant>(Handle<Context>(target->context())); |
7881 new(zone()) HConstant(Handle<Context>(target->context())); | |
7882 AddInstruction(context); | |
7883 inner_env->BindContext(context); | 7778 inner_env->BindContext(context); |
7884 #endif | 7779 #endif |
7885 | 7780 |
7886 AddSimulate(return_id); | 7781 AddSimulate(return_id); |
7887 current_block()->UpdateEnvironment(inner_env); | 7782 current_block()->UpdateEnvironment(inner_env); |
7888 HArgumentsObject* arguments_object = NULL; | 7783 HArgumentsObject* arguments_object = NULL; |
7889 | 7784 |
7890 // If the function uses arguments object create and bind one, also copy | 7785 // If the function uses arguments object create and bind one, also copy |
7891 // current arguments values to use them for materialization. | 7786 // current arguments values to use them for materialization. |
7892 if (function->scope()->arguments() != NULL) { | 7787 if (function->scope()->arguments() != NULL) { |
7893 ASSERT(function->scope()->arguments()->IsStackAllocated()); | 7788 ASSERT(function->scope()->arguments()->IsStackAllocated()); |
7894 HEnvironment* arguments_env = inner_env->arguments_environment(); | 7789 HEnvironment* arguments_env = inner_env->arguments_environment(); |
7895 int arguments_count = arguments_env->parameter_count(); | 7790 int arguments_count = arguments_env->parameter_count(); |
7896 arguments_object = new(zone()) HArgumentsObject(arguments_count, zone()); | 7791 arguments_object = Add<HArgumentsObject>(arguments_count, zone()); |
7897 inner_env->Bind(function->scope()->arguments(), arguments_object); | 7792 inner_env->Bind(function->scope()->arguments(), arguments_object); |
7898 for (int i = 0; i < arguments_count; i++) { | 7793 for (int i = 0; i < arguments_count; i++) { |
7899 arguments_object->AddArgument(arguments_env->Lookup(i), zone()); | 7794 arguments_object->AddArgument(arguments_env->Lookup(i), zone()); |
7900 } | 7795 } |
7901 AddInstruction(arguments_object); | |
7902 } | 7796 } |
7903 | 7797 |
7904 HEnterInlined* enter_inlined = | 7798 HEnterInlined* enter_inlined = |
7905 new(zone()) HEnterInlined(target, | 7799 Add<HEnterInlined>(target, arguments_count, function, |
7906 arguments_count, | 7800 function_state()->inlining_kind(), |
7907 function, | 7801 function->scope()->arguments(), |
7908 function_state()->inlining_kind(), | 7802 arguments_object, undefined_receiver, zone()); |
7909 function->scope()->arguments(), | |
7910 arguments_object, | |
7911 undefined_receiver, | |
7912 zone()); | |
7913 function_state()->set_entry(enter_inlined); | 7803 function_state()->set_entry(enter_inlined); |
7914 AddInstruction(enter_inlined); | |
7915 | 7804 |
7916 VisitDeclarations(target_info.scope()->declarations()); | 7805 VisitDeclarations(target_info.scope()->declarations()); |
7917 VisitStatements(function->body()); | 7806 VisitStatements(function->body()); |
7918 if (HasStackOverflow()) { | 7807 if (HasStackOverflow()) { |
7919 // Bail out if the inline function did, as we cannot residualize a call | 7808 // Bail out if the inline function did, as we cannot residualize a call |
7920 // instead. | 7809 // instead. |
7921 TraceInline(target, caller, "inline graph construction failed"); | 7810 TraceInline(target, caller, "inline graph construction failed"); |
7922 target_shared->DisableOptimization("inlining bailed out"); | 7811 target_shared->DisableOptimization("inlining bailed out"); |
7923 inline_bailout_ = true; | 7812 inline_bailout_ = true; |
7924 delete target_state; | 7813 delete target_state; |
(...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8142 BuiltinFunctionId id = expr->target()->shared()->builtin_function_id(); | 8031 BuiltinFunctionId id = expr->target()->shared()->builtin_function_id(); |
8143 int argument_count = expr->arguments()->length() + 1; // Plus receiver. | 8032 int argument_count = expr->arguments()->length() + 1; // Plus receiver. |
8144 switch (id) { | 8033 switch (id) { |
8145 case kStringCharCodeAt: | 8034 case kStringCharCodeAt: |
8146 case kStringCharAt: | 8035 case kStringCharAt: |
8147 if (argument_count == 2 && check_type == STRING_CHECK) { | 8036 if (argument_count == 2 && check_type == STRING_CHECK) { |
8148 HValue* index = Pop(); | 8037 HValue* index = Pop(); |
8149 HValue* string = Pop(); | 8038 HValue* string = Pop(); |
8150 HValue* context = environment()->LookupContext(); | 8039 HValue* context = environment()->LookupContext(); |
8151 ASSERT(!expr->holder().is_null()); | 8040 ASSERT(!expr->holder().is_null()); |
8152 AddInstruction(new(zone()) HCheckPrototypeMaps( | 8041 Add<HCheckPrototypeMaps>(Call::GetPrototypeForPrimitiveCheck( |
8153 Call::GetPrototypeForPrimitiveCheck(STRING_CHECK, | 8042 STRING_CHECK, expr->holder()->GetIsolate()), |
8154 expr->holder()->GetIsolate()), | 8043 expr->holder(), zone(), top_info()); |
8155 expr->holder(), | |
8156 zone(), | |
8157 top_info())); | |
8158 HInstruction* char_code = | 8044 HInstruction* char_code = |
8159 BuildStringCharCodeAt(context, string, index); | 8045 BuildStringCharCodeAt(context, string, index); |
8160 if (id == kStringCharCodeAt) { | 8046 if (id == kStringCharCodeAt) { |
8161 ast_context()->ReturnInstruction(char_code, expr->id()); | 8047 ast_context()->ReturnInstruction(char_code, expr->id()); |
8162 return true; | 8048 return true; |
8163 } | 8049 } |
8164 AddInstruction(char_code); | 8050 AddInstruction(char_code); |
8165 HInstruction* result = | 8051 HInstruction* result = |
8166 HStringCharFromCode::New(zone(), context, char_code); | 8052 HStringCharFromCode::New(zone(), context, char_code); |
8167 ast_context()->ReturnInstruction(result, expr->id()); | 8053 ast_context()->ReturnInstruction(result, expr->id()); |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8238 } | 8124 } |
8239 ast_context()->ReturnInstruction(result, expr->id()); | 8125 ast_context()->ReturnInstruction(result, expr->id()); |
8240 return true; | 8126 return true; |
8241 } | 8127 } |
8242 break; | 8128 break; |
8243 case kMathRandom: | 8129 case kMathRandom: |
8244 if (argument_count == 1 && check_type == RECEIVER_MAP_CHECK) { | 8130 if (argument_count == 1 && check_type == RECEIVER_MAP_CHECK) { |
8245 AddCheckConstantFunction(expr->holder(), receiver, receiver_map); | 8131 AddCheckConstantFunction(expr->holder(), receiver, receiver_map); |
8246 Drop(1); // Receiver. | 8132 Drop(1); // Receiver. |
8247 HValue* context = environment()->LookupContext(); | 8133 HValue* context = environment()->LookupContext(); |
8248 HGlobalObject* global_object = new(zone()) HGlobalObject(context); | 8134 HGlobalObject* global_object = Add<HGlobalObject>(context); |
8249 AddInstruction(global_object); | |
8250 HRandom* result = new(zone()) HRandom(global_object); | 8135 HRandom* result = new(zone()) HRandom(global_object); |
8251 ast_context()->ReturnInstruction(result, expr->id()); | 8136 ast_context()->ReturnInstruction(result, expr->id()); |
8252 return true; | 8137 return true; |
8253 } | 8138 } |
8254 break; | 8139 break; |
8255 case kMathMax: | 8140 case kMathMax: |
8256 case kMathMin: | 8141 case kMathMin: |
8257 if (argument_count == 3 && check_type == RECEIVER_MAP_CHECK) { | 8142 if (argument_count == 3 && check_type == RECEIVER_MAP_CHECK) { |
8258 AddCheckConstantFunction(expr->holder(), receiver, receiver_map); | 8143 AddCheckConstantFunction(expr->holder(), receiver, receiver_map); |
8259 HValue* right = Pop(); | 8144 HValue* right = Pop(); |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8318 if (HasStackOverflow() || current_block() == NULL) return true; | 8203 if (HasStackOverflow() || current_block() == NULL) return true; |
8319 HValue* function = Top(); | 8204 HValue* function = Top(); |
8320 AddCheckConstantFunction(expr->holder(), function, function_map); | 8205 AddCheckConstantFunction(expr->holder(), function, function_map); |
8321 Drop(1); | 8206 Drop(1); |
8322 | 8207 |
8323 VisitForValue(args->at(0)); | 8208 VisitForValue(args->at(0)); |
8324 if (HasStackOverflow() || current_block() == NULL) return true; | 8209 if (HasStackOverflow() || current_block() == NULL) return true; |
8325 HValue* receiver = Pop(); | 8210 HValue* receiver = Pop(); |
8326 | 8211 |
8327 if (function_state()->outer() == NULL) { | 8212 if (function_state()->outer() == NULL) { |
8328 HInstruction* elements = AddInstruction( | 8213 HInstruction* elements = Add<HArgumentsElements>(false); |
8329 new(zone()) HArgumentsElements(false)); | 8214 HInstruction* length = Add<HArgumentsLength>(elements); |
8330 HInstruction* length = | 8215 HValue* wrapped_receiver = Add<HWrapReceiver>(receiver, function); |
8331 AddInstruction(new(zone()) HArgumentsLength(elements)); | |
8332 HValue* wrapped_receiver = | |
8333 AddInstruction(new(zone()) HWrapReceiver(receiver, function)); | |
8334 HInstruction* result = | 8216 HInstruction* result = |
8335 new(zone()) HApplyArguments(function, | 8217 new(zone()) HApplyArguments(function, |
8336 wrapped_receiver, | 8218 wrapped_receiver, |
8337 length, | 8219 length, |
8338 elements); | 8220 elements); |
8339 result->set_position(expr->position()); | 8221 result->set_position(expr->position()); |
8340 ast_context()->ReturnInstruction(result, expr->id()); | 8222 ast_context()->ReturnInstruction(result, expr->id()); |
8341 return true; | 8223 return true; |
8342 } else { | 8224 } else { |
8343 // We are inside inlined function and we know exactly what is inside | 8225 // We are inside inlined function and we know exactly what is inside |
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8548 if (known_global_function) { | 8430 if (known_global_function) { |
8549 // Push the global object instead of the global receiver because | 8431 // Push the global object instead of the global receiver because |
8550 // code generated by the full code generator expects it. | 8432 // code generated by the full code generator expects it. |
8551 HValue* context = environment()->LookupContext(); | 8433 HValue* context = environment()->LookupContext(); |
8552 HGlobalObject* global_object = new(zone()) HGlobalObject(context); | 8434 HGlobalObject* global_object = new(zone()) HGlobalObject(context); |
8553 PushAndAdd(global_object); | 8435 PushAndAdd(global_object); |
8554 CHECK_ALIVE(VisitExpressions(expr->arguments())); | 8436 CHECK_ALIVE(VisitExpressions(expr->arguments())); |
8555 | 8437 |
8556 CHECK_ALIVE(VisitForValue(expr->expression())); | 8438 CHECK_ALIVE(VisitForValue(expr->expression())); |
8557 HValue* function = Pop(); | 8439 HValue* function = Pop(); |
8558 AddInstruction(new(zone()) HCheckFunction(function, expr->target())); | 8440 Add<HCheckFunction>(function, expr->target()); |
8559 | 8441 |
8560 // Replace the global object with the global receiver. | 8442 // Replace the global object with the global receiver. |
8561 HGlobalReceiver* global_receiver = | 8443 HGlobalReceiver* global_receiver = Add<HGlobalReceiver>(global_object); |
8562 new(zone()) HGlobalReceiver(global_object); | |
8563 // Index of the receiver from the top of the expression stack. | 8444 // Index of the receiver from the top of the expression stack. |
8564 const int receiver_index = argument_count - 1; | 8445 const int receiver_index = argument_count - 1; |
8565 AddInstruction(global_receiver); | |
8566 ASSERT(environment()->ExpressionStackAt(receiver_index)-> | 8446 ASSERT(environment()->ExpressionStackAt(receiver_index)-> |
8567 IsGlobalObject()); | 8447 IsGlobalObject()); |
8568 environment()->SetExpressionStackAt(receiver_index, global_receiver); | 8448 environment()->SetExpressionStackAt(receiver_index, global_receiver); |
8569 | 8449 |
8570 if (TryInlineBuiltinFunctionCall(expr, false)) { // Nothing to drop. | 8450 if (TryInlineBuiltinFunctionCall(expr, false)) { // Nothing to drop. |
8571 if (FLAG_trace_inlining) { | 8451 if (FLAG_trace_inlining) { |
8572 PrintF("Inlining builtin "); | 8452 PrintF("Inlining builtin "); |
8573 expr->target()->ShortPrint(); | 8453 expr->target()->ShortPrint(); |
8574 PrintF("\n"); | 8454 PrintF("\n"); |
8575 } | 8455 } |
(...skipping 10 matching lines...) Expand all Loading... |
8586 // because it is likely to generate better code. | 8466 // because it is likely to generate better code. |
8587 HValue* context = environment()->LookupContext(); | 8467 HValue* context = environment()->LookupContext(); |
8588 call = PreProcessCall( | 8468 call = PreProcessCall( |
8589 new(zone()) HCallNamed(context, var->name(), argument_count)); | 8469 new(zone()) HCallNamed(context, var->name(), argument_count)); |
8590 } else { | 8470 } else { |
8591 call = PreProcessCall(new(zone()) HCallKnownGlobal(expr->target(), | 8471 call = PreProcessCall(new(zone()) HCallKnownGlobal(expr->target(), |
8592 argument_count)); | 8472 argument_count)); |
8593 } | 8473 } |
8594 } else { | 8474 } else { |
8595 HValue* context = environment()->LookupContext(); | 8475 HValue* context = environment()->LookupContext(); |
8596 HGlobalObject* receiver = new(zone()) HGlobalObject(context); | 8476 HGlobalObject* receiver = Add<HGlobalObject>(context); |
8597 AddInstruction(receiver); | |
8598 PushAndAdd(new(zone()) HPushArgument(receiver)); | 8477 PushAndAdd(new(zone()) HPushArgument(receiver)); |
8599 CHECK_ALIVE(VisitArgumentList(expr->arguments())); | 8478 CHECK_ALIVE(VisitArgumentList(expr->arguments())); |
8600 | 8479 |
8601 call = new(zone()) HCallGlobal(context, var->name(), argument_count); | 8480 call = new(zone()) HCallGlobal(context, var->name(), argument_count); |
8602 Drop(argument_count); | 8481 Drop(argument_count); |
8603 } | 8482 } |
8604 | 8483 |
8605 } else if (expr->IsMonomorphic()) { | 8484 } else if (expr->IsMonomorphic()) { |
8606 // The function is on the stack in the unoptimized code during | 8485 // The function is on the stack in the unoptimized code during |
8607 // evaluation of the arguments. | 8486 // evaluation of the arguments. |
8608 CHECK_ALIVE(VisitForValue(expr->expression())); | 8487 CHECK_ALIVE(VisitForValue(expr->expression())); |
8609 HValue* function = Top(); | 8488 HValue* function = Top(); |
8610 HValue* context = environment()->LookupContext(); | 8489 HValue* context = environment()->LookupContext(); |
8611 HGlobalObject* global = new(zone()) HGlobalObject(context); | 8490 HGlobalObject* global = Add<HGlobalObject>(context); |
8612 AddInstruction(global); | |
8613 HGlobalReceiver* receiver = new(zone()) HGlobalReceiver(global); | 8491 HGlobalReceiver* receiver = new(zone()) HGlobalReceiver(global); |
8614 PushAndAdd(receiver); | 8492 PushAndAdd(receiver); |
8615 CHECK_ALIVE(VisitExpressions(expr->arguments())); | 8493 CHECK_ALIVE(VisitExpressions(expr->arguments())); |
8616 AddInstruction(new(zone()) HCheckFunction(function, expr->target())); | 8494 Add<HCheckFunction>(function, expr->target()); |
8617 | 8495 |
8618 if (TryInlineBuiltinFunctionCall(expr, true)) { // Drop the function. | 8496 if (TryInlineBuiltinFunctionCall(expr, true)) { // Drop the function. |
8619 if (FLAG_trace_inlining) { | 8497 if (FLAG_trace_inlining) { |
8620 PrintF("Inlining builtin "); | 8498 PrintF("Inlining builtin "); |
8621 expr->target()->ShortPrint(); | 8499 expr->target()->ShortPrint(); |
8622 PrintF("\n"); | 8500 PrintF("\n"); |
8623 } | 8501 } |
8624 return; | 8502 return; |
8625 } | 8503 } |
8626 | 8504 |
8627 if (TryInlineCall(expr, true)) { // Drop function from environment. | 8505 if (TryInlineCall(expr, true)) { // Drop function from environment. |
8628 return; | 8506 return; |
8629 } else { | 8507 } else { |
8630 call = PreProcessCall( | 8508 call = PreProcessCall( |
8631 new(zone()) HInvokeFunction(context, | 8509 new(zone()) HInvokeFunction(context, |
8632 function, | 8510 function, |
8633 expr->target(), | 8511 expr->target(), |
8634 argument_count)); | 8512 argument_count)); |
8635 Drop(1); // The function. | 8513 Drop(1); // The function. |
8636 } | 8514 } |
8637 | 8515 |
8638 } else { | 8516 } else { |
8639 CHECK_ALIVE(VisitForValue(expr->expression())); | 8517 CHECK_ALIVE(VisitForValue(expr->expression())); |
8640 HValue* function = Top(); | 8518 HValue* function = Top(); |
8641 HValue* context = environment()->LookupContext(); | 8519 HValue* context = environment()->LookupContext(); |
8642 HGlobalObject* global_object = new(zone()) HGlobalObject(context); | 8520 HGlobalObject* global_object = Add<HGlobalObject>(context); |
8643 AddInstruction(global_object); | 8521 HGlobalReceiver* receiver = Add<HGlobalReceiver>(global_object); |
8644 HGlobalReceiver* receiver = new(zone()) HGlobalReceiver(global_object); | |
8645 AddInstruction(receiver); | |
8646 PushAndAdd(new(zone()) HPushArgument(receiver)); | 8522 PushAndAdd(new(zone()) HPushArgument(receiver)); |
8647 CHECK_ALIVE(VisitArgumentList(expr->arguments())); | 8523 CHECK_ALIVE(VisitArgumentList(expr->arguments())); |
8648 | 8524 |
8649 call = new(zone()) HCallFunction(context, function, argument_count); | 8525 call = new(zone()) HCallFunction(context, function, argument_count); |
8650 Drop(argument_count + 1); | 8526 Drop(argument_count + 1); |
8651 } | 8527 } |
8652 } | 8528 } |
8653 | 8529 |
8654 call->set_position(expr->position()); | 8530 call->set_position(expr->position()); |
8655 return ast_context()->ReturnInstruction(call, expr->id()); | 8531 return ast_context()->ReturnInstruction(call, expr->id()); |
(...skipping 17 matching lines...) Expand all Loading... |
8673 | 8549 |
8674 if (FLAG_inline_construct && | 8550 if (FLAG_inline_construct && |
8675 expr->IsMonomorphic() && | 8551 expr->IsMonomorphic() && |
8676 IsAllocationInlineable(expr->target())) { | 8552 IsAllocationInlineable(expr->target())) { |
8677 // The constructor function is on the stack in the unoptimized code | 8553 // The constructor function is on the stack in the unoptimized code |
8678 // during evaluation of the arguments. | 8554 // during evaluation of the arguments. |
8679 CHECK_ALIVE(VisitForValue(expr->expression())); | 8555 CHECK_ALIVE(VisitForValue(expr->expression())); |
8680 HValue* function = Top(); | 8556 HValue* function = Top(); |
8681 CHECK_ALIVE(VisitExpressions(expr->arguments())); | 8557 CHECK_ALIVE(VisitExpressions(expr->arguments())); |
8682 Handle<JSFunction> constructor = expr->target(); | 8558 Handle<JSFunction> constructor = expr->target(); |
8683 HValue* check = AddInstruction( | 8559 HValue* check = Add<HCheckFunction>(function, constructor); |
8684 new(zone()) HCheckFunction(function, constructor)); | |
8685 | 8560 |
8686 // Force completion of inobject slack tracking before generating | 8561 // Force completion of inobject slack tracking before generating |
8687 // allocation code to finalize instance size. | 8562 // allocation code to finalize instance size. |
8688 if (constructor->shared()->IsInobjectSlackTrackingInProgress()) { | 8563 if (constructor->shared()->IsInobjectSlackTrackingInProgress()) { |
8689 constructor->shared()->CompleteInobjectSlackTracking(); | 8564 constructor->shared()->CompleteInobjectSlackTracking(); |
8690 } | 8565 } |
8691 | 8566 |
8692 // Replace the constructor function with a newly allocated receiver. | 8567 // Replace the constructor function with a newly allocated receiver. |
8693 HInstruction* receiver = new(zone()) HAllocateObject(context, constructor); | 8568 HInstruction* receiver = Add<HAllocateObject>(context, constructor); |
8694 // Index of the receiver from the top of the expression stack. | 8569 // Index of the receiver from the top of the expression stack. |
8695 const int receiver_index = argument_count - 1; | 8570 const int receiver_index = argument_count - 1; |
8696 AddInstruction(receiver); | |
8697 ASSERT(environment()->ExpressionStackAt(receiver_index) == function); | 8571 ASSERT(environment()->ExpressionStackAt(receiver_index) == function); |
8698 environment()->SetExpressionStackAt(receiver_index, receiver); | 8572 environment()->SetExpressionStackAt(receiver_index, receiver); |
8699 | 8573 |
8700 if (TryInlineConstruct(expr, receiver)) return; | 8574 if (TryInlineConstruct(expr, receiver)) return; |
8701 | 8575 |
8702 // TODO(mstarzinger): For now we remove the previous HAllocateObject and | 8576 // TODO(mstarzinger): For now we remove the previous HAllocateObject and |
8703 // add HPushArgument for the arguments in case inlining failed. What we | 8577 // add HPushArgument for the arguments in case inlining failed. What we |
8704 // actually should do is emit HInvokeFunction on the constructor instead | 8578 // actually should do is emit HInvokeFunction on the constructor instead |
8705 // of using HCallNew as a fallback. | 8579 // of using HCallNew as a fallback. |
8706 receiver->DeleteAndReplaceWith(NULL); | 8580 receiver->DeleteAndReplaceWith(NULL); |
8707 check->DeleteAndReplaceWith(NULL); | 8581 check->DeleteAndReplaceWith(NULL); |
8708 environment()->SetExpressionStackAt(receiver_index, function); | 8582 environment()->SetExpressionStackAt(receiver_index, function); |
8709 HInstruction* call = PreProcessCall( | 8583 HInstruction* call = PreProcessCall( |
8710 new(zone()) HCallNew(context, function, argument_count)); | 8584 new(zone()) HCallNew(context, function, argument_count)); |
8711 call->set_position(expr->position()); | 8585 call->set_position(expr->position()); |
8712 return ast_context()->ReturnInstruction(call, expr->id()); | 8586 return ast_context()->ReturnInstruction(call, expr->id()); |
8713 } else { | 8587 } else { |
8714 // The constructor function is both an operand to the instruction and an | 8588 // The constructor function is both an operand to the instruction and an |
8715 // argument to the construct call. | 8589 // argument to the construct call. |
8716 Handle<JSFunction> array_function( | 8590 Handle<JSFunction> array_function( |
8717 isolate()->global_context()->array_function(), isolate()); | 8591 isolate()->global_context()->array_function(), isolate()); |
8718 CHECK_ALIVE(VisitArgument(expr->expression())); | 8592 CHECK_ALIVE(VisitArgument(expr->expression())); |
8719 HValue* constructor = HPushArgument::cast(Top())->argument(); | 8593 HValue* constructor = HPushArgument::cast(Top())->argument(); |
8720 CHECK_ALIVE(VisitArgumentList(expr->arguments())); | 8594 CHECK_ALIVE(VisitArgumentList(expr->arguments())); |
8721 HCallNew* call; | 8595 HCallNew* call; |
8722 if (expr->target().is_identical_to(array_function)) { | 8596 if (expr->target().is_identical_to(array_function)) { |
8723 Handle<Cell> cell = expr->allocation_info_cell(); | 8597 Handle<Cell> cell = expr->allocation_info_cell(); |
8724 AddInstruction(new(zone()) HCheckFunction(constructor, array_function)); | 8598 Add<HCheckFunction>(constructor, array_function); |
8725 call = new(zone()) HCallNewArray(context, constructor, argument_count, | 8599 call = new(zone()) HCallNewArray(context, constructor, argument_count, |
8726 cell, expr->elements_kind()); | 8600 cell, expr->elements_kind()); |
8727 } else { | 8601 } else { |
8728 call = new(zone()) HCallNew(context, constructor, argument_count); | 8602 call = new(zone()) HCallNew(context, constructor, argument_count); |
8729 } | 8603 } |
8730 Drop(argument_count); | 8604 Drop(argument_count); |
8731 call->set_position(expr->position()); | 8605 call->set_position(expr->position()); |
8732 return ast_context()->ReturnInstruction(call, expr->id()); | 8606 return ast_context()->ReturnInstruction(call, expr->id()); |
8733 } | 8607 } |
8734 } | 8608 } |
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8937 Representation rep = ToRepresentation(info); | 8811 Representation rep = ToRepresentation(info); |
8938 if (rep.IsNone() || rep.IsTagged()) { | 8812 if (rep.IsNone() || rep.IsTagged()) { |
8939 rep = Representation::Smi(); | 8813 rep = Representation::Smi(); |
8940 } | 8814 } |
8941 | 8815 |
8942 if (returns_original_input) { | 8816 if (returns_original_input) { |
8943 // We need an explicit HValue representing ToNumber(input). The | 8817 // We need an explicit HValue representing ToNumber(input). The |
8944 // actual HChange instruction we need is (sometimes) added in a later | 8818 // actual HChange instruction we need is (sometimes) added in a later |
8945 // phase, so it is not available now to be used as an input to HAdd and | 8819 // phase, so it is not available now to be used as an input to HAdd and |
8946 // as the return value. | 8820 // as the return value. |
8947 HInstruction* number_input = new(zone()) HForceRepresentation(Pop(), rep); | 8821 HInstruction* number_input = Add<HForceRepresentation>(Pop(), rep); |
8948 if (!rep.IsDouble()) { | 8822 if (!rep.IsDouble()) { |
8949 number_input->SetFlag(HInstruction::kFlexibleRepresentation); | 8823 number_input->SetFlag(HInstruction::kFlexibleRepresentation); |
8950 number_input->SetFlag(HInstruction::kCannotBeTagged); | 8824 number_input->SetFlag(HInstruction::kCannotBeTagged); |
8951 } | 8825 } |
8952 AddInstruction(number_input); | |
8953 Push(number_input); | 8826 Push(number_input); |
8954 } | 8827 } |
8955 | 8828 |
8956 // The addition has no side effects, so we do not need | 8829 // The addition has no side effects, so we do not need |
8957 // to simulate the expression stack after this instruction. | 8830 // to simulate the expression stack after this instruction. |
8958 // Any later failures deopt to the load of the input or earlier. | 8831 // Any later failures deopt to the load of the input or earlier. |
8959 HConstant* delta = (expr->op() == Token::INC) | 8832 HConstant* delta = (expr->op() == Token::INC) |
8960 ? graph()->GetConstant1() | 8833 ? graph()->GetConstant1() |
8961 : graph()->GetConstantMinus1(); | 8834 : graph()->GetConstantMinus1(); |
8962 HValue* context = environment()->LookupContext(); | 8835 HValue* context = environment()->LookupContext(); |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9025 for (int i = 0; i < count; ++i) { | 8898 for (int i = 0; i < count; ++i) { |
9026 if (var == current_info()->scope()->parameter(i)) { | 8899 if (var == current_info()->scope()->parameter(i)) { |
9027 return Bailout("assignment to parameter in arguments object"); | 8900 return Bailout("assignment to parameter in arguments object"); |
9028 } | 8901 } |
9029 } | 8902 } |
9030 } | 8903 } |
9031 | 8904 |
9032 HValue* context = BuildContextChainWalk(var); | 8905 HValue* context = BuildContextChainWalk(var); |
9033 HStoreContextSlot::Mode mode = IsLexicalVariableMode(var->mode()) | 8906 HStoreContextSlot::Mode mode = IsLexicalVariableMode(var->mode()) |
9034 ? HStoreContextSlot::kCheckDeoptimize : HStoreContextSlot::kNoCheck; | 8907 ? HStoreContextSlot::kCheckDeoptimize : HStoreContextSlot::kNoCheck; |
9035 HStoreContextSlot* instr = | 8908 HStoreContextSlot* instr = Add<HStoreContextSlot>(context, var->index(), |
9036 new(zone()) HStoreContextSlot(context, var->index(), mode, after); | 8909 mode, after); |
9037 AddInstruction(instr); | |
9038 if (instr->HasObservableSideEffects()) { | 8910 if (instr->HasObservableSideEffects()) { |
9039 AddSimulate(expr->AssignmentId(), REMOVABLE_SIMULATE); | 8911 AddSimulate(expr->AssignmentId(), REMOVABLE_SIMULATE); |
9040 } | 8912 } |
9041 break; | 8913 break; |
9042 } | 8914 } |
9043 | 8915 |
9044 case Variable::LOOKUP: | 8916 case Variable::LOOKUP: |
9045 return Bailout("lookup variable in count operation"); | 8917 return Bailout("lookup variable in count operation"); |
9046 } | 8918 } |
9047 | 8919 |
(...skipping 600 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9648 } | 9520 } |
9649 } | 9521 } |
9650 | 9522 |
9651 // If the target is not null we have found a known global function that is | 9523 // If the target is not null we have found a known global function that is |
9652 // assumed to stay the same for this instanceof. | 9524 // assumed to stay the same for this instanceof. |
9653 if (target.is_null()) { | 9525 if (target.is_null()) { |
9654 HInstanceOf* result = new(zone()) HInstanceOf(context, left, right); | 9526 HInstanceOf* result = new(zone()) HInstanceOf(context, left, right); |
9655 result->set_position(expr->position()); | 9527 result->set_position(expr->position()); |
9656 return ast_context()->ReturnInstruction(result, expr->id()); | 9528 return ast_context()->ReturnInstruction(result, expr->id()); |
9657 } else { | 9529 } else { |
9658 AddInstruction(new(zone()) HCheckFunction(right, target)); | 9530 Add<HCheckFunction>(right, target); |
9659 HInstanceOfKnownGlobal* result = | 9531 HInstanceOfKnownGlobal* result = |
9660 new(zone()) HInstanceOfKnownGlobal(context, left, target); | 9532 new(zone()) HInstanceOfKnownGlobal(context, left, target); |
9661 result->set_position(expr->position()); | 9533 result->set_position(expr->position()); |
9662 return ast_context()->ReturnInstruction(result, expr->id()); | 9534 return ast_context()->ReturnInstruction(result, expr->id()); |
9663 } | 9535 } |
9664 } else if (op == Token::IN) { | 9536 } else if (op == Token::IN) { |
9665 HIn* result = new(zone()) HIn(context, left, right); | 9537 HIn* result = new(zone()) HIn(context, left, right); |
9666 result->set_position(expr->position()); | 9538 result->set_position(expr->position()); |
9667 return ast_context()->ReturnInstruction(result, expr->id()); | 9539 return ast_context()->ReturnInstruction(result, expr->id()); |
9668 } else if (combined_type->Is(Type::Receiver())) { | 9540 } else if (combined_type->Is(Type::Receiver())) { |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9762 } | 9634 } |
9763 | 9635 |
9764 | 9636 |
9765 HInstruction* HOptimizedGraphBuilder::BuildFastLiteral( | 9637 HInstruction* HOptimizedGraphBuilder::BuildFastLiteral( |
9766 HValue* context, | 9638 HValue* context, |
9767 Handle<JSObject> boilerplate_object, | 9639 Handle<JSObject> boilerplate_object, |
9768 Handle<JSObject> original_boilerplate_object, | 9640 Handle<JSObject> original_boilerplate_object, |
9769 int data_size, | 9641 int data_size, |
9770 int pointer_size, | 9642 int pointer_size, |
9771 AllocationSiteMode mode) { | 9643 AllocationSiteMode mode) { |
9772 Zone* zone = this->zone(); | |
9773 NoObservableSideEffectsScope no_effects(this); | 9644 NoObservableSideEffectsScope no_effects(this); |
9774 | 9645 |
9775 HInstruction* target = NULL; | 9646 HInstruction* target = NULL; |
9776 HInstruction* data_target = NULL; | 9647 HInstruction* data_target = NULL; |
9777 | 9648 |
9778 HAllocate::Flags flags = HAllocate::DefaultFlags(); | 9649 HAllocate::Flags flags = HAllocate::DefaultFlags(); |
9779 | 9650 |
9780 if (isolate()->heap()->ShouldGloballyPretenure()) { | 9651 if (isolate()->heap()->ShouldGloballyPretenure()) { |
9781 if (data_size != 0) { | 9652 if (data_size != 0) { |
9782 HAllocate::Flags data_flags = | 9653 HAllocate::Flags data_flags = |
9783 static_cast<HAllocate::Flags>(HAllocate::DefaultFlags() | | 9654 static_cast<HAllocate::Flags>(HAllocate::DefaultFlags() | |
9784 HAllocate::CAN_ALLOCATE_IN_OLD_DATA_SPACE); | 9655 HAllocate::CAN_ALLOCATE_IN_OLD_DATA_SPACE); |
9785 HValue* size_in_bytes = AddInstruction(new(zone) HConstant(data_size)); | 9656 HValue* size_in_bytes = Add<HConstant>(data_size); |
9786 data_target = AddInstruction(new(zone) HAllocate( | 9657 data_target = Add<HAllocate>(context, size_in_bytes, |
9787 context, size_in_bytes, HType::JSObject(), data_flags)); | 9658 HType::JSObject(), data_flags); |
9788 Handle<Map> free_space_map = isolate()->factory()->free_space_map(); | 9659 Handle<Map> free_space_map = isolate()->factory()->free_space_map(); |
9789 AddStoreMapConstant(data_target, free_space_map); | 9660 AddStoreMapConstant(data_target, free_space_map); |
9790 HObjectAccess access = | 9661 HObjectAccess access = |
9791 HObjectAccess::ForJSObjectOffset(FreeSpace::kSizeOffset); | 9662 HObjectAccess::ForJSObjectOffset(FreeSpace::kSizeOffset); |
9792 AddStore(data_target, access, size_in_bytes); | 9663 AddStore(data_target, access, size_in_bytes); |
9793 } | 9664 } |
9794 if (pointer_size != 0) { | 9665 if (pointer_size != 0) { |
9795 flags = static_cast<HAllocate::Flags>( | 9666 flags = static_cast<HAllocate::Flags>( |
9796 flags | HAllocate::CAN_ALLOCATE_IN_OLD_POINTER_SPACE); | 9667 flags | HAllocate::CAN_ALLOCATE_IN_OLD_POINTER_SPACE); |
9797 HValue* size_in_bytes = AddInstruction(new(zone) HConstant(pointer_size)); | 9668 HValue* size_in_bytes = Add<HConstant>(pointer_size); |
9798 target = AddInstruction(new(zone) HAllocate(context, | 9669 target = Add<HAllocate>(context, size_in_bytes, HType::JSObject(), flags); |
9799 size_in_bytes, HType::JSObject(), flags)); | |
9800 } | 9670 } |
9801 } else { | 9671 } else { |
9802 HValue* size_in_bytes = | 9672 HValue* size_in_bytes = Add<HConstant>(data_size + pointer_size); |
9803 AddInstruction(new(zone) HConstant(data_size + pointer_size)); | 9673 target = Add<HAllocate>(context, size_in_bytes, HType::JSObject(), flags); |
9804 target = AddInstruction(new(zone) HAllocate(context, size_in_bytes, | |
9805 HType::JSObject(), flags)); | |
9806 } | 9674 } |
9807 | 9675 |
9808 int offset = 0; | 9676 int offset = 0; |
9809 int data_offset = 0; | 9677 int data_offset = 0; |
9810 BuildEmitDeepCopy(boilerplate_object, original_boilerplate_object, target, | 9678 BuildEmitDeepCopy(boilerplate_object, original_boilerplate_object, target, |
9811 &offset, data_target, &data_offset, mode); | 9679 &offset, data_target, &data_offset, mode); |
9812 return target; | 9680 return target; |
9813 } | 9681 } |
9814 | 9682 |
9815 | 9683 |
9816 void HOptimizedGraphBuilder::BuildEmitDeepCopy( | 9684 void HOptimizedGraphBuilder::BuildEmitDeepCopy( |
9817 Handle<JSObject> boilerplate_object, | 9685 Handle<JSObject> boilerplate_object, |
9818 Handle<JSObject> original_boilerplate_object, | 9686 Handle<JSObject> original_boilerplate_object, |
9819 HInstruction* target, | 9687 HInstruction* target, |
9820 int* offset, | 9688 int* offset, |
9821 HInstruction* data_target, | 9689 HInstruction* data_target, |
9822 int* data_offset, | 9690 int* data_offset, |
9823 AllocationSiteMode mode) { | 9691 AllocationSiteMode mode) { |
9824 Zone* zone = this->zone(); | |
9825 | |
9826 Handle<FixedArrayBase> elements(boilerplate_object->elements()); | 9692 Handle<FixedArrayBase> elements(boilerplate_object->elements()); |
9827 Handle<FixedArrayBase> original_elements( | 9693 Handle<FixedArrayBase> original_elements( |
9828 original_boilerplate_object->elements()); | 9694 original_boilerplate_object->elements()); |
9829 ElementsKind kind = boilerplate_object->map()->elements_kind(); | 9695 ElementsKind kind = boilerplate_object->map()->elements_kind(); |
9830 | 9696 |
9831 int object_offset = *offset; | 9697 int object_offset = *offset; |
9832 int object_size = boilerplate_object->map()->instance_size(); | 9698 int object_size = boilerplate_object->map()->instance_size(); |
9833 int elements_size = (elements->length() > 0 && | 9699 int elements_size = (elements->length() > 0 && |
9834 elements->map() != isolate()->heap()->fixed_cow_array_map()) ? | 9700 elements->map() != isolate()->heap()->fixed_cow_array_map()) ? |
9835 elements->Size() : 0; | 9701 elements->Size() : 0; |
(...skipping 15 matching lines...) Expand all Loading... |
9851 HValue* object_elements = BuildEmitObjectHeader(boilerplate_object, target, | 9717 HValue* object_elements = BuildEmitObjectHeader(boilerplate_object, target, |
9852 data_target, object_offset, elements_offset, elements_size); | 9718 data_target, object_offset, elements_offset, elements_size); |
9853 if (object_elements != NULL) { | 9719 if (object_elements != NULL) { |
9854 BuildEmitElements(elements, original_elements, kind, object_elements, | 9720 BuildEmitElements(elements, original_elements, kind, object_elements, |
9855 target, offset, data_target, data_offset); | 9721 target, offset, data_target, data_offset); |
9856 } | 9722 } |
9857 | 9723 |
9858 // Copy in-object properties. | 9724 // Copy in-object properties. |
9859 if (boilerplate_object->map()->NumberOfFields() != 0) { | 9725 if (boilerplate_object->map()->NumberOfFields() != 0) { |
9860 HValue* object_properties = | 9726 HValue* object_properties = |
9861 AddInstruction(new(zone) HInnerAllocatedObject(target, object_offset)); | 9727 Add<HInnerAllocatedObject>(target, object_offset); |
9862 BuildEmitInObjectProperties(boilerplate_object, original_boilerplate_object, | 9728 BuildEmitInObjectProperties(boilerplate_object, original_boilerplate_object, |
9863 object_properties, target, offset, data_target, data_offset); | 9729 object_properties, target, offset, data_target, data_offset); |
9864 } | 9730 } |
9865 | 9731 |
9866 // Create allocation site info. | 9732 // Create allocation site info. |
9867 if (mode == TRACK_ALLOCATION_SITE && | 9733 if (mode == TRACK_ALLOCATION_SITE && |
9868 boilerplate_object->map()->CanTrackAllocationSite()) { | 9734 boilerplate_object->map()->CanTrackAllocationSite()) { |
9869 elements_offset += AllocationSiteInfo::kSize; | 9735 elements_offset += AllocationSiteInfo::kSize; |
9870 *offset += AllocationSiteInfo::kSize; | 9736 *offset += AllocationSiteInfo::kSize; |
9871 HInstruction* original_boilerplate = AddInstruction(new(zone) HConstant( | 9737 HInstruction* original_boilerplate = |
9872 original_boilerplate_object)); | 9738 Add<HConstant>(original_boilerplate_object); |
9873 BuildCreateAllocationSiteInfo(target, JSArray::kSize, original_boilerplate); | 9739 BuildCreateAllocationSiteInfo(target, JSArray::kSize, original_boilerplate); |
9874 } | 9740 } |
9875 } | 9741 } |
9876 | 9742 |
9877 | 9743 |
9878 HValue* HOptimizedGraphBuilder::BuildEmitObjectHeader( | 9744 HValue* HOptimizedGraphBuilder::BuildEmitObjectHeader( |
9879 Handle<JSObject> boilerplate_object, | 9745 Handle<JSObject> boilerplate_object, |
9880 HInstruction* target, | 9746 HInstruction* target, |
9881 HInstruction* data_target, | 9747 HInstruction* data_target, |
9882 int object_offset, | 9748 int object_offset, |
9883 int elements_offset, | 9749 int elements_offset, |
9884 int elements_size) { | 9750 int elements_size) { |
9885 ASSERT(boilerplate_object->properties()->length() == 0); | 9751 ASSERT(boilerplate_object->properties()->length() == 0); |
9886 Zone* zone = this->zone(); | |
9887 HValue* result = NULL; | 9752 HValue* result = NULL; |
9888 | 9753 |
9889 HValue* object_header = | 9754 HValue* object_header = Add<HInnerAllocatedObject>(target, object_offset); |
9890 AddInstruction(new(zone) HInnerAllocatedObject(target, object_offset)); | |
9891 Handle<Map> boilerplate_object_map(boilerplate_object->map()); | 9755 Handle<Map> boilerplate_object_map(boilerplate_object->map()); |
9892 AddStoreMapConstant(object_header, boilerplate_object_map); | 9756 AddStoreMapConstant(object_header, boilerplate_object_map); |
9893 | 9757 |
9894 HInstruction* elements; | 9758 HInstruction* elements; |
9895 if (elements_size == 0) { | 9759 if (elements_size == 0) { |
9896 Handle<Object> elements_field = | 9760 Handle<Object> elements_field = |
9897 Handle<Object>(boilerplate_object->elements(), isolate()); | 9761 Handle<Object>(boilerplate_object->elements(), isolate()); |
9898 elements = AddInstruction(new(zone) HConstant(elements_field)); | 9762 elements = Add<HConstant>(elements_field); |
9899 } else { | 9763 } else { |
9900 if (data_target != NULL && boilerplate_object->HasFastDoubleElements()) { | 9764 if (data_target != NULL && boilerplate_object->HasFastDoubleElements()) { |
9901 elements = AddInstruction(new(zone) HInnerAllocatedObject( | 9765 elements = Add<HInnerAllocatedObject>(data_target, elements_offset); |
9902 data_target, elements_offset)); | |
9903 } else { | 9766 } else { |
9904 elements = AddInstruction(new(zone) HInnerAllocatedObject( | 9767 elements = Add<HInnerAllocatedObject>(target, elements_offset); |
9905 target, elements_offset)); | |
9906 } | 9768 } |
9907 result = elements; | 9769 result = elements; |
9908 } | 9770 } |
9909 AddStore(object_header, HObjectAccess::ForElementsPointer(), elements); | 9771 AddStore(object_header, HObjectAccess::ForElementsPointer(), elements); |
9910 | 9772 |
9911 Handle<Object> properties_field = | 9773 Handle<Object> properties_field = |
9912 Handle<Object>(boilerplate_object->properties(), isolate()); | 9774 Handle<Object>(boilerplate_object->properties(), isolate()); |
9913 ASSERT(*properties_field == isolate()->heap()->empty_fixed_array()); | 9775 ASSERT(*properties_field == isolate()->heap()->empty_fixed_array()); |
9914 HInstruction* properties = AddInstruction(new(zone) HConstant( | 9776 HInstruction* properties = Add<HConstant>(properties_field); |
9915 properties_field)); | |
9916 HObjectAccess access = HObjectAccess::ForPropertiesPointer(); | 9777 HObjectAccess access = HObjectAccess::ForPropertiesPointer(); |
9917 AddStore(object_header, access, properties); | 9778 AddStore(object_header, access, properties); |
9918 | 9779 |
9919 if (boilerplate_object->IsJSArray()) { | 9780 if (boilerplate_object->IsJSArray()) { |
9920 Handle<JSArray> boilerplate_array = | 9781 Handle<JSArray> boilerplate_array = |
9921 Handle<JSArray>::cast(boilerplate_object); | 9782 Handle<JSArray>::cast(boilerplate_object); |
9922 Handle<Object> length_field = | 9783 Handle<Object> length_field = |
9923 Handle<Object>(boilerplate_array->length(), isolate()); | 9784 Handle<Object>(boilerplate_array->length(), isolate()); |
9924 HInstruction* length = AddInstruction(new(zone) HConstant(length_field)); | 9785 HInstruction* length = Add<HConstant>(length_field); |
9925 | 9786 |
9926 ASSERT(boilerplate_array->length()->IsSmi()); | 9787 ASSERT(boilerplate_array->length()->IsSmi()); |
9927 Representation representation = | 9788 Representation representation = |
9928 IsFastElementsKind(boilerplate_array->GetElementsKind()) | 9789 IsFastElementsKind(boilerplate_array->GetElementsKind()) |
9929 ? Representation::Smi() : Representation::Tagged(); | 9790 ? Representation::Smi() : Representation::Tagged(); |
9930 AddStore(object_header, HObjectAccess::ForArrayLength(), | 9791 AddStore(object_header, HObjectAccess::ForArrayLength(), |
9931 length, representation); | 9792 length, representation); |
9932 } | 9793 } |
9933 | 9794 |
9934 return result; | 9795 return result; |
9935 } | 9796 } |
9936 | 9797 |
9937 | 9798 |
9938 void HOptimizedGraphBuilder::BuildEmitInObjectProperties( | 9799 void HOptimizedGraphBuilder::BuildEmitInObjectProperties( |
9939 Handle<JSObject> boilerplate_object, | 9800 Handle<JSObject> boilerplate_object, |
9940 Handle<JSObject> original_boilerplate_object, | 9801 Handle<JSObject> original_boilerplate_object, |
9941 HValue* object_properties, | 9802 HValue* object_properties, |
9942 HInstruction* target, | 9803 HInstruction* target, |
9943 int* offset, | 9804 int* offset, |
9944 HInstruction* data_target, | 9805 HInstruction* data_target, |
9945 int* data_offset) { | 9806 int* data_offset) { |
9946 Zone* zone = this->zone(); | |
9947 Handle<DescriptorArray> descriptors( | 9807 Handle<DescriptorArray> descriptors( |
9948 boilerplate_object->map()->instance_descriptors()); | 9808 boilerplate_object->map()->instance_descriptors()); |
9949 int limit = boilerplate_object->map()->NumberOfOwnDescriptors(); | 9809 int limit = boilerplate_object->map()->NumberOfOwnDescriptors(); |
9950 | 9810 |
9951 int copied_fields = 0; | 9811 int copied_fields = 0; |
9952 for (int i = 0; i < limit; i++) { | 9812 for (int i = 0; i < limit; i++) { |
9953 PropertyDetails details = descriptors->GetDetails(i); | 9813 PropertyDetails details = descriptors->GetDetails(i); |
9954 if (details.type() != FIELD) continue; | 9814 if (details.type() != FIELD) continue; |
9955 copied_fields++; | 9815 copied_fields++; |
9956 int index = descriptors->GetFieldIndex(i); | 9816 int index = descriptors->GetFieldIndex(i); |
9957 int property_offset = boilerplate_object->GetInObjectPropertyOffset(index); | 9817 int property_offset = boilerplate_object->GetInObjectPropertyOffset(index); |
9958 Handle<Name> name(descriptors->GetKey(i)); | 9818 Handle<Name> name(descriptors->GetKey(i)); |
9959 Handle<Object> value = | 9819 Handle<Object> value = |
9960 Handle<Object>(boilerplate_object->InObjectPropertyAt(index), | 9820 Handle<Object>(boilerplate_object->InObjectPropertyAt(index), |
9961 isolate()); | 9821 isolate()); |
9962 | 9822 |
9963 // The access for the store depends on the type of the boilerplate. | 9823 // The access for the store depends on the type of the boilerplate. |
9964 HObjectAccess access = boilerplate_object->IsJSArray() ? | 9824 HObjectAccess access = boilerplate_object->IsJSArray() ? |
9965 HObjectAccess::ForJSArrayOffset(property_offset) : | 9825 HObjectAccess::ForJSArrayOffset(property_offset) : |
9966 HObjectAccess::ForJSObjectOffset(property_offset); | 9826 HObjectAccess::ForJSObjectOffset(property_offset); |
9967 | 9827 |
9968 if (value->IsJSObject()) { | 9828 if (value->IsJSObject()) { |
9969 Handle<JSObject> value_object = Handle<JSObject>::cast(value); | 9829 Handle<JSObject> value_object = Handle<JSObject>::cast(value); |
9970 Handle<JSObject> original_value_object = Handle<JSObject>::cast( | 9830 Handle<JSObject> original_value_object = Handle<JSObject>::cast( |
9971 Handle<Object>(original_boilerplate_object->InObjectPropertyAt(index), | 9831 Handle<Object>(original_boilerplate_object->InObjectPropertyAt(index), |
9972 isolate())); | 9832 isolate())); |
9973 HInstruction* value_instruction = | 9833 HInstruction* value_instruction = Add<HInnerAllocatedObject>(target, |
9974 AddInstruction(new(zone) HInnerAllocatedObject(target, *offset)); | 9834 *offset); |
9975 | 9835 |
9976 AddStore(object_properties, access, value_instruction); | 9836 AddStore(object_properties, access, value_instruction); |
9977 | 9837 |
9978 BuildEmitDeepCopy(value_object, original_value_object, target, | 9838 BuildEmitDeepCopy(value_object, original_value_object, target, |
9979 offset, data_target, data_offset, DONT_TRACK_ALLOCATION_SITE); | 9839 offset, data_target, data_offset, DONT_TRACK_ALLOCATION_SITE); |
9980 } else { | 9840 } else { |
9981 Representation representation = details.representation(); | 9841 Representation representation = details.representation(); |
9982 HInstruction* value_instruction = | 9842 HInstruction* value_instruction = Add<HConstant>(value); |
9983 AddInstruction(new(zone) HConstant(value)); | |
9984 | 9843 |
9985 if (representation.IsDouble()) { | 9844 if (representation.IsDouble()) { |
9986 // Allocate a HeapNumber box and store the value into it. | 9845 // Allocate a HeapNumber box and store the value into it. |
9987 HInstruction* double_box; | 9846 HInstruction* double_box; |
9988 if (data_target != NULL) { | 9847 if (data_target != NULL) { |
9989 double_box = AddInstruction(new(zone) HInnerAllocatedObject( | 9848 double_box = Add<HInnerAllocatedObject>(data_target, *data_offset); |
9990 data_target, *data_offset)); | |
9991 *data_offset += HeapNumber::kSize; | 9849 *data_offset += HeapNumber::kSize; |
9992 } else { | 9850 } else { |
9993 double_box = AddInstruction(new(zone) HInnerAllocatedObject( | 9851 double_box = Add<HInnerAllocatedObject>(target, *offset); |
9994 target, *offset)); | |
9995 *offset += HeapNumber::kSize; | 9852 *offset += HeapNumber::kSize; |
9996 } | 9853 } |
9997 AddStoreMapConstant(double_box, | 9854 AddStoreMapConstant(double_box, |
9998 isolate()->factory()->heap_number_map()); | 9855 isolate()->factory()->heap_number_map()); |
9999 AddStore(double_box, HObjectAccess::ForHeapNumberValue(), | 9856 AddStore(double_box, HObjectAccess::ForHeapNumberValue(), |
10000 value_instruction, Representation::Double()); | 9857 value_instruction, Representation::Double()); |
10001 value_instruction = double_box; | 9858 value_instruction = double_box; |
10002 } | 9859 } |
10003 | 9860 |
10004 AddStore(object_properties, access, value_instruction); | 9861 AddStore(object_properties, access, value_instruction); |
10005 } | 9862 } |
10006 } | 9863 } |
10007 | 9864 |
10008 int inobject_properties = boilerplate_object->map()->inobject_properties(); | 9865 int inobject_properties = boilerplate_object->map()->inobject_properties(); |
10009 HInstruction* value_instruction = AddInstruction(new(zone) | 9866 HInstruction* value_instruction = |
10010 HConstant(isolate()->factory()->one_pointer_filler_map())); | 9867 Add<HConstant>(isolate()->factory()->one_pointer_filler_map()); |
10011 for (int i = copied_fields; i < inobject_properties; i++) { | 9868 for (int i = copied_fields; i < inobject_properties; i++) { |
10012 ASSERT(boilerplate_object->IsJSObject()); | 9869 ASSERT(boilerplate_object->IsJSObject()); |
10013 int property_offset = boilerplate_object->GetInObjectPropertyOffset(i); | 9870 int property_offset = boilerplate_object->GetInObjectPropertyOffset(i); |
10014 HObjectAccess access = HObjectAccess::ForJSObjectOffset(property_offset); | 9871 HObjectAccess access = HObjectAccess::ForJSObjectOffset(property_offset); |
10015 AddStore(object_properties, access, value_instruction); | 9872 AddStore(object_properties, access, value_instruction); |
10016 } | 9873 } |
10017 } | 9874 } |
10018 | 9875 |
10019 | 9876 |
10020 void HOptimizedGraphBuilder::BuildEmitElements( | 9877 void HOptimizedGraphBuilder::BuildEmitElements( |
10021 Handle<FixedArrayBase> elements, | 9878 Handle<FixedArrayBase> elements, |
10022 Handle<FixedArrayBase> original_elements, | 9879 Handle<FixedArrayBase> original_elements, |
10023 ElementsKind kind, | 9880 ElementsKind kind, |
10024 HValue* object_elements, | 9881 HValue* object_elements, |
10025 HInstruction* target, | 9882 HInstruction* target, |
10026 int* offset, | 9883 int* offset, |
10027 HInstruction* data_target, | 9884 HInstruction* data_target, |
10028 int* data_offset) { | 9885 int* data_offset) { |
10029 Zone* zone = this->zone(); | |
10030 | |
10031 int elements_length = elements->length(); | 9886 int elements_length = elements->length(); |
10032 HValue* object_elements_length = | 9887 HValue* object_elements_length = Add<HConstant>(elements_length); |
10033 AddInstruction(new(zone) HConstant(elements_length)); | |
10034 | 9888 |
10035 BuildInitializeElementsHeader(object_elements, kind, object_elements_length); | 9889 BuildInitializeElementsHeader(object_elements, kind, object_elements_length); |
10036 | 9890 |
10037 // Copy elements backing store content. | 9891 // Copy elements backing store content. |
10038 if (elements->IsFixedDoubleArray()) { | 9892 if (elements->IsFixedDoubleArray()) { |
10039 BuildEmitFixedDoubleArray(elements, kind, object_elements); | 9893 BuildEmitFixedDoubleArray(elements, kind, object_elements); |
10040 } else if (elements->IsFixedArray()) { | 9894 } else if (elements->IsFixedArray()) { |
10041 BuildEmitFixedArray(elements, original_elements, kind, object_elements, | 9895 BuildEmitFixedArray(elements, original_elements, kind, object_elements, |
10042 target, offset, data_target, data_offset); | 9896 target, offset, data_target, data_offset); |
10043 } else { | 9897 } else { |
10044 UNREACHABLE(); | 9898 UNREACHABLE(); |
10045 } | 9899 } |
10046 } | 9900 } |
10047 | 9901 |
10048 | 9902 |
10049 void HOptimizedGraphBuilder::BuildEmitFixedDoubleArray( | 9903 void HOptimizedGraphBuilder::BuildEmitFixedDoubleArray( |
10050 Handle<FixedArrayBase> elements, | 9904 Handle<FixedArrayBase> elements, |
10051 ElementsKind kind, | 9905 ElementsKind kind, |
10052 HValue* object_elements) { | 9906 HValue* object_elements) { |
10053 Zone* zone = this->zone(); | 9907 HInstruction* boilerplate_elements = Add<HConstant>(elements); |
10054 HInstruction* boilerplate_elements = | |
10055 AddInstruction(new(zone) HConstant(elements)); | |
10056 int elements_length = elements->length(); | 9908 int elements_length = elements->length(); |
10057 for (int i = 0; i < elements_length; i++) { | 9909 for (int i = 0; i < elements_length; i++) { |
10058 HValue* key_constant = AddInstruction(new(zone) HConstant(i)); | 9910 HValue* key_constant = Add<HConstant>(i); |
10059 HInstruction* value_instruction = | 9911 HInstruction* value_instruction = |
10060 AddInstruction(new(zone) HLoadKeyed( | 9912 Add<HLoadKeyed>(boilerplate_elements, key_constant, |
10061 boilerplate_elements, key_constant, NULL, kind, ALLOW_RETURN_HOLE)); | 9913 static_cast<HValue*>(NULL), kind, |
10062 HInstruction* store = AddInstruction(new(zone) HStoreKeyed( | 9914 ALLOW_RETURN_HOLE); |
10063 object_elements, key_constant, value_instruction, kind)); | 9915 HInstruction* store = Add<HStoreKeyed>(object_elements, key_constant, |
| 9916 value_instruction, kind); |
10064 store->SetFlag(HValue::kAllowUndefinedAsNaN); | 9917 store->SetFlag(HValue::kAllowUndefinedAsNaN); |
10065 } | 9918 } |
10066 } | 9919 } |
10067 | 9920 |
10068 | 9921 |
10069 void HOptimizedGraphBuilder::BuildEmitFixedArray( | 9922 void HOptimizedGraphBuilder::BuildEmitFixedArray( |
10070 Handle<FixedArrayBase> elements, | 9923 Handle<FixedArrayBase> elements, |
10071 Handle<FixedArrayBase> original_elements, | 9924 Handle<FixedArrayBase> original_elements, |
10072 ElementsKind kind, | 9925 ElementsKind kind, |
10073 HValue* object_elements, | 9926 HValue* object_elements, |
10074 HInstruction* target, | 9927 HInstruction* target, |
10075 int* offset, | 9928 int* offset, |
10076 HInstruction* data_target, | 9929 HInstruction* data_target, |
10077 int* data_offset) { | 9930 int* data_offset) { |
10078 Zone* zone = this->zone(); | 9931 HInstruction* boilerplate_elements = Add<HConstant>(elements); |
10079 HInstruction* boilerplate_elements = | |
10080 AddInstruction(new(zone) HConstant(elements)); | |
10081 int elements_length = elements->length(); | 9932 int elements_length = elements->length(); |
10082 Handle<FixedArray> fast_elements = Handle<FixedArray>::cast(elements); | 9933 Handle<FixedArray> fast_elements = Handle<FixedArray>::cast(elements); |
10083 Handle<FixedArray> original_fast_elements = | 9934 Handle<FixedArray> original_fast_elements = |
10084 Handle<FixedArray>::cast(original_elements); | 9935 Handle<FixedArray>::cast(original_elements); |
10085 for (int i = 0; i < elements_length; i++) { | 9936 for (int i = 0; i < elements_length; i++) { |
10086 Handle<Object> value(fast_elements->get(i), isolate()); | 9937 Handle<Object> value(fast_elements->get(i), isolate()); |
10087 HValue* key_constant = AddInstruction(new(zone) HConstant(i)); | 9938 HValue* key_constant = Add<HConstant>(i); |
10088 if (value->IsJSObject()) { | 9939 if (value->IsJSObject()) { |
10089 Handle<JSObject> value_object = Handle<JSObject>::cast(value); | 9940 Handle<JSObject> value_object = Handle<JSObject>::cast(value); |
10090 Handle<JSObject> original_value_object = Handle<JSObject>::cast( | 9941 Handle<JSObject> original_value_object = Handle<JSObject>::cast( |
10091 Handle<Object>(original_fast_elements->get(i), isolate())); | 9942 Handle<Object>(original_fast_elements->get(i), isolate())); |
10092 HInstruction* value_instruction = | 9943 HInstruction* value_instruction = Add<HInnerAllocatedObject>(target, |
10093 AddInstruction(new(zone) HInnerAllocatedObject(target, *offset)); | 9944 *offset); |
10094 AddInstruction(new(zone) HStoreKeyed( | 9945 Add<HStoreKeyed>(object_elements, key_constant, value_instruction, kind); |
10095 object_elements, key_constant, value_instruction, kind)); | |
10096 BuildEmitDeepCopy(value_object, original_value_object, target, | 9946 BuildEmitDeepCopy(value_object, original_value_object, target, |
10097 offset, data_target, data_offset, DONT_TRACK_ALLOCATION_SITE); | 9947 offset, data_target, data_offset, DONT_TRACK_ALLOCATION_SITE); |
10098 } else { | 9948 } else { |
10099 HInstruction* value_instruction = | 9949 HInstruction* value_instruction = |
10100 AddInstruction(new(zone) HLoadKeyed( | 9950 Add<HLoadKeyed>(boilerplate_elements, key_constant, |
10101 boilerplate_elements, key_constant, NULL, kind, | 9951 static_cast<HValue*>(NULL), kind, |
10102 ALLOW_RETURN_HOLE)); | 9952 ALLOW_RETURN_HOLE); |
10103 AddInstruction(new(zone) HStoreKeyed( | 9953 Add<HStoreKeyed>(object_elements, key_constant, value_instruction, kind); |
10104 object_elements, key_constant, value_instruction, kind)); | |
10105 } | 9954 } |
10106 } | 9955 } |
10107 } | 9956 } |
10108 | 9957 |
10109 void HOptimizedGraphBuilder::VisitThisFunction(ThisFunction* expr) { | 9958 void HOptimizedGraphBuilder::VisitThisFunction(ThisFunction* expr) { |
10110 ASSERT(!HasStackOverflow()); | 9959 ASSERT(!HasStackOverflow()); |
10111 ASSERT(current_block() != NULL); | 9960 ASSERT(current_block() != NULL); |
10112 ASSERT(current_block()->HasPredecessor()); | 9961 ASSERT(current_block()->HasPredecessor()); |
10113 HInstruction* instr = BuildThisFunction(); | 9962 HInstruction* instr = BuildThisFunction(); |
10114 return ast_context()->ReturnInstruction(instr, expr->id()); | 9963 return ast_context()->ReturnInstruction(instr, expr->id()); |
10115 } | 9964 } |
10116 | 9965 |
10117 | 9966 |
10118 void HOptimizedGraphBuilder::VisitDeclarations( | 9967 void HOptimizedGraphBuilder::VisitDeclarations( |
10119 ZoneList<Declaration*>* declarations) { | 9968 ZoneList<Declaration*>* declarations) { |
10120 ASSERT(globals_.is_empty()); | 9969 ASSERT(globals_.is_empty()); |
10121 AstVisitor::VisitDeclarations(declarations); | 9970 AstVisitor::VisitDeclarations(declarations); |
10122 if (!globals_.is_empty()) { | 9971 if (!globals_.is_empty()) { |
10123 Handle<FixedArray> array = | 9972 Handle<FixedArray> array = |
10124 isolate()->factory()->NewFixedArray(globals_.length(), TENURED); | 9973 isolate()->factory()->NewFixedArray(globals_.length(), TENURED); |
10125 for (int i = 0; i < globals_.length(); ++i) array->set(i, *globals_.at(i)); | 9974 for (int i = 0; i < globals_.length(); ++i) array->set(i, *globals_.at(i)); |
10126 int flags = DeclareGlobalsEvalFlag::encode(current_info()->is_eval()) | | 9975 int flags = DeclareGlobalsEvalFlag::encode(current_info()->is_eval()) | |
10127 DeclareGlobalsNativeFlag::encode(current_info()->is_native()) | | 9976 DeclareGlobalsNativeFlag::encode(current_info()->is_native()) | |
10128 DeclareGlobalsLanguageMode::encode(current_info()->language_mode()); | 9977 DeclareGlobalsLanguageMode::encode(current_info()->language_mode()); |
10129 HInstruction* result = new(zone()) HDeclareGlobals( | 9978 Add<HDeclareGlobals>(environment()->LookupContext(), array, flags); |
10130 environment()->LookupContext(), array, flags); | |
10131 AddInstruction(result); | |
10132 globals_.Clear(); | 9979 globals_.Clear(); |
10133 } | 9980 } |
10134 } | 9981 } |
10135 | 9982 |
10136 | 9983 |
10137 void HOptimizedGraphBuilder::VisitVariableDeclaration( | 9984 void HOptimizedGraphBuilder::VisitVariableDeclaration( |
10138 VariableDeclaration* declaration) { | 9985 VariableDeclaration* declaration) { |
10139 VariableProxy* proxy = declaration->proxy(); | 9986 VariableProxy* proxy = declaration->proxy(); |
10140 VariableMode mode = declaration->mode(); | 9987 VariableMode mode = declaration->mode(); |
10141 Variable* variable = proxy->var(); | 9988 Variable* variable = proxy->var(); |
10142 bool hole_init = mode == CONST || mode == CONST_HARMONY || mode == LET; | 9989 bool hole_init = mode == CONST || mode == CONST_HARMONY || mode == LET; |
10143 switch (variable->location()) { | 9990 switch (variable->location()) { |
10144 case Variable::UNALLOCATED: | 9991 case Variable::UNALLOCATED: |
10145 globals_.Add(variable->name(), zone()); | 9992 globals_.Add(variable->name(), zone()); |
10146 globals_.Add(variable->binding_needs_init() | 9993 globals_.Add(variable->binding_needs_init() |
10147 ? isolate()->factory()->the_hole_value() | 9994 ? isolate()->factory()->the_hole_value() |
10148 : isolate()->factory()->undefined_value(), zone()); | 9995 : isolate()->factory()->undefined_value(), zone()); |
10149 return; | 9996 return; |
10150 case Variable::PARAMETER: | 9997 case Variable::PARAMETER: |
10151 case Variable::LOCAL: | 9998 case Variable::LOCAL: |
10152 if (hole_init) { | 9999 if (hole_init) { |
10153 HValue* value = graph()->GetConstantHole(); | 10000 HValue* value = graph()->GetConstantHole(); |
10154 environment()->Bind(variable, value); | 10001 environment()->Bind(variable, value); |
10155 } | 10002 } |
10156 break; | 10003 break; |
10157 case Variable::CONTEXT: | 10004 case Variable::CONTEXT: |
10158 if (hole_init) { | 10005 if (hole_init) { |
10159 HValue* value = graph()->GetConstantHole(); | 10006 HValue* value = graph()->GetConstantHole(); |
10160 HValue* context = environment()->LookupContext(); | 10007 HValue* context = environment()->LookupContext(); |
10161 HStoreContextSlot* store = new(zone()) HStoreContextSlot( | 10008 HStoreContextSlot* store = Add<HStoreContextSlot>( |
10162 context, variable->index(), HStoreContextSlot::kNoCheck, value); | 10009 context, variable->index(), HStoreContextSlot::kNoCheck, value); |
10163 AddInstruction(store); | |
10164 if (store->HasObservableSideEffects()) { | 10010 if (store->HasObservableSideEffects()) { |
10165 AddSimulate(proxy->id(), REMOVABLE_SIMULATE); | 10011 AddSimulate(proxy->id(), REMOVABLE_SIMULATE); |
10166 } | 10012 } |
10167 } | 10013 } |
10168 break; | 10014 break; |
10169 case Variable::LOOKUP: | 10015 case Variable::LOOKUP: |
10170 return Bailout("unsupported lookup slot in declaration"); | 10016 return Bailout("unsupported lookup slot in declaration"); |
10171 } | 10017 } |
10172 } | 10018 } |
10173 | 10019 |
(...skipping 16 matching lines...) Expand all Loading... |
10190 case Variable::LOCAL: { | 10036 case Variable::LOCAL: { |
10191 CHECK_ALIVE(VisitForValue(declaration->fun())); | 10037 CHECK_ALIVE(VisitForValue(declaration->fun())); |
10192 HValue* value = Pop(); | 10038 HValue* value = Pop(); |
10193 BindIfLive(variable, value); | 10039 BindIfLive(variable, value); |
10194 break; | 10040 break; |
10195 } | 10041 } |
10196 case Variable::CONTEXT: { | 10042 case Variable::CONTEXT: { |
10197 CHECK_ALIVE(VisitForValue(declaration->fun())); | 10043 CHECK_ALIVE(VisitForValue(declaration->fun())); |
10198 HValue* value = Pop(); | 10044 HValue* value = Pop(); |
10199 HValue* context = environment()->LookupContext(); | 10045 HValue* context = environment()->LookupContext(); |
10200 HStoreContextSlot* store = new(zone()) HStoreContextSlot( | 10046 HStoreContextSlot* store = Add<HStoreContextSlot>( |
10201 context, variable->index(), HStoreContextSlot::kNoCheck, value); | 10047 context, variable->index(), HStoreContextSlot::kNoCheck, value); |
10202 AddInstruction(store); | |
10203 if (store->HasObservableSideEffects()) { | 10048 if (store->HasObservableSideEffects()) { |
10204 AddSimulate(proxy->id(), REMOVABLE_SIMULATE); | 10049 AddSimulate(proxy->id(), REMOVABLE_SIMULATE); |
10205 } | 10050 } |
10206 break; | 10051 break; |
10207 } | 10052 } |
10208 case Variable::LOOKUP: | 10053 case Variable::LOOKUP: |
10209 return Bailout("unsupported lookup slot in declaration"); | 10054 return Bailout("unsupported lookup slot in declaration"); |
10210 } | 10055 } |
10211 } | 10056 } |
10212 | 10057 |
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10364 } | 10209 } |
10365 | 10210 |
10366 | 10211 |
10367 // Support for arguments.length and arguments[?]. | 10212 // Support for arguments.length and arguments[?]. |
10368 void HOptimizedGraphBuilder::GenerateArgumentsLength(CallRuntime* call) { | 10213 void HOptimizedGraphBuilder::GenerateArgumentsLength(CallRuntime* call) { |
10369 // Our implementation of arguments (based on this stack frame or an | 10214 // Our implementation of arguments (based on this stack frame or an |
10370 // adapter below it) does not work for inlined functions. This runtime | 10215 // adapter below it) does not work for inlined functions. This runtime |
10371 // function is blacklisted by AstNode::IsInlineable. | 10216 // function is blacklisted by AstNode::IsInlineable. |
10372 ASSERT(function_state()->outer() == NULL); | 10217 ASSERT(function_state()->outer() == NULL); |
10373 ASSERT(call->arguments()->length() == 0); | 10218 ASSERT(call->arguments()->length() == 0); |
10374 HInstruction* elements = AddInstruction( | 10219 HInstruction* elements = Add<HArgumentsElements>(false); |
10375 new(zone()) HArgumentsElements(false)); | |
10376 HArgumentsLength* result = new(zone()) HArgumentsLength(elements); | 10220 HArgumentsLength* result = new(zone()) HArgumentsLength(elements); |
10377 return ast_context()->ReturnInstruction(result, call->id()); | 10221 return ast_context()->ReturnInstruction(result, call->id()); |
10378 } | 10222 } |
10379 | 10223 |
10380 | 10224 |
10381 void HOptimizedGraphBuilder::GenerateArguments(CallRuntime* call) { | 10225 void HOptimizedGraphBuilder::GenerateArguments(CallRuntime* call) { |
10382 // Our implementation of arguments (based on this stack frame or an | 10226 // Our implementation of arguments (based on this stack frame or an |
10383 // adapter below it) does not work for inlined functions. This runtime | 10227 // adapter below it) does not work for inlined functions. This runtime |
10384 // function is blacklisted by AstNode::IsInlineable. | 10228 // function is blacklisted by AstNode::IsInlineable. |
10385 ASSERT(function_state()->outer() == NULL); | 10229 ASSERT(function_state()->outer() == NULL); |
10386 ASSERT(call->arguments()->length() == 1); | 10230 ASSERT(call->arguments()->length() == 1); |
10387 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); | 10231 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); |
10388 HValue* index = Pop(); | 10232 HValue* index = Pop(); |
10389 HInstruction* elements = AddInstruction( | 10233 HInstruction* elements = Add<HArgumentsElements>(false); |
10390 new(zone()) HArgumentsElements(false)); | 10234 HInstruction* length = Add<HArgumentsLength>(elements); |
10391 HInstruction* length = AddInstruction(new(zone()) HArgumentsLength(elements)); | |
10392 HInstruction* checked_index = Add<HBoundsCheck>(index, length); | 10235 HInstruction* checked_index = Add<HBoundsCheck>(index, length); |
10393 HAccessArgumentsAt* result = | 10236 HAccessArgumentsAt* result = |
10394 new(zone()) HAccessArgumentsAt(elements, length, checked_index); | 10237 new(zone()) HAccessArgumentsAt(elements, length, checked_index); |
10395 return ast_context()->ReturnInstruction(result, call->id()); | 10238 return ast_context()->ReturnInstruction(result, call->id()); |
10396 } | 10239 } |
10397 | 10240 |
10398 | 10241 |
10399 // Support for accessing the class and value fields of an object. | 10242 // Support for accessing the class and value fields of an object. |
10400 void HOptimizedGraphBuilder::GenerateClassOf(CallRuntime* call) { | 10243 void HOptimizedGraphBuilder::GenerateClassOf(CallRuntime* call) { |
10401 // The special form detected by IsClassOfTest is detected before we get here | 10244 // The special form detected by IsClassOfTest is detected before we get here |
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10546 | 10389 |
10547 void HOptimizedGraphBuilder::GenerateLog(CallRuntime* call) { | 10390 void HOptimizedGraphBuilder::GenerateLog(CallRuntime* call) { |
10548 // %_Log is ignored in optimized code. | 10391 // %_Log is ignored in optimized code. |
10549 return ast_context()->ReturnValue(graph()->GetConstantUndefined()); | 10392 return ast_context()->ReturnValue(graph()->GetConstantUndefined()); |
10550 } | 10393 } |
10551 | 10394 |
10552 | 10395 |
10553 // Fast support for Math.random(). | 10396 // Fast support for Math.random(). |
10554 void HOptimizedGraphBuilder::GenerateRandomHeapNumber(CallRuntime* call) { | 10397 void HOptimizedGraphBuilder::GenerateRandomHeapNumber(CallRuntime* call) { |
10555 HValue* context = environment()->LookupContext(); | 10398 HValue* context = environment()->LookupContext(); |
10556 HGlobalObject* global_object = new(zone()) HGlobalObject(context); | 10399 HGlobalObject* global_object = Add<HGlobalObject>(context); |
10557 AddInstruction(global_object); | |
10558 HRandom* result = new(zone()) HRandom(global_object); | 10400 HRandom* result = new(zone()) HRandom(global_object); |
10559 return ast_context()->ReturnInstruction(result, call->id()); | 10401 return ast_context()->ReturnInstruction(result, call->id()); |
10560 } | 10402 } |
10561 | 10403 |
10562 | 10404 |
10563 // Fast support for StringAdd. | 10405 // Fast support for StringAdd. |
10564 void HOptimizedGraphBuilder::GenerateStringAdd(CallRuntime* call) { | 10406 void HOptimizedGraphBuilder::GenerateStringAdd(CallRuntime* call) { |
10565 ASSERT_EQ(2, call->arguments()->length()); | 10407 ASSERT_EQ(2, call->arguments()->length()); |
10566 CHECK_ALIVE(VisitArgumentList(call->arguments())); | 10408 CHECK_ALIVE(VisitArgumentList(call->arguments())); |
10567 HValue* context = environment()->LookupContext(); | 10409 HValue* context = environment()->LookupContext(); |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10653 HHasInstanceTypeAndBranch* typecheck = | 10495 HHasInstanceTypeAndBranch* typecheck = |
10654 new(zone()) HHasInstanceTypeAndBranch(function, JS_FUNCTION_TYPE); | 10496 new(zone()) HHasInstanceTypeAndBranch(function, JS_FUNCTION_TYPE); |
10655 HBasicBlock* if_jsfunction = graph()->CreateBasicBlock(); | 10497 HBasicBlock* if_jsfunction = graph()->CreateBasicBlock(); |
10656 HBasicBlock* if_nonfunction = graph()->CreateBasicBlock(); | 10498 HBasicBlock* if_nonfunction = graph()->CreateBasicBlock(); |
10657 HBasicBlock* join = graph()->CreateBasicBlock(); | 10499 HBasicBlock* join = graph()->CreateBasicBlock(); |
10658 typecheck->SetSuccessorAt(0, if_jsfunction); | 10500 typecheck->SetSuccessorAt(0, if_jsfunction); |
10659 typecheck->SetSuccessorAt(1, if_nonfunction); | 10501 typecheck->SetSuccessorAt(1, if_nonfunction); |
10660 current_block()->Finish(typecheck); | 10502 current_block()->Finish(typecheck); |
10661 | 10503 |
10662 set_current_block(if_jsfunction); | 10504 set_current_block(if_jsfunction); |
10663 HInstruction* invoke_result = AddInstruction( | 10505 HInstruction* invoke_result = |
10664 new(zone()) HInvokeFunction(context, function, arg_count)); | 10506 Add<HInvokeFunction>(context, function, arg_count); |
10665 Drop(arg_count); | 10507 Drop(arg_count); |
10666 Push(invoke_result); | 10508 Push(invoke_result); |
10667 if_jsfunction->Goto(join); | 10509 if_jsfunction->Goto(join); |
10668 | 10510 |
10669 set_current_block(if_nonfunction); | 10511 set_current_block(if_nonfunction); |
10670 HInstruction* call_result = AddInstruction( | 10512 HInstruction* call_result = Add<HCallFunction>(context, function, arg_count); |
10671 new(zone()) HCallFunction(context, function, arg_count)); | |
10672 Drop(arg_count); | 10513 Drop(arg_count); |
10673 Push(call_result); | 10514 Push(call_result); |
10674 if_nonfunction->Goto(join); | 10515 if_nonfunction->Goto(join); |
10675 | 10516 |
10676 set_current_block(join); | 10517 set_current_block(join); |
10677 join->SetJoinId(call->id()); | 10518 join->SetJoinId(call->id()); |
10678 return ast_context()->ReturnValue(Pop()); | 10519 return ast_context()->ReturnValue(Pop()); |
10679 } | 10520 } |
10680 | 10521 |
10681 | 10522 |
(...skipping 708 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11390 if (ShouldProduceTraceOutput()) { | 11231 if (ShouldProduceTraceOutput()) { |
11391 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 11232 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
11392 } | 11233 } |
11393 | 11234 |
11394 #ifdef DEBUG | 11235 #ifdef DEBUG |
11395 graph_->Verify(false); // No full verify. | 11236 graph_->Verify(false); // No full verify. |
11396 #endif | 11237 #endif |
11397 } | 11238 } |
11398 | 11239 |
11399 } } // namespace v8::internal | 11240 } } // namespace v8::internal |
OLD | NEW |