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

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
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 explicit StoreInstanceFieldSlowPath(const Class& cls,
1662 : instruction_(instruction) { } 1662 StoreInstanceFieldInstr* instruction)
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(*cls, this);
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(compiler->double_class(), this);
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 194 matching lines...) Expand 10 before | Expand all | Expand 10 after
1996 return locs; 2023 return locs;
1997 } 2024 }
1998 2025
1999 2026
2000 void LoadFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 2027 void LoadFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
2001 Register instance_reg = locs()->in(0).reg(); 2028 Register instance_reg = locs()->in(0).reg();
2002 if (IsUnboxedLoad() && compiler->is_optimizing()) { 2029 if (IsUnboxedLoad() && compiler->is_optimizing()) {
2003 DRegister result = locs()->out().fpu_reg(); 2030 DRegister result = locs()->out().fpu_reg();
2004 Register temp = locs()->temp(0).reg(); 2031 Register temp = locs()->temp(0).reg();
2005 __ lw(temp, FieldAddress(instance_reg, offset_in_bytes())); 2032 __ lw(temp, FieldAddress(instance_reg, offset_in_bytes()));
2006 __ LoadDFromOffset(result, temp, Double::value_offset() - kHeapObjectTag); 2033 intptr_t cid = field()->UnboxedFieldCid();
2034 switch (cid) {
2035 case kDoubleCid:
2036 __ LoadDFromOffset(result, temp,
2037 Double::value_offset() - kHeapObjectTag);
2038 break;
2039 default:
2040 UNREACHABLE();
2041 }
2007 return; 2042 return;
2008 } 2043 }
2009 2044
2010 Label done; 2045 Label done;
2011 Register result_reg = locs()->out().reg(); 2046 Register result_reg = locs()->out().reg();
2012 if (IsPotentialUnboxedLoad()) { 2047 if (IsPotentialUnboxedLoad()) {
2013 Register temp = locs()->temp(1).reg(); 2048 Register temp = locs()->temp(1).reg();
2014 DRegister value = locs()->temp(0).fpu_reg(); 2049 DRegister value = locs()->temp(0).fpu_reg();
2015 2050
2016 Label load_pointer; 2051 Label load_pointer;
2052 Label load_double;
2053
2017 __ LoadObject(result_reg, Field::ZoneHandle(field()->raw())); 2054 __ LoadObject(result_reg, Field::ZoneHandle(field()->raw()));
2018 2055
2019 FieldAddress field_cid_operand(result_reg, Field::guarded_cid_offset()); 2056 FieldAddress field_cid_operand(result_reg, Field::guarded_cid_offset());
2020 FieldAddress field_nullability_operand(result_reg, 2057 FieldAddress field_nullability_operand(result_reg,
2021 Field::is_nullable_offset()); 2058 Field::is_nullable_offset());
2022 2059
2023 __ lw(temp, field_cid_operand);
2024 __ BranchNotEqual(temp, kDoubleCid, &load_pointer);
2025
2026 __ lw(temp, field_nullability_operand); 2060 __ lw(temp, field_nullability_operand);
2027 __ BranchEqual(temp, kNullCid, &load_pointer); 2061 __ BranchEqual(temp, kNullCid, &load_pointer);
2028 2062
2063 __ lw(temp, field_cid_operand);
2064 __ BranchEqual(temp, kDoubleCid, &load_double);
2065
2066 // Fall through.
2067 __ b(&load_pointer);
2068
2069 __ Bind(&load_double);
2070
2029 BoxDoubleSlowPath* slow_path = new BoxDoubleSlowPath(this); 2071 BoxDoubleSlowPath* slow_path = new BoxDoubleSlowPath(this);
2030 compiler->AddSlowPathCode(slow_path); 2072 compiler->AddSlowPathCode(slow_path);
2031 2073
2032 if (!compiler->is_optimizing()) { 2074 if (!compiler->is_optimizing()) {
2033 locs()->live_registers()->Add(locs()->in(0)); 2075 locs()->live_registers()->Add(locs()->in(0));
2034 } 2076 }
2035 2077
2036 __ TryAllocate(compiler->double_class(), 2078 __ TryAllocate(compiler->double_class(),
2037 slow_path->entry_label(), 2079 slow_path->entry_label(),
2038 result_reg, 2080 result_reg,
(...skipping 2162 matching lines...) Expand 10 before | Expand all | Expand 10 after
4201 compiler->GenerateCall(token_pos(), 4243 compiler->GenerateCall(token_pos(),
4202 &label, 4244 &label,
4203 PcDescriptors::kOther, 4245 PcDescriptors::kOther,
4204 locs()); 4246 locs());
4205 __ Drop(2); // Discard type arguments and receiver. 4247 __ Drop(2); // Discard type arguments and receiver.
4206 } 4248 }
4207 4249
4208 } // namespace dart 4250 } // namespace dart
4209 4251
4210 #endif // defined TARGET_ARCH_MIPS 4252 #endif // defined TARGET_ARCH_MIPS
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698