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

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

Issue 2358263002: [builtins] migrate C++ String Iterator builtins to baseline TurboFan (Closed)
Patch Set: v3 (try again, but probably not ._.) 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/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 9
10 namespace v8 { 10 namespace v8 {
(...skipping 598 matching lines...) Expand 10 before | Expand all | Expand 10 after
609 typedef compiler::Node Node; 609 typedef compiler::Node Node;
610 610
611 Node* receiver = assembler->Parameter(0); 611 Node* receiver = assembler->Parameter(0);
612 Node* context = assembler->Parameter(3); 612 Node* context = assembler->Parameter(3);
613 613
614 Node* result = assembler->ToThisValue( 614 Node* result = assembler->ToThisValue(
615 context, receiver, PrimitiveType::kString, "String.prototype.valueOf"); 615 context, receiver, PrimitiveType::kString, "String.prototype.valueOf");
616 assembler->Return(result); 616 assembler->Return(result);
617 } 617 }
618 618
619 BUILTIN(StringPrototypeIterator) { 619 void Builtins::Generate_StringPrototypeIterator(CodeStubAssembler* assembler) {
620 HandleScope scope(isolate); 620 typedef CodeStubAssembler::Label Label;
621 TO_THIS_STRING(object, "String.prototype[Symbol.iterator]"); 621 typedef compiler::Node Node;
622 typedef CodeStubAssembler::Variable Variable;
622 623
623 Handle<String> string; 624 Variable var_string(assembler, MachineRepresentation::kTagged);
624 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, string, 625 Variable var_index(assembler, MachineRepresentation::kWord32);
625 Object::ToString(isolate, object));
626 626
627 return *isolate->factory()->NewJSStringIterator(string); 627 Variable* loop_inputs[] = {&var_string, &var_index};
628 Label loop(assembler, 2, loop_inputs);
629 Label allocate_iterator(assembler);
630
631 Node* receiver = assembler->Parameter(0);
632 Node* context = assembler->Parameter(3);
633
634 Node* string =
635 assembler->ToThisValue(context, receiver, PrimitiveType::kString,
636 "String.prototype[Symbol.iterator]");
637 var_string.Bind(string);
638 var_index.Bind(assembler->Int32Constant(0));
639
640 assembler->Goto(&loop);
641 assembler->Bind(&loop);
642 {
643 // Load the instance type of the {string}.
644 Node* string_instance_type = assembler->LoadInstanceType(string);
645
646 // Check if the {string} is a SeqString.
647 Label if_stringisnotsequential(assembler);
648 assembler->Branch(assembler->Word32Equal(
649 assembler->Word32And(string_instance_type,
650 assembler->Int32Constant(
651 kStringRepresentationMask)),
652 assembler->Int32Constant(kSeqStringTag)),
653 &allocate_iterator, &if_stringisnotsequential);
654
655 assembler->Bind(&if_stringisnotsequential);
656 {
657 // Check if the {string} is a ConsString.
658 Label if_stringiscons(assembler), if_stringisnotcons(assembler);
659 assembler->Branch(
660 assembler->Word32Equal(
661 assembler->Word32And(
662 string_instance_type,
663 assembler->Int32Constant(kStringRepresentationMask)),
664 assembler->Int32Constant(kConsStringTag)),
665 &if_stringiscons, &if_stringisnotcons);
666
667 assembler->Bind(&if_stringiscons);
668 {
669 // Flatten cons-string and finish.
670 var_string.Bind(assembler->CallRuntime(
671 Runtime::kFlattenString, assembler->NoContextConstant(), string));
672 assembler->Goto(&allocate_iterator);
673 }
674
675 assembler->Bind(&if_stringisnotcons);
676 {
677 // Check if the {string} is an ExternalString.
678 Label if_stringisnotexternal(assembler);
679 assembler->Branch(
680 assembler->Word32Equal(
681 assembler->Word32And(
682 string_instance_type,
683 assembler->Int32Constant(kStringRepresentationMask)),
684 assembler->Int32Constant(kExternalStringTag)),
685 &allocate_iterator, &if_stringisnotexternal);
686
687 assembler->Bind(&if_stringisnotexternal);
688 {
689 // The {string} is a SlicedString, continue with its parent.
690 Node* index = var_index.value();
691 Node* string_offset = assembler->LoadAndUntagObjectField(
692 string, SlicedString::kOffsetOffset);
693 Node* string_parent =
694 assembler->LoadObjectField(string, SlicedString::kParentOffset);
695 var_index.Bind(assembler->IntPtrAdd(index, string_offset));
696 var_string.Bind(string_parent);
697 assembler->Goto(&loop);
698 }
699 }
700 }
701 }
702
703 assembler->Bind(&allocate_iterator);
704 {
705 Node* native_context = assembler->LoadNativeContext(context);
706 Node* index = assembler->Int32Constant(Context::STRING_ITERATOR_MAP_INDEX);
707 Node* map = assembler->LoadFixedArrayElement(
708 native_context, index, 0, CodeStubAssembler::INTPTR_PARAMETERS);
709 Node* js_iter = assembler->Allocate(JSStringIterator::kSize);
710 assembler->StoreMapNoWriteBarrier(js_iter, map);
711 assembler->StoreObjectFieldRoot(js_iter, JSValue::kPropertiesOffset,
712 Heap::kEmptyFixedArrayRootIndex);
713 assembler->StoreObjectFieldRoot(js_iter, JSObject::kElementsOffset,
714 Heap::kEmptyFixedArrayRootIndex);
715 assembler->StoreObjectField(js_iter, JSStringIterator::kStringOffset,
716 var_string.value());
717
718 assembler->StoreObjectField(js_iter, JSStringIterator::kNextIndexOffset,
719 assembler->SmiFromWord32(var_index.value()));
720 assembler->Return(js_iter);
721 }
628 } 722 }
629 723
630 BUILTIN(StringIteratorPrototypeNext) { 724 void Builtins::Generate_StringIteratorPrototypeNext(
631 HandleScope scope(isolate); 725 CodeStubAssembler* assembler) {
726 typedef CodeStubAssembler::Label Label;
727 typedef compiler::Node Node;
728 typedef CodeStubAssembler::Variable Variable;
632 729
633 if (!args.receiver()->IsJSStringIterator()) { 730 Variable var_value(assembler, MachineRepresentation::kTagged);
634 Handle<String> reason = isolate->factory()->NewStringFromAsciiChecked( 731 Variable var_done(assembler, MachineRepresentation::kTagged);
635 "String Iterator.prototype.next");
636 THROW_NEW_ERROR_RETURN_FAILURE(
637 isolate,
638 NewTypeError(MessageTemplate::kIncompatibleMethodReceiver, reason));
639 }
640 Handle<JSStringIterator> iterator =
641 Handle<JSStringIterator>::cast(args.receiver());
642 Handle<String> string(iterator->string());
643 732
644 int position = iterator->index(); 733 var_value.Bind(assembler->UndefinedConstant());
645 int length = string->length(); 734 var_done.Bind(assembler->BooleanConstant(true));
646 735
647 if (position < length) { 736 Label throw_bad_receiver(assembler), next_codepoint(assembler),
648 uint16_t lead = string->Get(position); 737 return_result(assembler);
649 if (lead >= 0xD800 && lead <= 0xDBFF && position + 1 < length) {
650 uint16_t trail = string->Get(position + 1);
651 if (V8_LIKELY(trail >= 0xDC00 && trail <= 0xDFFF)) {
652 // Return surrogate pair code units
653 iterator->set_index(position + 2);
654 Handle<String> value =
655 isolate->factory()->NewSurrogatePairString(lead, trail);
656 return *isolate->factory()->NewJSIteratorResult(value, false);
657 }
658 }
659 738
660 // Return single code unit 739 Node* js_iter = assembler->Parameter(0);
Benedikt Meurer 2016/09/22 03:48:23 Nit: rename js_iter to iterator.
661 iterator->set_index(position + 1); 740 Node* context = assembler->Parameter(3);
662 Handle<String> value = 741
663 isolate->factory()->LookupSingleCharacterStringFromCode(lead); 742 assembler->GotoIf(assembler->WordIsSmi(js_iter), &throw_bad_receiver);
664 return *isolate->factory()->NewJSIteratorResult(value, false); 743 assembler->GotoUnless(
744 assembler->WordEqual(assembler->LoadInstanceType(js_iter),
745 assembler->Int32Constant(JS_STRING_ITERATOR_TYPE)),
746 &throw_bad_receiver);
747
748 Node* string =
749 assembler->LoadObjectField(js_iter, JSStringIterator::kStringOffset);
750 Node* position = assembler->LoadAndUntagObjectField(
751 js_iter, JSStringIterator::kNextIndexOffset);
752 Node* length =
753 assembler->LoadAndUntagObjectField(string, String::kLengthOffset);
754
755 assembler->Branch(assembler->Int32LessThan(position, length), &next_codepoint,
756 &return_result);
757
758 assembler->Bind(&next_codepoint);
759 {
760 Node* value = assembler->StringFromCodePointAt(string, length, position);
761 Node* length =
762 assembler->LoadAndUntagObjectField(value, String::kLengthOffset);
763 assembler->StoreObjectFieldNoWriteBarrier(
764 js_iter, JSStringIterator::kNextIndexOffset,
765 assembler->SmiFromWord32(assembler->Int32Add(position, length)));
766 var_value.Bind(value);
767 var_done.Bind(assembler->BooleanConstant(false));
768 assembler->Goto(&return_result);
665 } 769 }
666 770
667 iterator->set_string(isolate->heap()->empty_string()); 771 assembler->Bind(&return_result);
772 {
773 Node* native_context = assembler->LoadNativeContext(context);
774 Node* map = assembler->LoadFixedArrayElement(
775 native_context,
776 assembler->Int32Constant(Context::ITERATOR_RESULT_MAP_INDEX), 0,
Benedikt Meurer 2016/09/22 03:48:23 This must be IntPtrConstant then.
777 CodeStubAssembler::INTPTR_PARAMETERS);
778 Node* iterator = assembler->Allocate(JSIteratorResult::kSize);
Benedikt Meurer 2016/09/22 03:48:22 Nit: Rename iterator to result.
779 assembler->StoreMapNoWriteBarrier(iterator, map);
780 assembler->StoreObjectFieldRoot(iterator,
781 JSIteratorResult::kPropertiesOffset,
782 Heap::kEmptyFixedArrayRootIndex);
783 assembler->StoreObjectFieldRoot(iterator, JSIteratorResult::kElementsOffset,
784 Heap::kEmptyFixedArrayRootIndex);
785 assembler->StoreObjectField(iterator, JSIteratorResult::kValueOffset,
786 var_value.value());
787 assembler->StoreObjectField(iterator, JSIteratorResult::kDoneOffset,
788 var_done.value());
789 assembler->Return(iterator);
790 }
668 791
669 return *isolate->factory()->NewJSIteratorResult( 792 assembler->Bind(&throw_bad_receiver);
670 isolate->factory()->undefined_value(), true); 793 {
794 // The {receiver} is not a valid JSGeneratorObject.
795 Node* result = assembler->CallRuntime(
796 Runtime::kThrowIncompatibleMethodReceiver, context,
797 assembler->HeapConstant(assembler->factory()->NewStringFromAsciiChecked(
798 "String Iterator.prototype.next", TENURED)),
799 js_iter);
800 assembler->Return(result); // Never reached.
801 }
671 } 802 }
672 803
673 } // namespace internal 804 } // namespace internal
674 } // namespace v8 805 } // namespace v8
OLDNEW
« no previous file with comments | « src/builtins/builtins.h ('k') | src/code-stub-assembler.h » ('j') | src/code-stub-assembler.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698