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

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: Move all construction of HObjectAccess into static methods, hiding Portion. 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, HObjectAccess::ForArrayLength(), new_length,
1195 Representation representation = IsFastElementsKind(kind) 1195 IsFastElementsKind(kind)
1196 ? 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 } 1197 }
1205 1198
1206 length_checker.Else(); 1199 length_checker.Else();
1207 1200
1208 AddBoundsCheck(key, length, ALLOW_SMI_KEY); 1201 AddBoundsCheck(key, length, ALLOW_SMI_KEY);
1209 environment()->Push(elements); 1202 environment()->Push(elements);
1210 1203
1211 length_checker.End(); 1204 length_checker.End();
1212 1205
1213 return environment()->Pop(); 1206 return environment()->Pop();
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
1275 AddInstruction(new(zone) HLoadElements(object, mapcheck)); 1268 AddInstruction(new(zone) HLoadElements(object, mapcheck));
1276 if (is_store && (fast_elements || fast_smi_only_elements) && 1269 if (is_store && (fast_elements || fast_smi_only_elements) &&
1277 store_mode != STORE_NO_TRANSITION_HANDLE_COW) { 1270 store_mode != STORE_NO_TRANSITION_HANDLE_COW) {
1278 HCheckMaps* check_cow_map = HCheckMaps::New( 1271 HCheckMaps* check_cow_map = HCheckMaps::New(
1279 elements, isolate()->factory()->fixed_array_map(), zone); 1272 elements, isolate()->factory()->fixed_array_map(), zone);
1280 check_cow_map->ClearGVNFlag(kDependsOnElementsKind); 1273 check_cow_map->ClearGVNFlag(kDependsOnElementsKind);
1281 AddInstruction(check_cow_map); 1274 AddInstruction(check_cow_map);
1282 } 1275 }
1283 HInstruction* length = NULL; 1276 HInstruction* length = NULL;
1284 if (is_js_array) { 1277 if (is_js_array) {
1285 length = AddInstruction( 1278 length = AddLoad(object, HObjectAccess::ForArrayLength(), mapcheck);
1286 HLoadNamedField::NewArrayLength(zone, object, mapcheck, HType::Smi())); 1279 length->set_type(HType::Smi());
1287 } else { 1280 } else {
1288 length = AddInstruction(new(zone) HFixedArrayBaseLength(elements)); 1281 length = AddInstruction(new(zone) HFixedArrayBaseLength(elements));
1289 } 1282 }
1290 HValue* checked_key = NULL; 1283 HValue* checked_key = NULL;
1291 if (IsExternalArrayElementsKind(elements_kind)) { 1284 if (IsExternalArrayElementsKind(elements_kind)) {
1292 if (store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS) { 1285 if (store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS) {
1293 NoObservableSideEffectsScope no_effects(this); 1286 NoObservableSideEffectsScope no_effects(this);
1294 HLoadExternalArrayPointer* external_elements = 1287 HLoadExternalArrayPointer* external_elements =
1295 new(zone) HLoadExternalArrayPointer(elements); 1288 new(zone) HLoadExternalArrayPointer(elements);
1296 AddInstruction(external_elements); 1289 AddInstruction(external_elements);
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
1402 HValue* elements = 1395 HValue* elements =
1403 AddInstruction(new(zone) HAllocate(context, total_size, 1396 AddInstruction(new(zone) HAllocate(context, total_size,
1404 HType::JSArray(), flags)); 1397 HType::JSArray(), flags));
1405 return elements; 1398 return elements;
1406 } 1399 }
1407 1400
1408 1401
1409 void HGraphBuilder::BuildInitializeElements(HValue* elements, 1402 void HGraphBuilder::BuildInitializeElements(HValue* elements,
1410 ElementsKind kind, 1403 ElementsKind kind,
1411 HValue* capacity) { 1404 HValue* capacity) {
1412 Zone* zone = this->zone();
1413 Factory* factory = isolate()->factory(); 1405 Factory* factory = isolate()->factory();
1414 Handle<Map> map = IsFastDoubleElementsKind(kind) 1406 Handle<Map> map = IsFastDoubleElementsKind(kind)
1415 ? factory->fixed_double_array_map() 1407 ? factory->fixed_double_array_map()
1416 : factory->fixed_array_map(); 1408 : factory->fixed_array_map();
1417 BuildStoreMap(elements, map);
1418 1409
1419 Handle<String> fixed_array_length_field_name = factory->length_field_string(); 1410 AddStoreMapConstant(elements, map);
1420 Representation representation = IsFastElementsKind(kind) 1411 AddStore(elements, HObjectAccess::ForFixedArrayLength(), capacity,
1421 ? Representation::Smi() : Representation::Tagged(); 1412 IsFastElementsKind(kind)
1422 HInstruction* store_length = 1413 ? 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 } 1414 }
1428 1415
1429 1416
1430 HValue* HGraphBuilder::BuildAllocateAndInitializeElements(HValue* context, 1417 HValue* HGraphBuilder::BuildAllocateAndInitializeElements(HValue* context,
1431 ElementsKind kind, 1418 ElementsKind kind,
1432 HValue* capacity) { 1419 HValue* capacity) {
1433 HValue* new_elements = BuildAllocateElements(context, kind, capacity); 1420 HValue* new_elements = BuildAllocateElements(context, kind, capacity);
1434 BuildInitializeElements(new_elements, kind, capacity); 1421 BuildInitializeElements(new_elements, kind, capacity);
1435 return new_elements; 1422 return new_elements;
1436 } 1423 }
1437 1424
1438 1425
1439 HInnerAllocatedObject* HGraphBuilder::BuildJSArrayHeader(HValue* array, 1426 HInnerAllocatedObject* HGraphBuilder::BuildJSArrayHeader(HValue* array,
1440 HValue* array_map, 1427 HValue* array_map,
1441 AllocationSiteMode mode, 1428 AllocationSiteMode mode,
1442 HValue* allocation_site_payload, 1429 HValue* allocation_site_payload,
1443 HValue* length_field) { 1430 HValue* length_field) {
1444 1431
1445 BuildStoreMap(array, array_map); 1432 AddStore(array, HObjectAccess::ForMap(), array_map);
1446 1433
1447 HConstant* empty_fixed_array = 1434 HConstant* empty_fixed_array =
1448 new(zone()) HConstant( 1435 new(zone()) HConstant(
1449 Handle<FixedArray>(isolate()->heap()->empty_fixed_array()), 1436 Handle<FixedArray>(isolate()->heap()->empty_fixed_array()),
1450 Representation::Tagged()); 1437 Representation::Tagged());
1451 AddInstruction(empty_fixed_array); 1438 AddInstruction(empty_fixed_array);
1452 1439
1453 AddInstruction(new(zone()) HStoreNamedField(array, 1440 HObjectAccess *access = HObjectAccess::ForInobjectOffset(zone(),
1454 isolate()->factory()->properties_field_symbol(), 1441 JSArray::kPropertiesOffset,
1455 empty_fixed_array, 1442 isolate()->factory()->properties_field_symbol());
1456 true,
1457 Representation::Tagged(),
1458 JSArray::kPropertiesOffset));
1459 1443
1460 HInstruction* length_store = AddInstruction( 1444 AddStore(array, access, empty_fixed_array);
1461 new(zone()) HStoreNamedField(array, 1445 AddStore(array, HObjectAccess::ForArrayLength(), length_field);
1462 isolate()->factory()->length_field_string(),
1463 length_field,
1464 true,
1465 Representation::Tagged(),
1466 JSArray::kLengthOffset));
1467 length_store->SetGVNFlag(kChangesArrayLengths);
1468 1446
1469 if (mode == TRACK_ALLOCATION_SITE) { 1447 if (mode == TRACK_ALLOCATION_SITE) {
1470 BuildCreateAllocationSiteInfo(array, 1448 BuildCreateAllocationSiteInfo(array,
1471 JSArray::kSize, 1449 JSArray::kSize,
1472 allocation_site_payload); 1450 allocation_site_payload);
1473 } 1451 }
1474 1452
1475 int elements_location = JSArray::kSize; 1453 int elements_location = JSArray::kSize;
1476 if (mode == TRACK_ALLOCATION_SITE) { 1454 if (mode == TRACK_ALLOCATION_SITE) {
1477 elements_location += AllocationSiteInfo::kSize; 1455 elements_location += AllocationSiteInfo::kSize;
1478 } 1456 }
1479 1457
1480 HInnerAllocatedObject* elements = new(zone()) HInnerAllocatedObject( 1458 HInnerAllocatedObject* elements = new(zone()) HInnerAllocatedObject(
1481 array, 1459 array, elements_location);
1482 elements_location);
1483 AddInstruction(elements); 1460 AddInstruction(elements);
1484 1461
1485 HInstruction* elements_store = AddInstruction( 1462 AddStore(array, HObjectAccess::ForElementsPointer(), 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; 1463 return elements;
1496 } 1464 }
1497 1465
1498 1466
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, 1467 HValue* HGraphBuilder::BuildNewElementsCapacity(HValue* context,
1525 HValue* old_capacity) { 1468 HValue* old_capacity) {
1526 Zone* zone = this->zone(); 1469 Zone* zone = this->zone();
1527 HValue* half_old_capacity = 1470 HValue* half_old_capacity =
1528 AddInstruction(HShr::New(zone, context, old_capacity, 1471 AddInstruction(HShr::New(zone, context, old_capacity,
1529 graph_->GetConstant1())); 1472 graph_->GetConstant1()));
1530 half_old_capacity->ChangeRepresentation(Representation::Integer32()); 1473 half_old_capacity->ChangeRepresentation(Representation::Integer32());
1531 half_old_capacity->ClearFlag(HValue::kCanOverflow); 1474 half_old_capacity->ClearFlag(HValue::kCanOverflow);
1532 1475
1533 HValue* new_capacity = AddInstruction( 1476 HValue* new_capacity = AddInstruction(
(...skipping 29 matching lines...) Expand all
1563 HBoundsCheck(length, max_size_constant, 1506 HBoundsCheck(length, max_size_constant,
1564 DONT_ALLOW_SMI_KEY, Representation::Integer32())); 1507 DONT_ALLOW_SMI_KEY, Representation::Integer32()));
1565 } 1508 }
1566 1509
1567 1510
1568 HValue* HGraphBuilder::BuildGrowElementsCapacity(HValue* object, 1511 HValue* HGraphBuilder::BuildGrowElementsCapacity(HValue* object,
1569 HValue* elements, 1512 HValue* elements,
1570 ElementsKind kind, 1513 ElementsKind kind,
1571 HValue* length, 1514 HValue* length,
1572 HValue* new_capacity) { 1515 HValue* new_capacity) {
1573 Zone* zone = this->zone();
1574 HValue* context = environment()->LookupContext(); 1516 HValue* context = environment()->LookupContext();
1575 1517
1576 BuildNewSpaceArrayCheck(new_capacity, kind); 1518 BuildNewSpaceArrayCheck(new_capacity, kind);
1577 1519
1578 HValue* new_elements = 1520 HValue* new_elements =
1579 BuildAllocateAndInitializeElements(context, kind, new_capacity); 1521 BuildAllocateAndInitializeElements(context, kind, new_capacity);
1580 1522
1581 BuildCopyElements(context, elements, kind, 1523 BuildCopyElements(context, elements, kind,
1582 new_elements, kind, 1524 new_elements, kind,
1583 length, new_capacity); 1525 length, new_capacity);
1584 1526
1585 Factory* factory = isolate()->factory(); 1527 AddStore(object, HObjectAccess::ForElementsPointer(), 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 1528
1593 return new_elements; 1529 return new_elements;
1594 } 1530 }
1595 1531
1596 1532
1597 void HGraphBuilder::BuildFillElementsWithHole(HValue* context, 1533 void HGraphBuilder::BuildFillElementsWithHole(HValue* context,
1598 HValue* elements, 1534 HValue* elements,
1599 ElementsKind elements_kind, 1535 ElementsKind elements_kind,
1600 HValue* from, 1536 HValue* from,
1601 HValue* to) { 1537 HValue* to) {
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
1686 } 1622 }
1687 } 1623 }
1688 1624
1689 1625
1690 HValue* HGraphBuilder::BuildCloneShallowArray(HContext* context, 1626 HValue* HGraphBuilder::BuildCloneShallowArray(HContext* context,
1691 HValue* boilerplate, 1627 HValue* boilerplate,
1692 AllocationSiteMode mode, 1628 AllocationSiteMode mode,
1693 ElementsKind kind, 1629 ElementsKind kind,
1694 int length) { 1630 int length) {
1695 Zone* zone = this->zone(); 1631 Zone* zone = this->zone();
1696 Factory* factory = isolate()->factory();
1697 1632
1698 NoObservableSideEffectsScope no_effects(this); 1633 NoObservableSideEffectsScope no_effects(this);
1699 1634
1700 // All sizes here are multiples of kPointerSize. 1635 // All sizes here are multiples of kPointerSize.
1701 int size = JSArray::kSize; 1636 int size = JSArray::kSize;
1702 if (mode == TRACK_ALLOCATION_SITE) { 1637 if (mode == TRACK_ALLOCATION_SITE) {
1703 size += AllocationSiteInfo::kSize; 1638 size += AllocationSiteInfo::kSize;
1704 } 1639 }
1705 int elems_offset = size; 1640 int elems_offset = size;
1706 if (length > 0) { 1641 if (length > 0) {
1707 size += IsFastDoubleElementsKind(kind) 1642 size += IsFastDoubleElementsKind(kind)
1708 ? FixedDoubleArray::SizeFor(length) 1643 ? FixedDoubleArray::SizeFor(length)
1709 : FixedArray::SizeFor(length); 1644 : FixedArray::SizeFor(length);
1710 } 1645 }
1711 1646
1712 HAllocate::Flags allocate_flags = HAllocate::DefaultFlags(kind); 1647 HAllocate::Flags allocate_flags = HAllocate::DefaultFlags(kind);
1713 // Allocate both the JS array and the elements array in one big 1648 // Allocate both the JS array and the elements array in one big
1714 // allocation. This avoids multiple limit checks. 1649 // allocation. This avoids multiple limit checks.
1715 HValue* size_in_bytes = 1650 HValue* size_in_bytes =
1716 AddInstruction(new(zone) HConstant(size, Representation::Integer32())); 1651 AddInstruction(new(zone) HConstant(size, Representation::Integer32()));
1717 HInstruction* object = 1652 HInstruction* object =
1718 AddInstruction(new(zone) HAllocate(context, 1653 AddInstruction(new(zone) HAllocate(context,
1719 size_in_bytes, 1654 size_in_bytes,
1720 HType::JSObject(), 1655 HType::JSObject(),
1721 allocate_flags)); 1656 allocate_flags));
1722 1657
1723 // Copy the JS array part. 1658 // Copy the JS array part.
1724 for (int i = 0; i < JSArray::kSize; i += kPointerSize) { 1659 for (int i = 0; i < JSArray::kSize; i += kPointerSize) {
1725 if ((i != JSArray::kElementsOffset) || (length == 0)) { 1660 if ((i != JSArray::kElementsOffset) || (length == 0)) {
1726 HInstruction* value = AddInstruction(new(zone) HLoadNamedField( 1661 HObjectAccess* access = HObjectAccess::ForInobjectOffset(zone, i);
1727 boilerplate, true, Representation::Tagged(), i)); 1662 HInstruction* value = AddLoad(boilerplate, access);
1728 if (i != JSArray::kMapOffset) { 1663 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 } 1664 }
1737 } 1665 }
1738 1666
1739 // Create an allocation site info if requested. 1667 // Create an allocation site info if requested.
1740 if (mode == TRACK_ALLOCATION_SITE) { 1668 if (mode == TRACK_ALLOCATION_SITE) {
1741 BuildCreateAllocationSiteInfo(object, JSArray::kSize, boilerplate); 1669 BuildCreateAllocationSiteInfo(object, JSArray::kSize, boilerplate);
1742 } 1670 }
1743 1671
1744 if (length > 0) { 1672 if (length > 0) {
1745 // Get hold of the elements array of the boilerplate and setup the 1673 // Get hold of the elements array of the boilerplate and setup the
1746 // elements pointer in the resulting object. 1674 // elements pointer in the resulting object.
1747 HValue* boilerplate_elements = 1675 HValue* boilerplate_elements =
1748 AddInstruction(new(zone) HLoadElements(boilerplate, NULL)); 1676 AddInstruction(new(zone) HLoadElements(boilerplate, NULL));
1749 HValue* object_elements = 1677 HValue* object_elements =
1750 AddInstruction(new(zone) HInnerAllocatedObject(object, elems_offset)); 1678 AddInstruction(new(zone) HInnerAllocatedObject(object, elems_offset));
1751 AddInstruction(new(zone) HStoreNamedField(object, 1679 AddStore(object, HObjectAccess::ForElementsPointer(), object_elements);
1752 factory->elements_field_string(),
1753 object_elements, true,
1754 Representation::Tagged(),
1755 JSObject::kElementsOffset));
1756 1680
1757 // Copy the elements array header. 1681 // Copy the elements array header.
1758 for (int i = 0; i < FixedArrayBase::kHeaderSize; i += kPointerSize) { 1682 for (int i = 0; i < FixedArrayBase::kHeaderSize; i += kPointerSize) {
1759 HInstruction* value = 1683 // TODO(titzer): AccessFixedArray?
1760 AddInstruction(new(zone) HLoadNamedField( 1684 HObjectAccess* access = HObjectAccess::ForInobjectOffset(zone, i);
1761 boilerplate_elements, true, Representation::Tagged(), i)); 1685 HInstruction* value = AddLoad(boilerplate_elements, access);
1762 AddInstruction(new(zone) HStoreNamedField(object_elements, 1686 AddStore(object_elements, access, value);
1763 factory->empty_string(),
1764 value, true,
1765 Representation::Tagged(), i));
1766 } 1687 }
1767 1688
1768 // Copy the elements array contents. 1689 // Copy the elements array contents.
1769 // TODO(mstarzinger): Teach HGraphBuilder::BuildCopyElements to unfold 1690 // TODO(mstarzinger): Teach HGraphBuilder::BuildCopyElements to unfold
1770 // copying loops with constant length up to a given boundary and use this 1691 // copying loops with constant length up to a given boundary and use this
1771 // helper here instead. 1692 // helper here instead.
1772 for (int i = 0; i < length; i++) { 1693 for (int i = 0; i < length; i++) {
1773 HValue* key_constant = 1694 HValue* key_constant =
1774 AddInstruction(new(zone) HConstant(i, Representation::Integer32())); 1695 AddInstruction(new(zone) HConstant(i, Representation::Integer32()));
1775 HInstruction* value = 1696 HInstruction* value =
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
1835 } 1756 }
1836 1757
1837 1758
1838 HValue* HGraphBuilder::BuildCreateAllocationSiteInfo(HValue* previous_object, 1759 HValue* HGraphBuilder::BuildCreateAllocationSiteInfo(HValue* previous_object,
1839 int previous_object_size, 1760 int previous_object_size,
1840 HValue* payload) { 1761 HValue* payload) {
1841 HInnerAllocatedObject* alloc_site = new(zone()) 1762 HInnerAllocatedObject* alloc_site = new(zone())
1842 HInnerAllocatedObject(previous_object, previous_object_size); 1763 HInnerAllocatedObject(previous_object, previous_object_size);
1843 AddInstruction(alloc_site); 1764 AddInstruction(alloc_site);
1844 Handle<Map> alloc_site_map(isolate()->heap()->allocation_site_info_map()); 1765 Handle<Map> alloc_site_map(isolate()->heap()->allocation_site_info_map());
1845 BuildStoreMap(alloc_site, alloc_site_map); 1766 AddStoreMapConstant(alloc_site, alloc_site_map);
1846 AddInstruction(new(zone()) HStoreNamedField(alloc_site, 1767 HObjectAccess* access = HObjectAccess::ForInobjectOffset(zone(),
1847 isolate()->factory()->payload_string(), 1768 AllocationSiteInfo::kPayloadOffset,
1848 payload, 1769 isolate()->factory()->payload_string());
1849 true, 1770 AddStore(alloc_site, access, payload);
1850 Representation::Tagged(),
1851 AllocationSiteInfo::kPayloadOffset));
1852 return alloc_site; 1771 return alloc_site;
1853 } 1772 }
1854 1773
1855 1774
1856 HGraphBuilder::JSArrayBuilder::JSArrayBuilder(HGraphBuilder* builder, 1775 HGraphBuilder::JSArrayBuilder::JSArrayBuilder(HGraphBuilder* builder,
1857 ElementsKind kind, 1776 ElementsKind kind,
1858 HValue* allocation_site_payload, 1777 HValue* allocation_site_payload,
1859 AllocationSiteMode mode) : 1778 AllocationSiteMode mode) :
1860 builder_(builder), 1779 builder_(builder),
1861 kind_(kind), 1780 kind_(kind),
1862 allocation_site_payload_(allocation_site_payload) { 1781 allocation_site_payload_(allocation_site_payload) {
1863 if (mode == DONT_TRACK_ALLOCATION_SITE) { 1782 if (mode == DONT_TRACK_ALLOCATION_SITE) {
1864 mode_ = mode; 1783 mode_ = mode;
1865 } else { 1784 } else {
1866 mode_ = AllocationSiteInfo::GetMode(kind); 1785 mode_ = AllocationSiteInfo::GetMode(kind);
1867 } 1786 }
1868 } 1787 }
1869 1788
1870 1789
1871 HValue* HGraphBuilder::JSArrayBuilder::EmitMapCode(HValue* context) { 1790 HValue* HGraphBuilder::JSArrayBuilder::EmitMapCode(HValue* context) {
1872 // Get the global context, the native context, the map array 1791 // Get the global context, the native context, the map array
1873 HInstruction* global_object = AddInstruction(new(zone()) 1792 HInstruction* global_object = AddInstruction(new(zone())
1874 HGlobalObject(context)); 1793 HGlobalObject(context));
1875 HInstruction* native_context = AddInstruction(new(zone()) 1794 HObjectAccess* access = HObjectAccess::ForOffset(zone(),
1876 HLoadNamedField(global_object, true, Representation::Tagged(), 1795 GlobalObject::kNativeContextOffset);
1877 GlobalObject::kNativeContextOffset)); 1796 HInstruction* native_context = builder()->AddLoad(global_object, access);
1797
1878 int offset = Context::kHeaderSize + 1798 int offset = Context::kHeaderSize +
1879 kPointerSize * Context::JS_ARRAY_MAPS_INDEX; 1799 kPointerSize * Context::JS_ARRAY_MAPS_INDEX;
1880 HInstruction* map_array = AddInstruction(new(zone()) 1800 access = HObjectAccess::ForOffset(zone(), offset);
1881 HLoadNamedField(native_context, true, Representation::Tagged(), offset)); 1801 HInstruction* map_array = builder()->AddLoad(native_context, access);
1802
1882 offset = kind_ * kPointerSize + FixedArrayBase::kHeaderSize; 1803 offset = kind_ * kPointerSize + FixedArrayBase::kHeaderSize;
1883 return AddInstruction(new(zone()) HLoadNamedField( 1804 access = HObjectAccess::ForOffset(zone(), offset);
1884 map_array, true, Representation::Tagged(), offset)); 1805 return builder()->AddLoad(map_array, access);
1885 } 1806 }
1886 1807
1887 1808
1888 HValue* HGraphBuilder::JSArrayBuilder::EstablishAllocationSize( 1809 HValue* HGraphBuilder::JSArrayBuilder::EstablishAllocationSize(
1889 HValue* length_node) { 1810 HValue* length_node) {
1890 HValue* context = builder()->environment()->LookupContext(); 1811 HValue* context = builder()->environment()->LookupContext();
1891 ASSERT(length_node != NULL); 1812 ASSERT(length_node != NULL);
1892 1813
1893 int base_size = JSArray::kSize; 1814 int base_size = JSArray::kSize;
1894 if (mode_ == TRACK_ALLOCATION_SITE) { 1815 if (mode_ == TRACK_ALLOCATION_SITE) {
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
1983 1904
1984 if (fill_with_hole) { 1905 if (fill_with_hole) {
1985 builder()->BuildFillElementsWithHole(context, elements_location_, kind_, 1906 builder()->BuildFillElementsWithHole(context, elements_location_, kind_,
1986 graph()->GetConstant0(), capacity); 1907 graph()->GetConstant0(), capacity);
1987 } 1908 }
1988 1909
1989 return new_object; 1910 return new_object;
1990 } 1911 }
1991 1912
1992 1913
1914 HStoreNamedField* HGraphBuilder::AddStore(HValue *object, HObjectAccess* access,
1915 HValue *val, Representation representation) {
1916 HStoreNamedField *instr = new(zone()) HStoreNamedField(object, access, val);
1917 AddInstruction(instr);
1918 instr->set_field_representation(representation);
danno 2013/05/06 15:53:06 Any reason you took this out of the constructor?
titzer 2013/05/07 17:51:03 Done.
1919 return instr;
1920 }
1921
1922
1923 HLoadNamedField* HGraphBuilder::AddLoad(HValue *object, HObjectAccess* access,
danno 2013/05/06 15:53:06 nit: Here and elsewhere, although not strictly dic
titzer 2013/05/07 17:51:03 Done.
1924 HValue *typecheck) {
1925 HLoadNamedField *instr = new(zone())
danno 2013/05/06 15:53:06 nit: we usually would line break before the new(zo
titzer 2013/05/07 17:51:03 Done.
1926 HLoadNamedField(object, access, typecheck);
1927 AddInstruction(instr);
1928 return instr;
1929 }
1930
1931
1932 HStoreNamedField* HGraphBuilder::AddStoreMapConstant(HValue *object,
1933 Handle<Map> map) {
1934 HValue* constant = AddInstruction(new(zone())
1935 HConstant(map, Representation::Tagged()));
1936 HStoreNamedField *instr = new(zone())
1937 HStoreNamedField(object, HObjectAccess::ForMap(), constant);
1938 AddInstruction(instr);
1939 return instr;
1940 }
1941
1942
1993 HOptimizedGraphBuilder::HOptimizedGraphBuilder(CompilationInfo* info, 1943 HOptimizedGraphBuilder::HOptimizedGraphBuilder(CompilationInfo* info,
1994 TypeFeedbackOracle* oracle) 1944 TypeFeedbackOracle* oracle)
1995 : HGraphBuilder(info), 1945 : HGraphBuilder(info),
1996 function_state_(NULL), 1946 function_state_(NULL),
1997 initial_function_state_(this, info, oracle, NORMAL_RETURN), 1947 initial_function_state_(this, info, oracle, NORMAL_RETURN),
1998 ast_context_(NULL), 1948 ast_context_(NULL),
1999 break_scope_(NULL), 1949 break_scope_(NULL),
2000 inlined_count_(0), 1950 inlined_count_(0),
2001 globals_(10, info->zone()), 1951 globals_(10, info->zone()),
2002 inline_bailout_(false) { 1952 inline_bailout_(false) {
(...skipping 4272 matching lines...) Expand 10 before | Expand all | Expand 10 after
6275 ASSERT(current_block() != NULL); 6225 ASSERT(current_block() != NULL);
6276 ASSERT(current_block()->HasPredecessor()); 6226 ASSERT(current_block()->HasPredecessor());
6277 return Bailout("DebuggerStatement"); 6227 return Bailout("DebuggerStatement");
6278 } 6228 }
6279 6229
6280 6230
6281 static Handle<SharedFunctionInfo> SearchSharedFunctionInfo( 6231 static Handle<SharedFunctionInfo> SearchSharedFunctionInfo(
6282 Code* unoptimized_code, FunctionLiteral* expr) { 6232 Code* unoptimized_code, FunctionLiteral* expr) {
6283 int start_position = expr->start_position(); 6233 int start_position = expr->start_position();
6284 RelocIterator it(unoptimized_code); 6234 RelocIterator it(unoptimized_code);
6285 for (;!it.done(); it.next()) { 6235 for (; !it.done(); it.next()) {
6286 RelocInfo* rinfo = it.rinfo(); 6236 RelocInfo* rinfo = it.rinfo();
6287 if (rinfo->rmode() != RelocInfo::EMBEDDED_OBJECT) continue; 6237 if (rinfo->rmode() != RelocInfo::EMBEDDED_OBJECT) continue;
6288 Object* obj = rinfo->target_object(); 6238 Object* obj = rinfo->target_object();
6289 if (obj->IsSharedFunctionInfo()) { 6239 if (obj->IsSharedFunctionInfo()) {
6290 SharedFunctionInfo* shared = SharedFunctionInfo::cast(obj); 6240 SharedFunctionInfo* shared = SharedFunctionInfo::cast(obj);
6291 if (shared->start_position() == start_position) { 6241 if (shared->start_position() == start_position) {
6292 return Handle<SharedFunctionInfo>(shared); 6242 return Handle<SharedFunctionInfo>(shared);
6293 } 6243 }
6294 } 6244 }
6295 } 6245 }
(...skipping 599 matching lines...) Expand 10 before | Expand all | Expand 10 after
6895 if (!is_store) return false; 6845 if (!is_store) return false;
6896 6846
6897 // 2nd chance: A store into a non-existent field can still be inlined if we 6847 // 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. 6848 // have a matching transition and some room left in the object.
6899 type->LookupTransition(NULL, *name, lookup); 6849 type->LookupTransition(NULL, *name, lookup);
6900 return lookup->IsTransitionToField(*type) && 6850 return lookup->IsTransitionToField(*type) &&
6901 (type->unused_property_fields() > 0); 6851 (type->unused_property_fields() > 0);
6902 } 6852 }
6903 6853
6904 6854
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, 6855 static Representation ComputeLoadStoreRepresentation(Handle<Map> type,
6920 LookupResult* lookup) { 6856 LookupResult* lookup) {
6921 if (lookup->IsField()) { 6857 if (lookup->IsField()) {
6922 return lookup->representation(); 6858 return lookup->representation();
6923 } else { 6859 } else {
6924 Map* transition = lookup->GetTransitionMapFromMap(*type); 6860 Map* transition = lookup->GetTransitionMapFromMap(*type);
6925 int descriptor = transition->LastAdded(); 6861 int descriptor = transition->LastAdded();
6926 PropertyDetails details = 6862 PropertyDetails details =
6927 transition->instance_descriptors()->GetDetails(descriptor); 6863 transition->instance_descriptors()->GetDetails(descriptor);
6928 return details.representation(); 6864 return details.representation();
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
6973 } 6909 }
6974 ASSERT(proto->GetPrototype(isolate())->IsNull()); 6910 ASSERT(proto->GetPrototype(isolate())->IsNull());
6975 } 6911 }
6976 ASSERT(proto->IsJSObject()); 6912 ASSERT(proto->IsJSObject());
6977 AddInstruction(new(zone()) HCheckPrototypeMaps( 6913 AddInstruction(new(zone()) HCheckPrototypeMaps(
6978 Handle<JSObject>(JSObject::cast(map->prototype())), 6914 Handle<JSObject>(JSObject::cast(map->prototype())),
6979 Handle<JSObject>(JSObject::cast(proto)), 6915 Handle<JSObject>(JSObject::cast(proto)),
6980 zone())); 6916 zone()));
6981 } 6917 }
6982 6918
6983 int index = ComputeLoadStoreFieldIndex(map, lookup); 6919 HObjectAccess* access = HObjectAccess::ForField(zone(), map, lookup, name);
6984 bool is_in_object = index < 0; 6920 HStoreNamedField* instr = new(zone()) HStoreNamedField(object, access, value);
6985 Representation representation = ComputeLoadStoreRepresentation(map, lookup); 6921 instr->set_field_representation(ComputeLoadStoreRepresentation(map, lookup));
danno 2013/05/06 15:53:06 Any reason that you took the setting of the repres
titzer 2013/05/07 17:51:03 Done.
6986 int offset = index * kPointerSize; 6922
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)) { 6923 if (lookup->IsTransitionToField(*map)) {
6997 Handle<Map> transition(lookup->GetTransitionMapFromMap(*map)); 6924 Handle<Map> transition(lookup->GetTransitionMapFromMap(*map));
6998 instr->set_transition(transition); 6925 instr->set_transition(transition);
6999 // TODO(fschneider): Record the new map type of the object in the IR to 6926 // TODO(fschneider): Record the new map type of the object in the IR to
7000 // enable elimination of redundant checks after the transition store. 6927 // enable elimination of redundant checks after the transition store.
7001 instr->SetGVNFlag(kChangesMaps); 6928 instr->SetGVNFlag(kChangesMaps);
7002 } 6929 }
7003 return instr; 6930 return instr;
7004 } 6931 }
7005 6932
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
7055 Handle<String> name) { 6982 Handle<String> name) {
7056 if (!name->Equals(isolate()->heap()->length_string())) return false; 6983 if (!name->Equals(isolate()->heap()->length_string())) return false;
7057 6984
7058 for (int i = 0; i < types->length(); i++) { 6985 for (int i = 0; i < types->length(); i++) {
7059 if (types->at(i)->instance_type() != JS_ARRAY_TYPE) return false; 6986 if (types->at(i)->instance_type() != JS_ARRAY_TYPE) return false;
7060 } 6987 }
7061 6988
7062 AddInstruction(new(zone()) HCheckNonSmi(object)); 6989 AddInstruction(new(zone()) HCheckNonSmi(object));
7063 6990
7064 HInstruction* typecheck = 6991 HInstruction* typecheck =
7065 AddInstruction(HCheckMaps::New(object, types, zone())); 6992 AddInstruction(HCheckMaps::New(object, types, zone()));
7066 HInstruction* instr = 6993 HInstruction* instr = new(zone())
7067 HLoadNamedField::NewArrayLength(zone(), object, typecheck); 6994 HLoadNamedField(object, HObjectAccess::ForArrayLength(), typecheck);
6995
7068 instr->set_position(expr->position()); 6996 instr->set_position(expr->position());
7069 ast_context()->ReturnInstruction(instr, expr->id()); 6997 ast_context()->ReturnInstruction(instr, expr->id());
7070 return true; 6998 return true;
7071 } 6999 }
7072 7000
7073 7001
7074 void HOptimizedGraphBuilder::HandlePolymorphicLoadNamedField(Property* expr, 7002 void HOptimizedGraphBuilder::HandlePolymorphicLoadNamedField(Property* expr,
7075 HValue* object, 7003 HValue* object,
7076 SmallMapList* types, 7004 SmallMapList* types,
7077 Handle<String> name) { 7005 Handle<String> name) {
7078 int count = 0; 7006 int count = 0;
7079 int previous_field_offset = 0; 7007 int previous_field_offset = 0;
7080 bool previous_field_is_in_object = false; 7008 bool previous_field_is_in_object = false;
7081 bool is_monomorphic_field = true; 7009 bool is_monomorphic_field = true;
7082 7010
7083 if (HandlePolymorphicArrayLengthLoad(expr, object, types, name)) 7011 if (HandlePolymorphicArrayLengthLoad(expr, object, types, name))
7084 return; 7012 return;
7085 7013
7086 Handle<Map> map; 7014 Handle<Map> map;
7087 LookupResult lookup(isolate()); 7015 LookupResult lookup(isolate());
7088 for (int i = 0; i < types->length() && count < kMaxLoadPolymorphism; ++i) { 7016 for (int i = 0; i < types->length() && count < kMaxLoadPolymorphism; ++i) {
7089 map = types->at(i); 7017 map = types->at(i);
7090 if (ComputeLoadStoreField(map, name, &lookup, false)) { 7018 if (ComputeLoadStoreField(map, name, &lookup, false)) {
7091 int index = ComputeLoadStoreFieldIndex(map, &lookup); 7019 HObjectAccess* access =
7092 bool is_in_object = index < 0; 7020 HObjectAccess::ForField(zone(), map, &lookup, name);
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) { 7021 if (count == 0) {
7102 previous_field_offset = offset; 7022 previous_field_offset = access->offset();
7103 previous_field_is_in_object = is_in_object; 7023 previous_field_is_in_object = access->IsInobject();
7104 } else if (is_monomorphic_field) { 7024 } else if (is_monomorphic_field) {
7105 is_monomorphic_field = (offset == previous_field_offset) && 7025 // TODO(titzer): just break out of this loop if not the same
7106 (is_in_object == previous_field_is_in_object); 7026 is_monomorphic_field =
7027 (access->offset() == previous_field_offset) &&
7028 (access->IsInobject() == previous_field_is_in_object);
7107 } 7029 }
7108 ++count; 7030 ++count;
7109 } 7031 }
7110 } 7032 }
7111 7033
7112 // Use monomorphic load if property lookup results in the same field index 7034 // 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. 7035 // for all maps. Requires special map check on the set of all handled maps.
7114 AddInstruction(new(zone()) HCheckNonSmi(object)); 7036 AddInstruction(new(zone()) HCheckNonSmi(object));
7115 HInstruction* instr; 7037 HInstruction* instr;
7116 if (count == types->length() && is_monomorphic_field) { 7038 if (count == types->length() && is_monomorphic_field) {
7117 AddInstruction(HCheckMaps::New(object, types, zone())); 7039 AddInstruction(HCheckMaps::New(object, types, zone()));
7118 instr = BuildLoadNamedField(object, map, &lookup); 7040 instr = new(zone()) HLoadNamedField(object,
7041 HObjectAccess::ForField(zone(), map, &lookup, name));
7042 // TODO(titzer): ensure the representation is the same for all maps
7119 } else { 7043 } else {
7120 HValue* context = environment()->LookupContext(); 7044 HValue* context = environment()->LookupContext();
7121 instr = new(zone()) HLoadNamedFieldPolymorphic(context, 7045 instr = new(zone())
7122 object, 7046 HLoadNamedFieldPolymorphic(context, object, types, name, zone());
7123 types,
7124 name,
7125 zone());
7126 } 7047 }
7127 7048
7128 instr->set_position(expr->position()); 7049 instr->set_position(expr->position());
7129 return ast_context()->ReturnInstruction(instr, expr->id()); 7050 return ast_context()->ReturnInstruction(instr, expr->id());
7130 } 7051 }
7131 7052
7132 7053
7133 void HOptimizedGraphBuilder::HandlePolymorphicStoreNamedField( 7054 void HOptimizedGraphBuilder::HandlePolymorphicStoreNamedField(
7134 Assignment* expr, 7055 Assignment* expr,
7135 HValue* object, 7056 HValue* object,
(...skipping 532 matching lines...) Expand 10 before | Expand all | Expand 10 after
7668 HValue* value = environment()->Pop(); 7589 HValue* value = environment()->Pop();
7669 HThrow* instr = new(zone()) HThrow(context, value); 7590 HThrow* instr = new(zone()) HThrow(context, value);
7670 instr->set_position(expr->position()); 7591 instr->set_position(expr->position());
7671 AddInstruction(instr); 7592 AddInstruction(instr);
7672 AddSimulate(expr->id()); 7593 AddSimulate(expr->id());
7673 current_block()->FinishExit(new(zone()) HAbnormalExit); 7594 current_block()->FinishExit(new(zone()) HAbnormalExit);
7674 set_current_block(NULL); 7595 set_current_block(NULL);
7675 } 7596 }
7676 7597
7677 7598
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( 7599 HInstruction* HOptimizedGraphBuilder::BuildLoadNamedGeneric(
7698 HValue* object, 7600 HValue* object,
7699 Handle<String> name, 7601 Handle<String> name,
7700 Property* expr) { 7602 Property* expr) {
7701 if (expr->IsUninitialized()) { 7603 if (expr->IsUninitialized()) {
7702 AddSoftDeoptimize(); 7604 AddSoftDeoptimize();
7703 } 7605 }
7704 HValue* context = environment()->LookupContext(); 7606 HValue* context = environment()->LookupContext();
7705 return new(zone()) HLoadNamedGeneric(context, object, name); 7607 return new(zone()) HLoadNamedGeneric(context, object, name);
7706 } 7608 }
(...skipping 15 matching lines...) Expand all
7722 Handle<String> name, 7624 Handle<String> name,
7723 Property* expr, 7625 Property* expr,
7724 Handle<Map> map) { 7626 Handle<Map> map) {
7725 // Handle a load from a known field. 7627 // Handle a load from a known field.
7726 ASSERT(!map->is_dictionary_map()); 7628 ASSERT(!map->is_dictionary_map());
7727 7629
7728 // Handle access to various length properties 7630 // Handle access to various length properties
7729 if (name->Equals(isolate()->heap()->length_string())) { 7631 if (name->Equals(isolate()->heap()->length_string())) {
7730 if (map->instance_type() == JS_ARRAY_TYPE) { 7632 if (map->instance_type() == JS_ARRAY_TYPE) {
7731 AddCheckMapsWithTransitions(object, map); 7633 AddCheckMapsWithTransitions(object, map);
7732 return HLoadNamedField::NewArrayLength(zone(), object, object); 7634 return new(zone()) HLoadNamedField(object,
7635 HObjectAccess::ForArrayLength());
7733 } 7636 }
7734 } 7637 }
7735 7638
7736 LookupResult lookup(isolate()); 7639 LookupResult lookup(isolate());
7737 map->LookupDescriptor(NULL, *name, &lookup); 7640 map->LookupDescriptor(NULL, *name, &lookup);
7738 if (lookup.IsField()) { 7641 if (lookup.IsField()) {
7739 AddCheckMap(object, map); 7642 AddCheckMap(object, map);
7740 return BuildLoadNamedField(object, map, &lookup); 7643 HLoadNamedField* load = new(zone()) HLoadNamedField(object,
7644 HObjectAccess::ForField(zone(), map, &lookup, name));
7645 load->set_field_representation(
7646 ComputeLoadStoreRepresentation(map, &lookup));
7647 return load;
7741 } 7648 }
7742 7649
7743 // Handle a load of a constant known function. 7650 // Handle a load of a constant known function.
7744 if (lookup.IsConstantFunction()) { 7651 if (lookup.IsConstantFunction()) {
7745 AddCheckMap(object, map); 7652 AddCheckMap(object, map);
7746 Handle<JSFunction> function(lookup.GetConstantFunctionFromMap(*map)); 7653 Handle<JSFunction> function(lookup.GetConstantFunctionFromMap(*map));
7747 return new(zone()) HConstant(function, Representation::Tagged()); 7654 return new(zone()) HConstant(function, Representation::Tagged());
7748 } 7655 }
7749 7656
7750 // Handle a load from a known field somewhere in the prototype chain. 7657 // Handle a load from a known field somewhere in the prototype chain.
7751 LookupInPrototypes(map, name, &lookup); 7658 LookupInPrototypes(map, name, &lookup);
7752 if (lookup.IsField()) { 7659 if (lookup.IsField()) {
7753 Handle<JSObject> prototype(JSObject::cast(map->prototype())); 7660 Handle<JSObject> prototype(JSObject::cast(map->prototype()));
7754 Handle<JSObject> holder(lookup.holder()); 7661 Handle<JSObject> holder(lookup.holder());
7755 Handle<Map> holder_map(holder->map()); 7662 Handle<Map> holder_map(holder->map());
7756 AddCheckMap(object, map); 7663 AddCheckMap(object, map);
7757 AddInstruction( 7664 AddInstruction(new(zone())
7758 new(zone()) HCheckPrototypeMaps(prototype, holder, zone())); 7665 HCheckPrototypeMaps(prototype, holder, zone()));
danno 2013/05/06 15:53:06 nit: unnecessary whitespace change
titzer 2013/05/07 17:51:03 want: auto code formatter
7759 HValue* holder_value = AddInstruction( 7666 HValue* holder_value = AddInstruction(new(zone())
7760 new(zone()) HConstant(holder, Representation::Tagged())); 7667 HConstant(holder, Representation::Tagged()));
7761 return BuildLoadNamedField(holder_value, holder_map, &lookup); 7668 HLoadNamedField* load = new(zone()) HLoadNamedField(holder_value,
7669 HObjectAccess::ForField(zone(), holder_map, &lookup, name));
7670 load->set_field_representation(
7671 ComputeLoadStoreRepresentation(map, &lookup));
7672 return load;
7762 } 7673 }
7763 7674
7764 // Handle a load of a constant function somewhere in the prototype chain. 7675 // Handle a load of a constant function somewhere in the prototype chain.
7765 if (lookup.IsConstantFunction()) { 7676 if (lookup.IsConstantFunction()) {
7766 Handle<JSObject> prototype(JSObject::cast(map->prototype())); 7677 Handle<JSObject> prototype(JSObject::cast(map->prototype()));
7767 Handle<JSObject> holder(lookup.holder()); 7678 Handle<JSObject> holder(lookup.holder());
7768 Handle<Map> holder_map(holder->map()); 7679 Handle<Map> holder_map(holder->map());
7769 AddCheckMap(object, map); 7680 AddCheckMap(object, map);
7770 AddInstruction(new(zone()) HCheckPrototypeMaps(prototype, holder, zone())); 7681 AddInstruction(new(zone()) HCheckPrototypeMaps(prototype, holder, zone()));
7771 Handle<JSFunction> function(lookup.GetConstantFunctionFromMap(*holder_map)); 7682 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. 7926 // it's a keyed property) and registered in the full codegen.
8016 HBasicBlock* if_jsarray = graph()->CreateBasicBlock(); 7927 HBasicBlock* if_jsarray = graph()->CreateBasicBlock();
8017 HBasicBlock* if_fastobject = graph()->CreateBasicBlock(); 7928 HBasicBlock* if_fastobject = graph()->CreateBasicBlock();
8018 HHasInstanceTypeAndBranch* typecheck = 7929 HHasInstanceTypeAndBranch* typecheck =
8019 new(zone()) HHasInstanceTypeAndBranch(object, JS_ARRAY_TYPE); 7930 new(zone()) HHasInstanceTypeAndBranch(object, JS_ARRAY_TYPE);
8020 typecheck->SetSuccessorAt(0, if_jsarray); 7931 typecheck->SetSuccessorAt(0, if_jsarray);
8021 typecheck->SetSuccessorAt(1, if_fastobject); 7932 typecheck->SetSuccessorAt(1, if_fastobject);
8022 current_block()->Finish(typecheck); 7933 current_block()->Finish(typecheck);
8023 7934
8024 set_current_block(if_jsarray); 7935 set_current_block(if_jsarray);
8025 HInstruction* length; 7936 HInstruction* length = AddLoad(object,
8026 length = AddInstruction( 7937 HObjectAccess::ForArrayLength(), typecheck);
8027 HLoadNamedField::NewArrayLength(zone(), object, typecheck, 7938 length->set_type(HType::Smi());
8028 HType::Smi())); 7939 // TODO(titzer): length->set_field_representation(Representation::Smi())
7940
8029 checked_key = AddBoundsCheck(key, length, ALLOW_SMI_KEY); 7941 checked_key = AddBoundsCheck(key, length, ALLOW_SMI_KEY);
8030 access = AddInstruction(BuildFastElementAccess( 7942 access = AddInstruction(BuildFastElementAccess(
8031 elements, checked_key, val, elements_kind_branch, 7943 elements, checked_key, val, elements_kind_branch,
8032 elements_kind, is_store, STANDARD_STORE)); 7944 elements_kind, is_store, STANDARD_STORE));
8033 if (!is_store) { 7945 if (!is_store) {
8034 Push(access); 7946 Push(access);
8035 } 7947 }
8036 7948
8037 *has_side_effects |= access->HasObservableSideEffects(); 7949 *has_side_effects |= access->HasObservableSideEffects();
8038 // The caller will use has_side_effects and add correct Simulate. 7950 // The caller will use has_side_effects and add correct Simulate.
(...skipping 2625 matching lines...) Expand 10 before | Expand all | Expand 10 after
10664 } 10576 }
10665 10577
10666 10578
10667 void HOptimizedGraphBuilder::BuildEmitDeepCopy( 10579 void HOptimizedGraphBuilder::BuildEmitDeepCopy(
10668 Handle<JSObject> boilerplate_object, 10580 Handle<JSObject> boilerplate_object,
10669 Handle<JSObject> original_boilerplate_object, 10581 Handle<JSObject> original_boilerplate_object,
10670 HInstruction* target, 10582 HInstruction* target,
10671 int* offset, 10583 int* offset,
10672 AllocationSiteMode mode) { 10584 AllocationSiteMode mode) {
10673 Zone* zone = this->zone(); 10585 Zone* zone = this->zone();
10674 Factory* factory = isolate()->factory();
10675 10586
10676 HInstruction* original_boilerplate = AddInstruction(new(zone) HConstant( 10587 HInstruction* original_boilerplate = AddInstruction(new(zone) HConstant(
10677 original_boilerplate_object, Representation::Tagged())); 10588 original_boilerplate_object, Representation::Tagged()));
10678 10589
10679 bool create_allocation_site_info = mode == TRACK_ALLOCATION_SITE && 10590 bool create_allocation_site_info = mode == TRACK_ALLOCATION_SITE &&
10680 boilerplate_object->map()->CanTrackAllocationSite(); 10591 boilerplate_object->map()->CanTrackAllocationSite();
10681 10592
10682 // Only elements backing stores for non-COW arrays need to be copied. 10593 // Only elements backing stores for non-COW arrays need to be copied.
10683 Handle<FixedArrayBase> elements(boilerplate_object->elements()); 10594 Handle<FixedArrayBase> elements(boilerplate_object->elements());
10684 Handle<FixedArrayBase> original_elements( 10595 Handle<FixedArrayBase> original_elements(
(...skipping 26 matching lines...) Expand all
10711 Handle<Object> value = 10622 Handle<Object> value =
10712 Handle<Object>(boilerplate_object->InObjectPropertyAt(i), 10623 Handle<Object>(boilerplate_object->InObjectPropertyAt(i),
10713 isolate()); 10624 isolate());
10714 if (value->IsJSObject()) { 10625 if (value->IsJSObject()) {
10715 Handle<JSObject> value_object = Handle<JSObject>::cast(value); 10626 Handle<JSObject> value_object = Handle<JSObject>::cast(value);
10716 Handle<JSObject> original_value_object = Handle<JSObject>::cast( 10627 Handle<JSObject> original_value_object = Handle<JSObject>::cast(
10717 Handle<Object>(original_boilerplate_object->InObjectPropertyAt(i), 10628 Handle<Object>(original_boilerplate_object->InObjectPropertyAt(i),
10718 isolate())); 10629 isolate()));
10719 HInstruction* value_instruction = 10630 HInstruction* value_instruction =
10720 AddInstruction(new(zone) HInnerAllocatedObject(target, *offset)); 10631 AddInstruction(new(zone) HInnerAllocatedObject(target, *offset));
10632
10721 // TODO(verwaest): choose correct storage. 10633 // TODO(verwaest): choose correct storage.
10722 AddInstruction(new(zone) HStoreNamedField( 10634 HObjectAccess* access = HObjectAccess::ForInobjectOffset(zone,
10723 object_properties, factory->unknown_field_string(), value_instruction, 10635 boilerplate_object->GetInObjectPropertyOffset(i));
10724 true, Representation::Tagged(), 10636 AddStore(object_properties, access, value_instruction);
10725 boilerplate_object->GetInObjectPropertyOffset(i))); 10637
10726 BuildEmitDeepCopy(value_object, original_value_object, target, 10638 BuildEmitDeepCopy(value_object, original_value_object, target,
10727 offset, DONT_TRACK_ALLOCATION_SITE); 10639 offset, DONT_TRACK_ALLOCATION_SITE);
10728 } else { 10640 } else {
10729 // TODO(verwaest): choose correct storage. 10641 // TODO(verwaest): choose correct storage.
10730 HInstruction* value_instruction = AddInstruction(new(zone) HConstant( 10642 HInstruction* value_instruction = AddInstruction(new(zone) HConstant(
10731 value, Representation::Tagged())); 10643 value, Representation::Tagged()));
10732 AddInstruction(new(zone) HStoreNamedField( 10644
10733 object_properties, factory->unknown_field_string(), value_instruction, 10645 HObjectAccess* access = HObjectAccess::ForInobjectOffset(zone,
10734 true, Representation::Tagged(), 10646 boilerplate_object->GetInObjectPropertyOffset(i));
10735 boilerplate_object->GetInObjectPropertyOffset(i))); 10647 AddStore(object_properties, access, value_instruction);
10736 } 10648 }
10737 } 10649 }
10738 10650
10739 // Build Allocation Site Info if desired 10651 // Build Allocation Site Info if desired
10740 if (create_allocation_site_info) { 10652 if (create_allocation_site_info) {
10741 BuildCreateAllocationSiteInfo(target, JSArray::kSize, original_boilerplate); 10653 BuildCreateAllocationSiteInfo(target, JSArray::kSize, original_boilerplate);
10742 } 10654 }
10743 10655
10744 if (object_elements != NULL) { 10656 if (object_elements != NULL) {
10745 HInstruction* boilerplate_elements = AddInstruction(new(zone) HConstant( 10657 HInstruction* boilerplate_elements = AddInstruction(new(zone) HConstant(
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
10797 10709
10798 10710
10799 HValue* HOptimizedGraphBuilder::BuildCopyObjectHeader( 10711 HValue* HOptimizedGraphBuilder::BuildCopyObjectHeader(
10800 Handle<JSObject> boilerplate_object, 10712 Handle<JSObject> boilerplate_object,
10801 HInstruction* target, 10713 HInstruction* target,
10802 int object_offset, 10714 int object_offset,
10803 int elements_offset, 10715 int elements_offset,
10804 int elements_size) { 10716 int elements_size) {
10805 ASSERT(boilerplate_object->properties()->length() == 0); 10717 ASSERT(boilerplate_object->properties()->length() == 0);
10806 Zone* zone = this->zone(); 10718 Zone* zone = this->zone();
10807 Factory* factory = isolate()->factory();
10808 HValue* result = NULL; 10719 HValue* result = NULL;
10809 10720
10810 HValue* object_header = 10721 HValue* object_header =
10811 AddInstruction(new(zone) HInnerAllocatedObject(target, object_offset)); 10722 AddInstruction(new(zone) HInnerAllocatedObject(target, object_offset));
10812 Handle<Map> boilerplate_object_map(boilerplate_object->map()); 10723 Handle<Map> boilerplate_object_map(boilerplate_object->map());
10813 BuildStoreMap(object_header, boilerplate_object_map); 10724 AddStoreMapConstant(object_header, boilerplate_object_map);
10814 10725
10815 HInstruction* elements; 10726 HInstruction* elements;
10816 if (elements_size == 0) { 10727 if (elements_size == 0) {
10817 Handle<Object> elements_field = 10728 Handle<Object> elements_field =
10818 Handle<Object>(boilerplate_object->elements(), isolate()); 10729 Handle<Object>(boilerplate_object->elements(), isolate());
10819 elements = AddInstruction(new(zone) HConstant( 10730 elements = AddInstruction(new(zone) HConstant(
10820 elements_field, Representation::Tagged())); 10731 elements_field, Representation::Tagged()));
10821 } else { 10732 } else {
10822 elements = AddInstruction(new(zone) HInnerAllocatedObject( 10733 elements = AddInstruction(new(zone) HInnerAllocatedObject(
10823 target, elements_offset)); 10734 target, elements_offset));
10824 result = elements; 10735 result = elements;
10825 } 10736 }
10826 HInstruction* elements_store = AddInstruction(new(zone) HStoreNamedField( 10737 AddStore(object_header, HObjectAccess::ForElementsPointer(), elements);
10827 object_header,
10828 factory->elements_field_string(),
10829 elements,
10830 true, Representation::Tagged(), JSObject::kElementsOffset));
10831 elements_store->SetGVNFlag(kChangesElementsPointer);
10832 10738
10833 Handle<Object> properties_field = 10739 Handle<Object> properties_field =
10834 Handle<Object>(boilerplate_object->properties(), isolate()); 10740 Handle<Object>(boilerplate_object->properties(), isolate());
10835 ASSERT(*properties_field == isolate()->heap()->empty_fixed_array()); 10741 ASSERT(*properties_field == isolate()->heap()->empty_fixed_array());
10836 HInstruction* properties = AddInstruction(new(zone) HConstant( 10742 HInstruction* properties = AddInstruction(new(zone) HConstant(
10837 properties_field, Representation::None())); 10743 properties_field, Representation::None()));
10838 AddInstruction(new(zone) HStoreNamedField(object_header, 10744 HObjectAccess* access = HObjectAccess::ForInobjectOffset(zone,
10839 factory->empty_string(), 10745 JSObject::kPropertiesOffset);
10840 properties, true, 10746 AddStore(object_header, access, properties);
10841 Representation::Tagged(),
10842 JSObject::kPropertiesOffset));
10843 10747
10844 if (boilerplate_object->IsJSArray()) { 10748 if (boilerplate_object->IsJSArray()) {
10845 Handle<JSArray> boilerplate_array = 10749 Handle<JSArray> boilerplate_array =
10846 Handle<JSArray>::cast(boilerplate_object); 10750 Handle<JSArray>::cast(boilerplate_object);
10847 Handle<Object> length_field = 10751 Handle<Object> length_field =
10848 Handle<Object>(boilerplate_array->length(), isolate()); 10752 Handle<Object>(boilerplate_array->length(), isolate());
10849 HInstruction* length = AddInstruction(new(zone) HConstant( 10753 HInstruction* length = AddInstruction(new(zone) HConstant(
10850 length_field, Representation::None())); 10754 length_field, Representation::None()));
10755
10851 ASSERT(boilerplate_array->length()->IsSmi()); 10756 ASSERT(boilerplate_array->length()->IsSmi());
10852 Representation representation = 10757 Representation representation =
10853 IsFastElementsKind(boilerplate_array->GetElementsKind()) 10758 IsFastElementsKind(boilerplate_array->GetElementsKind())
10854 ? Representation::Smi() : Representation::Tagged(); 10759 ? Representation::Smi() : Representation::Tagged();
10855 HInstruction* length_store = AddInstruction(new(zone) HStoreNamedField( 10760 AddStore(object_header, HObjectAccess::ForArrayLength(),
10856 object_header, 10761 length, representation);
10857 factory->length_field_string(),
10858 length,
10859 true, representation, JSArray::kLengthOffset));
10860 length_store->SetGVNFlag(kChangesArrayLengths);
10861 } 10762 }
10862 10763
10863 return result; 10764 return result;
10864 } 10765 }
10865 10766
10866 10767
10867 void HOptimizedGraphBuilder::VisitThisFunction(ThisFunction* expr) { 10768 void HOptimizedGraphBuilder::VisitThisFunction(ThisFunction* expr) {
10868 ASSERT(!HasStackOverflow()); 10769 ASSERT(!HasStackOverflow());
10869 ASSERT(current_block() != NULL); 10770 ASSERT(current_block() != NULL);
10870 ASSERT(current_block()->HasPredecessor()); 10771 ASSERT(current_block()->HasPredecessor());
(...skipping 366 matching lines...) Expand 10 before | Expand all | Expand 10 after
11237 new(zone()) HHasInstanceTypeAndBranch(object, JS_VALUE_TYPE); 11138 new(zone()) HHasInstanceTypeAndBranch(object, JS_VALUE_TYPE);
11238 HBasicBlock* if_js_value = graph()->CreateBasicBlock(); 11139 HBasicBlock* if_js_value = graph()->CreateBasicBlock();
11239 HBasicBlock* not_js_value = graph()->CreateBasicBlock(); 11140 HBasicBlock* not_js_value = graph()->CreateBasicBlock();
11240 typecheck->SetSuccessorAt(0, if_js_value); 11141 typecheck->SetSuccessorAt(0, if_js_value);
11241 typecheck->SetSuccessorAt(1, not_js_value); 11142 typecheck->SetSuccessorAt(1, not_js_value);
11242 current_block()->Finish(typecheck); 11143 current_block()->Finish(typecheck);
11243 not_js_value->Goto(join); 11144 not_js_value->Goto(join);
11244 11145
11245 // Create in-object property store to kValueOffset. 11146 // Create in-object property store to kValueOffset.
11246 set_current_block(if_js_value); 11147 set_current_block(if_js_value);
11247 Handle<String> name = isolate()->factory()->undefined_string(); 11148 AddStore(object, HObjectAccess::ForInobjectOffset(
11248 AddInstruction(new(zone()) HStoreNamedField(object, 11149 zone(), JSValue::kValueOffset), value);
11249 name,
11250 value,
11251 true, // in-object store.
11252 Representation::Tagged(),
11253 JSValue::kValueOffset));
11254 if_js_value->Goto(join); 11150 if_js_value->Goto(join);
11255 join->SetJoinId(call->id()); 11151 join->SetJoinId(call->id());
11256 set_current_block(join); 11152 set_current_block(join);
11257 return ast_context()->ReturnValue(value); 11153 return ast_context()->ReturnValue(value);
11258 } 11154 }
11259 11155
11260 11156
11261 // Fast support for charCodeAt(n). 11157 // Fast support for charCodeAt(n).
11262 void HOptimizedGraphBuilder::GenerateStringCharCodeAt(CallRuntime* call) { 11158 void HOptimizedGraphBuilder::GenerateStringCharCodeAt(CallRuntime* call) {
11263 ASSERT(call->arguments()->length() == 2); 11159 ASSERT(call->arguments()->length() == 2);
(...skipping 954 matching lines...) Expand 10 before | Expand all | Expand 10 after
12218 } 12114 }
12219 } 12115 }
12220 12116
12221 #ifdef DEBUG 12117 #ifdef DEBUG
12222 if (graph_ != NULL) graph_->Verify(false); // No full verify. 12118 if (graph_ != NULL) graph_->Verify(false); // No full verify.
12223 if (allocator_ != NULL) allocator_->Verify(); 12119 if (allocator_ != NULL) allocator_->Verify();
12224 #endif 12120 #endif
12225 } 12121 }
12226 12122
12227 } } // namespace v8::internal 12123 } } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698