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 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
144 slots = ICSlots(); | 145 slots = ICSlots(); |
145 if (slots == 0) return; | 146 if (slots == 0) return; |
146 | 147 |
147 // Now clear vector-based ICs. They are all CallICs. | 148 // Now clear vector-based ICs. They are all CallICs. |
148 // Try and pass the containing code (the "host"). | 149 // Try and pass the containing code (the "host"). |
149 Code* host = shared->code(); | 150 Code* host = shared->code(); |
150 for (int i = 0; i < slots; i++) { | 151 for (int i = 0; i < slots; i++) { |
151 FeedbackVectorICSlot slot(i); | 152 FeedbackVectorICSlot slot(i); |
152 Object* obj = Get(slot); | 153 Object* obj = Get(slot); |
153 if (obj != uninitialized_sentinel) { | 154 if (obj != uninitialized_sentinel) { |
154 ICUtility::Clear(isolate, Code::CALL_IC, host, this, slot); | 155 // TODO(mvstanton): To make this code work with --vector-ics, |
| 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); |
155 } | 161 } |
156 } | 162 } |
157 } | 163 } |
| 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 } |
158 } | 292 } |
159 } // namespace v8::internal | 293 } // namespace v8::internal |
OLD | NEW |