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

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

Issue 14238036: Improve type optimization reusing the type argument vector of the instantiator (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 8 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
« no previous file with comments | « runtime/vm/intermediate_language_arm.cc ('k') | runtime/vm/intermediate_language_mips.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/globals.h" // Needed here to get TARGET_ARCH_IA32. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_IA32.
6 #if defined(TARGET_ARCH_IA32) 6 #if defined(TARGET_ARCH_IA32)
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 1841 matching lines...) Expand 10 before | Expand all | Expand 10 after
1852 void LoadFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1852 void LoadFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
1853 Register instance_reg = locs()->in(0).reg(); 1853 Register instance_reg = locs()->in(0).reg();
1854 Register result_reg = locs()->out().reg(); 1854 Register result_reg = locs()->out().reg();
1855 1855
1856 __ movl(result_reg, FieldAddress(instance_reg, offset_in_bytes())); 1856 __ movl(result_reg, FieldAddress(instance_reg, offset_in_bytes()));
1857 } 1857 }
1858 1858
1859 1859
1860 LocationSummary* InstantiateTypeArgumentsInstr::MakeLocationSummary() const { 1860 LocationSummary* InstantiateTypeArgumentsInstr::MakeLocationSummary() const {
1861 const intptr_t kNumInputs = 1; 1861 const intptr_t kNumInputs = 1;
1862 const intptr_t kNumTemps = 1; 1862 const intptr_t kNumTemps = 0;
1863 LocationSummary* locs = 1863 LocationSummary* locs =
1864 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 1864 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
1865 locs->set_in(0, Location::RegisterLocation(EAX)); 1865 locs->set_in(0, Location::RegisterLocation(EAX));
1866 locs->set_temp(0, Location::RegisterLocation(ECX));
1867 locs->set_out(Location::RegisterLocation(EAX)); 1866 locs->set_out(Location::RegisterLocation(EAX));
1868 return locs; 1867 return locs;
1869 } 1868 }
1870 1869
1871 1870
1872 void InstantiateTypeArgumentsInstr::EmitNativeCode( 1871 void InstantiateTypeArgumentsInstr::EmitNativeCode(
1873 FlowGraphCompiler* compiler) { 1872 FlowGraphCompiler* compiler) {
1874 Register instantiator_reg = locs()->in(0).reg(); 1873 Register instantiator_reg = locs()->in(0).reg();
1875 Register temp = locs()->temp(0).reg();
1876 Register result_reg = locs()->out().reg(); 1874 Register result_reg = locs()->out().reg();
1877 1875
1878 // 'instantiator_reg' is the instantiator AbstractTypeArguments object 1876 // 'instantiator_reg' is the instantiator AbstractTypeArguments object
1879 // (or null). 1877 // (or null).
1880 // If the instantiator is null and if the type argument vector 1878 if (!type_arguments().IsUninstantiatedIdentity()) {
1881 // instantiated from null becomes a vector of dynamic, then use null as 1879 // If the instantiator is null and if the type argument vector
1882 // the type arguments. 1880 // instantiated from null becomes a vector of dynamic, then use null as
1883 Label type_arguments_instantiated; 1881 // the type arguments.
1884 const intptr_t len = type_arguments().Length(); 1882 Label type_arguments_instantiated;
1885 if (type_arguments().IsRawInstantiatedRaw(len)) { 1883 const intptr_t len = type_arguments().Length();
1886 const Immediate& raw_null = 1884 if (type_arguments().IsRawInstantiatedRaw(len)) {
1887 Immediate(reinterpret_cast<intptr_t>(Object::null())); 1885 const Immediate& raw_null =
1888 __ cmpl(instantiator_reg, raw_null); 1886 Immediate(reinterpret_cast<intptr_t>(Object::null()));
1889 __ j(EQUAL, &type_arguments_instantiated, Assembler::kNearJump); 1887 __ cmpl(instantiator_reg, raw_null);
1888 __ j(EQUAL, &type_arguments_instantiated, Assembler::kNearJump);
1889 }
1890 // Instantiate non-null type arguments.
1891 // A runtime call to instantiate the type arguments is required.
1892 __ PushObject(Object::ZoneHandle()); // Make room for the result.
1893 __ PushObject(type_arguments());
1894 __ pushl(instantiator_reg); // Push instantiator type arguments.
1895 compiler->GenerateCallRuntime(token_pos(),
1896 deopt_id(),
1897 kInstantiateTypeArgumentsRuntimeEntry,
1898 locs());
1899 __ Drop(2); // Drop instantiator and uninstantiated type arguments.
1900 __ popl(result_reg); // Pop instantiated type arguments.
1901 __ Bind(&type_arguments_instantiated);
1890 } 1902 }
1891 // Instantiate non-null type arguments.
1892 if (type_arguments().IsUninstantiatedIdentity()) {
1893 // Check if the instantiator type argument vector is a TypeArguments of a
1894 // matching length and, if so, use it as the instantiated type_arguments.
1895 // No need to check the instantiator ('instantiator_reg') for null here,
1896 // because a null instantiator will have the wrong class (Null instead of
1897 // TypeArguments).
1898 Label type_arguments_uninstantiated;
1899 __ CompareClassId(instantiator_reg, kTypeArgumentsCid, temp);
1900 __ j(NOT_EQUAL, &type_arguments_uninstantiated, Assembler::kNearJump);
1901 __ cmpl(FieldAddress(instantiator_reg, TypeArguments::length_offset()),
1902 Immediate(Smi::RawValue(len)));
1903 __ j(EQUAL, &type_arguments_instantiated, Assembler::kNearJump);
1904 __ Bind(&type_arguments_uninstantiated);
1905 }
1906 // A runtime call to instantiate the type arguments is required.
1907 __ PushObject(Object::ZoneHandle()); // Make room for the result.
1908 __ PushObject(type_arguments());
1909 __ pushl(instantiator_reg); // Push instantiator type arguments.
1910 compiler->GenerateCallRuntime(token_pos(),
1911 deopt_id(),
1912 kInstantiateTypeArgumentsRuntimeEntry,
1913 locs());
1914 __ Drop(2); // Drop instantiator and uninstantiated type arguments.
1915 __ popl(result_reg); // Pop instantiated type arguments.
1916 __ Bind(&type_arguments_instantiated);
1917 ASSERT(instantiator_reg == result_reg); 1903 ASSERT(instantiator_reg == result_reg);
1918 // 'result_reg': Instantiated type arguments. 1904 // 'result_reg': Instantiated type arguments.
1919 } 1905 }
1920 1906
1921 1907
1922 LocationSummary* 1908 LocationSummary*
1923 ExtractConstructorTypeArgumentsInstr::MakeLocationSummary() const { 1909 ExtractConstructorTypeArgumentsInstr::MakeLocationSummary() const {
1924 const intptr_t kNumInputs = 1; 1910 const intptr_t kNumInputs = 1;
1925 const intptr_t kNumTemps = 1; 1911 const intptr_t kNumTemps = 0;
1926 LocationSummary* locs = 1912 LocationSummary* locs =
1927 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 1913 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
1928 locs->set_in(0, Location::RequiresRegister()); 1914 locs->set_in(0, Location::RequiresRegister());
1929 locs->set_out(Location::SameAsFirstInput()); 1915 locs->set_out(Location::SameAsFirstInput());
1930 locs->set_temp(0, Location::RequiresRegister());
1931 return locs; 1916 return locs;
1932 } 1917 }
1933 1918
1934 1919
1935 void ExtractConstructorTypeArgumentsInstr::EmitNativeCode( 1920 void ExtractConstructorTypeArgumentsInstr::EmitNativeCode(
1936 FlowGraphCompiler* compiler) { 1921 FlowGraphCompiler* compiler) {
1937 Register instantiator_reg = locs()->in(0).reg(); 1922 Register instantiator_reg = locs()->in(0).reg();
1938 Register result_reg = locs()->out().reg(); 1923 Register result_reg = locs()->out().reg();
1939 ASSERT(instantiator_reg == result_reg); 1924 ASSERT(instantiator_reg == result_reg);
1940 Register temp_reg = locs()->temp(0).reg();
1941 1925
1942 // instantiator_reg is the instantiator type argument vector, i.e. an 1926 // instantiator_reg is the instantiator type argument vector, i.e. an
1943 // AbstractTypeArguments object (or null). 1927 // AbstractTypeArguments object (or null).
1944 // If the instantiator is null and if the type argument vector 1928 if (!type_arguments().IsUninstantiatedIdentity()) {
1945 // instantiated from null becomes a vector of dynamic, then use null as 1929 // If the instantiator is null and if the type argument vector
1946 // the type arguments. 1930 // instantiated from null becomes a vector of dynamic, then use null as
1947 Label type_arguments_instantiated; 1931 // the type arguments.
1948 const intptr_t len = type_arguments().Length(); 1932 Label type_arguments_instantiated;
1949 if (type_arguments().IsRawInstantiatedRaw(len)) { 1933 const intptr_t len = type_arguments().Length();
1950 const Immediate& raw_null = 1934 if (type_arguments().IsRawInstantiatedRaw(len)) {
1951 Immediate(reinterpret_cast<intptr_t>(Object::null())); 1935 const Immediate& raw_null =
1952 __ cmpl(instantiator_reg, raw_null); 1936 Immediate(reinterpret_cast<intptr_t>(Object::null()));
1953 __ j(EQUAL, &type_arguments_instantiated, Assembler::kNearJump); 1937 __ cmpl(instantiator_reg, raw_null);
1938 __ j(EQUAL, &type_arguments_instantiated, Assembler::kNearJump);
1939 }
1940 // Instantiate non-null type arguments.
1941 // In the non-factory case, we rely on the allocation stub to
1942 // instantiate the type arguments.
1943 __ LoadObject(result_reg, type_arguments());
1944 // result_reg: uninstantiated type arguments.
1945 __ Bind(&type_arguments_instantiated);
1954 } 1946 }
1955 // Instantiate non-null type arguments. 1947 ASSERT(instantiator_reg == result_reg);
1956 if (type_arguments().IsUninstantiatedIdentity()) {
1957 // Check if the instantiator type argument vector is a TypeArguments of a
1958 // matching length and, if so, use it as the instantiated type_arguments.
1959 // No need to check instantiator_reg for null here, because a null
1960 // instantiator will have the wrong class (Null instead of TypeArguments).
1961 Label type_arguments_uninstantiated;
1962 __ CompareClassId(instantiator_reg, kTypeArgumentsCid, temp_reg);
1963 __ j(NOT_EQUAL, &type_arguments_uninstantiated, Assembler::kNearJump);
1964 const Immediate& arguments_length =
1965 Immediate(Smi::RawValue(type_arguments().Length()));
1966 __ cmpl(FieldAddress(instantiator_reg, TypeArguments::length_offset()),
1967 arguments_length);
1968 __ j(EQUAL, &type_arguments_instantiated, Assembler::kNearJump);
1969 __ Bind(&type_arguments_uninstantiated);
1970 }
1971 // In the non-factory case, we rely on the allocation stub to
1972 // instantiate the type arguments.
1973 __ LoadObject(result_reg, type_arguments());
1974 // result_reg: uninstantiated type arguments.
1975 __ Bind(&type_arguments_instantiated);
1976 // result_reg: uninstantiated or instantiated type arguments. 1948 // result_reg: uninstantiated or instantiated type arguments.
1977 } 1949 }
1978 1950
1979 1951
1980 LocationSummary* 1952 LocationSummary*
1981 ExtractConstructorInstantiatorInstr::MakeLocationSummary() const { 1953 ExtractConstructorInstantiatorInstr::MakeLocationSummary() const {
1982 const intptr_t kNumInputs = 1; 1954 const intptr_t kNumInputs = 1;
1983 const intptr_t kNumTemps = 1; 1955 const intptr_t kNumTemps = 0;
1984 LocationSummary* locs = 1956 LocationSummary* locs =
1985 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 1957 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
1986 locs->set_in(0, Location::RequiresRegister()); 1958 locs->set_in(0, Location::RequiresRegister());
1987 locs->set_out(Location::SameAsFirstInput()); 1959 locs->set_out(Location::SameAsFirstInput());
1988 locs->set_temp(0, Location::RequiresRegister());
1989 return locs; 1960 return locs;
1990 } 1961 }
1991 1962
1992 1963
1993 void ExtractConstructorInstantiatorInstr::EmitNativeCode( 1964 void ExtractConstructorInstantiatorInstr::EmitNativeCode(
1994 FlowGraphCompiler* compiler) { 1965 FlowGraphCompiler* compiler) {
1995 Register instantiator_reg = locs()->in(0).reg(); 1966 Register instantiator_reg = locs()->in(0).reg();
1996 ASSERT(locs()->out().reg() == instantiator_reg); 1967 ASSERT(locs()->out().reg() == instantiator_reg);
1997 Register temp_reg = locs()->temp(0).reg();
1998 1968
1999 // instantiator_reg is the instantiator AbstractTypeArguments object 1969 // instantiator_reg is the instantiator AbstractTypeArguments object
2000 // (or null). If the instantiator is null and if the type argument vector 1970 // (or null).
2001 // instantiated from null becomes a vector of dynamic, then use null as
2002 // the type arguments and do not pass the instantiator.
2003 Label done;
2004 const intptr_t len = type_arguments().Length();
2005 if (type_arguments().IsRawInstantiatedRaw(len)) {
2006 const Immediate& raw_null =
2007 Immediate(reinterpret_cast<intptr_t>(Object::null()));
2008 Label instantiator_not_null;
2009 __ cmpl(instantiator_reg, raw_null);
2010 __ j(NOT_EQUAL, &instantiator_not_null, Assembler::kNearJump);
2011 // Null was used in VisitExtractConstructorTypeArguments as the
2012 // instantiated type arguments, no proper instantiator needed.
2013 __ movl(instantiator_reg,
2014 Immediate(Smi::RawValue(StubCode::kNoInstantiator)));
2015 __ jmp(&done);
2016 __ Bind(&instantiator_not_null);
2017 }
2018 // Instantiate non-null type arguments.
2019 if (type_arguments().IsUninstantiatedIdentity()) { 1971 if (type_arguments().IsUninstantiatedIdentity()) {
2020 // TODO(regis): The following emitted code is duplicated in
2021 // VisitExtractConstructorTypeArguments above. The reason is that the code
2022 // is split between two computations, so that each one produces a
2023 // single value, rather than producing a pair of values.
2024 // If this becomes an issue, we should expose these tests at the IL level.
2025
2026 // Check if the instantiator type argument vector is a TypeArguments of a
2027 // matching length and, if so, use it as the instantiated type_arguments.
2028 // No need to check the instantiator for null here, because a null
2029 // instantiator will have the wrong class (Null instead of TypeArguments).
2030 __ CompareClassId(instantiator_reg, kTypeArgumentsCid, temp_reg);
2031 __ j(NOT_EQUAL, &done, Assembler::kNearJump);
2032 const Immediate& arguments_length =
2033 Immediate(Smi::RawValue(type_arguments().Length()));
2034 __ cmpl(FieldAddress(instantiator_reg, TypeArguments::length_offset()),
2035 arguments_length);
2036 __ j(NOT_EQUAL, &done, Assembler::kNearJump);
2037 // The instantiator was used in VisitExtractConstructorTypeArguments as the 1972 // The instantiator was used in VisitExtractConstructorTypeArguments as the
2038 // instantiated type arguments, no proper instantiator needed. 1973 // instantiated type arguments, no proper instantiator needed.
2039 __ movl(instantiator_reg, 1974 __ movl(instantiator_reg,
2040 Immediate(Smi::RawValue(StubCode::kNoInstantiator))); 1975 Immediate(Smi::RawValue(StubCode::kNoInstantiator)));
1976 } else {
1977 // If the instantiator is null and if the type argument vector
1978 // instantiated from null becomes a vector of dynamic, then use null as
1979 // the type arguments and do not pass the instantiator.
1980 const intptr_t len = type_arguments().Length();
1981 if (type_arguments().IsRawInstantiatedRaw(len)) {
1982 const Immediate& raw_null =
1983 Immediate(reinterpret_cast<intptr_t>(Object::null()));
1984 Label instantiator_not_null;
1985 __ cmpl(instantiator_reg, raw_null);
1986 __ j(NOT_EQUAL, &instantiator_not_null, Assembler::kNearJump);
1987 // Null was used in VisitExtractConstructorTypeArguments as the
1988 // instantiated type arguments, no proper instantiator needed.
1989 __ movl(instantiator_reg,
1990 Immediate(Smi::RawValue(StubCode::kNoInstantiator)));
1991 __ Bind(&instantiator_not_null);
1992 }
2041 } 1993 }
2042 __ Bind(&done);
2043 // instantiator_reg: instantiator or kNoInstantiator. 1994 // instantiator_reg: instantiator or kNoInstantiator.
2044 } 1995 }
2045 1996
2046 1997
2047 LocationSummary* AllocateContextInstr::MakeLocationSummary() const { 1998 LocationSummary* AllocateContextInstr::MakeLocationSummary() const {
2048 const intptr_t kNumInputs = 0; 1999 const intptr_t kNumInputs = 0;
2049 const intptr_t kNumTemps = 1; 2000 const intptr_t kNumTemps = 1;
2050 LocationSummary* locs = 2001 LocationSummary* locs =
2051 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 2002 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
2052 locs->set_temp(0, Location::RegisterLocation(EDX)); 2003 locs->set_temp(0, Location::RegisterLocation(EDX));
(...skipping 2044 matching lines...) Expand 10 before | Expand all | Expand 10 after
4097 PcDescriptors::kOther, 4048 PcDescriptors::kOther,
4098 locs()); 4049 locs());
4099 __ Drop(2); // Discard type arguments and receiver. 4050 __ Drop(2); // Discard type arguments and receiver.
4100 } 4051 }
4101 4052
4102 } // namespace dart 4053 } // namespace dart
4103 4054
4104 #undef __ 4055 #undef __
4105 4056
4106 #endif // defined TARGET_ARCH_IA32 4057 #endif // defined TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « runtime/vm/intermediate_language_arm.cc ('k') | runtime/vm/intermediate_language_mips.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698