| OLD | NEW |
| 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_X64. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_X64. |
| 6 #if defined(TARGET_ARCH_X64) | 6 #if defined(TARGET_ARCH_X64) |
| 7 | 7 |
| 8 #include "vm/intermediate_language.h" | 8 #include "vm/intermediate_language.h" |
| 9 | 9 |
| 10 #include "lib/error.h" | 10 #include "lib/error.h" |
| (...skipping 1827 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1838 } | 1838 } |
| 1839 | 1839 |
| 1840 | 1840 |
| 1841 void InstantiateTypeArgumentsInstr::EmitNativeCode( | 1841 void InstantiateTypeArgumentsInstr::EmitNativeCode( |
| 1842 FlowGraphCompiler* compiler) { | 1842 FlowGraphCompiler* compiler) { |
| 1843 Register instantiator_reg = locs()->in(0).reg(); | 1843 Register instantiator_reg = locs()->in(0).reg(); |
| 1844 Register result_reg = locs()->out().reg(); | 1844 Register result_reg = locs()->out().reg(); |
| 1845 | 1845 |
| 1846 // 'instantiator_reg' is the instantiator AbstractTypeArguments object | 1846 // 'instantiator_reg' is the instantiator AbstractTypeArguments object |
| 1847 // (or null). | 1847 // (or null). |
| 1848 // If the instantiator is null and if the type argument vector | 1848 if (!type_arguments().IsUninstantiatedIdentity()) { |
| 1849 // instantiated from null becomes a vector of dynamic, then use null as | 1849 // If the instantiator is null and if the type argument vector |
| 1850 // the type arguments. | 1850 // instantiated from null becomes a vector of dynamic, then use null as |
| 1851 Label type_arguments_instantiated; | 1851 // the type arguments. |
| 1852 const intptr_t len = type_arguments().Length(); | 1852 Label type_arguments_instantiated; |
| 1853 if (type_arguments().IsRawInstantiatedRaw(len)) { | 1853 const intptr_t len = type_arguments().Length(); |
| 1854 const Immediate& raw_null = | 1854 if (type_arguments().IsRawInstantiatedRaw(len)) { |
| 1855 Immediate(reinterpret_cast<intptr_t>(Object::null())); | 1855 const Immediate& raw_null = |
| 1856 __ cmpq(instantiator_reg, raw_null); | 1856 Immediate(reinterpret_cast<intptr_t>(Object::null())); |
| 1857 __ j(EQUAL, &type_arguments_instantiated, Assembler::kNearJump); | 1857 __ cmpq(instantiator_reg, raw_null); |
| 1858 __ j(EQUAL, &type_arguments_instantiated, Assembler::kNearJump); |
| 1859 } |
| 1860 // Instantiate non-null type arguments. |
| 1861 // A runtime call to instantiate the type arguments is required. |
| 1862 __ PushObject(Object::ZoneHandle()); // Make room for the result. |
| 1863 __ PushObject(type_arguments()); |
| 1864 __ pushq(instantiator_reg); // Push instantiator type arguments. |
| 1865 compiler->GenerateCallRuntime(token_pos(), |
| 1866 deopt_id(), |
| 1867 kInstantiateTypeArgumentsRuntimeEntry, |
| 1868 locs()); |
| 1869 __ Drop(2); // Drop instantiator and uninstantiated type arguments. |
| 1870 __ popq(result_reg); // Pop instantiated type arguments. |
| 1871 __ Bind(&type_arguments_instantiated); |
| 1858 } | 1872 } |
| 1859 // Instantiate non-null type arguments. | |
| 1860 if (type_arguments().IsUninstantiatedIdentity()) { | |
| 1861 // Check if the instantiator type argument vector is a TypeArguments of a | |
| 1862 // matching length and, if so, use it as the instantiated type_arguments. | |
| 1863 // No need to check the instantiator ('instantiator_reg') for null here, | |
| 1864 // because a null instantiator will have the wrong class (Null instead of | |
| 1865 // TypeArguments). | |
| 1866 Label type_arguments_uninstantiated; | |
| 1867 __ CompareClassId(instantiator_reg, kTypeArgumentsCid); | |
| 1868 __ j(NOT_EQUAL, &type_arguments_uninstantiated, Assembler::kNearJump); | |
| 1869 __ cmpq(FieldAddress(instantiator_reg, TypeArguments::length_offset()), | |
| 1870 Immediate(Smi::RawValue(len))); | |
| 1871 __ j(EQUAL, &type_arguments_instantiated, Assembler::kNearJump); | |
| 1872 __ Bind(&type_arguments_uninstantiated); | |
| 1873 } | |
| 1874 // A runtime call to instantiate the type arguments is required. | |
| 1875 __ PushObject(Object::ZoneHandle()); // Make room for the result. | |
| 1876 __ PushObject(type_arguments()); | |
| 1877 __ pushq(instantiator_reg); // Push instantiator type arguments. | |
| 1878 compiler->GenerateCallRuntime(token_pos(), | |
| 1879 deopt_id(), | |
| 1880 kInstantiateTypeArgumentsRuntimeEntry, | |
| 1881 locs()); | |
| 1882 __ Drop(2); // Drop instantiator and uninstantiated type arguments. | |
| 1883 __ popq(result_reg); // Pop instantiated type arguments. | |
| 1884 __ Bind(&type_arguments_instantiated); | |
| 1885 ASSERT(instantiator_reg == result_reg); | 1873 ASSERT(instantiator_reg == result_reg); |
| 1886 // 'result_reg': Instantiated type arguments. | 1874 // 'result_reg': Instantiated type arguments. |
| 1887 } | 1875 } |
| 1888 | 1876 |
| 1889 | 1877 |
| 1890 LocationSummary* | 1878 LocationSummary* |
| 1891 ExtractConstructorTypeArgumentsInstr::MakeLocationSummary() const { | 1879 ExtractConstructorTypeArgumentsInstr::MakeLocationSummary() const { |
| 1892 const intptr_t kNumInputs = 1; | 1880 const intptr_t kNumInputs = 1; |
| 1893 const intptr_t kNumTemps = 0; | 1881 const intptr_t kNumTemps = 0; |
| 1894 LocationSummary* locs = | 1882 LocationSummary* locs = |
| 1895 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 1883 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 1896 locs->set_in(0, Location::RequiresRegister()); | 1884 locs->set_in(0, Location::RequiresRegister()); |
| 1897 locs->set_out(Location::SameAsFirstInput()); | 1885 locs->set_out(Location::SameAsFirstInput()); |
| 1898 return locs; | 1886 return locs; |
| 1899 } | 1887 } |
| 1900 | 1888 |
| 1901 | 1889 |
| 1902 void ExtractConstructorTypeArgumentsInstr::EmitNativeCode( | 1890 void ExtractConstructorTypeArgumentsInstr::EmitNativeCode( |
| 1903 FlowGraphCompiler* compiler) { | 1891 FlowGraphCompiler* compiler) { |
| 1904 Register instantiator_reg = locs()->in(0).reg(); | 1892 Register instantiator_reg = locs()->in(0).reg(); |
| 1905 Register result_reg = locs()->out().reg(); | 1893 Register result_reg = locs()->out().reg(); |
| 1906 ASSERT(instantiator_reg == result_reg); | 1894 ASSERT(instantiator_reg == result_reg); |
| 1907 | 1895 |
| 1908 // instantiator_reg is the instantiator type argument vector, i.e. an | 1896 // instantiator_reg is the instantiator type argument vector, i.e. an |
| 1909 // AbstractTypeArguments object (or null). | 1897 // AbstractTypeArguments object (or null). |
| 1910 // If the instantiator is null and if the type argument vector | 1898 if (!type_arguments().IsUninstantiatedIdentity()) { |
| 1911 // instantiated from null becomes a vector of dynamic, then use null as | 1899 // If the instantiator is null and if the type argument vector |
| 1912 // the type arguments. | 1900 // instantiated from null becomes a vector of dynamic, then use null as |
| 1913 Label type_arguments_instantiated; | 1901 // the type arguments. |
| 1914 const intptr_t len = type_arguments().Length(); | 1902 Label type_arguments_instantiated; |
| 1915 if (type_arguments().IsRawInstantiatedRaw(len)) { | 1903 const intptr_t len = type_arguments().Length(); |
| 1916 const Immediate& raw_null = | 1904 if (type_arguments().IsRawInstantiatedRaw(len)) { |
| 1917 Immediate(reinterpret_cast<intptr_t>(Object::null())); | 1905 const Immediate& raw_null = |
| 1918 __ cmpq(instantiator_reg, raw_null); | 1906 Immediate(reinterpret_cast<intptr_t>(Object::null())); |
| 1919 __ j(EQUAL, &type_arguments_instantiated, Assembler::kNearJump); | 1907 __ cmpq(instantiator_reg, raw_null); |
| 1908 __ j(EQUAL, &type_arguments_instantiated, Assembler::kNearJump); |
| 1909 } |
| 1910 // Instantiate non-null type arguments. |
| 1911 // In the non-factory case, we rely on the allocation stub to |
| 1912 // instantiate the type arguments. |
| 1913 __ LoadObject(result_reg, type_arguments()); |
| 1914 // result_reg: uninstantiated type arguments. |
| 1915 __ Bind(&type_arguments_instantiated); |
| 1920 } | 1916 } |
| 1921 // Instantiate non-null type arguments. | 1917 ASSERT(instantiator_reg == result_reg); |
| 1922 if (type_arguments().IsUninstantiatedIdentity()) { | |
| 1923 // Check if the instantiator type argument vector is a TypeArguments of a | |
| 1924 // matching length and, if so, use it as the instantiated type_arguments. | |
| 1925 // No need to check instantiator_reg for null here, because a null | |
| 1926 // instantiator will have the wrong class (Null instead of TypeArguments). | |
| 1927 Label type_arguments_uninstantiated; | |
| 1928 __ CompareClassId(instantiator_reg, kTypeArgumentsCid); | |
| 1929 __ j(NOT_EQUAL, &type_arguments_uninstantiated, Assembler::kNearJump); | |
| 1930 const Immediate& arguments_length = | |
| 1931 Immediate(Smi::RawValue(type_arguments().Length())); | |
| 1932 __ cmpq(FieldAddress(instantiator_reg, TypeArguments::length_offset()), | |
| 1933 arguments_length); | |
| 1934 __ j(EQUAL, &type_arguments_instantiated, Assembler::kNearJump); | |
| 1935 __ Bind(&type_arguments_uninstantiated); | |
| 1936 } | |
| 1937 // In the non-factory case, we rely on the allocation stub to | |
| 1938 // instantiate the type arguments. | |
| 1939 __ LoadObject(result_reg, type_arguments()); | |
| 1940 // result_reg: uninstantiated type arguments. | |
| 1941 __ Bind(&type_arguments_instantiated); | |
| 1942 // result_reg: uninstantiated or instantiated type arguments. | 1918 // result_reg: uninstantiated or instantiated type arguments. |
| 1943 } | 1919 } |
| 1944 | 1920 |
| 1945 | 1921 |
| 1946 LocationSummary* | 1922 LocationSummary* |
| 1947 ExtractConstructorInstantiatorInstr::MakeLocationSummary() const { | 1923 ExtractConstructorInstantiatorInstr::MakeLocationSummary() const { |
| 1948 const intptr_t kNumInputs = 1; | 1924 const intptr_t kNumInputs = 1; |
| 1949 const intptr_t kNumTemps = 0; | 1925 const intptr_t kNumTemps = 0; |
| 1950 LocationSummary* locs = | 1926 LocationSummary* locs = |
| 1951 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 1927 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 1952 locs->set_in(0, Location::RequiresRegister()); | 1928 locs->set_in(0, Location::RequiresRegister()); |
| 1953 locs->set_out(Location::SameAsFirstInput()); | 1929 locs->set_out(Location::SameAsFirstInput()); |
| 1954 return locs; | 1930 return locs; |
| 1955 } | 1931 } |
| 1956 | 1932 |
| 1957 | 1933 |
| 1958 void ExtractConstructorInstantiatorInstr::EmitNativeCode( | 1934 void ExtractConstructorInstantiatorInstr::EmitNativeCode( |
| 1959 FlowGraphCompiler* compiler) { | 1935 FlowGraphCompiler* compiler) { |
| 1960 Register instantiator_reg = locs()->in(0).reg(); | 1936 Register instantiator_reg = locs()->in(0).reg(); |
| 1961 ASSERT(locs()->out().reg() == instantiator_reg); | 1937 ASSERT(locs()->out().reg() == instantiator_reg); |
| 1962 | 1938 |
| 1963 // instantiator_reg is the instantiator AbstractTypeArguments object | 1939 // instantiator_reg is the instantiator AbstractTypeArguments object |
| 1964 // (or null). If the instantiator is null and if the type argument vector | 1940 // (or null). |
| 1965 // instantiated from null becomes a vector of dynamic, then use null as | |
| 1966 // the type arguments and do not pass the instantiator. | |
| 1967 Label done; | |
| 1968 const intptr_t len = type_arguments().Length(); | |
| 1969 if (type_arguments().IsRawInstantiatedRaw(len)) { | |
| 1970 const Immediate& raw_null = | |
| 1971 Immediate(reinterpret_cast<intptr_t>(Object::null())); | |
| 1972 Label instantiator_not_null; | |
| 1973 __ cmpq(instantiator_reg, raw_null); | |
| 1974 __ j(NOT_EQUAL, &instantiator_not_null, Assembler::kNearJump); | |
| 1975 // Null was used in VisitExtractConstructorTypeArguments as the | |
| 1976 // instantiated type arguments, no proper instantiator needed. | |
| 1977 __ movq(instantiator_reg, | |
| 1978 Immediate(Smi::RawValue(StubCode::kNoInstantiator))); | |
| 1979 __ jmp(&done); | |
| 1980 __ Bind(&instantiator_not_null); | |
| 1981 } | |
| 1982 // Instantiate non-null type arguments. | |
| 1983 if (type_arguments().IsUninstantiatedIdentity()) { | 1941 if (type_arguments().IsUninstantiatedIdentity()) { |
| 1984 // TODO(regis): The following emitted code is duplicated in | |
| 1985 // VisitExtractConstructorTypeArguments above. The reason is that the code | |
| 1986 // is split between two computations, so that each one produces a | |
| 1987 // single value, rather than producing a pair of values. | |
| 1988 // If this becomes an issue, we should expose these tests at the IL level. | |
| 1989 | |
| 1990 // Check if the instantiator type argument vector is a TypeArguments of a | |
| 1991 // matching length and, if so, use it as the instantiated type_arguments. | |
| 1992 // No need to check the instantiator ('instantiator_reg') for null here, | |
| 1993 // because a null instantiator will have the wrong class (Null instead of | |
| 1994 // TypeArguments). | |
| 1995 __ CompareClassId(instantiator_reg, kTypeArgumentsCid); | |
| 1996 __ j(NOT_EQUAL, &done, Assembler::kNearJump); | |
| 1997 const Immediate& arguments_length = | |
| 1998 Immediate(Smi::RawValue(type_arguments().Length())); | |
| 1999 __ cmpq(FieldAddress(instantiator_reg, TypeArguments::length_offset()), | |
| 2000 arguments_length); | |
| 2001 __ j(NOT_EQUAL, &done, Assembler::kNearJump); | |
| 2002 // The instantiator was used in VisitExtractConstructorTypeArguments as the | 1942 // The instantiator was used in VisitExtractConstructorTypeArguments as the |
| 2003 // instantiated type arguments, no proper instantiator needed. | 1943 // instantiated type arguments, no proper instantiator needed. |
| 2004 __ movq(instantiator_reg, | 1944 __ movq(instantiator_reg, |
| 2005 Immediate(Smi::RawValue(StubCode::kNoInstantiator))); | 1945 Immediate(Smi::RawValue(StubCode::kNoInstantiator))); |
| 1946 } else { |
| 1947 // If the instantiator is null and if the type argument vector |
| 1948 // instantiated from null becomes a vector of dynamic, then use null as |
| 1949 // the type arguments and do not pass the instantiator. |
| 1950 const intptr_t len = type_arguments().Length(); |
| 1951 if (type_arguments().IsRawInstantiatedRaw(len)) { |
| 1952 const Immediate& raw_null = |
| 1953 Immediate(reinterpret_cast<intptr_t>(Object::null())); |
| 1954 Label instantiator_not_null; |
| 1955 __ cmpq(instantiator_reg, raw_null); |
| 1956 __ j(NOT_EQUAL, &instantiator_not_null, Assembler::kNearJump); |
| 1957 // Null was used in VisitExtractConstructorTypeArguments as the |
| 1958 // instantiated type arguments, no proper instantiator needed. |
| 1959 __ movq(instantiator_reg, |
| 1960 Immediate(Smi::RawValue(StubCode::kNoInstantiator))); |
| 1961 __ Bind(&instantiator_not_null); |
| 1962 } |
| 2006 } | 1963 } |
| 2007 __ Bind(&done); | |
| 2008 // instantiator_reg: instantiator or kNoInstantiator. | 1964 // instantiator_reg: instantiator or kNoInstantiator. |
| 2009 } | 1965 } |
| 2010 | 1966 |
| 2011 | 1967 |
| 2012 LocationSummary* AllocateContextInstr::MakeLocationSummary() const { | 1968 LocationSummary* AllocateContextInstr::MakeLocationSummary() const { |
| 2013 const intptr_t kNumInputs = 0; | 1969 const intptr_t kNumInputs = 0; |
| 2014 const intptr_t kNumTemps = 1; | 1970 const intptr_t kNumTemps = 1; |
| 2015 LocationSummary* locs = | 1971 LocationSummary* locs = |
| 2016 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 1972 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
| 2017 locs->set_temp(0, Location::RegisterLocation(R10)); | 1973 locs->set_temp(0, Location::RegisterLocation(R10)); |
| (...skipping 1715 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3733 PcDescriptors::kOther, | 3689 PcDescriptors::kOther, |
| 3734 locs()); | 3690 locs()); |
| 3735 __ Drop(2); // Discard type arguments and receiver. | 3691 __ Drop(2); // Discard type arguments and receiver. |
| 3736 } | 3692 } |
| 3737 | 3693 |
| 3738 } // namespace dart | 3694 } // namespace dart |
| 3739 | 3695 |
| 3740 #undef __ | 3696 #undef __ |
| 3741 | 3697 |
| 3742 #endif // defined TARGET_ARCH_X64 | 3698 #endif // defined TARGET_ARCH_X64 |
| OLD | NEW |