| 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.h" |
| 8 #include "src/ic/ic-state.h" | 8 #include "src/ic/ic-state.h" |
| 9 #include "src/objects.h" | 9 #include "src/objects.h" |
| 10 #include "src/type-feedback-vector-inl.h" | 10 #include "src/type-feedback-vector-inl.h" |
| (...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 216 SetFeedback(*array); | 216 SetFeedback(*array); |
| 217 return array; | 217 return array; |
| 218 } | 218 } |
| 219 return Handle<FixedArray>::cast(feedback); | 219 return Handle<FixedArray>::cast(feedback); |
| 220 } | 220 } |
| 221 | 221 |
| 222 | 222 |
| 223 void FeedbackNexus::InstallHandlers(int start_index, TypeHandleList* types, | 223 void FeedbackNexus::InstallHandlers(int start_index, TypeHandleList* types, |
| 224 CodeHandleList* handlers) { | 224 CodeHandleList* handlers) { |
| 225 Isolate* isolate = GetIsolate(); | 225 Isolate* isolate = GetIsolate(); |
| 226 FixedArray* array = FixedArray::cast(GetFeedback()); | 226 Handle<FixedArray> array = handle(FixedArray::cast(GetFeedback()), isolate); |
| 227 int receiver_count = types->length(); | 227 int receiver_count = types->length(); |
| 228 for (int current = 0; current < receiver_count; ++current) { | 228 for (int current = 0; current < receiver_count; ++current) { |
| 229 Handle<HeapType> type = types->at(current); | 229 Handle<HeapType> type = types->at(current); |
| 230 Handle<Map> map = IC::TypeToMap(*type, isolate); | 230 Handle<Map> map = IC::TypeToMap(*type, isolate); |
| 231 array->set(start_index + (current * 2), *map); | 231 Handle<WeakCell> cell = Map::WeakCellForMap(map); |
| 232 array->set(start_index + (current * 2), *cell); |
| 232 array->set(start_index + (current * 2 + 1), *handlers->at(current)); | 233 array->set(start_index + (current * 2 + 1), *handlers->at(current)); |
| 233 } | 234 } |
| 234 } | 235 } |
| 235 | 236 |
| 236 | 237 |
| 237 InlineCacheState LoadICNexus::StateFromFeedback() const { | 238 InlineCacheState LoadICNexus::StateFromFeedback() const { |
| 238 Isolate* isolate = GetIsolate(); | 239 Isolate* isolate = GetIsolate(); |
| 239 Object* feedback = GetFeedback(); | 240 Object* feedback = GetFeedback(); |
| 240 if (feedback == *vector()->UninitializedSentinel(isolate)) { | 241 if (feedback == *vector()->UninitializedSentinel(isolate)) { |
| 241 return UNINITIALIZED; | 242 return UNINITIALIZED; |
| 242 } else if (feedback == *vector()->MegamorphicSentinel(isolate)) { | 243 } else if (feedback == *vector()->MegamorphicSentinel(isolate)) { |
| 243 return MEGAMORPHIC; | 244 return MEGAMORPHIC; |
| 244 } else if (feedback == *vector()->PremonomorphicSentinel(isolate)) { | 245 } else if (feedback == *vector()->PremonomorphicSentinel(isolate)) { |
| 245 return PREMONOMORPHIC; | 246 return PREMONOMORPHIC; |
| 246 } else if (feedback->IsFixedArray()) { | 247 } else if (feedback->IsFixedArray()) { |
| 248 // Determine state purely by our structure, don't check if the maps are |
| 249 // cleared. |
| 247 FixedArray* array = FixedArray::cast(feedback); | 250 FixedArray* array = FixedArray::cast(feedback); |
| 248 int length = array->length(); | 251 int length = array->length(); |
| 249 DCHECK(length >= 2); | 252 DCHECK(length >= 2); |
| 250 return length == 2 ? MONOMORPHIC : POLYMORPHIC; | 253 return length == 2 ? MONOMORPHIC : POLYMORPHIC; |
| 251 } | 254 } |
| 252 | 255 |
| 253 return UNINITIALIZED; | 256 return UNINITIALIZED; |
| 254 } | 257 } |
| 255 | 258 |
| 256 | 259 |
| 257 InlineCacheState KeyedLoadICNexus::StateFromFeedback() const { | 260 InlineCacheState KeyedLoadICNexus::StateFromFeedback() const { |
| 258 Isolate* isolate = GetIsolate(); | 261 Isolate* isolate = GetIsolate(); |
| 259 Object* feedback = GetFeedback(); | 262 Object* feedback = GetFeedback(); |
| 260 if (feedback == *vector()->UninitializedSentinel(isolate)) { | 263 if (feedback == *vector()->UninitializedSentinel(isolate)) { |
| 261 return UNINITIALIZED; | 264 return UNINITIALIZED; |
| 262 } else if (feedback == *vector()->PremonomorphicSentinel(isolate)) { | 265 } else if (feedback == *vector()->PremonomorphicSentinel(isolate)) { |
| 263 return PREMONOMORPHIC; | 266 return PREMONOMORPHIC; |
| 264 } else if (feedback == *vector()->GenericSentinel(isolate)) { | 267 } else if (feedback == *vector()->GenericSentinel(isolate)) { |
| 265 return GENERIC; | 268 return GENERIC; |
| 266 } else if (feedback->IsFixedArray()) { | 269 } else if (feedback->IsFixedArray()) { |
| 270 // Determine state purely by our structure, don't check if the maps are |
| 271 // cleared. |
| 267 FixedArray* array = FixedArray::cast(feedback); | 272 FixedArray* array = FixedArray::cast(feedback); |
| 268 int length = array->length(); | 273 int length = array->length(); |
| 269 DCHECK(length >= 3); | 274 DCHECK(length >= 3); |
| 270 return length == 3 ? MONOMORPHIC : POLYMORPHIC; | 275 return length == 3 ? MONOMORPHIC : POLYMORPHIC; |
| 271 } | 276 } |
| 272 | 277 |
| 273 return UNINITIALIZED; | 278 return UNINITIALIZED; |
| 274 } | 279 } |
| 275 | 280 |
| 276 | 281 |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 337 void KeyedLoadICNexus::ConfigurePremonomorphic() { | 342 void KeyedLoadICNexus::ConfigurePremonomorphic() { |
| 338 SetFeedback(*vector()->PremonomorphicSentinel(GetIsolate()), | 343 SetFeedback(*vector()->PremonomorphicSentinel(GetIsolate()), |
| 339 SKIP_WRITE_BARRIER); | 344 SKIP_WRITE_BARRIER); |
| 340 } | 345 } |
| 341 | 346 |
| 342 | 347 |
| 343 void LoadICNexus::ConfigureMonomorphic(Handle<HeapType> type, | 348 void LoadICNexus::ConfigureMonomorphic(Handle<HeapType> type, |
| 344 Handle<Code> handler) { | 349 Handle<Code> handler) { |
| 345 Handle<FixedArray> array = EnsureArrayOfSize(2); | 350 Handle<FixedArray> array = EnsureArrayOfSize(2); |
| 346 Handle<Map> receiver_map = IC::TypeToMap(*type, GetIsolate()); | 351 Handle<Map> receiver_map = IC::TypeToMap(*type, GetIsolate()); |
| 347 array->set(0, *receiver_map); | 352 Handle<WeakCell> cell = Map::WeakCellForMap(receiver_map); |
| 353 array->set(0, *cell); |
| 348 array->set(1, *handler); | 354 array->set(1, *handler); |
| 349 } | 355 } |
| 350 | 356 |
| 351 | 357 |
| 352 void KeyedLoadICNexus::ConfigureMonomorphic(Handle<Name> name, | 358 void KeyedLoadICNexus::ConfigureMonomorphic(Handle<Name> name, |
| 353 Handle<HeapType> type, | 359 Handle<HeapType> type, |
| 354 Handle<Code> handler) { | 360 Handle<Code> handler) { |
| 355 Handle<FixedArray> array = EnsureArrayOfSize(3); | 361 Handle<FixedArray> array = EnsureArrayOfSize(3); |
| 356 Handle<Map> receiver_map = IC::TypeToMap(*type, GetIsolate()); | 362 Handle<Map> receiver_map = IC::TypeToMap(*type, GetIsolate()); |
| 357 if (name.is_null()) { | 363 if (name.is_null()) { |
| 358 array->set(0, Smi::FromInt(0)); | 364 array->set(0, Smi::FromInt(0)); |
| 359 } else { | 365 } else { |
| 360 array->set(0, *name); | 366 array->set(0, *name); |
| 361 } | 367 } |
| 362 array->set(1, *receiver_map); | 368 Handle<WeakCell> cell = Map::WeakCellForMap(receiver_map); |
| 369 array->set(1, *cell); |
| 363 array->set(2, *handler); | 370 array->set(2, *handler); |
| 364 } | 371 } |
| 365 | 372 |
| 366 | 373 |
| 367 void LoadICNexus::ConfigurePolymorphic(TypeHandleList* types, | 374 void LoadICNexus::ConfigurePolymorphic(TypeHandleList* types, |
| 368 CodeHandleList* handlers) { | 375 CodeHandleList* handlers) { |
| 369 int receiver_count = types->length(); | 376 int receiver_count = types->length(); |
| 370 EnsureArrayOfSize(receiver_count * 2); | 377 EnsureArrayOfSize(receiver_count * 2); |
| 371 InstallHandlers(0, types, handlers); | 378 InstallHandlers(0, types, handlers); |
| 372 } | 379 } |
| (...skipping 10 matching lines...) Expand all Loading... |
| 383 array->set(0, *name); | 390 array->set(0, *name); |
| 384 } | 391 } |
| 385 InstallHandlers(1, types, handlers); | 392 InstallHandlers(1, types, handlers); |
| 386 } | 393 } |
| 387 | 394 |
| 388 | 395 |
| 389 int FeedbackNexus::ExtractMaps(int start_index, MapHandleList* maps) const { | 396 int FeedbackNexus::ExtractMaps(int start_index, MapHandleList* maps) const { |
| 390 Isolate* isolate = GetIsolate(); | 397 Isolate* isolate = GetIsolate(); |
| 391 Object* feedback = GetFeedback(); | 398 Object* feedback = GetFeedback(); |
| 392 if (feedback->IsFixedArray()) { | 399 if (feedback->IsFixedArray()) { |
| 400 int found = 0; |
| 393 FixedArray* array = FixedArray::cast(feedback); | 401 FixedArray* array = FixedArray::cast(feedback); |
| 394 // The array should be of the form [<optional name>], then | 402 // The array should be of the form [<optional name>], then |
| 395 // [map, handler, map, handler, ... ] | 403 // [map, handler, map, handler, ... ] |
| 396 DCHECK(array->length() >= (2 + start_index)); | 404 DCHECK(array->length() >= (2 + start_index)); |
| 397 for (int i = start_index; i < array->length(); i += 2) { | 405 for (int i = start_index; i < array->length(); i += 2) { |
| 398 Map* map = Map::cast(array->get(i)); | 406 WeakCell* cell = WeakCell::cast(array->get(i)); |
| 399 maps->Add(handle(map, isolate)); | 407 if (!cell->cleared()) { |
| 408 Map* map = Map::cast(cell->value()); |
| 409 maps->Add(handle(map, isolate)); |
| 410 found++; |
| 411 } |
| 400 } | 412 } |
| 401 return (array->length() - start_index) / 2; | 413 return found; |
| 402 } | 414 } |
| 403 | 415 |
| 404 return 0; | 416 return 0; |
| 405 } | 417 } |
| 406 | 418 |
| 407 | 419 |
| 408 MaybeHandle<Code> FeedbackNexus::FindHandlerForMap(int start_index, | 420 MaybeHandle<Code> FeedbackNexus::FindHandlerForMap(int start_index, |
| 409 Handle<Map> map) const { | 421 Handle<Map> map) const { |
| 410 Object* feedback = GetFeedback(); | 422 Object* feedback = GetFeedback(); |
| 411 if (feedback->IsFixedArray()) { | 423 if (feedback->IsFixedArray()) { |
| 412 FixedArray* array = FixedArray::cast(feedback); | 424 FixedArray* array = FixedArray::cast(feedback); |
| 413 for (int i = start_index; i < array->length(); i += 2) { | 425 for (int i = start_index; i < array->length(); i += 2) { |
| 414 Map* array_map = Map::cast(array->get(i)); | 426 WeakCell* cell = WeakCell::cast(array->get(i)); |
| 415 if (array_map == *map) { | 427 if (!cell->cleared()) { |
| 416 Code* code = Code::cast(array->get(i + 1)); | 428 Map* array_map = Map::cast(cell->value()); |
| 417 DCHECK(code->kind() == Code::HANDLER); | 429 if (array_map == *map) { |
| 418 return handle(code); | 430 Code* code = Code::cast(array->get(i + 1)); |
| 431 DCHECK(code->kind() == Code::HANDLER); |
| 432 return handle(code); |
| 433 } |
| 419 } | 434 } |
| 420 } | 435 } |
| 421 } | 436 } |
| 422 | 437 |
| 423 return MaybeHandle<Code>(); | 438 return MaybeHandle<Code>(); |
| 424 } | 439 } |
| 425 | 440 |
| 426 | 441 |
| 427 bool FeedbackNexus::FindHandlers(int start_index, CodeHandleList* code_list, | 442 bool FeedbackNexus::FindHandlers(int start_index, CodeHandleList* code_list, |
| 428 int length) const { | 443 int length) const { |
| 429 Object* feedback = GetFeedback(); | 444 Object* feedback = GetFeedback(); |
| 430 int count = 0; | 445 int count = 0; |
| 431 if (feedback->IsFixedArray()) { | 446 if (feedback->IsFixedArray()) { |
| 432 FixedArray* array = FixedArray::cast(feedback); | 447 FixedArray* array = FixedArray::cast(feedback); |
| 433 // The array should be of the form [<optional name>], then | 448 // The array should be of the form [<optional name>], then |
| 434 // [map, handler, map, handler, ... ] | 449 // [map, handler, map, handler, ... ]. Be sure to skip handlers whose maps |
| 450 // have been cleared. |
| 435 DCHECK(array->length() >= (2 + start_index)); | 451 DCHECK(array->length() >= (2 + start_index)); |
| 436 for (int i = start_index; i < array->length(); i += 2) { | 452 for (int i = start_index; i < array->length(); i += 2) { |
| 437 Code* code = Code::cast(array->get(i + 1)); | 453 WeakCell* cell = WeakCell::cast(array->get(i)); |
| 438 DCHECK(code->kind() == Code::HANDLER); | 454 if (!cell->cleared()) { |
| 439 code_list->Add(handle(code)); | 455 Code* code = Code::cast(array->get(i + 1)); |
| 440 count++; | 456 DCHECK(code->kind() == Code::HANDLER); |
| 457 code_list->Add(handle(code)); |
| 458 count++; |
| 459 } |
| 441 } | 460 } |
| 442 } | 461 } |
| 443 return count == length; | 462 return count == length; |
| 444 } | 463 } |
| 445 | 464 |
| 446 | 465 |
| 447 int LoadICNexus::ExtractMaps(MapHandleList* maps) const { | 466 int LoadICNexus::ExtractMaps(MapHandleList* maps) const { |
| 448 return FeedbackNexus::ExtractMaps(0, maps); | 467 return FeedbackNexus::ExtractMaps(0, maps); |
| 449 } | 468 } |
| 450 | 469 |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 488 if (feedback->IsFixedArray()) { | 507 if (feedback->IsFixedArray()) { |
| 489 FixedArray* array = FixedArray::cast(feedback); | 508 FixedArray* array = FixedArray::cast(feedback); |
| 490 DCHECK(array->length() >= 3); | 509 DCHECK(array->length() >= 3); |
| 491 Object* name = array->get(0); | 510 Object* name = array->get(0); |
| 492 if (name->IsName()) return Name::cast(name); | 511 if (name->IsName()) return Name::cast(name); |
| 493 } | 512 } |
| 494 return NULL; | 513 return NULL; |
| 495 } | 514 } |
| 496 } | 515 } |
| 497 } // namespace v8::internal | 516 } // namespace v8::internal |
| OLD | NEW |