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

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

Issue 150063004: Support reusable boxes for Float32x4 fields (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
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_MIPS. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_MIPS.
6 #if defined(TARGET_ARCH_MIPS) 6 #if defined(TARGET_ARCH_MIPS)
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 1640 matching lines...) Expand 10 before | Expand all | Expand 10 after
1651 UNREACHABLE(); 1651 UNREACHABLE();
1652 } 1652 }
1653 } 1653 }
1654 } 1654 }
1655 __ Bind(&ok); 1655 __ Bind(&ok);
1656 } 1656 }
1657 1657
1658 1658
1659 class StoreInstanceFieldSlowPath : public SlowPathCode { 1659 class StoreInstanceFieldSlowPath : public SlowPathCode {
1660 public: 1660 public:
1661 StoreInstanceFieldSlowPath(StoreInstanceFieldInstr* instruction, 1661 explicit StoreInstanceFieldSlowPath(StoreInstanceFieldInstr* instruction)
1662 const Class& cls) 1662 : instruction_(instruction) { }
1663 : instruction_(instruction), cls_(cls) { }
1664 1663
1665 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { 1664 virtual void EmitNativeCode(FlowGraphCompiler* compiler) {
1666 __ Comment("StoreInstanceFieldSlowPath"); 1665 __ Comment("StoreInstanceFieldSlowPath");
1667 __ Bind(entry_label()); 1666 __ Bind(double_entry_label());
1667 const Class& cls = compiler->double_class();
1668 const Code& stub = 1668 const Code& stub =
1669 Code::Handle(StubCode::GetAllocationStubForClass(cls_)); 1669 Code::Handle(StubCode::GetAllocationStubForClass(cls));
1670 const ExternalLabel label(cls_.ToCString(), stub.EntryPoint()); 1670 const ExternalLabel label(cls.ToCString(), stub.EntryPoint());
1671 1671
1672 LocationSummary* locs = instruction_->locs(); 1672 LocationSummary* locs = instruction_->locs();
1673 locs->live_registers()->Remove(locs->out()); 1673 locs->live_registers()->Remove(locs->out());
1674 1674
1675 compiler->SaveLiveRegisters(locs); 1675 compiler->SaveLiveRegisters(locs);
1676 compiler->GenerateCall(Scanner::kNoSourcePos, // No token position. 1676 compiler->GenerateCall(Scanner::kNoSourcePos, // No token position.
1677 &label, 1677 &label,
1678 PcDescriptors::kOther, 1678 PcDescriptors::kOther,
1679 locs); 1679 locs);
1680 __ mov(locs->temp(0).reg(), V0); 1680 __ mov(locs->temp(0).reg(), V0);
1681 compiler->RestoreLiveRegisters(locs); 1681 compiler->RestoreLiveRegisters(locs);
1682 1682
1683 __ b(exit_label()); 1683 __ b(double_exit_label());
1684 }
1685
1686 Label* double_entry_label() {
1687 // Use default SlowPathCode label for double.
1688 return entry_label();
1689 }
1690 Label* double_exit_label() {
1691 // Use default SlowPathCode label for double.
1692 return exit_label();
1684 } 1693 }
1685 1694
1686 private: 1695 private:
1687 StoreInstanceFieldInstr* instruction_; 1696 StoreInstanceFieldInstr* instruction_;
1688 const Class& cls_;
1689 }; 1697 };
1690 1698
1691 1699
1692 LocationSummary* StoreInstanceFieldInstr::MakeLocationSummary(bool opt) const { 1700 LocationSummary* StoreInstanceFieldInstr::MakeLocationSummary(bool opt) const {
1693 const intptr_t kNumInputs = 2; 1701 const intptr_t kNumInputs = 2;
1694 const intptr_t kNumTemps = 0; 1702 const intptr_t kNumTemps = 0;
1695 LocationSummary* summary = 1703 LocationSummary* summary =
1696 new LocationSummary(kNumInputs, kNumTemps, 1704 new LocationSummary(kNumInputs, kNumTemps,
1697 (field().guarded_cid() == kIllegalCid) || (is_initialization_) 1705 (field().guarded_cid() == kIllegalCid) || (is_initialization_)
1698 ? LocationSummary::kCallOnSlowPath 1706 ? LocationSummary::kCallOnSlowPath
(...skipping 24 matching lines...) Expand all
1723 void StoreInstanceFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1731 void StoreInstanceFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
1724 Label skip_store; 1732 Label skip_store;
1725 1733
1726 Register instance_reg = locs()->in(0).reg(); 1734 Register instance_reg = locs()->in(0).reg();
1727 1735
1728 if (IsUnboxedStore() && compiler->is_optimizing()) { 1736 if (IsUnboxedStore() && compiler->is_optimizing()) {
1729 DRegister value = locs()->in(1).fpu_reg(); 1737 DRegister value = locs()->in(1).fpu_reg();
1730 Register temp = locs()->temp(0).reg(); 1738 Register temp = locs()->temp(0).reg();
1731 Register temp2 = locs()->temp(1).reg(); 1739 Register temp2 = locs()->temp(1).reg();
1732 const intptr_t cid = field().UnboxedFieldCid(); 1740 const intptr_t cid = field().UnboxedFieldCid();
1741 StoreInstanceFieldSlowPath* slow_path =
1742 new StoreInstanceFieldSlowPath(this);
1743 compiler->AddSlowPathCode(slow_path);
1733 1744
1734 if (is_initialization_) { 1745 if (is_initialization_) {
1735 const Class* cls = NULL; 1746 const Class* cls = NULL;
1747 Label* entry_label = NULL;
1748 Label* exit_label = NULL;
1736 switch (cid) { 1749 switch (cid) {
1737 case kDoubleCid: 1750 case kDoubleCid:
1738 cls = &compiler->double_class(); 1751 cls = &compiler->double_class();
1752 entry_label = slow_path->double_entry_label();
1753 exit_label = slow_path->double_exit_label();
1739 break; 1754 break;
1740 default: 1755 default:
1741 UNREACHABLE(); 1756 UNREACHABLE();
1742 } 1757 }
1743 StoreInstanceFieldSlowPath* slow_path =
1744 new StoreInstanceFieldSlowPath(this, *cls);
1745 compiler->AddSlowPathCode(slow_path);
1746 __ TryAllocate(*cls, 1758 __ TryAllocate(*cls,
1747 slow_path->entry_label(), 1759 entry_label,
1748 temp, 1760 temp,
1749 temp2); 1761 temp2);
1750 __ Bind(slow_path->exit_label()); 1762 __ Bind(exit_label);
1751 __ mov(temp2, temp); 1763 __ mov(temp2, temp);
1752 __ StoreIntoObject(instance_reg, 1764 __ StoreIntoObject(instance_reg,
1753 FieldAddress(instance_reg, field().Offset()), 1765 FieldAddress(instance_reg, field().Offset()),
1754 temp2); 1766 temp2);
1755 } else { 1767 } else {
1756 __ lw(temp, FieldAddress(instance_reg, field().Offset())); 1768 __ lw(temp, FieldAddress(instance_reg, field().Offset()));
1757 } 1769 }
1758 switch (cid) { 1770 switch (cid) {
1759 case kDoubleCid: 1771 case kDoubleCid:
1760 __ StoreDToOffset(value, temp, Double::value_offset() - kHeapObjectTag); 1772 __ StoreDToOffset(value, temp, Double::value_offset() - kHeapObjectTag);
(...skipping 29 matching lines...) Expand all
1790 // Fall through. 1802 // Fall through.
1791 __ b(&store_pointer); 1803 __ b(&store_pointer);
1792 1804
1793 __ Bind(&store_double); 1805 __ Bind(&store_double);
1794 1806
1795 __ lw(temp, FieldAddress(instance_reg, field().Offset())); 1807 __ lw(temp, FieldAddress(instance_reg, field().Offset()));
1796 __ BranchNotEqual(temp, reinterpret_cast<int32_t>(Object::null()), 1808 __ BranchNotEqual(temp, reinterpret_cast<int32_t>(Object::null()),
1797 &copy_double); 1809 &copy_double);
1798 1810
1799 StoreInstanceFieldSlowPath* slow_path = 1811 StoreInstanceFieldSlowPath* slow_path =
1800 new StoreInstanceFieldSlowPath(this, compiler->double_class()); 1812 new StoreInstanceFieldSlowPath(this);
1801 compiler->AddSlowPathCode(slow_path); 1813 compiler->AddSlowPathCode(slow_path);
1802 1814
1803 if (!compiler->is_optimizing()) { 1815 if (!compiler->is_optimizing()) {
1804 locs()->live_registers()->Add(locs()->in(0)); 1816 locs()->live_registers()->Add(locs()->in(0));
1805 locs()->live_registers()->Add(locs()->in(1)); 1817 locs()->live_registers()->Add(locs()->in(1));
1806 } 1818 }
1807 1819
1808 __ TryAllocate(compiler->double_class(), 1820 __ TryAllocate(compiler->double_class(),
1809 slow_path->entry_label(), 1821 slow_path->double_entry_label(),
1810 temp, 1822 temp,
1811 temp2); 1823 temp2);
1812 __ Bind(slow_path->exit_label()); 1824 __ Bind(slow_path->double_exit_label());
1813 __ mov(temp2, temp); 1825 __ mov(temp2, temp);
1814 __ StoreIntoObject(instance_reg, 1826 __ StoreIntoObject(instance_reg,
1815 FieldAddress(instance_reg, field().Offset()), 1827 FieldAddress(instance_reg, field().Offset()),
1816 temp2); 1828 temp2);
1817 1829
1818 __ Bind(&copy_double); 1830 __ Bind(&copy_double);
1819 __ LoadDFromOffset(fpu_temp, 1831 __ LoadDFromOffset(fpu_temp,
1820 value_reg, 1832 value_reg,
1821 Double::value_offset() - kHeapObjectTag); 1833 Double::value_offset() - kHeapObjectTag);
1822 __ StoreDToOffset(fpu_temp, temp, Double::value_offset() - kHeapObjectTag); 1834 __ StoreDToOffset(fpu_temp, temp, Double::value_offset() - kHeapObjectTag);
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after
1960 deopt_id(), 1972 deopt_id(),
1961 kAllocateObjectWithBoundsCheckRuntimeEntry, 1973 kAllocateObjectWithBoundsCheckRuntimeEntry,
1962 3, 1974 3,
1963 locs()); 1975 locs());
1964 __ Drop(3); 1976 __ Drop(3);
1965 ASSERT(locs()->out().reg() == V0); 1977 ASSERT(locs()->out().reg() == V0);
1966 __ Pop(V0); // Pop new instance. 1978 __ Pop(V0); // Pop new instance.
1967 } 1979 }
1968 1980
1969 1981
1970 class BoxDoubleSlowPath : public SlowPathCode { 1982 class LoadFieldSlowPath : public SlowPathCode {
1971 public: 1983 public:
1972 explicit BoxDoubleSlowPath(Instruction* instruction) 1984 explicit LoadFieldSlowPath(Instruction* instruction)
1973 : instruction_(instruction) { } 1985 : instruction_(instruction) { }
1974 1986
1975 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { 1987 virtual void EmitNativeCode(FlowGraphCompiler* compiler) {
1976 __ Comment("BoxDoubleSlowPath"); 1988 __ Comment("LoadFieldSlowPath");
1977 __ Bind(entry_label()); 1989 __ Bind(entry_label());
1978 const Class& double_class = compiler->double_class(); 1990 const Class& double_class = compiler->double_class();
1979 const Code& stub = 1991 const Code& stub =
1980 Code::Handle(StubCode::GetAllocationStubForClass(double_class)); 1992 Code::Handle(StubCode::GetAllocationStubForClass(double_class));
1981 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint()); 1993 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint());
1982 1994
1983 LocationSummary* locs = instruction_->locs(); 1995 LocationSummary* locs = instruction_->locs();
1984 locs->live_registers()->Remove(locs->out()); 1996 locs->live_registers()->Remove(locs->out());
1985 1997
1986 compiler->SaveLiveRegisters(locs); 1998 compiler->SaveLiveRegisters(locs);
1987 compiler->GenerateCall(Scanner::kNoSourcePos, // No token position. 1999 compiler->GenerateCall(Scanner::kNoSourcePos, // No token position.
1988 &label, 2000 &label,
1989 PcDescriptors::kOther, 2001 PcDescriptors::kOther,
1990 locs); 2002 locs);
1991 if (locs->out().reg() != V0) { 2003 if (locs->out().reg() != V0) {
1992 __ mov(locs->out().reg(), V0); 2004 __ mov(locs->out().reg(), V0);
1993 } 2005 }
1994 compiler->RestoreLiveRegisters(locs); 2006 compiler->RestoreLiveRegisters(locs);
1995 2007
1996 __ b(exit_label()); 2008 __ b(exit_label());
1997 } 2009 }
1998 2010
2011 Label* double_entry_label() {
2012 // Use default SlowPathCode label for double.
2013 return entry_label();
2014 }
2015 Label* double_exit_label() {
2016 // Use default SlowPathCode label for double.
2017 return exit_label();
2018 }
2019
1999 private: 2020 private:
2000 Instruction* instruction_; 2021 Instruction* instruction_;
2001 }; 2022 };
2002 2023
2003 2024
2004 LocationSummary* LoadFieldInstr::MakeLocationSummary(bool opt) const { 2025 LocationSummary* LoadFieldInstr::MakeLocationSummary(bool opt) const {
2005 const intptr_t kNumInputs = 1; 2026 const intptr_t kNumInputs = 1;
2006 const intptr_t kNumTemps = 0; 2027 const intptr_t kNumTemps = 0;
2007 LocationSummary* locs = 2028 LocationSummary* locs =
2008 new LocationSummary( 2029 new LocationSummary(
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
2041 UNREACHABLE(); 2062 UNREACHABLE();
2042 } 2063 }
2043 return; 2064 return;
2044 } 2065 }
2045 2066
2046 Label done; 2067 Label done;
2047 Register result_reg = locs()->out().reg(); 2068 Register result_reg = locs()->out().reg();
2048 if (IsPotentialUnboxedLoad()) { 2069 if (IsPotentialUnboxedLoad()) {
2049 Register temp = locs()->temp(1).reg(); 2070 Register temp = locs()->temp(1).reg();
2050 DRegister value = locs()->temp(0).fpu_reg(); 2071 DRegister value = locs()->temp(0).fpu_reg();
2072 LoadFieldSlowPath* slow_path = new LoadFieldSlowPath(this);
2073 compiler->AddSlowPathCode(slow_path);
2051 2074
2052 Label load_pointer; 2075 Label load_pointer;
2053 Label load_double; 2076 Label load_double;
2054 2077
2055 __ LoadObject(result_reg, Field::ZoneHandle(field()->raw())); 2078 __ LoadObject(result_reg, Field::ZoneHandle(field()->raw()));
2056 2079
2057 FieldAddress field_cid_operand(result_reg, Field::guarded_cid_offset()); 2080 FieldAddress field_cid_operand(result_reg, Field::guarded_cid_offset());
2058 FieldAddress field_nullability_operand(result_reg, 2081 FieldAddress field_nullability_operand(result_reg,
2059 Field::is_nullable_offset()); 2082 Field::is_nullable_offset());
2060 2083
2061 __ lw(temp, field_nullability_operand); 2084 __ lw(temp, field_nullability_operand);
2062 __ BranchEqual(temp, kNullCid, &load_pointer); 2085 __ BranchEqual(temp, kNullCid, &load_pointer);
2063 2086
2064 __ lw(temp, field_cid_operand); 2087 __ lw(temp, field_cid_operand);
2065 __ BranchEqual(temp, kDoubleCid, &load_double); 2088 __ BranchEqual(temp, kDoubleCid, &load_double);
2066 2089
2067 // Fall through. 2090 // Fall through.
2068 __ b(&load_pointer); 2091 __ b(&load_pointer);
2069 2092
2070 __ Bind(&load_double); 2093 {
2094 __ Bind(&load_double);
2071 2095
2072 BoxDoubleSlowPath* slow_path = new BoxDoubleSlowPath(this); 2096 if (!compiler->is_optimizing()) {
2073 compiler->AddSlowPathCode(slow_path); 2097 locs()->live_registers()->Add(locs()->in(0));
2098 }
2074 2099
2075 if (!compiler->is_optimizing()) { 2100 __ TryAllocate(compiler->double_class(),
2076 locs()->live_registers()->Add(locs()->in(0)); 2101 slow_path->double_entry_label(),
2102 result_reg,
2103 temp);
2104 __ Bind(slow_path->double_exit_label());
2105 __ lw(temp, FieldAddress(instance_reg, offset_in_bytes()));
2106 __ LoadDFromOffset(value, temp, Double::value_offset() - kHeapObjectTag);
2107 __ StoreDToOffset(value,
2108 result_reg,
2109 Double::value_offset() - kHeapObjectTag);
2110 __ b(&done);
2077 } 2111 }
2078 2112
2079 __ TryAllocate(compiler->double_class(),
2080 slow_path->entry_label(),
2081 result_reg,
2082 temp);
2083 __ Bind(slow_path->exit_label());
2084 __ lw(temp, FieldAddress(instance_reg, offset_in_bytes()));
2085 __ LoadDFromOffset(value, temp, Double::value_offset() - kHeapObjectTag);
2086 __ StoreDToOffset(value,
2087 result_reg,
2088 Double::value_offset() - kHeapObjectTag);
2089 __ b(&done);
2090 __ Bind(&load_pointer); 2113 __ Bind(&load_pointer);
2091 } 2114 }
2092 __ lw(result_reg, Address(instance_reg, offset_in_bytes() - kHeapObjectTag)); 2115 __ lw(result_reg, Address(instance_reg, offset_in_bytes() - kHeapObjectTag));
2093 __ Bind(&done); 2116 __ Bind(&done);
2094 } 2117 }
2095 2118
2096 2119
2097 LocationSummary* InstantiateTypeInstr::MakeLocationSummary(bool opt) const { 2120 LocationSummary* InstantiateTypeInstr::MakeLocationSummary(bool opt) const {
2098 const intptr_t kNumInputs = 1; 2121 const intptr_t kNumInputs = 1;
2099 const intptr_t kNumTemps = 0; 2122 const intptr_t kNumTemps = 0;
(...skipping 828 matching lines...) Expand 10 before | Expand all | Expand 10 after
2928 } else if (right_cid == kSmiCid) { 2951 } else if (right_cid == kSmiCid) {
2929 __ andi(CMPRES1, left, Immediate(kSmiTagMask)); 2952 __ andi(CMPRES1, left, Immediate(kSmiTagMask));
2930 } else { 2953 } else {
2931 __ or_(TMP, left, right); 2954 __ or_(TMP, left, right);
2932 __ andi(CMPRES1, TMP, Immediate(kSmiTagMask)); 2955 __ andi(CMPRES1, TMP, Immediate(kSmiTagMask));
2933 } 2956 }
2934 __ beq(CMPRES1, ZR, deopt); 2957 __ beq(CMPRES1, ZR, deopt);
2935 } 2958 }
2936 2959
2937 2960
2961 class BoxDoubleSlowPath : public SlowPathCode {
2962 public:
2963 explicit BoxDoubleSlowPath(Instruction* instruction)
2964 : instruction_(instruction) { }
2965
2966 virtual void EmitNativeCode(FlowGraphCompiler* compiler) {
2967 __ Comment("BoxDoubleSlowPath");
2968 __ Bind(entry_label());
2969 const Class& double_class = compiler->double_class();
2970 const Code& stub =
2971 Code::Handle(StubCode::GetAllocationStubForClass(double_class));
2972 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint());
2973
2974 LocationSummary* locs = instruction_->locs();
2975 locs->live_registers()->Remove(locs->out());
2976
2977 compiler->SaveLiveRegisters(locs);
2978 compiler->GenerateCall(Scanner::kNoSourcePos, // No token position.
2979 &label,
2980 PcDescriptors::kOther,
2981 locs);
2982 if (locs->out().reg() != V0) {
2983 __ mov(locs->out().reg(), V0);
2984 }
2985 compiler->RestoreLiveRegisters(locs);
2986
2987 __ b(exit_label());
2988 }
2989
2990 private:
2991 Instruction* instruction_;
2992 };
2993
2994
2938 LocationSummary* BoxDoubleInstr::MakeLocationSummary(bool opt) const { 2995 LocationSummary* BoxDoubleInstr::MakeLocationSummary(bool opt) const {
2939 const intptr_t kNumInputs = 1; 2996 const intptr_t kNumInputs = 1;
2940 const intptr_t kNumTemps = 1; 2997 const intptr_t kNumTemps = 1;
2941 LocationSummary* summary = 2998 LocationSummary* summary =
2942 new LocationSummary(kNumInputs, 2999 new LocationSummary(kNumInputs,
2943 kNumTemps, 3000 kNumTemps,
2944 LocationSummary::kCallOnSlowPath); 3001 LocationSummary::kCallOnSlowPath);
2945 summary->set_in(0, Location::RequiresFpuRegister()); 3002 summary->set_in(0, Location::RequiresFpuRegister());
2946 summary->set_temp(0, Location::RequiresRegister()); 3003 summary->set_temp(0, Location::RequiresRegister());
2947 summary->set_out(Location::RequiresRegister()); 3004 summary->set_out(Location::RequiresRegister());
(...skipping 1296 matching lines...) Expand 10 before | Expand all | Expand 10 after
4244 compiler->GenerateCall(token_pos(), 4301 compiler->GenerateCall(token_pos(),
4245 &label, 4302 &label,
4246 PcDescriptors::kOther, 4303 PcDescriptors::kOther,
4247 locs()); 4304 locs());
4248 __ Drop(2); // Discard type arguments and receiver. 4305 __ Drop(2); // Discard type arguments and receiver.
4249 } 4306 }
4250 4307
4251 } // namespace dart 4308 } // namespace dart
4252 4309
4253 #endif // defined TARGET_ARCH_MIPS 4310 #endif // defined TARGET_ARCH_MIPS
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698