Chromium Code Reviews

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: REBASE Created 7 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff | | Annotate | Revision Log
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 1385 matching lines...)
1396 mul->ClearFlag(HValue::kCanOverflow); 1396 mul->ClearFlag(HValue::kCanOverflow);
1397 1397
1398 HConstant* header_size = 1398 HConstant* header_size =
1399 new(zone) HConstant(FixedArray::kHeaderSize, Representation::Integer32()); 1399 new(zone) HConstant(FixedArray::kHeaderSize, Representation::Integer32());
1400 AddInstruction(header_size); 1400 AddInstruction(header_size);
1401 HValue* total_size = AddInstruction( 1401 HValue* total_size = AddInstruction(
1402 HAdd::New(zone, context, mul, header_size)); 1402 HAdd::New(zone, context, mul, header_size));
1403 total_size->ChangeRepresentation(Representation::Integer32()); 1403 total_size->ChangeRepresentation(Representation::Integer32());
1404 total_size->ClearFlag(HValue::kCanOverflow); 1404 total_size->ClearFlag(HValue::kCanOverflow);
1405 1405
1406 HAllocate::Flags flags = HAllocate::CAN_ALLOCATE_IN_NEW_SPACE; 1406 HAllocate::Flags flags = HAllocate::DefaultFlags(kind);
1407 if (FLAG_pretenure_literals) { 1407 if (FLAG_pretenure_literals) {
1408 // TODO(hpayer): When pretenuring can be internalized, flags can become
1409 // private to HAllocate.
1408 if (IsFastDoubleElementsKind(kind)) { 1410 if (IsFastDoubleElementsKind(kind)) {
1409 flags = static_cast<HAllocate::Flags>( 1411 flags = static_cast<HAllocate::Flags>(
1410 flags | HAllocate::CAN_ALLOCATE_IN_OLD_DATA_SPACE); 1412 flags | HAllocate::CAN_ALLOCATE_IN_OLD_DATA_SPACE);
1411 } else { 1413 } else {
1412 flags = static_cast<HAllocate::Flags>( 1414 flags = static_cast<HAllocate::Flags>(
1413 flags | HAllocate::CAN_ALLOCATE_IN_OLD_POINTER_SPACE); 1415 flags | HAllocate::CAN_ALLOCATE_IN_OLD_POINTER_SPACE);
1414 } 1416 }
1415 } 1417 }
1416 if (IsFastDoubleElementsKind(kind)) {
1417 flags = static_cast<HAllocate::Flags>(
1418 flags | HAllocate::ALLOCATE_DOUBLE_ALIGNED);
1419 }
1420 1418
1421 HValue* elements = 1419 HValue* elements =
1422 AddInstruction(new(zone) HAllocate(context, total_size, 1420 AddInstruction(new(zone) HAllocate(context, total_size,
1423 HType::JSArray(), flags)); 1421 HType::JSArray(), flags));
1424 return elements; 1422 return elements;
1425 } 1423 }
1426 1424
1427 1425
1428 void HGraphBuilder::BuildInitializeElements(HValue* elements, 1426 void HGraphBuilder::BuildInitializeElements(HValue* elements,
1429 ElementsKind kind, 1427 ElementsKind kind,
(...skipping 15 matching lines...)
1445 1443
1446 HValue* HGraphBuilder::BuildAllocateAndInitializeElements(HValue* context, 1444 HValue* HGraphBuilder::BuildAllocateAndInitializeElements(HValue* context,
1447 ElementsKind kind, 1445 ElementsKind kind,
1448 HValue* capacity) { 1446 HValue* capacity) {
1449 HValue* new_elements = BuildAllocateElements(context, kind, capacity); 1447 HValue* new_elements = BuildAllocateElements(context, kind, capacity);
1450 BuildInitializeElements(new_elements, kind, capacity); 1448 BuildInitializeElements(new_elements, kind, capacity);
1451 return new_elements; 1449 return new_elements;
1452 } 1450 }
1453 1451
1454 1452
1453 HInnerAllocatedObject* HGraphBuilder::BuildJSArrayHeader(HValue* array,
1454 HValue* array_map,
1455 AllocationSiteMode mode,
1456 HValue* allocation_site_payload,
1457 HValue* length_field) {
1458
1459 BuildStoreMap(array, array_map);
1460
1461 HConstant* empty_fixed_array =
1462 new(zone()) HConstant(
1463 Handle<FixedArray>(isolate()->heap()->empty_fixed_array()),
1464 Representation::Tagged());
1465 AddInstruction(empty_fixed_array);
1466
1467 AddInstruction(new(zone()) HStoreNamedField(array,
1468 isolate()->factory()->properties_field_symbol(),
1469 empty_fixed_array,
1470 true,
1471 JSArray::kPropertiesOffset));
1472
1473 HInstruction* length_store = AddInstruction(
1474 new(zone()) HStoreNamedField(array,
1475 isolate()->factory()->length_field_string(),
1476 length_field,
1477 true,
1478 JSArray::kLengthOffset));
1479 length_store->SetGVNFlag(kChangesArrayLengths);
1480
1481 if (mode == TRACK_ALLOCATION_SITE) {
1482 BuildCreateAllocationSiteInfo(array,
1483 JSArray::kSize,
1484 allocation_site_payload);
1485 }
1486
1487 int elements_location = JSArray::kSize;
1488 if (mode == TRACK_ALLOCATION_SITE) {
1489 elements_location += AllocationSiteInfo::kSize;
1490 }
1491
1492 HInnerAllocatedObject* elements = new(zone()) HInnerAllocatedObject(
1493 array,
1494 elements_location);
1495 AddInstruction(elements);
1496
1497 HInstruction* elements_store = AddInstruction(
1498 new(zone()) HStoreNamedField(
1499 array,
1500 isolate()->factory()->elements_field_string(),
1501 elements,
1502 true,
1503 JSArray::kElementsOffset));
1504 elements_store->SetGVNFlag(kChangesElementsPointer);
1505
1506 return elements;
1507 }
1508
1509
1455 HInstruction* HGraphBuilder::BuildStoreMap(HValue* object, 1510 HInstruction* HGraphBuilder::BuildStoreMap(HValue* object,
1456 HValue* map) { 1511 HValue* map) {
1457 Zone* zone = this->zone(); 1512 Zone* zone = this->zone();
1458 Factory* factory = isolate()->factory(); 1513 Factory* factory = isolate()->factory();
1459 Handle<String> map_field_name = factory->map_field_string(); 1514 Handle<String> map_field_name = factory->map_field_string();
1460 HInstruction* store_map = 1515 HInstruction* store_map =
1461 new(zone) HStoreNamedField(object, map_field_name, map, 1516 new(zone) HStoreNamedField(object, map_field_name, map,
1462 true, JSObject::kMapOffset); 1517 true, JSObject::kMapOffset);
1463 store_map->SetGVNFlag(kChangesMaps); 1518 store_map->SetGVNFlag(kChangesMaps);
1464 AddInstruction(store_map); 1519 AddInstruction(store_map);
(...skipping 93 matching lines...)
1558 Factory* factory = isolate()->factory(); 1613 Factory* factory = isolate()->factory();
1559 1614
1560 double nan_double = FixedDoubleArray::hole_nan_as_double(); 1615 double nan_double = FixedDoubleArray::hole_nan_as_double();
1561 Zone* zone = this->zone(); 1616 Zone* zone = this->zone();
1562 HValue* hole = IsFastSmiOrObjectElementsKind(elements_kind) 1617 HValue* hole = IsFastSmiOrObjectElementsKind(elements_kind)
1563 ? AddInstruction(new(zone) HConstant(factory->the_hole_value(), 1618 ? AddInstruction(new(zone) HConstant(factory->the_hole_value(),
1564 Representation::Tagged())) 1619 Representation::Tagged()))
1565 : AddInstruction(new(zone) HConstant(nan_double, 1620 : AddInstruction(new(zone) HConstant(nan_double,
1566 Representation::Double())); 1621 Representation::Double()));
1567 1622
1568 LoopBuilder builder(this, context, LoopBuilder::kPostIncrement); 1623 // Special loop unfolding case
1624 static const int kLoopUnfoldLimit = 4;
1625 bool unfold_loop = false;
1626 int initial_capacity = JSArray::kPreallocatedArrayElements;
1627 if (from->IsConstant() && to->IsConstant() &&
1628 initial_capacity <= kLoopUnfoldLimit) {
1629 HConstant* constant_from = HConstant::cast(from);
1630 HConstant* constant_to = HConstant::cast(to);
1569 1631
1570 HValue* key = builder.BeginBody(from, to, Token::LT); 1632 if (constant_from->HasInteger32Value() &&
1633 constant_from->Integer32Value() == 0 &&
1634 constant_to->HasInteger32Value() &&
1635 constant_to->Integer32Value() == initial_capacity) {
1636 unfold_loop = true;
1637 }
1638 }
1571 1639
1572 AddInstruction(new(zone) HStoreKeyed(elements, key, hole, elements_kind)); 1640 if (unfold_loop) {
1641 for (int i = 0; i < initial_capacity; i++) {
1642 HInstruction* key = AddInstruction(new(zone)
1643 HConstant(i, Representation::Integer32()));
1644 AddInstruction(new(zone) HStoreKeyed(elements, key, hole, elements_kind));
1645 }
1646 } else {
1647 LoopBuilder builder(this, context, LoopBuilder::kPostIncrement);
1573 1648
1574 builder.EndBody(); 1649 HValue* key = builder.BeginBody(from, to, Token::LT);
1650
1651 AddInstruction(new(zone) HStoreKeyed(elements, key, hole, elements_kind));
1652
1653 builder.EndBody();
1654 }
1575 } 1655 }
1576 1656
1577 1657
1578 void HGraphBuilder::BuildCopyElements(HValue* context, 1658 void HGraphBuilder::BuildCopyElements(HValue* context,
1579 HValue* from_elements, 1659 HValue* from_elements,
1580 ElementsKind from_elements_kind, 1660 ElementsKind from_elements_kind,
1581 HValue* to_elements, 1661 HValue* to_elements,
1582 ElementsKind to_elements_kind, 1662 ElementsKind to_elements_kind,
1583 HValue* length, 1663 HValue* length,
1584 HValue* capacity) { 1664 HValue* capacity) {
(...skipping 46 matching lines...)
1631 if (mode == TRACK_ALLOCATION_SITE) { 1711 if (mode == TRACK_ALLOCATION_SITE) {
1632 size += AllocationSiteInfo::kSize; 1712 size += AllocationSiteInfo::kSize;
1633 } 1713 }
1634 int elems_offset = size; 1714 int elems_offset = size;
1635 if (length > 0) { 1715 if (length > 0) {
1636 size += IsFastDoubleElementsKind(kind) 1716 size += IsFastDoubleElementsKind(kind)
1637 ? FixedDoubleArray::SizeFor(length) 1717 ? FixedDoubleArray::SizeFor(length)
1638 : FixedArray::SizeFor(length); 1718 : FixedArray::SizeFor(length);
1639 } 1719 }
1640 1720
1641 HAllocate::Flags allocate_flags = HAllocate::CAN_ALLOCATE_IN_NEW_SPACE; 1721 HAllocate::Flags allocate_flags = HAllocate::DefaultFlags(kind);
1642 if (IsFastDoubleElementsKind(kind)) {
1643 allocate_flags = static_cast<HAllocate::Flags>(
1644 allocate_flags | HAllocate::ALLOCATE_DOUBLE_ALIGNED);
1645 }
1646
1647 // Allocate both the JS array and the elements array in one big 1722 // Allocate both the JS array and the elements array in one big
1648 // allocation. This avoids multiple limit checks. 1723 // allocation. This avoids multiple limit checks.
1649 HValue* size_in_bytes = 1724 HValue* size_in_bytes =
1650 AddInstruction(new(zone) HConstant(size, Representation::Integer32())); 1725 AddInstruction(new(zone) HConstant(size, Representation::Integer32()));
1651 HInstruction* object = 1726 HInstruction* object =
1652 AddInstruction(new(zone) HAllocate(context, 1727 AddInstruction(new(zone) HAllocate(context,
1653 size_in_bytes, 1728 size_in_bytes,
1654 HType::JSObject(), 1729 HType::JSObject(),
1655 allocate_flags)); 1730 allocate_flags));
1656 1731
1657 // Copy the JS array part. 1732 // Copy the JS array part.
1658 for (int i = 0; i < JSArray::kSize; i += kPointerSize) { 1733 for (int i = 0; i < JSArray::kSize; i += kPointerSize) {
1659 if ((i != JSArray::kElementsOffset) || (length == 0)) { 1734 if ((i != JSArray::kElementsOffset) || (length == 0)) {
1660 HInstruction* value = 1735 HInstruction* value =
1661 AddInstruction(new(zone) HLoadNamedField(boilerplate, true, i)); 1736 AddInstruction(new(zone) HLoadNamedField(boilerplate, true, i));
1662 if (i != JSArray::kMapOffset) { 1737 if (i != JSArray::kMapOffset) {
1663 AddInstruction(new(zone) HStoreNamedField(object, 1738 AddInstruction(new(zone) HStoreNamedField(object,
1664 factory->empty_string(), 1739 factory->empty_string(),
1665 value, 1740 value,
1666 true, i)); 1741 true, i));
1667 } else { 1742 } else {
1668 BuildStoreMap(object, value); 1743 BuildStoreMap(object, value);
1669 } 1744 }
1670 } 1745 }
1671 } 1746 }
1672 1747
1673 // Create an allocation site info if requested. 1748 // Create an allocation site info if requested.
1674 if (mode == TRACK_ALLOCATION_SITE) { 1749 if (mode == TRACK_ALLOCATION_SITE) {
1675 HValue* alloc_site = 1750 BuildCreateAllocationSiteInfo(object, JSArray::kSize, boilerplate);
1676 AddInstruction(new(zone) HInnerAllocatedObject(object, JSArray::kSize));
1677 Handle<Map> alloc_site_map(isolate()->heap()->allocation_site_info_map());
1678 BuildStoreMap(alloc_site, alloc_site_map);
1679 int alloc_payload_offset = AllocationSiteInfo::kPayloadOffset;
1680 AddInstruction(new(zone) HStoreNamedField(alloc_site,
1681 factory->empty_string(),
1682 boilerplate,
1683 true, alloc_payload_offset));
1684 } 1751 }
1685 1752
1686 if (length > 0) { 1753 if (length > 0) {
1687 // Get hold of the elements array of the boilerplate and setup the 1754 // Get hold of the elements array of the boilerplate and setup the
1688 // elements pointer in the resulting object. 1755 // elements pointer in the resulting object.
1689 HValue* boilerplate_elements = 1756 HValue* boilerplate_elements =
1690 AddInstruction(new(zone) HLoadElements(boilerplate, NULL)); 1757 AddInstruction(new(zone) HLoadElements(boilerplate, NULL));
1691 HValue* object_elements = 1758 HValue* object_elements =
1692 AddInstruction(new(zone) HInnerAllocatedObject(object, elems_offset)); 1759 AddInstruction(new(zone) HInnerAllocatedObject(object, elems_offset));
1693 AddInstruction(new(zone) HStoreNamedField(object, 1760 AddInstruction(new(zone) HStoreNamedField(object,
(...skipping 28 matching lines...)
1722 key_constant, 1789 key_constant,
1723 value, 1790 value,
1724 kind)); 1791 kind));
1725 } 1792 }
1726 } 1793 }
1727 1794
1728 return object; 1795 return object;
1729 } 1796 }
1730 1797
1731 1798
1799 HValue* HGraphBuilder::BuildCreateAllocationSiteInfo(HValue* previous_object,
1800 int previous_object_size,
1801 HValue* payload) {
1802 HInnerAllocatedObject* alloc_site = new(zone())
1803 HInnerAllocatedObject(previous_object, previous_object_size);
1804 AddInstruction(alloc_site);
1805 Handle<Map> alloc_site_map(isolate()->heap()->allocation_site_info_map());
1806 BuildStoreMap(alloc_site, alloc_site_map);
1807 AddInstruction(new(zone()) HStoreNamedField(alloc_site,
1808 isolate()->factory()->payload_string(),
1809 payload,
1810 true,
1811 AllocationSiteInfo::kPayloadOffset));
1812 return alloc_site;
1813 }
1814
1815
1816 HGraphBuilder::JSArrayBuilder::JSArrayBuilder(HGraphBuilder* builder,
1817 ElementsKind kind,
1818 HValue* allocation_site_payload,
1819 AllocationSiteMode mode) :
1820 builder_(builder),
1821 kind_(kind),
1822 allocation_site_payload_(allocation_site_payload) {
1823 if (mode == DONT_TRACK_ALLOCATION_SITE) {
1824 mode_ = mode;
1825 } else {
1826 mode_ = AllocationSiteInfo::GetMode(kind);
1827 }
1828 }
1829
1830
1831 HValue* HGraphBuilder::JSArrayBuilder::EmitMapCode(HValue* context) {
1832 // Get the global context, the native context, the map array
1833 HInstruction* global_object = AddInstruction(new(zone())
1834 HGlobalObject(context));
1835 HInstruction* native_context = AddInstruction(new(zone())
1836 HLoadNamedField(global_object, true, GlobalObject::kNativeContextOffset));
1837 size_t offset = Context::kHeaderSize +
1838 kPointerSize * Context::JS_ARRAY_MAPS_INDEX;
1839 HInstruction* map_array = AddInstruction(new(zone())
1840 HLoadNamedField(native_context, true, offset));
1841 offset = kind_ * kPointerSize + FixedArrayBase::kHeaderSize;
1842 return AddInstruction(new(zone()) HLoadNamedField(map_array, true, offset));
1843 }
1844
1845
1846 HValue* HGraphBuilder::JSArrayBuilder::EstablishAllocationSize(
1847 HValue* length_node) {
1848 HValue* context = builder()->environment()->LookupContext();
1849 ASSERT(length_node != NULL);
1850
1851 int base_size = JSArray::kSize;
1852 if (mode_ == TRACK_ALLOCATION_SITE) {
1853 base_size += AllocationSiteInfo::kSize;
1854 }
1855
1856 if (IsFastDoubleElementsKind(kind_)) {
1857 base_size += FixedDoubleArray::kHeaderSize;
1858 } else {
1859 base_size += FixedArray::kHeaderSize;
1860 }
1861
1862 HInstruction* elements_size_value = new(zone())
1863 HConstant(elements_size(), Representation::Integer32());
1864 AddInstruction(elements_size_value);
1865 HInstruction* mul = HMul::New(zone(), context, length_node,
1866 elements_size_value);
1867 mul->ChangeRepresentation(Representation::Integer32());
1868 mul->ClearFlag(HValue::kCanOverflow);
1869 AddInstruction(mul);
1870
1871 HInstruction* base = new(zone()) HConstant(base_size,
1872 Representation::Integer32());
1873 AddInstruction(base);
1874 HInstruction* total_size = HAdd::New(zone(), context, base, mul);
1875 total_size->ChangeRepresentation(Representation::Integer32());
1876 total_size->ClearFlag(HValue::kCanOverflow);
1877 AddInstruction(total_size);
1878 return total_size;
1879 }
1880
1881
1882 HValue* HGraphBuilder::JSArrayBuilder::EstablishEmptyArrayAllocationSize() {
1883 int base_size = JSArray::kSize;
1884 if (mode_ == TRACK_ALLOCATION_SITE) {
1885 base_size += AllocationSiteInfo::kSize;
1886 }
1887
1888 base_size += IsFastDoubleElementsKind(kind_)
1889 ? FixedDoubleArray::SizeFor(initial_capacity())
1890 : FixedArray::SizeFor(initial_capacity());
1891
1892 HConstant* array_size =
1893 new(zone()) HConstant(base_size, Representation::Integer32());
1894 AddInstruction(array_size);
1895 return array_size;
1896 }
1897
1898
1899 HValue* HGraphBuilder::JSArrayBuilder::AllocateEmptyArray() {
1900 HValue* size_in_bytes = EstablishEmptyArrayAllocationSize();
1901 HConstant* capacity =
1902 new(zone()) HConstant(initial_capacity(), Representation::Integer32());
1903 AddInstruction(capacity);
1904 return AllocateArray(size_in_bytes,
1905 capacity,
1906 builder()->graph()->GetConstant0(),
1907 true);
1908 }
1909
1910
1911 HValue* HGraphBuilder::JSArrayBuilder::AllocateArray(HValue* capacity,
1912 HValue* length_field,
1913 bool fill_with_hole) {
1914 HValue* size_in_bytes = EstablishAllocationSize(capacity);
1915 return AllocateArray(size_in_bytes, capacity, length_field, fill_with_hole);
1916 }
1917
1918
1919 HValue* HGraphBuilder::JSArrayBuilder::AllocateArray(HValue* size_in_bytes,
1920 HValue* capacity,
1921 HValue* length_field,
1922 bool fill_with_hole) {
1923 HValue* context = builder()->environment()->LookupContext();
1924
1925 // Allocate (dealing with failure appropriately)
1926 HAllocate::Flags flags = HAllocate::DefaultFlags(kind_);
1927 HAllocate* new_object = new(zone()) HAllocate(context, size_in_bytes,
1928 HType::JSArray(), flags);
1929 AddInstruction(new_object);
1930
1931 // Fill in the fields: map, properties, length
1932 HValue* map = EmitMapCode(context);
1933 elements_location_ = builder()->BuildJSArrayHeader(new_object,
1934 map,
1935 mode_,
1936 allocation_site_payload_,
1937 length_field);
1938
1939 // Initialize the elements
1940 builder()->BuildInitializeElements(elements_location_, kind_, capacity);
1941
1942 if (fill_with_hole) {
1943 builder()->BuildFillElementsWithHole(context, elements_location_, kind_,
1944 graph()->GetConstant0(), capacity);
1945 }
1946
1947 return new_object;
1948 }
1949
1950
1732 HOptimizedGraphBuilder::HOptimizedGraphBuilder(CompilationInfo* info, 1951 HOptimizedGraphBuilder::HOptimizedGraphBuilder(CompilationInfo* info,
1733 TypeFeedbackOracle* oracle) 1952 TypeFeedbackOracle* oracle)
1734 : HGraphBuilder(info), 1953 : HGraphBuilder(info),
1735 function_state_(NULL), 1954 function_state_(NULL),
1736 initial_function_state_(this, info, oracle, NORMAL_RETURN), 1955 initial_function_state_(this, info, oracle, NORMAL_RETURN),
1737 ast_context_(NULL), 1956 ast_context_(NULL),
1738 break_scope_(NULL), 1957 break_scope_(NULL),
1739 inlined_count_(0), 1958 inlined_count_(0),
1740 globals_(10, info->zone()), 1959 globals_(10, info->zone()),
1741 inline_bailout_(false) { 1960 inline_bailout_(false) {
(...skipping 7523 matching lines...)
9265 receiver->DeleteAndReplaceWith(NULL); 9484 receiver->DeleteAndReplaceWith(NULL);
9266 check->DeleteAndReplaceWith(NULL); 9485 check->DeleteAndReplaceWith(NULL);
9267 environment()->SetExpressionStackAt(receiver_index, function); 9486 environment()->SetExpressionStackAt(receiver_index, function);
9268 HInstruction* call = PreProcessCall( 9487 HInstruction* call = PreProcessCall(
9269 new(zone()) HCallNew(context, function, argument_count)); 9488 new(zone()) HCallNew(context, function, argument_count));
9270 call->set_position(expr->position()); 9489 call->set_position(expr->position());
9271 return ast_context()->ReturnInstruction(call, expr->id()); 9490 return ast_context()->ReturnInstruction(call, expr->id());
9272 } else { 9491 } else {
9273 // The constructor function is both an operand to the instruction and an 9492 // The constructor function is both an operand to the instruction and an
9274 // argument to the construct call. 9493 // argument to the construct call.
9494 bool use_call_new_array = FLAG_optimize_constructed_arrays &&
9495 !(expr->target().is_null()) &&
9496 *(expr->target()) == isolate()->global_context()->array_function();
9497
9275 CHECK_ALIVE(VisitArgument(expr->expression())); 9498 CHECK_ALIVE(VisitArgument(expr->expression()));
9276 HValue* constructor = HPushArgument::cast(Top())->argument(); 9499 HValue* constructor = HPushArgument::cast(Top())->argument();
9277 CHECK_ALIVE(VisitArgumentList(expr->arguments())); 9500 CHECK_ALIVE(VisitArgumentList(expr->arguments()));
9278 HCallNew* call; 9501 HCallNew* call;
9279 if (FLAG_optimize_constructed_arrays && 9502 if (use_call_new_array) {
9280 !(expr->target().is_null()) && 9503 AddInstruction(new(zone()) HCheckFunction(constructor,
9281 *(expr->target()) == isolate()->global_context()->array_function()) { 9504 Handle<JSFunction>(isolate()->global_context()->array_function())));
9282 Handle<Object> feedback = oracle()->GetInfo(expr->CallNewFeedbackId()); 9505 Handle<Object> feedback = oracle()->GetInfo(expr->CallNewFeedbackId());
9283 ASSERT(feedback->IsSmi()); 9506 ASSERT(feedback->IsSmi());
9507
9508 // TODO(mvstanton): It would be better to use the already created global
9509 // property cell that is shared by full code gen. That way, any transition
9510 // information that happened after crankshaft won't be lost. The right
9511 // way to do that is to begin passing the cell to the type feedback oracle
9512 // instead of just the value in the cell. Do this in a follow-up checkin.
9284 Handle<JSGlobalPropertyCell> cell = 9513 Handle<JSGlobalPropertyCell> cell =
9285 isolate()->factory()->NewJSGlobalPropertyCell(feedback); 9514 isolate()->factory()->NewJSGlobalPropertyCell(feedback);
9286 AddInstruction(new(zone()) HCheckFunction(constructor, 9515
9287 Handle<JSFunction>(isolate()->global_context()->array_function()))); 9516 // TODO(mvstanton): Here we should probably insert code to check if the
9517 // type cell elements kind is different from when we compiled, and deopt
9518 // in that case. Do this in a follow-up checin.
9288 call = new(zone()) HCallNewArray(context, constructor, argument_count, 9519 call = new(zone()) HCallNewArray(context, constructor, argument_count,
9289 cell); 9520 cell);
9290 } else { 9521 } else {
9291 call = new(zone()) HCallNew(context, constructor, argument_count); 9522 call = new(zone()) HCallNew(context, constructor, argument_count);
9292 } 9523 }
9293 Drop(argument_count); 9524 Drop(argument_count);
9294 call->set_position(expr->position()); 9525 call->set_position(expr->position());
9295 return ast_context()->ReturnInstruction(call, expr->id()); 9526 return ast_context()->ReturnInstruction(call, expr->id());
9296 } 9527 }
9297 } 9528 }
(...skipping 1092 matching lines...)
10390 HInstruction* value_instruction = AddInstruction(new(zone) HConstant( 10621 HInstruction* value_instruction = AddInstruction(new(zone) HConstant(
10391 value, Representation::Tagged())); 10622 value, Representation::Tagged()));
10392 AddInstruction(new(zone) HStoreNamedField( 10623 AddInstruction(new(zone) HStoreNamedField(
10393 object_properties, factory->unknown_field_string(), value_instruction, 10624 object_properties, factory->unknown_field_string(), value_instruction,
10394 true, boilerplate_object->GetInObjectPropertyOffset(i))); 10625 true, boilerplate_object->GetInObjectPropertyOffset(i)));
10395 } 10626 }
10396 } 10627 }
10397 10628
10398 // Build Allocation Site Info if desired 10629 // Build Allocation Site Info if desired
10399 if (create_allocation_site_info) { 10630 if (create_allocation_site_info) {
10400 HValue* alloc_site = 10631 BuildCreateAllocationSiteInfo(target, JSArray::kSize, original_boilerplate);
10401 AddInstruction(new(zone) HInnerAllocatedObject(target, JSArray::kSize));
10402 Handle<Map> alloc_site_map(isolate()->heap()->allocation_site_info_map());
10403 BuildStoreMap(alloc_site, alloc_site_map);
10404 int alloc_payload_offset = AllocationSiteInfo::kPayloadOffset;
10405 AddInstruction(new(zone) HStoreNamedField(alloc_site,
10406 factory->payload_string(),
10407 original_boilerplate,
10408 true, alloc_payload_offset));
10409 } 10632 }
10410 10633
10411 if (object_elements != NULL) { 10634 if (object_elements != NULL) {
10412 HInstruction* boilerplate_elements = AddInstruction(new(zone) HConstant( 10635 HInstruction* boilerplate_elements = AddInstruction(new(zone) HConstant(
10413 elements, Representation::Tagged())); 10636 elements, Representation::Tagged()));
10414 10637
10415 int elements_length = elements->length(); 10638 int elements_length = elements->length();
10416 HValue* object_elements_length = 10639 HValue* object_elements_length =
10417 AddInstruction(new(zone) HConstant( 10640 AddInstruction(new(zone) HConstant(
10418 elements_length, Representation::Integer32())); 10641 elements_length, Representation::Integer32()));
(...skipping 1451 matching lines...)
11870 } 12093 }
11871 } 12094 }
11872 12095
11873 #ifdef DEBUG 12096 #ifdef DEBUG
11874 if (graph_ != NULL) graph_->Verify(false); // No full verify. 12097 if (graph_ != NULL) graph_->Verify(false); // No full verify.
11875 if (allocator_ != NULL) allocator_->Verify(); 12098 if (allocator_ != NULL) allocator_->Verify();
11876 #endif 12099 #endif
11877 } 12100 }
11878 12101
11879 } } // namespace v8::internal 12102 } } // namespace v8::internal
OLDNEW
« src/flag-definitions.h ('K') | « src/hydrogen.h ('k') | src/hydrogen-instructions.h » ('j') | no next file with comments »

Powered by Google App Engine