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

Side by Side Diff: src/hydrogen.cc

Issue 14284010: Introduce HObjectAccess, which is used by LoadNamedField and StoreNamedField to denote what parts (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Some small cleanups; add AddLoad to simplify construction of loads 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
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 1173 matching lines...) Expand 10 before | Expand all | Expand 10 after
1184 1184
1185 environment()->Push(elements); 1185 environment()->Push(elements);
1186 capacity_checker.End(); 1186 capacity_checker.End();
1187 1187
1188 if (is_js_array) { 1188 if (is_js_array) {
1189 HValue* new_length = AddInstruction( 1189 HValue* new_length = AddInstruction(
1190 HAdd::New(zone, context, length, graph_->GetConstant1())); 1190 HAdd::New(zone, context, length, graph_->GetConstant1()));
1191 new_length->ChangeRepresentation(Representation::Integer32()); 1191 new_length->ChangeRepresentation(Representation::Integer32());
1192 new_length->ClearFlag(HValue::kCanOverflow); 1192 new_length->ClearFlag(HValue::kCanOverflow);
1193 1193
1194 Factory* factory = isolate()->factory(); 1194 AddStore(object, AccessArrayLength(), new_length, IsFastElementsKind(kind)
1195 Representation representation = IsFastElementsKind(kind) 1195 ? Representation::Smi() : Representation::Tagged());
1196 ? Representation::Smi() : Representation::Tagged();
1197 HInstruction* length_store = AddInstruction(new(zone) HStoreNamedField(
1198 object,
1199 factory->length_field_string(),
1200 new_length, true,
1201 representation,
1202 JSArray::kLengthOffset));
1203 length_store->SetGVNFlag(kChangesArrayLengths);
1204 } 1196 }
1205 1197
1206 length_checker.Else(); 1198 length_checker.Else();
1207 1199
1208 AddBoundsCheck(key, length, ALLOW_SMI_KEY); 1200 AddBoundsCheck(key, length, ALLOW_SMI_KEY);
1209 environment()->Push(elements); 1201 environment()->Push(elements);
1210 1202
1211 length_checker.End(); 1203 length_checker.End();
1212 1204
1213 return environment()->Pop(); 1205 return environment()->Pop();
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
1275 AddInstruction(new(zone) HLoadElements(object, mapcheck)); 1267 AddInstruction(new(zone) HLoadElements(object, mapcheck));
1276 if (is_store && (fast_elements || fast_smi_only_elements) && 1268 if (is_store && (fast_elements || fast_smi_only_elements) &&
1277 store_mode != STORE_NO_TRANSITION_HANDLE_COW) { 1269 store_mode != STORE_NO_TRANSITION_HANDLE_COW) {
1278 HCheckMaps* check_cow_map = HCheckMaps::New( 1270 HCheckMaps* check_cow_map = HCheckMaps::New(
1279 elements, isolate()->factory()->fixed_array_map(), zone); 1271 elements, isolate()->factory()->fixed_array_map(), zone);
1280 check_cow_map->ClearGVNFlag(kDependsOnElementsKind); 1272 check_cow_map->ClearGVNFlag(kDependsOnElementsKind);
1281 AddInstruction(check_cow_map); 1273 AddInstruction(check_cow_map);
1282 } 1274 }
1283 HInstruction* length = NULL; 1275 HInstruction* length = NULL;
1284 if (is_js_array) { 1276 if (is_js_array) {
1285 length = AddInstruction( 1277 length = AddLoad(object, AccessArrayLength(), mapcheck);
1286 HLoadNamedField::NewArrayLength(zone, object, mapcheck, HType::Smi())); 1278 length->set_type(HType::Smi());
1287 } else { 1279 } else {
1288 length = AddInstruction(new(zone) HFixedArrayBaseLength(elements)); 1280 length = AddInstruction(new(zone) HFixedArrayBaseLength(elements));
1289 } 1281 }
1290 HValue* checked_key = NULL; 1282 HValue* checked_key = NULL;
1291 if (IsExternalArrayElementsKind(elements_kind)) { 1283 if (IsExternalArrayElementsKind(elements_kind)) {
1292 if (store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS) { 1284 if (store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS) {
1293 NoObservableSideEffectsScope no_effects(this); 1285 NoObservableSideEffectsScope no_effects(this);
1294 HLoadExternalArrayPointer* external_elements = 1286 HLoadExternalArrayPointer* external_elements =
1295 new(zone) HLoadExternalArrayPointer(elements); 1287 new(zone) HLoadExternalArrayPointer(elements);
1296 AddInstruction(external_elements); 1288 AddInstruction(external_elements);
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
1402 HValue* elements = 1394 HValue* elements =
1403 AddInstruction(new(zone) HAllocate(context, total_size, 1395 AddInstruction(new(zone) HAllocate(context, total_size,
1404 HType::JSArray(), flags)); 1396 HType::JSArray(), flags));
1405 return elements; 1397 return elements;
1406 } 1398 }
1407 1399
1408 1400
1409 void HGraphBuilder::BuildInitializeElements(HValue* elements, 1401 void HGraphBuilder::BuildInitializeElements(HValue* elements,
1410 ElementsKind kind, 1402 ElementsKind kind,
1411 HValue* capacity) { 1403 HValue* capacity) {
1412 Zone* zone = this->zone();
1413 Factory* factory = isolate()->factory(); 1404 Factory* factory = isolate()->factory();
1414 Handle<Map> map = IsFastDoubleElementsKind(kind) 1405 Handle<Map> map = IsFastDoubleElementsKind(kind)
1415 ? factory->fixed_double_array_map() 1406 ? factory->fixed_double_array_map()
1416 : factory->fixed_array_map(); 1407 : factory->fixed_array_map();
1417 BuildStoreMap(elements, map);
1418 1408
1419 Handle<String> fixed_array_length_field_name = factory->length_field_string(); 1409 AddStoreMapConstant(elements, map);
1420 Representation representation = IsFastElementsKind(kind) 1410 AddStore(elements, AccessFixedArrayLength(), capacity,
1421 ? Representation::Smi() : Representation::Tagged(); 1411 IsFastElementsKind(kind)
1422 HInstruction* store_length = 1412 ? Representation::Smi() : Representation::Tagged());
1423 new(zone) HStoreNamedField(elements, fixed_array_length_field_name,
1424 capacity, true, representation,
1425 FixedArray::kLengthOffset);
1426 AddInstruction(store_length);
1427 } 1413 }
1428 1414
1429 1415
1430 HValue* HGraphBuilder::BuildAllocateAndInitializeElements(HValue* context, 1416 HValue* HGraphBuilder::BuildAllocateAndInitializeElements(HValue* context,
1431 ElementsKind kind, 1417 ElementsKind kind,
1432 HValue* capacity) { 1418 HValue* capacity) {
1433 HValue* new_elements = BuildAllocateElements(context, kind, capacity); 1419 HValue* new_elements = BuildAllocateElements(context, kind, capacity);
1434 BuildInitializeElements(new_elements, kind, capacity); 1420 BuildInitializeElements(new_elements, kind, capacity);
1435 return new_elements; 1421 return new_elements;
1436 } 1422 }
1437 1423
1438 1424
1439 HInnerAllocatedObject* HGraphBuilder::BuildJSArrayHeader(HValue* array, 1425 HInnerAllocatedObject* HGraphBuilder::BuildJSArrayHeader(HValue* array,
1440 HValue* array_map, 1426 HValue* array_map,
1441 AllocationSiteMode mode, 1427 AllocationSiteMode mode,
1442 HValue* allocation_site_payload, 1428 HValue* allocation_site_payload,
1443 HValue* length_field) { 1429 HValue* length_field) {
1444 1430
1445 BuildStoreMap(array, array_map); 1431 AddStore(array, AccessMap(), array_map);
1446 1432
1447 HConstant* empty_fixed_array = 1433 HConstant* empty_fixed_array =
1448 new(zone()) HConstant( 1434 new(zone()) HConstant(
1449 Handle<FixedArray>(isolate()->heap()->empty_fixed_array()), 1435 Handle<FixedArray>(isolate()->heap()->empty_fixed_array()),
1450 Representation::Tagged()); 1436 Representation::Tagged());
1451 AddInstruction(empty_fixed_array); 1437 AddInstruction(empty_fixed_array);
1452 1438
1453 AddInstruction(new(zone()) HStoreNamedField(array, 1439 HObjectAccess *access = AccessInobject(
1454 isolate()->factory()->properties_field_symbol(), 1440 isolate()->factory()->properties_field_symbol(),
1455 empty_fixed_array, 1441 JSArray::kPropertiesOffset);
1456 true, 1442 AddStore(array, access, empty_fixed_array);
1457 Representation::Tagged(), 1443 AddStore(array, AccessArrayLength(), length_field);
1458 JSArray::kPropertiesOffset));
1459
1460 HInstruction* length_store = AddInstruction(
1461 new(zone()) HStoreNamedField(array,
1462 isolate()->factory()->length_field_string(),
1463 length_field,
1464 true,
1465 Representation::Tagged(),
1466 JSArray::kLengthOffset));
1467 length_store->SetGVNFlag(kChangesArrayLengths);
1468 1444
1469 if (mode == TRACK_ALLOCATION_SITE) { 1445 if (mode == TRACK_ALLOCATION_SITE) {
1470 BuildCreateAllocationSiteInfo(array, 1446 BuildCreateAllocationSiteInfo(array,
1471 JSArray::kSize, 1447 JSArray::kSize,
1472 allocation_site_payload); 1448 allocation_site_payload);
1473 } 1449 }
1474 1450
1475 int elements_location = JSArray::kSize; 1451 int elements_location = JSArray::kSize;
1476 if (mode == TRACK_ALLOCATION_SITE) { 1452 if (mode == TRACK_ALLOCATION_SITE) {
1477 elements_location += AllocationSiteInfo::kSize; 1453 elements_location += AllocationSiteInfo::kSize;
1478 } 1454 }
1479 1455
1480 HInnerAllocatedObject* elements = new(zone()) HInnerAllocatedObject( 1456 HInnerAllocatedObject* elements = new(zone()) HInnerAllocatedObject(
1481 array, 1457 array, elements_location);
1482 elements_location);
1483 AddInstruction(elements); 1458 AddInstruction(elements);
1484 1459
1485 HInstruction* elements_store = AddInstruction( 1460 AddStore(array, AccessElements(), elements);
1486 new(zone()) HStoreNamedField(
1487 array,
1488 isolate()->factory()->elements_field_string(),
1489 elements,
1490 true,
1491 Representation::Tagged(),
1492 JSArray::kElementsOffset));
1493 elements_store->SetGVNFlag(kChangesElementsPointer);
1494
1495 return elements; 1461 return elements;
1496 } 1462 }
1497 1463
1498 1464
1499 HInstruction* HGraphBuilder::BuildStoreMap(HValue* object,
1500 HValue* map) {
1501 Zone* zone = this->zone();
1502 Factory* factory = isolate()->factory();
1503 Handle<String> map_field_name = factory->map_field_string();
1504 HInstruction* store_map =
1505 new(zone) HStoreNamedField(object, map_field_name, map,
1506 true, Representation::Tagged(),
1507 JSObject::kMapOffset);
1508 store_map->ClearGVNFlag(kChangesInobjectFields);
1509 store_map->SetGVNFlag(kChangesMaps);
1510 AddInstruction(store_map);
1511 return store_map;
1512 }
1513
1514
1515 HInstruction* HGraphBuilder::BuildStoreMap(HValue* object,
1516 Handle<Map> map) {
1517 Zone* zone = this->zone();
1518 HValue* map_constant =
1519 AddInstruction(new(zone) HConstant(map, Representation::Tagged()));
1520 return BuildStoreMap(object, map_constant);
1521 }
1522
1523
1524 HValue* HGraphBuilder::BuildNewElementsCapacity(HValue* context, 1465 HValue* HGraphBuilder::BuildNewElementsCapacity(HValue* context,
1525 HValue* old_capacity) { 1466 HValue* old_capacity) {
1526 Zone* zone = this->zone(); 1467 Zone* zone = this->zone();
1527 HValue* half_old_capacity = 1468 HValue* half_old_capacity =
1528 AddInstruction(HShr::New(zone, context, old_capacity, 1469 AddInstruction(HShr::New(zone, context, old_capacity,
1529 graph_->GetConstant1())); 1470 graph_->GetConstant1()));
1530 half_old_capacity->ChangeRepresentation(Representation::Integer32()); 1471 half_old_capacity->ChangeRepresentation(Representation::Integer32());
1531 half_old_capacity->ClearFlag(HValue::kCanOverflow); 1472 half_old_capacity->ClearFlag(HValue::kCanOverflow);
1532 1473
1533 HValue* new_capacity = AddInstruction( 1474 HValue* new_capacity = AddInstruction(
(...skipping 29 matching lines...) Expand all
1563 HBoundsCheck(length, max_size_constant, 1504 HBoundsCheck(length, max_size_constant,
1564 DONT_ALLOW_SMI_KEY, Representation::Integer32())); 1505 DONT_ALLOW_SMI_KEY, Representation::Integer32()));
1565 } 1506 }
1566 1507
1567 1508
1568 HValue* HGraphBuilder::BuildGrowElementsCapacity(HValue* object, 1509 HValue* HGraphBuilder::BuildGrowElementsCapacity(HValue* object,
1569 HValue* elements, 1510 HValue* elements,
1570 ElementsKind kind, 1511 ElementsKind kind,
1571 HValue* length, 1512 HValue* length,
1572 HValue* new_capacity) { 1513 HValue* new_capacity) {
1573 Zone* zone = this->zone();
1574 HValue* context = environment()->LookupContext(); 1514 HValue* context = environment()->LookupContext();
1575 1515
1576 BuildNewSpaceArrayCheck(new_capacity, kind); 1516 BuildNewSpaceArrayCheck(new_capacity, kind);
1577 1517
1578 HValue* new_elements = 1518 HValue* new_elements =
1579 BuildAllocateAndInitializeElements(context, kind, new_capacity); 1519 BuildAllocateAndInitializeElements(context, kind, new_capacity);
1580 1520
1581 BuildCopyElements(context, elements, kind, 1521 BuildCopyElements(context, elements, kind,
1582 new_elements, kind, 1522 new_elements, kind,
1583 length, new_capacity); 1523 length, new_capacity);
1584 1524
1585 Factory* factory = isolate()->factory(); 1525 AddStore(object, AccessElements(), new_elements);
1586 HInstruction* elements_store = AddInstruction(new(zone) HStoreNamedField(
1587 object,
1588 factory->elements_field_string(),
1589 new_elements, true, Representation::Tagged(),
1590 JSArray::kElementsOffset));
1591 elements_store->SetGVNFlag(kChangesElementsPointer);
1592 1526
1593 return new_elements; 1527 return new_elements;
1594 } 1528 }
1595 1529
1596 1530
1597 void HGraphBuilder::BuildFillElementsWithHole(HValue* context, 1531 void HGraphBuilder::BuildFillElementsWithHole(HValue* context,
1598 HValue* elements, 1532 HValue* elements,
1599 ElementsKind elements_kind, 1533 ElementsKind elements_kind,
1600 HValue* from, 1534 HValue* from,
1601 HValue* to) { 1535 HValue* to) {
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
1716 AddInstruction(new(zone) HConstant(size, Representation::Integer32())); 1650 AddInstruction(new(zone) HConstant(size, Representation::Integer32()));
1717 HInstruction* object = 1651 HInstruction* object =
1718 AddInstruction(new(zone) HAllocate(context, 1652 AddInstruction(new(zone) HAllocate(context,
1719 size_in_bytes, 1653 size_in_bytes,
1720 HType::JSObject(), 1654 HType::JSObject(),
1721 allocate_flags)); 1655 allocate_flags));
1722 1656
1723 // Copy the JS array part. 1657 // Copy the JS array part.
1724 for (int i = 0; i < JSArray::kSize; i += kPointerSize) { 1658 for (int i = 0; i < JSArray::kSize; i += kPointerSize) {
1725 if ((i != JSArray::kElementsOffset) || (length == 0)) { 1659 if ((i != JSArray::kElementsOffset) || (length == 0)) {
1726 HInstruction* value = AddInstruction(new(zone) HLoadNamedField( 1660 HObjectAccess* access = AccessArrayHeader(i);
1727 boilerplate, true, Representation::Tagged(), i)); 1661 HInstruction* value = AddLoad(boilerplate, access);
1728 if (i != JSArray::kMapOffset) { 1662 AddStore(object, access, value);
1729 AddInstruction(new(zone) HStoreNamedField(object,
1730 factory->empty_string(),
1731 value, true,
1732 Representation::Tagged(), i));
1733 } else {
1734 BuildStoreMap(object, value);
1735 }
1736 } 1663 }
1737 } 1664 }
1738 1665
1739 // Create an allocation site info if requested. 1666 // Create an allocation site info if requested.
1740 if (mode == TRACK_ALLOCATION_SITE) { 1667 if (mode == TRACK_ALLOCATION_SITE) {
1741 BuildCreateAllocationSiteInfo(object, JSArray::kSize, boilerplate); 1668 BuildCreateAllocationSiteInfo(object, JSArray::kSize, boilerplate);
1742 } 1669 }
1743 1670
1744 if (length > 0) { 1671 if (length > 0) {
1745 // Get hold of the elements array of the boilerplate and setup the 1672 // Get hold of the elements array of the boilerplate and setup the
1746 // elements pointer in the resulting object. 1673 // elements pointer in the resulting object.
1747 HValue* boilerplate_elements = 1674 HValue* boilerplate_elements =
1748 AddInstruction(new(zone) HLoadElements(boilerplate, NULL)); 1675 AddInstruction(new(zone) HLoadElements(boilerplate, NULL));
1749 HValue* object_elements = 1676 HValue* object_elements =
1750 AddInstruction(new(zone) HInnerAllocatedObject(object, elems_offset)); 1677 AddInstruction(new(zone) HInnerAllocatedObject(object, elems_offset));
1751 AddInstruction(new(zone) HStoreNamedField(object, 1678 AddStore(object, AccessElements(), object_elements);
1752 factory->elements_field_string(),
1753 object_elements, true,
1754 Representation::Tagged(),
1755 JSObject::kElementsOffset));
1756 1679
1757 // Copy the elements array header. 1680 // Copy the elements array header.
1758 for (int i = 0; i < FixedArrayBase::kHeaderSize; i += kPointerSize) { 1681 for (int i = 0; i < FixedArrayBase::kHeaderSize; i += kPointerSize) {
1759 HInstruction* value = 1682 // TODO(titzer): AccessFixedArray?
1760 AddInstruction(new(zone) HLoadNamedField( 1683 HObjectAccess* access = AccessInobject(factory->empty_string(), i);
1761 boilerplate_elements, true, Representation::Tagged(), i)); 1684 HInstruction* value = AddLoad(boilerplate_elements, access);
1762 AddInstruction(new(zone) HStoreNamedField(object_elements, 1685 AddStore(object_elements, access, value);
1763 factory->empty_string(),
1764 value, true,
1765 Representation::Tagged(), i));
1766 } 1686 }
1767 1687
1768 // Copy the elements array contents. 1688 // Copy the elements array contents.
1769 // TODO(mstarzinger): Teach HGraphBuilder::BuildCopyElements to unfold 1689 // TODO(mstarzinger): Teach HGraphBuilder::BuildCopyElements to unfold
1770 // copying loops with constant length up to a given boundary and use this 1690 // copying loops with constant length up to a given boundary and use this
1771 // helper here instead. 1691 // helper here instead.
1772 for (int i = 0; i < length; i++) { 1692 for (int i = 0; i < length; i++) {
1773 HValue* key_constant = 1693 HValue* key_constant =
1774 AddInstruction(new(zone) HConstant(i, Representation::Integer32())); 1694 AddInstruction(new(zone) HConstant(i, Representation::Integer32()));
1775 HInstruction* value = 1695 HInstruction* value =
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
1835 } 1755 }
1836 1756
1837 1757
1838 HValue* HGraphBuilder::BuildCreateAllocationSiteInfo(HValue* previous_object, 1758 HValue* HGraphBuilder::BuildCreateAllocationSiteInfo(HValue* previous_object,
1839 int previous_object_size, 1759 int previous_object_size,
1840 HValue* payload) { 1760 HValue* payload) {
1841 HInnerAllocatedObject* alloc_site = new(zone()) 1761 HInnerAllocatedObject* alloc_site = new(zone())
1842 HInnerAllocatedObject(previous_object, previous_object_size); 1762 HInnerAllocatedObject(previous_object, previous_object_size);
1843 AddInstruction(alloc_site); 1763 AddInstruction(alloc_site);
1844 Handle<Map> alloc_site_map(isolate()->heap()->allocation_site_info_map()); 1764 Handle<Map> alloc_site_map(isolate()->heap()->allocation_site_info_map());
1845 BuildStoreMap(alloc_site, alloc_site_map); 1765 AddStoreMapConstant(alloc_site, alloc_site_map);
1846 AddInstruction(new(zone()) HStoreNamedField(alloc_site, 1766 HObjectAccess* access = AccessInobject(
1847 isolate()->factory()->payload_string(), 1767 isolate()->factory()->payload_string(),
1848 payload, 1768 AllocationSiteInfo::kPayloadOffset);
1849 true, 1769 AddStore(alloc_site, access, payload);
1850 Representation::Tagged(),
1851 AllocationSiteInfo::kPayloadOffset));
1852 return alloc_site; 1770 return alloc_site;
1853 } 1771 }
1854 1772
1855 1773
1856 HGraphBuilder::JSArrayBuilder::JSArrayBuilder(HGraphBuilder* builder, 1774 HGraphBuilder::JSArrayBuilder::JSArrayBuilder(HGraphBuilder* builder,
1857 ElementsKind kind, 1775 ElementsKind kind,
1858 HValue* allocation_site_payload, 1776 HValue* allocation_site_payload,
1859 AllocationSiteMode mode) : 1777 AllocationSiteMode mode) :
1860 builder_(builder), 1778 builder_(builder),
1861 kind_(kind), 1779 kind_(kind),
1862 allocation_site_payload_(allocation_site_payload) { 1780 allocation_site_payload_(allocation_site_payload) {
1863 if (mode == DONT_TRACK_ALLOCATION_SITE) { 1781 if (mode == DONT_TRACK_ALLOCATION_SITE) {
1864 mode_ = mode; 1782 mode_ = mode;
1865 } else { 1783 } else {
1866 mode_ = AllocationSiteInfo::GetMode(kind); 1784 mode_ = AllocationSiteInfo::GetMode(kind);
1867 } 1785 }
1868 } 1786 }
1869 1787
1870 1788
1871 HValue* HGraphBuilder::JSArrayBuilder::EmitMapCode(HValue* context) { 1789 HValue* HGraphBuilder::JSArrayBuilder::EmitMapCode(HValue* context) {
1872 // Get the global context, the native context, the map array 1790 // Get the global context, the native context, the map array
1873 HInstruction* global_object = AddInstruction(new(zone()) 1791 HInstruction* global_object = AddInstruction(new(zone())
1874 HGlobalObject(context)); 1792 HGlobalObject(context));
1875 HInstruction* native_context = AddInstruction(new(zone()) 1793 Handle<String> unknown =
1876 HLoadNamedField(global_object, true, Representation::Tagged(), 1794 builder()->isolate()->factory()->unknown_field_string();
1877 GlobalObject::kNativeContextOffset)); 1795 HObjectAccess* access = builder()->AccessInobject(unknown,
1796 GlobalObject::kNativeContextOffset);
1797 HInstruction* native_context = builder()->AddLoad(global_object, access);
1798
1878 int offset = Context::kHeaderSize + 1799 int offset = Context::kHeaderSize +
1879 kPointerSize * Context::JS_ARRAY_MAPS_INDEX; 1800 kPointerSize * Context::JS_ARRAY_MAPS_INDEX;
1880 HInstruction* map_array = AddInstruction(new(zone()) 1801 access = builder()->AccessInobject(unknown, offset);
1881 HLoadNamedField(native_context, true, Representation::Tagged(), offset)); 1802 HInstruction* map_array = builder()->AddLoad(native_context, access);
1803
1882 offset = kind_ * kPointerSize + FixedArrayBase::kHeaderSize; 1804 offset = kind_ * kPointerSize + FixedArrayBase::kHeaderSize;
1883 return AddInstruction(new(zone()) HLoadNamedField( 1805 access = builder()->AccessInobject(unknown, offset);
1884 map_array, true, Representation::Tagged(), offset)); 1806 return builder()->AddLoad(map_array, access);
1885 } 1807 }
1886 1808
1887 1809
1888 HValue* HGraphBuilder::JSArrayBuilder::EstablishAllocationSize( 1810 HValue* HGraphBuilder::JSArrayBuilder::EstablishAllocationSize(
1889 HValue* length_node) { 1811 HValue* length_node) {
1890 HValue* context = builder()->environment()->LookupContext(); 1812 HValue* context = builder()->environment()->LookupContext();
1891 ASSERT(length_node != NULL); 1813 ASSERT(length_node != NULL);
1892 1814
1893 int base_size = JSArray::kSize; 1815 int base_size = JSArray::kSize;
1894 if (mode_ == TRACK_ALLOCATION_SITE) { 1816 if (mode_ == TRACK_ALLOCATION_SITE) {
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
1983 1905
1984 if (fill_with_hole) { 1906 if (fill_with_hole) {
1985 builder()->BuildFillElementsWithHole(context, elements_location_, kind_, 1907 builder()->BuildFillElementsWithHole(context, elements_location_, kind_,
1986 graph()->GetConstant0(), capacity); 1908 graph()->GetConstant0(), capacity);
1987 } 1909 }
1988 1910
1989 return new_object; 1911 return new_object;
1990 } 1912 }
1991 1913
1992 1914
1915 HStoreNamedField* HGraphBuilder::AddStore(HValue *object, HObjectAccess* access,
1916 HValue *val, Representation representation) {
1917 HStoreNamedField *instr = new(zone()) HStoreNamedField(object, access, val);
1918 AddInstruction(instr);
1919 instr->set_field_representation(representation);
1920 return instr;
1921 }
1922
1923
1924 HLoadNamedField* HGraphBuilder::AddLoad(HValue *object, HObjectAccess* access,
1925 HValue *typecheck) {
1926 HLoadNamedField *instr = new(zone())
1927 HLoadNamedField(object, access, typecheck);
1928 AddInstruction(instr);
1929 return instr;
1930 }
1931
1932
1933 HStoreNamedField* HGraphBuilder::AddStoreMapConstant(HValue *object,
1934 Handle<Map> map) {
1935 HValue* constant = AddInstruction(new(zone())
1936 HConstant(map, Representation::Tagged()));
1937 HStoreNamedField *instr = new(zone())
1938 HStoreNamedField(object, AccessMap(), constant);
1939 AddInstruction(instr);
1940 return instr;
1941 }
1942
1943
1944 HObjectAccess* HGraphBuilder::AccessArrayHeader(int offset) {
danno 2013/05/02 14:16:47 I am not convinced this should be separate method.
titzer 2013/05/03 09:18:41 I've moved this and other constructor methods to H
1945 ASSERT(offset >= 0 && offset <= JSArray::kSize);
1946 Factory *factory = isolate()->factory();
1947 HObjectAccess::Portion portion = HObjectAccess::kInobject;
1948 Handle<String> name = factory->empty_string();
1949 if (offset == JSObject::kElementsOffset) {
1950 portion = HObjectAccess::kElementsPointer;
1951 name = factory->elements_field_string();
1952 } else if (offset == JSArray::kLengthOffset) {
1953 portion = HObjectAccess::kArrayLengths;
1954 name = factory->length_field_string();
1955 } else if (offset == JSArray::kMapOffset) {
1956 portion = HObjectAccess::kMaps;
1957 name = factory->map_field_string();
1958 }
1959 return new(zone()) HObjectAccess(portion, offset, name);
1960 }
1961
1962
1963 HObjectAccess* HGraphBuilder::AccessArrayLength() {
1964 return new (zone()) HObjectAccess(HObjectAccess::kArrayLengths,
danno 2013/05/02 14:16:47 This method and the methods below should return th
titzer 2013/05/03 09:18:41 Done (in HObjectAccess).
1965 JSArray::kLengthOffset, isolate()->factory()->length_field_string());
1966 }
1967
1968
1969 HObjectAccess* HGraphBuilder::AccessFixedArrayLength() {
1970 return new(zone()) HObjectAccess(HObjectAccess::kInobject,
1971 FixedArray::kLengthOffset, isolate()->factory()->length_field_string());
1972 }
1973
1974
1975 HObjectAccess* HGraphBuilder::AccessElements() {
1976 return new(zone()) HObjectAccess(HObjectAccess::kElementsPointer,
1977 JSObject::kElementsOffset, isolate()->factory()->elements_field_string());
1978 }
1979
1980
1981 HObjectAccess* HGraphBuilder::AccessMap() {
1982 return new(zone()) HObjectAccess(HObjectAccess::kMaps, JSObject::kMapOffset,
1983 isolate()->factory()->map_field_string());
1984 }
1985
1986
1987 HObjectAccess* HGraphBuilder::AccessField(Handle<Map> map, Handle<String> name,
1988 LookupResult* lookup) {
1989 ASSERT(lookup->IsField() || lookup->IsTransitionToField(*map));
1990 int index;
1991 if (lookup->IsField()) {
1992 index = lookup->GetLocalFieldIndexFromMap(*map);
1993 } else {
1994 Map* transition = lookup->GetTransitionMapFromMap(*map);
1995 int descriptor = transition->LastAdded();
1996 index = transition->instance_descriptors()->GetFieldIndex(descriptor) -
1997 map->inobject_properties();
1998 }
1999 if (index < 0) {
2000 // Negative property indices are in-object properties, indexed
2001 // from the end of the fixed part of the object.
2002 int offset = (index * kPointerSize) + map->instance_size();
2003 return new(zone()) HObjectAccess(HObjectAccess::kInobject, offset);
2004 } else {
2005 // Non-negative property indices are in the properties array.
2006 int offset = (index * kPointerSize) + FixedArray::kHeaderSize;
2007 return new(zone())
2008 HObjectAccess(HObjectAccess::kBackingStore, offset, name);
danno 2013/05/02 14:16:47 Seems like a wast of memory, these can be stack al
titzer 2013/05/03 09:18:41 Can't do that, since a pointer to them is retained
2009 }
2010 }
2011
2012 HObjectAccess* HGraphBuilder::AccessInobject(Handle<String> name, int offset) {
2013 return new(zone()) HObjectAccess(HObjectAccess::kInobject, offset, name);
danno 2013/05/02 14:16:47 Same here...
2014 }
2015
2016
1993 HOptimizedGraphBuilder::HOptimizedGraphBuilder(CompilationInfo* info, 2017 HOptimizedGraphBuilder::HOptimizedGraphBuilder(CompilationInfo* info,
1994 TypeFeedbackOracle* oracle) 2018 TypeFeedbackOracle* oracle)
1995 : HGraphBuilder(info), 2019 : HGraphBuilder(info),
1996 function_state_(NULL), 2020 function_state_(NULL),
1997 initial_function_state_(this, info, oracle, NORMAL_RETURN), 2021 initial_function_state_(this, info, oracle, NORMAL_RETURN),
1998 ast_context_(NULL), 2022 ast_context_(NULL),
1999 break_scope_(NULL), 2023 break_scope_(NULL),
2000 inlined_count_(0), 2024 inlined_count_(0),
2001 globals_(10, info->zone()), 2025 globals_(10, info->zone()),
2002 inline_bailout_(false) { 2026 inline_bailout_(false) {
(...skipping 4892 matching lines...) Expand 10 before | Expand all | Expand 10 after
6895 if (!is_store) return false; 6919 if (!is_store) return false;
6896 6920
6897 // 2nd chance: A store into a non-existent field can still be inlined if we 6921 // 2nd chance: A store into a non-existent field can still be inlined if we
6898 // have a matching transition and some room left in the object. 6922 // have a matching transition and some room left in the object.
6899 type->LookupTransition(NULL, *name, lookup); 6923 type->LookupTransition(NULL, *name, lookup);
6900 return lookup->IsTransitionToField(*type) && 6924 return lookup->IsTransitionToField(*type) &&
6901 (type->unused_property_fields() > 0); 6925 (type->unused_property_fields() > 0);
6902 } 6926 }
6903 6927
6904 6928
6905 static int ComputeLoadStoreFieldIndex(Handle<Map> type,
6906 LookupResult* lookup) {
6907 ASSERT(lookup->IsField() || lookup->IsTransitionToField(*type));
6908 if (lookup->IsField()) {
6909 return lookup->GetLocalFieldIndexFromMap(*type);
6910 } else {
6911 Map* transition = lookup->GetTransitionMapFromMap(*type);
6912 int descriptor = transition->LastAdded();
6913 int index = transition->instance_descriptors()->GetFieldIndex(descriptor);
6914 return index - type->inobject_properties();
6915 }
6916 }
6917
6918
6919 static Representation ComputeLoadStoreRepresentation(Handle<Map> type, 6929 static Representation ComputeLoadStoreRepresentation(Handle<Map> type,
6920 LookupResult* lookup) { 6930 LookupResult* lookup) {
6921 if (lookup->IsField()) { 6931 if (lookup->IsField()) {
6922 return lookup->representation(); 6932 return lookup->representation();
6923 } else { 6933 } else {
6924 Map* transition = lookup->GetTransitionMapFromMap(*type); 6934 Map* transition = lookup->GetTransitionMapFromMap(*type);
6925 int descriptor = transition->LastAdded(); 6935 int descriptor = transition->LastAdded();
6926 PropertyDetails details = 6936 PropertyDetails details =
6927 transition->instance_descriptors()->GetDetails(descriptor); 6937 transition->instance_descriptors()->GetDetails(descriptor);
6928 return details.representation(); 6938 return details.representation();
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
6973 } 6983 }
6974 ASSERT(proto->GetPrototype(isolate())->IsNull()); 6984 ASSERT(proto->GetPrototype(isolate())->IsNull());
6975 } 6985 }
6976 ASSERT(proto->IsJSObject()); 6986 ASSERT(proto->IsJSObject());
6977 AddInstruction(new(zone()) HCheckPrototypeMaps( 6987 AddInstruction(new(zone()) HCheckPrototypeMaps(
6978 Handle<JSObject>(JSObject::cast(map->prototype())), 6988 Handle<JSObject>(JSObject::cast(map->prototype())),
6979 Handle<JSObject>(JSObject::cast(proto)), 6989 Handle<JSObject>(JSObject::cast(proto)),
6980 zone())); 6990 zone()));
6981 } 6991 }
6982 6992
6983 int index = ComputeLoadStoreFieldIndex(map, lookup); 6993 HObjectAccess* access = AccessField(map, name, lookup);
6984 bool is_in_object = index < 0; 6994 HStoreNamedField* instr = new(zone()) HStoreNamedField(object, access, value);
6985 Representation representation = ComputeLoadStoreRepresentation(map, lookup); 6995 instr->set_field_representation(ComputeLoadStoreRepresentation(map, lookup));
6986 int offset = index * kPointerSize; 6996
6987 if (index < 0) {
6988 // Negative property indices are in-object properties, indexed
6989 // from the end of the fixed part of the object.
6990 offset += map->instance_size();
6991 } else {
6992 offset += FixedArray::kHeaderSize;
6993 }
6994 HStoreNamedField* instr = new(zone()) HStoreNamedField(
6995 object, name, value, is_in_object, representation, offset);
6996 if (lookup->IsTransitionToField(*map)) { 6997 if (lookup->IsTransitionToField(*map)) {
6997 Handle<Map> transition(lookup->GetTransitionMapFromMap(*map)); 6998 Handle<Map> transition(lookup->GetTransitionMapFromMap(*map));
6998 instr->set_transition(transition); 6999 instr->set_transition(transition);
6999 // TODO(fschneider): Record the new map type of the object in the IR to 7000 // TODO(fschneider): Record the new map type of the object in the IR to
7000 // enable elimination of redundant checks after the transition store. 7001 // enable elimination of redundant checks after the transition store.
7001 instr->SetGVNFlag(kChangesMaps); 7002 instr->SetGVNFlag(kChangesMaps);
7002 } 7003 }
7003 return instr; 7004 return instr;
7004 } 7005 }
7005 7006
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
7055 Handle<String> name) { 7056 Handle<String> name) {
7056 if (!name->Equals(isolate()->heap()->length_string())) return false; 7057 if (!name->Equals(isolate()->heap()->length_string())) return false;
7057 7058
7058 for (int i = 0; i < types->length(); i++) { 7059 for (int i = 0; i < types->length(); i++) {
7059 if (types->at(i)->instance_type() != JS_ARRAY_TYPE) return false; 7060 if (types->at(i)->instance_type() != JS_ARRAY_TYPE) return false;
7060 } 7061 }
7061 7062
7062 AddInstruction(new(zone()) HCheckNonSmi(object)); 7063 AddInstruction(new(zone()) HCheckNonSmi(object));
7063 7064
7064 HInstruction* typecheck = 7065 HInstruction* typecheck =
7065 AddInstruction(HCheckMaps::New(object, types, zone())); 7066 AddInstruction(HCheckMaps::New(object, types, zone()));
7066 HInstruction* instr = 7067 HInstruction* instr = new(zone())
7067 HLoadNamedField::NewArrayLength(zone(), object, typecheck); 7068 HLoadNamedField(object, AccessArrayLength(), typecheck);
7069
7068 instr->set_position(expr->position()); 7070 instr->set_position(expr->position());
7069 ast_context()->ReturnInstruction(instr, expr->id()); 7071 ast_context()->ReturnInstruction(instr, expr->id());
7070 return true; 7072 return true;
7071 } 7073 }
7072 7074
7073 7075
7074 void HOptimizedGraphBuilder::HandlePolymorphicLoadNamedField(Property* expr, 7076 void HOptimizedGraphBuilder::HandlePolymorphicLoadNamedField(Property* expr,
7075 HValue* object, 7077 HValue* object,
7076 SmallMapList* types, 7078 SmallMapList* types,
7077 Handle<String> name) { 7079 Handle<String> name) {
7078 int count = 0; 7080 int count = 0;
7079 int previous_field_offset = 0; 7081 int previous_field_offset = 0;
7080 bool previous_field_is_in_object = false; 7082 bool previous_field_is_in_object = false;
7081 bool is_monomorphic_field = true; 7083 bool is_monomorphic_field = true;
7082 7084
7083 if (HandlePolymorphicArrayLengthLoad(expr, object, types, name)) 7085 if (HandlePolymorphicArrayLengthLoad(expr, object, types, name))
7084 return; 7086 return;
7085 7087
7086 Handle<Map> map; 7088 Handle<Map> map;
7087 LookupResult lookup(isolate()); 7089 LookupResult lookup(isolate());
7088 for (int i = 0; i < types->length() && count < kMaxLoadPolymorphism; ++i) { 7090 for (int i = 0; i < types->length() && count < kMaxLoadPolymorphism; ++i) {
7089 map = types->at(i); 7091 map = types->at(i);
7090 if (ComputeLoadStoreField(map, name, &lookup, false)) { 7092 if (ComputeLoadStoreField(map, name, &lookup, false)) {
7091 int index = ComputeLoadStoreFieldIndex(map, &lookup); 7093 HObjectAccess* access = AccessField(map, name, &lookup);
7092 bool is_in_object = index < 0;
7093 int offset = index * kPointerSize;
7094 if (index < 0) {
7095 // Negative property indices are in-object properties, indexed
7096 // from the end of the fixed part of the object.
7097 offset += map->instance_size();
7098 } else {
7099 offset += FixedArray::kHeaderSize;
7100 }
7101 if (count == 0) { 7094 if (count == 0) {
7102 previous_field_offset = offset; 7095 previous_field_offset = access->offset();
7103 previous_field_is_in_object = is_in_object; 7096 previous_field_is_in_object = access->IsInobject();
7104 } else if (is_monomorphic_field) { 7097 } else if (is_monomorphic_field) {
7105 is_monomorphic_field = (offset == previous_field_offset) && 7098 // TODO(titzer): just break out of this loop if not the same
7106 (is_in_object == previous_field_is_in_object); 7099 is_monomorphic_field =
7100 (access->offset() == previous_field_offset) &&
7101 (access->IsInobject() == previous_field_is_in_object);
7107 } 7102 }
7108 ++count; 7103 ++count;
7109 } 7104 }
7110 } 7105 }
7111 7106
7112 // Use monomorphic load if property lookup results in the same field index 7107 // Use monomorphic load if property lookup results in the same field index
7113 // for all maps. Requires special map check on the set of all handled maps. 7108 // for all maps. Requires special map check on the set of all handled maps.
7114 AddInstruction(new(zone()) HCheckNonSmi(object)); 7109 AddInstruction(new(zone()) HCheckNonSmi(object));
7115 HInstruction* instr; 7110 HInstruction* instr;
7116 if (count == types->length() && is_monomorphic_field) { 7111 if (count == types->length() && is_monomorphic_field) {
7117 AddInstruction(HCheckMaps::New(object, types, zone())); 7112 AddInstruction(HCheckMaps::New(object, types, zone()));
7118 instr = BuildLoadNamedField(object, map, &lookup); 7113 instr = new(zone())
7114 HLoadNamedField(object, AccessField(map, name, &lookup));
7115 // TODO(titzer): ensure the representation is the same for all maps
7119 } else { 7116 } else {
7120 HValue* context = environment()->LookupContext(); 7117 HValue* context = environment()->LookupContext();
7121 instr = new(zone()) HLoadNamedFieldPolymorphic(context, 7118 instr = new(zone())
7122 object, 7119 HLoadNamedFieldPolymorphic(context, object, types, name, zone());
7123 types,
7124 name,
7125 zone());
7126 } 7120 }
7127 7121
7128 instr->set_position(expr->position()); 7122 instr->set_position(expr->position());
7129 return ast_context()->ReturnInstruction(instr, expr->id()); 7123 return ast_context()->ReturnInstruction(instr, expr->id());
7130 } 7124 }
7131 7125
7132 7126
7133 void HOptimizedGraphBuilder::HandlePolymorphicStoreNamedField( 7127 void HOptimizedGraphBuilder::HandlePolymorphicStoreNamedField(
7134 Assignment* expr, 7128 Assignment* expr,
7135 HValue* object, 7129 HValue* object,
(...skipping 532 matching lines...) Expand 10 before | Expand all | Expand 10 after
7668 HValue* value = environment()->Pop(); 7662 HValue* value = environment()->Pop();
7669 HThrow* instr = new(zone()) HThrow(context, value); 7663 HThrow* instr = new(zone()) HThrow(context, value);
7670 instr->set_position(expr->position()); 7664 instr->set_position(expr->position());
7671 AddInstruction(instr); 7665 AddInstruction(instr);
7672 AddSimulate(expr->id()); 7666 AddSimulate(expr->id());
7673 current_block()->FinishExit(new(zone()) HAbnormalExit); 7667 current_block()->FinishExit(new(zone()) HAbnormalExit);
7674 set_current_block(NULL); 7668 set_current_block(NULL);
7675 } 7669 }
7676 7670
7677 7671
7678 HLoadNamedField* HOptimizedGraphBuilder::BuildLoadNamedField(
7679 HValue* object,
7680 Handle<Map> map,
7681 LookupResult* lookup) {
7682 Representation representation = lookup->representation();
7683 int index = lookup->GetLocalFieldIndexFromMap(*map);
7684 if (index < 0) {
7685 // Negative property indices are in-object properties, indexed
7686 // from the end of the fixed part of the object.
7687 int offset = (index * kPointerSize) + map->instance_size();
7688 return new(zone()) HLoadNamedField(object, true, representation, offset);
7689 } else {
7690 // Non-negative property indices are in the properties array.
7691 int offset = (index * kPointerSize) + FixedArray::kHeaderSize;
7692 return new(zone()) HLoadNamedField(object, false, representation, offset);
7693 }
7694 }
7695
7696
7697 HInstruction* HOptimizedGraphBuilder::BuildLoadNamedGeneric( 7672 HInstruction* HOptimizedGraphBuilder::BuildLoadNamedGeneric(
7698 HValue* object, 7673 HValue* object,
7699 Handle<String> name, 7674 Handle<String> name,
7700 Property* expr) { 7675 Property* expr) {
7701 if (expr->IsUninitialized()) { 7676 if (expr->IsUninitialized()) {
7702 AddSoftDeoptimize(); 7677 AddSoftDeoptimize();
7703 } 7678 }
7704 HValue* context = environment()->LookupContext(); 7679 HValue* context = environment()->LookupContext();
7705 return new(zone()) HLoadNamedGeneric(context, object, name); 7680 return new(zone()) HLoadNamedGeneric(context, object, name);
7706 } 7681 }
(...skipping 15 matching lines...) Expand all
7722 Handle<String> name, 7697 Handle<String> name,
7723 Property* expr, 7698 Property* expr,
7724 Handle<Map> map) { 7699 Handle<Map> map) {
7725 // Handle a load from a known field. 7700 // Handle a load from a known field.
7726 ASSERT(!map->is_dictionary_map()); 7701 ASSERT(!map->is_dictionary_map());
7727 7702
7728 // Handle access to various length properties 7703 // Handle access to various length properties
7729 if (name->Equals(isolate()->heap()->length_string())) { 7704 if (name->Equals(isolate()->heap()->length_string())) {
7730 if (map->instance_type() == JS_ARRAY_TYPE) { 7705 if (map->instance_type() == JS_ARRAY_TYPE) {
7731 AddCheckMapsWithTransitions(object, map); 7706 AddCheckMapsWithTransitions(object, map);
7732 return HLoadNamedField::NewArrayLength(zone(), object, object); 7707 return new(zone()) HLoadNamedField(object, AccessArrayLength());
7733 } 7708 }
7734 } 7709 }
7735 7710
7736 LookupResult lookup(isolate()); 7711 LookupResult lookup(isolate());
7737 map->LookupDescriptor(NULL, *name, &lookup); 7712 map->LookupDescriptor(NULL, *name, &lookup);
7738 if (lookup.IsField()) { 7713 if (lookup.IsField()) {
7739 AddCheckMap(object, map); 7714 AddCheckMap(object, map);
7740 return BuildLoadNamedField(object, map, &lookup); 7715 HLoadNamedField* load = new(zone())
7716 HLoadNamedField(object, AccessField(map, name, &lookup));
7717 load->set_field_representation(
7718 ComputeLoadStoreRepresentation(map, &lookup));
7719 return load;
7741 } 7720 }
7742 7721
7743 // Handle a load of a constant known function. 7722 // Handle a load of a constant known function.
7744 if (lookup.IsConstantFunction()) { 7723 if (lookup.IsConstantFunction()) {
7745 AddCheckMap(object, map); 7724 AddCheckMap(object, map);
7746 Handle<JSFunction> function(lookup.GetConstantFunctionFromMap(*map)); 7725 Handle<JSFunction> function(lookup.GetConstantFunctionFromMap(*map));
7747 return new(zone()) HConstant(function, Representation::Tagged()); 7726 return new(zone()) HConstant(function, Representation::Tagged());
7748 } 7727 }
7749 7728
7750 // Handle a load from a known field somewhere in the prototype chain. 7729 // Handle a load from a known field somewhere in the prototype chain.
7751 LookupInPrototypes(map, name, &lookup); 7730 LookupInPrototypes(map, name, &lookup);
7752 if (lookup.IsField()) { 7731 if (lookup.IsField()) {
7753 Handle<JSObject> prototype(JSObject::cast(map->prototype())); 7732 Handle<JSObject> prototype(JSObject::cast(map->prototype()));
7754 Handle<JSObject> holder(lookup.holder()); 7733 Handle<JSObject> holder(lookup.holder());
7755 Handle<Map> holder_map(holder->map()); 7734 Handle<Map> holder_map(holder->map());
7756 AddCheckMap(object, map); 7735 AddCheckMap(object, map);
7757 AddInstruction( 7736 AddInstruction(new(zone())
7758 new(zone()) HCheckPrototypeMaps(prototype, holder, zone())); 7737 HCheckPrototypeMaps(prototype, holder, zone()));
7759 HValue* holder_value = AddInstruction( 7738 HValue* holder_value = AddInstruction(new(zone())
7760 new(zone()) HConstant(holder, Representation::Tagged())); 7739 HConstant(holder, Representation::Tagged()));
7761 return BuildLoadNamedField(holder_value, holder_map, &lookup); 7740 HLoadNamedField* load = new(zone())
7741 HLoadNamedField(holder_value, AccessField(holder_map, name, &lookup));
7742 load->set_field_representation(
7743 ComputeLoadStoreRepresentation(map, &lookup));
7744 return load;
7762 } 7745 }
7763 7746
7764 // Handle a load of a constant function somewhere in the prototype chain. 7747 // Handle a load of a constant function somewhere in the prototype chain.
7765 if (lookup.IsConstantFunction()) { 7748 if (lookup.IsConstantFunction()) {
7766 Handle<JSObject> prototype(JSObject::cast(map->prototype())); 7749 Handle<JSObject> prototype(JSObject::cast(map->prototype()));
7767 Handle<JSObject> holder(lookup.holder()); 7750 Handle<JSObject> holder(lookup.holder());
7768 Handle<Map> holder_map(holder->map()); 7751 Handle<Map> holder_map(holder->map());
7769 AddCheckMap(object, map); 7752 AddCheckMap(object, map);
7770 AddInstruction(new(zone()) HCheckPrototypeMaps(prototype, holder, zone())); 7753 AddInstruction(new(zone()) HCheckPrototypeMaps(prototype, holder, zone()));
7771 Handle<JSFunction> function(lookup.GetConstantFunctionFromMap(*holder_map)); 7754 Handle<JSFunction> function(lookup.GetConstantFunctionFromMap(*holder_map));
(...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after
8015 // it's a keyed property) and registered in the full codegen. 7998 // it's a keyed property) and registered in the full codegen.
8016 HBasicBlock* if_jsarray = graph()->CreateBasicBlock(); 7999 HBasicBlock* if_jsarray = graph()->CreateBasicBlock();
8017 HBasicBlock* if_fastobject = graph()->CreateBasicBlock(); 8000 HBasicBlock* if_fastobject = graph()->CreateBasicBlock();
8018 HHasInstanceTypeAndBranch* typecheck = 8001 HHasInstanceTypeAndBranch* typecheck =
8019 new(zone()) HHasInstanceTypeAndBranch(object, JS_ARRAY_TYPE); 8002 new(zone()) HHasInstanceTypeAndBranch(object, JS_ARRAY_TYPE);
8020 typecheck->SetSuccessorAt(0, if_jsarray); 8003 typecheck->SetSuccessorAt(0, if_jsarray);
8021 typecheck->SetSuccessorAt(1, if_fastobject); 8004 typecheck->SetSuccessorAt(1, if_fastobject);
8022 current_block()->Finish(typecheck); 8005 current_block()->Finish(typecheck);
8023 8006
8024 set_current_block(if_jsarray); 8007 set_current_block(if_jsarray);
8025 HInstruction* length; 8008 HInstruction* length = AddLoad(object, AccessArrayLength(), typecheck);
8026 length = AddInstruction( 8009 length->set_type(HType::Smi());
8027 HLoadNamedField::NewArrayLength(zone(), object, typecheck, 8010 // TODO(titzer): length->set_field_representation(Representation::Smi())
8028 HType::Smi())); 8011
8029 checked_key = AddBoundsCheck(key, length, ALLOW_SMI_KEY); 8012 checked_key = AddBoundsCheck(key, length, ALLOW_SMI_KEY);
8030 access = AddInstruction(BuildFastElementAccess( 8013 access = AddInstruction(BuildFastElementAccess(
8031 elements, checked_key, val, elements_kind_branch, 8014 elements, checked_key, val, elements_kind_branch,
8032 elements_kind, is_store, STANDARD_STORE)); 8015 elements_kind, is_store, STANDARD_STORE));
8033 if (!is_store) { 8016 if (!is_store) {
8034 Push(access); 8017 Push(access);
8035 } 8018 }
8036 8019
8037 *has_side_effects |= access->HasObservableSideEffects(); 8020 *has_side_effects |= access->HasObservableSideEffects();
8038 // The caller will use has_side_effects and add correct Simulate. 8021 // The caller will use has_side_effects and add correct Simulate.
(...skipping 2672 matching lines...) Expand 10 before | Expand all | Expand 10 after
10711 Handle<Object> value = 10694 Handle<Object> value =
10712 Handle<Object>(boilerplate_object->InObjectPropertyAt(i), 10695 Handle<Object>(boilerplate_object->InObjectPropertyAt(i),
10713 isolate()); 10696 isolate());
10714 if (value->IsJSObject()) { 10697 if (value->IsJSObject()) {
10715 Handle<JSObject> value_object = Handle<JSObject>::cast(value); 10698 Handle<JSObject> value_object = Handle<JSObject>::cast(value);
10716 Handle<JSObject> original_value_object = Handle<JSObject>::cast( 10699 Handle<JSObject> original_value_object = Handle<JSObject>::cast(
10717 Handle<Object>(original_boilerplate_object->InObjectPropertyAt(i), 10700 Handle<Object>(original_boilerplate_object->InObjectPropertyAt(i),
10718 isolate())); 10701 isolate()));
10719 HInstruction* value_instruction = 10702 HInstruction* value_instruction =
10720 AddInstruction(new(zone) HInnerAllocatedObject(target, *offset)); 10703 AddInstruction(new(zone) HInnerAllocatedObject(target, *offset));
10704
10721 // TODO(verwaest): choose correct storage. 10705 // TODO(verwaest): choose correct storage.
10722 AddInstruction(new(zone) HStoreNamedField( 10706 HObjectAccess* access = AccessInobject(factory->unknown_field_string(),
10723 object_properties, factory->unknown_field_string(), value_instruction, 10707 boilerplate_object->GetInObjectPropertyOffset(i));
10724 true, Representation::Tagged(), 10708 AddStore(object_properties, access, value_instruction);
10725 boilerplate_object->GetInObjectPropertyOffset(i))); 10709
10726 BuildEmitDeepCopy(value_object, original_value_object, target, 10710 BuildEmitDeepCopy(value_object, original_value_object, target,
10727 offset, DONT_TRACK_ALLOCATION_SITE); 10711 offset, DONT_TRACK_ALLOCATION_SITE);
10728 } else { 10712 } else {
10729 // TODO(verwaest): choose correct storage. 10713 // TODO(verwaest): choose correct storage.
10730 HInstruction* value_instruction = AddInstruction(new(zone) HConstant( 10714 HInstruction* value_instruction = AddInstruction(new(zone) HConstant(
10731 value, Representation::Tagged())); 10715 value, Representation::Tagged()));
10732 AddInstruction(new(zone) HStoreNamedField( 10716
10733 object_properties, factory->unknown_field_string(), value_instruction, 10717 HObjectAccess* access = AccessInobject(factory->unknown_field_string(),
10734 true, Representation::Tagged(), 10718 boilerplate_object->GetInObjectPropertyOffset(i));
10735 boilerplate_object->GetInObjectPropertyOffset(i))); 10719 AddStore(object_properties, access, value_instruction);
10736 } 10720 }
10737 } 10721 }
10738 10722
10739 // Build Allocation Site Info if desired 10723 // Build Allocation Site Info if desired
10740 if (create_allocation_site_info) { 10724 if (create_allocation_site_info) {
10741 BuildCreateAllocationSiteInfo(target, JSArray::kSize, original_boilerplate); 10725 BuildCreateAllocationSiteInfo(target, JSArray::kSize, original_boilerplate);
10742 } 10726 }
10743 10727
10744 if (object_elements != NULL) { 10728 if (object_elements != NULL) {
10745 HInstruction* boilerplate_elements = AddInstruction(new(zone) HConstant( 10729 HInstruction* boilerplate_elements = AddInstruction(new(zone) HConstant(
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
10803 int elements_offset, 10787 int elements_offset,
10804 int elements_size) { 10788 int elements_size) {
10805 ASSERT(boilerplate_object->properties()->length() == 0); 10789 ASSERT(boilerplate_object->properties()->length() == 0);
10806 Zone* zone = this->zone(); 10790 Zone* zone = this->zone();
10807 Factory* factory = isolate()->factory(); 10791 Factory* factory = isolate()->factory();
10808 HValue* result = NULL; 10792 HValue* result = NULL;
10809 10793
10810 HValue* object_header = 10794 HValue* object_header =
10811 AddInstruction(new(zone) HInnerAllocatedObject(target, object_offset)); 10795 AddInstruction(new(zone) HInnerAllocatedObject(target, object_offset));
10812 Handle<Map> boilerplate_object_map(boilerplate_object->map()); 10796 Handle<Map> boilerplate_object_map(boilerplate_object->map());
10813 BuildStoreMap(object_header, boilerplate_object_map); 10797 AddStoreMapConstant(object_header, boilerplate_object_map);
10814 10798
10815 HInstruction* elements; 10799 HInstruction* elements;
10816 if (elements_size == 0) { 10800 if (elements_size == 0) {
10817 Handle<Object> elements_field = 10801 Handle<Object> elements_field =
10818 Handle<Object>(boilerplate_object->elements(), isolate()); 10802 Handle<Object>(boilerplate_object->elements(), isolate());
10819 elements = AddInstruction(new(zone) HConstant( 10803 elements = AddInstruction(new(zone) HConstant(
10820 elements_field, Representation::Tagged())); 10804 elements_field, Representation::Tagged()));
10821 } else { 10805 } else {
10822 elements = AddInstruction(new(zone) HInnerAllocatedObject( 10806 elements = AddInstruction(new(zone) HInnerAllocatedObject(
10823 target, elements_offset)); 10807 target, elements_offset));
10824 result = elements; 10808 result = elements;
10825 } 10809 }
10826 HInstruction* elements_store = AddInstruction(new(zone) HStoreNamedField( 10810 AddStore(object_header, AccessElements(), elements);
10827 object_header,
10828 factory->elements_field_string(),
10829 elements,
10830 true, Representation::Tagged(), JSObject::kElementsOffset));
10831 elements_store->SetGVNFlag(kChangesElementsPointer);
10832 10811
10833 Handle<Object> properties_field = 10812 Handle<Object> properties_field =
10834 Handle<Object>(boilerplate_object->properties(), isolate()); 10813 Handle<Object>(boilerplate_object->properties(), isolate());
10835 ASSERT(*properties_field == isolate()->heap()->empty_fixed_array()); 10814 ASSERT(*properties_field == isolate()->heap()->empty_fixed_array());
10836 HInstruction* properties = AddInstruction(new(zone) HConstant( 10815 HInstruction* properties = AddInstruction(new(zone) HConstant(
10837 properties_field, Representation::None())); 10816 properties_field, Representation::None()));
10838 AddInstruction(new(zone) HStoreNamedField(object_header, 10817 HObjectAccess* access = AccessInobject(
10839 factory->empty_string(), 10818 factory->empty_string(), JSObject::kPropertiesOffset);
10840 properties, true, 10819 AddStore(object_header, access, properties);
10841 Representation::Tagged(),
10842 JSObject::kPropertiesOffset));
10843 10820
10844 if (boilerplate_object->IsJSArray()) { 10821 if (boilerplate_object->IsJSArray()) {
10845 Handle<JSArray> boilerplate_array = 10822 Handle<JSArray> boilerplate_array =
10846 Handle<JSArray>::cast(boilerplate_object); 10823 Handle<JSArray>::cast(boilerplate_object);
10847 Handle<Object> length_field = 10824 Handle<Object> length_field =
10848 Handle<Object>(boilerplate_array->length(), isolate()); 10825 Handle<Object>(boilerplate_array->length(), isolate());
10849 HInstruction* length = AddInstruction(new(zone) HConstant( 10826 HInstruction* length = AddInstruction(new(zone) HConstant(
10850 length_field, Representation::None())); 10827 length_field, Representation::None()));
10828
10851 ASSERT(boilerplate_array->length()->IsSmi()); 10829 ASSERT(boilerplate_array->length()->IsSmi());
10852 Representation representation = 10830 Representation representation =
10853 IsFastElementsKind(boilerplate_array->GetElementsKind()) 10831 IsFastElementsKind(boilerplate_array->GetElementsKind())
10854 ? Representation::Smi() : Representation::Tagged(); 10832 ? Representation::Smi() : Representation::Tagged();
10855 HInstruction* length_store = AddInstruction(new(zone) HStoreNamedField( 10833 AddStore(object_header, AccessArrayLength(), length, representation);
10856 object_header,
10857 factory->length_field_string(),
10858 length,
10859 true, representation, JSArray::kLengthOffset));
10860 length_store->SetGVNFlag(kChangesArrayLengths);
10861 } 10834 }
10862 10835
10863 return result; 10836 return result;
10864 } 10837 }
10865 10838
10866 10839
10867 void HOptimizedGraphBuilder::VisitThisFunction(ThisFunction* expr) { 10840 void HOptimizedGraphBuilder::VisitThisFunction(ThisFunction* expr) {
10868 ASSERT(!HasStackOverflow()); 10841 ASSERT(!HasStackOverflow());
10869 ASSERT(current_block() != NULL); 10842 ASSERT(current_block() != NULL);
10870 ASSERT(current_block()->HasPredecessor()); 10843 ASSERT(current_block()->HasPredecessor());
(...skipping 367 matching lines...) Expand 10 before | Expand all | Expand 10 after
11238 HBasicBlock* if_js_value = graph()->CreateBasicBlock(); 11211 HBasicBlock* if_js_value = graph()->CreateBasicBlock();
11239 HBasicBlock* not_js_value = graph()->CreateBasicBlock(); 11212 HBasicBlock* not_js_value = graph()->CreateBasicBlock();
11240 typecheck->SetSuccessorAt(0, if_js_value); 11213 typecheck->SetSuccessorAt(0, if_js_value);
11241 typecheck->SetSuccessorAt(1, not_js_value); 11214 typecheck->SetSuccessorAt(1, not_js_value);
11242 current_block()->Finish(typecheck); 11215 current_block()->Finish(typecheck);
11243 not_js_value->Goto(join); 11216 not_js_value->Goto(join);
11244 11217
11245 // Create in-object property store to kValueOffset. 11218 // Create in-object property store to kValueOffset.
11246 set_current_block(if_js_value); 11219 set_current_block(if_js_value);
11247 Handle<String> name = isolate()->factory()->undefined_string(); 11220 Handle<String> name = isolate()->factory()->undefined_string();
11248 AddInstruction(new(zone()) HStoreNamedField(object, 11221 AddStore(object, AccessInobject(name, JSValue::kValueOffset), value);
11249 name,
11250 value,
11251 true, // in-object store.
11252 Representation::Tagged(),
11253 JSValue::kValueOffset));
11254 if_js_value->Goto(join); 11222 if_js_value->Goto(join);
11255 join->SetJoinId(call->id()); 11223 join->SetJoinId(call->id());
11256 set_current_block(join); 11224 set_current_block(join);
11257 return ast_context()->ReturnValue(value); 11225 return ast_context()->ReturnValue(value);
11258 } 11226 }
11259 11227
11260 11228
11261 // Fast support for charCodeAt(n). 11229 // Fast support for charCodeAt(n).
11262 void HOptimizedGraphBuilder::GenerateStringCharCodeAt(CallRuntime* call) { 11230 void HOptimizedGraphBuilder::GenerateStringCharCodeAt(CallRuntime* call) {
11263 ASSERT(call->arguments()->length() == 2); 11231 ASSERT(call->arguments()->length() == 2);
(...skipping 954 matching lines...) Expand 10 before | Expand all | Expand 10 after
12218 } 12186 }
12219 } 12187 }
12220 12188
12221 #ifdef DEBUG 12189 #ifdef DEBUG
12222 if (graph_ != NULL) graph_->Verify(false); // No full verify. 12190 if (graph_ != NULL) graph_->Verify(false); // No full verify.
12223 if (allocator_ != NULL) allocator_->Verify(); 12191 if (allocator_ != NULL) allocator_->Verify();
12224 #endif 12192 #endif
12225 } 12193 }
12226 12194
12227 } } // namespace v8::internal 12195 } } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698