| 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 <functional> | 8 #include <functional> |
| 9 | 9 |
| 10 #include "src/compiler/code-assembler.h" | 10 #include "src/compiler/code-assembler.h" |
| (...skipping 29 matching lines...) Expand all Loading... |
| 40 V(TrueValue, True) \ | 40 V(TrueValue, True) \ |
| 41 V(UndefinedValue, Undefined) | 41 V(UndefinedValue, Undefined) |
| 42 | 42 |
| 43 // Provides JavaScript-specific "macro-assembler" functionality on top of the | 43 // Provides JavaScript-specific "macro-assembler" functionality on top of the |
| 44 // CodeAssembler. By factoring the JavaScript-isms out of the CodeAssembler, | 44 // CodeAssembler. By factoring the JavaScript-isms out of the CodeAssembler, |
| 45 // it's possible to add JavaScript-specific useful CodeAssembler "macros" | 45 // it's possible to add JavaScript-specific useful CodeAssembler "macros" |
| 46 // without modifying files in the compiler directory (and requiring a review | 46 // without modifying files in the compiler directory (and requiring a review |
| 47 // from a compiler directory OWNER). | 47 // from a compiler directory OWNER). |
| 48 class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler { | 48 class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler { |
| 49 public: | 49 public: |
| 50 typedef compiler::Node Node; |
| 51 |
| 50 CodeStubAssembler(compiler::CodeAssemblerState* state) | 52 CodeStubAssembler(compiler::CodeAssemblerState* state) |
| 51 : compiler::CodeAssembler(state) {} | 53 : compiler::CodeAssembler(state) {} |
| 52 | 54 |
| 53 enum AllocationFlag : uint8_t { | 55 enum AllocationFlag : uint8_t { |
| 54 kNone = 0, | 56 kNone = 0, |
| 55 kDoubleAlignment = 1, | 57 kDoubleAlignment = 1, |
| 56 kPretenured = 1 << 1 | 58 kPretenured = 1 << 1 |
| 57 }; | 59 }; |
| 58 | 60 |
| 59 typedef base::Flags<AllocationFlag> AllocationFlags; | 61 typedef base::Flags<AllocationFlag> AllocationFlags; |
| 60 | 62 |
| 61 // TODO(ishell): Fix all loads/stores from arrays by int32 offsets/indices | 63 // TODO(ishell): Fix all loads/stores from arrays by int32 offsets/indices |
| 62 // and eventually remove INTEGER_PARAMETERS in favour of INTPTR_PARAMETERS. | 64 // and eventually remove INTEGER_PARAMETERS in favour of INTPTR_PARAMETERS. |
| 63 enum ParameterMode { INTEGER_PARAMETERS, SMI_PARAMETERS, INTPTR_PARAMETERS }; | 65 enum ParameterMode { INTEGER_PARAMETERS, SMI_PARAMETERS, INTPTR_PARAMETERS }; |
| 64 | 66 |
| 65 // On 32-bit platforms, there is a slight performance advantage to doing all | 67 // On 32-bit platforms, there is a slight performance advantage to doing all |
| 66 // of the array offset/index arithmetic with SMIs, since it's possible | 68 // of the array offset/index arithmetic with SMIs, since it's possible |
| 67 // to save a few tag/untag operations without paying an extra expense when | 69 // to save a few tag/untag operations without paying an extra expense when |
| 68 // calculating array offset (the smi math can be folded away) and there are | 70 // calculating array offset (the smi math can be folded away) and there are |
| 69 // fewer live ranges. Thus only convert indices to untagged value on 64-bit | 71 // fewer live ranges. Thus only convert indices to untagged value on 64-bit |
| 70 // platforms. | 72 // platforms. |
| 71 ParameterMode OptimalParameterMode() const { | 73 ParameterMode OptimalParameterMode() const { |
| 72 return Is64() ? INTPTR_PARAMETERS : SMI_PARAMETERS; | 74 return Is64() ? INTPTR_PARAMETERS : SMI_PARAMETERS; |
| 73 } | 75 } |
| 74 | 76 |
| 75 compiler::Node* UntagParameter(compiler::Node* value, ParameterMode mode) { | 77 Node* UntagParameter(Node* value, ParameterMode mode) { |
| 76 if (mode != SMI_PARAMETERS) value = SmiUntag(value); | 78 if (mode != SMI_PARAMETERS) value = SmiUntag(value); |
| 77 return value; | 79 return value; |
| 78 } | 80 } |
| 79 | 81 |
| 80 compiler::Node* TagParameter(compiler::Node* value, ParameterMode mode) { | 82 Node* TagParameter(Node* value, ParameterMode mode) { |
| 81 if (mode != SMI_PARAMETERS) value = SmiTag(value); | 83 if (mode != SMI_PARAMETERS) value = SmiTag(value); |
| 82 return value; | 84 return value; |
| 83 } | 85 } |
| 84 | 86 |
| 85 compiler::Node* NoContextConstant(); | 87 Node* NoContextConstant(); |
| 86 #define HEAP_CONSTANT_ACCESSOR(rootName, name) compiler::Node* name##Constant(); | 88 #define HEAP_CONSTANT_ACCESSOR(rootName, name) Node* name##Constant(); |
| 87 HEAP_CONSTANT_LIST(HEAP_CONSTANT_ACCESSOR) | 89 HEAP_CONSTANT_LIST(HEAP_CONSTANT_ACCESSOR) |
| 88 #undef HEAP_CONSTANT_ACCESSOR | 90 #undef HEAP_CONSTANT_ACCESSOR |
| 89 | 91 |
| 90 #define HEAP_CONSTANT_TEST(rootName, name) \ | 92 #define HEAP_CONSTANT_TEST(rootName, name) Node* Is##name(Node* value); |
| 91 compiler::Node* Is##name(compiler::Node* value); | |
| 92 HEAP_CONSTANT_LIST(HEAP_CONSTANT_TEST) | 93 HEAP_CONSTANT_LIST(HEAP_CONSTANT_TEST) |
| 93 #undef HEAP_CONSTANT_TEST | 94 #undef HEAP_CONSTANT_TEST |
| 94 | 95 |
| 95 compiler::Node* HashSeed(); | 96 Node* HashSeed(); |
| 96 compiler::Node* StaleRegisterConstant(); | 97 Node* StaleRegisterConstant(); |
| 97 | 98 |
| 98 compiler::Node* IntPtrOrSmiConstant(int value, ParameterMode mode); | 99 Node* IntPtrOrSmiConstant(int value, ParameterMode mode); |
| 99 | 100 |
| 100 compiler::Node* IntPtrAddFoldConstants(compiler::Node* left, | 101 Node* IntPtrAddFoldConstants(Node* left, Node* right); |
| 101 compiler::Node* right); | 102 Node* IntPtrSubFoldConstants(Node* left, Node* right); |
| 102 compiler::Node* IntPtrSubFoldConstants(compiler::Node* left, | |
| 103 compiler::Node* right); | |
| 104 // Round the 32bits payload of the provided word up to the next power of two. | 103 // Round the 32bits payload of the provided word up to the next power of two. |
| 105 compiler::Node* IntPtrRoundUpToPowerOfTwo32(compiler::Node* value); | 104 Node* IntPtrRoundUpToPowerOfTwo32(Node* value); |
| 106 compiler::Node* IntPtrMax(compiler::Node* left, compiler::Node* right); | 105 Node* IntPtrMax(Node* left, Node* right); |
| 107 | 106 |
| 108 // Float64 operations. | 107 // Float64 operations. |
| 109 compiler::Node* Float64Ceil(compiler::Node* x); | 108 Node* Float64Ceil(Node* x); |
| 110 compiler::Node* Float64Floor(compiler::Node* x); | 109 Node* Float64Floor(Node* x); |
| 111 compiler::Node* Float64Round(compiler::Node* x); | 110 Node* Float64Round(Node* x); |
| 112 compiler::Node* Float64Trunc(compiler::Node* x); | 111 Node* Float64Trunc(Node* x); |
| 113 | 112 |
| 114 // Tag a Word as a Smi value. | 113 // Tag a Word as a Smi value. |
| 115 compiler::Node* SmiTag(compiler::Node* value); | 114 Node* SmiTag(Node* value); |
| 116 // Untag a Smi value as a Word. | 115 // Untag a Smi value as a Word. |
| 117 compiler::Node* SmiUntag(compiler::Node* value); | 116 Node* SmiUntag(Node* value); |
| 118 | 117 |
| 119 // Smi conversions. | 118 // Smi conversions. |
| 120 compiler::Node* SmiToFloat64(compiler::Node* value); | 119 Node* SmiToFloat64(Node* value); |
| 121 compiler::Node* SmiFromWord(compiler::Node* value) { return SmiTag(value); } | 120 Node* SmiFromWord(Node* value) { return SmiTag(value); } |
| 122 compiler::Node* SmiFromWord32(compiler::Node* value); | 121 Node* SmiFromWord32(Node* value); |
| 123 compiler::Node* SmiToWord(compiler::Node* value) { return SmiUntag(value); } | 122 Node* SmiToWord(Node* value) { return SmiUntag(value); } |
| 124 compiler::Node* SmiToWord32(compiler::Node* value); | 123 Node* SmiToWord32(Node* value); |
| 125 | 124 |
| 126 // Smi operations. | 125 // Smi operations. |
| 127 compiler::Node* SmiAdd(compiler::Node* a, compiler::Node* b); | 126 Node* SmiAdd(Node* a, Node* b); |
| 128 compiler::Node* SmiSub(compiler::Node* a, compiler::Node* b); | 127 Node* SmiSub(Node* a, Node* b); |
| 129 compiler::Node* SmiEqual(compiler::Node* a, compiler::Node* b); | 128 Node* SmiEqual(Node* a, Node* b); |
| 130 compiler::Node* SmiAbove(compiler::Node* a, compiler::Node* b); | 129 Node* SmiAbove(Node* a, Node* b); |
| 131 compiler::Node* SmiAboveOrEqual(compiler::Node* a, compiler::Node* b); | 130 Node* SmiAboveOrEqual(Node* a, Node* b); |
| 132 compiler::Node* SmiBelow(compiler::Node* a, compiler::Node* b); | 131 Node* SmiBelow(Node* a, Node* b); |
| 133 compiler::Node* SmiLessThan(compiler::Node* a, compiler::Node* b); | 132 Node* SmiLessThan(Node* a, Node* b); |
| 134 compiler::Node* SmiLessThanOrEqual(compiler::Node* a, compiler::Node* b); | 133 Node* SmiLessThanOrEqual(Node* a, Node* b); |
| 135 compiler::Node* SmiMax(compiler::Node* a, compiler::Node* b); | 134 Node* SmiMax(Node* a, Node* b); |
| 136 compiler::Node* SmiMin(compiler::Node* a, compiler::Node* b); | 135 Node* SmiMin(Node* a, Node* b); |
| 137 // Computes a % b for Smi inputs a and b; result is not necessarily a Smi. | 136 // Computes a % b for Smi inputs a and b; result is not necessarily a Smi. |
| 138 compiler::Node* SmiMod(compiler::Node* a, compiler::Node* b); | 137 Node* SmiMod(Node* a, Node* b); |
| 139 // Computes a * b for Smi inputs a and b; result is not necessarily a Smi. | 138 // Computes a * b for Smi inputs a and b; result is not necessarily a Smi. |
| 140 compiler::Node* SmiMul(compiler::Node* a, compiler::Node* b); | 139 Node* SmiMul(Node* a, Node* b); |
| 141 compiler::Node* SmiOr(compiler::Node* a, compiler::Node* b) { | 140 Node* SmiOr(Node* a, Node* b) { |
| 142 return BitcastWordToTaggedSigned( | 141 return BitcastWordToTaggedSigned( |
| 143 WordOr(BitcastTaggedToWord(a), BitcastTaggedToWord(b))); | 142 WordOr(BitcastTaggedToWord(a), BitcastTaggedToWord(b))); |
| 144 } | 143 } |
| 145 | 144 |
| 146 // Smi | HeapNumber operations. | 145 // Smi | HeapNumber operations. |
| 147 compiler::Node* NumberInc(compiler::Node* value); | 146 Node* NumberInc(Node* value); |
| 148 | 147 |
| 149 // Allocate an object of the given size. | 148 // Allocate an object of the given size. |
| 150 compiler::Node* Allocate(compiler::Node* size, AllocationFlags flags = kNone); | 149 Node* Allocate(Node* size, AllocationFlags flags = kNone); |
| 151 compiler::Node* Allocate(int size, AllocationFlags flags = kNone); | 150 Node* Allocate(int size, AllocationFlags flags = kNone); |
| 152 compiler::Node* InnerAllocate(compiler::Node* previous, int offset); | 151 Node* InnerAllocate(Node* previous, int offset); |
| 153 compiler::Node* InnerAllocate(compiler::Node* previous, | 152 Node* InnerAllocate(Node* previous, Node* offset); |
| 154 compiler::Node* offset); | 153 Node* IsRegularHeapObjectSize(Node* size); |
| 155 compiler::Node* IsRegularHeapObjectSize(compiler::Node* size); | 154 |
| 156 | 155 typedef std::function<Node*()> ConditionBody; |
| 157 typedef std::function<compiler::Node*()> ConditionBody; | |
| 158 void Assert(ConditionBody condition_body, const char* string = nullptr, | 156 void Assert(ConditionBody condition_body, const char* string = nullptr, |
| 159 const char* file = nullptr, int line = 0); | 157 const char* file = nullptr, int line = 0); |
| 160 | 158 |
| 161 // Check a value for smi-ness | 159 // Check a value for smi-ness |
| 162 compiler::Node* TaggedIsSmi(compiler::Node* a); | 160 Node* TaggedIsSmi(Node* a); |
| 163 // Check that the value is a non-negative smi. | 161 // Check that the value is a non-negative smi. |
| 164 compiler::Node* WordIsPositiveSmi(compiler::Node* a); | 162 Node* WordIsPositiveSmi(Node* a); |
| 165 // Check that a word has a word-aligned address. | 163 // Check that a word has a word-aligned address. |
| 166 compiler::Node* WordIsWordAligned(compiler::Node* word); | 164 Node* WordIsWordAligned(Node* word); |
| 167 compiler::Node* WordIsPowerOfTwo(compiler::Node* value); | 165 Node* WordIsPowerOfTwo(Node* value); |
| 168 | 166 |
| 169 void BranchIfSmiEqual(compiler::Node* a, compiler::Node* b, Label* if_true, | 167 void BranchIfSmiEqual(Node* a, Node* b, Label* if_true, Label* if_false) { |
| 170 Label* if_false) { | |
| 171 Branch(SmiEqual(a, b), if_true, if_false); | 168 Branch(SmiEqual(a, b), if_true, if_false); |
| 172 } | 169 } |
| 173 | 170 |
| 174 void BranchIfSmiLessThan(compiler::Node* a, compiler::Node* b, Label* if_true, | 171 void BranchIfSmiLessThan(Node* a, Node* b, Label* if_true, Label* if_false) { |
| 175 Label* if_false) { | |
| 176 Branch(SmiLessThan(a, b), if_true, if_false); | 172 Branch(SmiLessThan(a, b), if_true, if_false); |
| 177 } | 173 } |
| 178 | 174 |
| 179 void BranchIfSmiLessThanOrEqual(compiler::Node* a, compiler::Node* b, | 175 void BranchIfSmiLessThanOrEqual(Node* a, Node* b, Label* if_true, |
| 180 Label* if_true, Label* if_false) { | 176 Label* if_false) { |
| 181 Branch(SmiLessThanOrEqual(a, b), if_true, if_false); | 177 Branch(SmiLessThanOrEqual(a, b), if_true, if_false); |
| 182 } | 178 } |
| 183 | 179 |
| 184 void BranchIfFloat64IsNaN(compiler::Node* value, Label* if_true, | 180 void BranchIfFloat64IsNaN(Node* value, Label* if_true, Label* if_false) { |
| 185 Label* if_false) { | |
| 186 Branch(Float64Equal(value, value), if_false, if_true); | 181 Branch(Float64Equal(value, value), if_false, if_true); |
| 187 } | 182 } |
| 188 | 183 |
| 189 // Branches to {if_true} if ToBoolean applied to {value} yields true, | 184 // Branches to {if_true} if ToBoolean applied to {value} yields true, |
| 190 // otherwise goes to {if_false}. | 185 // otherwise goes to {if_false}. |
| 191 void BranchIfToBooleanIsTrue(compiler::Node* value, Label* if_true, | 186 void BranchIfToBooleanIsTrue(Node* value, Label* if_true, Label* if_false); |
| 192 Label* if_false); | 187 |
| 193 | 188 void BranchIfSimd128Equal(Node* lhs, Node* lhs_map, Node* rhs, Node* rhs_map, |
| 194 void BranchIfSimd128Equal(compiler::Node* lhs, compiler::Node* lhs_map, | |
| 195 compiler::Node* rhs, compiler::Node* rhs_map, | |
| 196 Label* if_equal, Label* if_notequal); | 189 Label* if_equal, Label* if_notequal); |
| 197 void BranchIfSimd128Equal(compiler::Node* lhs, compiler::Node* rhs, | 190 void BranchIfSimd128Equal(Node* lhs, Node* rhs, Label* if_equal, |
| 198 Label* if_equal, Label* if_notequal) { | 191 Label* if_notequal) { |
| 199 BranchIfSimd128Equal(lhs, LoadMap(lhs), rhs, LoadMap(rhs), if_equal, | 192 BranchIfSimd128Equal(lhs, LoadMap(lhs), rhs, LoadMap(rhs), if_equal, |
| 200 if_notequal); | 193 if_notequal); |
| 201 } | 194 } |
| 202 | 195 |
| 203 void BranchIfJSReceiver(compiler::Node* object, Label* if_true, | 196 void BranchIfJSReceiver(Node* object, Label* if_true, Label* if_false); |
| 204 Label* if_false); | 197 void BranchIfJSObject(Node* object, Label* if_true, Label* if_false); |
| 205 void BranchIfJSObject(compiler::Node* object, Label* if_true, | 198 void BranchIfFastJSArray(Node* object, Node* context, Label* if_true, |
| 206 Label* if_false); | 199 Label* if_false); |
| 207 void BranchIfFastJSArray(compiler::Node* object, compiler::Node* context, | |
| 208 Label* if_true, Label* if_false); | |
| 209 | 200 |
| 210 // Load value from current frame by given offset in bytes. | 201 // Load value from current frame by given offset in bytes. |
| 211 compiler::Node* LoadFromFrame(int offset, | 202 Node* LoadFromFrame(int offset, MachineType rep = MachineType::AnyTagged()); |
| 212 MachineType rep = MachineType::AnyTagged()); | |
| 213 // Load value from current parent frame by given offset in bytes. | 203 // Load value from current parent frame by given offset in bytes. |
| 214 compiler::Node* LoadFromParentFrame( | 204 Node* LoadFromParentFrame(int offset, |
| 215 int offset, MachineType rep = MachineType::AnyTagged()); | 205 MachineType rep = MachineType::AnyTagged()); |
| 216 | 206 |
| 217 // Load an object pointer from a buffer that isn't in the heap. | 207 // Load an object pointer from a buffer that isn't in the heap. |
| 218 compiler::Node* LoadBufferObject(compiler::Node* buffer, int offset, | 208 Node* LoadBufferObject(Node* buffer, int offset, |
| 219 MachineType rep = MachineType::AnyTagged()); | 209 MachineType rep = MachineType::AnyTagged()); |
| 220 // Load a field from an object on the heap. | 210 // Load a field from an object on the heap. |
| 221 compiler::Node* LoadObjectField(compiler::Node* object, int offset, | 211 Node* LoadObjectField(Node* object, int offset, |
| 222 MachineType rep = MachineType::AnyTagged()); | 212 MachineType rep = MachineType::AnyTagged()); |
| 223 compiler::Node* LoadObjectField(compiler::Node* object, | 213 Node* LoadObjectField(Node* object, Node* offset, |
| 224 compiler::Node* offset, | 214 MachineType rep = MachineType::AnyTagged()); |
| 225 MachineType rep = MachineType::AnyTagged()); | |
| 226 // Load a SMI field and untag it. | 215 // Load a SMI field and untag it. |
| 227 compiler::Node* LoadAndUntagObjectField(compiler::Node* object, int offset); | 216 Node* LoadAndUntagObjectField(Node* object, int offset); |
| 228 // Load a SMI field, untag it, and convert to Word32. | 217 // Load a SMI field, untag it, and convert to Word32. |
| 229 compiler::Node* LoadAndUntagToWord32ObjectField(compiler::Node* object, | 218 Node* LoadAndUntagToWord32ObjectField(Node* object, int offset); |
| 230 int offset); | |
| 231 // Load a SMI and untag it. | 219 // Load a SMI and untag it. |
| 232 compiler::Node* LoadAndUntagSmi(compiler::Node* base, int index); | 220 Node* LoadAndUntagSmi(Node* base, int index); |
| 233 // Load a SMI root, untag it, and convert to Word32. | 221 // Load a SMI root, untag it, and convert to Word32. |
| 234 compiler::Node* LoadAndUntagToWord32Root(Heap::RootListIndex root_index); | 222 Node* LoadAndUntagToWord32Root(Heap::RootListIndex root_index); |
| 235 | 223 |
| 236 // Load the floating point value of a HeapNumber. | 224 // Load the floating point value of a HeapNumber. |
| 237 compiler::Node* LoadHeapNumberValue(compiler::Node* object); | 225 Node* LoadHeapNumberValue(Node* object); |
| 238 // Load the Map of an HeapObject. | 226 // Load the Map of an HeapObject. |
| 239 compiler::Node* LoadMap(compiler::Node* object); | 227 Node* LoadMap(Node* object); |
| 240 // Load the instance type of an HeapObject. | 228 // Load the instance type of an HeapObject. |
| 241 compiler::Node* LoadInstanceType(compiler::Node* object); | 229 Node* LoadInstanceType(Node* object); |
| 242 // Compare the instance the type of the object against the provided one. | 230 // Compare the instance the type of the object against the provided one. |
| 243 compiler::Node* HasInstanceType(compiler::Node* object, InstanceType type); | 231 Node* HasInstanceType(Node* object, InstanceType type); |
| 244 // Load the properties backing store of a JSObject. | 232 // Load the properties backing store of a JSObject. |
| 245 compiler::Node* LoadProperties(compiler::Node* object); | 233 Node* LoadProperties(Node* object); |
| 246 // Load the elements backing store of a JSObject. | 234 // Load the elements backing store of a JSObject. |
| 247 compiler::Node* LoadElements(compiler::Node* object); | 235 Node* LoadElements(Node* object); |
| 248 // Load the length of a JSArray instance. | 236 // Load the length of a JSArray instance. |
| 249 compiler::Node* LoadJSArrayLength(compiler::Node* array); | 237 Node* LoadJSArrayLength(Node* array); |
| 250 // Load the length of a fixed array base instance. | 238 // Load the length of a fixed array base instance. |
| 251 compiler::Node* LoadFixedArrayBaseLength(compiler::Node* array); | 239 Node* LoadFixedArrayBaseLength(Node* array); |
| 252 // Load the length of a fixed array base instance. | 240 // Load the length of a fixed array base instance. |
| 253 compiler::Node* LoadAndUntagFixedArrayBaseLength(compiler::Node* array); | 241 Node* LoadAndUntagFixedArrayBaseLength(Node* array); |
| 254 // Load the bit field of a Map. | 242 // Load the bit field of a Map. |
| 255 compiler::Node* LoadMapBitField(compiler::Node* map); | 243 Node* LoadMapBitField(Node* map); |
| 256 // Load bit field 2 of a map. | 244 // Load bit field 2 of a map. |
| 257 compiler::Node* LoadMapBitField2(compiler::Node* map); | 245 Node* LoadMapBitField2(Node* map); |
| 258 // Load bit field 3 of a map. | 246 // Load bit field 3 of a map. |
| 259 compiler::Node* LoadMapBitField3(compiler::Node* map); | 247 Node* LoadMapBitField3(Node* map); |
| 260 // Load the instance type of a map. | 248 // Load the instance type of a map. |
| 261 compiler::Node* LoadMapInstanceType(compiler::Node* map); | 249 Node* LoadMapInstanceType(Node* map); |
| 262 // Load the ElementsKind of a map. | 250 // Load the ElementsKind of a map. |
| 263 compiler::Node* LoadMapElementsKind(compiler::Node* map); | 251 Node* LoadMapElementsKind(Node* map); |
| 264 // Load the instance descriptors of a map. | 252 // Load the instance descriptors of a map. |
| 265 compiler::Node* LoadMapDescriptors(compiler::Node* map); | 253 Node* LoadMapDescriptors(Node* map); |
| 266 // Load the prototype of a map. | 254 // Load the prototype of a map. |
| 267 compiler::Node* LoadMapPrototype(compiler::Node* map); | 255 Node* LoadMapPrototype(Node* map); |
| 268 // Load the prototype info of a map. The result has to be checked if it is a | 256 // Load the prototype info of a map. The result has to be checked if it is a |
| 269 // prototype info object or not. | 257 // prototype info object or not. |
| 270 compiler::Node* LoadMapPrototypeInfo(compiler::Node* map, | 258 Node* LoadMapPrototypeInfo(Node* map, Label* if_has_no_proto_info); |
| 271 Label* if_has_no_proto_info); | |
| 272 // Load the instance size of a Map. | 259 // Load the instance size of a Map. |
| 273 compiler::Node* LoadMapInstanceSize(compiler::Node* map); | 260 Node* LoadMapInstanceSize(Node* map); |
| 274 // Load the inobject properties count of a Map (valid only for JSObjects). | 261 // Load the inobject properties count of a Map (valid only for JSObjects). |
| 275 compiler::Node* LoadMapInobjectProperties(compiler::Node* map); | 262 Node* LoadMapInobjectProperties(Node* map); |
| 276 // Load the constructor function index of a Map (only for primitive maps). | 263 // Load the constructor function index of a Map (only for primitive maps). |
| 277 compiler::Node* LoadMapConstructorFunctionIndex(compiler::Node* map); | 264 Node* LoadMapConstructorFunctionIndex(Node* map); |
| 278 // Load the constructor of a Map (equivalent to Map::GetConstructor()). | 265 // Load the constructor of a Map (equivalent to Map::GetConstructor()). |
| 279 compiler::Node* LoadMapConstructor(compiler::Node* map); | 266 Node* LoadMapConstructor(Node* map); |
| 280 // Check if the map is set for slow properties. | 267 // Check if the map is set for slow properties. |
| 281 compiler::Node* IsDictionaryMap(compiler::Node* map); | 268 Node* IsDictionaryMap(Node* map); |
| 282 | 269 |
| 283 // Load the hash field of a name as an uint32 value. | 270 // Load the hash field of a name as an uint32 value. |
| 284 compiler::Node* LoadNameHashField(compiler::Node* name); | 271 Node* LoadNameHashField(Node* name); |
| 285 // Load the hash value of a name as an uint32 value. | 272 // Load the hash value of a name as an uint32 value. |
| 286 // If {if_hash_not_computed} label is specified then it also checks if | 273 // If {if_hash_not_computed} label is specified then it also checks if |
| 287 // hash is actually computed. | 274 // hash is actually computed. |
| 288 compiler::Node* LoadNameHash(compiler::Node* name, | 275 Node* LoadNameHash(Node* name, Label* if_hash_not_computed = nullptr); |
| 289 Label* if_hash_not_computed = nullptr); | |
| 290 | 276 |
| 291 // Load length field of a String object. | 277 // Load length field of a String object. |
| 292 compiler::Node* LoadStringLength(compiler::Node* object); | 278 Node* LoadStringLength(Node* object); |
| 293 // Load value field of a JSValue object. | 279 // Load value field of a JSValue object. |
| 294 compiler::Node* LoadJSValueValue(compiler::Node* object); | 280 Node* LoadJSValueValue(Node* object); |
| 295 // Load value field of a WeakCell object. | 281 // Load value field of a WeakCell object. |
| 296 compiler::Node* LoadWeakCellValueUnchecked(compiler::Node* weak_cell); | 282 Node* LoadWeakCellValueUnchecked(Node* weak_cell); |
| 297 compiler::Node* LoadWeakCellValue(compiler::Node* weak_cell, | 283 Node* LoadWeakCellValue(Node* weak_cell, Label* if_cleared = nullptr); |
| 298 Label* if_cleared = nullptr); | |
| 299 | 284 |
| 300 // Load an array element from a FixedArray. | 285 // Load an array element from a FixedArray. |
| 301 compiler::Node* LoadFixedArrayElement( | 286 Node* LoadFixedArrayElement( |
| 302 compiler::Node* object, compiler::Node* index, int additional_offset = 0, | 287 Node* object, Node* index, int additional_offset = 0, |
| 303 ParameterMode parameter_mode = INTEGER_PARAMETERS); | 288 ParameterMode parameter_mode = INTEGER_PARAMETERS); |
| 304 // Load an array element from a FixedArray, untag it and return it as Word32. | 289 // Load an array element from a FixedArray, untag it and return it as Word32. |
| 305 compiler::Node* LoadAndUntagToWord32FixedArrayElement( | 290 Node* LoadAndUntagToWord32FixedArrayElement( |
| 306 compiler::Node* object, compiler::Node* index, int additional_offset = 0, | 291 Node* object, Node* index, int additional_offset = 0, |
| 307 ParameterMode parameter_mode = INTEGER_PARAMETERS); | 292 ParameterMode parameter_mode = INTEGER_PARAMETERS); |
| 308 // Load an array element from a FixedDoubleArray. | 293 // Load an array element from a FixedDoubleArray. |
| 309 compiler::Node* LoadFixedDoubleArrayElement( | 294 Node* LoadFixedDoubleArrayElement( |
| 310 compiler::Node* object, compiler::Node* index, MachineType machine_type, | 295 Node* object, Node* index, MachineType machine_type, |
| 311 int additional_offset = 0, | 296 int additional_offset = 0, |
| 312 ParameterMode parameter_mode = INTEGER_PARAMETERS, | 297 ParameterMode parameter_mode = INTEGER_PARAMETERS, |
| 313 Label* if_hole = nullptr); | 298 Label* if_hole = nullptr); |
| 314 | 299 |
| 315 // Load Float64 value by |base| + |offset| address. If the value is a double | 300 // Load Float64 value by |base| + |offset| address. If the value is a double |
| 316 // hole then jump to |if_hole|. If |machine_type| is None then only the hole | 301 // hole then jump to |if_hole|. If |machine_type| is None then only the hole |
| 317 // check is generated. | 302 // check is generated. |
| 318 compiler::Node* LoadDoubleWithHoleCheck( | 303 Node* LoadDoubleWithHoleCheck( |
| 319 compiler::Node* base, compiler::Node* offset, Label* if_hole, | 304 Node* base, Node* offset, Label* if_hole, |
| 320 MachineType machine_type = MachineType::Float64()); | 305 MachineType machine_type = MachineType::Float64()); |
| 321 compiler::Node* LoadFixedTypedArrayElement( | 306 Node* LoadFixedTypedArrayElement( |
| 322 compiler::Node* data_pointer, compiler::Node* index_node, | 307 Node* data_pointer, Node* index_node, ElementsKind elements_kind, |
| 323 ElementsKind elements_kind, | |
| 324 ParameterMode parameter_mode = INTEGER_PARAMETERS); | 308 ParameterMode parameter_mode = INTEGER_PARAMETERS); |
| 325 | 309 |
| 326 // Context manipulation | 310 // Context manipulation |
| 327 compiler::Node* LoadContextElement(compiler::Node* context, int slot_index); | 311 Node* LoadContextElement(Node* context, int slot_index); |
| 328 compiler::Node* LoadContextElement(compiler::Node* context, | 312 Node* LoadContextElement(Node* context, Node* slot_index); |
| 329 compiler::Node* slot_index); | 313 Node* StoreContextElement(Node* context, int slot_index, Node* value); |
| 330 compiler::Node* StoreContextElement(compiler::Node* context, int slot_index, | 314 Node* StoreContextElement(Node* context, Node* slot_index, Node* value); |
| 331 compiler::Node* value); | 315 Node* LoadNativeContext(Node* context); |
| 332 compiler::Node* StoreContextElement(compiler::Node* context, | |
| 333 compiler::Node* slot_index, | |
| 334 compiler::Node* value); | |
| 335 compiler::Node* LoadNativeContext(compiler::Node* context); | |
| 336 | 316 |
| 337 compiler::Node* LoadJSArrayElementsMap(ElementsKind kind, | 317 Node* LoadJSArrayElementsMap(ElementsKind kind, Node* native_context); |
| 338 compiler::Node* native_context); | |
| 339 | 318 |
| 340 // Store the floating point value of a HeapNumber. | 319 // Store the floating point value of a HeapNumber. |
| 341 compiler::Node* StoreHeapNumberValue(compiler::Node* object, | 320 Node* StoreHeapNumberValue(Node* object, Node* value); |
| 342 compiler::Node* value); | |
| 343 // Store a field to an object on the heap. | 321 // Store a field to an object on the heap. |
| 344 compiler::Node* StoreObjectField( | 322 Node* StoreObjectField(Node* object, int offset, Node* value); |
| 345 compiler::Node* object, int offset, compiler::Node* value); | 323 Node* StoreObjectField(Node* object, Node* offset, Node* value); |
| 346 compiler::Node* StoreObjectField(compiler::Node* object, | 324 Node* StoreObjectFieldNoWriteBarrier( |
| 347 compiler::Node* offset, | 325 Node* object, int offset, Node* value, |
| 348 compiler::Node* value); | |
| 349 compiler::Node* StoreObjectFieldNoWriteBarrier( | |
| 350 compiler::Node* object, int offset, compiler::Node* value, | |
| 351 MachineRepresentation rep = MachineRepresentation::kTagged); | 326 MachineRepresentation rep = MachineRepresentation::kTagged); |
| 352 compiler::Node* StoreObjectFieldNoWriteBarrier( | 327 Node* StoreObjectFieldNoWriteBarrier( |
| 353 compiler::Node* object, compiler::Node* offset, compiler::Node* value, | 328 Node* object, Node* offset, Node* value, |
| 354 MachineRepresentation rep = MachineRepresentation::kTagged); | 329 MachineRepresentation rep = MachineRepresentation::kTagged); |
| 355 // Store the Map of an HeapObject. | 330 // Store the Map of an HeapObject. |
| 356 compiler::Node* StoreMapNoWriteBarrier(compiler::Node* object, | 331 Node* StoreMapNoWriteBarrier(Node* object, Node* map); |
| 357 compiler::Node* map); | 332 Node* StoreObjectFieldRoot(Node* object, int offset, |
| 358 compiler::Node* StoreObjectFieldRoot(compiler::Node* object, int offset, | 333 Heap::RootListIndex root); |
| 359 Heap::RootListIndex root); | |
| 360 // Store an array element to a FixedArray. | 334 // Store an array element to a FixedArray. |
| 361 compiler::Node* StoreFixedArrayElement( | 335 Node* StoreFixedArrayElement( |
| 362 compiler::Node* object, int index, compiler::Node* value, | 336 Node* object, int index, Node* value, |
| 363 WriteBarrierMode barrier_mode = UPDATE_WRITE_BARRIER) { | 337 WriteBarrierMode barrier_mode = UPDATE_WRITE_BARRIER) { |
| 364 return StoreFixedArrayElement(object, IntPtrConstant(index), value, | 338 return StoreFixedArrayElement(object, IntPtrConstant(index), value, |
| 365 barrier_mode, 0, INTPTR_PARAMETERS); | 339 barrier_mode, 0, INTPTR_PARAMETERS); |
| 366 } | 340 } |
| 367 | 341 |
| 368 compiler::Node* StoreFixedArrayElement( | 342 Node* StoreFixedArrayElement( |
| 369 compiler::Node* object, compiler::Node* index, compiler::Node* value, | 343 Node* object, Node* index, Node* value, |
| 370 WriteBarrierMode barrier_mode = UPDATE_WRITE_BARRIER, | 344 WriteBarrierMode barrier_mode = UPDATE_WRITE_BARRIER, |
| 371 int additional_offset = 0, | 345 int additional_offset = 0, |
| 372 ParameterMode parameter_mode = INTEGER_PARAMETERS); | 346 ParameterMode parameter_mode = INTEGER_PARAMETERS); |
| 373 | 347 |
| 374 compiler::Node* StoreFixedDoubleArrayElement( | 348 Node* StoreFixedDoubleArrayElement( |
| 375 compiler::Node* object, compiler::Node* index, compiler::Node* value, | 349 Node* object, Node* index, Node* value, |
| 376 ParameterMode parameter_mode = INTEGER_PARAMETERS); | 350 ParameterMode parameter_mode = INTEGER_PARAMETERS); |
| 377 | 351 |
| 378 void StoreFieldsNoWriteBarrier(compiler::Node* start_address, | 352 void StoreFieldsNoWriteBarrier(Node* start_address, Node* end_address, |
| 379 compiler::Node* end_address, | 353 Node* value); |
| 380 compiler::Node* value); | |
| 381 | 354 |
| 382 // Allocate a HeapNumber without initializing its value. | 355 // Allocate a HeapNumber without initializing its value. |
| 383 compiler::Node* AllocateHeapNumber(MutableMode mode = IMMUTABLE); | 356 Node* AllocateHeapNumber(MutableMode mode = IMMUTABLE); |
| 384 // Allocate a HeapNumber with a specific value. | 357 // Allocate a HeapNumber with a specific value. |
| 385 compiler::Node* AllocateHeapNumberWithValue(compiler::Node* value, | 358 Node* AllocateHeapNumberWithValue(Node* value, MutableMode mode = IMMUTABLE); |
| 386 MutableMode mode = IMMUTABLE); | |
| 387 // Allocate a SeqOneByteString with the given length. | 359 // Allocate a SeqOneByteString with the given length. |
| 388 compiler::Node* AllocateSeqOneByteString(int length, | 360 Node* AllocateSeqOneByteString(int length, AllocationFlags flags = kNone); |
| 389 AllocationFlags flags = kNone); | 361 Node* AllocateSeqOneByteString(Node* context, Node* length, |
| 390 compiler::Node* AllocateSeqOneByteString( | 362 ParameterMode mode = INTPTR_PARAMETERS, |
| 391 compiler::Node* context, compiler::Node* length, | 363 AllocationFlags flags = kNone); |
| 392 ParameterMode mode = INTPTR_PARAMETERS, AllocationFlags flags = kNone); | |
| 393 // Allocate a SeqTwoByteString with the given length. | 364 // Allocate a SeqTwoByteString with the given length. |
| 394 compiler::Node* AllocateSeqTwoByteString(int length, | 365 Node* AllocateSeqTwoByteString(int length, AllocationFlags flags = kNone); |
| 395 AllocationFlags flags = kNone); | 366 Node* AllocateSeqTwoByteString(Node* context, Node* length, |
| 396 compiler::Node* AllocateSeqTwoByteString( | 367 ParameterMode mode = INTPTR_PARAMETERS, |
| 397 compiler::Node* context, compiler::Node* length, | 368 AllocationFlags flags = kNone); |
| 398 ParameterMode mode = INTPTR_PARAMETERS, AllocationFlags flags = kNone); | |
| 399 | 369 |
| 400 // Allocate a SlicedOneByteString with the given length, parent and offset. | 370 // Allocate a SlicedOneByteString with the given length, parent and offset. |
| 401 // |length| and |offset| are expected to be tagged. | 371 // |length| and |offset| are expected to be tagged. |
| 402 compiler::Node* AllocateSlicedOneByteString(compiler::Node* length, | 372 Node* AllocateSlicedOneByteString(Node* length, Node* parent, Node* offset); |
| 403 compiler::Node* parent, | |
| 404 compiler::Node* offset); | |
| 405 // Allocate a SlicedTwoByteString with the given length, parent and offset. | 373 // Allocate a SlicedTwoByteString with the given length, parent and offset. |
| 406 // |length| and |offset| are expected to be tagged. | 374 // |length| and |offset| are expected to be tagged. |
| 407 compiler::Node* AllocateSlicedTwoByteString(compiler::Node* length, | 375 Node* AllocateSlicedTwoByteString(Node* length, Node* parent, Node* offset); |
| 408 compiler::Node* parent, | |
| 409 compiler::Node* offset); | |
| 410 | 376 |
| 411 // Allocate a one-byte ConsString with the given length, first and second | 377 // Allocate a one-byte ConsString with the given length, first and second |
| 412 // parts. |length| is expected to be tagged, and |first| and |second| are | 378 // parts. |length| is expected to be tagged, and |first| and |second| are |
| 413 // expected to be one-byte strings. | 379 // expected to be one-byte strings. |
| 414 compiler::Node* AllocateOneByteConsString(compiler::Node* length, | 380 Node* AllocateOneByteConsString(Node* length, Node* first, Node* second, |
| 415 compiler::Node* first, | 381 AllocationFlags flags = kNone); |
| 416 compiler::Node* second, | |
| 417 AllocationFlags flags = kNone); | |
| 418 // Allocate a two-byte ConsString with the given length, first and second | 382 // Allocate a two-byte ConsString with the given length, first and second |
| 419 // parts. |length| is expected to be tagged, and |first| and |second| are | 383 // parts. |length| is expected to be tagged, and |first| and |second| are |
| 420 // expected to be two-byte strings. | 384 // expected to be two-byte strings. |
| 421 compiler::Node* AllocateTwoByteConsString(compiler::Node* length, | 385 Node* AllocateTwoByteConsString(Node* length, Node* first, Node* second, |
| 422 compiler::Node* first, | 386 AllocationFlags flags = kNone); |
| 423 compiler::Node* second, | |
| 424 AllocationFlags flags = kNone); | |
| 425 | 387 |
| 426 // Allocate an appropriate one- or two-byte ConsString with the first and | 388 // Allocate an appropriate one- or two-byte ConsString with the first and |
| 427 // second parts specified by |first| and |second|. | 389 // second parts specified by |first| and |second|. |
| 428 compiler::Node* NewConsString(compiler::Node* context, compiler::Node* length, | 390 Node* NewConsString(Node* context, Node* length, Node* left, Node* right, |
| 429 compiler::Node* left, compiler::Node* right, | 391 AllocationFlags flags = kNone); |
| 430 AllocationFlags flags = kNone); | |
| 431 | 392 |
| 432 // Allocate a RegExpResult with the given length (the number of captures, | 393 // Allocate a RegExpResult with the given length (the number of captures, |
| 433 // including the match itself), index (the index where the match starts), | 394 // including the match itself), index (the index where the match starts), |
| 434 // and input string. |length| and |index| are expected to be tagged, and | 395 // and input string. |length| and |index| are expected to be tagged, and |
| 435 // |input| must be a string. | 396 // |input| must be a string. |
| 436 compiler::Node* AllocateRegExpResult(compiler::Node* context, | 397 Node* AllocateRegExpResult(Node* context, Node* length, Node* index, |
| 437 compiler::Node* length, | 398 Node* input); |
| 438 compiler::Node* index, | |
| 439 compiler::Node* input); | |
| 440 | 399 |
| 441 compiler::Node* AllocateNameDictionary(int capacity); | 400 Node* AllocateNameDictionary(int capacity); |
| 442 compiler::Node* AllocateNameDictionary(compiler::Node* capacity); | 401 Node* AllocateNameDictionary(Node* capacity); |
| 443 | 402 |
| 444 compiler::Node* AllocateJSObjectFromMap(compiler::Node* map, | 403 Node* AllocateJSObjectFromMap(Node* map, Node* properties = nullptr, |
| 445 compiler::Node* properties = nullptr, | 404 Node* elements = nullptr); |
| 446 compiler::Node* elements = nullptr); | |
| 447 | 405 |
| 448 void InitializeJSObjectFromMap(compiler::Node* object, compiler::Node* map, | 406 void InitializeJSObjectFromMap(Node* object, Node* map, Node* size, |
| 449 compiler::Node* size, | 407 Node* properties = nullptr, |
| 450 compiler::Node* properties = nullptr, | 408 Node* elements = nullptr); |
| 451 compiler::Node* elements = nullptr); | |
| 452 | 409 |
| 453 void InitializeJSObjectBody(compiler::Node* object, compiler::Node* map, | 410 void InitializeJSObjectBody(Node* object, Node* map, Node* size, |
| 454 compiler::Node* size, | |
| 455 int start_offset = JSObject::kHeaderSize); | 411 int start_offset = JSObject::kHeaderSize); |
| 456 | 412 |
| 457 // Allocate a JSArray without elements and initialize the header fields. | 413 // Allocate a JSArray without elements and initialize the header fields. |
| 458 compiler::Node* AllocateUninitializedJSArrayWithoutElements( | 414 Node* AllocateUninitializedJSArrayWithoutElements(ElementsKind kind, |
| 459 ElementsKind kind, compiler::Node* array_map, compiler::Node* length, | 415 Node* array_map, |
| 460 compiler::Node* allocation_site); | 416 Node* length, |
| 417 Node* allocation_site); |
| 461 // Allocate and return a JSArray with initialized header fields and its | 418 // Allocate and return a JSArray with initialized header fields and its |
| 462 // uninitialized elements. | 419 // uninitialized elements. |
| 463 // The ParameterMode argument is only used for the capacity parameter. | 420 // The ParameterMode argument is only used for the capacity parameter. |
| 464 std::pair<compiler::Node*, compiler::Node*> | 421 std::pair<Node*, Node*> AllocateUninitializedJSArrayWithElements( |
| 465 AllocateUninitializedJSArrayWithElements( | 422 ElementsKind kind, Node* array_map, Node* length, Node* allocation_site, |
| 466 ElementsKind kind, compiler::Node* array_map, compiler::Node* length, | 423 Node* capacity, ParameterMode capacity_mode = INTEGER_PARAMETERS); |
| 467 compiler::Node* allocation_site, compiler::Node* capacity, | |
| 468 ParameterMode capacity_mode = INTEGER_PARAMETERS); | |
| 469 // Allocate a JSArray and fill elements with the hole. | 424 // Allocate a JSArray and fill elements with the hole. |
| 470 // The ParameterMode argument is only used for the capacity parameter. | 425 // The ParameterMode argument is only used for the capacity parameter. |
| 471 compiler::Node* AllocateJSArray( | 426 Node* AllocateJSArray(ElementsKind kind, Node* array_map, Node* capacity, |
| 472 ElementsKind kind, compiler::Node* array_map, compiler::Node* capacity, | 427 Node* length, Node* allocation_site = nullptr, |
| 473 compiler::Node* length, compiler::Node* allocation_site = nullptr, | 428 ParameterMode capacity_mode = INTEGER_PARAMETERS); |
| 474 ParameterMode capacity_mode = INTEGER_PARAMETERS); | |
| 475 | 429 |
| 476 compiler::Node* AllocateFixedArray(ElementsKind kind, | 430 Node* AllocateFixedArray(ElementsKind kind, Node* capacity, |
| 477 compiler::Node* capacity, | 431 ParameterMode mode = INTEGER_PARAMETERS, |
| 478 ParameterMode mode = INTEGER_PARAMETERS, | 432 AllocationFlags flags = kNone); |
| 479 AllocationFlags flags = kNone); | |
| 480 | 433 |
| 481 // Perform CreateArrayIterator (ES6 #sec-createarrayiterator). | 434 // Perform CreateArrayIterator (ES6 #sec-createarrayiterator). |
| 482 compiler::Node* CreateArrayIterator(compiler::Node* array, | 435 Node* CreateArrayIterator(Node* array, Node* array_map, Node* array_type, |
| 483 compiler::Node* array_map, | 436 Node* context, IterationKind mode); |
| 484 compiler::Node* array_type, | |
| 485 compiler::Node* context, | |
| 486 IterationKind mode); | |
| 487 | 437 |
| 488 compiler::Node* AllocateJSArrayIterator(compiler::Node* array, | 438 Node* AllocateJSArrayIterator(Node* array, Node* array_map, Node* map); |
| 489 compiler::Node* array_map, | |
| 490 compiler::Node* map); | |
| 491 | 439 |
| 492 void FillFixedArrayWithValue(ElementsKind kind, compiler::Node* array, | 440 void FillFixedArrayWithValue(ElementsKind kind, Node* array, Node* from_index, |
| 493 compiler::Node* from_index, | 441 Node* to_index, |
| 494 compiler::Node* to_index, | |
| 495 Heap::RootListIndex value_root_index, | 442 Heap::RootListIndex value_root_index, |
| 496 ParameterMode mode = INTEGER_PARAMETERS); | 443 ParameterMode mode = INTEGER_PARAMETERS); |
| 497 | 444 |
| 498 // Copies all elements from |from_array| of |length| size to | 445 // Copies all elements from |from_array| of |length| size to |
| 499 // |to_array| of the same size respecting the elements kind. | 446 // |to_array| of the same size respecting the elements kind. |
| 500 void CopyFixedArrayElements( | 447 void CopyFixedArrayElements( |
| 501 ElementsKind kind, compiler::Node* from_array, compiler::Node* to_array, | 448 ElementsKind kind, Node* from_array, Node* to_array, Node* length, |
| 502 compiler::Node* length, | |
| 503 WriteBarrierMode barrier_mode = UPDATE_WRITE_BARRIER, | 449 WriteBarrierMode barrier_mode = UPDATE_WRITE_BARRIER, |
| 504 ParameterMode mode = INTEGER_PARAMETERS) { | 450 ParameterMode mode = INTEGER_PARAMETERS) { |
| 505 CopyFixedArrayElements(kind, from_array, kind, to_array, length, length, | 451 CopyFixedArrayElements(kind, from_array, kind, to_array, length, length, |
| 506 barrier_mode, mode); | 452 barrier_mode, mode); |
| 507 } | 453 } |
| 508 | 454 |
| 509 // Copies |element_count| elements from |from_array| to |to_array| of | 455 // Copies |element_count| elements from |from_array| to |to_array| of |
| 510 // |capacity| size respecting both array's elements kinds. | 456 // |capacity| size respecting both array's elements kinds. |
| 511 void CopyFixedArrayElements( | 457 void CopyFixedArrayElements( |
| 512 ElementsKind from_kind, compiler::Node* from_array, ElementsKind to_kind, | 458 ElementsKind from_kind, Node* from_array, ElementsKind to_kind, |
| 513 compiler::Node* to_array, compiler::Node* element_count, | 459 Node* to_array, Node* element_count, Node* capacity, |
| 514 compiler::Node* capacity, | |
| 515 WriteBarrierMode barrier_mode = UPDATE_WRITE_BARRIER, | 460 WriteBarrierMode barrier_mode = UPDATE_WRITE_BARRIER, |
| 516 ParameterMode mode = INTEGER_PARAMETERS); | 461 ParameterMode mode = INTEGER_PARAMETERS); |
| 517 | 462 |
| 518 // Copies |character_count| elements from |from_string| to |to_string| | 463 // Copies |character_count| elements from |from_string| to |to_string| |
| 519 // starting at the |from_index|'th character. |from_string| and |to_string| | 464 // starting at the |from_index|'th character. |from_string| and |to_string| |
| 520 // can either be one-byte strings or two-byte strings, although if | 465 // can either be one-byte strings or two-byte strings, although if |
| 521 // |from_string| is two-byte, then |to_string| must be two-byte. | 466 // |from_string| is two-byte, then |to_string| must be two-byte. |
| 522 // |from_index|, |to_index| and |character_count| must be either Smis or | 467 // |from_index|, |to_index| and |character_count| must be either Smis or |
| 523 // intptr_ts depending on |mode| s.t. 0 <= |from_index| <= |from_index| + | 468 // intptr_ts depending on |mode| s.t. 0 <= |from_index| <= |from_index| + |
| 524 // |character_count| <= from_string.length and 0 <= |to_index| <= |to_index| + | 469 // |character_count| <= from_string.length and 0 <= |to_index| <= |to_index| + |
| 525 // |character_count| <= to_string.length. | 470 // |character_count| <= to_string.length. |
| 526 void CopyStringCharacters(compiler::Node* from_string, | 471 void CopyStringCharacters(Node* from_string, Node* to_string, |
| 527 compiler::Node* to_string, | 472 Node* from_index, Node* to_index, |
| 528 compiler::Node* from_index, | 473 Node* character_count, |
| 529 compiler::Node* to_index, | |
| 530 compiler::Node* character_count, | |
| 531 String::Encoding from_encoding, | 474 String::Encoding from_encoding, |
| 532 String::Encoding to_encoding, ParameterMode mode); | 475 String::Encoding to_encoding, ParameterMode mode); |
| 533 | 476 |
| 534 // Loads an element from |array| of |from_kind| elements by given |offset| | 477 // Loads an element from |array| of |from_kind| elements by given |offset| |
| 535 // (NOTE: not index!), does a hole check if |if_hole| is provided and | 478 // (NOTE: not index!), does a hole check if |if_hole| is provided and |
| 536 // converts the value so that it becomes ready for storing to array of | 479 // converts the value so that it becomes ready for storing to array of |
| 537 // |to_kind| elements. | 480 // |to_kind| elements. |
| 538 compiler::Node* LoadElementAndPrepareForStore(compiler::Node* array, | 481 Node* LoadElementAndPrepareForStore(Node* array, Node* offset, |
| 539 compiler::Node* offset, | 482 ElementsKind from_kind, |
| 540 ElementsKind from_kind, | 483 ElementsKind to_kind, Label* if_hole); |
| 541 ElementsKind to_kind, | |
| 542 Label* if_hole); | |
| 543 | 484 |
| 544 compiler::Node* CalculateNewElementsCapacity( | 485 Node* CalculateNewElementsCapacity(Node* old_capacity, |
| 545 compiler::Node* old_capacity, ParameterMode mode = INTEGER_PARAMETERS); | 486 ParameterMode mode = INTEGER_PARAMETERS); |
| 546 | 487 |
| 547 // Tries to grow the |elements| array of given |object| to store the |key| | 488 // Tries to grow the |elements| array of given |object| to store the |key| |
| 548 // or bails out if the growing gap is too big. Returns new elements. | 489 // or bails out if the growing gap is too big. Returns new elements. |
| 549 compiler::Node* TryGrowElementsCapacity(compiler::Node* object, | 490 Node* TryGrowElementsCapacity(Node* object, Node* elements, ElementsKind kind, |
| 550 compiler::Node* elements, | 491 Node* key, Label* bailout); |
| 551 ElementsKind kind, | |
| 552 compiler::Node* key, Label* bailout); | |
| 553 | 492 |
| 554 // Tries to grow the |capacity|-length |elements| array of given |object| | 493 // Tries to grow the |capacity|-length |elements| array of given |object| |
| 555 // to store the |key| or bails out if the growing gap is too big. Returns | 494 // to store the |key| or bails out if the growing gap is too big. Returns |
| 556 // new elements. | 495 // new elements. |
| 557 compiler::Node* TryGrowElementsCapacity(compiler::Node* object, | 496 Node* TryGrowElementsCapacity(Node* object, Node* elements, ElementsKind kind, |
| 558 compiler::Node* elements, | 497 Node* key, Node* capacity, ParameterMode mode, |
| 559 ElementsKind kind, | 498 Label* bailout); |
| 560 compiler::Node* key, | |
| 561 compiler::Node* capacity, | |
| 562 ParameterMode mode, Label* bailout); | |
| 563 | 499 |
| 564 // Grows elements capacity of given object. Returns new elements. | 500 // Grows elements capacity of given object. Returns new elements. |
| 565 compiler::Node* GrowElementsCapacity( | 501 Node* GrowElementsCapacity(Node* object, Node* elements, |
| 566 compiler::Node* object, compiler::Node* elements, ElementsKind from_kind, | 502 ElementsKind from_kind, ElementsKind to_kind, |
| 567 ElementsKind to_kind, compiler::Node* capacity, | 503 Node* capacity, Node* new_capacity, |
| 568 compiler::Node* new_capacity, ParameterMode mode, Label* bailout); | 504 ParameterMode mode, Label* bailout); |
| 569 | 505 |
| 570 // Allocation site manipulation | 506 // Allocation site manipulation |
| 571 void InitializeAllocationMemento(compiler::Node* base_allocation, | 507 void InitializeAllocationMemento(Node* base_allocation, |
| 572 int base_allocation_size, | 508 int base_allocation_size, |
| 573 compiler::Node* allocation_site); | 509 Node* allocation_site); |
| 574 | 510 |
| 575 compiler::Node* TryTaggedToFloat64(compiler::Node* value, | 511 Node* TryTaggedToFloat64(Node* value, Label* if_valueisnotnumber); |
| 576 Label* if_valueisnotnumber); | 512 Node* TruncateTaggedToFloat64(Node* context, Node* value); |
| 577 compiler::Node* TruncateTaggedToFloat64(compiler::Node* context, | 513 Node* TruncateTaggedToWord32(Node* context, Node* value); |
| 578 compiler::Node* value); | |
| 579 compiler::Node* TruncateTaggedToWord32(compiler::Node* context, | |
| 580 compiler::Node* value); | |
| 581 // Truncate the floating point value of a HeapNumber to an Int32. | 514 // Truncate the floating point value of a HeapNumber to an Int32. |
| 582 compiler::Node* TruncateHeapNumberValueToWord32(compiler::Node* object); | 515 Node* TruncateHeapNumberValueToWord32(Node* object); |
| 583 | 516 |
| 584 // Conversions. | 517 // Conversions. |
| 585 compiler::Node* ChangeFloat64ToTagged(compiler::Node* value); | 518 Node* ChangeFloat64ToTagged(Node* value); |
| 586 compiler::Node* ChangeInt32ToTagged(compiler::Node* value); | 519 Node* ChangeInt32ToTagged(Node* value); |
| 587 compiler::Node* ChangeUint32ToTagged(compiler::Node* value); | 520 Node* ChangeUint32ToTagged(Node* value); |
| 588 | 521 |
| 589 // Type conversions. | 522 // Type conversions. |
| 590 // Throws a TypeError for {method_name} if {value} is not coercible to Object, | 523 // Throws a TypeError for {method_name} if {value} is not coercible to Object, |
| 591 // or returns the {value} converted to a String otherwise. | 524 // or returns the {value} converted to a String otherwise. |
| 592 compiler::Node* ToThisString(compiler::Node* context, compiler::Node* value, | 525 Node* ToThisString(Node* context, Node* value, char const* method_name); |
| 593 char const* method_name); | |
| 594 // Throws a TypeError for {method_name} if {value} is neither of the given | 526 // Throws a TypeError for {method_name} if {value} is neither of the given |
| 595 // {primitive_type} nor a JSValue wrapping a value of {primitive_type}, or | 527 // {primitive_type} nor a JSValue wrapping a value of {primitive_type}, or |
| 596 // returns the {value} (or wrapped value) otherwise. | 528 // returns the {value} (or wrapped value) otherwise. |
| 597 compiler::Node* ToThisValue(compiler::Node* context, compiler::Node* value, | 529 Node* ToThisValue(Node* context, Node* value, PrimitiveType primitive_type, |
| 598 PrimitiveType primitive_type, | 530 char const* method_name); |
| 599 char const* method_name); | |
| 600 | 531 |
| 601 // Throws a TypeError for {method_name} if {value} is not of the given | 532 // Throws a TypeError for {method_name} if {value} is not of the given |
| 602 // instance type. Returns {value}'s map. | 533 // instance type. Returns {value}'s map. |
| 603 compiler::Node* ThrowIfNotInstanceType(compiler::Node* context, | 534 Node* ThrowIfNotInstanceType(Node* context, Node* value, |
| 604 compiler::Node* value, | 535 InstanceType instance_type, |
| 605 InstanceType instance_type, | 536 char const* method_name); |
| 606 char const* method_name); | |
| 607 | 537 |
| 608 // Type checks. | 538 // Type checks. |
| 609 // Check whether the map is for an object with special properties, such as a | 539 // Check whether the map is for an object with special properties, such as a |
| 610 // JSProxy or an object with interceptors. | 540 // JSProxy or an object with interceptors. |
| 611 compiler::Node* IsSpecialReceiverMap(compiler::Node* map); | 541 Node* IsSpecialReceiverMap(Node* map); |
| 612 compiler::Node* IsSpecialReceiverInstanceType(compiler::Node* instance_type); | 542 Node* IsSpecialReceiverInstanceType(Node* instance_type); |
| 613 compiler::Node* IsStringInstanceType(compiler::Node* instance_type); | 543 Node* IsStringInstanceType(Node* instance_type); |
| 614 compiler::Node* IsString(compiler::Node* object); | 544 Node* IsString(Node* object); |
| 615 compiler::Node* IsJSObject(compiler::Node* object); | 545 Node* IsJSObject(Node* object); |
| 616 compiler::Node* IsJSGlobalProxy(compiler::Node* object); | 546 Node* IsJSGlobalProxy(Node* object); |
| 617 compiler::Node* IsJSReceiverInstanceType(compiler::Node* instance_type); | 547 Node* IsJSReceiverInstanceType(Node* instance_type); |
| 618 compiler::Node* IsJSReceiver(compiler::Node* object); | 548 Node* IsJSReceiver(Node* object); |
| 619 compiler::Node* IsMap(compiler::Node* object); | 549 Node* IsMap(Node* object); |
| 620 compiler::Node* IsCallableMap(compiler::Node* map); | 550 Node* IsCallableMap(Node* map); |
| 621 compiler::Node* IsName(compiler::Node* object); | 551 Node* IsName(Node* object); |
| 622 compiler::Node* IsJSValue(compiler::Node* object); | 552 Node* IsJSValue(Node* object); |
| 623 compiler::Node* IsJSArray(compiler::Node* object); | 553 Node* IsJSArray(Node* object); |
| 624 compiler::Node* IsNativeContext(compiler::Node* object); | 554 Node* IsNativeContext(Node* object); |
| 625 compiler::Node* IsWeakCell(compiler::Node* object); | 555 Node* IsWeakCell(Node* object); |
| 626 compiler::Node* IsFixedDoubleArray(compiler::Node* object); | 556 Node* IsFixedDoubleArray(Node* object); |
| 627 compiler::Node* IsHashTable(compiler::Node* object); | 557 Node* IsHashTable(Node* object); |
| 628 compiler::Node* IsDictionary(compiler::Node* object); | 558 Node* IsDictionary(Node* object); |
| 629 compiler::Node* IsUnseededNumberDictionary(compiler::Node* object); | 559 Node* IsUnseededNumberDictionary(Node* object); |
| 630 | 560 |
| 631 // ElementsKind helpers: | 561 // ElementsKind helpers: |
| 632 compiler::Node* IsFastElementsKind(compiler::Node* elements_kind); | 562 Node* IsFastElementsKind(Node* elements_kind); |
| 633 compiler::Node* IsHoleyFastElementsKind(compiler::Node* elements_kind); | 563 Node* IsHoleyFastElementsKind(Node* elements_kind); |
| 634 | 564 |
| 635 // String helpers. | 565 // String helpers. |
| 636 // Load a character from a String (might flatten a ConsString). | 566 // Load a character from a String (might flatten a ConsString). |
| 637 compiler::Node* StringCharCodeAt(compiler::Node* string, | 567 Node* StringCharCodeAt(Node* string, Node* smi_index); |
| 638 compiler::Node* smi_index); | |
| 639 // Return the single character string with only {code}. | 568 // Return the single character string with only {code}. |
| 640 compiler::Node* StringFromCharCode(compiler::Node* code); | 569 Node* StringFromCharCode(Node* code); |
| 641 // Return a new string object which holds a substring containing the range | 570 // Return a new string object which holds a substring containing the range |
| 642 // [from,to[ of string. |from| and |to| are expected to be tagged. | 571 // [from,to[ of string. |from| and |to| are expected to be tagged. |
| 643 compiler::Node* SubString(compiler::Node* context, compiler::Node* string, | 572 Node* SubString(Node* context, Node* string, Node* from, Node* to); |
| 644 compiler::Node* from, compiler::Node* to); | |
| 645 | 573 |
| 646 // Return a new string object produced by concatenating |first| with |second|. | 574 // Return a new string object produced by concatenating |first| with |second|. |
| 647 compiler::Node* StringAdd(compiler::Node* context, compiler::Node* first, | 575 Node* StringAdd(Node* context, Node* first, Node* second, |
| 648 compiler::Node* second, | 576 AllocationFlags flags = kNone); |
| 649 AllocationFlags flags = kNone); | |
| 650 | 577 |
| 651 // Return the first index >= {from} at which {needle_char} was found in | 578 // Return the first index >= {from} at which {needle_char} was found in |
| 652 // {string}, or -1 if such an index does not exist. The returned value is | 579 // {string}, or -1 if such an index does not exist. The returned value is |
| 653 // a Smi, {string} is expected to be a String, {needle_char} is an intptr, | 580 // a Smi, {string} is expected to be a String, {needle_char} is an intptr, |
| 654 // and {from} is expected to be tagged. | 581 // and {from} is expected to be tagged. |
| 655 compiler::Node* StringIndexOfChar(compiler::Node* context, | 582 Node* StringIndexOfChar(Node* context, Node* string, Node* needle_char, |
| 656 compiler::Node* string, | 583 Node* from); |
| 657 compiler::Node* needle_char, | |
| 658 compiler::Node* from); | |
| 659 | 584 |
| 660 compiler::Node* StringFromCodePoint(compiler::Node* codepoint, | 585 Node* StringFromCodePoint(Node* codepoint, UnicodeEncoding encoding); |
| 661 UnicodeEncoding encoding); | |
| 662 | 586 |
| 663 // Type conversion helpers. | 587 // Type conversion helpers. |
| 664 // Convert a String to a Number. | 588 // Convert a String to a Number. |
| 665 compiler::Node* StringToNumber(compiler::Node* context, | 589 Node* StringToNumber(Node* context, Node* input); |
| 666 compiler::Node* input); | 590 Node* NumberToString(Node* context, Node* input); |
| 667 compiler::Node* NumberToString(compiler::Node* context, | |
| 668 compiler::Node* input); | |
| 669 // Convert an object to a name. | 591 // Convert an object to a name. |
| 670 compiler::Node* ToName(compiler::Node* context, compiler::Node* input); | 592 Node* ToName(Node* context, Node* input); |
| 671 // Convert a Non-Number object to a Number. | 593 // Convert a Non-Number object to a Number. |
| 672 compiler::Node* NonNumberToNumber(compiler::Node* context, | 594 Node* NonNumberToNumber(Node* context, Node* input); |
| 673 compiler::Node* input); | |
| 674 // Convert any object to a Number. | 595 // Convert any object to a Number. |
| 675 compiler::Node* ToNumber(compiler::Node* context, compiler::Node* input); | 596 Node* ToNumber(Node* context, Node* input); |
| 676 | 597 |
| 677 // Convert any object to a String. | 598 // Convert any object to a String. |
| 678 compiler::Node* ToString(compiler::Node* context, compiler::Node* input); | 599 Node* ToString(Node* context, Node* input); |
| 679 | 600 |
| 680 // Convert any object to a Primitive. | 601 // Convert any object to a Primitive. |
| 681 compiler::Node* JSReceiverToPrimitive(compiler::Node* context, | 602 Node* JSReceiverToPrimitive(Node* context, Node* input); |
| 682 compiler::Node* input); | |
| 683 | 603 |
| 684 // Convert a String to a flat String. | 604 // Convert a String to a flat String. |
| 685 compiler::Node* FlattenString(compiler::Node* string); | 605 Node* FlattenString(Node* string); |
| 686 | 606 |
| 687 enum ToIntegerTruncationMode { | 607 enum ToIntegerTruncationMode { |
| 688 kNoTruncation, | 608 kNoTruncation, |
| 689 kTruncateMinusZero, | 609 kTruncateMinusZero, |
| 690 }; | 610 }; |
| 691 | 611 |
| 692 // Convert any object to an Integer. | 612 // Convert any object to an Integer. |
| 693 compiler::Node* ToInteger(compiler::Node* context, compiler::Node* input, | 613 Node* ToInteger(Node* context, Node* input, |
| 694 ToIntegerTruncationMode mode = kNoTruncation); | 614 ToIntegerTruncationMode mode = kNoTruncation); |
| 695 | 615 |
| 696 // Returns a node that contains a decoded (unsigned!) value of a bit | 616 // Returns a node that contains a decoded (unsigned!) value of a bit |
| 697 // field |T| in |word32|. Returns result as an uint32 node. | 617 // field |T| in |word32|. Returns result as an uint32 node. |
| 698 template <typename T> | 618 template <typename T> |
| 699 compiler::Node* DecodeWord32(compiler::Node* word32) { | 619 Node* DecodeWord32(Node* word32) { |
| 700 return DecodeWord32(word32, T::kShift, T::kMask); | 620 return DecodeWord32(word32, T::kShift, T::kMask); |
| 701 } | 621 } |
| 702 | 622 |
| 703 // Returns a node that contains a decoded (unsigned!) value of a bit | 623 // Returns a node that contains a decoded (unsigned!) value of a bit |
| 704 // field |T| in |word|. Returns result as a word-size node. | 624 // field |T| in |word|. Returns result as a word-size node. |
| 705 template <typename T> | 625 template <typename T> |
| 706 compiler::Node* DecodeWord(compiler::Node* word) { | 626 Node* DecodeWord(Node* word) { |
| 707 return DecodeWord(word, T::kShift, T::kMask); | 627 return DecodeWord(word, T::kShift, T::kMask); |
| 708 } | 628 } |
| 709 | 629 |
| 710 // Returns a node that contains a decoded (unsigned!) value of a bit | 630 // Returns a node that contains a decoded (unsigned!) value of a bit |
| 711 // field |T| in |word32|. Returns result as a word-size node. | 631 // field |T| in |word32|. Returns result as a word-size node. |
| 712 template <typename T> | 632 template <typename T> |
| 713 compiler::Node* DecodeWordFromWord32(compiler::Node* word32) { | 633 Node* DecodeWordFromWord32(Node* word32) { |
| 714 return DecodeWord<T>(ChangeUint32ToWord(word32)); | 634 return DecodeWord<T>(ChangeUint32ToWord(word32)); |
| 715 } | 635 } |
| 716 | 636 |
| 717 // Decodes an unsigned (!) value from |word32| to an uint32 node. | 637 // Decodes an unsigned (!) value from |word32| to an uint32 node. |
| 718 compiler::Node* DecodeWord32(compiler::Node* word32, uint32_t shift, | 638 Node* DecodeWord32(Node* word32, uint32_t shift, uint32_t mask); |
| 719 uint32_t mask); | |
| 720 | 639 |
| 721 // Decodes an unsigned (!) value from |word| to a word-size node. | 640 // Decodes an unsigned (!) value from |word| to a word-size node. |
| 722 compiler::Node* DecodeWord(compiler::Node* word, uint32_t shift, | 641 Node* DecodeWord(Node* word, uint32_t shift, uint32_t mask); |
| 723 uint32_t mask); | |
| 724 | 642 |
| 725 // Returns true if any of the |T|'s bits in given |word32| are set. | 643 // Returns true if any of the |T|'s bits in given |word32| are set. |
| 726 template <typename T> | 644 template <typename T> |
| 727 compiler::Node* IsSetWord32(compiler::Node* word32) { | 645 Node* IsSetWord32(Node* word32) { |
| 728 return IsSetWord32(word32, T::kMask); | 646 return IsSetWord32(word32, T::kMask); |
| 729 } | 647 } |
| 730 | 648 |
| 731 // Returns true if any of the mask's bits in given |word32| are set. | 649 // Returns true if any of the mask's bits in given |word32| are set. |
| 732 compiler::Node* IsSetWord32(compiler::Node* word32, uint32_t mask) { | 650 Node* IsSetWord32(Node* word32, uint32_t mask) { |
| 733 return Word32NotEqual(Word32And(word32, Int32Constant(mask)), | 651 return Word32NotEqual(Word32And(word32, Int32Constant(mask)), |
| 734 Int32Constant(0)); | 652 Int32Constant(0)); |
| 735 } | 653 } |
| 736 | 654 |
| 737 // Returns true if any of the |T|'s bits in given |word| are set. | 655 // Returns true if any of the |T|'s bits in given |word| are set. |
| 738 template <typename T> | 656 template <typename T> |
| 739 compiler::Node* IsSetWord(compiler::Node* word) { | 657 Node* IsSetWord(Node* word) { |
| 740 return WordNotEqual(WordAnd(word, IntPtrConstant(T::kMask)), | 658 return WordNotEqual(WordAnd(word, IntPtrConstant(T::kMask)), |
| 741 IntPtrConstant(0)); | 659 IntPtrConstant(0)); |
| 742 } | 660 } |
| 743 | 661 |
| 744 void SetCounter(StatsCounter* counter, int value); | 662 void SetCounter(StatsCounter* counter, int value); |
| 745 void IncrementCounter(StatsCounter* counter, int delta); | 663 void IncrementCounter(StatsCounter* counter, int delta); |
| 746 void DecrementCounter(StatsCounter* counter, int delta); | 664 void DecrementCounter(StatsCounter* counter, int delta); |
| 747 | 665 |
| 748 // Generates "if (false) goto label" code. Useful for marking a label as | 666 // Generates "if (false) goto label" code. Useful for marking a label as |
| 749 // "live" to avoid assertion failures during graph building. In the resulting | 667 // "live" to avoid assertion failures during graph building. In the resulting |
| 750 // code this check will be eliminated. | 668 // code this check will be eliminated. |
| 751 void Use(Label* label); | 669 void Use(Label* label); |
| 752 | 670 |
| 753 // Various building blocks for stubs doing property lookups. | 671 // Various building blocks for stubs doing property lookups. |
| 754 void TryToName(compiler::Node* key, Label* if_keyisindex, Variable* var_index, | 672 void TryToName(Node* key, Label* if_keyisindex, Variable* var_index, |
| 755 Label* if_keyisunique, Label* if_bailout); | 673 Label* if_keyisunique, Label* if_bailout); |
| 756 | 674 |
| 757 // Calculates array index for given dictionary entry and entry field. | 675 // Calculates array index for given dictionary entry and entry field. |
| 758 // See Dictionary::EntryToIndex(). | 676 // See Dictionary::EntryToIndex(). |
| 759 template <typename Dictionary> | 677 template <typename Dictionary> |
| 760 compiler::Node* EntryToIndex(compiler::Node* entry, int field_index); | 678 Node* EntryToIndex(Node* entry, int field_index); |
| 761 template <typename Dictionary> | 679 template <typename Dictionary> |
| 762 compiler::Node* EntryToIndex(compiler::Node* entry) { | 680 Node* EntryToIndex(Node* entry) { |
| 763 return EntryToIndex<Dictionary>(entry, Dictionary::kEntryKeyIndex); | 681 return EntryToIndex<Dictionary>(entry, Dictionary::kEntryKeyIndex); |
| 764 } | 682 } |
| 765 // Calculate a valid size for the a hash table. | 683 // Calculate a valid size for the a hash table. |
| 766 compiler::Node* HashTableComputeCapacity(compiler::Node* at_least_space_for); | 684 Node* HashTableComputeCapacity(Node* at_least_space_for); |
| 767 | 685 |
| 768 template <class Dictionary> | 686 template <class Dictionary> |
| 769 compiler::Node* GetNumberOfElements(compiler::Node* dictionary); | 687 Node* GetNumberOfElements(Node* dictionary); |
| 770 | 688 |
| 771 template <class Dictionary> | 689 template <class Dictionary> |
| 772 void SetNumberOfElements(compiler::Node* dictionary, | 690 void SetNumberOfElements(Node* dictionary, Node* num_elements_smi); |
| 773 compiler::Node* num_elements_smi); | |
| 774 | 691 |
| 775 template <class Dictionary> | 692 template <class Dictionary> |
| 776 compiler::Node* GetNumberOfDeletedElements(compiler::Node* dictionary); | 693 Node* GetNumberOfDeletedElements(Node* dictionary); |
| 777 | 694 |
| 778 template <class Dictionary> | 695 template <class Dictionary> |
| 779 compiler::Node* GetCapacity(compiler::Node* dictionary); | 696 Node* GetCapacity(Node* dictionary); |
| 780 | 697 |
| 781 template <class Dictionary> | 698 template <class Dictionary> |
| 782 compiler::Node* GetNextEnumerationIndex(compiler::Node* dictionary); | 699 Node* GetNextEnumerationIndex(Node* dictionary); |
| 783 | 700 |
| 784 template <class Dictionary> | 701 template <class Dictionary> |
| 785 void SetNextEnumerationIndex(compiler::Node* dictionary, | 702 void SetNextEnumerationIndex(Node* dictionary, Node* next_enum_index_smi); |
| 786 compiler::Node* next_enum_index_smi); | |
| 787 | 703 |
| 788 // Looks up an entry in a NameDictionaryBase successor. If the entry is found | 704 // Looks up an entry in a NameDictionaryBase successor. If the entry is found |
| 789 // control goes to {if_found} and {var_name_index} contains an index of the | 705 // control goes to {if_found} and {var_name_index} contains an index of the |
| 790 // key field of the entry found. If the key is not found control goes to | 706 // key field of the entry found. If the key is not found control goes to |
| 791 // {if_not_found}. | 707 // {if_not_found}. |
| 792 static const int kInlinedDictionaryProbes = 4; | 708 static const int kInlinedDictionaryProbes = 4; |
| 793 enum LookupMode { kFindExisting, kFindInsertionIndex }; | 709 enum LookupMode { kFindExisting, kFindInsertionIndex }; |
| 794 template <typename Dictionary> | 710 template <typename Dictionary> |
| 795 void NameDictionaryLookup(compiler::Node* dictionary, | 711 void NameDictionaryLookup(Node* dictionary, Node* unique_name, |
| 796 compiler::Node* unique_name, Label* if_found, | 712 Label* if_found, Variable* var_name_index, |
| 797 Variable* var_name_index, Label* if_not_found, | 713 Label* if_not_found, |
| 798 int inlined_probes = kInlinedDictionaryProbes, | 714 int inlined_probes = kInlinedDictionaryProbes, |
| 799 LookupMode mode = kFindExisting); | 715 LookupMode mode = kFindExisting); |
| 800 | 716 |
| 801 compiler::Node* ComputeIntegerHash(compiler::Node* key, compiler::Node* seed); | 717 Node* ComputeIntegerHash(Node* key, Node* seed); |
| 802 | 718 |
| 803 template <typename Dictionary> | 719 template <typename Dictionary> |
| 804 void NumberDictionaryLookup(compiler::Node* dictionary, | 720 void NumberDictionaryLookup(Node* dictionary, Node* intptr_index, |
| 805 compiler::Node* intptr_index, Label* if_found, | 721 Label* if_found, Variable* var_entry, |
| 806 Variable* var_entry, Label* if_not_found); | 722 Label* if_not_found); |
| 807 | 723 |
| 808 template <class Dictionary> | 724 template <class Dictionary> |
| 809 void FindInsertionEntry(compiler::Node* dictionary, compiler::Node* key, | 725 void FindInsertionEntry(Node* dictionary, Node* key, Variable* var_key_index); |
| 810 Variable* var_key_index); | |
| 811 | 726 |
| 812 template <class Dictionary> | 727 template <class Dictionary> |
| 813 void InsertEntry(compiler::Node* dictionary, compiler::Node* key, | 728 void InsertEntry(Node* dictionary, Node* key, Node* value, Node* index, |
| 814 compiler::Node* value, compiler::Node* index, | 729 Node* enum_index); |
| 815 compiler::Node* enum_index); | |
| 816 | 730 |
| 817 template <class Dictionary> | 731 template <class Dictionary> |
| 818 void Add(compiler::Node* dictionary, compiler::Node* key, | 732 void Add(Node* dictionary, Node* key, Node* value, Label* bailout); |
| 819 compiler::Node* value, Label* bailout); | |
| 820 | 733 |
| 821 // Tries to check if {object} has own {unique_name} property. | 734 // Tries to check if {object} has own {unique_name} property. |
| 822 void TryHasOwnProperty(compiler::Node* object, compiler::Node* map, | 735 void TryHasOwnProperty(Node* object, Node* map, Node* instance_type, |
| 823 compiler::Node* instance_type, | 736 Node* unique_name, Label* if_found, |
| 824 compiler::Node* unique_name, Label* if_found, | |
| 825 Label* if_not_found, Label* if_bailout); | 737 Label* if_not_found, Label* if_bailout); |
| 826 | 738 |
| 827 // Tries to get {object}'s own {unique_name} property value. If the property | 739 // Tries to get {object}'s own {unique_name} property value. If the property |
| 828 // is an accessor then it also calls a getter. If the property is a double | 740 // is an accessor then it also calls a getter. If the property is a double |
| 829 // field it re-wraps value in an immutable heap number. | 741 // field it re-wraps value in an immutable heap number. |
| 830 void TryGetOwnProperty(compiler::Node* context, compiler::Node* receiver, | 742 void TryGetOwnProperty(Node* context, Node* receiver, Node* object, Node* map, |
| 831 compiler::Node* object, compiler::Node* map, | 743 Node* instance_type, Node* unique_name, |
| 832 compiler::Node* instance_type, | 744 Label* if_found, Variable* var_value, |
| 833 compiler::Node* unique_name, Label* if_found, | 745 Label* if_not_found, Label* if_bailout); |
| 834 Variable* var_value, Label* if_not_found, | |
| 835 Label* if_bailout); | |
| 836 | 746 |
| 837 void LoadPropertyFromFastObject(compiler::Node* object, compiler::Node* map, | 747 void LoadPropertyFromFastObject(Node* object, Node* map, Node* descriptors, |
| 838 compiler::Node* descriptors, | 748 Node* name_index, Variable* var_details, |
| 839 compiler::Node* name_index, | 749 Variable* var_value); |
| 840 Variable* var_details, Variable* var_value); | |
| 841 | 750 |
| 842 void LoadPropertyFromNameDictionary(compiler::Node* dictionary, | 751 void LoadPropertyFromNameDictionary(Node* dictionary, Node* entry, |
| 843 compiler::Node* entry, | |
| 844 Variable* var_details, | 752 Variable* var_details, |
| 845 Variable* var_value); | 753 Variable* var_value); |
| 846 | 754 |
| 847 void LoadPropertyFromGlobalDictionary(compiler::Node* dictionary, | 755 void LoadPropertyFromGlobalDictionary(Node* dictionary, Node* entry, |
| 848 compiler::Node* entry, | |
| 849 Variable* var_details, | 756 Variable* var_details, |
| 850 Variable* var_value, Label* if_deleted); | 757 Variable* var_value, Label* if_deleted); |
| 851 | 758 |
| 852 // Generic property lookup generator. If the {object} is fast and | 759 // Generic property lookup generator. If the {object} is fast and |
| 853 // {unique_name} property is found then the control goes to {if_found_fast} | 760 // {unique_name} property is found then the control goes to {if_found_fast} |
| 854 // label and {var_meta_storage} and {var_name_index} will contain | 761 // label and {var_meta_storage} and {var_name_index} will contain |
| 855 // DescriptorArray and an index of the descriptor's name respectively. | 762 // DescriptorArray and an index of the descriptor's name respectively. |
| 856 // If the {object} is slow or global then the control goes to {if_found_dict} | 763 // If the {object} is slow or global then the control goes to {if_found_dict} |
| 857 // or {if_found_global} and the {var_meta_storage} and {var_name_index} will | 764 // or {if_found_global} and the {var_meta_storage} and {var_name_index} will |
| 858 // contain a dictionary and an index of the key field of the found entry. | 765 // contain a dictionary and an index of the key field of the found entry. |
| 859 // If property is not found or given lookup is not supported then | 766 // If property is not found or given lookup is not supported then |
| 860 // the control goes to {if_not_found} or {if_bailout} respectively. | 767 // the control goes to {if_not_found} or {if_bailout} respectively. |
| 861 // | 768 // |
| 862 // Note: this code does not check if the global dictionary points to deleted | 769 // Note: this code does not check if the global dictionary points to deleted |
| 863 // entry! This has to be done by the caller. | 770 // entry! This has to be done by the caller. |
| 864 void TryLookupProperty(compiler::Node* object, compiler::Node* map, | 771 void TryLookupProperty(Node* object, Node* map, Node* instance_type, |
| 865 compiler::Node* instance_type, | 772 Node* unique_name, Label* if_found_fast, |
| 866 compiler::Node* unique_name, Label* if_found_fast, | |
| 867 Label* if_found_dict, Label* if_found_global, | 773 Label* if_found_dict, Label* if_found_global, |
| 868 Variable* var_meta_storage, Variable* var_name_index, | 774 Variable* var_meta_storage, Variable* var_name_index, |
| 869 Label* if_not_found, Label* if_bailout); | 775 Label* if_not_found, Label* if_bailout); |
| 870 | 776 |
| 871 void TryLookupElement(compiler::Node* object, compiler::Node* map, | 777 void TryLookupElement(Node* object, Node* map, Node* instance_type, |
| 872 compiler::Node* instance_type, | 778 Node* intptr_index, Label* if_found, |
| 873 compiler::Node* intptr_index, Label* if_found, | |
| 874 Label* if_not_found, Label* if_bailout); | 779 Label* if_not_found, Label* if_bailout); |
| 875 | 780 |
| 876 // This is a type of a lookup in holder generator function. In case of a | 781 // This is a type of a lookup in holder generator function. In case of a |
| 877 // property lookup the {key} is guaranteed to be a unique name and in case of | 782 // property lookup the {key} is guaranteed to be a unique name and in case of |
| 878 // element lookup the key is an Int32 index. | 783 // element lookup the key is an Int32 index. |
| 879 typedef std::function<void(compiler::Node* receiver, compiler::Node* holder, | 784 typedef std::function<void(Node* receiver, Node* holder, Node* map, |
| 880 compiler::Node* map, compiler::Node* instance_type, | 785 Node* instance_type, Node* key, Label* next_holder, |
| 881 compiler::Node* key, Label* next_holder, | |
| 882 Label* if_bailout)> | 786 Label* if_bailout)> |
| 883 LookupInHolder; | 787 LookupInHolder; |
| 884 | 788 |
| 885 // Generic property prototype chain lookup generator. | 789 // Generic property prototype chain lookup generator. |
| 886 // For properties it generates lookup using given {lookup_property_in_holder} | 790 // For properties it generates lookup using given {lookup_property_in_holder} |
| 887 // and for elements it uses {lookup_element_in_holder}. | 791 // and for elements it uses {lookup_element_in_holder}. |
| 888 // Upon reaching the end of prototype chain the control goes to {if_end}. | 792 // Upon reaching the end of prototype chain the control goes to {if_end}. |
| 889 // If it can't handle the case {receiver}/{key} case then the control goes | 793 // If it can't handle the case {receiver}/{key} case then the control goes |
| 890 // to {if_bailout}. | 794 // to {if_bailout}. |
| 891 void TryPrototypeChainLookup(compiler::Node* receiver, compiler::Node* key, | 795 void TryPrototypeChainLookup(Node* receiver, Node* key, |
| 892 LookupInHolder& lookup_property_in_holder, | 796 LookupInHolder& lookup_property_in_holder, |
| 893 LookupInHolder& lookup_element_in_holder, | 797 LookupInHolder& lookup_element_in_holder, |
| 894 Label* if_end, Label* if_bailout); | 798 Label* if_end, Label* if_bailout); |
| 895 | 799 |
| 896 // Instanceof helpers. | 800 // Instanceof helpers. |
| 897 // ES6 section 7.3.19 OrdinaryHasInstance (C, O) | 801 // ES6 section 7.3.19 OrdinaryHasInstance (C, O) |
| 898 compiler::Node* OrdinaryHasInstance(compiler::Node* context, | 802 Node* OrdinaryHasInstance(Node* context, Node* callable, Node* object); |
| 899 compiler::Node* callable, | |
| 900 compiler::Node* object); | |
| 901 | 803 |
| 902 // Load type feedback vector from the stub caller's frame. | 804 // Load type feedback vector from the stub caller's frame. |
| 903 compiler::Node* LoadTypeFeedbackVectorForStub(); | 805 Node* LoadTypeFeedbackVectorForStub(); |
| 904 | 806 |
| 905 // Update the type feedback vector. | 807 // Update the type feedback vector. |
| 906 void UpdateFeedback(compiler::Node* feedback, | 808 void UpdateFeedback(Node* feedback, Node* type_feedback_vector, |
| 907 compiler::Node* type_feedback_vector, | 809 Node* slot_id); |
| 908 compiler::Node* slot_id); | |
| 909 | 810 |
| 910 compiler::Node* LoadReceiverMap(compiler::Node* receiver); | 811 Node* LoadReceiverMap(Node* receiver); |
| 911 | 812 |
| 912 // Extends properties backing store by JSObject::kFieldsAdded elements. | 813 // Extends properties backing store by JSObject::kFieldsAdded elements. |
| 913 void ExtendPropertiesBackingStore(compiler::Node* object); | 814 void ExtendPropertiesBackingStore(Node* object); |
| 914 | 815 |
| 915 compiler::Node* PrepareValueForWrite(compiler::Node* value, | 816 Node* PrepareValueForWrite(Node* value, Representation representation, |
| 916 Representation representation, | 817 Label* bailout); |
| 917 Label* bailout); | |
| 918 | 818 |
| 919 void StoreNamedField(compiler::Node* object, FieldIndex index, | 819 void StoreNamedField(Node* object, FieldIndex index, |
| 920 Representation representation, compiler::Node* value, | 820 Representation representation, Node* value, |
| 921 bool transition_to_field); | 821 bool transition_to_field); |
| 922 | 822 |
| 923 void StoreNamedField(compiler::Node* object, compiler::Node* offset, | 823 void StoreNamedField(Node* object, Node* offset, bool is_inobject, |
| 924 bool is_inobject, Representation representation, | 824 Representation representation, Node* value, |
| 925 compiler::Node* value, bool transition_to_field); | 825 bool transition_to_field); |
| 926 | 826 |
| 927 // Emits keyed sloppy arguments load. Returns either the loaded value. | 827 // Emits keyed sloppy arguments load. Returns either the loaded value. |
| 928 compiler::Node* LoadKeyedSloppyArguments(compiler::Node* receiver, | 828 Node* LoadKeyedSloppyArguments(Node* receiver, Node* key, Label* bailout) { |
| 929 compiler::Node* key, | |
| 930 Label* bailout) { | |
| 931 return EmitKeyedSloppyArguments(receiver, key, nullptr, bailout); | 829 return EmitKeyedSloppyArguments(receiver, key, nullptr, bailout); |
| 932 } | 830 } |
| 933 | 831 |
| 934 // Emits keyed sloppy arguments store. | 832 // Emits keyed sloppy arguments store. |
| 935 void StoreKeyedSloppyArguments(compiler::Node* receiver, compiler::Node* key, | 833 void StoreKeyedSloppyArguments(Node* receiver, Node* key, Node* value, |
| 936 compiler::Node* value, Label* bailout) { | 834 Label* bailout) { |
| 937 DCHECK_NOT_NULL(value); | 835 DCHECK_NOT_NULL(value); |
| 938 EmitKeyedSloppyArguments(receiver, key, value, bailout); | 836 EmitKeyedSloppyArguments(receiver, key, value, bailout); |
| 939 } | 837 } |
| 940 | 838 |
| 941 // Loads script context from the script context table. | 839 // Loads script context from the script context table. |
| 942 compiler::Node* LoadScriptContext(compiler::Node* context, int context_index); | 840 Node* LoadScriptContext(Node* context, int context_index); |
| 943 | 841 |
| 944 compiler::Node* ClampedToUint8(compiler::Node* int32_value); | 842 Node* ClampedToUint8(Node* int32_value); |
| 945 | 843 |
| 946 // Store value to an elements array with given elements kind. | 844 // Store value to an elements array with given elements kind. |
| 947 void StoreElement(compiler::Node* elements, ElementsKind kind, | 845 void StoreElement(Node* elements, ElementsKind kind, Node* index, Node* value, |
| 948 compiler::Node* index, compiler::Node* value, | |
| 949 ParameterMode mode); | 846 ParameterMode mode); |
| 950 | 847 |
| 951 void EmitElementStore(compiler::Node* object, compiler::Node* key, | 848 void EmitElementStore(Node* object, Node* key, Node* value, bool is_jsarray, |
| 952 compiler::Node* value, bool is_jsarray, | |
| 953 ElementsKind elements_kind, | 849 ElementsKind elements_kind, |
| 954 KeyedAccessStoreMode store_mode, Label* bailout); | 850 KeyedAccessStoreMode store_mode, Label* bailout); |
| 955 | 851 |
| 956 compiler::Node* CheckForCapacityGrow(compiler::Node* object, | 852 Node* CheckForCapacityGrow(Node* object, Node* elements, ElementsKind kind, |
| 957 compiler::Node* elements, | 853 Node* length, Node* key, ParameterMode mode, |
| 958 ElementsKind kind, | 854 bool is_js_array, Label* bailout); |
| 959 compiler::Node* length, | |
| 960 compiler::Node* key, ParameterMode mode, | |
| 961 bool is_js_array, Label* bailout); | |
| 962 | 855 |
| 963 compiler::Node* CopyElementsOnWrite(compiler::Node* object, | 856 Node* CopyElementsOnWrite(Node* object, Node* elements, ElementsKind kind, |
| 964 compiler::Node* elements, | 857 Node* length, ParameterMode mode, Label* bailout); |
| 965 ElementsKind kind, compiler::Node* length, | |
| 966 ParameterMode mode, Label* bailout); | |
| 967 | 858 |
| 968 void TransitionElementsKind(compiler::Node* object, compiler::Node* map, | 859 void TransitionElementsKind(Node* object, Node* map, ElementsKind from_kind, |
| 969 ElementsKind from_kind, ElementsKind to_kind, | 860 ElementsKind to_kind, bool is_jsarray, |
| 970 bool is_jsarray, Label* bailout); | 861 Label* bailout); |
| 971 | 862 |
| 972 void TrapAllocationMemento(compiler::Node* object, Label* memento_found); | 863 void TrapAllocationMemento(Node* object, Label* memento_found); |
| 973 | 864 |
| 974 compiler::Node* PageFromAddress(compiler::Node* address); | 865 Node* PageFromAddress(Node* address); |
| 975 | 866 |
| 976 // Get the enumerable length from |map| and return the result as a Smi. | 867 // Get the enumerable length from |map| and return the result as a Smi. |
| 977 compiler::Node* EnumLength(compiler::Node* map); | 868 Node* EnumLength(Node* map); |
| 978 | 869 |
| 979 // Check the cache validity for |receiver|. Branch to |use_cache| if | 870 // Check the cache validity for |receiver|. Branch to |use_cache| if |
| 980 // the cache is valid, otherwise branch to |use_runtime|. | 871 // the cache is valid, otherwise branch to |use_runtime|. |
| 981 void CheckEnumCache(compiler::Node* receiver, | 872 void CheckEnumCache(Node* receiver, CodeStubAssembler::Label* use_cache, |
| 982 CodeStubAssembler::Label* use_cache, | |
| 983 CodeStubAssembler::Label* use_runtime); | 873 CodeStubAssembler::Label* use_runtime); |
| 984 | 874 |
| 985 // Create a new weak cell with a specified value and install it into a | 875 // Create a new weak cell with a specified value and install it into a |
| 986 // feedback vector. | 876 // feedback vector. |
| 987 compiler::Node* CreateWeakCellInFeedbackVector( | 877 Node* CreateWeakCellInFeedbackVector(Node* feedback_vector, Node* slot, |
| 988 compiler::Node* feedback_vector, compiler::Node* slot, | 878 Node* value); |
| 989 compiler::Node* value); | |
| 990 | 879 |
| 991 // Create a new AllocationSite and install it into a feedback vector. | 880 // Create a new AllocationSite and install it into a feedback vector. |
| 992 compiler::Node* CreateAllocationSiteInFeedbackVector( | 881 Node* CreateAllocationSiteInFeedbackVector(Node* feedback_vector, Node* slot); |
| 993 compiler::Node* feedback_vector, compiler::Node* slot); | |
| 994 | 882 |
| 995 enum class IndexAdvanceMode { kPre, kPost }; | 883 enum class IndexAdvanceMode { kPre, kPost }; |
| 996 | 884 |
| 997 void BuildFastLoop( | 885 void BuildFastLoop( |
| 998 const VariableList& var_list, MachineRepresentation index_rep, | 886 const VariableList& var_list, MachineRepresentation index_rep, |
| 999 compiler::Node* start_index, compiler::Node* end_index, | 887 Node* start_index, Node* end_index, |
| 1000 std::function<void(CodeStubAssembler* assembler, compiler::Node* index)> | 888 std::function<void(CodeStubAssembler* assembler, Node* index)> body, |
| 1001 body, | |
| 1002 int increment, IndexAdvanceMode mode = IndexAdvanceMode::kPre); | 889 int increment, IndexAdvanceMode mode = IndexAdvanceMode::kPre); |
| 1003 | 890 |
| 1004 void BuildFastLoop( | 891 void BuildFastLoop( |
| 1005 MachineRepresentation index_rep, compiler::Node* start_index, | 892 MachineRepresentation index_rep, Node* start_index, Node* end_index, |
| 1006 compiler::Node* end_index, | 893 std::function<void(CodeStubAssembler* assembler, Node* index)> body, |
| 1007 std::function<void(CodeStubAssembler* assembler, compiler::Node* index)> | |
| 1008 body, | |
| 1009 int increment, IndexAdvanceMode mode = IndexAdvanceMode::kPre) { | 894 int increment, IndexAdvanceMode mode = IndexAdvanceMode::kPre) { |
| 1010 BuildFastLoop(VariableList(0, zone()), index_rep, start_index, end_index, | 895 BuildFastLoop(VariableList(0, zone()), index_rep, start_index, end_index, |
| 1011 body, increment, mode); | 896 body, increment, mode); |
| 1012 } | 897 } |
| 1013 | 898 |
| 1014 enum class ForEachDirection { kForward, kReverse }; | 899 enum class ForEachDirection { kForward, kReverse }; |
| 1015 | 900 |
| 1016 void BuildFastFixedArrayForEach( | 901 void BuildFastFixedArrayForEach( |
| 1017 compiler::Node* fixed_array, ElementsKind kind, | 902 Node* fixed_array, ElementsKind kind, Node* first_element_inclusive, |
| 1018 compiler::Node* first_element_inclusive, | 903 Node* last_element_exclusive, |
| 1019 compiler::Node* last_element_exclusive, | 904 std::function<void(CodeStubAssembler* assembler, Node* fixed_array, |
| 1020 std::function<void(CodeStubAssembler* assembler, | 905 Node* offset)> |
| 1021 compiler::Node* fixed_array, compiler::Node* offset)> | |
| 1022 body, | 906 body, |
| 1023 ParameterMode mode = INTPTR_PARAMETERS, | 907 ParameterMode mode = INTPTR_PARAMETERS, |
| 1024 ForEachDirection direction = ForEachDirection::kReverse); | 908 ForEachDirection direction = ForEachDirection::kReverse); |
| 1025 | 909 |
| 1026 compiler::Node* GetArrayAllocationSize(compiler::Node* element_count, | 910 Node* GetArrayAllocationSize(Node* element_count, ElementsKind kind, |
| 1027 ElementsKind kind, ParameterMode mode, | 911 ParameterMode mode, int header_size) { |
| 1028 int header_size) { | |
| 1029 return ElementOffsetFromIndex(element_count, kind, mode, header_size); | 912 return ElementOffsetFromIndex(element_count, kind, mode, header_size); |
| 1030 } | 913 } |
| 1031 | 914 |
| 1032 compiler::Node* GetFixedArrayAllocationSize(compiler::Node* element_count, | 915 Node* GetFixedArrayAllocationSize(Node* element_count, ElementsKind kind, |
| 1033 ElementsKind kind, | 916 ParameterMode mode) { |
| 1034 ParameterMode mode) { | |
| 1035 return GetArrayAllocationSize(element_count, kind, mode, | 917 return GetArrayAllocationSize(element_count, kind, mode, |
| 1036 FixedArray::kHeaderSize); | 918 FixedArray::kHeaderSize); |
| 1037 } | 919 } |
| 1038 | 920 |
| 1039 enum RelationalComparisonMode { | 921 enum RelationalComparisonMode { |
| 1040 kLessThan, | 922 kLessThan, |
| 1041 kLessThanOrEqual, | 923 kLessThanOrEqual, |
| 1042 kGreaterThan, | 924 kGreaterThan, |
| 1043 kGreaterThanOrEqual | 925 kGreaterThanOrEqual |
| 1044 }; | 926 }; |
| 1045 | 927 |
| 1046 compiler::Node* RelationalComparison(RelationalComparisonMode mode, | 928 Node* RelationalComparison(RelationalComparisonMode mode, Node* lhs, |
| 1047 compiler::Node* lhs, compiler::Node* rhs, | 929 Node* rhs, Node* context); |
| 1048 compiler::Node* context); | |
| 1049 | 930 |
| 1050 void BranchIfNumericRelationalComparison(RelationalComparisonMode mode, | 931 void BranchIfNumericRelationalComparison(RelationalComparisonMode mode, |
| 1051 compiler::Node* lhs, | 932 Node* lhs, Node* rhs, Label* if_true, |
| 1052 compiler::Node* rhs, Label* if_true, | |
| 1053 Label* if_false); | 933 Label* if_false); |
| 1054 | 934 |
| 1055 void GotoUnlessNumberLessThan(compiler::Node* lhs, compiler::Node* rhs, | 935 void GotoUnlessNumberLessThan(Node* lhs, Node* rhs, Label* if_false); |
| 1056 Label* if_false); | |
| 1057 | 936 |
| 1058 enum ResultMode { kDontNegateResult, kNegateResult }; | 937 enum ResultMode { kDontNegateResult, kNegateResult }; |
| 1059 | 938 |
| 1060 compiler::Node* Equal(ResultMode mode, compiler::Node* lhs, | 939 Node* Equal(ResultMode mode, Node* lhs, Node* rhs, Node* context); |
| 1061 compiler::Node* rhs, compiler::Node* context); | |
| 1062 | 940 |
| 1063 compiler::Node* StrictEqual(ResultMode mode, compiler::Node* lhs, | 941 Node* StrictEqual(ResultMode mode, Node* lhs, Node* rhs, Node* context); |
| 1064 compiler::Node* rhs, compiler::Node* context); | |
| 1065 | 942 |
| 1066 // ECMA#sec-samevalue | 943 // ECMA#sec-samevalue |
| 1067 // Similar to StrictEqual except that NaNs are treated as equal and minus zero | 944 // Similar to StrictEqual except that NaNs are treated as equal and minus zero |
| 1068 // differs from positive zero. | 945 // differs from positive zero. |
| 1069 // Unlike Equal and StrictEqual, returns a value suitable for use in Branch | 946 // Unlike Equal and StrictEqual, returns a value suitable for use in Branch |
| 1070 // instructions, e.g. Branch(SameValue(...), &label). | 947 // instructions, e.g. Branch(SameValue(...), &label). |
| 1071 compiler::Node* SameValue(compiler::Node* lhs, compiler::Node* rhs, | 948 Node* SameValue(Node* lhs, Node* rhs, Node* context); |
| 1072 compiler::Node* context); | |
| 1073 | 949 |
| 1074 compiler::Node* HasProperty( | 950 Node* HasProperty( |
| 1075 compiler::Node* object, compiler::Node* key, compiler::Node* context, | 951 Node* object, Node* key, Node* context, |
| 1076 Runtime::FunctionId fallback_runtime_function_id = Runtime::kHasProperty); | 952 Runtime::FunctionId fallback_runtime_function_id = Runtime::kHasProperty); |
| 1077 compiler::Node* ForInFilter(compiler::Node* key, compiler::Node* object, | 953 Node* ForInFilter(Node* key, Node* object, Node* context); |
| 1078 compiler::Node* context); | |
| 1079 | 954 |
| 1080 compiler::Node* Typeof(compiler::Node* value, compiler::Node* context); | 955 Node* Typeof(Node* value, Node* context); |
| 1081 | 956 |
| 1082 compiler::Node* InstanceOf(compiler::Node* object, compiler::Node* callable, | 957 Node* InstanceOf(Node* object, Node* callable, Node* context); |
| 1083 compiler::Node* context); | |
| 1084 | 958 |
| 1085 // Debug helpers | 959 // Debug helpers |
| 1086 compiler::Node* IsDebugActive(); | 960 Node* IsDebugActive(); |
| 1087 | 961 |
| 1088 // TypedArray/ArrayBuffer helpers | 962 // TypedArray/ArrayBuffer helpers |
| 1089 compiler::Node* IsDetachedBuffer(compiler::Node* buffer); | 963 Node* IsDetachedBuffer(Node* buffer); |
| 1090 | 964 |
| 1091 compiler::Node* ElementOffsetFromIndex(compiler::Node* index, | 965 Node* ElementOffsetFromIndex(Node* index, ElementsKind kind, |
| 1092 ElementsKind kind, ParameterMode mode, | 966 ParameterMode mode, int base_size = 0); |
| 1093 int base_size = 0); | |
| 1094 | 967 |
| 1095 protected: | 968 protected: |
| 1096 void DescriptorLookupLinear(compiler::Node* unique_name, | 969 void DescriptorLookupLinear(Node* unique_name, Node* descriptors, Node* nof, |
| 1097 compiler::Node* descriptors, compiler::Node* nof, | |
| 1098 Label* if_found, Variable* var_name_index, | 970 Label* if_found, Variable* var_name_index, |
| 1099 Label* if_not_found); | 971 Label* if_not_found); |
| 1100 | 972 |
| 1101 compiler::Node* CallGetterIfAccessor(compiler::Node* value, | 973 Node* CallGetterIfAccessor(Node* value, Node* details, Node* context, |
| 1102 compiler::Node* details, | 974 Node* receiver, Label* if_bailout); |
| 1103 compiler::Node* context, | |
| 1104 compiler::Node* receiver, | |
| 1105 Label* if_bailout); | |
| 1106 | 975 |
| 1107 compiler::Node* TryToIntptr(compiler::Node* key, Label* miss); | 976 Node* TryToIntptr(Node* key, Label* miss); |
| 1108 | 977 |
| 1109 void BranchIfPrototypesHaveNoElements(compiler::Node* receiver_map, | 978 void BranchIfPrototypesHaveNoElements(Node* receiver_map, |
| 1110 Label* definitely_no_elements, | 979 Label* definitely_no_elements, |
| 1111 Label* possibly_elements); | 980 Label* possibly_elements); |
| 1112 | 981 |
| 1113 private: | 982 private: |
| 1114 friend class CodeStubArguments; | 983 friend class CodeStubArguments; |
| 1115 | 984 |
| 1116 compiler::Node* AllocateRawAligned(compiler::Node* size_in_bytes, | 985 Node* AllocateRawAligned(Node* size_in_bytes, AllocationFlags flags, |
| 1117 AllocationFlags flags, | 986 Node* top_address, Node* limit_address); |
| 1118 compiler::Node* top_address, | 987 Node* AllocateRawUnaligned(Node* size_in_bytes, AllocationFlags flags, |
| 1119 compiler::Node* limit_address); | 988 Node* top_adddress, Node* limit_address); |
| 1120 compiler::Node* AllocateRawUnaligned(compiler::Node* size_in_bytes, | |
| 1121 AllocationFlags flags, | |
| 1122 compiler::Node* top_adddress, | |
| 1123 compiler::Node* limit_address); | |
| 1124 // Allocate and return a JSArray of given total size in bytes with header | 989 // Allocate and return a JSArray of given total size in bytes with header |
| 1125 // fields initialized. | 990 // fields initialized. |
| 1126 compiler::Node* AllocateUninitializedJSArray(ElementsKind kind, | 991 Node* AllocateUninitializedJSArray(ElementsKind kind, Node* array_map, |
| 1127 compiler::Node* array_map, | 992 Node* length, Node* allocation_site, |
| 1128 compiler::Node* length, | 993 Node* size_in_bytes); |
| 1129 compiler::Node* allocation_site, | |
| 1130 compiler::Node* size_in_bytes); | |
| 1131 | 994 |
| 1132 compiler::Node* SmiShiftBitsConstant(); | 995 Node* SmiShiftBitsConstant(); |
| 1133 | 996 |
| 1134 // Emits keyed sloppy arguments load if the |value| is nullptr or store | 997 // Emits keyed sloppy arguments load if the |value| is nullptr or store |
| 1135 // otherwise. Returns either the loaded value or |value|. | 998 // otherwise. Returns either the loaded value or |value|. |
| 1136 compiler::Node* EmitKeyedSloppyArguments(compiler::Node* receiver, | 999 Node* EmitKeyedSloppyArguments(Node* receiver, Node* key, Node* value, |
| 1137 compiler::Node* key, | 1000 Label* bailout); |
| 1138 compiler::Node* value, | |
| 1139 Label* bailout); | |
| 1140 | 1001 |
| 1141 compiler::Node* AllocateSlicedString(Heap::RootListIndex map_root_index, | 1002 Node* AllocateSlicedString(Heap::RootListIndex map_root_index, Node* length, |
| 1142 compiler::Node* length, | 1003 Node* parent, Node* offset); |
| 1143 compiler::Node* parent, | |
| 1144 compiler::Node* offset); | |
| 1145 | 1004 |
| 1146 compiler::Node* AllocateConsString(Heap::RootListIndex map_root_index, | 1005 Node* AllocateConsString(Heap::RootListIndex map_root_index, Node* length, |
| 1147 compiler::Node* length, | 1006 Node* first, Node* second, AllocationFlags flags); |
| 1148 compiler::Node* first, | |
| 1149 compiler::Node* second, | |
| 1150 AllocationFlags flags); | |
| 1151 | 1007 |
| 1152 static const int kElementLoopUnrollThreshold = 8; | 1008 static const int kElementLoopUnrollThreshold = 8; |
| 1153 }; | 1009 }; |
| 1154 | 1010 |
| 1155 class CodeStubArguments { | 1011 class CodeStubArguments { |
| 1156 public: | 1012 public: |
| 1013 typedef compiler::Node Node; |
| 1014 |
| 1157 // |argc| specifies the number of arguments passed to the builtin excluding | 1015 // |argc| specifies the number of arguments passed to the builtin excluding |
| 1158 // the receiver. | 1016 // the receiver. |
| 1159 CodeStubArguments(CodeStubAssembler* assembler, compiler::Node* argc, | 1017 CodeStubArguments(CodeStubAssembler* assembler, Node* argc, |
| 1160 CodeStubAssembler::ParameterMode mode = | 1018 CodeStubAssembler::ParameterMode mode = |
| 1161 CodeStubAssembler::INTPTR_PARAMETERS); | 1019 CodeStubAssembler::INTPTR_PARAMETERS); |
| 1162 | 1020 |
| 1163 compiler::Node* GetReceiver(); | 1021 Node* GetReceiver(); |
| 1164 | 1022 |
| 1165 // |index| is zero-based and does not include the receiver | 1023 // |index| is zero-based and does not include the receiver |
| 1166 compiler::Node* AtIndex(compiler::Node* index, | 1024 Node* AtIndex(Node* index, CodeStubAssembler::ParameterMode mode = |
| 1167 CodeStubAssembler::ParameterMode mode = | 1025 CodeStubAssembler::INTPTR_PARAMETERS); |
| 1168 CodeStubAssembler::INTPTR_PARAMETERS); | |
| 1169 | 1026 |
| 1170 compiler::Node* AtIndex(int index); | 1027 Node* AtIndex(int index); |
| 1171 | 1028 |
| 1172 typedef std::function<void(CodeStubAssembler* assembler, compiler::Node* arg)> | 1029 typedef std::function<void(CodeStubAssembler* assembler, Node* arg)> |
| 1173 ForEachBodyFunction; | 1030 ForEachBodyFunction; |
| 1174 | 1031 |
| 1175 // Iteration doesn't include the receiver. |first| and |last| are zero-based. | 1032 // Iteration doesn't include the receiver. |first| and |last| are zero-based. |
| 1176 void ForEach(ForEachBodyFunction body, compiler::Node* first = nullptr, | 1033 void ForEach(ForEachBodyFunction body, Node* first = nullptr, |
| 1177 compiler::Node* last = nullptr, | 1034 Node* last = nullptr, CodeStubAssembler::ParameterMode mode = |
| 1178 CodeStubAssembler::ParameterMode mode = | 1035 CodeStubAssembler::INTPTR_PARAMETERS) { |
| 1179 CodeStubAssembler::INTPTR_PARAMETERS) { | |
| 1180 CodeStubAssembler::VariableList list(0, assembler_->zone()); | 1036 CodeStubAssembler::VariableList list(0, assembler_->zone()); |
| 1181 ForEach(list, body, first, last); | 1037 ForEach(list, body, first, last); |
| 1182 } | 1038 } |
| 1183 | 1039 |
| 1184 // Iteration doesn't include the receiver. |first| and |last| are zero-based. | 1040 // Iteration doesn't include the receiver. |first| and |last| are zero-based. |
| 1185 void ForEach(const CodeStubAssembler::VariableList& vars, | 1041 void ForEach(const CodeStubAssembler::VariableList& vars, |
| 1186 ForEachBodyFunction body, compiler::Node* first = nullptr, | 1042 ForEachBodyFunction body, Node* first = nullptr, |
| 1187 compiler::Node* last = nullptr, | 1043 Node* last = nullptr, CodeStubAssembler::ParameterMode mode = |
| 1188 CodeStubAssembler::ParameterMode mode = | 1044 CodeStubAssembler::INTPTR_PARAMETERS); |
| 1189 CodeStubAssembler::INTPTR_PARAMETERS); | |
| 1190 | 1045 |
| 1191 void PopAndReturn(compiler::Node* value); | 1046 void PopAndReturn(Node* value); |
| 1192 | 1047 |
| 1193 private: | 1048 private: |
| 1194 compiler::Node* GetArguments(); | 1049 Node* GetArguments(); |
| 1195 | 1050 |
| 1196 CodeStubAssembler* assembler_; | 1051 CodeStubAssembler* assembler_; |
| 1197 compiler::Node* argc_; | 1052 Node* argc_; |
| 1198 compiler::Node* arguments_; | 1053 Node* arguments_; |
| 1199 compiler::Node* fp_; | 1054 Node* fp_; |
| 1200 }; | 1055 }; |
| 1201 | 1056 |
| 1202 #ifdef DEBUG | 1057 #ifdef DEBUG |
| 1203 #define CSA_ASSERT(csa, x) \ | 1058 #define CSA_ASSERT(csa, x) \ |
| 1204 (csa)->Assert([&] { return (x); }, #x, __FILE__, __LINE__) | 1059 (csa)->Assert([&] { return (x); }, #x, __FILE__, __LINE__) |
| 1205 #else | 1060 #else |
| 1206 #define CSA_ASSERT(csa, x) ((void)0) | 1061 #define CSA_ASSERT(csa, x) ((void)0) |
| 1207 #endif | 1062 #endif |
| 1208 | 1063 |
| 1209 #ifdef ENABLE_SLOW_DCHECKS | 1064 #ifdef ENABLE_SLOW_DCHECKS |
| 1210 #define CSA_SLOW_ASSERT(csa, x) \ | 1065 #define CSA_SLOW_ASSERT(csa, x) \ |
| 1211 if (FLAG_enable_slow_asserts) { \ | 1066 if (FLAG_enable_slow_asserts) { \ |
| 1212 (csa)->Assert([&] { return (x); }, #x, __FILE__, __LINE__); \ | 1067 (csa)->Assert([&] { return (x); }, #x, __FILE__, __LINE__); \ |
| 1213 } | 1068 } |
| 1214 #else | 1069 #else |
| 1215 #define CSA_SLOW_ASSERT(csa, x) ((void)0) | 1070 #define CSA_SLOW_ASSERT(csa, x) ((void)0) |
| 1216 #endif | 1071 #endif |
| 1217 | 1072 |
| 1218 DEFINE_OPERATORS_FOR_FLAGS(CodeStubAssembler::AllocationFlags); | 1073 DEFINE_OPERATORS_FOR_FLAGS(CodeStubAssembler::AllocationFlags); |
| 1219 | 1074 |
| 1220 } // namespace internal | 1075 } // namespace internal |
| 1221 } // namespace v8 | 1076 } // namespace v8 |
| 1222 #endif // V8_CODE_STUB_ASSEMBLER_H_ | 1077 #endif // V8_CODE_STUB_ASSEMBLER_H_ |
| OLD | NEW |