| 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 368 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 379 " var y = typeof o;" | 379 " var y = typeof o;" |
| 380 " return o , typeof o, x , y, o;" | 380 " return o , typeof o, x , y, o;" |
| 381 "}" | 381 "}" |
| 382 "f();"); | 382 "f();"); |
| 383 Handle<JSFunction> f = GetFunction("f"); | 383 Handle<JSFunction> f = GetFunction("f"); |
| 384 // There should be two IC slots for {o} references outside and inside | 384 // There should be two IC slots for {o} references outside and inside |
| 385 // typeof operator respectively. | 385 // typeof operator respectively. |
| 386 Handle<FeedbackVector> feedback_vector = | 386 Handle<FeedbackVector> feedback_vector = |
| 387 Handle<FeedbackVector>(f->feedback_vector(), isolate); | 387 Handle<FeedbackVector>(f->feedback_vector(), isolate); |
| 388 FeedbackVectorHelper helper(feedback_vector); | 388 FeedbackVectorHelper helper(feedback_vector); |
| 389 CHECK_EQ(2, helper.slot_count()); | 389 CHECK_EQ(4, helper.slot_count()); |
| 390 CHECK_SLOT_KIND(helper, 0, FeedbackSlotKind::kLoadGlobalNotInsideTypeof); | 390 CHECK_SLOT_KIND(helper, 0, FeedbackSlotKind::kLoadGlobalNotInsideTypeof); |
| 391 CHECK_SLOT_KIND(helper, 1, FeedbackSlotKind::kLoadGlobalInsideTypeof); | 391 CHECK_SLOT_KIND(helper, 1, FeedbackSlotKind::kTypeProfile); |
| 392 CHECK_SLOT_KIND(helper, 2, FeedbackSlotKind::kLoadGlobalInsideTypeof); |
| 392 FeedbackSlot slot1 = helper.slot(0); | 393 FeedbackSlot slot1 = helper.slot(0); |
| 393 FeedbackSlot slot2 = helper.slot(1); | 394 FeedbackSlot slot2 = helper.slot(2); |
| 394 CHECK_EQ(MONOMORPHIC, | 395 CHECK_EQ(MONOMORPHIC, |
| 395 LoadGlobalICNexus(feedback_vector, slot1).StateFromFeedback()); | 396 LoadGlobalICNexus(feedback_vector, slot1).StateFromFeedback()); |
| 396 CHECK_EQ(MONOMORPHIC, | 397 CHECK_EQ(MONOMORPHIC, |
| 397 LoadGlobalICNexus(feedback_vector, slot2).StateFromFeedback()); | 398 LoadGlobalICNexus(feedback_vector, slot2).StateFromFeedback()); |
| 398 } | 399 } |
| 399 | 400 |
| 400 | 401 |
| 401 TEST(VectorLoadICOnSmi) { | 402 TEST(VectorLoadICOnSmi) { |
| 402 if (i::FLAG_always_opt) return; | 403 if (i::FLAG_always_opt) return; |
| 403 CcTest::InitializeVM(); | 404 CcTest::InitializeVM(); |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 473 "}" | 474 "}" |
| 474 "a = 3;" | 475 "a = 3;" |
| 475 "testvar({});"); | 476 "testvar({});"); |
| 476 | 477 |
| 477 Handle<JSFunction> f = GetFunction("testvar"); | 478 Handle<JSFunction> f = GetFunction("testvar"); |
| 478 | 479 |
| 479 // There should be two LOAD_ICs, one for a and one for y at the end. | 480 // There should be two LOAD_ICs, one for a and one for y at the end. |
| 480 Handle<FeedbackVector> feedback_vector = | 481 Handle<FeedbackVector> feedback_vector = |
| 481 handle(f->feedback_vector(), isolate); | 482 handle(f->feedback_vector(), isolate); |
| 482 FeedbackVectorHelper helper(feedback_vector); | 483 FeedbackVectorHelper helper(feedback_vector); |
| 483 CHECK_EQ(4, helper.slot_count()); | 484 CHECK_EQ(6, helper.slot_count()); |
| 484 CHECK_SLOT_KIND(helper, 0, FeedbackSlotKind::kStoreNamedSloppy); | 485 CHECK_SLOT_KIND(helper, 0, FeedbackSlotKind::kStoreNamedSloppy); |
| 485 CHECK_SLOT_KIND(helper, 1, FeedbackSlotKind::kLoadGlobalNotInsideTypeof); | 486 CHECK_SLOT_KIND(helper, 1, FeedbackSlotKind::kTypeProfile); |
| 486 CHECK_SLOT_KIND(helper, 2, FeedbackSlotKind::kStoreNamedSloppy); | 487 CHECK_SLOT_KIND(helper, 2, FeedbackSlotKind::kLoadGlobalNotInsideTypeof); |
| 487 CHECK_SLOT_KIND(helper, 3, FeedbackSlotKind::kLoadGlobalNotInsideTypeof); | 488 CHECK_SLOT_KIND(helper, 3, FeedbackSlotKind::kStoreNamedSloppy); |
| 489 CHECK_SLOT_KIND(helper, 4, FeedbackSlotKind::kTypeProfile); |
| 490 CHECK_SLOT_KIND(helper, 5, FeedbackSlotKind::kLoadGlobalNotInsideTypeof); |
| 488 } | 491 } |
| 489 | 492 |
| 490 { | 493 { |
| 491 CompileRun( | 494 CompileRun( |
| 492 "function testprop(x) {" | 495 "function testprop(x) {" |
| 493 " 'use strict';" | 496 " 'use strict';" |
| 494 " x.blue = a;" | 497 " x.blue = a;" |
| 495 "}" | 498 "}" |
| 496 "testprop({ blue: 3 });"); | 499 "testprop({ blue: 3 });"); |
| 497 | 500 |
| 498 Handle<JSFunction> f = GetFunction("testprop"); | 501 Handle<JSFunction> f = GetFunction("testprop"); |
| 499 | 502 |
| 500 // There should be one LOAD_IC, for the load of a. | 503 // There should be one LOAD_IC, for the load of a. |
| 501 Handle<FeedbackVector> feedback_vector(f->feedback_vector()); | 504 Handle<FeedbackVector> feedback_vector(f->feedback_vector()); |
| 502 FeedbackVectorHelper helper(feedback_vector); | 505 FeedbackVectorHelper helper(feedback_vector); |
| 503 CHECK_EQ(2, helper.slot_count()); | 506 CHECK_EQ(3, helper.slot_count()); |
| 504 CHECK_SLOT_KIND(helper, 0, FeedbackSlotKind::kLoadGlobalNotInsideTypeof); | 507 CHECK_SLOT_KIND(helper, 0, FeedbackSlotKind::kLoadGlobalNotInsideTypeof); |
| 505 CHECK_SLOT_KIND(helper, 1, FeedbackSlotKind::kStoreNamedStrict); | 508 CHECK_SLOT_KIND(helper, 1, FeedbackSlotKind::kStoreNamedStrict); |
| 506 } | 509 } |
| 507 | 510 |
| 508 { | 511 { |
| 509 CompileRun( | 512 CompileRun( |
| 510 "function testpropfunc(x) {" | 513 "function testpropfunc(x) {" |
| 511 " x().blue = a;" | 514 " x().blue = a;" |
| 512 " return x().blue;" | 515 " return x().blue;" |
| 513 "}" | 516 "}" |
| 514 "function makeresult() { return { blue: 3 }; }" | 517 "function makeresult() { return { blue: 3 }; }" |
| 515 "testpropfunc(makeresult);"); | 518 "testpropfunc(makeresult);"); |
| 516 | 519 |
| 517 Handle<JSFunction> f = GetFunction("testpropfunc"); | 520 Handle<JSFunction> f = GetFunction("testpropfunc"); |
| 518 | 521 |
| 519 // There should be 1 LOAD_GLOBAL_IC to load x (in both cases), 2 CALL_ICs | 522 // There should be 1 LOAD_GLOBAL_IC to load x (in both cases), 2 CALL_ICs |
| 520 // to call x and a LOAD_IC to load blue. | 523 // to call x and a LOAD_IC to load blue. |
| 521 Handle<FeedbackVector> feedback_vector(f->feedback_vector()); | 524 Handle<FeedbackVector> feedback_vector(f->feedback_vector()); |
| 522 FeedbackVectorHelper helper(feedback_vector); | 525 FeedbackVectorHelper helper(feedback_vector); |
| 523 CHECK_EQ(5, helper.slot_count()); | 526 CHECK_EQ(6, helper.slot_count()); |
| 524 CHECK_SLOT_KIND(helper, 0, FeedbackSlotKind::kCall); | 527 CHECK_SLOT_KIND(helper, 0, FeedbackSlotKind::kCall); |
| 525 CHECK_SLOT_KIND(helper, 1, FeedbackSlotKind::kLoadGlobalNotInsideTypeof); | 528 CHECK_SLOT_KIND(helper, 1, FeedbackSlotKind::kLoadGlobalNotInsideTypeof); |
| 526 CHECK_SLOT_KIND(helper, 2, FeedbackSlotKind::kStoreNamedSloppy); | 529 CHECK_SLOT_KIND(helper, 2, FeedbackSlotKind::kStoreNamedSloppy); |
| 527 CHECK_SLOT_KIND(helper, 3, FeedbackSlotKind::kCall); | 530 CHECK_SLOT_KIND(helper, 3, FeedbackSlotKind::kTypeProfile); |
| 528 CHECK_SLOT_KIND(helper, 4, FeedbackSlotKind::kLoadProperty); | 531 CHECK_SLOT_KIND(helper, 4, FeedbackSlotKind::kCall); |
| 532 CHECK_SLOT_KIND(helper, 5, FeedbackSlotKind::kLoadProperty); |
| 529 } | 533 } |
| 530 | 534 |
| 531 { | 535 { |
| 532 CompileRun( | 536 CompileRun( |
| 533 "function testkeyedprop(x) {" | 537 "function testkeyedprop(x) {" |
| 534 " x[0] = a;" | 538 " x[0] = a;" |
| 535 " return x[0];" | 539 " return x[0];" |
| 536 "}" | 540 "}" |
| 537 "testkeyedprop([0, 1, 2]);"); | 541 "testkeyedprop([0, 1, 2]);"); |
| 538 | 542 |
| 539 Handle<JSFunction> f = GetFunction("testkeyedprop"); | 543 Handle<JSFunction> f = GetFunction("testkeyedprop"); |
| 540 | 544 |
| 541 // There should be 1 LOAD_GLOBAL_ICs for the load of a, and one | 545 // There should be 1 LOAD_GLOBAL_ICs for the load of a, and one |
| 542 // KEYED_LOAD_IC for the load of x[0] in the return statement. | 546 // KEYED_LOAD_IC for the load of x[0] in the return statement. |
| 543 Handle<FeedbackVector> feedback_vector(f->feedback_vector()); | 547 Handle<FeedbackVector> feedback_vector(f->feedback_vector()); |
| 544 FeedbackVectorHelper helper(feedback_vector); | 548 FeedbackVectorHelper helper(feedback_vector); |
| 545 CHECK_EQ(3, helper.slot_count()); | 549 CHECK_EQ(4, helper.slot_count()); |
| 546 CHECK_SLOT_KIND(helper, 0, FeedbackSlotKind::kLoadGlobalNotInsideTypeof); | 550 CHECK_SLOT_KIND(helper, 0, FeedbackSlotKind::kLoadGlobalNotInsideTypeof); |
| 547 CHECK_SLOT_KIND(helper, 1, FeedbackSlotKind::kStoreKeyedSloppy); | 551 CHECK_SLOT_KIND(helper, 1, FeedbackSlotKind::kStoreKeyedSloppy); |
| 548 CHECK_SLOT_KIND(helper, 2, FeedbackSlotKind::kLoadKeyed); | 552 CHECK_SLOT_KIND(helper, 2, FeedbackSlotKind::kTypeProfile); |
| 553 CHECK_SLOT_KIND(helper, 3, FeedbackSlotKind::kLoadKeyed); |
| 549 } | 554 } |
| 550 | 555 |
| 551 { | 556 { |
| 552 CompileRun( | 557 CompileRun( |
| 553 "function testkeyedprop(x) {" | 558 "function testkeyedprop(x) {" |
| 554 " 'use strict';" | 559 " 'use strict';" |
| 555 " x[0] = a;" | 560 " x[0] = a;" |
| 556 " return x[0];" | 561 " return x[0];" |
| 557 "}" | 562 "}" |
| 558 "testkeyedprop([0, 1, 2]);"); | 563 "testkeyedprop([0, 1, 2]);"); |
| 559 | 564 |
| 560 Handle<JSFunction> f = GetFunction("testkeyedprop"); | 565 Handle<JSFunction> f = GetFunction("testkeyedprop"); |
| 561 | 566 |
| 562 // There should be 1 LOAD_GLOBAL_ICs for the load of a, and one | 567 // There should be 1 LOAD_GLOBAL_ICs for the load of a, and one |
| 563 // KEYED_LOAD_IC for the load of x[0] in the return statement. | 568 // KEYED_LOAD_IC for the load of x[0] in the return statement. |
| 564 Handle<FeedbackVector> feedback_vector(f->feedback_vector()); | 569 Handle<FeedbackVector> feedback_vector(f->feedback_vector()); |
| 565 FeedbackVectorHelper helper(feedback_vector); | 570 FeedbackVectorHelper helper(feedback_vector); |
| 566 CHECK_EQ(3, helper.slot_count()); | 571 CHECK_EQ(4, helper.slot_count()); |
| 567 CHECK_SLOT_KIND(helper, 0, FeedbackSlotKind::kLoadGlobalNotInsideTypeof); | 572 CHECK_SLOT_KIND(helper, 0, FeedbackSlotKind::kLoadGlobalNotInsideTypeof); |
| 568 CHECK_SLOT_KIND(helper, 1, FeedbackSlotKind::kStoreKeyedStrict); | 573 CHECK_SLOT_KIND(helper, 1, FeedbackSlotKind::kStoreKeyedStrict); |
| 569 CHECK_SLOT_KIND(helper, 2, FeedbackSlotKind::kLoadKeyed); | 574 CHECK_SLOT_KIND(helper, 2, FeedbackSlotKind::kTypeProfile); |
| 575 CHECK_SLOT_KIND(helper, 3, FeedbackSlotKind::kLoadKeyed); |
| 570 } | 576 } |
| 571 | 577 |
| 572 { | 578 { |
| 573 CompileRun( | 579 CompileRun( |
| 574 "function testcompound(x) {" | 580 "function testcompound(x) {" |
| 575 " 'use strict';" | 581 " 'use strict';" |
| 576 " x.old = x.young = x.in_between = a;" | 582 " x.old = x.young = x.in_between = a;" |
| 577 " return x.old + x.young;" | 583 " return x.old + x.young;" |
| 578 "}" | 584 "}" |
| 579 "testcompound({ old: 3, young: 3, in_between: 3 });"); | 585 "testcompound({ old: 3, young: 3, in_between: 3 });"); |
| 580 | 586 |
| 581 Handle<JSFunction> f = GetFunction("testcompound"); | 587 Handle<JSFunction> f = GetFunction("testcompound"); |
| 582 | 588 |
| 583 // There should be 1 LOAD_GLOBAL_IC for load of a and 2 LOAD_ICs, for load | 589 // There should be 1 LOAD_GLOBAL_IC for load of a and 2 LOAD_ICs, for load |
| 584 // of x.old and x.young. | 590 // of x.old and x.young. |
| 585 Handle<FeedbackVector> feedback_vector(f->feedback_vector()); | 591 Handle<FeedbackVector> feedback_vector(f->feedback_vector()); |
| 586 FeedbackVectorHelper helper(feedback_vector); | 592 FeedbackVectorHelper helper(feedback_vector); |
| 587 CHECK_EQ(7, helper.slot_count()); | 593 CHECK_EQ(10, helper.slot_count()); |
| 588 CHECK_SLOT_KIND(helper, 0, FeedbackSlotKind::kLoadGlobalNotInsideTypeof); | 594 CHECK_SLOT_KIND(helper, 0, FeedbackSlotKind::kLoadGlobalNotInsideTypeof); |
| 589 CHECK_SLOT_KIND(helper, 1, FeedbackSlotKind::kStoreNamedStrict); | 595 CHECK_SLOT_KIND(helper, 1, FeedbackSlotKind::kStoreNamedStrict); |
| 590 CHECK_SLOT_KIND(helper, 2, FeedbackSlotKind::kStoreNamedStrict); | 596 CHECK_SLOT_KIND(helper, 2, FeedbackSlotKind::kTypeProfile); |
| 591 CHECK_SLOT_KIND(helper, 3, FeedbackSlotKind::kStoreNamedStrict); | 597 CHECK_SLOT_KIND(helper, 3, FeedbackSlotKind::kStoreNamedStrict); |
| 592 CHECK_SLOT_KIND(helper, 4, FeedbackSlotKind::kLoadProperty); | 598 CHECK_SLOT_KIND(helper, 4, FeedbackSlotKind::kTypeProfile); |
| 593 CHECK_SLOT_KIND(helper, 5, FeedbackSlotKind::kLoadProperty); | 599 CHECK_SLOT_KIND(helper, 5, FeedbackSlotKind::kStoreNamedStrict); |
| 594 CHECK_SLOT_KIND(helper, 6, FeedbackSlotKind::kBinaryOp); | 600 CHECK_SLOT_KIND(helper, 6, FeedbackSlotKind::kTypeProfile); |
| 601 CHECK_SLOT_KIND(helper, 7, FeedbackSlotKind::kLoadProperty); |
| 602 CHECK_SLOT_KIND(helper, 8, FeedbackSlotKind::kLoadProperty); |
| 603 CHECK_SLOT_KIND(helper, 9, FeedbackSlotKind::kBinaryOp); |
| 595 } | 604 } |
| 596 } | 605 } |
| 597 | 606 |
| 598 | 607 |
| 599 TEST(VectorStoreICBasic) { | 608 TEST(VectorStoreICBasic) { |
| 600 if (i::FLAG_always_opt) return; | 609 if (i::FLAG_always_opt) return; |
| 601 | 610 |
| 602 CcTest::InitializeVM(); | 611 CcTest::InitializeVM(); |
| 603 LocalContext context; | 612 LocalContext context; |
| 604 v8::HandleScope scope(context->GetIsolate()); | 613 v8::HandleScope scope(context->GetIsolate()); |
| 605 | 614 |
| 606 CompileRun( | 615 CompileRun( |
| 607 "function f(a) {" | 616 "function f(a) {" |
| 608 " a.foo = 5;" | 617 " a.foo = 5;" |
| 609 "}" | 618 "}" |
| 610 "var a = { foo: 3 };" | 619 "var a = { foo: 3 };" |
| 611 "f(a);" | 620 "f(a);" |
| 612 "f(a);" | 621 "f(a);" |
| 613 "f(a);"); | 622 "f(a);"); |
| 614 Handle<JSFunction> f = GetFunction("f"); | 623 Handle<JSFunction> f = GetFunction("f"); |
| 615 // There should be one IC slot. | 624 // There should be one IC slot. |
| 616 Handle<FeedbackVector> feedback_vector(f->feedback_vector()); | 625 Handle<FeedbackVector> feedback_vector(f->feedback_vector()); |
| 617 FeedbackVectorHelper helper(feedback_vector); | 626 FeedbackVectorHelper helper(feedback_vector); |
| 618 CHECK_EQ(1, helper.slot_count()); | 627 CHECK_EQ(2, helper.slot_count()); |
| 619 FeedbackSlot slot(0); | 628 FeedbackSlot slot(0); |
| 620 StoreICNexus nexus(feedback_vector, slot); | 629 StoreICNexus nexus(feedback_vector, slot); |
| 621 CHECK_EQ(MONOMORPHIC, nexus.StateFromFeedback()); | 630 CHECK_EQ(MONOMORPHIC, nexus.StateFromFeedback()); |
| 622 } | 631 } |
| 623 | 632 |
| 624 TEST(StoreOwnIC) { | 633 TEST(StoreOwnIC) { |
| 625 if (i::FLAG_always_opt) return; | 634 if (i::FLAG_always_opt) return; |
| 626 | 635 |
| 627 CcTest::InitializeVM(); | 636 CcTest::InitializeVM(); |
| 628 LocalContext context; | 637 LocalContext context; |
| (...skipping 11 matching lines...) Expand all Loading... |
| 640 Handle<FeedbackVector> feedback_vector(f->feedback_vector()); | 649 Handle<FeedbackVector> feedback_vector(f->feedback_vector()); |
| 641 FeedbackVectorHelper helper(feedback_vector); | 650 FeedbackVectorHelper helper(feedback_vector); |
| 642 CHECK_EQ(2, helper.slot_count()); | 651 CHECK_EQ(2, helper.slot_count()); |
| 643 CHECK_SLOT_KIND(helper, 0, FeedbackSlotKind::kLiteral); | 652 CHECK_SLOT_KIND(helper, 0, FeedbackSlotKind::kLiteral); |
| 644 CHECK_SLOT_KIND(helper, 1, FeedbackSlotKind::kStoreOwnNamed); | 653 CHECK_SLOT_KIND(helper, 1, FeedbackSlotKind::kStoreOwnNamed); |
| 645 StoreOwnICNexus nexus(feedback_vector, helper.slot(1)); | 654 StoreOwnICNexus nexus(feedback_vector, helper.slot(1)); |
| 646 CHECK_EQ(MONOMORPHIC, nexus.StateFromFeedback()); | 655 CHECK_EQ(MONOMORPHIC, nexus.StateFromFeedback()); |
| 647 } | 656 } |
| 648 | 657 |
| 649 } // namespace | 658 } // namespace |
| OLD | NEW |