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

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

Issue 99573005: Add mutable double boxes for fields. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years 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.h ('k') | runtime/vm/intermediate_language_arm.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/intermediate_language.h" 5 #include "vm/intermediate_language.h"
6 6
7 #include "vm/bigint_operations.h" 7 #include "vm/bigint_operations.h"
8 #include "vm/bit_vector.h" 8 #include "vm/bit_vector.h"
9 #include "vm/dart_entry.h" 9 #include "vm/dart_entry.h"
10 #include "vm/flow_graph_allocator.h" 10 #include "vm/flow_graph_allocator.h"
11 #include "vm/flow_graph_builder.h" 11 #include "vm/flow_graph_builder.h"
12 #include "vm/flow_graph_compiler.h" 12 #include "vm/flow_graph_compiler.h"
13 #include "vm/flow_graph_optimizer.h" 13 #include "vm/flow_graph_optimizer.h"
14 #include "vm/locations.h" 14 #include "vm/locations.h"
15 #include "vm/object.h" 15 #include "vm/object.h"
16 #include "vm/object_store.h" 16 #include "vm/object_store.h"
17 #include "vm/os.h" 17 #include "vm/os.h"
18 #include "vm/resolver.h" 18 #include "vm/resolver.h"
19 #include "vm/scopes.h" 19 #include "vm/scopes.h"
20 #include "vm/stub_code.h" 20 #include "vm/stub_code.h"
21 #include "vm/symbols.h" 21 #include "vm/symbols.h"
22 22
23 #include "vm/il_printer.h" 23 #include "vm/il_printer.h"
24 24
25 namespace dart { 25 namespace dart {
26 26
27 DEFINE_FLAG(bool, propagate_ic_data, true, 27 DEFINE_FLAG(bool, propagate_ic_data, true,
28 "Propagate IC data from unoptimized to optimized IC calls."); 28 "Propagate IC data from unoptimized to optimized IC calls.");
29 DEFINE_FLAG(bool, unbox_double_fields, true, "Support unboxed double fields.");
29 DECLARE_FLAG(bool, enable_type_checks); 30 DECLARE_FLAG(bool, enable_type_checks);
30 DECLARE_FLAG(bool, eliminate_type_checks); 31 DECLARE_FLAG(bool, eliminate_type_checks);
31 DECLARE_FLAG(bool, trace_optimization); 32 DECLARE_FLAG(bool, trace_optimization);
32 DECLARE_FLAG(bool, trace_constant_propagation); 33 DECLARE_FLAG(bool, trace_constant_propagation);
33 DECLARE_FLAG(bool, throw_on_javascript_int_overflow); 34 DECLARE_FLAG(bool, throw_on_javascript_int_overflow);
34 35
35 Definition::Definition() 36 Definition::Definition()
36 : range_(NULL), 37 : range_(NULL),
37 type_(NULL), 38 type_(NULL),
38 temp_index_(-1), 39 temp_index_(-1),
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
129 return false; 130 return false;
130 } 131 }
131 CompileType* in_type = value()->Type(); 132 CompileType* in_type = value()->Type();
132 const intptr_t cid = unary_checks().GetCidAt(0); 133 const intptr_t cid = unary_checks().GetCidAt(0);
133 // Performance check: use CheckSmiInstr instead. 134 // Performance check: use CheckSmiInstr instead.
134 ASSERT(cid != kSmiCid); 135 ASSERT(cid != kSmiCid);
135 return in_type->is_nullable() && (in_type->ToNullableCid() == cid); 136 return in_type->is_nullable() && (in_type->ToNullableCid() == cid);
136 } 137 }
137 138
138 139
140 bool LoadFieldInstr::IsUnboxedLoad() const {
141 return FLAG_unbox_double_fields
142 && (field() != NULL)
143 && field()->IsUnboxedField();
144 }
145
146
147 bool LoadFieldInstr::IsPotentialUnboxedLoad() const {
148 return FLAG_unbox_double_fields
149 && (field() != NULL)
150 && field()->IsPotentialUnboxedField();
151 }
152
153
154 bool StoreInstanceFieldInstr::IsUnboxedStore() const {
155 return FLAG_unbox_double_fields && field().IsUnboxedField();
156 }
157
158
159 bool StoreInstanceFieldInstr::IsPotentialUnboxedStore() const {
160 return FLAG_unbox_double_fields && field().IsPotentialUnboxedField();
161 }
162
163
139 bool GuardFieldInstr::AttributesEqual(Instruction* other) const { 164 bool GuardFieldInstr::AttributesEqual(Instruction* other) const {
140 return field().raw() == other->AsGuardField()->field().raw(); 165 return field().raw() == other->AsGuardField()->field().raw();
141 } 166 }
142 167
143 168
144 bool AssertAssignableInstr::AttributesEqual(Instruction* other) const { 169 bool AssertAssignableInstr::AttributesEqual(Instruction* other) const {
145 AssertAssignableInstr* other_assert = other->AsAssertAssignable(); 170 AssertAssignableInstr* other_assert = other->AsAssertAssignable();
146 ASSERT(other_assert != NULL); 171 ASSERT(other_assert != NULL);
147 // This predicate has to be commutative for DominatorBasedCSE to work. 172 // This predicate has to be commutative for DominatorBasedCSE to work.
148 // TODO(fschneider): Eliminate more asserts with subtype relation. 173 // TODO(fschneider): Eliminate more asserts with subtype relation.
(...skipping 1601 matching lines...) Expand 10 before | Expand all | Expand 10 after
1750 } 1775 }
1751 1776
1752 1777
1753 // Shared code generation methods (EmitNativeCode and 1778 // Shared code generation methods (EmitNativeCode and
1754 // MakeLocationSummary). Only assembly code that can be shared across all 1779 // MakeLocationSummary). Only assembly code that can be shared across all
1755 // architectures can be used. Machine specific register allocation and code 1780 // architectures can be used. Machine specific register allocation and code
1756 // generation is located in intermediate_language_<arch>.cc 1781 // generation is located in intermediate_language_<arch>.cc
1757 1782
1758 #define __ compiler->assembler()-> 1783 #define __ compiler->assembler()->
1759 1784
1760 LocationSummary* GraphEntryInstr::MakeLocationSummary() const { 1785 LocationSummary* GraphEntryInstr::MakeLocationSummary(bool optimizing) const {
1761 UNREACHABLE(); 1786 UNREACHABLE();
1762 return NULL; 1787 return NULL;
1763 } 1788 }
1764 1789
1765 1790
1766 LocationSummary* JoinEntryInstr::MakeLocationSummary() const { 1791 LocationSummary* JoinEntryInstr::MakeLocationSummary(bool optimizing) const {
1767 UNREACHABLE(); 1792 UNREACHABLE();
1768 return NULL; 1793 return NULL;
1769 } 1794 }
1770 1795
1771 1796
1772 void JoinEntryInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1797 void JoinEntryInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
1773 __ Bind(compiler->GetJumpLabel(this)); 1798 __ Bind(compiler->GetJumpLabel(this));
1774 if (!compiler->is_optimizing()) { 1799 if (!compiler->is_optimizing()) {
1775 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt, 1800 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt,
1776 deopt_id_, 1801 deopt_id_,
1777 Scanner::kDummyTokenIndex); 1802 Scanner::kDummyTokenIndex);
1778 } 1803 }
1779 if (HasParallelMove()) { 1804 if (HasParallelMove()) {
1780 compiler->parallel_move_resolver()->EmitNativeCode(parallel_move()); 1805 compiler->parallel_move_resolver()->EmitNativeCode(parallel_move());
1781 } 1806 }
1782 } 1807 }
1783 1808
1784 1809
1785 LocationSummary* TargetEntryInstr::MakeLocationSummary() const { 1810 LocationSummary* TargetEntryInstr::MakeLocationSummary(bool optimizing) const {
1786 // FlowGraphCompiler::EmitInstructionPrologue is not called for block 1811 // FlowGraphCompiler::EmitInstructionPrologue is not called for block
1787 // entry instructions, so this function is unused. If it becomes 1812 // entry instructions, so this function is unused. If it becomes
1788 // reachable, note that the deoptimization descriptor in unoptimized code 1813 // reachable, note that the deoptimization descriptor in unoptimized code
1789 // comes after the point of local register allocation due to pattern 1814 // comes after the point of local register allocation due to pattern
1790 // matching the edge counter code backwards (as a code reuse convenience 1815 // matching the edge counter code backwards (as a code reuse convenience
1791 // on some platforms). 1816 // on some platforms).
1792 UNREACHABLE(); 1817 UNREACHABLE();
1793 return NULL; 1818 return NULL;
1794 } 1819 }
1795 1820
1796 1821
1797 LocationSummary* PhiInstr::MakeLocationSummary() const { 1822 LocationSummary* PhiInstr::MakeLocationSummary(bool optimizing) const {
1798 UNREACHABLE(); 1823 UNREACHABLE();
1799 return NULL; 1824 return NULL;
1800 } 1825 }
1801 1826
1802 1827
1803 void PhiInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1828 void PhiInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
1804 UNREACHABLE(); 1829 UNREACHABLE();
1805 } 1830 }
1806 1831
1807 1832
1808 LocationSummary* RedefinitionInstr::MakeLocationSummary() const { 1833 LocationSummary* RedefinitionInstr::MakeLocationSummary(bool optimizing) const {
1809 UNREACHABLE(); 1834 UNREACHABLE();
1810 return NULL; 1835 return NULL;
1811 } 1836 }
1812 1837
1813 1838
1814 void RedefinitionInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1839 void RedefinitionInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
1815 UNREACHABLE(); 1840 UNREACHABLE();
1816 } 1841 }
1817 1842
1818 1843
1819 LocationSummary* ParameterInstr::MakeLocationSummary() const { 1844 LocationSummary* ParameterInstr::MakeLocationSummary(bool optimizing) const {
1820 UNREACHABLE(); 1845 UNREACHABLE();
1821 return NULL; 1846 return NULL;
1822 } 1847 }
1823 1848
1824 1849
1825 void ParameterInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1850 void ParameterInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
1826 UNREACHABLE(); 1851 UNREACHABLE();
1827 } 1852 }
1828 1853
1829 1854
1830 LocationSummary* ParallelMoveInstr::MakeLocationSummary() const { 1855 LocationSummary* ParallelMoveInstr::MakeLocationSummary(bool optimizing) const {
1831 return NULL; 1856 return NULL;
1832 } 1857 }
1833 1858
1834 1859
1835 void ParallelMoveInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1860 void ParallelMoveInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
1836 UNREACHABLE(); 1861 UNREACHABLE();
1837 } 1862 }
1838 1863
1839 1864
1840 LocationSummary* ConstraintInstr::MakeLocationSummary() const { 1865 LocationSummary* ConstraintInstr::MakeLocationSummary(bool optimizing) const {
1841 UNREACHABLE(); 1866 UNREACHABLE();
1842 return NULL; 1867 return NULL;
1843 } 1868 }
1844 1869
1845 1870
1846 void ConstraintInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1871 void ConstraintInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
1847 UNREACHABLE(); 1872 UNREACHABLE();
1848 } 1873 }
1849 1874
1850 1875
1851 LocationSummary* MaterializeObjectInstr::MakeLocationSummary() const { 1876 LocationSummary* MaterializeObjectInstr::MakeLocationSummary(
1877 bool optimizing) const {
1852 UNREACHABLE(); 1878 UNREACHABLE();
1853 return NULL; 1879 return NULL;
1854 } 1880 }
1855 1881
1856 1882
1857 void MaterializeObjectInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1883 void MaterializeObjectInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
1858 UNREACHABLE(); 1884 UNREACHABLE();
1859 } 1885 }
1860 1886
1861 1887
1862 LocationSummary* StoreContextInstr::MakeLocationSummary() const { 1888 LocationSummary* StoreContextInstr::MakeLocationSummary(bool optimizing) const {
1863 const intptr_t kNumInputs = 1; 1889 const intptr_t kNumInputs = 1;
1864 const intptr_t kNumTemps = 0; 1890 const intptr_t kNumTemps = 0;
1865 LocationSummary* summary = 1891 LocationSummary* summary =
1866 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 1892 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
1867 summary->set_in(0, Location::RegisterLocation(CTX)); 1893 summary->set_in(0, Location::RegisterLocation(CTX));
1868 return summary; 1894 return summary;
1869 } 1895 }
1870 1896
1871 1897
1872 LocationSummary* PushTempInstr::MakeLocationSummary() const { 1898 LocationSummary* PushTempInstr::MakeLocationSummary(bool optimizing) const {
1873 return LocationSummary::Make(1, 1899 return LocationSummary::Make(1,
1874 Location::NoLocation(), 1900 Location::NoLocation(),
1875 LocationSummary::kNoCall); 1901 LocationSummary::kNoCall);
1876 } 1902 }
1877 1903
1878 1904
1879 void PushTempInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1905 void PushTempInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
1880 ASSERT(!compiler->is_optimizing()); 1906 ASSERT(!compiler->is_optimizing());
1881 // Nothing to do. 1907 // Nothing to do.
1882 } 1908 }
1883 1909
1884 1910
1885 LocationSummary* DropTempsInstr::MakeLocationSummary() const { 1911 LocationSummary* DropTempsInstr::MakeLocationSummary(bool optimizing) const {
1886 return LocationSummary::Make(1, 1912 return LocationSummary::Make(1,
1887 Location::SameAsFirstInput(), 1913 Location::SameAsFirstInput(),
1888 LocationSummary::kNoCall); 1914 LocationSummary::kNoCall);
1889 } 1915 }
1890 1916
1891 1917
1892 void DropTempsInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1918 void DropTempsInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
1893 ASSERT(!compiler->is_optimizing()); 1919 ASSERT(!compiler->is_optimizing());
1894 Register value = locs()->in(0).reg(); 1920 Register value = locs()->in(0).reg();
1895 Register result = locs()->out().reg(); 1921 Register result = locs()->out().reg();
(...skipping 12 matching lines...) Expand all
1908 Token::Kind kind, 1934 Token::Kind kind,
1909 Value* left, 1935 Value* left,
1910 Value* right, 1936 Value* right,
1911 bool needs_number_check) 1937 bool needs_number_check)
1912 : ComparisonInstr(token_pos, kind, left, right), 1938 : ComparisonInstr(token_pos, kind, left, right),
1913 needs_number_check_(needs_number_check) { 1939 needs_number_check_(needs_number_check) {
1914 ASSERT((kind == Token::kEQ_STRICT) || (kind == Token::kNE_STRICT)); 1940 ASSERT((kind == Token::kEQ_STRICT) || (kind == Token::kNE_STRICT));
1915 } 1941 }
1916 1942
1917 1943
1918 LocationSummary* InstanceCallInstr::MakeLocationSummary() const { 1944 LocationSummary* InstanceCallInstr::MakeLocationSummary(bool optimizing) const {
1919 return MakeCallSummary(); 1945 return MakeCallSummary();
1920 } 1946 }
1921 1947
1922 1948
1923 void InstanceCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1949 void InstanceCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
1924 ICData& call_ic_data = ICData::ZoneHandle(ic_data()->raw()); 1950 ICData& call_ic_data = ICData::ZoneHandle(ic_data()->raw());
1925 if (!FLAG_propagate_ic_data || !compiler->is_optimizing()) { 1951 if (!FLAG_propagate_ic_data || !compiler->is_optimizing()) {
1926 const Array& arguments_descriptor = 1952 const Array& arguments_descriptor =
1927 Array::Handle(ArgumentsDescriptor::New(ArgumentCount(), 1953 Array::Handle(ArgumentsDescriptor::New(ArgumentCount(),
1928 argument_names())); 1954 argument_names()));
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
1969 1995
1970 1996
1971 bool PolymorphicInstanceCallInstr::HasRecognizedTarget() const { 1997 bool PolymorphicInstanceCallInstr::HasRecognizedTarget() const {
1972 return ic_data().HasOneTarget() && 1998 return ic_data().HasOneTarget() &&
1973 (MethodRecognizer::RecognizeKind( 1999 (MethodRecognizer::RecognizeKind(
1974 Function::Handle(ic_data().GetTargetAt(0))) != 2000 Function::Handle(ic_data().GetTargetAt(0))) !=
1975 MethodRecognizer::kUnknown); 2001 MethodRecognizer::kUnknown);
1976 } 2002 }
1977 2003
1978 2004
1979 LocationSummary* StaticCallInstr::MakeLocationSummary() const { 2005 LocationSummary* StaticCallInstr::MakeLocationSummary(bool optimizing) const {
1980 return MakeCallSummary(); 2006 return MakeCallSummary();
1981 } 2007 }
1982 2008
1983 2009
1984 void StaticCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 2010 void StaticCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
1985 if (!compiler->is_optimizing()) { 2011 if (!compiler->is_optimizing()) {
1986 // Some static calls can be optimized by the optimizing compiler (e.g. sqrt) 2012 // Some static calls can be optimized by the optimizing compiler (e.g. sqrt)
1987 // and therefore need a deoptimization descriptor. 2013 // and therefore need a deoptimization descriptor.
1988 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt, 2014 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt,
1989 deopt_id(), 2015 deopt_id(),
(...skipping 873 matching lines...) Expand 10 before | Expand all | Expand 10 after
2863 concatenated = Symbols::New(concatenated); 2889 concatenated = Symbols::New(concatenated);
2864 return flow_graph->GetConstant(concatenated); 2890 return flow_graph->GetConstant(concatenated);
2865 } 2891 }
2866 2892
2867 2893
2868 InvokeMathCFunctionInstr::InvokeMathCFunctionInstr( 2894 InvokeMathCFunctionInstr::InvokeMathCFunctionInstr(
2869 ZoneGrowableArray<Value*>* inputs, 2895 ZoneGrowableArray<Value*>* inputs,
2870 intptr_t original_deopt_id, 2896 intptr_t original_deopt_id,
2871 MethodRecognizer::Kind recognized_kind) 2897 MethodRecognizer::Kind recognized_kind)
2872 : inputs_(inputs), 2898 : inputs_(inputs),
2873 locs_(NULL),
2874 recognized_kind_(recognized_kind) { 2899 recognized_kind_(recognized_kind) {
2875 ASSERT(inputs_->length() == ArgumentCountFor(recognized_kind_)); 2900 ASSERT(inputs_->length() == ArgumentCountFor(recognized_kind_));
2876 for (intptr_t i = 0; i < inputs_->length(); ++i) { 2901 for (intptr_t i = 0; i < inputs_->length(); ++i) {
2877 ASSERT((*inputs)[i] != NULL); 2902 ASSERT((*inputs)[i] != NULL);
2878 (*inputs)[i]->set_instruction(this); 2903 (*inputs)[i]->set_instruction(this);
2879 (*inputs)[i]->set_use_index(i); 2904 (*inputs)[i]->set_use_index(i);
2880 } 2905 }
2881 deopt_id_ = original_deopt_id; 2906 deopt_id_ = original_deopt_id;
2882 } 2907 }
2883 2908
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
2971 UNREACHABLE(); 2996 UNREACHABLE();
2972 } 2997 }
2973 return kSinRuntimeEntry; 2998 return kSinRuntimeEntry;
2974 } 2999 }
2975 3000
2976 3001
2977 MergedMathInstr::MergedMathInstr(ZoneGrowableArray<Value*>* inputs, 3002 MergedMathInstr::MergedMathInstr(ZoneGrowableArray<Value*>* inputs,
2978 intptr_t original_deopt_id, 3003 intptr_t original_deopt_id,
2979 MergedMathInstr::Kind kind) 3004 MergedMathInstr::Kind kind)
2980 : inputs_(inputs), 3005 : inputs_(inputs),
2981 locs_(NULL),
2982 kind_(kind) { 3006 kind_(kind) {
2983 ASSERT(inputs_->length() == InputCountFor(kind_)); 3007 ASSERT(inputs_->length() == InputCountFor(kind_));
2984 for (intptr_t i = 0; i < inputs_->length(); ++i) { 3008 for (intptr_t i = 0; i < inputs_->length(); ++i) {
2985 ASSERT((*inputs)[i] != NULL); 3009 ASSERT((*inputs)[i] != NULL);
2986 (*inputs)[i]->set_instruction(this); 3010 (*inputs)[i]->set_instruction(this);
2987 (*inputs)[i]->set_use_index(i); 3011 (*inputs)[i]->set_use_index(i);
2988 } 3012 }
2989 deopt_id_ = original_deopt_id; 3013 deopt_id_ = original_deopt_id;
2990 } 3014 }
2991 3015
(...skipping 12 matching lines...) Expand all
3004 case Token::kTRUNCDIV: return 0; 3028 case Token::kTRUNCDIV: return 0;
3005 case Token::kMOD: return 1; 3029 case Token::kMOD: return 1;
3006 default: UNIMPLEMENTED(); return -1; 3030 default: UNIMPLEMENTED(); return -1;
3007 } 3031 }
3008 } 3032 }
3009 3033
3010 3034
3011 #undef __ 3035 #undef __
3012 3036
3013 } // namespace dart 3037 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/intermediate_language.h ('k') | runtime/vm/intermediate_language_arm.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698