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

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

Issue 1670143002: Visit the Optimized Code Map on first call rather than closure creation. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Fix mips64 rebase error. Created 4 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
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 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
90 HValue* UnmappedCase(HValue* elements, HValue* key, HValue* value); 90 HValue* UnmappedCase(HValue* elements, HValue* key, HValue* value);
91 HValue* EmitKeyedSloppyArguments(HValue* receiver, HValue* key, 91 HValue* EmitKeyedSloppyArguments(HValue* receiver, HValue* key,
92 HValue* value); 92 HValue* value);
93 93
94 HValue* BuildArrayConstructor(ElementsKind kind, 94 HValue* BuildArrayConstructor(ElementsKind kind,
95 AllocationSiteOverrideMode override_mode, 95 AllocationSiteOverrideMode override_mode,
96 ArgumentClass argument_class); 96 ArgumentClass argument_class);
97 HValue* BuildInternalArrayConstructor(ElementsKind kind, 97 HValue* BuildInternalArrayConstructor(ElementsKind kind,
98 ArgumentClass argument_class); 98 ArgumentClass argument_class);
99 99
100 // BuildCheckAndInstallOptimizedCode emits code to install the optimized
101 // function found in the optimized code map at map_index in js_function, if
102 // the function at map_index matches the given native_context. Builder is
103 // left in the "Then()" state after the install.
104 void BuildCheckAndInstallOptimizedCode(HValue* js_function,
105 HValue* native_context,
106 IfBuilder* builder,
107 HValue* optimized_map,
108 HValue* map_index);
109 void BuildInstallOptimizedCode(HValue* js_function, HValue* native_context,
110 HValue* code_object, HValue* literals);
111 void BuildInstallCode(HValue* js_function, HValue* shared_info);
112
113 HInstruction* LoadFromOptimizedCodeMap(HValue* optimized_map,
114 HValue* iterator,
115 int field_offset);
116 void BuildInstallFromOptimizedCodeMap(HValue* js_function,
117 HValue* shared_info,
118 HValue* native_context);
119
120 HValue* BuildToString(HValue* input, bool convert); 100 HValue* BuildToString(HValue* input, bool convert);
121 HValue* BuildToPrimitive(HValue* input, HValue* input_map); 101 HValue* BuildToPrimitive(HValue* input, HValue* input_map);
122 102
123 private: 103 private:
124 HValue* BuildArraySingleArgumentConstructor(JSArrayBuilder* builder); 104 HValue* BuildArraySingleArgumentConstructor(JSArrayBuilder* builder);
125 HValue* BuildArrayNArgumentsConstructor(JSArrayBuilder* builder, 105 HValue* BuildArrayNArgumentsConstructor(JSArrayBuilder* builder,
126 ElementsKind kind); 106 ElementsKind kind);
127 107
128 base::SmartArrayPointer<HParameter*> parameters_; 108 base::SmartArrayPointer<HParameter*> parameters_;
129 HValue* arguments_length_; 109 HValue* arguments_length_;
(...skipping 1803 matching lines...) Expand 10 before | Expand all | Expand 10 after
1933 template <> 1913 template <>
1934 HValue* CodeStubGraphBuilder<ToObjectStub>::BuildCodeStub() { 1914 HValue* CodeStubGraphBuilder<ToObjectStub>::BuildCodeStub() {
1935 HValue* receiver = GetParameter(TypeConversionDescriptor::kArgumentIndex); 1915 HValue* receiver = GetParameter(TypeConversionDescriptor::kArgumentIndex);
1936 return BuildToObject(receiver); 1916 return BuildToObject(receiver);
1937 } 1917 }
1938 1918
1939 1919
1940 Handle<Code> ToObjectStub::GenerateCode() { return DoGenerateCode(this); } 1920 Handle<Code> ToObjectStub::GenerateCode() { return DoGenerateCode(this); }
1941 1921
1942 1922
1943 void CodeStubGraphBuilderBase::BuildCheckAndInstallOptimizedCode(
1944 HValue* js_function,
1945 HValue* native_context,
1946 IfBuilder* builder,
1947 HValue* optimized_map,
1948 HValue* map_index) {
1949 HValue* osr_ast_id_none = Add<HConstant>(BailoutId::None().ToInt());
1950 HValue* context_slot = LoadFromOptimizedCodeMap(
1951 optimized_map, map_index, SharedFunctionInfo::kContextOffset);
1952 context_slot = Add<HLoadNamedField>(context_slot, nullptr,
1953 HObjectAccess::ForWeakCellValue());
1954 HValue* osr_ast_slot = LoadFromOptimizedCodeMap(
1955 optimized_map, map_index, SharedFunctionInfo::kOsrAstIdOffset);
1956 HValue* code_object = LoadFromOptimizedCodeMap(
1957 optimized_map, map_index, SharedFunctionInfo::kCachedCodeOffset);
1958 code_object = Add<HLoadNamedField>(code_object, nullptr,
1959 HObjectAccess::ForWeakCellValue());
1960 builder->If<HCompareObjectEqAndBranch>(native_context,
1961 context_slot);
1962 builder->AndIf<HCompareObjectEqAndBranch>(osr_ast_slot, osr_ast_id_none);
1963 builder->And();
1964 builder->IfNot<HCompareObjectEqAndBranch>(code_object,
1965 graph()->GetConstant0());
1966 builder->Then();
1967 HValue* literals = LoadFromOptimizedCodeMap(optimized_map,
1968 map_index, SharedFunctionInfo::kLiteralsOffset);
1969 literals = Add<HLoadNamedField>(literals, nullptr,
1970 HObjectAccess::ForWeakCellValue());
1971 IfBuilder maybe_deopt(this);
1972 maybe_deopt.If<HCompareObjectEqAndBranch>(literals, graph()->GetConstant0());
1973 maybe_deopt.ThenDeopt(Deoptimizer::kLiteralsWereDisposed);
1974 maybe_deopt.End();
1975
1976 BuildInstallOptimizedCode(js_function, native_context, code_object, literals);
1977
1978 // The builder continues in the "then" after this function.
1979 }
1980
1981
1982 void CodeStubGraphBuilderBase::BuildInstallOptimizedCode(HValue* js_function,
1983 HValue* native_context,
1984 HValue* code_object,
1985 HValue* literals) {
1986 Counters* counters = isolate()->counters();
1987 AddIncrementCounter(counters->fast_new_closure_install_optimized());
1988
1989 // TODO(fschneider): Idea: store proper code pointers in the optimized code
1990 // map and either unmangle them on marking or do nothing as the whole map is
1991 // discarded on major GC anyway.
1992 Add<HStoreCodeEntry>(js_function, code_object);
1993 Add<HStoreNamedField>(js_function, HObjectAccess::ForLiteralsPointer(),
1994 literals);
1995
1996 // Now link a function into a list of optimized functions.
1997 HValue* optimized_functions_list = Add<HLoadNamedField>(
1998 native_context, nullptr,
1999 HObjectAccess::ForContextSlot(Context::OPTIMIZED_FUNCTIONS_LIST));
2000 Add<HStoreNamedField>(js_function,
2001 HObjectAccess::ForNextFunctionLinkPointer(),
2002 optimized_functions_list);
2003
2004 // This store is the only one that should have a write barrier.
2005 Add<HStoreNamedField>(native_context,
2006 HObjectAccess::ForContextSlot(Context::OPTIMIZED_FUNCTIONS_LIST),
2007 js_function);
2008 }
2009
2010
2011 void CodeStubGraphBuilderBase::BuildInstallCode(HValue* js_function,
2012 HValue* shared_info) {
2013 Add<HStoreNamedField>(js_function,
2014 HObjectAccess::ForNextFunctionLinkPointer(),
2015 graph()->GetConstantUndefined());
2016 HValue* code_object = Add<HLoadNamedField>(shared_info, nullptr,
2017 HObjectAccess::ForCodeOffset());
2018 Add<HStoreCodeEntry>(js_function, code_object);
2019 }
2020
2021
2022 HInstruction* CodeStubGraphBuilderBase::LoadFromOptimizedCodeMap(
2023 HValue* optimized_map,
2024 HValue* iterator,
2025 int field_offset) {
2026 // By making sure to express these loads in the form [<hvalue> + constant]
2027 // the keyed load can be hoisted.
2028 DCHECK(field_offset >= 0 && field_offset < SharedFunctionInfo::kEntryLength);
2029 HValue* field_slot = iterator;
2030 if (field_offset > 0) {
2031 HValue* field_offset_value = Add<HConstant>(field_offset);
2032 field_slot = AddUncasted<HAdd>(iterator, field_offset_value);
2033 }
2034 HInstruction* field_entry = Add<HLoadKeyed>(optimized_map, field_slot,
2035 nullptr, nullptr, FAST_ELEMENTS);
2036 return field_entry;
2037 }
2038
2039
2040 void CodeStubGraphBuilderBase::BuildInstallFromOptimizedCodeMap(
2041 HValue* js_function,
2042 HValue* shared_info,
2043 HValue* native_context) {
2044 Counters* counters = isolate()->counters();
2045 Factory* factory = isolate()->factory();
2046 IfBuilder is_optimized(this);
2047 HInstruction* optimized_map = Add<HLoadNamedField>(
2048 shared_info, nullptr, HObjectAccess::ForOptimizedCodeMap());
2049 HValue* null_constant = Add<HConstant>(0);
2050 is_optimized.If<HCompareObjectEqAndBranch>(optimized_map, null_constant);
2051 is_optimized.Then();
2052 {
2053 BuildInstallCode(js_function, shared_info);
2054 }
2055 is_optimized.Else();
2056 {
2057 AddIncrementCounter(counters->fast_new_closure_try_optimized());
2058 // The {optimized_map} points to fixed array of 4-element entries:
2059 // (native context, optimized code, literals, ast-id).
2060 // Iterate through the {optimized_map} backwards. After the loop, if no
2061 // matching optimized code was found, install unoptimized code.
2062 // for(i = map.length() - SharedFunctionInfo::kEntryLength;
2063 // i >= SharedFunctionInfo::kEntriesStart;
2064 // i -= SharedFunctionInfo::kEntryLength) { ... }
2065 HValue* first_entry_index =
2066 Add<HConstant>(SharedFunctionInfo::kEntriesStart);
2067 HValue* shared_function_entry_length =
2068 Add<HConstant>(SharedFunctionInfo::kEntryLength);
2069 LoopBuilder loop_builder(this, context(), LoopBuilder::kPostDecrement,
2070 shared_function_entry_length);
2071 HValue* array_length = Add<HLoadNamedField>(
2072 optimized_map, nullptr, HObjectAccess::ForFixedArrayLength());
2073 HValue* start_pos =
2074 AddUncasted<HSub>(array_length, shared_function_entry_length);
2075 HValue* slot_iterator =
2076 loop_builder.BeginBody(start_pos, first_entry_index, Token::GTE);
2077 {
2078 IfBuilder done_check(this);
2079 BuildCheckAndInstallOptimizedCode(js_function, native_context,
2080 &done_check, optimized_map,
2081 slot_iterator);
2082 // Fall out of the loop
2083 loop_builder.Break();
2084 }
2085 loop_builder.EndBody();
2086
2087 // If {slot_iterator} is less than the first entry index, then we failed to
2088 // find a context-dependent code and try context-independent code next.
2089 IfBuilder no_optimized_code_check(this);
2090 no_optimized_code_check.If<HCompareNumericAndBranch>(
2091 slot_iterator, first_entry_index, Token::LT);
2092 no_optimized_code_check.Then();
2093 {
2094 IfBuilder shared_code_check(this);
2095 HValue* shared_code =
2096 Add<HLoadNamedField>(optimized_map, nullptr,
2097 HObjectAccess::ForOptimizedCodeMapSharedCode());
2098 shared_code = Add<HLoadNamedField>(shared_code, nullptr,
2099 HObjectAccess::ForWeakCellValue());
2100 shared_code_check.IfNot<HCompareObjectEqAndBranch>(
2101 shared_code, graph()->GetConstant0());
2102 shared_code_check.Then();
2103 {
2104 // Store the context-independent optimized code.
2105 HValue* literals = Add<HConstant>(factory->empty_fixed_array());
2106 BuildInstallOptimizedCode(js_function, native_context, shared_code,
2107 literals);
2108 }
2109 shared_code_check.Else();
2110 {
2111 // Store the unoptimized code.
2112 BuildInstallCode(js_function, shared_info);
2113 }
2114 }
2115 }
2116 }
2117
2118
2119 template<> 1923 template<>
2120 HValue* CodeStubGraphBuilder<FastNewClosureStub>::BuildCodeStub() { 1924 HValue* CodeStubGraphBuilder<FastNewClosureStub>::BuildCodeStub() {
2121 Counters* counters = isolate()->counters(); 1925 Counters* counters = isolate()->counters();
2122 Factory* factory = isolate()->factory(); 1926 Factory* factory = isolate()->factory();
2123 HInstruction* empty_fixed_array = 1927 HInstruction* empty_fixed_array =
2124 Add<HConstant>(factory->empty_fixed_array()); 1928 Add<HConstant>(factory->empty_fixed_array());
2125 HValue* shared_info = GetParameter(0); 1929 HValue* shared_info = GetParameter(0);
2126 1930
2127 AddIncrementCounter(counters->fast_new_closure_total()); 1931 AddIncrementCounter(counters->fast_new_closure_total());
2128 1932
(...skipping 19 matching lines...) Expand all
2148 empty_fixed_array); 1952 empty_fixed_array);
2149 Add<HStoreNamedField>(js_function, HObjectAccess::ForLiteralsPointer(), 1953 Add<HStoreNamedField>(js_function, HObjectAccess::ForLiteralsPointer(),
2150 empty_fixed_array); 1954 empty_fixed_array);
2151 Add<HStoreNamedField>(js_function, HObjectAccess::ForPrototypeOrInitialMap(), 1955 Add<HStoreNamedField>(js_function, HObjectAccess::ForPrototypeOrInitialMap(),
2152 graph()->GetConstantHole()); 1956 graph()->GetConstantHole());
2153 Add<HStoreNamedField>( 1957 Add<HStoreNamedField>(
2154 js_function, HObjectAccess::ForSharedFunctionInfoPointer(), shared_info); 1958 js_function, HObjectAccess::ForSharedFunctionInfoPointer(), shared_info);
2155 Add<HStoreNamedField>(js_function, HObjectAccess::ForFunctionContextPointer(), 1959 Add<HStoreNamedField>(js_function, HObjectAccess::ForFunctionContextPointer(),
2156 context()); 1960 context());
2157 1961
2158 // Initialize the code pointer in the function to be the one found in the 1962 Handle<Code> lazy_builtin(
2159 // shared function info object. But first check if there is an optimized 1963 isolate()->builtins()->builtin(Builtins::kCompileLazy));
2160 // version for our context. 1964 HConstant* lazy = Add<HConstant>(lazy_builtin);
2161 BuildInstallFromOptimizedCodeMap(js_function, shared_info, native_context); 1965 Add<HStoreCodeEntry>(js_function, lazy);
1966 Add<HStoreNamedField>(js_function,
1967 HObjectAccess::ForNextFunctionLinkPointer(),
1968 graph()->GetConstantUndefined());
2162 1969
2163 return js_function; 1970 return js_function;
2164 } 1971 }
2165 1972
2166 1973
2167 Handle<Code> FastNewClosureStub::GenerateCode() { 1974 Handle<Code> FastNewClosureStub::GenerateCode() {
2168 return DoGenerateCode(this); 1975 return DoGenerateCode(this);
2169 } 1976 }
2170 1977
2171 1978
(...skipping 329 matching lines...) Expand 10 before | Expand all | Expand 10 after
2501 return Pop(); 2308 return Pop();
2502 } 2309 }
2503 2310
2504 2311
2505 Handle<Code> KeyedLoadGenericStub::GenerateCode() { 2312 Handle<Code> KeyedLoadGenericStub::GenerateCode() {
2506 return DoGenerateCode(this); 2313 return DoGenerateCode(this);
2507 } 2314 }
2508 2315
2509 } // namespace internal 2316 } // namespace internal
2510 } // namespace v8 2317 } // namespace v8
OLDNEW
« no previous file with comments | « src/code-stubs.cc ('k') | src/compiler.cc » ('j') | src/compiler.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698