blob: 362dc4bdc2e5ecbf787972635f6b3875fb8c437c [file] [log] [blame]
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_HEAP_ALLOCATOR_IMPL_H_
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_HEAP_ALLOCATOR_IMPL_H_
#include "build/build_config.h"
#include "third_party/blink/renderer/platform/heap/collection_support/heap_hash_table_backing.h"
#include "third_party/blink/renderer/platform/heap/collection_support/heap_vector_backing.h"
#include "third_party/blink/renderer/platform/heap/impl/heap.h"
#include "third_party/blink/renderer/platform/heap/impl/marking_visitor.h"
#include "third_party/blink/renderer/platform/heap/impl/trace_traits.h"
#include "third_party/blink/renderer/platform/wtf/type_traits.h"
namespace blink {
// This is a static-only class used as a trait on collections to make them heap
// allocated.
class PLATFORM_EXPORT HeapAllocator {
STATIC_ONLY(HeapAllocator);
public:
using LivenessBroker = blink::LivenessBroker;
using Visitor = blink::Visitor;
static constexpr bool kIsGarbageCollected = true;
// See wtf/size_t.h for details.
static constexpr size_t kMaxHeapObjectSizeLog2 = 27;
static constexpr size_t kMaxHeapObjectSize = 1 << kMaxHeapObjectSizeLog2;
template <typename T>
static size_t MaxElementCountInBackingStore() {
return kMaxHeapObjectSize / sizeof(T);
}
template <typename T>
static size_t QuantizedSize(size_t count) {
CHECK_LE(count, MaxElementCountInBackingStore<T>());
// Oilpan's internal size is independent of MaxElementCountInBackingStore()
// and the required size to match capacity needs.
return count * sizeof(T);
}
template <typename T>
static T* AllocateVectorBacking(size_t size) {
return reinterpret_cast<T*>(
MakeGarbageCollected<HeapVectorBacking<T>>(size / sizeof(T)));
}
static void FreeVectorBacking(void*);
static bool ExpandVectorBacking(void*, size_t);
static bool ShrinkVectorBacking(void* address,
size_t quantized_current_size,
size_t quantized_shrunk_size);
template <typename T, typename HashTable>
static T* AllocateHashTableBacking(size_t size) {
static_assert(sizeof(T) == sizeof(typename HashTable::ValueType),
"T must match ValueType.");
return reinterpret_cast<T*>(
MakeGarbageCollected<HeapHashTableBacking<HashTable>>(size /
sizeof(T)));
}
template <typename T, typename HashTable>
static T* AllocateZeroedHashTableBacking(size_t size) {
return AllocateHashTableBacking<T, HashTable>(size);
}
static void FreeHashTableBacking(void* address);
static bool ExpandHashTableBacking(void*, size_t);
template <typename Traits>
static bool CanReuseHashTableDeletedBucket() {
if (Traits::kEmptyValueIsZero || !Traits::kCanTraceConcurrently)
return true;
return !ThreadState::Current()->IsMarkingInProgress();
}
static bool IsAllocationAllowed() {
return ThreadState::Current()->IsAllocationAllowed();
}
static bool IsIncrementalMarking() {
return ThreadState::IsAnyIncrementalMarking() &&
ThreadState::Current()->IsIncrementalMarking();
}
static void EnterGCForbiddenScope() {
ThreadState::Current()->EnterGCForbiddenScope();
}
static void LeaveGCForbiddenScope() {
ThreadState::Current()->LeaveGCForbiddenScope();
}
template <typename T, typename Traits>
static void Trace(Visitor* visitor, const T& t) {
TraceCollectionIfEnabled<WTF::WeakHandlingTrait<T>::value, T,
Traits>::Trace(visitor, &t);
}
template <typename T>
static void TraceVectorBacking(Visitor* visitor,
const T* backing,
const T* const* backing_slot) {
visitor->TraceMovablePointer(backing_slot);
visitor->Trace(reinterpret_cast<const HeapVectorBacking<T>*>(backing));
}
template <typename T, typename HashTable>
static void TraceHashTableBackingStrongly(Visitor* visitor,
const T* backing,
const T* const* backing_slot) {
visitor->TraceMovablePointer(backing_slot);
visitor->Trace(
reinterpret_cast<const HeapHashTableBacking<HashTable>*>(backing));
}
template <typename T, typename HashTable>
static void TraceHashTableBackingWeakly(Visitor* visitor,
const T* backing,
const T* const* backing_slot,
WeakCallback callback,
const void* parameter) {
visitor->TraceMovablePointer(backing_slot);
visitor->TraceWeakContainer(
reinterpret_cast<const HeapHashTableBacking<HashTable>*>(backing),
reinterpret_cast<const HeapHashTableBacking<HashTable>* const*>(
backing_slot),
TraceTrait<HeapHashTableBacking<HashTable>>::GetTraceDescriptor(
backing),
TraceTrait<HeapHashTableBacking<HashTable>>::GetWeakTraceDescriptor(
backing),
callback, parameter);
}
template <typename T>
static void BackingWriteBarrier(T** slot) {
MarkingVisitor::WriteBarrier(reinterpret_cast<void**>(slot));
}
template <typename T>
static void TraceBackingStoreIfMarked(T** slot) {
MarkingVisitor::RetraceObject(*slot);
}
template <typename T, typename Traits>
static void NotifyNewObject(T* object) {
MarkingVisitor::WriteBarrier(
[]() { return ThreadState::Current(); }, object, sizeof(T), 1,
TraceCollectionIfEnabled<WTF::kNoWeakHandling, T, Traits>::Trace);
}
template <typename T, typename Traits>
static void NotifyNewObjects(T* array, size_t len) {
MarkingVisitor::WriteBarrier(
[]() { return ThreadState::Current(); }, array, sizeof(T), len,
TraceCollectionIfEnabled<WTF::kNoWeakHandling, T, Traits>::Trace);
}
static bool DeferTraceToMutatorThreadIfConcurrent(Visitor* visitor,
const void* object,
TraceCallback callback,
size_t deferred_size) {
return visitor->DeferredTraceIfConcurrent({object, callback},
deferred_size);
}
private:
static void BackingFree(void*);
static bool BackingExpand(void*, size_t);
static bool BackingShrink(void*,
size_t quantized_current_size,
size_t quantized_shrunk_size);
};
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_HEAP_ALLOCATOR_IMPL_H_