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 869 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
880 HPhase phase("H_Block building", isolate()); | 880 HPhase phase("H_Block building", isolate()); |
881 set_current_block(graph()->entry_block()); | 881 set_current_block(graph()->entry_block()); |
882 if (!BuildGraph()) return NULL; | 882 if (!BuildGraph()) return NULL; |
883 return graph_; | 883 return graph_; |
884 } | 884 } |
885 | 885 |
886 | 886 |
887 HInstruction* HGraphBuilder::AddInstruction(HInstruction* instr) { | 887 HInstruction* HGraphBuilder::AddInstruction(HInstruction* instr) { |
888 ASSERT(current_block() != NULL); | 888 ASSERT(current_block() != NULL); |
889 current_block()->AddInstruction(instr); | 889 current_block()->AddInstruction(instr); |
| 890 if (no_side_effects_scope_count_ > 0) { |
| 891 instr->SetFlag(HValue::kHasNoObservableSideEffects); |
| 892 } |
890 return instr; | 893 return instr; |
891 } | 894 } |
892 | 895 |
893 | 896 |
894 void HGraphBuilder::AddSimulate(BailoutId id, | 897 void HGraphBuilder::AddSimulate(BailoutId id, |
895 RemovableSimulate removable) { | 898 RemovableSimulate removable) { |
896 ASSERT(current_block() != NULL); | 899 ASSERT(current_block() != NULL); |
| 900 ASSERT(no_side_effects_scope_count_ == 0); |
897 current_block()->AddSimulate(id, removable); | 901 current_block()->AddSimulate(id, removable); |
898 environment()->set_previous_ast_id(id); | 902 environment()->set_previous_ast_id(id); |
899 } | 903 } |
900 | 904 |
901 | 905 |
902 HBoundsCheck* HGraphBuilder::AddBoundsCheck(HValue* index, | 906 HBoundsCheck* HGraphBuilder::AddBoundsCheck(HValue* index, |
903 HValue* length, | 907 HValue* length, |
904 BoundsCheckKeyMode key_mode, | 908 BoundsCheckKeyMode key_mode, |
905 Representation r) { | 909 Representation r) { |
906 if (!index->type().IsSmi()) { | 910 if (!index->type().IsSmi()) { |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1034 elements_kind); | 1038 elements_kind); |
1035 } | 1039 } |
1036 | 1040 |
1037 | 1041 |
1038 HValue* HGraphBuilder::BuildCheckForCapacityGrow(HValue* object, | 1042 HValue* HGraphBuilder::BuildCheckForCapacityGrow(HValue* object, |
1039 HValue* elements, | 1043 HValue* elements, |
1040 ElementsKind kind, | 1044 ElementsKind kind, |
1041 HValue* length, | 1045 HValue* length, |
1042 HValue* key, | 1046 HValue* key, |
1043 bool is_js_array) { | 1047 bool is_js_array) { |
1044 BailoutId ast_id = environment()->previous_ast_id(); | |
1045 Zone* zone = this->zone(); | 1048 Zone* zone = this->zone(); |
1046 IfBuilder length_checker(this); | 1049 IfBuilder length_checker(this); |
1047 | 1050 |
1048 length_checker.BeginIf(length, key, Token::EQ); | 1051 length_checker.BeginIf(length, key, Token::EQ); |
1049 | 1052 |
1050 HValue* current_capacity = | 1053 HValue* current_capacity = |
1051 AddInstruction(new(zone) HFixedArrayBaseLength(elements)); | 1054 AddInstruction(new(zone) HFixedArrayBaseLength(elements)); |
1052 | 1055 |
1053 IfBuilder capacity_checker(this); | 1056 IfBuilder capacity_checker(this); |
1054 | 1057 |
(...skipping 12 matching lines...) Expand all Loading... |
1067 capacity_checker.BeginElse(); | 1070 capacity_checker.BeginElse(); |
1068 | 1071 |
1069 environment()->Push(elements); | 1072 environment()->Push(elements); |
1070 capacity_checker.End(); | 1073 capacity_checker.End(); |
1071 | 1074 |
1072 if (is_js_array) { | 1075 if (is_js_array) { |
1073 HValue* new_length = AddInstruction( | 1076 HValue* new_length = AddInstruction( |
1074 HAdd::New(zone, context, length, graph_->GetConstant1())); | 1077 HAdd::New(zone, context, length, graph_->GetConstant1())); |
1075 new_length->ChangeRepresentation(Representation::Integer32()); | 1078 new_length->ChangeRepresentation(Representation::Integer32()); |
1076 new_length->ClearFlag(HValue::kCanOverflow); | 1079 new_length->ClearFlag(HValue::kCanOverflow); |
1077 AddSimulate(ast_id, REMOVABLE_SIMULATE); | |
1078 | 1080 |
1079 Factory* factory = isolate()->factory(); | 1081 Factory* factory = isolate()->factory(); |
1080 HInstruction* length_store = AddInstruction(new(zone) HStoreNamedField( | 1082 HInstruction* length_store = AddInstruction(new(zone) HStoreNamedField( |
1081 object, | 1083 object, |
1082 factory->length_field_string(), | 1084 factory->length_field_string(), |
1083 new_length, true, | 1085 new_length, true, |
1084 JSArray::kLengthOffset)); | 1086 JSArray::kLengthOffset)); |
1085 length_store->SetGVNFlag(kChangesArrayLengths); | 1087 length_store->SetGVNFlag(kChangesArrayLengths); |
1086 AddSimulate(ast_id, REMOVABLE_SIMULATE); | |
1087 } | 1088 } |
1088 | 1089 |
1089 length_checker.BeginElse(); | 1090 length_checker.BeginElse(); |
1090 | 1091 |
1091 AddBoundsCheck(key, length, ALLOW_SMI_KEY); | 1092 AddBoundsCheck(key, length, ALLOW_SMI_KEY); |
1092 environment()->Push(elements); | 1093 environment()->Push(elements); |
1093 | 1094 |
1094 length_checker.End(); | 1095 length_checker.End(); |
1095 | 1096 |
1096 return environment()->Pop(); | 1097 return environment()->Pop(); |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1203 ASSERT(fast_smi_only_elements || | 1204 ASSERT(fast_smi_only_elements || |
1204 fast_elements || | 1205 fast_elements || |
1205 IsFastDoubleElementsKind(elements_kind)); | 1206 IsFastDoubleElementsKind(elements_kind)); |
1206 | 1207 |
1207 if (is_store && IsFastSmiElementsKind(elements_kind) && | 1208 if (is_store && IsFastSmiElementsKind(elements_kind) && |
1208 !val->type().IsSmi()) { | 1209 !val->type().IsSmi()) { |
1209 AddInstruction(new(zone) HCheckSmi(val)); | 1210 AddInstruction(new(zone) HCheckSmi(val)); |
1210 } | 1211 } |
1211 | 1212 |
1212 if (IsGrowStoreMode(store_mode)) { | 1213 if (IsGrowStoreMode(store_mode)) { |
| 1214 NoObservableSideEffectsScope no_effects(this); |
| 1215 |
1213 elements = BuildCheckForCapacityGrow(object, elements, elements_kind, | 1216 elements = BuildCheckForCapacityGrow(object, elements, elements_kind, |
1214 length, key, is_js_array); | 1217 length, key, is_js_array); |
1215 checked_key = key; | 1218 checked_key = key; |
1216 } else { | 1219 } else { |
1217 checked_key = AddBoundsCheck( | 1220 checked_key = AddBoundsCheck( |
1218 key, length, ALLOW_SMI_KEY, checked_index_representation); | 1221 key, length, ALLOW_SMI_KEY, checked_index_representation); |
1219 | 1222 |
1220 if (is_store && (fast_elements || fast_smi_only_elements)) { | 1223 if (is_store && (fast_elements || fast_smi_only_elements)) { |
1221 if (store_mode == STORE_NO_TRANSITION_HANDLE_COW) { | 1224 if (store_mode == STORE_NO_TRANSITION_HANDLE_COW) { |
| 1225 NoObservableSideEffectsScope no_effects(this); |
| 1226 |
1222 elements = BuildCopyElementsOnWrite(object, elements, elements_kind, | 1227 elements = BuildCopyElementsOnWrite(object, elements, elements_kind, |
1223 length); | 1228 length); |
1224 } else { | 1229 } else { |
1225 HCheckMaps* check_cow_map = new(zone) HCheckMaps( | 1230 HCheckMaps* check_cow_map = new(zone) HCheckMaps( |
1226 elements, isolate()->factory()->fixed_array_map(), zone); | 1231 elements, isolate()->factory()->fixed_array_map(), zone); |
1227 check_cow_map->ClearGVNFlag(kDependsOnElementsKind); | 1232 check_cow_map->ClearGVNFlag(kDependsOnElementsKind); |
1228 AddInstruction(check_cow_map); | 1233 AddInstruction(check_cow_map); |
1229 } | 1234 } |
1230 } | 1235 } |
1231 } | 1236 } |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1285 Handle<Map> map = IsFastDoubleElementsKind(kind) | 1290 Handle<Map> map = IsFastDoubleElementsKind(kind) |
1286 ? factory->fixed_double_array_map() | 1291 ? factory->fixed_double_array_map() |
1287 : factory->fixed_array_map(); | 1292 : factory->fixed_array_map(); |
1288 BuildStoreMap(elements, map, ast_id); | 1293 BuildStoreMap(elements, map, ast_id); |
1289 | 1294 |
1290 Handle<String> fixed_array_length_field_name = factory->length_field_string(); | 1295 Handle<String> fixed_array_length_field_name = factory->length_field_string(); |
1291 HInstruction* store_length = | 1296 HInstruction* store_length = |
1292 new(zone) HStoreNamedField(elements, fixed_array_length_field_name, | 1297 new(zone) HStoreNamedField(elements, fixed_array_length_field_name, |
1293 capacity, true, FixedArray::kLengthOffset); | 1298 capacity, true, FixedArray::kLengthOffset); |
1294 AddInstruction(store_length); | 1299 AddInstruction(store_length); |
1295 AddSimulate(ast_id, REMOVABLE_SIMULATE); | |
1296 } | 1300 } |
1297 | 1301 |
1298 | 1302 |
1299 HValue* HGraphBuilder::BuildAllocateAndInitializeElements(HValue* context, | 1303 HValue* HGraphBuilder::BuildAllocateAndInitializeElements(HValue* context, |
1300 ElementsKind kind, | 1304 ElementsKind kind, |
1301 HValue* capacity) { | 1305 HValue* capacity) { |
1302 HValue* new_elements = | 1306 HValue* new_elements = |
1303 BuildAllocateElements(context, kind, capacity); | 1307 BuildAllocateElements(context, kind, capacity); |
1304 BuildInitializeElements(new_elements, kind, capacity); | 1308 BuildInitializeElements(new_elements, kind, capacity); |
1305 return new_elements; | 1309 return new_elements; |
1306 } | 1310 } |
1307 | 1311 |
1308 | 1312 |
1309 HInstruction* HGraphBuilder::BuildStoreMap(HValue* object, | 1313 HInstruction* HGraphBuilder::BuildStoreMap(HValue* object, |
1310 HValue* map, | 1314 HValue* map, |
1311 BailoutId id) { | 1315 BailoutId id) { |
1312 Zone* zone = this->zone(); | 1316 Zone* zone = this->zone(); |
1313 Factory* factory = isolate()->factory(); | 1317 Factory* factory = isolate()->factory(); |
1314 Handle<String> map_field_name = factory->map_field_string(); | 1318 Handle<String> map_field_name = factory->map_field_string(); |
1315 HInstruction* store_map = | 1319 HInstruction* store_map = |
1316 new(zone) HStoreNamedField(object, map_field_name, map, | 1320 new(zone) HStoreNamedField(object, map_field_name, map, |
1317 true, JSObject::kMapOffset); | 1321 true, JSObject::kMapOffset); |
1318 store_map->SetGVNFlag(kChangesMaps); | 1322 store_map->SetGVNFlag(kChangesMaps); |
1319 AddInstruction(store_map); | 1323 AddInstruction(store_map); |
1320 AddSimulate(id, REMOVABLE_SIMULATE); | |
1321 return store_map; | 1324 return store_map; |
1322 } | 1325 } |
1323 | 1326 |
1324 | 1327 |
1325 HInstruction* HGraphBuilder::BuildStoreMap(HValue* object, | 1328 HInstruction* HGraphBuilder::BuildStoreMap(HValue* object, |
1326 Handle<Map> map, | 1329 Handle<Map> map, |
1327 BailoutId id) { | 1330 BailoutId id) { |
1328 Zone* zone = this->zone(); | 1331 Zone* zone = this->zone(); |
1329 HValue* map_constant = | 1332 HValue* map_constant = |
1330 AddInstruction(new(zone) HConstant(map, Representation::Tagged())); | 1333 AddInstruction(new(zone) HConstant(map, Representation::Tagged())); |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1403 | 1406 |
1404 return new_elements; | 1407 return new_elements; |
1405 } | 1408 } |
1406 | 1409 |
1407 | 1410 |
1408 void HGraphBuilder::BuildFillElementsWithHole(HValue* context, | 1411 void HGraphBuilder::BuildFillElementsWithHole(HValue* context, |
1409 HValue* elements, | 1412 HValue* elements, |
1410 ElementsKind elements_kind, | 1413 ElementsKind elements_kind, |
1411 HValue* from, | 1414 HValue* from, |
1412 HValue* to) { | 1415 HValue* to) { |
1413 BailoutId ast_id = current_block()->last_environment()->previous_ast_id(); | |
1414 // Fast elements kinds need to be initialized in case statements below cause | 1416 // Fast elements kinds need to be initialized in case statements below cause |
1415 // a garbage collection. | 1417 // a garbage collection. |
1416 Factory* factory = isolate()->factory(); | 1418 Factory* factory = isolate()->factory(); |
1417 | 1419 |
1418 double nan_double = FixedDoubleArray::hole_nan_as_double(); | 1420 double nan_double = FixedDoubleArray::hole_nan_as_double(); |
1419 Zone* zone = this->zone(); | 1421 Zone* zone = this->zone(); |
1420 HValue* hole = IsFastSmiOrObjectElementsKind(elements_kind) | 1422 HValue* hole = IsFastSmiOrObjectElementsKind(elements_kind) |
1421 ? AddInstruction(new(zone) HConstant(factory->the_hole_value(), | 1423 ? AddInstruction(new(zone) HConstant(factory->the_hole_value(), |
1422 Representation::Tagged())) | 1424 Representation::Tagged())) |
1423 : AddInstruction(new(zone) HConstant(nan_double, | 1425 : AddInstruction(new(zone) HConstant(nan_double, |
1424 Representation::Double())); | 1426 Representation::Double())); |
1425 | 1427 |
1426 LoopBuilder builder(this, context, LoopBuilder::kPostIncrement); | 1428 LoopBuilder builder(this, context, LoopBuilder::kPostIncrement); |
1427 | 1429 |
1428 HValue* key = builder.BeginBody(from, to, Token::LT); | 1430 HValue* key = builder.BeginBody(from, to, Token::LT); |
1429 | 1431 |
1430 AddInstruction(new(zone) HStoreKeyed(elements, key, hole, elements_kind)); | 1432 AddInstruction(new(zone) HStoreKeyed(elements, key, hole, elements_kind)); |
1431 AddSimulate(ast_id, REMOVABLE_SIMULATE); | |
1432 | 1433 |
1433 builder.EndBody(); | 1434 builder.EndBody(); |
1434 } | 1435 } |
1435 | 1436 |
1436 | 1437 |
1437 void HGraphBuilder::BuildCopyElements(HValue* context, | 1438 void HGraphBuilder::BuildCopyElements(HValue* context, |
1438 HValue* from_elements, | 1439 HValue* from_elements, |
1439 ElementsKind from_elements_kind, | 1440 ElementsKind from_elements_kind, |
1440 HValue* to_elements, | 1441 HValue* to_elements, |
1441 ElementsKind to_elements_kind, | 1442 ElementsKind to_elements_kind, |
1442 HValue* length, | 1443 HValue* length, |
1443 HValue* capacity) { | 1444 HValue* capacity) { |
1444 BailoutId ast_id = environment()->previous_ast_id(); | |
1445 bool pre_fill_with_holes = | 1445 bool pre_fill_with_holes = |
1446 IsFastDoubleElementsKind(from_elements_kind) && | 1446 IsFastDoubleElementsKind(from_elements_kind) && |
1447 IsFastObjectElementsKind(to_elements_kind); | 1447 IsFastObjectElementsKind(to_elements_kind); |
1448 | 1448 |
1449 if (pre_fill_with_holes) { | 1449 if (pre_fill_with_holes) { |
1450 // If the copy might trigger a GC, make sure that the FixedArray is | 1450 // If the copy might trigger a GC, make sure that the FixedArray is |
1451 // pre-initialized with holes to make sure that it's always in a consistent | 1451 // pre-initialized with holes to make sure that it's always in a consistent |
1452 // state. | 1452 // state. |
1453 BuildFillElementsWithHole(context, to_elements, to_elements_kind, | 1453 BuildFillElementsWithHole(context, to_elements, to_elements_kind, |
1454 graph()->GetConstant0(), capacity); | 1454 graph()->GetConstant0(), capacity); |
1455 } | 1455 } |
1456 | 1456 |
1457 LoopBuilder builder(this, context, LoopBuilder::kPostIncrement); | 1457 LoopBuilder builder(this, context, LoopBuilder::kPostIncrement); |
1458 | 1458 |
1459 HValue* key = builder.BeginBody(graph()->GetConstant0(), length, Token::LT); | 1459 HValue* key = builder.BeginBody(graph()->GetConstant0(), length, Token::LT); |
1460 | 1460 |
1461 HValue* element = | 1461 HValue* element = |
1462 AddInstruction(new(zone()) HLoadKeyed(from_elements, key, NULL, | 1462 AddInstruction(new(zone()) HLoadKeyed(from_elements, key, NULL, |
1463 from_elements_kind, | 1463 from_elements_kind, |
1464 ALLOW_RETURN_HOLE)); | 1464 ALLOW_RETURN_HOLE)); |
1465 | 1465 |
1466 AddInstruction(new(zone()) HStoreKeyed(to_elements, key, element, | 1466 AddInstruction(new(zone()) HStoreKeyed(to_elements, key, element, |
1467 to_elements_kind)); | 1467 to_elements_kind)); |
1468 AddSimulate(ast_id, REMOVABLE_SIMULATE); | |
1469 | 1468 |
1470 builder.EndBody(); | 1469 builder.EndBody(); |
1471 | 1470 |
1472 if (!pre_fill_with_holes && length != capacity) { | 1471 if (!pre_fill_with_holes && length != capacity) { |
1473 // Fill unused capacity with the hole. | 1472 // Fill unused capacity with the hole. |
1474 BuildFillElementsWithHole(context, to_elements, to_elements_kind, | 1473 BuildFillElementsWithHole(context, to_elements, to_elements_kind, |
1475 key, capacity); | 1474 key, capacity); |
1476 } | 1475 } |
1477 } | 1476 } |
1478 | 1477 |
1479 | 1478 |
1480 HValue* HGraphBuilder::BuildCloneShallowArray(HContext* context, | 1479 HValue* HGraphBuilder::BuildCloneShallowArray(HContext* context, |
1481 HValue* boilerplate, | 1480 HValue* boilerplate, |
1482 AllocationSiteMode mode, | 1481 AllocationSiteMode mode, |
1483 ElementsKind kind, | 1482 ElementsKind kind, |
1484 BailoutId id, | 1483 BailoutId id, |
1485 int length) { | 1484 int length) { |
1486 Zone* zone = this->zone(); | 1485 Zone* zone = this->zone(); |
1487 Factory* factory = isolate()->factory(); | 1486 Factory* factory = isolate()->factory(); |
1488 | 1487 |
| 1488 NoObservableSideEffectsScope no_effects(this); |
| 1489 |
1489 // All sizes here are multiples of kPointerSize. | 1490 // All sizes here are multiples of kPointerSize. |
1490 int size = JSArray::kSize; | 1491 int size = JSArray::kSize; |
1491 if (mode == TRACK_ALLOCATION_SITE) { | 1492 if (mode == TRACK_ALLOCATION_SITE) { |
1492 size += AllocationSiteInfo::kSize; | 1493 size += AllocationSiteInfo::kSize; |
1493 } | 1494 } |
1494 int elems_offset = size; | 1495 int elems_offset = size; |
1495 if (length > 0) { | 1496 if (length > 0) { |
1496 size += IsFastDoubleElementsKind(kind) | 1497 size += IsFastDoubleElementsKind(kind) |
1497 ? FixedDoubleArray::SizeFor(length) | 1498 ? FixedDoubleArray::SizeFor(length) |
1498 : FixedArray::SizeFor(length); | 1499 : FixedArray::SizeFor(length); |
(...skipping 18 matching lines...) Expand all Loading... |
1517 // Copy the JS array part. | 1518 // Copy the JS array part. |
1518 for (int i = 0; i < JSArray::kSize; i += kPointerSize) { | 1519 for (int i = 0; i < JSArray::kSize; i += kPointerSize) { |
1519 if ((i != JSArray::kElementsOffset) || (length == 0)) { | 1520 if ((i != JSArray::kElementsOffset) || (length == 0)) { |
1520 HInstruction* value = | 1521 HInstruction* value = |
1521 AddInstruction(new(zone) HLoadNamedField(boilerplate, true, i)); | 1522 AddInstruction(new(zone) HLoadNamedField(boilerplate, true, i)); |
1522 if (i != JSArray::kMapOffset) { | 1523 if (i != JSArray::kMapOffset) { |
1523 AddInstruction(new(zone) HStoreNamedField(object, | 1524 AddInstruction(new(zone) HStoreNamedField(object, |
1524 factory->empty_string(), | 1525 factory->empty_string(), |
1525 value, | 1526 value, |
1526 true, i)); | 1527 true, i)); |
1527 AddSimulate(id); | |
1528 } else { | 1528 } else { |
1529 BuildStoreMap(object, value, id); | 1529 BuildStoreMap(object, value, id); |
1530 } | 1530 } |
1531 } | 1531 } |
1532 } | 1532 } |
1533 | 1533 |
1534 // Create an allocation site info if requested. | 1534 // Create an allocation site info if requested. |
1535 if (mode == TRACK_ALLOCATION_SITE) { | 1535 if (mode == TRACK_ALLOCATION_SITE) { |
1536 HValue* alloc_site = | 1536 HValue* alloc_site = |
1537 AddInstruction(new(zone) HInnerAllocatedObject(object, JSArray::kSize)); | 1537 AddInstruction(new(zone) HInnerAllocatedObject(object, JSArray::kSize)); |
1538 Handle<Map> alloc_site_map(isolate()->heap()->allocation_site_info_map()); | 1538 Handle<Map> alloc_site_map(isolate()->heap()->allocation_site_info_map()); |
1539 BuildStoreMap(alloc_site, alloc_site_map, id); | 1539 BuildStoreMap(alloc_site, alloc_site_map, id); |
1540 int alloc_payload_offset = AllocationSiteInfo::kPayloadOffset; | 1540 int alloc_payload_offset = AllocationSiteInfo::kPayloadOffset; |
1541 AddInstruction(new(zone) HStoreNamedField(alloc_site, | 1541 AddInstruction(new(zone) HStoreNamedField(alloc_site, |
1542 factory->empty_string(), | 1542 factory->empty_string(), |
1543 boilerplate, | 1543 boilerplate, |
1544 true, alloc_payload_offset)); | 1544 true, alloc_payload_offset)); |
1545 AddSimulate(id); | |
1546 } | 1545 } |
1547 | 1546 |
1548 if (length > 0) { | 1547 if (length > 0) { |
1549 // Get hold of the elements array of the boilerplate and setup the | 1548 // Get hold of the elements array of the boilerplate and setup the |
1550 // elements pointer in the resulting object. | 1549 // elements pointer in the resulting object. |
1551 HValue* boilerplate_elements = | 1550 HValue* boilerplate_elements = |
1552 AddInstruction(new(zone) HLoadElements(boilerplate, NULL)); | 1551 AddInstruction(new(zone) HLoadElements(boilerplate, NULL)); |
1553 HValue* object_elements = | 1552 HValue* object_elements = |
1554 AddInstruction(new(zone) HInnerAllocatedObject(object, elems_offset)); | 1553 AddInstruction(new(zone) HInnerAllocatedObject(object, elems_offset)); |
1555 AddInstruction(new(zone) HStoreNamedField(object, | 1554 AddInstruction(new(zone) HStoreNamedField(object, |
1556 factory->elements_field_string(), | 1555 factory->elements_field_string(), |
1557 object_elements, | 1556 object_elements, |
1558 true, JSObject::kElementsOffset)); | 1557 true, JSObject::kElementsOffset)); |
1559 AddSimulate(id); | |
1560 | 1558 |
1561 // Copy the elements array header. | 1559 // Copy the elements array header. |
1562 for (int i = 0; i < FixedArrayBase::kHeaderSize; i += kPointerSize) { | 1560 for (int i = 0; i < FixedArrayBase::kHeaderSize; i += kPointerSize) { |
1563 HInstruction* value = | 1561 HInstruction* value = |
1564 AddInstruction(new(zone) HLoadNamedField(boilerplate_elements, | 1562 AddInstruction(new(zone) HLoadNamedField(boilerplate_elements, |
1565 true, i)); | 1563 true, i)); |
1566 AddInstruction(new(zone) HStoreNamedField(object_elements, | 1564 AddInstruction(new(zone) HStoreNamedField(object_elements, |
1567 factory->empty_string(), | 1565 factory->empty_string(), |
1568 value, | 1566 value, |
1569 true, i)); | 1567 true, i)); |
1570 AddSimulate(id); | |
1571 } | 1568 } |
1572 | 1569 |
1573 // Copy the elements array contents. | 1570 // Copy the elements array contents. |
1574 // TODO(mstarzinger): Teach HGraphBuilder::BuildCopyElements to unfold | 1571 // TODO(mstarzinger): Teach HGraphBuilder::BuildCopyElements to unfold |
1575 // copying loops with constant length up to a given boundary and use this | 1572 // copying loops with constant length up to a given boundary and use this |
1576 // helper here instead. | 1573 // helper here instead. |
1577 for (int i = 0; i < length; i++) { | 1574 for (int i = 0; i < length; i++) { |
1578 HValue* key_constant = | 1575 HValue* key_constant = |
1579 AddInstruction(new(zone) HConstant(i, Representation::Integer32())); | 1576 AddInstruction(new(zone) HConstant(i, Representation::Integer32())); |
1580 HInstruction* value = | 1577 HInstruction* value = |
1581 AddInstruction(new(zone) HLoadKeyed(boilerplate_elements, | 1578 AddInstruction(new(zone) HLoadKeyed(boilerplate_elements, |
1582 key_constant, | 1579 key_constant, |
1583 NULL, | 1580 NULL, |
1584 kind)); | 1581 kind)); |
1585 AddInstruction(new(zone) HStoreKeyed(object_elements, | 1582 AddInstruction(new(zone) HStoreKeyed(object_elements, |
1586 key_constant, | 1583 key_constant, |
1587 value, | 1584 value, |
1588 kind)); | 1585 kind)); |
1589 AddSimulate(id); | |
1590 } | 1586 } |
1591 } | 1587 } |
1592 | 1588 |
1593 return object; | 1589 return object; |
1594 } | 1590 } |
1595 | 1591 |
1596 | 1592 |
1597 HOptimizedGraphBuilder::HOptimizedGraphBuilder(CompilationInfo* info, | 1593 HOptimizedGraphBuilder::HOptimizedGraphBuilder(CompilationInfo* info, |
1598 TypeFeedbackOracle* oracle) | 1594 TypeFeedbackOracle* oracle) |
1599 : HGraphBuilder(info), | 1595 : HGraphBuilder(info), |
(...skipping 8492 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10092 | 10088 |
10093 HInstruction* HOptimizedGraphBuilder::BuildFastLiteral( | 10089 HInstruction* HOptimizedGraphBuilder::BuildFastLiteral( |
10094 HValue* context, | 10090 HValue* context, |
10095 Handle<JSObject> boilerplate_object, | 10091 Handle<JSObject> boilerplate_object, |
10096 Handle<JSObject> original_boilerplate_object, | 10092 Handle<JSObject> original_boilerplate_object, |
10097 int size, | 10093 int size, |
10098 AllocationSiteMode mode, | 10094 AllocationSiteMode mode, |
10099 BailoutId id) { | 10095 BailoutId id) { |
10100 Zone* zone = this->zone(); | 10096 Zone* zone = this->zone(); |
10101 | 10097 |
| 10098 NoObservableSideEffectsScope no_effects(this); |
| 10099 |
10102 HValue* size_in_bytes = | 10100 HValue* size_in_bytes = |
10103 AddInstruction(new(zone) HConstant(size, Representation::Integer32())); | 10101 AddInstruction(new(zone) HConstant(size, Representation::Integer32())); |
10104 HInstruction* result = | 10102 HInstruction* result = |
10105 AddInstruction(new(zone) HAllocate(context, | 10103 AddInstruction(new(zone) HAllocate(context, |
10106 size_in_bytes, | 10104 size_in_bytes, |
10107 HType::JSObject(), | 10105 HType::JSObject(), |
10108 HAllocate::CAN_ALLOCATE_IN_NEW_SPACE)); | 10106 HAllocate::CAN_ALLOCATE_IN_NEW_SPACE)); |
10109 int offset = 0; | 10107 int offset = 0; |
10110 BuildEmitDeepCopy(boilerplate_object, original_boilerplate_object, result, | 10108 BuildEmitDeepCopy(boilerplate_object, original_boilerplate_object, result, |
10111 &offset, mode, id); | 10109 &offset, mode, id); |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10165 if (value->IsJSObject()) { | 10163 if (value->IsJSObject()) { |
10166 Handle<JSObject> value_object = Handle<JSObject>::cast(value); | 10164 Handle<JSObject> value_object = Handle<JSObject>::cast(value); |
10167 Handle<JSObject> original_value_object = Handle<JSObject>::cast( | 10165 Handle<JSObject> original_value_object = Handle<JSObject>::cast( |
10168 Handle<Object>(original_boilerplate_object->InObjectPropertyAt(i), | 10166 Handle<Object>(original_boilerplate_object->InObjectPropertyAt(i), |
10169 isolate())); | 10167 isolate())); |
10170 HInstruction* value_instruction = | 10168 HInstruction* value_instruction = |
10171 AddInstruction(new(zone) HInnerAllocatedObject(target, *offset)); | 10169 AddInstruction(new(zone) HInnerAllocatedObject(target, *offset)); |
10172 AddInstruction(new(zone) HStoreNamedField( | 10170 AddInstruction(new(zone) HStoreNamedField( |
10173 object_properties, factory->unknown_field_string(), value_instruction, | 10171 object_properties, factory->unknown_field_string(), value_instruction, |
10174 true, boilerplate_object->GetInObjectPropertyOffset(i))); | 10172 true, boilerplate_object->GetInObjectPropertyOffset(i))); |
10175 AddSimulate(id); | |
10176 BuildEmitDeepCopy(value_object, original_value_object, target, | 10173 BuildEmitDeepCopy(value_object, original_value_object, target, |
10177 offset, DONT_TRACK_ALLOCATION_SITE, id); | 10174 offset, DONT_TRACK_ALLOCATION_SITE, id); |
10178 } else { | 10175 } else { |
10179 HInstruction* value_instruction = AddInstruction(new(zone) HConstant( | 10176 HInstruction* value_instruction = AddInstruction(new(zone) HConstant( |
10180 value, Representation::Tagged())); | 10177 value, Representation::Tagged())); |
10181 AddInstruction(new(zone) HStoreNamedField( | 10178 AddInstruction(new(zone) HStoreNamedField( |
10182 object_properties, factory->unknown_field_string(), value_instruction, | 10179 object_properties, factory->unknown_field_string(), value_instruction, |
10183 true, boilerplate_object->GetInObjectPropertyOffset(i))); | 10180 true, boilerplate_object->GetInObjectPropertyOffset(i))); |
10184 AddSimulate(id); | |
10185 } | 10181 } |
10186 } | 10182 } |
10187 | 10183 |
10188 // Build Allocation Site Info if desired | 10184 // Build Allocation Site Info if desired |
10189 if (create_allocation_site_info) { | 10185 if (create_allocation_site_info) { |
10190 HValue* alloc_site = | 10186 HValue* alloc_site = |
10191 AddInstruction(new(zone) HInnerAllocatedObject(target, JSArray::kSize)); | 10187 AddInstruction(new(zone) HInnerAllocatedObject(target, JSArray::kSize)); |
10192 Handle<Map> alloc_site_map(isolate()->heap()->allocation_site_info_map()); | 10188 Handle<Map> alloc_site_map(isolate()->heap()->allocation_site_info_map()); |
10193 BuildStoreMap(alloc_site, alloc_site_map, id); | 10189 BuildStoreMap(alloc_site, alloc_site_map, id); |
10194 int alloc_payload_offset = AllocationSiteInfo::kPayloadOffset; | 10190 int alloc_payload_offset = AllocationSiteInfo::kPayloadOffset; |
10195 AddInstruction(new(zone) HStoreNamedField(alloc_site, | 10191 AddInstruction(new(zone) HStoreNamedField(alloc_site, |
10196 factory->payload_string(), | 10192 factory->payload_string(), |
10197 original_boilerplate, | 10193 original_boilerplate, |
10198 true, alloc_payload_offset)); | 10194 true, alloc_payload_offset)); |
10199 AddSimulate(id); | |
10200 } | 10195 } |
10201 | 10196 |
10202 if (object_elements != NULL) { | 10197 if (object_elements != NULL) { |
10203 HInstruction* boilerplate_elements = AddInstruction(new(zone) HConstant( | 10198 HInstruction* boilerplate_elements = AddInstruction(new(zone) HConstant( |
10204 elements, Representation::Tagged())); | 10199 elements, Representation::Tagged())); |
10205 | 10200 |
10206 int elements_length = elements->length(); | 10201 int elements_length = elements->length(); |
10207 HValue* object_elements_length = | 10202 HValue* object_elements_length = |
10208 AddInstruction(new(zone) HConstant( | 10203 AddInstruction(new(zone) HConstant( |
10209 elements_length, Representation::Integer32())); | 10204 elements_length, Representation::Integer32())); |
10210 | 10205 |
10211 BuildInitializeElements(object_elements, kind, object_elements_length); | 10206 BuildInitializeElements(object_elements, kind, object_elements_length); |
10212 | 10207 |
10213 // Copy elements backing store content. | 10208 // Copy elements backing store content. |
10214 if (elements->IsFixedDoubleArray()) { | 10209 if (elements->IsFixedDoubleArray()) { |
10215 for (int i = 0; i < elements_length; i++) { | 10210 for (int i = 0; i < elements_length; i++) { |
10216 HValue* key_constant = | 10211 HValue* key_constant = |
10217 AddInstruction(new(zone) HConstant(i, Representation::Integer32())); | 10212 AddInstruction(new(zone) HConstant(i, Representation::Integer32())); |
10218 HInstruction* value_instruction = | 10213 HInstruction* value_instruction = |
10219 AddInstruction(new(zone) HLoadKeyed( | 10214 AddInstruction(new(zone) HLoadKeyed( |
10220 boilerplate_elements, key_constant, NULL, kind)); | 10215 boilerplate_elements, key_constant, NULL, kind)); |
10221 AddInstruction(new(zone) HStoreKeyed( | 10216 AddInstruction(new(zone) HStoreKeyed( |
10222 object_elements, key_constant, value_instruction, kind)); | 10217 object_elements, key_constant, value_instruction, kind)); |
10223 AddSimulate(id); | |
10224 } | 10218 } |
10225 } else if (elements->IsFixedArray()) { | 10219 } else if (elements->IsFixedArray()) { |
10226 Handle<FixedArray> fast_elements = Handle<FixedArray>::cast(elements); | 10220 Handle<FixedArray> fast_elements = Handle<FixedArray>::cast(elements); |
10227 Handle<FixedArray> original_fast_elements = | 10221 Handle<FixedArray> original_fast_elements = |
10228 Handle<FixedArray>::cast(original_elements); | 10222 Handle<FixedArray>::cast(original_elements); |
10229 for (int i = 0; i < elements_length; i++) { | 10223 for (int i = 0; i < elements_length; i++) { |
10230 Handle<Object> value(fast_elements->get(i), isolate()); | 10224 Handle<Object> value(fast_elements->get(i), isolate()); |
10231 HValue* key_constant = | 10225 HValue* key_constant = |
10232 AddInstruction(new(zone) HConstant(i, Representation::Integer32())); | 10226 AddInstruction(new(zone) HConstant(i, Representation::Integer32())); |
10233 if (value->IsJSObject()) { | 10227 if (value->IsJSObject()) { |
10234 Handle<JSObject> value_object = Handle<JSObject>::cast(value); | 10228 Handle<JSObject> value_object = Handle<JSObject>::cast(value); |
10235 Handle<JSObject> original_value_object = Handle<JSObject>::cast( | 10229 Handle<JSObject> original_value_object = Handle<JSObject>::cast( |
10236 Handle<Object>(original_fast_elements->get(i), isolate())); | 10230 Handle<Object>(original_fast_elements->get(i), isolate())); |
10237 HInstruction* value_instruction = | 10231 HInstruction* value_instruction = |
10238 AddInstruction(new(zone) HInnerAllocatedObject(target, *offset)); | 10232 AddInstruction(new(zone) HInnerAllocatedObject(target, *offset)); |
10239 AddInstruction(new(zone) HStoreKeyed( | 10233 AddInstruction(new(zone) HStoreKeyed( |
10240 object_elements, key_constant, value_instruction, kind)); | 10234 object_elements, key_constant, value_instruction, kind)); |
10241 AddSimulate(id); | |
10242 BuildEmitDeepCopy(value_object, original_value_object, target, | 10235 BuildEmitDeepCopy(value_object, original_value_object, target, |
10243 offset, DONT_TRACK_ALLOCATION_SITE, id); | 10236 offset, DONT_TRACK_ALLOCATION_SITE, id); |
10244 } else { | 10237 } else { |
10245 HInstruction* value_instruction = | 10238 HInstruction* value_instruction = |
10246 AddInstruction(new(zone) HLoadKeyed( | 10239 AddInstruction(new(zone) HLoadKeyed( |
10247 boilerplate_elements, key_constant, NULL, kind)); | 10240 boilerplate_elements, key_constant, NULL, kind)); |
10248 AddInstruction(new(zone) HStoreKeyed( | 10241 AddInstruction(new(zone) HStoreKeyed( |
10249 object_elements, key_constant, value_instruction, kind)); | 10242 object_elements, key_constant, value_instruction, kind)); |
10250 AddSimulate(id); | |
10251 } | 10243 } |
10252 } | 10244 } |
10253 } else { | 10245 } else { |
10254 UNREACHABLE(); | 10246 UNREACHABLE(); |
10255 } | 10247 } |
10256 } | 10248 } |
10257 } | 10249 } |
10258 | 10250 |
10259 | 10251 |
10260 HValue* HOptimizedGraphBuilder::BuildCopyObjectHeader( | 10252 HValue* HOptimizedGraphBuilder::BuildCopyObjectHeader( |
(...skipping 23 matching lines...) Expand all Loading... |
10284 elements = AddInstruction(new(zone) HInnerAllocatedObject( | 10276 elements = AddInstruction(new(zone) HInnerAllocatedObject( |
10285 target, elements_offset)); | 10277 target, elements_offset)); |
10286 result = elements; | 10278 result = elements; |
10287 } | 10279 } |
10288 HInstruction* elements_store = AddInstruction(new(zone) HStoreNamedField( | 10280 HInstruction* elements_store = AddInstruction(new(zone) HStoreNamedField( |
10289 object_header, | 10281 object_header, |
10290 factory->elements_field_string(), | 10282 factory->elements_field_string(), |
10291 elements, | 10283 elements, |
10292 true, JSObject::kElementsOffset)); | 10284 true, JSObject::kElementsOffset)); |
10293 elements_store->SetGVNFlag(kChangesElementsPointer); | 10285 elements_store->SetGVNFlag(kChangesElementsPointer); |
10294 AddSimulate(id); | |
10295 | 10286 |
10296 Handle<Object> properties_field = | 10287 Handle<Object> properties_field = |
10297 Handle<Object>(boilerplate_object->properties(), isolate()); | 10288 Handle<Object>(boilerplate_object->properties(), isolate()); |
10298 ASSERT(*properties_field == isolate()->heap()->empty_fixed_array()); | 10289 ASSERT(*properties_field == isolate()->heap()->empty_fixed_array()); |
10299 HInstruction* properties = AddInstruction(new(zone) HConstant( | 10290 HInstruction* properties = AddInstruction(new(zone) HConstant( |
10300 properties_field, Representation::None())); | 10291 properties_field, Representation::None())); |
10301 AddInstruction(new(zone) HStoreNamedField(object_header, | 10292 AddInstruction(new(zone) HStoreNamedField(object_header, |
10302 factory->empty_string(), | 10293 factory->empty_string(), |
10303 properties, | 10294 properties, |
10304 true, JSObject::kPropertiesOffset)); | 10295 true, JSObject::kPropertiesOffset)); |
10305 AddSimulate(id); | |
10306 | 10296 |
10307 if (boilerplate_object->IsJSArray()) { | 10297 if (boilerplate_object->IsJSArray()) { |
10308 Handle<JSArray> boilerplate_array = | 10298 Handle<JSArray> boilerplate_array = |
10309 Handle<JSArray>::cast(boilerplate_object); | 10299 Handle<JSArray>::cast(boilerplate_object); |
10310 Handle<Object> length_field = | 10300 Handle<Object> length_field = |
10311 Handle<Object>(boilerplate_array->length(), isolate()); | 10301 Handle<Object>(boilerplate_array->length(), isolate()); |
10312 HInstruction* length = AddInstruction(new(zone) HConstant( | 10302 HInstruction* length = AddInstruction(new(zone) HConstant( |
10313 length_field, Representation::None())); | 10303 length_field, Representation::None())); |
10314 HInstruction* length_store = AddInstruction(new(zone) HStoreNamedField( | 10304 HInstruction* length_store = AddInstruction(new(zone) HStoreNamedField( |
10315 object_header, | 10305 object_header, |
10316 factory->length_field_string(), | 10306 factory->length_field_string(), |
10317 length, | 10307 length, |
10318 true, JSArray::kLengthOffset)); | 10308 true, JSArray::kLengthOffset)); |
10319 length_store->SetGVNFlag(kChangesArrayLengths); | 10309 length_store->SetGVNFlag(kChangesArrayLengths); |
10320 AddSimulate(id); | |
10321 } | 10310 } |
10322 | 10311 |
10323 return result; | 10312 return result; |
10324 } | 10313 } |
10325 | 10314 |
10326 | 10315 |
10327 void HOptimizedGraphBuilder::VisitThisFunction(ThisFunction* expr) { | 10316 void HOptimizedGraphBuilder::VisitThisFunction(ThisFunction* expr) { |
10328 ASSERT(!HasStackOverflow()); | 10317 ASSERT(!HasStackOverflow()); |
10329 ASSERT(current_block() != NULL); | 10318 ASSERT(current_block() != NULL); |
10330 ASSERT(current_block()->HasPredecessor()); | 10319 ASSERT(current_block()->HasPredecessor()); |
(...skipping 1335 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11666 } | 11655 } |
11667 } | 11656 } |
11668 | 11657 |
11669 #ifdef DEBUG | 11658 #ifdef DEBUG |
11670 if (graph_ != NULL) graph_->Verify(false); // No full verify. | 11659 if (graph_ != NULL) graph_->Verify(false); // No full verify. |
11671 if (allocator_ != NULL) allocator_->Verify(); | 11660 if (allocator_ != NULL) allocator_->Verify(); |
11672 #endif | 11661 #endif |
11673 } | 11662 } |
11674 | 11663 |
11675 } } // namespace v8::internal | 11664 } } // namespace v8::internal |
OLD | NEW |