Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(100)

Side by Side Diff: Source/platform/heap/HeapTest.cpp

Issue 1086413003: Oilpan: HeapVectorBacking should call destructors for its elements (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: rebased past r194046 (upto r194085.) Created 5 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « Source/platform/heap/Heap.h ('k') | Source/wtf/Deque.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2013 Google Inc. All rights reserved. 2 * Copyright (C) 2013 Google Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are 5 * modification, are permitted provided that the following conditions are
6 * met: 6 * met:
7 * 7 *
8 * * Redistributions of source code must retain the above copyright 8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above 10 * * Redistributions in binary form must reproduce the above
(...skipping 3869 matching lines...) Expand 10 before | Expand all | Expand 10 after
3880 VectorObjectNoTrace n1, n2; 3880 VectorObjectNoTrace n1, n2;
3881 dequeNoTrace.append(n1); 3881 dequeNoTrace.append(n1);
3882 dequeNoTrace.append(n2); 3882 dequeNoTrace.append(n2);
3883 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GC WithSweep, Heap::ForcedGC); 3883 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GC WithSweep, Heap::ForcedGC);
3884 EXPECT_EQ(2, SimpleFinalizedObject::s_destructorCalls); 3884 EXPECT_EQ(2, SimpleFinalizedObject::s_destructorCalls);
3885 } 3885 }
3886 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith Sweep, Heap::ForcedGC); 3886 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith Sweep, Heap::ForcedGC);
3887 EXPECT_EQ(8, SimpleFinalizedObject::s_destructorCalls); 3887 EXPECT_EQ(8, SimpleFinalizedObject::s_destructorCalls);
3888 } 3888 }
3889 3889
3890 class InlinedVectorObject {
3891 ALLOW_ONLY_INLINE_ALLOCATION();
3892 public:
3893 InlinedVectorObject()
3894 {
3895 }
3896 ~InlinedVectorObject()
3897 {
3898 s_destructorCalls++;
3899 }
3900 DEFINE_INLINE_TRACE()
3901 {
3902 }
3903
3904 static int s_destructorCalls;
3905 };
3906
3907 int InlinedVectorObject::s_destructorCalls = 0;
3908
3909 } // namespace blink
3910
3911 WTF_ALLOW_MOVE_AND_INIT_WITH_MEM_FUNCTIONS(blink::InlinedVectorObject);
3912
3913 namespace blink {
3914
3915 class InlinedVectorObjectWrapper final : public GarbageCollectedFinalized<Inline dVectorObjectWrapper> {
3916 public:
3917 InlinedVectorObjectWrapper()
3918 {
3919 InlinedVectorObject i1, i2;
3920 m_vector1.append(i1);
3921 m_vector1.append(i2);
3922 m_vector2.append(i1);
3923 m_vector2.append(i2); // This allocates an out-of-line buffer.
3924 m_vector3.append(i1);
3925 m_vector3.append(i2);
3926 }
3927
3928 DEFINE_INLINE_TRACE()
3929 {
3930 visitor->trace(m_vector1);
3931 visitor->trace(m_vector2);
3932 visitor->trace(m_vector3);
3933 }
3934
3935 private:
3936 HeapVector<InlinedVectorObject> m_vector1;
3937 HeapVector<InlinedVectorObject, 1> m_vector2;
3938 HeapVector<InlinedVectorObject, 2> m_vector3;
3939 };
3940
3941 TEST(HeapTest, VectorDestructors)
3942 {
3943 clearOutOldGarbage();
3944 InlinedVectorObject::s_destructorCalls = 0;
3945 {
3946 HeapVector<InlinedVectorObject> vector;
3947 InlinedVectorObject i1, i2;
3948 vector.append(i1);
3949 vector.append(i2);
3950 }
3951 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith Sweep, Heap::ForcedGC);
3952 // This is not EXPECT_EQ but EXPECT_LE because a HeapVectorBacking calls
3953 // destructors for all elements in (not the size but) the capacity of
3954 // the vector. Thus the number of destructors called becomes larger
3955 // than the actual number of objects in the vector.
3956 EXPECT_LE(4, InlinedVectorObject::s_destructorCalls);
3957
3958 InlinedVectorObject::s_destructorCalls = 0;
3959 {
3960 HeapVector<InlinedVectorObject, 1> vector;
3961 InlinedVectorObject i1, i2;
3962 vector.append(i1);
3963 vector.append(i2); // This allocates an out-of-line buffer.
3964 }
3965 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith Sweep, Heap::ForcedGC);
3966 EXPECT_LE(4, InlinedVectorObject::s_destructorCalls);
3967
3968 InlinedVectorObject::s_destructorCalls = 0;
3969 {
3970 HeapVector<InlinedVectorObject, 2> vector;
3971 InlinedVectorObject i1, i2;
3972 vector.append(i1);
3973 vector.append(i2);
3974 }
3975 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith Sweep, Heap::ForcedGC);
3976 EXPECT_LE(4, InlinedVectorObject::s_destructorCalls);
3977
3978 InlinedVectorObject::s_destructorCalls = 0;
3979 {
3980 new InlinedVectorObjectWrapper();
3981 Heap::collectGarbage(ThreadState::HeapPointersOnStack, ThreadState::GCWi thSweep, Heap::ForcedGC);
3982 EXPECT_EQ(2, InlinedVectorObject::s_destructorCalls);
3983 }
3984 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, ThreadState::GCWith Sweep, Heap::ForcedGC);
3985 EXPECT_LE(8, InlinedVectorObject::s_destructorCalls);
3986 }
3987
3890 template<typename Set> 3988 template<typename Set>
3891 void rawPtrInHashHelper() 3989 void rawPtrInHashHelper()
3892 { 3990 {
3893 Set set; 3991 Set set;
3894 set.add(new int(42)); 3992 set.add(new int(42));
3895 set.add(new int(42)); 3993 set.add(new int(42));
3896 EXPECT_EQ(2u, set.size()); 3994 EXPECT_EQ(2u, set.size());
3897 for (typename Set::iterator it = set.begin(); it != set.end(); ++it) { 3995 for (typename Set::iterator it = set.begin(); it != set.end(); ++it) {
3898 EXPECT_EQ(42, **it); 3996 EXPECT_EQ(42, **it);
3899 delete *it; 3997 delete *it;
(...skipping 1648 matching lines...) Expand 10 before | Expand all | Expand 10 after
5548 // of the old buffer to both ends of the expanded buffer, along with 5646 // of the old buffer to both ends of the expanded buffer, along with
5549 // re-adjusting both start&end indices in terms of that expanded buffer. 5647 // re-adjusting both start&end indices in terms of that expanded buffer.
5550 EXPECT_EQ(80u, deque->size()); 5648 EXPECT_EQ(80u, deque->size());
5551 i = 0; 5649 i = 0;
5552 for (const auto& intWrapper : *deque) { 5650 for (const auto& intWrapper : *deque) {
5553 EXPECT_EQ(i + 50, intWrapper->value()); 5651 EXPECT_EQ(i + 50, intWrapper->value());
5554 i++; 5652 i++;
5555 } 5653 }
5556 } 5654 }
5557 5655
5656 class SimpleRefValue : public RefCounted<SimpleRefValue> {
5657 public:
5658 static PassRefPtr<SimpleRefValue> create(int i)
5659 {
5660 return adoptRef(new SimpleRefValue(i));
5661 }
5662
5663 int value() const { return m_value; }
5664 private:
5665 explicit SimpleRefValue(int value)
5666 : m_value(value)
5667 {
5668 }
5669
5670 int m_value;
5671 };
5672
5673 class PartObjectWithRef {
5674 ALLOW_ONLY_INLINE_ALLOCATION();
5675 public:
5676 PartObjectWithRef(int i)
5677 : m_value(SimpleRefValue::create(i))
5678 {
5679 }
5680
5681 int value() const { return m_value->value(); }
5682
5683 private:
5684 RefPtr<SimpleRefValue> m_value;
5685 };
5686
5687 } // namespace blink
5688
5689 WTF_ALLOW_INIT_WITH_MEM_FUNCTIONS(blink::PartObjectWithRef);
5690
5691 namespace blink {
5692
5693 TEST(HeapTest, DequePartObjectsExpand)
5694 {
5695 // Test expansion of HeapDeque<PartObject>
5696
5697 using PartDeque = HeapDeque<PartObjectWithRef>;
5698
5699 Persistent<PartDeque> deque = new PartDeque();
5700 // Auxillary Deque used to prevent 'inline' buffer expansion.
5701 Persistent<PartDeque> dequeUnused = new PartDeque();
5702
5703 // Append a sequence, bringing about repeated expansions of the
5704 // deque's buffer.
5705 int i = 0;
5706 for (; i < 60; ++i) {
5707 deque->append(PartObjectWithRef(i));
5708 dequeUnused->append(PartObjectWithRef(i));
5709 }
5710
5711 EXPECT_EQ(60u, deque->size());
5712 i = 0;
5713 for (const PartObjectWithRef& part : *deque) {
5714 EXPECT_EQ(i, part.value());
5715 i++;
5716 }
5717
5718 // Remove most of the queued objects and have the buffer's start index
5719 // 'point' somewhere into the buffer, just behind the end index.
5720 for (i = 0; i < 50; ++i)
5721 deque->takeFirst();
5722
5723 EXPECT_EQ(10u, deque->size());
5724 i = 0;
5725 for (const PartObjectWithRef& part : *deque) {
5726 EXPECT_EQ(50 + i, part.value());
5727 i++;
5728 }
5729
5730 // Append even more, eventually causing an expansion of the underlying
5731 // buffer once the end index wraps around and reaches the start index.
5732 for (i = 0; i < 70; ++i)
5733 deque->append(PartObjectWithRef(60 + i));
5734
5735 // Verify that the final buffer expansion copied the start and end segments
5736 // of the old buffer to both ends of the expanded buffer, along with
5737 // re-adjusting both start&end indices in terms of that expanded buffer.
5738 EXPECT_EQ(80u, deque->size());
5739 i = 0;
5740 for (const PartObjectWithRef& part : *deque) {
5741 EXPECT_EQ(i + 50, part.value());
5742 i++;
5743 }
5744
5745 for (i = 0; i < 70; ++i)
5746 deque->append(PartObjectWithRef(130 + i));
5747
5748 EXPECT_EQ(150u, deque->size());
5749 i = 0;
5750 for (const PartObjectWithRef& part : *deque) {
5751 EXPECT_EQ(i + 50, part.value());
5752 i++;
5753 }
5754 }
5755
5756 TEST(HeapTest, HeapVectorPartObjects)
5757 {
5758 HeapVector<PartObjectWithRef> vector1;
5759 HeapVector<PartObjectWithRef> vector2;
5760
5761 for (int i = 0; i < 10; ++i) {
5762 vector1.append(PartObjectWithRef(i));
5763 vector2.append(PartObjectWithRef(i));
5764 }
5765
5766 vector1.reserveCapacity(150);
5767 EXPECT_EQ(150u, vector1.capacity());
5768 EXPECT_EQ(10u, vector1.size());
5769
5770 vector2.reserveCapacity(100);
5771 EXPECT_EQ(100u, vector2.capacity());
5772 EXPECT_EQ(10u, vector2.size());
5773
5774 for (int i = 0; i < 4; ++i) {
5775 vector1.append(PartObjectWithRef(10 + i));
5776 vector2.append(PartObjectWithRef(10 + i));
5777 vector2.append(PartObjectWithRef(10 + i));
5778 }
5779
5780 // Shrinking heap vector backing stores always succeeds,
5781 // so these two will not currently exercise the code path
5782 // where shrinking causes copying into a new, small buffer.
5783 vector2.shrinkToReasonableCapacity();
5784 EXPECT_EQ(18u, vector2.size());
5785
5786 vector1.shrinkToReasonableCapacity();
5787 EXPECT_EQ(14u, vector1.size());
5788 }
5789
5558 namespace { 5790 namespace {
5559 5791
5560 enum GrowthDirection { 5792 enum GrowthDirection {
5561 GrowsTowardsHigher, 5793 GrowsTowardsHigher,
5562 GrowsTowardsLower, 5794 GrowsTowardsLower,
5563 }; 5795 };
5564 5796
5565 NEVER_INLINE NO_SANITIZE_ADDRESS GrowthDirection stackGrowthDirection() 5797 NEVER_INLINE NO_SANITIZE_ADDRESS GrowthDirection stackGrowthDirection()
5566 { 5798 {
5567 // Disable ASan, otherwise its stack checking (use-after-return) will 5799 // Disable ASan, otherwise its stack checking (use-after-return) will
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
5692 { 5924 {
5693 Persistent<ClassWithMember> object = ClassWithMember::create(); 5925 Persistent<ClassWithMember> object = ClassWithMember::create();
5694 EXPECT_EQ(0, object->traceCount()); 5926 EXPECT_EQ(0, object->traceCount());
5695 TestMixinAllocatingObject* mixin = TestMixinAllocatingObject::create(object. get()); 5927 TestMixinAllocatingObject* mixin = TestMixinAllocatingObject::create(object. get());
5696 EXPECT_TRUE(mixin); 5928 EXPECT_TRUE(mixin);
5697 EXPECT_GT(object->traceCount(), 0); 5929 EXPECT_GT(object->traceCount(), 0);
5698 EXPECT_GT(mixin->traceCount(), 0); 5930 EXPECT_GT(mixin->traceCount(), 0);
5699 } 5931 }
5700 5932
5701 } // namespace blink 5933 } // namespace blink
OLDNEW
« no previous file with comments | « Source/platform/heap/Heap.h ('k') | Source/wtf/Deque.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698