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

Side by Side Diff: runtime/vm/intermediate_language_arm.cc

Issue 136753012: Refactor unboxed fields in preparation of reusable SIMD boxes (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 10 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
« no previous file with comments | « runtime/vm/intermediate_language.cc ('k') | runtime/vm/intermediate_language_ia32.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_ARM. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_ARM.
6 #if defined(TARGET_ARCH_ARM) 6 #if defined(TARGET_ARCH_ARM)
7 7
8 #include "vm/intermediate_language.h" 8 #include "vm/intermediate_language.h"
9 9
10 #include "vm/dart_entry.h" 10 #include "vm/dart_entry.h"
(...skipping 1565 matching lines...) Expand 10 before | Expand all | Expand 10 after
1576 UNREACHABLE(); 1576 UNREACHABLE();
1577 } 1577 }
1578 } 1578 }
1579 } 1579 }
1580 __ Bind(&ok); 1580 __ Bind(&ok);
1581 } 1581 }
1582 1582
1583 1583
1584 class StoreInstanceFieldSlowPath : public SlowPathCode { 1584 class StoreInstanceFieldSlowPath : public SlowPathCode {
1585 public: 1585 public:
1586 explicit StoreInstanceFieldSlowPath(StoreInstanceFieldInstr* instruction) 1586 StoreInstanceFieldSlowPath(StoreInstanceFieldInstr* instruction,
1587 : instruction_(instruction) { } 1587 const Class& cls)
1588 : instruction_(instruction), cls_(cls) { }
1588 1589
1589 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { 1590 virtual void EmitNativeCode(FlowGraphCompiler* compiler) {
1590 __ Comment("StoreInstanceFieldSlowPath"); 1591 __ Comment("StoreInstanceFieldSlowPath");
1591 __ Bind(entry_label()); 1592 __ Bind(entry_label());
1592 const Class& double_class = compiler->double_class();
1593 const Code& stub = 1593 const Code& stub =
1594 Code::Handle(StubCode::GetAllocationStubForClass(double_class)); 1594 Code::Handle(StubCode::GetAllocationStubForClass(cls_));
1595 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint()); 1595 const ExternalLabel label(cls_.ToCString(), stub.EntryPoint());
1596 1596
1597 LocationSummary* locs = instruction_->locs(); 1597 LocationSummary* locs = instruction_->locs();
1598 locs->live_registers()->Remove(locs->out()); 1598 locs->live_registers()->Remove(locs->out());
1599 1599
1600 compiler->SaveLiveRegisters(locs); 1600 compiler->SaveLiveRegisters(locs);
1601 compiler->GenerateCall(Scanner::kNoSourcePos, // No token position. 1601 compiler->GenerateCall(Scanner::kNoSourcePos, // No token position.
1602 &label, 1602 &label,
1603 PcDescriptors::kOther, 1603 PcDescriptors::kOther,
1604 locs); 1604 locs);
1605 __ MoveRegister(locs->temp(0).reg(), R0); 1605 __ MoveRegister(locs->temp(0).reg(), R0);
1606 compiler->RestoreLiveRegisters(locs); 1606 compiler->RestoreLiveRegisters(locs);
1607 1607
1608 __ b(exit_label()); 1608 __ b(exit_label());
1609 } 1609 }
1610 1610
1611 private: 1611 private:
1612 StoreInstanceFieldInstr* instruction_; 1612 StoreInstanceFieldInstr* instruction_;
1613 const Class& cls_;
1613 }; 1614 };
1614 1615
1615 1616
1616 LocationSummary* StoreInstanceFieldInstr::MakeLocationSummary(bool opt) const { 1617 LocationSummary* StoreInstanceFieldInstr::MakeLocationSummary(bool opt) const {
1617 const intptr_t kNumInputs = 2; 1618 const intptr_t kNumInputs = 2;
1618 const intptr_t kNumTemps = 0; 1619 const intptr_t kNumTemps = 0;
1619 LocationSummary* summary = 1620 LocationSummary* summary =
1620 new LocationSummary(kNumInputs, kNumTemps, 1621 new LocationSummary(kNumInputs, kNumTemps,
1621 (field().guarded_cid() == kIllegalCid) || (is_initialization_) 1622 (field().guarded_cid() == kIllegalCid) || (is_initialization_)
1622 ? LocationSummary::kCallOnSlowPath 1623 ? LocationSummary::kCallOnSlowPath
(...skipping 23 matching lines...) Expand all
1646 1647
1647 void StoreInstanceFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1648 void StoreInstanceFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
1648 Label skip_store; 1649 Label skip_store;
1649 1650
1650 Register instance_reg = locs()->in(0).reg(); 1651 Register instance_reg = locs()->in(0).reg();
1651 1652
1652 if (IsUnboxedStore() && compiler->is_optimizing()) { 1653 if (IsUnboxedStore() && compiler->is_optimizing()) {
1653 DRegister value = EvenDRegisterOf(locs()->in(1).fpu_reg()); 1654 DRegister value = EvenDRegisterOf(locs()->in(1).fpu_reg());
1654 Register temp = locs()->temp(0).reg(); 1655 Register temp = locs()->temp(0).reg();
1655 Register temp2 = locs()->temp(1).reg(); 1656 Register temp2 = locs()->temp(1).reg();
1657 const intptr_t cid = field().UnboxedFieldCid();
1656 1658
1657 if (is_initialization_) { 1659 if (is_initialization_) {
1660 const Class* cls = NULL;
1661 switch (cid) {
1662 case kDoubleCid:
1663 cls = &compiler->double_class();
1664 break;
1665 // TODO(johnmccutchan): Add kFloat32x4Cid here.
1666 default:
1667 UNREACHABLE();
1668 }
1658 StoreInstanceFieldSlowPath* slow_path = 1669 StoreInstanceFieldSlowPath* slow_path =
1659 new StoreInstanceFieldSlowPath(this); 1670 new StoreInstanceFieldSlowPath(this, *cls);
1660 compiler->AddSlowPathCode(slow_path); 1671 compiler->AddSlowPathCode(slow_path);
1661 __ TryAllocate(compiler->double_class(), 1672 __ TryAllocate(*cls,
1662 slow_path->entry_label(), 1673 slow_path->entry_label(),
1663 temp, 1674 temp,
1664 temp2); 1675 temp2);
1665 __ Bind(slow_path->exit_label()); 1676 __ Bind(slow_path->exit_label());
1666 __ MoveRegister(temp2, temp); 1677 __ MoveRegister(temp2, temp);
1667 __ StoreIntoObject(instance_reg, 1678 __ StoreIntoObject(instance_reg,
1668 FieldAddress(instance_reg, field().Offset()), 1679 FieldAddress(instance_reg, field().Offset()),
1669 temp2); 1680 temp2);
1670 } else { 1681 } else {
1671 __ ldr(temp, FieldAddress(instance_reg, field().Offset())); 1682 __ ldr(temp, FieldAddress(instance_reg, field().Offset()));
1672 } 1683 }
1673 __ StoreDToOffset(value, temp, Double::value_offset() - kHeapObjectTag); 1684 switch (cid) {
1685 case kDoubleCid:
1686 __ StoreDToOffset(value, temp, Double::value_offset() - kHeapObjectTag);
1687 // TODO(johnmccutchan): Add kFloat32x4Cid here.
1688 break;
1689 default:
1690 UNREACHABLE();
1691 }
1692
1674 return; 1693 return;
1675 } 1694 }
1676 1695
1677 if (IsPotentialUnboxedStore()) { 1696 if (IsPotentialUnboxedStore()) {
1678 Register value_reg = locs()->in(1).reg(); 1697 Register value_reg = locs()->in(1).reg();
1679 Register temp = locs()->temp(0).reg(); 1698 Register temp = locs()->temp(0).reg();
1680 Register temp2 = locs()->temp(1).reg(); 1699 Register temp2 = locs()->temp(1).reg();
1681 DRegister fpu_temp = EvenDRegisterOf(locs()->temp(2).fpu_reg()); 1700 DRegister fpu_temp = EvenDRegisterOf(locs()->temp(2).fpu_reg());
1682 1701
1683 Label store_pointer, copy_payload; 1702 Label store_pointer;
1703 Label copy_double;
1704 Label store_double;
1705
1684 __ LoadObject(temp, Field::ZoneHandle(field().raw())); 1706 __ LoadObject(temp, Field::ZoneHandle(field().raw()));
1685 __ ldr(temp2, FieldAddress(temp, Field::guarded_cid_offset())); 1707
1686 __ CompareImmediate(temp2, kDoubleCid);
1687 __ b(&store_pointer, NE);
1688 __ ldr(temp2, FieldAddress(temp, Field::is_nullable_offset())); 1708 __ ldr(temp2, FieldAddress(temp, Field::is_nullable_offset()));
1689 __ CompareImmediate(temp2, kNullCid); 1709 __ CompareImmediate(temp2, kNullCid);
1690 __ b(&store_pointer, EQ); 1710 __ b(&store_pointer, EQ);
1711
1691 __ ldrb(temp2, FieldAddress(temp, Field::kind_bits_offset())); 1712 __ ldrb(temp2, FieldAddress(temp, Field::kind_bits_offset()));
1692 __ tst(temp2, ShifterOperand(1 << Field::kUnboxingCandidateBit)); 1713 __ tst(temp2, ShifterOperand(1 << Field::kUnboxingCandidateBit));
1693 __ b(&store_pointer, EQ); 1714 __ b(&store_pointer, EQ);
1694 1715
1716 __ ldr(temp2, FieldAddress(temp, Field::guarded_cid_offset()));
1717 __ CompareImmediate(temp2, kDoubleCid);
1718 __ b(&store_double, EQ);
1719
1720 // Fall through.
1721 __ b(&store_pointer);
1722
1723 __ Bind(&store_double);
1724
1695 __ ldr(temp, FieldAddress(instance_reg, field().Offset())); 1725 __ ldr(temp, FieldAddress(instance_reg, field().Offset()));
1696 __ CompareImmediate(temp, 1726 __ CompareImmediate(temp,
1697 reinterpret_cast<intptr_t>(Object::null())); 1727 reinterpret_cast<intptr_t>(Object::null()));
1698 __ b(&copy_payload, NE); 1728 __ b(&copy_double, NE);
1699 1729
1700 StoreInstanceFieldSlowPath* slow_path = 1730 StoreInstanceFieldSlowPath* slow_path =
1701 new StoreInstanceFieldSlowPath(this); 1731 new StoreInstanceFieldSlowPath(this, compiler->double_class());
1702 compiler->AddSlowPathCode(slow_path); 1732 compiler->AddSlowPathCode(slow_path);
1703 1733
1704 if (!compiler->is_optimizing()) { 1734 if (!compiler->is_optimizing()) {
1705 locs()->live_registers()->Add(locs()->in(0)); 1735 locs()->live_registers()->Add(locs()->in(0));
1706 locs()->live_registers()->Add(locs()->in(1)); 1736 locs()->live_registers()->Add(locs()->in(1));
1707 } 1737 }
1708 1738
1709 __ TryAllocate(compiler->double_class(), 1739 __ TryAllocate(compiler->double_class(),
1710 slow_path->entry_label(), 1740 slow_path->entry_label(),
1711 temp, 1741 temp,
1712 temp2); 1742 temp2);
1713 __ Bind(slow_path->exit_label()); 1743 __ Bind(slow_path->exit_label());
1714 __ MoveRegister(temp2, temp); 1744 __ MoveRegister(temp2, temp);
1715 __ StoreIntoObject(instance_reg, 1745 __ StoreIntoObject(instance_reg,
1716 FieldAddress(instance_reg, field().Offset()), 1746 FieldAddress(instance_reg, field().Offset()),
1717 temp2); 1747 temp2);
1718 __ Bind(&copy_payload); 1748 __ Bind(&copy_double);
1719 __ LoadDFromOffset(fpu_temp, 1749 __ LoadDFromOffset(fpu_temp,
1720 value_reg, 1750 value_reg,
1721 Double::value_offset() - kHeapObjectTag); 1751 Double::value_offset() - kHeapObjectTag);
1722 __ StoreDToOffset(fpu_temp, temp, Double::value_offset() - kHeapObjectTag); 1752 __ StoreDToOffset(fpu_temp, temp, Double::value_offset() - kHeapObjectTag);
1723 __ b(&skip_store); 1753 __ b(&skip_store);
1724 __ Bind(&store_pointer); 1754 __ Bind(&store_pointer);
1725 } 1755 }
1726 1756
1727 if (ShouldEmitStoreBarrier()) { 1757 if (ShouldEmitStoreBarrier()) {
1728 Register value_reg = locs()->in(1).reg(); 1758 Register value_reg = locs()->in(1).reg();
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after
1919 return locs; 1949 return locs;
1920 } 1950 }
1921 1951
1922 1952
1923 void LoadFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1953 void LoadFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
1924 Register instance_reg = locs()->in(0).reg(); 1954 Register instance_reg = locs()->in(0).reg();
1925 if (IsUnboxedLoad() && compiler->is_optimizing()) { 1955 if (IsUnboxedLoad() && compiler->is_optimizing()) {
1926 DRegister result = EvenDRegisterOf(locs()->out().fpu_reg()); 1956 DRegister result = EvenDRegisterOf(locs()->out().fpu_reg());
1927 Register temp = locs()->temp(0).reg(); 1957 Register temp = locs()->temp(0).reg();
1928 __ ldr(temp, FieldAddress(instance_reg, offset_in_bytes())); 1958 __ ldr(temp, FieldAddress(instance_reg, offset_in_bytes()));
1929 __ LoadDFromOffset(result, temp, Double::value_offset() - kHeapObjectTag); 1959 intptr_t cid = field()->UnboxedFieldCid();
1960 switch (cid) {
1961 case kDoubleCid:
1962 __ LoadDFromOffset(result, temp,
1963 Double::value_offset() - kHeapObjectTag);
1964 break;
1965 // TODO(johnmccutchan): Add Float32x4 path here.
1966 default:
1967 UNREACHABLE();
1968 }
1930 return; 1969 return;
1931 } 1970 }
1932 1971
1933 Label done; 1972 Label done;
1934 Register result_reg = locs()->out().reg(); 1973 Register result_reg = locs()->out().reg();
1935 if (IsPotentialUnboxedLoad()) { 1974 if (IsPotentialUnboxedLoad()) {
1936 Register temp = locs()->temp(1).reg(); 1975 Register temp = locs()->temp(1).reg();
1937 DRegister value = EvenDRegisterOf(locs()->temp(0).fpu_reg()); 1976 DRegister value = EvenDRegisterOf(locs()->temp(0).fpu_reg());
1938 1977
1939 Label load_pointer; 1978 Label load_pointer;
1979 Label load_double;
1980
1940 __ LoadObject(result_reg, Field::ZoneHandle(field()->raw())); 1981 __ LoadObject(result_reg, Field::ZoneHandle(field()->raw()));
1941 1982
1942 FieldAddress field_cid_operand(result_reg, Field::guarded_cid_offset()); 1983 FieldAddress field_cid_operand(result_reg, Field::guarded_cid_offset());
1943 FieldAddress field_nullability_operand(result_reg, 1984 FieldAddress field_nullability_operand(result_reg,
1944 Field::is_nullable_offset()); 1985 Field::is_nullable_offset());
1945 1986
1946 __ ldr(temp, field_cid_operand);
1947 __ CompareImmediate(temp, kDoubleCid);
1948 __ b(&load_pointer, NE);
1949
1950 __ ldr(temp, field_nullability_operand); 1987 __ ldr(temp, field_nullability_operand);
1951 __ CompareImmediate(temp, kNullCid); 1988 __ CompareImmediate(temp, kNullCid);
1952 __ b(&load_pointer, EQ); 1989 __ b(&load_pointer, EQ);
1953 1990
1991 __ ldr(temp, field_cid_operand);
1992 __ CompareImmediate(temp, kDoubleCid);
1993 __ b(&load_double, EQ);
1994
1995 // Fall through.
1996 __ b(&load_pointer);
1997
1998 __ Bind(&load_double);
1999
1954 BoxDoubleSlowPath* slow_path = new BoxDoubleSlowPath(this); 2000 BoxDoubleSlowPath* slow_path = new BoxDoubleSlowPath(this);
1955 compiler->AddSlowPathCode(slow_path); 2001 compiler->AddSlowPathCode(slow_path);
1956 2002
1957 if (!compiler->is_optimizing()) { 2003 if (!compiler->is_optimizing()) {
1958 locs()->live_registers()->Add(locs()->in(0)); 2004 locs()->live_registers()->Add(locs()->in(0));
1959 } 2005 }
1960 2006
1961 __ TryAllocate(compiler->double_class(), 2007 __ TryAllocate(compiler->double_class(),
1962 slow_path->entry_label(), 2008 slow_path->entry_label(),
1963 result_reg, 2009 result_reg,
1964 temp); 2010 temp);
1965 __ Bind(slow_path->exit_label()); 2011 __ Bind(slow_path->exit_label());
1966 __ ldr(temp, FieldAddress(instance_reg, offset_in_bytes())); 2012 __ ldr(temp, FieldAddress(instance_reg, offset_in_bytes()));
1967 __ LoadDFromOffset(value, temp, Double::value_offset() - kHeapObjectTag); 2013 __ LoadDFromOffset(value, temp, Double::value_offset() - kHeapObjectTag);
1968 __ StoreDToOffset(value, 2014 __ StoreDToOffset(value,
1969 result_reg, 2015 result_reg,
1970 Double::value_offset() - kHeapObjectTag); 2016 Double::value_offset() - kHeapObjectTag);
1971 __ b(&done); 2017 __ b(&done);
2018
2019 // TODO(johnmccutchan): Add Float32x4 path here.
2020
1972 __ Bind(&load_pointer); 2021 __ Bind(&load_pointer);
1973 } 2022 }
1974 __ LoadFromOffset(kWord, result_reg, 2023 __ LoadFromOffset(kWord, result_reg,
1975 instance_reg, offset_in_bytes() - kHeapObjectTag); 2024 instance_reg, offset_in_bytes() - kHeapObjectTag);
1976 __ Bind(&done); 2025 __ Bind(&done);
1977 } 2026 }
1978 2027
1979 2028
1980 LocationSummary* InstantiateTypeInstr::MakeLocationSummary(bool opt) const { 2029 LocationSummary* InstantiateTypeInstr::MakeLocationSummary(bool opt) const {
1981 const intptr_t kNumInputs = 1; 2030 const intptr_t kNumInputs = 1;
(...skipping 2856 matching lines...) Expand 10 before | Expand all | Expand 10 after
4838 compiler->GenerateCall(token_pos(), 4887 compiler->GenerateCall(token_pos(),
4839 &label, 4888 &label,
4840 PcDescriptors::kOther, 4889 PcDescriptors::kOther,
4841 locs()); 4890 locs());
4842 __ Drop(2); // Discard type arguments and receiver. 4891 __ Drop(2); // Discard type arguments and receiver.
4843 } 4892 }
4844 4893
4845 } // namespace dart 4894 } // namespace dart
4846 4895
4847 #endif // defined TARGET_ARCH_ARM 4896 #endif // defined TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « runtime/vm/intermediate_language.cc ('k') | runtime/vm/intermediate_language_ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698