Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(230)

Side by Side Diff: src/builtins/builtins-array.cc

Issue 2734323004: [cleanup] Refactor remaining builtins-*.cc to use TF_BUILTIN macro (Closed)
Patch Set: drop unused variable Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | src/builtins/builtins-conversion.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 #include "src/builtins/builtins.h" 5 #include "src/builtins/builtins.h"
6 #include "src/builtins/builtins-utils.h" 6 #include "src/builtins/builtins-utils.h"
7 7
8 #include "src/code-factory.h" 8 #include "src/code-factory.h"
9 #include "src/code-stub-assembler.h" 9 #include "src/code-stub-assembler.h"
10 #include "src/contexts.h" 10 #include "src/contexts.h"
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after
181 181
182 if (JSArray::HasReadOnlyLength(array)) { 182 if (JSArray::HasReadOnlyLength(array)) {
183 return CallJsIntrinsic(isolate, isolate->array_push(), args); 183 return CallJsIntrinsic(isolate, isolate->array_push(), args);
184 } 184 }
185 185
186 ElementsAccessor* accessor = array->GetElementsAccessor(); 186 ElementsAccessor* accessor = array->GetElementsAccessor();
187 int new_length = accessor->Push(array, &args, to_add); 187 int new_length = accessor->Push(array, &args, to_add);
188 return Smi::FromInt(new_length); 188 return Smi::FromInt(new_length);
189 } 189 }
190 190
191 void Builtins::Generate_FastArrayPush(compiler::CodeAssemblerState* state) { 191 TF_BUILTIN(FastArrayPush, CodeStubAssembler) {
192 typedef compiler::Node Node; 192 Variable arg_index(this, MachineType::PointerRepresentation());
193 typedef CodeStubAssembler::Label Label; 193 Label default_label(this, &arg_index);
194 typedef CodeStubAssembler::Variable Variable; 194 Label smi_transition(this);
195 CodeStubAssembler assembler(state); 195 Label object_push_pre(this);
196 Variable arg_index(&assembler, MachineType::PointerRepresentation()); 196 Label object_push(this, &arg_index);
197 Label default_label(&assembler, &arg_index); 197 Label double_push(this, &arg_index);
198 Label smi_transition(&assembler); 198 Label double_transition(this);
199 Label object_push_pre(&assembler); 199 Label runtime(this, Label::kDeferred);
200 Label object_push(&assembler, &arg_index);
201 Label double_push(&assembler, &arg_index);
202 Label double_transition(&assembler);
203 Label runtime(&assembler, Label::kDeferred);
204 200
205 Node* argc = assembler.Parameter(BuiltinDescriptor::kArgumentsCount); 201 Node* argc = Parameter(BuiltinDescriptor::kArgumentsCount);
206 Node* context = assembler.Parameter(BuiltinDescriptor::kContext); 202 Node* context = Parameter(BuiltinDescriptor::kContext);
207 Node* new_target = assembler.Parameter(BuiltinDescriptor::kNewTarget); 203 Node* new_target = Parameter(BuiltinDescriptor::kNewTarget);
208 204
209 CodeStubArguments args(&assembler, assembler.ChangeInt32ToIntPtr(argc)); 205 CodeStubArguments args(this, ChangeInt32ToIntPtr(argc));
210 Node* receiver = args.GetReceiver(); 206 Node* receiver = args.GetReceiver();
211 Node* kind = nullptr; 207 Node* kind = nullptr;
212 208
213 Label fast(&assembler); 209 Label fast(this);
214 { 210 BranchIfFastJSArray(receiver, context, FastJSArrayAccessMode::ANY_ACCESS,
215 assembler.BranchIfFastJSArray( 211 &fast, &runtime);
216 receiver, context, CodeStubAssembler::FastJSArrayAccessMode::ANY_ACCESS,
217 &fast, &runtime);
218 }
219 212
220 assembler.Bind(&fast); 213 Bind(&fast);
221 { 214 {
222 // Disallow pushing onto prototypes. It might be the JSArray prototype. 215 // Disallow pushing onto prototypes. It might be the JSArray prototype.
223 // Disallow pushing onto non-extensible objects. 216 // Disallow pushing onto non-extensible objects.
224 assembler.Comment("Disallow pushing onto prototypes"); 217 Comment("Disallow pushing onto prototypes");
225 Node* map = assembler.LoadMap(receiver); 218 Node* map = LoadMap(receiver);
226 Node* bit_field2 = assembler.LoadMapBitField2(map); 219 Node* bit_field2 = LoadMapBitField2(map);
227 int mask = static_cast<int>(Map::IsPrototypeMapBits::kMask) | 220 int mask = static_cast<int>(Map::IsPrototypeMapBits::kMask) |
228 (1 << Map::kIsExtensible); 221 (1 << Map::kIsExtensible);
229 Node* test = assembler.Word32And(bit_field2, assembler.Int32Constant(mask)); 222 Node* test = Word32And(bit_field2, Int32Constant(mask));
230 assembler.GotoIf( 223 GotoIf(Word32NotEqual(test, Int32Constant(1 << Map::kIsExtensible)),
231 assembler.Word32NotEqual( 224 &runtime);
232 test, assembler.Int32Constant(1 << Map::kIsExtensible)),
233 &runtime);
234 225
235 // Disallow pushing onto arrays in dictionary named property mode. We need 226 // Disallow pushing onto arrays in dictionary named property mode. We need
236 // to figure out whether the length property is still writable. 227 // to figure out whether the length property is still writable.
237 assembler.Comment( 228 Comment("Disallow pushing onto arrays in dictionary named property mode");
238 "Disallow pushing onto arrays in dictionary named property mode"); 229 GotoIf(IsDictionaryMap(map), &runtime);
239 assembler.GotoIf(assembler.IsDictionaryMap(map), &runtime);
240 230
241 // Check whether the length property is writable. The length property is the 231 // Check whether the length property is writable. The length property is the
242 // only default named property on arrays. It's nonconfigurable, hence is 232 // only default named property on arrays. It's nonconfigurable, hence is
243 // guaranteed to stay the first property. 233 // guaranteed to stay the first property.
244 Node* descriptors = assembler.LoadMapDescriptors(map); 234 Node* descriptors = LoadMapDescriptors(map);
245 Node* details = assembler.LoadFixedArrayElement( 235 Node* details =
246 descriptors, DescriptorArray::ToDetailsIndex(0)); 236 LoadFixedArrayElement(descriptors, DescriptorArray::ToDetailsIndex(0));
247 assembler.GotoIf( 237 GotoIf(IsSetSmi(details, PropertyDetails::kAttributesReadOnlyMask),
248 assembler.IsSetSmi(details, PropertyDetails::kAttributesReadOnlyMask), 238 &runtime);
249 &runtime);
250 239
251 arg_index.Bind(assembler.IntPtrConstant(0)); 240 arg_index.Bind(IntPtrConstant(0));
252 kind = assembler.DecodeWord32<Map::ElementsKindBits>(bit_field2); 241 kind = DecodeWord32<Map::ElementsKindBits>(bit_field2);
253 242
254 assembler.GotoIf( 243 GotoIf(Int32GreaterThan(kind, Int32Constant(FAST_HOLEY_SMI_ELEMENTS)),
255 assembler.Int32GreaterThan( 244 &object_push_pre);
256 kind, assembler.Int32Constant(FAST_HOLEY_SMI_ELEMENTS)),
257 &object_push_pre);
258 245
259 Node* new_length = assembler.BuildAppendJSArray( 246 Node* new_length = BuildAppendJSArray(FAST_SMI_ELEMENTS, context, receiver,
260 FAST_SMI_ELEMENTS, context, receiver, args, arg_index, &smi_transition); 247 args, arg_index, &smi_transition);
261 args.PopAndReturn(new_length); 248 args.PopAndReturn(new_length);
262 } 249 }
263 250
264 // If the argument is not a smi, then use a heavyweight SetProperty to 251 // If the argument is not a smi, then use a heavyweight SetProperty to
265 // transition the array for only the single next element. If the argument is 252 // transition the array for only the single next element. If the argument is
266 // a smi, the failure is due to some other reason and we should fall back on 253 // a smi, the failure is due to some other reason and we should fall back on
267 // the most generic implementation for the rest of the array. 254 // the most generic implementation for the rest of the array.
268 assembler.Bind(&smi_transition); 255 Bind(&smi_transition);
269 { 256 {
270 Node* arg = args.AtIndex(arg_index.value()); 257 Node* arg = args.AtIndex(arg_index.value());
271 assembler.GotoIf(assembler.TaggedIsSmi(arg), &default_label); 258 GotoIf(TaggedIsSmi(arg), &default_label);
272 Node* length = assembler.LoadJSArrayLength(receiver); 259 Node* length = LoadJSArrayLength(receiver);
273 // TODO(danno): Use the KeyedStoreGeneric stub here when possible, 260 // TODO(danno): Use the KeyedStoreGeneric stub here when possible,
274 // calling into the runtime to do the elements transition is overkill. 261 // calling into the runtime to do the elements transition is overkill.
275 assembler.CallRuntime(Runtime::kSetProperty, context, receiver, length, arg, 262 CallRuntime(Runtime::kSetProperty, context, receiver, length, arg,
276 assembler.SmiConstant(STRICT)); 263 SmiConstant(STRICT));
277 assembler.Increment(arg_index); 264 Increment(arg_index);
278 // The runtime SetProperty call could have converted the array to dictionary 265 // The runtime SetProperty call could have converted the array to dictionary
279 // mode, which must be detected to abort the fast-path. 266 // mode, which must be detected to abort the fast-path.
280 Node* map = assembler.LoadMap(receiver); 267 Node* map = LoadMap(receiver);
281 Node* bit_field2 = assembler.LoadMapBitField2(map); 268 Node* bit_field2 = LoadMapBitField2(map);
282 Node* kind = assembler.DecodeWord32<Map::ElementsKindBits>(bit_field2); 269 Node* kind = DecodeWord32<Map::ElementsKindBits>(bit_field2);
283 assembler.GotoIf(assembler.Word32Equal( 270 GotoIf(Word32Equal(kind, Int32Constant(DICTIONARY_ELEMENTS)),
284 kind, assembler.Int32Constant(DICTIONARY_ELEMENTS)), 271 &default_label);
285 &default_label);
286 272
287 assembler.GotoIfNotNumber(arg, &object_push); 273 GotoIfNotNumber(arg, &object_push);
288 assembler.Goto(&double_push); 274 Goto(&double_push);
289 } 275 }
290 276
291 assembler.Bind(&object_push_pre); 277 Bind(&object_push_pre);
292 { 278 {
293 assembler.Branch(assembler.Int32GreaterThan( 279 Branch(Int32GreaterThan(kind, Int32Constant(FAST_HOLEY_ELEMENTS)),
294 kind, assembler.Int32Constant(FAST_HOLEY_ELEMENTS)), 280 &double_push, &object_push);
295 &double_push, &object_push);
296 } 281 }
297 282
298 assembler.Bind(&object_push); 283 Bind(&object_push);
299 { 284 {
300 Node* new_length = assembler.BuildAppendJSArray( 285 Node* new_length = BuildAppendJSArray(FAST_ELEMENTS, context, receiver,
301 FAST_ELEMENTS, context, receiver, args, arg_index, &default_label); 286 args, arg_index, &default_label);
302 args.PopAndReturn(new_length); 287 args.PopAndReturn(new_length);
303 } 288 }
304 289
305 assembler.Bind(&double_push); 290 Bind(&double_push);
306 { 291 {
307 Node* new_length = 292 Node* new_length =
308 assembler.BuildAppendJSArray(FAST_DOUBLE_ELEMENTS, context, receiver, 293 BuildAppendJSArray(FAST_DOUBLE_ELEMENTS, context, receiver, args,
309 args, arg_index, &double_transition); 294 arg_index, &double_transition);
310 args.PopAndReturn(new_length); 295 args.PopAndReturn(new_length);
311 } 296 }
312 297
313 // If the argument is not a double, then use a heavyweight SetProperty to 298 // If the argument is not a double, then use a heavyweight SetProperty to
314 // transition the array for only the single next element. If the argument is 299 // transition the array for only the single next element. If the argument is
315 // a double, the failure is due to some other reason and we should fall back 300 // a double, the failure is due to some other reason and we should fall back
316 // on the most generic implementation for the rest of the array. 301 // on the most generic implementation for the rest of the array.
317 assembler.Bind(&double_transition); 302 Bind(&double_transition);
318 { 303 {
319 Node* arg = args.AtIndex(arg_index.value()); 304 Node* arg = args.AtIndex(arg_index.value());
320 assembler.GotoIfNumber(arg, &default_label); 305 GotoIfNumber(arg, &default_label);
321 Node* length = assembler.LoadJSArrayLength(receiver); 306 Node* length = LoadJSArrayLength(receiver);
322 // TODO(danno): Use the KeyedStoreGeneric stub here when possible, 307 // TODO(danno): Use the KeyedStoreGeneric stub here when possible,
323 // calling into the runtime to do the elements transition is overkill. 308 // calling into the runtime to do the elements transition is overkill.
324 assembler.CallRuntime(Runtime::kSetProperty, context, receiver, length, arg, 309 CallRuntime(Runtime::kSetProperty, context, receiver, length, arg,
325 assembler.SmiConstant(STRICT)); 310 SmiConstant(STRICT));
326 assembler.Increment(arg_index); 311 Increment(arg_index);
327 // The runtime SetProperty call could have converted the array to dictionary 312 // The runtime SetProperty call could have converted the array to dictionary
328 // mode, which must be detected to abort the fast-path. 313 // mode, which must be detected to abort the fast-path.
329 Node* map = assembler.LoadMap(receiver); 314 Node* map = LoadMap(receiver);
330 Node* bit_field2 = assembler.LoadMapBitField2(map); 315 Node* bit_field2 = LoadMapBitField2(map);
331 Node* kind = assembler.DecodeWord32<Map::ElementsKindBits>(bit_field2); 316 Node* kind = DecodeWord32<Map::ElementsKindBits>(bit_field2);
332 assembler.GotoIf(assembler.Word32Equal( 317 GotoIf(Word32Equal(kind, Int32Constant(DICTIONARY_ELEMENTS)),
333 kind, assembler.Int32Constant(DICTIONARY_ELEMENTS)), 318 &default_label);
334 &default_label); 319 Goto(&object_push);
335 assembler.Goto(&object_push);
336 } 320 }
337 321
338 // Fallback that stores un-processed arguments using the full, heavyweight 322 // Fallback that stores un-processed arguments using the full, heavyweight
339 // SetProperty machinery. 323 // SetProperty machinery.
340 assembler.Bind(&default_label); 324 Bind(&default_label);
341 { 325 {
342 args.ForEach( 326 args.ForEach(
343 [&assembler, receiver, context](Node* arg) { 327 [this, receiver, context](Node* arg) {
344 Node* length = assembler.LoadJSArrayLength(receiver); 328 Node* length = LoadJSArrayLength(receiver);
345 assembler.CallRuntime(Runtime::kSetProperty, context, receiver, 329 CallRuntime(Runtime::kSetProperty, context, receiver, length, arg,
346 length, arg, assembler.SmiConstant(STRICT)); 330 SmiConstant(STRICT));
347 }, 331 },
348 arg_index.value()); 332 arg_index.value());
349 args.PopAndReturn(assembler.LoadJSArrayLength(receiver)); 333 args.PopAndReturn(LoadJSArrayLength(receiver));
350 } 334 }
351 335
352 assembler.Bind(&runtime); 336 Bind(&runtime);
353 { 337 {
354 Node* target = assembler.LoadFromFrame( 338 Node* target = LoadFromFrame(StandardFrameConstants::kFunctionOffset,
355 StandardFrameConstants::kFunctionOffset, MachineType::TaggedPointer()); 339 MachineType::TaggedPointer());
356 assembler.TailCallStub(CodeFactory::ArrayPush(assembler.isolate()), context, 340 TailCallStub(CodeFactory::ArrayPush(isolate()), context, target, new_target,
357 target, new_target, argc); 341 argc);
358 } 342 }
359 } 343 }
360 344
361 BUILTIN(ArrayPop) { 345 BUILTIN(ArrayPop) {
362 HandleScope scope(isolate); 346 HandleScope scope(isolate);
363 Handle<Object> receiver = args.receiver(); 347 Handle<Object> receiver = args.receiver();
364 if (!EnsureJSArrayWithWritableFastElements(isolate, receiver, nullptr, 0)) { 348 if (!EnsureJSArrayWithWritableFastElements(isolate, receiver, nullptr, 0)) {
365 return CallJsIntrinsic(isolate, isolate->array_pop(), args); 349 return CallJsIntrinsic(isolate, isolate->array_pop(), args);
366 } 350 }
367 351
(...skipping 1270 matching lines...) Expand 10 before | Expand all | Expand 10 after
1638 isolate, species, Object::ArraySpeciesConstructor(isolate, receiver)); 1622 isolate, species, Object::ArraySpeciesConstructor(isolate, receiver));
1639 if (*species == *isolate->array_function()) { 1623 if (*species == *isolate->array_function()) {
1640 if (Fast_ArrayConcat(isolate, &args).ToHandle(&result_array)) { 1624 if (Fast_ArrayConcat(isolate, &args).ToHandle(&result_array)) {
1641 return *result_array; 1625 return *result_array;
1642 } 1626 }
1643 if (isolate->has_pending_exception()) return isolate->heap()->exception(); 1627 if (isolate->has_pending_exception()) return isolate->heap()->exception();
1644 } 1628 }
1645 return Slow_ArrayConcat(&args, species, isolate); 1629 return Slow_ArrayConcat(&args, species, isolate);
1646 } 1630 }
1647 1631
1648 void Builtins::Generate_ArrayIsArray(compiler::CodeAssemblerState* state) { 1632 TF_BUILTIN(ArrayIsArray, CodeStubAssembler) {
1649 typedef compiler::Node Node; 1633 Node* object = Parameter(1);
1650 typedef CodeStubAssembler::Label Label; 1634 Node* context = Parameter(4);
1651 CodeStubAssembler assembler(state);
1652 1635
1653 Node* object = assembler.Parameter(1); 1636 Label call_runtime(this), return_true(this), return_false(this);
1654 Node* context = assembler.Parameter(4);
1655 1637
1656 Label call_runtime(&assembler), return_true(&assembler), 1638 GotoIf(TaggedIsSmi(object), &return_false);
1657 return_false(&assembler); 1639 Node* instance_type = LoadInstanceType(object);
1658 1640
1659 assembler.GotoIf(assembler.TaggedIsSmi(object), &return_false); 1641 GotoIf(Word32Equal(instance_type, Int32Constant(JS_ARRAY_TYPE)),
1660 Node* instance_type = assembler.LoadInstanceType(object); 1642 &return_true);
1661
1662 assembler.GotoIf(assembler.Word32Equal(
1663 instance_type, assembler.Int32Constant(JS_ARRAY_TYPE)),
1664 &return_true);
1665 1643
1666 // TODO(verwaest): Handle proxies in-place. 1644 // TODO(verwaest): Handle proxies in-place.
1667 assembler.Branch(assembler.Word32Equal( 1645 Branch(Word32Equal(instance_type, Int32Constant(JS_PROXY_TYPE)),
1668 instance_type, assembler.Int32Constant(JS_PROXY_TYPE)), 1646 &call_runtime, &return_false);
1669 &call_runtime, &return_false);
1670 1647
1671 assembler.Bind(&return_true); 1648 Bind(&return_true);
1672 assembler.Return(assembler.BooleanConstant(true)); 1649 Return(BooleanConstant(true));
1673 1650
1674 assembler.Bind(&return_false); 1651 Bind(&return_false);
1675 assembler.Return(assembler.BooleanConstant(false)); 1652 Return(BooleanConstant(false));
1676 1653
1677 assembler.Bind(&call_runtime); 1654 Bind(&call_runtime);
1678 assembler.Return( 1655 Return(CallRuntime(Runtime::kArrayIsArray, context, object));
1679 assembler.CallRuntime(Runtime::kArrayIsArray, context, object));
1680 } 1656 }
1681 1657
1682 TF_BUILTIN(ArrayIncludes, CodeStubAssembler) { 1658 TF_BUILTIN(ArrayIncludes, CodeStubAssembler) {
1683 Node* const array = Parameter(0); 1659 Node* const array = Parameter(0);
1684 Node* const search_element = Parameter(1); 1660 Node* const search_element = Parameter(1);
1685 Node* const start_from = Parameter(2); 1661 Node* const start_from = Parameter(2);
1686 Node* const context = Parameter(3 + 2); 1662 Node* const context = Parameter(3 + 2);
1687 1663
1688 Variable index_var(this, MachineType::PointerRepresentation()); 1664 Variable index_var(this, MachineType::PointerRepresentation());
1689 1665
1690 Label init_k(this), return_true(this), return_false(this), call_runtime(this); 1666 Label init_k(this), return_true(this), return_false(this), call_runtime(this);
1691 Label init_len(this), select_loop(this); 1667 Label init_len(this), select_loop(this);
1692 1668
1693 index_var.Bind(IntPtrConstant(0)); 1669 index_var.Bind(IntPtrConstant(0));
1694 1670
1695 // Take slow path if not a JSArray, if retrieving elements requires 1671 // Take slow path if not a JSArray, if retrieving elements requires
1696 // traversing prototype, or if access checks are required. 1672 // traversing prototype, or if access checks are required.
1697 BranchIfFastJSArray(array, context, 1673 BranchIfFastJSArray(array, context, FastJSArrayAccessMode::INBOUNDS_READ,
1698 CodeStubAssembler::FastJSArrayAccessMode::INBOUNDS_READ,
1699 &init_len, &call_runtime); 1674 &init_len, &call_runtime);
1700 1675
1701 Bind(&init_len); 1676 Bind(&init_len);
1702 // JSArray length is always an Smi for fast arrays. 1677 // JSArray length is always an Smi for fast arrays.
1703 CSA_ASSERT(this, TaggedIsSmi(LoadObjectField(array, JSArray::kLengthOffset))); 1678 CSA_ASSERT(this, TaggedIsSmi(LoadObjectField(array, JSArray::kLengthOffset)));
1704 Node* const len = LoadAndUntagObjectField(array, JSArray::kLengthOffset); 1679 Node* const len = LoadAndUntagObjectField(array, JSArray::kLengthOffset);
1705 1680
1706 GotoIf(IsUndefined(start_from), &select_loop); 1681 GotoIf(IsUndefined(start_from), &select_loop);
1707 1682
1708 // Bailout to slow path if startIndex is not an Smi. 1683 // Bailout to slow path if startIndex is not an Smi.
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after
1910 1885
1911 // Search for HeapNumber 1886 // Search for HeapNumber
1912 Bind(&not_nan_loop); 1887 Bind(&not_nan_loop);
1913 { 1888 {
1914 Label continue_loop(this); 1889 Label continue_loop(this);
1915 GotoIfNot(UintPtrLessThan(index_var.value(), len), &return_false); 1890 GotoIfNot(UintPtrLessThan(index_var.value(), len), &return_false);
1916 1891
1917 // Load double value or continue if it contains a double hole. 1892 // Load double value or continue if it contains a double hole.
1918 Node* element_k = LoadFixedDoubleArrayElement( 1893 Node* element_k = LoadFixedDoubleArrayElement(
1919 elements, index_var.value(), MachineType::Float64(), 0, 1894 elements, index_var.value(), MachineType::Float64(), 0,
1920 CodeStubAssembler::INTPTR_PARAMETERS, &continue_loop); 1895 INTPTR_PARAMETERS, &continue_loop);
1921 1896
1922 Branch(Float64Equal(element_k, search_num.value()), &return_true, 1897 Branch(Float64Equal(element_k, search_num.value()), &return_true,
1923 &continue_loop); 1898 &continue_loop);
1924 Bind(&continue_loop); 1899 Bind(&continue_loop);
1925 index_var.Bind(IntPtrAdd(index_var.value(), IntPtrConstant(1))); 1900 index_var.Bind(IntPtrAdd(index_var.value(), IntPtrConstant(1)));
1926 Goto(&not_nan_loop); 1901 Goto(&not_nan_loop);
1927 } 1902 }
1928 1903
1929 // Search for NaN 1904 // Search for NaN
1930 Bind(&nan_loop); 1905 Bind(&nan_loop);
1931 { 1906 {
1932 Label continue_loop(this); 1907 Label continue_loop(this);
1933 GotoIfNot(UintPtrLessThan(index_var.value(), len), &return_false); 1908 GotoIfNot(UintPtrLessThan(index_var.value(), len), &return_false);
1934 1909
1935 // Load double value or continue if it contains a double hole. 1910 // Load double value or continue if it contains a double hole.
1936 Node* element_k = LoadFixedDoubleArrayElement( 1911 Node* element_k = LoadFixedDoubleArrayElement(
1937 elements, index_var.value(), MachineType::Float64(), 0, 1912 elements, index_var.value(), MachineType::Float64(), 0,
1938 CodeStubAssembler::INTPTR_PARAMETERS, &continue_loop); 1913 INTPTR_PARAMETERS, &continue_loop);
1939 1914
1940 BranchIfFloat64IsNaN(element_k, &return_true, &continue_loop); 1915 BranchIfFloat64IsNaN(element_k, &return_true, &continue_loop);
1941 Bind(&continue_loop); 1916 Bind(&continue_loop);
1942 index_var.Bind(IntPtrAdd(index_var.value(), IntPtrConstant(1))); 1917 index_var.Bind(IntPtrAdd(index_var.value(), IntPtrConstant(1)));
1943 Goto(&nan_loop); 1918 Goto(&nan_loop);
1944 } 1919 }
1945 1920
1946 // Search for the Hole 1921 // Search for the Hole
1947 Bind(&hole_loop); 1922 Bind(&hole_loop);
1948 { 1923 {
1949 GotoIfNot(UintPtrLessThan(index_var.value(), len), &return_false); 1924 GotoIfNot(UintPtrLessThan(index_var.value(), len), &return_false);
1950 1925
1951 // Check if the element is a double hole, but don't load it. 1926 // Check if the element is a double hole, but don't load it.
1952 LoadFixedDoubleArrayElement( 1927 LoadFixedDoubleArrayElement(elements, index_var.value(),
1953 elements, index_var.value(), MachineType::None(), 0, 1928 MachineType::None(), 0, INTPTR_PARAMETERS,
1954 CodeStubAssembler::INTPTR_PARAMETERS, &return_true); 1929 &return_true);
1955 1930
1956 index_var.Bind(IntPtrAdd(index_var.value(), IntPtrConstant(1))); 1931 index_var.Bind(IntPtrAdd(index_var.value(), IntPtrConstant(1)));
1957 Goto(&hole_loop); 1932 Goto(&hole_loop);
1958 } 1933 }
1959 } 1934 }
1960 1935
1961 Bind(&return_true); 1936 Bind(&return_true);
1962 Return(TrueConstant()); 1937 Return(TrueConstant());
1963 1938
1964 Bind(&return_false); 1939 Bind(&return_false);
1965 Return(FalseConstant()); 1940 Return(FalseConstant());
1966 1941
1967 Bind(&call_runtime); 1942 Bind(&call_runtime);
1968 Return(CallRuntime(Runtime::kArrayIncludes_Slow, context, array, 1943 Return(CallRuntime(Runtime::kArrayIncludes_Slow, context, array,
1969 search_element, start_from)); 1944 search_element, start_from));
1970 } 1945 }
1971 1946
1972 void Builtins::Generate_ArrayIndexOf(compiler::CodeAssemblerState* state) { 1947 TF_BUILTIN(ArrayIndexOf, CodeStubAssembler) {
1973 typedef compiler::Node Node; 1948 Node* array = Parameter(0);
1974 typedef CodeStubAssembler::Label Label; 1949 Node* search_element = Parameter(1);
1975 typedef CodeStubAssembler::Variable Variable; 1950 Node* start_from = Parameter(2);
1976 CodeStubAssembler assembler(state); 1951 Node* context = Parameter(3 + 2);
1977 1952
1978 Node* array = assembler.Parameter(0); 1953 Node* intptr_zero = IntPtrConstant(0);
1979 Node* search_element = assembler.Parameter(1); 1954 Node* intptr_one = IntPtrConstant(1);
1980 Node* start_from = assembler.Parameter(2);
1981 Node* context = assembler.Parameter(3 + 2);
1982 1955
1983 Node* intptr_zero = assembler.IntPtrConstant(0); 1956 Variable len_var(this, MachineType::PointerRepresentation()),
1984 Node* intptr_one = assembler.IntPtrConstant(1); 1957 index_var(this, MachineType::PointerRepresentation()),
1958 start_from_var(this, MachineType::PointerRepresentation());
1985 1959
1986 Node* undefined = assembler.UndefinedConstant(); 1960 Label init_k(this), return_found(this), return_not_found(this),
1961 call_runtime(this);
1987 1962
1988 Variable len_var(&assembler, MachineType::PointerRepresentation()), 1963 Label init_len(this);
1989 index_var(&assembler, MachineType::PointerRepresentation()),
1990 start_from_var(&assembler, MachineType::PointerRepresentation());
1991
1992 Label init_k(&assembler), return_found(&assembler),
1993 return_not_found(&assembler), call_runtime(&assembler);
1994
1995 Label init_len(&assembler);
1996 1964
1997 index_var.Bind(intptr_zero); 1965 index_var.Bind(intptr_zero);
1998 len_var.Bind(intptr_zero); 1966 len_var.Bind(intptr_zero);
1999 1967
2000 // Take slow path if not a JSArray, if retrieving elements requires 1968 // Take slow path if not a JSArray, if retrieving elements requires
2001 // traversing prototype, or if access checks are required. 1969 // traversing prototype, or if access checks are required.
2002 assembler.BranchIfFastJSArray( 1970 BranchIfFastJSArray(array, context, FastJSArrayAccessMode::INBOUNDS_READ,
2003 array, context, CodeStubAssembler::FastJSArrayAccessMode::INBOUNDS_READ, 1971 &init_len, &call_runtime);
2004 &init_len, &call_runtime);
2005 1972
2006 assembler.Bind(&init_len); 1973 Bind(&init_len);
2007 { 1974 {
2008 // JSArray length is always an Smi for fast arrays. 1975 // JSArray length is always an Smi for fast arrays.
2009 CSA_ASSERT(&assembler, assembler.TaggedIsSmi(assembler.LoadObjectField( 1976 CSA_ASSERT(this,
2010 array, JSArray::kLengthOffset))); 1977 TaggedIsSmi(LoadObjectField(array, JSArray::kLengthOffset)));
2011 Node* len = 1978 Node* len = LoadAndUntagObjectField(array, JSArray::kLengthOffset);
2012 assembler.LoadAndUntagObjectField(array, JSArray::kLengthOffset);
2013 1979
2014 len_var.Bind(len); 1980 len_var.Bind(len);
2015 assembler.Branch(assembler.WordEqual(len_var.value(), intptr_zero), 1981 Branch(WordEqual(len_var.value(), intptr_zero), &return_not_found, &init_k);
2016 &return_not_found, &init_k);
2017 } 1982 }
2018 1983
2019 assembler.Bind(&init_k); 1984 Bind(&init_k);
2020 { 1985 {
2021 Label done(&assembler), init_k_smi(&assembler), init_k_heap_num(&assembler), 1986 Label done(this), init_k_smi(this), init_k_heap_num(this),
2022 init_k_zero(&assembler), init_k_n(&assembler); 1987 init_k_zero(this), init_k_n(this);
2023 Node* tagged_n = assembler.ToInteger(context, start_from); 1988 Node* tagged_n = ToInteger(context, start_from);
2024 1989
2025 assembler.Branch(assembler.TaggedIsSmi(tagged_n), &init_k_smi, 1990 Branch(TaggedIsSmi(tagged_n), &init_k_smi, &init_k_heap_num);
2026 &init_k_heap_num);
2027 1991
2028 assembler.Bind(&init_k_smi); 1992 Bind(&init_k_smi);
2029 { 1993 {
2030 start_from_var.Bind(assembler.SmiUntag(tagged_n)); 1994 start_from_var.Bind(SmiUntag(tagged_n));
2031 assembler.Goto(&init_k_n); 1995 Goto(&init_k_n);
2032 } 1996 }
2033 1997
2034 assembler.Bind(&init_k_heap_num); 1998 Bind(&init_k_heap_num);
2035 { 1999 {
2036 Label do_return_not_found(&assembler); 2000 Label do_return_not_found(this);
2037 // This round is lossless for all valid lengths. 2001 // This round is lossless for all valid lengths.
2038 Node* fp_len = assembler.RoundIntPtrToFloat64(len_var.value()); 2002 Node* fp_len = RoundIntPtrToFloat64(len_var.value());
2039 Node* fp_n = assembler.LoadHeapNumberValue(tagged_n); 2003 Node* fp_n = LoadHeapNumberValue(tagged_n);
2040 assembler.GotoIf(assembler.Float64GreaterThanOrEqual(fp_n, fp_len), 2004 GotoIf(Float64GreaterThanOrEqual(fp_n, fp_len), &do_return_not_found);
2041 &do_return_not_found); 2005 start_from_var.Bind(ChangeInt32ToIntPtr(TruncateFloat64ToWord32(fp_n)));
2042 start_from_var.Bind(assembler.ChangeInt32ToIntPtr( 2006 Goto(&init_k_n);
2043 assembler.TruncateFloat64ToWord32(fp_n)));
2044 assembler.Goto(&init_k_n);
2045 2007
2046 assembler.Bind(&do_return_not_found); 2008 Bind(&do_return_not_found);
2047 { 2009 {
2048 index_var.Bind(intptr_zero); 2010 index_var.Bind(intptr_zero);
2049 assembler.Goto(&return_not_found); 2011 Goto(&return_not_found);
2050 } 2012 }
2051 } 2013 }
2052 2014
2053 assembler.Bind(&init_k_n); 2015 Bind(&init_k_n);
2054 { 2016 {
2055 Label if_positive(&assembler), if_negative(&assembler), done(&assembler); 2017 Label if_positive(this), if_negative(this), done(this);
2056 assembler.Branch( 2018 Branch(IntPtrLessThan(start_from_var.value(), intptr_zero), &if_negative,
2057 assembler.IntPtrLessThan(start_from_var.value(), intptr_zero), 2019 &if_positive);
2058 &if_negative, &if_positive);
2059 2020
2060 assembler.Bind(&if_positive); 2021 Bind(&if_positive);
2061 { 2022 {
2062 index_var.Bind(start_from_var.value()); 2023 index_var.Bind(start_from_var.value());
2063 assembler.Goto(&done); 2024 Goto(&done);
2064 } 2025 }
2065 2026
2066 assembler.Bind(&if_negative); 2027 Bind(&if_negative);
2067 { 2028 {
2068 index_var.Bind( 2029 index_var.Bind(IntPtrAdd(len_var.value(), start_from_var.value()));
2069 assembler.IntPtrAdd(len_var.value(), start_from_var.value())); 2030 Branch(IntPtrLessThan(index_var.value(), intptr_zero), &init_k_zero,
2070 assembler.Branch( 2031 &done);
2071 assembler.IntPtrLessThan(index_var.value(), intptr_zero),
2072 &init_k_zero, &done);
2073 } 2032 }
2074 2033
2075 assembler.Bind(&init_k_zero); 2034 Bind(&init_k_zero);
2076 { 2035 {
2077 index_var.Bind(intptr_zero); 2036 index_var.Bind(intptr_zero);
2078 assembler.Goto(&done); 2037 Goto(&done);
2079 } 2038 }
2080 2039
2081 assembler.Bind(&done); 2040 Bind(&done);
2082 } 2041 }
2083 } 2042 }
2084 2043
2085 static int32_t kElementsKind[] = { 2044 static int32_t kElementsKind[] = {
2086 FAST_SMI_ELEMENTS, FAST_HOLEY_SMI_ELEMENTS, FAST_ELEMENTS, 2045 FAST_SMI_ELEMENTS, FAST_HOLEY_SMI_ELEMENTS, FAST_ELEMENTS,
2087 FAST_HOLEY_ELEMENTS, FAST_DOUBLE_ELEMENTS, FAST_HOLEY_DOUBLE_ELEMENTS, 2046 FAST_HOLEY_ELEMENTS, FAST_DOUBLE_ELEMENTS, FAST_HOLEY_DOUBLE_ELEMENTS,
2088 }; 2047 };
2089 2048
2090 Label if_smiorobjects(&assembler), if_packed_doubles(&assembler), 2049 Label if_smiorobjects(this), if_packed_doubles(this), if_holey_doubles(this);
2091 if_holey_doubles(&assembler);
2092 Label* element_kind_handlers[] = {&if_smiorobjects, &if_smiorobjects, 2050 Label* element_kind_handlers[] = {&if_smiorobjects, &if_smiorobjects,
2093 &if_smiorobjects, &if_smiorobjects, 2051 &if_smiorobjects, &if_smiorobjects,
2094 &if_packed_doubles, &if_holey_doubles}; 2052 &if_packed_doubles, &if_holey_doubles};
2095 2053
2096 Node* map = assembler.LoadMap(array); 2054 Node* map = LoadMap(array);
2097 Node* elements_kind = assembler.LoadMapElementsKind(map); 2055 Node* elements_kind = LoadMapElementsKind(map);
2098 Node* elements = assembler.LoadElements(array); 2056 Node* elements = LoadElements(array);
2099 assembler.Switch(elements_kind, &return_not_found, kElementsKind, 2057 Switch(elements_kind, &return_not_found, kElementsKind, element_kind_handlers,
2100 element_kind_handlers, arraysize(kElementsKind)); 2058 arraysize(kElementsKind));
2101 2059
2102 assembler.Bind(&if_smiorobjects); 2060 Bind(&if_smiorobjects);
2103 { 2061 {
2104 Variable search_num(&assembler, MachineRepresentation::kFloat64); 2062 Variable search_num(this, MachineRepresentation::kFloat64);
2105 Label ident_loop(&assembler, &index_var), 2063 Label ident_loop(this, &index_var), heap_num_loop(this, &search_num),
2106 heap_num_loop(&assembler, &search_num), 2064 string_loop(this, &index_var), not_smi(this), not_heap_num(this);
2107 string_loop(&assembler, &index_var), undef_loop(&assembler, &index_var), 2065
2108 not_smi(&assembler), not_heap_num(&assembler); 2066 GotoIfNot(TaggedIsSmi(search_element), &not_smi);
2109 2067 search_num.Bind(SmiToFloat64(search_element));
2110 assembler.GotoIfNot(assembler.TaggedIsSmi(search_element), &not_smi); 2068 Goto(&heap_num_loop);
2111 search_num.Bind(assembler.SmiToFloat64(search_element)); 2069
2112 assembler.Goto(&heap_num_loop); 2070 Bind(&not_smi);
2113 2071 Node* map = LoadMap(search_element);
2114 assembler.Bind(&not_smi); 2072 GotoIfNot(IsHeapNumberMap(map), &not_heap_num);
2115 assembler.GotoIf(assembler.WordEqual(search_element, undefined), 2073 search_num.Bind(LoadHeapNumberValue(search_element));
2116 &undef_loop); 2074 Goto(&heap_num_loop);
2117 Node* map = assembler.LoadMap(search_element); 2075
2118 assembler.GotoIfNot(assembler.IsHeapNumberMap(map), &not_heap_num); 2076 Bind(&not_heap_num);
2119 search_num.Bind(assembler.LoadHeapNumberValue(search_element)); 2077 Node* search_type = LoadMapInstanceType(map);
2120 assembler.Goto(&heap_num_loop); 2078 GotoIf(IsStringInstanceType(search_type), &string_loop);
2121 2079 Goto(&ident_loop);
2122 assembler.Bind(&not_heap_num); 2080
2123 Node* search_type = assembler.LoadMapInstanceType(map); 2081 Bind(&ident_loop);
2124 assembler.GotoIf(assembler.IsStringInstanceType(search_type), &string_loop); 2082 {
2125 assembler.Goto(&ident_loop); 2083 GotoIfNot(UintPtrLessThan(index_var.value(), len_var.value()),
2126 2084 &return_not_found);
2127 assembler.Bind(&ident_loop); 2085 Node* element_k = LoadFixedArrayElement(elements, index_var.value());
2128 { 2086 GotoIf(WordEqual(element_k, search_element), &return_found);
2129 assembler.GotoIfNot( 2087
2130 assembler.UintPtrLessThan(index_var.value(), len_var.value()), 2088 index_var.Bind(IntPtrAdd(index_var.value(), intptr_one));
2131 &return_not_found); 2089 Goto(&ident_loop);
2132 Node* element_k = 2090 }
2133 assembler.LoadFixedArrayElement(elements, index_var.value()); 2091
2134 assembler.GotoIf(assembler.WordEqual(element_k, search_element), 2092 Bind(&heap_num_loop);
2135 &return_found); 2093 {
2136 2094 Label not_nan_loop(this, &index_var);
2137 index_var.Bind(assembler.IntPtrAdd(index_var.value(), intptr_one)); 2095 BranchIfFloat64IsNaN(search_num.value(), &return_not_found,
2138 assembler.Goto(&ident_loop); 2096 &not_nan_loop);
2139 } 2097
2140 2098 Bind(&not_nan_loop);
2141 assembler.Bind(&undef_loop);
2142 {
2143 assembler.GotoIfNot(
2144 assembler.UintPtrLessThan(index_var.value(), len_var.value()),
2145 &return_not_found);
2146 Node* element_k =
2147 assembler.LoadFixedArrayElement(elements, index_var.value());
2148 assembler.GotoIf(assembler.WordEqual(element_k, undefined),
2149 &return_found);
2150
2151 index_var.Bind(assembler.IntPtrAdd(index_var.value(), intptr_one));
2152 assembler.Goto(&undef_loop);
2153 }
2154
2155 assembler.Bind(&heap_num_loop);
2156 {
2157 Label not_nan_loop(&assembler, &index_var);
2158 assembler.BranchIfFloat64IsNaN(search_num.value(), &return_not_found,
2159 &not_nan_loop);
2160
2161 assembler.Bind(&not_nan_loop);
2162 { 2099 {
2163 Label continue_loop(&assembler), not_smi(&assembler); 2100 Label continue_loop(this), not_smi(this);
2164 assembler.GotoIfNot( 2101 GotoIfNot(UintPtrLessThan(index_var.value(), len_var.value()),
2165 assembler.UintPtrLessThan(index_var.value(), len_var.value()), 2102 &return_not_found);
2166 &return_not_found); 2103 Node* element_k = LoadFixedArrayElement(elements, index_var.value());
2167 Node* element_k = 2104 GotoIfNot(TaggedIsSmi(element_k), &not_smi);
2168 assembler.LoadFixedArrayElement(elements, index_var.value()); 2105 Branch(Float64Equal(search_num.value(), SmiToFloat64(element_k)),
2169 assembler.GotoIfNot(assembler.TaggedIsSmi(element_k), &not_smi); 2106 &return_found, &continue_loop);
2170 assembler.Branch( 2107
2171 assembler.Float64Equal(search_num.value(), 2108 Bind(&not_smi);
2172 assembler.SmiToFloat64(element_k)), 2109 GotoIfNot(IsHeapNumber(element_k), &continue_loop);
2173 &return_found, &continue_loop); 2110 Branch(Float64Equal(search_num.value(), LoadHeapNumberValue(element_k)),
2174 2111 &return_found, &continue_loop);
2175 assembler.Bind(&not_smi); 2112
2176 assembler.GotoIfNot( 2113 Bind(&continue_loop);
2177 assembler.IsHeapNumberMap(assembler.LoadMap(element_k)), 2114 index_var.Bind(IntPtrAdd(index_var.value(), intptr_one));
2178 &continue_loop); 2115 Goto(&not_nan_loop);
2179 assembler.Branch(
2180 assembler.Float64Equal(search_num.value(),
2181 assembler.LoadHeapNumberValue(element_k)),
2182 &return_found, &continue_loop);
2183
2184 assembler.Bind(&continue_loop);
2185 index_var.Bind(assembler.IntPtrAdd(index_var.value(), intptr_one));
2186 assembler.Goto(&not_nan_loop);
2187 } 2116 }
2188 } 2117 }
2189 2118
2190 assembler.Bind(&string_loop); 2119 Bind(&string_loop);
2191 { 2120 {
2192 Label continue_loop(&assembler); 2121 Label continue_loop(this);
2193 assembler.GotoIfNot( 2122 GotoIfNot(UintPtrLessThan(index_var.value(), len_var.value()),
2194 assembler.UintPtrLessThan(index_var.value(), len_var.value()), 2123 &return_not_found);
2195 &return_not_found); 2124 Node* element_k = LoadFixedArrayElement(elements, index_var.value());
2196 Node* element_k = 2125 GotoIf(TaggedIsSmi(element_k), &continue_loop);
2197 assembler.LoadFixedArrayElement(elements, index_var.value()); 2126 GotoIfNot(IsString(element_k), &continue_loop);
2198 assembler.GotoIf(assembler.TaggedIsSmi(element_k), &continue_loop);
2199 assembler.GotoIfNot(
2200 assembler.IsStringInstanceType(assembler.LoadInstanceType(element_k)),
2201 &continue_loop);
2202 2127
2203 // TODO(bmeurer): Consider inlining the StringEqual logic here. 2128 // TODO(bmeurer): Consider inlining the StringEqual logic here.
2204 Callable callable = CodeFactory::StringEqual(assembler.isolate()); 2129 Callable callable = CodeFactory::StringEqual(isolate());
2205 Node* result = 2130 Node* result = CallStub(callable, context, search_element, element_k);
2206 assembler.CallStub(callable, context, search_element, element_k); 2131 Branch(WordEqual(BooleanConstant(true), result), &return_found,
2207 assembler.Branch( 2132 &continue_loop);
2208 assembler.WordEqual(assembler.BooleanConstant(true), result), 2133
2209 &return_found, &continue_loop); 2134 Bind(&continue_loop);
2210 2135 index_var.Bind(IntPtrAdd(index_var.value(), intptr_one));
2211 assembler.Bind(&continue_loop); 2136 Goto(&string_loop);
2212 index_var.Bind(assembler.IntPtrAdd(index_var.value(), intptr_one)); 2137 }
2213 assembler.Goto(&string_loop); 2138 }
2214 } 2139
2215 } 2140 Bind(&if_packed_doubles);
2216 2141 {
2217 assembler.Bind(&if_packed_doubles); 2142 Label not_nan_loop(this, &index_var), search_notnan(this);
2218 { 2143 Variable search_num(this, MachineRepresentation::kFloat64);
2219 Label not_nan_loop(&assembler, &index_var), search_notnan(&assembler); 2144
2220 Variable search_num(&assembler, MachineRepresentation::kFloat64); 2145 GotoIfNot(TaggedIsSmi(search_element), &search_notnan);
2221 2146 search_num.Bind(SmiToFloat64(search_element));
2222 assembler.GotoIfNot(assembler.TaggedIsSmi(search_element), &search_notnan); 2147 Goto(&not_nan_loop);
2223 search_num.Bind(assembler.SmiToFloat64(search_element)); 2148
2224 assembler.Goto(&not_nan_loop); 2149 Bind(&search_notnan);
2225 2150 GotoIfNot(IsHeapNumber(search_element), &return_not_found);
2226 assembler.Bind(&search_notnan); 2151
2227 assembler.GotoIfNot( 2152 search_num.Bind(LoadHeapNumberValue(search_element));
2228 assembler.IsHeapNumberMap(assembler.LoadMap(search_element)), 2153
2229 &return_not_found); 2154 BranchIfFloat64IsNaN(search_num.value(), &return_not_found, &not_nan_loop);
2230
2231 search_num.Bind(assembler.LoadHeapNumberValue(search_element));
2232
2233 assembler.BranchIfFloat64IsNaN(search_num.value(), &return_not_found,
2234 &not_nan_loop);
2235 2155
2236 // Search for HeapNumber 2156 // Search for HeapNumber
2237 assembler.Bind(&not_nan_loop); 2157 Bind(&not_nan_loop);
2238 { 2158 {
2239 Label continue_loop(&assembler); 2159 GotoIfNot(UintPtrLessThan(index_var.value(), len_var.value()),
2240 assembler.GotoIfNot( 2160 &return_not_found);
2241 assembler.UintPtrLessThan(index_var.value(), len_var.value()), 2161 Node* element_k = LoadFixedDoubleArrayElement(elements, index_var.value(),
2242 &return_not_found); 2162 MachineType::Float64());
2243 Node* element_k = assembler.LoadFixedDoubleArrayElement( 2163 GotoIf(Float64Equal(element_k, search_num.value()), &return_found);
2244 elements, index_var.value(), MachineType::Float64()); 2164
2245 assembler.Branch(assembler.Float64Equal(element_k, search_num.value()), 2165 index_var.Bind(IntPtrAdd(index_var.value(), intptr_one));
2246 &return_found, &continue_loop); 2166 Goto(&not_nan_loop);
2247 assembler.Bind(&continue_loop); 2167 }
2248 index_var.Bind(assembler.IntPtrAdd(index_var.value(), intptr_one)); 2168 }
2249 assembler.Goto(&not_nan_loop); 2169
2250 } 2170 Bind(&if_holey_doubles);
2251 } 2171 {
2252 2172 Label not_nan_loop(this, &index_var), search_notnan(this);
2253 assembler.Bind(&if_holey_doubles); 2173 Variable search_num(this, MachineRepresentation::kFloat64);
2254 { 2174
2255 Label not_nan_loop(&assembler, &index_var), search_notnan(&assembler); 2175 GotoIfNot(TaggedIsSmi(search_element), &search_notnan);
2256 Variable search_num(&assembler, MachineRepresentation::kFloat64); 2176 search_num.Bind(SmiToFloat64(search_element));
2257 2177 Goto(&not_nan_loop);
2258 assembler.GotoIfNot(assembler.TaggedIsSmi(search_element), &search_notnan); 2178
2259 search_num.Bind(assembler.SmiToFloat64(search_element)); 2179 Bind(&search_notnan);
2260 assembler.Goto(&not_nan_loop); 2180 GotoIfNot(IsHeapNumber(search_element), &return_not_found);
2261 2181
2262 assembler.Bind(&search_notnan); 2182 search_num.Bind(LoadHeapNumberValue(search_element));
2263 assembler.GotoIfNot( 2183
2264 assembler.IsHeapNumberMap(assembler.LoadMap(search_element)), 2184 BranchIfFloat64IsNaN(search_num.value(), &return_not_found, &not_nan_loop);
2265 &return_not_found);
2266
2267 search_num.Bind(assembler.LoadHeapNumberValue(search_element));
2268
2269 assembler.BranchIfFloat64IsNaN(search_num.value(), &return_not_found,
2270 &not_nan_loop);
2271 2185
2272 // Search for HeapNumber 2186 // Search for HeapNumber
2273 assembler.Bind(&not_nan_loop); 2187 Bind(&not_nan_loop);
2274 { 2188 {
2275 Label continue_loop(&assembler); 2189 Label continue_loop(this);
2276 assembler.GotoIfNot( 2190 GotoIfNot(UintPtrLessThan(index_var.value(), len_var.value()),
2277 assembler.UintPtrLessThan(index_var.value(), len_var.value()), 2191 &return_not_found);
2278 &return_not_found);
2279 2192
2280 // Load double value or continue if it contains a double hole. 2193 // Load double value or continue if it contains a double hole.
2281 Node* element_k = assembler.LoadFixedDoubleArrayElement( 2194 Node* element_k = LoadFixedDoubleArrayElement(
2282 elements, index_var.value(), MachineType::Float64(), 0, 2195 elements, index_var.value(), MachineType::Float64(), 0,
2283 CodeStubAssembler::INTPTR_PARAMETERS, &continue_loop); 2196 INTPTR_PARAMETERS, &continue_loop);
2284 2197
2285 assembler.Branch(assembler.Float64Equal(element_k, search_num.value()), 2198 Branch(Float64Equal(element_k, search_num.value()), &return_found,
2286 &return_found, &continue_loop); 2199 &continue_loop);
2287 assembler.Bind(&continue_loop); 2200 Bind(&continue_loop);
2288 index_var.Bind(assembler.IntPtrAdd(index_var.value(), intptr_one)); 2201 index_var.Bind(IntPtrAdd(index_var.value(), intptr_one));
2289 assembler.Goto(&not_nan_loop); 2202 Goto(&not_nan_loop);
2290 } 2203 }
2291 } 2204 }
2292 2205
2293 assembler.Bind(&return_found); 2206 Bind(&return_found);
2294 assembler.Return(assembler.SmiTag(index_var.value())); 2207 Return(SmiTag(index_var.value()));
2295 2208
2296 assembler.Bind(&return_not_found); 2209 Bind(&return_not_found);
2297 assembler.Return(assembler.NumberConstant(-1)); 2210 Return(NumberConstant(-1));
2298 2211
2299 assembler.Bind(&call_runtime); 2212 Bind(&call_runtime);
2300 assembler.Return(assembler.CallRuntime(Runtime::kArrayIndexOf, context, array, 2213 Return(CallRuntime(Runtime::kArrayIndexOf, context, array, search_element,
2301 search_element, start_from)); 2214 start_from));
2302 } 2215 }
2303 2216
2304 namespace { 2217 class ArrayPrototypeIterationAssembler : public CodeStubAssembler {
2305 2218 public:
2306 template <IterationKind kIterationKind> 2219 explicit ArrayPrototypeIterationAssembler(compiler::CodeAssemblerState* state)
2307 void Generate_ArrayPrototypeIterationMethod( 2220 : CodeStubAssembler(state) {}
2308 compiler::CodeAssemblerState* state) { 2221
2309 typedef compiler::Node Node; 2222 protected:
2310 typedef CodeStubAssembler::Label Label; 2223 void Generate_ArrayPrototypeIterationMethod(IterationKind iteration_kind) {
2311 typedef CodeStubAssembler::Variable Variable; 2224 Node* receiver = Parameter(0);
2312 CodeStubAssembler assembler(state); 2225 Node* context = Parameter(3);
2313 2226
2314 Node* receiver = assembler.Parameter(0); 2227 Variable var_array(this, MachineRepresentation::kTagged);
2315 Node* context = assembler.Parameter(3); 2228 Variable var_map(this, MachineRepresentation::kTagged);
2316 2229 Variable var_type(this, MachineRepresentation::kWord32);
2317 Variable var_array(&assembler, MachineRepresentation::kTagged); 2230
2318 Variable var_map(&assembler, MachineRepresentation::kTagged); 2231 Label if_isnotobject(this, Label::kDeferred);
2319 Variable var_type(&assembler, MachineRepresentation::kWord32); 2232 Label create_array_iterator(this);
2320 2233
2321 Label if_isnotobject(&assembler, Label::kDeferred); 2234 GotoIf(TaggedIsSmi(receiver), &if_isnotobject);
2322 Label create_array_iterator(&assembler); 2235 var_array.Bind(receiver);
2323 2236 var_map.Bind(LoadMap(receiver));
2324 assembler.GotoIf(assembler.TaggedIsSmi(receiver), &if_isnotobject); 2237 var_type.Bind(LoadMapInstanceType(var_map.value()));
2325 var_array.Bind(receiver); 2238 Branch(IsJSReceiverInstanceType(var_type.value()), &create_array_iterator,
2326 var_map.Bind(assembler.LoadMap(receiver)); 2239 &if_isnotobject);
2327 var_type.Bind(assembler.LoadMapInstanceType(var_map.value())); 2240
2328 assembler.Branch(assembler.IsJSReceiverInstanceType(var_type.value()), 2241 Bind(&if_isnotobject);
2329 &create_array_iterator, &if_isnotobject); 2242 {
2330 2243 Callable callable = CodeFactory::ToObject(isolate());
2331 assembler.Bind(&if_isnotobject); 2244 Node* result = CallStub(callable, context, receiver);
2332 { 2245 var_array.Bind(result);
2333 Callable callable = CodeFactory::ToObject(assembler.isolate()); 2246 var_map.Bind(LoadMap(result));
2334 Node* result = assembler.CallStub(callable, context, receiver); 2247 var_type.Bind(LoadMapInstanceType(var_map.value()));
2335 var_array.Bind(result); 2248 Goto(&create_array_iterator);
2336 var_map.Bind(assembler.LoadMap(result)); 2249 }
2337 var_type.Bind(assembler.LoadMapInstanceType(var_map.value())); 2250
2338 assembler.Goto(&create_array_iterator); 2251 Bind(&create_array_iterator);
2339 } 2252 Return(CreateArrayIterator(var_array.value(), var_map.value(),
2340 2253 var_type.value(), context, iteration_kind));
2341 assembler.Bind(&create_array_iterator); 2254 }
2342 assembler.Return( 2255 };
2343 assembler.CreateArrayIterator(var_array.value(), var_map.value(), 2256
2344 var_type.value(), context, kIterationKind)); 2257 TF_BUILTIN(ArrayPrototypeValues, ArrayPrototypeIterationAssembler) {
2345 } 2258 Generate_ArrayPrototypeIterationMethod(IterationKind::kValues);
2346 2259 }
2347 } // namespace 2260
2348 2261 TF_BUILTIN(ArrayPrototypeEntries, ArrayPrototypeIterationAssembler) {
2349 void Builtins::Generate_ArrayPrototypeValues( 2262 Generate_ArrayPrototypeIterationMethod(IterationKind::kEntries);
2350 compiler::CodeAssemblerState* state) { 2263 }
2351 Generate_ArrayPrototypeIterationMethod<IterationKind::kValues>(state); 2264
2352 } 2265 TF_BUILTIN(ArrayPrototypeKeys, ArrayPrototypeIterationAssembler) {
2353 2266 Generate_ArrayPrototypeIterationMethod(IterationKind::kKeys);
2354 void Builtins::Generate_ArrayPrototypeEntries( 2267 }
2355 compiler::CodeAssemblerState* state) { 2268
2356 Generate_ArrayPrototypeIterationMethod<IterationKind::kEntries>(state); 2269 TF_BUILTIN(ArrayIteratorPrototypeNext, CodeStubAssembler) {
2357 } 2270 Handle<String> operation = factory()->NewStringFromAsciiChecked(
2358
2359 void Builtins::Generate_ArrayPrototypeKeys(
2360 compiler::CodeAssemblerState* state) {
2361 Generate_ArrayPrototypeIterationMethod<IterationKind::kKeys>(state);
2362 }
2363
2364 void Builtins::Generate_ArrayIteratorPrototypeNext(
2365 compiler::CodeAssemblerState* state) {
2366 typedef compiler::Node Node;
2367 typedef CodeStubAssembler::Label Label;
2368 typedef CodeStubAssembler::Variable Variable;
2369 CodeStubAssembler assembler(state);
2370
2371 Handle<String> operation = assembler.factory()->NewStringFromAsciiChecked(
2372 "Array Iterator.prototype.next", TENURED); 2271 "Array Iterator.prototype.next", TENURED);
2373 2272
2374 Node* iterator = assembler.Parameter(0); 2273 Node* iterator = Parameter(0);
2375 Node* context = assembler.Parameter(3); 2274 Node* context = Parameter(3);
2376 2275
2377 Variable var_value(&assembler, MachineRepresentation::kTagged); 2276 Variable var_value(this, MachineRepresentation::kTagged);
2378 Variable var_done(&assembler, MachineRepresentation::kTagged); 2277 Variable var_done(this, MachineRepresentation::kTagged);
2379 2278
2380 // Required, or else `throw_bad_receiver` fails a DCHECK due to these 2279 // Required, or else `throw_bad_receiver` fails a DCHECK due to these
2381 // variables not being bound along all paths, despite not being used. 2280 // variables not being bound along all paths, despite not being used.
2382 var_done.Bind(assembler.TrueConstant()); 2281 var_done.Bind(TrueConstant());
2383 var_value.Bind(assembler.UndefinedConstant()); 2282 var_value.Bind(UndefinedConstant());
2384 2283
2385 Label throw_bad_receiver(&assembler, Label::kDeferred); 2284 Label throw_bad_receiver(this, Label::kDeferred);
2386 Label set_done(&assembler); 2285 Label set_done(this);
2387 Label allocate_key_result(&assembler); 2286 Label allocate_key_result(this);
2388 Label allocate_entry_if_needed(&assembler); 2287 Label allocate_entry_if_needed(this);
2389 Label allocate_iterator_result(&assembler); 2288 Label allocate_iterator_result(this);
2390 Label generic_values(&assembler); 2289 Label generic_values(this);
2391 2290
2392 // If O does not have all of the internal slots of an Array Iterator Instance 2291 // If O does not have all of the internal slots of an Array Iterator Instance
2393 // (22.1.5.3), throw a TypeError exception 2292 // (22.1.5.3), throw a TypeError exception
2394 assembler.GotoIf(assembler.TaggedIsSmi(iterator), &throw_bad_receiver); 2293 GotoIf(TaggedIsSmi(iterator), &throw_bad_receiver);
2395 Node* instance_type = assembler.LoadInstanceType(iterator); 2294 Node* instance_type = LoadInstanceType(iterator);
2396 assembler.GotoIf( 2295 GotoIf(
2397 assembler.Uint32LessThan( 2296 Uint32LessThan(
2398 assembler.Int32Constant(LAST_ARRAY_ITERATOR_TYPE - 2297 Int32Constant(LAST_ARRAY_ITERATOR_TYPE - FIRST_ARRAY_ITERATOR_TYPE),
2399 FIRST_ARRAY_ITERATOR_TYPE), 2298 Int32Sub(instance_type, Int32Constant(FIRST_ARRAY_ITERATOR_TYPE))),
2400 assembler.Int32Sub(instance_type, assembler.Int32Constant(
2401 FIRST_ARRAY_ITERATOR_TYPE))),
2402 &throw_bad_receiver); 2299 &throw_bad_receiver);
2403 2300
2404 // Let a be O.[[IteratedObject]]. 2301 // Let a be O.[[IteratedObject]].
2405 Node* array = assembler.LoadObjectField( 2302 Node* array =
2406 iterator, JSArrayIterator::kIteratedObjectOffset); 2303 LoadObjectField(iterator, JSArrayIterator::kIteratedObjectOffset);
2407 2304
2408 // Let index be O.[[ArrayIteratorNextIndex]]. 2305 // Let index be O.[[ArrayIteratorNextIndex]].
2409 Node* index = 2306 Node* index = LoadObjectField(iterator, JSArrayIterator::kNextIndexOffset);
2410 assembler.LoadObjectField(iterator, JSArrayIterator::kNextIndexOffset); 2307 Node* orig_map =
2411 Node* orig_map = assembler.LoadObjectField( 2308 LoadObjectField(iterator, JSArrayIterator::kIteratedObjectMapOffset);
2412 iterator, JSArrayIterator::kIteratedObjectMapOffset); 2309 Node* array_map = LoadMap(array);
2413 Node* array_map = assembler.LoadMap(array); 2310
2414 2311 Label if_isfastarray(this), if_isnotfastarray(this),
2415 Label if_isfastarray(&assembler), if_isnotfastarray(&assembler), 2312 if_isdetached(this, Label::kDeferred);
2416 if_isdetached(&assembler, Label::kDeferred); 2313
2417 2314 Branch(WordEqual(orig_map, array_map), &if_isfastarray, &if_isnotfastarray);
2418 assembler.Branch(assembler.WordEqual(orig_map, array_map), &if_isfastarray, 2315
2419 &if_isnotfastarray); 2316 Bind(&if_isfastarray);
2420 2317 {
2421 assembler.Bind(&if_isfastarray); 2318 CSA_ASSERT(this, Word32Equal(LoadMapInstanceType(array_map),
2422 { 2319 Int32Constant(JS_ARRAY_TYPE)));
2423 CSA_ASSERT(&assembler, 2320
2424 assembler.Word32Equal(assembler.LoadMapInstanceType(array_map), 2321 Node* length = LoadObjectField(array, JSArray::kLengthOffset);
2425 assembler.Int32Constant(JS_ARRAY_TYPE))); 2322
2426 2323 CSA_ASSERT(this, TaggedIsSmi(length));
2427 Node* length = assembler.LoadObjectField(array, JSArray::kLengthOffset); 2324 CSA_ASSERT(this, TaggedIsSmi(index));
2428 2325
2429 CSA_ASSERT(&assembler, assembler.TaggedIsSmi(length)); 2326 GotoIfNot(SmiBelow(index, length), &set_done);
2430 CSA_ASSERT(&assembler, assembler.TaggedIsSmi(index)); 2327
2431 2328 Node* one = SmiConstant(Smi::FromInt(1));
2432 assembler.GotoIfNot(assembler.SmiBelow(index, length), &set_done); 2329 StoreObjectFieldNoWriteBarrier(iterator, JSArrayIterator::kNextIndexOffset,
2433 2330 SmiAdd(index, one));
2434 Node* one = assembler.SmiConstant(Smi::FromInt(1)); 2331
2435 assembler.StoreObjectFieldNoWriteBarrier(iterator, 2332 var_done.Bind(FalseConstant());
2436 JSArrayIterator::kNextIndexOffset, 2333 Node* elements = LoadElements(array);
2437 assembler.SmiAdd(index, one));
2438
2439 var_done.Bind(assembler.FalseConstant());
2440 Node* elements = assembler.LoadElements(array);
2441 2334
2442 static int32_t kInstanceType[] = { 2335 static int32_t kInstanceType[] = {
2443 JS_FAST_ARRAY_KEY_ITERATOR_TYPE, 2336 JS_FAST_ARRAY_KEY_ITERATOR_TYPE,
2444 JS_FAST_SMI_ARRAY_KEY_VALUE_ITERATOR_TYPE, 2337 JS_FAST_SMI_ARRAY_KEY_VALUE_ITERATOR_TYPE,
2445 JS_FAST_HOLEY_SMI_ARRAY_KEY_VALUE_ITERATOR_TYPE, 2338 JS_FAST_HOLEY_SMI_ARRAY_KEY_VALUE_ITERATOR_TYPE,
2446 JS_FAST_ARRAY_KEY_VALUE_ITERATOR_TYPE, 2339 JS_FAST_ARRAY_KEY_VALUE_ITERATOR_TYPE,
2447 JS_FAST_HOLEY_ARRAY_KEY_VALUE_ITERATOR_TYPE, 2340 JS_FAST_HOLEY_ARRAY_KEY_VALUE_ITERATOR_TYPE,
2448 JS_FAST_DOUBLE_ARRAY_KEY_VALUE_ITERATOR_TYPE, 2341 JS_FAST_DOUBLE_ARRAY_KEY_VALUE_ITERATOR_TYPE,
2449 JS_FAST_HOLEY_DOUBLE_ARRAY_KEY_VALUE_ITERATOR_TYPE, 2342 JS_FAST_HOLEY_DOUBLE_ARRAY_KEY_VALUE_ITERATOR_TYPE,
2450 JS_FAST_SMI_ARRAY_VALUE_ITERATOR_TYPE, 2343 JS_FAST_SMI_ARRAY_VALUE_ITERATOR_TYPE,
2451 JS_FAST_HOLEY_SMI_ARRAY_VALUE_ITERATOR_TYPE, 2344 JS_FAST_HOLEY_SMI_ARRAY_VALUE_ITERATOR_TYPE,
2452 JS_FAST_ARRAY_VALUE_ITERATOR_TYPE, 2345 JS_FAST_ARRAY_VALUE_ITERATOR_TYPE,
2453 JS_FAST_HOLEY_ARRAY_VALUE_ITERATOR_TYPE, 2346 JS_FAST_HOLEY_ARRAY_VALUE_ITERATOR_TYPE,
2454 JS_FAST_DOUBLE_ARRAY_VALUE_ITERATOR_TYPE, 2347 JS_FAST_DOUBLE_ARRAY_VALUE_ITERATOR_TYPE,
2455 JS_FAST_HOLEY_DOUBLE_ARRAY_VALUE_ITERATOR_TYPE, 2348 JS_FAST_HOLEY_DOUBLE_ARRAY_VALUE_ITERATOR_TYPE,
2456 }; 2349 };
2457 2350
2458 Label packed_object_values(&assembler), holey_object_values(&assembler), 2351 Label packed_object_values(this), holey_object_values(this),
2459 packed_double_values(&assembler), holey_double_values(&assembler); 2352 packed_double_values(this), holey_double_values(this);
2460 Label* kInstanceTypeHandlers[] = { 2353 Label* kInstanceTypeHandlers[] = {
2461 &allocate_key_result, &packed_object_values, &holey_object_values, 2354 &allocate_key_result, &packed_object_values, &holey_object_values,
2462 &packed_object_values, &holey_object_values, &packed_double_values, 2355 &packed_object_values, &holey_object_values, &packed_double_values,
2463 &holey_double_values, &packed_object_values, &holey_object_values, 2356 &holey_double_values, &packed_object_values, &holey_object_values,
2464 &packed_object_values, &holey_object_values, &packed_double_values, 2357 &packed_object_values, &holey_object_values, &packed_double_values,
2465 &holey_double_values}; 2358 &holey_double_values};
2466 2359
2467 assembler.Switch(instance_type, &throw_bad_receiver, kInstanceType, 2360 Switch(instance_type, &throw_bad_receiver, kInstanceType,
2468 kInstanceTypeHandlers, arraysize(kInstanceType)); 2361 kInstanceTypeHandlers, arraysize(kInstanceType));
2469 2362
2470 assembler.Bind(&packed_object_values); 2363 Bind(&packed_object_values);
2471 { 2364 {
2472 var_value.Bind(assembler.LoadFixedArrayElement( 2365 var_value.Bind(LoadFixedArrayElement(elements, index, 0, SMI_PARAMETERS));
2473 elements, index, 0, CodeStubAssembler::SMI_PARAMETERS)); 2366 Goto(&allocate_entry_if_needed);
2474 assembler.Goto(&allocate_entry_if_needed);
2475 } 2367 }
2476 2368
2477 assembler.Bind(&packed_double_values); 2369 Bind(&packed_double_values);
2478 { 2370 {
2479 Node* value = assembler.LoadFixedDoubleArrayElement( 2371 Node* value = LoadFixedDoubleArrayElement(
2480 elements, index, MachineType::Float64(), 0, 2372 elements, index, MachineType::Float64(), 0, SMI_PARAMETERS);
2481 CodeStubAssembler::SMI_PARAMETERS); 2373 var_value.Bind(AllocateHeapNumberWithValue(value));
2482 var_value.Bind(assembler.AllocateHeapNumberWithValue(value)); 2374 Goto(&allocate_entry_if_needed);
2483 assembler.Goto(&allocate_entry_if_needed);
2484 } 2375 }
2485 2376
2486 assembler.Bind(&holey_object_values); 2377 Bind(&holey_object_values);
2487 { 2378 {
2488 // Check the array_protector cell, and take the slow path if it's invalid. 2379 // Check the array_protector cell, and take the slow path if it's invalid.
2489 Node* invalid = 2380 Node* invalid = SmiConstant(Smi::FromInt(Isolate::kProtectorInvalid));
2490 assembler.SmiConstant(Smi::FromInt(Isolate::kProtectorInvalid)); 2381 Node* cell = LoadRoot(Heap::kArrayProtectorRootIndex);
2491 Node* cell = assembler.LoadRoot(Heap::kArrayProtectorRootIndex); 2382 Node* cell_value = LoadObjectField(cell, PropertyCell::kValueOffset);
2492 Node* cell_value = 2383 GotoIf(WordEqual(cell_value, invalid), &generic_values);
2493 assembler.LoadObjectField(cell, PropertyCell::kValueOffset);
2494 assembler.GotoIf(assembler.WordEqual(cell_value, invalid),
2495 &generic_values);
2496 2384
2497 var_value.Bind(assembler.UndefinedConstant()); 2385 var_value.Bind(UndefinedConstant());
2498 Node* value = assembler.LoadFixedArrayElement( 2386 Node* value = LoadFixedArrayElement(elements, index, 0, SMI_PARAMETERS);
2499 elements, index, 0, CodeStubAssembler::SMI_PARAMETERS); 2387 GotoIf(WordEqual(value, TheHoleConstant()), &allocate_entry_if_needed);
2500 assembler.GotoIf(assembler.WordEqual(value, assembler.TheHoleConstant()),
2501 &allocate_entry_if_needed);
2502 var_value.Bind(value); 2388 var_value.Bind(value);
2503 assembler.Goto(&allocate_entry_if_needed); 2389 Goto(&allocate_entry_if_needed);
2504 } 2390 }
2505 2391
2506 assembler.Bind(&holey_double_values); 2392 Bind(&holey_double_values);
2507 { 2393 {
2508 // Check the array_protector cell, and take the slow path if it's invalid. 2394 // Check the array_protector cell, and take the slow path if it's invalid.
2509 Node* invalid = 2395 Node* invalid = SmiConstant(Smi::FromInt(Isolate::kProtectorInvalid));
2510 assembler.SmiConstant(Smi::FromInt(Isolate::kProtectorInvalid)); 2396 Node* cell = LoadRoot(Heap::kArrayProtectorRootIndex);
2511 Node* cell = assembler.LoadRoot(Heap::kArrayProtectorRootIndex); 2397 Node* cell_value = LoadObjectField(cell, PropertyCell::kValueOffset);
2512 Node* cell_value = 2398 GotoIf(WordEqual(cell_value, invalid), &generic_values);
2513 assembler.LoadObjectField(cell, PropertyCell::kValueOffset);
2514 assembler.GotoIf(assembler.WordEqual(cell_value, invalid),
2515 &generic_values);
2516 2399
2517 var_value.Bind(assembler.UndefinedConstant()); 2400 var_value.Bind(UndefinedConstant());
2518 Node* value = assembler.LoadFixedDoubleArrayElement( 2401 Node* value = LoadFixedDoubleArrayElement(
2519 elements, index, MachineType::Float64(), 0, 2402 elements, index, MachineType::Float64(), 0, SMI_PARAMETERS,
2520 CodeStubAssembler::SMI_PARAMETERS, &allocate_entry_if_needed); 2403 &allocate_entry_if_needed);
2521 var_value.Bind(assembler.AllocateHeapNumberWithValue(value)); 2404 var_value.Bind(AllocateHeapNumberWithValue(value));
2522 assembler.Goto(&allocate_entry_if_needed); 2405 Goto(&allocate_entry_if_needed);
2523 } 2406 }
2524 } 2407 }
2525 2408
2526 assembler.Bind(&if_isnotfastarray); 2409 Bind(&if_isnotfastarray);
2527 { 2410 {
2528 Label if_istypedarray(&assembler), if_isgeneric(&assembler); 2411 Label if_istypedarray(this), if_isgeneric(this);
2529 2412
2530 // If a is undefined, return CreateIterResultObject(undefined, true) 2413 // If a is undefined, return CreateIterResultObject(undefined, true)
2531 assembler.GotoIf(assembler.WordEqual(array, assembler.UndefinedConstant()), 2414 GotoIf(WordEqual(array, UndefinedConstant()), &allocate_iterator_result);
2532 &allocate_iterator_result);
2533 2415
2534 Node* array_type = assembler.LoadInstanceType(array); 2416 Node* array_type = LoadInstanceType(array);
2535 assembler.Branch( 2417 Branch(Word32Equal(array_type, Int32Constant(JS_TYPED_ARRAY_TYPE)),
2536 assembler.Word32Equal(array_type, 2418 &if_istypedarray, &if_isgeneric);
2537 assembler.Int32Constant(JS_TYPED_ARRAY_TYPE)),
2538 &if_istypedarray, &if_isgeneric);
2539 2419
2540 assembler.Bind(&if_isgeneric); 2420 Bind(&if_isgeneric);
2541 { 2421 {
2542 Label if_wasfastarray(&assembler); 2422 Label if_wasfastarray(this);
2543 2423
2544 Node* length = nullptr; 2424 Node* length = nullptr;
2545 { 2425 {
2546 Variable var_length(&assembler, MachineRepresentation::kTagged); 2426 Variable var_length(this, MachineRepresentation::kTagged);
2547 Label if_isarray(&assembler), if_isnotarray(&assembler), 2427 Label if_isarray(this), if_isnotarray(this), done(this);
2548 done(&assembler); 2428 Branch(Word32Equal(array_type, Int32Constant(JS_ARRAY_TYPE)),
2549 assembler.Branch( 2429 &if_isarray, &if_isnotarray);
2550 assembler.Word32Equal(array_type,
2551 assembler.Int32Constant(JS_ARRAY_TYPE)),
2552 &if_isarray, &if_isnotarray);
2553 2430
2554 assembler.Bind(&if_isarray); 2431 Bind(&if_isarray);
2555 { 2432 {
2556 var_length.Bind( 2433 var_length.Bind(LoadObjectField(array, JSArray::kLengthOffset));
2557 assembler.LoadObjectField(array, JSArray::kLengthOffset));
2558 2434
2559 // Invalidate protector cell if needed 2435 // Invalidate protector cell if needed
2560 assembler.Branch( 2436 Branch(WordNotEqual(orig_map, UndefinedConstant()), &if_wasfastarray,
2561 assembler.WordNotEqual(orig_map, assembler.UndefinedConstant()), 2437 &done);
2562 &if_wasfastarray, &done);
2563 2438
2564 assembler.Bind(&if_wasfastarray); 2439 Bind(&if_wasfastarray);
2565 { 2440 {
2566 Label if_invalid(&assembler, Label::kDeferred); 2441 Label if_invalid(this, Label::kDeferred);
2567 // A fast array iterator transitioned to a slow iterator during 2442 // A fast array iterator transitioned to a slow iterator during
2568 // iteration. Invalidate fast_array_iteration_prtoector cell to 2443 // iteration. Invalidate fast_array_iteration_prtoector cell to
2569 // prevent potential deopt loops. 2444 // prevent potential deopt loops.
2570 assembler.StoreObjectFieldNoWriteBarrier( 2445 StoreObjectFieldNoWriteBarrier(
2571 iterator, JSArrayIterator::kIteratedObjectMapOffset, 2446 iterator, JSArrayIterator::kIteratedObjectMapOffset,
2572 assembler.UndefinedConstant()); 2447 UndefinedConstant());
2573 assembler.GotoIf( 2448 GotoIf(Uint32LessThanOrEqual(
2574 assembler.Uint32LessThanOrEqual( 2449 instance_type,
2575 instance_type, assembler.Int32Constant( 2450 Int32Constant(JS_GENERIC_ARRAY_KEY_ITERATOR_TYPE)),
2576 JS_GENERIC_ARRAY_KEY_ITERATOR_TYPE)), 2451 &done);
2577 &done);
2578 2452
2579 Node* invalid = 2453 Node* invalid =
2580 assembler.SmiConstant(Smi::FromInt(Isolate::kProtectorInvalid)); 2454 SmiConstant(Smi::FromInt(Isolate::kProtectorInvalid));
2581 Node* cell = 2455 Node* cell = LoadRoot(Heap::kFastArrayIterationProtectorRootIndex);
2582 assembler.LoadRoot(Heap::kFastArrayIterationProtectorRootIndex); 2456 StoreObjectFieldNoWriteBarrier(cell, Cell::kValueOffset, invalid);
2583 assembler.StoreObjectFieldNoWriteBarrier(cell, Cell::kValueOffset, 2457 Goto(&done);
2584 invalid);
2585 assembler.Goto(&done);
2586 } 2458 }
2587 } 2459 }
2588 2460
2589 assembler.Bind(&if_isnotarray); 2461 Bind(&if_isnotarray);
2590 { 2462 {
2591 Node* length_string = assembler.HeapConstant( 2463 Node* length_string = HeapConstant(factory()->length_string());
2592 assembler.isolate()->factory()->length_string()); 2464 Callable get_property = CodeFactory::GetProperty(isolate());
2593 Callable get_property = CodeFactory::GetProperty(assembler.isolate()); 2465 Node* length = CallStub(get_property, context, array, length_string);
2594 Node* length = 2466 Callable to_length = CodeFactory::ToLength(isolate());
2595 assembler.CallStub(get_property, context, array, length_string); 2467 var_length.Bind(CallStub(to_length, context, length));
2596 Callable to_length = CodeFactory::ToLength(assembler.isolate()); 2468 Goto(&done);
2597 var_length.Bind(assembler.CallStub(to_length, context, length));
2598 assembler.Goto(&done);
2599 } 2469 }
2600 2470
2601 assembler.Bind(&done); 2471 Bind(&done);
2602 length = var_length.value(); 2472 length = var_length.value();
2603 } 2473 }
2604 2474
2605 assembler.GotoUnlessNumberLessThan(index, length, &set_done); 2475 GotoUnlessNumberLessThan(index, length, &set_done);
2606 2476
2607 assembler.StoreObjectField(iterator, JSArrayIterator::kNextIndexOffset, 2477 StoreObjectField(iterator, JSArrayIterator::kNextIndexOffset,
2608 assembler.NumberInc(index)); 2478 NumberInc(index));
2609 var_done.Bind(assembler.FalseConstant()); 2479 var_done.Bind(FalseConstant());
2610 2480
2611 assembler.Branch( 2481 Branch(
2612 assembler.Uint32LessThanOrEqual( 2482 Uint32LessThanOrEqual(
2613 instance_type, 2483 instance_type, Int32Constant(JS_GENERIC_ARRAY_KEY_ITERATOR_TYPE)),
2614 assembler.Int32Constant(JS_GENERIC_ARRAY_KEY_ITERATOR_TYPE)),
2615 &allocate_key_result, &generic_values); 2484 &allocate_key_result, &generic_values);
2616 2485
2617 assembler.Bind(&generic_values); 2486 Bind(&generic_values);
2618 { 2487 {
2619 Callable get_property = CodeFactory::GetProperty(assembler.isolate()); 2488 Callable get_property = CodeFactory::GetProperty(isolate());
2620 var_value.Bind(assembler.CallStub(get_property, context, array, index)); 2489 var_value.Bind(CallStub(get_property, context, array, index));
2621 assembler.Goto(&allocate_entry_if_needed); 2490 Goto(&allocate_entry_if_needed);
2622 } 2491 }
2623 } 2492 }
2624 2493
2625 assembler.Bind(&if_istypedarray); 2494 Bind(&if_istypedarray);
2626 { 2495 {
2627 Node* buffer = 2496 Node* buffer = LoadObjectField(array, JSTypedArray::kBufferOffset);
2628 assembler.LoadObjectField(array, JSTypedArray::kBufferOffset); 2497 GotoIf(IsDetachedBuffer(buffer), &if_isdetached);
2629 assembler.GotoIf(assembler.IsDetachedBuffer(buffer), &if_isdetached);
2630 2498
2631 Node* length = 2499 Node* length = LoadObjectField(array, JSTypedArray::kLengthOffset);
2632 assembler.LoadObjectField(array, JSTypedArray::kLengthOffset);
2633 2500
2634 CSA_ASSERT(&assembler, assembler.TaggedIsSmi(length)); 2501 CSA_ASSERT(this, TaggedIsSmi(length));
2635 CSA_ASSERT(&assembler, assembler.TaggedIsSmi(index)); 2502 CSA_ASSERT(this, TaggedIsSmi(index));
2636 2503
2637 assembler.GotoIfNot(assembler.SmiBelow(index, length), &set_done); 2504 GotoIfNot(SmiBelow(index, length), &set_done);
2638 2505
2639 Node* one = assembler.SmiConstant(1); 2506 Node* one = SmiConstant(1);
2640 assembler.StoreObjectFieldNoWriteBarrier( 2507 StoreObjectFieldNoWriteBarrier(
2641 iterator, JSArrayIterator::kNextIndexOffset, 2508 iterator, JSArrayIterator::kNextIndexOffset, SmiAdd(index, one));
2642 assembler.SmiAdd(index, one)); 2509 var_done.Bind(FalseConstant());
2643 var_done.Bind(assembler.FalseConstant());
2644 2510
2645 Node* elements = assembler.LoadElements(array); 2511 Node* elements = LoadElements(array);
2646 Node* base_ptr = assembler.LoadObjectField( 2512 Node* base_ptr =
2647 elements, FixedTypedArrayBase::kBasePointerOffset); 2513 LoadObjectField(elements, FixedTypedArrayBase::kBasePointerOffset);
2648 Node* external_ptr = assembler.LoadObjectField( 2514 Node* external_ptr =
2649 elements, FixedTypedArrayBase::kExternalPointerOffset, 2515 LoadObjectField(elements, FixedTypedArrayBase::kExternalPointerOffset,
2650 MachineType::Pointer()); 2516 MachineType::Pointer());
2651 Node* data_ptr = assembler.IntPtrAdd( 2517 Node* data_ptr = IntPtrAdd(BitcastTaggedToWord(base_ptr), external_ptr);
2652 assembler.BitcastTaggedToWord(base_ptr), external_ptr);
2653 2518
2654 static int32_t kInstanceType[] = { 2519 static int32_t kInstanceType[] = {
2655 JS_TYPED_ARRAY_KEY_ITERATOR_TYPE, 2520 JS_TYPED_ARRAY_KEY_ITERATOR_TYPE,
2656 JS_UINT8_ARRAY_KEY_VALUE_ITERATOR_TYPE, 2521 JS_UINT8_ARRAY_KEY_VALUE_ITERATOR_TYPE,
2657 JS_UINT8_CLAMPED_ARRAY_KEY_VALUE_ITERATOR_TYPE, 2522 JS_UINT8_CLAMPED_ARRAY_KEY_VALUE_ITERATOR_TYPE,
2658 JS_INT8_ARRAY_KEY_VALUE_ITERATOR_TYPE, 2523 JS_INT8_ARRAY_KEY_VALUE_ITERATOR_TYPE,
2659 JS_UINT16_ARRAY_KEY_VALUE_ITERATOR_TYPE, 2524 JS_UINT16_ARRAY_KEY_VALUE_ITERATOR_TYPE,
2660 JS_INT16_ARRAY_KEY_VALUE_ITERATOR_TYPE, 2525 JS_INT16_ARRAY_KEY_VALUE_ITERATOR_TYPE,
2661 JS_UINT32_ARRAY_KEY_VALUE_ITERATOR_TYPE, 2526 JS_UINT32_ARRAY_KEY_VALUE_ITERATOR_TYPE,
2662 JS_INT32_ARRAY_KEY_VALUE_ITERATOR_TYPE, 2527 JS_INT32_ARRAY_KEY_VALUE_ITERATOR_TYPE,
2663 JS_FLOAT32_ARRAY_KEY_VALUE_ITERATOR_TYPE, 2528 JS_FLOAT32_ARRAY_KEY_VALUE_ITERATOR_TYPE,
2664 JS_FLOAT64_ARRAY_KEY_VALUE_ITERATOR_TYPE, 2529 JS_FLOAT64_ARRAY_KEY_VALUE_ITERATOR_TYPE,
2665 JS_UINT8_ARRAY_VALUE_ITERATOR_TYPE, 2530 JS_UINT8_ARRAY_VALUE_ITERATOR_TYPE,
2666 JS_UINT8_CLAMPED_ARRAY_VALUE_ITERATOR_TYPE, 2531 JS_UINT8_CLAMPED_ARRAY_VALUE_ITERATOR_TYPE,
2667 JS_INT8_ARRAY_VALUE_ITERATOR_TYPE, 2532 JS_INT8_ARRAY_VALUE_ITERATOR_TYPE,
2668 JS_UINT16_ARRAY_VALUE_ITERATOR_TYPE, 2533 JS_UINT16_ARRAY_VALUE_ITERATOR_TYPE,
2669 JS_INT16_ARRAY_VALUE_ITERATOR_TYPE, 2534 JS_INT16_ARRAY_VALUE_ITERATOR_TYPE,
2670 JS_UINT32_ARRAY_VALUE_ITERATOR_TYPE, 2535 JS_UINT32_ARRAY_VALUE_ITERATOR_TYPE,
2671 JS_INT32_ARRAY_VALUE_ITERATOR_TYPE, 2536 JS_INT32_ARRAY_VALUE_ITERATOR_TYPE,
2672 JS_FLOAT32_ARRAY_VALUE_ITERATOR_TYPE, 2537 JS_FLOAT32_ARRAY_VALUE_ITERATOR_TYPE,
2673 JS_FLOAT64_ARRAY_VALUE_ITERATOR_TYPE, 2538 JS_FLOAT64_ARRAY_VALUE_ITERATOR_TYPE,
2674 }; 2539 };
2675 2540
2676 Label uint8_values(&assembler), int8_values(&assembler), 2541 Label uint8_values(this), int8_values(this), uint16_values(this),
2677 uint16_values(&assembler), int16_values(&assembler), 2542 int16_values(this), uint32_values(this), int32_values(this),
2678 uint32_values(&assembler), int32_values(&assembler), 2543 float32_values(this), float64_values(this);
2679 float32_values(&assembler), float64_values(&assembler);
2680 Label* kInstanceTypeHandlers[] = { 2544 Label* kInstanceTypeHandlers[] = {
2681 &allocate_key_result, &uint8_values, &uint8_values, 2545 &allocate_key_result, &uint8_values, &uint8_values,
2682 &int8_values, &uint16_values, &int16_values, 2546 &int8_values, &uint16_values, &int16_values,
2683 &uint32_values, &int32_values, &float32_values, 2547 &uint32_values, &int32_values, &float32_values,
2684 &float64_values, &uint8_values, &uint8_values, 2548 &float64_values, &uint8_values, &uint8_values,
2685 &int8_values, &uint16_values, &int16_values, 2549 &int8_values, &uint16_values, &int16_values,
2686 &uint32_values, &int32_values, &float32_values, 2550 &uint32_values, &int32_values, &float32_values,
2687 &float64_values, 2551 &float64_values,
2688 }; 2552 };
2689 2553
2690 var_done.Bind(assembler.FalseConstant()); 2554 var_done.Bind(FalseConstant());
2691 assembler.Switch(instance_type, &throw_bad_receiver, kInstanceType, 2555 Switch(instance_type, &throw_bad_receiver, kInstanceType,
2692 kInstanceTypeHandlers, arraysize(kInstanceType)); 2556 kInstanceTypeHandlers, arraysize(kInstanceType));
2693 2557
2694 assembler.Bind(&uint8_values); 2558 Bind(&uint8_values);
2695 { 2559 {
2696 Node* value_uint8 = assembler.LoadFixedTypedArrayElement( 2560 Node* value_uint8 = LoadFixedTypedArrayElement(
2697 data_ptr, index, UINT8_ELEMENTS, CodeStubAssembler::SMI_PARAMETERS); 2561 data_ptr, index, UINT8_ELEMENTS, SMI_PARAMETERS);
2698 var_value.Bind(assembler.SmiFromWord32(value_uint8)); 2562 var_value.Bind(SmiFromWord32(value_uint8));
2699 assembler.Goto(&allocate_entry_if_needed); 2563 Goto(&allocate_entry_if_needed);
2700 } 2564 }
2701 2565 Bind(&int8_values);
2702 assembler.Bind(&int8_values);
2703 { 2566 {
2704 Node* value_int8 = assembler.LoadFixedTypedArrayElement( 2567 Node* value_int8 = LoadFixedTypedArrayElement(
2705 data_ptr, index, INT8_ELEMENTS, CodeStubAssembler::SMI_PARAMETERS); 2568 data_ptr, index, INT8_ELEMENTS, SMI_PARAMETERS);
2706 var_value.Bind(assembler.SmiFromWord32(value_int8)); 2569 var_value.Bind(SmiFromWord32(value_int8));
2707 assembler.Goto(&allocate_entry_if_needed); 2570 Goto(&allocate_entry_if_needed);
2708 } 2571 }
2709 2572 Bind(&uint16_values);
2710 assembler.Bind(&uint16_values);
2711 { 2573 {
2712 Node* value_uint16 = assembler.LoadFixedTypedArrayElement( 2574 Node* value_uint16 = LoadFixedTypedArrayElement(
2713 data_ptr, index, UINT16_ELEMENTS, 2575 data_ptr, index, UINT16_ELEMENTS, SMI_PARAMETERS);
2714 CodeStubAssembler::SMI_PARAMETERS); 2576 var_value.Bind(SmiFromWord32(value_uint16));
2715 var_value.Bind(assembler.SmiFromWord32(value_uint16)); 2577 Goto(&allocate_entry_if_needed);
2716 assembler.Goto(&allocate_entry_if_needed);
2717 } 2578 }
2718 2579 Bind(&int16_values);
2719 assembler.Bind(&int16_values);
2720 { 2580 {
2721 Node* value_int16 = assembler.LoadFixedTypedArrayElement( 2581 Node* value_int16 = LoadFixedTypedArrayElement(
2722 data_ptr, index, INT16_ELEMENTS, CodeStubAssembler::SMI_PARAMETERS); 2582 data_ptr, index, INT16_ELEMENTS, SMI_PARAMETERS);
2723 var_value.Bind(assembler.SmiFromWord32(value_int16)); 2583 var_value.Bind(SmiFromWord32(value_int16));
2724 assembler.Goto(&allocate_entry_if_needed); 2584 Goto(&allocate_entry_if_needed);
2725 } 2585 }
2726 2586 Bind(&uint32_values);
2727 assembler.Bind(&uint32_values);
2728 { 2587 {
2729 Node* value_uint32 = assembler.LoadFixedTypedArrayElement( 2588 Node* value_uint32 = LoadFixedTypedArrayElement(
2730 data_ptr, index, UINT32_ELEMENTS, 2589 data_ptr, index, UINT32_ELEMENTS, SMI_PARAMETERS);
2731 CodeStubAssembler::SMI_PARAMETERS); 2590 var_value.Bind(ChangeUint32ToTagged(value_uint32));
2732 var_value.Bind(assembler.ChangeUint32ToTagged(value_uint32)); 2591 Goto(&allocate_entry_if_needed);
2733 assembler.Goto(&allocate_entry_if_needed);
2734 } 2592 }
2735 assembler.Bind(&int32_values); 2593 Bind(&int32_values);
2736 { 2594 {
2737 Node* value_int32 = assembler.LoadFixedTypedArrayElement( 2595 Node* value_int32 = LoadFixedTypedArrayElement(
2738 data_ptr, index, INT32_ELEMENTS, CodeStubAssembler::SMI_PARAMETERS); 2596 data_ptr, index, INT32_ELEMENTS, SMI_PARAMETERS);
2739 var_value.Bind(assembler.ChangeInt32ToTagged(value_int32)); 2597 var_value.Bind(ChangeInt32ToTagged(value_int32));
2740 assembler.Goto(&allocate_entry_if_needed); 2598 Goto(&allocate_entry_if_needed);
2741 } 2599 }
2742 assembler.Bind(&float32_values); 2600 Bind(&float32_values);
2743 { 2601 {
2744 Node* value_float32 = assembler.LoadFixedTypedArrayElement( 2602 Node* value_float32 = LoadFixedTypedArrayElement(
2745 data_ptr, index, FLOAT32_ELEMENTS, 2603 data_ptr, index, FLOAT32_ELEMENTS, SMI_PARAMETERS);
2746 CodeStubAssembler::SMI_PARAMETERS); 2604 var_value.Bind(
2747 var_value.Bind(assembler.AllocateHeapNumberWithValue( 2605 AllocateHeapNumberWithValue(ChangeFloat32ToFloat64(value_float32)));
2748 assembler.ChangeFloat32ToFloat64(value_float32))); 2606 Goto(&allocate_entry_if_needed);
2749 assembler.Goto(&allocate_entry_if_needed);
2750 } 2607 }
2751 assembler.Bind(&float64_values); 2608 Bind(&float64_values);
2752 { 2609 {
2753 Node* value_float64 = assembler.LoadFixedTypedArrayElement( 2610 Node* value_float64 = LoadFixedTypedArrayElement(
2754 data_ptr, index, FLOAT64_ELEMENTS, 2611 data_ptr, index, FLOAT64_ELEMENTS, SMI_PARAMETERS);
2755 CodeStubAssembler::SMI_PARAMETERS); 2612 var_value.Bind(AllocateHeapNumberWithValue(value_float64));
2756 var_value.Bind(assembler.AllocateHeapNumberWithValue(value_float64)); 2613 Goto(&allocate_entry_if_needed);
2757 assembler.Goto(&allocate_entry_if_needed);
2758 } 2614 }
2759 } 2615 }
2760 } 2616 }
2761 2617
2762 assembler.Bind(&set_done); 2618 Bind(&set_done);
2763 { 2619 {
2764 assembler.StoreObjectFieldNoWriteBarrier( 2620 StoreObjectFieldNoWriteBarrier(
2765 iterator, JSArrayIterator::kIteratedObjectOffset, 2621 iterator, JSArrayIterator::kIteratedObjectOffset, UndefinedConstant());
2766 assembler.UndefinedConstant()); 2622 Goto(&allocate_iterator_result);
2767 assembler.Goto(&allocate_iterator_result);
2768 } 2623 }
2769 2624
2770 assembler.Bind(&allocate_key_result); 2625 Bind(&allocate_key_result);
2771 { 2626 {
2772 var_value.Bind(index); 2627 var_value.Bind(index);
2773 var_done.Bind(assembler.FalseConstant()); 2628 var_done.Bind(FalseConstant());
2774 assembler.Goto(&allocate_iterator_result); 2629 Goto(&allocate_iterator_result);
2775 } 2630 }
2776 2631
2777 assembler.Bind(&allocate_entry_if_needed); 2632 Bind(&allocate_entry_if_needed);
2778 { 2633 {
2779 assembler.GotoIf( 2634 GotoIf(Int32GreaterThan(instance_type,
2780 assembler.Int32GreaterThan( 2635 Int32Constant(LAST_ARRAY_KEY_VALUE_ITERATOR_TYPE)),
2781 instance_type, 2636 &allocate_iterator_result);
2782 assembler.Int32Constant(LAST_ARRAY_KEY_VALUE_ITERATOR_TYPE)),
2783 &allocate_iterator_result);
2784 2637
2785 Node* elements = assembler.AllocateFixedArray(FAST_ELEMENTS, 2638 Node* elements = AllocateFixedArray(FAST_ELEMENTS, IntPtrConstant(2));
2786 assembler.IntPtrConstant(2)); 2639 StoreFixedArrayElement(elements, 0, index, SKIP_WRITE_BARRIER);
2787 assembler.StoreFixedArrayElement(elements, 0, index, SKIP_WRITE_BARRIER); 2640 StoreFixedArrayElement(elements, 1, var_value.value(), SKIP_WRITE_BARRIER);
2788 assembler.StoreFixedArrayElement(elements, 1, var_value.value(),
2789 SKIP_WRITE_BARRIER);
2790 2641
2791 Node* entry = assembler.Allocate(JSArray::kSize); 2642 Node* entry = Allocate(JSArray::kSize);
2792 Node* map = 2643 Node* map = LoadContextElement(LoadNativeContext(context),
2793 assembler.LoadContextElement(assembler.LoadNativeContext(context), 2644 Context::JS_ARRAY_FAST_ELEMENTS_MAP_INDEX);
2794 Context::JS_ARRAY_FAST_ELEMENTS_MAP_INDEX);
2795 2645
2796 assembler.StoreMapNoWriteBarrier(entry, map); 2646 StoreMapNoWriteBarrier(entry, map);
2797 assembler.StoreObjectFieldRoot(entry, JSArray::kPropertiesOffset, 2647 StoreObjectFieldRoot(entry, JSArray::kPropertiesOffset,
2798 Heap::kEmptyFixedArrayRootIndex); 2648 Heap::kEmptyFixedArrayRootIndex);
2799 assembler.StoreObjectFieldNoWriteBarrier(entry, JSArray::kElementsOffset, 2649 StoreObjectFieldNoWriteBarrier(entry, JSArray::kElementsOffset, elements);
2800 elements); 2650 StoreObjectFieldNoWriteBarrier(entry, JSArray::kLengthOffset,
2801 assembler.StoreObjectFieldNoWriteBarrier( 2651 SmiConstant(Smi::FromInt(2)));
2802 entry, JSArray::kLengthOffset, assembler.SmiConstant(Smi::FromInt(2)));
2803 2652
2804 var_value.Bind(entry); 2653 var_value.Bind(entry);
2805 assembler.Goto(&allocate_iterator_result); 2654 Goto(&allocate_iterator_result);
2806 } 2655 }
2807 2656
2808 assembler.Bind(&allocate_iterator_result); 2657 Bind(&allocate_iterator_result);
2809 { 2658 {
2810 Node* result = assembler.Allocate(JSIteratorResult::kSize); 2659 Node* result = Allocate(JSIteratorResult::kSize);
2811 Node* map = 2660 Node* map = LoadContextElement(LoadNativeContext(context),
2812 assembler.LoadContextElement(assembler.LoadNativeContext(context), 2661 Context::ITERATOR_RESULT_MAP_INDEX);
2813 Context::ITERATOR_RESULT_MAP_INDEX); 2662 StoreMapNoWriteBarrier(result, map);
2814 assembler.StoreMapNoWriteBarrier(result, map); 2663 StoreObjectFieldRoot(result, JSIteratorResult::kPropertiesOffset,
2815 assembler.StoreObjectFieldRoot(result, JSIteratorResult::kPropertiesOffset, 2664 Heap::kEmptyFixedArrayRootIndex);
2816 Heap::kEmptyFixedArrayRootIndex); 2665 StoreObjectFieldRoot(result, JSIteratorResult::kElementsOffset,
2817 assembler.StoreObjectFieldRoot(result, JSIteratorResult::kElementsOffset, 2666 Heap::kEmptyFixedArrayRootIndex);
2818 Heap::kEmptyFixedArrayRootIndex); 2667 StoreObjectFieldNoWriteBarrier(result, JSIteratorResult::kValueOffset,
2819 assembler.StoreObjectFieldNoWriteBarrier( 2668 var_value.value());
2820 result, JSIteratorResult::kValueOffset, var_value.value()); 2669 StoreObjectFieldNoWriteBarrier(result, JSIteratorResult::kDoneOffset,
2821 assembler.StoreObjectFieldNoWriteBarrier( 2670 var_done.value());
2822 result, JSIteratorResult::kDoneOffset, var_done.value()); 2671 Return(result);
2823 assembler.Return(result);
2824 } 2672 }
2825 2673
2826 assembler.Bind(&throw_bad_receiver); 2674 Bind(&throw_bad_receiver);
2827 { 2675 {
2828 // The {receiver} is not a valid JSArrayIterator. 2676 // The {receiver} is not a valid JSArrayIterator.
2829 assembler.CallRuntime(Runtime::kThrowIncompatibleMethodReceiver, context, 2677 CallRuntime(Runtime::kThrowIncompatibleMethodReceiver, context,
2830 assembler.HeapConstant(operation), iterator); 2678 HeapConstant(operation), iterator);
2831 assembler.Unreachable(); 2679 Unreachable();
2832 } 2680 }
2833 2681
2834 assembler.Bind(&if_isdetached); 2682 Bind(&if_isdetached);
2835 { 2683 {
2836 Node* message = assembler.SmiConstant(MessageTemplate::kDetachedOperation); 2684 Node* message = SmiConstant(MessageTemplate::kDetachedOperation);
2837 assembler.CallRuntime(Runtime::kThrowTypeError, context, message, 2685 CallRuntime(Runtime::kThrowTypeError, context, message,
2838 assembler.HeapConstant(operation)); 2686 HeapConstant(operation));
2839 assembler.Unreachable(); 2687 Unreachable();
2840 } 2688 }
2841 } 2689 }
2842 2690
2843 } // namespace internal 2691 } // namespace internal
2844 } // namespace v8 2692 } // namespace v8
OLDNEW
« no previous file with comments | « no previous file | src/builtins/builtins-conversion.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698