| OLD | NEW |
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 505 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 516 | 516 |
| 517 static HeapObject* AllocateUnaligned(NewSpace* space, int size) { | 517 static HeapObject* AllocateUnaligned(NewSpace* space, int size) { |
| 518 AllocationResult allocation = space->AllocateRawUnaligned(size); | 518 AllocationResult allocation = space->AllocateRawUnaligned(size); |
| 519 CHECK(!allocation.IsRetry()); | 519 CHECK(!allocation.IsRetry()); |
| 520 HeapObject* filler = NULL; | 520 HeapObject* filler = NULL; |
| 521 CHECK(allocation.To(&filler)); | 521 CHECK(allocation.To(&filler)); |
| 522 space->heap()->CreateFillerObjectAt(filler->address(), size); | 522 space->heap()->CreateFillerObjectAt(filler->address(), size); |
| 523 return filler; | 523 return filler; |
| 524 } | 524 } |
| 525 | 525 |
| 526 class Observer : public InlineAllocationObserver { | 526 static HeapObject* AllocateUnaligned(PagedSpace* space, int size) { |
| 527 AllocationResult allocation = space->AllocateRaw(size, kDoubleUnaligned); |
| 528 CHECK(!allocation.IsRetry()); |
| 529 HeapObject* filler = NULL; |
| 530 CHECK(allocation.To(&filler)); |
| 531 space->heap()->CreateFillerObjectAt(filler->address(), size); |
| 532 return filler; |
| 533 } |
| 534 |
| 535 static HeapObject* AllocateUnaligned(LargeObjectSpace* space, int size) { |
| 536 AllocationResult allocation = space->AllocateRaw(size, EXECUTABLE); |
| 537 CHECK(!allocation.IsRetry()); |
| 538 HeapObject* filler = NULL; |
| 539 CHECK(allocation.To(&filler)); |
| 540 return filler; |
| 541 } |
| 542 |
| 543 class Observer : public AllocationObserver { |
| 527 public: | 544 public: |
| 528 explicit Observer(intptr_t step_size) | 545 explicit Observer(intptr_t step_size) |
| 529 : InlineAllocationObserver(step_size), count_(0) {} | 546 : AllocationObserver(step_size), count_(0) {} |
| 530 | 547 |
| 531 void Step(int bytes_allocated, Address, size_t) override { count_++; } | 548 void Step(int bytes_allocated, Address, size_t) override { count_++; } |
| 532 | 549 |
| 533 int count() const { return count_; } | 550 int count() const { return count_; } |
| 534 | 551 |
| 535 private: | 552 private: |
| 536 int count_; | 553 int count_; |
| 537 }; | 554 }; |
| 538 | 555 |
| 556 template <typename T> |
| 557 void testAllocationObserver(Isolate* i_isolate, T* space) { |
| 558 Observer observer1(128); |
| 559 space->AddAllocationObserver(&observer1); |
| 539 | 560 |
| 540 UNINITIALIZED_TEST(InlineAllocationObserver) { | 561 // The observer should not get notified if we have only allocated less than |
| 562 // 128 bytes. |
| 563 AllocateUnaligned(space, 64); |
| 564 CHECK_EQ(observer1.count(), 0); |
| 565 |
| 566 // The observer should get called when we have allocated exactly 128 bytes. |
| 567 AllocateUnaligned(space, 64); |
| 568 CHECK_EQ(observer1.count(), 1); |
| 569 |
| 570 // Another >128 bytes should get another notification. |
| 571 AllocateUnaligned(space, 136); |
| 572 CHECK_EQ(observer1.count(), 2); |
| 573 |
| 574 // Allocating a large object should get only one notification. |
| 575 AllocateUnaligned(space, 1024); |
| 576 CHECK_EQ(observer1.count(), 3); |
| 577 |
| 578 // Allocating another 2048 bytes in small objects should get 16 |
| 579 // notifications. |
| 580 for (int i = 0; i < 64; ++i) { |
| 581 AllocateUnaligned(space, 32); |
| 582 } |
| 583 CHECK_EQ(observer1.count(), 19); |
| 584 |
| 585 // Multiple observers should work. |
| 586 Observer observer2(96); |
| 587 space->AddAllocationObserver(&observer2); |
| 588 |
| 589 AllocateUnaligned(space, 2048); |
| 590 CHECK_EQ(observer1.count(), 20); |
| 591 CHECK_EQ(observer2.count(), 1); |
| 592 |
| 593 AllocateUnaligned(space, 104); |
| 594 CHECK_EQ(observer1.count(), 20); |
| 595 CHECK_EQ(observer2.count(), 2); |
| 596 |
| 597 // Callback should stop getting called after an observer is removed. |
| 598 space->RemoveAllocationObserver(&observer1); |
| 599 |
| 600 AllocateUnaligned(space, 384); |
| 601 CHECK_EQ(observer1.count(), 20); // no more notifications. |
| 602 CHECK_EQ(observer2.count(), 3); // this one is still active. |
| 603 |
| 604 // Ensure that PauseInlineAllocationObserversScope work correctly. |
| 605 AllocateUnaligned(space, 48); |
| 606 CHECK_EQ(observer2.count(), 3); |
| 607 { |
| 608 PauseAllocationObserversScope pause_observers(i_isolate->heap()); |
| 609 CHECK_EQ(observer2.count(), 3); |
| 610 AllocateUnaligned(space, 384); |
| 611 CHECK_EQ(observer2.count(), 3); |
| 612 } |
| 613 CHECK_EQ(observer2.count(), 3); |
| 614 // Coupled with the 48 bytes allocated before the pause, another 48 bytes |
| 615 // allocated here should trigger a notification. |
| 616 AllocateUnaligned(space, 48); |
| 617 CHECK_EQ(observer2.count(), 4); |
| 618 |
| 619 space->RemoveAllocationObserver(&observer2); |
| 620 AllocateUnaligned(space, 384); |
| 621 CHECK_EQ(observer1.count(), 20); |
| 622 CHECK_EQ(observer2.count(), 4); |
| 623 } |
| 624 |
| 625 UNINITIALIZED_TEST(AllocationObserver) { |
| 541 v8::Isolate::CreateParams create_params; | 626 v8::Isolate::CreateParams create_params; |
| 542 create_params.array_buffer_allocator = CcTest::array_buffer_allocator(); | 627 create_params.array_buffer_allocator = CcTest::array_buffer_allocator(); |
| 543 v8::Isolate* isolate = v8::Isolate::New(create_params); | 628 v8::Isolate* isolate = v8::Isolate::New(create_params); |
| 544 { | 629 { |
| 545 v8::Isolate::Scope isolate_scope(isolate); | 630 v8::Isolate::Scope isolate_scope(isolate); |
| 546 v8::HandleScope handle_scope(isolate); | 631 v8::HandleScope handle_scope(isolate); |
| 547 v8::Context::New(isolate)->Enter(); | 632 v8::Context::New(isolate)->Enter(); |
| 548 | 633 |
| 549 Isolate* i_isolate = reinterpret_cast<Isolate*>(isolate); | 634 Isolate* i_isolate = reinterpret_cast<Isolate*>(isolate); |
| 550 | 635 |
| 551 NewSpace* new_space = i_isolate->heap()->new_space(); | 636 testAllocationObserver<NewSpace>(i_isolate, i_isolate->heap()->new_space()); |
| 552 | 637 // Old space is used but the code path is shared for all |
| 553 Observer observer1(128); | 638 // classes inheriting from PagedSpace. |
| 554 new_space->AddInlineAllocationObserver(&observer1); | 639 testAllocationObserver<PagedSpace>(i_isolate, |
| 555 | 640 i_isolate->heap()->old_space()); |
| 556 // The observer should not get notified if we have only allocated less than | 641 testAllocationObserver<LargeObjectSpace>(i_isolate, |
| 557 // 128 bytes. | 642 i_isolate->heap()->lo_space()); |
| 558 AllocateUnaligned(new_space, 64); | |
| 559 CHECK_EQ(observer1.count(), 0); | |
| 560 | |
| 561 // The observer should get called when we have allocated exactly 128 bytes. | |
| 562 AllocateUnaligned(new_space, 64); | |
| 563 CHECK_EQ(observer1.count(), 1); | |
| 564 | |
| 565 // Another >128 bytes should get another notification. | |
| 566 AllocateUnaligned(new_space, 136); | |
| 567 CHECK_EQ(observer1.count(), 2); | |
| 568 | |
| 569 // Allocating a large object should get only one notification. | |
| 570 AllocateUnaligned(new_space, 1024); | |
| 571 CHECK_EQ(observer1.count(), 3); | |
| 572 | |
| 573 // Allocating another 2048 bytes in small objects should get 16 | |
| 574 // notifications. | |
| 575 for (int i = 0; i < 64; ++i) { | |
| 576 AllocateUnaligned(new_space, 32); | |
| 577 } | |
| 578 CHECK_EQ(observer1.count(), 19); | |
| 579 | |
| 580 // Multiple observers should work. | |
| 581 Observer observer2(96); | |
| 582 new_space->AddInlineAllocationObserver(&observer2); | |
| 583 | |
| 584 AllocateUnaligned(new_space, 2048); | |
| 585 CHECK_EQ(observer1.count(), 20); | |
| 586 CHECK_EQ(observer2.count(), 1); | |
| 587 | |
| 588 AllocateUnaligned(new_space, 104); | |
| 589 CHECK_EQ(observer1.count(), 20); | |
| 590 CHECK_EQ(observer2.count(), 2); | |
| 591 | |
| 592 // Callback should stop getting called after an observer is removed. | |
| 593 new_space->RemoveInlineAllocationObserver(&observer1); | |
| 594 | |
| 595 AllocateUnaligned(new_space, 384); | |
| 596 CHECK_EQ(observer1.count(), 20); // no more notifications. | |
| 597 CHECK_EQ(observer2.count(), 3); // this one is still active. | |
| 598 | |
| 599 // Ensure that PauseInlineAllocationObserversScope work correctly. | |
| 600 AllocateUnaligned(new_space, 48); | |
| 601 CHECK_EQ(observer2.count(), 3); | |
| 602 { | |
| 603 PauseInlineAllocationObserversScope pause_observers(new_space); | |
| 604 CHECK_EQ(observer2.count(), 3); | |
| 605 AllocateUnaligned(new_space, 384); | |
| 606 CHECK_EQ(observer2.count(), 3); | |
| 607 } | |
| 608 CHECK_EQ(observer2.count(), 3); | |
| 609 // Coupled with the 48 bytes allocated before the pause, another 48 bytes | |
| 610 // allocated here should trigger a notification. | |
| 611 AllocateUnaligned(new_space, 48); | |
| 612 CHECK_EQ(observer2.count(), 4); | |
| 613 | |
| 614 new_space->RemoveInlineAllocationObserver(&observer2); | |
| 615 AllocateUnaligned(new_space, 384); | |
| 616 CHECK_EQ(observer1.count(), 20); | |
| 617 CHECK_EQ(observer2.count(), 4); | |
| 618 } | 643 } |
| 619 isolate->Dispose(); | 644 isolate->Dispose(); |
| 620 } | 645 } |
| 621 | 646 |
| 622 | 647 |
| 623 UNINITIALIZED_TEST(InlineAllocationObserverCadence) { | 648 UNINITIALIZED_TEST(InlineAllocationObserverCadence) { |
| 624 v8::Isolate::CreateParams create_params; | 649 v8::Isolate::CreateParams create_params; |
| 625 create_params.array_buffer_allocator = CcTest::array_buffer_allocator(); | 650 create_params.array_buffer_allocator = CcTest::array_buffer_allocator(); |
| 626 v8::Isolate* isolate = v8::Isolate::New(create_params); | 651 v8::Isolate* isolate = v8::Isolate::New(create_params); |
| 627 { | 652 { |
| 628 v8::Isolate::Scope isolate_scope(isolate); | 653 v8::Isolate::Scope isolate_scope(isolate); |
| 629 v8::HandleScope handle_scope(isolate); | 654 v8::HandleScope handle_scope(isolate); |
| 630 v8::Context::New(isolate)->Enter(); | 655 v8::Context::New(isolate)->Enter(); |
| 631 | 656 |
| 632 Isolate* i_isolate = reinterpret_cast<Isolate*>(isolate); | 657 Isolate* i_isolate = reinterpret_cast<Isolate*>(isolate); |
| 633 | 658 |
| 634 NewSpace* new_space = i_isolate->heap()->new_space(); | 659 NewSpace* new_space = i_isolate->heap()->new_space(); |
| 635 | 660 |
| 636 Observer observer1(512); | 661 Observer observer1(512); |
| 637 new_space->AddInlineAllocationObserver(&observer1); | 662 new_space->AddAllocationObserver(&observer1); |
| 638 Observer observer2(576); | 663 Observer observer2(576); |
| 639 new_space->AddInlineAllocationObserver(&observer2); | 664 new_space->AddAllocationObserver(&observer2); |
| 640 | 665 |
| 641 for (int i = 0; i < 512; ++i) { | 666 for (int i = 0; i < 512; ++i) { |
| 642 AllocateUnaligned(new_space, 32); | 667 AllocateUnaligned(new_space, 32); |
| 643 } | 668 } |
| 644 | 669 |
| 645 new_space->RemoveInlineAllocationObserver(&observer1); | 670 new_space->RemoveAllocationObserver(&observer1); |
| 646 new_space->RemoveInlineAllocationObserver(&observer2); | 671 new_space->RemoveAllocationObserver(&observer2); |
| 647 | 672 |
| 648 CHECK_EQ(observer1.count(), 32); | 673 CHECK_EQ(observer1.count(), 32); |
| 649 CHECK_EQ(observer2.count(), 28); | 674 CHECK_EQ(observer2.count(), 28); |
| 650 } | 675 } |
| 651 isolate->Dispose(); | 676 isolate->Dispose(); |
| 652 } | 677 } |
| 653 | 678 |
| 654 } // namespace internal | 679 } // namespace internal |
| 655 } // namespace v8 | 680 } // namespace v8 |
| OLD | NEW |