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" | |
8 #include "src/ic/ic-state.h" | 7 #include "src/ic/ic-state.h" |
9 #include "src/objects.h" | 8 #include "src/objects.h" |
10 #include "src/type-feedback-vector-inl.h" | 9 #include "src/type-feedback-vector-inl.h" |
11 | 10 |
12 namespace v8 { | 11 namespace v8 { |
13 namespace internal { | 12 namespace internal { |
14 | 13 |
15 // static | 14 // static |
16 TypeFeedbackVector::VectorICKind TypeFeedbackVector::FromCodeKind( | 15 TypeFeedbackVector::VectorICKind TypeFeedbackVector::FromCodeKind( |
17 Code::Kind kind) { | 16 Code::Kind kind) { |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
145 slots = ICSlots(); | 144 slots = ICSlots(); |
146 if (slots == 0) return; | 145 if (slots == 0) return; |
147 | 146 |
148 // Now clear vector-based ICs. They are all CallICs. | 147 // Now clear vector-based ICs. They are all CallICs. |
149 // Try and pass the containing code (the "host"). | 148 // Try and pass the containing code (the "host"). |
150 Code* host = shared->code(); | 149 Code* host = shared->code(); |
151 for (int i = 0; i < slots; i++) { | 150 for (int i = 0; i < slots; i++) { |
152 FeedbackVectorICSlot slot(i); | 151 FeedbackVectorICSlot slot(i); |
153 Object* obj = Get(slot); | 152 Object* obj = Get(slot); |
154 if (obj != uninitialized_sentinel) { | 153 if (obj != uninitialized_sentinel) { |
155 // TODO(mvstanton): To make this code work with --vector-ics, | 154 ICUtility::Clear(isolate, Code::CALL_IC, host, this, slot); |
156 // additional Nexus types must be created. | |
157 DCHECK(!FLAG_vector_ics); | |
158 DCHECK(GetKind(slot) == Code::CALL_IC); | |
159 CallICNexus nexus(this, slot); | |
160 ICUtility::Clear(isolate, Code::CALL_IC, host, &nexus); | |
161 } | 155 } |
162 } | 156 } |
163 } | 157 } |
164 | |
165 | |
166 Handle<FixedArray> FeedbackNexus::EnsureArrayOfSize(int length) { | |
167 Isolate* isolate = GetIsolate(); | |
168 Handle<Object> feedback = handle(GetFeedback(), isolate); | |
169 if (!feedback->IsFixedArray() || | |
170 FixedArray::cast(*feedback)->length() != length) { | |
171 Handle<FixedArray> array = isolate->factory()->NewFixedArray(length); | |
172 SetFeedback(*array); | |
173 return array; | |
174 } | |
175 return Handle<FixedArray>::cast(feedback); | |
176 } | |
177 | |
178 | |
179 void FeedbackNexus::InstallHandlers(int start_index, TypeHandleList* types, | |
180 CodeHandleList* handlers) { | |
181 Isolate* isolate = GetIsolate(); | |
182 FixedArray* array = FixedArray::cast(GetFeedback()); | |
183 int receiver_count = types->length(); | |
184 for (int current = 0; current < receiver_count; ++current) { | |
185 Handle<HeapType> type = types->at(current); | |
186 Handle<Map> map = IC::TypeToMap(*type, isolate); | |
187 array->set(start_index + (current * 2), *map); | |
188 array->set(start_index + (current * 2 + 1), *handlers->at(current)); | |
189 } | |
190 } | |
191 | |
192 | |
193 InlineCacheState CallICNexus::StateFromFeedback() const { | |
194 Isolate* isolate = GetIsolate(); | |
195 InlineCacheState state = UNINITIALIZED; | |
196 Object* feedback = GetFeedback(); | |
197 | |
198 if (feedback == *vector()->MegamorphicSentinel(isolate)) { | |
199 state = GENERIC; | |
200 } else if (feedback->IsAllocationSite() || feedback->IsJSFunction()) { | |
201 state = MONOMORPHIC; | |
202 } else { | |
203 CHECK(feedback == *vector()->UninitializedSentinel(isolate)); | |
204 } | |
205 | |
206 return state; | |
207 } | |
208 | |
209 | |
210 void CallICNexus::ConfigureGeneric() { | |
211 SetFeedback(*vector()->MegamorphicSentinel(GetIsolate()), SKIP_WRITE_BARRIER); | |
212 } | |
213 | |
214 | |
215 void CallICNexus::ConfigureMonomorphicArray() { | |
216 Object* feedback = GetFeedback(); | |
217 if (!feedback->IsAllocationSite()) { | |
218 Handle<AllocationSite> new_site = | |
219 GetIsolate()->factory()->NewAllocationSite(); | |
220 SetFeedback(*new_site); | |
221 } | |
222 } | |
223 | |
224 | |
225 void CallICNexus::ConfigureUninitialized() { | |
226 SetFeedback(*vector()->UninitializedSentinel(GetIsolate()), | |
227 SKIP_WRITE_BARRIER); | |
228 } | |
229 | |
230 | |
231 void CallICNexus::ConfigureMonomorphic(Handle<JSFunction> function) { | |
232 SetFeedback(*function); | |
233 } | |
234 | |
235 | |
236 int FeedbackNexus::ExtractMaps(int start_index, MapHandleList* maps) const { | |
237 Isolate* isolate = GetIsolate(); | |
238 Object* feedback = GetFeedback(); | |
239 if (feedback->IsFixedArray()) { | |
240 FixedArray* array = FixedArray::cast(feedback); | |
241 // The array should be of the form [<optional name>], then | |
242 // [map, handler, map, handler, ... ] | |
243 DCHECK(array->length() >= (2 + start_index)); | |
244 for (int i = start_index; i < array->length(); i += 2) { | |
245 Map* map = Map::cast(array->get(i)); | |
246 maps->Add(handle(map, isolate)); | |
247 } | |
248 return (array->length() - start_index) / 2; | |
249 } | |
250 | |
251 return 0; | |
252 } | |
253 | |
254 | |
255 MaybeHandle<Code> FeedbackNexus::FindHandlerForMap(int start_index, | |
256 Handle<Map> map) const { | |
257 Object* feedback = GetFeedback(); | |
258 if (feedback->IsFixedArray()) { | |
259 FixedArray* array = FixedArray::cast(feedback); | |
260 for (int i = start_index; i < array->length(); i += 2) { | |
261 Map* array_map = Map::cast(array->get(i)); | |
262 if (array_map == *map) { | |
263 Code* code = Code::cast(array->get(i + 1)); | |
264 DCHECK(code->kind() == Code::HANDLER); | |
265 return handle(code); | |
266 } | |
267 } | |
268 } | |
269 | |
270 return MaybeHandle<Code>(); | |
271 } | |
272 | |
273 | |
274 bool FeedbackNexus::FindHandlers(int start_index, CodeHandleList* code_list, | |
275 int length) const { | |
276 Object* feedback = GetFeedback(); | |
277 int count = 0; | |
278 if (feedback->IsFixedArray()) { | |
279 FixedArray* array = FixedArray::cast(feedback); | |
280 // The array should be of the form [<optional name>], then | |
281 // [map, handler, map, handler, ... ] | |
282 DCHECK(array->length() >= (2 + start_index)); | |
283 for (int i = start_index; i < array->length(); i += 2) { | |
284 Code* code = Code::cast(array->get(i + 1)); | |
285 DCHECK(code->kind() == Code::HANDLER); | |
286 code_list->Add(handle(code)); | |
287 count++; | |
288 } | |
289 } | |
290 return count == length; | |
291 } | |
292 } | 158 } |
293 } // namespace v8::internal | 159 } // namespace v8::internal |
OLD | NEW |