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

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

Issue 680883004: Introduce FeedbackNexus for vector-based ics. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Comment response. Created 6 years, 1 month 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 | Annotate | Revision Log
« 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/v8.h" 5 #include "src/v8.h"
6 6
7 #include "src/ic/ic.h"
7 #include "src/ic/ic-state.h" 8 #include "src/ic/ic-state.h"
8 #include "src/objects.h" 9 #include "src/objects.h"
9 #include "src/type-feedback-vector-inl.h" 10 #include "src/type-feedback-vector-inl.h"
10 11
11 namespace v8 { 12 namespace v8 {
12 namespace internal { 13 namespace internal {
13 14
14 // static 15 // static
16 TypeFeedbackVector::VectorICKind TypeFeedbackVector::FromCodeKind(
17 Code::Kind kind) {
18 if (kind == Code::CALL_IC) {
19 return KindCallIC;
20 } else if (kind == Code::LOAD_IC) {
21 return KindLoadIC;
22 } else if (kind == Code::KEYED_LOAD_IC) {
23 return KindKeyedLoadIC;
24 }
25
26 // Shouldn't get here.
27 UNREACHABLE();
28 return KindUnused;
29 }
30
31
32 // static
33 Code::Kind TypeFeedbackVector::FromVectorICKind(VectorICKind kind) {
34 if (kind == KindCallIC)
35 return Code::CALL_IC;
36 else if (kind == KindLoadIC)
37 return Code::LOAD_IC;
38 else if (kind == KindKeyedLoadIC)
39 return Code::KEYED_LOAD_IC;
40 DCHECK(kind == KindUnused);
41 return Code::NUMBER_OF_KINDS; // Sentinel for no information.
42 }
43
44
45 Code::Kind TypeFeedbackVector::GetKind(FeedbackVectorICSlot slot) const {
46 if (!FLAG_vector_ics) {
47 // We only have CALL_ICs
48 return Code::CALL_IC;
49 }
50
51 int index = VectorICComputer::index(kReservedIndexCount, slot.ToInt());
52 int data = Smi::cast(get(index))->value();
53 VectorICKind b = VectorICComputer::decode(data, slot.ToInt());
54 return FromVectorICKind(b);
55 }
56
57
58 void TypeFeedbackVector::SetKind(FeedbackVectorICSlot slot, Code::Kind kind) {
59 if (!FLAG_vector_ics) {
60 // Nothing to do if we only have CALL_ICs
61 return;
62 }
63
64 VectorICKind b = FromCodeKind(kind);
65 int index = VectorICComputer::index(kReservedIndexCount, slot.ToInt());
66 int data = Smi::cast(get(index))->value();
67 int new_data = VectorICComputer::encode(data, slot.ToInt(), b);
68 set(index, Smi::FromInt(new_data));
69 }
70
71
72 // static
15 Handle<TypeFeedbackVector> TypeFeedbackVector::Allocate(Isolate* isolate, 73 Handle<TypeFeedbackVector> TypeFeedbackVector::Allocate(Isolate* isolate,
16 int slot_count, 74 int slot_count,
17 int ic_slot_count) { 75 int ic_slot_count) {
18 int length = slot_count + ic_slot_count + kReservedIndexCount; 76 int index_count =
77 FLAG_vector_ics ? VectorICComputer::word_count(ic_slot_count) : 0;
78 int length = slot_count + ic_slot_count + index_count + kReservedIndexCount;
19 if (length == kReservedIndexCount) { 79 if (length == kReservedIndexCount) {
20 return Handle<TypeFeedbackVector>::cast( 80 return Handle<TypeFeedbackVector>::cast(
21 isolate->factory()->empty_fixed_array()); 81 isolate->factory()->empty_fixed_array());
22 } 82 }
23 83
24 Handle<FixedArray> array = isolate->factory()->NewFixedArray(length, TENURED); 84 Handle<FixedArray> array = isolate->factory()->NewFixedArray(length, TENURED);
25 if (ic_slot_count > 0) { 85 if (ic_slot_count > 0) {
26 array->set(kFirstICSlotIndex, 86 array->set(kFirstICSlotIndex,
27 Smi::FromInt(slot_count + kReservedIndexCount)); 87 Smi::FromInt(slot_count + index_count + kReservedIndexCount));
28 } else { 88 } else {
29 array->set(kFirstICSlotIndex, Smi::FromInt(length)); 89 array->set(kFirstICSlotIndex, Smi::FromInt(length));
30 } 90 }
31 array->set(kWithTypesIndex, Smi::FromInt(0)); 91 array->set(kWithTypesIndex, Smi::FromInt(0));
32 array->set(kGenericCountIndex, Smi::FromInt(0)); 92 array->set(kGenericCountIndex, Smi::FromInt(0));
93 // Fill the indexes with zeros.
94 for (int i = 0; i < index_count; i++) {
95 array->set(kReservedIndexCount + i, Smi::FromInt(0));
96 }
33 97
34 // Ensure we can skip the write barrier 98 // Ensure we can skip the write barrier
35 Handle<Object> uninitialized_sentinel = UninitializedSentinel(isolate); 99 Handle<Object> uninitialized_sentinel = UninitializedSentinel(isolate);
36 DCHECK_EQ(isolate->heap()->uninitialized_symbol(), *uninitialized_sentinel); 100 DCHECK_EQ(isolate->heap()->uninitialized_symbol(), *uninitialized_sentinel);
37 for (int i = kReservedIndexCount; i < length; i++) { 101 for (int i = kReservedIndexCount + index_count; i < length; i++) {
38 array->set(i, *uninitialized_sentinel, SKIP_WRITE_BARRIER); 102 array->set(i, *uninitialized_sentinel, SKIP_WRITE_BARRIER);
39 } 103 }
40 return Handle<TypeFeedbackVector>::cast(array); 104 return Handle<TypeFeedbackVector>::cast(array);
41 } 105 }
42 106
43 107
44 // static 108 // static
45 Handle<TypeFeedbackVector> TypeFeedbackVector::Copy( 109 Handle<TypeFeedbackVector> TypeFeedbackVector::Copy(
46 Isolate* isolate, Handle<TypeFeedbackVector> vector) { 110 Isolate* isolate, Handle<TypeFeedbackVector> vector) {
47 Handle<TypeFeedbackVector> result; 111 Handle<TypeFeedbackVector> result;
(...skipping 27 matching lines...) Expand all
75 slots = ICSlots(); 139 slots = ICSlots();
76 if (slots == 0) return; 140 if (slots == 0) return;
77 141
78 // Now clear vector-based ICs. They are all CallICs. 142 // Now clear vector-based ICs. They are all CallICs.
79 // Try and pass the containing code (the "host"). 143 // Try and pass the containing code (the "host").
80 Code* host = shared->code(); 144 Code* host = shared->code();
81 for (int i = 0; i < slots; i++) { 145 for (int i = 0; i < slots; i++) {
82 FeedbackVectorICSlot slot(i); 146 FeedbackVectorICSlot slot(i);
83 Object* obj = Get(slot); 147 Object* obj = Get(slot);
84 if (obj != uninitialized_sentinel) { 148 if (obj != uninitialized_sentinel) {
85 ICUtility::Clear(isolate, Code::CALL_IC, host, this, slot); 149 // TODO(mvstanton): To make this code work with --vector-ics,
150 // additional Nexus types must be created.
151 DCHECK(!FLAG_vector_ics);
152 DCHECK(GetKind(slot) == Code::CALL_IC);
153 CallICNexus nexus(this, slot);
154 ICUtility::Clear(isolate, Code::CALL_IC, host, &nexus);
86 } 155 }
87 } 156 }
88 } 157 }
158
159
160 Handle<FixedArray> FeedbackNexus::EnsureArrayOfSize(int length) {
161 Isolate* isolate = GetIsolate();
162 Handle<Object> feedback = handle(GetFeedback(), isolate);
163 if (!feedback->IsFixedArray() ||
164 FixedArray::cast(*feedback)->length() != length) {
165 Handle<FixedArray> array = isolate->factory()->NewFixedArray(length);
166 SetFeedback(*array);
167 return array;
168 }
169 return Handle<FixedArray>::cast(feedback);
170 }
171
172
173 void FeedbackNexus::InstallHandlers(int start_index, TypeHandleList* types,
174 CodeHandleList* handlers) {
175 Isolate* isolate = GetIsolate();
176 FixedArray* array = FixedArray::cast(GetFeedback());
177 int receiver_count = types->length();
178 for (int current = 0; current < receiver_count; ++current) {
179 Handle<HeapType> type = types->at(current);
180 Handle<Map> map = IC::TypeToMap(*type, isolate);
181 array->set(start_index + (current * 2), *map);
182 array->set(start_index + (current * 2 + 1), *handlers->at(current));
183 }
184 }
185
186
187 InlineCacheState CallICNexus::StateFromFeedback() const {
188 Isolate* isolate = GetIsolate();
189 InlineCacheState state = UNINITIALIZED;
190 Object* feedback = GetFeedback();
191
192 if (feedback == *vector()->MegamorphicSentinel(isolate)) {
193 state = GENERIC;
194 } else if (feedback->IsAllocationSite() || feedback->IsJSFunction()) {
195 state = MONOMORPHIC;
196 } else {
197 CHECK(feedback == *vector()->UninitializedSentinel(isolate));
198 }
199
200 return state;
201 }
202
203
204 void CallICNexus::ConfigureGeneric() {
205 SetFeedback(*vector()->MegamorphicSentinel(GetIsolate()), SKIP_WRITE_BARRIER);
206 }
207
208
209 void CallICNexus::ConfigureMonomorphicArray() {
210 Object* feedback = GetFeedback();
211 if (!feedback->IsAllocationSite()) {
212 Handle<AllocationSite> new_site =
213 GetIsolate()->factory()->NewAllocationSite();
214 SetFeedback(*new_site);
215 }
216 }
217
218
219 void CallICNexus::ConfigureUninitialized() {
220 SetFeedback(*vector()->UninitializedSentinel(GetIsolate()),
221 SKIP_WRITE_BARRIER);
222 }
223
224
225 void CallICNexus::ConfigureMonomorphic(Handle<JSFunction> function) {
226 SetFeedback(*function);
227 }
228
229
230 int FeedbackNexus::ExtractMaps(int start_index, MapHandleList* maps) const {
231 Isolate* isolate = GetIsolate();
232 Object* feedback = GetFeedback();
233 if (feedback->IsFixedArray()) {
234 FixedArray* array = FixedArray::cast(feedback);
235 // The array should be of the form [<optional name>], then
236 // [map, handler, map, handler, ... ]
237 DCHECK(array->length() >= (2 + start_index));
238 for (int i = start_index; i < array->length(); i += 2) {
239 Map* map = Map::cast(array->get(i));
240 maps->Add(handle(map, isolate));
241 }
242 return (array->length() - start_index) / 2;
243 }
244
245 return 0;
246 }
247
248
249 MaybeHandle<Code> FeedbackNexus::FindHandlerForMap(int start_index,
250 Handle<Map> map) const {
251 Object* feedback = GetFeedback();
252 if (feedback->IsFixedArray()) {
253 FixedArray* array = FixedArray::cast(feedback);
254 for (int i = start_index; i < array->length(); i += 2) {
255 Map* array_map = Map::cast(array->get(i));
256 if (array_map == *map) {
257 Code* code = Code::cast(array->get(i + 1));
258 DCHECK(code->kind() == Code::HANDLER);
259 return handle(code);
260 }
261 }
262 }
263
264 return MaybeHandle<Code>();
265 }
266
267
268 bool FeedbackNexus::FindHandlers(int start_index, CodeHandleList* code_list,
269 int length) const {
270 Object* feedback = GetFeedback();
271 int count = 0;
272 if (feedback->IsFixedArray()) {
273 FixedArray* array = FixedArray::cast(feedback);
274 // The array should be of the form [<optional name>], then
275 // [map, handler, map, handler, ... ]
276 DCHECK(array->length() >= (2 + start_index));
277 for (int i = start_index; i < array->length(); i += 2) {
278 Code* code = Code::cast(array->get(i + 1));
279 DCHECK(code->kind() == Code::HANDLER);
280 code_list->Add(handle(code));
281 count++;
282 }
283 }
284 return count == length;
285 }
89 } 286 }
90 } // namespace v8::internal 287 } // namespace v8::internal
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