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

Side by Side Diff: src/type-feedback-vector.cc

Issue 2084913006: [ic] Let LoadGlobalIC load the variable name from TypeFeedbackMetadata. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@fix-load-ic-slow-stub
Patch Set: Addressing comments Created 4 years, 5 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/type-feedback-vector.h ('k') | src/type-feedback-vector-inl.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 2014 the V8 project authors. All rights reserved. 1 // Copyright 2014 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/type-feedback-vector.h" 5 #include "src/type-feedback-vector.h"
6 6
7 #include "src/code-stubs.h" 7 #include "src/code-stubs.h"
8 #include "src/ic/ic.h" 8 #include "src/ic/ic.h"
9 #include "src/ic/ic-state.h" 9 #include "src/ic/ic-state.h"
10 #include "src/objects.h" 10 #include "src/objects.h"
(...skipping 19 matching lines...) Expand all
30 } 30 }
31 31
32 32
33 FeedbackVectorSlotKind TypeFeedbackMetadata::GetKind( 33 FeedbackVectorSlotKind TypeFeedbackMetadata::GetKind(
34 FeedbackVectorSlot slot) const { 34 FeedbackVectorSlot slot) const {
35 int index = VectorICComputer::index(kReservedIndexCount, slot.ToInt()); 35 int index = VectorICComputer::index(kReservedIndexCount, slot.ToInt());
36 int data = Smi::cast(get(index))->value(); 36 int data = Smi::cast(get(index))->value();
37 return VectorICComputer::decode(data, slot.ToInt()); 37 return VectorICComputer::decode(data, slot.ToInt());
38 } 38 }
39 39
40 String* TypeFeedbackMetadata::GetName(FeedbackVectorSlot slot) const {
41 DCHECK(SlotRequiresName(GetKind(slot)));
42 FixedArray* names = FixedArray::cast(get(kNamesTableIndex));
43 // TODO(ishell): consider using binary search here or even Dictionary when we
44 // have more ICs with names.
45 Smi* key = Smi::FromInt(slot.ToInt());
46 for (int entry = 0; entry < names->length(); entry += kNameTableEntrySize) {
47 Object* current_key = names->get(entry + kNameTableSlotIndex);
48 if (current_key == key) {
49 Object* name = names->get(entry + kNameTableNameIndex);
50 DCHECK(name->IsString());
51 return String::cast(name);
52 }
53 }
54 UNREACHABLE();
55 return nullptr;
56 }
40 57
41 void TypeFeedbackMetadata::SetKind(FeedbackVectorSlot slot, 58 void TypeFeedbackMetadata::SetKind(FeedbackVectorSlot slot,
42 FeedbackVectorSlotKind kind) { 59 FeedbackVectorSlotKind kind) {
43 int index = VectorICComputer::index(kReservedIndexCount, slot.ToInt()); 60 int index = VectorICComputer::index(kReservedIndexCount, slot.ToInt());
44 int data = Smi::cast(get(index))->value(); 61 int data = Smi::cast(get(index))->value();
45 int new_data = VectorICComputer::encode(data, slot.ToInt(), kind); 62 int new_data = VectorICComputer::encode(data, slot.ToInt(), kind);
46 set(index, Smi::FromInt(new_data)); 63 set(index, Smi::FromInt(new_data));
47 } 64 }
48 65
49 66
50 template Handle<TypeFeedbackMetadata> TypeFeedbackMetadata::New( 67 template Handle<TypeFeedbackMetadata> TypeFeedbackMetadata::New(
51 Isolate* isolate, const StaticFeedbackVectorSpec* spec); 68 Isolate* isolate, const StaticFeedbackVectorSpec* spec);
52 template Handle<TypeFeedbackMetadata> TypeFeedbackMetadata::New( 69 template Handle<TypeFeedbackMetadata> TypeFeedbackMetadata::New(
53 Isolate* isolate, const FeedbackVectorSpec* spec); 70 Isolate* isolate, const FeedbackVectorSpec* spec);
54 71
55 72
56 // static 73 // static
57 template <typename Spec> 74 template <typename Spec>
58 Handle<TypeFeedbackMetadata> TypeFeedbackMetadata::New(Isolate* isolate, 75 Handle<TypeFeedbackMetadata> TypeFeedbackMetadata::New(Isolate* isolate,
59 const Spec* spec) { 76 const Spec* spec) {
77 Factory* factory = isolate->factory();
78
60 const int slot_count = spec->slots(); 79 const int slot_count = spec->slots();
61 const int slot_kinds_length = VectorICComputer::word_count(slot_count); 80 const int slot_kinds_length = VectorICComputer::word_count(slot_count);
62 const int length = slot_kinds_length + kReservedIndexCount; 81 const int length = slot_kinds_length + kReservedIndexCount;
63 if (length == kReservedIndexCount) { 82 if (length == kReservedIndexCount) {
64 return Handle<TypeFeedbackMetadata>::cast( 83 return Handle<TypeFeedbackMetadata>::cast(factory->empty_fixed_array());
65 isolate->factory()->empty_fixed_array());
66 } 84 }
67 #ifdef DEBUG 85 #ifdef DEBUG
68 for (int i = 0; i < slot_count;) { 86 for (int i = 0; i < slot_count;) {
69 FeedbackVectorSlotKind kind = spec->GetKind(i); 87 FeedbackVectorSlotKind kind = spec->GetKind(i);
70 int entry_size = TypeFeedbackMetadata::GetSlotSize(kind); 88 int entry_size = TypeFeedbackMetadata::GetSlotSize(kind);
71 for (int j = 1; j < entry_size; j++) { 89 for (int j = 1; j < entry_size; j++) {
72 FeedbackVectorSlotKind kind = spec->GetKind(i + j); 90 FeedbackVectorSlotKind kind = spec->GetKind(i + j);
73 DCHECK_EQ(FeedbackVectorSlotKind::INVALID, kind); 91 DCHECK_EQ(FeedbackVectorSlotKind::INVALID, kind);
74 } 92 }
75 i += entry_size; 93 i += entry_size;
76 } 94 }
77 #endif 95 #endif
78 96
79 Handle<FixedArray> array = isolate->factory()->NewFixedArray(length, TENURED); 97 Handle<FixedArray> array = factory->NewFixedArray(length, TENURED);
80 array->set(kSlotsCountIndex, Smi::FromInt(slot_count)); 98 array->set(kSlotsCountIndex, Smi::FromInt(slot_count));
81 // Fill the bit-vector part with zeros. 99 // Fill the bit-vector part with zeros.
82 for (int i = 0; i < slot_kinds_length; i++) { 100 for (int i = 0; i < slot_kinds_length; i++) {
83 array->set(kReservedIndexCount + i, Smi::FromInt(0)); 101 array->set(kReservedIndexCount + i, Smi::FromInt(0));
84 } 102 }
85 103
86 Handle<TypeFeedbackMetadata> metadata = 104 Handle<TypeFeedbackMetadata> metadata =
87 Handle<TypeFeedbackMetadata>::cast(array); 105 Handle<TypeFeedbackMetadata>::cast(array);
106
107 // Add names to NamesTable.
108 const int name_count = spec->name_count();
109
110 Handle<FixedArray> names =
111 name_count == 0
112 ? factory->empty_fixed_array()
113 : factory->NewFixedArray(name_count * kNameTableEntrySize);
114 int name_index = 0;
88 for (int i = 0; i < slot_count; i++) { 115 for (int i = 0; i < slot_count; i++) {
89 metadata->SetKind(FeedbackVectorSlot(i), spec->GetKind(i)); 116 FeedbackVectorSlotKind kind = spec->GetKind(i);
117 metadata->SetKind(FeedbackVectorSlot(i), kind);
118 if (SlotRequiresName(kind)) {
119 Handle<String> name = spec->GetName(name_index);
120 DCHECK(!name.is_null());
121 int entry = name_index * kNameTableEntrySize;
122 names->set(entry + kNameTableSlotIndex, Smi::FromInt(i));
123 names->set(entry + kNameTableNameIndex, *name);
124 name_index++;
125 }
90 } 126 }
127 DCHECK_EQ(name_count, name_index);
128 metadata->set(kNamesTableIndex, *names);
91 129
92 // It's important that the TypeFeedbackMetadata have a COW map, since it's 130 // It's important that the TypeFeedbackMetadata have a COW map, since it's
93 // pointed to by both a SharedFunctionInfo and indirectly by closures through 131 // pointed to by both a SharedFunctionInfo and indirectly by closures through
94 // the TypeFeedbackVector. The serializer uses the COW map type to decide 132 // the TypeFeedbackVector. The serializer uses the COW map type to decide
95 // this object belongs in the startup snapshot and not the partial 133 // this object belongs in the startup snapshot and not the partial
96 // snapshot(s). 134 // snapshot(s).
97 metadata->set_map(isolate->heap()->fixed_cow_array_map()); 135 metadata->set_map(isolate->heap()->fixed_cow_array_map());
98 136
99 return metadata; 137 return metadata;
100 } 138 }
101 139
102 140
103 bool TypeFeedbackMetadata::SpecDiffersFrom( 141 bool TypeFeedbackMetadata::SpecDiffersFrom(
104 const FeedbackVectorSpec* other_spec) const { 142 const FeedbackVectorSpec* other_spec) const {
105 if (other_spec->slots() != slot_count()) { 143 if (other_spec->slots() != slot_count()) {
106 return true; 144 return true;
107 } 145 }
108 146
109 int slots = slot_count(); 147 int slots = slot_count();
110 for (int i = 0; i < slots; i++) { 148 int name_index = 0;
111 if (GetKind(FeedbackVectorSlot(i)) != other_spec->GetKind(i)) { 149 for (int i = 0; i < slots;) {
150 FeedbackVectorSlot slot(i);
151 FeedbackVectorSlotKind kind = GetKind(slot);
152 int entry_size = TypeFeedbackMetadata::GetSlotSize(kind);
153
154 if (kind != other_spec->GetKind(i)) {
112 return true; 155 return true;
113 } 156 }
157 if (SlotRequiresName(kind)) {
158 String* name = GetName(slot);
159 DCHECK(name != GetHeap()->empty_string());
160 String* other_name = *other_spec->GetName(name_index++);
161 if (name != other_name) {
162 return true;
163 }
164 }
165 i += entry_size;
114 } 166 }
115 return false; 167 return false;
116 } 168 }
117 169
118 bool TypeFeedbackMetadata::DiffersFrom( 170 bool TypeFeedbackMetadata::DiffersFrom(
119 const TypeFeedbackMetadata* other_metadata) const { 171 const TypeFeedbackMetadata* other_metadata) const {
120 if (other_metadata->slot_count() != slot_count()) { 172 if (other_metadata->slot_count() != slot_count()) {
121 return true; 173 return true;
122 } 174 }
123 175
124 int slots = slot_count(); 176 int slots = slot_count();
125 for (int i = 0; i < slots; i++) { 177 for (int i = 0; i < slots;) {
126 FeedbackVectorSlot slot(i); 178 FeedbackVectorSlot slot(i);
179 FeedbackVectorSlotKind kind = GetKind(slot);
180 int entry_size = TypeFeedbackMetadata::GetSlotSize(kind);
127 if (GetKind(slot) != other_metadata->GetKind(slot)) { 181 if (GetKind(slot) != other_metadata->GetKind(slot)) {
128 return true; 182 return true;
129 } 183 }
184 if (SlotRequiresName(kind)) {
185 if (GetName(slot) != other_metadata->GetName(slot)) {
186 return true;
187 }
188 }
189 i += entry_size;
130 } 190 }
131 return false; 191 return false;
132 } 192 }
133 193
134 const char* TypeFeedbackMetadata::Kind2String(FeedbackVectorSlotKind kind) { 194 const char* TypeFeedbackMetadata::Kind2String(FeedbackVectorSlotKind kind) {
135 switch (kind) { 195 switch (kind) {
136 case FeedbackVectorSlotKind::INVALID: 196 case FeedbackVectorSlotKind::INVALID:
137 return "INVALID"; 197 return "INVALID";
138 case FeedbackVectorSlotKind::CALL_IC: 198 case FeedbackVectorSlotKind::CALL_IC:
139 return "CALL_IC"; 199 return "CALL_IC";
(...skipping 15 matching lines...) Expand all
155 UNREACHABLE(); 215 UNREACHABLE();
156 return "?"; 216 return "?";
157 } 217 }
158 218
159 FeedbackVectorSlotKind TypeFeedbackVector::GetKind( 219 FeedbackVectorSlotKind TypeFeedbackVector::GetKind(
160 FeedbackVectorSlot slot) const { 220 FeedbackVectorSlot slot) const {
161 DCHECK(!is_empty()); 221 DCHECK(!is_empty());
162 return metadata()->GetKind(slot); 222 return metadata()->GetKind(slot);
163 } 223 }
164 224
225 String* TypeFeedbackVector::GetName(FeedbackVectorSlot slot) const {
226 DCHECK(!is_empty());
227 return metadata()->GetName(slot);
228 }
229
165 // static 230 // static
166 Handle<TypeFeedbackVector> TypeFeedbackVector::New( 231 Handle<TypeFeedbackVector> TypeFeedbackVector::New(
167 Isolate* isolate, Handle<TypeFeedbackMetadata> metadata) { 232 Isolate* isolate, Handle<TypeFeedbackMetadata> metadata) {
168 Factory* factory = isolate->factory(); 233 Factory* factory = isolate->factory();
169 234
170 const int slot_count = metadata->slot_count(); 235 const int slot_count = metadata->slot_count();
171 const int length = slot_count + kReservedIndexCount; 236 const int length = slot_count + kReservedIndexCount;
172 if (length == kReservedIndexCount) { 237 if (length == kReservedIndexCount) {
173 return Handle<TypeFeedbackVector>::cast(factory->empty_fixed_array()); 238 return Handle<TypeFeedbackVector>::cast(factory->empty_fixed_array());
174 } 239 }
175 240
176 Handle<FixedArray> array = factory->NewFixedArray(length, TENURED); 241 Handle<FixedArray> array = factory->NewFixedArray(length, TENURED);
177 array->set(kMetadataIndex, *metadata); 242 array->set(kMetadataIndex, *metadata);
178 243
244 DisallowHeapAllocation no_gc;
245
179 // Ensure we can skip the write barrier 246 // Ensure we can skip the write barrier
180 Handle<Object> uninitialized_sentinel = UninitializedSentinel(isolate); 247 Handle<Object> uninitialized_sentinel = UninitializedSentinel(isolate);
181 DCHECK_EQ(*factory->uninitialized_symbol(), *uninitialized_sentinel); 248 DCHECK_EQ(*factory->uninitialized_symbol(), *uninitialized_sentinel);
182 for (int i = 0; i < slot_count;) { 249 for (int i = 0; i < slot_count;) {
183 FeedbackVectorSlot slot(i); 250 FeedbackVectorSlot slot(i);
184 FeedbackVectorSlotKind kind = metadata->GetKind(slot); 251 FeedbackVectorSlotKind kind = metadata->GetKind(slot);
185 int index = TypeFeedbackVector::GetIndex(slot); 252 int index = TypeFeedbackVector::GetIndex(slot);
186 int entry_size = TypeFeedbackMetadata::GetSlotSize(kind); 253 int entry_size = TypeFeedbackMetadata::GetSlotSize(kind);
187 254
188 Object* value; 255 Object* value;
(...skipping 763 matching lines...) Expand 10 before | Expand all | Expand 10 after
952 1019
953 IcCheckType KeyedStoreICNexus::GetKeyType() const { 1020 IcCheckType KeyedStoreICNexus::GetKeyType() const {
954 Object* feedback = GetFeedback(); 1021 Object* feedback = GetFeedback();
955 if (feedback == *TypeFeedbackVector::MegamorphicSentinel(GetIsolate())) { 1022 if (feedback == *TypeFeedbackVector::MegamorphicSentinel(GetIsolate())) {
956 return static_cast<IcCheckType>(Smi::cast(GetFeedbackExtra())->value()); 1023 return static_cast<IcCheckType>(Smi::cast(GetFeedbackExtra())->value());
957 } 1024 }
958 return IsPropertyNameFeedback(feedback) ? PROPERTY : ELEMENT; 1025 return IsPropertyNameFeedback(feedback) ? PROPERTY : ELEMENT;
959 } 1026 }
960 } // namespace internal 1027 } // namespace internal
961 } // namespace v8 1028 } // namespace v8
OLDNEW
« no previous file with comments | « src/type-feedback-vector.h ('k') | src/type-feedback-vector-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698