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

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

Issue 2385423005: [stubs] Implement fast TF Builtin for Object.create (Closed)
Patch Set: addressing nits 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
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 305 matching lines...) Expand 10 before | Expand all | Expand 10 after
904 } 921 }
905 922
906 Node* CodeStubAssembler::LoadMap(Node* object) { 923 Node* CodeStubAssembler::LoadMap(Node* object) {
907 return LoadObjectField(object, HeapObject::kMapOffset); 924 return LoadObjectField(object, HeapObject::kMapOffset);
908 } 925 }
909 926
910 Node* CodeStubAssembler::LoadInstanceType(Node* object) { 927 Node* CodeStubAssembler::LoadInstanceType(Node* object) {
911 return LoadMapInstanceType(LoadMap(object)); 928 return LoadMapInstanceType(LoadMap(object));
912 } 929 }
913 930
931 Node* CodeStubAssembler::HasInstanceType(Node* object,
932 InstanceType instance_type) {
933 return Word32Equal(LoadInstanceType(object), Int32Constant(instance_type));
934 }
935
914 void CodeStubAssembler::AssertInstanceType(Node* object, 936 void CodeStubAssembler::AssertInstanceType(Node* object,
915 InstanceType instance_type) { 937 InstanceType instance_type) {
916 CSA_ASSERT( 938 CSA_ASSERT(HasInstanceType(object, instance_type));
917 Word32Equal(LoadInstanceType(object), Int32Constant(instance_type)));
918 } 939 }
919 940
920 Node* CodeStubAssembler::LoadProperties(Node* object) { 941 Node* CodeStubAssembler::LoadProperties(Node* object) {
921 return LoadObjectField(object, JSObject::kPropertiesOffset); 942 return LoadObjectField(object, JSObject::kPropertiesOffset);
922 } 943 }
923 944
924 Node* CodeStubAssembler::LoadElements(Node* object) { 945 Node* CodeStubAssembler::LoadElements(Node* object) {
925 return LoadObjectField(object, JSObject::kElementsOffset); 946 return LoadObjectField(object, JSObject::kElementsOffset);
926 } 947 }
927 948
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
959 } 980 }
960 981
961 Node* CodeStubAssembler::LoadMapDescriptors(Node* map) { 982 Node* CodeStubAssembler::LoadMapDescriptors(Node* map) {
962 return LoadObjectField(map, Map::kDescriptorsOffset); 983 return LoadObjectField(map, Map::kDescriptorsOffset);
963 } 984 }
964 985
965 Node* CodeStubAssembler::LoadMapPrototype(Node* map) { 986 Node* CodeStubAssembler::LoadMapPrototype(Node* map) {
966 return LoadObjectField(map, Map::kPrototypeOffset); 987 return LoadObjectField(map, Map::kPrototypeOffset);
967 } 988 }
968 989
990 Node* CodeStubAssembler::LoadMapPrototypeInfo(Node* map,
991 Label* if_no_proto_info) {
992 Node* prototype_info =
993 LoadObjectField(map, Map::kTransitionsOrPrototypeInfoOffset);
994 GotoIf(TaggedIsSmi(prototype_info), if_no_proto_info);
995 GotoUnless(WordEqual(LoadMap(prototype_info),
996 LoadRoot(Heap::kPrototypeInfoMapRootIndex)),
997 if_no_proto_info);
998 return prototype_info;
999 }
1000
969 Node* CodeStubAssembler::LoadMapInstanceSize(Node* map) { 1001 Node* CodeStubAssembler::LoadMapInstanceSize(Node* map) {
970 return ChangeUint32ToWord( 1002 return ChangeUint32ToWord(
971 LoadObjectField(map, Map::kInstanceSizeOffset, MachineType::Uint8())); 1003 LoadObjectField(map, Map::kInstanceSizeOffset, MachineType::Uint8()));
972 } 1004 }
973 1005
974 Node* CodeStubAssembler::LoadMapInobjectProperties(Node* map) { 1006 Node* CodeStubAssembler::LoadMapInobjectProperties(Node* map) {
975 // See Map::GetInObjectProperties() for details. 1007 // See Map::GetInObjectProperties() for details.
976 STATIC_ASSERT(LAST_JS_OBJECT_TYPE == LAST_TYPE); 1008 STATIC_ASSERT(LAST_JS_OBJECT_TYPE == LAST_TYPE);
977 CSA_ASSERT(Int32GreaterThanOrEqual(LoadMapInstanceType(map), 1009 CSA_ASSERT(Int32GreaterThanOrEqual(LoadMapInstanceType(map),
978 Int32Constant(FIRST_JS_OBJECT_TYPE))); 1010 Int32Constant(FIRST_JS_OBJECT_TYPE)));
(...skipping 25 matching lines...) Expand all
1004 Word32Equal(LoadInstanceType(result.value()), Int32Constant(MAP_TYPE)); 1036 Word32Equal(LoadInstanceType(result.value()), Int32Constant(MAP_TYPE));
1005 GotoUnless(is_map_type, &done); 1037 GotoUnless(is_map_type, &done);
1006 result.Bind( 1038 result.Bind(
1007 LoadObjectField(result.value(), Map::kConstructorOrBackPointerOffset)); 1039 LoadObjectField(result.value(), Map::kConstructorOrBackPointerOffset));
1008 Goto(&loop); 1040 Goto(&loop);
1009 } 1041 }
1010 Bind(&done); 1042 Bind(&done);
1011 return result.value(); 1043 return result.value();
1012 } 1044 }
1013 1045
1046 Node* CodeStubAssembler::IsSpecialReceiverMap(Node* map) {
1047 Node* bit_field = LoadMapBitField(map);
1048 Node* mask = Int32Constant(1 << Map::kHasNamedInterceptor |
1049 1 << Map::kIsAccessCheckNeeded);
1050 Assert(Word32Equal(Word32And(bit_field, mask), Int32Constant(0)));
1051 return IsSpecialReceiverInstanceType(LoadMapInstanceType(map));
1052 }
1053
1054 Node* CodeStubAssembler::IsSpecialReceiverInstanceType(Node* instance_type) {
1055 STATIC_ASSERT(JS_GLOBAL_OBJECT_TYPE <= LAST_SPECIAL_RECEIVER_TYPE);
1056 return Int32LessThanOrEqual(instance_type,
1057 Int32Constant(LAST_SPECIAL_RECEIVER_TYPE));
1058 }
1059
1014 Node* CodeStubAssembler::LoadNameHashField(Node* name) { 1060 Node* CodeStubAssembler::LoadNameHashField(Node* name) {
1015 return LoadObjectField(name, Name::kHashFieldOffset, MachineType::Uint32()); 1061 return LoadObjectField(name, Name::kHashFieldOffset, MachineType::Uint32());
1016 } 1062 }
1017 1063
1018 Node* CodeStubAssembler::LoadNameHash(Node* name, Label* if_hash_not_computed) { 1064 Node* CodeStubAssembler::LoadNameHash(Node* name, Label* if_hash_not_computed) {
1019 Node* hash_field = LoadNameHashField(name); 1065 Node* hash_field = LoadNameHashField(name);
1020 if (if_hash_not_computed != nullptr) { 1066 if (if_hash_not_computed != nullptr) {
1021 GotoIf(Word32Equal( 1067 GotoIf(Word32Equal(
1022 Word32And(hash_field, Int32Constant(Name::kHashNotComputedMask)), 1068 Word32And(hash_field, Int32Constant(Name::kHashNotComputedMask)),
1023 Int32Constant(0)), 1069 Int32Constant(0)),
(...skipping 408 matching lines...) Expand 10 before | Expand all | Expand 10 after
1432 AllocateFixedArray(elements_kind, length_intptr, parameter_mode); 1478 AllocateFixedArray(elements_kind, length_intptr, parameter_mode);
1433 StoreObjectField(result, JSArray::kElementsOffset, elements); 1479 StoreObjectField(result, JSArray::kElementsOffset, elements);
1434 1480
1435 // Fill in the elements with undefined. 1481 // Fill in the elements with undefined.
1436 FillFixedArrayWithValue(elements_kind, elements, zero, length_intptr, 1482 FillFixedArrayWithValue(elements_kind, elements, zero, length_intptr,
1437 Heap::kUndefinedValueRootIndex, parameter_mode); 1483 Heap::kUndefinedValueRootIndex, parameter_mode);
1438 1484
1439 return result; 1485 return result;
1440 } 1486 }
1441 1487
1488 Node* CodeStubAssembler::AllocateJSObjectFromMap(Node* map, Node* properties,
1489 Node* elements) {
1490 Node* size =
1491 IntPtrMul(LoadMapInstanceSize(map), IntPtrConstant(kPointerSize));
1492 CSA_ASSERT(IntPtrLessThan(size, IntPtrConstant(kMaxRegularHeapObjectSize)));
1493 Node* object = Allocate(size);
1494 StoreMapNoWriteBarrier(object, map);
1495 InitializeJSObjectFromMap(object, map, size, properties, elements);
1496 return object;
1497 }
1498
1499 void CodeStubAssembler::InitializeJSObjectFromMap(Node* object, Node* map,
1500 Node* size, Node* properties,
1501 Node* elements) {
1502 // This helper assumes that the object is in new-space, as guarded by the
1503 // check in AllocatedJSObjectFromMap.
1504 if (properties == nullptr) {
1505 StoreObjectFieldRoot(object, JSObject::kPropertiesOffset,
1506 Heap::kEmptyFixedArrayRootIndex);
1507 } else {
1508 StoreObjectFieldNoWriteBarrier(object, JSObject::kPropertiesOffset,
1509 properties);
1510 }
1511 if (elements == nullptr) {
1512 StoreObjectFieldRoot(object, JSObject::kElementsOffset,
1513 Heap::kEmptyFixedArrayRootIndex);
1514 } else {
1515 StoreObjectFieldNoWriteBarrier(object, JSObject::kElementsOffset, elements);
1516 }
1517 InitializeJSObjectBody(object, map, size, JSObject::kHeaderSize);
1518 }
1519
1520 void CodeStubAssembler::InitializeJSObjectBody(Node* object, Node* map,
1521 Node* size, int start_offset) {
1522 // TODO(cbruni): activate in-object slack tracking machinery.
1523 Comment("InitializeJSObjectBody");
1524 Node* filler = LoadRoot(Heap::kUndefinedValueRootIndex);
1525 // Calculate the untagged field addresses.
1526 Node* start_address = IntPtrAdd(object, IntPtrConstant(start_offset - 1));
1527 Node* end_address = IntPtrSub(IntPtrAdd(object, size), IntPtrConstant(1));
1528 StoreFieldsNoWriteBarrier(start_address, end_address, filler);
1529 }
1530
1531 void CodeStubAssembler::StoreFieldsNoWriteBarrier(Node* start_address,
1532 Node* end_address,
1533 Node* value) {
1534 Comment("StoreFieldsNoWriteBarrier");
1535
1536 Assert(IsWordAligned(start_address));
1537 Assert(IsWordAligned(end_address));
1538 BuildFastLoop(MachineType::PointerRepresentation(), start_address,
1539 end_address,
1540 [value](CodeStubAssembler* a, Node* current) {
1541 a->StoreNoWriteBarrier(MachineType::PointerRepresentation(),
1542 current, value);
1543 },
1544 kPointerSize, IndexAdvanceMode::kPost);
1545 }
1546
1442 Node* CodeStubAssembler::AllocateUninitializedJSArrayWithoutElements( 1547 Node* CodeStubAssembler::AllocateUninitializedJSArrayWithoutElements(
1443 ElementsKind kind, Node* array_map, Node* length, Node* allocation_site) { 1548 ElementsKind kind, Node* array_map, Node* length, Node* allocation_site) {
1444 Comment("begin allocation of JSArray without elements"); 1549 Comment("begin allocation of JSArray without elements");
1445 int base_size = JSArray::kSize; 1550 int base_size = JSArray::kSize;
1446 if (allocation_site != nullptr) { 1551 if (allocation_site != nullptr) {
1447 base_size += AllocationMemento::kSize; 1552 base_size += AllocationMemento::kSize;
1448 } 1553 }
1449 1554
1450 Node* size = IntPtrConstant(base_size); 1555 Node* size = IntPtrConstant(base_size);
1451 Node* array = AllocateUninitializedJSArray(kind, array_map, length, 1556 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)); 7590 result.Bind(CallRuntime(Runtime::kInstanceOf, context, object, callable));
7486 Goto(&end); 7591 Goto(&end);
7487 } 7592 }
7488 7593
7489 Bind(&end); 7594 Bind(&end);
7490 return result.value(); 7595 return result.value();
7491 } 7596 }
7492 7597
7493 } // namespace internal 7598 } // namespace internal
7494 } // namespace v8 7599 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698