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: update comments 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 27 matching lines...) Expand all
955 976
956 Node* CodeStubAssembler::LoadMapElementsKind(Node* map) { 977 Node* CodeStubAssembler::LoadMapElementsKind(Node* map) {
957 Node* bit_field2 = LoadMapBitField2(map); 978 Node* bit_field2 = LoadMapBitField2(map);
958 return BitFieldDecode<Map::ElementsKindBits>(bit_field2); 979 return BitFieldDecode<Map::ElementsKindBits>(bit_field2);
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
986 Node* CodeStubAssembler::LoadMapNumberOfOwnDescriptors(Node* map) {
987 return BitFieldDecodeWord<Map::NumberOfOwnDescriptorsBits>(
988 LoadMapBitField3(map));
989 }
990
965 Node* CodeStubAssembler::LoadMapPrototype(Node* map) { 991 Node* CodeStubAssembler::LoadMapPrototype(Node* map) {
966 return LoadObjectField(map, Map::kPrototypeOffset); 992 return LoadObjectField(map, Map::kPrototypeOffset);
967 } 993 }
968 994
995 Node* CodeStubAssembler::LoadMapPrototypeInfo(Node* map,
996 Label* if_no_proto_info) {
997 Node* prototype_info =
998 LoadObjectField(map, Map::kTransitionsOrPrototypeInfoOffset);
999 GotoIf(TaggedIsSmi(prototype_info), if_no_proto_info);
1000 GotoUnless(HasInstanceType(prototype_info, PROTOTYPE_INFO_TYPE),
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::IsFastMap(Node* map) {
1051 Node* bit_field3 = LoadMapBitField3(map);
1052 return BitFieldDecode<Map::DictionaryMap>(bit_field3);
1053 }
1054
1055 Node* CodeStubAssembler::IsSpecialReceiverMap(Node* map) {
1056 Node* bit_field = LoadMapBitField(map);
1057 Node* mask = Int32Constant(1 << Map::kHasNamedInterceptor |
1058 1 << Map::kIsAccessCheckNeeded);
1059 Assert(Word32Equal(Word32And(bit_field, mask), Int32Constant(0)));
Igor Sheludko 2016/10/18 12:33:21 Please ensure that bit_field is not loaded when as
1060 return IsSpecialReceiverInstanceType(LoadMapInstanceType(map));
1061 }
1062
1063 Node* CodeStubAssembler::IsSpecialReceiverInstanceType(Node* instance_type) {
1064 STATIC_ASSERT(JS_GLOBAL_OBJECT_TYPE <= LAST_SPECIAL_RECEIVER_TYPE);
1065 return Int32LessThanOrEqual(instance_type,
1066 Int32Constant(LAST_SPECIAL_RECEIVER_TYPE));
1067 }
1068
1014 Node* CodeStubAssembler::LoadNameHashField(Node* name) { 1069 Node* CodeStubAssembler::LoadNameHashField(Node* name) {
1015 return LoadObjectField(name, Name::kHashFieldOffset, MachineType::Uint32()); 1070 return LoadObjectField(name, Name::kHashFieldOffset, MachineType::Uint32());
1016 } 1071 }
1017 1072
1018 Node* CodeStubAssembler::LoadNameHash(Node* name, Label* if_hash_not_computed) { 1073 Node* CodeStubAssembler::LoadNameHash(Node* name, Label* if_hash_not_computed) {
1019 Node* hash_field = LoadNameHashField(name); 1074 Node* hash_field = LoadNameHashField(name);
1020 if (if_hash_not_computed != nullptr) { 1075 if (if_hash_not_computed != nullptr) {
1021 GotoIf(Word32Equal( 1076 GotoIf(Word32Equal(
1022 Word32And(hash_field, Int32Constant(Name::kHashNotComputedMask)), 1077 Word32And(hash_field, Int32Constant(Name::kHashNotComputedMask)),
1023 Int32Constant(0)), 1078 Int32Constant(0)),
(...skipping 408 matching lines...) Expand 10 before | Expand all | Expand 10 after
1432 AllocateFixedArray(elements_kind, length_intptr, parameter_mode); 1487 AllocateFixedArray(elements_kind, length_intptr, parameter_mode);
1433 StoreObjectField(result, JSArray::kElementsOffset, elements); 1488 StoreObjectField(result, JSArray::kElementsOffset, elements);
1434 1489
1435 // Fill in the elements with undefined. 1490 // Fill in the elements with undefined.
1436 FillFixedArrayWithValue(elements_kind, elements, zero, length_intptr, 1491 FillFixedArrayWithValue(elements_kind, elements, zero, length_intptr,
1437 Heap::kUndefinedValueRootIndex, parameter_mode); 1492 Heap::kUndefinedValueRootIndex, parameter_mode);
1438 1493
1439 return result; 1494 return result;
1440 } 1495 }
1441 1496
1497 Node* CodeStubAssembler::AllocateJSObjectFromMap(Node* map, Node* properties,
1498 Node* elements) {
1499 Node* size =
1500 IntPtrMul(LoadMapInstanceSize(map), IntPtrConstant(kPointerSize));
1501 Node* object = Allocate(size);
1502 StoreMapNoWriteBarrier(object, map);
1503 InitializeJSObjectFromMap(object, map, size, properties, elements);
1504 return object;
1505 }
1506
1507 void CodeStubAssembler::InitializeJSObjectFromMap(Node* object, Node* map,
1508 Node* size, Node* properties,
1509 Node* elements) {
1510 if (properties == nullptr) {
1511 StoreObjectFieldRoot(object, JSObject::kPropertiesOffset,
1512 Heap::kEmptyFixedArrayRootIndex);
1513 } else {
1514 StoreObjectFieldNoWriteBarrier(object, JSObject::kPropertiesOffset,
1515 properties);
1516 }
1517 if (elements == nullptr) {
1518 StoreObjectFieldRoot(object, JSObject::kElementsOffset,
1519 Heap::kEmptyFixedArrayRootIndex);
1520 } else {
1521 StoreObjectFieldNoWriteBarrier(object, JSObject::kElementsOffset, elements);
1522 }
1523 InitializeJSObjectBody(object, map, size, JSObject::kHeaderSize);
1524 }
1525
1526 void CodeStubAssembler::InitializeJSObjectBody(Node* object, Node* map,
1527 Node* size, int start_offset) {
1528 // TODO(cbruni): activate in-object slack tracking machinery.
1529 Comment("InitializeJSObjectBody");
1530 Node* filler = LoadRoot(Heap::kUndefinedValueRootIndex);
1531 Node* start_address = IntPtrAdd(object, IntPtrConstant(start_offset));
1532 Node* end_address = IntPtrAdd(object, size);
1533 StoreFieldsNoWriteBarrier(start_address, end_address, filler);
1534 }
1535
1536 void CodeStubAssembler::StoreFieldsNoWriteBarrier(Node* start_address,
1537 Node* end_address,
1538 Node* value) {
1539 Comment("StoreFieldsNoWriteBarrier");
1540 Variable current(this, MachineRepresentation::kTagged);
1541 Label decrement(this, &current), done(this);
1542
1543 start_address = IntPtrSub(start_address, IntPtrConstant(1));
1544 end_address = IntPtrSub(end_address, IntPtrConstant(1));
1545 Assert(IsWordAligned(start_address));
1546 Assert(IsWordAligned(end_address));
1547
1548 current.Bind(end_address);
1549 Branch(WordEqual(current.value(), start_address), &done, &decrement);
1550 Bind(&decrement);
1551 {
1552 current.Bind(IntPtrSub(current.value(), IntPtrConstant(kPointerSize)));
1553
1554 StoreNoWriteBarrier(MachineType::PointerRepresentation(), current.value(),
1555 value);
1556
1557 Branch(WordEqual(current.value(), start_address), &done, &decrement);
1558 }
1559
1560 Bind(&done);
1561 }
1562
1442 Node* CodeStubAssembler::AllocateUninitializedJSArrayWithoutElements( 1563 Node* CodeStubAssembler::AllocateUninitializedJSArrayWithoutElements(
1443 ElementsKind kind, Node* array_map, Node* length, Node* allocation_site) { 1564 ElementsKind kind, Node* array_map, Node* length, Node* allocation_site) {
1444 Comment("begin allocation of JSArray without elements"); 1565 Comment("begin allocation of JSArray without elements");
1445 int base_size = JSArray::kSize; 1566 int base_size = JSArray::kSize;
1446 if (allocation_site != nullptr) { 1567 if (allocation_site != nullptr) {
1447 base_size += AllocationMemento::kSize; 1568 base_size += AllocationMemento::kSize;
1448 } 1569 }
1449 1570
1450 Node* size = IntPtrConstant(base_size); 1571 Node* size = IntPtrConstant(base_size);
1451 Node* array = AllocateUninitializedJSArray(kind, array_map, length, 1572 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)); 7606 result.Bind(CallRuntime(Runtime::kInstanceOf, context, object, callable));
7486 Goto(&end); 7607 Goto(&end);
7487 } 7608 }
7488 7609
7489 Bind(&end); 7610 Bind(&end);
7490 return result.value(); 7611 return result.value();
7491 } 7612 }
7492 7613
7493 } // namespace internal 7614 } // namespace internal
7494 } // namespace v8 7615 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698