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

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

Issue 1894953004: Add HasProperty code stub that tries simple lookups or jumps to runtime otherwise. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Addressing comments, tweak linear search limit based on local measurements Created 4 years, 8 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/code-stub-assembler.h" 5 #include "src/code-stub-assembler.h"
6 #include "src/code-factory.h" 6 #include "src/code-factory.h"
7 7
8 namespace v8 { 8 namespace v8 {
9 namespace internal { 9 namespace internal {
10 10
(...skipping 315 matching lines...) Expand 10 before | Expand all | Expand 10 after
326 326
327 Node* CodeStubAssembler::LoadMapInstanceType(Node* map) { 327 Node* CodeStubAssembler::LoadMapInstanceType(Node* map) {
328 return Load(MachineType::Uint8(), map, 328 return Load(MachineType::Uint8(), map,
329 IntPtrConstant(Map::kInstanceTypeOffset - kHeapObjectTag)); 329 IntPtrConstant(Map::kInstanceTypeOffset - kHeapObjectTag));
330 } 330 }
331 331
332 Node* CodeStubAssembler::LoadMapDescriptors(Node* map) { 332 Node* CodeStubAssembler::LoadMapDescriptors(Node* map) {
333 return LoadObjectField(map, Map::kDescriptorsOffset); 333 return LoadObjectField(map, Map::kDescriptorsOffset);
334 } 334 }
335 335
336 Node* CodeStubAssembler::LoadMapPrototype(Node* map) {
337 return LoadObjectField(map, Map::kPrototypeOffset);
338 }
339
336 Node* CodeStubAssembler::LoadNameHash(Node* name) { 340 Node* CodeStubAssembler::LoadNameHash(Node* name) {
337 return Load(MachineType::Uint32(), name, 341 return Load(MachineType::Uint32(), name,
338 IntPtrConstant(Name::kHashFieldOffset - kHeapObjectTag)); 342 IntPtrConstant(Name::kHashFieldOffset - kHeapObjectTag));
339 } 343 }
340 344
341 Node* CodeStubAssembler::LoadFixedArrayElementInt32Index( 345 Node* CodeStubAssembler::LoadFixedArrayElementInt32Index(
342 Node* object, Node* index, int additional_offset) { 346 Node* object, Node* index, int additional_offset) {
343 Node* header_size = IntPtrConstant(additional_offset + 347 Node* header_size = IntPtrConstant(additional_offset +
344 FixedArray::kHeaderSize - kHeapObjectTag); 348 FixedArray::kHeaderSize - kHeapObjectTag);
345 if (Is64()) { 349 if (Is64()) {
(...skipping 622 matching lines...) Expand 10 before | Expand all | Expand 10 after
968 Bind(&if_done); 972 Bind(&if_done);
969 return var_result.value(); 973 return var_result.value();
970 } 974 }
971 975
972 Node* CodeStubAssembler::BitFieldDecode(Node* word32, uint32_t shift, 976 Node* CodeStubAssembler::BitFieldDecode(Node* word32, uint32_t shift,
973 uint32_t mask) { 977 uint32_t mask) {
974 return Word32Shr(Word32And(word32, Int32Constant(mask)), 978 return Word32Shr(Word32And(word32, Int32Constant(mask)),
975 Int32Constant(shift)); 979 Int32Constant(shift));
976 } 980 }
977 981
982 void CodeStubAssembler::TryToName(Node* key, Label* if_keyisindex,
983 Variable* var_index, Label* if_keyisunique,
984 Label* call_runtime) {
985 DCHECK_EQ(MachineRepresentation::kWord32, var_index->rep());
986
987 Label if_keyissmi(this), if_keyisnotsmi(this);
988 Branch(WordIsSmi(key), &if_keyissmi, &if_keyisnotsmi);
989 Bind(&if_keyissmi);
990 {
991 // Negative smi keys are named properties. Handle in the runtime.
992 Label if_keyispositive(this);
993 Branch(WordIsPositiveSmi(key), &if_keyispositive, call_runtime);
994 Bind(&if_keyispositive);
995
996 var_index->Bind(SmiUntag(key));
Toon Verwaest 2016/04/20 10:00:04 This should be SmiToWord32 according to Rodolph Pe
Igor Sheludko 2016/04/20 13:14:56 Done.
997 Goto(if_keyisindex);
998 }
999
1000 Bind(&if_keyisnotsmi);
1001
1002 Node* key_instance_type = LoadInstanceType(key);
1003 Label if_iskeyunique(this), if_iskeynotsymbol(this);
Toon Verwaest 2016/04/20 10:00:04 if_iskeyunique is not used anymore
Igor Sheludko 2016/04/20 13:14:56 Done.
1004 Branch(Word32Equal(key_instance_type, Int32Constant(SYMBOL_TYPE)),
1005 if_keyisunique, &if_iskeynotsymbol);
1006 Bind(&if_iskeynotsymbol);
1007 {
1008 Label if_iskeyinternalized(this);
1009 Node* bits =
1010 WordAnd(key_instance_type,
1011 Int32Constant(kIsNotStringMask | kIsNotInternalizedMask));
1012 Branch(Word32Equal(bits, Int32Constant(kStringTag | kInternalizedTag)),
1013 &if_iskeyinternalized, call_runtime);
1014 Bind(&if_iskeyinternalized);
1015
1016 // Check whether the key is an array index passed in as string. Handle
1017 // uniform with smi keys if so.
1018 // TODO(verwaest): Also support non-internalized strings.
1019 Node* hash = LoadNameHash(key);
1020 Node* bit =
1021 Word32And(hash, Int32Constant(internal::Name::kIsNotArrayIndexMask));
1022 Label if_isarrayindex(this);
1023 Branch(Word32Equal(bit, Int32Constant(0)), &if_isarrayindex,
1024 if_keyisunique);
1025 Bind(&if_isarrayindex);
1026 var_index->Bind(BitFieldDecode<internal::Name::ArrayIndexValueBits>(hash));
1027 Goto(if_keyisindex);
1028 }
1029 }
1030
1031 void CodeStubAssembler::TryLookupProperty(Node* object, Node* map,
1032 Node* instance_type, Node* name,
1033 Label* if_found, Label* if_not_found,
1034 Label* call_runtime) {
1035 {
1036 Label if_objectissimple(this);
1037 Branch(Int32LessThanOrEqual(instance_type,
1038 Int32Constant(LAST_SPECIAL_RECEIVER_TYPE)),
1039 call_runtime, &if_objectissimple);
1040 Bind(&if_objectissimple);
1041 }
1042
1043 // TODO(verwaest): Perform a dictonary lookup on slow-mode receivers.
1044 Node* bit_field3 = LoadMapBitField3(map);
1045 Node* bit = BitFieldDecode<Map::DictionaryMap>(bit_field3);
1046 Label if_isfastmap(this);
1047 Branch(Word32Equal(bit, Int32Constant(0)), &if_isfastmap, call_runtime);
1048 Bind(&if_isfastmap);
1049 Node* nof = BitFieldDecode<Map::NumberOfOwnDescriptorsBits>(bit_field3);
1050 // Bail out to the runtime for large numbers of own descriptors. The stub only
1051 // does linear search, which becomes too expensive in that case.
1052 {
1053 static const int32_t kMaxLinear = 210;
1054 Label above_max(this), below_max(this);
1055 Branch(Int32LessThanOrEqual(nof, Int32Constant(kMaxLinear)), &below_max,
1056 call_runtime);
1057 Bind(&below_max);
1058 }
1059 Node* descriptors = LoadMapDescriptors(map);
1060
1061 Variable var_descriptor(this, MachineRepresentation::kWord32);
1062 Label loop(this, &var_descriptor);
1063 var_descriptor.Bind(Int32Constant(0));
1064 Goto(&loop);
1065 Bind(&loop);
1066 {
1067 Node* index = var_descriptor.value();
1068 Node* offset = Int32Constant(DescriptorArray::ToKeyIndex(0));
1069 Node* factor = Int32Constant(DescriptorArray::kDescriptorSize);
1070 Label if_notdone(this);
1071 Branch(Word32Equal(index, nof), if_not_found, &if_notdone);
1072 Bind(&if_notdone);
1073 {
1074 Node* array_index = Int32Add(offset, Int32Mul(index, factor));
1075 Node* current = LoadFixedArrayElementInt32Index(descriptors, array_index);
1076 Label if_unequal(this);
1077 Branch(WordEqual(current, name), if_found, &if_unequal);
1078 Bind(&if_unequal);
1079
1080 var_descriptor.Bind(Int32Add(index, Int32Constant(1)));
1081 Goto(&loop);
1082 }
1083 }
1084 }
1085
1086 void CodeStubAssembler::TryLookupElement(Node* object, Node* map,
1087 Node* instance_type, Node* index,
1088 Label* if_found, Label* if_not_found,
1089 Label* call_runtime) {
1090 {
1091 Label if_objectissimple(this);
1092 Branch(Int32LessThanOrEqual(instance_type,
1093 Int32Constant(LAST_CUSTOM_ELEMENTS_RECEIVER)),
1094 call_runtime, &if_objectissimple);
1095 Bind(&if_objectissimple);
1096 }
1097
1098 Node* bit_field2 = LoadMapBitField2(map);
1099 Node* elements_kind = BitFieldDecode<Map::ElementsKindBits>(bit_field2);
1100
1101 // TODO(verwaest): Support other elements kinds as well.
1102 Label if_isobjectorsmi(this);
1103 Branch(
1104 Int32LessThanOrEqual(elements_kind, Int32Constant(FAST_HOLEY_ELEMENTS)),
1105 &if_isobjectorsmi, call_runtime);
1106 Bind(&if_isobjectorsmi);
1107 {
1108 Node* elements = LoadElements(object);
1109 Node* length = LoadFixedArrayBaseLength(elements);
1110
1111 Label if_iskeyinrange(this);
1112 Branch(Int32LessThan(index, SmiToWord32(length)), &if_iskeyinrange,
1113 if_not_found);
1114
1115 Bind(&if_iskeyinrange);
1116 Node* element = LoadFixedArrayElementInt32Index(elements, index);
1117 Node* the_hole = LoadRoot(Heap::kTheHoleValueRootIndex);
1118 Branch(WordEqual(element, the_hole), if_not_found, if_found);
1119 }
1120 }
1121
978 } // namespace internal 1122 } // namespace internal
979 } // namespace v8 1123 } // namespace v8
OLDNEW
« no previous file with comments | « src/code-stub-assembler.h ('k') | src/code-stubs.h » ('j') | src/code-stubs.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698