OLD | NEW |
---|---|
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 |
15 TypeFeedbackVector::VectorICKind TypeFeedbackVector::FromCodeKind( | 16 TypeFeedbackVector::VectorICKind TypeFeedbackVector::FromCodeKind( |
16 Code::Kind kind) { | 17 Code::Kind kind) { |
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
138 slots = ICSlots(); | 139 slots = ICSlots(); |
139 if (slots == 0) return; | 140 if (slots == 0) return; |
140 | 141 |
141 // Now clear vector-based ICs. They are all CallICs. | 142 // Now clear vector-based ICs. They are all CallICs. |
142 // Try and pass the containing code (the "host"). | 143 // Try and pass the containing code (the "host"). |
143 Code* host = shared->code(); | 144 Code* host = shared->code(); |
144 for (int i = 0; i < slots; i++) { | 145 for (int i = 0; i < slots; i++) { |
145 FeedbackVectorICSlot slot(i); | 146 FeedbackVectorICSlot slot(i); |
146 Object* obj = Get(slot); | 147 Object* obj = Get(slot); |
147 if (obj != uninitialized_sentinel) { | 148 if (obj != uninitialized_sentinel) { |
148 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); | |
149 } | 155 } |
150 } | 156 } |
151 } | 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) { | |
Igor Sheludko
2014/10/28 11:12:36
Do we need to allocate another array if existing o
mvstanton
2014/10/28 13:23:28
Hmm, the only case that would happen would be if t
| |
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())); | |
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 } | |
222 | |
223 | |
224 void CallICNexus::ConfigureMonomorphic(Handle<JSFunction> function) { | |
225 SetFeedback(*function); | |
226 } | |
227 | |
Igor Sheludko
2014/10/28 11:12:36
Empty line is missing.
mvstanton
2014/10/28 13:23:28
Done.
| |
228 int FeedbackNexus::ExtractMaps(int start_index, MapHandleList* maps) const { | |
229 Isolate* isolate = GetIsolate(); | |
230 Object* feedback = GetFeedback(); | |
231 if (feedback->IsFixedArray()) { | |
232 FixedArray* array = FixedArray::cast(feedback); | |
233 // The array should be of the form [<optional name>], then | |
234 // [map, handler, map, handler, ... ] | |
235 DCHECK(array->length() >= (2 + start_index)); | |
236 for (int i = start_index; i < array->length(); i += 2) { | |
237 Map* map = Map::cast(array->get(i)); | |
238 maps->Add(handle(map, isolate)); | |
239 } | |
240 return (array->length() - start_index) / 2; | |
241 } | |
242 | |
243 return 0; | |
244 } | |
245 | |
246 | |
247 MaybeHandle<Code> FeedbackNexus::FindHandlerForMap(int start_index, | |
248 Handle<Map> map) const { | |
249 Object* feedback = GetFeedback(); | |
250 if (feedback->IsFixedArray()) { | |
251 FixedArray* array = FixedArray::cast(feedback); | |
252 for (int i = start_index; i < array->length(); i += 2) { | |
253 Map* array_map = Map::cast(array->get(i)); | |
254 if (array_map == *map) { | |
255 Code* code = Code::cast(array->get(i + 1)); | |
256 DCHECK(code->kind() == Code::HANDLER); | |
257 return handle(code); | |
258 } | |
259 } | |
260 } | |
261 | |
262 return MaybeHandle<Code>(); | |
263 } | |
264 | |
265 | |
266 bool FeedbackNexus::FindHandlers(int start_index, CodeHandleList* code_list, | |
267 int length) const { | |
268 Object* feedback = GetFeedback(); | |
269 int count = 0; | |
270 if (feedback->IsFixedArray()) { | |
271 FixedArray* array = FixedArray::cast(feedback); | |
272 // The array should be of the form [<optional name>], then | |
273 // [map, handler, map, handler, ... ] | |
274 DCHECK(array->length() >= (2 + start_index)); | |
275 for (int i = start_index; i < array->length(); i += 2) { | |
276 Code* code = Code::cast(array->get(i + 1)); | |
277 DCHECK(code->kind() == Code::HANDLER); | |
278 code_list->Add(handle(code)); | |
279 count++; | |
280 } | |
281 } | |
282 return count == length; | |
283 } | |
152 } | 284 } |
153 } // namespace v8::internal | 285 } // namespace v8::internal |
OLD | NEW |