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

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: Removed overly-restrictive assert. 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
« no previous file with comments | « src/code-stubs.cc ('k') | src/compiler.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 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 1872 matching lines...) Expand 10 before | Expand all | Expand 10 after
2002 template <> 1982 template <>
2003 HValue* CodeStubGraphBuilder<ToObjectStub>::BuildCodeStub() { 1983 HValue* CodeStubGraphBuilder<ToObjectStub>::BuildCodeStub() {
2004 HValue* receiver = GetParameter(TypeConversionDescriptor::kArgumentIndex); 1984 HValue* receiver = GetParameter(TypeConversionDescriptor::kArgumentIndex);
2005 return BuildToObject(receiver); 1985 return BuildToObject(receiver);
2006 } 1986 }
2007 1987
2008 1988
2009 Handle<Code> ToObjectStub::GenerateCode() { return DoGenerateCode(this); } 1989 Handle<Code> ToObjectStub::GenerateCode() { return DoGenerateCode(this); }
2010 1990
2011 1991
2012 void CodeStubGraphBuilderBase::BuildCheckAndInstallOptimizedCode(
2013 HValue* js_function,
2014 HValue* native_context,
2015 IfBuilder* builder,
2016 HValue* optimized_map,
2017 HValue* map_index) {
2018 HValue* osr_ast_id_none = Add<HConstant>(BailoutId::None().ToInt());
2019 HValue* context_slot = LoadFromOptimizedCodeMap(
2020 optimized_map, map_index, SharedFunctionInfo::kContextOffset);
2021 context_slot = Add<HLoadNamedField>(context_slot, nullptr,
2022 HObjectAccess::ForWeakCellValue());
2023 HValue* osr_ast_slot = LoadFromOptimizedCodeMap(
2024 optimized_map, map_index, SharedFunctionInfo::kOsrAstIdOffset);
2025 HValue* code_object = LoadFromOptimizedCodeMap(
2026 optimized_map, map_index, SharedFunctionInfo::kCachedCodeOffset);
2027 code_object = Add<HLoadNamedField>(code_object, nullptr,
2028 HObjectAccess::ForWeakCellValue());
2029 builder->If<HCompareObjectEqAndBranch>(native_context,
2030 context_slot);
2031 builder->AndIf<HCompareObjectEqAndBranch>(osr_ast_slot, osr_ast_id_none);
2032 builder->And();
2033 builder->IfNot<HCompareObjectEqAndBranch>(code_object,
2034 graph()->GetConstant0());
2035 builder->Then();
2036 HValue* literals = LoadFromOptimizedCodeMap(optimized_map,
2037 map_index, SharedFunctionInfo::kLiteralsOffset);
2038 literals = Add<HLoadNamedField>(literals, nullptr,
2039 HObjectAccess::ForWeakCellValue());
2040 IfBuilder maybe_deopt(this);
2041 maybe_deopt.If<HCompareObjectEqAndBranch>(literals, graph()->GetConstant0());
2042 maybe_deopt.ThenDeopt(Deoptimizer::kLiteralsWereDisposed);
2043 maybe_deopt.End();
2044
2045 BuildInstallOptimizedCode(js_function, native_context, code_object, literals);
2046
2047 // The builder continues in the "then" after this function.
2048 }
2049
2050
2051 void CodeStubGraphBuilderBase::BuildInstallOptimizedCode(HValue* js_function,
2052 HValue* native_context,
2053 HValue* code_object,
2054 HValue* literals) {
2055 Counters* counters = isolate()->counters();
2056 AddIncrementCounter(counters->fast_new_closure_install_optimized());
2057
2058 // TODO(fschneider): Idea: store proper code pointers in the optimized code
2059 // map and either unmangle them on marking or do nothing as the whole map is
2060 // discarded on major GC anyway.
2061 Add<HStoreCodeEntry>(js_function, code_object);
2062 Add<HStoreNamedField>(js_function, HObjectAccess::ForLiteralsPointer(),
2063 literals);
2064
2065 // Now link a function into a list of optimized functions.
2066 HValue* optimized_functions_list = Add<HLoadNamedField>(
2067 native_context, nullptr,
2068 HObjectAccess::ForContextSlot(Context::OPTIMIZED_FUNCTIONS_LIST));
2069 Add<HStoreNamedField>(js_function,
2070 HObjectAccess::ForNextFunctionLinkPointer(),
2071 optimized_functions_list);
2072
2073 // This store is the only one that should have a write barrier.
2074 Add<HStoreNamedField>(native_context,
2075 HObjectAccess::ForContextSlot(Context::OPTIMIZED_FUNCTIONS_LIST),
2076 js_function);
2077 }
2078
2079
2080 void CodeStubGraphBuilderBase::BuildInstallCode(HValue* js_function,
2081 HValue* shared_info) {
2082 Add<HStoreNamedField>(js_function,
2083 HObjectAccess::ForNextFunctionLinkPointer(),
2084 graph()->GetConstantUndefined());
2085 HValue* code_object = Add<HLoadNamedField>(shared_info, nullptr,
2086 HObjectAccess::ForCodeOffset());
2087 Add<HStoreCodeEntry>(js_function, code_object);
2088 }
2089
2090
2091 HInstruction* CodeStubGraphBuilderBase::LoadFromOptimizedCodeMap(
2092 HValue* optimized_map,
2093 HValue* iterator,
2094 int field_offset) {
2095 // By making sure to express these loads in the form [<hvalue> + constant]
2096 // the keyed load can be hoisted.
2097 DCHECK(field_offset >= 0 && field_offset < SharedFunctionInfo::kEntryLength);
2098 HValue* field_slot = iterator;
2099 if (field_offset > 0) {
2100 HValue* field_offset_value = Add<HConstant>(field_offset);
2101 field_slot = AddUncasted<HAdd>(iterator, field_offset_value);
2102 }
2103 HInstruction* field_entry = Add<HLoadKeyed>(optimized_map, field_slot,
2104 nullptr, nullptr, FAST_ELEMENTS);
2105 return field_entry;
2106 }
2107
2108
2109 void CodeStubGraphBuilderBase::BuildInstallFromOptimizedCodeMap(
2110 HValue* js_function,
2111 HValue* shared_info,
2112 HValue* native_context) {
2113 Counters* counters = isolate()->counters();
2114 Factory* factory = isolate()->factory();
2115 IfBuilder is_optimized(this);
2116 HInstruction* optimized_map = Add<HLoadNamedField>(
2117 shared_info, nullptr, HObjectAccess::ForOptimizedCodeMap());
2118 HValue* null_constant = Add<HConstant>(0);
2119 is_optimized.If<HCompareObjectEqAndBranch>(optimized_map, null_constant);
2120 is_optimized.Then();
2121 {
2122 BuildInstallCode(js_function, shared_info);
2123 }
2124 is_optimized.Else();
2125 {
2126 AddIncrementCounter(counters->fast_new_closure_try_optimized());
2127 // The {optimized_map} points to fixed array of 4-element entries:
2128 // (native context, optimized code, literals, ast-id).
2129 // Iterate through the {optimized_map} backwards. After the loop, if no
2130 // matching optimized code was found, install unoptimized code.
2131 // for(i = map.length() - SharedFunctionInfo::kEntryLength;
2132 // i >= SharedFunctionInfo::kEntriesStart;
2133 // i -= SharedFunctionInfo::kEntryLength) { ... }
2134 HValue* first_entry_index =
2135 Add<HConstant>(SharedFunctionInfo::kEntriesStart);
2136 HValue* shared_function_entry_length =
2137 Add<HConstant>(SharedFunctionInfo::kEntryLength);
2138 LoopBuilder loop_builder(this, context(), LoopBuilder::kPostDecrement,
2139 shared_function_entry_length);
2140 HValue* array_length = Add<HLoadNamedField>(
2141 optimized_map, nullptr, HObjectAccess::ForFixedArrayLength());
2142 HValue* start_pos =
2143 AddUncasted<HSub>(array_length, shared_function_entry_length);
2144 HValue* slot_iterator =
2145 loop_builder.BeginBody(start_pos, first_entry_index, Token::GTE);
2146 {
2147 IfBuilder done_check(this);
2148 BuildCheckAndInstallOptimizedCode(js_function, native_context,
2149 &done_check, optimized_map,
2150 slot_iterator);
2151 // Fall out of the loop
2152 loop_builder.Break();
2153 }
2154 loop_builder.EndBody();
2155
2156 // If {slot_iterator} is less than the first entry index, then we failed to
2157 // find a context-dependent code and try context-independent code next.
2158 IfBuilder no_optimized_code_check(this);
2159 no_optimized_code_check.If<HCompareNumericAndBranch>(
2160 slot_iterator, first_entry_index, Token::LT);
2161 no_optimized_code_check.Then();
2162 {
2163 IfBuilder shared_code_check(this);
2164 HValue* shared_code =
2165 Add<HLoadNamedField>(optimized_map, nullptr,
2166 HObjectAccess::ForOptimizedCodeMapSharedCode());
2167 shared_code = Add<HLoadNamedField>(shared_code, nullptr,
2168 HObjectAccess::ForWeakCellValue());
2169 shared_code_check.IfNot<HCompareObjectEqAndBranch>(
2170 shared_code, graph()->GetConstant0());
2171 shared_code_check.Then();
2172 {
2173 // Store the context-independent optimized code.
2174 HValue* literals = Add<HConstant>(factory->empty_fixed_array());
2175 BuildInstallOptimizedCode(js_function, native_context, shared_code,
2176 literals);
2177 }
2178 shared_code_check.Else();
2179 {
2180 // Store the unoptimized code.
2181 BuildInstallCode(js_function, shared_info);
2182 }
2183 }
2184 }
2185 }
2186
2187
2188 template<> 1992 template<>
2189 HValue* CodeStubGraphBuilder<FastNewClosureStub>::BuildCodeStub() { 1993 HValue* CodeStubGraphBuilder<FastNewClosureStub>::BuildCodeStub() {
2190 Counters* counters = isolate()->counters(); 1994 Counters* counters = isolate()->counters();
2191 Factory* factory = isolate()->factory(); 1995 Factory* factory = isolate()->factory();
2192 HInstruction* empty_fixed_array = 1996 HInstruction* empty_fixed_array =
2193 Add<HConstant>(factory->empty_fixed_array()); 1997 Add<HConstant>(factory->empty_fixed_array());
2194 HValue* shared_info = GetParameter(0); 1998 HValue* shared_info = GetParameter(0);
2195 1999
2196 AddIncrementCounter(counters->fast_new_closure_total()); 2000 AddIncrementCounter(counters->fast_new_closure_total());
2197 2001
(...skipping 19 matching lines...) Expand all
2217 empty_fixed_array); 2021 empty_fixed_array);
2218 Add<HStoreNamedField>(js_function, HObjectAccess::ForLiteralsPointer(), 2022 Add<HStoreNamedField>(js_function, HObjectAccess::ForLiteralsPointer(),
2219 empty_fixed_array); 2023 empty_fixed_array);
2220 Add<HStoreNamedField>(js_function, HObjectAccess::ForPrototypeOrInitialMap(), 2024 Add<HStoreNamedField>(js_function, HObjectAccess::ForPrototypeOrInitialMap(),
2221 graph()->GetConstantHole()); 2025 graph()->GetConstantHole());
2222 Add<HStoreNamedField>( 2026 Add<HStoreNamedField>(
2223 js_function, HObjectAccess::ForSharedFunctionInfoPointer(), shared_info); 2027 js_function, HObjectAccess::ForSharedFunctionInfoPointer(), shared_info);
2224 Add<HStoreNamedField>(js_function, HObjectAccess::ForFunctionContextPointer(), 2028 Add<HStoreNamedField>(js_function, HObjectAccess::ForFunctionContextPointer(),
2225 context()); 2029 context());
2226 2030
2227 // Initialize the code pointer in the function to be the one found in the 2031 Handle<Code> lazy_builtin(
2228 // shared function info object. But first check if there is an optimized 2032 isolate()->builtins()->builtin(Builtins::kCompileLazy));
2229 // version for our context. 2033 HConstant* lazy = Add<HConstant>(lazy_builtin);
2230 BuildInstallFromOptimizedCodeMap(js_function, shared_info, native_context); 2034 Add<HStoreCodeEntry>(js_function, lazy);
2035 Add<HStoreNamedField>(js_function,
2036 HObjectAccess::ForNextFunctionLinkPointer(),
2037 graph()->GetConstantUndefined());
2231 2038
2232 return js_function; 2039 return js_function;
2233 } 2040 }
2234 2041
2235 2042
2236 Handle<Code> FastNewClosureStub::GenerateCode() { 2043 Handle<Code> FastNewClosureStub::GenerateCode() {
2237 return DoGenerateCode(this); 2044 return DoGenerateCode(this);
2238 } 2045 }
2239 2046
2240 2047
(...skipping 329 matching lines...) Expand 10 before | Expand all | Expand 10 after
2570 return Pop(); 2377 return Pop();
2571 } 2378 }
2572 2379
2573 2380
2574 Handle<Code> KeyedLoadGenericStub::GenerateCode() { 2381 Handle<Code> KeyedLoadGenericStub::GenerateCode() {
2575 return DoGenerateCode(this); 2382 return DoGenerateCode(this);
2576 } 2383 }
2577 2384
2578 } // namespace internal 2385 } // namespace internal
2579 } // namespace v8 2386 } // namespace v8
OLDNEW
« no previous file with comments | « src/code-stubs.cc ('k') | src/compiler.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698