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

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: Add HObjectAccess::ForBackingStoreOffset and HObjectAccess::ForAllocationSitePayload. 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)
danno 2013/05/13 15:44:32 nit: For readability, please calculate the represe
titzer 2013/05/14 09:26:19 Done.
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 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
1274 HValue* elements = AddLoadElements(object, mapcheck); 1267 HValue* elements = AddLoadElements(object, mapcheck);
1275 if (is_store && (fast_elements || fast_smi_only_elements) && 1268 if (is_store && (fast_elements || fast_smi_only_elements) &&
1276 store_mode != STORE_NO_TRANSITION_HANDLE_COW) { 1269 store_mode != STORE_NO_TRANSITION_HANDLE_COW) {
1277 HCheckMaps* check_cow_map = HCheckMaps::New( 1270 HCheckMaps* check_cow_map = HCheckMaps::New(
1278 elements, isolate()->factory()->fixed_array_map(), zone); 1271 elements, isolate()->factory()->fixed_array_map(), zone);
1279 check_cow_map->ClearGVNFlag(kDependsOnElementsKind); 1272 check_cow_map->ClearGVNFlag(kDependsOnElementsKind);
1280 AddInstruction(check_cow_map); 1273 AddInstruction(check_cow_map);
1281 } 1274 }
1282 HInstruction* length = NULL; 1275 HInstruction* length = NULL;
1283 if (is_js_array) { 1276 if (is_js_array) {
1284 length = AddInstruction( 1277 length = AddLoad(object, HObjectAccess::ForArrayLength(), mapcheck);
1285 HLoadNamedField::NewArrayLength(zone, object, mapcheck, HType::Smi())); 1278 length->set_type(HType::Smi());
1286 } else { 1279 } else {
1287 length = AddInstruction(new(zone) HFixedArrayBaseLength(elements)); 1280 length = AddInstruction(new(zone) HFixedArrayBaseLength(elements));
1288 } 1281 }
1289 HValue* checked_key = NULL; 1282 HValue* checked_key = NULL;
1290 if (IsExternalArrayElementsKind(elements_kind)) { 1283 if (IsExternalArrayElementsKind(elements_kind)) {
1291 if (store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS) { 1284 if (store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS) {
1292 NoObservableSideEffectsScope no_effects(this); 1285 NoObservableSideEffectsScope no_effects(this);
1293 HLoadExternalArrayPointer* external_elements = 1286 HLoadExternalArrayPointer* external_elements =
1294 new(zone) HLoadExternalArrayPointer(elements); 1287 new(zone) HLoadExternalArrayPointer(elements);
1295 AddInstruction(external_elements); 1288 AddInstruction(external_elements);
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
1401 HValue* elements = 1394 HValue* elements =
1402 AddInstruction(new(zone) HAllocate(context, total_size, 1395 AddInstruction(new(zone) HAllocate(context, total_size,
1403 HType::JSArray(), flags)); 1396 HType::JSArray(), flags));
1404 return elements; 1397 return elements;
1405 } 1398 }
1406 1399
1407 1400
1408 void HGraphBuilder::BuildInitializeElements(HValue* elements, 1401 void HGraphBuilder::BuildInitializeElements(HValue* elements,
1409 ElementsKind kind, 1402 ElementsKind kind,
1410 HValue* capacity) { 1403 HValue* capacity) {
1411 Zone* zone = this->zone();
1412 Factory* factory = isolate()->factory(); 1404 Factory* factory = isolate()->factory();
1413 Handle<Map> map = IsFastDoubleElementsKind(kind) 1405 Handle<Map> map = IsFastDoubleElementsKind(kind)
1414 ? factory->fixed_double_array_map() 1406 ? factory->fixed_double_array_map()
1415 : factory->fixed_array_map(); 1407 : factory->fixed_array_map();
1416 BuildStoreMap(elements, map);
1417 1408
1418 Handle<String> fixed_array_length_field_name = factory->length_field_string(); 1409 AddStoreMapConstant(elements, map);
1419 Representation representation = IsFastElementsKind(kind) 1410 Representation representation = IsFastElementsKind(kind)
1420 ? Representation::Smi() : Representation::Tagged(); 1411 ? Representation::Smi() : Representation::Tagged();
1421 HInstruction* store_length = 1412 AddStore(elements, HObjectAccess::ForFixedArrayLength(), capacity,
1422 new(zone) HStoreNamedField(elements, fixed_array_length_field_name, 1413 representation);
1423 capacity, true, representation,
1424 FixedArray::kLengthOffset);
1425 AddInstruction(store_length);
1426 } 1414 }
1427 1415
1428 1416
1429 HValue* HGraphBuilder::BuildAllocateAndInitializeElements(HValue* context, 1417 HValue* HGraphBuilder::BuildAllocateAndInitializeElements(HValue* context,
1430 ElementsKind kind, 1418 ElementsKind kind,
1431 HValue* capacity) { 1419 HValue* capacity) {
1432 HValue* new_elements = BuildAllocateElements(context, kind, capacity); 1420 HValue* new_elements = BuildAllocateElements(context, kind, capacity);
1433 BuildInitializeElements(new_elements, kind, capacity); 1421 BuildInitializeElements(new_elements, kind, capacity);
1434 return new_elements; 1422 return new_elements;
1435 } 1423 }
1436 1424
1437 1425
1438 HInnerAllocatedObject* HGraphBuilder::BuildJSArrayHeader(HValue* array, 1426 HInnerAllocatedObject* HGraphBuilder::BuildJSArrayHeader(HValue* array,
1439 HValue* array_map, 1427 HValue* array_map,
1440 AllocationSiteMode mode, 1428 AllocationSiteMode mode,
1441 HValue* allocation_site_payload, 1429 HValue* allocation_site_payload,
1442 HValue* length_field) { 1430 HValue* length_field) {
1443 1431
1444 BuildStoreMap(array, array_map); 1432 AddStore(array, HObjectAccess::ForMap(), array_map);
1445 1433
1446 HConstant* empty_fixed_array = 1434 HConstant* empty_fixed_array =
1447 new(zone()) HConstant( 1435 new(zone()) HConstant(
1448 Handle<FixedArray>(isolate()->heap()->empty_fixed_array()), 1436 Handle<FixedArray>(isolate()->heap()->empty_fixed_array()),
1449 Representation::Tagged()); 1437 Representation::Tagged());
1450 AddInstruction(empty_fixed_array); 1438 AddInstruction(empty_fixed_array);
1451 1439
1452 AddInstruction(new(zone()) HStoreNamedField(array, 1440 HObjectAccess access = HObjectAccess::ForPropertiesPointer();
1453 isolate()->factory()->properties_field_symbol(), 1441 AddStore(array, access, empty_fixed_array);
1454 empty_fixed_array, 1442 AddStore(array, HObjectAccess::ForArrayLength(), length_field);
1455 true,
1456 Representation::Tagged(),
1457 JSArray::kPropertiesOffset));
1458
1459 HInstruction* length_store = AddInstruction(
1460 new(zone()) HStoreNamedField(array,
1461 isolate()->factory()->length_field_string(),
1462 length_field,
1463 true,
1464 Representation::Tagged(),
1465 JSArray::kLengthOffset));
1466 length_store->SetGVNFlag(kChangesArrayLengths);
1467 1443
1468 if (mode == TRACK_ALLOCATION_SITE) { 1444 if (mode == TRACK_ALLOCATION_SITE) {
1469 BuildCreateAllocationSiteInfo(array, 1445 BuildCreateAllocationSiteInfo(array,
1470 JSArray::kSize, 1446 JSArray::kSize,
1471 allocation_site_payload); 1447 allocation_site_payload);
1472 } 1448 }
1473 1449
1474 int elements_location = JSArray::kSize; 1450 int elements_location = JSArray::kSize;
1475 if (mode == TRACK_ALLOCATION_SITE) { 1451 if (mode == TRACK_ALLOCATION_SITE) {
1476 elements_location += AllocationSiteInfo::kSize; 1452 elements_location += AllocationSiteInfo::kSize;
1477 } 1453 }
1478 1454
1479 HInnerAllocatedObject* elements = new(zone()) HInnerAllocatedObject( 1455 HInnerAllocatedObject* elements = new(zone()) HInnerAllocatedObject(
1480 array, 1456 array, elements_location);
1481 elements_location);
1482 AddInstruction(elements); 1457 AddInstruction(elements);
1483 1458
1484 HInstruction* elements_store = AddInstruction( 1459 AddStore(array, HObjectAccess::ForElementsPointer(), elements);
1485 new(zone()) HStoreNamedField(
1486 array,
1487 isolate()->factory()->elements_field_string(),
1488 elements,
1489 true,
1490 Representation::Tagged(),
1491 JSArray::kElementsOffset));
1492 elements_store->SetGVNFlag(kChangesElementsPointer);
1493
1494 return elements; 1460 return elements;
1495 } 1461 }
1496 1462
1497 1463
1498 HInstruction* HGraphBuilder::BuildStoreMap(HValue* object, 1464 HLoadNamedField* HGraphBuilder::AddLoadElements(HValue* object,
1499 HValue* map) { 1465 HValue* typecheck) {
1500 Zone* zone = this->zone(); 1466 return AddLoad(object, HObjectAccess::ForElementsPointer(), typecheck);
1501 Factory* factory = isolate()->factory();
1502 Handle<String> map_field_name = factory->map_field_string();
1503 HInstruction* store_map =
1504 new(zone) HStoreNamedField(object, map_field_name, map,
1505 true, Representation::Tagged(),
1506 JSObject::kMapOffset);
1507 store_map->ClearGVNFlag(kChangesInobjectFields);
1508 store_map->SetGVNFlag(kChangesMaps);
1509 AddInstruction(store_map);
1510 return store_map;
1511 } 1467 }
1512 1468
1513 1469
1514 HInstruction* HGraphBuilder::BuildStoreMap(HValue* object,
1515 Handle<Map> map) {
1516 Zone* zone = this->zone();
1517 HValue* map_constant =
1518 AddInstruction(new(zone) HConstant(map, Representation::Tagged()));
1519 return BuildStoreMap(object, map_constant);
1520 }
1521
1522
1523 HLoadNamedField* HGraphBuilder::AddLoadElements(HValue* object,
1524 HValue* typecheck) {
1525 HLoadNamedField* instr = new(zone()) HLoadNamedField(object, true,
1526 Representation::Tagged(), JSObject::kElementsOffset, typecheck);
1527 AddInstruction(instr);
1528 instr->SetGVNFlag(kDependsOnElementsPointer);
1529 instr->ClearGVNFlag(kDependsOnMaps);
1530 instr->ClearGVNFlag(kDependsOnInobjectFields);
1531 return instr;
1532 }
1533
1534
1535 HValue* HGraphBuilder::BuildNewElementsCapacity(HValue* context, 1470 HValue* HGraphBuilder::BuildNewElementsCapacity(HValue* context,
1536 HValue* old_capacity) { 1471 HValue* old_capacity) {
1537 Zone* zone = this->zone(); 1472 Zone* zone = this->zone();
1538 HValue* half_old_capacity = 1473 HValue* half_old_capacity =
1539 AddInstruction(HShr::New(zone, context, old_capacity, 1474 AddInstruction(HShr::New(zone, context, old_capacity,
1540 graph_->GetConstant1())); 1475 graph_->GetConstant1()));
1541 half_old_capacity->ChangeRepresentation(Representation::Integer32()); 1476 half_old_capacity->ChangeRepresentation(Representation::Integer32());
1542 half_old_capacity->ClearFlag(HValue::kCanOverflow); 1477 half_old_capacity->ClearFlag(HValue::kCanOverflow);
1543 1478
1544 HValue* new_capacity = AddInstruction( 1479 HValue* new_capacity = AddInstruction(
(...skipping 29 matching lines...) Expand all
1574 HBoundsCheck(length, max_size_constant, 1509 HBoundsCheck(length, max_size_constant,
1575 DONT_ALLOW_SMI_KEY, Representation::Integer32())); 1510 DONT_ALLOW_SMI_KEY, Representation::Integer32()));
1576 } 1511 }
1577 1512
1578 1513
1579 HValue* HGraphBuilder::BuildGrowElementsCapacity(HValue* object, 1514 HValue* HGraphBuilder::BuildGrowElementsCapacity(HValue* object,
1580 HValue* elements, 1515 HValue* elements,
1581 ElementsKind kind, 1516 ElementsKind kind,
1582 HValue* length, 1517 HValue* length,
1583 HValue* new_capacity) { 1518 HValue* new_capacity) {
1584 Zone* zone = this->zone();
1585 HValue* context = environment()->LookupContext(); 1519 HValue* context = environment()->LookupContext();
1586 1520
1587 BuildNewSpaceArrayCheck(new_capacity, kind); 1521 BuildNewSpaceArrayCheck(new_capacity, kind);
1588 1522
1589 HValue* new_elements = 1523 HValue* new_elements =
1590 BuildAllocateAndInitializeElements(context, kind, new_capacity); 1524 BuildAllocateAndInitializeElements(context, kind, new_capacity);
1591 1525
1592 BuildCopyElements(context, elements, kind, 1526 BuildCopyElements(context, elements, kind,
1593 new_elements, kind, 1527 new_elements, kind,
1594 length, new_capacity); 1528 length, new_capacity);
1595 1529
1596 Factory* factory = isolate()->factory(); 1530 AddStore(object, HObjectAccess::ForElementsPointer(), new_elements);
1597 HInstruction* elements_store = AddInstruction(new(zone) HStoreNamedField(
1598 object,
1599 factory->elements_field_string(),
1600 new_elements, true, Representation::Tagged(),
1601 JSArray::kElementsOffset));
1602 elements_store->SetGVNFlag(kChangesElementsPointer);
1603 1531
1604 return new_elements; 1532 return new_elements;
1605 } 1533 }
1606 1534
1607 1535
1608 void HGraphBuilder::BuildFillElementsWithHole(HValue* context, 1536 void HGraphBuilder::BuildFillElementsWithHole(HValue* context,
1609 HValue* elements, 1537 HValue* elements,
1610 ElementsKind elements_kind, 1538 ElementsKind elements_kind,
1611 HValue* from, 1539 HValue* from,
1612 HValue* to) { 1540 HValue* to) {
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
1697 } 1625 }
1698 } 1626 }
1699 1627
1700 1628
1701 HValue* HGraphBuilder::BuildCloneShallowArray(HContext* context, 1629 HValue* HGraphBuilder::BuildCloneShallowArray(HContext* context,
1702 HValue* boilerplate, 1630 HValue* boilerplate,
1703 AllocationSiteMode mode, 1631 AllocationSiteMode mode,
1704 ElementsKind kind, 1632 ElementsKind kind,
1705 int length) { 1633 int length) {
1706 Zone* zone = this->zone(); 1634 Zone* zone = this->zone();
1707 Factory* factory = isolate()->factory();
1708 1635
1709 NoObservableSideEffectsScope no_effects(this); 1636 NoObservableSideEffectsScope no_effects(this);
1710 1637
1711 // All sizes here are multiples of kPointerSize. 1638 // All sizes here are multiples of kPointerSize.
1712 int size = JSArray::kSize; 1639 int size = JSArray::kSize;
1713 if (mode == TRACK_ALLOCATION_SITE) { 1640 if (mode == TRACK_ALLOCATION_SITE) {
1714 size += AllocationSiteInfo::kSize; 1641 size += AllocationSiteInfo::kSize;
1715 } 1642 }
1716 int elems_offset = size; 1643 int elems_offset = size;
1717 if (length > 0) { 1644 if (length > 0) {
1718 size += IsFastDoubleElementsKind(kind) 1645 size += IsFastDoubleElementsKind(kind)
1719 ? FixedDoubleArray::SizeFor(length) 1646 ? FixedDoubleArray::SizeFor(length)
1720 : FixedArray::SizeFor(length); 1647 : FixedArray::SizeFor(length);
1721 } 1648 }
1722 1649
1723 HAllocate::Flags allocate_flags = HAllocate::DefaultFlags(kind); 1650 HAllocate::Flags allocate_flags = HAllocate::DefaultFlags(kind);
1724 // Allocate both the JS array and the elements array in one big 1651 // Allocate both the JS array and the elements array in one big
1725 // allocation. This avoids multiple limit checks. 1652 // allocation. This avoids multiple limit checks.
1726 HValue* size_in_bytes = 1653 HValue* size_in_bytes =
1727 AddInstruction(new(zone) HConstant(size, Representation::Integer32())); 1654 AddInstruction(new(zone) HConstant(size, Representation::Integer32()));
1728 HInstruction* object = 1655 HInstruction* object =
1729 AddInstruction(new(zone) HAllocate(context, 1656 AddInstruction(new(zone) HAllocate(context,
1730 size_in_bytes, 1657 size_in_bytes,
1731 HType::JSObject(), 1658 HType::JSObject(),
1732 allocate_flags)); 1659 allocate_flags));
1733 1660
1734 // Copy the JS array part. 1661 // Copy the JS array part.
1735 for (int i = 0; i < JSArray::kSize; i += kPointerSize) { 1662 for (int i = 0; i < JSArray::kSize; i += kPointerSize) {
1736 if ((i != JSArray::kElementsOffset) || (length == 0)) { 1663 if ((i != JSArray::kElementsOffset) || (length == 0)) {
1737 HInstruction* value = AddInstruction(new(zone) HLoadNamedField( 1664 HObjectAccess access = HObjectAccess::ForJSArrayOffset(i);
1738 boilerplate, true, Representation::Tagged(), i)); 1665 AddStore(object, access, AddLoad(boilerplate, access));
1739 if (i != JSArray::kMapOffset) {
1740 AddInstruction(new(zone) HStoreNamedField(object,
1741 factory->empty_string(),
1742 value, true,
1743 Representation::Tagged(), i));
1744 } else {
1745 BuildStoreMap(object, value);
1746 }
1747 } 1666 }
1748 } 1667 }
1749 1668
1750 // Create an allocation site info if requested. 1669 // Create an allocation site info if requested.
1751 if (mode == TRACK_ALLOCATION_SITE) { 1670 if (mode == TRACK_ALLOCATION_SITE) {
1752 BuildCreateAllocationSiteInfo(object, JSArray::kSize, boilerplate); 1671 BuildCreateAllocationSiteInfo(object, JSArray::kSize, boilerplate);
1753 } 1672 }
1754 1673
1755 if (length > 0) { 1674 if (length > 0) {
1756 // Get hold of the elements array of the boilerplate and setup the 1675 // Get hold of the elements array of the boilerplate and setup the
1757 // elements pointer in the resulting object. 1676 // elements pointer in the resulting object.
1758 HValue* boilerplate_elements = AddLoadElements(boilerplate); 1677 HValue* boilerplate_elements = AddLoadElements(boilerplate);
1759 HValue* object_elements = 1678 HValue* object_elements =
1760 AddInstruction(new(zone) HInnerAllocatedObject(object, elems_offset)); 1679 AddInstruction(new(zone) HInnerAllocatedObject(object, elems_offset));
1761 AddInstruction(new(zone) HStoreNamedField(object, 1680 AddStore(object, HObjectAccess::ForElementsPointer(), object_elements);
1762 factory->elements_field_string(),
1763 object_elements, true,
1764 Representation::Tagged(),
1765 JSObject::kElementsOffset));
1766 1681
1767 // Copy the elements array header. 1682 // Copy the elements array header.
1768 for (int i = 0; i < FixedArrayBase::kHeaderSize; i += kPointerSize) { 1683 for (int i = 0; i < FixedArrayBase::kHeaderSize; i += kPointerSize) {
1769 HInstruction* value = 1684 HObjectAccess access = HObjectAccess::ForFixedArrayOffset(i);
1770 AddInstruction(new(zone) HLoadNamedField( 1685 AddStore(object_elements, access, AddLoad(boilerplate_elements, access));
1771 boilerplate_elements, true, Representation::Tagged(), i));
1772 AddInstruction(new(zone) HStoreNamedField(object_elements,
1773 factory->empty_string(),
1774 value, true,
1775 Representation::Tagged(), i));
1776 } 1686 }
1777 1687
1778 // Copy the elements array contents. 1688 // Copy the elements array contents.
1779 // TODO(mstarzinger): Teach HGraphBuilder::BuildCopyElements to unfold 1689 // TODO(mstarzinger): Teach HGraphBuilder::BuildCopyElements to unfold
1780 // 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
1781 // helper here instead. 1691 // helper here instead.
1782 for (int i = 0; i < length; i++) { 1692 for (int i = 0; i < length; i++) {
1783 HValue* key_constant = 1693 HValue* key_constant =
1784 AddInstruction(new(zone) HConstant(i, Representation::Integer32())); 1694 AddInstruction(new(zone) HConstant(i, Representation::Integer32()));
1785 HInstruction* value = 1695 HInstruction* value =
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
1845 } 1755 }
1846 1756
1847 1757
1848 HValue* HGraphBuilder::BuildCreateAllocationSiteInfo(HValue* previous_object, 1758 HValue* HGraphBuilder::BuildCreateAllocationSiteInfo(HValue* previous_object,
1849 int previous_object_size, 1759 int previous_object_size,
1850 HValue* payload) { 1760 HValue* payload) {
1851 HInnerAllocatedObject* alloc_site = new(zone()) 1761 HInnerAllocatedObject* alloc_site = new(zone())
1852 HInnerAllocatedObject(previous_object, previous_object_size); 1762 HInnerAllocatedObject(previous_object, previous_object_size);
1853 AddInstruction(alloc_site); 1763 AddInstruction(alloc_site);
1854 Handle<Map> alloc_site_map(isolate()->heap()->allocation_site_info_map()); 1764 Handle<Map> alloc_site_map(isolate()->heap()->allocation_site_info_map());
1855 BuildStoreMap(alloc_site, alloc_site_map); 1765 AddStoreMapConstant(alloc_site, alloc_site_map);
1856 AddInstruction(new(zone()) HStoreNamedField(alloc_site, 1766 HObjectAccess access = HObjectAccess::ForAllocationSitePayload();
1857 isolate()->factory()->payload_string(), 1767 AddStore(alloc_site, access, payload);
1858 payload,
1859 true,
1860 Representation::Tagged(),
1861 AllocationSiteInfo::kPayloadOffset));
1862 return alloc_site; 1768 return alloc_site;
1863 } 1769 }
1864 1770
1865 1771
1866 HGraphBuilder::JSArrayBuilder::JSArrayBuilder(HGraphBuilder* builder, 1772 HGraphBuilder::JSArrayBuilder::JSArrayBuilder(HGraphBuilder* builder,
1867 ElementsKind kind, 1773 ElementsKind kind,
1868 HValue* allocation_site_payload, 1774 HValue* allocation_site_payload,
1869 AllocationSiteMode mode) : 1775 AllocationSiteMode mode) :
1870 builder_(builder), 1776 builder_(builder),
1871 kind_(kind), 1777 kind_(kind),
1872 allocation_site_payload_(allocation_site_payload) { 1778 allocation_site_payload_(allocation_site_payload) {
1873 if (mode == DONT_TRACK_ALLOCATION_SITE) { 1779 if (mode == DONT_TRACK_ALLOCATION_SITE) {
1874 mode_ = mode; 1780 mode_ = mode;
1875 } else { 1781 } else {
1876 mode_ = AllocationSiteInfo::GetMode(kind); 1782 mode_ = AllocationSiteInfo::GetMode(kind);
1877 } 1783 }
1878 } 1784 }
1879 1785
1880 1786
1881 HValue* HGraphBuilder::JSArrayBuilder::EmitMapCode(HValue* context) { 1787 HValue* HGraphBuilder::JSArrayBuilder::EmitMapCode(HValue* context) {
1882 // Get the global context, the native context, the map array 1788 // Get the global context, the native context, the map array
1883 HInstruction* global_object = AddInstruction(new(zone()) 1789 HInstruction* global_object = AddInstruction(new(zone())
1884 HGlobalObject(context)); 1790 HGlobalObject(context));
1885 HInstruction* native_context = AddInstruction(new(zone()) 1791 HObjectAccess access = HObjectAccess::ForFixedArrayOffset(
1886 HLoadNamedField(global_object, true, Representation::Tagged(), 1792 GlobalObject::kNativeContextOffset);
1887 GlobalObject::kNativeContextOffset)); 1793 HInstruction* native_context = builder()->AddLoad(global_object, access);
1888 int offset = Context::kHeaderSize + 1794
1889 kPointerSize * Context::JS_ARRAY_MAPS_INDEX; 1795 access = HObjectAccess::ForFixedArrayOffset(
1890 HInstruction* map_array = AddInstruction(new(zone()) 1796 Context::kHeaderSize + kPointerSize * Context::JS_ARRAY_MAPS_INDEX);
1891 HLoadNamedField(native_context, true, Representation::Tagged(), offset)); 1797 HInstruction* map_array = builder()->AddLoad(native_context, access);
1892 offset = kind_ * kPointerSize + FixedArrayBase::kHeaderSize; 1798
1893 return AddInstruction(new(zone()) HLoadNamedField( 1799 access = HObjectAccess::ForFixedArrayOffset(
1894 map_array, true, Representation::Tagged(), offset)); 1800 kind_ * kPointerSize + FixedArrayBase::kHeaderSize);
1801 return builder()->AddLoad(map_array, access);
1895 } 1802 }
1896 1803
1897 1804
1898 HValue* HGraphBuilder::JSArrayBuilder::EstablishAllocationSize( 1805 HValue* HGraphBuilder::JSArrayBuilder::EstablishAllocationSize(
1899 HValue* length_node) { 1806 HValue* length_node) {
1900 HValue* context = builder()->environment()->LookupContext(); 1807 HValue* context = builder()->environment()->LookupContext();
1901 ASSERT(length_node != NULL); 1808 ASSERT(length_node != NULL);
1902 1809
1903 int base_size = JSArray::kSize; 1810 int base_size = JSArray::kSize;
1904 if (mode_ == TRACK_ALLOCATION_SITE) { 1811 if (mode_ == TRACK_ALLOCATION_SITE) {
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
1993 1900
1994 if (fill_with_hole) { 1901 if (fill_with_hole) {
1995 builder()->BuildFillElementsWithHole(context, elements_location_, kind_, 1902 builder()->BuildFillElementsWithHole(context, elements_location_, kind_,
1996 graph()->GetConstant0(), capacity); 1903 graph()->GetConstant0(), capacity);
1997 } 1904 }
1998 1905
1999 return new_object; 1906 return new_object;
2000 } 1907 }
2001 1908
2002 1909
1910 HStoreNamedField* HGraphBuilder::AddStore(HValue *object,
1911 HObjectAccess access,
1912 HValue *val,
1913 Representation representation) {
1914 HStoreNamedField *instr = new(zone())
1915 HStoreNamedField(object, access, val, representation);
1916 AddInstruction(instr);
1917 return instr;
1918 }
1919
1920
1921 HLoadNamedField* HGraphBuilder::AddLoad(HValue *object,
1922 HObjectAccess access,
1923 HValue *typecheck,
1924 Representation representation) {
1925 HLoadNamedField *instr =
1926 new(zone()) HLoadNamedField(object, access, typecheck, representation);
1927 AddInstruction(instr);
1928 return instr;
1929 }
1930
1931
1932 HStoreNamedField* HGraphBuilder::AddStoreMapConstant(HValue *object,
1933 Handle<Map> map) {
1934 HValue* constant =
1935 AddInstruction(new(zone()) HConstant(map, Representation::Tagged()));
1936 HStoreNamedField *instr =
1937 new(zone()) HStoreNamedField(object, HObjectAccess::ForMap(), constant);
1938 AddInstruction(instr);
1939 return instr;
1940 }
1941
1942
2003 HOptimizedGraphBuilder::HOptimizedGraphBuilder(CompilationInfo* info, 1943 HOptimizedGraphBuilder::HOptimizedGraphBuilder(CompilationInfo* info,
2004 TypeFeedbackOracle* oracle) 1944 TypeFeedbackOracle* oracle)
2005 : HGraphBuilder(info), 1945 : HGraphBuilder(info),
2006 function_state_(NULL), 1946 function_state_(NULL),
2007 initial_function_state_(this, info, oracle, NORMAL_RETURN), 1947 initial_function_state_(this, info, oracle, NORMAL_RETURN),
2008 ast_context_(NULL), 1948 ast_context_(NULL),
2009 break_scope_(NULL), 1949 break_scope_(NULL),
2010 inlined_count_(0), 1950 inlined_count_(0),
2011 globals_(10, info->zone()), 1951 globals_(10, info->zone()),
2012 inline_bailout_(false) { 1952 inline_bailout_(false) {
(...skipping 4321 matching lines...) Expand 10 before | Expand all | Expand 10 after
6334 ASSERT(current_block() != NULL); 6274 ASSERT(current_block() != NULL);
6335 ASSERT(current_block()->HasPredecessor()); 6275 ASSERT(current_block()->HasPredecessor());
6336 return Bailout("DebuggerStatement"); 6276 return Bailout("DebuggerStatement");
6337 } 6277 }
6338 6278
6339 6279
6340 static Handle<SharedFunctionInfo> SearchSharedFunctionInfo( 6280 static Handle<SharedFunctionInfo> SearchSharedFunctionInfo(
6341 Code* unoptimized_code, FunctionLiteral* expr) { 6281 Code* unoptimized_code, FunctionLiteral* expr) {
6342 int start_position = expr->start_position(); 6282 int start_position = expr->start_position();
6343 RelocIterator it(unoptimized_code); 6283 RelocIterator it(unoptimized_code);
6344 for (;!it.done(); it.next()) { 6284 for (; !it.done(); it.next()) {
6345 RelocInfo* rinfo = it.rinfo(); 6285 RelocInfo* rinfo = it.rinfo();
6346 if (rinfo->rmode() != RelocInfo::EMBEDDED_OBJECT) continue; 6286 if (rinfo->rmode() != RelocInfo::EMBEDDED_OBJECT) continue;
6347 Object* obj = rinfo->target_object(); 6287 Object* obj = rinfo->target_object();
6348 if (obj->IsSharedFunctionInfo()) { 6288 if (obj->IsSharedFunctionInfo()) {
6349 SharedFunctionInfo* shared = SharedFunctionInfo::cast(obj); 6289 SharedFunctionInfo* shared = SharedFunctionInfo::cast(obj);
6350 if (shared->start_position() == start_position) { 6290 if (shared->start_position() == start_position) {
6351 return Handle<SharedFunctionInfo>(shared); 6291 return Handle<SharedFunctionInfo>(shared);
6352 } 6292 }
6353 } 6293 }
6354 } 6294 }
(...skipping 596 matching lines...) Expand 10 before | Expand all | Expand 10 after
6951 if (!is_store) return false; 6891 if (!is_store) return false;
6952 6892
6953 // 2nd chance: A store into a non-existent field can still be inlined if we 6893 // 2nd chance: A store into a non-existent field can still be inlined if we
6954 // have a matching transition and some room left in the object. 6894 // have a matching transition and some room left in the object.
6955 type->LookupTransition(NULL, *name, lookup); 6895 type->LookupTransition(NULL, *name, lookup);
6956 return lookup->IsTransitionToField(*type) && 6896 return lookup->IsTransitionToField(*type) &&
6957 (type->unused_property_fields() > 0); 6897 (type->unused_property_fields() > 0);
6958 } 6898 }
6959 6899
6960 6900
6961 static int ComputeLoadStoreFieldIndex(Handle<Map> type,
6962 LookupResult* lookup) {
6963 ASSERT(lookup->IsField() || lookup->IsTransitionToField(*type));
6964 if (lookup->IsField()) {
6965 return lookup->GetLocalFieldIndexFromMap(*type);
6966 } else {
6967 Map* transition = lookup->GetTransitionMapFromMap(*type);
6968 int descriptor = transition->LastAdded();
6969 int index = transition->instance_descriptors()->GetFieldIndex(descriptor);
6970 return index - type->inobject_properties();
6971 }
6972 }
6973
6974
6975 static Representation ComputeLoadStoreRepresentation(Handle<Map> type, 6901 static Representation ComputeLoadStoreRepresentation(Handle<Map> type,
6976 LookupResult* lookup) { 6902 LookupResult* lookup) {
6977 if (lookup->IsField()) { 6903 if (lookup->IsField()) {
6978 return lookup->representation(); 6904 return lookup->representation();
6979 } else { 6905 } else {
6980 Map* transition = lookup->GetTransitionMapFromMap(*type); 6906 Map* transition = lookup->GetTransitionMapFromMap(*type);
6981 int descriptor = transition->LastAdded(); 6907 int descriptor = transition->LastAdded();
6982 PropertyDetails details = 6908 PropertyDetails details =
6983 transition->instance_descriptors()->GetDetails(descriptor); 6909 transition->instance_descriptors()->GetDetails(descriptor);
6984 return details.representation(); 6910 return details.representation();
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
7029 } 6955 }
7030 ASSERT(proto->GetPrototype(isolate())->IsNull()); 6956 ASSERT(proto->GetPrototype(isolate())->IsNull());
7031 } 6957 }
7032 ASSERT(proto->IsJSObject()); 6958 ASSERT(proto->IsJSObject());
7033 AddInstruction(new(zone()) HCheckPrototypeMaps( 6959 AddInstruction(new(zone()) HCheckPrototypeMaps(
7034 Handle<JSObject>(JSObject::cast(map->prototype())), 6960 Handle<JSObject>(JSObject::cast(map->prototype())),
7035 Handle<JSObject>(JSObject::cast(proto)), 6961 Handle<JSObject>(JSObject::cast(proto)),
7036 zone())); 6962 zone()));
7037 } 6963 }
7038 6964
7039 int index = ComputeLoadStoreFieldIndex(map, lookup); 6965 HObjectAccess access = HObjectAccess::ForField(map, lookup, name);
7040 bool is_in_object = index < 0; 6966 HStoreNamedField* instr = new(zone()) HStoreNamedField(object, access, value,
7041 Representation representation = ComputeLoadStoreRepresentation(map, lookup); 6967 ComputeLoadStoreRepresentation(map, lookup));
7042 int offset = index * kPointerSize; 6968
7043 if (index < 0) {
7044 // Negative property indices are in-object properties, indexed
7045 // from the end of the fixed part of the object.
7046 offset += map->instance_size();
7047 } else {
7048 offset += FixedArray::kHeaderSize;
7049 }
7050 HStoreNamedField* instr = new(zone()) HStoreNamedField(
7051 object, name, value, is_in_object, representation, offset);
7052 if (lookup->IsTransitionToField(*map)) { 6969 if (lookup->IsTransitionToField(*map)) {
7053 Handle<Map> transition(lookup->GetTransitionMapFromMap(*map)); 6970 Handle<Map> transition(lookup->GetTransitionMapFromMap(*map));
7054 instr->set_transition(transition); 6971 instr->set_transition(transition);
7055 // TODO(fschneider): Record the new map type of the object in the IR to 6972 // TODO(fschneider): Record the new map type of the object in the IR to
7056 // enable elimination of redundant checks after the transition store. 6973 // enable elimination of redundant checks after the transition store.
7057 instr->SetGVNFlag(kChangesMaps); 6974 instr->SetGVNFlag(kChangesMaps);
7058 } 6975 }
7059 return instr; 6976 return instr;
7060 } 6977 }
7061 6978
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
7111 Handle<String> name) { 7028 Handle<String> name) {
7112 if (!name->Equals(isolate()->heap()->length_string())) return false; 7029 if (!name->Equals(isolate()->heap()->length_string())) return false;
7113 7030
7114 for (int i = 0; i < types->length(); i++) { 7031 for (int i = 0; i < types->length(); i++) {
7115 if (types->at(i)->instance_type() != JS_ARRAY_TYPE) return false; 7032 if (types->at(i)->instance_type() != JS_ARRAY_TYPE) return false;
7116 } 7033 }
7117 7034
7118 AddInstruction(new(zone()) HCheckNonSmi(object)); 7035 AddInstruction(new(zone()) HCheckNonSmi(object));
7119 7036
7120 HInstruction* typecheck = 7037 HInstruction* typecheck =
7121 AddInstruction(HCheckMaps::New(object, types, zone())); 7038 AddInstruction(HCheckMaps::New(object, types, zone()));
7122 HInstruction* instr = 7039 HInstruction* instr = new(zone())
7123 HLoadNamedField::NewArrayLength(zone(), object, typecheck); 7040 HLoadNamedField(object, HObjectAccess::ForArrayLength(), typecheck);
7041
7124 instr->set_position(expr->position()); 7042 instr->set_position(expr->position());
7125 ast_context()->ReturnInstruction(instr, expr->id()); 7043 ast_context()->ReturnInstruction(instr, expr->id());
7126 return true; 7044 return true;
7127 } 7045 }
7128 7046
7129 7047
7130 void HOptimizedGraphBuilder::HandlePolymorphicLoadNamedField(Property* expr, 7048 void HOptimizedGraphBuilder::HandlePolymorphicLoadNamedField(Property* expr,
7131 HValue* object, 7049 HValue* object,
7132 SmallMapList* types, 7050 SmallMapList* types,
7133 Handle<String> name) { 7051 Handle<String> name) {
7134 int count = 0; 7052 int count = 0;
7135 int previous_field_offset = 0; 7053 int previous_field_offset = 0;
7136 bool previous_field_is_in_object = false; 7054 bool previous_field_is_in_object = false;
7137 bool is_monomorphic_field = true; 7055 bool is_monomorphic_field = true;
7138 7056
7139 if (HandlePolymorphicArrayLengthLoad(expr, object, types, name)) 7057 if (HandlePolymorphicArrayLengthLoad(expr, object, types, name))
7140 return; 7058 return;
7141 7059
7142 Handle<Map> map; 7060 Handle<Map> map;
7143 LookupResult lookup(isolate()); 7061 LookupResult lookup(isolate());
7144 for (int i = 0; i < types->length() && count < kMaxLoadPolymorphism; ++i) { 7062 for (int i = 0; i < types->length() && count < kMaxLoadPolymorphism; ++i) {
7145 map = types->at(i); 7063 map = types->at(i);
7146 if (ComputeLoadStoreField(map, name, &lookup, false)) { 7064 if (ComputeLoadStoreField(map, name, &lookup, false)) {
7147 int index = ComputeLoadStoreFieldIndex(map, &lookup); 7065 HObjectAccess access =
7148 bool is_in_object = index < 0; 7066 HObjectAccess::ForField(map, &lookup, name);
7149 int offset = index * kPointerSize;
7150 if (index < 0) {
7151 // Negative property indices are in-object properties, indexed
7152 // from the end of the fixed part of the object.
7153 offset += map->instance_size();
7154 } else {
7155 offset += FixedArray::kHeaderSize;
7156 }
7157 if (count == 0) { 7067 if (count == 0) {
7158 previous_field_offset = offset; 7068 previous_field_offset = access.offset();
7159 previous_field_is_in_object = is_in_object; 7069 previous_field_is_in_object = access.IsInobject();
7160 } else if (is_monomorphic_field) { 7070 } else if (is_monomorphic_field) {
7161 is_monomorphic_field = (offset == previous_field_offset) && 7071 // TODO(titzer): just break out of this loop if not the same
7162 (is_in_object == previous_field_is_in_object); 7072 is_monomorphic_field =
7073 (access.offset() == previous_field_offset) &&
7074 (access.IsInobject() == previous_field_is_in_object);
7163 } 7075 }
7164 ++count; 7076 ++count;
7165 } 7077 }
7166 } 7078 }
7167 7079
7168 // Use monomorphic load if property lookup results in the same field index 7080 // Use monomorphic load if property lookup results in the same field index
7169 // for all maps. Requires special map check on the set of all handled maps. 7081 // for all maps. Requires special map check on the set of all handled maps.
7170 AddInstruction(new(zone()) HCheckNonSmi(object)); 7082 AddInstruction(new(zone()) HCheckNonSmi(object));
7171 HInstruction* instr; 7083 HInstruction* instr;
7172 if (count == types->length() && is_monomorphic_field) { 7084 if (count == types->length() && is_monomorphic_field) {
7173 AddInstruction(HCheckMaps::New(object, types, zone())); 7085 AddInstruction(HCheckMaps::New(object, types, zone()));
7174 instr = BuildLoadNamedField(object, map, &lookup); 7086 instr = new(zone()) HLoadNamedField(object,
7087 HObjectAccess::ForField(map, &lookup, name));
7088 // TODO(titzer): ensure the representation is the same for all maps
7175 } else { 7089 } else {
7176 HValue* context = environment()->LookupContext(); 7090 HValue* context = environment()->LookupContext();
7177 instr = new(zone()) HLoadNamedFieldPolymorphic(context, 7091 instr = new(zone())
7178 object, 7092 HLoadNamedFieldPolymorphic(context, object, types, name, zone());
7179 types,
7180 name,
7181 zone());
7182 } 7093 }
7183 7094
7184 instr->set_position(expr->position()); 7095 instr->set_position(expr->position());
7185 return ast_context()->ReturnInstruction(instr, expr->id()); 7096 return ast_context()->ReturnInstruction(instr, expr->id());
7186 } 7097 }
7187 7098
7188 7099
7189 void HOptimizedGraphBuilder::HandlePolymorphicStoreNamedField( 7100 void HOptimizedGraphBuilder::HandlePolymorphicStoreNamedField(
7190 Assignment* expr, 7101 Assignment* expr,
7191 HValue* object, 7102 HValue* object,
(...skipping 532 matching lines...) Expand 10 before | Expand all | Expand 10 after
7724 HValue* value = environment()->Pop(); 7635 HValue* value = environment()->Pop();
7725 HThrow* instr = new(zone()) HThrow(context, value); 7636 HThrow* instr = new(zone()) HThrow(context, value);
7726 instr->set_position(expr->position()); 7637 instr->set_position(expr->position());
7727 AddInstruction(instr); 7638 AddInstruction(instr);
7728 AddSimulate(expr->id()); 7639 AddSimulate(expr->id());
7729 current_block()->FinishExit(new(zone()) HAbnormalExit); 7640 current_block()->FinishExit(new(zone()) HAbnormalExit);
7730 set_current_block(NULL); 7641 set_current_block(NULL);
7731 } 7642 }
7732 7643
7733 7644
7734 HLoadNamedField* HOptimizedGraphBuilder::BuildLoadNamedField(
7735 HValue* object,
7736 Handle<Map> map,
7737 LookupResult* lookup) {
7738 Representation representation = lookup->representation();
7739 int index = lookup->GetLocalFieldIndexFromMap(*map);
7740 if (index < 0) {
7741 // Negative property indices are in-object properties, indexed
7742 // from the end of the fixed part of the object.
7743 int offset = (index * kPointerSize) + map->instance_size();
7744 return new(zone()) HLoadNamedField(object, true, representation, offset);
7745 } else {
7746 // Non-negative property indices are in the properties array.
7747 int offset = (index * kPointerSize) + FixedArray::kHeaderSize;
7748 return new(zone()) HLoadNamedField(object, false, representation, offset);
7749 }
7750 }
7751
7752
7753 HInstruction* HOptimizedGraphBuilder::BuildLoadNamedGeneric( 7645 HInstruction* HOptimizedGraphBuilder::BuildLoadNamedGeneric(
7754 HValue* object, 7646 HValue* object,
7755 Handle<String> name, 7647 Handle<String> name,
7756 Property* expr) { 7648 Property* expr) {
7757 if (expr->IsUninitialized()) { 7649 if (expr->IsUninitialized()) {
7758 AddSoftDeoptimize(); 7650 AddSoftDeoptimize();
7759 } 7651 }
7760 HValue* context = environment()->LookupContext(); 7652 HValue* context = environment()->LookupContext();
7761 return new(zone()) HLoadNamedGeneric(context, object, name); 7653 return new(zone()) HLoadNamedGeneric(context, object, name);
7762 } 7654 }
(...skipping 15 matching lines...) Expand all
7778 Handle<String> name, 7670 Handle<String> name,
7779 Property* expr, 7671 Property* expr,
7780 Handle<Map> map) { 7672 Handle<Map> map) {
7781 // Handle a load from a known field. 7673 // Handle a load from a known field.
7782 ASSERT(!map->is_dictionary_map()); 7674 ASSERT(!map->is_dictionary_map());
7783 7675
7784 // Handle access to various length properties 7676 // Handle access to various length properties
7785 if (name->Equals(isolate()->heap()->length_string())) { 7677 if (name->Equals(isolate()->heap()->length_string())) {
7786 if (map->instance_type() == JS_ARRAY_TYPE) { 7678 if (map->instance_type() == JS_ARRAY_TYPE) {
7787 AddCheckMapsWithTransitions(object, map); 7679 AddCheckMapsWithTransitions(object, map);
7788 return HLoadNamedField::NewArrayLength(zone(), object, object); 7680 return new(zone()) HLoadNamedField(object,
7681 HObjectAccess::ForArrayLength());
7789 } 7682 }
7790 } 7683 }
7791 7684
7792 LookupResult lookup(isolate()); 7685 LookupResult lookup(isolate());
7793 map->LookupDescriptor(NULL, *name, &lookup); 7686 map->LookupDescriptor(NULL, *name, &lookup);
7794 if (lookup.IsField()) { 7687 if (lookup.IsField()) {
7795 AddCheckMap(object, map); 7688 AddCheckMap(object, map);
7796 return BuildLoadNamedField(object, map, &lookup); 7689 return new(zone()) HLoadNamedField(object,
7690 HObjectAccess::ForField(map, &lookup, name),
7691 NULL,
7692 ComputeLoadStoreRepresentation(map, &lookup));
7797 } 7693 }
7798 7694
7799 // Handle a load of a constant known function. 7695 // Handle a load of a constant known function.
7800 if (lookup.IsConstantFunction()) { 7696 if (lookup.IsConstantFunction()) {
7801 AddCheckMap(object, map); 7697 AddCheckMap(object, map);
7802 Handle<JSFunction> function(lookup.GetConstantFunctionFromMap(*map)); 7698 Handle<JSFunction> function(lookup.GetConstantFunctionFromMap(*map));
7803 return new(zone()) HConstant(function, Representation::Tagged()); 7699 return new(zone()) HConstant(function, Representation::Tagged());
7804 } 7700 }
7805 7701
7806 // Handle a load from a known field somewhere in the prototype chain. 7702 // Handle a load from a known field somewhere in the prototype chain.
7807 LookupInPrototypes(map, name, &lookup); 7703 LookupInPrototypes(map, name, &lookup);
7808 if (lookup.IsField()) { 7704 if (lookup.IsField()) {
7809 Handle<JSObject> prototype(JSObject::cast(map->prototype())); 7705 Handle<JSObject> prototype(JSObject::cast(map->prototype()));
7810 Handle<JSObject> holder(lookup.holder()); 7706 Handle<JSObject> holder(lookup.holder());
7811 Handle<Map> holder_map(holder->map()); 7707 Handle<Map> holder_map(holder->map());
7812 AddCheckMap(object, map); 7708 AddCheckMap(object, map);
7813 AddInstruction( 7709 AddInstruction(
7814 new(zone()) HCheckPrototypeMaps(prototype, holder, zone())); 7710 new(zone()) HCheckPrototypeMaps(prototype, holder, zone()));
7815 HValue* holder_value = AddInstruction( 7711 HValue* holder_value = AddInstruction(new(zone())
7816 new(zone()) HConstant(holder, Representation::Tagged())); 7712 HConstant(holder, Representation::Tagged()));
7817 return BuildLoadNamedField(holder_value, holder_map, &lookup); 7713 return new(zone()) HLoadNamedField(holder_value,
7714 HObjectAccess::ForField(holder_map, &lookup, name),
7715 NULL,
7716 ComputeLoadStoreRepresentation(map, &lookup));
7818 } 7717 }
7819 7718
7820 // Handle a load of a constant function somewhere in the prototype chain. 7719 // Handle a load of a constant function somewhere in the prototype chain.
7821 if (lookup.IsConstantFunction()) { 7720 if (lookup.IsConstantFunction()) {
7822 Handle<JSObject> prototype(JSObject::cast(map->prototype())); 7721 Handle<JSObject> prototype(JSObject::cast(map->prototype()));
7823 Handle<JSObject> holder(lookup.holder()); 7722 Handle<JSObject> holder(lookup.holder());
7824 Handle<Map> holder_map(holder->map()); 7723 Handle<Map> holder_map(holder->map());
7825 AddCheckMap(object, map); 7724 AddCheckMap(object, map);
7826 AddInstruction(new(zone()) HCheckPrototypeMaps(prototype, holder, zone())); 7725 AddInstruction(new(zone()) HCheckPrototypeMaps(prototype, holder, zone()));
7827 Handle<JSFunction> function(lookup.GetConstantFunctionFromMap(*holder_map)); 7726 Handle<JSFunction> function(lookup.GetConstantFunctionFromMap(*holder_map));
(...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after
8070 // it's a keyed property) and registered in the full codegen. 7969 // it's a keyed property) and registered in the full codegen.
8071 HBasicBlock* if_jsarray = graph()->CreateBasicBlock(); 7970 HBasicBlock* if_jsarray = graph()->CreateBasicBlock();
8072 HBasicBlock* if_fastobject = graph()->CreateBasicBlock(); 7971 HBasicBlock* if_fastobject = graph()->CreateBasicBlock();
8073 HHasInstanceTypeAndBranch* typecheck = 7972 HHasInstanceTypeAndBranch* typecheck =
8074 new(zone()) HHasInstanceTypeAndBranch(object, JS_ARRAY_TYPE); 7973 new(zone()) HHasInstanceTypeAndBranch(object, JS_ARRAY_TYPE);
8075 typecheck->SetSuccessorAt(0, if_jsarray); 7974 typecheck->SetSuccessorAt(0, if_jsarray);
8076 typecheck->SetSuccessorAt(1, if_fastobject); 7975 typecheck->SetSuccessorAt(1, if_fastobject);
8077 current_block()->Finish(typecheck); 7976 current_block()->Finish(typecheck);
8078 7977
8079 set_current_block(if_jsarray); 7978 set_current_block(if_jsarray);
8080 HInstruction* length; 7979 HInstruction* length = AddLoad(object,
8081 length = AddInstruction( 7980 HObjectAccess::ForArrayLength(), typecheck);
8082 HLoadNamedField::NewArrayLength(zone(), object, typecheck, 7981 length->set_type(HType::Smi());
8083 HType::Smi())); 7982
8084 checked_key = AddBoundsCheck(key, length, ALLOW_SMI_KEY); 7983 checked_key = AddBoundsCheck(key, length, ALLOW_SMI_KEY);
8085 access = AddInstruction(BuildFastElementAccess( 7984 access = AddInstruction(BuildFastElementAccess(
8086 elements, checked_key, val, elements_kind_branch, 7985 elements, checked_key, val, elements_kind_branch,
8087 elements_kind, is_store, STANDARD_STORE)); 7986 elements_kind, is_store, STANDARD_STORE));
8088 if (!is_store) { 7987 if (!is_store) {
8089 Push(access); 7988 Push(access);
8090 } 7989 }
8091 7990
8092 *has_side_effects |= access->HasObservableSideEffects(); 7991 *has_side_effects |= access->HasObservableSideEffects();
8093 // The caller will use has_side_effects and add correct Simulate. 7992 // The caller will use has_side_effects and add correct Simulate.
(...skipping 2625 matching lines...) Expand 10 before | Expand all | Expand 10 after
10719 } 10618 }
10720 10619
10721 10620
10722 void HOptimizedGraphBuilder::BuildEmitDeepCopy( 10621 void HOptimizedGraphBuilder::BuildEmitDeepCopy(
10723 Handle<JSObject> boilerplate_object, 10622 Handle<JSObject> boilerplate_object,
10724 Handle<JSObject> original_boilerplate_object, 10623 Handle<JSObject> original_boilerplate_object,
10725 HInstruction* target, 10624 HInstruction* target,
10726 int* offset, 10625 int* offset,
10727 AllocationSiteMode mode) { 10626 AllocationSiteMode mode) {
10728 Zone* zone = this->zone(); 10627 Zone* zone = this->zone();
10729 Factory* factory = isolate()->factory();
10730 10628
10731 HInstruction* original_boilerplate = AddInstruction(new(zone) HConstant( 10629 HInstruction* original_boilerplate = AddInstruction(new(zone) HConstant(
10732 original_boilerplate_object, Representation::Tagged())); 10630 original_boilerplate_object, Representation::Tagged()));
10733 10631
10734 bool create_allocation_site_info = mode == TRACK_ALLOCATION_SITE && 10632 bool create_allocation_site_info = mode == TRACK_ALLOCATION_SITE &&
10735 boilerplate_object->map()->CanTrackAllocationSite(); 10633 boilerplate_object->map()->CanTrackAllocationSite();
10736 10634
10737 // Only elements backing stores for non-COW arrays need to be copied. 10635 // Only elements backing stores for non-COW arrays need to be copied.
10738 Handle<FixedArrayBase> elements(boilerplate_object->elements()); 10636 Handle<FixedArrayBase> elements(boilerplate_object->elements());
10739 Handle<FixedArrayBase> original_elements( 10637 Handle<FixedArrayBase> original_elements(
(...skipping 19 matching lines...) Expand all
10759 HValue* object_elements = BuildCopyObjectHeader(boilerplate_object, target, 10657 HValue* object_elements = BuildCopyObjectHeader(boilerplate_object, target,
10760 object_offset, elements_offset, elements_size); 10658 object_offset, elements_offset, elements_size);
10761 10659
10762 // Copy in-object properties. 10660 // Copy in-object properties.
10763 HValue* object_properties = 10661 HValue* object_properties =
10764 AddInstruction(new(zone) HInnerAllocatedObject(target, object_offset)); 10662 AddInstruction(new(zone) HInnerAllocatedObject(target, object_offset));
10765 for (int i = 0; i < inobject_properties; i++) { 10663 for (int i = 0; i < inobject_properties; i++) {
10766 Handle<Object> value = 10664 Handle<Object> value =
10767 Handle<Object>(boilerplate_object->InObjectPropertyAt(i), 10665 Handle<Object>(boilerplate_object->InObjectPropertyAt(i),
10768 isolate()); 10666 isolate());
10667
10668 // The access for the store depends on the type of the boilerplate.
10669 int store_offset = boilerplate_object->GetInObjectPropertyOffset(i);
10670 HObjectAccess access = boilerplate_object->IsJSArray() ?
10671 HObjectAccess::ForJSArrayOffset(store_offset) :
10672 HObjectAccess::ForJSObjectOffset(store_offset);
10673
10769 if (value->IsJSObject()) { 10674 if (value->IsJSObject()) {
10770 Handle<JSObject> value_object = Handle<JSObject>::cast(value); 10675 Handle<JSObject> value_object = Handle<JSObject>::cast(value);
10771 Handle<JSObject> original_value_object = Handle<JSObject>::cast( 10676 Handle<JSObject> original_value_object = Handle<JSObject>::cast(
10772 Handle<Object>(original_boilerplate_object->InObjectPropertyAt(i), 10677 Handle<Object>(original_boilerplate_object->InObjectPropertyAt(i),
10773 isolate())); 10678 isolate()));
10774 HInstruction* value_instruction = 10679 HInstruction* value_instruction =
10775 AddInstruction(new(zone) HInnerAllocatedObject(target, *offset)); 10680 AddInstruction(new(zone) HInnerAllocatedObject(target, *offset));
10681
10776 // TODO(verwaest): choose correct storage. 10682 // TODO(verwaest): choose correct storage.
10777 AddInstruction(new(zone) HStoreNamedField( 10683 AddStore(object_properties, access, value_instruction);
10778 object_properties, factory->unknown_field_string(), value_instruction, 10684
10779 true, Representation::Tagged(),
10780 boilerplate_object->GetInObjectPropertyOffset(i)));
10781 BuildEmitDeepCopy(value_object, original_value_object, target, 10685 BuildEmitDeepCopy(value_object, original_value_object, target,
10782 offset, DONT_TRACK_ALLOCATION_SITE); 10686 offset, DONT_TRACK_ALLOCATION_SITE);
10783 } else { 10687 } else {
10784 // TODO(verwaest): choose correct storage. 10688 // TODO(verwaest): choose correct storage.
10785 HInstruction* value_instruction = AddInstruction(new(zone) HConstant( 10689 HInstruction* value_instruction = AddInstruction(new(zone) HConstant(
10786 value, Representation::Tagged())); 10690 value, Representation::Tagged()));
10787 AddInstruction(new(zone) HStoreNamedField( 10691
10788 object_properties, factory->unknown_field_string(), value_instruction, 10692 AddStore(object_properties, access, value_instruction);
10789 true, Representation::Tagged(),
10790 boilerplate_object->GetInObjectPropertyOffset(i)));
10791 } 10693 }
10792 } 10694 }
10793 10695
10794 // Build Allocation Site Info if desired 10696 // Build Allocation Site Info if desired
10795 if (create_allocation_site_info) { 10697 if (create_allocation_site_info) {
10796 BuildCreateAllocationSiteInfo(target, JSArray::kSize, original_boilerplate); 10698 BuildCreateAllocationSiteInfo(target, JSArray::kSize, original_boilerplate);
10797 } 10699 }
10798 10700
10799 if (object_elements != NULL) { 10701 if (object_elements != NULL) {
10800 HInstruction* boilerplate_elements = AddInstruction(new(zone) HConstant( 10702 HInstruction* boilerplate_elements = AddInstruction(new(zone) HConstant(
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
10852 10754
10853 10755
10854 HValue* HOptimizedGraphBuilder::BuildCopyObjectHeader( 10756 HValue* HOptimizedGraphBuilder::BuildCopyObjectHeader(
10855 Handle<JSObject> boilerplate_object, 10757 Handle<JSObject> boilerplate_object,
10856 HInstruction* target, 10758 HInstruction* target,
10857 int object_offset, 10759 int object_offset,
10858 int elements_offset, 10760 int elements_offset,
10859 int elements_size) { 10761 int elements_size) {
10860 ASSERT(boilerplate_object->properties()->length() == 0); 10762 ASSERT(boilerplate_object->properties()->length() == 0);
10861 Zone* zone = this->zone(); 10763 Zone* zone = this->zone();
10862 Factory* factory = isolate()->factory();
10863 HValue* result = NULL; 10764 HValue* result = NULL;
10864 10765
10865 HValue* object_header = 10766 HValue* object_header =
10866 AddInstruction(new(zone) HInnerAllocatedObject(target, object_offset)); 10767 AddInstruction(new(zone) HInnerAllocatedObject(target, object_offset));
10867 Handle<Map> boilerplate_object_map(boilerplate_object->map()); 10768 Handle<Map> boilerplate_object_map(boilerplate_object->map());
10868 BuildStoreMap(object_header, boilerplate_object_map); 10769 AddStoreMapConstant(object_header, boilerplate_object_map);
10869 10770
10870 HInstruction* elements; 10771 HInstruction* elements;
10871 if (elements_size == 0) { 10772 if (elements_size == 0) {
10872 Handle<Object> elements_field = 10773 Handle<Object> elements_field =
10873 Handle<Object>(boilerplate_object->elements(), isolate()); 10774 Handle<Object>(boilerplate_object->elements(), isolate());
10874 elements = AddInstruction(new(zone) HConstant( 10775 elements = AddInstruction(new(zone) HConstant(
10875 elements_field, Representation::Tagged())); 10776 elements_field, Representation::Tagged()));
10876 } else { 10777 } else {
10877 elements = AddInstruction(new(zone) HInnerAllocatedObject( 10778 elements = AddInstruction(new(zone) HInnerAllocatedObject(
10878 target, elements_offset)); 10779 target, elements_offset));
10879 result = elements; 10780 result = elements;
10880 } 10781 }
10881 HInstruction* elements_store = AddInstruction(new(zone) HStoreNamedField( 10782 AddStore(object_header, HObjectAccess::ForElementsPointer(), elements);
10882 object_header,
10883 factory->elements_field_string(),
10884 elements,
10885 true, Representation::Tagged(), JSObject::kElementsOffset));
10886 elements_store->SetGVNFlag(kChangesElementsPointer);
10887 10783
10888 Handle<Object> properties_field = 10784 Handle<Object> properties_field =
10889 Handle<Object>(boilerplate_object->properties(), isolate()); 10785 Handle<Object>(boilerplate_object->properties(), isolate());
10890 ASSERT(*properties_field == isolate()->heap()->empty_fixed_array()); 10786 ASSERT(*properties_field == isolate()->heap()->empty_fixed_array());
10891 HInstruction* properties = AddInstruction(new(zone) HConstant( 10787 HInstruction* properties = AddInstruction(new(zone) HConstant(
10892 properties_field, Representation::None())); 10788 properties_field, Representation::None()));
10893 AddInstruction(new(zone) HStoreNamedField(object_header, 10789 HObjectAccess access = HObjectAccess::ForPropertiesPointer();
10894 factory->empty_string(), 10790 AddStore(object_header, access, properties);
10895 properties, true,
10896 Representation::Tagged(),
10897 JSObject::kPropertiesOffset));
10898 10791
10899 if (boilerplate_object->IsJSArray()) { 10792 if (boilerplate_object->IsJSArray()) {
10900 Handle<JSArray> boilerplate_array = 10793 Handle<JSArray> boilerplate_array =
10901 Handle<JSArray>::cast(boilerplate_object); 10794 Handle<JSArray>::cast(boilerplate_object);
10902 Handle<Object> length_field = 10795 Handle<Object> length_field =
10903 Handle<Object>(boilerplate_array->length(), isolate()); 10796 Handle<Object>(boilerplate_array->length(), isolate());
10904 HInstruction* length = AddInstruction(new(zone) HConstant( 10797 HInstruction* length = AddInstruction(new(zone) HConstant(
10905 length_field, Representation::None())); 10798 length_field, Representation::None()));
10799
10906 ASSERT(boilerplate_array->length()->IsSmi()); 10800 ASSERT(boilerplate_array->length()->IsSmi());
10907 Representation representation = 10801 Representation representation =
10908 IsFastElementsKind(boilerplate_array->GetElementsKind()) 10802 IsFastElementsKind(boilerplate_array->GetElementsKind())
10909 ? Representation::Smi() : Representation::Tagged(); 10803 ? Representation::Smi() : Representation::Tagged();
10910 HInstruction* length_store = AddInstruction(new(zone) HStoreNamedField( 10804 AddStore(object_header, HObjectAccess::ForArrayLength(),
10911 object_header, 10805 length, representation);
10912 factory->length_field_string(),
10913 length,
10914 true, representation, JSArray::kLengthOffset));
10915 length_store->SetGVNFlag(kChangesArrayLengths);
10916 } 10806 }
10917 10807
10918 return result; 10808 return result;
10919 } 10809 }
10920 10810
10921 10811
10922 void HOptimizedGraphBuilder::VisitThisFunction(ThisFunction* expr) { 10812 void HOptimizedGraphBuilder::VisitThisFunction(ThisFunction* expr) {
10923 ASSERT(!HasStackOverflow()); 10813 ASSERT(!HasStackOverflow());
10924 ASSERT(current_block() != NULL); 10814 ASSERT(current_block() != NULL);
10925 ASSERT(current_block()->HasPredecessor()); 10815 ASSERT(current_block()->HasPredecessor());
(...skipping 366 matching lines...) Expand 10 before | Expand all | Expand 10 after
11292 new(zone()) HHasInstanceTypeAndBranch(object, JS_VALUE_TYPE); 11182 new(zone()) HHasInstanceTypeAndBranch(object, JS_VALUE_TYPE);
11293 HBasicBlock* if_js_value = graph()->CreateBasicBlock(); 11183 HBasicBlock* if_js_value = graph()->CreateBasicBlock();
11294 HBasicBlock* not_js_value = graph()->CreateBasicBlock(); 11184 HBasicBlock* not_js_value = graph()->CreateBasicBlock();
11295 typecheck->SetSuccessorAt(0, if_js_value); 11185 typecheck->SetSuccessorAt(0, if_js_value);
11296 typecheck->SetSuccessorAt(1, not_js_value); 11186 typecheck->SetSuccessorAt(1, not_js_value);
11297 current_block()->Finish(typecheck); 11187 current_block()->Finish(typecheck);
11298 not_js_value->Goto(join); 11188 not_js_value->Goto(join);
11299 11189
11300 // Create in-object property store to kValueOffset. 11190 // Create in-object property store to kValueOffset.
11301 set_current_block(if_js_value); 11191 set_current_block(if_js_value);
11302 Handle<String> name = isolate()->factory()->undefined_string(); 11192 AddStore(object,
11303 AddInstruction(new(zone()) HStoreNamedField(object, 11193 HObjectAccess::ForJSObjectOffset(JSValue::kValueOffset), value);
11304 name,
11305 value,
11306 true, // in-object store.
11307 Representation::Tagged(),
11308 JSValue::kValueOffset));
11309 if_js_value->Goto(join); 11194 if_js_value->Goto(join);
11310 join->SetJoinId(call->id()); 11195 join->SetJoinId(call->id());
11311 set_current_block(join); 11196 set_current_block(join);
11312 return ast_context()->ReturnValue(value); 11197 return ast_context()->ReturnValue(value);
11313 } 11198 }
11314 11199
11315 11200
11316 // Fast support for charCodeAt(n). 11201 // Fast support for charCodeAt(n).
11317 void HOptimizedGraphBuilder::GenerateStringCharCodeAt(CallRuntime* call) { 11202 void HOptimizedGraphBuilder::GenerateStringCharCodeAt(CallRuntime* call) {
11318 ASSERT(call->arguments()->length() == 2); 11203 ASSERT(call->arguments()->length() == 2);
(...skipping 954 matching lines...) Expand 10 before | Expand all | Expand 10 after
12273 } 12158 }
12274 } 12159 }
12275 12160
12276 #ifdef DEBUG 12161 #ifdef DEBUG
12277 if (graph_ != NULL) graph_->Verify(false); // No full verify. 12162 if (graph_ != NULL) graph_->Verify(false); // No full verify.
12278 if (allocator_ != NULL) allocator_->Verify(); 12163 if (allocator_ != NULL) allocator_->Verify();
12279 #endif 12164 #endif
12280 } 12165 }
12281 12166
12282 } } // namespace v8::internal 12167 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/hydrogen.h ('k') | src/hydrogen-instructions.h » ('j') | src/hydrogen-instructions.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698