Commit c1bb8b91 authored by Omer Katz's avatar Omer Katz Committed by Commit Bot

heap: Limit HeapDeque to no inline buffers

There are no usages of HeapDeque that use an inline buffer.

Bug: 986235
Change-Id: I72d2c173690b5498cbb0726ae7521fdea2756a84
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2032117Reviewed-by: default avatarKentaro Hara <haraken@chromium.org>
Reviewed-by: default avatarMichael Lippautz <mlippautz@chromium.org>
Commit-Queue: Omer Katz <omerkatz@chromium.org>
Cr-Commit-Position: refs/heads/master@{#737308}
parent f2f3f7a1
......@@ -130,7 +130,7 @@ template <typename ValueArg, wtf_size_t inlineCapacity>
class HeapListHashSetAllocator;
template <typename T, wtf_size_t inlineCapacity>
class HeapVector;
template <typename T, wtf_size_t inlineCapacity>
template <typename T>
class HeapDeque;
template <typename T, typename U, typename V>
class HeapHashCountedSet;
......@@ -154,9 +154,9 @@ struct GCInfoTrait<HeapListHashSet<T, inlineCapacity, U>>
template <typename T, wtf_size_t inlineCapacity>
struct GCInfoTrait<HeapVector<T, inlineCapacity>>
: public GCInfoTrait<Vector<T, inlineCapacity, HeapAllocator>> {};
template <typename T, wtf_size_t inlineCapacity>
struct GCInfoTrait<HeapDeque<T, inlineCapacity>>
: public GCInfoTrait<Deque<T, inlineCapacity, HeapAllocator>> {};
template <typename T>
struct GCInfoTrait<HeapDeque<T>>
: public GCInfoTrait<Deque<T, 0, HeapAllocator>> {};
template <typename T, typename U, typename V>
struct GCInfoTrait<HeapHashCountedSet<T, U, V>>
: public GCInfoTrait<HashCountedSet<T, U, V, HeapAllocator>> {};
......
......@@ -657,14 +657,13 @@ class HeapVector : public Vector<T, inlineCapacity, HeapAllocator> {
}
};
template <typename T, wtf_size_t inlineCapacity = 0>
class HeapDeque : public Deque<T, inlineCapacity, HeapAllocator> {
template <typename T>
class HeapDeque : public Deque<T, 0, HeapAllocator> {
IS_GARBAGE_COLLECTED_CONTAINER_TYPE();
DISALLOW_NEW();
static void CheckType() {
static_assert(
std::is_trivially_destructible<HeapDeque>::value || inlineCapacity,
static_assert(std::is_trivially_destructible<HeapDeque>::value,
"HeapDeque must be trivially destructible.");
static_assert(
IsAllowedInContainer<T>::value,
......@@ -677,35 +676,27 @@ class HeapDeque : public Deque<T, inlineCapacity, HeapAllocator> {
public:
template <typename>
static void* AllocateObject(size_t size) {
// On-heap HeapDeques generally should not have inline capacity, but it is
// hard to avoid when using a type alias. Hence we only disallow the
// VectorTraits<T>::kNeedsDestruction case for now.
static_assert(inlineCapacity == 0 || !VectorTraits<T>::kNeedsDestruction,
"on-heap HeapDeque<> should not have an inline capacity");
return ThreadHeap::Allocate<HeapDeque<T, inlineCapacity>>(size);
return ThreadHeap::Allocate<HeapDeque<T>>(size);
}
HeapDeque() { CheckType(); }
explicit HeapDeque(wtf_size_t size)
: Deque<T, inlineCapacity, HeapAllocator>(size) {
explicit HeapDeque(wtf_size_t size) : Deque<T, 0, HeapAllocator>(size) {
CheckType();
}
HeapDeque(wtf_size_t size, const T& val)
: Deque<T, inlineCapacity, HeapAllocator>(size, val) {
: Deque<T, 0, HeapAllocator>(size, val) {
CheckType();
}
HeapDeque& operator=(const HeapDeque& other) {
HeapDeque<T> copy(other);
Deque<T, inlineCapacity, HeapAllocator>::Swap(copy);
Deque<T, 0, HeapAllocator>::Swap(copy);
return *this;
}
template <wtf_size_t otherCapacity>
HeapDeque(const HeapDeque<T, otherCapacity>& other)
: Deque<T, inlineCapacity, HeapAllocator>(other) {}
HeapDeque(const HeapDeque<T>& other) : Deque<T, 0, HeapAllocator>(other) {}
};
} // namespace blink
......@@ -753,8 +744,8 @@ struct VectorTraits<blink::HeapVector<T, 0>>
};
template <typename T>
struct VectorTraits<blink::HeapDeque<T, 0>>
: VectorTraitsBase<blink::HeapDeque<T, 0>> {
struct VectorTraits<blink::HeapDeque<T>>
: VectorTraitsBase<blink::HeapDeque<T>> {
STATIC_ONLY(VectorTraits);
static const bool kNeedsDestruction = false;
static const bool kCanInitializeWithMemset = true;
......@@ -774,18 +765,6 @@ struct VectorTraits<blink::HeapVector<T, inlineCapacity>>
static const bool kCanMoveWithMemcpy = VectorTraits<T>::kCanMoveWithMemcpy;
};
template <typename T, wtf_size_t inlineCapacity>
struct VectorTraits<blink::HeapDeque<T, inlineCapacity>>
: VectorTraitsBase<blink::HeapDeque<T, inlineCapacity>> {
STATIC_ONLY(VectorTraits);
static const bool kNeedsDestruction = VectorTraits<T>::kNeedsDestruction;
static const bool kCanInitializeWithMemset =
VectorTraits<T>::kCanInitializeWithMemset;
static const bool kCanClearUnusedSlotsWithMemset =
VectorTraits<T>::kCanClearUnusedSlotsWithMemset;
static const bool kCanMoveWithMemcpy = VectorTraits<T>::kCanMoveWithMemcpy;
};
template <typename T>
struct HashTraits<blink::Member<T>> : SimpleClassHashTraits<blink::Member<T>> {
STATIC_ONLY(HashTraits);
......
......@@ -2243,9 +2243,9 @@ class Container final : public GarbageCollected<Container> {
HeapVector<Member<IntWrapper>, 2> vector;
HeapVector<PairWrappedUnwrapped, 2> vector_wu;
HeapVector<PairUnwrappedWrapped, 2> vector_uw;
HeapDeque<Member<IntWrapper>, 0> deque;
HeapDeque<PairWrappedUnwrapped, 0> deque_wu;
HeapDeque<PairUnwrappedWrapped, 0> deque_uw;
HeapDeque<Member<IntWrapper>> deque;
HeapDeque<PairWrappedUnwrapped> deque_wu;
HeapDeque<PairUnwrappedWrapped> deque_uw;
void Trace(blink::Visitor* visitor) {
visitor->Trace(map);
visitor->Trace(set);
......@@ -2407,9 +2407,9 @@ TEST_F(HeapTest, HeapVectorOnStackLargeObjectPageSized) {
ConservativelyCollectGarbage();
}
template <typename T, wtf_size_t inlineCapacity, typename U>
bool DequeContains(HeapDeque<T, inlineCapacity>& deque, U u) {
typedef typename HeapDeque<T, inlineCapacity>::iterator iterator;
template <typename T, typename U>
bool DequeContains(HeapDeque<T>& deque, U u) {
typedef typename HeapDeque<T>::iterator iterator;
for (iterator it = deque.begin(); it != deque.end(); ++it) {
if (*it == u)
return true;
......@@ -2428,12 +2428,12 @@ TEST_F(HeapTest, HeapCollectionTypes) {
typedef HeapHashCountedSet<Member<IntWrapper>> MemberCountedSet;
typedef HeapVector<Member<IntWrapper>, 2> MemberVector;
typedef HeapDeque<Member<IntWrapper>, 0> MemberDeque;
typedef HeapDeque<Member<IntWrapper>> MemberDeque;
typedef HeapVector<PairWrappedUnwrapped, 2> VectorWU;
typedef HeapVector<PairUnwrappedWrapped, 2> VectorUW;
typedef HeapDeque<PairWrappedUnwrapped, 0> DequeWU;
typedef HeapDeque<PairUnwrappedWrapped, 0> DequeUW;
typedef HeapDeque<PairWrappedUnwrapped> DequeWU;
typedef HeapDeque<PairUnwrappedWrapped> DequeUW;
Persistent<MemberMember> member_member = MakeGarbageCollected<MemberMember>();
Persistent<MemberMember> member_member2 =
......@@ -4085,8 +4085,8 @@ TEST_F(HeapTest, EmbeddedInDeque) {
ClearOutOldGarbage();
SimpleFinalizedObject::destructor_calls_ = 0;
{
Persistent<HeapDeque<VectorObject, 2>> inline_deque =
MakeGarbageCollected<HeapDeque<VectorObject, 2>>();
Persistent<HeapDeque<VectorObject>> inline_deque =
MakeGarbageCollected<HeapDeque<VectorObject>>();
Persistent<HeapDeque<VectorObject>> outline_deque =
MakeGarbageCollected<HeapDeque<VectorObject>>();
VectorObject i1, i2;
......
......@@ -154,7 +154,7 @@ template <typename T, typename U, typename V>
class HeapHashSet;
template <typename T, wtf_size_t inlineCapacity>
class HeapVector;
template <typename T, wtf_size_t inlineCapacity>
template <typename T>
class HeapDeque;
template <typename T, typename U, typename V>
class HeapHashCountedSet;
......@@ -174,9 +174,9 @@ struct ThreadingTrait<HeapVector<T, inlineCapacity>>
: public ThreadingTrait<Vector<T, inlineCapacity, HeapAllocator>> {
STATIC_ONLY(ThreadingTrait);
};
template <typename T, size_t inlineCapacity>
struct ThreadingTrait<HeapDeque<T, inlineCapacity>>
: public ThreadingTrait<Deque<T, inlineCapacity, HeapAllocator>> {
template <typename T>
struct ThreadingTrait<HeapDeque<T>>
: public ThreadingTrait<Deque<T, 0, HeapAllocator>> {
STATIC_ONLY(ThreadingTrait);
};
template <typename T, typename U, typename V>
......
......@@ -685,38 +685,13 @@ Deque<T, inlineCapacity, Allocator>::Trace(VisitorDispatcher visitor) {
}}))
return;
static_assert(inlineCapacity == 0,
"Heap allocated Deque should not use inline buffer");
static_assert(Allocator::kIsGarbageCollected,
"Garbage collector must be enabled.");
if (buffer_.HasOutOfLineBuffer()) {
DCHECK(buffer_.HasOutOfLineBuffer() || IsEmpty());
Allocator::TraceVectorBacking(visitor, buffer_.Buffer(),
buffer_.BufferSlot());
} else {
Allocator::TraceVectorBacking(visitor, static_cast<T*>(nullptr),
buffer_.BufferSlot());
const T* buffer_begin = buffer_.Buffer();
const T* end = buffer_begin + end_;
if (IsTraceableInCollectionTrait<VectorTraits<T>>::value) {
if (start_ <= end_) {
for (const T* buffer_entry = buffer_begin + start_; buffer_entry != end;
buffer_entry++) {
Allocator::template Trace<T, VectorTraits<T>>(
visitor, *const_cast<T*>(buffer_entry));
}
} else {
for (const T* buffer_entry = buffer_begin; buffer_entry != end;
buffer_entry++) {
Allocator::template Trace<T, VectorTraits<T>>(
visitor, *const_cast<T*>(buffer_entry));
}
const T* buffer_end = buffer_.Buffer() + buffer_.capacity();
for (const T* buffer_entry = buffer_begin + start_;
buffer_entry != buffer_end; buffer_entry++) {
Allocator::template Trace<T, VectorTraits<T>>(
visitor, *const_cast<T*>(buffer_entry));
}
}
}
}
}
template <typename T, wtf_size_t inlineCapacity, typename Allocator>
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment