Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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/bit_vector.h" | 7 #include "vm/bit_vector.h" |
| 8 #include "vm/dart_entry.h" | 8 #include "vm/dart_entry.h" |
| 9 #include "vm/flow_graph_allocator.h" | 9 #include "vm/flow_graph_allocator.h" |
| 10 #include "vm/flow_graph_builder.h" | 10 #include "vm/flow_graph_builder.h" |
| 11 #include "vm/flow_graph_compiler.h" | 11 #include "vm/flow_graph_compiler.h" |
| 12 #include "vm/flow_graph_optimizer.h" | 12 #include "vm/flow_graph_optimizer.h" |
| 13 #include "vm/locations.h" | 13 #include "vm/locations.h" |
| 14 #include "vm/object.h" | 14 #include "vm/object.h" |
| 15 #include "vm/object_store.h" | 15 #include "vm/object_store.h" |
| 16 #include "vm/os.h" | 16 #include "vm/os.h" |
| 17 #include "vm/scopes.h" | 17 #include "vm/scopes.h" |
| 18 #include "vm/stub_code.h" | 18 #include "vm/stub_code.h" |
| 19 #include "vm/symbols.h" | 19 #include "vm/symbols.h" |
| 20 | 20 |
| 21 namespace dart { | 21 namespace dart { |
| 22 | 22 |
| 23 DEFINE_FLAG(bool, new_identity_spec, true, | |
| 24 "Use new identity check rules for numbers."); | |
| 23 DEFINE_FLAG(bool, propagate_ic_data, true, | 25 DEFINE_FLAG(bool, propagate_ic_data, true, |
| 24 "Propagate IC data from unoptimized to optimized IC calls."); | 26 "Propagate IC data from unoptimized to optimized IC calls."); |
| 25 DECLARE_FLAG(bool, enable_type_checks); | 27 DECLARE_FLAG(bool, enable_type_checks); |
| 26 DECLARE_FLAG(int, max_polymorphic_checks); | 28 DECLARE_FLAG(int, max_polymorphic_checks); |
| 27 | 29 |
| 28 Definition::Definition() | 30 Definition::Definition() |
| 29 : range_(NULL), | 31 : range_(NULL), |
| 30 temp_index_(-1), | 32 temp_index_(-1), |
| 31 ssa_temp_index_(-1), | 33 ssa_temp_index_(-1), |
| 32 propagated_type_(AbstractType::Handle()), | 34 propagated_type_(AbstractType::Handle()), |
| (...skipping 1744 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1777 return summary; | 1779 return summary; |
| 1778 } | 1780 } |
| 1779 | 1781 |
| 1780 | 1782 |
| 1781 void StoreContextInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 1783 void StoreContextInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1782 // Nothing to do. Context register were loaded by register allocator. | 1784 // Nothing to do. Context register were loaded by register allocator. |
| 1783 ASSERT(locs()->in(0).reg() == CTX); | 1785 ASSERT(locs()->in(0).reg() == CTX); |
| 1784 } | 1786 } |
| 1785 | 1787 |
| 1786 | 1788 |
| 1789 StrictCompareInstr::StrictCompareInstr(Token::Kind kind, | |
| 1790 Value* left, | |
| 1791 Value* right) | |
| 1792 : ComparisonInstr(kind, left, right), | |
| 1793 needs_number_check_(FLAG_new_identity_spec) { | |
| 1794 ASSERT((kind == Token::kEQ_STRICT) || (kind == Token::kNE_STRICT)); | |
| 1795 } | |
| 1796 | |
| 1797 | |
| 1787 LocationSummary* StrictCompareInstr::MakeLocationSummary() const { | 1798 LocationSummary* StrictCompareInstr::MakeLocationSummary() const { |
| 1788 const intptr_t kNumInputs = 2; | 1799 const intptr_t kNumInputs = 2; |
| 1789 const intptr_t kNumTemps = 0; | 1800 const intptr_t kNumTemps = 00; |
|
Florian Schneider
2012/11/23 10:33:40
s/00/0/
srdjan
2012/11/23 19:45:39
Done.
| |
| 1790 LocationSummary* locs = | 1801 LocationSummary* locs = |
| 1791 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 1802 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 1792 locs->set_in(0, Location::RegisterOrConstant(left())); | 1803 locs->set_in(0, Location::RegisterOrConstant(left())); |
| 1793 locs->set_in(1, Location::RegisterOrConstant(right())); | 1804 locs->set_in(1, Location::RegisterOrConstant(right())); |
| 1794 locs->set_out(Location::RequiresRegister()); | 1805 locs->set_out(Location::RequiresRegister()); |
| 1795 return locs; | 1806 return locs; |
| 1796 } | 1807 } |
| 1797 | 1808 |
| 1798 | 1809 |
| 1810 // Special code for doubles (compare values instead of references.) | |
|
Florian Schneider
2012/11/23 10:33:40
s/doubles/numbers/
srdjan
2012/11/23 19:45:39
Done.
| |
| 1799 void StrictCompareInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 1811 void StrictCompareInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1800 ASSERT(kind() == Token::kEQ_STRICT || kind() == Token::kNE_STRICT); | 1812 ASSERT(kind() == Token::kEQ_STRICT || kind() == Token::kNE_STRICT); |
| 1801 Location left = locs()->in(0); | 1813 Location left = locs()->in(0); |
| 1802 Location right = locs()->in(1); | 1814 Location right = locs()->in(1); |
| 1803 if (left.IsConstant() && right.IsConstant()) { | 1815 if (left.IsConstant() && right.IsConstant()) { |
| 1804 // TODO(vegorov): should be eliminated earlier by constant propagation. | 1816 // TODO(vegorov): should be eliminated earlier by constant propagation. |
| 1805 const bool result = (kind() == Token::kEQ_STRICT) ? | 1817 const bool result = (kind() == Token::kEQ_STRICT) ? |
| 1806 left.constant().raw() == right.constant().raw() : | 1818 left.constant().raw() == right.constant().raw() : |
| 1807 left.constant().raw() != right.constant().raw(); | 1819 left.constant().raw() != right.constant().raw(); |
| 1808 __ LoadObject(locs()->out().reg(), result ? compiler->bool_true() : | 1820 __ LoadObject(locs()->out().reg(), result ? compiler->bool_true() : |
| 1809 compiler->bool_false()); | 1821 compiler->bool_false()); |
| 1810 return; | 1822 return; |
| 1811 } | 1823 } |
| 1812 if (left.IsConstant()) { | 1824 if (left.IsConstant()) { |
| 1813 compiler->EmitEqualityRegConstCompare(right.reg(), left.constant()); | 1825 compiler->EmitEqualityRegConstCompare(right.reg(), |
| 1826 left.constant(), | |
| 1827 needs_number_check()); | |
| 1814 } else if (right.IsConstant()) { | 1828 } else if (right.IsConstant()) { |
| 1815 compiler->EmitEqualityRegConstCompare(left.reg(), right.constant()); | 1829 compiler->EmitEqualityRegConstCompare(left.reg(), |
| 1830 right.constant(), | |
| 1831 needs_number_check()); | |
| 1816 } else { | 1832 } else { |
| 1817 __ CompareRegisters(left.reg(), right.reg()); | 1833 compiler->EmitEqualityRegRegCompare(left.reg(), |
| 1834 right.reg(), | |
| 1835 needs_number_check()); | |
| 1818 } | 1836 } |
| 1819 | 1837 |
| 1820 Register result = locs()->out().reg(); | 1838 Register result = locs()->out().reg(); |
| 1821 Label load_true, done; | 1839 Label load_true, done; |
| 1822 Condition true_condition = (kind() == Token::kEQ_STRICT) ? EQUAL : NOT_EQUAL; | 1840 Condition true_condition = (kind() == Token::kEQ_STRICT) ? EQUAL : NOT_EQUAL; |
| 1823 __ j(true_condition, &load_true, Assembler::kNearJump); | 1841 __ j(true_condition, &load_true, Assembler::kNearJump); |
| 1824 __ LoadObject(result, compiler->bool_false()); | 1842 __ LoadObject(result, compiler->bool_false()); |
| 1825 __ jmp(&done, Assembler::kNearJump); | 1843 __ jmp(&done, Assembler::kNearJump); |
| 1826 __ Bind(&load_true); | 1844 __ Bind(&load_true); |
| 1827 __ LoadObject(result, compiler->bool_true()); | 1845 __ LoadObject(result, compiler->bool_true()); |
| 1828 __ Bind(&done); | 1846 __ Bind(&done); |
| 1829 } | 1847 } |
| 1830 | 1848 |
| 1831 | 1849 |
| 1832 void StrictCompareInstr::EmitBranchCode(FlowGraphCompiler* compiler, | 1850 void StrictCompareInstr::EmitBranchCode(FlowGraphCompiler* compiler, |
| 1833 BranchInstr* branch) { | 1851 BranchInstr* branch) { |
| 1834 ASSERT(kind() == Token::kEQ_STRICT || kind() == Token::kNE_STRICT); | 1852 ASSERT(kind() == Token::kEQ_STRICT || kind() == Token::kNE_STRICT); |
| 1835 Location left = locs()->in(0); | 1853 Location left = locs()->in(0); |
| 1836 Location right = locs()->in(1); | 1854 Location right = locs()->in(1); |
| 1837 if (left.IsConstant() && right.IsConstant()) { | 1855 if (left.IsConstant() && right.IsConstant()) { |
| 1838 // TODO(vegorov): should be eliminated earlier by constant propagation. | 1856 // TODO(vegorov): should be eliminated earlier by constant propagation. |
| 1839 const bool result = (kind() == Token::kEQ_STRICT) ? | 1857 const bool result = (kind() == Token::kEQ_STRICT) ? |
| 1840 left.constant().raw() == right.constant().raw() : | 1858 left.constant().raw() == right.constant().raw() : |
| 1841 left.constant().raw() != right.constant().raw(); | 1859 left.constant().raw() != right.constant().raw(); |
| 1842 branch->EmitBranchOnValue(compiler, result); | 1860 branch->EmitBranchOnValue(compiler, result); |
| 1843 return; | 1861 return; |
| 1844 } | 1862 } |
| 1845 if (left.IsConstant()) { | 1863 if (left.IsConstant()) { |
| 1846 compiler->EmitEqualityRegConstCompare(right.reg(), left.constant()); | 1864 compiler->EmitEqualityRegConstCompare(right.reg(), |
| 1865 left.constant(), | |
| 1866 needs_number_check()); | |
| 1847 } else if (right.IsConstant()) { | 1867 } else if (right.IsConstant()) { |
| 1848 compiler->EmitEqualityRegConstCompare(left.reg(), right.constant()); | 1868 compiler->EmitEqualityRegConstCompare(left.reg(), |
| 1869 right.constant(), | |
| 1870 needs_number_check()); | |
| 1849 } else { | 1871 } else { |
| 1850 __ CompareRegisters(left.reg(), right.reg()); | 1872 compiler->EmitEqualityRegRegCompare(left.reg(), |
| 1873 right.reg(), | |
| 1874 needs_number_check()); | |
| 1851 } | 1875 } |
| 1852 | 1876 |
| 1853 Condition true_condition = (kind() == Token::kEQ_STRICT) ? EQUAL : NOT_EQUAL; | 1877 Condition true_condition = (kind() == Token::kEQ_STRICT) ? EQUAL : NOT_EQUAL; |
| 1854 branch->EmitBranchOnCondition(compiler, true_condition); | 1878 branch->EmitBranchOnCondition(compiler, true_condition); |
| 1855 } | 1879 } |
| 1856 | 1880 |
| 1857 | 1881 |
| 1858 void ClosureCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 1882 void ClosureCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1859 // The arguments to the stub include the closure, as does the arguments | 1883 // The arguments to the stub include the closure, as does the arguments |
| 1860 // descriptor. | 1884 // descriptor. |
| (...skipping 803 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2664 return Array::length_offset(); | 2688 return Array::length_offset(); |
| 2665 default: | 2689 default: |
| 2666 UNREACHABLE(); | 2690 UNREACHABLE(); |
| 2667 return -1; | 2691 return -1; |
| 2668 } | 2692 } |
| 2669 } | 2693 } |
| 2670 | 2694 |
| 2671 #undef __ | 2695 #undef __ |
| 2672 | 2696 |
| 2673 } // namespace dart | 2697 } // namespace dart |
| OLD | NEW |