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

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

Issue 2385423005: [stubs] Implement fast TF Builtin for Object.create (Closed)
Patch Set: removing unused symbol 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
« no previous file with comments | « src/code-stub-assembler.h ('k') | src/compiler/code-assembler.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2016 the V8 project authors. All rights reserved. 1 // Copyright 2016 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4
5 #include "src/code-stub-assembler.h" 4 #include "src/code-stub-assembler.h"
6 #include "src/code-factory.h" 5 #include "src/code-factory.h"
7 #include "src/frames-inl.h" 6 #include "src/frames-inl.h"
8 #include "src/frames.h" 7 #include "src/frames.h"
9 #include "src/ic/handler-configuration.h" 8 #include "src/ic/handler-configuration.h"
10 #include "src/ic/stub-cache.h" 9 #include "src/ic/stub-cache.h"
11 10
12 namespace v8 { 11 namespace v8 {
13 namespace internal { 12 namespace internal {
14 13
(...skipping 503 matching lines...) Expand 10 before | Expand all | Expand 10 after
518 Node* CodeStubAssembler::TaggedIsSmi(Node* a) { 517 Node* CodeStubAssembler::TaggedIsSmi(Node* a) {
519 return WordEqual(WordAnd(BitcastTaggedToWord(a), IntPtrConstant(kSmiTagMask)), 518 return WordEqual(WordAnd(BitcastTaggedToWord(a), IntPtrConstant(kSmiTagMask)),
520 IntPtrConstant(0)); 519 IntPtrConstant(0));
521 } 520 }
522 521
523 Node* CodeStubAssembler::WordIsPositiveSmi(Node* a) { 522 Node* CodeStubAssembler::WordIsPositiveSmi(Node* a) {
524 return WordEqual(WordAnd(a, IntPtrConstant(kSmiTagMask | kSmiSignMask)), 523 return WordEqual(WordAnd(a, IntPtrConstant(kSmiTagMask | kSmiSignMask)),
525 IntPtrConstant(0)); 524 IntPtrConstant(0));
526 } 525 }
527 526
527 Node* CodeStubAssembler::WordIsWordAligned(Node* word) {
528 return WordEqual(IntPtrConstant(0),
529 WordAnd(word, IntPtrConstant((1 << kPointerSizeLog2) - 1)));
530 }
531
528 void CodeStubAssembler::BranchIfSimd128Equal(Node* lhs, Node* lhs_map, 532 void CodeStubAssembler::BranchIfSimd128Equal(Node* lhs, Node* lhs_map,
529 Node* rhs, Node* rhs_map, 533 Node* rhs, Node* rhs_map,
530 Label* if_equal, 534 Label* if_equal,
531 Label* if_notequal) { 535 Label* if_notequal) {
532 Label if_mapsame(this), if_mapnotsame(this); 536 Label if_mapsame(this), if_mapnotsame(this);
533 Branch(WordEqual(lhs_map, rhs_map), &if_mapsame, &if_mapnotsame); 537 Branch(WordEqual(lhs_map, rhs_map), &if_mapsame, &if_mapnotsame);
534 538
535 Bind(&if_mapsame); 539 Bind(&if_mapsame);
536 { 540 {
537 // Both {lhs} and {rhs} are Simd128Values with the same map, need special 541 // Both {lhs} and {rhs} are Simd128Values with the same map, need special
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
618 GotoIf(Int32LessThanOrEqual(LoadMapInstanceType(prototype_map), 622 GotoIf(Int32LessThanOrEqual(LoadMapInstanceType(prototype_map),
619 Int32Constant(LAST_CUSTOM_ELEMENTS_RECEIVER)), 623 Int32Constant(LAST_CUSTOM_ELEMENTS_RECEIVER)),
620 possibly_elements); 624 possibly_elements);
621 GotoIf(WordNotEqual(LoadElements(prototype), empty_elements), 625 GotoIf(WordNotEqual(LoadElements(prototype), empty_elements),
622 possibly_elements); 626 possibly_elements);
623 var_map.Bind(prototype_map); 627 var_map.Bind(prototype_map);
624 Goto(&loop_body); 628 Goto(&loop_body);
625 } 629 }
626 } 630 }
627 631
632 void CodeStubAssembler::BranchIfJSReceiver(Node* object, Label* if_true,
633 Label* if_false) {
634 GotoIf(TaggedIsSmi(object), if_false);
635 STATIC_ASSERT(LAST_JS_RECEIVER_TYPE == LAST_TYPE);
636 Branch(Int32GreaterThanOrEqual(LoadInstanceType(object),
637 Int32Constant(FIRST_JS_RECEIVER_TYPE)),
638 if_true, if_false);
639 }
640
641 void CodeStubAssembler::BranchIfJSObject(Node* object, Label* if_true,
642 Label* if_false) {
643 GotoIf(TaggedIsSmi(object), if_false);
644 STATIC_ASSERT(LAST_JS_OBJECT_TYPE == LAST_TYPE);
645 Branch(Int32GreaterThanOrEqual(LoadInstanceType(object),
646 Int32Constant(FIRST_JS_OBJECT_TYPE)),
647 if_true, if_false);
648 }
649
628 void CodeStubAssembler::BranchIfFastJSArray(Node* object, Node* context, 650 void CodeStubAssembler::BranchIfFastJSArray(Node* object, Node* context,
629 Label* if_true, Label* if_false) { 651 Label* if_true, Label* if_false) {
630 // Bailout if receiver is a Smi. 652 // Bailout if receiver is a Smi.
631 GotoIf(TaggedIsSmi(object), if_false); 653 GotoIf(TaggedIsSmi(object), if_false);
632 654
633 Node* map = LoadMap(object); 655 Node* map = LoadMap(object);
634 656
635 // Bailout if instance type is not JS_ARRAY_TYPE. 657 // Bailout if instance type is not JS_ARRAY_TYPE.
636 GotoIf(WordNotEqual(LoadMapInstanceType(map), Int32Constant(JS_ARRAY_TYPE)), 658 GotoIf(WordNotEqual(LoadMapInstanceType(map), Int32Constant(JS_ARRAY_TYPE)),
637 if_false); 659 if_false);
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after
778 } 800 }
779 801
780 Node* CodeStubAssembler::InnerAllocate(Node* previous, Node* offset) { 802 Node* CodeStubAssembler::InnerAllocate(Node* previous, Node* offset) {
781 return BitcastWordToTagged(IntPtrAdd(previous, offset)); 803 return BitcastWordToTagged(IntPtrAdd(previous, offset));
782 } 804 }
783 805
784 Node* CodeStubAssembler::InnerAllocate(Node* previous, int offset) { 806 Node* CodeStubAssembler::InnerAllocate(Node* previous, int offset) {
785 return InnerAllocate(previous, IntPtrConstant(offset)); 807 return InnerAllocate(previous, IntPtrConstant(offset));
786 } 808 }
787 809
810 Node* CodeStubAssembler::IsRegularHeapObjectSize(Node* size) {
811 return UintPtrLessThanOrEqual(size,
812 IntPtrConstant(kMaxRegularHeapObjectSize));
813 }
814
788 void CodeStubAssembler::BranchIfToBooleanIsTrue(Node* value, Label* if_true, 815 void CodeStubAssembler::BranchIfToBooleanIsTrue(Node* value, Label* if_true,
789 Label* if_false) { 816 Label* if_false) {
790 Label if_valueissmi(this), if_valueisnotsmi(this), if_valueisstring(this), 817 Label if_valueissmi(this), if_valueisnotsmi(this), if_valueisstring(this),
791 if_valueisheapnumber(this), if_valueisother(this); 818 if_valueisheapnumber(this), if_valueisother(this);
792 819
793 // Fast check for Boolean {value}s (common case). 820 // Fast check for Boolean {value}s (common case).
794 GotoIf(WordEqual(value, BooleanConstant(true)), if_true); 821 GotoIf(WordEqual(value, BooleanConstant(true)), if_true);
795 GotoIf(WordEqual(value, BooleanConstant(false)), if_false); 822 GotoIf(WordEqual(value, BooleanConstant(false)), if_false);
796 823
797 // Check if {value} is a Smi or a HeapObject. 824 // Check if {value} is a Smi or a HeapObject.
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after
943 } 970 }
944 971
945 Node* CodeStubAssembler::LoadMap(Node* object) { 972 Node* CodeStubAssembler::LoadMap(Node* object) {
946 return LoadObjectField(object, HeapObject::kMapOffset); 973 return LoadObjectField(object, HeapObject::kMapOffset);
947 } 974 }
948 975
949 Node* CodeStubAssembler::LoadInstanceType(Node* object) { 976 Node* CodeStubAssembler::LoadInstanceType(Node* object) {
950 return LoadMapInstanceType(LoadMap(object)); 977 return LoadMapInstanceType(LoadMap(object));
951 } 978 }
952 979
980 Node* CodeStubAssembler::HasInstanceType(Node* object,
981 InstanceType instance_type) {
982 return Word32Equal(LoadInstanceType(object), Int32Constant(instance_type));
983 }
984
953 void CodeStubAssembler::AssertInstanceType(Node* object, 985 void CodeStubAssembler::AssertInstanceType(Node* object,
954 InstanceType instance_type) { 986 InstanceType instance_type) {
955 CSA_ASSERT( 987 CSA_ASSERT(HasInstanceType(object, instance_type));
956 Word32Equal(LoadInstanceType(object), Int32Constant(instance_type)));
957 } 988 }
958 989
959 Node* CodeStubAssembler::LoadProperties(Node* object) { 990 Node* CodeStubAssembler::LoadProperties(Node* object) {
960 return LoadObjectField(object, JSObject::kPropertiesOffset); 991 return LoadObjectField(object, JSObject::kPropertiesOffset);
961 } 992 }
962 993
963 Node* CodeStubAssembler::LoadElements(Node* object) { 994 Node* CodeStubAssembler::LoadElements(Node* object) {
964 return LoadObjectField(object, JSObject::kElementsOffset); 995 return LoadObjectField(object, JSObject::kElementsOffset);
965 } 996 }
966 997
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
998 } 1029 }
999 1030
1000 Node* CodeStubAssembler::LoadMapDescriptors(Node* map) { 1031 Node* CodeStubAssembler::LoadMapDescriptors(Node* map) {
1001 return LoadObjectField(map, Map::kDescriptorsOffset); 1032 return LoadObjectField(map, Map::kDescriptorsOffset);
1002 } 1033 }
1003 1034
1004 Node* CodeStubAssembler::LoadMapPrototype(Node* map) { 1035 Node* CodeStubAssembler::LoadMapPrototype(Node* map) {
1005 return LoadObjectField(map, Map::kPrototypeOffset); 1036 return LoadObjectField(map, Map::kPrototypeOffset);
1006 } 1037 }
1007 1038
1039 Node* CodeStubAssembler::LoadMapPrototypeInfo(Node* map,
1040 Label* if_no_proto_info) {
1041 Node* prototype_info =
1042 LoadObjectField(map, Map::kTransitionsOrPrototypeInfoOffset);
1043 GotoIf(TaggedIsSmi(prototype_info), if_no_proto_info);
1044 GotoUnless(WordEqual(LoadMap(prototype_info),
1045 LoadRoot(Heap::kPrototypeInfoMapRootIndex)),
1046 if_no_proto_info);
1047 return prototype_info;
1048 }
1049
1008 Node* CodeStubAssembler::LoadMapInstanceSize(Node* map) { 1050 Node* CodeStubAssembler::LoadMapInstanceSize(Node* map) {
1009 return ChangeUint32ToWord( 1051 return ChangeUint32ToWord(
1010 LoadObjectField(map, Map::kInstanceSizeOffset, MachineType::Uint8())); 1052 LoadObjectField(map, Map::kInstanceSizeOffset, MachineType::Uint8()));
1011 } 1053 }
1012 1054
1013 Node* CodeStubAssembler::LoadMapInobjectProperties(Node* map) { 1055 Node* CodeStubAssembler::LoadMapInobjectProperties(Node* map) {
1014 // See Map::GetInObjectProperties() for details. 1056 // See Map::GetInObjectProperties() for details.
1015 STATIC_ASSERT(LAST_JS_OBJECT_TYPE == LAST_TYPE); 1057 STATIC_ASSERT(LAST_JS_OBJECT_TYPE == LAST_TYPE);
1016 CSA_ASSERT(Int32GreaterThanOrEqual(LoadMapInstanceType(map), 1058 CSA_ASSERT(Int32GreaterThanOrEqual(LoadMapInstanceType(map),
1017 Int32Constant(FIRST_JS_OBJECT_TYPE))); 1059 Int32Constant(FIRST_JS_OBJECT_TYPE)));
(...skipping 25 matching lines...) Expand all
1043 Word32Equal(LoadInstanceType(result.value()), Int32Constant(MAP_TYPE)); 1085 Word32Equal(LoadInstanceType(result.value()), Int32Constant(MAP_TYPE));
1044 GotoUnless(is_map_type, &done); 1086 GotoUnless(is_map_type, &done);
1045 result.Bind( 1087 result.Bind(
1046 LoadObjectField(result.value(), Map::kConstructorOrBackPointerOffset)); 1088 LoadObjectField(result.value(), Map::kConstructorOrBackPointerOffset));
1047 Goto(&loop); 1089 Goto(&loop);
1048 } 1090 }
1049 Bind(&done); 1091 Bind(&done);
1050 return result.value(); 1092 return result.value();
1051 } 1093 }
1052 1094
1095 Node* CodeStubAssembler::IsSpecialReceiverMap(Node* map) {
1096 Node* bit_field = LoadMapBitField(map);
1097 Node* mask = Int32Constant(1 << Map::kHasNamedInterceptor |
1098 1 << Map::kIsAccessCheckNeeded);
1099 Assert(Word32Equal(Word32And(bit_field, mask), Int32Constant(0)));
1100 return IsSpecialReceiverInstanceType(LoadMapInstanceType(map));
1101 }
1102
1103 Node* CodeStubAssembler::IsSpecialReceiverInstanceType(Node* instance_type) {
1104 STATIC_ASSERT(JS_GLOBAL_OBJECT_TYPE <= LAST_SPECIAL_RECEIVER_TYPE);
1105 return Int32LessThanOrEqual(instance_type,
1106 Int32Constant(LAST_SPECIAL_RECEIVER_TYPE));
1107 }
1108
1053 Node* CodeStubAssembler::LoadNameHashField(Node* name) { 1109 Node* CodeStubAssembler::LoadNameHashField(Node* name) {
1054 return LoadObjectField(name, Name::kHashFieldOffset, MachineType::Uint32()); 1110 return LoadObjectField(name, Name::kHashFieldOffset, MachineType::Uint32());
1055 } 1111 }
1056 1112
1057 Node* CodeStubAssembler::LoadNameHash(Node* name, Label* if_hash_not_computed) { 1113 Node* CodeStubAssembler::LoadNameHash(Node* name, Label* if_hash_not_computed) {
1058 Node* hash_field = LoadNameHashField(name); 1114 Node* hash_field = LoadNameHashField(name);
1059 if (if_hash_not_computed != nullptr) { 1115 if (if_hash_not_computed != nullptr) {
1060 GotoIf(Word32Equal( 1116 GotoIf(Word32Equal(
1061 Word32And(hash_field, Int32Constant(Name::kHashNotComputedMask)), 1117 Word32And(hash_field, Int32Constant(Name::kHashNotComputedMask)),
1062 Int32Constant(0)), 1118 Int32Constant(0)),
(...skipping 534 matching lines...) Expand 10 before | Expand all | Expand 10 after
1597 AllocateFixedArray(elements_kind, length_intptr, parameter_mode); 1653 AllocateFixedArray(elements_kind, length_intptr, parameter_mode);
1598 StoreObjectField(result, JSArray::kElementsOffset, elements); 1654 StoreObjectField(result, JSArray::kElementsOffset, elements);
1599 1655
1600 // Fill in the elements with undefined. 1656 // Fill in the elements with undefined.
1601 FillFixedArrayWithValue(elements_kind, elements, zero, length_intptr, 1657 FillFixedArrayWithValue(elements_kind, elements, zero, length_intptr,
1602 Heap::kUndefinedValueRootIndex, parameter_mode); 1658 Heap::kUndefinedValueRootIndex, parameter_mode);
1603 1659
1604 return result; 1660 return result;
1605 } 1661 }
1606 1662
1663 Node* CodeStubAssembler::AllocateJSObjectFromMap(Node* map, Node* properties,
1664 Node* elements) {
1665 Node* size =
1666 IntPtrMul(LoadMapInstanceSize(map), IntPtrConstant(kPointerSize));
1667 CSA_ASSERT(IsRegularHeapObjectSize(size));
1668 Node* object = Allocate(size);
1669 StoreMapNoWriteBarrier(object, map);
1670 InitializeJSObjectFromMap(object, map, size, properties, elements);
1671 return object;
1672 }
1673
1674 void CodeStubAssembler::InitializeJSObjectFromMap(Node* object, Node* map,
1675 Node* size, Node* properties,
1676 Node* elements) {
1677 // This helper assumes that the object is in new-space, as guarded by the
1678 // check in AllocatedJSObjectFromMap.
1679 if (properties == nullptr) {
1680 StoreObjectFieldRoot(object, JSObject::kPropertiesOffset,
1681 Heap::kEmptyFixedArrayRootIndex);
1682 } else {
1683 StoreObjectFieldNoWriteBarrier(object, JSObject::kPropertiesOffset,
1684 properties);
1685 }
1686 if (elements == nullptr) {
1687 StoreObjectFieldRoot(object, JSObject::kElementsOffset,
1688 Heap::kEmptyFixedArrayRootIndex);
1689 } else {
1690 StoreObjectFieldNoWriteBarrier(object, JSObject::kElementsOffset, elements);
1691 }
1692 InitializeJSObjectBody(object, map, size, JSObject::kHeaderSize);
1693 }
1694
1695 void CodeStubAssembler::InitializeJSObjectBody(Node* object, Node* map,
1696 Node* size, int start_offset) {
1697 // TODO(cbruni): activate in-object slack tracking machinery.
1698 Comment("InitializeJSObjectBody");
1699 Node* filler = LoadRoot(Heap::kUndefinedValueRootIndex);
1700 // Calculate the untagged field addresses.
1701 Node* start_address =
1702 IntPtrAdd(object, IntPtrConstant(start_offset - kHeapObjectTag));
1703 Node* end_address =
1704 IntPtrSub(IntPtrAdd(object, size), IntPtrConstant(kHeapObjectTag));
1705 StoreFieldsNoWriteBarrier(start_address, end_address, filler);
1706 }
1707
1708 void CodeStubAssembler::StoreFieldsNoWriteBarrier(Node* start_address,
1709 Node* end_address,
1710 Node* value) {
1711 Comment("StoreFieldsNoWriteBarrier");
1712 CSA_ASSERT(WordIsWordAligned(start_address));
1713 CSA_ASSERT(WordIsWordAligned(end_address));
1714 BuildFastLoop(MachineType::PointerRepresentation(), start_address,
1715 end_address,
1716 [value](CodeStubAssembler* a, Node* current) {
1717 a->StoreNoWriteBarrier(MachineType::PointerRepresentation(),
1718 current, value);
1719 },
1720 kPointerSize, IndexAdvanceMode::kPost);
1721 }
1722
1607 Node* CodeStubAssembler::AllocateUninitializedJSArrayWithoutElements( 1723 Node* CodeStubAssembler::AllocateUninitializedJSArrayWithoutElements(
1608 ElementsKind kind, Node* array_map, Node* length, Node* allocation_site) { 1724 ElementsKind kind, Node* array_map, Node* length, Node* allocation_site) {
1609 Comment("begin allocation of JSArray without elements"); 1725 Comment("begin allocation of JSArray without elements");
1610 int base_size = JSArray::kSize; 1726 int base_size = JSArray::kSize;
1611 if (allocation_site != nullptr) { 1727 if (allocation_site != nullptr) {
1612 base_size += AllocationMemento::kSize; 1728 base_size += AllocationMemento::kSize;
1613 } 1729 }
1614 1730
1615 Node* size = IntPtrConstant(base_size); 1731 Node* size = IntPtrConstant(base_size);
1616 Node* array = AllocateUninitializedJSArray(kind, array_map, length, 1732 Node* array = AllocateUninitializedJSArray(kind, array_map, length,
(...skipping 6453 matching lines...) Expand 10 before | Expand all | Expand 10 after
8070 Node* buffer_bit_field = LoadObjectField( 8186 Node* buffer_bit_field = LoadObjectField(
8071 buffer, JSArrayBuffer::kBitFieldOffset, MachineType::Uint32()); 8187 buffer, JSArrayBuffer::kBitFieldOffset, MachineType::Uint32());
8072 Node* was_neutered_mask = Int32Constant(JSArrayBuffer::WasNeutered::kMask); 8188 Node* was_neutered_mask = Int32Constant(JSArrayBuffer::WasNeutered::kMask);
8073 8189
8074 return Word32NotEqual(Word32And(buffer_bit_field, was_neutered_mask), 8190 return Word32NotEqual(Word32And(buffer_bit_field, was_neutered_mask),
8075 Int32Constant(0)); 8191 Int32Constant(0));
8076 } 8192 }
8077 8193
8078 } // namespace internal 8194 } // namespace internal
8079 } // namespace v8 8195 } // namespace v8
OLDNEW
« no previous file with comments | « src/code-stub-assembler.h ('k') | src/compiler/code-assembler.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698