| OLD | NEW | 
|---|
| 1 // Copyright 2016 the V8 project authors. All rights reserved. | 1 // Copyright 2016 the V8 project authors. All rights reserved. | 
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be | 
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. | 
| 4 | 4 | 
| 5 #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  Loading... | 
| 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  Loading... | 
| 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  Loading... | 
| 1910 | 1885 | 
| 1911     // Search for HeapNumber | 1886     // Search for HeapNumber | 
| 1912     Bind(¬_nan_loop); | 1887     Bind(¬_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(¬_nan_loop); | 1901       Goto(¬_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), ¬_smi); | 
| 2109 | 2067     search_num.Bind(SmiToFloat64(search_element)); | 
| 2110     assembler.GotoIfNot(assembler.TaggedIsSmi(search_element), ¬_smi); | 2068     Goto(&heap_num_loop); | 
| 2111     search_num.Bind(assembler.SmiToFloat64(search_element)); | 2069 | 
| 2112     assembler.Goto(&heap_num_loop); | 2070     Bind(¬_smi); | 
| 2113 | 2071     Node* map = LoadMap(search_element); | 
| 2114     assembler.Bind(¬_smi); | 2072     GotoIfNot(IsHeapNumberMap(map), ¬_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), ¬_heap_num); | 2076     Bind(¬_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(¬_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                            ¬_nan_loop); | 
| 2139     } | 2097 | 
| 2140 | 2098       Bind(¬_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                                      ¬_nan_loop); |  | 
| 2160 |  | 
| 2161       assembler.Bind(¬_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), ¬_smi); | 
| 2168             assembler.LoadFixedArrayElement(elements, index_var.value()); | 2105         Branch(Float64Equal(search_num.value(), SmiToFloat64(element_k)), | 
| 2169         assembler.GotoIfNot(assembler.TaggedIsSmi(element_k), ¬_smi); | 2106                &return_found, &continue_loop); | 
| 2170         assembler.Branch( | 2107 | 
| 2171             assembler.Float64Equal(search_num.value(), | 2108         Bind(¬_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(¬_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(¬_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(¬_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(¬_nan_loop); | 
| 2223     search_num.Bind(assembler.SmiToFloat64(search_element)); | 2148 | 
| 2224     assembler.Goto(¬_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, ¬_nan_loop); | 
| 2230 |  | 
| 2231     search_num.Bind(assembler.LoadHeapNumberValue(search_element)); |  | 
| 2232 |  | 
| 2233     assembler.BranchIfFloat64IsNaN(search_num.value(), &return_not_found, |  | 
| 2234                                    ¬_nan_loop); |  | 
| 2235 | 2155 | 
| 2236     // Search for HeapNumber | 2156     // Search for HeapNumber | 
| 2237     assembler.Bind(¬_nan_loop); | 2157     Bind(¬_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(¬_nan_loop); | 
| 2247       assembler.Bind(&continue_loop); | 2167     } | 
| 2248       index_var.Bind(assembler.IntPtrAdd(index_var.value(), intptr_one)); | 2168   } | 
| 2249       assembler.Goto(¬_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(¬_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(¬_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, ¬_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                                    ¬_nan_loop); |  | 
| 2271 | 2185 | 
| 2272     // Search for HeapNumber | 2186     // Search for HeapNumber | 
| 2273     assembler.Bind(¬_nan_loop); | 2187     Bind(¬_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(¬_nan_loop); | 2202       Goto(¬_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 | 
| OLD | NEW | 
|---|