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

Side by Side Diff: src/hydrogen.cc

Issue 12385014: Hydrogen stubs for array constructors (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: We still generated the arrays with feature flag off. Fixed. Created 7 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/hydrogen.h ('k') | src/hydrogen-instructions.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 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 1323 matching lines...) Expand 10 before | Expand all | Expand 10 after
1334 mul->ClearFlag(HValue::kCanOverflow); 1334 mul->ClearFlag(HValue::kCanOverflow);
1335 1335
1336 HConstant* header_size = 1336 HConstant* header_size =
1337 new(zone) HConstant(FixedArray::kHeaderSize, Representation::Integer32()); 1337 new(zone) HConstant(FixedArray::kHeaderSize, Representation::Integer32());
1338 AddInstruction(header_size); 1338 AddInstruction(header_size);
1339 HValue* total_size = AddInstruction( 1339 HValue* total_size = AddInstruction(
1340 HAdd::New(zone, context, mul, header_size)); 1340 HAdd::New(zone, context, mul, header_size));
1341 total_size->ChangeRepresentation(Representation::Integer32()); 1341 total_size->ChangeRepresentation(Representation::Integer32());
1342 total_size->ClearFlag(HValue::kCanOverflow); 1342 total_size->ClearFlag(HValue::kCanOverflow);
1343 1343
1344 HAllocate::Flags flags = HAllocate::CAN_ALLOCATE_IN_NEW_SPACE; 1344 HAllocate::Flags flags = HAllocate::DefaultFlags(kind);
1345 if (FLAG_pretenure_literals) { 1345 if (FLAG_pretenure_literals) {
1346 // TODO(hpayer): When pretenuring can be internalized, flags can become
1347 // private to HAllocate.
1346 if (IsFastDoubleElementsKind(kind)) { 1348 if (IsFastDoubleElementsKind(kind)) {
1347 flags = static_cast<HAllocate::Flags>( 1349 flags = static_cast<HAllocate::Flags>(
1348 flags | HAllocate::CAN_ALLOCATE_IN_OLD_DATA_SPACE); 1350 flags | HAllocate::CAN_ALLOCATE_IN_OLD_DATA_SPACE);
1349 } else { 1351 } else {
1350 flags = static_cast<HAllocate::Flags>( 1352 flags = static_cast<HAllocate::Flags>(
1351 flags | HAllocate::CAN_ALLOCATE_IN_OLD_POINTER_SPACE); 1353 flags | HAllocate::CAN_ALLOCATE_IN_OLD_POINTER_SPACE);
1352 } 1354 }
1353 } 1355 }
1354 if (IsFastDoubleElementsKind(kind)) {
1355 flags = static_cast<HAllocate::Flags>(
1356 flags | HAllocate::ALLOCATE_DOUBLE_ALIGNED);
1357 }
1358 1356
1359 HValue* elements = 1357 HValue* elements =
1360 AddInstruction(new(zone) HAllocate(context, total_size, 1358 AddInstruction(new(zone) HAllocate(context, total_size,
1361 HType::JSArray(), flags)); 1359 HType::JSArray(), flags));
1362 return elements; 1360 return elements;
1363 } 1361 }
1364 1362
1365 1363
1366 void HGraphBuilder::BuildInitializeElements(HValue* elements, 1364 void HGraphBuilder::BuildInitializeElements(HValue* elements,
1367 ElementsKind kind, 1365 ElementsKind kind,
(...skipping 15 matching lines...) Expand all
1383 1381
1384 HValue* HGraphBuilder::BuildAllocateAndInitializeElements(HValue* context, 1382 HValue* HGraphBuilder::BuildAllocateAndInitializeElements(HValue* context,
1385 ElementsKind kind, 1383 ElementsKind kind,
1386 HValue* capacity) { 1384 HValue* capacity) {
1387 HValue* new_elements = BuildAllocateElements(context, kind, capacity); 1385 HValue* new_elements = BuildAllocateElements(context, kind, capacity);
1388 BuildInitializeElements(new_elements, kind, capacity); 1386 BuildInitializeElements(new_elements, kind, capacity);
1389 return new_elements; 1387 return new_elements;
1390 } 1388 }
1391 1389
1392 1390
1391 HInnerAllocatedObject* HGraphBuilder::BuildJSArrayHeader(HValue* array,
1392 HValue* array_map,
1393 AllocationSiteMode mode,
1394 HValue* allocation_site_payload,
1395 HValue* length_field) {
1396
1397 BuildStoreMap(array, array_map);
1398
1399 HConstant* empty_fixed_array =
1400 new(zone()) HConstant(
1401 Handle<FixedArray>(isolate()->heap()->empty_fixed_array()),
1402 Representation::Tagged());
1403 AddInstruction(empty_fixed_array);
1404
1405 AddInstruction(new(zone()) HStoreNamedField(array,
1406 isolate()->factory()->properties_field_symbol(),
1407 empty_fixed_array,
1408 true,
1409 JSArray::kPropertiesOffset));
1410
1411 HInstruction* length_store = AddInstruction(
1412 new(zone()) HStoreNamedField(array,
1413 isolate()->factory()->length_field_string(),
1414 length_field,
1415 true,
1416 JSArray::kLengthOffset));
1417 length_store->SetGVNFlag(kChangesArrayLengths);
1418
1419 if (mode == TRACK_ALLOCATION_SITE) {
1420 BuildCreateAllocationSiteInfo(array,
1421 JSArray::kSize,
1422 allocation_site_payload);
1423 }
1424
1425 int elements_location = JSArray::kSize;
1426 if (mode == TRACK_ALLOCATION_SITE) {
1427 elements_location += AllocationSiteInfo::kSize;
1428 }
1429
1430 HInnerAllocatedObject* elements = new(zone()) HInnerAllocatedObject(
1431 array,
1432 elements_location);
1433 AddInstruction(elements);
1434
1435 HInstruction* elements_store = AddInstruction(
1436 new(zone()) HStoreNamedField(
1437 array,
1438 isolate()->factory()->elements_field_string(),
1439 elements,
1440 true,
1441 JSArray::kElementsOffset));
1442 elements_store->SetGVNFlag(kChangesElementsPointer);
1443
1444 return elements;
1445 }
1446
1447
1393 HInstruction* HGraphBuilder::BuildStoreMap(HValue* object, 1448 HInstruction* HGraphBuilder::BuildStoreMap(HValue* object,
1394 HValue* map) { 1449 HValue* map) {
1395 Zone* zone = this->zone(); 1450 Zone* zone = this->zone();
1396 Factory* factory = isolate()->factory(); 1451 Factory* factory = isolate()->factory();
1397 Handle<String> map_field_name = factory->map_field_string(); 1452 Handle<String> map_field_name = factory->map_field_string();
1398 HInstruction* store_map = 1453 HInstruction* store_map =
1399 new(zone) HStoreNamedField(object, map_field_name, map, 1454 new(zone) HStoreNamedField(object, map_field_name, map,
1400 true, JSObject::kMapOffset); 1455 true, JSObject::kMapOffset);
1401 store_map->SetGVNFlag(kChangesMaps); 1456 store_map->SetGVNFlag(kChangesMaps);
1402 AddInstruction(store_map); 1457 AddInstruction(store_map);
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
1496 Factory* factory = isolate()->factory(); 1551 Factory* factory = isolate()->factory();
1497 1552
1498 double nan_double = FixedDoubleArray::hole_nan_as_double(); 1553 double nan_double = FixedDoubleArray::hole_nan_as_double();
1499 Zone* zone = this->zone(); 1554 Zone* zone = this->zone();
1500 HValue* hole = IsFastSmiOrObjectElementsKind(elements_kind) 1555 HValue* hole = IsFastSmiOrObjectElementsKind(elements_kind)
1501 ? AddInstruction(new(zone) HConstant(factory->the_hole_value(), 1556 ? AddInstruction(new(zone) HConstant(factory->the_hole_value(),
1502 Representation::Tagged())) 1557 Representation::Tagged()))
1503 : AddInstruction(new(zone) HConstant(nan_double, 1558 : AddInstruction(new(zone) HConstant(nan_double,
1504 Representation::Double())); 1559 Representation::Double()));
1505 1560
1506 LoopBuilder builder(this, context, LoopBuilder::kPostIncrement); 1561 // Special loop unfolding case
1562 static const int kLoopUnfoldLimit = 4;
1563 bool unfold_loop = false;
1564 int initial_capacity = JSArray::kPreallocatedArrayElements;
1565 if (from->IsConstant() && to->IsConstant() &&
1566 initial_capacity <= kLoopUnfoldLimit) {
1567 HConstant* constant_from = HConstant::cast(from);
1568 HConstant* constant_to = HConstant::cast(to);
1507 1569
1508 HValue* key = builder.BeginBody(from, to, Token::LT); 1570 if (constant_from->HasInteger32Value() &&
1571 constant_from->Integer32Value() == 0 &&
1572 constant_to->HasInteger32Value() &&
1573 constant_to->Integer32Value() == initial_capacity) {
1574 unfold_loop = true;
1575 }
1576 }
1509 1577
1510 AddInstruction(new(zone) HStoreKeyed(elements, key, hole, elements_kind)); 1578 if (unfold_loop) {
1579 for (int i = 0; i < initial_capacity; i++) {
1580 HInstruction* key = AddInstruction(new(zone)
1581 HConstant(i, Representation::Integer32()));
1582 AddInstruction(new(zone) HStoreKeyed(elements, key, hole, elements_kind));
1583 }
1584 } else {
1585 LoopBuilder builder(this, context, LoopBuilder::kPostIncrement);
1511 1586
1512 builder.EndBody(); 1587 HValue* key = builder.BeginBody(from, to, Token::LT);
1588
1589 AddInstruction(new(zone) HStoreKeyed(elements, key, hole, elements_kind));
1590
1591 builder.EndBody();
1592 }
1513 } 1593 }
1514 1594
1515 1595
1516 void HGraphBuilder::BuildCopyElements(HValue* context, 1596 void HGraphBuilder::BuildCopyElements(HValue* context,
1517 HValue* from_elements, 1597 HValue* from_elements,
1518 ElementsKind from_elements_kind, 1598 ElementsKind from_elements_kind,
1519 HValue* to_elements, 1599 HValue* to_elements,
1520 ElementsKind to_elements_kind, 1600 ElementsKind to_elements_kind,
1521 HValue* length, 1601 HValue* length,
1522 HValue* capacity) { 1602 HValue* capacity) {
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
1569 if (mode == TRACK_ALLOCATION_SITE) { 1649 if (mode == TRACK_ALLOCATION_SITE) {
1570 size += AllocationSiteInfo::kSize; 1650 size += AllocationSiteInfo::kSize;
1571 } 1651 }
1572 int elems_offset = size; 1652 int elems_offset = size;
1573 if (length > 0) { 1653 if (length > 0) {
1574 size += IsFastDoubleElementsKind(kind) 1654 size += IsFastDoubleElementsKind(kind)
1575 ? FixedDoubleArray::SizeFor(length) 1655 ? FixedDoubleArray::SizeFor(length)
1576 : FixedArray::SizeFor(length); 1656 : FixedArray::SizeFor(length);
1577 } 1657 }
1578 1658
1579 HAllocate::Flags allocate_flags = HAllocate::CAN_ALLOCATE_IN_NEW_SPACE; 1659 HAllocate::Flags allocate_flags = HAllocate::DefaultFlags(kind);
1580 if (IsFastDoubleElementsKind(kind)) {
1581 allocate_flags = static_cast<HAllocate::Flags>(
1582 allocate_flags | HAllocate::ALLOCATE_DOUBLE_ALIGNED);
1583 }
1584
1585 // Allocate both the JS array and the elements array in one big 1660 // Allocate both the JS array and the elements array in one big
1586 // allocation. This avoids multiple limit checks. 1661 // allocation. This avoids multiple limit checks.
1587 HValue* size_in_bytes = 1662 HValue* size_in_bytes =
1588 AddInstruction(new(zone) HConstant(size, Representation::Integer32())); 1663 AddInstruction(new(zone) HConstant(size, Representation::Integer32()));
1589 HInstruction* object = 1664 HInstruction* object =
1590 AddInstruction(new(zone) HAllocate(context, 1665 AddInstruction(new(zone) HAllocate(context,
1591 size_in_bytes, 1666 size_in_bytes,
1592 HType::JSObject(), 1667 HType::JSObject(),
1593 allocate_flags)); 1668 allocate_flags));
1594 1669
1595 // Copy the JS array part. 1670 // Copy the JS array part.
1596 for (int i = 0; i < JSArray::kSize; i += kPointerSize) { 1671 for (int i = 0; i < JSArray::kSize; i += kPointerSize) {
1597 if ((i != JSArray::kElementsOffset) || (length == 0)) { 1672 if ((i != JSArray::kElementsOffset) || (length == 0)) {
1598 HInstruction* value = 1673 HInstruction* value =
1599 AddInstruction(new(zone) HLoadNamedField(boilerplate, true, i)); 1674 AddInstruction(new(zone) HLoadNamedField(boilerplate, true, i));
1600 if (i != JSArray::kMapOffset) { 1675 if (i != JSArray::kMapOffset) {
1601 AddInstruction(new(zone) HStoreNamedField(object, 1676 AddInstruction(new(zone) HStoreNamedField(object,
1602 factory->empty_string(), 1677 factory->empty_string(),
1603 value, 1678 value,
1604 true, i)); 1679 true, i));
1605 } else { 1680 } else {
1606 BuildStoreMap(object, value); 1681 BuildStoreMap(object, value);
1607 } 1682 }
1608 } 1683 }
1609 } 1684 }
1610 1685
1611 // Create an allocation site info if requested. 1686 // Create an allocation site info if requested.
1612 if (mode == TRACK_ALLOCATION_SITE) { 1687 if (mode == TRACK_ALLOCATION_SITE) {
1613 HValue* alloc_site = 1688 BuildCreateAllocationSiteInfo(object, JSArray::kSize, boilerplate);
1614 AddInstruction(new(zone) HInnerAllocatedObject(object, JSArray::kSize));
1615 Handle<Map> alloc_site_map(isolate()->heap()->allocation_site_info_map());
1616 BuildStoreMap(alloc_site, alloc_site_map);
1617 int alloc_payload_offset = AllocationSiteInfo::kPayloadOffset;
1618 AddInstruction(new(zone) HStoreNamedField(alloc_site,
1619 factory->empty_string(),
1620 boilerplate,
1621 true, alloc_payload_offset));
1622 } 1689 }
1623 1690
1624 if (length > 0) { 1691 if (length > 0) {
1625 // Get hold of the elements array of the boilerplate and setup the 1692 // Get hold of the elements array of the boilerplate and setup the
1626 // elements pointer in the resulting object. 1693 // elements pointer in the resulting object.
1627 HValue* boilerplate_elements = 1694 HValue* boilerplate_elements =
1628 AddInstruction(new(zone) HLoadElements(boilerplate, NULL)); 1695 AddInstruction(new(zone) HLoadElements(boilerplate, NULL));
1629 HValue* object_elements = 1696 HValue* object_elements =
1630 AddInstruction(new(zone) HInnerAllocatedObject(object, elems_offset)); 1697 AddInstruction(new(zone) HInnerAllocatedObject(object, elems_offset));
1631 AddInstruction(new(zone) HStoreNamedField(object, 1698 AddInstruction(new(zone) HStoreNamedField(object,
(...skipping 28 matching lines...) Expand all
1660 key_constant, 1727 key_constant,
1661 value, 1728 value,
1662 kind)); 1729 kind));
1663 } 1730 }
1664 } 1731 }
1665 1732
1666 return object; 1733 return object;
1667 } 1734 }
1668 1735
1669 1736
1737 HValue* HGraphBuilder::BuildCreateAllocationSiteInfo(HValue* previous_object,
1738 int previous_object_size,
1739 HValue* payload) {
1740 HInnerAllocatedObject* alloc_site = new(zone())
1741 HInnerAllocatedObject(previous_object, previous_object_size);
1742 AddInstruction(alloc_site);
1743 Handle<Map> alloc_site_map(isolate()->heap()->allocation_site_info_map());
1744 BuildStoreMap(alloc_site, alloc_site_map);
1745 AddInstruction(new(zone()) HStoreNamedField(alloc_site,
1746 isolate()->factory()->payload_string(),
1747 payload,
1748 true,
1749 AllocationSiteInfo::kPayloadOffset));
1750 return alloc_site;
1751 }
1752
1753
1754 HGraphBuilder::JSArrayBuilder::JSArrayBuilder(HGraphBuilder* builder,
1755 ElementsKind kind,
1756 HValue* allocation_site_payload,
1757 AllocationSiteMode mode) :
1758 builder_(builder),
1759 kind_(kind),
1760 allocation_site_payload_(allocation_site_payload) {
1761 if (mode == DONT_TRACK_ALLOCATION_SITE) {
1762 mode_ = mode;
1763 } else {
1764 mode_ = AllocationSiteInfo::GetMode(kind);
1765 }
1766 }
1767
1768
1769 HValue* HGraphBuilder::JSArrayBuilder::EmitMapCode(HValue* context) {
1770 // Get the global context, the native context, the map array
1771 HInstruction* global_object = AddInstruction(new(zone())
1772 HGlobalObject(context));
1773 HInstruction* native_context = AddInstruction(new(zone())
1774 HLoadNamedField(global_object, true, GlobalObject::kNativeContextOffset));
1775 size_t offset = Context::kHeaderSize +
1776 kPointerSize * Context::JS_ARRAY_MAPS_INDEX;
1777 HInstruction* map_array = AddInstruction(new(zone())
1778 HLoadNamedField(native_context, true, offset));
1779 offset = kind_ * kPointerSize + FixedArrayBase::kHeaderSize;
1780 return AddInstruction(new(zone()) HLoadNamedField(map_array, true, offset));
1781 }
1782
1783
1784 HValue* HGraphBuilder::JSArrayBuilder::EstablishAllocationSize(
1785 HValue* length_node) {
1786 HValue* context = builder()->environment()->LookupContext();
1787 ASSERT(length_node != NULL);
1788
1789 int base_size = JSArray::kSize;
1790 if (mode_ == TRACK_ALLOCATION_SITE) {
1791 base_size += AllocationSiteInfo::kSize;
1792 }
1793
1794 if (IsFastDoubleElementsKind(kind_)) {
1795 base_size += FixedDoubleArray::kHeaderSize;
1796 } else {
1797 base_size += FixedArray::kHeaderSize;
1798 }
1799
1800 HInstruction* elements_size_value = new(zone())
1801 HConstant(elements_size(), Representation::Integer32());
1802 AddInstruction(elements_size_value);
1803 HInstruction* mul = HMul::New(zone(), context, length_node,
1804 elements_size_value);
1805 mul->ChangeRepresentation(Representation::Integer32());
1806 mul->ClearFlag(HValue::kCanOverflow);
1807 AddInstruction(mul);
1808
1809 HInstruction* base = new(zone()) HConstant(base_size,
1810 Representation::Integer32());
1811 AddInstruction(base);
1812 HInstruction* total_size = HAdd::New(zone(), context, base, mul);
1813 total_size->ChangeRepresentation(Representation::Integer32());
1814 total_size->ClearFlag(HValue::kCanOverflow);
1815 AddInstruction(total_size);
1816 return total_size;
1817 }
1818
1819
1820 HValue* HGraphBuilder::JSArrayBuilder::EstablishEmptyArrayAllocationSize() {
1821 int base_size = JSArray::kSize;
1822 if (mode_ == TRACK_ALLOCATION_SITE) {
1823 base_size += AllocationSiteInfo::kSize;
1824 }
1825
1826 base_size += IsFastDoubleElementsKind(kind_)
1827 ? FixedDoubleArray::SizeFor(initial_capacity())
1828 : FixedArray::SizeFor(initial_capacity());
1829
1830 HConstant* array_size =
1831 new(zone()) HConstant(base_size, Representation::Integer32());
1832 AddInstruction(array_size);
1833 return array_size;
1834 }
1835
1836
1837 HValue* HGraphBuilder::JSArrayBuilder::AllocateEmptyArray() {
1838 HValue* size_in_bytes = EstablishEmptyArrayAllocationSize();
1839 HConstant* capacity =
1840 new(zone()) HConstant(initial_capacity(), Representation::Integer32());
1841 AddInstruction(capacity);
1842 return AllocateArray(size_in_bytes,
1843 capacity,
1844 builder()->graph()->GetConstant0(),
1845 true);
1846 }
1847
1848
1849 HValue* HGraphBuilder::JSArrayBuilder::AllocateArray(HValue* capacity,
1850 HValue* length_field,
1851 bool fill_with_hole) {
1852 HValue* size_in_bytes = EstablishAllocationSize(capacity);
1853 return AllocateArray(size_in_bytes, capacity, length_field, fill_with_hole);
1854 }
1855
1856
1857 HValue* HGraphBuilder::JSArrayBuilder::AllocateArray(HValue* size_in_bytes,
1858 HValue* capacity,
1859 HValue* length_field,
1860 bool fill_with_hole) {
1861 HValue* context = builder()->environment()->LookupContext();
1862
1863 // Allocate (dealing with failure appropriately)
1864 HAllocate::Flags flags = HAllocate::DefaultFlags(kind_);
1865 HAllocate* new_object = new(zone()) HAllocate(context, size_in_bytes,
1866 HType::JSArray(), flags);
1867 AddInstruction(new_object);
1868
1869 // Fill in the fields: map, properties, length
1870 HValue* map = EmitMapCode(context);
1871 elements_location_ = builder()->BuildJSArrayHeader(new_object,
1872 map,
1873 mode_,
1874 allocation_site_payload_,
1875 length_field);
1876
1877 // Initialize the elements
1878 builder()->BuildInitializeElements(elements_location_, kind_, capacity);
1879
1880 if (fill_with_hole) {
1881 builder()->BuildFillElementsWithHole(context, elements_location_, kind_,
1882 graph()->GetConstant0(), capacity);
1883 }
1884
1885 return new_object;
1886 }
1887
1888
1670 HOptimizedGraphBuilder::HOptimizedGraphBuilder(CompilationInfo* info, 1889 HOptimizedGraphBuilder::HOptimizedGraphBuilder(CompilationInfo* info,
1671 TypeFeedbackOracle* oracle) 1890 TypeFeedbackOracle* oracle)
1672 : HGraphBuilder(info), 1891 : HGraphBuilder(info),
1673 function_state_(NULL), 1892 function_state_(NULL),
1674 initial_function_state_(this, info, oracle, NORMAL_RETURN), 1893 initial_function_state_(this, info, oracle, NORMAL_RETURN),
1675 ast_context_(NULL), 1894 ast_context_(NULL),
1676 break_scope_(NULL), 1895 break_scope_(NULL),
1677 inlined_count_(0), 1896 inlined_count_(0),
1678 globals_(10, info->zone()), 1897 globals_(10, info->zone()),
1679 inline_bailout_(false) { 1898 inline_bailout_(false) {
(...skipping 7528 matching lines...) Expand 10 before | Expand all | Expand 10 after
9208 receiver->DeleteAndReplaceWith(NULL); 9427 receiver->DeleteAndReplaceWith(NULL);
9209 check->DeleteAndReplaceWith(NULL); 9428 check->DeleteAndReplaceWith(NULL);
9210 environment()->SetExpressionStackAt(receiver_index, function); 9429 environment()->SetExpressionStackAt(receiver_index, function);
9211 HInstruction* call = PreProcessCall( 9430 HInstruction* call = PreProcessCall(
9212 new(zone()) HCallNew(context, function, argument_count)); 9431 new(zone()) HCallNew(context, function, argument_count));
9213 call->set_position(expr->position()); 9432 call->set_position(expr->position());
9214 return ast_context()->ReturnInstruction(call, expr->id()); 9433 return ast_context()->ReturnInstruction(call, expr->id());
9215 } else { 9434 } else {
9216 // The constructor function is both an operand to the instruction and an 9435 // The constructor function is both an operand to the instruction and an
9217 // argument to the construct call. 9436 // argument to the construct call.
9437 bool use_call_new_array = FLAG_optimize_constructed_arrays &&
9438 !(expr->target().is_null()) &&
9439 *(expr->target()) == isolate()->global_context()->array_function();
9440
9218 CHECK_ALIVE(VisitArgument(expr->expression())); 9441 CHECK_ALIVE(VisitArgument(expr->expression()));
9219 HValue* constructor = HPushArgument::cast(Top())->argument(); 9442 HValue* constructor = HPushArgument::cast(Top())->argument();
9220 CHECK_ALIVE(VisitArgumentList(expr->arguments())); 9443 CHECK_ALIVE(VisitArgumentList(expr->arguments()));
9221 HCallNew* call; 9444 HCallNew* call;
9222 if (FLAG_optimize_constructed_arrays && 9445 if (use_call_new_array) {
9223 !(expr->target().is_null()) && 9446 AddInstruction(new(zone()) HCheckFunction(constructor,
9224 *(expr->target()) == isolate()->global_context()->array_function()) { 9447 Handle<JSFunction>(isolate()->global_context()->array_function())));
9225 Handle<Object> feedback = oracle()->GetInfo(expr->CallNewFeedbackId()); 9448 Handle<Object> feedback = oracle()->GetInfo(expr->CallNewFeedbackId());
9226 ASSERT(feedback->IsSmi()); 9449 ASSERT(feedback->IsSmi());
9450
9451 // TODO(mvstanton): It would be better to use the already created global
9452 // property cell that is shared by full code gen. That way, any transition
9453 // information that happened after crankshaft won't be lost. The right
9454 // way to do that is to begin passing the cell to the type feedback oracle
9455 // instead of just the value in the cell. Do this in a follow-up checkin.
9227 Handle<JSGlobalPropertyCell> cell = 9456 Handle<JSGlobalPropertyCell> cell =
9228 isolate()->factory()->NewJSGlobalPropertyCell(feedback); 9457 isolate()->factory()->NewJSGlobalPropertyCell(feedback);
9229 AddInstruction(new(zone()) HCheckFunction(constructor, 9458
9230 Handle<JSFunction>(isolate()->global_context()->array_function()))); 9459 // TODO(mvstanton): Here we should probably insert code to check if the
9460 // type cell elements kind is different from when we compiled, and deopt
9461 // in that case. Do this in a follow-up checin.
9231 call = new(zone()) HCallNewArray(context, constructor, argument_count, 9462 call = new(zone()) HCallNewArray(context, constructor, argument_count,
9232 cell); 9463 cell);
9233 } else { 9464 } else {
9234 call = new(zone()) HCallNew(context, constructor, argument_count); 9465 call = new(zone()) HCallNew(context, constructor, argument_count);
9235 } 9466 }
9236 Drop(argument_count); 9467 Drop(argument_count);
9237 call->set_position(expr->position()); 9468 call->set_position(expr->position());
9238 return ast_context()->ReturnInstruction(call, expr->id()); 9469 return ast_context()->ReturnInstruction(call, expr->id());
9239 } 9470 }
9240 } 9471 }
(...skipping 1092 matching lines...) Expand 10 before | Expand all | Expand 10 after
10333 HInstruction* value_instruction = AddInstruction(new(zone) HConstant( 10564 HInstruction* value_instruction = AddInstruction(new(zone) HConstant(
10334 value, Representation::Tagged())); 10565 value, Representation::Tagged()));
10335 AddInstruction(new(zone) HStoreNamedField( 10566 AddInstruction(new(zone) HStoreNamedField(
10336 object_properties, factory->unknown_field_string(), value_instruction, 10567 object_properties, factory->unknown_field_string(), value_instruction,
10337 true, boilerplate_object->GetInObjectPropertyOffset(i))); 10568 true, boilerplate_object->GetInObjectPropertyOffset(i)));
10338 } 10569 }
10339 } 10570 }
10340 10571
10341 // Build Allocation Site Info if desired 10572 // Build Allocation Site Info if desired
10342 if (create_allocation_site_info) { 10573 if (create_allocation_site_info) {
10343 HValue* alloc_site = 10574 BuildCreateAllocationSiteInfo(target, JSArray::kSize, original_boilerplate);
10344 AddInstruction(new(zone) HInnerAllocatedObject(target, JSArray::kSize));
10345 Handle<Map> alloc_site_map(isolate()->heap()->allocation_site_info_map());
10346 BuildStoreMap(alloc_site, alloc_site_map);
10347 int alloc_payload_offset = AllocationSiteInfo::kPayloadOffset;
10348 AddInstruction(new(zone) HStoreNamedField(alloc_site,
10349 factory->payload_string(),
10350 original_boilerplate,
10351 true, alloc_payload_offset));
10352 } 10575 }
10353 10576
10354 if (object_elements != NULL) { 10577 if (object_elements != NULL) {
10355 HInstruction* boilerplate_elements = AddInstruction(new(zone) HConstant( 10578 HInstruction* boilerplate_elements = AddInstruction(new(zone) HConstant(
10356 elements, Representation::Tagged())); 10579 elements, Representation::Tagged()));
10357 10580
10358 int elements_length = elements->length(); 10581 int elements_length = elements->length();
10359 HValue* object_elements_length = 10582 HValue* object_elements_length =
10360 AddInstruction(new(zone) HConstant( 10583 AddInstruction(new(zone) HConstant(
10361 elements_length, Representation::Integer32())); 10584 elements_length, Representation::Integer32()));
(...skipping 1449 matching lines...) Expand 10 before | Expand all | Expand 10 after
11811 } 12034 }
11812 } 12035 }
11813 12036
11814 #ifdef DEBUG 12037 #ifdef DEBUG
11815 if (graph_ != NULL) graph_->Verify(false); // No full verify. 12038 if (graph_ != NULL) graph_->Verify(false); // No full verify.
11816 if (allocator_ != NULL) allocator_->Verify(); 12039 if (allocator_ != NULL) allocator_->Verify();
11817 #endif 12040 #endif
11818 } 12041 }
11819 12042
11820 } } // namespace v8::internal 12043 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/hydrogen.h ('k') | src/hydrogen-instructions.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698