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 1176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1187 | 1187 |
1188 environment()->Push(elements); | 1188 environment()->Push(elements); |
1189 capacity_checker.End(); | 1189 capacity_checker.End(); |
1190 | 1190 |
1191 if (is_js_array) { | 1191 if (is_js_array) { |
1192 HValue* new_length = AddInstruction( | 1192 HValue* new_length = AddInstruction( |
1193 HAdd::New(zone, context, length, graph_->GetConstant1())); | 1193 HAdd::New(zone, context, length, graph_->GetConstant1())); |
1194 new_length->AssumeRepresentation(Representation::Integer32()); | 1194 new_length->AssumeRepresentation(Representation::Integer32()); |
1195 new_length->ClearFlag(HValue::kCanOverflow); | 1195 new_length->ClearFlag(HValue::kCanOverflow); |
1196 | 1196 |
1197 Factory* factory = isolate()->factory(); | |
1198 Representation representation = IsFastElementsKind(kind) | 1197 Representation representation = IsFastElementsKind(kind) |
1199 ? Representation::Smi() : Representation::Tagged(); | 1198 ? Representation::Smi() : Representation::Tagged(); |
1200 HInstruction* length_store = AddInstruction(new(zone) HStoreNamedField( | 1199 AddStore(object, HObjectAccess::ForArrayLength(), new_length, |
1201 object, | 1200 representation); |
1202 factory->length_field_string(), | |
1203 new_length, true, | |
1204 representation, | |
1205 JSArray::kLengthOffset)); | |
1206 length_store->SetGVNFlag(kChangesArrayLengths); | |
1207 } | 1201 } |
1208 | 1202 |
1209 length_checker.Else(); | 1203 length_checker.Else(); |
1210 | 1204 |
1211 AddBoundsCheck(key, length, ALLOW_SMI_KEY); | 1205 AddBoundsCheck(key, length, ALLOW_SMI_KEY); |
1212 environment()->Push(elements); | 1206 environment()->Push(elements); |
1213 | 1207 |
1214 length_checker.End(); | 1208 length_checker.End(); |
1215 | 1209 |
1216 return environment()->Pop(); | 1210 return environment()->Pop(); |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1277 HValue* elements = AddLoadElements(object, mapcheck); | 1271 HValue* elements = AddLoadElements(object, mapcheck); |
1278 if (is_store && (fast_elements || fast_smi_only_elements) && | 1272 if (is_store && (fast_elements || fast_smi_only_elements) && |
1279 store_mode != STORE_NO_TRANSITION_HANDLE_COW) { | 1273 store_mode != STORE_NO_TRANSITION_HANDLE_COW) { |
1280 HCheckMaps* check_cow_map = HCheckMaps::New( | 1274 HCheckMaps* check_cow_map = HCheckMaps::New( |
1281 elements, isolate()->factory()->fixed_array_map(), zone); | 1275 elements, isolate()->factory()->fixed_array_map(), zone); |
1282 check_cow_map->ClearGVNFlag(kDependsOnElementsKind); | 1276 check_cow_map->ClearGVNFlag(kDependsOnElementsKind); |
1283 AddInstruction(check_cow_map); | 1277 AddInstruction(check_cow_map); |
1284 } | 1278 } |
1285 HInstruction* length = NULL; | 1279 HInstruction* length = NULL; |
1286 if (is_js_array) { | 1280 if (is_js_array) { |
1287 length = AddInstruction( | 1281 length = AddLoad(object, HObjectAccess::ForArrayLength(), mapcheck, |
1288 HLoadNamedField::NewArrayLength(zone, object, mapcheck, HType::Smi())); | 1282 Representation::Smi()); |
1283 length->set_type(HType::Smi()); | |
1289 } else { | 1284 } else { |
1290 length = AddInstruction(new(zone) HFixedArrayBaseLength(elements)); | 1285 length = AddInstruction(new(zone) HFixedArrayBaseLength(elements)); |
1291 } | 1286 } |
1292 HValue* checked_key = NULL; | 1287 HValue* checked_key = NULL; |
1293 if (IsExternalArrayElementsKind(elements_kind)) { | 1288 if (IsExternalArrayElementsKind(elements_kind)) { |
1294 if (store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS) { | 1289 if (store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS) { |
1295 NoObservableSideEffectsScope no_effects(this); | 1290 NoObservableSideEffectsScope no_effects(this); |
1296 HLoadExternalArrayPointer* external_elements = | 1291 HLoadExternalArrayPointer* external_elements = |
1297 new(zone) HLoadExternalArrayPointer(elements); | 1292 new(zone) HLoadExternalArrayPointer(elements); |
1298 AddInstruction(external_elements); | 1293 AddInstruction(external_elements); |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1404 HValue* elements = | 1399 HValue* elements = |
1405 AddInstruction(new(zone) HAllocate(context, total_size, | 1400 AddInstruction(new(zone) HAllocate(context, total_size, |
1406 HType::JSArray(), flags)); | 1401 HType::JSArray(), flags)); |
1407 return elements; | 1402 return elements; |
1408 } | 1403 } |
1409 | 1404 |
1410 | 1405 |
1411 void HGraphBuilder::BuildInitializeElements(HValue* elements, | 1406 void HGraphBuilder::BuildInitializeElements(HValue* elements, |
1412 ElementsKind kind, | 1407 ElementsKind kind, |
1413 HValue* capacity) { | 1408 HValue* capacity) { |
1414 Zone* zone = this->zone(); | |
1415 Factory* factory = isolate()->factory(); | 1409 Factory* factory = isolate()->factory(); |
1416 Handle<Map> map = IsFastDoubleElementsKind(kind) | 1410 Handle<Map> map = IsFastDoubleElementsKind(kind) |
1417 ? factory->fixed_double_array_map() | 1411 ? factory->fixed_double_array_map() |
1418 : factory->fixed_array_map(); | 1412 : factory->fixed_array_map(); |
1419 BuildStoreMap(elements, map); | |
1420 | 1413 |
1421 Handle<String> fixed_array_length_field_name = factory->length_field_string(); | 1414 AddStoreMapConstant(elements, map); |
1422 Representation representation = IsFastElementsKind(kind) | 1415 Representation representation = IsFastElementsKind(kind) |
1423 ? Representation::Smi() : Representation::Tagged(); | 1416 ? Representation::Smi() : Representation::Tagged(); |
1424 HInstruction* store_length = | 1417 AddStore(elements, HObjectAccess::ForFixedArrayLength(), capacity, |
1425 new(zone) HStoreNamedField(elements, fixed_array_length_field_name, | 1418 representation); |
1426 capacity, true, representation, | |
1427 FixedArray::kLengthOffset); | |
1428 AddInstruction(store_length); | |
1429 } | 1419 } |
1430 | 1420 |
1431 | 1421 |
1432 HValue* HGraphBuilder::BuildAllocateAndInitializeElements(HValue* context, | 1422 HValue* HGraphBuilder::BuildAllocateAndInitializeElements(HValue* context, |
1433 ElementsKind kind, | 1423 ElementsKind kind, |
1434 HValue* capacity) { | 1424 HValue* capacity) { |
1435 HValue* new_elements = BuildAllocateElements(context, kind, capacity); | 1425 HValue* new_elements = BuildAllocateElements(context, kind, capacity); |
1436 BuildInitializeElements(new_elements, kind, capacity); | 1426 BuildInitializeElements(new_elements, kind, capacity); |
1437 return new_elements; | 1427 return new_elements; |
1438 } | 1428 } |
1439 | 1429 |
1440 | 1430 |
1441 HInnerAllocatedObject* HGraphBuilder::BuildJSArrayHeader(HValue* array, | 1431 HInnerAllocatedObject* HGraphBuilder::BuildJSArrayHeader(HValue* array, |
1442 HValue* array_map, | 1432 HValue* array_map, |
1443 AllocationSiteMode mode, | 1433 AllocationSiteMode mode, |
1444 HValue* allocation_site_payload, | 1434 HValue* allocation_site_payload, |
1445 HValue* length_field) { | 1435 HValue* length_field) { |
1446 | 1436 |
1447 BuildStoreMap(array, array_map); | 1437 AddStore(array, HObjectAccess::ForMap(), array_map); |
1448 | 1438 |
1449 HConstant* empty_fixed_array = | 1439 HConstant* empty_fixed_array = |
1450 new(zone()) HConstant( | 1440 new(zone()) HConstant( |
1451 Handle<FixedArray>(isolate()->heap()->empty_fixed_array()), | 1441 Handle<FixedArray>(isolate()->heap()->empty_fixed_array()), |
1452 Representation::Tagged()); | 1442 Representation::Tagged()); |
1453 AddInstruction(empty_fixed_array); | 1443 AddInstruction(empty_fixed_array); |
1454 | 1444 |
1455 AddInstruction(new(zone()) HStoreNamedField(array, | 1445 HObjectAccess access = HObjectAccess::ForPropertiesPointer(); |
1456 isolate()->factory()->properties_field_symbol(), | 1446 AddStore(array, access, empty_fixed_array); |
1457 empty_fixed_array, | 1447 AddStore(array, HObjectAccess::ForArrayLength(), length_field); |
1458 true, | |
1459 Representation::Tagged(), | |
1460 JSArray::kPropertiesOffset)); | |
1461 | |
1462 HInstruction* length_store = AddInstruction( | |
1463 new(zone()) HStoreNamedField(array, | |
1464 isolate()->factory()->length_field_string(), | |
1465 length_field, | |
1466 true, | |
1467 Representation::Tagged(), | |
1468 JSArray::kLengthOffset)); | |
1469 length_store->SetGVNFlag(kChangesArrayLengths); | |
1470 | 1448 |
1471 if (mode == TRACK_ALLOCATION_SITE) { | 1449 if (mode == TRACK_ALLOCATION_SITE) { |
1472 BuildCreateAllocationSiteInfo(array, | 1450 BuildCreateAllocationSiteInfo(array, |
1473 JSArray::kSize, | 1451 JSArray::kSize, |
1474 allocation_site_payload); | 1452 allocation_site_payload); |
1475 } | 1453 } |
1476 | 1454 |
1477 int elements_location = JSArray::kSize; | 1455 int elements_location = JSArray::kSize; |
1478 if (mode == TRACK_ALLOCATION_SITE) { | 1456 if (mode == TRACK_ALLOCATION_SITE) { |
1479 elements_location += AllocationSiteInfo::kSize; | 1457 elements_location += AllocationSiteInfo::kSize; |
1480 } | 1458 } |
1481 | 1459 |
1482 HInnerAllocatedObject* elements = new(zone()) HInnerAllocatedObject( | 1460 HInnerAllocatedObject* elements = new(zone()) HInnerAllocatedObject( |
1483 array, | 1461 array, elements_location); |
1484 elements_location); | |
1485 AddInstruction(elements); | 1462 AddInstruction(elements); |
1486 | 1463 |
1487 HInstruction* elements_store = AddInstruction( | 1464 AddStore(array, HObjectAccess::ForElementsPointer(), elements); |
1488 new(zone()) HStoreNamedField( | |
1489 array, | |
1490 isolate()->factory()->elements_field_string(), | |
1491 elements, | |
1492 true, | |
1493 Representation::Tagged(), | |
1494 JSArray::kElementsOffset)); | |
1495 elements_store->SetGVNFlag(kChangesElementsPointer); | |
1496 | |
1497 return elements; | 1465 return elements; |
1498 } | 1466 } |
1499 | 1467 |
1500 | 1468 |
1501 HInstruction* HGraphBuilder::BuildStoreMap(HValue* object, | 1469 HLoadNamedField* HGraphBuilder::AddLoadElements(HValue* object, |
1502 HValue* map) { | 1470 HValue* typecheck) { |
1503 Zone* zone = this->zone(); | 1471 return AddLoad(object, HObjectAccess::ForElementsPointer(), typecheck); |
1504 Factory* factory = isolate()->factory(); | |
1505 Handle<String> map_field_name = factory->map_field_string(); | |
1506 HInstruction* store_map = | |
1507 new(zone) HStoreNamedField(object, map_field_name, map, | |
1508 true, Representation::Tagged(), | |
1509 JSObject::kMapOffset); | |
1510 store_map->ClearGVNFlag(kChangesInobjectFields); | |
1511 store_map->SetGVNFlag(kChangesMaps); | |
1512 AddInstruction(store_map); | |
1513 return store_map; | |
1514 } | 1472 } |
1515 | 1473 |
1516 | 1474 |
1517 HInstruction* HGraphBuilder::BuildStoreMap(HValue* object, | |
1518 Handle<Map> map) { | |
1519 Zone* zone = this->zone(); | |
1520 HValue* map_constant = | |
1521 AddInstruction(new(zone) HConstant(map, Representation::Tagged())); | |
1522 return BuildStoreMap(object, map_constant); | |
1523 } | |
1524 | |
1525 | |
1526 HLoadNamedField* HGraphBuilder::AddLoadElements(HValue* object, | |
1527 HValue* typecheck) { | |
1528 HLoadNamedField* instr = new(zone()) HLoadNamedField(object, true, | |
1529 Representation::Tagged(), JSObject::kElementsOffset, typecheck); | |
1530 AddInstruction(instr); | |
1531 instr->SetGVNFlag(kDependsOnElementsPointer); | |
1532 instr->ClearGVNFlag(kDependsOnMaps); | |
1533 instr->ClearGVNFlag(kDependsOnInobjectFields); | |
1534 return instr; | |
1535 } | |
1536 | |
1537 | |
1538 HValue* HGraphBuilder::BuildNewElementsCapacity(HValue* context, | 1475 HValue* HGraphBuilder::BuildNewElementsCapacity(HValue* context, |
1539 HValue* old_capacity) { | 1476 HValue* old_capacity) { |
1540 Zone* zone = this->zone(); | 1477 Zone* zone = this->zone(); |
1541 HValue* half_old_capacity = | 1478 HValue* half_old_capacity = |
1542 AddInstruction(HShr::New(zone, context, old_capacity, | 1479 AddInstruction(HShr::New(zone, context, old_capacity, |
1543 graph_->GetConstant1())); | 1480 graph_->GetConstant1())); |
1544 half_old_capacity->AssumeRepresentation(Representation::Integer32()); | 1481 half_old_capacity->AssumeRepresentation(Representation::Integer32()); |
1545 half_old_capacity->ClearFlag(HValue::kCanOverflow); | 1482 half_old_capacity->ClearFlag(HValue::kCanOverflow); |
1546 | 1483 |
1547 HValue* new_capacity = AddInstruction( | 1484 HValue* new_capacity = AddInstruction( |
(...skipping 29 matching lines...) Expand all Loading... | |
1577 HBoundsCheck(length, max_size_constant, | 1514 HBoundsCheck(length, max_size_constant, |
1578 DONT_ALLOW_SMI_KEY, Representation::Integer32())); | 1515 DONT_ALLOW_SMI_KEY, Representation::Integer32())); |
1579 } | 1516 } |
1580 | 1517 |
1581 | 1518 |
1582 HValue* HGraphBuilder::BuildGrowElementsCapacity(HValue* object, | 1519 HValue* HGraphBuilder::BuildGrowElementsCapacity(HValue* object, |
1583 HValue* elements, | 1520 HValue* elements, |
1584 ElementsKind kind, | 1521 ElementsKind kind, |
1585 HValue* length, | 1522 HValue* length, |
1586 HValue* new_capacity) { | 1523 HValue* new_capacity) { |
1587 Zone* zone = this->zone(); | |
1588 HValue* context = environment()->LookupContext(); | 1524 HValue* context = environment()->LookupContext(); |
1589 | 1525 |
1590 BuildNewSpaceArrayCheck(new_capacity, kind); | 1526 BuildNewSpaceArrayCheck(new_capacity, kind); |
1591 | 1527 |
1592 HValue* new_elements = | 1528 HValue* new_elements = |
1593 BuildAllocateAndInitializeElements(context, kind, new_capacity); | 1529 BuildAllocateAndInitializeElements(context, kind, new_capacity); |
1594 | 1530 |
1595 BuildCopyElements(context, elements, kind, | 1531 BuildCopyElements(context, elements, kind, |
1596 new_elements, kind, | 1532 new_elements, kind, |
1597 length, new_capacity); | 1533 length, new_capacity); |
1598 | 1534 |
1599 Factory* factory = isolate()->factory(); | 1535 AddStore(object, HObjectAccess::ForElementsPointer(), new_elements); |
1600 HInstruction* elements_store = AddInstruction(new(zone) HStoreNamedField( | |
1601 object, | |
1602 factory->elements_field_string(), | |
1603 new_elements, true, Representation::Tagged(), | |
1604 JSArray::kElementsOffset)); | |
1605 elements_store->SetGVNFlag(kChangesElementsPointer); | |
1606 | 1536 |
1607 return new_elements; | 1537 return new_elements; |
1608 } | 1538 } |
1609 | 1539 |
1610 | 1540 |
1611 void HGraphBuilder::BuildFillElementsWithHole(HValue* context, | 1541 void HGraphBuilder::BuildFillElementsWithHole(HValue* context, |
1612 HValue* elements, | 1542 HValue* elements, |
1613 ElementsKind elements_kind, | 1543 ElementsKind elements_kind, |
1614 HValue* from, | 1544 HValue* from, |
1615 HValue* to) { | 1545 HValue* to) { |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1700 } | 1630 } |
1701 } | 1631 } |
1702 | 1632 |
1703 | 1633 |
1704 HValue* HGraphBuilder::BuildCloneShallowArray(HContext* context, | 1634 HValue* HGraphBuilder::BuildCloneShallowArray(HContext* context, |
1705 HValue* boilerplate, | 1635 HValue* boilerplate, |
1706 AllocationSiteMode mode, | 1636 AllocationSiteMode mode, |
1707 ElementsKind kind, | 1637 ElementsKind kind, |
1708 int length) { | 1638 int length) { |
1709 Zone* zone = this->zone(); | 1639 Zone* zone = this->zone(); |
1710 Factory* factory = isolate()->factory(); | |
1711 | 1640 |
1712 NoObservableSideEffectsScope no_effects(this); | 1641 NoObservableSideEffectsScope no_effects(this); |
1713 | 1642 |
1714 // All sizes here are multiples of kPointerSize. | 1643 // All sizes here are multiples of kPointerSize. |
1715 int size = JSArray::kSize; | 1644 int size = JSArray::kSize; |
1716 if (mode == TRACK_ALLOCATION_SITE) { | 1645 if (mode == TRACK_ALLOCATION_SITE) { |
1717 size += AllocationSiteInfo::kSize; | 1646 size += AllocationSiteInfo::kSize; |
1718 } | 1647 } |
1719 int elems_offset = size; | 1648 int elems_offset = size; |
1720 if (length > 0) { | 1649 if (length > 0) { |
1721 size += IsFastDoubleElementsKind(kind) | 1650 size += IsFastDoubleElementsKind(kind) |
1722 ? FixedDoubleArray::SizeFor(length) | 1651 ? FixedDoubleArray::SizeFor(length) |
1723 : FixedArray::SizeFor(length); | 1652 : FixedArray::SizeFor(length); |
1724 } | 1653 } |
1725 | 1654 |
1726 HAllocate::Flags allocate_flags = HAllocate::DefaultFlags(kind); | 1655 HAllocate::Flags allocate_flags = HAllocate::DefaultFlags(kind); |
1727 // Allocate both the JS array and the elements array in one big | 1656 // Allocate both the JS array and the elements array in one big |
1728 // allocation. This avoids multiple limit checks. | 1657 // allocation. This avoids multiple limit checks. |
1729 HValue* size_in_bytes = | 1658 HValue* size_in_bytes = |
1730 AddInstruction(new(zone) HConstant(size, Representation::Integer32())); | 1659 AddInstruction(new(zone) HConstant(size, Representation::Integer32())); |
1731 HInstruction* object = | 1660 HInstruction* object = |
1732 AddInstruction(new(zone) HAllocate(context, | 1661 AddInstruction(new(zone) HAllocate(context, |
1733 size_in_bytes, | 1662 size_in_bytes, |
1734 HType::JSObject(), | 1663 HType::JSObject(), |
1735 allocate_flags)); | 1664 allocate_flags)); |
1736 | 1665 |
1737 // Copy the JS array part. | 1666 // Copy the JS array part. |
1738 for (int i = 0; i < JSArray::kSize; i += kPointerSize) { | 1667 for (int i = 0; i < JSArray::kSize; i += kPointerSize) { |
1739 if ((i != JSArray::kElementsOffset) || (length == 0)) { | 1668 if ((i != JSArray::kElementsOffset) || (length == 0)) { |
1740 HInstruction* value = AddInstruction(new(zone) HLoadNamedField( | 1669 HObjectAccess access = HObjectAccess::ForJSArrayOffset(i); |
1741 boilerplate, true, Representation::Tagged(), i)); | 1670 AddStore(object, access, AddLoad(boilerplate, access)); |
1742 if (i != JSArray::kMapOffset) { | |
1743 AddInstruction(new(zone) HStoreNamedField(object, | |
1744 factory->empty_string(), | |
1745 value, true, | |
1746 Representation::Tagged(), i)); | |
1747 } else { | |
1748 BuildStoreMap(object, value); | |
1749 } | |
1750 } | 1671 } |
1751 } | 1672 } |
1752 | 1673 |
1753 // Create an allocation site info if requested. | 1674 // Create an allocation site info if requested. |
1754 if (mode == TRACK_ALLOCATION_SITE) { | 1675 if (mode == TRACK_ALLOCATION_SITE) { |
1755 BuildCreateAllocationSiteInfo(object, JSArray::kSize, boilerplate); | 1676 BuildCreateAllocationSiteInfo(object, JSArray::kSize, boilerplate); |
1756 } | 1677 } |
1757 | 1678 |
1758 if (length > 0) { | 1679 if (length > 0) { |
1759 // Get hold of the elements array of the boilerplate and setup the | 1680 // Get hold of the elements array of the boilerplate and setup the |
1760 // elements pointer in the resulting object. | 1681 // elements pointer in the resulting object. |
1761 HValue* boilerplate_elements = AddLoadElements(boilerplate); | 1682 HValue* boilerplate_elements = AddLoadElements(boilerplate); |
1762 HValue* object_elements = | 1683 HValue* object_elements = |
1763 AddInstruction(new(zone) HInnerAllocatedObject(object, elems_offset)); | 1684 AddInstruction(new(zone) HInnerAllocatedObject(object, elems_offset)); |
1764 AddInstruction(new(zone) HStoreNamedField(object, | 1685 AddStore(object, HObjectAccess::ForElementsPointer(), object_elements); |
1765 factory->elements_field_string(), | |
1766 object_elements, true, | |
1767 Representation::Tagged(), | |
1768 JSObject::kElementsOffset)); | |
1769 | 1686 |
1770 // Copy the elements array header. | 1687 // Copy the elements array header. |
1771 for (int i = 0; i < FixedArrayBase::kHeaderSize; i += kPointerSize) { | 1688 for (int i = 0; i < FixedArrayBase::kHeaderSize; i += kPointerSize) { |
1772 HInstruction* value = | 1689 HObjectAccess access = HObjectAccess::ForFixedArrayHeader(i); |
1773 AddInstruction(new(zone) HLoadNamedField( | 1690 AddStore(object_elements, access, AddLoad(boilerplate_elements, access)); |
1774 boilerplate_elements, true, Representation::Tagged(), i)); | |
1775 AddInstruction(new(zone) HStoreNamedField(object_elements, | |
1776 factory->empty_string(), | |
1777 value, true, | |
1778 Representation::Tagged(), i)); | |
1779 } | 1691 } |
1780 | 1692 |
1781 // Copy the elements array contents. | 1693 // Copy the elements array contents. |
1782 // TODO(mstarzinger): Teach HGraphBuilder::BuildCopyElements to unfold | 1694 // TODO(mstarzinger): Teach HGraphBuilder::BuildCopyElements to unfold |
1783 // copying loops with constant length up to a given boundary and use this | 1695 // copying loops with constant length up to a given boundary and use this |
1784 // helper here instead. | 1696 // helper here instead. |
1785 for (int i = 0; i < length; i++) { | 1697 for (int i = 0; i < length; i++) { |
1786 HValue* key_constant = | 1698 HValue* key_constant = |
1787 AddInstruction(new(zone) HConstant(i, Representation::Integer32())); | 1699 AddInstruction(new(zone) HConstant(i, Representation::Integer32())); |
1788 HInstruction* value = | 1700 HInstruction* value = |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1848 } | 1760 } |
1849 | 1761 |
1850 | 1762 |
1851 HValue* HGraphBuilder::BuildCreateAllocationSiteInfo(HValue* previous_object, | 1763 HValue* HGraphBuilder::BuildCreateAllocationSiteInfo(HValue* previous_object, |
1852 int previous_object_size, | 1764 int previous_object_size, |
1853 HValue* payload) { | 1765 HValue* payload) { |
1854 HInnerAllocatedObject* alloc_site = new(zone()) | 1766 HInnerAllocatedObject* alloc_site = new(zone()) |
1855 HInnerAllocatedObject(previous_object, previous_object_size); | 1767 HInnerAllocatedObject(previous_object, previous_object_size); |
1856 AddInstruction(alloc_site); | 1768 AddInstruction(alloc_site); |
1857 Handle<Map> alloc_site_map(isolate()->heap()->allocation_site_info_map()); | 1769 Handle<Map> alloc_site_map(isolate()->heap()->allocation_site_info_map()); |
1858 BuildStoreMap(alloc_site, alloc_site_map); | 1770 AddStoreMapConstant(alloc_site, alloc_site_map); |
1859 AddInstruction(new(zone()) HStoreNamedField(alloc_site, | 1771 HObjectAccess access = HObjectAccess::ForAllocationSitePayload(); |
1860 isolate()->factory()->payload_string(), | 1772 AddStore(alloc_site, access, payload); |
1861 payload, | |
1862 true, | |
1863 Representation::Tagged(), | |
1864 AllocationSiteInfo::kPayloadOffset)); | |
1865 return alloc_site; | 1773 return alloc_site; |
1866 } | 1774 } |
1867 | 1775 |
1868 | 1776 |
1869 HInstruction* HGraphBuilder::BuildGetNativeContext(HValue* context) { | 1777 HInstruction* HGraphBuilder::BuildGetNativeContext(HValue* context) { |
1778 // Get the global context, then the native context | |
1870 HInstruction* global_object = AddInstruction(new(zone()) | 1779 HInstruction* global_object = AddInstruction(new(zone()) |
1871 HGlobalObject(context)); | 1780 HGlobalObject(context)); |
1872 HInstruction* native_context = AddInstruction(new(zone()) | 1781 HObjectAccess access = HObjectAccess::ForJSObjectOffset( |
1873 HLoadNamedField(global_object, true, Representation::Tagged(), | 1782 GlobalObject::kNativeContextOffset); |
1874 GlobalObject::kNativeContextOffset)); | 1783 return AddLoad(global_object, access); |
1875 return native_context; | |
1876 } | 1784 } |
1877 | 1785 |
1878 | 1786 |
1879 HInstruction* HGraphBuilder::BuildGetArrayFunction(HValue* context) { | 1787 HInstruction* HGraphBuilder::BuildGetArrayFunction(HValue* context) { |
1880 HInstruction* native_context = BuildGetNativeContext(context); | 1788 HInstruction* native_context = BuildGetNativeContext(context); |
1881 int offset = Context::kHeaderSize + | 1789 HInstruction* index = AddInstruction(new(zone()) |
1882 kPointerSize * Context::ARRAY_FUNCTION_INDEX; | 1790 HConstant(Context::ARRAY_FUNCTION_INDEX, Representation::Integer32())); |
1883 HInstruction* array_function = AddInstruction(new(zone()) | 1791 |
1884 HLoadNamedField(native_context, true, Representation::Tagged(), offset)); | 1792 return AddInstruction(new (zone()) |
1885 return array_function; | 1793 HLoadKeyed(native_context, index, NULL, FAST_ELEMENTS)); |
1886 } | 1794 } |
1887 | 1795 |
1888 | 1796 |
1889 HGraphBuilder::JSArrayBuilder::JSArrayBuilder(HGraphBuilder* builder, | 1797 HGraphBuilder::JSArrayBuilder::JSArrayBuilder(HGraphBuilder* builder, |
1890 ElementsKind kind, | 1798 ElementsKind kind, |
1891 HValue* allocation_site_payload, | 1799 HValue* allocation_site_payload, |
1892 AllocationSiteMode mode) : | 1800 AllocationSiteMode mode) : |
1893 builder_(builder), | 1801 builder_(builder), |
1894 kind_(kind), | 1802 kind_(kind), |
1895 allocation_site_payload_(allocation_site_payload) { | 1803 allocation_site_payload_(allocation_site_payload) { |
1896 if (mode == DONT_TRACK_ALLOCATION_SITE) { | 1804 if (mode == DONT_TRACK_ALLOCATION_SITE) { |
1897 mode_ = mode; | 1805 mode_ = mode; |
1898 } else { | 1806 } else { |
1899 mode_ = AllocationSiteInfo::GetMode(kind); | 1807 mode_ = AllocationSiteInfo::GetMode(kind); |
1900 } | 1808 } |
1901 } | 1809 } |
1902 | 1810 |
1903 | 1811 |
1904 HValue* HGraphBuilder::JSArrayBuilder::EmitMapCode(HValue* context) { | 1812 HValue* HGraphBuilder::JSArrayBuilder::EmitMapCode(HValue* context) { |
1905 HInstruction* native_context = builder()->BuildGetNativeContext(context); | 1813 HInstruction* native_context = builder()->BuildGetNativeContext(context); |
1906 int offset = Context::kHeaderSize + | 1814 |
1907 kPointerSize * Context::JS_ARRAY_MAPS_INDEX; | 1815 HInstruction* index = builder()->AddInstruction(new(zone()) |
1908 HInstruction* map_array = AddInstruction(new(zone()) | 1816 HConstant(Context::JS_ARRAY_MAPS_INDEX, Representation::Integer32())); |
1909 HLoadNamedField(native_context, true, Representation::Tagged(), offset)); | 1817 |
1910 offset = kind_ * kPointerSize + FixedArrayBase::kHeaderSize; | 1818 HInstruction* map_array = builder()->AddInstruction(new(zone()) |
1911 return AddInstruction(new(zone()) HLoadNamedField( | 1819 HLoadKeyed(native_context, index, NULL, FAST_ELEMENTS)); |
1912 map_array, true, Representation::Tagged(), offset)); | 1820 |
1821 HInstruction* kind_index = builder()->AddInstruction(new(zone()) | |
1822 HConstant(kind_, Representation::Integer32())); | |
1823 | |
1824 return builder()->AddInstruction(new(zone()) | |
1825 HLoadKeyed(map_array, kind_index, NULL, FAST_ELEMENTS)); | |
danno
2013/05/14 14:41:58
Nice :-)
| |
1913 } | 1826 } |
1914 | 1827 |
1915 | 1828 |
1916 HValue* HGraphBuilder::JSArrayBuilder::EstablishAllocationSize( | 1829 HValue* HGraphBuilder::JSArrayBuilder::EstablishAllocationSize( |
1917 HValue* length_node) { | 1830 HValue* length_node) { |
1918 HValue* context = builder()->environment()->LookupContext(); | 1831 HValue* context = builder()->environment()->LookupContext(); |
1919 ASSERT(length_node != NULL); | 1832 ASSERT(length_node != NULL); |
1920 | 1833 |
1921 int base_size = JSArray::kSize; | 1834 int base_size = JSArray::kSize; |
1922 if (mode_ == TRACK_ALLOCATION_SITE) { | 1835 if (mode_ == TRACK_ALLOCATION_SITE) { |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2011 | 1924 |
2012 if (fill_with_hole) { | 1925 if (fill_with_hole) { |
2013 builder()->BuildFillElementsWithHole(context, elements_location_, kind_, | 1926 builder()->BuildFillElementsWithHole(context, elements_location_, kind_, |
2014 graph()->GetConstant0(), capacity); | 1927 graph()->GetConstant0(), capacity); |
2015 } | 1928 } |
2016 | 1929 |
2017 return new_object; | 1930 return new_object; |
2018 } | 1931 } |
2019 | 1932 |
2020 | 1933 |
1934 HStoreNamedField* HGraphBuilder::AddStore(HValue *object, | |
1935 HObjectAccess access, | |
1936 HValue *val, | |
1937 Representation representation) { | |
1938 HStoreNamedField *instr = new(zone()) | |
1939 HStoreNamedField(object, access, val, representation); | |
1940 AddInstruction(instr); | |
1941 return instr; | |
1942 } | |
1943 | |
1944 | |
1945 HLoadNamedField* HGraphBuilder::AddLoad(HValue *object, | |
1946 HObjectAccess access, | |
1947 HValue *typecheck, | |
1948 Representation representation) { | |
1949 HLoadNamedField *instr = | |
1950 new(zone()) HLoadNamedField(object, access, typecheck, representation); | |
1951 AddInstruction(instr); | |
1952 return instr; | |
1953 } | |
1954 | |
1955 | |
1956 HStoreNamedField* HGraphBuilder::AddStoreMapConstant(HValue *object, | |
1957 Handle<Map> map) { | |
1958 HValue* constant = | |
1959 AddInstruction(new(zone()) HConstant(map, Representation::Tagged())); | |
1960 HStoreNamedField *instr = | |
1961 new(zone()) HStoreNamedField(object, HObjectAccess::ForMap(), constant); | |
1962 AddInstruction(instr); | |
1963 return instr; | |
1964 } | |
1965 | |
1966 | |
2021 HOptimizedGraphBuilder::HOptimizedGraphBuilder(CompilationInfo* info, | 1967 HOptimizedGraphBuilder::HOptimizedGraphBuilder(CompilationInfo* info, |
2022 TypeFeedbackOracle* oracle) | 1968 TypeFeedbackOracle* oracle) |
2023 : HGraphBuilder(info), | 1969 : HGraphBuilder(info), |
2024 function_state_(NULL), | 1970 function_state_(NULL), |
2025 initial_function_state_(this, info, oracle, NORMAL_RETURN), | 1971 initial_function_state_(this, info, oracle, NORMAL_RETURN), |
2026 ast_context_(NULL), | 1972 ast_context_(NULL), |
2027 break_scope_(NULL), | 1973 break_scope_(NULL), |
2028 inlined_count_(0), | 1974 inlined_count_(0), |
2029 globals_(10, info->zone()), | 1975 globals_(10, info->zone()), |
2030 inline_bailout_(false) { | 1976 inline_bailout_(false) { |
(...skipping 4320 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6351 ASSERT(current_block() != NULL); | 6297 ASSERT(current_block() != NULL); |
6352 ASSERT(current_block()->HasPredecessor()); | 6298 ASSERT(current_block()->HasPredecessor()); |
6353 return Bailout("DebuggerStatement"); | 6299 return Bailout("DebuggerStatement"); |
6354 } | 6300 } |
6355 | 6301 |
6356 | 6302 |
6357 static Handle<SharedFunctionInfo> SearchSharedFunctionInfo( | 6303 static Handle<SharedFunctionInfo> SearchSharedFunctionInfo( |
6358 Code* unoptimized_code, FunctionLiteral* expr) { | 6304 Code* unoptimized_code, FunctionLiteral* expr) { |
6359 int start_position = expr->start_position(); | 6305 int start_position = expr->start_position(); |
6360 RelocIterator it(unoptimized_code); | 6306 RelocIterator it(unoptimized_code); |
6361 for (;!it.done(); it.next()) { | 6307 for (; !it.done(); it.next()) { |
6362 RelocInfo* rinfo = it.rinfo(); | 6308 RelocInfo* rinfo = it.rinfo(); |
6363 if (rinfo->rmode() != RelocInfo::EMBEDDED_OBJECT) continue; | 6309 if (rinfo->rmode() != RelocInfo::EMBEDDED_OBJECT) continue; |
6364 Object* obj = rinfo->target_object(); | 6310 Object* obj = rinfo->target_object(); |
6365 if (obj->IsSharedFunctionInfo()) { | 6311 if (obj->IsSharedFunctionInfo()) { |
6366 SharedFunctionInfo* shared = SharedFunctionInfo::cast(obj); | 6312 SharedFunctionInfo* shared = SharedFunctionInfo::cast(obj); |
6367 if (shared->start_position() == start_position) { | 6313 if (shared->start_position() == start_position) { |
6368 return Handle<SharedFunctionInfo>(shared); | 6314 return Handle<SharedFunctionInfo>(shared); |
6369 } | 6315 } |
6370 } | 6316 } |
6371 } | 6317 } |
(...skipping 655 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
7027 if (!is_store) return false; | 6973 if (!is_store) return false; |
7028 | 6974 |
7029 // 2nd chance: A store into a non-existent field can still be inlined if we | 6975 // 2nd chance: A store into a non-existent field can still be inlined if we |
7030 // have a matching transition and some room left in the object. | 6976 // have a matching transition and some room left in the object. |
7031 type->LookupTransition(NULL, *name, lookup); | 6977 type->LookupTransition(NULL, *name, lookup); |
7032 return lookup->IsTransitionToField(*type) && | 6978 return lookup->IsTransitionToField(*type) && |
7033 (type->unused_property_fields() > 0); | 6979 (type->unused_property_fields() > 0); |
7034 } | 6980 } |
7035 | 6981 |
7036 | 6982 |
7037 static int ComputeLoadStoreFieldIndex(Handle<Map> type, | |
7038 LookupResult* lookup) { | |
7039 ASSERT(lookup->IsField() || lookup->IsTransitionToField(*type)); | |
7040 if (lookup->IsField()) { | |
7041 return lookup->GetLocalFieldIndexFromMap(*type); | |
7042 } else { | |
7043 Map* transition = lookup->GetTransitionMapFromMap(*type); | |
7044 int descriptor = transition->LastAdded(); | |
7045 int index = transition->instance_descriptors()->GetFieldIndex(descriptor); | |
7046 return index - type->inobject_properties(); | |
7047 } | |
7048 } | |
7049 | |
7050 | |
7051 static Representation ComputeLoadStoreRepresentation(Handle<Map> type, | 6983 static Representation ComputeLoadStoreRepresentation(Handle<Map> type, |
7052 LookupResult* lookup) { | 6984 LookupResult* lookup) { |
7053 if (lookup->IsField()) { | 6985 if (lookup->IsField()) { |
7054 return lookup->representation(); | 6986 return lookup->representation(); |
7055 } else { | 6987 } else { |
7056 Map* transition = lookup->GetTransitionMapFromMap(*type); | 6988 Map* transition = lookup->GetTransitionMapFromMap(*type); |
7057 int descriptor = transition->LastAdded(); | 6989 int descriptor = transition->LastAdded(); |
7058 PropertyDetails details = | 6990 PropertyDetails details = |
7059 transition->instance_descriptors()->GetDetails(descriptor); | 6991 transition->instance_descriptors()->GetDetails(descriptor); |
7060 return details.representation(); | 6992 return details.representation(); |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
7105 } | 7037 } |
7106 ASSERT(proto->GetPrototype(isolate())->IsNull()); | 7038 ASSERT(proto->GetPrototype(isolate())->IsNull()); |
7107 } | 7039 } |
7108 ASSERT(proto->IsJSObject()); | 7040 ASSERT(proto->IsJSObject()); |
7109 AddInstruction(new(zone()) HCheckPrototypeMaps( | 7041 AddInstruction(new(zone()) HCheckPrototypeMaps( |
7110 Handle<JSObject>(JSObject::cast(map->prototype())), | 7042 Handle<JSObject>(JSObject::cast(map->prototype())), |
7111 Handle<JSObject>(JSObject::cast(proto)), | 7043 Handle<JSObject>(JSObject::cast(proto)), |
7112 zone())); | 7044 zone())); |
7113 } | 7045 } |
7114 | 7046 |
7115 int index = ComputeLoadStoreFieldIndex(map, lookup); | 7047 HObjectAccess field_access = HObjectAccess::ForField(map, lookup, name); |
7116 bool is_in_object = index < 0; | |
7117 Representation representation = ComputeLoadStoreRepresentation(map, lookup); | 7048 Representation representation = ComputeLoadStoreRepresentation(map, lookup); |
7118 int offset = index * kPointerSize; | |
7119 if (index < 0) { | |
7120 // Negative property indices are in-object properties, indexed | |
7121 // from the end of the fixed part of the object. | |
7122 offset += map->instance_size(); | |
7123 } else { | |
7124 offset += FixedArray::kHeaderSize; | |
7125 } | |
7126 bool transition_to_field = lookup->IsTransitionToField(*map); | 7049 bool transition_to_field = lookup->IsTransitionToField(*map); |
7050 | |
7051 HStoreNamedField *instr; | |
7127 if (FLAG_track_double_fields && representation.IsDouble()) { | 7052 if (FLAG_track_double_fields && representation.IsDouble()) { |
7128 if (transition_to_field) { | 7053 if (transition_to_field) { |
7054 // The store requires a mutable HeapNumber to be allocated. | |
7129 NoObservableSideEffectsScope no_side_effects(this); | 7055 NoObservableSideEffectsScope no_side_effects(this); |
7130 HInstruction* heap_number_size = AddInstruction(new(zone()) HConstant( | 7056 HInstruction* heap_number_size = AddInstruction(new(zone()) HConstant( |
7131 HeapNumber::kSize, Representation::Integer32())); | 7057 HeapNumber::kSize, Representation::Integer32())); |
7132 HInstruction* double_box = AddInstruction(new(zone()) HAllocate( | 7058 HInstruction* double_box = AddInstruction(new(zone()) HAllocate( |
7133 environment()->LookupContext(), heap_number_size, | 7059 environment()->LookupContext(), heap_number_size, |
7134 HType::HeapNumber(), HAllocate::CAN_ALLOCATE_IN_NEW_SPACE)); | 7060 HType::HeapNumber(), HAllocate::CAN_ALLOCATE_IN_NEW_SPACE)); |
7135 BuildStoreMap(double_box, isolate()->factory()->heap_number_map()); | 7061 AddStoreMapConstant(double_box, isolate()->factory()->heap_number_map()); |
7136 AddInstruction(new(zone()) HStoreNamedField( | 7062 AddStore(double_box, HObjectAccess::ForHeapNumberValue(), |
7137 double_box, name, value, true, | 7063 value, Representation::Double()); |
7138 Representation::Double(), HeapNumber::kValueOffset)); | 7064 instr = new(zone()) HStoreNamedField(object, field_access, double_box); |
7139 value = double_box; | |
7140 representation = Representation::Tagged(); | |
7141 } else { | 7065 } else { |
7142 HInstruction* double_box = AddInstruction(new(zone()) HLoadNamedField( | 7066 // Already holds a HeapNumber; load the box and write its value field. |
7143 object, is_in_object, Representation::Tagged(), offset)); | 7067 HInstruction* double_box = AddLoad(object, field_access); |
7144 double_box->set_type(HType::HeapNumber()); | 7068 double_box->set_type(HType::HeapNumber()); |
7145 return new(zone()) HStoreNamedField( | 7069 instr = new(zone()) HStoreNamedField(double_box, |
7146 double_box, name, value, true, | 7070 HObjectAccess::ForHeapNumberValue(), value, Representation::Double()); |
7147 Representation::Double(), HeapNumber::kValueOffset); | |
7148 } | 7071 } |
7072 } else { | |
7073 // This is a non-double store. | |
7074 instr = new(zone()) HStoreNamedField( | |
7075 object, field_access, value, representation); | |
7149 } | 7076 } |
7150 HStoreNamedField* instr = new(zone()) HStoreNamedField( | 7077 |
7151 object, name, value, is_in_object, representation, offset); | |
7152 if (transition_to_field) { | 7078 if (transition_to_field) { |
7153 Handle<Map> transition(lookup->GetTransitionMapFromMap(*map)); | 7079 Handle<Map> transition(lookup->GetTransitionMapFromMap(*map)); |
7154 instr->set_transition(transition); | 7080 instr->set_transition(transition); |
7155 // TODO(fschneider): Record the new map type of the object in the IR to | 7081 // TODO(fschneider): Record the new map type of the object in the IR to |
7156 // enable elimination of redundant checks after the transition store. | 7082 // enable elimination of redundant checks after the transition store. |
7157 instr->SetGVNFlag(kChangesMaps); | 7083 instr->SetGVNFlag(kChangesMaps); |
7158 } | 7084 } |
7159 return instr; | 7085 return instr; |
7160 } | 7086 } |
7161 | 7087 |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
7211 Handle<String> name) { | 7137 Handle<String> name) { |
7212 if (!name->Equals(isolate()->heap()->length_string())) return false; | 7138 if (!name->Equals(isolate()->heap()->length_string())) return false; |
7213 | 7139 |
7214 for (int i = 0; i < types->length(); i++) { | 7140 for (int i = 0; i < types->length(); i++) { |
7215 if (types->at(i)->instance_type() != JS_ARRAY_TYPE) return false; | 7141 if (types->at(i)->instance_type() != JS_ARRAY_TYPE) return false; |
7216 } | 7142 } |
7217 | 7143 |
7218 BuildCheckNonSmi(object); | 7144 BuildCheckNonSmi(object); |
7219 | 7145 |
7220 HInstruction* typecheck = | 7146 HInstruction* typecheck = |
7221 AddInstruction(HCheckMaps::New(object, types, zone())); | 7147 AddInstruction(HCheckMaps::New(object, types, zone())); |
7222 HInstruction* instr = | 7148 HInstruction* instr = new(zone()) |
7223 HLoadNamedField::NewArrayLength(zone(), object, typecheck); | 7149 HLoadNamedField(object, HObjectAccess::ForArrayLength(), typecheck); |
7150 | |
7224 instr->set_position(expr->position()); | 7151 instr->set_position(expr->position()); |
7225 ast_context()->ReturnInstruction(instr, expr->id()); | 7152 ast_context()->ReturnInstruction(instr, expr->id()); |
7226 return true; | 7153 return true; |
7227 } | 7154 } |
7228 | 7155 |
7229 | 7156 |
7230 void HOptimizedGraphBuilder::HandlePolymorphicLoadNamedField(Property* expr, | 7157 void HOptimizedGraphBuilder::HandlePolymorphicLoadNamedField(Property* expr, |
7231 HValue* object, | 7158 HValue* object, |
7232 SmallMapList* types, | 7159 SmallMapList* types, |
7233 Handle<String> name) { | 7160 Handle<String> name) { |
7234 | 7161 |
7235 if (HandlePolymorphicArrayLengthLoad(expr, object, types, name)) | 7162 if (HandlePolymorphicArrayLengthLoad(expr, object, types, name)) |
7236 return; | 7163 return; |
7237 | 7164 |
7238 BuildCheckNonSmi(object); | 7165 BuildCheckNonSmi(object); |
7239 | 7166 |
7240 // Use monomorphic load if property lookup results in the same field index | 7167 // Use monomorphic load if property lookup results in the same field index |
7241 // for all maps. Requires special map check on the set of all handled maps. | 7168 // for all maps. Requires special map check on the set of all handled maps. |
7242 HInstruction* instr = NULL; | 7169 HInstruction* instr = NULL; |
7243 if (types->length() > 0 && types->length() <= kMaxLoadPolymorphism) { | 7170 LookupResult lookup(isolate()); |
7244 LookupResult lookup(isolate()); | 7171 int count; |
7245 int previous_field_offset = 0; | 7172 Representation representation = Representation::None(); |
7246 bool previous_field_is_in_object = false; | 7173 HObjectAccess access = HObjectAccess::ForMap(); // initial value unused. |
7247 Representation representation = Representation::None(); | 7174 for (count = 0; |
7248 int count; | 7175 count < types->length() && count < kMaxLoadPolymorphism; |
7249 for (count = 0; count < types->length(); ++count) { | 7176 ++count) { |
7250 Handle<Map> map = types->at(count); | 7177 Handle<Map> map = types->at(count); |
7251 if (!ComputeLoadStoreField(map, name, &lookup, false)) break; | 7178 if (!ComputeLoadStoreField(map, name, &lookup, false)) break; |
7252 | 7179 |
7253 int index = ComputeLoadStoreFieldIndex(map, &lookup); | 7180 HObjectAccess new_access = HObjectAccess::ForField(map, &lookup, name); |
7254 Representation new_representation = | 7181 Representation new_representation = |
7255 ComputeLoadStoreRepresentation(map, &lookup); | 7182 ComputeLoadStoreRepresentation(map, &lookup); |
7256 bool is_in_object = index < 0; | |
7257 int offset = index * kPointerSize; | |
7258 | 7183 |
7259 if (index < 0) { | 7184 if (count == 0) { |
7260 // Negative property indices are in-object properties, indexed | 7185 // First time through the loop; set access and representation. |
7261 // from the end of the fixed part of the object. | 7186 access = new_access; |
7262 offset += map->instance_size(); | 7187 representation = new_representation; |
7263 } else { | 7188 } else if (!representation.IsCompatibleForLoad(new_representation)) { |
7264 offset += FixedArray::kHeaderSize; | 7189 // Representations did not match. |
7265 } | 7190 break; |
7266 | 7191 } else if (access.offset() != new_access.offset()) { |
7267 if (count == 0) { | 7192 // Offsets did not match. |
7268 previous_field_offset = offset; | 7193 break; |
7269 previous_field_is_in_object = is_in_object; | 7194 } else if (access.IsInobject() != new_access.IsInobject()) { |
7270 representation = new_representation; | 7195 // In-objectness did not match. |
7271 } else if (offset != previous_field_offset || | 7196 break; |
7272 is_in_object != previous_field_is_in_object || | |
7273 (FLAG_track_fields && | |
7274 !representation.IsCompatibleForLoad(new_representation))) { | |
7275 break; | |
7276 } | |
7277 | |
7278 representation = representation.generalize(new_representation); | |
7279 } | |
7280 | |
7281 if (count == types->length()) { | |
7282 AddInstruction(HCheckMaps::New(object, types, zone())); | |
7283 instr = DoBuildLoadNamedField( | |
7284 object, previous_field_is_in_object, | |
7285 representation, previous_field_offset); | |
7286 } | 7197 } |
7287 } | 7198 } |
7288 | 7199 |
7289 if (instr == NULL) { | 7200 if (count == types->length()) { |
7201 // Everything matched; can use monomorphic load. | |
7202 AddInstruction(HCheckMaps::New(object, types, zone())); | |
7203 instr = BuildLoadNamedField(object, access, representation); | |
7204 } else { | |
7205 // Something did not match; must use a polymorphic load. | |
7290 HValue* context = environment()->LookupContext(); | 7206 HValue* context = environment()->LookupContext(); |
7291 instr = new(zone()) HLoadNamedFieldPolymorphic( | 7207 instr = new(zone()) HLoadNamedFieldPolymorphic( |
7292 context, object, types, name, zone()); | 7208 context, object, types, name, zone()); |
7293 } | 7209 } |
7294 | 7210 |
7295 instr->set_position(expr->position()); | 7211 instr->set_position(expr->position()); |
7296 return ast_context()->ReturnInstruction(instr, expr->id()); | 7212 return ast_context()->ReturnInstruction(instr, expr->id()); |
7297 } | 7213 } |
7298 | 7214 |
7299 | 7215 |
(...skipping 536 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
7836 HValue* value = environment()->Pop(); | 7752 HValue* value = environment()->Pop(); |
7837 HThrow* instr = new(zone()) HThrow(context, value); | 7753 HThrow* instr = new(zone()) HThrow(context, value); |
7838 instr->set_position(expr->position()); | 7754 instr->set_position(expr->position()); |
7839 AddInstruction(instr); | 7755 AddInstruction(instr); |
7840 AddSimulate(expr->id()); | 7756 AddSimulate(expr->id()); |
7841 current_block()->FinishExit(new(zone()) HAbnormalExit); | 7757 current_block()->FinishExit(new(zone()) HAbnormalExit); |
7842 set_current_block(NULL); | 7758 set_current_block(NULL); |
7843 } | 7759 } |
7844 | 7760 |
7845 | 7761 |
7846 HLoadNamedField* HOptimizedGraphBuilder::BuildLoadNamedField( | 7762 HLoadNamedField* HGraphBuilder::BuildLoadNamedField( |
7847 HValue* object, | 7763 HValue* object, |
7848 Handle<Map> map, | 7764 HObjectAccess access, |
7849 LookupResult* lookup) { | 7765 Representation representation) { |
7850 int index = lookup->GetLocalFieldIndexFromMap(*map); | |
7851 // Negative property indices are in-object properties, indexed from the end of | |
7852 // the fixed part of the object. Non-negative property indices are in the | |
7853 // properties array. | |
7854 int inobject = index < 0; | |
7855 Representation representation = lookup->representation(); | |
7856 int offset = inobject | |
7857 ? index * kPointerSize + map->instance_size() | |
7858 : index * kPointerSize + FixedArray::kHeaderSize; | |
7859 return DoBuildLoadNamedField(object, inobject, representation, offset); | |
7860 } | |
7861 | |
7862 | |
7863 HLoadNamedField* HGraphBuilder::DoBuildLoadNamedField( | |
7864 HValue* object, | |
7865 bool inobject, | |
7866 Representation representation, | |
7867 int offset) { | |
7868 bool load_double = false; | 7766 bool load_double = false; |
7869 if (representation.IsDouble()) { | 7767 if (representation.IsDouble()) { |
7870 representation = Representation::Tagged(); | 7768 representation = Representation::Tagged(); |
7871 load_double = FLAG_track_double_fields; | 7769 load_double = FLAG_track_double_fields; |
7872 } | 7770 } |
7873 HLoadNamedField* field = | 7771 HLoadNamedField* field = |
7874 new(zone()) HLoadNamedField(object, inobject, representation, offset); | 7772 new(zone()) HLoadNamedField(object, access, NULL, representation); |
7875 if (load_double) { | 7773 if (load_double) { |
7876 AddInstruction(field); | 7774 AddInstruction(field); |
7877 field->set_type(HType::HeapNumber()); | 7775 field->set_type(HType::HeapNumber()); |
7878 return new(zone()) HLoadNamedField( | 7776 return new(zone()) HLoadNamedField(field, |
7879 field, true, Representation::Double(), HeapNumber::kValueOffset); | 7777 HObjectAccess::ForHeapNumberValue(), NULL, Representation::Double()); |
7880 } | 7778 } |
7881 return field; | 7779 return field; |
7882 } | 7780 } |
7883 | 7781 |
7884 | 7782 |
7885 HInstruction* HOptimizedGraphBuilder::BuildLoadNamedGeneric( | 7783 HInstruction* HOptimizedGraphBuilder::BuildLoadNamedGeneric( |
7886 HValue* object, | 7784 HValue* object, |
7887 Handle<String> name, | 7785 Handle<String> name, |
7888 Property* expr) { | 7786 Property* expr) { |
7889 if (expr->IsUninitialized()) { | 7787 if (expr->IsUninitialized()) { |
(...skipping 20 matching lines...) Expand all Loading... | |
7910 Handle<String> name, | 7808 Handle<String> name, |
7911 Property* expr, | 7809 Property* expr, |
7912 Handle<Map> map) { | 7810 Handle<Map> map) { |
7913 // Handle a load from a known field. | 7811 // Handle a load from a known field. |
7914 ASSERT(!map->is_dictionary_map()); | 7812 ASSERT(!map->is_dictionary_map()); |
7915 | 7813 |
7916 // Handle access to various length properties | 7814 // Handle access to various length properties |
7917 if (name->Equals(isolate()->heap()->length_string())) { | 7815 if (name->Equals(isolate()->heap()->length_string())) { |
7918 if (map->instance_type() == JS_ARRAY_TYPE) { | 7816 if (map->instance_type() == JS_ARRAY_TYPE) { |
7919 AddCheckMapsWithTransitions(object, map); | 7817 AddCheckMapsWithTransitions(object, map); |
7920 return HLoadNamedField::NewArrayLength(zone(), object, object); | 7818 return new(zone()) HLoadNamedField(object, |
7819 HObjectAccess::ForArrayLength()); | |
7921 } | 7820 } |
7922 } | 7821 } |
7923 | 7822 |
7924 LookupResult lookup(isolate()); | 7823 LookupResult lookup(isolate()); |
7925 map->LookupDescriptor(NULL, *name, &lookup); | 7824 map->LookupDescriptor(NULL, *name, &lookup); |
7926 if (lookup.IsField()) { | 7825 if (lookup.IsField()) { |
7927 AddCheckMap(object, map); | 7826 AddCheckMap(object, map); |
7928 return BuildLoadNamedField(object, map, &lookup); | 7827 return BuildLoadNamedField(object, |
7828 HObjectAccess::ForField(map, &lookup, name), | |
7829 ComputeLoadStoreRepresentation(map, &lookup)); | |
7929 } | 7830 } |
7930 | 7831 |
7931 // Handle a load of a constant known function. | 7832 // Handle a load of a constant known function. |
7932 if (lookup.IsConstantFunction()) { | 7833 if (lookup.IsConstantFunction()) { |
7933 AddCheckMap(object, map); | 7834 AddCheckMap(object, map); |
7934 Handle<JSFunction> function(lookup.GetConstantFunctionFromMap(*map)); | 7835 Handle<JSFunction> function(lookup.GetConstantFunctionFromMap(*map)); |
7935 return new(zone()) HConstant(function, Representation::Tagged()); | 7836 return new(zone()) HConstant(function, Representation::Tagged()); |
7936 } | 7837 } |
7937 | 7838 |
7938 // Handle a load from a known field somewhere in the prototype chain. | 7839 // Handle a load from a known field somewhere in the prototype chain. |
7939 LookupInPrototypes(map, name, &lookup); | 7840 LookupInPrototypes(map, name, &lookup); |
7940 if (lookup.IsField()) { | 7841 if (lookup.IsField()) { |
7941 Handle<JSObject> prototype(JSObject::cast(map->prototype())); | 7842 Handle<JSObject> prototype(JSObject::cast(map->prototype())); |
7942 Handle<JSObject> holder(lookup.holder()); | 7843 Handle<JSObject> holder(lookup.holder()); |
7943 Handle<Map> holder_map(holder->map()); | 7844 Handle<Map> holder_map(holder->map()); |
7944 AddCheckMap(object, map); | 7845 AddCheckMap(object, map); |
7945 AddInstruction( | 7846 AddInstruction( |
7946 new(zone()) HCheckPrototypeMaps(prototype, holder, zone())); | 7847 new(zone()) HCheckPrototypeMaps(prototype, holder, zone())); |
7947 HValue* holder_value = AddInstruction( | 7848 HValue* holder_value = AddInstruction(new(zone()) |
7948 new(zone()) HConstant(holder, Representation::Tagged())); | 7849 HConstant(holder, Representation::Tagged())); |
7949 return BuildLoadNamedField(holder_value, holder_map, &lookup); | 7850 return BuildLoadNamedField(holder_value, |
7851 HObjectAccess::ForField(holder_map, &lookup, name), | |
7852 ComputeLoadStoreRepresentation(map, &lookup)); | |
7950 } | 7853 } |
7951 | 7854 |
7952 // Handle a load of a constant function somewhere in the prototype chain. | 7855 // Handle a load of a constant function somewhere in the prototype chain. |
7953 if (lookup.IsConstantFunction()) { | 7856 if (lookup.IsConstantFunction()) { |
7954 Handle<JSObject> prototype(JSObject::cast(map->prototype())); | 7857 Handle<JSObject> prototype(JSObject::cast(map->prototype())); |
7955 Handle<JSObject> holder(lookup.holder()); | 7858 Handle<JSObject> holder(lookup.holder()); |
7956 Handle<Map> holder_map(holder->map()); | 7859 Handle<Map> holder_map(holder->map()); |
7957 AddCheckMap(object, map); | 7860 AddCheckMap(object, map); |
7958 AddInstruction(new(zone()) HCheckPrototypeMaps(prototype, holder, zone())); | 7861 AddInstruction(new(zone()) HCheckPrototypeMaps(prototype, holder, zone())); |
7959 Handle<JSFunction> function(lookup.GetConstantFunctionFromMap(*holder_map)); | 7862 Handle<JSFunction> function(lookup.GetConstantFunctionFromMap(*holder_map)); |
(...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
8202 // it's a keyed property) and registered in the full codegen. | 8105 // it's a keyed property) and registered in the full codegen. |
8203 HBasicBlock* if_jsarray = graph()->CreateBasicBlock(); | 8106 HBasicBlock* if_jsarray = graph()->CreateBasicBlock(); |
8204 HBasicBlock* if_fastobject = graph()->CreateBasicBlock(); | 8107 HBasicBlock* if_fastobject = graph()->CreateBasicBlock(); |
8205 HHasInstanceTypeAndBranch* typecheck = | 8108 HHasInstanceTypeAndBranch* typecheck = |
8206 new(zone()) HHasInstanceTypeAndBranch(object, JS_ARRAY_TYPE); | 8109 new(zone()) HHasInstanceTypeAndBranch(object, JS_ARRAY_TYPE); |
8207 typecheck->SetSuccessorAt(0, if_jsarray); | 8110 typecheck->SetSuccessorAt(0, if_jsarray); |
8208 typecheck->SetSuccessorAt(1, if_fastobject); | 8111 typecheck->SetSuccessorAt(1, if_fastobject); |
8209 current_block()->Finish(typecheck); | 8112 current_block()->Finish(typecheck); |
8210 | 8113 |
8211 set_current_block(if_jsarray); | 8114 set_current_block(if_jsarray); |
8212 HInstruction* length; | 8115 HInstruction* length = AddLoad(object, HObjectAccess::ForArrayLength(), |
8213 length = AddInstruction( | 8116 typecheck, Representation::Smi()); |
8214 HLoadNamedField::NewArrayLength(zone(), object, typecheck, | 8117 length->set_type(HType::Smi()); |
8215 HType::Smi())); | 8118 |
8216 checked_key = AddBoundsCheck(key, length, ALLOW_SMI_KEY); | 8119 checked_key = AddBoundsCheck(key, length, ALLOW_SMI_KEY); |
8217 access = AddInstruction(BuildFastElementAccess( | 8120 access = AddInstruction(BuildFastElementAccess( |
8218 elements, checked_key, val, elements_kind_branch, | 8121 elements, checked_key, val, elements_kind_branch, |
8219 elements_kind, is_store, STANDARD_STORE)); | 8122 elements_kind, is_store, STANDARD_STORE)); |
8220 if (!is_store) { | 8123 if (!is_store) { |
8221 Push(access); | 8124 Push(access); |
8222 } | 8125 } |
8223 | 8126 |
8224 *has_side_effects |= access->HasObservableSideEffects(); | 8127 *has_side_effects |= access->HasObservableSideEffects(); |
8225 // The caller will use has_side_effects and add correct Simulate. | 8128 // The caller will use has_side_effects and add correct Simulate. |
(...skipping 2622 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
10848 } | 10751 } |
10849 | 10752 |
10850 | 10753 |
10851 void HOptimizedGraphBuilder::BuildEmitDeepCopy( | 10754 void HOptimizedGraphBuilder::BuildEmitDeepCopy( |
10852 Handle<JSObject> boilerplate_object, | 10755 Handle<JSObject> boilerplate_object, |
10853 Handle<JSObject> original_boilerplate_object, | 10756 Handle<JSObject> original_boilerplate_object, |
10854 HInstruction* target, | 10757 HInstruction* target, |
10855 int* offset, | 10758 int* offset, |
10856 AllocationSiteMode mode) { | 10759 AllocationSiteMode mode) { |
10857 Zone* zone = this->zone(); | 10760 Zone* zone = this->zone(); |
10858 Factory* factory = isolate()->factory(); | |
10859 | 10761 |
10860 HInstruction* original_boilerplate = AddInstruction(new(zone) HConstant( | 10762 HInstruction* original_boilerplate = AddInstruction(new(zone) HConstant( |
10861 original_boilerplate_object, Representation::Tagged())); | 10763 original_boilerplate_object, Representation::Tagged())); |
10862 | 10764 |
10863 bool create_allocation_site_info = mode == TRACK_ALLOCATION_SITE && | 10765 bool create_allocation_site_info = mode == TRACK_ALLOCATION_SITE && |
10864 boilerplate_object->map()->CanTrackAllocationSite(); | 10766 boilerplate_object->map()->CanTrackAllocationSite(); |
10865 | 10767 |
10866 // Only elements backing stores for non-COW arrays need to be copied. | 10768 // Only elements backing stores for non-COW arrays need to be copied. |
10867 Handle<FixedArrayBase> elements(boilerplate_object->elements()); | 10769 Handle<FixedArrayBase> elements(boilerplate_object->elements()); |
10868 Handle<FixedArrayBase> original_elements( | 10770 Handle<FixedArrayBase> original_elements( |
(...skipping 28 matching lines...) Expand all Loading... | |
10897 | 10799 |
10898 for (int i = 0; i < limit; i++) { | 10800 for (int i = 0; i < limit; i++) { |
10899 PropertyDetails details = descriptors->GetDetails(i); | 10801 PropertyDetails details = descriptors->GetDetails(i); |
10900 if (details.type() != FIELD) continue; | 10802 if (details.type() != FIELD) continue; |
10901 int index = descriptors->GetFieldIndex(i); | 10803 int index = descriptors->GetFieldIndex(i); |
10902 int property_offset = boilerplate_object->GetInObjectPropertyOffset(index); | 10804 int property_offset = boilerplate_object->GetInObjectPropertyOffset(index); |
10903 Handle<Name> name(descriptors->GetKey(i)); | 10805 Handle<Name> name(descriptors->GetKey(i)); |
10904 Handle<Object> value = | 10806 Handle<Object> value = |
10905 Handle<Object>(boilerplate_object->InObjectPropertyAt(index), | 10807 Handle<Object>(boilerplate_object->InObjectPropertyAt(index), |
10906 isolate()); | 10808 isolate()); |
10809 | |
10810 // The access for the store depends on the type of the boilerplate. | |
10811 HObjectAccess access = boilerplate_object->IsJSArray() ? | |
10812 HObjectAccess::ForJSArrayOffset(property_offset) : | |
10813 HObjectAccess::ForJSObjectOffset(property_offset); | |
10814 | |
10907 if (value->IsJSObject()) { | 10815 if (value->IsJSObject()) { |
10908 Handle<JSObject> value_object = Handle<JSObject>::cast(value); | 10816 Handle<JSObject> value_object = Handle<JSObject>::cast(value); |
10909 Handle<JSObject> original_value_object = Handle<JSObject>::cast( | 10817 Handle<JSObject> original_value_object = Handle<JSObject>::cast( |
10910 Handle<Object>(original_boilerplate_object->InObjectPropertyAt(index), | 10818 Handle<Object>(original_boilerplate_object->InObjectPropertyAt(index), |
10911 isolate())); | 10819 isolate())); |
10912 HInstruction* value_instruction = | 10820 HInstruction* value_instruction = |
10913 AddInstruction(new(zone) HInnerAllocatedObject(target, *offset)); | 10821 AddInstruction(new(zone) HInnerAllocatedObject(target, *offset)); |
10914 AddInstruction(new(zone) HStoreNamedField( | 10822 |
10915 object_properties, name, value_instruction, true, | 10823 AddStore(object_properties, access, value_instruction); |
10916 Representation::Tagged(), property_offset)); | 10824 |
10917 BuildEmitDeepCopy(value_object, original_value_object, target, | 10825 BuildEmitDeepCopy(value_object, original_value_object, target, |
10918 offset, DONT_TRACK_ALLOCATION_SITE); | 10826 offset, DONT_TRACK_ALLOCATION_SITE); |
10919 } else { | 10827 } else { |
10920 Representation representation = details.representation(); | 10828 Representation representation = details.representation(); |
10921 HInstruction* value_instruction = AddInstruction(new(zone) HConstant( | 10829 HInstruction* value_instruction = AddInstruction(new(zone) HConstant( |
10922 value, Representation::Tagged())); | 10830 value, Representation::Tagged())); |
10831 | |
10923 if (representation.IsDouble()) { | 10832 if (representation.IsDouble()) { |
10833 // Allocate a HeapNumber box and store the value into it. | |
10924 HInstruction* double_box = | 10834 HInstruction* double_box = |
10925 AddInstruction(new(zone) HInnerAllocatedObject(target, *offset)); | 10835 AddInstruction(new(zone) HInnerAllocatedObject(target, *offset)); |
10926 BuildStoreMap(double_box, factory->heap_number_map()); | 10836 AddStoreMapConstant(double_box, |
10927 AddInstruction(new(zone) HStoreNamedField( | 10837 isolate()->factory()->heap_number_map()); |
10928 double_box, name, value_instruction, true, | 10838 AddStore(double_box, HObjectAccess::ForHeapNumberValue(), |
10929 Representation::Double(), HeapNumber::kValueOffset)); | 10839 value_instruction, Representation::Double()); |
10930 value_instruction = double_box; | 10840 value_instruction = double_box; |
10931 *offset += HeapNumber::kSize; | 10841 *offset += HeapNumber::kSize; |
10932 } | 10842 } |
10933 AddInstruction(new(zone) HStoreNamedField( | 10843 |
10934 object_properties, name, value_instruction, true, | 10844 AddStore(object_properties, access, value_instruction); |
10935 Representation::Tagged(), property_offset)); | |
10936 } | 10845 } |
10937 } | 10846 } |
10938 | 10847 |
10939 // Build Allocation Site Info if desired | 10848 // Build Allocation Site Info if desired |
10940 if (create_allocation_site_info) { | 10849 if (create_allocation_site_info) { |
10941 BuildCreateAllocationSiteInfo(target, JSArray::kSize, original_boilerplate); | 10850 BuildCreateAllocationSiteInfo(target, JSArray::kSize, original_boilerplate); |
10942 } | 10851 } |
10943 | 10852 |
10944 if (object_elements != NULL) { | 10853 if (object_elements != NULL) { |
10945 HInstruction* boilerplate_elements = AddInstruction(new(zone) HConstant( | 10854 HInstruction* boilerplate_elements = AddInstruction(new(zone) HConstant( |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
10997 | 10906 |
10998 | 10907 |
10999 HValue* HOptimizedGraphBuilder::BuildCopyObjectHeader( | 10908 HValue* HOptimizedGraphBuilder::BuildCopyObjectHeader( |
11000 Handle<JSObject> boilerplate_object, | 10909 Handle<JSObject> boilerplate_object, |
11001 HInstruction* target, | 10910 HInstruction* target, |
11002 int object_offset, | 10911 int object_offset, |
11003 int elements_offset, | 10912 int elements_offset, |
11004 int elements_size) { | 10913 int elements_size) { |
11005 ASSERT(boilerplate_object->properties()->length() == 0); | 10914 ASSERT(boilerplate_object->properties()->length() == 0); |
11006 Zone* zone = this->zone(); | 10915 Zone* zone = this->zone(); |
11007 Factory* factory = isolate()->factory(); | |
11008 HValue* result = NULL; | 10916 HValue* result = NULL; |
11009 | 10917 |
11010 HValue* object_header = | 10918 HValue* object_header = |
11011 AddInstruction(new(zone) HInnerAllocatedObject(target, object_offset)); | 10919 AddInstruction(new(zone) HInnerAllocatedObject(target, object_offset)); |
11012 Handle<Map> boilerplate_object_map(boilerplate_object->map()); | 10920 Handle<Map> boilerplate_object_map(boilerplate_object->map()); |
11013 BuildStoreMap(object_header, boilerplate_object_map); | 10921 AddStoreMapConstant(object_header, boilerplate_object_map); |
11014 | 10922 |
11015 HInstruction* elements; | 10923 HInstruction* elements; |
11016 if (elements_size == 0) { | 10924 if (elements_size == 0) { |
11017 Handle<Object> elements_field = | 10925 Handle<Object> elements_field = |
11018 Handle<Object>(boilerplate_object->elements(), isolate()); | 10926 Handle<Object>(boilerplate_object->elements(), isolate()); |
11019 elements = AddInstruction(new(zone) HConstant( | 10927 elements = AddInstruction(new(zone) HConstant( |
11020 elements_field, Representation::Tagged())); | 10928 elements_field, Representation::Tagged())); |
11021 } else { | 10929 } else { |
11022 elements = AddInstruction(new(zone) HInnerAllocatedObject( | 10930 elements = AddInstruction(new(zone) HInnerAllocatedObject( |
11023 target, elements_offset)); | 10931 target, elements_offset)); |
11024 result = elements; | 10932 result = elements; |
11025 } | 10933 } |
11026 HInstruction* elements_store = AddInstruction(new(zone) HStoreNamedField( | 10934 AddStore(object_header, HObjectAccess::ForElementsPointer(), elements); |
11027 object_header, | |
11028 factory->elements_field_string(), | |
11029 elements, | |
11030 true, Representation::Tagged(), JSObject::kElementsOffset)); | |
11031 elements_store->SetGVNFlag(kChangesElementsPointer); | |
11032 | 10935 |
11033 Handle<Object> properties_field = | 10936 Handle<Object> properties_field = |
11034 Handle<Object>(boilerplate_object->properties(), isolate()); | 10937 Handle<Object>(boilerplate_object->properties(), isolate()); |
11035 ASSERT(*properties_field == isolate()->heap()->empty_fixed_array()); | 10938 ASSERT(*properties_field == isolate()->heap()->empty_fixed_array()); |
11036 HInstruction* properties = AddInstruction(new(zone) HConstant( | 10939 HInstruction* properties = AddInstruction(new(zone) HConstant( |
11037 properties_field, Representation::None())); | 10940 properties_field, Representation::None())); |
11038 AddInstruction(new(zone) HStoreNamedField(object_header, | 10941 HObjectAccess access = HObjectAccess::ForPropertiesPointer(); |
11039 factory->empty_string(), | 10942 AddStore(object_header, access, properties); |
11040 properties, true, | |
11041 Representation::Tagged(), | |
11042 JSObject::kPropertiesOffset)); | |
11043 | 10943 |
11044 if (boilerplate_object->IsJSArray()) { | 10944 if (boilerplate_object->IsJSArray()) { |
11045 Handle<JSArray> boilerplate_array = | 10945 Handle<JSArray> boilerplate_array = |
11046 Handle<JSArray>::cast(boilerplate_object); | 10946 Handle<JSArray>::cast(boilerplate_object); |
11047 Handle<Object> length_field = | 10947 Handle<Object> length_field = |
11048 Handle<Object>(boilerplate_array->length(), isolate()); | 10948 Handle<Object>(boilerplate_array->length(), isolate()); |
11049 HInstruction* length = AddInstruction(new(zone) HConstant( | 10949 HInstruction* length = AddInstruction(new(zone) HConstant( |
11050 length_field, Representation::None())); | 10950 length_field, Representation::None())); |
10951 | |
11051 ASSERT(boilerplate_array->length()->IsSmi()); | 10952 ASSERT(boilerplate_array->length()->IsSmi()); |
11052 Representation representation = | 10953 Representation representation = |
11053 IsFastElementsKind(boilerplate_array->GetElementsKind()) | 10954 IsFastElementsKind(boilerplate_array->GetElementsKind()) |
11054 ? Representation::Smi() : Representation::Tagged(); | 10955 ? Representation::Smi() : Representation::Tagged(); |
11055 HInstruction* length_store = AddInstruction(new(zone) HStoreNamedField( | 10956 AddStore(object_header, HObjectAccess::ForArrayLength(), |
11056 object_header, | 10957 length, representation); |
11057 factory->length_field_string(), | |
11058 length, | |
11059 true, representation, JSArray::kLengthOffset)); | |
11060 length_store->SetGVNFlag(kChangesArrayLengths); | |
11061 } | 10958 } |
11062 | 10959 |
11063 return result; | 10960 return result; |
11064 } | 10961 } |
11065 | 10962 |
11066 | 10963 |
11067 void HOptimizedGraphBuilder::VisitThisFunction(ThisFunction* expr) { | 10964 void HOptimizedGraphBuilder::VisitThisFunction(ThisFunction* expr) { |
11068 ASSERT(!HasStackOverflow()); | 10965 ASSERT(!HasStackOverflow()); |
11069 ASSERT(current_block() != NULL); | 10966 ASSERT(current_block() != NULL); |
11070 ASSERT(current_block()->HasPredecessor()); | 10967 ASSERT(current_block()->HasPredecessor()); |
(...skipping 366 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
11437 new(zone()) HHasInstanceTypeAndBranch(object, JS_VALUE_TYPE); | 11334 new(zone()) HHasInstanceTypeAndBranch(object, JS_VALUE_TYPE); |
11438 HBasicBlock* if_js_value = graph()->CreateBasicBlock(); | 11335 HBasicBlock* if_js_value = graph()->CreateBasicBlock(); |
11439 HBasicBlock* not_js_value = graph()->CreateBasicBlock(); | 11336 HBasicBlock* not_js_value = graph()->CreateBasicBlock(); |
11440 typecheck->SetSuccessorAt(0, if_js_value); | 11337 typecheck->SetSuccessorAt(0, if_js_value); |
11441 typecheck->SetSuccessorAt(1, not_js_value); | 11338 typecheck->SetSuccessorAt(1, not_js_value); |
11442 current_block()->Finish(typecheck); | 11339 current_block()->Finish(typecheck); |
11443 not_js_value->Goto(join); | 11340 not_js_value->Goto(join); |
11444 | 11341 |
11445 // Create in-object property store to kValueOffset. | 11342 // Create in-object property store to kValueOffset. |
11446 set_current_block(if_js_value); | 11343 set_current_block(if_js_value); |
11447 Handle<String> name = isolate()->factory()->undefined_string(); | 11344 AddStore(object, |
11448 AddInstruction(new(zone()) HStoreNamedField(object, | 11345 HObjectAccess::ForJSObjectOffset(JSValue::kValueOffset), value); |
11449 name, | |
11450 value, | |
11451 true, // in-object store. | |
11452 Representation::Tagged(), | |
11453 JSValue::kValueOffset)); | |
11454 if_js_value->Goto(join); | 11346 if_js_value->Goto(join); |
11455 join->SetJoinId(call->id()); | 11347 join->SetJoinId(call->id()); |
11456 set_current_block(join); | 11348 set_current_block(join); |
11457 return ast_context()->ReturnValue(value); | 11349 return ast_context()->ReturnValue(value); |
11458 } | 11350 } |
11459 | 11351 |
11460 | 11352 |
11461 // Fast support for charCodeAt(n). | 11353 // Fast support for charCodeAt(n). |
11462 void HOptimizedGraphBuilder::GenerateStringCharCodeAt(CallRuntime* call) { | 11354 void HOptimizedGraphBuilder::GenerateStringCharCodeAt(CallRuntime* call) { |
11463 ASSERT(call->arguments()->length() == 2); | 11355 ASSERT(call->arguments()->length() == 2); |
(...skipping 954 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
12418 } | 12310 } |
12419 } | 12311 } |
12420 | 12312 |
12421 #ifdef DEBUG | 12313 #ifdef DEBUG |
12422 if (graph_ != NULL) graph_->Verify(false); // No full verify. | 12314 if (graph_ != NULL) graph_->Verify(false); // No full verify. |
12423 if (allocator_ != NULL) allocator_->Verify(); | 12315 if (allocator_ != NULL) allocator_->Verify(); |
12424 #endif | 12316 #endif |
12425 } | 12317 } |
12426 | 12318 |
12427 } } // namespace v8::internal | 12319 } } // namespace v8::internal |
OLD | NEW |