Revert "cppgc: Integrate conservative stack scan into GC"
This reverts commit 44a1ed8f7f
.
Reason for revert: https://ci.chromium.org/p/v8/builders/ci/V8%20Linux%20gcc/6124?
Original change's description:
> cppgc: Integrate conservative stack scan into GC
>
> With this change we support allocation of objects and keeping them alive via
> conservative stack scan.
>
> Change-Id: Id94d7ced503ad0b1378643e0c13c2a8b65ad2327
> Bug: chromium:1056170
> Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2135729
> Reviewed-by: Omer Katz <omerkatz@chromium.org>
> Reviewed-by: Ulan Degenbaev <ulan@chromium.org>
> Reviewed-by: Anton Bikineev <bikineev@chromium.org>
> Commit-Queue: Michael Lippautz <mlippautz@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#67008}
TBR=ulan@chromium.org,hpayer@chromium.org,mlippautz@chromium.org,bikineev@chromium.org,omerkatz@chromium.org
Change-Id: I71bf7a9b7f54f0ec8d64b1b1781699adb0feb138
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Bug: chromium:1056170
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2137401
Reviewed-by: Nico Hartmann <nicohartmann@chromium.org>
Commit-Queue: Nico Hartmann <nicohartmann@chromium.org>
Cr-Commit-Position: refs/heads/master@{#67009}
This commit is contained in:
parent
44a1ed8f7f
commit
2b047a58f8
@ -6,9 +6,7 @@
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "src/base/platform/platform.h"
|
||||
#include "src/heap/cppgc/heap-object-header-inl.h"
|
||||
#include "src/heap/cppgc/stack.h"
|
||||
#include "src/heap/cppgc/heap-object-header.h"
|
||||
|
||||
namespace cppgc {
|
||||
|
||||
@ -18,54 +16,12 @@ std::unique_ptr<Heap> Heap::Create() {
|
||||
|
||||
namespace internal {
|
||||
|
||||
namespace {
|
||||
|
||||
constexpr bool NeedsConservativeStackScan(Heap::GCConfig config) {
|
||||
return config.stack_state == Heap::GCConfig::StackState::kNonEmpty;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
// TODO(chromium:1056170): Replace with fast stack scanning once
|
||||
// object are allocated actual arenas/spaces.
|
||||
class StackMarker final : public StackVisitor {
|
||||
public:
|
||||
explicit StackMarker(const std::vector<HeapObjectHeader*>& objects)
|
||||
: objects_(objects) {}
|
||||
|
||||
void VisitPointer(const void* address) final {
|
||||
for (auto* header : objects_) {
|
||||
if (address >= header->Payload() &&
|
||||
address < (header + header->GetSize())) {
|
||||
header->TryMarkAtomic();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
const std::vector<HeapObjectHeader*>& objects_;
|
||||
};
|
||||
|
||||
Heap::Heap()
|
||||
: stack_(std::make_unique<Stack>(v8::base::Stack::GetStackStart())) {}
|
||||
|
||||
void Heap::CollectGarbage(GCConfig config) {
|
||||
current_config_ = config;
|
||||
// TODO(chromium:1056170): Replace with proper mark-sweep algorithm.
|
||||
// "Marking".
|
||||
if (NeedsConservativeStackScan(current_config_)) {
|
||||
StackMarker marker(objects_);
|
||||
stack_->IteratePointers(&marker);
|
||||
}
|
||||
// "Sweeping and finalization".
|
||||
void Heap::CollectGarbage() {
|
||||
for (HeapObjectHeader* header : objects_) {
|
||||
if (header->IsMarked()) {
|
||||
header->Unmark();
|
||||
} else {
|
||||
header->Finalize();
|
||||
free(header);
|
||||
}
|
||||
header->Finalize();
|
||||
free(header);
|
||||
}
|
||||
objects_.clear();
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
|
@ -5,7 +5,6 @@
|
||||
#ifndef V8_HEAP_CPPGC_HEAP_H_
|
||||
#define V8_HEAP_CPPGC_HEAP_H_
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "include/cppgc/gc-info.h"
|
||||
@ -15,34 +14,18 @@
|
||||
namespace cppgc {
|
||||
namespace internal {
|
||||
|
||||
class Stack;
|
||||
|
||||
class V8_EXPORT_PRIVATE Heap final : public cppgc::Heap {
|
||||
public:
|
||||
struct GCConfig {
|
||||
enum class StackState : uint8_t {
|
||||
kEmpty,
|
||||
kNonEmpty,
|
||||
};
|
||||
|
||||
static GCConfig Default() { return {StackState::kNonEmpty}; }
|
||||
|
||||
StackState stack_state = StackState::kNonEmpty;
|
||||
};
|
||||
|
||||
static Heap* From(cppgc::Heap* heap) { return static_cast<Heap*>(heap); }
|
||||
|
||||
Heap();
|
||||
Heap() = default;
|
||||
~Heap() final = default;
|
||||
|
||||
inline void* Allocate(size_t size, GCInfoIndex index);
|
||||
|
||||
void CollectGarbage(GCConfig config = GCConfig::Default());
|
||||
void CollectGarbage();
|
||||
|
||||
private:
|
||||
GCConfig current_config_;
|
||||
|
||||
std::unique_ptr<Stack> stack_;
|
||||
std::vector<HeapObjectHeader*> objects_;
|
||||
};
|
||||
|
||||
|
@ -122,16 +122,14 @@ void IteratePointersImpl(const Stack* stack, StackVisitor* visitor,
|
||||
|
||||
} // namespace
|
||||
|
||||
void Stack::IteratePointers(StackVisitor* visitor) const {
|
||||
#ifdef CPPGC_SUPPORTS_CONSERVATIVE_STACK_SCAN
|
||||
void Stack::IteratePointers(StackVisitor* visitor) const {
|
||||
PushAllRegistersAndIterateStack(this, visitor, &IteratePointersImpl);
|
||||
// No need to deal with callee-saved registers as they will be kept alive by
|
||||
// the regular conservative stack iteration.
|
||||
IterateSafeStackIfNecessary(visitor);
|
||||
#else // !CPPGC_SUPPORTS_CONSERVATIVE_STACK_SCAN
|
||||
FATAL("Conservative stack scan not supported on current platform.");
|
||||
#endif // !CPPGC_SUPPORTS_CONSERVATIVE_STACK_SCAN
|
||||
}
|
||||
#endif // CPPGC_SUPPORTS_CONSERVATIVE_STACK_SCAN
|
||||
|
||||
} // namespace internal
|
||||
} // namespace cppgc
|
||||
|
@ -28,7 +28,9 @@ class V8_EXPORT_PRIVATE Stack final {
|
||||
|
||||
// Word-aligned iteration of the stack. Slot values are passed on to
|
||||
// |visitor|.
|
||||
#ifdef CPPGC_SUPPORTS_CONSERVATIVE_STACK_SCAN
|
||||
void IteratePointers(StackVisitor* visitor) const;
|
||||
#endif // CPPGC_SUPPORTS_CONSERVATIVE_STACK_SCAN
|
||||
|
||||
// Returns the start of the stack.
|
||||
const void* stack_start() const { return stack_start_; }
|
||||
|
@ -44,11 +44,11 @@ v8_source_set("cppgc_unittests_sources") {
|
||||
testonly = true
|
||||
|
||||
sources = [
|
||||
"heap/cppgc/allocation_unittest.cc",
|
||||
"heap/cppgc/finalizer-trait_unittest.cc",
|
||||
"heap/cppgc/garbage-collected_unittest.cc",
|
||||
"heap/cppgc/gc-info_unittest.cc",
|
||||
"heap/cppgc/heap-object-header_unittest.cc",
|
||||
"heap/cppgc/heap_unittest.cc",
|
||||
"heap/cppgc/member_unittests.cc",
|
||||
"heap/cppgc/source-location_unittest.cc",
|
||||
"heap/cppgc/stack_unittest.cc",
|
||||
|
42
test/unittests/heap/cppgc/allocation_unittest.cc
Normal file
42
test/unittests/heap/cppgc/allocation_unittest.cc
Normal file
@ -0,0 +1,42 @@
|
||||
// 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/allocation.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "src/heap/cppgc/heap.h"
|
||||
#include "test/unittests/heap/cppgc/tests.h"
|
||||
#include "testing/gtest/include/gtest/gtest.h"
|
||||
|
||||
namespace cppgc {
|
||||
|
||||
TEST(GCBasicHeapTest, CreateAndDestroyHeap) {
|
||||
std::unique_ptr<Heap> heap{Heap::Create()};
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
class Foo : public GarbageCollected<Foo> {
|
||||
public:
|
||||
static size_t destructor_callcount;
|
||||
|
||||
Foo() { destructor_callcount = 0; }
|
||||
~Foo() { destructor_callcount++; }
|
||||
};
|
||||
|
||||
size_t Foo::destructor_callcount;
|
||||
|
||||
class GCAllocationTest : public testing::TestWithHeap {};
|
||||
|
||||
} // namespace
|
||||
|
||||
TEST_F(GCAllocationTest, MakeGarbageCollectedAndReclaim) {
|
||||
MakeGarbageCollected<Foo>(GetHeap());
|
||||
EXPECT_EQ(0u, Foo::destructor_callcount);
|
||||
internal::Heap::From(GetHeap())->CollectGarbage();
|
||||
EXPECT_EQ(1u, Foo::destructor_callcount);
|
||||
}
|
||||
|
||||
} // namespace cppgc
|
@ -1,62 +0,0 @@
|
||||
// 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.
|
||||
|
||||
#ifdef CPPGC_SUPPORTS_CONSERVATIVE_STACK_SCAN
|
||||
|
||||
#include "src/heap/cppgc/heap.h"
|
||||
#include "include/cppgc/allocation.h"
|
||||
#include "test/unittests/heap/cppgc/tests.h"
|
||||
#include "testing/gtest/include/gtest/gtest.h"
|
||||
|
||||
namespace cppgc {
|
||||
namespace internal {
|
||||
|
||||
namespace {
|
||||
|
||||
class GCHeapTest : public testing::TestWithHeap {
|
||||
public:
|
||||
void ConservativeGC() {
|
||||
internal::Heap::From(GetHeap())->CollectGarbage(
|
||||
{Heap::GCConfig::StackState::kNonEmpty});
|
||||
}
|
||||
void PreciseGC() {
|
||||
internal::Heap::From(GetHeap())->CollectGarbage(
|
||||
{Heap::GCConfig::StackState::kEmpty});
|
||||
}
|
||||
};
|
||||
|
||||
class Foo : public GarbageCollected<Foo> {
|
||||
public:
|
||||
static size_t destructor_callcount;
|
||||
|
||||
Foo() { destructor_callcount = 0; }
|
||||
~Foo() { destructor_callcount++; }
|
||||
};
|
||||
|
||||
size_t Foo::destructor_callcount;
|
||||
|
||||
} // namespace
|
||||
|
||||
TEST_F(GCHeapTest, PreciseGCReclaimsObjectOnStack) {
|
||||
Foo* volatile do_not_acces = MakeGarbageCollected<Foo>(GetHeap());
|
||||
USE(do_not_acces);
|
||||
EXPECT_EQ(0u, Foo::destructor_callcount);
|
||||
PreciseGC();
|
||||
EXPECT_EQ(1u, Foo::destructor_callcount);
|
||||
}
|
||||
|
||||
TEST_F(GCHeapTest, ConservaitveGCRetainsObjectOnStack) {
|
||||
Foo* volatile do_not_acces = MakeGarbageCollected<Foo>(GetHeap());
|
||||
USE(do_not_acces);
|
||||
EXPECT_EQ(0u, Foo::destructor_callcount);
|
||||
ConservativeGC();
|
||||
EXPECT_EQ(0u, Foo::destructor_callcount);
|
||||
PreciseGC();
|
||||
EXPECT_EQ(1u, Foo::destructor_callcount);
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
} // namespace cppgc
|
||||
|
||||
#endif // CPPGC_SUPPORTS_CONSERVATIVE_STACK_SCAN
|
Loading…
Reference in New Issue
Block a user