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

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

Issue 410333003: Shorter TryAllocate instruction sequence on ARM/ARM64/MIPS. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 4 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 1656 matching lines...) Expand 10 before | Expand all | Expand 10 after
1667 1667
1668 __ lw(CMPRES1, 1668 __ lw(CMPRES1,
1669 FieldAddress(value_reg, 1669 FieldAddress(value_reg,
1670 field().guarded_list_length_in_object_offset())); 1670 field().guarded_list_length_in_object_offset()));
1671 __ LoadImmediate(TMP, Smi::RawValue(field().guarded_list_length())); 1671 __ LoadImmediate(TMP, Smi::RawValue(field().guarded_list_length()));
1672 __ bne(CMPRES1, TMP, deopt); 1672 __ bne(CMPRES1, TMP, deopt);
1673 } 1673 }
1674 } 1674 }
1675 1675
1676 1676
1677 class StoreInstanceFieldSlowPath : public SlowPathCode { 1677 class BoxAllocationSlowPath : public SlowPathCode {
1678 public: 1678 public:
1679 StoreInstanceFieldSlowPath(StoreInstanceFieldInstr* instruction, 1679 BoxAllocationSlowPath(Instruction* instruction,
1680 const Class& cls) 1680 const Class& cls,
1681 : instruction_(instruction), cls_(cls) { } 1681 Register result)
1682 : instruction_(instruction),
1683 cls_(cls),
1684 result_(result) { }
1682 1685
1683 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { 1686 virtual void EmitNativeCode(FlowGraphCompiler* compiler) {
1684 Isolate* isolate = compiler->isolate(); 1687 Isolate* isolate = compiler->isolate();
1685 StubCode* stub_code = isolate->stub_code(); 1688 StubCode* stub_code = isolate->stub_code();
1686 1689
1687 __ Comment("StoreInstanceFieldSlowPath"); 1690 if (Assembler::EmittingComments()) {
1691 __ Comment("%s slow path allocation of %s",
1692 instruction_->DebugName(),
1693 String::Handle(cls_.PrettyName()).ToCString());
1694 }
1688 __ Bind(entry_label()); 1695 __ Bind(entry_label());
1689 const Code& stub = 1696 const Code& stub =
1690 Code::Handle(isolate, stub_code->GetAllocationStubForClass(cls_)); 1697 Code::Handle(isolate, stub_code->GetAllocationStubForClass(cls_));
1691 const ExternalLabel label(stub.EntryPoint()); 1698 const ExternalLabel label(stub.EntryPoint());
1692 1699
1693 LocationSummary* locs = instruction_->locs(); 1700 LocationSummary* locs = instruction_->locs();
1694 locs->live_registers()->Remove(locs->temp(0)); 1701 locs->live_registers()->Remove(Location::RegisterLocation(result_));
1695 1702
1696 compiler->SaveLiveRegisters(locs); 1703 compiler->SaveLiveRegisters(locs);
1697 compiler->GenerateCall(Scanner::kNoSourcePos, // No token position. 1704 compiler->GenerateCall(Scanner::kNoSourcePos, // No token position.
1698 &label, 1705 &label,
1699 RawPcDescriptors::kOther, 1706 RawPcDescriptors::kOther,
1700 locs); 1707 locs);
1701 __ mov(locs->temp(0).reg(), V0); 1708 if (result_ != V0) {
1709 __ mov(result_, V0);
1710 }
1702 compiler->RestoreLiveRegisters(locs); 1711 compiler->RestoreLiveRegisters(locs);
1703 1712
1704 __ b(exit_label()); 1713 __ b(exit_label());
1705 } 1714 }
1706 1715
1716 static void Allocate(FlowGraphCompiler* compiler,
1717 Instruction* instruction,
1718 const Class& cls,
1719 Register result,
1720 Register temp) {
1721 BoxAllocationSlowPath* slow_path =
1722 new BoxAllocationSlowPath(instruction, cls, result);
1723 compiler->AddSlowPathCode(slow_path);
1724
1725 __ TryAllocate(cls,
1726 slow_path->entry_label(),
1727 result,
1728 temp);
1729 __ Bind(slow_path->exit_label());
1730 }
1731
1707 private: 1732 private:
1708 StoreInstanceFieldInstr* instruction_; 1733 Instruction* instruction_;
1709 const Class& cls_; 1734 const Class& cls_;
1735 Register result_;
1710 }; 1736 };
1711 1737
1712 1738
1713 LocationSummary* StoreInstanceFieldInstr::MakeLocationSummary(Isolate* isolate, 1739 LocationSummary* StoreInstanceFieldInstr::MakeLocationSummary(Isolate* isolate,
1714 bool opt) const { 1740 bool opt) const {
1715 const intptr_t kNumInputs = 2; 1741 const intptr_t kNumInputs = 2;
1716 const intptr_t kNumTemps = 1742 const intptr_t kNumTemps =
1717 (IsUnboxedStore() && opt) ? 2 : 1743 (IsUnboxedStore() && opt) ? 2 :
1718 ((IsPotentialUnboxedStore()) ? 3 : 0); 1744 ((IsPotentialUnboxedStore()) ? 3 : 0);
1719 LocationSummary* summary = new(isolate) LocationSummary( 1745 LocationSummary* summary = new(isolate) LocationSummary(
(...skipping 18 matching lines...) Expand all
1738 : Location::FpuRegisterLocation(D1)); 1764 : Location::FpuRegisterLocation(D1));
1739 } else { 1765 } else {
1740 summary->set_in(1, ShouldEmitStoreBarrier() 1766 summary->set_in(1, ShouldEmitStoreBarrier()
1741 ? Location::WritableRegister() 1767 ? Location::WritableRegister()
1742 : Location::RegisterOrConstant(value())); 1768 : Location::RegisterOrConstant(value()));
1743 } 1769 }
1744 return summary; 1770 return summary;
1745 } 1771 }
1746 1772
1747 1773
1774 static void EnsureMutableBox(FlowGraphCompiler* compiler,
1775 StoreInstanceFieldInstr* instruction,
1776 Register box_reg,
1777 const Class& cls,
1778 Register instance_reg,
1779 intptr_t offset,
1780 Register temp) {
1781 Label done;
1782 __ lw(box_reg, FieldAddress(instance_reg, offset));
1783 __ BranchNotEqual(box_reg, reinterpret_cast<int32_t>(Object::null()),
1784 &done);
1785 BoxAllocationSlowPath::Allocate(compiler, instruction, cls, box_reg, temp);
1786 __ mov(temp, box_reg);
1787 __ StoreIntoObjectOffset(instance_reg, offset, temp);
1788 __ Bind(&done);
1789 }
1790
1791
1748 void StoreInstanceFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1792 void StoreInstanceFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
1749 Label skip_store; 1793 Label skip_store;
1750 1794
1751 Register instance_reg = locs()->in(0).reg(); 1795 Register instance_reg = locs()->in(0).reg();
1752 1796
1753 if (IsUnboxedStore() && compiler->is_optimizing()) { 1797 if (IsUnboxedStore() && compiler->is_optimizing()) {
1754 DRegister value = locs()->in(1).fpu_reg(); 1798 DRegister value = locs()->in(1).fpu_reg();
1755 Register temp = locs()->temp(0).reg(); 1799 Register temp = locs()->temp(0).reg();
1756 Register temp2 = locs()->temp(1).reg(); 1800 Register temp2 = locs()->temp(1).reg();
1757 const intptr_t cid = field().UnboxedFieldCid(); 1801 const intptr_t cid = field().UnboxedFieldCid();
1758 1802
1759 if (is_initialization_) { 1803 if (is_initialization_) {
1760 const Class* cls = NULL; 1804 const Class* cls = NULL;
1761 switch (cid) { 1805 switch (cid) {
1762 case kDoubleCid: 1806 case kDoubleCid:
1763 cls = &compiler->double_class(); 1807 cls = &compiler->double_class();
1764 break; 1808 break;
1765 default: 1809 default:
1766 UNREACHABLE(); 1810 UNREACHABLE();
1767 } 1811 }
1768 1812
1769 StoreInstanceFieldSlowPath* slow_path = 1813 BoxAllocationSlowPath::Allocate(compiler, this, *cls, temp, temp2);
1770 new StoreInstanceFieldSlowPath(this, *cls);
1771 compiler->AddSlowPathCode(slow_path);
1772
1773 __ TryAllocate(*cls,
1774 slow_path->entry_label(),
1775 temp,
1776 temp2);
1777 __ Bind(slow_path->exit_label());
1778 __ mov(temp2, temp); 1814 __ mov(temp2, temp);
1779 __ StoreIntoObjectOffset(instance_reg, offset_in_bytes_, temp2); 1815 __ StoreIntoObjectOffset(instance_reg, offset_in_bytes_, temp2);
1780 } else { 1816 } else {
1781 __ lw(temp, FieldAddress(instance_reg, offset_in_bytes_)); 1817 __ lw(temp, FieldAddress(instance_reg, offset_in_bytes_));
1782 } 1818 }
1783 switch (cid) { 1819 switch (cid) {
1784 case kDoubleCid: 1820 case kDoubleCid:
1785 __ StoreDToOffset(value, temp, Double::value_offset() - kHeapObjectTag); 1821 __ StoreDToOffset(value, temp, Double::value_offset() - kHeapObjectTag);
1786 break; 1822 break;
1787 default: 1823 default:
(...skipping 26 matching lines...) Expand all
1814 // Fall through. 1850 // Fall through.
1815 __ b(&store_pointer); 1851 __ b(&store_pointer);
1816 1852
1817 if (!compiler->is_optimizing()) { 1853 if (!compiler->is_optimizing()) {
1818 locs()->live_registers()->Add(locs()->in(0)); 1854 locs()->live_registers()->Add(locs()->in(0));
1819 locs()->live_registers()->Add(locs()->in(1)); 1855 locs()->live_registers()->Add(locs()->in(1));
1820 } 1856 }
1821 1857
1822 { 1858 {
1823 __ Bind(&store_double); 1859 __ Bind(&store_double);
1824 Label copy_double; 1860 EnsureMutableBox(compiler,
1825 1861 this,
1826 __ lw(temp, FieldAddress(instance_reg, offset_in_bytes_)); 1862 temp,
1827 __ BranchNotEqual(temp, reinterpret_cast<int32_t>(Object::null()), 1863 compiler->double_class(),
1828 &copy_double); 1864 instance_reg,
1829 1865 offset_in_bytes_,
1830 StoreInstanceFieldSlowPath* slow_path = 1866 temp2);
1831 new StoreInstanceFieldSlowPath(this, compiler->double_class());
1832 compiler->AddSlowPathCode(slow_path);
1833
1834 __ TryAllocate(compiler->double_class(),
1835 slow_path->entry_label(),
1836 temp,
1837 temp2);
1838 __ Bind(slow_path->exit_label());
1839 __ mov(temp2, temp);
1840 __ StoreIntoObjectOffset(instance_reg, offset_in_bytes_, temp2);
1841
1842 __ Bind(&copy_double);
1843 __ LoadDFromOffset(fpu_temp, 1867 __ LoadDFromOffset(fpu_temp,
1844 value_reg, 1868 value_reg,
1845 Double::value_offset() - kHeapObjectTag); 1869 Double::value_offset() - kHeapObjectTag);
1846 __ StoreDToOffset(fpu_temp, temp, 1870 __ StoreDToOffset(fpu_temp, temp,
1847 Double::value_offset() - kHeapObjectTag); 1871 Double::value_offset() - kHeapObjectTag);
1848 __ b(&skip_store); 1872 __ b(&skip_store);
1849 } 1873 }
1850 1874
1851 __ Bind(&store_pointer); 1875 __ Bind(&store_pointer);
1852 } 1876 }
(...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after
2076 StubCode* stub_code = compiler->isolate()->stub_code(); 2100 StubCode* stub_code = compiler->isolate()->stub_code();
2077 compiler->GenerateCall(token_pos(), 2101 compiler->GenerateCall(token_pos(),
2078 &stub_code->AllocateArrayLabel(), 2102 &stub_code->AllocateArrayLabel(),
2079 RawPcDescriptors::kOther, 2103 RawPcDescriptors::kOther,
2080 locs()); 2104 locs());
2081 __ Bind(&done); 2105 __ Bind(&done);
2082 ASSERT(locs()->out(0).reg() == kResultReg); 2106 ASSERT(locs()->out(0).reg() == kResultReg);
2083 } 2107 }
2084 2108
2085 2109
2086 class BoxDoubleSlowPath : public SlowPathCode {
2087 public:
2088 explicit BoxDoubleSlowPath(Instruction* instruction)
2089 : instruction_(instruction) { }
2090
2091 virtual void EmitNativeCode(FlowGraphCompiler* compiler) {
2092 __ Comment("BoxDoubleSlowPath");
2093 __ Bind(entry_label());
2094 Isolate* isolate = compiler->isolate();
2095 StubCode* stub_code = isolate->stub_code();
2096 const Class& double_class = compiler->double_class();
2097 const Code& stub =
2098 Code::Handle(isolate,
2099 stub_code->GetAllocationStubForClass(double_class));
2100 const ExternalLabel label(stub.EntryPoint());
2101
2102 LocationSummary* locs = instruction_->locs();
2103 ASSERT(!locs->live_registers()->Contains(locs->out(0)));
2104
2105 compiler->SaveLiveRegisters(locs);
2106 compiler->GenerateCall(Scanner::kNoSourcePos, // No token position.
2107 &label,
2108 RawPcDescriptors::kOther,
2109 locs);
2110 if (locs->out(0).reg() != V0) {
2111 __ mov(locs->out(0).reg(), V0);
2112 }
2113 compiler->RestoreLiveRegisters(locs);
2114
2115 __ b(exit_label());
2116 }
2117
2118 private:
2119 Instruction* instruction_;
2120 };
2121
2122
2123 LocationSummary* LoadFieldInstr::MakeLocationSummary(Isolate* isolate, 2110 LocationSummary* LoadFieldInstr::MakeLocationSummary(Isolate* isolate,
2124 bool opt) const { 2111 bool opt) const {
2125 const intptr_t kNumInputs = 1; 2112 const intptr_t kNumInputs = 1;
2126 const intptr_t kNumTemps = 2113 const intptr_t kNumTemps =
2127 (IsUnboxedLoad() && opt) ? 1 : 2114 (IsUnboxedLoad() && opt) ? 1 :
2128 ((IsPotentialUnboxedLoad()) ? 2 : 0); 2115 ((IsPotentialUnboxedLoad()) ? 2 : 0);
2129 LocationSummary* locs = new(isolate) LocationSummary( 2116 LocationSummary* locs = new(isolate) LocationSummary(
2130 isolate, kNumInputs, kNumTemps, 2117 isolate, kNumInputs, kNumTemps,
2131 (opt && !IsPotentialUnboxedLoad()) 2118 (opt && !IsPotentialUnboxedLoad())
2132 ? LocationSummary::kNoCall 2119 ? LocationSummary::kNoCall
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
2187 2174
2188 // Fall through. 2175 // Fall through.
2189 __ b(&load_pointer); 2176 __ b(&load_pointer);
2190 2177
2191 if (!compiler->is_optimizing()) { 2178 if (!compiler->is_optimizing()) {
2192 locs()->live_registers()->Add(locs()->in(0)); 2179 locs()->live_registers()->Add(locs()->in(0));
2193 } 2180 }
2194 2181
2195 { 2182 {
2196 __ Bind(&load_double); 2183 __ Bind(&load_double);
2197 BoxDoubleSlowPath* slow_path = new BoxDoubleSlowPath(this); 2184 BoxAllocationSlowPath::Allocate(
2198 compiler->AddSlowPathCode(slow_path); 2185 compiler, this, compiler->double_class(), result_reg, temp);
2199
2200 __ TryAllocate(compiler->double_class(),
2201 slow_path->entry_label(),
2202 result_reg,
2203 temp);
2204 __ Bind(slow_path->exit_label());
2205 __ lw(temp, FieldAddress(instance_reg, offset_in_bytes())); 2186 __ lw(temp, FieldAddress(instance_reg, offset_in_bytes()));
2206 __ LoadDFromOffset(value, temp, Double::value_offset() - kHeapObjectTag); 2187 __ LoadDFromOffset(value, temp, Double::value_offset() - kHeapObjectTag);
2207 __ StoreDToOffset(value, 2188 __ StoreDToOffset(value,
2208 result_reg, 2189 result_reg,
2209 Double::value_offset() - kHeapObjectTag); 2190 Double::value_offset() - kHeapObjectTag);
2210 __ b(&done); 2191 __ b(&done);
2211 } 2192 }
2212 2193
2213 __ Bind(&load_pointer); 2194 __ Bind(&load_pointer);
2214 } 2195 }
(...skipping 824 matching lines...) Expand 10 before | Expand all | Expand 10 after
3039 kNumTemps, 3020 kNumTemps,
3040 LocationSummary::kCallOnSlowPath); 3021 LocationSummary::kCallOnSlowPath);
3041 summary->set_in(0, Location::RequiresFpuRegister()); 3022 summary->set_in(0, Location::RequiresFpuRegister());
3042 summary->set_temp(0, Location::RequiresRegister()); 3023 summary->set_temp(0, Location::RequiresRegister());
3043 summary->set_out(0, Location::RequiresRegister()); 3024 summary->set_out(0, Location::RequiresRegister());
3044 return summary; 3025 return summary;
3045 } 3026 }
3046 3027
3047 3028
3048 void BoxDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3029 void BoxDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3049 BoxDoubleSlowPath* slow_path = new BoxDoubleSlowPath(this);
3050 compiler->AddSlowPathCode(slow_path);
3051
3052 Register out_reg = locs()->out(0).reg(); 3030 Register out_reg = locs()->out(0).reg();
3053 DRegister value = locs()->in(0).fpu_reg(); 3031 DRegister value = locs()->in(0).fpu_reg();
3054 3032
3055 __ TryAllocate(compiler->double_class(), 3033 BoxAllocationSlowPath::Allocate(
3056 slow_path->entry_label(), 3034 compiler, this, compiler->double_class(), out_reg, locs()->temp(0).reg());
3057 out_reg,
3058 locs()->temp(0).reg());
3059 __ Bind(slow_path->exit_label());
3060 __ StoreDToOffset(value, out_reg, Double::value_offset() - kHeapObjectTag); 3035 __ StoreDToOffset(value, out_reg, Double::value_offset() - kHeapObjectTag);
3061 } 3036 }
3062 3037
3063 3038
3064 LocationSummary* UnboxDoubleInstr::MakeLocationSummary(Isolate* isolate, 3039 LocationSummary* UnboxDoubleInstr::MakeLocationSummary(Isolate* isolate,
3065 bool opt) const { 3040 bool opt) const {
3066 const intptr_t kNumInputs = 1; 3041 const intptr_t kNumInputs = 1;
3067 const intptr_t kNumTemps = 0; 3042 const intptr_t kNumTemps = 0;
3068 LocationSummary* summary = new(isolate) LocationSummary( 3043 LocationSummary* summary = new(isolate) LocationSummary(
3069 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); 3044 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
(...skipping 1735 matching lines...) Expand 10 before | Expand all | Expand 10 after
4805 compiler->GenerateCall(token_pos(), &label, stub_kind_, locs()); 4780 compiler->GenerateCall(token_pos(), &label, stub_kind_, locs());
4806 #if defined(DEBUG) 4781 #if defined(DEBUG)
4807 __ LoadImmediate(S4, kInvalidObjectPointer); 4782 __ LoadImmediate(S4, kInvalidObjectPointer);
4808 __ LoadImmediate(S5, kInvalidObjectPointer); 4783 __ LoadImmediate(S5, kInvalidObjectPointer);
4809 #endif 4784 #endif
4810 } 4785 }
4811 4786
4812 } // namespace dart 4787 } // namespace dart
4813 4788
4814 #endif // defined TARGET_ARCH_MIPS 4789 #endif // defined TARGET_ARCH_MIPS
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698