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

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

Issue 2385423005: [stubs] Implement fast TF Builtin for Object.create (Closed)
Patch Set: fix heap size check 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 564 matching lines...) Expand 10 before | Expand all | Expand 10 after
579 GotoIf(Int32LessThanOrEqual(LoadMapInstanceType(prototype_map), 578 GotoIf(Int32LessThanOrEqual(LoadMapInstanceType(prototype_map),
580 Int32Constant(LAST_CUSTOM_ELEMENTS_RECEIVER)), 579 Int32Constant(LAST_CUSTOM_ELEMENTS_RECEIVER)),
581 possibly_elements); 580 possibly_elements);
582 GotoIf(WordNotEqual(LoadElements(prototype), empty_elements), 581 GotoIf(WordNotEqual(LoadElements(prototype), empty_elements),
583 possibly_elements); 582 possibly_elements);
584 var_map.Bind(prototype_map); 583 var_map.Bind(prototype_map);
585 Goto(&loop_body); 584 Goto(&loop_body);
586 } 585 }
587 } 586 }
588 587
588 void CodeStubAssembler::BranchIfJSReceiver(Node* object, Label* if_true,
589 Label* if_false) {
590 GotoIf(TaggedIsSmi(object), if_false);
591 STATIC_ASSERT(LAST_JS_RECEIVER_TYPE == LAST_TYPE);
592 Branch(Int32GreaterThanOrEqual(LoadInstanceType(object),
593 Int32Constant(FIRST_JS_RECEIVER_TYPE)),
594 if_true, if_false);
595 }
596
597 void CodeStubAssembler::BranchIfJSObject(Node* object, Label* if_true,
598 Label* if_false) {
599 GotoIf(TaggedIsSmi(object), if_false);
600 STATIC_ASSERT(LAST_JS_OBJECT_TYPE == LAST_TYPE);
601 Branch(Int32GreaterThanOrEqual(LoadInstanceType(object),
602 Int32Constant(FIRST_JS_OBJECT_TYPE)),
603 if_true, if_false);
604 }
605
589 void CodeStubAssembler::BranchIfFastJSArray(Node* object, Node* context, 606 void CodeStubAssembler::BranchIfFastJSArray(Node* object, Node* context,
590 Label* if_true, Label* if_false) { 607 Label* if_true, Label* if_false) {
591 // Bailout if receiver is a Smi. 608 // Bailout if receiver is a Smi.
592 GotoIf(TaggedIsSmi(object), if_false); 609 GotoIf(TaggedIsSmi(object), if_false);
593 610
594 Node* map = LoadMap(object); 611 Node* map = LoadMap(object);
595 612
596 // Bailout if instance type is not JS_ARRAY_TYPE. 613 // Bailout if instance type is not JS_ARRAY_TYPE.
597 GotoIf(WordNotEqual(LoadMapInstanceType(map), Int32Constant(JS_ARRAY_TYPE)), 614 GotoIf(WordNotEqual(LoadMapInstanceType(map), Int32Constant(JS_ARRAY_TYPE)),
598 if_false); 615 if_false);
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after
739 } 756 }
740 757
741 Node* CodeStubAssembler::InnerAllocate(Node* previous, Node* offset) { 758 Node* CodeStubAssembler::InnerAllocate(Node* previous, Node* offset) {
742 return BitcastWordToTagged(IntPtrAdd(previous, offset)); 759 return BitcastWordToTagged(IntPtrAdd(previous, offset));
743 } 760 }
744 761
745 Node* CodeStubAssembler::InnerAllocate(Node* previous, int offset) { 762 Node* CodeStubAssembler::InnerAllocate(Node* previous, int offset) {
746 return InnerAllocate(previous, IntPtrConstant(offset)); 763 return InnerAllocate(previous, IntPtrConstant(offset));
747 } 764 }
748 765
766 Node* CodeStubAssembler::IsRegularHeapObjectSize(Node* size) {
767 return IntPtrLessThanOrEqual(size, IntPtrConstant(kMaxRegularHeapObjectSize));
Igor Sheludko 2016/10/18 14:22:19 UintPtrLessThanOrEqual
768 }
769
749 void CodeStubAssembler::BranchIfToBooleanIsTrue(Node* value, Label* if_true, 770 void CodeStubAssembler::BranchIfToBooleanIsTrue(Node* value, Label* if_true,
750 Label* if_false) { 771 Label* if_false) {
751 Label if_valueissmi(this), if_valueisnotsmi(this), if_valueisstring(this), 772 Label if_valueissmi(this), if_valueisnotsmi(this), if_valueisstring(this),
752 if_valueisheapnumber(this), if_valueisother(this); 773 if_valueisheapnumber(this), if_valueisother(this);
753 774
754 // Fast check for Boolean {value}s (common case). 775 // Fast check for Boolean {value}s (common case).
755 GotoIf(WordEqual(value, BooleanConstant(true)), if_true); 776 GotoIf(WordEqual(value, BooleanConstant(true)), if_true);
756 GotoIf(WordEqual(value, BooleanConstant(false)), if_false); 777 GotoIf(WordEqual(value, BooleanConstant(false)), if_false);
757 778
758 // Check if {value} is a Smi or a HeapObject. 779 // Check if {value} is a Smi or a HeapObject.
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after
904 } 925 }
905 926
906 Node* CodeStubAssembler::LoadMap(Node* object) { 927 Node* CodeStubAssembler::LoadMap(Node* object) {
907 return LoadObjectField(object, HeapObject::kMapOffset); 928 return LoadObjectField(object, HeapObject::kMapOffset);
908 } 929 }
909 930
910 Node* CodeStubAssembler::LoadInstanceType(Node* object) { 931 Node* CodeStubAssembler::LoadInstanceType(Node* object) {
911 return LoadMapInstanceType(LoadMap(object)); 932 return LoadMapInstanceType(LoadMap(object));
912 } 933 }
913 934
935 Node* CodeStubAssembler::HasInstanceType(Node* object,
936 InstanceType instance_type) {
937 return Word32Equal(LoadInstanceType(object), Int32Constant(instance_type));
938 }
939
914 void CodeStubAssembler::AssertInstanceType(Node* object, 940 void CodeStubAssembler::AssertInstanceType(Node* object,
915 InstanceType instance_type) { 941 InstanceType instance_type) {
916 CSA_ASSERT( 942 CSA_ASSERT(HasInstanceType(object, instance_type));
917 Word32Equal(LoadInstanceType(object), Int32Constant(instance_type)));
918 } 943 }
919 944
920 Node* CodeStubAssembler::LoadProperties(Node* object) { 945 Node* CodeStubAssembler::LoadProperties(Node* object) {
921 return LoadObjectField(object, JSObject::kPropertiesOffset); 946 return LoadObjectField(object, JSObject::kPropertiesOffset);
922 } 947 }
923 948
924 Node* CodeStubAssembler::LoadElements(Node* object) { 949 Node* CodeStubAssembler::LoadElements(Node* object) {
925 return LoadObjectField(object, JSObject::kElementsOffset); 950 return LoadObjectField(object, JSObject::kElementsOffset);
926 } 951 }
927 952
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
959 } 984 }
960 985
961 Node* CodeStubAssembler::LoadMapDescriptors(Node* map) { 986 Node* CodeStubAssembler::LoadMapDescriptors(Node* map) {
962 return LoadObjectField(map, Map::kDescriptorsOffset); 987 return LoadObjectField(map, Map::kDescriptorsOffset);
963 } 988 }
964 989
965 Node* CodeStubAssembler::LoadMapPrototype(Node* map) { 990 Node* CodeStubAssembler::LoadMapPrototype(Node* map) {
966 return LoadObjectField(map, Map::kPrototypeOffset); 991 return LoadObjectField(map, Map::kPrototypeOffset);
967 } 992 }
968 993
994 Node* CodeStubAssembler::LoadMapPrototypeInfo(Node* map,
995 Label* if_no_proto_info) {
996 Node* prototype_info =
997 LoadObjectField(map, Map::kTransitionsOrPrototypeInfoOffset);
998 GotoIf(TaggedIsSmi(prototype_info), if_no_proto_info);
999 GotoUnless(WordEqual(LoadMap(prototype_info),
1000 LoadRoot(Heap::kPrototypeInfoMapRootIndex)),
1001 if_no_proto_info);
1002 return prototype_info;
1003 }
1004
969 Node* CodeStubAssembler::LoadMapInstanceSize(Node* map) { 1005 Node* CodeStubAssembler::LoadMapInstanceSize(Node* map) {
970 return ChangeUint32ToWord( 1006 return ChangeUint32ToWord(
971 LoadObjectField(map, Map::kInstanceSizeOffset, MachineType::Uint8())); 1007 LoadObjectField(map, Map::kInstanceSizeOffset, MachineType::Uint8()));
972 } 1008 }
973 1009
974 Node* CodeStubAssembler::LoadMapInobjectProperties(Node* map) { 1010 Node* CodeStubAssembler::LoadMapInobjectProperties(Node* map) {
975 // See Map::GetInObjectProperties() for details. 1011 // See Map::GetInObjectProperties() for details.
976 STATIC_ASSERT(LAST_JS_OBJECT_TYPE == LAST_TYPE); 1012 STATIC_ASSERT(LAST_JS_OBJECT_TYPE == LAST_TYPE);
977 CSA_ASSERT(Int32GreaterThanOrEqual(LoadMapInstanceType(map), 1013 CSA_ASSERT(Int32GreaterThanOrEqual(LoadMapInstanceType(map),
978 Int32Constant(FIRST_JS_OBJECT_TYPE))); 1014 Int32Constant(FIRST_JS_OBJECT_TYPE)));
(...skipping 25 matching lines...) Expand all
1004 Word32Equal(LoadInstanceType(result.value()), Int32Constant(MAP_TYPE)); 1040 Word32Equal(LoadInstanceType(result.value()), Int32Constant(MAP_TYPE));
1005 GotoUnless(is_map_type, &done); 1041 GotoUnless(is_map_type, &done);
1006 result.Bind( 1042 result.Bind(
1007 LoadObjectField(result.value(), Map::kConstructorOrBackPointerOffset)); 1043 LoadObjectField(result.value(), Map::kConstructorOrBackPointerOffset));
1008 Goto(&loop); 1044 Goto(&loop);
1009 } 1045 }
1010 Bind(&done); 1046 Bind(&done);
1011 return result.value(); 1047 return result.value();
1012 } 1048 }
1013 1049
1050 Node* CodeStubAssembler::IsSpecialReceiverMap(Node* map) {
1051 Node* bit_field = LoadMapBitField(map);
1052 Node* mask = Int32Constant(1 << Map::kHasNamedInterceptor |
1053 1 << Map::kIsAccessCheckNeeded);
1054 Assert(Word32Equal(Word32And(bit_field, mask), Int32Constant(0)));
1055 return IsSpecialReceiverInstanceType(LoadMapInstanceType(map));
1056 }
1057
1058 Node* CodeStubAssembler::IsSpecialReceiverInstanceType(Node* instance_type) {
1059 STATIC_ASSERT(JS_GLOBAL_OBJECT_TYPE <= LAST_SPECIAL_RECEIVER_TYPE);
1060 return Int32LessThanOrEqual(instance_type,
1061 Int32Constant(LAST_SPECIAL_RECEIVER_TYPE));
1062 }
1063
1014 Node* CodeStubAssembler::LoadNameHashField(Node* name) { 1064 Node* CodeStubAssembler::LoadNameHashField(Node* name) {
1015 return LoadObjectField(name, Name::kHashFieldOffset, MachineType::Uint32()); 1065 return LoadObjectField(name, Name::kHashFieldOffset, MachineType::Uint32());
1016 } 1066 }
1017 1067
1018 Node* CodeStubAssembler::LoadNameHash(Node* name, Label* if_hash_not_computed) { 1068 Node* CodeStubAssembler::LoadNameHash(Node* name, Label* if_hash_not_computed) {
1019 Node* hash_field = LoadNameHashField(name); 1069 Node* hash_field = LoadNameHashField(name);
1020 if (if_hash_not_computed != nullptr) { 1070 if (if_hash_not_computed != nullptr) {
1021 GotoIf(Word32Equal( 1071 GotoIf(Word32Equal(
1022 Word32And(hash_field, Int32Constant(Name::kHashNotComputedMask)), 1072 Word32And(hash_field, Int32Constant(Name::kHashNotComputedMask)),
1023 Int32Constant(0)), 1073 Int32Constant(0)),
(...skipping 408 matching lines...) Expand 10 before | Expand all | Expand 10 after
1432 AllocateFixedArray(elements_kind, length_intptr, parameter_mode); 1482 AllocateFixedArray(elements_kind, length_intptr, parameter_mode);
1433 StoreObjectField(result, JSArray::kElementsOffset, elements); 1483 StoreObjectField(result, JSArray::kElementsOffset, elements);
1434 1484
1435 // Fill in the elements with undefined. 1485 // Fill in the elements with undefined.
1436 FillFixedArrayWithValue(elements_kind, elements, zero, length_intptr, 1486 FillFixedArrayWithValue(elements_kind, elements, zero, length_intptr,
1437 Heap::kUndefinedValueRootIndex, parameter_mode); 1487 Heap::kUndefinedValueRootIndex, parameter_mode);
1438 1488
1439 return result; 1489 return result;
1440 } 1490 }
1441 1491
1492 Node* CodeStubAssembler::AllocateJSObjectFromMap(Node* map, Node* properties,
1493 Node* elements) {
1494 Node* size =
1495 IntPtrMul(LoadMapInstanceSize(map), IntPtrConstant(kPointerSize));
1496 CSA_ASSERT(IsRegularHeapObjectSize(size));
1497 Node* object = Allocate(size);
1498 StoreMapNoWriteBarrier(object, map);
1499 InitializeJSObjectFromMap(object, map, size, properties, elements);
1500 return object;
1501 }
1502
1503 void CodeStubAssembler::InitializeJSObjectFromMap(Node* object, Node* map,
1504 Node* size, Node* properties,
1505 Node* elements) {
1506 // This helper assumes that the object is in new-space, as guarded by the
1507 // check in AllocatedJSObjectFromMap.
1508 if (properties == nullptr) {
1509 StoreObjectFieldRoot(object, JSObject::kPropertiesOffset,
1510 Heap::kEmptyFixedArrayRootIndex);
1511 } else {
1512 StoreObjectFieldNoWriteBarrier(object, JSObject::kPropertiesOffset,
1513 properties);
1514 }
1515 if (elements == nullptr) {
1516 StoreObjectFieldRoot(object, JSObject::kElementsOffset,
1517 Heap::kEmptyFixedArrayRootIndex);
1518 } else {
1519 StoreObjectFieldNoWriteBarrier(object, JSObject::kElementsOffset, elements);
1520 }
1521 InitializeJSObjectBody(object, map, size, JSObject::kHeaderSize);
1522 }
1523
1524 void CodeStubAssembler::InitializeJSObjectBody(Node* object, Node* map,
1525 Node* size, int start_offset) {
1526 // TODO(cbruni): activate in-object slack tracking machinery.
1527 Comment("InitializeJSObjectBody");
1528 Node* filler = LoadRoot(Heap::kUndefinedValueRootIndex);
1529 // Calculate the untagged field addresses.
1530 Node* start_address = IntPtrAdd(object, IntPtrConstant(start_offset - 1));
1531 Node* end_address = IntPtrSub(IntPtrAdd(object, size), IntPtrConstant(1));
1532 StoreFieldsNoWriteBarrier(start_address, end_address, filler);
1533 }
1534
1535 void CodeStubAssembler::StoreFieldsNoWriteBarrier(Node* start_address,
1536 Node* end_address,
1537 Node* value) {
1538 Comment("StoreFieldsNoWriteBarrier");
1539
1540 Assert(IsWordAligned(start_address));
1541 Assert(IsWordAligned(end_address));
1542 BuildFastLoop(MachineType::PointerRepresentation(), start_address,
1543 end_address,
1544 [value](CodeStubAssembler* a, Node* current) {
1545 a->StoreNoWriteBarrier(MachineType::PointerRepresentation(),
1546 current, value);
1547 },
1548 kPointerSize, IndexAdvanceMode::kPost);
1549 }
1550
1442 Node* CodeStubAssembler::AllocateUninitializedJSArrayWithoutElements( 1551 Node* CodeStubAssembler::AllocateUninitializedJSArrayWithoutElements(
1443 ElementsKind kind, Node* array_map, Node* length, Node* allocation_site) { 1552 ElementsKind kind, Node* array_map, Node* length, Node* allocation_site) {
1444 Comment("begin allocation of JSArray without elements"); 1553 Comment("begin allocation of JSArray without elements");
1445 int base_size = JSArray::kSize; 1554 int base_size = JSArray::kSize;
1446 if (allocation_site != nullptr) { 1555 if (allocation_site != nullptr) {
1447 base_size += AllocationMemento::kSize; 1556 base_size += AllocationMemento::kSize;
1448 } 1557 }
1449 1558
1450 Node* size = IntPtrConstant(base_size); 1559 Node* size = IntPtrConstant(base_size);
1451 Node* array = AllocateUninitializedJSArray(kind, array_map, length, 1560 Node* array = AllocateUninitializedJSArray(kind, array_map, length,
(...skipping 6033 matching lines...) Expand 10 before | Expand all | Expand 10 after
7485 result.Bind(CallRuntime(Runtime::kInstanceOf, context, object, callable)); 7594 result.Bind(CallRuntime(Runtime::kInstanceOf, context, object, callable));
7486 Goto(&end); 7595 Goto(&end);
7487 } 7596 }
7488 7597
7489 Bind(&end); 7598 Bind(&end);
7490 return result.value(); 7599 return result.value();
7491 } 7600 }
7492 7601
7493 } // namespace internal 7602 } // namespace internal
7494 } // namespace v8 7603 } // 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