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

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

Issue 2688503002: [ic] Refactor LoadGlobalIC in preparation for handler inlining (Closed)
Patch Set: Address comments 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') | no next file with comments »
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 LoadGlobalIC_TryPropertyCellCase(
71 Node* vector, Node* slot, ExitPoint* exit_point, Label* try_handler,
72 Label* miss, ParameterMode slot_mode = SMI_PARAMETERS);
73 void LoadGlobalIC_TryHandlerCase(const LoadICParameters* p,
74 TypeofMode typeof_mode,
75 ExitPoint* exit_point, Label* miss);
76 void LoadGlobalIC_MissCase(const LoadICParameters* p, ExitPoint* exit_point);
77
78 protected:
69 struct StoreICParameters : public LoadICParameters { 79 struct StoreICParameters : public LoadICParameters {
70 StoreICParameters(Node* context, Node* receiver, Node* name, Node* value, 80 StoreICParameters(Node* context, Node* receiver, Node* name, Node* value,
71 Node* slot, Node* vector) 81 Node* slot, Node* vector)
72 : LoadICParameters(context, receiver, name, slot, vector), 82 : LoadICParameters(context, receiver, name, slot, vector),
73 value(value) {} 83 value(value) {}
74 Node* value; 84 Node* value;
75 }; 85 };
76 86
77 enum ElementSupport { kOnlyProperties, kSupportElements }; 87 enum ElementSupport { kOnlyProperties, kSupportElements };
78 void HandleStoreICHandlerCase( 88 void HandleStoreICHandlerCase(
(...skipping 28 matching lines...) Expand all
107 Label* if_miss); 117 Label* if_miss);
108 118
109 // LoadIC implementation. 119 // LoadIC implementation.
110 120
111 void HandleLoadICHandlerCase( 121 void HandleLoadICHandlerCase(
112 const LoadICParameters* p, Node* handler, Label* miss, 122 const LoadICParameters* p, Node* handler, Label* miss,
113 ElementSupport support_elements = kOnlyProperties); 123 ElementSupport support_elements = kOnlyProperties);
114 124
115 void HandleLoadICSmiHandlerCase(const LoadICParameters* p, Node* holder, 125 void HandleLoadICSmiHandlerCase(const LoadICParameters* p, Node* holder,
116 Node* smi_handler, Label* miss, 126 Node* smi_handler, Label* miss,
127 ExitPoint* exit_point,
117 ElementSupport support_elements); 128 ElementSupport support_elements);
118 129
119 void HandleLoadICProtoHandlerCase(const LoadICParameters* p, Node* handler, 130 void HandleLoadICProtoHandlerCase(const LoadICParameters* p, Node* handler,
120 Variable* var_holder, 131 Variable* var_holder,
121 Variable* var_smi_handler, 132 Variable* var_smi_handler,
122 Label* if_smi_handler, Label* miss, 133 Label* if_smi_handler, Label* miss,
134 ExitPoint* exit_point,
123 bool throw_reference_error_if_nonexistent); 135 bool throw_reference_error_if_nonexistent);
124 136
125 Node* EmitLoadICProtoArrayCheck(const LoadICParameters* p, Node* handler, 137 Node* EmitLoadICProtoArrayCheck(const LoadICParameters* p, Node* handler,
126 Node* handler_length, Node* handler_flags, 138 Node* handler_length, Node* handler_flags,
127 Label* miss, 139 Label* miss,
128 bool throw_reference_error_if_nonexistent); 140 bool throw_reference_error_if_nonexistent);
129 141
130 // LoadGlobalIC implementation. 142 // LoadGlobalIC implementation.
131 143
132 void HandleLoadGlobalICHandlerCase(const LoadICParameters* p, Node* handler, 144 void HandleLoadGlobalICHandlerCase(const LoadICParameters* p, Node* handler,
133 Label* miss, 145 Label* miss, ExitPoint* exit_point,
134 bool throw_reference_error_if_nonexistent); 146 bool throw_reference_error_if_nonexistent);
135 147
136 // StoreIC implementation. 148 // StoreIC implementation.
137 149
138 void HandleStoreICElementHandlerCase(const StoreICParameters* p, 150 void HandleStoreICElementHandlerCase(const StoreICParameters* p,
139 Node* handler, Label* miss); 151 Node* handler, Label* miss);
140 152
141 void HandleStoreICProtoHandler(const StoreICParameters* p, Node* handler, 153 void HandleStoreICProtoHandler(const StoreICParameters* p, Node* handler,
142 Label* miss); 154 Label* miss);
143 // If |transition| is nullptr then the normal field store is generated or 155 // If |transition| is nullptr then the normal field store is generated or
(...skipping 28 matching lines...) Expand all
172 Representation representation, Node* value, 184 Representation representation, Node* value,
173 bool transition_to_field); 185 bool transition_to_field);
174 186
175 void EmitFastElementsBoundsCheck(Node* object, Node* elements, 187 void EmitFastElementsBoundsCheck(Node* object, Node* elements,
176 Node* intptr_index, 188 Node* intptr_index,
177 Node* is_jsarray_condition, Label* miss); 189 Node* is_jsarray_condition, Label* miss);
178 void EmitElementLoad(Node* object, Node* elements, Node* elements_kind, 190 void EmitElementLoad(Node* object, Node* elements, Node* elements_kind,
179 Node* key, Node* is_jsarray_condition, Label* if_hole, 191 Node* key, Node* is_jsarray_condition, Label* if_hole,
180 Label* rebox_double, Variable* var_double_value, 192 Label* rebox_double, Variable* var_double_value,
181 Label* unimplemented_elements_kind, Label* out_of_bounds, 193 Label* unimplemented_elements_kind, Label* out_of_bounds,
182 Label* miss); 194 Label* miss, ExitPoint* exit_point);
183 void CheckPrototype(Node* prototype_cell, Node* name, Label* miss); 195 void CheckPrototype(Node* prototype_cell, Node* name, Label* miss);
184 void NameDictionaryNegativeLookup(Node* object, Node* name, Label* miss); 196 void NameDictionaryNegativeLookup(Node* object, Node* name, Label* miss);
185 197
186 // Stub cache access helpers. 198 // Stub cache access helpers.
187 199
188 // This enum is used here as a replacement for StubCache::Table to avoid 200 // This enum is used here as a replacement for StubCache::Table to avoid
189 // including stub cache header. 201 // including stub cache header.
190 enum StubCacheTable : int; 202 enum StubCacheTable : int;
191 203
192 Node* StubCachePrimaryOffset(Node* name, Node* map); 204 Node* StubCachePrimaryOffset(Node* name, Node* map);
193 Node* StubCacheSecondaryOffset(Node* name, Node* seed); 205 Node* StubCacheSecondaryOffset(Node* name, Node* seed);
194 206
195 void TryProbeStubCacheTable(StubCache* stub_cache, StubCacheTable table_id, 207 void TryProbeStubCacheTable(StubCache* stub_cache, StubCacheTable table_id,
196 Node* entry_offset, Node* name, Node* map, 208 Node* entry_offset, Node* name, Node* map,
197 Label* if_handler, Variable* var_handler, 209 Label* if_handler, Variable* var_handler,
198 Label* if_miss); 210 Label* if_miss);
199 }; 211 };
200 212
213 // Abstraction over direct and indirect exit points. Direct exits correspond to
214 // tailcalls and Return, while indirect exits store the result in a variable
215 // and then jump to an exit label.
216 class ExitPoint {
217 private:
218 typedef compiler::Node Node;
219 typedef compiler::CodeAssemblerLabel CodeAssemblerLabel;
220 typedef compiler::CodeAssemblerVariable CodeAssemblerVariable;
221
222 public:
223 explicit ExitPoint(CodeStubAssembler* assembler)
224 : ExitPoint(assembler, nullptr, nullptr) {}
225 ExitPoint(CodeStubAssembler* assembler, CodeAssemblerLabel* out,
226 CodeAssemblerVariable* var_result)
227 : out_(out), var_result_(var_result), asm_(assembler) {
228 DCHECK_EQ(out != nullptr, var_result != nullptr);
229 }
230
231 template <class... TArgs>
232 void ReturnCallRuntime(Runtime::FunctionId function, Node* context,
233 TArgs... args) {
234 if (IsDirect()) {
235 asm_->TailCallRuntime(function, context, args...);
236 } else {
237 IndirectReturn(asm_->CallRuntime(function, context, args...));
238 }
239 }
240
241 template <class... TArgs>
242 void ReturnCallStub(Callable const& callable, Node* context, TArgs... args) {
243 if (IsDirect()) {
244 asm_->TailCallStub(callable, context, args...);
245 } else {
246 IndirectReturn(asm_->CallStub(callable, context, args...));
247 }
248 }
249
250 template <class... TArgs>
251 void ReturnCallStub(const CallInterfaceDescriptor& descriptor, Node* target,
252 Node* context, TArgs... args) {
253 if (IsDirect()) {
254 asm_->TailCallStub(descriptor, target, context, args...);
255 } else {
256 IndirectReturn(asm_->CallStub(descriptor, target, context, args...));
257 }
258 }
259
260 void Return(Node* const result) {
261 if (IsDirect()) {
262 asm_->Return(result);
263 } else {
264 IndirectReturn(result);
265 }
266 }
267
268 bool IsDirect() const { return out_ == nullptr; }
269
270 private:
271 void IndirectReturn(Node* const result) {
272 var_result_->Bind(result);
273 asm_->Goto(out_);
274 }
275
276 CodeAssemblerLabel* const out_;
277 CodeAssemblerVariable* const var_result_;
278 CodeStubAssembler* const asm_;
279 };
280
201 } // namespace internal 281 } // namespace internal
202 } // namespace v8 282 } // namespace v8
203 283
204 #endif // V8_SRC_IC_ACCESSOR_ASSEMBLER_H_ 284 #endif // V8_SRC_IC_ACCESSOR_ASSEMBLER_H_
OLDNEW
« no previous file with comments | « no previous file | src/ic/accessor-assembler.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698