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

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: 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 const int kEntrySize = 2;
44 for (int i = 0; i < names->length(); i += kEntrySize) {
45 int current_slot = Smi::cast(names->get(i))->value();
46 if (current_slot == slot.ToInt()) {
47 Object* name = names->get(i + 1);
48 if (!name->IsSmi()) {
49 return String::cast(name);
50 } else {
51 break;
52 }
53 }
54 }
55 return GetHeap()->empty_string();
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 kEntrySize = 2;
109 Handle<FixedArray> names = factory->empty_fixed_array();
110
111 int name_index = 0;
88 for (int i = 0; i < slot_count; i++) { 112 for (int i = 0; i < slot_count; i++) {
89 metadata->SetKind(FeedbackVectorSlot(i), spec->GetKind(i)); 113 FeedbackVectorSlotKind kind = spec->GetKind(i);
114 metadata->SetKind(FeedbackVectorSlot(i), kind);
115 if (SlotRequiresName(kind)) {
116 Handle<String> name = spec->GetName(name_index);
117
118 // Add entry to names.
119 int length = names->length();
120 if (length < (name_index + 1) * kEntrySize) {
121 Handle<FixedArray> tmp =
mvstanton 2016/06/24 10:04:11 maybe call this newNames.
Igor Sheludko 2016/06/24 13:30:50 Done.
122 factory->NewFixedArray(length == 0 ? 16 : length * 2);
mvstanton 2016/06/24 10:04:12 Did you do anything like figure out average # of g
Igor Sheludko 2016/06/24 13:30:50 Good point! Although we don't waste space in the e
123 names->CopyTo(0, *tmp, 0, length);
124 names = tmp;
125 }
126 names->set(name_index * 2, Smi::FromInt(i));
127 names->set(name_index * 2 + 1,
128 !name.is_null() ? Object::cast(*name) : Smi::FromInt(0));
129 name_index++;
130 }
90 } 131 }
132 if (name_index > 0) {
133 names->Shrink(name_index * 2);
134 }
135 metadata->set(kNamesTableIndex, *names);
91 136
92 // It's important that the TypeFeedbackMetadata have a COW map, since it's 137 // 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 138 // pointed to by both a SharedFunctionInfo and indirectly by closures through
94 // the TypeFeedbackVector. The serializer uses the COW map type to decide 139 // the TypeFeedbackVector. The serializer uses the COW map type to decide
95 // this object belongs in the startup snapshot and not the partial 140 // this object belongs in the startup snapshot and not the partial
96 // snapshot(s). 141 // snapshot(s).
97 metadata->set_map(isolate->heap()->fixed_cow_array_map()); 142 metadata->set_map(isolate->heap()->fixed_cow_array_map());
98 143
99 return metadata; 144 return metadata;
100 } 145 }
101 146
102 147
103 bool TypeFeedbackMetadata::SpecDiffersFrom( 148 bool TypeFeedbackMetadata::SpecDiffersFrom(
104 const FeedbackVectorSpec* other_spec) const { 149 const FeedbackVectorSpec* other_spec) const {
105 if (other_spec->slots() != slot_count()) { 150 if (other_spec->slots() != slot_count()) {
106 return true; 151 return true;
107 } 152 }
108 153
109 int slots = slot_count(); 154 int slots = slot_count();
110 for (int i = 0; i < slots; i++) { 155 int name_index = 0;
111 if (GetKind(FeedbackVectorSlot(i)) != other_spec->GetKind(i)) { 156 for (int i = 0; i < slots;) {
157 FeedbackVectorSlot slot(i);
158 FeedbackVectorSlotKind kind = GetKind(slot);
159 int entry_size = TypeFeedbackMetadata::GetSlotSize(kind);
160
161 if (kind != other_spec->GetKind(i)) {
112 return true; 162 return true;
113 } 163 }
164 if (SlotRequiresName(kind)) {
165 String* name = GetName(slot);
166 DCHECK(name != GetHeap()->empty_string());
167 String* other_name = *other_spec->GetName(name_index++);
168 if (name != other_name) {
169 return true;
170 }
171 }
172 i += entry_size;
114 } 173 }
115 return false; 174 return false;
116 } 175 }
117 176
118 bool TypeFeedbackMetadata::DiffersFrom( 177 bool TypeFeedbackMetadata::DiffersFrom(
119 const TypeFeedbackMetadata* other_metadata) const { 178 const TypeFeedbackMetadata* other_metadata) const {
120 if (other_metadata->slot_count() != slot_count()) { 179 if (other_metadata->slot_count() != slot_count()) {
121 return true; 180 return true;
122 } 181 }
123 182
124 int slots = slot_count(); 183 int slots = slot_count();
125 for (int i = 0; i < slots; i++) { 184 for (int i = 0; i < slots;) {
126 FeedbackVectorSlot slot(i); 185 FeedbackVectorSlot slot(i);
186 FeedbackVectorSlotKind kind = GetKind(slot);
187 int entry_size = TypeFeedbackMetadata::GetSlotSize(kind);
127 if (GetKind(slot) != other_metadata->GetKind(slot)) { 188 if (GetKind(slot) != other_metadata->GetKind(slot)) {
128 return true; 189 return true;
129 } 190 }
191 if (SlotRequiresName(kind)) {
192 if (GetName(slot) != other_metadata->GetName(slot)) {
193 return true;
194 }
195 }
196 i += entry_size;
130 } 197 }
131 return false; 198 return false;
132 } 199 }
133 200
134 const char* TypeFeedbackMetadata::Kind2String(FeedbackVectorSlotKind kind) { 201 const char* TypeFeedbackMetadata::Kind2String(FeedbackVectorSlotKind kind) {
135 switch (kind) { 202 switch (kind) {
136 case FeedbackVectorSlotKind::INVALID: 203 case FeedbackVectorSlotKind::INVALID:
137 return "INVALID"; 204 return "INVALID";
138 case FeedbackVectorSlotKind::CALL_IC: 205 case FeedbackVectorSlotKind::CALL_IC:
139 return "CALL_IC"; 206 return "CALL_IC";
(...skipping 15 matching lines...) Expand all
155 UNREACHABLE(); 222 UNREACHABLE();
156 return "?"; 223 return "?";
157 } 224 }
158 225
159 FeedbackVectorSlotKind TypeFeedbackVector::GetKind( 226 FeedbackVectorSlotKind TypeFeedbackVector::GetKind(
160 FeedbackVectorSlot slot) const { 227 FeedbackVectorSlot slot) const {
161 DCHECK(!is_empty()); 228 DCHECK(!is_empty());
162 return metadata()->GetKind(slot); 229 return metadata()->GetKind(slot);
163 } 230 }
164 231
232 String* TypeFeedbackVector::GetName(FeedbackVectorSlot slot) const {
233 DCHECK(!is_empty());
234 return metadata()->GetName(slot);
235 }
236
165 // static 237 // static
166 Handle<TypeFeedbackVector> TypeFeedbackVector::New( 238 Handle<TypeFeedbackVector> TypeFeedbackVector::New(
167 Isolate* isolate, Handle<TypeFeedbackMetadata> metadata) { 239 Isolate* isolate, Handle<TypeFeedbackMetadata> metadata) {
168 Factory* factory = isolate->factory(); 240 Factory* factory = isolate->factory();
169 241
170 const int slot_count = metadata->slot_count(); 242 const int slot_count = metadata->slot_count();
171 const int length = slot_count + kReservedIndexCount; 243 const int length = slot_count + kReservedIndexCount;
172 if (length == kReservedIndexCount) { 244 if (length == kReservedIndexCount) {
173 return Handle<TypeFeedbackVector>::cast(factory->empty_fixed_array()); 245 return Handle<TypeFeedbackVector>::cast(factory->empty_fixed_array());
174 } 246 }
175 247
176 Handle<FixedArray> array = factory->NewFixedArray(length, TENURED); 248 Handle<FixedArray> array = factory->NewFixedArray(length, TENURED);
177 array->set(kMetadataIndex, *metadata); 249 array->set(kMetadataIndex, *metadata);
178 250
251 DisallowHeapAllocation no_gc;
252
179 // Ensure we can skip the write barrier 253 // Ensure we can skip the write barrier
180 Handle<Object> uninitialized_sentinel = UninitializedSentinel(isolate); 254 Handle<Object> uninitialized_sentinel = UninitializedSentinel(isolate);
181 DCHECK_EQ(*factory->uninitialized_symbol(), *uninitialized_sentinel); 255 DCHECK_EQ(*factory->uninitialized_symbol(), *uninitialized_sentinel);
182 for (int i = 0; i < slot_count;) { 256 for (int i = 0; i < slot_count;) {
183 FeedbackVectorSlot slot(i); 257 FeedbackVectorSlot slot(i);
184 FeedbackVectorSlotKind kind = metadata->GetKind(slot); 258 FeedbackVectorSlotKind kind = metadata->GetKind(slot);
185 int index = TypeFeedbackVector::GetIndex(slot); 259 int index = TypeFeedbackVector::GetIndex(slot);
186 int entry_size = TypeFeedbackMetadata::GetSlotSize(kind); 260 int entry_size = TypeFeedbackMetadata::GetSlotSize(kind);
187 261
188 Object* value; 262 Object* value;
(...skipping 763 matching lines...) Expand 10 before | Expand all | Expand 10 after
952 1026
953 IcCheckType KeyedStoreICNexus::GetKeyType() const { 1027 IcCheckType KeyedStoreICNexus::GetKeyType() const {
954 Object* feedback = GetFeedback(); 1028 Object* feedback = GetFeedback();
955 if (feedback == *TypeFeedbackVector::MegamorphicSentinel(GetIsolate())) { 1029 if (feedback == *TypeFeedbackVector::MegamorphicSentinel(GetIsolate())) {
956 return static_cast<IcCheckType>(Smi::cast(GetFeedbackExtra())->value()); 1030 return static_cast<IcCheckType>(Smi::cast(GetFeedbackExtra())->value());
957 } 1031 }
958 return IsPropertyNameFeedback(feedback) ? PROPERTY : ELEMENT; 1032 return IsPropertyNameFeedback(feedback) ? PROPERTY : ELEMENT;
959 } 1033 }
960 } // namespace internal 1034 } // namespace internal
961 } // namespace v8 1035 } // 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