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