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

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

Issue 2734323004: [cleanup] Refactor remaining builtins-*.cc to use TF_BUILTIN macro (Closed)
Patch Set: fix diff view 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
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 Node* undefined = UndefinedConstant();
1984 Node* intptr_one = assembler.IntPtrConstant(1);
1985 1957
1986 Node* undefined = assembler.UndefinedConstant(); 1958 Variable len_var(this, MachineType::PointerRepresentation()),
1959 index_var(this, MachineType::PointerRepresentation()),
1960 start_from_var(this, MachineType::PointerRepresentation());
1987 1961
1988 Variable len_var(&assembler, MachineType::PointerRepresentation()), 1962 Label init_k(this), return_found(this), return_not_found(this),
1989 index_var(&assembler, MachineType::PointerRepresentation()), 1963 call_runtime(this);
1990 start_from_var(&assembler, MachineType::PointerRepresentation());
1991 1964
1992 Label init_k(&assembler), return_found(&assembler), 1965 Label init_len(this);
1993 return_not_found(&assembler), call_runtime(&assembler);
1994
1995 Label init_len(&assembler);
1996 1966
1997 index_var.Bind(intptr_zero); 1967 index_var.Bind(intptr_zero);
1998 len_var.Bind(intptr_zero); 1968 len_var.Bind(intptr_zero);
1999 1969
2000 // Take slow path if not a JSArray, if retrieving elements requires 1970 // Take slow path if not a JSArray, if retrieving elements requires
2001 // traversing prototype, or if access checks are required. 1971 // traversing prototype, or if access checks are required.
2002 assembler.BranchIfFastJSArray( 1972 BranchIfFastJSArray(array, context, FastJSArrayAccessMode::INBOUNDS_READ,
2003 array, context, CodeStubAssembler::FastJSArrayAccessMode::INBOUNDS_READ, 1973 &init_len, &call_runtime);
2004 &init_len, &call_runtime);
2005 1974
2006 assembler.Bind(&init_len); 1975 Bind(&init_len);
2007 { 1976 {
2008 // JSArray length is always an Smi for fast arrays. 1977 // JSArray length is always an Smi for fast arrays.
2009 CSA_ASSERT(&assembler, assembler.TaggedIsSmi(assembler.LoadObjectField( 1978 CSA_ASSERT(this,
2010 array, JSArray::kLengthOffset))); 1979 TaggedIsSmi(LoadObjectField(array, JSArray::kLengthOffset)));
2011 Node* len = 1980 Node* len = LoadAndUntagObjectField(array, JSArray::kLengthOffset);
2012 assembler.LoadAndUntagObjectField(array, JSArray::kLengthOffset);
2013 1981
2014 len_var.Bind(len); 1982 len_var.Bind(len);
2015 assembler.Branch(assembler.WordEqual(len_var.value(), intptr_zero), 1983 Branch(WordEqual(len_var.value(), intptr_zero), &return_not_found, &init_k);
2016 &return_not_found, &init_k);
2017 } 1984 }
2018 1985
2019 assembler.Bind(&init_k); 1986 Bind(&init_k);
2020 { 1987 {
2021 Label done(&assembler), init_k_smi(&assembler), init_k_heap_num(&assembler), 1988 Label done(this), init_k_smi(this), init_k_heap_num(this),
2022 init_k_zero(&assembler), init_k_n(&assembler); 1989 init_k_zero(this), init_k_n(this);
2023 Node* tagged_n = assembler.ToInteger(context, start_from); 1990 Node* tagged_n = ToInteger(context, start_from);
2024 1991
2025 assembler.Branch(assembler.TaggedIsSmi(tagged_n), &init_k_smi, 1992 Branch(TaggedIsSmi(tagged_n), &init_k_smi, &init_k_heap_num);
2026 &init_k_heap_num);
2027 1993
2028 assembler.Bind(&init_k_smi); 1994 Bind(&init_k_smi);
2029 { 1995 {
2030 start_from_var.Bind(assembler.SmiUntag(tagged_n)); 1996 start_from_var.Bind(SmiUntag(tagged_n));
2031 assembler.Goto(&init_k_n); 1997 Goto(&init_k_n);
2032 } 1998 }
2033 1999
2034 assembler.Bind(&init_k_heap_num); 2000 Bind(&init_k_heap_num);
2035 { 2001 {
2036 Label do_return_not_found(&assembler); 2002 Label do_return_not_found(this);
2037 // This round is lossless for all valid lengths. 2003 // This round is lossless for all valid lengths.
2038 Node* fp_len = assembler.RoundIntPtrToFloat64(len_var.value()); 2004 Node* fp_len = RoundIntPtrToFloat64(len_var.value());
2039 Node* fp_n = assembler.LoadHeapNumberValue(tagged_n); 2005 Node* fp_n = LoadHeapNumberValue(tagged_n);
2040 assembler.GotoIf(assembler.Float64GreaterThanOrEqual(fp_n, fp_len), 2006 GotoIf(Float64GreaterThanOrEqual(fp_n, fp_len), &do_return_not_found);
2041 &do_return_not_found); 2007 start_from_var.Bind(ChangeInt32ToIntPtr(TruncateFloat64ToWord32(fp_n)));
2042 start_from_var.Bind(assembler.ChangeInt32ToIntPtr( 2008 Goto(&init_k_n);
2043 assembler.TruncateFloat64ToWord32(fp_n)));
2044 assembler.Goto(&init_k_n);
2045 2009
2046 assembler.Bind(&do_return_not_found); 2010 Bind(&do_return_not_found);
2047 { 2011 {
2048 index_var.Bind(intptr_zero); 2012 index_var.Bind(intptr_zero);
2049 assembler.Goto(&return_not_found); 2013 Goto(&return_not_found);
2050 } 2014 }
2051 } 2015 }
2052 2016
2053 assembler.Bind(&init_k_n); 2017 Bind(&init_k_n);
2054 { 2018 {
2055 Label if_positive(&assembler), if_negative(&assembler), done(&assembler); 2019 Label if_positive(this), if_negative(this), done(this);
2056 assembler.Branch( 2020 Branch(IntPtrLessThan(start_from_var.value(), intptr_zero), &if_negative,
2057 assembler.IntPtrLessThan(start_from_var.value(), intptr_zero), 2021 &if_positive);
2058 &if_negative, &if_positive);
2059 2022
2060 assembler.Bind(&if_positive); 2023 Bind(&if_positive);
2061 { 2024 {
2062 index_var.Bind(start_from_var.value()); 2025 index_var.Bind(start_from_var.value());
2063 assembler.Goto(&done); 2026 Goto(&done);
2064 } 2027 }
2065 2028
2066 assembler.Bind(&if_negative); 2029 Bind(&if_negative);
2067 { 2030 {
2068 index_var.Bind( 2031 index_var.Bind(IntPtrAdd(len_var.value(), start_from_var.value()));
2069 assembler.IntPtrAdd(len_var.value(), start_from_var.value())); 2032 Branch(IntPtrLessThan(index_var.value(), intptr_zero), &init_k_zero,
2070 assembler.Branch( 2033 &done);
2071 assembler.IntPtrLessThan(index_var.value(), intptr_zero),
2072 &init_k_zero, &done);
2073 } 2034 }
2074 2035
2075 assembler.Bind(&init_k_zero); 2036 Bind(&init_k_zero);
2076 { 2037 {
2077 index_var.Bind(intptr_zero); 2038 index_var.Bind(intptr_zero);
2078 assembler.Goto(&done); 2039 Goto(&done);
2079 } 2040 }
2080 2041
2081 assembler.Bind(&done); 2042 Bind(&done);
2082 } 2043 }
2083 } 2044 }
2084 2045
2085 static int32_t kElementsKind[] = { 2046 static int32_t kElementsKind[] = {
2086 FAST_SMI_ELEMENTS, FAST_HOLEY_SMI_ELEMENTS, FAST_ELEMENTS, 2047 FAST_SMI_ELEMENTS, FAST_HOLEY_SMI_ELEMENTS, FAST_ELEMENTS,
2087 FAST_HOLEY_ELEMENTS, FAST_DOUBLE_ELEMENTS, FAST_HOLEY_DOUBLE_ELEMENTS, 2048 FAST_HOLEY_ELEMENTS, FAST_DOUBLE_ELEMENTS, FAST_HOLEY_DOUBLE_ELEMENTS,
2088 }; 2049 };
2089 2050
2090 Label if_smiorobjects(&assembler), if_packed_doubles(&assembler), 2051 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, 2052 Label* element_kind_handlers[] = {&if_smiorobjects, &if_smiorobjects,
2093 &if_smiorobjects, &if_smiorobjects, 2053 &if_smiorobjects, &if_smiorobjects,
2094 &if_packed_doubles, &if_holey_doubles}; 2054 &if_packed_doubles, &if_holey_doubles};
2095 2055
2096 Node* map = assembler.LoadMap(array); 2056 Node* map = LoadMap(array);
2097 Node* elements_kind = assembler.LoadMapElementsKind(map); 2057 Node* elements_kind = LoadMapElementsKind(map);
2098 Node* elements = assembler.LoadElements(array); 2058 Node* elements = LoadElements(array);
2099 assembler.Switch(elements_kind, &return_not_found, kElementsKind, 2059 Switch(elements_kind, &return_not_found, kElementsKind, element_kind_handlers,
2100 element_kind_handlers, arraysize(kElementsKind)); 2060 arraysize(kElementsKind));
2101 2061
2102 assembler.Bind(&if_smiorobjects); 2062 Bind(&if_smiorobjects);
2103 { 2063 {
2104 Variable search_num(&assembler, MachineRepresentation::kFloat64); 2064 Variable search_num(this, MachineRepresentation::kFloat64);
2105 Label ident_loop(&assembler, &index_var), 2065 Label ident_loop(this, &index_var), heap_num_loop(this, &search_num),
2106 heap_num_loop(&assembler, &search_num), 2066 string_loop(this, &index_var), not_smi(this), not_heap_num(this);
2107 string_loop(&assembler, &index_var), undef_loop(&assembler, &index_var), 2067
2108 not_smi(&assembler), not_heap_num(&assembler); 2068 GotoIfNot(TaggedIsSmi(search_element), &not_smi);
2109 2069 search_num.Bind(SmiToFloat64(search_element));
2110 assembler.GotoIfNot(assembler.TaggedIsSmi(search_element), &not_smi); 2070 Goto(&heap_num_loop);
2111 search_num.Bind(assembler.SmiToFloat64(search_element)); 2071
2112 assembler.Goto(&heap_num_loop); 2072 Bind(&not_smi);
2113 2073 Node* map = LoadMap(search_element);
2114 assembler.Bind(&not_smi); 2074 GotoIfNot(IsHeapNumberMap(map), &not_heap_num);
2115 assembler.GotoIf(assembler.WordEqual(search_element, undefined), 2075 search_num.Bind(LoadHeapNumberValue(search_element));
2116 &undef_loop); 2076 Goto(&heap_num_loop);
2117 Node* map = assembler.LoadMap(search_element); 2077
2118 assembler.GotoIfNot(assembler.IsHeapNumberMap(map), &not_heap_num); 2078 Bind(&not_heap_num);
2119 search_num.Bind(assembler.LoadHeapNumberValue(search_element)); 2079 Node* search_type = LoadMapInstanceType(map);
2120 assembler.Goto(&heap_num_loop); 2080 GotoIf(IsStringInstanceType(search_type), &string_loop);
2121 2081 Goto(&ident_loop);
2122 assembler.Bind(&not_heap_num); 2082
2123 Node* search_type = assembler.LoadMapInstanceType(map); 2083 Bind(&ident_loop);
2124 assembler.GotoIf(assembler.IsStringInstanceType(search_type), &string_loop); 2084 {
2125 assembler.Goto(&ident_loop); 2085 GotoIfNot(UintPtrLessThan(index_var.value(), len_var.value()),
2126 2086 &return_not_found);
2127 assembler.Bind(&ident_loop); 2087 Node* element_k = LoadFixedArrayElement(elements, index_var.value());
2128 { 2088 GotoIf(WordEqual(element_k, search_element), &return_found);
2129 assembler.GotoIfNot( 2089
2130 assembler.UintPtrLessThan(index_var.value(), len_var.value()), 2090 index_var.Bind(IntPtrAdd(index_var.value(), intptr_one));
2131 &return_not_found); 2091 Goto(&ident_loop);
2132 Node* element_k = 2092 }
2133 assembler.LoadFixedArrayElement(elements, index_var.value()); 2093
2134 assembler.GotoIf(assembler.WordEqual(element_k, search_element), 2094 Bind(&heap_num_loop);
2135 &return_found); 2095 {
2136 2096 Label not_nan_loop(this, &index_var);
2137 index_var.Bind(assembler.IntPtrAdd(index_var.value(), intptr_one)); 2097 BranchIfFloat64IsNaN(search_num.value(), &return_not_found,
2138 assembler.Goto(&ident_loop); 2098 &not_nan_loop);
2139 } 2099
2140 2100 Bind(&not_nan_loop);
2141 assembler.Bind(&undef_loop);
Jakob Kummerow 2017/03/08 19:43:49 I've dropped this. It's the same as |ident_loop| a
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 { 2101 {
2163 Label continue_loop(&assembler), not_smi(&assembler); 2102 Label continue_loop(this), not_smi(this);
2164 assembler.GotoIfNot( 2103 GotoIfNot(UintPtrLessThan(index_var.value(), len_var.value()),
2165 assembler.UintPtrLessThan(index_var.value(), len_var.value()), 2104 &return_not_found);
2166 &return_not_found); 2105 Node* element_k = LoadFixedArrayElement(elements, index_var.value());
2167 Node* element_k = 2106 GotoIfNot(TaggedIsSmi(element_k), &not_smi);
2168 assembler.LoadFixedArrayElement(elements, index_var.value()); 2107 Branch(Float64Equal(search_num.value(), SmiToFloat64(element_k)),
2169 assembler.GotoIfNot(assembler.TaggedIsSmi(element_k), &not_smi); 2108 &return_found, &continue_loop);
2170 assembler.Branch( 2109
2171 assembler.Float64Equal(search_num.value(), 2110 Bind(&not_smi);
2172 assembler.SmiToFloat64(element_k)), 2111 GotoIfNot(IsHeapNumber(element_k), &continue_loop);
2173 &return_found, &continue_loop); 2112 Branch(Float64Equal(search_num.value(), LoadHeapNumberValue(element_k)),
2174 2113 &return_found, &continue_loop);
2175 assembler.Bind(&not_smi); 2114
2176 assembler.GotoIfNot( 2115 Bind(&continue_loop);
2177 assembler.IsHeapNumberMap(assembler.LoadMap(element_k)), 2116 index_var.Bind(IntPtrAdd(index_var.value(), intptr_one));
2178 &continue_loop); 2117 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 } 2118 }
2188 } 2119 }
2189 2120
2190 assembler.Bind(&string_loop); 2121 Bind(&string_loop);
2191 { 2122 {
2192 Label continue_loop(&assembler); 2123 Label continue_loop(this);
2193 assembler.GotoIfNot( 2124 GotoIfNot(UintPtrLessThan(index_var.value(), len_var.value()),
2194 assembler.UintPtrLessThan(index_var.value(), len_var.value()), 2125 &return_not_found);
2195 &return_not_found); 2126 Node* element_k = LoadFixedArrayElement(elements, index_var.value());
2196 Node* element_k = 2127 GotoIf(TaggedIsSmi(element_k), &continue_loop);
2197 assembler.LoadFixedArrayElement(elements, index_var.value()); 2128 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 2129
2203 // TODO(bmeurer): Consider inlining the StringEqual logic here. 2130 // TODO(bmeurer): Consider inlining the StringEqual logic here.
2204 Callable callable = CodeFactory::StringEqual(assembler.isolate()); 2131 Callable callable = CodeFactory::StringEqual(isolate());
2205 Node* result = 2132 Node* result = CallStub(callable, context, search_element, element_k);
2206 assembler.CallStub(callable, context, search_element, element_k); 2133 Branch(WordEqual(BooleanConstant(true), result), &return_found,
2207 assembler.Branch( 2134 &continue_loop);
2208 assembler.WordEqual(assembler.BooleanConstant(true), result), 2135
2209 &return_found, &continue_loop); 2136 Bind(&continue_loop);
2210 2137 index_var.Bind(IntPtrAdd(index_var.value(), intptr_one));
2211 assembler.Bind(&continue_loop); 2138 Goto(&string_loop);
2212 index_var.Bind(assembler.IntPtrAdd(index_var.value(), intptr_one)); 2139 }
2213 assembler.Goto(&string_loop); 2140 }
2214 } 2141
2215 } 2142 Bind(&if_packed_doubles);
2216 2143 {
2217 assembler.Bind(&if_packed_doubles); 2144 Label not_nan_loop(this, &index_var), search_notnan(this);
2218 { 2145 Variable search_num(this, MachineRepresentation::kFloat64);
2219 Label not_nan_loop(&assembler, &index_var), search_notnan(&assembler); 2146
2220 Variable search_num(&assembler, MachineRepresentation::kFloat64); 2147 GotoIfNot(TaggedIsSmi(search_element), &search_notnan);
2221 2148 search_num.Bind(SmiToFloat64(search_element));
2222 assembler.GotoIfNot(assembler.TaggedIsSmi(search_element), &search_notnan); 2149 Goto(&not_nan_loop);
2223 search_num.Bind(assembler.SmiToFloat64(search_element)); 2150
2224 assembler.Goto(&not_nan_loop); 2151 Bind(&search_notnan);
2225 2152 GotoIfNot(IsHeapNumber(search_element), &return_not_found);
2226 assembler.Bind(&search_notnan); 2153
2227 assembler.GotoIfNot( 2154 search_num.Bind(LoadHeapNumberValue(search_element));
2228 assembler.IsHeapNumberMap(assembler.LoadMap(search_element)), 2155
2229 &return_not_found); 2156 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 2157
2236 // Search for HeapNumber 2158 // Search for HeapNumber
2237 assembler.Bind(&not_nan_loop); 2159 Bind(&not_nan_loop);
2238 { 2160 {
2239 Label continue_loop(&assembler); 2161 GotoIfNot(UintPtrLessThan(index_var.value(), len_var.value()),
2240 assembler.GotoIfNot( 2162 &return_not_found);
2241 assembler.UintPtrLessThan(index_var.value(), len_var.value()), 2163 Node* element_k = LoadFixedDoubleArrayElement(elements, index_var.value(),
2242 &return_not_found); 2164 MachineType::Float64());
2243 Node* element_k = assembler.LoadFixedDoubleArrayElement( 2165 GotoIf(Float64Equal(element_k, search_num.value()), &return_found);
2244 elements, index_var.value(), MachineType::Float64()); 2166
2245 assembler.Branch(assembler.Float64Equal(element_k, search_num.value()), 2167 index_var.Bind(IntPtrAdd(index_var.value(), intptr_one));
2246 &return_found, &continue_loop); 2168 Goto(&not_nan_loop);
2247 assembler.Bind(&continue_loop); 2169 }
2248 index_var.Bind(assembler.IntPtrAdd(index_var.value(), intptr_one)); 2170 }
2249 assembler.Goto(&not_nan_loop); 2171
2250 } 2172 Bind(&if_holey_doubles);
2251 } 2173 {
2252 2174 Label not_nan_loop(this, &index_var), search_notnan(this);
2253 assembler.Bind(&if_holey_doubles); 2175 Variable search_num(this, MachineRepresentation::kFloat64);
2254 { 2176
2255 Label not_nan_loop(&assembler, &index_var), search_notnan(&assembler); 2177 GotoIfNot(TaggedIsSmi(search_element), &search_notnan);
2256 Variable search_num(&assembler, MachineRepresentation::kFloat64); 2178 search_num.Bind(SmiToFloat64(search_element));
2257 2179 Goto(&not_nan_loop);
2258 assembler.GotoIfNot(assembler.TaggedIsSmi(search_element), &search_notnan); 2180
2259 search_num.Bind(assembler.SmiToFloat64(search_element)); 2181 Bind(&search_notnan);
2260 assembler.Goto(&not_nan_loop); 2182 GotoIfNot(IsHeapNumber(search_element), &return_not_found);
2261 2183
2262 assembler.Bind(&search_notnan); 2184 search_num.Bind(LoadHeapNumberValue(search_element));
2263 assembler.GotoIfNot( 2185
2264 assembler.IsHeapNumberMap(assembler.LoadMap(search_element)), 2186 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 2187
2272 // Search for HeapNumber 2188 // Search for HeapNumber
2273 assembler.Bind(&not_nan_loop); 2189 Bind(&not_nan_loop);
2274 { 2190 {
2275 Label continue_loop(&assembler); 2191 Label continue_loop(this);
2276 assembler.GotoIfNot( 2192 GotoIfNot(UintPtrLessThan(index_var.value(), len_var.value()),
2277 assembler.UintPtrLessThan(index_var.value(), len_var.value()), 2193 &return_not_found);
2278 &return_not_found);
2279 2194
2280 // Load double value or continue if it contains a double hole. 2195 // Load double value or continue if it contains a double hole.
2281 Node* element_k = assembler.LoadFixedDoubleArrayElement( 2196 Node* element_k = LoadFixedDoubleArrayElement(
2282 elements, index_var.value(), MachineType::Float64(), 0, 2197 elements, index_var.value(), MachineType::Float64(), 0,
2283 CodeStubAssembler::INTPTR_PARAMETERS, &continue_loop); 2198 INTPTR_PARAMETERS, &continue_loop);
2284 2199
2285 assembler.Branch(assembler.Float64Equal(element_k, search_num.value()), 2200 Branch(Float64Equal(element_k, search_num.value()), &return_found,
2286 &return_found, &continue_loop); 2201 &continue_loop);
2287 assembler.Bind(&continue_loop); 2202 Bind(&continue_loop);
2288 index_var.Bind(assembler.IntPtrAdd(index_var.value(), intptr_one)); 2203 index_var.Bind(IntPtrAdd(index_var.value(), intptr_one));
2289 assembler.Goto(&not_nan_loop); 2204 Goto(&not_nan_loop);
2290 } 2205 }
2291 } 2206 }
2292 2207
2293 assembler.Bind(&return_found); 2208 Bind(&return_found);
2294 assembler.Return(assembler.SmiTag(index_var.value())); 2209 Return(SmiTag(index_var.value()));
2295 2210
2296 assembler.Bind(&return_not_found); 2211 Bind(&return_not_found);
2297 assembler.Return(assembler.NumberConstant(-1)); 2212 Return(NumberConstant(-1));
2298 2213
2299 assembler.Bind(&call_runtime); 2214 Bind(&call_runtime);
2300 assembler.Return(assembler.CallRuntime(Runtime::kArrayIndexOf, context, array, 2215 Return(CallRuntime(Runtime::kArrayIndexOf, context, array, search_element,
2301 search_element, start_from)); 2216 start_from));
2302 } 2217 }
2303 2218
2304 namespace { 2219 class ArrayPrototypeIterationAssembler : public CodeStubAssembler {
2305 2220 public:
2306 template <IterationKind kIterationKind> 2221 explicit ArrayPrototypeIterationAssembler(compiler::CodeAssemblerState* state)
2307 void Generate_ArrayPrototypeIterationMethod( 2222 : CodeStubAssembler(state) {}
2308 compiler::CodeAssemblerState* state) { 2223
2309 typedef compiler::Node Node; 2224 protected:
2310 typedef CodeStubAssembler::Label Label; 2225 void Generate_ArrayPrototypeIterationMethod(IterationKind iteration_kind) {
2311 typedef CodeStubAssembler::Variable Variable; 2226 Node* receiver = Parameter(0);
2312 CodeStubAssembler assembler(state); 2227 Node* context = Parameter(3);
2313 2228
2314 Node* receiver = assembler.Parameter(0); 2229 Variable var_array(this, MachineRepresentation::kTagged);
2315 Node* context = assembler.Parameter(3); 2230 Variable var_map(this, MachineRepresentation::kTagged);
2316 2231 Variable var_type(this, MachineRepresentation::kWord32);
2317 Variable var_array(&assembler, MachineRepresentation::kTagged); 2232
2318 Variable var_map(&assembler, MachineRepresentation::kTagged); 2233 Label if_isnotobject(this, Label::kDeferred);
2319 Variable var_type(&assembler, MachineRepresentation::kWord32); 2234 Label create_array_iterator(this);
2320 2235
2321 Label if_isnotobject(&assembler, Label::kDeferred); 2236 GotoIf(TaggedIsSmi(receiver), &if_isnotobject);
2322 Label create_array_iterator(&assembler); 2237 var_array.Bind(receiver);
2323 2238 var_map.Bind(LoadMap(receiver));
2324 assembler.GotoIf(assembler.TaggedIsSmi(receiver), &if_isnotobject); 2239 var_type.Bind(LoadMapInstanceType(var_map.value()));
2325 var_array.Bind(receiver); 2240 Branch(IsJSReceiverInstanceType(var_type.value()), &create_array_iterator,
2326 var_map.Bind(assembler.LoadMap(receiver)); 2241 &if_isnotobject);
2327 var_type.Bind(assembler.LoadMapInstanceType(var_map.value())); 2242
2328 assembler.Branch(assembler.IsJSReceiverInstanceType(var_type.value()), 2243 Bind(&if_isnotobject);
2329 &create_array_iterator, &if_isnotobject); 2244 {
2330 2245 Callable callable = CodeFactory::ToObject(isolate());
2331 assembler.Bind(&if_isnotobject); 2246 Node* result = CallStub(callable, context, receiver);
2332 { 2247 var_array.Bind(result);
2333 Callable callable = CodeFactory::ToObject(assembler.isolate()); 2248 var_map.Bind(LoadMap(result));
2334 Node* result = assembler.CallStub(callable, context, receiver); 2249 var_type.Bind(LoadMapInstanceType(var_map.value()));
2335 var_array.Bind(result); 2250 Goto(&create_array_iterator);
2336 var_map.Bind(assembler.LoadMap(result)); 2251 }
2337 var_type.Bind(assembler.LoadMapInstanceType(var_map.value())); 2252
2338 assembler.Goto(&create_array_iterator); 2253 Bind(&create_array_iterator);
2339 } 2254 Return(CreateArrayIterator(var_array.value(), var_map.value(),
2340 2255 var_type.value(), context, iteration_kind));
2341 assembler.Bind(&create_array_iterator); 2256 }
2342 assembler.Return( 2257 };
2343 assembler.CreateArrayIterator(var_array.value(), var_map.value(), 2258
2344 var_type.value(), context, kIterationKind)); 2259 TF_BUILTIN(ArrayPrototypeValues, ArrayPrototypeIterationAssembler) {
2345 } 2260 Generate_ArrayPrototypeIterationMethod(IterationKind::kValues);
2346 2261 }
2347 } // namespace 2262
2348 2263 TF_BUILTIN(ArrayPrototypeEntries, ArrayPrototypeIterationAssembler) {
2349 void Builtins::Generate_ArrayPrototypeValues( 2264 Generate_ArrayPrototypeIterationMethod(IterationKind::kEntries);
2350 compiler::CodeAssemblerState* state) { 2265 }
2351 Generate_ArrayPrototypeIterationMethod<IterationKind::kValues>(state); 2266
2352 } 2267 TF_BUILTIN(ArrayPrototypeKeys, ArrayPrototypeIterationAssembler) {
2353 2268 Generate_ArrayPrototypeIterationMethod(IterationKind::kKeys);
2354 void Builtins::Generate_ArrayPrototypeEntries( 2269 }
2355 compiler::CodeAssemblerState* state) { 2270
2356 Generate_ArrayPrototypeIterationMethod<IterationKind::kEntries>(state); 2271 TF_BUILTIN(ArrayIteratorPrototypeNext, CodeStubAssembler) {
2357 } 2272 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); 2273 "Array Iterator.prototype.next", TENURED);
2373 2274
2374 Node* iterator = assembler.Parameter(0); 2275 Node* iterator = Parameter(0);
2375 Node* context = assembler.Parameter(3); 2276 Node* context = Parameter(3);
2376 2277
2377 Variable var_value(&assembler, MachineRepresentation::kTagged); 2278 Variable var_value(this, MachineRepresentation::kTagged);
2378 Variable var_done(&assembler, MachineRepresentation::kTagged); 2279 Variable var_done(this, MachineRepresentation::kTagged);
2379 2280
2380 // Required, or else `throw_bad_receiver` fails a DCHECK due to these 2281 // Required, or else `throw_bad_receiver` fails a DCHECK due to these
2381 // variables not being bound along all paths, despite not being used. 2282 // variables not being bound along all paths, despite not being used.
2382 var_done.Bind(assembler.TrueConstant()); 2283 var_done.Bind(TrueConstant());
2383 var_value.Bind(assembler.UndefinedConstant()); 2284 var_value.Bind(UndefinedConstant());
2384 2285
2385 Label throw_bad_receiver(&assembler, Label::kDeferred); 2286 Label throw_bad_receiver(this, Label::kDeferred);
2386 Label set_done(&assembler); 2287 Label set_done(this);
2387 Label allocate_key_result(&assembler); 2288 Label allocate_key_result(this);
2388 Label allocate_entry_if_needed(&assembler); 2289 Label allocate_entry_if_needed(this);
2389 Label allocate_iterator_result(&assembler); 2290 Label allocate_iterator_result(this);
2390 Label generic_values(&assembler); 2291 Label generic_values(this);
2391 2292
2392 // If O does not have all of the internal slots of an Array Iterator Instance 2293 // If O does not have all of the internal slots of an Array Iterator Instance
2393 // (22.1.5.3), throw a TypeError exception 2294 // (22.1.5.3), throw a TypeError exception
2394 assembler.GotoIf(assembler.TaggedIsSmi(iterator), &throw_bad_receiver); 2295 GotoIf(TaggedIsSmi(iterator), &throw_bad_receiver);
2395 Node* instance_type = assembler.LoadInstanceType(iterator); 2296 Node* instance_type = LoadInstanceType(iterator);
2396 assembler.GotoIf( 2297 GotoIf(
2397 assembler.Uint32LessThan( 2298 Uint32LessThan(
2398 assembler.Int32Constant(LAST_ARRAY_ITERATOR_TYPE - 2299 Int32Constant(LAST_ARRAY_ITERATOR_TYPE - FIRST_ARRAY_ITERATOR_TYPE),
2399 FIRST_ARRAY_ITERATOR_TYPE), 2300 Int32Sub(instance_type, Int32Constant(FIRST_ARRAY_ITERATOR_TYPE))),
2400 assembler.Int32Sub(instance_type, assembler.Int32Constant(
2401 FIRST_ARRAY_ITERATOR_TYPE))),
2402 &throw_bad_receiver); 2301 &throw_bad_receiver);
2403 2302
2404 // Let a be O.[[IteratedObject]]. 2303 // Let a be O.[[IteratedObject]].
2405 Node* array = assembler.LoadObjectField( 2304 Node* array =
2406 iterator, JSArrayIterator::kIteratedObjectOffset); 2305 LoadObjectField(iterator, JSArrayIterator::kIteratedObjectOffset);
2407 2306
2408 // Let index be O.[[ArrayIteratorNextIndex]]. 2307 // Let index be O.[[ArrayIteratorNextIndex]].
2409 Node* index = 2308 Node* index = LoadObjectField(iterator, JSArrayIterator::kNextIndexOffset);
2410 assembler.LoadObjectField(iterator, JSArrayIterator::kNextIndexOffset); 2309 Node* orig_map =
2411 Node* orig_map = assembler.LoadObjectField( 2310 LoadObjectField(iterator, JSArrayIterator::kIteratedObjectMapOffset);
2412 iterator, JSArrayIterator::kIteratedObjectMapOffset); 2311 Node* array_map = LoadMap(array);
2413 Node* array_map = assembler.LoadMap(array); 2312
2414 2313 Label if_isfastarray(this), if_isnotfastarray(this),
2415 Label if_isfastarray(&assembler), if_isnotfastarray(&assembler), 2314 if_isdetached(this, Label::kDeferred);
2416 if_isdetached(&assembler, Label::kDeferred); 2315
2417 2316 Branch(WordEqual(orig_map, array_map), &if_isfastarray, &if_isnotfastarray);
2418 assembler.Branch(assembler.WordEqual(orig_map, array_map), &if_isfastarray, 2317
2419 &if_isnotfastarray); 2318 Bind(&if_isfastarray);
2420 2319 {
2421 assembler.Bind(&if_isfastarray); 2320 CSA_ASSERT(this, Word32Equal(LoadMapInstanceType(array_map),
2422 { 2321 Int32Constant(JS_ARRAY_TYPE)));
2423 CSA_ASSERT(&assembler, 2322
2424 assembler.Word32Equal(assembler.LoadMapInstanceType(array_map), 2323 Node* length = LoadObjectField(array, JSArray::kLengthOffset);
2425 assembler.Int32Constant(JS_ARRAY_TYPE))); 2324
2426 2325 CSA_ASSERT(this, TaggedIsSmi(length));
2427 Node* length = assembler.LoadObjectField(array, JSArray::kLengthOffset); 2326 CSA_ASSERT(this, TaggedIsSmi(index));
2428 2327
2429 CSA_ASSERT(&assembler, assembler.TaggedIsSmi(length)); 2328 GotoIfNot(SmiBelow(index, length), &set_done);
2430 CSA_ASSERT(&assembler, assembler.TaggedIsSmi(index)); 2329
2431 2330 Node* one = SmiConstant(Smi::FromInt(1));
2432 assembler.GotoIfNot(assembler.SmiBelow(index, length), &set_done); 2331 StoreObjectFieldNoWriteBarrier(iterator, JSArrayIterator::kNextIndexOffset,
2433 2332 SmiAdd(index, one));
2434 Node* one = assembler.SmiConstant(Smi::FromInt(1)); 2333
2435 assembler.StoreObjectFieldNoWriteBarrier(iterator, 2334 var_done.Bind(FalseConstant());
2436 JSArrayIterator::kNextIndexOffset, 2335 Node* elements = LoadElements(array);
2437 assembler.SmiAdd(index, one));
2438
2439 var_done.Bind(assembler.FalseConstant());
2440 Node* elements = assembler.LoadElements(array);
2441 2336
2442 static int32_t kInstanceType[] = { 2337 static int32_t kInstanceType[] = {
2443 JS_FAST_ARRAY_KEY_ITERATOR_TYPE, 2338 JS_FAST_ARRAY_KEY_ITERATOR_TYPE,
2444 JS_FAST_SMI_ARRAY_KEY_VALUE_ITERATOR_TYPE, 2339 JS_FAST_SMI_ARRAY_KEY_VALUE_ITERATOR_TYPE,
2445 JS_FAST_HOLEY_SMI_ARRAY_KEY_VALUE_ITERATOR_TYPE, 2340 JS_FAST_HOLEY_SMI_ARRAY_KEY_VALUE_ITERATOR_TYPE,
2446 JS_FAST_ARRAY_KEY_VALUE_ITERATOR_TYPE, 2341 JS_FAST_ARRAY_KEY_VALUE_ITERATOR_TYPE,
2447 JS_FAST_HOLEY_ARRAY_KEY_VALUE_ITERATOR_TYPE, 2342 JS_FAST_HOLEY_ARRAY_KEY_VALUE_ITERATOR_TYPE,
2448 JS_FAST_DOUBLE_ARRAY_KEY_VALUE_ITERATOR_TYPE, 2343 JS_FAST_DOUBLE_ARRAY_KEY_VALUE_ITERATOR_TYPE,
2449 JS_FAST_HOLEY_DOUBLE_ARRAY_KEY_VALUE_ITERATOR_TYPE, 2344 JS_FAST_HOLEY_DOUBLE_ARRAY_KEY_VALUE_ITERATOR_TYPE,
2450 JS_FAST_SMI_ARRAY_VALUE_ITERATOR_TYPE, 2345 JS_FAST_SMI_ARRAY_VALUE_ITERATOR_TYPE,
2451 JS_FAST_HOLEY_SMI_ARRAY_VALUE_ITERATOR_TYPE, 2346 JS_FAST_HOLEY_SMI_ARRAY_VALUE_ITERATOR_TYPE,
2452 JS_FAST_ARRAY_VALUE_ITERATOR_TYPE, 2347 JS_FAST_ARRAY_VALUE_ITERATOR_TYPE,
2453 JS_FAST_HOLEY_ARRAY_VALUE_ITERATOR_TYPE, 2348 JS_FAST_HOLEY_ARRAY_VALUE_ITERATOR_TYPE,
2454 JS_FAST_DOUBLE_ARRAY_VALUE_ITERATOR_TYPE, 2349 JS_FAST_DOUBLE_ARRAY_VALUE_ITERATOR_TYPE,
2455 JS_FAST_HOLEY_DOUBLE_ARRAY_VALUE_ITERATOR_TYPE, 2350 JS_FAST_HOLEY_DOUBLE_ARRAY_VALUE_ITERATOR_TYPE,
2456 }; 2351 };
2457 2352
2458 Label packed_object_values(&assembler), holey_object_values(&assembler), 2353 Label packed_object_values(this), holey_object_values(this),
2459 packed_double_values(&assembler), holey_double_values(&assembler); 2354 packed_double_values(this), holey_double_values(this);
2460 Label* kInstanceTypeHandlers[] = { 2355 Label* kInstanceTypeHandlers[] = {
2461 &allocate_key_result, &packed_object_values, &holey_object_values, 2356 &allocate_key_result, &packed_object_values, &holey_object_values,
2462 &packed_object_values, &holey_object_values, &packed_double_values, 2357 &packed_object_values, &holey_object_values, &packed_double_values,
2463 &holey_double_values, &packed_object_values, &holey_object_values, 2358 &holey_double_values, &packed_object_values, &holey_object_values,
2464 &packed_object_values, &holey_object_values, &packed_double_values, 2359 &packed_object_values, &holey_object_values, &packed_double_values,
2465 &holey_double_values}; 2360 &holey_double_values};
2466 2361
2467 assembler.Switch(instance_type, &throw_bad_receiver, kInstanceType, 2362 Switch(instance_type, &throw_bad_receiver, kInstanceType,
2468 kInstanceTypeHandlers, arraysize(kInstanceType)); 2363 kInstanceTypeHandlers, arraysize(kInstanceType));
2469 2364
2470 assembler.Bind(&packed_object_values); 2365 Bind(&packed_object_values);
2471 { 2366 {
2472 var_value.Bind(assembler.LoadFixedArrayElement( 2367 var_value.Bind(LoadFixedArrayElement(elements, index, 0, SMI_PARAMETERS));
2473 elements, index, 0, CodeStubAssembler::SMI_PARAMETERS)); 2368 Goto(&allocate_entry_if_needed);
2474 assembler.Goto(&allocate_entry_if_needed);
2475 } 2369 }
2476 2370
2477 assembler.Bind(&packed_double_values); 2371 Bind(&packed_double_values);
2478 { 2372 {
2479 Node* value = assembler.LoadFixedDoubleArrayElement( 2373 Node* value = LoadFixedDoubleArrayElement(
2480 elements, index, MachineType::Float64(), 0, 2374 elements, index, MachineType::Float64(), 0, SMI_PARAMETERS);
2481 CodeStubAssembler::SMI_PARAMETERS); 2375 var_value.Bind(AllocateHeapNumberWithValue(value));
2482 var_value.Bind(assembler.AllocateHeapNumberWithValue(value)); 2376 Goto(&allocate_entry_if_needed);
2483 assembler.Goto(&allocate_entry_if_needed);
2484 } 2377 }
2485 2378
2486 assembler.Bind(&holey_object_values); 2379 Bind(&holey_object_values);
2487 { 2380 {
2488 // Check the array_protector cell, and take the slow path if it's invalid. 2381 // Check the array_protector cell, and take the slow path if it's invalid.
2489 Node* invalid = 2382 Node* invalid = SmiConstant(Smi::FromInt(Isolate::kProtectorInvalid));
2490 assembler.SmiConstant(Smi::FromInt(Isolate::kProtectorInvalid)); 2383 Node* cell = LoadRoot(Heap::kArrayProtectorRootIndex);
2491 Node* cell = assembler.LoadRoot(Heap::kArrayProtectorRootIndex); 2384 Node* cell_value = LoadObjectField(cell, PropertyCell::kValueOffset);
2492 Node* cell_value = 2385 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 2386
2497 var_value.Bind(assembler.UndefinedConstant()); 2387 var_value.Bind(UndefinedConstant());
2498 Node* value = assembler.LoadFixedArrayElement( 2388 Node* value = LoadFixedArrayElement(elements, index, 0, SMI_PARAMETERS);
2499 elements, index, 0, CodeStubAssembler::SMI_PARAMETERS); 2389 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); 2390 var_value.Bind(value);
2503 assembler.Goto(&allocate_entry_if_needed); 2391 Goto(&allocate_entry_if_needed);
2504 } 2392 }
2505 2393
2506 assembler.Bind(&holey_double_values); 2394 Bind(&holey_double_values);
2507 { 2395 {
2508 // Check the array_protector cell, and take the slow path if it's invalid. 2396 // Check the array_protector cell, and take the slow path if it's invalid.
2509 Node* invalid = 2397 Node* invalid = SmiConstant(Smi::FromInt(Isolate::kProtectorInvalid));
2510 assembler.SmiConstant(Smi::FromInt(Isolate::kProtectorInvalid)); 2398 Node* cell = LoadRoot(Heap::kArrayProtectorRootIndex);
2511 Node* cell = assembler.LoadRoot(Heap::kArrayProtectorRootIndex); 2399 Node* cell_value = LoadObjectField(cell, PropertyCell::kValueOffset);
2512 Node* cell_value = 2400 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 2401
2517 var_value.Bind(assembler.UndefinedConstant()); 2402 var_value.Bind(UndefinedConstant());
2518 Node* value = assembler.LoadFixedDoubleArrayElement( 2403 Node* value = LoadFixedDoubleArrayElement(
2519 elements, index, MachineType::Float64(), 0, 2404 elements, index, MachineType::Float64(), 0, SMI_PARAMETERS,
2520 CodeStubAssembler::SMI_PARAMETERS, &allocate_entry_if_needed); 2405 &allocate_entry_if_needed);
2521 var_value.Bind(assembler.AllocateHeapNumberWithValue(value)); 2406 var_value.Bind(AllocateHeapNumberWithValue(value));
2522 assembler.Goto(&allocate_entry_if_needed); 2407 Goto(&allocate_entry_if_needed);
2523 } 2408 }
2524 } 2409 }
2525 2410
2526 assembler.Bind(&if_isnotfastarray); 2411 Bind(&if_isnotfastarray);
2527 { 2412 {
2528 Label if_istypedarray(&assembler), if_isgeneric(&assembler); 2413 Label if_istypedarray(this), if_isgeneric(this);
2529 2414
2530 // If a is undefined, return CreateIterResultObject(undefined, true) 2415 // If a is undefined, return CreateIterResultObject(undefined, true)
2531 assembler.GotoIf(assembler.WordEqual(array, assembler.UndefinedConstant()), 2416 GotoIf(WordEqual(array, UndefinedConstant()), &allocate_iterator_result);
2532 &allocate_iterator_result);
2533 2417
2534 Node* array_type = assembler.LoadInstanceType(array); 2418 Node* array_type = LoadInstanceType(array);
2535 assembler.Branch( 2419 Branch(Word32Equal(array_type, Int32Constant(JS_TYPED_ARRAY_TYPE)),
2536 assembler.Word32Equal(array_type, 2420 &if_istypedarray, &if_isgeneric);
2537 assembler.Int32Constant(JS_TYPED_ARRAY_TYPE)),
2538 &if_istypedarray, &if_isgeneric);
2539 2421
2540 assembler.Bind(&if_isgeneric); 2422 Bind(&if_isgeneric);
2541 { 2423 {
2542 Label if_wasfastarray(&assembler); 2424 Label if_wasfastarray(this);
2543 2425
2544 Node* length = nullptr; 2426 Node* length = nullptr;
2545 { 2427 {
2546 Variable var_length(&assembler, MachineRepresentation::kTagged); 2428 Variable var_length(this, MachineRepresentation::kTagged);
2547 Label if_isarray(&assembler), if_isnotarray(&assembler), 2429 Label if_isarray(this), if_isnotarray(this), done(this);
2548 done(&assembler); 2430 Branch(Word32Equal(array_type, Int32Constant(JS_ARRAY_TYPE)),
2549 assembler.Branch( 2431 &if_isarray, &if_isnotarray);
2550 assembler.Word32Equal(array_type,
2551 assembler.Int32Constant(JS_ARRAY_TYPE)),
2552 &if_isarray, &if_isnotarray);
2553 2432
2554 assembler.Bind(&if_isarray); 2433 Bind(&if_isarray);
2555 { 2434 {
2556 var_length.Bind( 2435 var_length.Bind(LoadObjectField(array, JSArray::kLengthOffset));
2557 assembler.LoadObjectField(array, JSArray::kLengthOffset));
2558 2436
2559 // Invalidate protector cell if needed 2437 // Invalidate protector cell if needed
2560 assembler.Branch( 2438 Branch(WordNotEqual(orig_map, UndefinedConstant()), &if_wasfastarray,
2561 assembler.WordNotEqual(orig_map, assembler.UndefinedConstant()), 2439 &done);
2562 &if_wasfastarray, &done);
2563 2440
2564 assembler.Bind(&if_wasfastarray); 2441 Bind(&if_wasfastarray);
2565 { 2442 {
2566 Label if_invalid(&assembler, Label::kDeferred); 2443 Label if_invalid(this, Label::kDeferred);
2567 // A fast array iterator transitioned to a slow iterator during 2444 // A fast array iterator transitioned to a slow iterator during
2568 // iteration. Invalidate fast_array_iteration_prtoector cell to 2445 // iteration. Invalidate fast_array_iteration_prtoector cell to
2569 // prevent potential deopt loops. 2446 // prevent potential deopt loops.
2570 assembler.StoreObjectFieldNoWriteBarrier( 2447 StoreObjectFieldNoWriteBarrier(
2571 iterator, JSArrayIterator::kIteratedObjectMapOffset, 2448 iterator, JSArrayIterator::kIteratedObjectMapOffset,
2572 assembler.UndefinedConstant()); 2449 UndefinedConstant());
2573 assembler.GotoIf( 2450 GotoIf(Uint32LessThanOrEqual(
2574 assembler.Uint32LessThanOrEqual( 2451 instance_type,
2575 instance_type, assembler.Int32Constant( 2452 Int32Constant(JS_GENERIC_ARRAY_KEY_ITERATOR_TYPE)),
2576 JS_GENERIC_ARRAY_KEY_ITERATOR_TYPE)), 2453 &done);
2577 &done);
2578 2454
2579 Node* invalid = 2455 Node* invalid =
2580 assembler.SmiConstant(Smi::FromInt(Isolate::kProtectorInvalid)); 2456 SmiConstant(Smi::FromInt(Isolate::kProtectorInvalid));
2581 Node* cell = 2457 Node* cell = LoadRoot(Heap::kFastArrayIterationProtectorRootIndex);
2582 assembler.LoadRoot(Heap::kFastArrayIterationProtectorRootIndex); 2458 StoreObjectFieldNoWriteBarrier(cell, Cell::kValueOffset, invalid);
2583 assembler.StoreObjectFieldNoWriteBarrier(cell, Cell::kValueOffset, 2459 Goto(&done);
2584 invalid);
2585 assembler.Goto(&done);
2586 } 2460 }
2587 } 2461 }
2588 2462
2589 assembler.Bind(&if_isnotarray); 2463 Bind(&if_isnotarray);
2590 { 2464 {
2591 Node* length_string = assembler.HeapConstant( 2465 Node* length_string = HeapConstant(factory()->length_string());
2592 assembler.isolate()->factory()->length_string()); 2466 Callable get_property = CodeFactory::GetProperty(isolate());
2593 Callable get_property = CodeFactory::GetProperty(assembler.isolate()); 2467 Node* length = CallStub(get_property, context, array, length_string);
2594 Node* length = 2468 Callable to_length = CodeFactory::ToLength(isolate());
2595 assembler.CallStub(get_property, context, array, length_string); 2469 var_length.Bind(CallStub(to_length, context, length));
2596 Callable to_length = CodeFactory::ToLength(assembler.isolate()); 2470 Goto(&done);
2597 var_length.Bind(assembler.CallStub(to_length, context, length));
2598 assembler.Goto(&done);
2599 } 2471 }
2600 2472
2601 assembler.Bind(&done); 2473 Bind(&done);
2602 length = var_length.value(); 2474 length = var_length.value();
2603 } 2475 }
2604 2476
2605 assembler.GotoUnlessNumberLessThan(index, length, &set_done); 2477 GotoUnlessNumberLessThan(index, length, &set_done);
2606 2478
2607 assembler.StoreObjectField(iterator, JSArrayIterator::kNextIndexOffset, 2479 StoreObjectField(iterator, JSArrayIterator::kNextIndexOffset,
2608 assembler.NumberInc(index)); 2480 NumberInc(index));
2609 var_done.Bind(assembler.FalseConstant()); 2481 var_done.Bind(FalseConstant());
2610 2482
2611 assembler.Branch( 2483 Branch(
2612 assembler.Uint32LessThanOrEqual( 2484 Uint32LessThanOrEqual(
2613 instance_type, 2485 instance_type, Int32Constant(JS_GENERIC_ARRAY_KEY_ITERATOR_TYPE)),
2614 assembler.Int32Constant(JS_GENERIC_ARRAY_KEY_ITERATOR_TYPE)),
2615 &allocate_key_result, &generic_values); 2486 &allocate_key_result, &generic_values);
2616 2487
2617 assembler.Bind(&generic_values); 2488 Bind(&generic_values);
2618 { 2489 {
2619 Callable get_property = CodeFactory::GetProperty(assembler.isolate()); 2490 Callable get_property = CodeFactory::GetProperty(isolate());
2620 var_value.Bind(assembler.CallStub(get_property, context, array, index)); 2491 var_value.Bind(CallStub(get_property, context, array, index));
2621 assembler.Goto(&allocate_entry_if_needed); 2492 Goto(&allocate_entry_if_needed);
2622 } 2493 }
2623 } 2494 }
2624 2495
2625 assembler.Bind(&if_istypedarray); 2496 Bind(&if_istypedarray);
2626 { 2497 {
2627 Node* buffer = 2498 Node* buffer = LoadObjectField(array, JSTypedArray::kBufferOffset);
2628 assembler.LoadObjectField(array, JSTypedArray::kBufferOffset); 2499 GotoIf(IsDetachedBuffer(buffer), &if_isdetached);
2629 assembler.GotoIf(assembler.IsDetachedBuffer(buffer), &if_isdetached);
2630 2500
2631 Node* length = 2501 Node* length = LoadObjectField(array, JSTypedArray::kLengthOffset);
2632 assembler.LoadObjectField(array, JSTypedArray::kLengthOffset);
2633 2502
2634 CSA_ASSERT(&assembler, assembler.TaggedIsSmi(length)); 2503 CSA_ASSERT(this, TaggedIsSmi(length));
2635 CSA_ASSERT(&assembler, assembler.TaggedIsSmi(index)); 2504 CSA_ASSERT(this, TaggedIsSmi(index));
2636 2505
2637 assembler.GotoIfNot(assembler.SmiBelow(index, length), &set_done); 2506 GotoIfNot(SmiBelow(index, length), &set_done);
2638 2507
2639 Node* one = assembler.SmiConstant(1); 2508 Node* one = SmiConstant(1);
2640 assembler.StoreObjectFieldNoWriteBarrier( 2509 StoreObjectFieldNoWriteBarrier(
2641 iterator, JSArrayIterator::kNextIndexOffset, 2510 iterator, JSArrayIterator::kNextIndexOffset, SmiAdd(index, one));
2642 assembler.SmiAdd(index, one)); 2511 var_done.Bind(FalseConstant());
2643 var_done.Bind(assembler.FalseConstant());
2644 2512
2645 Node* elements = assembler.LoadElements(array); 2513 Node* elements = LoadElements(array);
2646 Node* base_ptr = assembler.LoadObjectField( 2514 Node* base_ptr =
2647 elements, FixedTypedArrayBase::kBasePointerOffset); 2515 LoadObjectField(elements, FixedTypedArrayBase::kBasePointerOffset);
2648 Node* external_ptr = assembler.LoadObjectField( 2516 Node* external_ptr =
2649 elements, FixedTypedArrayBase::kExternalPointerOffset, 2517 LoadObjectField(elements, FixedTypedArrayBase::kExternalPointerOffset,
2650 MachineType::Pointer()); 2518 MachineType::Pointer());
2651 Node* data_ptr = assembler.IntPtrAdd( 2519 Node* data_ptr = IntPtrAdd(BitcastTaggedToWord(base_ptr), external_ptr);
2652 assembler.BitcastTaggedToWord(base_ptr), external_ptr);
2653 2520
2654 static int32_t kInstanceType[] = { 2521 static int32_t kInstanceType[] = {
2655 JS_TYPED_ARRAY_KEY_ITERATOR_TYPE, 2522 JS_TYPED_ARRAY_KEY_ITERATOR_TYPE,
2656 JS_UINT8_ARRAY_KEY_VALUE_ITERATOR_TYPE, 2523 JS_UINT8_ARRAY_KEY_VALUE_ITERATOR_TYPE,
2657 JS_UINT8_CLAMPED_ARRAY_KEY_VALUE_ITERATOR_TYPE, 2524 JS_UINT8_CLAMPED_ARRAY_KEY_VALUE_ITERATOR_TYPE,
2658 JS_INT8_ARRAY_KEY_VALUE_ITERATOR_TYPE, 2525 JS_INT8_ARRAY_KEY_VALUE_ITERATOR_TYPE,
2659 JS_UINT16_ARRAY_KEY_VALUE_ITERATOR_TYPE, 2526 JS_UINT16_ARRAY_KEY_VALUE_ITERATOR_TYPE,
2660 JS_INT16_ARRAY_KEY_VALUE_ITERATOR_TYPE, 2527 JS_INT16_ARRAY_KEY_VALUE_ITERATOR_TYPE,
2661 JS_UINT32_ARRAY_KEY_VALUE_ITERATOR_TYPE, 2528 JS_UINT32_ARRAY_KEY_VALUE_ITERATOR_TYPE,
2662 JS_INT32_ARRAY_KEY_VALUE_ITERATOR_TYPE, 2529 JS_INT32_ARRAY_KEY_VALUE_ITERATOR_TYPE,
2663 JS_FLOAT32_ARRAY_KEY_VALUE_ITERATOR_TYPE, 2530 JS_FLOAT32_ARRAY_KEY_VALUE_ITERATOR_TYPE,
2664 JS_FLOAT64_ARRAY_KEY_VALUE_ITERATOR_TYPE, 2531 JS_FLOAT64_ARRAY_KEY_VALUE_ITERATOR_TYPE,
2665 JS_UINT8_ARRAY_VALUE_ITERATOR_TYPE, 2532 JS_UINT8_ARRAY_VALUE_ITERATOR_TYPE,
2666 JS_UINT8_CLAMPED_ARRAY_VALUE_ITERATOR_TYPE, 2533 JS_UINT8_CLAMPED_ARRAY_VALUE_ITERATOR_TYPE,
2667 JS_INT8_ARRAY_VALUE_ITERATOR_TYPE, 2534 JS_INT8_ARRAY_VALUE_ITERATOR_TYPE,
2668 JS_UINT16_ARRAY_VALUE_ITERATOR_TYPE, 2535 JS_UINT16_ARRAY_VALUE_ITERATOR_TYPE,
2669 JS_INT16_ARRAY_VALUE_ITERATOR_TYPE, 2536 JS_INT16_ARRAY_VALUE_ITERATOR_TYPE,
2670 JS_UINT32_ARRAY_VALUE_ITERATOR_TYPE, 2537 JS_UINT32_ARRAY_VALUE_ITERATOR_TYPE,
2671 JS_INT32_ARRAY_VALUE_ITERATOR_TYPE, 2538 JS_INT32_ARRAY_VALUE_ITERATOR_TYPE,
2672 JS_FLOAT32_ARRAY_VALUE_ITERATOR_TYPE, 2539 JS_FLOAT32_ARRAY_VALUE_ITERATOR_TYPE,
2673 JS_FLOAT64_ARRAY_VALUE_ITERATOR_TYPE, 2540 JS_FLOAT64_ARRAY_VALUE_ITERATOR_TYPE,
2674 }; 2541 };
2675 2542
2676 Label uint8_values(&assembler), int8_values(&assembler), 2543 Label uint8_values(this), int8_values(this), uint16_values(this),
2677 uint16_values(&assembler), int16_values(&assembler), 2544 int16_values(this), uint32_values(this), int32_values(this),
2678 uint32_values(&assembler), int32_values(&assembler), 2545 float32_values(this), float64_values(this);
2679 float32_values(&assembler), float64_values(&assembler);
2680 Label* kInstanceTypeHandlers[] = { 2546 Label* kInstanceTypeHandlers[] = {
2681 &allocate_key_result, &uint8_values, &uint8_values, 2547 &allocate_key_result, &uint8_values, &uint8_values,
2682 &int8_values, &uint16_values, &int16_values, 2548 &int8_values, &uint16_values, &int16_values,
2683 &uint32_values, &int32_values, &float32_values, 2549 &uint32_values, &int32_values, &float32_values,
2684 &float64_values, &uint8_values, &uint8_values, 2550 &float64_values, &uint8_values, &uint8_values,
2685 &int8_values, &uint16_values, &int16_values, 2551 &int8_values, &uint16_values, &int16_values,
2686 &uint32_values, &int32_values, &float32_values, 2552 &uint32_values, &int32_values, &float32_values,
2687 &float64_values, 2553 &float64_values,
2688 }; 2554 };
2689 2555
2690 var_done.Bind(assembler.FalseConstant()); 2556 var_done.Bind(FalseConstant());
2691 assembler.Switch(instance_type, &throw_bad_receiver, kInstanceType, 2557 Switch(instance_type, &throw_bad_receiver, kInstanceType,
2692 kInstanceTypeHandlers, arraysize(kInstanceType)); 2558 kInstanceTypeHandlers, arraysize(kInstanceType));
2693 2559
2694 assembler.Bind(&uint8_values); 2560 Bind(&uint8_values);
2695 { 2561 {
2696 Node* value_uint8 = assembler.LoadFixedTypedArrayElement( 2562 Node* value_uint8 = LoadFixedTypedArrayElement(
2697 data_ptr, index, UINT8_ELEMENTS, CodeStubAssembler::SMI_PARAMETERS); 2563 data_ptr, index, UINT8_ELEMENTS, SMI_PARAMETERS);
2698 var_value.Bind(assembler.SmiFromWord32(value_uint8)); 2564 var_value.Bind(SmiFromWord32(value_uint8));
2699 assembler.Goto(&allocate_entry_if_needed); 2565 Goto(&allocate_entry_if_needed);
2700 } 2566 }
2701 2567 Bind(&int8_values);
2702 assembler.Bind(&int8_values);
2703 { 2568 {
2704 Node* value_int8 = assembler.LoadFixedTypedArrayElement( 2569 Node* value_int8 = LoadFixedTypedArrayElement(
2705 data_ptr, index, INT8_ELEMENTS, CodeStubAssembler::SMI_PARAMETERS); 2570 data_ptr, index, INT8_ELEMENTS, SMI_PARAMETERS);
2706 var_value.Bind(assembler.SmiFromWord32(value_int8)); 2571 var_value.Bind(SmiFromWord32(value_int8));
2707 assembler.Goto(&allocate_entry_if_needed); 2572 Goto(&allocate_entry_if_needed);
2708 } 2573 }
2709 2574 Bind(&uint16_values);
2710 assembler.Bind(&uint16_values);
2711 { 2575 {
2712 Node* value_uint16 = assembler.LoadFixedTypedArrayElement( 2576 Node* value_uint16 = LoadFixedTypedArrayElement(
2713 data_ptr, index, UINT16_ELEMENTS, 2577 data_ptr, index, UINT16_ELEMENTS, SMI_PARAMETERS);
2714 CodeStubAssembler::SMI_PARAMETERS); 2578 var_value.Bind(SmiFromWord32(value_uint16));
2715 var_value.Bind(assembler.SmiFromWord32(value_uint16)); 2579 Goto(&allocate_entry_if_needed);
2716 assembler.Goto(&allocate_entry_if_needed);
2717 } 2580 }
2718 2581 Bind(&int16_values);
2719 assembler.Bind(&int16_values);
2720 { 2582 {
2721 Node* value_int16 = assembler.LoadFixedTypedArrayElement( 2583 Node* value_int16 = LoadFixedTypedArrayElement(
2722 data_ptr, index, INT16_ELEMENTS, CodeStubAssembler::SMI_PARAMETERS); 2584 data_ptr, index, INT16_ELEMENTS, SMI_PARAMETERS);
2723 var_value.Bind(assembler.SmiFromWord32(value_int16)); 2585 var_value.Bind(SmiFromWord32(value_int16));
2724 assembler.Goto(&allocate_entry_if_needed); 2586 Goto(&allocate_entry_if_needed);
2725 } 2587 }
2726 2588 Bind(&uint32_values);
2727 assembler.Bind(&uint32_values);
2728 { 2589 {
2729 Node* value_uint32 = assembler.LoadFixedTypedArrayElement( 2590 Node* value_uint32 = LoadFixedTypedArrayElement(
2730 data_ptr, index, UINT32_ELEMENTS, 2591 data_ptr, index, UINT32_ELEMENTS, SMI_PARAMETERS);
2731 CodeStubAssembler::SMI_PARAMETERS); 2592 var_value.Bind(ChangeUint32ToTagged(value_uint32));
2732 var_value.Bind(assembler.ChangeUint32ToTagged(value_uint32)); 2593 Goto(&allocate_entry_if_needed);
2733 assembler.Goto(&allocate_entry_if_needed);
2734 } 2594 }
2735 assembler.Bind(&int32_values); 2595 Bind(&int32_values);
2736 { 2596 {
2737 Node* value_int32 = assembler.LoadFixedTypedArrayElement( 2597 Node* value_int32 = LoadFixedTypedArrayElement(
2738 data_ptr, index, INT32_ELEMENTS, CodeStubAssembler::SMI_PARAMETERS); 2598 data_ptr, index, INT32_ELEMENTS, SMI_PARAMETERS);
2739 var_value.Bind(assembler.ChangeInt32ToTagged(value_int32)); 2599 var_value.Bind(ChangeInt32ToTagged(value_int32));
2740 assembler.Goto(&allocate_entry_if_needed); 2600 Goto(&allocate_entry_if_needed);
2741 } 2601 }
2742 assembler.Bind(&float32_values); 2602 Bind(&float32_values);
2743 { 2603 {
2744 Node* value_float32 = assembler.LoadFixedTypedArrayElement( 2604 Node* value_float32 = LoadFixedTypedArrayElement(
2745 data_ptr, index, FLOAT32_ELEMENTS, 2605 data_ptr, index, FLOAT32_ELEMENTS, SMI_PARAMETERS);
2746 CodeStubAssembler::SMI_PARAMETERS); 2606 var_value.Bind(
2747 var_value.Bind(assembler.AllocateHeapNumberWithValue( 2607 AllocateHeapNumberWithValue(ChangeFloat32ToFloat64(value_float32)));
2748 assembler.ChangeFloat32ToFloat64(value_float32))); 2608 Goto(&allocate_entry_if_needed);
2749 assembler.Goto(&allocate_entry_if_needed);
2750 } 2609 }
2751 assembler.Bind(&float64_values); 2610 Bind(&float64_values);
2752 { 2611 {
2753 Node* value_float64 = assembler.LoadFixedTypedArrayElement( 2612 Node* value_float64 = LoadFixedTypedArrayElement(
2754 data_ptr, index, FLOAT64_ELEMENTS, 2613 data_ptr, index, FLOAT64_ELEMENTS, SMI_PARAMETERS);
2755 CodeStubAssembler::SMI_PARAMETERS); 2614 var_value.Bind(AllocateHeapNumberWithValue(value_float64));
2756 var_value.Bind(assembler.AllocateHeapNumberWithValue(value_float64)); 2615 Goto(&allocate_entry_if_needed);
2757 assembler.Goto(&allocate_entry_if_needed);
2758 } 2616 }
2759 } 2617 }
2760 } 2618 }
2761 2619
2762 assembler.Bind(&set_done); 2620 Bind(&set_done);
2763 { 2621 {
2764 assembler.StoreObjectFieldNoWriteBarrier( 2622 StoreObjectFieldNoWriteBarrier(
2765 iterator, JSArrayIterator::kIteratedObjectOffset, 2623 iterator, JSArrayIterator::kIteratedObjectOffset, UndefinedConstant());
2766 assembler.UndefinedConstant()); 2624 Goto(&allocate_iterator_result);
2767 assembler.Goto(&allocate_iterator_result);
2768 } 2625 }
2769 2626
2770 assembler.Bind(&allocate_key_result); 2627 Bind(&allocate_key_result);
2771 { 2628 {
2772 var_value.Bind(index); 2629 var_value.Bind(index);
2773 var_done.Bind(assembler.FalseConstant()); 2630 var_done.Bind(FalseConstant());
2774 assembler.Goto(&allocate_iterator_result); 2631 Goto(&allocate_iterator_result);
2775 } 2632 }
2776 2633
2777 assembler.Bind(&allocate_entry_if_needed); 2634 Bind(&allocate_entry_if_needed);
2778 { 2635 {
2779 assembler.GotoIf( 2636 GotoIf(Int32GreaterThan(instance_type,
2780 assembler.Int32GreaterThan( 2637 Int32Constant(LAST_ARRAY_KEY_VALUE_ITERATOR_TYPE)),
2781 instance_type, 2638 &allocate_iterator_result);
2782 assembler.Int32Constant(LAST_ARRAY_KEY_VALUE_ITERATOR_TYPE)),
2783 &allocate_iterator_result);
2784 2639
2785 Node* elements = assembler.AllocateFixedArray(FAST_ELEMENTS, 2640 Node* elements = AllocateFixedArray(FAST_ELEMENTS, IntPtrConstant(2));
2786 assembler.IntPtrConstant(2)); 2641 StoreFixedArrayElement(elements, 0, index, SKIP_WRITE_BARRIER);
2787 assembler.StoreFixedArrayElement(elements, 0, index, SKIP_WRITE_BARRIER); 2642 StoreFixedArrayElement(elements, 1, var_value.value(), SKIP_WRITE_BARRIER);
2788 assembler.StoreFixedArrayElement(elements, 1, var_value.value(),
2789 SKIP_WRITE_BARRIER);
2790 2643
2791 Node* entry = assembler.Allocate(JSArray::kSize); 2644 Node* entry = Allocate(JSArray::kSize);
2792 Node* map = 2645 Node* map = LoadContextElement(LoadNativeContext(context),
2793 assembler.LoadContextElement(assembler.LoadNativeContext(context), 2646 Context::JS_ARRAY_FAST_ELEMENTS_MAP_INDEX);
2794 Context::JS_ARRAY_FAST_ELEMENTS_MAP_INDEX);
2795 2647
2796 assembler.StoreMapNoWriteBarrier(entry, map); 2648 StoreMapNoWriteBarrier(entry, map);
2797 assembler.StoreObjectFieldRoot(entry, JSArray::kPropertiesOffset, 2649 StoreObjectFieldRoot(entry, JSArray::kPropertiesOffset,
2798 Heap::kEmptyFixedArrayRootIndex); 2650 Heap::kEmptyFixedArrayRootIndex);
2799 assembler.StoreObjectFieldNoWriteBarrier(entry, JSArray::kElementsOffset, 2651 StoreObjectFieldNoWriteBarrier(entry, JSArray::kElementsOffset, elements);
2800 elements); 2652 StoreObjectFieldNoWriteBarrier(entry, JSArray::kLengthOffset,
2801 assembler.StoreObjectFieldNoWriteBarrier( 2653 SmiConstant(Smi::FromInt(2)));
2802 entry, JSArray::kLengthOffset, assembler.SmiConstant(Smi::FromInt(2)));
2803 2654
2804 var_value.Bind(entry); 2655 var_value.Bind(entry);
2805 assembler.Goto(&allocate_iterator_result); 2656 Goto(&allocate_iterator_result);
2806 } 2657 }
2807 2658
2808 assembler.Bind(&allocate_iterator_result); 2659 Bind(&allocate_iterator_result);
2809 { 2660 {
2810 Node* result = assembler.Allocate(JSIteratorResult::kSize); 2661 Node* result = Allocate(JSIteratorResult::kSize);
2811 Node* map = 2662 Node* map = LoadContextElement(LoadNativeContext(context),
2812 assembler.LoadContextElement(assembler.LoadNativeContext(context), 2663 Context::ITERATOR_RESULT_MAP_INDEX);
2813 Context::ITERATOR_RESULT_MAP_INDEX); 2664 StoreMapNoWriteBarrier(result, map);
2814 assembler.StoreMapNoWriteBarrier(result, map); 2665 StoreObjectFieldRoot(result, JSIteratorResult::kPropertiesOffset,
2815 assembler.StoreObjectFieldRoot(result, JSIteratorResult::kPropertiesOffset, 2666 Heap::kEmptyFixedArrayRootIndex);
2816 Heap::kEmptyFixedArrayRootIndex); 2667 StoreObjectFieldRoot(result, JSIteratorResult::kElementsOffset,
2817 assembler.StoreObjectFieldRoot(result, JSIteratorResult::kElementsOffset, 2668 Heap::kEmptyFixedArrayRootIndex);
2818 Heap::kEmptyFixedArrayRootIndex); 2669 StoreObjectFieldNoWriteBarrier(result, JSIteratorResult::kValueOffset,
2819 assembler.StoreObjectFieldNoWriteBarrier( 2670 var_value.value());
2820 result, JSIteratorResult::kValueOffset, var_value.value()); 2671 StoreObjectFieldNoWriteBarrier(result, JSIteratorResult::kDoneOffset,
2821 assembler.StoreObjectFieldNoWriteBarrier( 2672 var_done.value());
2822 result, JSIteratorResult::kDoneOffset, var_done.value()); 2673 Return(result);
2823 assembler.Return(result);
2824 } 2674 }
2825 2675
2826 assembler.Bind(&throw_bad_receiver); 2676 Bind(&throw_bad_receiver);
2827 { 2677 {
2828 // The {receiver} is not a valid JSArrayIterator. 2678 // The {receiver} is not a valid JSArrayIterator.
2829 assembler.CallRuntime(Runtime::kThrowIncompatibleMethodReceiver, context, 2679 CallRuntime(Runtime::kThrowIncompatibleMethodReceiver, context,
2830 assembler.HeapConstant(operation), iterator); 2680 HeapConstant(operation), iterator);
2831 assembler.Unreachable(); 2681 Unreachable();
2832 } 2682 }
2833 2683
2834 assembler.Bind(&if_isdetached); 2684 Bind(&if_isdetached);
2835 { 2685 {
2836 Node* message = assembler.SmiConstant(MessageTemplate::kDetachedOperation); 2686 Node* message = SmiConstant(MessageTemplate::kDetachedOperation);
2837 assembler.CallRuntime(Runtime::kThrowTypeError, context, message, 2687 CallRuntime(Runtime::kThrowTypeError, context, message,
2838 assembler.HeapConstant(operation)); 2688 HeapConstant(operation));
2839 assembler.Unreachable(); 2689 Unreachable();
2840 } 2690 }
2841 } 2691 }
2842 2692
2843 } // namespace internal 2693 } // namespace internal
2844 } // namespace v8 2694 } // namespace v8
OLDNEW
« no previous file with comments | « no previous file | src/builtins/builtins-conversion.cc » ('j') | src/builtins/builtins-sharedarraybuffer.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698