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 |