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

Side by Side Diff: src/hydrogen.cc

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

Powered by Google App Engine
This is Rietveld 408576698