| 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/code-stubs.h" | 7 #include "src/code-stubs.h" |
| 8 #include "src/ic/ic.h" | 8 #include "src/ic/ic.h" |
| 9 #include "src/ic/ic-state.h" | 9 #include "src/ic/ic-state.h" |
| 10 #include "src/objects.h" | 10 #include "src/objects.h" |
| (...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 204 Code::Kind kind = GetKind(slot); | 204 Code::Kind kind = GetKind(slot); |
| 205 if (kind == Code::CALL_IC) { | 205 if (kind == Code::CALL_IC) { |
| 206 CallICNexus nexus(this, slot); | 206 CallICNexus nexus(this, slot); |
| 207 nexus.Clear(host); | 207 nexus.Clear(host); |
| 208 } else if (kind == Code::LOAD_IC) { | 208 } else if (kind == Code::LOAD_IC) { |
| 209 LoadICNexus nexus(this, slot); | 209 LoadICNexus nexus(this, slot); |
| 210 nexus.Clear(host); | 210 nexus.Clear(host); |
| 211 } else if (kind == Code::KEYED_LOAD_IC) { | 211 } else if (kind == Code::KEYED_LOAD_IC) { |
| 212 KeyedLoadICNexus nexus(this, slot); | 212 KeyedLoadICNexus nexus(this, slot); |
| 213 nexus.Clear(host); | 213 nexus.Clear(host); |
| 214 } else if (kind == Code::STORE_IC) { |
| 215 DCHECK(FLAG_vector_stores); |
| 216 StoreICNexus nexus(this, slot); |
| 217 nexus.Clear(host); |
| 218 } else if (kind == Code::KEYED_STORE_IC) { |
| 219 DCHECK(FLAG_vector_stores); |
| 220 KeyedStoreICNexus nexus(this, slot); |
| 221 nexus.Clear(host); |
| 214 } | 222 } |
| 215 // TODO(mvstanton): Handle clearing of store ics when FLAG_vector_stores | |
| 216 // is true. | |
| 217 } | 223 } |
| 218 } | 224 } |
| 219 } | 225 } |
| 220 | 226 |
| 221 | 227 |
| 222 Handle<FixedArray> FeedbackNexus::EnsureArrayOfSize(int length) { | 228 Handle<FixedArray> FeedbackNexus::EnsureArrayOfSize(int length) { |
| 223 Isolate* isolate = GetIsolate(); | 229 Isolate* isolate = GetIsolate(); |
| 224 Handle<Object> feedback = handle(GetFeedback(), isolate); | 230 Handle<Object> feedback = handle(GetFeedback(), isolate); |
| 225 if (!feedback->IsFixedArray() || | 231 if (!feedback->IsFixedArray() || |
| 226 FixedArray::cast(*feedback)->length() != length) { | 232 FixedArray::cast(*feedback)->length() != length) { |
| (...skipping 24 matching lines...) Expand all Loading... |
| 251 int receiver_count = maps->length(); | 257 int receiver_count = maps->length(); |
| 252 for (int current = 0; current < receiver_count; ++current) { | 258 for (int current = 0; current < receiver_count; ++current) { |
| 253 Handle<Map> map = maps->at(current); | 259 Handle<Map> map = maps->at(current); |
| 254 Handle<WeakCell> cell = Map::WeakCellForMap(map); | 260 Handle<WeakCell> cell = Map::WeakCellForMap(map); |
| 255 array->set(current * 2, *cell); | 261 array->set(current * 2, *cell); |
| 256 array->set(current * 2 + 1, *handlers->at(current)); | 262 array->set(current * 2 + 1, *handlers->at(current)); |
| 257 } | 263 } |
| 258 } | 264 } |
| 259 | 265 |
| 260 | 266 |
| 267 void FeedbackNexus::ConfigureUninitialized() { |
| 268 SetFeedback(*TypeFeedbackVector::UninitializedSentinel(GetIsolate()), |
| 269 SKIP_WRITE_BARRIER); |
| 270 SetFeedbackExtra(*TypeFeedbackVector::UninitializedSentinel(GetIsolate()), |
| 271 SKIP_WRITE_BARRIER); |
| 272 } |
| 273 |
| 274 |
| 275 void FeedbackNexus::ConfigurePremonomorphic() { |
| 276 SetFeedback(*TypeFeedbackVector::PremonomorphicSentinel(GetIsolate()), |
| 277 SKIP_WRITE_BARRIER); |
| 278 SetFeedbackExtra(*TypeFeedbackVector::UninitializedSentinel(GetIsolate()), |
| 279 SKIP_WRITE_BARRIER); |
| 280 } |
| 281 |
| 282 |
| 283 void FeedbackNexus::ConfigureMegamorphic() { |
| 284 Isolate* isolate = GetIsolate(); |
| 285 SetFeedback(*TypeFeedbackVector::MegamorphicSentinel(isolate), |
| 286 SKIP_WRITE_BARRIER); |
| 287 SetFeedbackExtra(*TypeFeedbackVector::UninitializedSentinel(isolate), |
| 288 SKIP_WRITE_BARRIER); |
| 289 } |
| 290 |
| 291 |
| 261 InlineCacheState LoadICNexus::StateFromFeedback() const { | 292 InlineCacheState LoadICNexus::StateFromFeedback() const { |
| 262 Isolate* isolate = GetIsolate(); | 293 Isolate* isolate = GetIsolate(); |
| 263 Object* feedback = GetFeedback(); | 294 Object* feedback = GetFeedback(); |
| 264 | 295 |
| 265 if (feedback == *TypeFeedbackVector::UninitializedSentinel(isolate)) { | 296 if (feedback == *TypeFeedbackVector::UninitializedSentinel(isolate)) { |
| 266 return UNINITIALIZED; | 297 return UNINITIALIZED; |
| 267 } else if (feedback == *TypeFeedbackVector::MegamorphicSentinel(isolate)) { | 298 } else if (feedback == *TypeFeedbackVector::MegamorphicSentinel(isolate)) { |
| 268 return MEGAMORPHIC; | 299 return MEGAMORPHIC; |
| 269 } else if (feedback == *TypeFeedbackVector::PremonomorphicSentinel(isolate)) { | 300 } else if (feedback == *TypeFeedbackVector::PremonomorphicSentinel(isolate)) { |
| 270 return PREMONOMORPHIC; | 301 return PREMONOMORPHIC; |
| (...skipping 30 matching lines...) Expand all Loading... |
| 301 } else if (feedback->IsName()) { | 332 } else if (feedback->IsName()) { |
| 302 Object* extra = GetFeedbackExtra(); | 333 Object* extra = GetFeedbackExtra(); |
| 303 FixedArray* extra_array = FixedArray::cast(extra); | 334 FixedArray* extra_array = FixedArray::cast(extra); |
| 304 return extra_array->length() > 2 ? POLYMORPHIC : MONOMORPHIC; | 335 return extra_array->length() > 2 ? POLYMORPHIC : MONOMORPHIC; |
| 305 } | 336 } |
| 306 | 337 |
| 307 return UNINITIALIZED; | 338 return UNINITIALIZED; |
| 308 } | 339 } |
| 309 | 340 |
| 310 | 341 |
| 342 InlineCacheState StoreICNexus::StateFromFeedback() const { |
| 343 Isolate* isolate = GetIsolate(); |
| 344 Object* feedback = GetFeedback(); |
| 345 |
| 346 if (feedback == *TypeFeedbackVector::UninitializedSentinel(isolate)) { |
| 347 return UNINITIALIZED; |
| 348 } else if (feedback == *TypeFeedbackVector::MegamorphicSentinel(isolate)) { |
| 349 return MEGAMORPHIC; |
| 350 } else if (feedback == *TypeFeedbackVector::PremonomorphicSentinel(isolate)) { |
| 351 return PREMONOMORPHIC; |
| 352 } else if (feedback->IsFixedArray()) { |
| 353 // Determine state purely by our structure, don't check if the maps are |
| 354 // cleared. |
| 355 return POLYMORPHIC; |
| 356 } else if (feedback->IsWeakCell()) { |
| 357 // Don't check if the map is cleared. |
| 358 return MONOMORPHIC; |
| 359 } |
| 360 |
| 361 return UNINITIALIZED; |
| 362 } |
| 363 |
| 364 |
| 365 InlineCacheState KeyedStoreICNexus::StateFromFeedback() const { |
| 366 Isolate* isolate = GetIsolate(); |
| 367 Object* feedback = GetFeedback(); |
| 368 |
| 369 if (feedback == *TypeFeedbackVector::UninitializedSentinel(isolate)) { |
| 370 return UNINITIALIZED; |
| 371 } else if (feedback == *TypeFeedbackVector::PremonomorphicSentinel(isolate)) { |
| 372 return PREMONOMORPHIC; |
| 373 } else if (feedback == *TypeFeedbackVector::MegamorphicSentinel(isolate)) { |
| 374 return MEGAMORPHIC; |
| 375 } else if (feedback->IsFixedArray()) { |
| 376 // Determine state purely by our structure, don't check if the maps are |
| 377 // cleared. |
| 378 return POLYMORPHIC; |
| 379 } else if (feedback->IsWeakCell()) { |
| 380 // Don't check if the map is cleared. |
| 381 return MONOMORPHIC; |
| 382 } else if (feedback->IsName()) { |
| 383 Object* extra = GetFeedbackExtra(); |
| 384 FixedArray* extra_array = FixedArray::cast(extra); |
| 385 return extra_array->length() > 2 ? POLYMORPHIC : MONOMORPHIC; |
| 386 } |
| 387 |
| 388 return UNINITIALIZED; |
| 389 } |
| 390 |
| 391 |
| 311 InlineCacheState CallICNexus::StateFromFeedback() const { | 392 InlineCacheState CallICNexus::StateFromFeedback() const { |
| 312 Isolate* isolate = GetIsolate(); | 393 Isolate* isolate = GetIsolate(); |
| 313 Object* feedback = GetFeedback(); | 394 Object* feedback = GetFeedback(); |
| 314 DCHECK(GetFeedbackExtra() == | 395 DCHECK(GetFeedbackExtra() == |
| 315 *TypeFeedbackVector::UninitializedSentinel(isolate) || | 396 *TypeFeedbackVector::UninitializedSentinel(isolate) || |
| 316 GetFeedbackExtra()->IsSmi()); | 397 GetFeedbackExtra()->IsSmi()); |
| 317 | 398 |
| 318 if (feedback == *TypeFeedbackVector::MegamorphicSentinel(isolate)) { | 399 if (feedback == *TypeFeedbackVector::MegamorphicSentinel(isolate)) { |
| 319 return GENERIC; | 400 return GENERIC; |
| 320 } else if (feedback->IsAllocationSite() || feedback->IsWeakCell()) { | 401 } else if (feedback->IsAllocationSite() || feedback->IsWeakCell()) { |
| (...skipping 11 matching lines...) Expand all Loading... |
| 332 int value = Smi::cast(call_count)->value() / 2; | 413 int value = Smi::cast(call_count)->value() / 2; |
| 333 return value; | 414 return value; |
| 334 } | 415 } |
| 335 return -1; | 416 return -1; |
| 336 } | 417 } |
| 337 | 418 |
| 338 | 419 |
| 339 void CallICNexus::Clear(Code* host) { CallIC::Clear(GetIsolate(), host, this); } | 420 void CallICNexus::Clear(Code* host) { CallIC::Clear(GetIsolate(), host, this); } |
| 340 | 421 |
| 341 | 422 |
| 342 void CallICNexus::ConfigureGeneric() { | |
| 343 SetFeedback(*TypeFeedbackVector::MegamorphicSentinel(GetIsolate()), | |
| 344 SKIP_WRITE_BARRIER); | |
| 345 SetFeedbackExtra(*TypeFeedbackVector::UninitializedSentinel(GetIsolate()), | |
| 346 SKIP_WRITE_BARRIER); | |
| 347 } | |
| 348 | |
| 349 | |
| 350 void CallICNexus::ConfigureMonomorphicArray() { | 423 void CallICNexus::ConfigureMonomorphicArray() { |
| 351 Object* feedback = GetFeedback(); | 424 Object* feedback = GetFeedback(); |
| 352 if (!feedback->IsAllocationSite()) { | 425 if (!feedback->IsAllocationSite()) { |
| 353 Handle<AllocationSite> new_site = | 426 Handle<AllocationSite> new_site = |
| 354 GetIsolate()->factory()->NewAllocationSite(); | 427 GetIsolate()->factory()->NewAllocationSite(); |
| 355 SetFeedback(*new_site); | 428 SetFeedback(*new_site); |
| 356 } | 429 } |
| 357 SetFeedbackExtra(Smi::FromInt(kCallCountIncrement), SKIP_WRITE_BARRIER); | 430 SetFeedbackExtra(Smi::FromInt(kCallCountIncrement), SKIP_WRITE_BARRIER); |
| 358 } | 431 } |
| 359 | 432 |
| 360 | 433 |
| 361 void CallICNexus::ConfigureUninitialized() { | |
| 362 SetFeedback(*TypeFeedbackVector::UninitializedSentinel(GetIsolate()), | |
| 363 SKIP_WRITE_BARRIER); | |
| 364 SetFeedbackExtra(*TypeFeedbackVector::UninitializedSentinel(GetIsolate()), | |
| 365 SKIP_WRITE_BARRIER); | |
| 366 } | |
| 367 | |
| 368 | |
| 369 void CallICNexus::ConfigureMonomorphic(Handle<JSFunction> function) { | 434 void CallICNexus::ConfigureMonomorphic(Handle<JSFunction> function) { |
| 370 Handle<WeakCell> new_cell = GetIsolate()->factory()->NewWeakCell(function); | 435 Handle<WeakCell> new_cell = GetIsolate()->factory()->NewWeakCell(function); |
| 371 SetFeedback(*new_cell); | 436 SetFeedback(*new_cell); |
| 372 SetFeedbackExtra(Smi::FromInt(kCallCountIncrement), SKIP_WRITE_BARRIER); | 437 SetFeedbackExtra(Smi::FromInt(kCallCountIncrement), SKIP_WRITE_BARRIER); |
| 373 } | 438 } |
| 374 | 439 |
| 375 | 440 |
| 376 void KeyedLoadICNexus::ConfigureMegamorphic() { | |
| 377 Isolate* isolate = GetIsolate(); | |
| 378 SetFeedback(*TypeFeedbackVector::MegamorphicSentinel(isolate), | |
| 379 SKIP_WRITE_BARRIER); | |
| 380 SetFeedbackExtra(*TypeFeedbackVector::UninitializedSentinel(isolate), | |
| 381 SKIP_WRITE_BARRIER); | |
| 382 } | |
| 383 | |
| 384 | |
| 385 void LoadICNexus::ConfigureMegamorphic() { | |
| 386 SetFeedback(*TypeFeedbackVector::MegamorphicSentinel(GetIsolate()), | |
| 387 SKIP_WRITE_BARRIER); | |
| 388 SetFeedbackExtra(*TypeFeedbackVector::UninitializedSentinel(GetIsolate()), | |
| 389 SKIP_WRITE_BARRIER); | |
| 390 } | |
| 391 | |
| 392 | |
| 393 void LoadICNexus::ConfigurePremonomorphic() { | |
| 394 SetFeedback(*TypeFeedbackVector::PremonomorphicSentinel(GetIsolate()), | |
| 395 SKIP_WRITE_BARRIER); | |
| 396 SetFeedbackExtra(*TypeFeedbackVector::UninitializedSentinel(GetIsolate()), | |
| 397 SKIP_WRITE_BARRIER); | |
| 398 } | |
| 399 | |
| 400 | |
| 401 void KeyedLoadICNexus::ConfigurePremonomorphic() { | |
| 402 Isolate* isolate = GetIsolate(); | |
| 403 SetFeedback(*TypeFeedbackVector::PremonomorphicSentinel(isolate), | |
| 404 SKIP_WRITE_BARRIER); | |
| 405 SetFeedbackExtra(*TypeFeedbackVector::UninitializedSentinel(isolate), | |
| 406 SKIP_WRITE_BARRIER); | |
| 407 } | |
| 408 | |
| 409 | |
| 410 void LoadICNexus::ConfigureMonomorphic(Handle<Map> receiver_map, | 441 void LoadICNexus::ConfigureMonomorphic(Handle<Map> receiver_map, |
| 411 Handle<Code> handler) { | 442 Handle<Code> handler) { |
| 412 Handle<WeakCell> cell = Map::WeakCellForMap(receiver_map); | 443 Handle<WeakCell> cell = Map::WeakCellForMap(receiver_map); |
| 413 SetFeedback(*cell); | 444 SetFeedback(*cell); |
| 414 SetFeedbackExtra(*handler); | 445 SetFeedbackExtra(*handler); |
| 415 } | 446 } |
| 416 | 447 |
| 417 | 448 |
| 418 void KeyedLoadICNexus::ConfigureMonomorphic(Handle<Name> name, | 449 void KeyedLoadICNexus::ConfigureMonomorphic(Handle<Name> name, |
| 419 Handle<Map> receiver_map, | 450 Handle<Map> receiver_map, |
| 420 Handle<Code> handler) { | 451 Handle<Code> handler) { |
| 421 Handle<WeakCell> cell = Map::WeakCellForMap(receiver_map); | 452 Handle<WeakCell> cell = Map::WeakCellForMap(receiver_map); |
| 422 if (name.is_null()) { | 453 if (name.is_null()) { |
| 423 SetFeedback(*cell); | 454 SetFeedback(*cell); |
| 455 SetFeedbackExtra(*handler); |
| 456 } else { |
| 457 SetFeedback(*name); |
| 458 Handle<FixedArray> array = EnsureExtraArrayOfSize(2); |
| 459 array->set(0, *cell); |
| 460 array->set(1, *handler); |
| 461 } |
| 462 } |
| 463 |
| 464 |
| 465 void StoreICNexus::ConfigureMonomorphic(Handle<Map> receiver_map, |
| 466 Handle<Code> handler) { |
| 467 Handle<WeakCell> cell = Map::WeakCellForMap(receiver_map); |
| 468 SetFeedback(*cell); |
| 469 SetFeedbackExtra(*handler); |
| 470 } |
| 471 |
| 472 |
| 473 void KeyedStoreICNexus::ConfigureMonomorphic(Handle<Name> name, |
| 474 Handle<Map> receiver_map, |
| 475 Handle<Code> handler) { |
| 476 Handle<WeakCell> cell = Map::WeakCellForMap(receiver_map); |
| 477 if (name.is_null()) { |
| 478 SetFeedback(*cell); |
| 424 SetFeedbackExtra(*handler); | 479 SetFeedbackExtra(*handler); |
| 425 } else { | 480 } else { |
| 426 SetFeedback(*name); | 481 SetFeedback(*name); |
| 427 Handle<FixedArray> array = EnsureExtraArrayOfSize(2); | 482 Handle<FixedArray> array = EnsureExtraArrayOfSize(2); |
| 428 array->set(0, *cell); | 483 array->set(0, *cell); |
| 429 array->set(1, *handler); | 484 array->set(1, *handler); |
| 430 } | 485 } |
| 431 } | 486 } |
| 432 | 487 |
| 433 | 488 |
| (...skipping 20 matching lines...) Expand all Loading... |
| 454 SKIP_WRITE_BARRIER); | 509 SKIP_WRITE_BARRIER); |
| 455 } else { | 510 } else { |
| 456 SetFeedback(*name); | 511 SetFeedback(*name); |
| 457 array = EnsureExtraArrayOfSize(receiver_count * 2); | 512 array = EnsureExtraArrayOfSize(receiver_count * 2); |
| 458 } | 513 } |
| 459 | 514 |
| 460 InstallHandlers(array, maps, handlers); | 515 InstallHandlers(array, maps, handlers); |
| 461 } | 516 } |
| 462 | 517 |
| 463 | 518 |
| 519 void StoreICNexus::ConfigurePolymorphic(MapHandleList* maps, |
| 520 CodeHandleList* handlers) { |
| 521 Isolate* isolate = GetIsolate(); |
| 522 int receiver_count = maps->length(); |
| 523 Handle<FixedArray> array = EnsureArrayOfSize(receiver_count * 2); |
| 524 InstallHandlers(array, maps, handlers); |
| 525 SetFeedbackExtra(*TypeFeedbackVector::UninitializedSentinel(isolate), |
| 526 SKIP_WRITE_BARRIER); |
| 527 } |
| 528 |
| 529 |
| 530 void KeyedStoreICNexus::ConfigurePolymorphic(Handle<Name> name, |
| 531 MapHandleList* maps, |
| 532 CodeHandleList* handlers) { |
| 533 int receiver_count = maps->length(); |
| 534 DCHECK(receiver_count > 1); |
| 535 Handle<FixedArray> array; |
| 536 if (name.is_null()) { |
| 537 array = EnsureArrayOfSize(receiver_count * 2); |
| 538 SetFeedbackExtra(*TypeFeedbackVector::UninitializedSentinel(GetIsolate()), |
| 539 SKIP_WRITE_BARRIER); |
| 540 } else { |
| 541 SetFeedback(*name); |
| 542 array = EnsureExtraArrayOfSize(receiver_count * 2); |
| 543 } |
| 544 |
| 545 InstallHandlers(array, maps, handlers); |
| 546 } |
| 547 |
| 548 |
| 464 int FeedbackNexus::ExtractMaps(MapHandleList* maps) const { | 549 int FeedbackNexus::ExtractMaps(MapHandleList* maps) const { |
| 465 Isolate* isolate = GetIsolate(); | 550 Isolate* isolate = GetIsolate(); |
| 466 Object* feedback = GetFeedback(); | 551 Object* feedback = GetFeedback(); |
| 467 if (feedback->IsFixedArray() || feedback->IsString()) { | 552 if (feedback->IsFixedArray() || feedback->IsString()) { |
| 468 int found = 0; | 553 int found = 0; |
| 469 if (feedback->IsString()) { | 554 if (feedback->IsString()) { |
| 470 feedback = GetFeedbackExtra(); | 555 feedback = GetFeedbackExtra(); |
| 471 } | 556 } |
| 472 FixedArray* array = FixedArray::cast(feedback); | 557 FixedArray* array = FixedArray::cast(feedback); |
| 473 // The array should be of the form [<optional name>], then | 558 // The array should be of the form [<optional name>], then |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 573 } | 658 } |
| 574 | 659 |
| 575 | 660 |
| 576 Name* KeyedLoadICNexus::FindFirstName() const { | 661 Name* KeyedLoadICNexus::FindFirstName() const { |
| 577 Object* feedback = GetFeedback(); | 662 Object* feedback = GetFeedback(); |
| 578 if (feedback->IsString()) { | 663 if (feedback->IsString()) { |
| 579 return Name::cast(feedback); | 664 return Name::cast(feedback); |
| 580 } | 665 } |
| 581 return NULL; | 666 return NULL; |
| 582 } | 667 } |
| 668 |
| 669 |
| 670 Name* KeyedStoreICNexus::FindFirstName() const { |
| 671 Object* feedback = GetFeedback(); |
| 672 if (feedback->IsString()) { |
| 673 return Name::cast(feedback); |
| 674 } |
| 675 return NULL; |
| 676 } |
| 677 |
| 678 |
| 679 void StoreICNexus::Clear(Code* host) { |
| 680 StoreIC::Clear(GetIsolate(), host, this); |
| 681 } |
| 682 |
| 683 |
| 684 void KeyedStoreICNexus::Clear(Code* host) { |
| 685 KeyedStoreIC::Clear(GetIsolate(), host, this); |
| 686 } |
| 583 } // namespace internal | 687 } // namespace internal |
| 584 } // namespace v8 | 688 } // namespace v8 |
| OLD | NEW |