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 #include "test/cctest/cctest.h" | 6 #include "test/cctest/cctest.h" |
7 | 7 |
8 #include "src/api.h" | 8 #include "src/api.h" |
9 #include "src/debug/debug.h" | 9 #include "src/debug/debug.h" |
10 #include "src/execution.h" | 10 #include "src/execution.h" |
(...skipping 356 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
367 // Finally driven megamorphic. | 367 // Finally driven megamorphic. |
368 CompileRun("f({ blarg: 3, gran: 3, torino: 10, foo: 2 })"); | 368 CompileRun("f({ blarg: 3, gran: 3, torino: 10, foo: 2 })"); |
369 CHECK_EQ(MEGAMORPHIC, nexus.StateFromFeedback()); | 369 CHECK_EQ(MEGAMORPHIC, nexus.StateFromFeedback()); |
370 CHECK(!nexus.FindFirstMap()); | 370 CHECK(!nexus.FindFirstMap()); |
371 | 371 |
372 // After a collection, state should not be reset to PREMONOMORPHIC. | 372 // After a collection, state should not be reset to PREMONOMORPHIC. |
373 CcTest::CollectAllGarbage(i::Heap::kFinalizeIncrementalMarkingMask); | 373 CcTest::CollectAllGarbage(i::Heap::kFinalizeIncrementalMarkingMask); |
374 CHECK_EQ(MEGAMORPHIC, nexus.StateFromFeedback()); | 374 CHECK_EQ(MEGAMORPHIC, nexus.StateFromFeedback()); |
375 } | 375 } |
376 | 376 |
377 | 377 TEST(VectorLoadGlobalICSlotSharing) { |
378 TEST(VectorLoadICSlotSharing) { | |
379 if (i::FLAG_always_opt) return; | 378 if (i::FLAG_always_opt) return; |
380 CcTest::InitializeVM(); | 379 CcTest::InitializeVM(); |
381 LocalContext context; | 380 LocalContext context; |
382 v8::HandleScope scope(context->GetIsolate()); | 381 v8::HandleScope scope(context->GetIsolate()); |
383 Isolate* isolate = CcTest::i_isolate(); | 382 Isolate* isolate = CcTest::i_isolate(); |
384 | 383 |
385 // Function f has 3 LoadICs, one for each o, but the ICs share the same | 384 // Function f has 5 LoadGlobalICs: 3 for {o} references outside of "typeof" |
386 // feedback vector IC slot. | 385 // operator and 2 for {o} references inside "typeof" operator. |
387 CompileRun( | 386 CompileRun( |
388 "o = 10;" | 387 "o = 10;" |
389 "function f() {" | 388 "function f() {" |
390 " var x = o || 10;" | 389 " var x = o || 10;" |
391 " return o , x , o;" | 390 " var y = typeof o;" |
| 391 " return o , typeof o, x , y, o;" |
392 "}" | 392 "}" |
393 "f();"); | 393 "f();"); |
394 Handle<JSFunction> f = GetFunction("f"); | 394 Handle<JSFunction> f = GetFunction("f"); |
395 // There should be one IC slot. | 395 // There should be two IC slots for {o} references outside and inside |
| 396 // typeof operator respectively. |
396 Handle<TypeFeedbackVector> feedback_vector = | 397 Handle<TypeFeedbackVector> feedback_vector = |
397 Handle<TypeFeedbackVector>(f->feedback_vector(), isolate); | 398 Handle<TypeFeedbackVector>(f->feedback_vector(), isolate); |
398 FeedbackVectorHelper helper(feedback_vector); | 399 FeedbackVectorHelper helper(feedback_vector); |
399 CHECK_EQ(1, helper.slot_count()); | 400 CHECK_EQ(2, helper.slot_count()); |
400 FeedbackVectorSlot slot(0); | 401 CHECK_SLOT_KIND(helper, 0, |
401 LoadGlobalICNexus nexus(feedback_vector, slot); | 402 FeedbackVectorSlotKind::LOAD_GLOBAL_NOT_INSIDE_TYPEOF_IC); |
402 CHECK_EQ(MONOMORPHIC, nexus.StateFromFeedback()); | 403 CHECK_SLOT_KIND(helper, 1, |
| 404 FeedbackVectorSlotKind::LOAD_GLOBAL_INSIDE_TYPEOF_IC); |
| 405 FeedbackVectorSlot slot1 = helper.slot(0); |
| 406 FeedbackVectorSlot slot2 = helper.slot(1); |
| 407 CHECK_EQ(MONOMORPHIC, |
| 408 LoadGlobalICNexus(feedback_vector, slot1).StateFromFeedback()); |
| 409 CHECK_EQ(MONOMORPHIC, |
| 410 LoadGlobalICNexus(feedback_vector, slot2).StateFromFeedback()); |
403 } | 411 } |
404 | 412 |
405 | 413 |
406 TEST(VectorLoadICOnSmi) { | 414 TEST(VectorLoadICOnSmi) { |
407 if (i::FLAG_always_opt) return; | 415 if (i::FLAG_always_opt) return; |
408 CcTest::InitializeVM(); | 416 CcTest::InitializeVM(); |
409 LocalContext context; | 417 LocalContext context; |
410 v8::HandleScope scope(context->GetIsolate()); | 418 v8::HandleScope scope(context->GetIsolate()); |
411 Isolate* isolate = CcTest::i_isolate(); | 419 Isolate* isolate = CcTest::i_isolate(); |
412 Heap* heap = isolate->heap(); | 420 Heap* heap = isolate->heap(); |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
480 "testvar({});"); | 488 "testvar({});"); |
481 | 489 |
482 Handle<JSFunction> f = GetFunction("testvar"); | 490 Handle<JSFunction> f = GetFunction("testvar"); |
483 | 491 |
484 // There should be two LOAD_ICs, one for a and one for y at the end. | 492 // There should be two LOAD_ICs, one for a and one for y at the end. |
485 Handle<TypeFeedbackVector> feedback_vector = | 493 Handle<TypeFeedbackVector> feedback_vector = |
486 handle(f->feedback_vector(), isolate); | 494 handle(f->feedback_vector(), isolate); |
487 FeedbackVectorHelper helper(feedback_vector); | 495 FeedbackVectorHelper helper(feedback_vector); |
488 CHECK_EQ(4, helper.slot_count()); | 496 CHECK_EQ(4, helper.slot_count()); |
489 CHECK_SLOT_KIND(helper, 0, FeedbackVectorSlotKind::STORE_SLOPPY_IC); | 497 CHECK_SLOT_KIND(helper, 0, FeedbackVectorSlotKind::STORE_SLOPPY_IC); |
490 CHECK_SLOT_KIND(helper, 1, FeedbackVectorSlotKind::LOAD_GLOBAL_IC); | 498 CHECK_SLOT_KIND(helper, 1, |
| 499 FeedbackVectorSlotKind::LOAD_GLOBAL_NOT_INSIDE_TYPEOF_IC); |
491 CHECK_SLOT_KIND(helper, 2, FeedbackVectorSlotKind::STORE_SLOPPY_IC); | 500 CHECK_SLOT_KIND(helper, 2, FeedbackVectorSlotKind::STORE_SLOPPY_IC); |
492 CHECK_SLOT_KIND(helper, 3, FeedbackVectorSlotKind::LOAD_GLOBAL_IC); | 501 CHECK_SLOT_KIND(helper, 3, |
| 502 FeedbackVectorSlotKind::LOAD_GLOBAL_NOT_INSIDE_TYPEOF_IC); |
493 } | 503 } |
494 | 504 |
495 { | 505 { |
496 CompileRun( | 506 CompileRun( |
497 "function testprop(x) {" | 507 "function testprop(x) {" |
498 " 'use strict';" | 508 " 'use strict';" |
499 " x.blue = a;" | 509 " x.blue = a;" |
500 "}" | 510 "}" |
501 "testprop({ blue: 3 });"); | 511 "testprop({ blue: 3 });"); |
502 | 512 |
503 Handle<JSFunction> f = GetFunction("testprop"); | 513 Handle<JSFunction> f = GetFunction("testprop"); |
504 | 514 |
505 // There should be one LOAD_IC, for the load of a. | 515 // There should be one LOAD_IC, for the load of a. |
506 Handle<TypeFeedbackVector> feedback_vector(f->feedback_vector()); | 516 Handle<TypeFeedbackVector> feedback_vector(f->feedback_vector()); |
507 FeedbackVectorHelper helper(feedback_vector); | 517 FeedbackVectorHelper helper(feedback_vector); |
508 CHECK_EQ(2, helper.slot_count()); | 518 CHECK_EQ(2, helper.slot_count()); |
509 CHECK_SLOT_KIND(helper, 0, FeedbackVectorSlotKind::LOAD_GLOBAL_IC); | 519 CHECK_SLOT_KIND(helper, 0, |
| 520 FeedbackVectorSlotKind::LOAD_GLOBAL_NOT_INSIDE_TYPEOF_IC); |
510 CHECK_SLOT_KIND(helper, 1, FeedbackVectorSlotKind::STORE_STRICT_IC); | 521 CHECK_SLOT_KIND(helper, 1, FeedbackVectorSlotKind::STORE_STRICT_IC); |
511 } | 522 } |
512 | 523 |
513 { | 524 { |
514 CompileRun( | 525 CompileRun( |
515 "function testpropfunc(x) {" | 526 "function testpropfunc(x) {" |
516 " x().blue = a;" | 527 " x().blue = a;" |
517 " return x().blue;" | 528 " return x().blue;" |
518 "}" | 529 "}" |
519 "function makeresult() { return { blue: 3 }; }" | 530 "function makeresult() { return { blue: 3 }; }" |
520 "testpropfunc(makeresult);"); | 531 "testpropfunc(makeresult);"); |
521 | 532 |
522 Handle<JSFunction> f = GetFunction("testpropfunc"); | 533 Handle<JSFunction> f = GetFunction("testpropfunc"); |
523 | 534 |
524 // There should be 1 LOAD_GLOBAL_IC to load x (in both cases), 2 CALL_ICs | 535 // There should be 1 LOAD_GLOBAL_IC to load x (in both cases), 2 CALL_ICs |
525 // to call x and a LOAD_IC to load blue. | 536 // to call x and a LOAD_IC to load blue. |
526 Handle<TypeFeedbackVector> feedback_vector(f->feedback_vector()); | 537 Handle<TypeFeedbackVector> feedback_vector(f->feedback_vector()); |
527 FeedbackVectorHelper helper(feedback_vector); | 538 FeedbackVectorHelper helper(feedback_vector); |
528 CHECK_EQ(5, helper.slot_count()); | 539 CHECK_EQ(5, helper.slot_count()); |
529 CHECK_SLOT_KIND(helper, 0, FeedbackVectorSlotKind::CALL_IC); | 540 CHECK_SLOT_KIND(helper, 0, FeedbackVectorSlotKind::CALL_IC); |
530 CHECK_SLOT_KIND(helper, 1, FeedbackVectorSlotKind::LOAD_GLOBAL_IC); | 541 CHECK_SLOT_KIND(helper, 1, |
| 542 FeedbackVectorSlotKind::LOAD_GLOBAL_NOT_INSIDE_TYPEOF_IC); |
531 CHECK_SLOT_KIND(helper, 2, FeedbackVectorSlotKind::STORE_SLOPPY_IC); | 543 CHECK_SLOT_KIND(helper, 2, FeedbackVectorSlotKind::STORE_SLOPPY_IC); |
532 CHECK_SLOT_KIND(helper, 3, FeedbackVectorSlotKind::CALL_IC); | 544 CHECK_SLOT_KIND(helper, 3, FeedbackVectorSlotKind::CALL_IC); |
533 CHECK_SLOT_KIND(helper, 4, FeedbackVectorSlotKind::LOAD_IC); | 545 CHECK_SLOT_KIND(helper, 4, FeedbackVectorSlotKind::LOAD_IC); |
534 } | 546 } |
535 | 547 |
536 { | 548 { |
537 CompileRun( | 549 CompileRun( |
538 "function testkeyedprop(x) {" | 550 "function testkeyedprop(x) {" |
539 " x[0] = a;" | 551 " x[0] = a;" |
540 " return x[0];" | 552 " return x[0];" |
541 "}" | 553 "}" |
542 "testkeyedprop([0, 1, 2]);"); | 554 "testkeyedprop([0, 1, 2]);"); |
543 | 555 |
544 Handle<JSFunction> f = GetFunction("testkeyedprop"); | 556 Handle<JSFunction> f = GetFunction("testkeyedprop"); |
545 | 557 |
546 // There should be 1 LOAD_GLOBAL_ICs for the load of a, and one | 558 // There should be 1 LOAD_GLOBAL_ICs for the load of a, and one |
547 // KEYED_LOAD_IC for the load of x[0] in the return statement. | 559 // KEYED_LOAD_IC for the load of x[0] in the return statement. |
548 Handle<TypeFeedbackVector> feedback_vector(f->feedback_vector()); | 560 Handle<TypeFeedbackVector> feedback_vector(f->feedback_vector()); |
549 FeedbackVectorHelper helper(feedback_vector); | 561 FeedbackVectorHelper helper(feedback_vector); |
550 CHECK_EQ(3, helper.slot_count()); | 562 CHECK_EQ(3, helper.slot_count()); |
551 CHECK_SLOT_KIND(helper, 0, FeedbackVectorSlotKind::LOAD_GLOBAL_IC); | 563 CHECK_SLOT_KIND(helper, 0, |
| 564 FeedbackVectorSlotKind::LOAD_GLOBAL_NOT_INSIDE_TYPEOF_IC); |
552 CHECK_SLOT_KIND(helper, 1, FeedbackVectorSlotKind::KEYED_STORE_SLOPPY_IC); | 565 CHECK_SLOT_KIND(helper, 1, FeedbackVectorSlotKind::KEYED_STORE_SLOPPY_IC); |
553 CHECK_SLOT_KIND(helper, 2, FeedbackVectorSlotKind::KEYED_LOAD_IC); | 566 CHECK_SLOT_KIND(helper, 2, FeedbackVectorSlotKind::KEYED_LOAD_IC); |
554 } | 567 } |
555 | 568 |
556 { | 569 { |
557 CompileRun( | 570 CompileRun( |
558 "function testkeyedprop(x) {" | 571 "function testkeyedprop(x) {" |
559 " 'use strict';" | 572 " 'use strict';" |
560 " x[0] = a;" | 573 " x[0] = a;" |
561 " return x[0];" | 574 " return x[0];" |
562 "}" | 575 "}" |
563 "testkeyedprop([0, 1, 2]);"); | 576 "testkeyedprop([0, 1, 2]);"); |
564 | 577 |
565 Handle<JSFunction> f = GetFunction("testkeyedprop"); | 578 Handle<JSFunction> f = GetFunction("testkeyedprop"); |
566 | 579 |
567 // There should be 1 LOAD_GLOBAL_ICs for the load of a, and one | 580 // There should be 1 LOAD_GLOBAL_ICs for the load of a, and one |
568 // KEYED_LOAD_IC for the load of x[0] in the return statement. | 581 // KEYED_LOAD_IC for the load of x[0] in the return statement. |
569 Handle<TypeFeedbackVector> feedback_vector(f->feedback_vector()); | 582 Handle<TypeFeedbackVector> feedback_vector(f->feedback_vector()); |
570 FeedbackVectorHelper helper(feedback_vector); | 583 FeedbackVectorHelper helper(feedback_vector); |
571 CHECK_EQ(3, helper.slot_count()); | 584 CHECK_EQ(3, helper.slot_count()); |
572 CHECK_SLOT_KIND(helper, 0, FeedbackVectorSlotKind::LOAD_GLOBAL_IC); | 585 CHECK_SLOT_KIND(helper, 0, |
| 586 FeedbackVectorSlotKind::LOAD_GLOBAL_NOT_INSIDE_TYPEOF_IC); |
573 CHECK_SLOT_KIND(helper, 1, FeedbackVectorSlotKind::KEYED_STORE_STRICT_IC); | 587 CHECK_SLOT_KIND(helper, 1, FeedbackVectorSlotKind::KEYED_STORE_STRICT_IC); |
574 CHECK_SLOT_KIND(helper, 2, FeedbackVectorSlotKind::KEYED_LOAD_IC); | 588 CHECK_SLOT_KIND(helper, 2, FeedbackVectorSlotKind::KEYED_LOAD_IC); |
575 } | 589 } |
576 | 590 |
577 { | 591 { |
578 CompileRun( | 592 CompileRun( |
579 "function testcompound(x) {" | 593 "function testcompound(x) {" |
580 " 'use strict';" | 594 " 'use strict';" |
581 " x.old = x.young = x.in_between = a;" | 595 " x.old = x.young = x.in_between = a;" |
582 " return x.old + x.young;" | 596 " return x.old + x.young;" |
583 "}" | 597 "}" |
584 "testcompound({ old: 3, young: 3, in_between: 3 });"); | 598 "testcompound({ old: 3, young: 3, in_between: 3 });"); |
585 | 599 |
586 Handle<JSFunction> f = GetFunction("testcompound"); | 600 Handle<JSFunction> f = GetFunction("testcompound"); |
587 | 601 |
588 // There should be 1 LOAD_GLOBAL_IC for load of a and 2 LOAD_ICs, for load | 602 // There should be 1 LOAD_GLOBAL_IC for load of a and 2 LOAD_ICs, for load |
589 // of x.old and x.young. | 603 // of x.old and x.young. |
590 Handle<TypeFeedbackVector> feedback_vector(f->feedback_vector()); | 604 Handle<TypeFeedbackVector> feedback_vector(f->feedback_vector()); |
591 FeedbackVectorHelper helper(feedback_vector); | 605 FeedbackVectorHelper helper(feedback_vector); |
592 CHECK_EQ(7, helper.slot_count()); | 606 CHECK_EQ(7, helper.slot_count()); |
593 CHECK_SLOT_KIND(helper, 0, FeedbackVectorSlotKind::LOAD_GLOBAL_IC); | 607 CHECK_SLOT_KIND(helper, 0, |
| 608 FeedbackVectorSlotKind::LOAD_GLOBAL_NOT_INSIDE_TYPEOF_IC); |
594 CHECK_SLOT_KIND(helper, 1, FeedbackVectorSlotKind::STORE_STRICT_IC); | 609 CHECK_SLOT_KIND(helper, 1, FeedbackVectorSlotKind::STORE_STRICT_IC); |
595 CHECK_SLOT_KIND(helper, 2, FeedbackVectorSlotKind::STORE_STRICT_IC); | 610 CHECK_SLOT_KIND(helper, 2, FeedbackVectorSlotKind::STORE_STRICT_IC); |
596 CHECK_SLOT_KIND(helper, 3, FeedbackVectorSlotKind::STORE_STRICT_IC); | 611 CHECK_SLOT_KIND(helper, 3, FeedbackVectorSlotKind::STORE_STRICT_IC); |
597 CHECK_SLOT_KIND(helper, 4, FeedbackVectorSlotKind::LOAD_IC); | 612 CHECK_SLOT_KIND(helper, 4, FeedbackVectorSlotKind::LOAD_IC); |
598 CHECK_SLOT_KIND(helper, 5, FeedbackVectorSlotKind::LOAD_IC); | 613 CHECK_SLOT_KIND(helper, 5, FeedbackVectorSlotKind::LOAD_IC); |
599 CHECK_SLOT_KIND(helper, 6, FeedbackVectorSlotKind::INTERPRETER_BINARYOP_IC); | 614 CHECK_SLOT_KIND(helper, 6, FeedbackVectorSlotKind::INTERPRETER_BINARYOP_IC); |
600 } | 615 } |
601 } | 616 } |
602 | 617 |
603 | 618 |
(...skipping 16 matching lines...) Expand all Loading... |
620 // There should be one IC slot. | 635 // There should be one IC slot. |
621 Handle<TypeFeedbackVector> feedback_vector(f->feedback_vector()); | 636 Handle<TypeFeedbackVector> feedback_vector(f->feedback_vector()); |
622 FeedbackVectorHelper helper(feedback_vector); | 637 FeedbackVectorHelper helper(feedback_vector); |
623 CHECK_EQ(1, helper.slot_count()); | 638 CHECK_EQ(1, helper.slot_count()); |
624 FeedbackVectorSlot slot(0); | 639 FeedbackVectorSlot slot(0); |
625 StoreICNexus nexus(feedback_vector, slot); | 640 StoreICNexus nexus(feedback_vector, slot); |
626 CHECK_EQ(MONOMORPHIC, nexus.StateFromFeedback()); | 641 CHECK_EQ(MONOMORPHIC, nexus.StateFromFeedback()); |
627 } | 642 } |
628 | 643 |
629 } // namespace | 644 } // namespace |
OLD | NEW |