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

Side by Side Diff: src/ic/accessor-assembler.h

Issue 2688503002: [ic] Refactor LoadGlobalIC in preparation for handler inlining (Closed)
Patch Set: Created 3 years, 10 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 | « no previous file | src/ic/accessor-assembler.cc » ('j') | src/ic/accessor-assembler.cc » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2016 the V8 project authors. All rights reserved. 1 // Copyright 2016 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 #ifndef V8_SRC_IC_ACCESSOR_ASSEMBLER_H_ 5 #ifndef V8_SRC_IC_ACCESSOR_ASSEMBLER_H_
6 #define V8_SRC_IC_ACCESSOR_ASSEMBLER_H_ 6 #define V8_SRC_IC_ACCESSOR_ASSEMBLER_H_
7 7
8 #include "src/code-stub-assembler.h" 8 #include "src/code-stub-assembler.h"
9 9
10 namespace v8 { 10 namespace v8 {
11 namespace internal { 11 namespace internal {
12 12
13 namespace compiler { 13 namespace compiler {
14 class CodeAssemblerState; 14 class CodeAssemblerState;
15 } 15 }
16 16
17 class ExitPoint;
18
17 class AccessorAssembler : public CodeStubAssembler { 19 class AccessorAssembler : public CodeStubAssembler {
18 public: 20 public:
19 typedef compiler::Node Node; 21 typedef compiler::Node Node;
20 22
21 explicit AccessorAssembler(compiler::CodeAssemblerState* state) 23 explicit AccessorAssembler(compiler::CodeAssemblerState* state)
22 : CodeStubAssembler(state) {} 24 : CodeStubAssembler(state) {}
23 25
24 void GenerateLoadIC(); 26 void GenerateLoadIC();
25 void GenerateLoadField(); 27 void GenerateLoadField();
26 void GenerateLoadICTrampoline(); 28 void GenerateLoadICTrampoline();
(...skipping 15 matching lines...) Expand all
42 Label* if_handler, Variable* var_handler, 44 Label* if_handler, Variable* var_handler,
43 Label* if_miss); 45 Label* if_miss);
44 46
45 Node* StubCachePrimaryOffsetForTesting(Node* name, Node* map) { 47 Node* StubCachePrimaryOffsetForTesting(Node* name, Node* map) {
46 return StubCachePrimaryOffset(name, map); 48 return StubCachePrimaryOffset(name, map);
47 } 49 }
48 Node* StubCacheSecondaryOffsetForTesting(Node* name, Node* map) { 50 Node* StubCacheSecondaryOffsetForTesting(Node* name, Node* map) {
49 return StubCacheSecondaryOffset(name, map); 51 return StubCacheSecondaryOffset(name, map);
50 } 52 }
51 53
52 protected:
53 struct LoadICParameters { 54 struct LoadICParameters {
54 LoadICParameters(Node* context, Node* receiver, Node* name, Node* slot, 55 LoadICParameters(Node* context, Node* receiver, Node* name, Node* slot,
55 Node* vector) 56 Node* vector)
56 : context(context), 57 : context(context),
57 receiver(receiver), 58 receiver(receiver),
58 name(name), 59 name(name),
59 slot(slot), 60 slot(slot),
60 vector(vector) {} 61 vector(vector) {}
61 62
62 Node* context; 63 Node* context;
63 Node* receiver; 64 Node* receiver;
64 Node* name; 65 Node* name;
65 Node* slot; 66 Node* slot;
66 Node* vector; 67 Node* vector;
67 }; 68 };
68 69
70 void LoadGlobalICData(const LoadICParameters* p, ExitPoint* exit_point,
71 Label* try_handler, Label* miss);
72 void LoadGlobalICHandler(const LoadICParameters* p, TypeofMode typeof_mode,
73 ExitPoint* exit_point, Label* miss);
74 void LoadGlobalICMiss(const LoadICParameters* p, ExitPoint* exit_point);
75
76 protected:
69 struct StoreICParameters : public LoadICParameters { 77 struct StoreICParameters : public LoadICParameters {
70 StoreICParameters(Node* context, Node* receiver, Node* name, Node* value, 78 StoreICParameters(Node* context, Node* receiver, Node* name, Node* value,
71 Node* slot, Node* vector) 79 Node* slot, Node* vector)
72 : LoadICParameters(context, receiver, name, slot, vector), 80 : LoadICParameters(context, receiver, name, slot, vector),
73 value(value) {} 81 value(value) {}
74 Node* value; 82 Node* value;
75 }; 83 };
76 84
77 enum ElementSupport { kOnlyProperties, kSupportElements }; 85 enum ElementSupport { kOnlyProperties, kSupportElements };
78 void HandleStoreICHandlerCase( 86 void HandleStoreICHandlerCase(
(...skipping 28 matching lines...) Expand all
107 Label* if_miss); 115 Label* if_miss);
108 116
109 // LoadIC implementation. 117 // LoadIC implementation.
110 118
111 void HandleLoadICHandlerCase( 119 void HandleLoadICHandlerCase(
112 const LoadICParameters* p, Node* handler, Label* miss, 120 const LoadICParameters* p, Node* handler, Label* miss,
113 ElementSupport support_elements = kOnlyProperties); 121 ElementSupport support_elements = kOnlyProperties);
114 122
115 void HandleLoadICSmiHandlerCase(const LoadICParameters* p, Node* holder, 123 void HandleLoadICSmiHandlerCase(const LoadICParameters* p, Node* holder,
116 Node* smi_handler, Label* miss, 124 Node* smi_handler, Label* miss,
125 ExitPoint* exit_point,
117 ElementSupport support_elements); 126 ElementSupport support_elements);
118 127
119 void HandleLoadICProtoHandlerCase(const LoadICParameters* p, Node* handler, 128 void HandleLoadICProtoHandlerCase(const LoadICParameters* p, Node* handler,
120 Variable* var_holder, 129 Variable* var_holder,
121 Variable* var_smi_handler, 130 Variable* var_smi_handler,
122 Label* if_smi_handler, Label* miss, 131 Label* if_smi_handler, Label* miss,
132 ExitPoint* exit_point,
123 bool throw_reference_error_if_nonexistent); 133 bool throw_reference_error_if_nonexistent);
124 134
125 Node* EmitLoadICProtoArrayCheck(const LoadICParameters* p, Node* handler, 135 Node* EmitLoadICProtoArrayCheck(const LoadICParameters* p, Node* handler,
126 Node* handler_length, Node* handler_flags, 136 Node* handler_length, Node* handler_flags,
127 Label* miss, 137 Label* miss,
128 bool throw_reference_error_if_nonexistent); 138 bool throw_reference_error_if_nonexistent);
129 139
130 // LoadGlobalIC implementation. 140 // LoadGlobalIC implementation.
131 141
132 void HandleLoadGlobalICHandlerCase(const LoadICParameters* p, Node* handler, 142 void HandleLoadGlobalICHandlerCase(const LoadICParameters* p, Node* handler,
133 Label* miss, 143 Label* miss, ExitPoint* exit_point,
134 bool throw_reference_error_if_nonexistent); 144 bool throw_reference_error_if_nonexistent);
135 145
136 // StoreIC implementation. 146 // StoreIC implementation.
137 147
138 void HandleStoreICElementHandlerCase(const StoreICParameters* p, 148 void HandleStoreICElementHandlerCase(const StoreICParameters* p,
139 Node* handler, Label* miss); 149 Node* handler, Label* miss);
140 150
141 void HandleStoreICProtoHandler(const StoreICParameters* p, Node* handler, 151 void HandleStoreICProtoHandler(const StoreICParameters* p, Node* handler,
142 Label* miss); 152 Label* miss);
143 // If |transition| is nullptr then the normal field store is generated or 153 // If |transition| is nullptr then the normal field store is generated or
(...skipping 28 matching lines...) Expand all
172 Representation representation, Node* value, 182 Representation representation, Node* value,
173 bool transition_to_field); 183 bool transition_to_field);
174 184
175 void EmitFastElementsBoundsCheck(Node* object, Node* elements, 185 void EmitFastElementsBoundsCheck(Node* object, Node* elements,
176 Node* intptr_index, 186 Node* intptr_index,
177 Node* is_jsarray_condition, Label* miss); 187 Node* is_jsarray_condition, Label* miss);
178 void EmitElementLoad(Node* object, Node* elements, Node* elements_kind, 188 void EmitElementLoad(Node* object, Node* elements, Node* elements_kind,
179 Node* key, Node* is_jsarray_condition, Label* if_hole, 189 Node* key, Node* is_jsarray_condition, Label* if_hole,
180 Label* rebox_double, Variable* var_double_value, 190 Label* rebox_double, Variable* var_double_value,
181 Label* unimplemented_elements_kind, Label* out_of_bounds, 191 Label* unimplemented_elements_kind, Label* out_of_bounds,
182 Label* miss); 192 Label* miss, ExitPoint* exit_point);
183 void CheckPrototype(Node* prototype_cell, Node* name, Label* miss); 193 void CheckPrototype(Node* prototype_cell, Node* name, Label* miss);
184 void NameDictionaryNegativeLookup(Node* object, Node* name, Label* miss); 194 void NameDictionaryNegativeLookup(Node* object, Node* name, Label* miss);
185 195
186 // Stub cache access helpers. 196 // Stub cache access helpers.
187 197
188 // This enum is used here as a replacement for StubCache::Table to avoid 198 // This enum is used here as a replacement for StubCache::Table to avoid
189 // including stub cache header. 199 // including stub cache header.
190 enum StubCacheTable : int; 200 enum StubCacheTable : int;
191 201
192 Node* StubCachePrimaryOffset(Node* name, Node* map); 202 Node* StubCachePrimaryOffset(Node* name, Node* map);
193 Node* StubCacheSecondaryOffset(Node* name, Node* seed); 203 Node* StubCacheSecondaryOffset(Node* name, Node* seed);
194 204
195 void TryProbeStubCacheTable(StubCache* stub_cache, StubCacheTable table_id, 205 void TryProbeStubCacheTable(StubCache* stub_cache, StubCacheTable table_id,
196 Node* entry_offset, Node* name, Node* map, 206 Node* entry_offset, Node* name, Node* map,
197 Label* if_handler, Variable* var_handler, 207 Label* if_handler, Variable* var_handler,
198 Label* if_miss); 208 Label* if_miss);
199 }; 209 };
200 210
211 // Abstraction over direct and indirect exit points. Direct exits correspond to
212 // tailcalls and Return, while indirect exits store the result in a variable
213 // and then jump to an exit label.
214 class ExitPoint {
215 private:
216 typedef compiler::Node Node;
217 typedef compiler::CodeAssemblerLabel CodeAssemblerLabel;
218 typedef compiler::CodeAssemblerVariable CodeAssemblerVariable;
219
220 public:
221 explicit ExitPoint(CodeStubAssembler* assembler)
222 : ExitPoint(assembler, nullptr, nullptr) {}
223 ExitPoint(CodeStubAssembler* assembler, CodeAssemblerLabel* out,
224 CodeAssemblerVariable* var_result)
225 : out_(out), var_result_(var_result), asm_(assembler) {
226 DCHECK(out_ != nullptr || var_result_ == nullptr);
Igor Sheludko 2017/02/08 15:26:32 DCHECK_EQ(out != nullptr, var_result != nullptr);
jgruber 2017/02/09 09:23:42 Done.
227 }
228
229 template <class... TArgs>
230 void ReturnRuntime(Runtime::FunctionId function, Node* context,
Igor Sheludko 2017/02/08 15:26:32 ReturnCallRuntime
jgruber 2017/02/09 09:23:42 Done.
231 TArgs... args) {
232 if (IsDirect()) {
233 asm_->TailCallRuntime(function, context, args...);
234 } else {
235 IndirectReturn(asm_->CallRuntime(function, context, args...));
236 }
237 }
238
239 template <class... TArgs>
240 void ReturnStub(Callable const& callable, Node* context, TArgs... args) {
Igor Sheludko 2017/02/08 15:26:32 ReturnCallStub
jgruber 2017/02/09 09:23:42 Done.
241 if (IsDirect()) {
242 asm_->TailCallStub(callable, context, args...);
243 } else {
244 IndirectReturn(asm_->CallStub(callable, context, args...));
245 }
246 }
247
248 template <class... TArgs>
249 void ReturnStub(const CallInterfaceDescriptor& descriptor, Node* target,
Igor Sheludko 2017/02/08 15:26:32 ReturnCallStub
jgruber 2017/02/09 09:23:42 Done.
250 Node* context, TArgs... args) {
251 if (IsDirect()) {
252 asm_->TailCallStub(descriptor, target, context, args...);
253 } else {
254 IndirectReturn(asm_->CallStub(descriptor, target, context, args...));
255 }
256 }
257
258 void Return(Node* const result) {
259 if (IsDirect()) {
260 asm_->Return(result);
261 } else {
262 IndirectReturn(result);
263 }
264 }
265
266 bool IsDirect() const { return out_ == nullptr; }
267 bool IsIndirect() const { return !IsDirect(); }
Igor Sheludko 2017/02/08 15:26:32 I'd just leave IsDirect()
jgruber 2017/02/09 09:23:42 Done.
268
269 private:
270 void IndirectReturn(Node* const result) {
271 var_result_->Bind(result);
272 asm_->Goto(out_);
273 }
274
275 CodeAssemblerLabel* const out_;
276 CodeAssemblerVariable* const var_result_;
277 CodeStubAssembler* const asm_;
278 };
279
201 } // namespace internal 280 } // namespace internal
202 } // namespace v8 281 } // namespace v8
203 282
204 #endif // V8_SRC_IC_ACCESSOR_ASSEMBLER_H_ 283 #endif // V8_SRC_IC_ACCESSOR_ASSEMBLER_H_
OLDNEW
« no previous file with comments | « no previous file | src/ic/accessor-assembler.cc » ('j') | src/ic/accessor-assembler.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698