Commit 4a19c62f authored by Zhi An Ng's avatar Zhi An Ng Committed by V8 LUCI CQ

Revert "cppgc: Implement basic Member and Persistent checks"

This reverts commit 7458e67c.

Reason for revert: Crash on windows https://ci.chromium.org/ui/p/v8/builders/ci/V8%20Win64%20-%20debug/37698/overview

Original change's description:
> cppgc: Implement basic Member and Persistent checks
>
> Adds check for
> - same heap on assignment
> - header and containment
>
> The verification state is eagerly created for on-heap Member
> references using caged heap and lazily created on first assignment for
> all others.
>
> Bug: chromium:1056170
> Change-Id: I38ee18eeb7ac489f69a46670cc5e5abe07f62dfa
> Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2878745
> Reviewed-by: Omer Katz <omerkatz@chromium.org>
> Commit-Queue: Michael Lippautz <mlippautz@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#74449}

Bug: chromium:1056170
Change-Id: I466522a7d879560c99dabbd96c3b097894743a87
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2880149
Auto-Submit: Zhi An Ng <zhin@chromium.org>
Commit-Queue: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
Cr-Commit-Position: refs/heads/master@{#74450}
parent 7458e67c
...@@ -139,7 +139,7 @@ class BasicCrossThreadPersistent final : public PersistentBase, ...@@ -139,7 +139,7 @@ class BasicCrossThreadPersistent final : public PersistentBase,
GetNode()->UpdateOwner(this); GetNode()->UpdateOwner(this);
other.SetValue(nullptr); other.SetValue(nullptr);
other.SetNode(nullptr); other.SetNode(nullptr);
this->CheckPointer(Get()); this->CheckPointer(GetValue());
return *this; return *this;
} }
......
...@@ -9,9 +9,7 @@ ...@@ -9,9 +9,7 @@
#include <type_traits> #include <type_traits>
#include "cppgc/internal/write-barrier.h" #include "cppgc/internal/write-barrier.h"
#include "cppgc/sentinel-pointer.h"
#include "cppgc/source-location.h" #include "cppgc/source-location.h"
#include "cppgc/type-traits.h"
#include "v8config.h" // NOLINT(build/include_directory) #include "v8config.h" // NOLINT(build/include_directory)
namespace cppgc { namespace cppgc {
...@@ -50,57 +48,24 @@ struct NoWriteBarrierPolicy { ...@@ -50,57 +48,24 @@ struct NoWriteBarrierPolicy {
static void AssigningBarrier(const void*, const void*) {} static void AssigningBarrier(const void*, const void*) {}
}; };
class V8_EXPORT EnabledCheckingPolicyBase { class V8_EXPORT EnabledCheckingPolicy {
protected: protected:
EnabledCheckingPolicyBase() = default; EnabledCheckingPolicy();
explicit EnabledCheckingPolicyBase(void* state) : state_(state) {} void CheckPointer(const void* ptr);
template <typename T>
void CheckPointer(const T* ptr) {
if (!ptr || (kSentinelPointer == ptr)) return;
CheckPointersImplTrampoline<T>::Call(this, ptr);
}
private: private:
void CheckPointerImpl(const void* ptr, bool points_to_payload); void* impl_;
template <typename T, bool = IsCompleteV<T>>
struct CheckPointersImplTrampoline {
static void Call(EnabledCheckingPolicyBase* policy, const T* ptr) {
policy->CheckPointerImpl(ptr, false);
}
};
template <typename T>
struct CheckPointersImplTrampoline<T, true> {
static void Call(EnabledCheckingPolicyBase* policy, const T* ptr) {
policy->CheckPointerImpl(ptr, IsGarbageCollectedTypeV<T>);
}
};
void* state_ = nullptr;
};
class V8_EXPORT EnabledMemberCheckingPolicy : public EnabledCheckingPolicyBase {
protected:
EnabledMemberCheckingPolicy();
}; };
class V8_EXPORT EnabledPersistentCheckingPolicy
: public EnabledCheckingPolicyBase {};
class DisabledCheckingPolicy { class DisabledCheckingPolicy {
protected: protected:
void CheckPointer(const void* raw) {} void CheckPointer(const void* raw) {}
}; };
#if V8_ENABLE_CHECKS #if V8_ENABLE_CHECKS
using DefaultMemberCheckingPolicy = EnabledMemberCheckingPolicy; using DefaultCheckingPolicy = EnabledCheckingPolicy;
using DefaultPersistentCheckingPolicy = EnabledPersistentCheckingPolicy;
#else #else
using DefaultMemberCheckingPolicy = DisabledCheckingPolicy; using DefaultCheckingPolicy = DisabledCheckingPolicy;
using DefaultPersistentCheckingPolicy = DisabledCheckingPolicy;
#endif #endif
class KeepLocationPolicy { class KeepLocationPolicy {
...@@ -168,10 +133,10 @@ template <typename T, typename WeaknessPolicy, ...@@ -168,10 +133,10 @@ template <typename T, typename WeaknessPolicy,
class BasicCrossThreadPersistent; class BasicCrossThreadPersistent;
template <typename T, typename WeaknessPolicy, template <typename T, typename WeaknessPolicy,
typename LocationPolicy = DefaultLocationPolicy, typename LocationPolicy = DefaultLocationPolicy,
typename CheckingPolicy = DefaultPersistentCheckingPolicy> typename CheckingPolicy = DefaultCheckingPolicy>
class BasicPersistent; class BasicPersistent;
template <typename T, typename WeaknessTag, typename WriteBarrierPolicy, template <typename T, typename WeaknessTag, typename WriteBarrierPolicy,
typename CheckingPolicy = DefaultMemberCheckingPolicy> typename CheckingPolicy = DefaultCheckingPolicy>
class BasicMember; class BasicMember;
} // namespace internal } // namespace internal
......
...@@ -7,7 +7,6 @@ ...@@ -7,7 +7,6 @@
// This file should stay with minimal dependencies to allow embedder to check // This file should stay with minimal dependencies to allow embedder to check
// against Oilpan types without including any other parts. // against Oilpan types without including any other parts.
#include <cstddef>
#include <type_traits> #include <type_traits>
namespace cppgc { namespace cppgc {
...@@ -165,18 +164,6 @@ struct IsUntracedMemberType : std::false_type {}; ...@@ -165,18 +164,6 @@ struct IsUntracedMemberType : std::false_type {};
template <typename T> template <typename T>
struct IsUntracedMemberType<T, true> : std::true_type {}; struct IsUntracedMemberType<T, true> : std::true_type {};
template <typename T>
struct IsComplete {
private:
template <typename U, size_t = sizeof(U)>
static std::true_type IsSizeOfKnown(U*);
static std::false_type IsSizeOfKnown(...);
public:
static constexpr bool value =
decltype(IsSizeOfKnown(std::declval<T*>()))::value;
};
} // namespace internal } // namespace internal
/** /**
...@@ -236,12 +223,6 @@ constexpr bool IsWeakMemberTypeV = internal::IsWeakMemberType<T>::value; ...@@ -236,12 +223,6 @@ constexpr bool IsWeakMemberTypeV = internal::IsWeakMemberType<T>::value;
template <typename T> template <typename T>
constexpr bool IsWeakV = internal::IsWeak<T>::value; constexpr bool IsWeakV = internal::IsWeak<T>::value;
/**
* Value is true for types that are complete, and false otherwise.
*/
template <typename T>
constexpr bool IsCompleteV = internal::IsComplete<T>::value;
} // namespace cppgc } // namespace cppgc
#endif // INCLUDE_CPPGC_TYPE_TRAITS_H_ #endif // INCLUDE_CPPGC_TYPE_TRAITS_H_
...@@ -4,85 +4,21 @@ ...@@ -4,85 +4,21 @@
#include "include/cppgc/internal/pointer-policies.h" #include "include/cppgc/internal/pointer-policies.h"
#include "include/cppgc/internal/caged-heap-local-data.h"
#include "include/cppgc/internal/persistent-node.h" #include "include/cppgc/internal/persistent-node.h"
#include "src/base/logging.h"
#include "src/base/macros.h" #include "src/base/macros.h"
#include "src/base/platform/platform.h"
#include "src/heap/cppgc/heap-object-header.h"
#include "src/heap/cppgc/heap-page.h" #include "src/heap/cppgc/heap-page.h"
#include "src/heap/cppgc/heap.h" #include "src/heap/cppgc/heap.h"
namespace cppgc { namespace cppgc {
namespace internal { namespace internal {
namespace { EnabledCheckingPolicy::EnabledCheckingPolicy() {
USE(impl_);
// Gets the state (HeapBase) for on-heap slots. // TODO(chromium:1056170): Save creating heap state.
void* TryGetStateFromSlot(void* slot) {
#ifdef CPPGC_CAGED_HEAP
if (v8::base::Stack::GetCurrentStackPosition() <= slot &&
slot < v8::base::Stack::GetStackStart())
return nullptr;
// `slot` may reside in a regular or large object. Get to the heap using the
// cage.
return reinterpret_cast<CagedHeapLocalData*>(
reinterpret_cast<uintptr_t>(slot) &
~(api_constants::kCagedHeapReservationAlignment - 1))
->heap_base;
#else // !CPPGC_CAGED_HEAP
return nullptr;
#endif // !CPPGC_CAGED_HEAP
} }
} // namespace void EnabledCheckingPolicy::CheckPointer(const void* ptr) {
// TODO(chromium:1056170): Provide implementation.
// We know that Member is only allowed on heap and on-stack in rare cases. Use
// this information to eagerly populate a verification state already on policy
// creation.
EnabledMemberCheckingPolicy::EnabledMemberCheckingPolicy()
: EnabledCheckingPolicyBase(TryGetStateFromSlot(this)) {}
void EnabledCheckingPolicyBase::CheckPointerImpl(const void* ptr,
bool points_to_payload) {
auto* base_page = BasePage::FromPayload(ptr);
// Large objects do not support mixins. This also means that `base_page` is
// valid for large objects.
DCHECK_IMPLIES(base_page->is_large(), points_to_payload);
if (!state_) {
state_ = base_page->heap();
// Member references are used from within objects that cannot change their
// heap association which means that state is immutable once it is set.
//
// TODO(chromium:1056170): Binding state late allows for getting the initial
// state wrong which requires a check that `this` is contained in heap that
// is itself expensive. Investigate options on non-caged builds to improve
// coverage.
}
HeapBase* heap = static_cast<HeapBase*>(state_);
if (!heap) return;
// Member references should never mix heaps.
DCHECK_EQ(heap, base_page->heap());
// Header checks.
const HeapObjectHeader* header = nullptr;
if (points_to_payload) {
header = &HeapObjectHeader::FromPayload(ptr);
} else if (!heap->sweeper().IsSweepingInProgress()) {
// Mixin case.
header = &base_page->ObjectHeaderFromInnerAddress(ptr);
DCHECK_LE(header->Payload(), ptr);
DCHECK_GT(header->PayloadEnd(), ptr);
}
if (header) {
DCHECK(!header->IsFree());
}
// TODO(v8:11749): Check mark bits when during pre-finalizer phase.
} }
PersistentRegion& StrongPersistentPolicy::GetPersistentRegion( PersistentRegion& StrongPersistentPolicy::GetPersistentRegion(
......
...@@ -84,17 +84,6 @@ TEST(GarbageCollectedTest, GarbageCollectedWithMixinTrait) { ...@@ -84,17 +84,6 @@ TEST(GarbageCollectedTest, GarbageCollectedWithMixinTrait) {
STATIC_ASSERT(IsGarbageCollectedWithMixinTypeV<GCWithMergedMixins>); STATIC_ASSERT(IsGarbageCollectedWithMixinTypeV<GCWithMergedMixins>);
} }
namespace {
class ForwardDeclaredType;
} // namespace
TEST(GarbageCollectedTest, CompleteTypeTrait) {
STATIC_ASSERT(IsCompleteV<GCed>);
STATIC_ASSERT(!IsCompleteV<ForwardDeclaredType>);
}
TEST_F(GarbageCollectedTestWithHeap, GetObjectStartReturnsCurrentAddress) { TEST_F(GarbageCollectedTestWithHeap, GetObjectStartReturnsCurrentAddress) {
GCed* gced = MakeGarbageCollected<GCed>(GetAllocationHandle()); GCed* gced = MakeGarbageCollected<GCed>(GetAllocationHandle());
GCedWithMixin* gced_with_mixin = GCedWithMixin* gced_with_mixin =
......
...@@ -506,51 +506,5 @@ TEST_F(MemberHeapTest, ConstWeakRefIsClearedOnGC) { ...@@ -506,51 +506,5 @@ TEST_F(MemberHeapTest, ConstWeakRefIsClearedOnGC) {
EXPECT_FALSE(persistent->weak_member()); EXPECT_FALSE(persistent->weak_member());
} }
#if V8_ENABLE_CHECKS
namespace {
class MemberHeapDeathTest : public testing::TestWithHeap {};
class LinkedNode final : public GarbageCollected<LinkedNode> {
public:
explicit LinkedNode(LinkedNode* next) : next_(next) {}
void Trace(Visitor* v) const { v->Trace(next_); }
void SetNext(LinkedNode* next) { next_ = next; }
private:
Member<LinkedNode> next_;
};
} // namespace
TEST_F(MemberHeapDeathTest, AssignDifferentHeapValues) {
auto* o1 = MakeGarbageCollected<LinkedNode>(GetAllocationHandle(), nullptr);
auto* o2 = MakeGarbageCollected<LinkedNode>(GetAllocationHandle(), o1);
{
auto tmp_heap = cppgc::Heap::Create(platform_);
auto* o3 = MakeGarbageCollected<LinkedNode>(tmp_heap->GetAllocationHandle(),
nullptr);
EXPECT_DEATH_IF_SUPPORTED(o2->SetNext(o3), "");
}
}
#ifdef CPPGC_CAGED_HEAP
TEST_F(MemberHeapDeathTest, VerificationStateDoesNotRequireValue) {
// For caged heap setups the verification state is constructed from Member
// itself and does not require an initial value.
auto* o1 = MakeGarbageCollected<LinkedNode>(GetAllocationHandle(), nullptr);
{
auto tmp_heap = cppgc::Heap::Create(platform_);
EXPECT_DEATH_IF_SUPPORTED(
MakeGarbageCollected<LinkedNode>(tmp_heap->GetAllocationHandle(), o1),
"");
}
}
#endif // CPPGC_CAGED_HEAP
#endif // V8_ENABLE_CHECKS
} // namespace internal } // namespace internal
} // namespace cppgc } // namespace cppgc
...@@ -74,12 +74,12 @@ template <typename T> ...@@ -74,12 +74,12 @@ template <typename T>
using LocalizedPersistent = using LocalizedPersistent =
internal::BasicPersistent<T, internal::StrongPersistentPolicy, internal::BasicPersistent<T, internal::StrongPersistentPolicy,
internal::KeepLocationPolicy, internal::KeepLocationPolicy,
internal::DefaultPersistentCheckingPolicy>; internal::DefaultCheckingPolicy>;
template <typename T> template <typename T>
using LocalizedCrossThreadPersistent = internal::BasicCrossThreadPersistent< using LocalizedCrossThreadPersistent = internal::BasicCrossThreadPersistent<
T, internal::StrongCrossThreadPersistentPolicy, T, internal::StrongCrossThreadPersistentPolicy,
internal::KeepLocationPolicy, internal::DisabledCheckingPolicy>; internal::KeepLocationPolicy, internal::DefaultCheckingPolicy>;
class RootVisitor final : public VisitorBase { class RootVisitor final : public VisitorBase {
public: public:
......
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