OLD | NEW |
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 1177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1188 | 1188 |
1189 environment()->Push(elements); | 1189 environment()->Push(elements); |
1190 capacity_checker.End(); | 1190 capacity_checker.End(); |
1191 | 1191 |
1192 if (is_js_array) { | 1192 if (is_js_array) { |
1193 HValue* new_length = AddInstruction( | 1193 HValue* new_length = AddInstruction( |
1194 HAdd::New(zone, context, length, graph_->GetConstant1())); | 1194 HAdd::New(zone, context, length, graph_->GetConstant1())); |
1195 new_length->AssumeRepresentation(Representation::Integer32()); | 1195 new_length->AssumeRepresentation(Representation::Integer32()); |
1196 new_length->ClearFlag(HValue::kCanOverflow); | 1196 new_length->ClearFlag(HValue::kCanOverflow); |
1197 | 1197 |
1198 Factory* factory = isolate()->factory(); | |
1199 Representation representation = IsFastElementsKind(kind) | 1198 Representation representation = IsFastElementsKind(kind) |
1200 ? Representation::Smi() : Representation::Tagged(); | 1199 ? Representation::Smi() : Representation::Tagged(); |
1201 HInstruction* length_store = AddInstruction(new(zone) HStoreNamedField( | 1200 AddStore(object, HObjectAccess::ForArrayLength(), new_length, |
1202 object, | 1201 representation); |
1203 factory->length_field_string(), | |
1204 new_length, true, | |
1205 representation, | |
1206 JSArray::kLengthOffset)); | |
1207 length_store->SetGVNFlag(kChangesArrayLengths); | |
1208 } | 1202 } |
1209 | 1203 |
1210 length_checker.Else(); | 1204 length_checker.Else(); |
1211 | 1205 |
1212 AddBoundsCheck(key, length, ALLOW_SMI_KEY); | 1206 AddBoundsCheck(key, length, ALLOW_SMI_KEY); |
1213 environment()->Push(elements); | 1207 environment()->Push(elements); |
1214 | 1208 |
1215 length_checker.End(); | 1209 length_checker.End(); |
1216 | 1210 |
1217 return environment()->Pop(); | 1211 return environment()->Pop(); |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1279 HValue* elements = AddLoadElements(object, mapcheck); | 1273 HValue* elements = AddLoadElements(object, mapcheck); |
1280 if (is_store && (fast_elements || fast_smi_only_elements) && | 1274 if (is_store && (fast_elements || fast_smi_only_elements) && |
1281 store_mode != STORE_NO_TRANSITION_HANDLE_COW) { | 1275 store_mode != STORE_NO_TRANSITION_HANDLE_COW) { |
1282 HCheckMaps* check_cow_map = HCheckMaps::New( | 1276 HCheckMaps* check_cow_map = HCheckMaps::New( |
1283 elements, isolate()->factory()->fixed_array_map(), zone); | 1277 elements, isolate()->factory()->fixed_array_map(), zone); |
1284 check_cow_map->ClearGVNFlag(kDependsOnElementsKind); | 1278 check_cow_map->ClearGVNFlag(kDependsOnElementsKind); |
1285 AddInstruction(check_cow_map); | 1279 AddInstruction(check_cow_map); |
1286 } | 1280 } |
1287 HInstruction* length = NULL; | 1281 HInstruction* length = NULL; |
1288 if (is_js_array) { | 1282 if (is_js_array) { |
1289 length = AddInstruction( | 1283 length = AddLoad(object, HObjectAccess::ForArrayLength(), mapcheck, |
1290 HLoadNamedField::NewArrayLength(zone, object, mapcheck, HType::Smi())); | 1284 Representation::Smi()); |
| 1285 length->set_type(HType::Smi()); |
1291 } else { | 1286 } else { |
1292 length = AddInstruction(new(zone) HFixedArrayBaseLength(elements)); | 1287 length = AddInstruction(new(zone) HFixedArrayBaseLength(elements)); |
1293 } | 1288 } |
1294 HValue* checked_key = NULL; | 1289 HValue* checked_key = NULL; |
1295 if (IsExternalArrayElementsKind(elements_kind)) { | 1290 if (IsExternalArrayElementsKind(elements_kind)) { |
1296 if (store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS) { | 1291 if (store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS) { |
1297 NoObservableSideEffectsScope no_effects(this); | 1292 NoObservableSideEffectsScope no_effects(this); |
1298 HLoadExternalArrayPointer* external_elements = | 1293 HLoadExternalArrayPointer* external_elements = |
1299 new(zone) HLoadExternalArrayPointer(elements); | 1294 new(zone) HLoadExternalArrayPointer(elements); |
1300 AddInstruction(external_elements); | 1295 AddInstruction(external_elements); |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1406 HValue* elements = | 1401 HValue* elements = |
1407 AddInstruction(new(zone) HAllocate(context, total_size, | 1402 AddInstruction(new(zone) HAllocate(context, total_size, |
1408 HType::JSArray(), flags)); | 1403 HType::JSArray(), flags)); |
1409 return elements; | 1404 return elements; |
1410 } | 1405 } |
1411 | 1406 |
1412 | 1407 |
1413 void HGraphBuilder::BuildInitializeElements(HValue* elements, | 1408 void HGraphBuilder::BuildInitializeElements(HValue* elements, |
1414 ElementsKind kind, | 1409 ElementsKind kind, |
1415 HValue* capacity) { | 1410 HValue* capacity) { |
1416 Zone* zone = this->zone(); | |
1417 Factory* factory = isolate()->factory(); | 1411 Factory* factory = isolate()->factory(); |
1418 Handle<Map> map = IsFastDoubleElementsKind(kind) | 1412 Handle<Map> map = IsFastDoubleElementsKind(kind) |
1419 ? factory->fixed_double_array_map() | 1413 ? factory->fixed_double_array_map() |
1420 : factory->fixed_array_map(); | 1414 : factory->fixed_array_map(); |
1421 BuildStoreMap(elements, map); | |
1422 | 1415 |
1423 Handle<String> fixed_array_length_field_name = factory->length_field_string(); | 1416 AddStoreMapConstant(elements, map); |
1424 Representation representation = IsFastElementsKind(kind) | 1417 Representation representation = IsFastElementsKind(kind) |
1425 ? Representation::Smi() : Representation::Tagged(); | 1418 ? Representation::Smi() : Representation::Tagged(); |
1426 HInstruction* store_length = | 1419 AddStore(elements, HObjectAccess::ForFixedArrayLength(), capacity, |
1427 new(zone) HStoreNamedField(elements, fixed_array_length_field_name, | 1420 representation); |
1428 capacity, true, representation, | |
1429 FixedArray::kLengthOffset); | |
1430 AddInstruction(store_length); | |
1431 } | 1421 } |
1432 | 1422 |
1433 | 1423 |
1434 HValue* HGraphBuilder::BuildAllocateAndInitializeElements(HValue* context, | 1424 HValue* HGraphBuilder::BuildAllocateAndInitializeElements(HValue* context, |
1435 ElementsKind kind, | 1425 ElementsKind kind, |
1436 HValue* capacity) { | 1426 HValue* capacity) { |
1437 HValue* new_elements = BuildAllocateElements(context, kind, capacity); | 1427 HValue* new_elements = BuildAllocateElements(context, kind, capacity); |
1438 BuildInitializeElements(new_elements, kind, capacity); | 1428 BuildInitializeElements(new_elements, kind, capacity); |
1439 return new_elements; | 1429 return new_elements; |
1440 } | 1430 } |
1441 | 1431 |
1442 | 1432 |
1443 HInnerAllocatedObject* HGraphBuilder::BuildJSArrayHeader(HValue* array, | 1433 HInnerAllocatedObject* HGraphBuilder::BuildJSArrayHeader(HValue* array, |
1444 HValue* array_map, | 1434 HValue* array_map, |
1445 AllocationSiteMode mode, | 1435 AllocationSiteMode mode, |
1446 HValue* allocation_site_payload, | 1436 HValue* allocation_site_payload, |
1447 HValue* length_field) { | 1437 HValue* length_field) { |
1448 | 1438 |
1449 BuildStoreMap(array, array_map); | 1439 AddStore(array, HObjectAccess::ForMap(), array_map); |
1450 | 1440 |
1451 HConstant* empty_fixed_array = | 1441 HConstant* empty_fixed_array = |
1452 new(zone()) HConstant( | 1442 new(zone()) HConstant( |
1453 Handle<FixedArray>(isolate()->heap()->empty_fixed_array()), | 1443 Handle<FixedArray>(isolate()->heap()->empty_fixed_array()), |
1454 Representation::Tagged()); | 1444 Representation::Tagged()); |
1455 AddInstruction(empty_fixed_array); | 1445 AddInstruction(empty_fixed_array); |
1456 | 1446 |
1457 AddInstruction(new(zone()) HStoreNamedField(array, | 1447 HObjectAccess access = HObjectAccess::ForPropertiesPointer(); |
1458 isolate()->factory()->properties_field_symbol(), | 1448 AddStore(array, access, empty_fixed_array); |
1459 empty_fixed_array, | 1449 AddStore(array, HObjectAccess::ForArrayLength(), length_field); |
1460 true, | |
1461 Representation::Tagged(), | |
1462 JSArray::kPropertiesOffset)); | |
1463 | |
1464 HInstruction* length_store = AddInstruction( | |
1465 new(zone()) HStoreNamedField(array, | |
1466 isolate()->factory()->length_field_string(), | |
1467 length_field, | |
1468 true, | |
1469 Representation::Tagged(), | |
1470 JSArray::kLengthOffset)); | |
1471 length_store->SetGVNFlag(kChangesArrayLengths); | |
1472 | 1450 |
1473 if (mode == TRACK_ALLOCATION_SITE) { | 1451 if (mode == TRACK_ALLOCATION_SITE) { |
1474 BuildCreateAllocationSiteInfo(array, | 1452 BuildCreateAllocationSiteInfo(array, |
1475 JSArray::kSize, | 1453 JSArray::kSize, |
1476 allocation_site_payload); | 1454 allocation_site_payload); |
1477 } | 1455 } |
1478 | 1456 |
1479 int elements_location = JSArray::kSize; | 1457 int elements_location = JSArray::kSize; |
1480 if (mode == TRACK_ALLOCATION_SITE) { | 1458 if (mode == TRACK_ALLOCATION_SITE) { |
1481 elements_location += AllocationSiteInfo::kSize; | 1459 elements_location += AllocationSiteInfo::kSize; |
1482 } | 1460 } |
1483 | 1461 |
1484 HInnerAllocatedObject* elements = new(zone()) HInnerAllocatedObject( | 1462 HInnerAllocatedObject* elements = new(zone()) HInnerAllocatedObject( |
1485 array, | 1463 array, elements_location); |
1486 elements_location); | |
1487 AddInstruction(elements); | 1464 AddInstruction(elements); |
1488 | 1465 |
1489 HInstruction* elements_store = AddInstruction( | 1466 AddStore(array, HObjectAccess::ForElementsPointer(), elements); |
1490 new(zone()) HStoreNamedField( | |
1491 array, | |
1492 isolate()->factory()->elements_field_string(), | |
1493 elements, | |
1494 true, | |
1495 Representation::Tagged(), | |
1496 JSArray::kElementsOffset)); | |
1497 elements_store->SetGVNFlag(kChangesElementsPointer); | |
1498 | |
1499 return elements; | 1467 return elements; |
1500 } | 1468 } |
1501 | 1469 |
1502 | 1470 |
1503 HInstruction* HGraphBuilder::BuildStoreMap(HValue* object, | 1471 HLoadNamedField* HGraphBuilder::AddLoadElements(HValue* object, |
1504 HValue* map) { | 1472 HValue* typecheck) { |
1505 Zone* zone = this->zone(); | 1473 return AddLoad(object, HObjectAccess::ForElementsPointer(), typecheck); |
1506 Factory* factory = isolate()->factory(); | |
1507 Handle<String> map_field_name = factory->map_field_string(); | |
1508 HInstruction* store_map = | |
1509 new(zone) HStoreNamedField(object, map_field_name, map, | |
1510 true, Representation::Tagged(), | |
1511 JSObject::kMapOffset); | |
1512 store_map->ClearGVNFlag(kChangesInobjectFields); | |
1513 store_map->SetGVNFlag(kChangesMaps); | |
1514 AddInstruction(store_map); | |
1515 return store_map; | |
1516 } | 1474 } |
1517 | 1475 |
1518 | 1476 |
1519 HInstruction* HGraphBuilder::BuildStoreMap(HValue* object, | |
1520 Handle<Map> map) { | |
1521 Zone* zone = this->zone(); | |
1522 HValue* map_constant = | |
1523 AddInstruction(new(zone) HConstant(map, Representation::Tagged())); | |
1524 return BuildStoreMap(object, map_constant); | |
1525 } | |
1526 | |
1527 | |
1528 HLoadNamedField* HGraphBuilder::AddLoadElements(HValue* object, | |
1529 HValue* typecheck) { | |
1530 HLoadNamedField* instr = new(zone()) HLoadNamedField(object, true, | |
1531 Representation::Tagged(), JSObject::kElementsOffset, typecheck); | |
1532 AddInstruction(instr); | |
1533 instr->SetGVNFlag(kDependsOnElementsPointer); | |
1534 instr->ClearGVNFlag(kDependsOnMaps); | |
1535 instr->ClearGVNFlag(kDependsOnInobjectFields); | |
1536 return instr; | |
1537 } | |
1538 | |
1539 | |
1540 HValue* HGraphBuilder::BuildNewElementsCapacity(HValue* context, | 1477 HValue* HGraphBuilder::BuildNewElementsCapacity(HValue* context, |
1541 HValue* old_capacity) { | 1478 HValue* old_capacity) { |
1542 Zone* zone = this->zone(); | 1479 Zone* zone = this->zone(); |
1543 HValue* half_old_capacity = | 1480 HValue* half_old_capacity = |
1544 AddInstruction(HShr::New(zone, context, old_capacity, | 1481 AddInstruction(HShr::New(zone, context, old_capacity, |
1545 graph_->GetConstant1())); | 1482 graph_->GetConstant1())); |
1546 half_old_capacity->AssumeRepresentation(Representation::Integer32()); | 1483 half_old_capacity->AssumeRepresentation(Representation::Integer32()); |
1547 half_old_capacity->ClearFlag(HValue::kCanOverflow); | 1484 half_old_capacity->ClearFlag(HValue::kCanOverflow); |
1548 | 1485 |
1549 HValue* new_capacity = AddInstruction( | 1486 HValue* new_capacity = AddInstruction( |
(...skipping 29 matching lines...) Expand all Loading... |
1579 HBoundsCheck(length, max_size_constant, | 1516 HBoundsCheck(length, max_size_constant, |
1580 DONT_ALLOW_SMI_KEY, Representation::Integer32())); | 1517 DONT_ALLOW_SMI_KEY, Representation::Integer32())); |
1581 } | 1518 } |
1582 | 1519 |
1583 | 1520 |
1584 HValue* HGraphBuilder::BuildGrowElementsCapacity(HValue* object, | 1521 HValue* HGraphBuilder::BuildGrowElementsCapacity(HValue* object, |
1585 HValue* elements, | 1522 HValue* elements, |
1586 ElementsKind kind, | 1523 ElementsKind kind, |
1587 HValue* length, | 1524 HValue* length, |
1588 HValue* new_capacity) { | 1525 HValue* new_capacity) { |
1589 Zone* zone = this->zone(); | |
1590 HValue* context = environment()->LookupContext(); | 1526 HValue* context = environment()->LookupContext(); |
1591 | 1527 |
1592 BuildNewSpaceArrayCheck(new_capacity, kind); | 1528 BuildNewSpaceArrayCheck(new_capacity, kind); |
1593 | 1529 |
1594 HValue* new_elements = | 1530 HValue* new_elements = |
1595 BuildAllocateAndInitializeElements(context, kind, new_capacity); | 1531 BuildAllocateAndInitializeElements(context, kind, new_capacity); |
1596 | 1532 |
1597 BuildCopyElements(context, elements, kind, | 1533 BuildCopyElements(context, elements, kind, |
1598 new_elements, kind, | 1534 new_elements, kind, |
1599 length, new_capacity); | 1535 length, new_capacity); |
1600 | 1536 |
1601 Factory* factory = isolate()->factory(); | 1537 AddStore(object, HObjectAccess::ForElementsPointer(), new_elements); |
1602 HInstruction* elements_store = AddInstruction(new(zone) HStoreNamedField( | |
1603 object, | |
1604 factory->elements_field_string(), | |
1605 new_elements, true, Representation::Tagged(), | |
1606 JSArray::kElementsOffset)); | |
1607 elements_store->SetGVNFlag(kChangesElementsPointer); | |
1608 | 1538 |
1609 return new_elements; | 1539 return new_elements; |
1610 } | 1540 } |
1611 | 1541 |
1612 | 1542 |
1613 void HGraphBuilder::BuildFillElementsWithHole(HValue* context, | 1543 void HGraphBuilder::BuildFillElementsWithHole(HValue* context, |
1614 HValue* elements, | 1544 HValue* elements, |
1615 ElementsKind elements_kind, | 1545 ElementsKind elements_kind, |
1616 HValue* from, | 1546 HValue* from, |
1617 HValue* to) { | 1547 HValue* to) { |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1702 } | 1632 } |
1703 } | 1633 } |
1704 | 1634 |
1705 | 1635 |
1706 HValue* HGraphBuilder::BuildCloneShallowArray(HContext* context, | 1636 HValue* HGraphBuilder::BuildCloneShallowArray(HContext* context, |
1707 HValue* boilerplate, | 1637 HValue* boilerplate, |
1708 AllocationSiteMode mode, | 1638 AllocationSiteMode mode, |
1709 ElementsKind kind, | 1639 ElementsKind kind, |
1710 int length) { | 1640 int length) { |
1711 Zone* zone = this->zone(); | 1641 Zone* zone = this->zone(); |
1712 Factory* factory = isolate()->factory(); | |
1713 | 1642 |
1714 NoObservableSideEffectsScope no_effects(this); | 1643 NoObservableSideEffectsScope no_effects(this); |
1715 | 1644 |
1716 // All sizes here are multiples of kPointerSize. | 1645 // All sizes here are multiples of kPointerSize. |
1717 int size = JSArray::kSize; | 1646 int size = JSArray::kSize; |
1718 if (mode == TRACK_ALLOCATION_SITE) { | 1647 if (mode == TRACK_ALLOCATION_SITE) { |
1719 size += AllocationSiteInfo::kSize; | 1648 size += AllocationSiteInfo::kSize; |
1720 } | 1649 } |
1721 int elems_offset = size; | 1650 int elems_offset = size; |
1722 if (length > 0) { | 1651 if (length > 0) { |
1723 size += IsFastDoubleElementsKind(kind) | 1652 size += IsFastDoubleElementsKind(kind) |
1724 ? FixedDoubleArray::SizeFor(length) | 1653 ? FixedDoubleArray::SizeFor(length) |
1725 : FixedArray::SizeFor(length); | 1654 : FixedArray::SizeFor(length); |
1726 } | 1655 } |
1727 | 1656 |
1728 HAllocate::Flags allocate_flags = HAllocate::DefaultFlags(kind); | 1657 HAllocate::Flags allocate_flags = HAllocate::DefaultFlags(kind); |
1729 // Allocate both the JS array and the elements array in one big | 1658 // Allocate both the JS array and the elements array in one big |
1730 // allocation. This avoids multiple limit checks. | 1659 // allocation. This avoids multiple limit checks. |
1731 HValue* size_in_bytes = | 1660 HValue* size_in_bytes = |
1732 AddInstruction(new(zone) HConstant(size, Representation::Integer32())); | 1661 AddInstruction(new(zone) HConstant(size, Representation::Integer32())); |
1733 HInstruction* object = | 1662 HInstruction* object = |
1734 AddInstruction(new(zone) HAllocate(context, | 1663 AddInstruction(new(zone) HAllocate(context, |
1735 size_in_bytes, | 1664 size_in_bytes, |
1736 HType::JSObject(), | 1665 HType::JSObject(), |
1737 allocate_flags)); | 1666 allocate_flags)); |
1738 | 1667 |
1739 // Copy the JS array part. | 1668 // Copy the JS array part. |
1740 for (int i = 0; i < JSArray::kSize; i += kPointerSize) { | 1669 for (int i = 0; i < JSArray::kSize; i += kPointerSize) { |
1741 if ((i != JSArray::kElementsOffset) || (length == 0)) { | 1670 if ((i != JSArray::kElementsOffset) || (length == 0)) { |
1742 HInstruction* value = AddInstruction(new(zone) HLoadNamedField( | 1671 HObjectAccess access = HObjectAccess::ForJSArrayOffset(i); |
1743 boilerplate, true, Representation::Tagged(), i)); | 1672 AddStore(object, access, AddLoad(boilerplate, access)); |
1744 if (i != JSArray::kMapOffset) { | |
1745 AddInstruction(new(zone) HStoreNamedField(object, | |
1746 factory->empty_string(), | |
1747 value, true, | |
1748 Representation::Tagged(), i)); | |
1749 } else { | |
1750 BuildStoreMap(object, value); | |
1751 } | |
1752 } | 1673 } |
1753 } | 1674 } |
1754 | 1675 |
1755 // Create an allocation site info if requested. | 1676 // Create an allocation site info if requested. |
1756 if (mode == TRACK_ALLOCATION_SITE) { | 1677 if (mode == TRACK_ALLOCATION_SITE) { |
1757 BuildCreateAllocationSiteInfo(object, JSArray::kSize, boilerplate); | 1678 BuildCreateAllocationSiteInfo(object, JSArray::kSize, boilerplate); |
1758 } | 1679 } |
1759 | 1680 |
1760 if (length > 0) { | 1681 if (length > 0) { |
1761 // Get hold of the elements array of the boilerplate and setup the | 1682 // Get hold of the elements array of the boilerplate and setup the |
1762 // elements pointer in the resulting object. | 1683 // elements pointer in the resulting object. |
1763 HValue* boilerplate_elements = AddLoadElements(boilerplate); | 1684 HValue* boilerplate_elements = AddLoadElements(boilerplate); |
1764 HValue* object_elements = | 1685 HValue* object_elements = |
1765 AddInstruction(new(zone) HInnerAllocatedObject(object, elems_offset)); | 1686 AddInstruction(new(zone) HInnerAllocatedObject(object, elems_offset)); |
1766 AddInstruction(new(zone) HStoreNamedField(object, | 1687 AddStore(object, HObjectAccess::ForElementsPointer(), object_elements); |
1767 factory->elements_field_string(), | |
1768 object_elements, true, | |
1769 Representation::Tagged(), | |
1770 JSObject::kElementsOffset)); | |
1771 | 1688 |
1772 // Copy the elements array header. | 1689 // Copy the elements array header. |
1773 for (int i = 0; i < FixedArrayBase::kHeaderSize; i += kPointerSize) { | 1690 for (int i = 0; i < FixedArrayBase::kHeaderSize; i += kPointerSize) { |
1774 HInstruction* value = | 1691 HObjectAccess access = HObjectAccess::ForFixedArrayHeader(i); |
1775 AddInstruction(new(zone) HLoadNamedField( | 1692 AddStore(object_elements, access, AddLoad(boilerplate_elements, access)); |
1776 boilerplate_elements, true, Representation::Tagged(), i)); | |
1777 AddInstruction(new(zone) HStoreNamedField(object_elements, | |
1778 factory->empty_string(), | |
1779 value, true, | |
1780 Representation::Tagged(), i)); | |
1781 } | 1693 } |
1782 | 1694 |
1783 // Copy the elements array contents. | 1695 // Copy the elements array contents. |
1784 // TODO(mstarzinger): Teach HGraphBuilder::BuildCopyElements to unfold | 1696 // TODO(mstarzinger): Teach HGraphBuilder::BuildCopyElements to unfold |
1785 // copying loops with constant length up to a given boundary and use this | 1697 // copying loops with constant length up to a given boundary and use this |
1786 // helper here instead. | 1698 // helper here instead. |
1787 for (int i = 0; i < length; i++) { | 1699 for (int i = 0; i < length; i++) { |
1788 HValue* key_constant = | 1700 HValue* key_constant = |
1789 AddInstruction(new(zone) HConstant(i, Representation::Integer32())); | 1701 AddInstruction(new(zone) HConstant(i, Representation::Integer32())); |
1790 HInstruction* value = | 1702 HInstruction* value = |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1850 } | 1762 } |
1851 | 1763 |
1852 | 1764 |
1853 HValue* HGraphBuilder::BuildCreateAllocationSiteInfo(HValue* previous_object, | 1765 HValue* HGraphBuilder::BuildCreateAllocationSiteInfo(HValue* previous_object, |
1854 int previous_object_size, | 1766 int previous_object_size, |
1855 HValue* payload) { | 1767 HValue* payload) { |
1856 HInnerAllocatedObject* alloc_site = new(zone()) | 1768 HInnerAllocatedObject* alloc_site = new(zone()) |
1857 HInnerAllocatedObject(previous_object, previous_object_size); | 1769 HInnerAllocatedObject(previous_object, previous_object_size); |
1858 AddInstruction(alloc_site); | 1770 AddInstruction(alloc_site); |
1859 Handle<Map> alloc_site_map(isolate()->heap()->allocation_site_info_map()); | 1771 Handle<Map> alloc_site_map(isolate()->heap()->allocation_site_info_map()); |
1860 BuildStoreMap(alloc_site, alloc_site_map); | 1772 AddStoreMapConstant(alloc_site, alloc_site_map); |
1861 AddInstruction(new(zone()) HStoreNamedField(alloc_site, | 1773 HObjectAccess access = HObjectAccess::ForAllocationSitePayload(); |
1862 isolate()->factory()->payload_string(), | 1774 AddStore(alloc_site, access, payload); |
1863 payload, | |
1864 true, | |
1865 Representation::Tagged(), | |
1866 AllocationSiteInfo::kPayloadOffset)); | |
1867 return alloc_site; | 1775 return alloc_site; |
1868 } | 1776 } |
1869 | 1777 |
1870 | 1778 |
1871 HInstruction* HGraphBuilder::BuildGetNativeContext(HValue* context) { | 1779 HInstruction* HGraphBuilder::BuildGetNativeContext(HValue* context) { |
| 1780 // Get the global context, then the native context |
1872 HInstruction* global_object = AddInstruction(new(zone()) | 1781 HInstruction* global_object = AddInstruction(new(zone()) |
1873 HGlobalObject(context)); | 1782 HGlobalObject(context)); |
1874 HInstruction* native_context = AddInstruction(new(zone()) | 1783 HObjectAccess access = HObjectAccess::ForJSObjectOffset( |
1875 HLoadNamedField(global_object, true, Representation::Tagged(), | 1784 GlobalObject::kNativeContextOffset); |
1876 GlobalObject::kNativeContextOffset)); | 1785 return AddLoad(global_object, access); |
1877 return native_context; | |
1878 } | 1786 } |
1879 | 1787 |
1880 | 1788 |
1881 HInstruction* HGraphBuilder::BuildGetArrayFunction(HValue* context) { | 1789 HInstruction* HGraphBuilder::BuildGetArrayFunction(HValue* context) { |
1882 HInstruction* native_context = BuildGetNativeContext(context); | 1790 HInstruction* native_context = BuildGetNativeContext(context); |
1883 int offset = Context::kHeaderSize + | 1791 HInstruction* index = AddInstruction(new(zone()) |
1884 kPointerSize * Context::ARRAY_FUNCTION_INDEX; | 1792 HConstant(Context::ARRAY_FUNCTION_INDEX, Representation::Integer32())); |
1885 HInstruction* array_function = AddInstruction(new(zone()) | 1793 |
1886 HLoadNamedField(native_context, true, Representation::Tagged(), offset)); | 1794 return AddInstruction(new (zone()) |
1887 return array_function; | 1795 HLoadKeyed(native_context, index, NULL, FAST_ELEMENTS)); |
1888 } | 1796 } |
1889 | 1797 |
1890 | 1798 |
1891 HGraphBuilder::JSArrayBuilder::JSArrayBuilder(HGraphBuilder* builder, | 1799 HGraphBuilder::JSArrayBuilder::JSArrayBuilder(HGraphBuilder* builder, |
1892 ElementsKind kind, | 1800 ElementsKind kind, |
1893 HValue* allocation_site_payload, | 1801 HValue* allocation_site_payload, |
1894 AllocationSiteMode mode) : | 1802 AllocationSiteMode mode) : |
1895 builder_(builder), | 1803 builder_(builder), |
1896 kind_(kind), | 1804 kind_(kind), |
1897 allocation_site_payload_(allocation_site_payload) { | 1805 allocation_site_payload_(allocation_site_payload) { |
1898 if (mode == DONT_TRACK_ALLOCATION_SITE) { | 1806 if (mode == DONT_TRACK_ALLOCATION_SITE) { |
1899 mode_ = mode; | 1807 mode_ = mode; |
1900 } else { | 1808 } else { |
1901 mode_ = AllocationSiteInfo::GetMode(kind); | 1809 mode_ = AllocationSiteInfo::GetMode(kind); |
1902 } | 1810 } |
1903 } | 1811 } |
1904 | 1812 |
1905 | 1813 |
1906 HValue* HGraphBuilder::JSArrayBuilder::EmitMapCode(HValue* context) { | 1814 HValue* HGraphBuilder::JSArrayBuilder::EmitMapCode(HValue* context) { |
1907 HInstruction* native_context = builder()->BuildGetNativeContext(context); | 1815 HInstruction* native_context = builder()->BuildGetNativeContext(context); |
1908 int offset = Context::kHeaderSize + | 1816 |
1909 kPointerSize * Context::JS_ARRAY_MAPS_INDEX; | 1817 HInstruction* index = builder()->AddInstruction(new(zone()) |
1910 HInstruction* map_array = AddInstruction(new(zone()) | 1818 HConstant(Context::JS_ARRAY_MAPS_INDEX, Representation::Integer32())); |
1911 HLoadNamedField(native_context, true, Representation::Tagged(), offset)); | 1819 |
1912 offset = kind_ * kPointerSize + FixedArrayBase::kHeaderSize; | 1820 HInstruction* map_array = builder()->AddInstruction(new(zone()) |
1913 return AddInstruction(new(zone()) HLoadNamedField( | 1821 HLoadKeyed(native_context, index, NULL, FAST_ELEMENTS)); |
1914 map_array, true, Representation::Tagged(), offset)); | 1822 |
| 1823 HInstruction* kind_index = builder()->AddInstruction(new(zone()) |
| 1824 HConstant(kind_, Representation::Integer32())); |
| 1825 |
| 1826 return builder()->AddInstruction(new(zone()) |
| 1827 HLoadKeyed(map_array, kind_index, NULL, FAST_ELEMENTS)); |
1915 } | 1828 } |
1916 | 1829 |
1917 | 1830 |
1918 HValue* HGraphBuilder::JSArrayBuilder::EstablishAllocationSize( | 1831 HValue* HGraphBuilder::JSArrayBuilder::EstablishAllocationSize( |
1919 HValue* length_node) { | 1832 HValue* length_node) { |
1920 HValue* context = builder()->environment()->LookupContext(); | 1833 HValue* context = builder()->environment()->LookupContext(); |
1921 ASSERT(length_node != NULL); | 1834 ASSERT(length_node != NULL); |
1922 | 1835 |
1923 int base_size = JSArray::kSize; | 1836 int base_size = JSArray::kSize; |
1924 if (mode_ == TRACK_ALLOCATION_SITE) { | 1837 if (mode_ == TRACK_ALLOCATION_SITE) { |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2013 | 1926 |
2014 if (fill_with_hole) { | 1927 if (fill_with_hole) { |
2015 builder()->BuildFillElementsWithHole(context, elements_location_, kind_, | 1928 builder()->BuildFillElementsWithHole(context, elements_location_, kind_, |
2016 graph()->GetConstant0(), capacity); | 1929 graph()->GetConstant0(), capacity); |
2017 } | 1930 } |
2018 | 1931 |
2019 return new_object; | 1932 return new_object; |
2020 } | 1933 } |
2021 | 1934 |
2022 | 1935 |
| 1936 HStoreNamedField* HGraphBuilder::AddStore(HValue *object, |
| 1937 HObjectAccess access, |
| 1938 HValue *val, |
| 1939 Representation representation) { |
| 1940 HStoreNamedField *instr = new(zone()) |
| 1941 HStoreNamedField(object, access, val, representation); |
| 1942 AddInstruction(instr); |
| 1943 return instr; |
| 1944 } |
| 1945 |
| 1946 |
| 1947 HLoadNamedField* HGraphBuilder::AddLoad(HValue *object, |
| 1948 HObjectAccess access, |
| 1949 HValue *typecheck, |
| 1950 Representation representation) { |
| 1951 HLoadNamedField *instr = |
| 1952 new(zone()) HLoadNamedField(object, access, typecheck, representation); |
| 1953 AddInstruction(instr); |
| 1954 return instr; |
| 1955 } |
| 1956 |
| 1957 |
| 1958 HStoreNamedField* HGraphBuilder::AddStoreMapConstant(HValue *object, |
| 1959 Handle<Map> map) { |
| 1960 HValue* constant = |
| 1961 AddInstruction(new(zone()) HConstant(map, Representation::Tagged())); |
| 1962 HStoreNamedField *instr = |
| 1963 new(zone()) HStoreNamedField(object, HObjectAccess::ForMap(), constant); |
| 1964 AddInstruction(instr); |
| 1965 return instr; |
| 1966 } |
| 1967 |
| 1968 |
2023 HOptimizedGraphBuilder::HOptimizedGraphBuilder(CompilationInfo* info, | 1969 HOptimizedGraphBuilder::HOptimizedGraphBuilder(CompilationInfo* info, |
2024 TypeFeedbackOracle* oracle) | 1970 TypeFeedbackOracle* oracle) |
2025 : HGraphBuilder(info), | 1971 : HGraphBuilder(info), |
2026 function_state_(NULL), | 1972 function_state_(NULL), |
2027 initial_function_state_(this, info, oracle, NORMAL_RETURN), | 1973 initial_function_state_(this, info, oracle, NORMAL_RETURN), |
2028 ast_context_(NULL), | 1974 ast_context_(NULL), |
2029 break_scope_(NULL), | 1975 break_scope_(NULL), |
2030 inlined_count_(0), | 1976 inlined_count_(0), |
2031 globals_(10, info->zone()), | 1977 globals_(10, info->zone()), |
2032 inline_bailout_(false) { | 1978 inline_bailout_(false) { |
(...skipping 4346 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6379 ASSERT(current_block() != NULL); | 6325 ASSERT(current_block() != NULL); |
6380 ASSERT(current_block()->HasPredecessor()); | 6326 ASSERT(current_block()->HasPredecessor()); |
6381 return Bailout("DebuggerStatement"); | 6327 return Bailout("DebuggerStatement"); |
6382 } | 6328 } |
6383 | 6329 |
6384 | 6330 |
6385 static Handle<SharedFunctionInfo> SearchSharedFunctionInfo( | 6331 static Handle<SharedFunctionInfo> SearchSharedFunctionInfo( |
6386 Code* unoptimized_code, FunctionLiteral* expr) { | 6332 Code* unoptimized_code, FunctionLiteral* expr) { |
6387 int start_position = expr->start_position(); | 6333 int start_position = expr->start_position(); |
6388 RelocIterator it(unoptimized_code); | 6334 RelocIterator it(unoptimized_code); |
6389 for (;!it.done(); it.next()) { | 6335 for (; !it.done(); it.next()) { |
6390 RelocInfo* rinfo = it.rinfo(); | 6336 RelocInfo* rinfo = it.rinfo(); |
6391 if (rinfo->rmode() != RelocInfo::EMBEDDED_OBJECT) continue; | 6337 if (rinfo->rmode() != RelocInfo::EMBEDDED_OBJECT) continue; |
6392 Object* obj = rinfo->target_object(); | 6338 Object* obj = rinfo->target_object(); |
6393 if (obj->IsSharedFunctionInfo()) { | 6339 if (obj->IsSharedFunctionInfo()) { |
6394 SharedFunctionInfo* shared = SharedFunctionInfo::cast(obj); | 6340 SharedFunctionInfo* shared = SharedFunctionInfo::cast(obj); |
6395 if (shared->start_position() == start_position) { | 6341 if (shared->start_position() == start_position) { |
6396 return Handle<SharedFunctionInfo>(shared); | 6342 return Handle<SharedFunctionInfo>(shared); |
6397 } | 6343 } |
6398 } | 6344 } |
6399 } | 6345 } |
(...skipping 655 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7055 if (!is_store) return false; | 7001 if (!is_store) return false; |
7056 | 7002 |
7057 // 2nd chance: A store into a non-existent field can still be inlined if we | 7003 // 2nd chance: A store into a non-existent field can still be inlined if we |
7058 // have a matching transition and some room left in the object. | 7004 // have a matching transition and some room left in the object. |
7059 type->LookupTransition(NULL, *name, lookup); | 7005 type->LookupTransition(NULL, *name, lookup); |
7060 return lookup->IsTransitionToField(*type) && | 7006 return lookup->IsTransitionToField(*type) && |
7061 (type->unused_property_fields() > 0); | 7007 (type->unused_property_fields() > 0); |
7062 } | 7008 } |
7063 | 7009 |
7064 | 7010 |
7065 static int ComputeLoadStoreFieldIndex(Handle<Map> type, | |
7066 LookupResult* lookup) { | |
7067 ASSERT(lookup->IsField() || lookup->IsTransitionToField(*type)); | |
7068 if (lookup->IsField()) { | |
7069 return lookup->GetLocalFieldIndexFromMap(*type); | |
7070 } else { | |
7071 Map* transition = lookup->GetTransitionMapFromMap(*type); | |
7072 int descriptor = transition->LastAdded(); | |
7073 int index = transition->instance_descriptors()->GetFieldIndex(descriptor); | |
7074 return index - type->inobject_properties(); | |
7075 } | |
7076 } | |
7077 | |
7078 | |
7079 static Representation ComputeLoadStoreRepresentation(Handle<Map> type, | 7011 static Representation ComputeLoadStoreRepresentation(Handle<Map> type, |
7080 LookupResult* lookup) { | 7012 LookupResult* lookup) { |
7081 if (lookup->IsField()) { | 7013 if (lookup->IsField()) { |
7082 return lookup->representation(); | 7014 return lookup->representation(); |
7083 } else { | 7015 } else { |
7084 Map* transition = lookup->GetTransitionMapFromMap(*type); | 7016 Map* transition = lookup->GetTransitionMapFromMap(*type); |
7085 int descriptor = transition->LastAdded(); | 7017 int descriptor = transition->LastAdded(); |
7086 PropertyDetails details = | 7018 PropertyDetails details = |
7087 transition->instance_descriptors()->GetDetails(descriptor); | 7019 transition->instance_descriptors()->GetDetails(descriptor); |
7088 return details.representation(); | 7020 return details.representation(); |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7133 } | 7065 } |
7134 ASSERT(proto->GetPrototype(isolate())->IsNull()); | 7066 ASSERT(proto->GetPrototype(isolate())->IsNull()); |
7135 } | 7067 } |
7136 ASSERT(proto->IsJSObject()); | 7068 ASSERT(proto->IsJSObject()); |
7137 AddInstruction(new(zone()) HCheckPrototypeMaps( | 7069 AddInstruction(new(zone()) HCheckPrototypeMaps( |
7138 Handle<JSObject>(JSObject::cast(map->prototype())), | 7070 Handle<JSObject>(JSObject::cast(map->prototype())), |
7139 Handle<JSObject>(JSObject::cast(proto)), | 7071 Handle<JSObject>(JSObject::cast(proto)), |
7140 zone())); | 7072 zone())); |
7141 } | 7073 } |
7142 | 7074 |
7143 int index = ComputeLoadStoreFieldIndex(map, lookup); | 7075 HObjectAccess field_access = HObjectAccess::ForField(map, lookup, name); |
7144 bool is_in_object = index < 0; | |
7145 Representation representation = ComputeLoadStoreRepresentation(map, lookup); | 7076 Representation representation = ComputeLoadStoreRepresentation(map, lookup); |
7146 int offset = index * kPointerSize; | |
7147 if (index < 0) { | |
7148 // Negative property indices are in-object properties, indexed | |
7149 // from the end of the fixed part of the object. | |
7150 offset += map->instance_size(); | |
7151 } else { | |
7152 offset += FixedArray::kHeaderSize; | |
7153 } | |
7154 bool transition_to_field = lookup->IsTransitionToField(*map); | 7077 bool transition_to_field = lookup->IsTransitionToField(*map); |
| 7078 |
| 7079 HStoreNamedField *instr; |
7155 if (FLAG_track_double_fields && representation.IsDouble()) { | 7080 if (FLAG_track_double_fields && representation.IsDouble()) { |
7156 if (transition_to_field) { | 7081 if (transition_to_field) { |
| 7082 // The store requires a mutable HeapNumber to be allocated. |
7157 NoObservableSideEffectsScope no_side_effects(this); | 7083 NoObservableSideEffectsScope no_side_effects(this); |
7158 HInstruction* heap_number_size = AddInstruction(new(zone()) HConstant( | 7084 HInstruction* heap_number_size = AddInstruction(new(zone()) HConstant( |
7159 HeapNumber::kSize, Representation::Integer32())); | 7085 HeapNumber::kSize, Representation::Integer32())); |
7160 HInstruction* double_box = AddInstruction(new(zone()) HAllocate( | 7086 HInstruction* double_box = AddInstruction(new(zone()) HAllocate( |
7161 environment()->LookupContext(), heap_number_size, | 7087 environment()->LookupContext(), heap_number_size, |
7162 HType::HeapNumber(), HAllocate::CAN_ALLOCATE_IN_NEW_SPACE)); | 7088 HType::HeapNumber(), HAllocate::CAN_ALLOCATE_IN_NEW_SPACE)); |
7163 BuildStoreMap(double_box, isolate()->factory()->heap_number_map()); | 7089 AddStoreMapConstant(double_box, isolate()->factory()->heap_number_map()); |
7164 AddInstruction(new(zone()) HStoreNamedField( | 7090 AddStore(double_box, HObjectAccess::ForHeapNumberValue(), |
7165 double_box, name, value, true, | 7091 value, Representation::Double()); |
7166 Representation::Double(), HeapNumber::kValueOffset)); | 7092 instr = new(zone()) HStoreNamedField(object, field_access, double_box); |
7167 value = double_box; | |
7168 representation = Representation::Tagged(); | |
7169 } else { | 7093 } else { |
7170 HInstruction* double_box = AddInstruction(new(zone()) HLoadNamedField( | 7094 // Already holds a HeapNumber; load the box and write its value field. |
7171 object, is_in_object, Representation::Tagged(), offset)); | 7095 HInstruction* double_box = AddLoad(object, field_access); |
7172 double_box->set_type(HType::HeapNumber()); | 7096 double_box->set_type(HType::HeapNumber()); |
7173 return new(zone()) HStoreNamedField( | 7097 instr = new(zone()) HStoreNamedField(double_box, |
7174 double_box, name, value, true, | 7098 HObjectAccess::ForHeapNumberValue(), value, Representation::Double()); |
7175 Representation::Double(), HeapNumber::kValueOffset); | |
7176 } | 7099 } |
| 7100 } else { |
| 7101 // This is a non-double store. |
| 7102 instr = new(zone()) HStoreNamedField( |
| 7103 object, field_access, value, representation); |
7177 } | 7104 } |
7178 HStoreNamedField* instr = new(zone()) HStoreNamedField( | 7105 |
7179 object, name, value, is_in_object, representation, offset); | |
7180 if (transition_to_field) { | 7106 if (transition_to_field) { |
7181 Handle<Map> transition(lookup->GetTransitionMapFromMap(*map)); | 7107 Handle<Map> transition(lookup->GetTransitionMapFromMap(*map)); |
7182 instr->set_transition(transition); | 7108 instr->set_transition(transition); |
7183 // TODO(fschneider): Record the new map type of the object in the IR to | 7109 // TODO(fschneider): Record the new map type of the object in the IR to |
7184 // enable elimination of redundant checks after the transition store. | 7110 // enable elimination of redundant checks after the transition store. |
7185 instr->SetGVNFlag(kChangesMaps); | 7111 instr->SetGVNFlag(kChangesMaps); |
7186 } | 7112 } |
7187 return instr; | 7113 return instr; |
7188 } | 7114 } |
7189 | 7115 |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7239 Handle<String> name) { | 7165 Handle<String> name) { |
7240 if (!name->Equals(isolate()->heap()->length_string())) return false; | 7166 if (!name->Equals(isolate()->heap()->length_string())) return false; |
7241 | 7167 |
7242 for (int i = 0; i < types->length(); i++) { | 7168 for (int i = 0; i < types->length(); i++) { |
7243 if (types->at(i)->instance_type() != JS_ARRAY_TYPE) return false; | 7169 if (types->at(i)->instance_type() != JS_ARRAY_TYPE) return false; |
7244 } | 7170 } |
7245 | 7171 |
7246 BuildCheckNonSmi(object); | 7172 BuildCheckNonSmi(object); |
7247 | 7173 |
7248 HInstruction* typecheck = | 7174 HInstruction* typecheck = |
7249 AddInstruction(HCheckMaps::New(object, types, zone())); | 7175 AddInstruction(HCheckMaps::New(object, types, zone())); |
7250 HInstruction* instr = | 7176 HInstruction* instr = new(zone()) |
7251 HLoadNamedField::NewArrayLength(zone(), object, typecheck); | 7177 HLoadNamedField(object, HObjectAccess::ForArrayLength(), typecheck); |
| 7178 |
7252 instr->set_position(expr->position()); | 7179 instr->set_position(expr->position()); |
7253 ast_context()->ReturnInstruction(instr, expr->id()); | 7180 ast_context()->ReturnInstruction(instr, expr->id()); |
7254 return true; | 7181 return true; |
7255 } | 7182 } |
7256 | 7183 |
7257 | 7184 |
7258 void HOptimizedGraphBuilder::HandlePolymorphicLoadNamedField(Property* expr, | 7185 void HOptimizedGraphBuilder::HandlePolymorphicLoadNamedField(Property* expr, |
7259 HValue* object, | 7186 HValue* object, |
7260 SmallMapList* types, | 7187 SmallMapList* types, |
7261 Handle<String> name) { | 7188 Handle<String> name) { |
7262 | 7189 |
7263 if (HandlePolymorphicArrayLengthLoad(expr, object, types, name)) | 7190 if (HandlePolymorphicArrayLengthLoad(expr, object, types, name)) |
7264 return; | 7191 return; |
7265 | 7192 |
7266 BuildCheckNonSmi(object); | 7193 BuildCheckNonSmi(object); |
7267 | 7194 |
7268 // Use monomorphic load if property lookup results in the same field index | 7195 // Use monomorphic load if property lookup results in the same field index |
7269 // for all maps. Requires special map check on the set of all handled maps. | 7196 // for all maps. Requires special map check on the set of all handled maps. |
7270 HInstruction* instr = NULL; | 7197 HInstruction* instr = NULL; |
7271 if (types->length() > 0 && types->length() <= kMaxLoadPolymorphism) { | 7198 LookupResult lookup(isolate()); |
7272 LookupResult lookup(isolate()); | 7199 int count; |
7273 int previous_field_offset = 0; | 7200 Representation representation = Representation::None(); |
7274 bool previous_field_is_in_object = false; | 7201 HObjectAccess access = HObjectAccess::ForMap(); // initial value unused. |
7275 Representation representation = Representation::None(); | 7202 for (count = 0; |
7276 int count; | 7203 count < types->length() && count < kMaxLoadPolymorphism; |
7277 for (count = 0; count < types->length(); ++count) { | 7204 ++count) { |
7278 Handle<Map> map = types->at(count); | 7205 Handle<Map> map = types->at(count); |
7279 if (!ComputeLoadStoreField(map, name, &lookup, false)) break; | 7206 if (!ComputeLoadStoreField(map, name, &lookup, false)) break; |
7280 | 7207 |
7281 int index = ComputeLoadStoreFieldIndex(map, &lookup); | 7208 HObjectAccess new_access = HObjectAccess::ForField(map, &lookup, name); |
7282 Representation new_representation = | 7209 Representation new_representation = |
7283 ComputeLoadStoreRepresentation(map, &lookup); | 7210 ComputeLoadStoreRepresentation(map, &lookup); |
7284 bool is_in_object = index < 0; | |
7285 int offset = index * kPointerSize; | |
7286 | 7211 |
7287 if (index < 0) { | 7212 if (count == 0) { |
7288 // Negative property indices are in-object properties, indexed | 7213 // First time through the loop; set access and representation. |
7289 // from the end of the fixed part of the object. | 7214 access = new_access; |
7290 offset += map->instance_size(); | 7215 representation = new_representation; |
7291 } else { | 7216 } else if (!representation.IsCompatibleForLoad(new_representation)) { |
7292 offset += FixedArray::kHeaderSize; | 7217 // Representations did not match. |
7293 } | 7218 break; |
7294 | 7219 } else if (access.offset() != new_access.offset()) { |
7295 if (count == 0) { | 7220 // Offsets did not match. |
7296 previous_field_offset = offset; | 7221 break; |
7297 previous_field_is_in_object = is_in_object; | 7222 } else if (access.IsInobject() != new_access.IsInobject()) { |
7298 representation = new_representation; | 7223 // In-objectness did not match. |
7299 } else if (offset != previous_field_offset || | 7224 break; |
7300 is_in_object != previous_field_is_in_object || | |
7301 (FLAG_track_fields && | |
7302 !representation.IsCompatibleForLoad(new_representation))) { | |
7303 break; | |
7304 } | |
7305 | |
7306 representation = representation.generalize(new_representation); | |
7307 } | |
7308 | |
7309 if (count == types->length()) { | |
7310 AddInstruction(HCheckMaps::New(object, types, zone())); | |
7311 instr = DoBuildLoadNamedField( | |
7312 object, previous_field_is_in_object, | |
7313 representation, previous_field_offset); | |
7314 } | 7225 } |
7315 } | 7226 } |
7316 | 7227 |
7317 if (instr == NULL) { | 7228 if (count == types->length()) { |
| 7229 // Everything matched; can use monomorphic load. |
| 7230 AddInstruction(HCheckMaps::New(object, types, zone())); |
| 7231 instr = BuildLoadNamedField(object, access, representation); |
| 7232 } else { |
| 7233 // Something did not match; must use a polymorphic load. |
7318 HValue* context = environment()->LookupContext(); | 7234 HValue* context = environment()->LookupContext(); |
7319 instr = new(zone()) HLoadNamedFieldPolymorphic( | 7235 instr = new(zone()) HLoadNamedFieldPolymorphic( |
7320 context, object, types, name, zone()); | 7236 context, object, types, name, zone()); |
7321 } | 7237 } |
7322 | 7238 |
7323 instr->set_position(expr->position()); | 7239 instr->set_position(expr->position()); |
7324 return ast_context()->ReturnInstruction(instr, expr->id()); | 7240 return ast_context()->ReturnInstruction(instr, expr->id()); |
7325 } | 7241 } |
7326 | 7242 |
7327 | 7243 |
(...skipping 536 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7864 HValue* value = environment()->Pop(); | 7780 HValue* value = environment()->Pop(); |
7865 HThrow* instr = new(zone()) HThrow(context, value); | 7781 HThrow* instr = new(zone()) HThrow(context, value); |
7866 instr->set_position(expr->position()); | 7782 instr->set_position(expr->position()); |
7867 AddInstruction(instr); | 7783 AddInstruction(instr); |
7868 AddSimulate(expr->id()); | 7784 AddSimulate(expr->id()); |
7869 current_block()->FinishExit(new(zone()) HAbnormalExit); | 7785 current_block()->FinishExit(new(zone()) HAbnormalExit); |
7870 set_current_block(NULL); | 7786 set_current_block(NULL); |
7871 } | 7787 } |
7872 | 7788 |
7873 | 7789 |
7874 HLoadNamedField* HOptimizedGraphBuilder::BuildLoadNamedField( | 7790 HLoadNamedField* HGraphBuilder::BuildLoadNamedField( |
7875 HValue* object, | 7791 HValue* object, |
7876 Handle<Map> map, | 7792 HObjectAccess access, |
7877 LookupResult* lookup) { | 7793 Representation representation) { |
7878 int index = lookup->GetLocalFieldIndexFromMap(*map); | |
7879 // Negative property indices are in-object properties, indexed from the end of | |
7880 // the fixed part of the object. Non-negative property indices are in the | |
7881 // properties array. | |
7882 int inobject = index < 0; | |
7883 Representation representation = lookup->representation(); | |
7884 int offset = inobject | |
7885 ? index * kPointerSize + map->instance_size() | |
7886 : index * kPointerSize + FixedArray::kHeaderSize; | |
7887 return DoBuildLoadNamedField(object, inobject, representation, offset); | |
7888 } | |
7889 | |
7890 | |
7891 HLoadNamedField* HGraphBuilder::DoBuildLoadNamedField( | |
7892 HValue* object, | |
7893 bool inobject, | |
7894 Representation representation, | |
7895 int offset) { | |
7896 bool load_double = false; | 7794 bool load_double = false; |
7897 if (representation.IsDouble()) { | 7795 if (representation.IsDouble()) { |
7898 representation = Representation::Tagged(); | 7796 representation = Representation::Tagged(); |
7899 load_double = FLAG_track_double_fields; | 7797 load_double = FLAG_track_double_fields; |
7900 } | 7798 } |
7901 HLoadNamedField* field = | 7799 HLoadNamedField* field = |
7902 new(zone()) HLoadNamedField(object, inobject, representation, offset); | 7800 new(zone()) HLoadNamedField(object, access, NULL, representation); |
7903 if (load_double) { | 7801 if (load_double) { |
7904 AddInstruction(field); | 7802 AddInstruction(field); |
7905 field->set_type(HType::HeapNumber()); | 7803 field->set_type(HType::HeapNumber()); |
7906 return new(zone()) HLoadNamedField( | 7804 return new(zone()) HLoadNamedField(field, |
7907 field, true, Representation::Double(), HeapNumber::kValueOffset); | 7805 HObjectAccess::ForHeapNumberValue(), NULL, Representation::Double()); |
7908 } | 7806 } |
7909 return field; | 7807 return field; |
7910 } | 7808 } |
7911 | 7809 |
7912 | 7810 |
7913 HInstruction* HOptimizedGraphBuilder::BuildLoadNamedGeneric( | 7811 HInstruction* HOptimizedGraphBuilder::BuildLoadNamedGeneric( |
7914 HValue* object, | 7812 HValue* object, |
7915 Handle<String> name, | 7813 Handle<String> name, |
7916 Property* expr) { | 7814 Property* expr) { |
7917 if (expr->IsUninitialized()) { | 7815 if (expr->IsUninitialized()) { |
(...skipping 20 matching lines...) Expand all Loading... |
7938 Handle<String> name, | 7836 Handle<String> name, |
7939 Property* expr, | 7837 Property* expr, |
7940 Handle<Map> map) { | 7838 Handle<Map> map) { |
7941 // Handle a load from a known field. | 7839 // Handle a load from a known field. |
7942 ASSERT(!map->is_dictionary_map()); | 7840 ASSERT(!map->is_dictionary_map()); |
7943 | 7841 |
7944 // Handle access to various length properties | 7842 // Handle access to various length properties |
7945 if (name->Equals(isolate()->heap()->length_string())) { | 7843 if (name->Equals(isolate()->heap()->length_string())) { |
7946 if (map->instance_type() == JS_ARRAY_TYPE) { | 7844 if (map->instance_type() == JS_ARRAY_TYPE) { |
7947 AddCheckMapsWithTransitions(object, map); | 7845 AddCheckMapsWithTransitions(object, map); |
7948 return HLoadNamedField::NewArrayLength(zone(), object, object); | 7846 return new(zone()) HLoadNamedField(object, |
| 7847 HObjectAccess::ForArrayLength()); |
7949 } | 7848 } |
7950 } | 7849 } |
7951 | 7850 |
7952 LookupResult lookup(isolate()); | 7851 LookupResult lookup(isolate()); |
7953 map->LookupDescriptor(NULL, *name, &lookup); | 7852 map->LookupDescriptor(NULL, *name, &lookup); |
7954 if (lookup.IsField()) { | 7853 if (lookup.IsField()) { |
7955 AddCheckMap(object, map); | 7854 AddCheckMap(object, map); |
7956 return BuildLoadNamedField(object, map, &lookup); | 7855 return BuildLoadNamedField(object, |
| 7856 HObjectAccess::ForField(map, &lookup, name), |
| 7857 ComputeLoadStoreRepresentation(map, &lookup)); |
7957 } | 7858 } |
7958 | 7859 |
7959 // Handle a load of a constant known function. | 7860 // Handle a load of a constant known function. |
7960 if (lookup.IsConstantFunction()) { | 7861 if (lookup.IsConstantFunction()) { |
7961 AddCheckMap(object, map); | 7862 AddCheckMap(object, map); |
7962 Handle<JSFunction> function(lookup.GetConstantFunctionFromMap(*map)); | 7863 Handle<JSFunction> function(lookup.GetConstantFunctionFromMap(*map)); |
7963 return new(zone()) HConstant(function, Representation::Tagged()); | 7864 return new(zone()) HConstant(function, Representation::Tagged()); |
7964 } | 7865 } |
7965 | 7866 |
7966 // Handle a load from a known field somewhere in the prototype chain. | 7867 // Handle a load from a known field somewhere in the prototype chain. |
7967 LookupInPrototypes(map, name, &lookup); | 7868 LookupInPrototypes(map, name, &lookup); |
7968 if (lookup.IsField()) { | 7869 if (lookup.IsField()) { |
7969 Handle<JSObject> prototype(JSObject::cast(map->prototype())); | 7870 Handle<JSObject> prototype(JSObject::cast(map->prototype())); |
7970 Handle<JSObject> holder(lookup.holder()); | 7871 Handle<JSObject> holder(lookup.holder()); |
7971 Handle<Map> holder_map(holder->map()); | 7872 Handle<Map> holder_map(holder->map()); |
7972 AddCheckMap(object, map); | 7873 AddCheckMap(object, map); |
7973 AddInstruction( | 7874 AddInstruction( |
7974 new(zone()) HCheckPrototypeMaps(prototype, holder, zone())); | 7875 new(zone()) HCheckPrototypeMaps(prototype, holder, zone())); |
7975 HValue* holder_value = AddInstruction( | 7876 HValue* holder_value = AddInstruction(new(zone()) |
7976 new(zone()) HConstant(holder, Representation::Tagged())); | 7877 HConstant(holder, Representation::Tagged())); |
7977 return BuildLoadNamedField(holder_value, holder_map, &lookup); | 7878 return BuildLoadNamedField(holder_value, |
| 7879 HObjectAccess::ForField(holder_map, &lookup, name), |
| 7880 ComputeLoadStoreRepresentation(map, &lookup)); |
7978 } | 7881 } |
7979 | 7882 |
7980 // Handle a load of a constant function somewhere in the prototype chain. | 7883 // Handle a load of a constant function somewhere in the prototype chain. |
7981 if (lookup.IsConstantFunction()) { | 7884 if (lookup.IsConstantFunction()) { |
7982 Handle<JSObject> prototype(JSObject::cast(map->prototype())); | 7885 Handle<JSObject> prototype(JSObject::cast(map->prototype())); |
7983 Handle<JSObject> holder(lookup.holder()); | 7886 Handle<JSObject> holder(lookup.holder()); |
7984 Handle<Map> holder_map(holder->map()); | 7887 Handle<Map> holder_map(holder->map()); |
7985 AddCheckMap(object, map); | 7888 AddCheckMap(object, map); |
7986 AddInstruction(new(zone()) HCheckPrototypeMaps(prototype, holder, zone())); | 7889 AddInstruction(new(zone()) HCheckPrototypeMaps(prototype, holder, zone())); |
7987 Handle<JSFunction> function(lookup.GetConstantFunctionFromMap(*holder_map)); | 7890 Handle<JSFunction> function(lookup.GetConstantFunctionFromMap(*holder_map)); |
(...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8243 // it's a keyed property) and registered in the full codegen. | 8146 // it's a keyed property) and registered in the full codegen. |
8244 HBasicBlock* if_jsarray = graph()->CreateBasicBlock(); | 8147 HBasicBlock* if_jsarray = graph()->CreateBasicBlock(); |
8245 HBasicBlock* if_fastobject = graph()->CreateBasicBlock(); | 8148 HBasicBlock* if_fastobject = graph()->CreateBasicBlock(); |
8246 HHasInstanceTypeAndBranch* typecheck = | 8149 HHasInstanceTypeAndBranch* typecheck = |
8247 new(zone()) HHasInstanceTypeAndBranch(object, JS_ARRAY_TYPE); | 8150 new(zone()) HHasInstanceTypeAndBranch(object, JS_ARRAY_TYPE); |
8248 typecheck->SetSuccessorAt(0, if_jsarray); | 8151 typecheck->SetSuccessorAt(0, if_jsarray); |
8249 typecheck->SetSuccessorAt(1, if_fastobject); | 8152 typecheck->SetSuccessorAt(1, if_fastobject); |
8250 current_block()->Finish(typecheck); | 8153 current_block()->Finish(typecheck); |
8251 | 8154 |
8252 set_current_block(if_jsarray); | 8155 set_current_block(if_jsarray); |
8253 HInstruction* length; | 8156 HInstruction* length = AddLoad(object, HObjectAccess::ForArrayLength(), |
8254 length = AddInstruction( | 8157 typecheck, Representation::Smi()); |
8255 HLoadNamedField::NewArrayLength(zone(), object, typecheck, | 8158 length->set_type(HType::Smi()); |
8256 HType::Smi())); | 8159 |
8257 checked_key = AddBoundsCheck(key, length, ALLOW_SMI_KEY); | 8160 checked_key = AddBoundsCheck(key, length, ALLOW_SMI_KEY); |
8258 access = AddInstruction(BuildFastElementAccess( | 8161 access = AddInstruction(BuildFastElementAccess( |
8259 elements, checked_key, val, elements_kind_branch, | 8162 elements, checked_key, val, elements_kind_branch, |
8260 elements_kind, is_store, NEVER_RETURN_HOLE, STANDARD_STORE)); | 8163 elements_kind, is_store, NEVER_RETURN_HOLE, STANDARD_STORE)); |
8261 if (!is_store) { | 8164 if (!is_store) { |
8262 Push(access); | 8165 Push(access); |
8263 } | 8166 } |
8264 | 8167 |
8265 *has_side_effects |= access->HasObservableSideEffects(); | 8168 *has_side_effects |= access->HasObservableSideEffects(); |
8266 // The caller will use has_side_effects and add correct Simulate. | 8169 // The caller will use has_side_effects and add correct Simulate. |
(...skipping 2622 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10889 } | 10792 } |
10890 | 10793 |
10891 | 10794 |
10892 void HOptimizedGraphBuilder::BuildEmitDeepCopy( | 10795 void HOptimizedGraphBuilder::BuildEmitDeepCopy( |
10893 Handle<JSObject> boilerplate_object, | 10796 Handle<JSObject> boilerplate_object, |
10894 Handle<JSObject> original_boilerplate_object, | 10797 Handle<JSObject> original_boilerplate_object, |
10895 HInstruction* target, | 10798 HInstruction* target, |
10896 int* offset, | 10799 int* offset, |
10897 AllocationSiteMode mode) { | 10800 AllocationSiteMode mode) { |
10898 Zone* zone = this->zone(); | 10801 Zone* zone = this->zone(); |
10899 Factory* factory = isolate()->factory(); | |
10900 | 10802 |
10901 HInstruction* original_boilerplate = AddInstruction(new(zone) HConstant( | 10803 HInstruction* original_boilerplate = AddInstruction(new(zone) HConstant( |
10902 original_boilerplate_object, Representation::Tagged())); | 10804 original_boilerplate_object, Representation::Tagged())); |
10903 | 10805 |
10904 bool create_allocation_site_info = mode == TRACK_ALLOCATION_SITE && | 10806 bool create_allocation_site_info = mode == TRACK_ALLOCATION_SITE && |
10905 boilerplate_object->map()->CanTrackAllocationSite(); | 10807 boilerplate_object->map()->CanTrackAllocationSite(); |
10906 | 10808 |
10907 // Only elements backing stores for non-COW arrays need to be copied. | 10809 // Only elements backing stores for non-COW arrays need to be copied. |
10908 Handle<FixedArrayBase> elements(boilerplate_object->elements()); | 10810 Handle<FixedArrayBase> elements(boilerplate_object->elements()); |
10909 Handle<FixedArrayBase> original_elements( | 10811 Handle<FixedArrayBase> original_elements( |
(...skipping 28 matching lines...) Expand all Loading... |
10938 | 10840 |
10939 for (int i = 0; i < limit; i++) { | 10841 for (int i = 0; i < limit; i++) { |
10940 PropertyDetails details = descriptors->GetDetails(i); | 10842 PropertyDetails details = descriptors->GetDetails(i); |
10941 if (details.type() != FIELD) continue; | 10843 if (details.type() != FIELD) continue; |
10942 int index = descriptors->GetFieldIndex(i); | 10844 int index = descriptors->GetFieldIndex(i); |
10943 int property_offset = boilerplate_object->GetInObjectPropertyOffset(index); | 10845 int property_offset = boilerplate_object->GetInObjectPropertyOffset(index); |
10944 Handle<Name> name(descriptors->GetKey(i)); | 10846 Handle<Name> name(descriptors->GetKey(i)); |
10945 Handle<Object> value = | 10847 Handle<Object> value = |
10946 Handle<Object>(boilerplate_object->InObjectPropertyAt(index), | 10848 Handle<Object>(boilerplate_object->InObjectPropertyAt(index), |
10947 isolate()); | 10849 isolate()); |
| 10850 |
| 10851 // The access for the store depends on the type of the boilerplate. |
| 10852 HObjectAccess access = boilerplate_object->IsJSArray() ? |
| 10853 HObjectAccess::ForJSArrayOffset(property_offset) : |
| 10854 HObjectAccess::ForJSObjectOffset(property_offset); |
| 10855 |
10948 if (value->IsJSObject()) { | 10856 if (value->IsJSObject()) { |
10949 Handle<JSObject> value_object = Handle<JSObject>::cast(value); | 10857 Handle<JSObject> value_object = Handle<JSObject>::cast(value); |
10950 Handle<JSObject> original_value_object = Handle<JSObject>::cast( | 10858 Handle<JSObject> original_value_object = Handle<JSObject>::cast( |
10951 Handle<Object>(original_boilerplate_object->InObjectPropertyAt(index), | 10859 Handle<Object>(original_boilerplate_object->InObjectPropertyAt(index), |
10952 isolate())); | 10860 isolate())); |
10953 HInstruction* value_instruction = | 10861 HInstruction* value_instruction = |
10954 AddInstruction(new(zone) HInnerAllocatedObject(target, *offset)); | 10862 AddInstruction(new(zone) HInnerAllocatedObject(target, *offset)); |
10955 AddInstruction(new(zone) HStoreNamedField( | 10863 |
10956 object_properties, name, value_instruction, true, | 10864 AddStore(object_properties, access, value_instruction); |
10957 Representation::Tagged(), property_offset)); | 10865 |
10958 BuildEmitDeepCopy(value_object, original_value_object, target, | 10866 BuildEmitDeepCopy(value_object, original_value_object, target, |
10959 offset, DONT_TRACK_ALLOCATION_SITE); | 10867 offset, DONT_TRACK_ALLOCATION_SITE); |
10960 } else { | 10868 } else { |
10961 Representation representation = details.representation(); | 10869 Representation representation = details.representation(); |
10962 HInstruction* value_instruction = AddInstruction(new(zone) HConstant( | 10870 HInstruction* value_instruction = AddInstruction(new(zone) HConstant( |
10963 value, Representation::Tagged())); | 10871 value, Representation::Tagged())); |
| 10872 |
10964 if (representation.IsDouble()) { | 10873 if (representation.IsDouble()) { |
| 10874 // Allocate a HeapNumber box and store the value into it. |
10965 HInstruction* double_box = | 10875 HInstruction* double_box = |
10966 AddInstruction(new(zone) HInnerAllocatedObject(target, *offset)); | 10876 AddInstruction(new(zone) HInnerAllocatedObject(target, *offset)); |
10967 BuildStoreMap(double_box, factory->heap_number_map()); | 10877 AddStoreMapConstant(double_box, |
10968 AddInstruction(new(zone) HStoreNamedField( | 10878 isolate()->factory()->heap_number_map()); |
10969 double_box, name, value_instruction, true, | 10879 AddStore(double_box, HObjectAccess::ForHeapNumberValue(), |
10970 Representation::Double(), HeapNumber::kValueOffset)); | 10880 value_instruction, Representation::Double()); |
10971 value_instruction = double_box; | 10881 value_instruction = double_box; |
10972 *offset += HeapNumber::kSize; | 10882 *offset += HeapNumber::kSize; |
10973 } | 10883 } |
10974 AddInstruction(new(zone) HStoreNamedField( | 10884 |
10975 object_properties, name, value_instruction, true, | 10885 AddStore(object_properties, access, value_instruction); |
10976 Representation::Tagged(), property_offset)); | |
10977 } | 10886 } |
10978 } | 10887 } |
10979 | 10888 |
10980 // Build Allocation Site Info if desired | 10889 // Build Allocation Site Info if desired |
10981 if (create_allocation_site_info) { | 10890 if (create_allocation_site_info) { |
10982 BuildCreateAllocationSiteInfo(target, JSArray::kSize, original_boilerplate); | 10891 BuildCreateAllocationSiteInfo(target, JSArray::kSize, original_boilerplate); |
10983 } | 10892 } |
10984 | 10893 |
10985 if (object_elements != NULL) { | 10894 if (object_elements != NULL) { |
10986 HInstruction* boilerplate_elements = AddInstruction(new(zone) HConstant( | 10895 HInstruction* boilerplate_elements = AddInstruction(new(zone) HConstant( |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11038 | 10947 |
11039 | 10948 |
11040 HValue* HOptimizedGraphBuilder::BuildCopyObjectHeader( | 10949 HValue* HOptimizedGraphBuilder::BuildCopyObjectHeader( |
11041 Handle<JSObject> boilerplate_object, | 10950 Handle<JSObject> boilerplate_object, |
11042 HInstruction* target, | 10951 HInstruction* target, |
11043 int object_offset, | 10952 int object_offset, |
11044 int elements_offset, | 10953 int elements_offset, |
11045 int elements_size) { | 10954 int elements_size) { |
11046 ASSERT(boilerplate_object->properties()->length() == 0); | 10955 ASSERT(boilerplate_object->properties()->length() == 0); |
11047 Zone* zone = this->zone(); | 10956 Zone* zone = this->zone(); |
11048 Factory* factory = isolate()->factory(); | |
11049 HValue* result = NULL; | 10957 HValue* result = NULL; |
11050 | 10958 |
11051 HValue* object_header = | 10959 HValue* object_header = |
11052 AddInstruction(new(zone) HInnerAllocatedObject(target, object_offset)); | 10960 AddInstruction(new(zone) HInnerAllocatedObject(target, object_offset)); |
11053 Handle<Map> boilerplate_object_map(boilerplate_object->map()); | 10961 Handle<Map> boilerplate_object_map(boilerplate_object->map()); |
11054 BuildStoreMap(object_header, boilerplate_object_map); | 10962 AddStoreMapConstant(object_header, boilerplate_object_map); |
11055 | 10963 |
11056 HInstruction* elements; | 10964 HInstruction* elements; |
11057 if (elements_size == 0) { | 10965 if (elements_size == 0) { |
11058 Handle<Object> elements_field = | 10966 Handle<Object> elements_field = |
11059 Handle<Object>(boilerplate_object->elements(), isolate()); | 10967 Handle<Object>(boilerplate_object->elements(), isolate()); |
11060 elements = AddInstruction(new(zone) HConstant( | 10968 elements = AddInstruction(new(zone) HConstant( |
11061 elements_field, Representation::Tagged())); | 10969 elements_field, Representation::Tagged())); |
11062 } else { | 10970 } else { |
11063 elements = AddInstruction(new(zone) HInnerAllocatedObject( | 10971 elements = AddInstruction(new(zone) HInnerAllocatedObject( |
11064 target, elements_offset)); | 10972 target, elements_offset)); |
11065 result = elements; | 10973 result = elements; |
11066 } | 10974 } |
11067 HInstruction* elements_store = AddInstruction(new(zone) HStoreNamedField( | 10975 AddStore(object_header, HObjectAccess::ForElementsPointer(), elements); |
11068 object_header, | |
11069 factory->elements_field_string(), | |
11070 elements, | |
11071 true, Representation::Tagged(), JSObject::kElementsOffset)); | |
11072 elements_store->SetGVNFlag(kChangesElementsPointer); | |
11073 | 10976 |
11074 Handle<Object> properties_field = | 10977 Handle<Object> properties_field = |
11075 Handle<Object>(boilerplate_object->properties(), isolate()); | 10978 Handle<Object>(boilerplate_object->properties(), isolate()); |
11076 ASSERT(*properties_field == isolate()->heap()->empty_fixed_array()); | 10979 ASSERT(*properties_field == isolate()->heap()->empty_fixed_array()); |
11077 HInstruction* properties = AddInstruction(new(zone) HConstant( | 10980 HInstruction* properties = AddInstruction(new(zone) HConstant( |
11078 properties_field, Representation::None())); | 10981 properties_field, Representation::None())); |
11079 AddInstruction(new(zone) HStoreNamedField(object_header, | 10982 HObjectAccess access = HObjectAccess::ForPropertiesPointer(); |
11080 factory->empty_string(), | 10983 AddStore(object_header, access, properties); |
11081 properties, true, | |
11082 Representation::Tagged(), | |
11083 JSObject::kPropertiesOffset)); | |
11084 | 10984 |
11085 if (boilerplate_object->IsJSArray()) { | 10985 if (boilerplate_object->IsJSArray()) { |
11086 Handle<JSArray> boilerplate_array = | 10986 Handle<JSArray> boilerplate_array = |
11087 Handle<JSArray>::cast(boilerplate_object); | 10987 Handle<JSArray>::cast(boilerplate_object); |
11088 Handle<Object> length_field = | 10988 Handle<Object> length_field = |
11089 Handle<Object>(boilerplate_array->length(), isolate()); | 10989 Handle<Object>(boilerplate_array->length(), isolate()); |
11090 HInstruction* length = AddInstruction(new(zone) HConstant( | 10990 HInstruction* length = AddInstruction(new(zone) HConstant( |
11091 length_field, Representation::None())); | 10991 length_field, Representation::None())); |
| 10992 |
11092 ASSERT(boilerplate_array->length()->IsSmi()); | 10993 ASSERT(boilerplate_array->length()->IsSmi()); |
11093 Representation representation = | 10994 Representation representation = |
11094 IsFastElementsKind(boilerplate_array->GetElementsKind()) | 10995 IsFastElementsKind(boilerplate_array->GetElementsKind()) |
11095 ? Representation::Smi() : Representation::Tagged(); | 10996 ? Representation::Smi() : Representation::Tagged(); |
11096 HInstruction* length_store = AddInstruction(new(zone) HStoreNamedField( | 10997 AddStore(object_header, HObjectAccess::ForArrayLength(), |
11097 object_header, | 10998 length, representation); |
11098 factory->length_field_string(), | |
11099 length, | |
11100 true, representation, JSArray::kLengthOffset)); | |
11101 length_store->SetGVNFlag(kChangesArrayLengths); | |
11102 } | 10999 } |
11103 | 11000 |
11104 return result; | 11001 return result; |
11105 } | 11002 } |
11106 | 11003 |
11107 | 11004 |
11108 void HOptimizedGraphBuilder::VisitThisFunction(ThisFunction* expr) { | 11005 void HOptimizedGraphBuilder::VisitThisFunction(ThisFunction* expr) { |
11109 ASSERT(!HasStackOverflow()); | 11006 ASSERT(!HasStackOverflow()); |
11110 ASSERT(current_block() != NULL); | 11007 ASSERT(current_block() != NULL); |
11111 ASSERT(current_block()->HasPredecessor()); | 11008 ASSERT(current_block()->HasPredecessor()); |
(...skipping 366 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11478 new(zone()) HHasInstanceTypeAndBranch(object, JS_VALUE_TYPE); | 11375 new(zone()) HHasInstanceTypeAndBranch(object, JS_VALUE_TYPE); |
11479 HBasicBlock* if_js_value = graph()->CreateBasicBlock(); | 11376 HBasicBlock* if_js_value = graph()->CreateBasicBlock(); |
11480 HBasicBlock* not_js_value = graph()->CreateBasicBlock(); | 11377 HBasicBlock* not_js_value = graph()->CreateBasicBlock(); |
11481 typecheck->SetSuccessorAt(0, if_js_value); | 11378 typecheck->SetSuccessorAt(0, if_js_value); |
11482 typecheck->SetSuccessorAt(1, not_js_value); | 11379 typecheck->SetSuccessorAt(1, not_js_value); |
11483 current_block()->Finish(typecheck); | 11380 current_block()->Finish(typecheck); |
11484 not_js_value->Goto(join); | 11381 not_js_value->Goto(join); |
11485 | 11382 |
11486 // Create in-object property store to kValueOffset. | 11383 // Create in-object property store to kValueOffset. |
11487 set_current_block(if_js_value); | 11384 set_current_block(if_js_value); |
11488 Handle<String> name = isolate()->factory()->undefined_string(); | 11385 AddStore(object, |
11489 AddInstruction(new(zone()) HStoreNamedField(object, | 11386 HObjectAccess::ForJSObjectOffset(JSValue::kValueOffset), value); |
11490 name, | |
11491 value, | |
11492 true, // in-object store. | |
11493 Representation::Tagged(), | |
11494 JSValue::kValueOffset)); | |
11495 if_js_value->Goto(join); | 11387 if_js_value->Goto(join); |
11496 join->SetJoinId(call->id()); | 11388 join->SetJoinId(call->id()); |
11497 set_current_block(join); | 11389 set_current_block(join); |
11498 return ast_context()->ReturnValue(value); | 11390 return ast_context()->ReturnValue(value); |
11499 } | 11391 } |
11500 | 11392 |
11501 | 11393 |
11502 // Fast support for charCodeAt(n). | 11394 // Fast support for charCodeAt(n). |
11503 void HOptimizedGraphBuilder::GenerateStringCharCodeAt(CallRuntime* call) { | 11395 void HOptimizedGraphBuilder::GenerateStringCharCodeAt(CallRuntime* call) { |
11504 ASSERT(call->arguments()->length() == 2); | 11396 ASSERT(call->arguments()->length() == 2); |
(...skipping 954 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12459 } | 12351 } |
12460 } | 12352 } |
12461 | 12353 |
12462 #ifdef DEBUG | 12354 #ifdef DEBUG |
12463 if (graph_ != NULL) graph_->Verify(false); // No full verify. | 12355 if (graph_ != NULL) graph_->Verify(false); // No full verify. |
12464 if (allocator_ != NULL) allocator_->Verify(); | 12356 if (allocator_ != NULL) allocator_->Verify(); |
12465 #endif | 12357 #endif |
12466 } | 12358 } |
12467 | 12359 |
12468 } } // namespace v8::internal | 12360 } } // namespace v8::internal |
OLD | NEW |