| 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 |