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

Side by Side Diff: src/code-stubs-hydrogen.cc

Issue 1563213002: Type Feedback Vector lives in the closure (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Exclude an ignition test. Created 4 years, 11 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
« no previous file with comments | « src/code-stubs.cc ('k') | src/compiler.h » ('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 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/code-stubs.h" 5 #include "src/code-stubs.h"
6 6
7 #include "src/bailout-reason.h" 7 #include "src/bailout-reason.h"
8 #include "src/crankshaft/hydrogen.h" 8 #include "src/crankshaft/hydrogen.h"
9 #include "src/crankshaft/lithium.h" 9 #include "src/crankshaft/lithium.h"
10 #include "src/field-index.h" 10 #include "src/field-index.h"
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
87 HValue* UnmappedCase(HValue* elements, HValue* key, HValue* value); 87 HValue* UnmappedCase(HValue* elements, HValue* key, HValue* value);
88 HValue* EmitKeyedSloppyArguments(HValue* receiver, HValue* key, 88 HValue* EmitKeyedSloppyArguments(HValue* receiver, HValue* key,
89 HValue* value); 89 HValue* value);
90 90
91 HValue* BuildArrayConstructor(ElementsKind kind, 91 HValue* BuildArrayConstructor(ElementsKind kind,
92 AllocationSiteOverrideMode override_mode, 92 AllocationSiteOverrideMode override_mode,
93 ArgumentClass argument_class); 93 ArgumentClass argument_class);
94 HValue* BuildInternalArrayConstructor(ElementsKind kind, 94 HValue* BuildInternalArrayConstructor(ElementsKind kind,
95 ArgumentClass argument_class); 95 ArgumentClass argument_class);
96 96
97 // BuildCheckAndInstallOptimizedCode emits code to install the optimized
98 // function found in the optimized code map at map_index in js_function, if
99 // the function at map_index matches the given native_context. Builder is
100 // left in the "Then()" state after the install.
101 void BuildCheckAndInstallOptimizedCode(HValue* js_function,
102 HValue* native_context,
103 IfBuilder* builder,
104 HValue* optimized_map,
105 HValue* map_index);
106 void BuildInstallOptimizedCode(HValue* js_function, HValue* native_context,
107 HValue* code_object, HValue* literals);
108 void BuildInstallCode(HValue* js_function, HValue* shared_info);
109
110 HInstruction* LoadFromOptimizedCodeMap(HValue* optimized_map,
111 HValue* iterator,
112 int field_offset);
113 void BuildInstallFromOptimizedCodeMap(HValue* js_function,
114 HValue* shared_info,
115 HValue* native_context);
116
117 HValue* BuildToString(HValue* input, bool convert); 97 HValue* BuildToString(HValue* input, bool convert);
118 HValue* BuildToPrimitive(HValue* input, HValue* input_map); 98 HValue* BuildToPrimitive(HValue* input, HValue* input_map);
119 99
120 private: 100 private:
121 HValue* BuildArraySingleArgumentConstructor(JSArrayBuilder* builder); 101 HValue* BuildArraySingleArgumentConstructor(JSArrayBuilder* builder);
122 HValue* BuildArrayNArgumentsConstructor(JSArrayBuilder* builder, 102 HValue* BuildArrayNArgumentsConstructor(JSArrayBuilder* builder,
123 ElementsKind kind); 103 ElementsKind kind);
124 104
125 base::SmartArrayPointer<HParameter*> parameters_; 105 base::SmartArrayPointer<HParameter*> parameters_;
126 HValue* arguments_length_; 106 HValue* arguments_length_;
(...skipping 1730 matching lines...) Expand 10 before | Expand all | Expand 10 after
1857 template <> 1837 template <>
1858 HValue* CodeStubGraphBuilder<ToObjectStub>::BuildCodeStub() { 1838 HValue* CodeStubGraphBuilder<ToObjectStub>::BuildCodeStub() {
1859 HValue* receiver = GetParameter(ToObjectDescriptor::kReceiverIndex); 1839 HValue* receiver = GetParameter(ToObjectDescriptor::kReceiverIndex);
1860 return BuildToObject(receiver); 1840 return BuildToObject(receiver);
1861 } 1841 }
1862 1842
1863 1843
1864 Handle<Code> ToObjectStub::GenerateCode() { return DoGenerateCode(this); } 1844 Handle<Code> ToObjectStub::GenerateCode() { return DoGenerateCode(this); }
1865 1845
1866 1846
1867 void CodeStubGraphBuilderBase::BuildCheckAndInstallOptimizedCode(
1868 HValue* js_function,
1869 HValue* native_context,
1870 IfBuilder* builder,
1871 HValue* optimized_map,
1872 HValue* map_index) {
1873 HValue* osr_ast_id_none = Add<HConstant>(BailoutId::None().ToInt());
1874 HValue* context_slot = LoadFromOptimizedCodeMap(
1875 optimized_map, map_index, SharedFunctionInfo::kContextOffset);
1876 context_slot = Add<HLoadNamedField>(context_slot, nullptr,
1877 HObjectAccess::ForWeakCellValue());
1878 HValue* osr_ast_slot = LoadFromOptimizedCodeMap(
1879 optimized_map, map_index, SharedFunctionInfo::kOsrAstIdOffset);
1880 HValue* code_object = LoadFromOptimizedCodeMap(
1881 optimized_map, map_index, SharedFunctionInfo::kCachedCodeOffset);
1882 code_object = Add<HLoadNamedField>(code_object, nullptr,
1883 HObjectAccess::ForWeakCellValue());
1884 builder->If<HCompareObjectEqAndBranch>(native_context,
1885 context_slot);
1886 builder->AndIf<HCompareObjectEqAndBranch>(osr_ast_slot, osr_ast_id_none);
1887 builder->And();
1888 builder->IfNot<HCompareObjectEqAndBranch>(code_object,
1889 graph()->GetConstant0());
1890 builder->Then();
1891 HValue* literals = LoadFromOptimizedCodeMap(optimized_map,
1892 map_index, SharedFunctionInfo::kLiteralsOffset);
1893 literals = Add<HLoadNamedField>(literals, nullptr,
1894 HObjectAccess::ForWeakCellValue());
1895 IfBuilder maybe_deopt(this);
1896 maybe_deopt.If<HCompareObjectEqAndBranch>(literals, graph()->GetConstant0());
1897 maybe_deopt.ThenDeopt(Deoptimizer::kLiteralsWereDisposed);
1898 maybe_deopt.End();
1899
1900 BuildInstallOptimizedCode(js_function, native_context, code_object, literals);
1901
1902 // The builder continues in the "then" after this function.
1903 }
1904
1905
1906 void CodeStubGraphBuilderBase::BuildInstallOptimizedCode(HValue* js_function,
1907 HValue* native_context,
1908 HValue* code_object,
1909 HValue* literals) {
1910 Counters* counters = isolate()->counters();
1911 AddIncrementCounter(counters->fast_new_closure_install_optimized());
1912
1913 // TODO(fschneider): Idea: store proper code pointers in the optimized code
1914 // map and either unmangle them on marking or do nothing as the whole map is
1915 // discarded on major GC anyway.
1916 Add<HStoreCodeEntry>(js_function, code_object);
1917 Add<HStoreNamedField>(js_function, HObjectAccess::ForLiteralsPointer(),
1918 literals);
1919
1920 // Now link a function into a list of optimized functions.
1921 HValue* optimized_functions_list = Add<HLoadNamedField>(
1922 native_context, nullptr,
1923 HObjectAccess::ForContextSlot(Context::OPTIMIZED_FUNCTIONS_LIST));
1924 Add<HStoreNamedField>(js_function,
1925 HObjectAccess::ForNextFunctionLinkPointer(),
1926 optimized_functions_list);
1927
1928 // This store is the only one that should have a write barrier.
1929 Add<HStoreNamedField>(native_context,
1930 HObjectAccess::ForContextSlot(Context::OPTIMIZED_FUNCTIONS_LIST),
1931 js_function);
1932 }
1933
1934
1935 void CodeStubGraphBuilderBase::BuildInstallCode(HValue* js_function,
1936 HValue* shared_info) {
1937 Add<HStoreNamedField>(js_function,
1938 HObjectAccess::ForNextFunctionLinkPointer(),
1939 graph()->GetConstantUndefined());
1940 HValue* code_object = Add<HLoadNamedField>(shared_info, nullptr,
1941 HObjectAccess::ForCodeOffset());
1942 Add<HStoreCodeEntry>(js_function, code_object);
1943 }
1944
1945
1946 HInstruction* CodeStubGraphBuilderBase::LoadFromOptimizedCodeMap(
1947 HValue* optimized_map,
1948 HValue* iterator,
1949 int field_offset) {
1950 // By making sure to express these loads in the form [<hvalue> + constant]
1951 // the keyed load can be hoisted.
1952 DCHECK(field_offset >= 0 && field_offset < SharedFunctionInfo::kEntryLength);
1953 HValue* field_slot = iterator;
1954 if (field_offset > 0) {
1955 HValue* field_offset_value = Add<HConstant>(field_offset);
1956 field_slot = AddUncasted<HAdd>(iterator, field_offset_value);
1957 }
1958 HInstruction* field_entry = Add<HLoadKeyed>(optimized_map, field_slot,
1959 nullptr, nullptr, FAST_ELEMENTS);
1960 return field_entry;
1961 }
1962
1963
1964 void CodeStubGraphBuilderBase::BuildInstallFromOptimizedCodeMap(
1965 HValue* js_function,
1966 HValue* shared_info,
1967 HValue* native_context) {
1968 Counters* counters = isolate()->counters();
1969 Factory* factory = isolate()->factory();
1970 IfBuilder is_optimized(this);
1971 HInstruction* optimized_map = Add<HLoadNamedField>(
1972 shared_info, nullptr, HObjectAccess::ForOptimizedCodeMap());
1973 HValue* null_constant = Add<HConstant>(0);
1974 is_optimized.If<HCompareObjectEqAndBranch>(optimized_map, null_constant);
1975 is_optimized.Then();
1976 {
1977 BuildInstallCode(js_function, shared_info);
1978 }
1979 is_optimized.Else();
1980 {
1981 AddIncrementCounter(counters->fast_new_closure_try_optimized());
1982 // The {optimized_map} points to fixed array of 4-element entries:
1983 // (native context, optimized code, literals, ast-id).
1984 // Iterate through the {optimized_map} backwards. After the loop, if no
1985 // matching optimized code was found, install unoptimized code.
1986 // for(i = map.length() - SharedFunctionInfo::kEntryLength;
1987 // i >= SharedFunctionInfo::kEntriesStart;
1988 // i -= SharedFunctionInfo::kEntryLength) { ... }
1989 HValue* first_entry_index =
1990 Add<HConstant>(SharedFunctionInfo::kEntriesStart);
1991 HValue* shared_function_entry_length =
1992 Add<HConstant>(SharedFunctionInfo::kEntryLength);
1993 LoopBuilder loop_builder(this, context(), LoopBuilder::kPostDecrement,
1994 shared_function_entry_length);
1995 HValue* array_length = Add<HLoadNamedField>(
1996 optimized_map, nullptr, HObjectAccess::ForFixedArrayLength());
1997 HValue* start_pos =
1998 AddUncasted<HSub>(array_length, shared_function_entry_length);
1999 HValue* slot_iterator =
2000 loop_builder.BeginBody(start_pos, first_entry_index, Token::GTE);
2001 {
2002 IfBuilder done_check(this);
2003 BuildCheckAndInstallOptimizedCode(js_function, native_context,
2004 &done_check, optimized_map,
2005 slot_iterator);
2006 // Fall out of the loop
2007 loop_builder.Break();
2008 }
2009 loop_builder.EndBody();
2010
2011 // If {slot_iterator} is less than the first entry index, then we failed to
2012 // find a context-dependent code and try context-independent code next.
2013 IfBuilder no_optimized_code_check(this);
2014 no_optimized_code_check.If<HCompareNumericAndBranch>(
2015 slot_iterator, first_entry_index, Token::LT);
2016 no_optimized_code_check.Then();
2017 {
2018 IfBuilder shared_code_check(this);
2019 HValue* shared_code =
2020 Add<HLoadNamedField>(optimized_map, nullptr,
2021 HObjectAccess::ForOptimizedCodeMapSharedCode());
2022 shared_code = Add<HLoadNamedField>(shared_code, nullptr,
2023 HObjectAccess::ForWeakCellValue());
2024 shared_code_check.IfNot<HCompareObjectEqAndBranch>(
2025 shared_code, graph()->GetConstant0());
2026 shared_code_check.Then();
2027 {
2028 // Store the context-independent optimized code.
2029 HValue* literals = Add<HConstant>(factory->empty_fixed_array());
2030 BuildInstallOptimizedCode(js_function, native_context, shared_code,
2031 literals);
2032 }
2033 shared_code_check.Else();
2034 {
2035 // Store the unoptimized code.
2036 BuildInstallCode(js_function, shared_info);
2037 }
2038 }
2039 }
2040 }
2041
2042
2043 template<> 1847 template<>
2044 HValue* CodeStubGraphBuilder<FastNewClosureStub>::BuildCodeStub() { 1848 HValue* CodeStubGraphBuilder<FastNewClosureStub>::BuildCodeStub() {
2045 Counters* counters = isolate()->counters(); 1849 Counters* counters = isolate()->counters();
2046 Factory* factory = isolate()->factory(); 1850 Factory* factory = isolate()->factory();
2047 HInstruction* empty_fixed_array = 1851 HInstruction* empty_fixed_array =
2048 Add<HConstant>(factory->empty_fixed_array()); 1852 Add<HConstant>(factory->empty_fixed_array());
1853 HInstruction* empty_literals_array =
1854 Add<HConstant>(factory->empty_literals_array());
2049 HValue* shared_info = GetParameter(0); 1855 HValue* shared_info = GetParameter(0);
2050 1856
2051 AddIncrementCounter(counters->fast_new_closure_total()); 1857 AddIncrementCounter(counters->fast_new_closure_total());
2052 1858
2053 // Create a new closure from the given function info in new space 1859 // Create a new closure from the given function info in new space
2054 HValue* size = Add<HConstant>(JSFunction::kSize); 1860 HValue* size = Add<HConstant>(JSFunction::kSize);
2055 HInstruction* js_function = 1861 HInstruction* js_function =
2056 Add<HAllocate>(size, HType::JSObject(), NOT_TENURED, JS_FUNCTION_TYPE); 1862 Add<HAllocate>(size, HType::JSObject(), NOT_TENURED, JS_FUNCTION_TYPE);
2057 1863
2058 int map_index = Context::FunctionMapIndex(casted_stub()->language_mode(), 1864 int map_index = Context::FunctionMapIndex(casted_stub()->language_mode(),
2059 casted_stub()->kind()); 1865 casted_stub()->kind());
2060 1866
2061 // Compute the function map in the current native context and set that 1867 // Compute the function map in the current native context and set that
2062 // as the map of the allocated object. 1868 // as the map of the allocated object.
2063 HInstruction* native_context = BuildGetNativeContext(); 1869 HInstruction* native_context = BuildGetNativeContext();
2064 HInstruction* map_slot_value = Add<HLoadNamedField>( 1870 HInstruction* map_slot_value = Add<HLoadNamedField>(
2065 native_context, nullptr, HObjectAccess::ForContextSlot(map_index)); 1871 native_context, nullptr, HObjectAccess::ForContextSlot(map_index));
2066 Add<HStoreNamedField>(js_function, HObjectAccess::ForMap(), map_slot_value); 1872 Add<HStoreNamedField>(js_function, HObjectAccess::ForMap(), map_slot_value);
2067 1873
2068 // Initialize the rest of the function. 1874 // Initialize the rest of the function.
2069 Add<HStoreNamedField>(js_function, HObjectAccess::ForPropertiesPointer(), 1875 Add<HStoreNamedField>(js_function, HObjectAccess::ForPropertiesPointer(),
2070 empty_fixed_array); 1876 empty_fixed_array);
2071 Add<HStoreNamedField>(js_function, HObjectAccess::ForElementsPointer(), 1877 Add<HStoreNamedField>(js_function, HObjectAccess::ForElementsPointer(),
2072 empty_fixed_array); 1878 empty_fixed_array);
2073 Add<HStoreNamedField>(js_function, HObjectAccess::ForLiteralsPointer(), 1879 Add<HStoreNamedField>(js_function, HObjectAccess::ForLiteralsPointer(),
2074 empty_fixed_array); 1880 empty_literals_array);
2075 Add<HStoreNamedField>(js_function, HObjectAccess::ForPrototypeOrInitialMap(), 1881 Add<HStoreNamedField>(js_function, HObjectAccess::ForPrototypeOrInitialMap(),
2076 graph()->GetConstantHole()); 1882 graph()->GetConstantHole());
2077 Add<HStoreNamedField>( 1883 Add<HStoreNamedField>(
2078 js_function, HObjectAccess::ForSharedFunctionInfoPointer(), shared_info); 1884 js_function, HObjectAccess::ForSharedFunctionInfoPointer(), shared_info);
2079 Add<HStoreNamedField>(js_function, HObjectAccess::ForFunctionContextPointer(), 1885 Add<HStoreNamedField>(js_function, HObjectAccess::ForFunctionContextPointer(),
2080 context()); 1886 context());
2081 1887 Handle<Code> lazy_builtin(
2082 // Initialize the code pointer in the function to be the one found in the 1888 isolate()->builtins()->builtin(Builtins::kCompileLazy));
2083 // shared function info object. But first check if there is an optimized 1889 HConstant* lazy = Add<HConstant>(lazy_builtin);
2084 // version for our context. 1890 Add<HStoreCodeEntry>(js_function, lazy);
2085 BuildInstallFromOptimizedCodeMap(js_function, shared_info, native_context); 1891 Add<HStoreNamedField>(js_function,
2086 1892 HObjectAccess::ForNextFunctionLinkPointer(),
1893 graph()->GetConstantUndefined());
2087 return js_function; 1894 return js_function;
2088 } 1895 }
2089 1896
2090 1897
2091 Handle<Code> FastNewClosureStub::GenerateCode() { 1898 Handle<Code> FastNewClosureStub::GenerateCode() {
2092 return DoGenerateCode(this); 1899 return DoGenerateCode(this);
2093 } 1900 }
2094 1901
2095 1902
2096 template<> 1903 template<>
(...skipping 333 matching lines...) Expand 10 before | Expand all | Expand 10 after
2430 return Pop(); 2237 return Pop();
2431 } 2238 }
2432 2239
2433 2240
2434 Handle<Code> KeyedLoadGenericStub::GenerateCode() { 2241 Handle<Code> KeyedLoadGenericStub::GenerateCode() {
2435 return DoGenerateCode(this); 2242 return DoGenerateCode(this);
2436 } 2243 }
2437 2244
2438 } // namespace internal 2245 } // namespace internal
2439 } // namespace v8 2246 } // namespace v8
OLDNEW
« no previous file with comments | « src/code-stubs.cc ('k') | src/compiler.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698