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