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

Side by Side Diff: runtime/vm/intermediate_language_mips.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_ia32.cc ('k') | runtime/vm/intermediate_language_x64.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_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 explicit StoreInstanceFieldSlowPath(StoreInstanceFieldInstr* instruction) 1661 StoreInstanceFieldSlowPath(StoreInstanceFieldInstr* instruction,
1662 : instruction_(instruction) { } 1662 const Class& cls)
1663 : instruction_(instruction), cls_(cls) { }
1663 1664
1664 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { 1665 virtual void EmitNativeCode(FlowGraphCompiler* compiler) {
1665 __ Comment("StoreInstanceFieldSlowPath"); 1666 __ Comment("StoreInstanceFieldSlowPath");
1666 __ Bind(entry_label()); 1667 __ Bind(entry_label());
1667 const Class& double_class = compiler->double_class();
1668 const Code& stub = 1668 const Code& stub =
1669 Code::Handle(StubCode::GetAllocationStubForClass(double_class)); 1669 Code::Handle(StubCode::GetAllocationStubForClass(cls_));
1670 const ExternalLabel label(double_class.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(exit_label());
1684 } 1684 }
1685 1685
1686 private: 1686 private:
1687 StoreInstanceFieldInstr* instruction_; 1687 StoreInstanceFieldInstr* instruction_;
1688 const Class& cls_;
1688 }; 1689 };
1689 1690
1690 1691
1691 LocationSummary* StoreInstanceFieldInstr::MakeLocationSummary(bool opt) const { 1692 LocationSummary* StoreInstanceFieldInstr::MakeLocationSummary(bool opt) const {
1692 const intptr_t kNumInputs = 2; 1693 const intptr_t kNumInputs = 2;
1693 const intptr_t kNumTemps = 0; 1694 const intptr_t kNumTemps = 0;
1694 LocationSummary* summary = 1695 LocationSummary* summary =
1695 new LocationSummary(kNumInputs, kNumTemps, 1696 new LocationSummary(kNumInputs, kNumTemps,
1696 (field().guarded_cid() == kIllegalCid) || (is_initialization_) 1697 (field().guarded_cid() == kIllegalCid) || (is_initialization_)
1697 ? LocationSummary::kCallOnSlowPath 1698 ? LocationSummary::kCallOnSlowPath
(...skipping 23 matching lines...) Expand all
1721 1722
1722 void StoreInstanceFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1723 void StoreInstanceFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
1723 Label skip_store; 1724 Label skip_store;
1724 1725
1725 Register instance_reg = locs()->in(0).reg(); 1726 Register instance_reg = locs()->in(0).reg();
1726 1727
1727 if (IsUnboxedStore() && compiler->is_optimizing()) { 1728 if (IsUnboxedStore() && compiler->is_optimizing()) {
1728 DRegister value = locs()->in(1).fpu_reg(); 1729 DRegister value = locs()->in(1).fpu_reg();
1729 Register temp = locs()->temp(0).reg(); 1730 Register temp = locs()->temp(0).reg();
1730 Register temp2 = locs()->temp(1).reg(); 1731 Register temp2 = locs()->temp(1).reg();
1732 const intptr_t cid = field().UnboxedFieldCid();
1731 1733
1732 if (is_initialization_) { 1734 if (is_initialization_) {
1735 const Class* cls = NULL;
1736 switch (cid) {
1737 case kDoubleCid:
1738 cls = &compiler->double_class();
1739 break;
1740 default:
1741 UNREACHABLE();
1742 }
1733 StoreInstanceFieldSlowPath* slow_path = 1743 StoreInstanceFieldSlowPath* slow_path =
1734 new StoreInstanceFieldSlowPath(this); 1744 new StoreInstanceFieldSlowPath(this, *cls);
1735 compiler->AddSlowPathCode(slow_path); 1745 compiler->AddSlowPathCode(slow_path);
1736 __ TryAllocate(compiler->double_class(), 1746 __ TryAllocate(*cls,
1737 slow_path->entry_label(), 1747 slow_path->entry_label(),
1738 temp, 1748 temp,
1739 temp2); 1749 temp2);
1740 __ Bind(slow_path->exit_label()); 1750 __ Bind(slow_path->exit_label());
1741 __ mov(temp2, temp); 1751 __ mov(temp2, temp);
1742 __ StoreIntoObject(instance_reg, 1752 __ StoreIntoObject(instance_reg,
1743 FieldAddress(instance_reg, field().Offset()), 1753 FieldAddress(instance_reg, field().Offset()),
1744 temp2); 1754 temp2);
1745 } else { 1755 } else {
1746 __ lw(temp, FieldAddress(instance_reg, field().Offset())); 1756 __ lw(temp, FieldAddress(instance_reg, field().Offset()));
1747 } 1757 }
1748 __ StoreDToOffset(value, temp, Double::value_offset() - kHeapObjectTag); 1758 switch (cid) {
1759 case kDoubleCid:
1760 __ StoreDToOffset(value, temp, Double::value_offset() - kHeapObjectTag);
1761 break;
1762 default:
1763 UNREACHABLE();
1764 }
1749 return; 1765 return;
1750 } 1766 }
1751 1767
1752 if (IsPotentialUnboxedStore()) { 1768 if (IsPotentialUnboxedStore()) {
1753 Register value_reg = locs()->in(1).reg(); 1769 Register value_reg = locs()->in(1).reg();
1754 Register temp = locs()->temp(0).reg(); 1770 Register temp = locs()->temp(0).reg();
1755 Register temp2 = locs()->temp(1).reg(); 1771 Register temp2 = locs()->temp(1).reg();
1756 DRegister fpu_temp = locs()->temp(2).fpu_reg(); 1772 DRegister fpu_temp = locs()->temp(2).fpu_reg();
1757 1773
1758 Label store_pointer, copy_payload; 1774 Label store_pointer;
1775 Label copy_double;
1776 Label store_double;
1777
1759 __ LoadObject(temp, Field::ZoneHandle(field().raw())); 1778 __ LoadObject(temp, Field::ZoneHandle(field().raw()));
1760 __ lw(temp2, FieldAddress(temp, Field::guarded_cid_offset())); 1779
1761 __ BranchNotEqual(temp2, kDoubleCid, &store_pointer);
1762 __ lw(temp2, FieldAddress(temp, Field::is_nullable_offset())); 1780 __ lw(temp2, FieldAddress(temp, Field::is_nullable_offset()));
1763 __ BranchEqual(temp2, kNullCid, &store_pointer); 1781 __ BranchEqual(temp2, kNullCid, &store_pointer);
1782
1764 __ lbu(temp2, FieldAddress(temp, Field::kind_bits_offset())); 1783 __ lbu(temp2, FieldAddress(temp, Field::kind_bits_offset()));
1765 __ andi(CMPRES1, temp2, Immediate(1 << Field::kUnboxingCandidateBit)); 1784 __ andi(CMPRES1, temp2, Immediate(1 << Field::kUnboxingCandidateBit));
1766 __ beq(CMPRES1, ZR, &store_pointer); 1785 __ beq(CMPRES1, ZR, &store_pointer);
1767 1786
1787 __ lw(temp2, FieldAddress(temp, Field::guarded_cid_offset()));
1788 __ BranchEqual(temp2, kDoubleCid, &store_double);
1789
1790 // Fall through.
1791 __ b(&store_pointer);
1792
1793 __ Bind(&store_double);
1794
1768 __ lw(temp, FieldAddress(instance_reg, field().Offset())); 1795 __ lw(temp, FieldAddress(instance_reg, field().Offset()));
1769 __ BranchNotEqual(temp, reinterpret_cast<int32_t>(Object::null()), 1796 __ BranchNotEqual(temp, reinterpret_cast<int32_t>(Object::null()),
1770 &copy_payload); 1797 &copy_double);
1771 1798
1772 StoreInstanceFieldSlowPath* slow_path = 1799 StoreInstanceFieldSlowPath* slow_path =
1773 new StoreInstanceFieldSlowPath(this); 1800 new StoreInstanceFieldSlowPath(this, compiler->double_class());
1774 compiler->AddSlowPathCode(slow_path); 1801 compiler->AddSlowPathCode(slow_path);
1775 1802
1776 if (!compiler->is_optimizing()) { 1803 if (!compiler->is_optimizing()) {
1777 locs()->live_registers()->Add(locs()->in(0)); 1804 locs()->live_registers()->Add(locs()->in(0));
1778 locs()->live_registers()->Add(locs()->in(1)); 1805 locs()->live_registers()->Add(locs()->in(1));
1779 } 1806 }
1780 1807
1781 __ TryAllocate(compiler->double_class(), 1808 __ TryAllocate(compiler->double_class(),
1782 slow_path->entry_label(), 1809 slow_path->entry_label(),
1783 temp, 1810 temp,
1784 temp2); 1811 temp2);
1785 __ Bind(slow_path->exit_label()); 1812 __ Bind(slow_path->exit_label());
1786 __ mov(temp2, temp); 1813 __ mov(temp2, temp);
1787 __ StoreIntoObject(instance_reg, 1814 __ StoreIntoObject(instance_reg,
1788 FieldAddress(instance_reg, field().Offset()), 1815 FieldAddress(instance_reg, field().Offset()),
1789 temp2); 1816 temp2);
1790 1817
1791 __ Bind(&copy_payload); 1818 __ Bind(&copy_double);
1792 __ LoadDFromOffset(fpu_temp, 1819 __ LoadDFromOffset(fpu_temp,
1793 value_reg, 1820 value_reg,
1794 Double::value_offset() - kHeapObjectTag); 1821 Double::value_offset() - kHeapObjectTag);
1795 __ StoreDToOffset(fpu_temp, temp, Double::value_offset() - kHeapObjectTag); 1822 __ StoreDToOffset(fpu_temp, temp, Double::value_offset() - kHeapObjectTag);
1796 __ b(&skip_store); 1823 __ b(&skip_store);
1797 __ Bind(&store_pointer); 1824 __ Bind(&store_pointer);
1798 } 1825 }
1799 1826
1800 if (ShouldEmitStoreBarrier()) { 1827 if (ShouldEmitStoreBarrier()) {
1801 Register value_reg = locs()->in(1).reg(); 1828 Register value_reg = locs()->in(1).reg();
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after
1997 return locs; 2024 return locs;
1998 } 2025 }
1999 2026
2000 2027
2001 void LoadFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 2028 void LoadFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
2002 Register instance_reg = locs()->in(0).reg(); 2029 Register instance_reg = locs()->in(0).reg();
2003 if (IsUnboxedLoad() && compiler->is_optimizing()) { 2030 if (IsUnboxedLoad() && compiler->is_optimizing()) {
2004 DRegister result = locs()->out().fpu_reg(); 2031 DRegister result = locs()->out().fpu_reg();
2005 Register temp = locs()->temp(0).reg(); 2032 Register temp = locs()->temp(0).reg();
2006 __ lw(temp, FieldAddress(instance_reg, offset_in_bytes())); 2033 __ lw(temp, FieldAddress(instance_reg, offset_in_bytes()));
2007 __ LoadDFromOffset(result, temp, Double::value_offset() - kHeapObjectTag); 2034 intptr_t cid = field()->UnboxedFieldCid();
2035 switch (cid) {
2036 case kDoubleCid:
2037 __ LoadDFromOffset(result, temp,
2038 Double::value_offset() - kHeapObjectTag);
2039 break;
2040 default:
2041 UNREACHABLE();
2042 }
2008 return; 2043 return;
2009 } 2044 }
2010 2045
2011 Label done; 2046 Label done;
2012 Register result_reg = locs()->out().reg(); 2047 Register result_reg = locs()->out().reg();
2013 if (IsPotentialUnboxedLoad()) { 2048 if (IsPotentialUnboxedLoad()) {
2014 Register temp = locs()->temp(1).reg(); 2049 Register temp = locs()->temp(1).reg();
2015 DRegister value = locs()->temp(0).fpu_reg(); 2050 DRegister value = locs()->temp(0).fpu_reg();
2016 2051
2017 Label load_pointer; 2052 Label load_pointer;
2053 Label load_double;
2054
2018 __ LoadObject(result_reg, Field::ZoneHandle(field()->raw())); 2055 __ LoadObject(result_reg, Field::ZoneHandle(field()->raw()));
2019 2056
2020 FieldAddress field_cid_operand(result_reg, Field::guarded_cid_offset()); 2057 FieldAddress field_cid_operand(result_reg, Field::guarded_cid_offset());
2021 FieldAddress field_nullability_operand(result_reg, 2058 FieldAddress field_nullability_operand(result_reg,
2022 Field::is_nullable_offset()); 2059 Field::is_nullable_offset());
2023 2060
2024 __ lw(temp, field_cid_operand);
2025 __ BranchNotEqual(temp, kDoubleCid, &load_pointer);
2026
2027 __ lw(temp, field_nullability_operand); 2061 __ lw(temp, field_nullability_operand);
2028 __ BranchEqual(temp, kNullCid, &load_pointer); 2062 __ BranchEqual(temp, kNullCid, &load_pointer);
2029 2063
2064 __ lw(temp, field_cid_operand);
2065 __ BranchEqual(temp, kDoubleCid, &load_double);
2066
2067 // Fall through.
2068 __ b(&load_pointer);
2069
2070 __ Bind(&load_double);
2071
2030 BoxDoubleSlowPath* slow_path = new BoxDoubleSlowPath(this); 2072 BoxDoubleSlowPath* slow_path = new BoxDoubleSlowPath(this);
2031 compiler->AddSlowPathCode(slow_path); 2073 compiler->AddSlowPathCode(slow_path);
2032 2074
2033 if (!compiler->is_optimizing()) { 2075 if (!compiler->is_optimizing()) {
2034 locs()->live_registers()->Add(locs()->in(0)); 2076 locs()->live_registers()->Add(locs()->in(0));
2035 } 2077 }
2036 2078
2037 __ TryAllocate(compiler->double_class(), 2079 __ TryAllocate(compiler->double_class(),
2038 slow_path->entry_label(), 2080 slow_path->entry_label(),
2039 result_reg, 2081 result_reg,
(...skipping 2162 matching lines...) Expand 10 before | Expand all | Expand 10 after
4202 compiler->GenerateCall(token_pos(), 4244 compiler->GenerateCall(token_pos(),
4203 &label, 4245 &label,
4204 PcDescriptors::kOther, 4246 PcDescriptors::kOther,
4205 locs()); 4247 locs());
4206 __ Drop(2); // Discard type arguments and receiver. 4248 __ Drop(2); // Discard type arguments and receiver.
4207 } 4249 }
4208 4250
4209 } // namespace dart 4251 } // namespace dart
4210 4252
4211 #endif // defined TARGET_ARCH_MIPS 4253 #endif // defined TARGET_ARCH_MIPS
OLDNEW
« no previous file with comments | « runtime/vm/intermediate_language_ia32.cc ('k') | runtime/vm/intermediate_language_x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698