Commit 3a50eae0 authored by Michael Lippautz's avatar Michael Lippautz Committed by Commit Bot

api: Add JSVisitor and JSMember reference

- Adds JSVisitor that is used for unified heap marking.
- Adds JSMember as supported reference type that also encapsulates a
  write barrier in future. JSMember is a replacement for
  TracedReference which can be deprecated with EmbedderHeapTracer once
  the library is used to handle unified heap collections.

The dispatch for v8::JSMember on cppgc::Visitor is provided through a
specialization of TraceTrait.

Bug: chromium:1056170
Change-Id: I60d976ae66db3e5fa2e690a21627bdcb8c6871af
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2284488Reviewed-by: 's avatarUlan Degenbaev <ulan@chromium.org>
Reviewed-by: 's avatarAnton Bikineev <bikineev@chromium.org>
Reviewed-by: 's avatarOmer Katz <omerkatz@chromium.org>
Commit-Queue: Michael Lippautz <mlippautz@chromium.org>
Cr-Commit-Position: refs/heads/master@{#68716}
parent bc793ae8
......@@ -1837,6 +1837,7 @@ v8_header_set("v8_headers") {
public_configs = [ ":v8_header_features" ]
sources = [
"include/v8-cppgc.h",
"include/v8-fast-api-calls.h",
"include/v8-internal.h",
"include/v8.h",
......@@ -2173,6 +2174,7 @@ v8_source_set("v8_base_without_compiler") {
### gcmole(all) ###
"$target_gen_dir/builtins-generated/bytecodes-builtins-list.h",
"include/cppgc/common.h",
"include/v8-cppgc.h",
"include/v8-fast-api-calls.h",
"include/v8-inspector-protocol.h",
"include/v8-inspector.h",
......
......@@ -2,4 +2,5 @@ include_rules = [
# v8-inspector-protocol.h depends on generated files under include/inspector.
"+inspector",
"+cppgc/common.h",
"+cppgc/visitor.h",
]
......@@ -21,6 +21,8 @@ template <typename T, typename WeaknessPolicy, typename LocationPolicy,
class BasicPersistent;
class ConservativeTracingVisitor;
class VisitorBase;
class VisitorFactory;
} // namespace internal
using WeakCallback = void (*)(const LivenessBroker&, const void*);
......@@ -44,6 +46,14 @@ using WeakCallback = void (*)(const LivenessBroker&, const void*);
*/
class Visitor {
public:
class Key {
private:
Key() = default;
friend class internal::VisitorFactory;
};
explicit Visitor(Key) {}
virtual ~Visitor() = default;
/**
......@@ -147,8 +157,6 @@ class Visitor {
}
}
Visitor() = default;
template <typename Persistent,
std::enable_if_t<Persistent::IsStrongPersistent::value>* = nullptr>
void TraceRoot(const Persistent& p, const SourceLocation& loc) {
......@@ -193,11 +201,11 @@ class Visitor {
V8_EXPORT void CheckObjectNotInConstruction(const void* address);
#endif // V8_ENABLE_CHECKS
friend class internal::VisitorBase;
template <typename T, typename WeaknessPolicy, typename LocationPolicy,
typename CheckingPolicy>
friend class internal::BasicPersistent;
friend class internal::ConservativeTracingVisitor;
friend class internal::VisitorBase;
};
} // namespace cppgc
......
// 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_V8_CPPGC_H_
#define INCLUDE_V8_CPPGC_H_
#include "cppgc/visitor.h"
#include "v8.h" // NOLINT(build/include_directory)
namespace v8 {
template <typename T>
class JSMember;
namespace internal {
// TODO(chromium:1056170): Provide implementation based on global handles.
class JSMemberBase {
private:
JSMemberBase() = default;
template <typename T>
friend class v8::JSMember;
};
} // namespace internal
/**
* A traced handle without destructor that clears the handle. The handle may
* only be used in GarbageCollected objects and must be processed in a Trace()
* method.
*
* TODO(chromium:1056170): Implementation.
*/
template <typename T>
class JSMember : public internal::JSMemberBase {
static_assert(std::is_base_of<v8::Value, T>::value,
"JSMember only supports references to v8::Value");
public:
JSMember() = default;
// Heterogeneous construction.
template <typename U,
typename = std::enable_if_t<std::is_base_of<T, U>::value>>
JSMember(const JSMember<U>& other) {} // NOLINT
};
class JSVisitor : public cppgc::Visitor {
public:
explicit JSVisitor(cppgc::Visitor::Key key) : cppgc::Visitor(key) {}
template <typename T>
void Trace(const JSMember<T>& ref) {
Visit(ref);
}
protected:
using cppgc::Visitor::Visit;
virtual void Visit(const internal::JSMemberBase& ref) {}
};
} // namespace v8
namespace cppgc {
template <typename T>
struct TraceTrait<v8::JSMember<T>> {
static void Trace(Visitor* visitor, const v8::JSMember<T>* self) {
static_cast<v8::JSVisitor*>(visitor)->Trace(*self);
}
};
} // namespace cppgc
#endif // INCLUDE_V8_CPPGC_H_
......@@ -16,11 +16,16 @@ class HeapBase;
class HeapObjectHeader;
class PageBackend;
class VisitorFactory {
public:
static constexpr Visitor::Key CreateKey() { return {}; }
};
// Base visitor that is allowed to create a public cppgc::Visitor object and
// use its internals.
class VisitorBase : public cppgc::Visitor {
public:
VisitorBase() = default;
VisitorBase() : cppgc::Visitor(VisitorFactory::CreateKey()) {}
~VisitorBase() override = default;
VisitorBase(const VisitorBase&) = delete;
......
......@@ -241,6 +241,7 @@ v8_source_set("unittests_sources") {
"heap/heap-unittest.cc",
"heap/heap-utils.h",
"heap/item-parallel-job-unittest.cc",
"heap/js-visitor-unittest.cc",
"heap/list-unittest.cc",
"heap/local-heap-unittest.cc",
"heap/marking-unittest.cc",
......
// 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.
#include "include/cppgc/type-traits.h"
#include "include/v8-cppgc.h"
#include "include/v8.h"
#include "src/heap/cppgc/visitor.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace v8 {
namespace internal {
namespace {
class TestingVisitor : public JSVisitor {
public:
TestingVisitor() : JSVisitor(cppgc::internal::VisitorFactory::CreateKey()) {}
size_t found() const { return found_; }
void ExpectReference(const void* expected) { expected_ = expected; }
cppgc::Visitor& AsBaseVisitor() { return *this; }
protected:
void Visit(const JSMemberBase& ref) final {
if (&ref == expected_) {
found_++;
}
}
private:
size_t found_ = 0;
const void* expected_ = nullptr;
};
} // namespace
TEST(JSVisitorTest, DispatchJSMember) {
TestingVisitor visitor;
JSMember<v8::Value> js_value;
visitor.ExpectReference(&js_value);
visitor.AsBaseVisitor().Trace(js_value);
EXPECT_EQ(1u, visitor.found());
JSMember<v8::Function> js_function;
visitor.ExpectReference(&js_function);
visitor.AsBaseVisitor().Trace(js_function);
EXPECT_EQ(2u, visitor.found());
}
} // namespace internal
} // namespace v8
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