Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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_ |
| OLD | NEW |