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

Side by Side Diff: src/code-stub-assembler.cc

Issue 2405253006: [builtins] implement Array.prototype[@@iterator] in TFJ builtins (Closed)
Patch Set: rebase and get tests passing Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2016 the V8 project authors. All rights reserved. 1 // Copyright 2016 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/code-stub-assembler.h" 5 #include "src/code-stub-assembler.h"
6 #include "src/code-factory.h" 6 #include "src/code-factory.h"
7 #include "src/frames-inl.h" 7 #include "src/frames-inl.h"
8 #include "src/frames.h" 8 #include "src/frames.h"
9 #include "src/ic/handler-configuration.h" 9 #include "src/ic/handler-configuration.h"
10 #include "src/ic/stub-cache.h" 10 #include "src/ic/stub-cache.h"
(...skipping 1015 matching lines...) Expand 10 before | Expand all | Expand 10 after
1026 Node* CodeStubAssembler::LoadFixedArrayElement(Node* object, Node* index_node, 1026 Node* CodeStubAssembler::LoadFixedArrayElement(Node* object, Node* index_node,
1027 int additional_offset, 1027 int additional_offset,
1028 ParameterMode parameter_mode) { 1028 ParameterMode parameter_mode) {
1029 int32_t header_size = 1029 int32_t header_size =
1030 FixedArray::kHeaderSize + additional_offset - kHeapObjectTag; 1030 FixedArray::kHeaderSize + additional_offset - kHeapObjectTag;
1031 Node* offset = ElementOffsetFromIndex(index_node, FAST_HOLEY_ELEMENTS, 1031 Node* offset = ElementOffsetFromIndex(index_node, FAST_HOLEY_ELEMENTS,
1032 parameter_mode, header_size); 1032 parameter_mode, header_size);
1033 return Load(MachineType::AnyTagged(), object, offset); 1033 return Load(MachineType::AnyTagged(), object, offset);
1034 } 1034 }
1035 1035
1036 Node* CodeStubAssembler::LoadFixedTypedArrayElement(
1037 Node* data_pointer, Node* index_node, ElementsKind elements_kind,
1038 ParameterMode parameter_mode) {
1039 Node* offset =
1040 ElementOffsetFromIndex(index_node, elements_kind, parameter_mode, 0);
1041 MachineType type;
1042 switch (elements_kind) {
1043 case UINT8_ELEMENTS: /* fall through */
1044 case UINT8_CLAMPED_ELEMENTS:
1045 type = MachineType::Uint8();
1046 break;
1047 case INT8_ELEMENTS:
1048 type = MachineType::Int8();
1049 break;
1050 case UINT16_ELEMENTS:
1051 type = MachineType::Uint16();
1052 break;
1053 case INT16_ELEMENTS:
1054 type = MachineType::Int16();
1055 break;
1056 case UINT32_ELEMENTS:
1057 type = MachineType::Uint32();
1058 break;
1059 case INT32_ELEMENTS:
1060 type = MachineType::Int32();
1061 break;
1062 case FLOAT32_ELEMENTS:
1063 type = MachineType::Float32();
1064 break;
1065 case FLOAT64_ELEMENTS:
1066 type = MachineType::Float64();
1067 break;
1068 default:
1069 UNREACHABLE();
1070 }
1071 return Load(type, data_pointer, offset);
1072 }
1073
1036 Node* CodeStubAssembler::LoadAndUntagToWord32FixedArrayElement( 1074 Node* CodeStubAssembler::LoadAndUntagToWord32FixedArrayElement(
1037 Node* object, Node* index_node, int additional_offset, 1075 Node* object, Node* index_node, int additional_offset,
1038 ParameterMode parameter_mode) { 1076 ParameterMode parameter_mode) {
1039 int32_t header_size = 1077 int32_t header_size =
1040 FixedArray::kHeaderSize + additional_offset - kHeapObjectTag; 1078 FixedArray::kHeaderSize + additional_offset - kHeapObjectTag;
1041 #if V8_TARGET_LITTLE_ENDIAN 1079 #if V8_TARGET_LITTLE_ENDIAN
1042 if (Is64()) { 1080 if (Is64()) {
1043 header_size += kPointerSize / 2; 1081 header_size += kPointerSize / 2;
1044 } 1082 }
1045 #endif 1083 #endif
(...skipping 6396 matching lines...) Expand 10 before | Expand all | Expand 10 after
7442 Bind(&return_runtime); 7480 Bind(&return_runtime);
7443 { 7481 {
7444 result.Bind(CallRuntime(Runtime::kInstanceOf, context, object, callable)); 7482 result.Bind(CallRuntime(Runtime::kInstanceOf, context, object, callable));
7445 Goto(&end); 7483 Goto(&end);
7446 } 7484 }
7447 7485
7448 Bind(&end); 7486 Bind(&end);
7449 return result.value(); 7487 return result.value();
7450 } 7488 }
7451 7489
7490 compiler::Node* CodeStubAssembler::NumberInc(compiler::Node* value) {
7491 Variable var_result(this, MachineRepresentation::kTagged),
7492 var_finc_value(this, MachineRepresentation::kFloat64);
7493 Label if_issmi(this), if_isnotsmi(this), do_finc(this), end(this);
7494 Branch(TaggedIsSmi(value), &if_issmi, &if_isnotsmi);
7495
7496 Bind(&if_issmi);
7497 {
7498 // Try fast Smi addition first.
7499 Node* one = SmiConstant(Smi::FromInt(1));
7500 Node* pair = IntPtrAddWithOverflow(BitcastTaggedToWord(value),
7501 BitcastTaggedToWord(one));
7502 Node* overflow = Projection(1, pair);
7503
7504 // Check if the Smi addition overflowed.
7505 Label if_overflow(this), if_notoverflow(this);
7506 Branch(overflow, &if_overflow, &if_notoverflow);
7507
7508 Bind(&if_notoverflow);
7509 var_result.Bind(Projection(0, pair));
7510 Goto(&end);
7511
7512 Bind(&if_overflow);
7513 {
7514 var_finc_value.Bind(SmiToFloat64(value));
7515 Goto(&do_finc);
7516 }
7517 }
7518
7519 Bind(&if_isnotsmi);
7520 {
7521 // Check if the value is a HeapNumber.
7522 Assert(IsHeapNumberMap(LoadMap(value)));
7523
7524 // Load the HeapNumber value.
7525 var_finc_value.Bind(LoadHeapNumberValue(value));
7526 Goto(&do_finc);
7527 }
7528
7529 Bind(&do_finc);
7530 {
7531 Node* finc_value = var_finc_value.value();
7532 Node* one = Float64Constant(1.0);
7533 Node* finc_result = Float64Add(finc_value, one);
7534 var_result.Bind(ChangeFloat64ToTagged(finc_result));
7535 Goto(&end);
7536 }
7537
7538 Bind(&end);
7539 return var_result.value();
7540 }
7541
7542 compiler::Node* CodeStubAssembler::CreateArrayIterator(
7543 compiler::Node* array, compiler::Node* array_map,
7544 compiler::Node* array_type, compiler::Node* context, IterationKind mode) {
7545 int kBaseMapIndex;
7546 switch (mode) {
7547 case IterationKind::kKeys:
7548 kBaseMapIndex = Context::TYPED_ARRAY_KEY_ITERATOR_MAP_INDEX;
7549 break;
7550 case IterationKind::kValues:
7551 kBaseMapIndex = Context::UINT8_ARRAY_VALUE_ITERATOR_MAP_INDEX;
7552 break;
7553 case IterationKind::kEntries:
7554 kBaseMapIndex = Context::UINT8_ARRAY_KEY_VALUE_ITERATOR_MAP_INDEX;
7555 break;
7556 }
7557
7558 // Fast Array iterator map index:
7559 // (kBaseIndex + kFastIteratorOffset) + ElementsKind (for JSArrays)
7560 // kBaseIndex + (ElementsKind - UINT8_ELEMENTS) (for JSTypedArrays)
7561 const int kFastIteratorOffset =
7562 Context::FAST_SMI_ARRAY_VALUE_ITERATOR_MAP_INDEX -
7563 Context::UINT8_ARRAY_VALUE_ITERATOR_MAP_INDEX;
7564 STATIC_ASSERT(kFastIteratorOffset ==
7565 (Context::FAST_SMI_ARRAY_KEY_VALUE_ITERATOR_MAP_INDEX -
7566 Context::UINT8_ARRAY_KEY_VALUE_ITERATOR_MAP_INDEX));
7567
7568 // Slow Array iterator map index: (kBaseIndex + kSlowIteratorOffset)
7569 const int kSlowIteratorOffset =
7570 Context::GENERIC_ARRAY_VALUE_ITERATOR_MAP_INDEX -
7571 Context::UINT8_ARRAY_VALUE_ITERATOR_MAP_INDEX;
7572 STATIC_ASSERT(kSlowIteratorOffset ==
7573 (Context::GENERIC_ARRAY_KEY_VALUE_ITERATOR_MAP_INDEX -
7574 Context::UINT8_ARRAY_KEY_VALUE_ITERATOR_MAP_INDEX));
7575
7576 // Assert: Type(array) is Object
7577 Assert(Int32GreaterThanOrEqual(array_type,
7578 Int32Constant(FIRST_JS_RECEIVER_TYPE)));
7579
7580 Variable var_result(this, MachineRepresentation::kTagged);
7581 Variable var_map_index(this, MachineType::PointerRepresentation());
7582
7583 Label return_result(this);
7584 Label allocate_array_iterator(this);
7585 Label allocate_typed_array_iterator(this);
7586
7587 if (mode == IterationKind::kKeys) {
7588 // There are only two key iterator maps, branch depending on whether or not
7589 // the receiver is a TypedArray or not.
7590 Label if_istypedarray(this), if_isgeneric(this);
7591 Branch(Word32Equal(array_type, Int32Constant(JS_TYPED_ARRAY_TYPE)),
7592 &if_istypedarray, &if_isgeneric);
7593 Bind(&if_istypedarray);
7594 var_map_index.Bind(
7595 IntPtrConstant(Context::TYPED_ARRAY_KEY_ITERATOR_MAP_INDEX));
7596 Goto(&allocate_typed_array_iterator);
7597
7598 Bind(&if_isgeneric);
7599 var_map_index.Bind(
7600 IntPtrConstant(Context::GENERIC_ARRAY_KEY_ITERATOR_MAP_INDEX));
7601 Goto(&allocate_array_iterator);
7602 } else {
7603 Label if_istypedarray(this), if_isgeneric(this);
7604 Branch(Word32Equal(array_type, Int32Constant(JS_TYPED_ARRAY_TYPE)),
7605 &if_istypedarray, &if_isgeneric);
7606
7607 Bind(&if_isgeneric);
7608 {
7609 Label if_isfast(this), if_isslow(this);
7610 BranchIfFastJSArray(array, context, &if_isfast, &if_isslow);
7611
7612 Bind(&if_isfast);
7613 {
7614 Node* map_index =
7615 IntPtrAdd(IntPtrConstant(kBaseMapIndex + kFastIteratorOffset),
7616 LoadMapElementsKind(array_map));
7617 Assert(IntPtrGreaterThanOrEqual(
7618 map_index, IntPtrConstant(kBaseMapIndex + kFastIteratorOffset)));
7619 Assert(IntPtrLessThan(
7620 map_index, IntPtrConstant(kBaseMapIndex + kSlowIteratorOffset)));
7621
7622 var_map_index.Bind(map_index);
7623 Goto(&allocate_array_iterator);
7624 }
7625
7626 Bind(&if_isslow);
7627 {
7628 Node* map_index = IntPtrAdd(IntPtrConstant(kBaseMapIndex),
7629 IntPtrConstant(kSlowIteratorOffset));
7630 var_map_index.Bind(map_index);
7631 Goto(&allocate_array_iterator);
7632 }
7633 }
7634
7635 Bind(&if_istypedarray);
7636 {
7637 Node* map_index =
7638 IntPtrAdd(IntPtrConstant(kBaseMapIndex - UINT8_ELEMENTS),
7639 LoadMapElementsKind(array_map));
7640 Assert(IntPtrLessThan(
7641 map_index, IntPtrConstant(kBaseMapIndex + kFastIteratorOffset)));
7642 Assert(
7643 IntPtrGreaterThanOrEqual(map_index, IntPtrConstant(kBaseMapIndex)));
7644 var_map_index.Bind(map_index);
7645 Goto(&allocate_typed_array_iterator);
7646 }
7647 }
7648
7649 Bind(&allocate_array_iterator);
7650 {
7651 Node* map =
7652 LoadFixedArrayElement(LoadNativeContext(context), var_map_index.value(),
7653 0, CodeStubAssembler::INTPTR_PARAMETERS);
7654 var_result.Bind(AllocateJSArrayIterator(array, array_map, map));
7655 Goto(&return_result);
7656 }
7657
7658 Bind(&allocate_typed_array_iterator);
7659 {
7660 Node* map =
7661 LoadFixedArrayElement(LoadNativeContext(context), var_map_index.value(),
7662 0, CodeStubAssembler::INTPTR_PARAMETERS);
7663 var_result.Bind(AllocateJSTypedArrayIterator(array, map));
7664 Goto(&return_result);
7665 }
7666
7667 Bind(&return_result);
7668 return var_result.value();
7669 }
7670
7671 compiler::Node* CodeStubAssembler::AllocateJSArrayIterator(
7672 compiler::Node* array, compiler::Node* array_map, compiler::Node* map) {
7673 Node* iterator = Allocate(JSArrayIterator::kSize);
7674 StoreMapNoWriteBarrier(iterator, map);
7675 StoreObjectFieldRoot(iterator, JSArrayIterator::kPropertiesOffset,
7676 Heap::kEmptyFixedArrayRootIndex);
7677 StoreObjectFieldRoot(iterator, JSArrayIterator::kElementsOffset,
7678 Heap::kEmptyFixedArrayRootIndex);
7679 StoreObjectFieldNoWriteBarrier(iterator,
7680 JSArrayIterator::kIteratedObjectOffset, array);
7681 StoreObjectFieldNoWriteBarrier(iterator, JSArrayIterator::kNextIndexOffset,
7682 SmiConstant(Smi::FromInt(0)));
7683 StoreObjectFieldNoWriteBarrier(
7684 iterator, JSArrayIterator::kIteratedObjectMapOffset, array_map);
7685 return iterator;
7686 }
7687
7688 compiler::Node* CodeStubAssembler::AllocateJSTypedArrayIterator(
7689 compiler::Node* array, compiler::Node* map) {
7690 Node* iterator = Allocate(JSTypedArrayIterator::kSize);
7691 StoreMapNoWriteBarrier(iterator, map);
7692 StoreObjectFieldRoot(iterator, JSTypedArrayIterator::kPropertiesOffset,
7693 Heap::kEmptyFixedArrayRootIndex);
7694 StoreObjectFieldRoot(iterator, JSTypedArrayIterator::kElementsOffset,
7695 Heap::kEmptyFixedArrayRootIndex);
7696 StoreObjectFieldNoWriteBarrier(
7697 iterator, JSTypedArrayIterator::kIteratedObjectOffset, array);
7698 StoreObjectFieldNoWriteBarrier(iterator,
7699 JSTypedArrayIterator::kNextIndexOffset,
7700 SmiConstant(Smi::FromInt(0)));
7701 return iterator;
7702 }
7703
7452 } // namespace internal 7704 } // namespace internal
7453 } // namespace v8 7705 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698