Chromium Code Reviews| 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 1245 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1256 mul->ClearFlag(HValue::kCanOverflow); | 1256 mul->ClearFlag(HValue::kCanOverflow); |
| 1257 | 1257 |
| 1258 HConstant* header_size = | 1258 HConstant* header_size = |
| 1259 new(zone) HConstant(FixedArray::kHeaderSize, Representation::Integer32()); | 1259 new(zone) HConstant(FixedArray::kHeaderSize, Representation::Integer32()); |
| 1260 AddInstruction(header_size); | 1260 AddInstruction(header_size); |
| 1261 HValue* total_size = AddInstruction( | 1261 HValue* total_size = AddInstruction( |
| 1262 HAdd::New(zone, context, mul, header_size)); | 1262 HAdd::New(zone, context, mul, header_size)); |
| 1263 total_size->ChangeRepresentation(Representation::Integer32()); | 1263 total_size->ChangeRepresentation(Representation::Integer32()); |
| 1264 total_size->ClearFlag(HValue::kCanOverflow); | 1264 total_size->ClearFlag(HValue::kCanOverflow); |
| 1265 | 1265 |
| 1266 HAllocate::Flags flags = HAllocate::CAN_ALLOCATE_IN_NEW_SPACE; | 1266 HAllocate::Flags flags = HAllocate::DefaultFlags(kind); |
| 1267 if (FLAG_pretenure_literals) { | 1267 if (FLAG_pretenure_literals) { |
| 1268 // TODO(hpayer): When pretenuring can be internalized, flags can become | |
| 1269 // private to HAllocate. | |
| 1268 if (IsFastDoubleElementsKind(kind)) { | 1270 if (IsFastDoubleElementsKind(kind)) { |
| 1269 flags = static_cast<HAllocate::Flags>( | 1271 flags = static_cast<HAllocate::Flags>( |
| 1270 flags | HAllocate::CAN_ALLOCATE_IN_OLD_DATA_SPACE); | 1272 flags | HAllocate::CAN_ALLOCATE_IN_OLD_DATA_SPACE); |
| 1271 } else { | 1273 } else { |
| 1272 flags = static_cast<HAllocate::Flags>( | 1274 flags = static_cast<HAllocate::Flags>( |
| 1273 flags | HAllocate::CAN_ALLOCATE_IN_OLD_POINTER_SPACE); | 1275 flags | HAllocate::CAN_ALLOCATE_IN_OLD_POINTER_SPACE); |
| 1274 } | 1276 } |
| 1275 } | 1277 } |
| 1276 if (IsFastDoubleElementsKind(kind)) { | |
| 1277 flags = static_cast<HAllocate::Flags>( | |
| 1278 flags | HAllocate::ALLOCATE_DOUBLE_ALIGNED); | |
| 1279 } | |
| 1280 | 1278 |
| 1281 HValue* elements = | 1279 HValue* elements = |
| 1282 AddInstruction(new(zone) HAllocate(context, total_size, | 1280 AddInstruction(new(zone) HAllocate(context, total_size, |
| 1283 HType::JSArray(), flags)); | 1281 HType::JSArray(), flags)); |
| 1284 return elements; | 1282 return elements; |
| 1285 } | 1283 } |
| 1286 | 1284 |
| 1287 | 1285 |
| 1288 void HGraphBuilder::BuildInitializeElements(HValue* elements, | 1286 void HGraphBuilder::BuildInitializeElements(HValue* elements, |
| 1289 ElementsKind kind, | 1287 ElementsKind kind, |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 1306 HValue* HGraphBuilder::BuildAllocateAndInitializeElements(HValue* context, | 1304 HValue* HGraphBuilder::BuildAllocateAndInitializeElements(HValue* context, |
| 1307 ElementsKind kind, | 1305 ElementsKind kind, |
| 1308 HValue* capacity) { | 1306 HValue* capacity) { |
| 1309 HValue* new_elements = | 1307 HValue* new_elements = |
| 1310 BuildAllocateElements(context, kind, capacity); | 1308 BuildAllocateElements(context, kind, capacity); |
| 1311 BuildInitializeElements(new_elements, kind, capacity); | 1309 BuildInitializeElements(new_elements, kind, capacity); |
| 1312 return new_elements; | 1310 return new_elements; |
| 1313 } | 1311 } |
| 1314 | 1312 |
| 1315 | 1313 |
| 1314 HInnerAllocatedObject* HGraphBuilder::BuildJSArrayHeader(HValue* array, | |
| 1315 HValue* array_map, | |
| 1316 AllocationSiteMode mode, | |
| 1317 HValue* allocation_site_payload, | |
| 1318 HValue* length_field) { | |
| 1319 | |
| 1320 BuildStoreMap(array, array_map); | |
| 1321 | |
| 1322 HConstant* empty_fixed_array = | |
| 1323 new(zone()) HConstant( | |
| 1324 Handle<FixedArray>(isolate()->heap()->empty_fixed_array()), | |
| 1325 Representation::Tagged()); | |
| 1326 AddInstruction(empty_fixed_array); | |
| 1327 | |
| 1328 AddInstruction(new(zone()) HStoreNamedField(array, | |
| 1329 isolate()->factory()->properties_field_symbol(), | |
| 1330 empty_fixed_array, | |
| 1331 true, | |
| 1332 JSArray::kPropertiesOffset)); | |
| 1333 | |
| 1334 AddInstruction(new(zone()) HStoreNamedField(array, | |
| 1335 isolate()->factory()->length_field_string(), | |
| 1336 length_field, | |
| 1337 true, | |
| 1338 JSArray::kLengthOffset)); | |
|
Hannes Payer (out of office)
2013/04/18 11:14:39
I think you have to take care of the GVN flags her
mvstanton
2013/04/18 13:39:26
Done.
| |
| 1339 | |
| 1340 if (mode == TRACK_ALLOCATION_SITE) { | |
| 1341 BuildCreateAllocationSiteInfo(array, | |
| 1342 JSArray::kSize, | |
| 1343 allocation_site_payload); | |
| 1344 } | |
| 1345 | |
| 1346 int elements_location = JSArray::kSize; | |
| 1347 if (mode == TRACK_ALLOCATION_SITE) { | |
| 1348 elements_location += AllocationSiteInfo::kSize; | |
| 1349 } | |
| 1350 | |
| 1351 HInnerAllocatedObject* elements = new(zone()) HInnerAllocatedObject( | |
| 1352 array, | |
| 1353 elements_location); | |
| 1354 AddInstruction(elements); | |
| 1355 | |
| 1356 AddInstruction(new(zone()) HStoreNamedField( | |
| 1357 array, | |
| 1358 isolate()->factory()->elements_field_string(), | |
| 1359 elements, | |
| 1360 true, | |
| 1361 JSArray::kElementsOffset)); | |
|
Hannes Payer (out of office)
2013/04/18 11:14:39
I think you have to take care of the GVN flags her
mvstanton
2013/04/18 13:39:26
Done.
| |
| 1362 | |
| 1363 return elements; | |
| 1364 } | |
| 1365 | |
| 1366 | |
| 1316 HInstruction* HGraphBuilder::BuildStoreMap(HValue* object, | 1367 HInstruction* HGraphBuilder::BuildStoreMap(HValue* object, |
| 1317 HValue* map) { | 1368 HValue* map) { |
| 1318 Zone* zone = this->zone(); | 1369 Zone* zone = this->zone(); |
| 1319 Factory* factory = isolate()->factory(); | 1370 Factory* factory = isolate()->factory(); |
| 1320 Handle<String> map_field_name = factory->map_field_string(); | 1371 Handle<String> map_field_name = factory->map_field_string(); |
| 1321 HInstruction* store_map = | 1372 HInstruction* store_map = |
| 1322 new(zone) HStoreNamedField(object, map_field_name, map, | 1373 new(zone) HStoreNamedField(object, map_field_name, map, |
| 1323 true, JSObject::kMapOffset); | 1374 true, JSObject::kMapOffset); |
| 1324 store_map->SetGVNFlag(kChangesMaps); | 1375 store_map->SetGVNFlag(kChangesMaps); |
| 1325 AddInstruction(store_map); | 1376 AddInstruction(store_map); |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1419 Factory* factory = isolate()->factory(); | 1470 Factory* factory = isolate()->factory(); |
| 1420 | 1471 |
| 1421 double nan_double = FixedDoubleArray::hole_nan_as_double(); | 1472 double nan_double = FixedDoubleArray::hole_nan_as_double(); |
| 1422 Zone* zone = this->zone(); | 1473 Zone* zone = this->zone(); |
| 1423 HValue* hole = IsFastSmiOrObjectElementsKind(elements_kind) | 1474 HValue* hole = IsFastSmiOrObjectElementsKind(elements_kind) |
| 1424 ? AddInstruction(new(zone) HConstant(factory->the_hole_value(), | 1475 ? AddInstruction(new(zone) HConstant(factory->the_hole_value(), |
| 1425 Representation::Tagged())) | 1476 Representation::Tagged())) |
| 1426 : AddInstruction(new(zone) HConstant(nan_double, | 1477 : AddInstruction(new(zone) HConstant(nan_double, |
| 1427 Representation::Double())); | 1478 Representation::Double())); |
| 1428 | 1479 |
| 1429 LoopBuilder builder(this, context, LoopBuilder::kPostIncrement); | 1480 // Special loop unfolding case |
| 1481 static const int kLoopUnfoldLimit = 4; | |
| 1482 bool unfold_loop = false; | |
| 1483 int initial_capacity = JSArray::kPreallocatedArrayElements; | |
| 1484 if (from->IsConstant() && to->IsConstant() && | |
| 1485 initial_capacity <= kLoopUnfoldLimit) { | |
| 1486 HConstant* constant_from = HConstant::cast(from); | |
| 1487 HConstant* constant_to = HConstant::cast(to); | |
| 1430 | 1488 |
| 1431 HValue* key = builder.BeginBody(from, to, Token::LT); | 1489 if (constant_from->HasInteger32Value() && |
| 1490 constant_from->Integer32Value() == 0 && | |
| 1491 constant_to->HasInteger32Value() && | |
| 1492 constant_to->Integer32Value() == initial_capacity) { | |
| 1493 unfold_loop = true; | |
| 1494 } | |
| 1495 } | |
| 1432 | 1496 |
| 1433 AddInstruction(new(zone) HStoreKeyed(elements, key, hole, elements_kind)); | 1497 if (unfold_loop) { |
| 1498 for (int i = 0; i < initial_capacity; i++) { | |
| 1499 HInstruction* key = AddInstruction(new(zone) | |
| 1500 HConstant(i, Representation::Integer32())); | |
| 1501 AddInstruction(new(zone) HStoreKeyed(elements, key, hole, elements_kind)); | |
| 1502 } | |
| 1503 } else { | |
| 1504 LoopBuilder builder(this, context, LoopBuilder::kPostIncrement); | |
| 1434 | 1505 |
| 1435 builder.EndBody(); | 1506 HValue* key = builder.BeginBody(from, to, Token::LT); |
| 1507 | |
| 1508 AddInstruction(new(zone) HStoreKeyed(elements, key, hole, elements_kind)); | |
| 1509 | |
| 1510 builder.EndBody(); | |
| 1511 } | |
| 1436 } | 1512 } |
| 1437 | 1513 |
| 1438 | 1514 |
| 1439 void HGraphBuilder::BuildCopyElements(HValue* context, | 1515 void HGraphBuilder::BuildCopyElements(HValue* context, |
| 1440 HValue* from_elements, | 1516 HValue* from_elements, |
| 1441 ElementsKind from_elements_kind, | 1517 ElementsKind from_elements_kind, |
| 1442 HValue* to_elements, | 1518 HValue* to_elements, |
| 1443 ElementsKind to_elements_kind, | 1519 ElementsKind to_elements_kind, |
| 1444 HValue* length, | 1520 HValue* length, |
| 1445 HValue* capacity) { | 1521 HValue* capacity) { |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1492 if (mode == TRACK_ALLOCATION_SITE) { | 1568 if (mode == TRACK_ALLOCATION_SITE) { |
| 1493 size += AllocationSiteInfo::kSize; | 1569 size += AllocationSiteInfo::kSize; |
| 1494 } | 1570 } |
| 1495 int elems_offset = size; | 1571 int elems_offset = size; |
| 1496 if (length > 0) { | 1572 if (length > 0) { |
| 1497 size += IsFastDoubleElementsKind(kind) | 1573 size += IsFastDoubleElementsKind(kind) |
| 1498 ? FixedDoubleArray::SizeFor(length) | 1574 ? FixedDoubleArray::SizeFor(length) |
| 1499 : FixedArray::SizeFor(length); | 1575 : FixedArray::SizeFor(length); |
| 1500 } | 1576 } |
| 1501 | 1577 |
| 1502 HAllocate::Flags allocate_flags = HAllocate::CAN_ALLOCATE_IN_NEW_SPACE; | 1578 HAllocate::Flags allocate_flags = HAllocate::DefaultFlags(kind); |
| 1503 if (IsFastDoubleElementsKind(kind)) { | |
| 1504 allocate_flags = static_cast<HAllocate::Flags>( | |
| 1505 allocate_flags | HAllocate::ALLOCATE_DOUBLE_ALIGNED); | |
| 1506 } | |
| 1507 | |
| 1508 // Allocate both the JS array and the elements array in one big | 1579 // Allocate both the JS array and the elements array in one big |
| 1509 // allocation. This avoids multiple limit checks. | 1580 // allocation. This avoids multiple limit checks. |
| 1510 HValue* size_in_bytes = | 1581 HValue* size_in_bytes = |
| 1511 AddInstruction(new(zone) HConstant(size, Representation::Integer32())); | 1582 AddInstruction(new(zone) HConstant(size, Representation::Integer32())); |
| 1512 HInstruction* object = | 1583 HInstruction* object = |
| 1513 AddInstruction(new(zone) HAllocate(context, | 1584 AddInstruction(new(zone) HAllocate(context, |
| 1514 size_in_bytes, | 1585 size_in_bytes, |
| 1515 HType::JSObject(), | 1586 HType::JSObject(), |
| 1516 allocate_flags)); | 1587 allocate_flags)); |
| 1517 | 1588 |
| 1518 // Copy the JS array part. | 1589 // Copy the JS array part. |
| 1519 for (int i = 0; i < JSArray::kSize; i += kPointerSize) { | 1590 for (int i = 0; i < JSArray::kSize; i += kPointerSize) { |
| 1520 if ((i != JSArray::kElementsOffset) || (length == 0)) { | 1591 if ((i != JSArray::kElementsOffset) || (length == 0)) { |
| 1521 HInstruction* value = | 1592 HInstruction* value = |
| 1522 AddInstruction(new(zone) HLoadNamedField(boilerplate, true, i)); | 1593 AddInstruction(new(zone) HLoadNamedField(boilerplate, true, i)); |
| 1523 if (i != JSArray::kMapOffset) { | 1594 if (i != JSArray::kMapOffset) { |
| 1524 AddInstruction(new(zone) HStoreNamedField(object, | 1595 AddInstruction(new(zone) HStoreNamedField(object, |
| 1525 factory->empty_string(), | 1596 factory->empty_string(), |
| 1526 value, | 1597 value, |
| 1527 true, i)); | 1598 true, i)); |
| 1528 } else { | 1599 } else { |
| 1529 BuildStoreMap(object, value); | 1600 BuildStoreMap(object, value); |
| 1530 } | 1601 } |
| 1531 } | 1602 } |
| 1532 } | 1603 } |
| 1533 | 1604 |
| 1534 // Create an allocation site info if requested. | 1605 // Create an allocation site info if requested. |
| 1535 if (mode == TRACK_ALLOCATION_SITE) { | 1606 if (mode == TRACK_ALLOCATION_SITE) { |
| 1536 HValue* alloc_site = | 1607 BuildCreateAllocationSiteInfo(object, JSArray::kSize, boilerplate); |
| 1537 AddInstruction(new(zone) HInnerAllocatedObject(object, JSArray::kSize)); | |
| 1538 Handle<Map> alloc_site_map(isolate()->heap()->allocation_site_info_map()); | |
| 1539 BuildStoreMap(alloc_site, alloc_site_map); | |
| 1540 int alloc_payload_offset = AllocationSiteInfo::kPayloadOffset; | |
| 1541 AddInstruction(new(zone) HStoreNamedField(alloc_site, | |
| 1542 factory->empty_string(), | |
| 1543 boilerplate, | |
| 1544 true, alloc_payload_offset)); | |
| 1545 } | 1608 } |
| 1546 | 1609 |
| 1547 if (length > 0) { | 1610 if (length > 0) { |
| 1548 // Get hold of the elements array of the boilerplate and setup the | 1611 // Get hold of the elements array of the boilerplate and setup the |
| 1549 // elements pointer in the resulting object. | 1612 // elements pointer in the resulting object. |
| 1550 HValue* boilerplate_elements = | 1613 HValue* boilerplate_elements = |
| 1551 AddInstruction(new(zone) HLoadElements(boilerplate, NULL)); | 1614 AddInstruction(new(zone) HLoadElements(boilerplate, NULL)); |
| 1552 HValue* object_elements = | 1615 HValue* object_elements = |
| 1553 AddInstruction(new(zone) HInnerAllocatedObject(object, elems_offset)); | 1616 AddInstruction(new(zone) HInnerAllocatedObject(object, elems_offset)); |
| 1554 AddInstruction(new(zone) HStoreNamedField(object, | 1617 AddInstruction(new(zone) HStoreNamedField(object, |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 1583 key_constant, | 1646 key_constant, |
| 1584 value, | 1647 value, |
| 1585 kind)); | 1648 kind)); |
| 1586 } | 1649 } |
| 1587 } | 1650 } |
| 1588 | 1651 |
| 1589 return object; | 1652 return object; |
| 1590 } | 1653 } |
| 1591 | 1654 |
| 1592 | 1655 |
| 1656 HValue* HGraphBuilder::BuildCreateAllocationSiteInfo(HValue* previous_object, | |
| 1657 int previous_object_size, | |
| 1658 HValue* payload) { | |
| 1659 HInnerAllocatedObject* alloc_site = new(zone()) | |
| 1660 HInnerAllocatedObject(previous_object, previous_object_size); | |
| 1661 AddInstruction(alloc_site); | |
| 1662 Handle<Map> alloc_site_map(isolate()->heap()->allocation_site_info_map()); | |
| 1663 BuildStoreMap(alloc_site, alloc_site_map); | |
| 1664 AddInstruction(new(zone()) HStoreNamedField(alloc_site, | |
| 1665 isolate()->factory()->payload_string(), | |
| 1666 payload, | |
| 1667 true, | |
| 1668 AllocationSiteInfo::kPayloadOffset)); | |
| 1669 return alloc_site; | |
| 1670 } | |
| 1671 | |
| 1672 | |
| 1673 HGraphBuilder::JSArrayBuilder::JSArrayBuilder(HGraphBuilder* builder, | |
| 1674 ElementsKind kind, | |
| 1675 HValue* allocation_site_payload, | |
| 1676 AllocationSiteMode mode) : | |
| 1677 builder_(builder), | |
| 1678 kind_(kind), | |
| 1679 allocation_site_payload_(allocation_site_payload) { | |
| 1680 // Determine mode | |
|
Hannes Payer (out of office)
2013/04/18 11:14:39
you can remove the comment, the following code sho
mvstanton
2013/04/18 13:39:26
Done.
| |
| 1681 if (mode == DONT_TRACK_ALLOCATION_SITE) { | |
| 1682 mode_ = mode; | |
| 1683 } else { | |
| 1684 mode_ = AllocationSiteInfo::GetMode(kind); | |
| 1685 } | |
| 1686 } | |
| 1687 | |
| 1688 | |
| 1689 HValue* HGraphBuilder::JSArrayBuilder::EmitMapCode(HValue* context) { | |
| 1690 // Get the global context, the native context, the map array | |
| 1691 HInstruction* global_object = AddInstruction(new(zone()) | |
| 1692 HGlobalObject(context)); | |
|
Hannes Payer (out of office)
2013/04/18 11:14:39
Why do you need the global_object?
mvstanton
2013/04/18 13:39:26
You mean instead of saying isolate()->native_conte
Hannes Payer (out of office)
2013/04/23 11:42:50
Never mind, keep it...
| |
| 1693 HInstruction* native_context = AddInstruction(new(zone()) | |
| 1694 HLoadNamedField(global_object, true, GlobalObject::kNativeContextOffset)); | |
| 1695 size_t offset = Context::kHeaderSize + | |
| 1696 kPointerSize * Context::JS_ARRAY_MAPS_INDEX; | |
| 1697 HInstruction* map_array = AddInstruction(new(zone()) | |
| 1698 HLoadNamedField(native_context, true, offset)); | |
| 1699 offset = kind_ * kPointerSize + FixedArrayBase::kHeaderSize; | |
| 1700 return AddInstruction(new(zone()) HLoadNamedField(map_array, true, offset)); | |
| 1701 } | |
| 1702 | |
| 1703 | |
| 1704 HValue* HGraphBuilder::JSArrayBuilder::EstablishAllocationSize( | |
| 1705 HValue* length_node) { | |
| 1706 HValue* context = builder()->environment()->LookupContext(); | |
| 1707 ASSERT(length_node != NULL); | |
| 1708 | |
| 1709 int base_size = JSArray::kSize; | |
| 1710 if (mode_ == TRACK_ALLOCATION_SITE) { | |
| 1711 base_size += AllocationSiteInfo::kSize; | |
| 1712 } | |
| 1713 | |
| 1714 if (IsFastDoubleElementsKind(kind_)) { | |
| 1715 base_size += FixedDoubleArray::kHeaderSize; | |
| 1716 } else { | |
| 1717 base_size += FixedArray::kHeaderSize; | |
| 1718 } | |
| 1719 | |
| 1720 HInstruction* elements_size_value = new(zone()) | |
| 1721 HConstant(elements_size(), Representation::Integer32()); | |
| 1722 AddInstruction(elements_size_value); | |
| 1723 HInstruction* mul = HMul::New(zone(), context, length_node, | |
| 1724 elements_size_value); | |
| 1725 mul->ChangeRepresentation(Representation::Integer32()); | |
| 1726 mul->ClearFlag(HValue::kCanOverflow); | |
| 1727 AddInstruction(mul); | |
| 1728 | |
| 1729 HInstruction* base = new(zone()) HConstant(base_size, | |
| 1730 Representation::Integer32()); | |
| 1731 AddInstruction(base); | |
| 1732 HInstruction* total_size = HAdd::New(zone(), context, base, mul); | |
| 1733 total_size->ChangeRepresentation(Representation::Integer32()); | |
| 1734 total_size->ClearFlag(HValue::kCanOverflow); | |
| 1735 AddInstruction(total_size); | |
| 1736 return total_size; | |
| 1737 } | |
| 1738 | |
| 1739 | |
| 1740 HValue* HGraphBuilder::JSArrayBuilder::EstablishEmptyArrayAllocationSize() { | |
| 1741 int base_size = JSArray::kSize; | |
| 1742 if (mode_ == TRACK_ALLOCATION_SITE) { | |
| 1743 base_size += AllocationSiteInfo::kSize; | |
| 1744 } | |
| 1745 | |
| 1746 base_size += IsFastDoubleElementsKind(kind_) | |
| 1747 ? FixedDoubleArray::SizeFor(initial_capacity()) | |
| 1748 : FixedArray::SizeFor(initial_capacity()); | |
| 1749 | |
| 1750 HConstant* array_size = | |
| 1751 new(zone()) HConstant(base_size, Representation::Integer32()); | |
| 1752 AddInstruction(array_size); | |
| 1753 return array_size; | |
| 1754 } | |
| 1755 | |
| 1756 | |
| 1757 HValue* HGraphBuilder::JSArrayBuilder::AllocateEmptyArray() { | |
| 1758 HValue* size_in_bytes = EstablishEmptyArrayAllocationSize(); | |
| 1759 HConstant* capacity = | |
| 1760 new(zone()) HConstant(initial_capacity(), Representation::Integer32()); | |
| 1761 AddInstruction(capacity); | |
| 1762 return AllocateArray(size_in_bytes, | |
| 1763 capacity, | |
| 1764 builder()->graph()->GetConstant0(), | |
| 1765 true); | |
| 1766 } | |
| 1767 | |
| 1768 | |
| 1769 HValue* HGraphBuilder::JSArrayBuilder::AllocateArray(HValue* capacity, | |
| 1770 HValue* length_field, | |
| 1771 bool fill_with_hole) { | |
| 1772 HValue* size_in_bytes = EstablishAllocationSize(capacity); | |
| 1773 return AllocateArray(size_in_bytes, capacity, length_field, fill_with_hole); | |
| 1774 } | |
| 1775 | |
| 1776 | |
| 1777 HValue* HGraphBuilder::JSArrayBuilder::AllocateArray(HValue* size_in_bytes, | |
| 1778 HValue* capacity, | |
| 1779 HValue* length_field, | |
| 1780 bool fill_with_hole) { | |
| 1781 HValue* context = builder()->environment()->LookupContext(); | |
| 1782 | |
| 1783 // Allocate (dealing with failure appropriately) | |
| 1784 HAllocate::Flags flags = HAllocate::DefaultFlags(kind_); | |
| 1785 HAllocate* new_object = new(zone()) HAllocate(context, size_in_bytes, | |
| 1786 HType::JSArray(), flags); | |
| 1787 AddInstruction(new_object); | |
| 1788 | |
| 1789 // Fill in the fields: map, properties, length | |
| 1790 HValue* map = EmitMapCode(context); | |
| 1791 elements_location_ = builder()->BuildJSArrayHeader(new_object, | |
| 1792 map, | |
| 1793 mode_, | |
| 1794 allocation_site_payload_, | |
| 1795 length_field); | |
| 1796 | |
| 1797 // Initialize the elements | |
| 1798 builder()->BuildInitializeElements(elements_location_, kind_, capacity); | |
| 1799 | |
| 1800 if (fill_with_hole) { | |
| 1801 builder()->BuildFillElementsWithHole(context, elements_location_, kind_, | |
| 1802 graph()->GetConstant0(), capacity); | |
| 1803 } | |
| 1804 | |
| 1805 return new_object; | |
| 1806 } | |
| 1807 | |
| 1808 | |
| 1593 HOptimizedGraphBuilder::HOptimizedGraphBuilder(CompilationInfo* info, | 1809 HOptimizedGraphBuilder::HOptimizedGraphBuilder(CompilationInfo* info, |
| 1594 TypeFeedbackOracle* oracle) | 1810 TypeFeedbackOracle* oracle) |
| 1595 : HGraphBuilder(info), | 1811 : HGraphBuilder(info), |
| 1596 function_state_(NULL), | 1812 function_state_(NULL), |
| 1597 initial_function_state_(this, info, oracle, NORMAL_RETURN), | 1813 initial_function_state_(this, info, oracle, NORMAL_RETURN), |
| 1598 ast_context_(NULL), | 1814 ast_context_(NULL), |
| 1599 break_scope_(NULL), | 1815 break_scope_(NULL), |
| 1600 inlined_count_(0), | 1816 inlined_count_(0), |
| 1601 globals_(10, info->zone()), | 1817 globals_(10, info->zone()), |
| 1602 inline_bailout_(false) { | 1818 inline_bailout_(false) { |
| (...skipping 7449 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 9052 receiver->DeleteAndReplaceWith(NULL); | 9268 receiver->DeleteAndReplaceWith(NULL); |
| 9053 check->DeleteAndReplaceWith(NULL); | 9269 check->DeleteAndReplaceWith(NULL); |
| 9054 environment()->SetExpressionStackAt(receiver_index, function); | 9270 environment()->SetExpressionStackAt(receiver_index, function); |
| 9055 HInstruction* call = PreProcessCall( | 9271 HInstruction* call = PreProcessCall( |
| 9056 new(zone()) HCallNew(context, function, argument_count)); | 9272 new(zone()) HCallNew(context, function, argument_count)); |
| 9057 call->set_position(expr->position()); | 9273 call->set_position(expr->position()); |
| 9058 return ast_context()->ReturnInstruction(call, expr->id()); | 9274 return ast_context()->ReturnInstruction(call, expr->id()); |
| 9059 } else { | 9275 } else { |
| 9060 // The constructor function is both an operand to the instruction and an | 9276 // The constructor function is both an operand to the instruction and an |
| 9061 // argument to the construct call. | 9277 // argument to the construct call. |
| 9278 bool use_call_new_array = FLAG_optimize_constructed_arrays && | |
| 9279 !(expr->target().is_null()) && | |
| 9280 *(expr->target()) == isolate()->global_context()->array_function(); | |
| 9281 | |
| 9062 CHECK_ALIVE(VisitArgument(expr->expression())); | 9282 CHECK_ALIVE(VisitArgument(expr->expression())); |
| 9063 HValue* constructor = HPushArgument::cast(Top())->argument(); | 9283 HValue* constructor = HPushArgument::cast(Top())->argument(); |
| 9064 CHECK_ALIVE(VisitArgumentList(expr->arguments())); | 9284 CHECK_ALIVE(VisitArgumentList(expr->arguments())); |
| 9065 HCallNew* call; | 9285 HCallNew* call; |
| 9066 if (FLAG_optimize_constructed_arrays && | 9286 if (use_call_new_array) { |
| 9067 !(expr->target().is_null()) && | 9287 AddInstruction(new(zone()) HCheckFunction(constructor, |
| 9068 *(expr->target()) == isolate()->global_context()->array_function()) { | 9288 Handle<JSFunction>(isolate()->global_context()->array_function()))); |
| 9069 Handle<Object> feedback = oracle()->GetInfo(expr->CallNewFeedbackId()); | 9289 Handle<Object> feedback = oracle()->GetInfo(expr->CallNewFeedbackId()); |
| 9070 ASSERT(feedback->IsSmi()); | 9290 ASSERT(feedback->IsSmi()); |
| 9291 // TODO(mvstanton): This is a bug because it makes a new JS property cell. | |
|
Hannes Payer (out of office)
2013/04/18 11:14:39
As discussed offline, this is not a bug but one co
mvstanton
2013/04/18 13:39:26
Done.
| |
| 9292 // INstead we need to use the same property cell as we used in the full | |
| 9293 // code gen case. The right way to do that is to begin passing the cell to | |
|
Hannes Payer (out of office)
2013/04/18 11:14:39
Instead
| |
| 9294 // the type feedback oracle instead of just the value in the cell. Almost | |
| 9295 // everyone will then just be interested in the value, but in my special | |
| 9296 // case I am interested in the cell itself (as well as the value). | |
| 9071 Handle<JSGlobalPropertyCell> cell = | 9297 Handle<JSGlobalPropertyCell> cell = |
| 9072 isolate()->factory()->NewJSGlobalPropertyCell(feedback); | 9298 isolate()->factory()->NewJSGlobalPropertyCell(feedback); |
| 9073 AddInstruction(new(zone()) HCheckFunction(constructor, | 9299 |
| 9074 Handle<JSFunction>(isolate()->global_context()->array_function()))); | 9300 // TODO(mvstanton): Here we should probably insert code to check if the |
| 9301 // type cell elements kind is different from when we compiled, and deopt | |
| 9302 // in that case. Right now we don't because of environment/simulate | |
| 9303 // issues. | |
| 9075 call = new(zone()) HCallNewArray(context, constructor, argument_count, | 9304 call = new(zone()) HCallNewArray(context, constructor, argument_count, |
| 9076 cell); | 9305 cell); |
| 9077 } else { | 9306 } else { |
| 9078 call = new(zone()) HCallNew(context, constructor, argument_count); | 9307 call = new(zone()) HCallNew(context, constructor, argument_count); |
| 9079 } | 9308 } |
| 9080 Drop(argument_count); | 9309 Drop(argument_count); |
| 9081 call->set_position(expr->position()); | 9310 call->set_position(expr->position()); |
| 9082 return ast_context()->ReturnInstruction(call, expr->id()); | 9311 return ast_context()->ReturnInstruction(call, expr->id()); |
| 9083 } | 9312 } |
| 9084 } | 9313 } |
| (...skipping 1108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 10193 HInstruction* value_instruction = AddInstruction(new(zone) HConstant( | 10422 HInstruction* value_instruction = AddInstruction(new(zone) HConstant( |
| 10194 value, Representation::Tagged())); | 10423 value, Representation::Tagged())); |
| 10195 AddInstruction(new(zone) HStoreNamedField( | 10424 AddInstruction(new(zone) HStoreNamedField( |
| 10196 object_properties, factory->unknown_field_string(), value_instruction, | 10425 object_properties, factory->unknown_field_string(), value_instruction, |
| 10197 true, boilerplate_object->GetInObjectPropertyOffset(i))); | 10426 true, boilerplate_object->GetInObjectPropertyOffset(i))); |
| 10198 } | 10427 } |
| 10199 } | 10428 } |
| 10200 | 10429 |
| 10201 // Build Allocation Site Info if desired | 10430 // Build Allocation Site Info if desired |
| 10202 if (create_allocation_site_info) { | 10431 if (create_allocation_site_info) { |
| 10203 HValue* alloc_site = | 10432 BuildCreateAllocationSiteInfo(target, JSArray::kSize, original_boilerplate); |
| 10204 AddInstruction(new(zone) HInnerAllocatedObject(target, JSArray::kSize)); | |
| 10205 Handle<Map> alloc_site_map(isolate()->heap()->allocation_site_info_map()); | |
| 10206 BuildStoreMap(alloc_site, alloc_site_map); | |
| 10207 int alloc_payload_offset = AllocationSiteInfo::kPayloadOffset; | |
| 10208 AddInstruction(new(zone) HStoreNamedField(alloc_site, | |
| 10209 factory->payload_string(), | |
| 10210 original_boilerplate, | |
| 10211 true, alloc_payload_offset)); | |
| 10212 } | 10433 } |
| 10213 | 10434 |
| 10214 if (object_elements != NULL) { | 10435 if (object_elements != NULL) { |
| 10215 HInstruction* boilerplate_elements = AddInstruction(new(zone) HConstant( | 10436 HInstruction* boilerplate_elements = AddInstruction(new(zone) HConstant( |
| 10216 elements, Representation::Tagged())); | 10437 elements, Representation::Tagged())); |
| 10217 | 10438 |
| 10218 int elements_length = elements->length(); | 10439 int elements_length = elements->length(); |
| 10219 HValue* object_elements_length = | 10440 HValue* object_elements_length = |
| 10220 AddInstruction(new(zone) HConstant( | 10441 AddInstruction(new(zone) HConstant( |
| 10221 elements_length, Representation::Integer32())); | 10442 elements_length, Representation::Integer32())); |
| (...skipping 1455 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 11677 } | 11898 } |
| 11678 } | 11899 } |
| 11679 | 11900 |
| 11680 #ifdef DEBUG | 11901 #ifdef DEBUG |
| 11681 if (graph_ != NULL) graph_->Verify(false); // No full verify. | 11902 if (graph_ != NULL) graph_->Verify(false); // No full verify. |
| 11682 if (allocator_ != NULL) allocator_->Verify(); | 11903 if (allocator_ != NULL) allocator_->Verify(); |
| 11683 #endif | 11904 #endif |
| 11684 } | 11905 } |
| 11685 | 11906 |
| 11686 } } // namespace v8::internal | 11907 } } // namespace v8::internal |
| OLD | NEW |