v8/include/cppgc/allocation.h
Michael Lippautz 872e315b34 cppgc: Add allocation support for managed types
This CL adds basic infrastructure for:
- MakeGarbageCollected
- GarbageCollected and related type traits
- Heap (API / internal)
- Basic allocation based on malloc
- CollectGarbage without marking

This allows for allocation and reclamation through an explicit GC
call. No objects are held alive from any source (stack, globals,
refs), yet.

The exact wiring of platform is future work.

Change-Id: I81b7c0ba7b525188f8c0bf9de3b7af35d34322af
Bug: chromium:1056170
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2120538
Commit-Queue: Michael Lippautz <mlippautz@chromium.org>
Reviewed-by: Hannes Payer <hpayer@chromium.org>
Reviewed-by: Ulan Degenbaev <ulan@chromium.org>
Reviewed-by: Omer Katz <omerkatz@chromium.org>
Cr-Commit-Position: refs/heads/master@{#66887}
2020-03-27 10:47:07 +00:00

92 lines
3.2 KiB
C++

// Copyright 2020 the V8 project 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 INCLUDE_CPPGC_ALLOCATION_H_
#define INCLUDE_CPPGC_ALLOCATION_H_
#include <stdint.h>
#include <atomic>
#include "include/cppgc/garbage-collected.h"
#include "include/cppgc/gc-info.h"
#include "include/cppgc/heap.h"
#include "include/cppgc/internals.h"
namespace cppgc {
template <typename T>
class MakeGarbageCollectedTraitBase;
namespace internal {
class V8_EXPORT MakeGarbageCollectedTraitInternal {
protected:
static inline void MarkObjectAsFullyConstructed(const void* payload) {
// See api_constants for an explanation of the constants.
std::atomic<uint16_t>* atomic_mutable_bitfield =
reinterpret_cast<std::atomic<uint16_t>*>(
const_cast<uint16_t*>(reinterpret_cast<const uint16_t*>(
reinterpret_cast<const uint8_t*>(payload) -
api_constants::kFullyConstructedBitFieldOffsetFromPayload)));
uint16_t value = atomic_mutable_bitfield->load(std::memory_order_relaxed);
value = value | api_constants::kFullyConstructedBitMask;
atomic_mutable_bitfield->store(value, std::memory_order_release);
}
static void* Allocate(cppgc::Heap* heap, size_t size, GCInfoIndex index);
friend class HeapObjectHeader;
};
} // namespace internal
// Users with custom allocation needs (e.g. overriding size) should override
// MakeGarbageCollectedTrait (see below) and inherit their trait from
// MakeGarbageCollectedTraitBase to get access to low-level primitives.
template <typename T>
class MakeGarbageCollectedTraitBase
: private internal::MakeGarbageCollectedTraitInternal {
protected:
// Allocates an object of |size| bytes on |heap|.
//
// TODO(mlippautz): Allow specifying arena for specific embedder uses.
static void* Allocate(Heap* heap, size_t size) {
return internal::MakeGarbageCollectedTraitInternal::Allocate(
heap, size, internal::GCInfoTrait<T>::Index());
}
// Marks an object as being fully constructed, resulting in precise handling
// by the garbage collector.
static void MarkObjectAsFullyConstructed(const void* payload) {
// internal::MarkObjectAsFullyConstructed(payload);
internal::MakeGarbageCollectedTraitInternal::MarkObjectAsFullyConstructed(
payload);
}
};
template <typename T>
class MakeGarbageCollectedTrait : public MakeGarbageCollectedTraitBase<T> {
public:
template <typename... Args>
static T* Call(Heap* heap, Args&&... args) {
static_assert(internal::IsGarbageCollectedType<T>::value,
"T needs to be a garbage collected object");
void* memory = MakeGarbageCollectedTraitBase<T>::Allocate(heap, sizeof(T));
T* object = ::new (memory) T(std::forward<Args>(args)...);
MakeGarbageCollectedTraitBase<T>::MarkObjectAsFullyConstructed(object);
return object;
}
};
// Default MakeGarbageCollected: Constructs an instance of T, which is a garbage
// collected type.
template <typename T, typename... Args>
T* MakeGarbageCollected(Heap* heap, Args&&... args) {
return MakeGarbageCollectedTrait<T>::Call(heap, std::forward<Args>(args)...);
}
} // namespace cppgc
#endif // INCLUDE_CPPGC_ALLOCATION_H_