Skip to content

Commit

Permalink
lib
Browse files Browse the repository at this point in the history
  • Loading branch information
Farhan committed Mar 14, 2021
1 parent 94a0e87 commit d283e99
Show file tree
Hide file tree
Showing 41 changed files with 18,465 additions and 1 deletion.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,5 @@ v8/build/.gclient_entries

bazel-*

*.a
*.a
*.DS_Store
3 changes: 3 additions & 0 deletions dev_notes
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Symlink the compiled libraries and includes
ln -s $(pwd)/libv8-darwin/include $GOPATH/src/github.com/Terfender/go-jsv8/include
ln -s $(pwd)/libv8-darwin/libv8 $GOPATH/src/github.com/Terfender/go-jsv8/libv8
124 changes: 124 additions & 0 deletions include/cppgc/allocation.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
// 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 "cppgc/garbage-collected.h"
#include "cppgc/heap.h"
#include "cppgc/internal/api-constants.h"
#include "cppgc/internal/gc-info.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

/**
* Base trait that provides utilities for advancers users that have custom
* allocation needs (e.g., overriding size). It's expected that users override
* MakeGarbageCollectedTrait (see below) and inherit from
* MakeGarbageCollectedTraitBase and make use of the low-level primitives
* offered to allocate and construct an object.
*/
template <typename T>
class MakeGarbageCollectedTraitBase
: private internal::MakeGarbageCollectedTraitInternal {
protected:
/**
* Allocates memory for an object of type T.
*
* \param heap The heap to allocate this object on.
* \param size The size that should be reserved for the object.
* \returns the memory to construct an object of type T on.
*/
static void* Allocate(Heap* heap, size_t size) {
// TODO(chromium:1056170): Allow specifying arena for specific embedder
// uses.
return internal::MakeGarbageCollectedTraitInternal::Allocate(
heap, size, internal::GCInfoTrait<T>::Index());
}

/**
* Marks an object as fully constructed, resulting in precise handling by the
* garbage collector.
*
* \param payload The base pointer the object is allocated at.
*/
static void MarkObjectAsFullyConstructed(const void* payload) {
internal::MakeGarbageCollectedTraitInternal::MarkObjectAsFullyConstructed(
payload);
}
};

/**
* Default trait class that specifies how to construct an object of type T.
* Advanced users may override how an object is constructed using the utilities
* that are provided through MakeGarbageCollectedTraitBase.
*
* Any trait overriding construction must
* - allocate through MakeGarbageCollectedTraitBase<T>::Allocate;
* - mark the object as fully constructed using
* MakeGarbageCollectedTraitBase<T>::MarkObjectAsFullyConstructed;
*/
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");
static_assert(
!internal::IsGarbageCollectedMixinType<T>::value ||
sizeof(T) <= internal::api_constants::kLargeObjectSizeThreshold,
"GarbageCollectedMixin may not be a large object");
void* memory = MakeGarbageCollectedTraitBase<T>::Allocate(heap, sizeof(T));
T* object = ::new (memory) T(std::forward<Args>(args)...);
MakeGarbageCollectedTraitBase<T>::MarkObjectAsFullyConstructed(object);
return object;
}
};

/**
* Constructs a managed object of type T where T transitively inherits from
* GarbageCollected.
*
* \param args List of arguments with which an instance of T will be
* constructed.
* \returns an instance of type T.
*/
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_
192 changes: 192 additions & 0 deletions include/cppgc/garbage-collected.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,192 @@
// 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_GARBAGE_COLLECTED_H_
#define INCLUDE_CPPGC_GARBAGE_COLLECTED_H_

#include <type_traits>

#include "cppgc/internal/api-constants.h"
#include "cppgc/macros.h"
#include "cppgc/platform.h"
#include "cppgc/trace-trait.h"
#include "cppgc/type-traits.h"

namespace cppgc {

class Visitor;

namespace internal {

class GarbageCollectedBase {
public:
// Must use MakeGarbageCollected.
void* operator new(size_t) = delete;
void* operator new[](size_t) = delete;
// The garbage collector is taking care of reclaiming the object. Also,
// virtual destructor requires an unambiguous, accessible 'operator delete'.
void operator delete(void*) {
#ifdef V8_ENABLE_CHECKS
internal::Abort();
#endif // V8_ENABLE_CHECKS
}
void operator delete[](void*) = delete;

protected:
GarbageCollectedBase() = default;
};

} // namespace internal

/**
* Base class for managed objects. Only descendent types of GarbageCollected
* can be constructed using MakeGarbageCollected. Must be inherited from as
* left-most base class.
*
* Types inheriting from GarbageCollected must provide a method of
* signature `void Trace(cppgc::Visitor*) const` that dispatchs all managed
* pointers to the visitor and delegates to garbage-collected base classes.
* The method must be virtual if the type is not directly a child of
* GarbageCollected and marked as final.
*
* \code
* // Example using final class.
* class FinalType final : public GarbageCollected<FinalType> {
* public:
* void Trace(cppgc::Visitor* visitor) const {
* // Dispatch using visitor->Trace(...);
* }
* };
*
* // Example using non-final base class.
* class NonFinalBase : public GarbageCollected<NonFinalBase> {
* public:
* virtual void Trace(cppgc::Visitor*) const {}
* };
*
* class FinalChild final : public NonFinalBase {
* public:
* void Trace(cppgc::Visitor* visitor) const final {
* // Dispatch using visitor->Trace(...);
* NonFinalBase::Trace(visitor);
* }
* };
* \endcode
*/
template <typename>
class GarbageCollected : public internal::GarbageCollectedBase {
public:
using IsGarbageCollectedTypeMarker = void;

protected:
GarbageCollected() = default;
};

/**
* Base class for managed mixin objects. Such objects cannot be constructed
* directly but must be mixed into the inheritance hierarchy of a
* GarbageCollected object.
*
* Types inheriting from GarbageCollectedMixin must override a virtual method
* of signature `void Trace(cppgc::Visitor*) const` that dispatchs all managed
* pointers to the visitor and delegates to base classes.
*
* \code
* class Mixin : public GarbageCollectedMixin {
* public:
* void Trace(cppgc::Visitor* visitor) const override {
* // Dispatch using visitor->Trace(...);
* }
* };
* \endcode
*/
class GarbageCollectedMixin : public internal::GarbageCollectedBase {
public:
using IsGarbageCollectedMixinTypeMarker = void;

// Sentinel used to mark not-fully-constructed mixins.
static constexpr void* kNotFullyConstructedObject = nullptr;

// Provide default implementation that indicate that the vtable is not yet
// set up properly. This is used to to get GCInfo objects for mixins so that
// these objects can be processed later on.
virtual TraceDescriptor GetTraceDescriptor() const {
return {kNotFullyConstructedObject, nullptr};
}

/**
* This Trace method must be overriden by objects inheriting from
* GarbageCollectedMixin.
*/
virtual void Trace(cppgc::Visitor*) const {}
};

/**
* Macro defines all methods and markers needed for handling mixins. Must be
* used on the type that is inheriting from GarbageCollected *and*
* GarbageCollectedMixin.
*
* \code
* class Mixin : public GarbageCollectedMixin {
* public:
* void Trace(cppgc::Visitor* visitor) const override {
* // Dispatch using visitor->Trace(...);
* }
* };
*
* class Foo : public GarbageCollected<Foo>, public Mixin {
* USING_GARBAGE_COLLECTED_MIXIN();
* public:
* void Trace(cppgc::Visitor* visitor) const override {
* // Dispatch using visitor->Trace(...);
* Mixin::Trace(visitor);
* }
* };
* \endcode
*/
#define USING_GARBAGE_COLLECTED_MIXIN() \
public: \
/* Marker is used by clang to check for proper usages of the macro. */ \
typedef int HasUsingGarbageCollectedMixinMacro; \
\
TraceDescriptor GetTraceDescriptor() const override { \
static_assert( \
internal::IsSubclassOfTemplate< \
std::remove_const_t<std::remove_pointer_t<decltype(this)>>, \
cppgc::GarbageCollected>::value, \
"Only garbage collected objects can have garbage collected mixins"); \
return {this, TraceTrait<std::remove_const_t< \
std::remove_pointer_t<decltype(this)>>>::Trace}; \
} \
\
private: \
friend class internal::__thisIsHereToForceASemicolonAfterThisMacro

/**
* Merge two or more Mixins into one.
*
* \code
* class A : public GarbageCollectedMixin {};
* class B : public GarbageCollectedMixin {};
* class C : public A, public B {
* MERGE_GARBAGE_COLLECTED_MIXINS();
* public:
* };
* \endcode
*/
#define MERGE_GARBAGE_COLLECTED_MIXINS() \
public: \
/* When using multiple mixins the methods become */ \
/* ambigous. Providing additional implementations */ \
/* disambiguate them again. */ \
TraceDescriptor GetTraceDescriptor() const override { \
return {kNotFullyConstructedObject, nullptr}; \
} \
\
private: \
friend class internal::__thisIsHereToForceASemicolonAfterThisMacro

} // namespace cppgc

#endif // INCLUDE_CPPGC_GARBAGE_COLLECTED_H_
50 changes: 50 additions & 0 deletions include/cppgc/heap.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
// 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_HEAP_H_
#define INCLUDE_CPPGC_HEAP_H_

#include <memory>

#include "v8config.h" // NOLINT(build/include_directory)

namespace cppgc {
namespace internal {
class Heap;
} // namespace internal

class V8_EXPORT Heap {
public:
// Normal spaces are used to store objects of different size classes:
// - kNormal1: < 32 bytes
// - kNormal2: < 64 bytes
// - kNormal3: < 128 bytes
// - kNormal4: >= 128 bytes
// Objects of size greater than 2^16 get stored in the large space. Users can
// register up to 4 arenas for application specific needs.
enum class SpaceType {
kNormal1,
kNormal2,
kNormal3,
kNormal4,
kLarge,
kUserDefined1,
kUserDefined2,
kUserDefined3,
kUserDefined4,
};

static std::unique_ptr<Heap> Create();

virtual ~Heap() = default;

private:
Heap() = default;

friend class internal::Heap;
};

} // namespace cppgc

#endif // INCLUDE_CPPGC_HEAP_H_
Loading

0 comments on commit d283e99

Please sign in to comment.