Chromium Code Reviews| 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 735 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 746 | 746 |
| 747 static HeapObject* AllocateUnaligned(NewSpace* space, int size) { | 747 static HeapObject* AllocateUnaligned(NewSpace* space, int size) { |
| 748 AllocationResult allocation = space->AllocateRawUnaligned(size); | 748 AllocationResult allocation = space->AllocateRawUnaligned(size); |
| 749 CHECK(!allocation.IsRetry()); | 749 CHECK(!allocation.IsRetry()); |
| 750 HeapObject* filler = NULL; | 750 HeapObject* filler = NULL; |
| 751 CHECK(allocation.To(&filler)); | 751 CHECK(allocation.To(&filler)); |
| 752 space->heap()->CreateFillerObjectAt(filler->address(), size); | 752 space->heap()->CreateFillerObjectAt(filler->address(), size); |
| 753 return filler; | 753 return filler; |
| 754 } | 754 } |
| 755 | 755 |
| 756 class Observer : public InlineAllocationObserver { | 756 static HeapObject* AllocateUnaligned(PagedSpace* space, int size) { |
| 757 AllocationResult allocation = space->AllocateRaw(size, kDoubleUnaligned); | |
| 758 CHECK(!allocation.IsRetry()); | |
| 759 HeapObject* filler = NULL; | |
| 760 CHECK(allocation.To(&filler)); | |
| 761 space->heap()->CreateFillerObjectAt(filler->address(), size); | |
| 762 return filler; | |
| 763 } | |
| 764 | |
| 765 static HeapObject* AllocateUnaligned(LargeObjectSpace* space, int size) { | |
| 766 AllocationResult allocation = space->AllocateRaw(size, EXECUTABLE); | |
| 767 CHECK(!allocation.IsRetry()); | |
| 768 HeapObject* filler = NULL; | |
| 769 CHECK(allocation.To(&filler)); | |
| 770 Code* code = Code::cast(filler); | |
|
Hannes Payer (out of office)
2016/02/08 10:13:48
Why cast to Code?
| |
| 771 return code; | |
| 772 } | |
| 773 | |
| 774 class Observer : public AllocationObserver { | |
| 757 public: | 775 public: |
| 758 explicit Observer(intptr_t step_size) | 776 explicit Observer(intptr_t step_size) |
| 759 : InlineAllocationObserver(step_size), count_(0) {} | 777 : AllocationObserver(step_size), count_(0) {} |
| 760 | 778 |
| 761 void Step(int bytes_allocated, Address, size_t) override { count_++; } | 779 void Step(int bytes_allocated, Address, size_t) override { count_++; } |
| 762 | 780 |
| 763 int count() const { return count_; } | 781 int count() const { return count_; } |
| 764 | 782 |
| 765 private: | 783 private: |
| 766 int count_; | 784 int count_; |
| 767 }; | 785 }; |
| 768 | 786 |
| 787 template <typename T> | |
| 788 void testAllocationObserver(Isolate* i_isolate, T* space) { | |
| 789 Observer observer1(128); | |
| 790 space->AddAllocationObserver(&observer1); | |
| 769 | 791 |
| 770 UNINITIALIZED_TEST(InlineAllocationObserver) { | 792 // The observer should not get notified if we have only allocated less than |
| 793 // 128 bytes. | |
| 794 AllocateUnaligned(space, 64); | |
| 795 CHECK_EQ(observer1.count(), 0); | |
| 796 | |
| 797 // The observer should get called when we have allocated exactly 128 bytes. | |
| 798 AllocateUnaligned(space, 64); | |
| 799 CHECK_EQ(observer1.count(), 1); | |
| 800 | |
| 801 // Another >128 bytes should get another notification. | |
| 802 AllocateUnaligned(space, 136); | |
| 803 CHECK_EQ(observer1.count(), 2); | |
| 804 | |
| 805 // Allocating a large object should get only one notification. | |
| 806 AllocateUnaligned(space, 1024); | |
| 807 CHECK_EQ(observer1.count(), 3); | |
| 808 | |
| 809 // Allocating another 2048 bytes in small objects should get 16 | |
| 810 // notifications. | |
| 811 for (int i = 0; i < 64; ++i) { | |
| 812 AllocateUnaligned(space, 32); | |
| 813 } | |
| 814 CHECK_EQ(observer1.count(), 19); | |
| 815 | |
| 816 // Multiple observers should work. | |
| 817 Observer observer2(96); | |
| 818 space->AddAllocationObserver(&observer2); | |
| 819 | |
| 820 AllocateUnaligned(space, 2048); | |
| 821 CHECK_EQ(observer1.count(), 20); | |
| 822 CHECK_EQ(observer2.count(), 1); | |
| 823 | |
| 824 AllocateUnaligned(space, 104); | |
| 825 CHECK_EQ(observer1.count(), 20); | |
| 826 CHECK_EQ(observer2.count(), 2); | |
| 827 | |
| 828 // Callback should stop getting called after an observer is removed. | |
| 829 space->RemoveAllocationObserver(&observer1); | |
| 830 | |
| 831 AllocateUnaligned(space, 384); | |
| 832 CHECK_EQ(observer1.count(), 20); // no more notifications. | |
| 833 CHECK_EQ(observer2.count(), 3); // this one is still active. | |
| 834 | |
| 835 // Ensure that PauseInlineAllocationObserversScope work correctly. | |
| 836 AllocateUnaligned(space, 48); | |
| 837 CHECK_EQ(observer2.count(), 3); | |
| 838 { | |
| 839 PauseAllocationObserversScope pause_observers(i_isolate->heap()); | |
| 840 CHECK_EQ(observer2.count(), 3); | |
| 841 AllocateUnaligned(space, 384); | |
| 842 CHECK_EQ(observer2.count(), 3); | |
| 843 } | |
| 844 CHECK_EQ(observer2.count(), 3); | |
| 845 // Coupled with the 48 bytes allocated before the pause, another 48 bytes | |
| 846 // allocated here should trigger a notification. | |
| 847 AllocateUnaligned(space, 48); | |
| 848 CHECK_EQ(observer2.count(), 4); | |
| 849 | |
| 850 space->RemoveAllocationObserver(&observer2); | |
| 851 AllocateUnaligned(space, 384); | |
| 852 CHECK_EQ(observer1.count(), 20); | |
| 853 CHECK_EQ(observer2.count(), 4); | |
| 854 } | |
| 855 | |
| 856 UNINITIALIZED_TEST(AllocationObserver) { | |
| 771 v8::Isolate::CreateParams create_params; | 857 v8::Isolate::CreateParams create_params; |
| 772 create_params.array_buffer_allocator = CcTest::array_buffer_allocator(); | 858 create_params.array_buffer_allocator = CcTest::array_buffer_allocator(); |
| 773 v8::Isolate* isolate = v8::Isolate::New(create_params); | 859 v8::Isolate* isolate = v8::Isolate::New(create_params); |
| 774 { | 860 { |
| 775 v8::Isolate::Scope isolate_scope(isolate); | 861 v8::Isolate::Scope isolate_scope(isolate); |
| 776 v8::HandleScope handle_scope(isolate); | 862 v8::HandleScope handle_scope(isolate); |
| 777 v8::Context::New(isolate)->Enter(); | 863 v8::Context::New(isolate)->Enter(); |
| 778 | 864 |
| 779 Isolate* i_isolate = reinterpret_cast<Isolate*>(isolate); | 865 Isolate* i_isolate = reinterpret_cast<Isolate*>(isolate); |
| 780 | 866 |
| 781 NewSpace* new_space = i_isolate->heap()->new_space(); | 867 testAllocationObserver<NewSpace>(i_isolate, i_isolate->heap()->new_space()); |
| 782 | 868 // Old space is used but the code path is shared for all |
| 783 Observer observer1(128); | 869 // classes inheriting from PagedSpace. |
| 784 new_space->AddInlineAllocationObserver(&observer1); | 870 testAllocationObserver<PagedSpace>(i_isolate, |
| 785 | 871 i_isolate->heap()->old_space()); |
| 786 // The observer should not get notified if we have only allocated less than | 872 testAllocationObserver<LargeObjectSpace>(i_isolate, |
| 787 // 128 bytes. | 873 i_isolate->heap()->lo_space()); |
| 788 AllocateUnaligned(new_space, 64); | |
| 789 CHECK_EQ(observer1.count(), 0); | |
| 790 | |
| 791 // The observer should get called when we have allocated exactly 128 bytes. | |
| 792 AllocateUnaligned(new_space, 64); | |
| 793 CHECK_EQ(observer1.count(), 1); | |
| 794 | |
| 795 // Another >128 bytes should get another notification. | |
| 796 AllocateUnaligned(new_space, 136); | |
| 797 CHECK_EQ(observer1.count(), 2); | |
| 798 | |
| 799 // Allocating a large object should get only one notification. | |
| 800 AllocateUnaligned(new_space, 1024); | |
| 801 CHECK_EQ(observer1.count(), 3); | |
| 802 | |
| 803 // Allocating another 2048 bytes in small objects should get 16 | |
| 804 // notifications. | |
| 805 for (int i = 0; i < 64; ++i) { | |
| 806 AllocateUnaligned(new_space, 32); | |
| 807 } | |
| 808 CHECK_EQ(observer1.count(), 19); | |
| 809 | |
| 810 // Multiple observers should work. | |
| 811 Observer observer2(96); | |
| 812 new_space->AddInlineAllocationObserver(&observer2); | |
| 813 | |
| 814 AllocateUnaligned(new_space, 2048); | |
| 815 CHECK_EQ(observer1.count(), 20); | |
| 816 CHECK_EQ(observer2.count(), 1); | |
| 817 | |
| 818 AllocateUnaligned(new_space, 104); | |
| 819 CHECK_EQ(observer1.count(), 20); | |
| 820 CHECK_EQ(observer2.count(), 2); | |
| 821 | |
| 822 // Callback should stop getting called after an observer is removed. | |
| 823 new_space->RemoveInlineAllocationObserver(&observer1); | |
| 824 | |
| 825 AllocateUnaligned(new_space, 384); | |
| 826 CHECK_EQ(observer1.count(), 20); // no more notifications. | |
| 827 CHECK_EQ(observer2.count(), 3); // this one is still active. | |
| 828 | |
| 829 // Ensure that PauseInlineAllocationObserversScope work correctly. | |
| 830 AllocateUnaligned(new_space, 48); | |
| 831 CHECK_EQ(observer2.count(), 3); | |
| 832 { | |
| 833 PauseInlineAllocationObserversScope pause_observers(new_space); | |
| 834 CHECK_EQ(observer2.count(), 3); | |
| 835 AllocateUnaligned(new_space, 384); | |
| 836 CHECK_EQ(observer2.count(), 3); | |
| 837 } | |
| 838 CHECK_EQ(observer2.count(), 3); | |
| 839 // Coupled with the 48 bytes allocated before the pause, another 48 bytes | |
| 840 // allocated here should trigger a notification. | |
| 841 AllocateUnaligned(new_space, 48); | |
| 842 CHECK_EQ(observer2.count(), 4); | |
| 843 | |
| 844 new_space->RemoveInlineAllocationObserver(&observer2); | |
| 845 AllocateUnaligned(new_space, 384); | |
| 846 CHECK_EQ(observer1.count(), 20); | |
| 847 CHECK_EQ(observer2.count(), 4); | |
| 848 } | 874 } |
| 849 isolate->Dispose(); | 875 isolate->Dispose(); |
| 850 } | 876 } |
| 851 | 877 |
| 852 | 878 |
| 853 UNINITIALIZED_TEST(InlineAllocationObserverCadence) { | 879 UNINITIALIZED_TEST(InlineAllocationObserverCadence) { |
| 854 v8::Isolate::CreateParams create_params; | 880 v8::Isolate::CreateParams create_params; |
| 855 create_params.array_buffer_allocator = CcTest::array_buffer_allocator(); | 881 create_params.array_buffer_allocator = CcTest::array_buffer_allocator(); |
| 856 v8::Isolate* isolate = v8::Isolate::New(create_params); | 882 v8::Isolate* isolate = v8::Isolate::New(create_params); |
| 857 { | 883 { |
| 858 v8::Isolate::Scope isolate_scope(isolate); | 884 v8::Isolate::Scope isolate_scope(isolate); |
| 859 v8::HandleScope handle_scope(isolate); | 885 v8::HandleScope handle_scope(isolate); |
| 860 v8::Context::New(isolate)->Enter(); | 886 v8::Context::New(isolate)->Enter(); |
| 861 | 887 |
| 862 Isolate* i_isolate = reinterpret_cast<Isolate*>(isolate); | 888 Isolate* i_isolate = reinterpret_cast<Isolate*>(isolate); |
| 863 | 889 |
| 864 NewSpace* new_space = i_isolate->heap()->new_space(); | 890 NewSpace* new_space = i_isolate->heap()->new_space(); |
| 865 | 891 |
| 866 Observer observer1(512); | 892 Observer observer1(512); |
| 867 new_space->AddInlineAllocationObserver(&observer1); | 893 new_space->AddAllocationObserver(&observer1); |
| 868 Observer observer2(576); | 894 Observer observer2(576); |
| 869 new_space->AddInlineAllocationObserver(&observer2); | 895 new_space->AddAllocationObserver(&observer2); |
| 870 | 896 |
| 871 for (int i = 0; i < 512; ++i) { | 897 for (int i = 0; i < 512; ++i) { |
| 872 AllocateUnaligned(new_space, 32); | 898 AllocateUnaligned(new_space, 32); |
| 873 } | 899 } |
| 874 | 900 |
| 875 new_space->RemoveInlineAllocationObserver(&observer1); | 901 new_space->RemoveAllocationObserver(&observer1); |
| 876 new_space->RemoveInlineAllocationObserver(&observer2); | 902 new_space->RemoveAllocationObserver(&observer2); |
| 877 | 903 |
| 878 CHECK_EQ(observer1.count(), 32); | 904 CHECK_EQ(observer1.count(), 32); |
| 879 CHECK_EQ(observer2.count(), 28); | 905 CHECK_EQ(observer2.count(), 28); |
| 880 } | 906 } |
| 881 isolate->Dispose(); | 907 isolate->Dispose(); |
| 882 } | 908 } |
| 883 | 909 |
| 884 } // namespace internal | 910 } // namespace internal |
| 885 } // namespace v8 | 911 } // namespace v8 |
| OLD | NEW |