| 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_CODE_STUB_ASSEMBLER_H_ | 5 #ifndef V8_CODE_STUB_ASSEMBLER_H_ |
| 6 #define V8_CODE_STUB_ASSEMBLER_H_ | 6 #define V8_CODE_STUB_ASSEMBLER_H_ |
| 7 | 7 |
| 8 #include "src/compiler/code-assembler.h" | 8 #include "src/compiler/code-assembler.h" |
| 9 #include "src/objects.h" | 9 #include "src/objects.h" |
| 10 | 10 |
| 11 namespace v8 { | 11 namespace v8 { |
| 12 namespace internal { | 12 namespace internal { |
| 13 | 13 |
| 14 class CallInterfaceDescriptor; | 14 class CallInterfaceDescriptor; |
| 15 class StatsCounter; |
| 16 class StubCache; |
| 15 | 17 |
| 16 // Provides JavaScript-specific "macro-assembler" functionality on top of the | 18 // Provides JavaScript-specific "macro-assembler" functionality on top of the |
| 17 // CodeAssembler. By factoring the JavaScript-isms out of the CodeAssembler, | 19 // CodeAssembler. By factoring the JavaScript-isms out of the CodeAssembler, |
| 18 // it's possible to add JavaScript-specific useful CodeAssembler "macros" | 20 // it's possible to add JavaScript-specific useful CodeAssembler "macros" |
| 19 // without modifying files in the compiler directory (and requiring a review | 21 // without modifying files in the compiler directory (and requiring a review |
| 20 // from a compiler directory OWNER). | 22 // from a compiler directory OWNER). |
| 21 class CodeStubAssembler : public compiler::CodeAssembler { | 23 class CodeStubAssembler : public compiler::CodeAssembler { |
| 22 public: | 24 public: |
| 23 // Create with CallStub linkage. | 25 // Create with CallStub linkage. |
| 24 // |result_size| specifies the number of results returned by the stub. | 26 // |result_size| specifies the number of results returned by the stub. |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 95 void BranchIfSmiLessThanOrEqual(compiler::Node* a, compiler::Node* b, | 97 void BranchIfSmiLessThanOrEqual(compiler::Node* a, compiler::Node* b, |
| 96 Label* if_true, Label* if_false) { | 98 Label* if_true, Label* if_false) { |
| 97 BranchIf(SmiLessThanOrEqual(a, b), if_true, if_false); | 99 BranchIf(SmiLessThanOrEqual(a, b), if_true, if_false); |
| 98 } | 100 } |
| 99 | 101 |
| 100 void BranchIfFloat64IsNaN(compiler::Node* value, Label* if_true, | 102 void BranchIfFloat64IsNaN(compiler::Node* value, Label* if_true, |
| 101 Label* if_false) { | 103 Label* if_false) { |
| 102 BranchIfFloat64Equal(value, value, if_false, if_true); | 104 BranchIfFloat64Equal(value, value, if_false, if_true); |
| 103 } | 105 } |
| 104 | 106 |
| 107 // Load value from current frame by given offset in bytes. |
| 108 compiler::Node* LoadFromFrame(int offset, |
| 109 MachineType rep = MachineType::AnyTagged()); |
| 110 // Load value from current parent frame by given offset in bytes. |
| 111 compiler::Node* LoadFromParentFrame( |
| 112 int offset, MachineType rep = MachineType::AnyTagged()); |
| 113 |
| 105 // Load an object pointer from a buffer that isn't in the heap. | 114 // Load an object pointer from a buffer that isn't in the heap. |
| 106 compiler::Node* LoadBufferObject(compiler::Node* buffer, int offset, | 115 compiler::Node* LoadBufferObject(compiler::Node* buffer, int offset, |
| 107 MachineType rep = MachineType::AnyTagged()); | 116 MachineType rep = MachineType::AnyTagged()); |
| 108 // Load a field from an object on the heap. | 117 // Load a field from an object on the heap. |
| 109 compiler::Node* LoadObjectField(compiler::Node* object, int offset, | 118 compiler::Node* LoadObjectField(compiler::Node* object, int offset, |
| 110 MachineType rep = MachineType::AnyTagged()); | 119 MachineType rep = MachineType::AnyTagged()); |
| 111 // Load the floating point value of a HeapNumber. | 120 // Load the floating point value of a HeapNumber. |
| 112 compiler::Node* LoadHeapNumberValue(compiler::Node* object); | 121 compiler::Node* LoadHeapNumberValue(compiler::Node* object); |
| 113 // Load the Map of an HeapObject. | 122 // Load the Map of an HeapObject. |
| 114 compiler::Node* LoadMap(compiler::Node* object); | 123 compiler::Node* LoadMap(compiler::Node* object); |
| (...skipping 24 matching lines...) Expand all Loading... |
| 139 compiler::Node* LoadNameHashField(compiler::Node* name); | 148 compiler::Node* LoadNameHashField(compiler::Node* name); |
| 140 // Load the hash value of a name. If {if_hash_not_computed} label | 149 // Load the hash value of a name. If {if_hash_not_computed} label |
| 141 // is specified then it also checks if hash is actually computed. | 150 // is specified then it also checks if hash is actually computed. |
| 142 compiler::Node* LoadNameHash(compiler::Node* name, | 151 compiler::Node* LoadNameHash(compiler::Node* name, |
| 143 Label* if_hash_not_computed = nullptr); | 152 Label* if_hash_not_computed = nullptr); |
| 144 | 153 |
| 145 // Load length field of a String object. | 154 // Load length field of a String object. |
| 146 compiler::Node* LoadStringLength(compiler::Node* object); | 155 compiler::Node* LoadStringLength(compiler::Node* object); |
| 147 // Load value field of a JSValue object. | 156 // Load value field of a JSValue object. |
| 148 compiler::Node* LoadJSValueValue(compiler::Node* object); | 157 compiler::Node* LoadJSValueValue(compiler::Node* object); |
| 158 // Load value field of a WeakCell object. |
| 159 compiler::Node* LoadWeakCellValue(compiler::Node* weak_cell); |
| 149 | 160 |
| 150 compiler::Node* AllocateUninitializedFixedArray(compiler::Node* length); | 161 compiler::Node* AllocateUninitializedFixedArray(compiler::Node* length); |
| 151 | 162 |
| 152 // Load an array element from a FixedArray. | 163 // Load an array element from a FixedArray. |
| 153 compiler::Node* LoadFixedArrayElement( | 164 compiler::Node* LoadFixedArrayElement( |
| 154 compiler::Node* object, compiler::Node* int32_index, | 165 compiler::Node* object, compiler::Node* int32_index, |
| 155 int additional_offset = 0, | 166 int additional_offset = 0, |
| 156 ParameterMode parameter_mode = INTEGER_PARAMETERS); | 167 ParameterMode parameter_mode = INTEGER_PARAMETERS); |
| 157 // Load an array element from a FixedDoubleArray. | 168 // Load an array element from a FixedDoubleArray. |
| 158 compiler::Node* LoadFixedDoubleArrayElement( | 169 compiler::Node* LoadFixedDoubleArrayElement( |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 239 | 250 |
| 240 // Returns a node that is true if the given bit is set in |word32|. | 251 // Returns a node that is true if the given bit is set in |word32|. |
| 241 template <typename T> | 252 template <typename T> |
| 242 compiler::Node* BitFieldDecode(compiler::Node* word32) { | 253 compiler::Node* BitFieldDecode(compiler::Node* word32) { |
| 243 return BitFieldDecode(word32, T::kShift, T::kMask); | 254 return BitFieldDecode(word32, T::kShift, T::kMask); |
| 244 } | 255 } |
| 245 | 256 |
| 246 compiler::Node* BitFieldDecode(compiler::Node* word32, uint32_t shift, | 257 compiler::Node* BitFieldDecode(compiler::Node* word32, uint32_t shift, |
| 247 uint32_t mask); | 258 uint32_t mask); |
| 248 | 259 |
| 260 void SetCounter(StatsCounter* counter, int value); |
| 261 void IncrementCounter(StatsCounter* counter, int delta); |
| 262 void DecrementCounter(StatsCounter* counter, int delta); |
| 263 |
| 249 // Various building blocks for stubs doing property lookups. | 264 // Various building blocks for stubs doing property lookups. |
| 250 void TryToName(compiler::Node* key, Label* if_keyisindex, Variable* var_index, | 265 void TryToName(compiler::Node* key, Label* if_keyisindex, Variable* var_index, |
| 251 Label* if_keyisunique, Label* if_bailout); | 266 Label* if_keyisunique, Label* if_bailout); |
| 252 | 267 |
| 253 static const int kInlinedDictionaryProbes = 4; | 268 static const int kInlinedDictionaryProbes = 4; |
| 254 template <typename Dictionary> | 269 template <typename Dictionary> |
| 255 void NameDictionaryLookup(compiler::Node* dictionary, | 270 void NameDictionaryLookup(compiler::Node* dictionary, |
| 256 compiler::Node* unique_name, Label* if_found, | 271 compiler::Node* unique_name, Label* if_found, |
| 257 Variable* var_entry, Label* if_not_found, | 272 Variable* var_entry, Label* if_not_found, |
| 258 int inlined_probes = kInlinedDictionaryProbes); | 273 int inlined_probes = kInlinedDictionaryProbes); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 273 compiler::Node* instance_type, compiler::Node* index, | 288 compiler::Node* instance_type, compiler::Node* index, |
| 274 Label* if_found, Label* if_not_found, | 289 Label* if_found, Label* if_not_found, |
| 275 Label* if_bailout); | 290 Label* if_bailout); |
| 276 | 291 |
| 277 // Instanceof helpers. | 292 // Instanceof helpers. |
| 278 // ES6 section 7.3.19 OrdinaryHasInstance (C, O) | 293 // ES6 section 7.3.19 OrdinaryHasInstance (C, O) |
| 279 compiler::Node* OrdinaryHasInstance(compiler::Node* context, | 294 compiler::Node* OrdinaryHasInstance(compiler::Node* context, |
| 280 compiler::Node* callable, | 295 compiler::Node* callable, |
| 281 compiler::Node* object); | 296 compiler::Node* object); |
| 282 | 297 |
| 298 // LoadIC helpers. |
| 299 struct LoadICParameters { |
| 300 LoadICParameters(compiler::Node* context, compiler::Node* receiver, |
| 301 compiler::Node* name, compiler::Node* slot, |
| 302 compiler::Node* vector) |
| 303 : context(context), |
| 304 receiver(receiver), |
| 305 name(name), |
| 306 slot(slot), |
| 307 vector(vector) {} |
| 308 |
| 309 compiler::Node* context; |
| 310 compiler::Node* receiver; |
| 311 compiler::Node* name; |
| 312 compiler::Node* slot; |
| 313 compiler::Node* vector; |
| 314 }; |
| 315 |
| 316 // Load type feedback vector from the stub caller's frame. |
| 317 compiler::Node* LoadTypeFeedbackVectorForStub(); |
| 318 |
| 319 compiler::Node* LoadReceiverMap(compiler::Node* receiver); |
| 320 |
| 321 // Checks monomorphic case. Returns {feedback} entry of the vector. |
| 322 compiler::Node* TryMonomorphicCase(const LoadICParameters* p, |
| 323 compiler::Node* receiver_map, |
| 324 Label* if_handler, Variable* var_handler, |
| 325 Label* if_miss); |
| 326 void HandlePolymorphicCase(const LoadICParameters* p, |
| 327 compiler::Node* receiver_map, |
| 328 compiler::Node* feedback, Label* if_handler, |
| 329 Variable* var_handler, Label* if_miss, |
| 330 int unroll_count); |
| 331 |
| 332 compiler::Node* StubCachePrimaryOffset(compiler::Node* name, |
| 333 Code::Flags flags, |
| 334 compiler::Node* map); |
| 335 |
| 336 compiler::Node* StubCacheSecondaryOffset(compiler::Node* name, |
| 337 Code::Flags flags, |
| 338 compiler::Node* seed); |
| 339 |
| 340 // This enum is used here as a replacement for StubCache::Table to avoid |
| 341 // including stub cache header. |
| 342 enum StubCacheTable : int; |
| 343 |
| 344 void TryProbeStubCacheTable(StubCache* stub_cache, StubCacheTable table_id, |
| 345 compiler::Node* entry_offset, |
| 346 compiler::Node* name, Code::Flags flags, |
| 347 compiler::Node* map, Label* if_handler, |
| 348 Variable* var_handler, Label* if_miss); |
| 349 |
| 350 void TryProbeStubCache(StubCache* stub_cache, Code::Flags flags, |
| 351 compiler::Node* receiver, compiler::Node* name, |
| 352 Label* if_handler, Variable* var_handler, |
| 353 Label* if_miss); |
| 354 |
| 355 void LoadIC(const LoadICParameters* p, Label* if_miss); |
| 356 |
| 283 private: | 357 private: |
| 284 compiler::Node* ElementOffsetFromIndex(compiler::Node* index, | 358 compiler::Node* ElementOffsetFromIndex(compiler::Node* index, |
| 285 ElementsKind kind, ParameterMode mode, | 359 ElementsKind kind, ParameterMode mode, |
| 286 int base_size = 0); | 360 int base_size = 0); |
| 287 | 361 |
| 288 compiler::Node* AllocateRawAligned(compiler::Node* size_in_bytes, | 362 compiler::Node* AllocateRawAligned(compiler::Node* size_in_bytes, |
| 289 AllocationFlags flags, | 363 AllocationFlags flags, |
| 290 compiler::Node* top_address, | 364 compiler::Node* top_address, |
| 291 compiler::Node* limit_address); | 365 compiler::Node* limit_address); |
| 292 compiler::Node* AllocateRawUnaligned(compiler::Node* size_in_bytes, | 366 compiler::Node* AllocateRawUnaligned(compiler::Node* size_in_bytes, |
| 293 AllocationFlags flags, | 367 AllocationFlags flags, |
| 294 compiler::Node* top_adddress, | 368 compiler::Node* top_adddress, |
| 295 compiler::Node* limit_address); | 369 compiler::Node* limit_address); |
| 296 | 370 |
| 297 static const int kElementLoopUnrollThreshold = 8; | 371 static const int kElementLoopUnrollThreshold = 8; |
| 298 }; | 372 }; |
| 299 | 373 |
| 300 } // namespace internal | 374 } // namespace internal |
| 301 } // namespace v8 | 375 } // namespace v8 |
| 302 | |
| 303 #endif // V8_CODE_STUB_ASSEMBLER_H_ | 376 #endif // V8_CODE_STUB_ASSEMBLER_H_ |
| OLD | NEW |