cppgc-js: Report C++ memory to V8's heap growing
Add reporting of C++ memory to V8's heap growing strategy via existing EmbedderHeapTracer interface. In addition, introduce API-level NoGarbageCollectionScope which allows to temporarily avoid scheduling GC finalizations. Replace internal NoGCScope with NoGarbageCollectionScope and remove NoGCScope. Bug: chromium:1056170 Change-Id: I0ad3dfd67eb81f09f48e2ab87f9bbece7491ed71 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2650210 Commit-Queue: Michael Lippautz <mlippautz@chromium.org> Reviewed-by: Ulan Degenbaev <ulan@chromium.org> Reviewed-by: Omer Katz <omerkatz@chromium.org> Cr-Commit-Position: refs/heads/master@{#72345}
This commit is contained in:
parent
cb1a2c98e7
commit
a2cf158ad4
1
BUILD.gn
1
BUILD.gn
@ -4634,6 +4634,7 @@ v8_source_set("cppgc_base") {
|
|||||||
"src/heap/cppgc/gc-invoker.h",
|
"src/heap/cppgc/gc-invoker.h",
|
||||||
"src/heap/cppgc/heap-base.cc",
|
"src/heap/cppgc/heap-base.cc",
|
||||||
"src/heap/cppgc/heap-base.h",
|
"src/heap/cppgc/heap-base.h",
|
||||||
|
"src/heap/cppgc/heap-consistency.cc",
|
||||||
"src/heap/cppgc/heap-growing.cc",
|
"src/heap/cppgc/heap-growing.cc",
|
||||||
"src/heap/cppgc/heap-growing.h",
|
"src/heap/cppgc/heap-growing.h",
|
||||||
"src/heap/cppgc/heap-object-header.cc",
|
"src/heap/cppgc/heap-object-header.cc",
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
|
|
||||||
#include "cppgc/internal/write-barrier.h"
|
#include "cppgc/internal/write-barrier.h"
|
||||||
|
#include "cppgc/macros.h"
|
||||||
#include "cppgc/trace-trait.h"
|
#include "cppgc/trace-trait.h"
|
||||||
#include "v8config.h" // NOLINT(build/include_directory)
|
#include "v8config.h" // NOLINT(build/include_directory)
|
||||||
|
|
||||||
@ -131,6 +132,49 @@ class HeapConsistency final {
|
|||||||
HeapConsistency() = delete;
|
HeapConsistency() = delete;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Avoids invoking garbage collection finalizations. Already running garbage
|
||||||
|
* collection phase are unaffected by this scope.
|
||||||
|
*
|
||||||
|
* Should only be used temporarily as the scope has an impact on memory usage
|
||||||
|
* and follow up garbage collections.
|
||||||
|
*/
|
||||||
|
class V8_EXPORT V8_NODISCARD NoGarbageCollectionScope final {
|
||||||
|
CPPGC_STACK_ALLOCATED();
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Enters a no garbage collection scope. Must be paired with `Leave()`. Prefer
|
||||||
|
* a scope instance of `NoGarbageCollectionScope`.
|
||||||
|
*
|
||||||
|
* \param heap_handle The corresponding heap.
|
||||||
|
*/
|
||||||
|
static void Enter(HeapHandle& heap_handle);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Leaves a no garbage collection scope. Must be paired with `Enter()`. Prefer
|
||||||
|
* a scope instance of `NoGarbageCollectionScope`.
|
||||||
|
*
|
||||||
|
* \param heap_handle The corresponding heap.
|
||||||
|
*/
|
||||||
|
static void Leave(HeapHandle& heap_handle);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a scoped object that automatically enters and leaves a no
|
||||||
|
* garbage collection scope based on its lifetime.
|
||||||
|
*
|
||||||
|
* \param heap_handle The corresponding heap.
|
||||||
|
*/
|
||||||
|
explicit NoGarbageCollectionScope(HeapHandle& heap_handle);
|
||||||
|
~NoGarbageCollectionScope();
|
||||||
|
|
||||||
|
NoGarbageCollectionScope(const NoGarbageCollectionScope&) = delete;
|
||||||
|
NoGarbageCollectionScope& operator=(const NoGarbageCollectionScope&) = delete;
|
||||||
|
|
||||||
|
private:
|
||||||
|
HeapHandle& heap_handle_;
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace subtle
|
} // namespace subtle
|
||||||
} // namespace cppgc
|
} // namespace cppgc
|
||||||
|
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
#include "src/heap/cppgc-js/cpp-heap.h"
|
#include "src/heap/cppgc-js/cpp-heap.h"
|
||||||
|
|
||||||
|
#include "include/cppgc/heap-consistency.h"
|
||||||
#include "include/cppgc/platform.h"
|
#include "include/cppgc/platform.h"
|
||||||
#include "include/v8-platform.h"
|
#include "include/v8-platform.h"
|
||||||
#include "include/v8.h"
|
#include "include/v8.h"
|
||||||
@ -181,6 +182,7 @@ CppHeap::CppHeap(
|
|||||||
isolate_.heap_profiler()->AddBuildEmbedderGraphCallback(
|
isolate_.heap_profiler()->AddBuildEmbedderGraphCallback(
|
||||||
&CppGraphBuilder::Run, this);
|
&CppGraphBuilder::Run, this);
|
||||||
}
|
}
|
||||||
|
stats_collector()->RegisterObserver(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
CppHeap::~CppHeap() {
|
CppHeap::~CppHeap() {
|
||||||
@ -290,7 +292,7 @@ void CppHeap::TraceEpilogue(TraceSummary* trace_summary) {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
{
|
{
|
||||||
NoGCScope no_gc(*this);
|
cppgc::subtle::NoGarbageCollectionScope no_gc(*this);
|
||||||
cppgc::internal::Sweeper::SweepingConfig::CompactableSpaceHandling
|
cppgc::internal::Sweeper::SweepingConfig::CompactableSpaceHandling
|
||||||
compactable_space_handling = compactor_.CompactSpacesIfEnabled();
|
compactable_space_handling = compactor_.CompactSpacesIfEnabled();
|
||||||
const cppgc::internal::Sweeper::SweepingConfig sweeping_config{
|
const cppgc::internal::Sweeper::SweepingConfig sweeping_config{
|
||||||
@ -302,5 +304,32 @@ void CppHeap::TraceEpilogue(TraceSummary* trace_summary) {
|
|||||||
sweeper().NotifyDoneIfNeeded();
|
sweeper().NotifyDoneIfNeeded();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CppHeap::AllocatedObjectSizeIncreased(size_t bytes) {
|
||||||
|
buffered_allocated_bytes_ += static_cast<int64_t>(bytes);
|
||||||
|
ReportBufferedAllocationSizeIfPossible();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CppHeap::AllocatedObjectSizeDecreased(size_t bytes) {
|
||||||
|
buffered_allocated_bytes_ -= static_cast<int64_t>(bytes);
|
||||||
|
ReportBufferedAllocationSizeIfPossible();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CppHeap::ReportBufferedAllocationSizeIfPossible() {
|
||||||
|
// Avoid reporting to V8 in the following conditions as that may trigger GC
|
||||||
|
// finalizations where not allowed.
|
||||||
|
// - Recursive sweeping.
|
||||||
|
// - GC forbidden scope.
|
||||||
|
if (sweeper().IsSweepingOnMutatorThread() || in_no_gc_scope()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (buffered_allocated_bytes_ < 0) {
|
||||||
|
DecreaseAllocatedSize(static_cast<size_t>(-buffered_allocated_bytes_));
|
||||||
|
} else {
|
||||||
|
IncreaseAllocatedSize(static_cast<size_t>(buffered_allocated_bytes_));
|
||||||
|
}
|
||||||
|
buffered_allocated_bytes_ = 0;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace internal
|
} // namespace internal
|
||||||
} // namespace v8
|
} // namespace v8
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
#include "include/v8.h"
|
#include "include/v8.h"
|
||||||
#include "src/base/macros.h"
|
#include "src/base/macros.h"
|
||||||
#include "src/heap/cppgc/heap-base.h"
|
#include "src/heap/cppgc/heap-base.h"
|
||||||
|
#include "src/heap/cppgc/stats-collector.h"
|
||||||
|
|
||||||
namespace v8 {
|
namespace v8 {
|
||||||
|
|
||||||
@ -17,9 +18,11 @@ class Isolate;
|
|||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
||||||
// A C++ heap implementation used with V8 to implement unified heap.
|
// A C++ heap implementation used with V8 to implement unified heap.
|
||||||
class V8_EXPORT_PRIVATE CppHeap final : public cppgc::internal::HeapBase,
|
class V8_EXPORT_PRIVATE CppHeap final
|
||||||
public v8::CppHeap,
|
: public cppgc::internal::HeapBase,
|
||||||
public v8::EmbedderHeapTracer {
|
public v8::CppHeap,
|
||||||
|
public v8::EmbedderHeapTracer,
|
||||||
|
public cppgc::internal::StatsCollector::AllocationObserver {
|
||||||
public:
|
public:
|
||||||
static CppHeap* From(v8::CppHeap* heap) {
|
static CppHeap* From(v8::CppHeap* heap) {
|
||||||
return static_cast<CppHeap*>(heap);
|
return static_cast<CppHeap*>(heap);
|
||||||
@ -41,6 +44,9 @@ class V8_EXPORT_PRIVATE CppHeap final : public cppgc::internal::HeapBase,
|
|||||||
HeapBase& AsBase() { return *this; }
|
HeapBase& AsBase() { return *this; }
|
||||||
const HeapBase& AsBase() const { return *this; }
|
const HeapBase& AsBase() const { return *this; }
|
||||||
|
|
||||||
|
void Terminate();
|
||||||
|
|
||||||
|
// v8::EmbedderHeapTracer interface.
|
||||||
void RegisterV8References(
|
void RegisterV8References(
|
||||||
const std::vector<std::pair<void*, void*> >& embedder_fields) final;
|
const std::vector<std::pair<void*, void*> >& embedder_fields) final;
|
||||||
void TracePrologue(TraceFlags flags) final;
|
void TracePrologue(TraceFlags flags) final;
|
||||||
@ -49,7 +55,10 @@ class V8_EXPORT_PRIVATE CppHeap final : public cppgc::internal::HeapBase,
|
|||||||
void TraceEpilogue(TraceSummary* trace_summary) final;
|
void TraceEpilogue(TraceSummary* trace_summary) final;
|
||||||
void EnterFinalPause(EmbedderStackState stack_state) final;
|
void EnterFinalPause(EmbedderStackState stack_state) final;
|
||||||
|
|
||||||
void Terminate();
|
// StatsCollector::AllocationObserver interface.
|
||||||
|
void AllocatedObjectSizeIncreased(size_t) final;
|
||||||
|
void AllocatedObjectSizeDecreased(size_t) final;
|
||||||
|
void ResetAllocatedObjectSize(size_t) final {}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void FinalizeIncrementalGarbageCollectionIfNeeded(
|
void FinalizeIncrementalGarbageCollectionIfNeeded(
|
||||||
@ -58,9 +67,16 @@ class V8_EXPORT_PRIVATE CppHeap final : public cppgc::internal::HeapBase,
|
|||||||
// finalization is not needed) thus this method is left empty.
|
// finalization is not needed) thus this method is left empty.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ReportBufferedAllocationSizeIfPossible();
|
||||||
|
|
||||||
Isolate& isolate_;
|
Isolate& isolate_;
|
||||||
bool marking_done_ = false;
|
bool marking_done_ = false;
|
||||||
bool is_in_final_pause_ = false;
|
bool is_in_final_pause_ = false;
|
||||||
|
|
||||||
|
// Buffered allocated bytes. Reporting allocated bytes to V8 can trigger a GC
|
||||||
|
// atomic pause. Allocated bytes are buffer in case this is temporarily
|
||||||
|
// prohibited.
|
||||||
|
int64_t buffered_allocated_bytes_ = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace internal
|
} // namespace internal
|
||||||
|
@ -85,12 +85,6 @@ size_t HeapBase::ObjectPayloadSize() const {
|
|||||||
return ObjectSizeCounter().GetSize(const_cast<RawHeap*>(&raw_heap()));
|
return ObjectSizeCounter().GetSize(const_cast<RawHeap*>(&raw_heap()));
|
||||||
}
|
}
|
||||||
|
|
||||||
HeapBase::NoGCScope::NoGCScope(HeapBase& heap) : heap_(heap) {
|
|
||||||
heap_.no_gc_scope_++;
|
|
||||||
}
|
|
||||||
|
|
||||||
HeapBase::NoGCScope::~NoGCScope() { heap_.no_gc_scope_--; }
|
|
||||||
|
|
||||||
void HeapBase::AdvanceIncrementalGarbageCollectionOnAllocationIfNeeded() {
|
void HeapBase::AdvanceIncrementalGarbageCollectionOnAllocationIfNeeded() {
|
||||||
if (marker_) marker_->AdvanceMarkingOnAllocation();
|
if (marker_) marker_->AdvanceMarkingOnAllocation();
|
||||||
}
|
}
|
||||||
|
@ -31,6 +31,9 @@ class Stack;
|
|||||||
} // namespace heap
|
} // namespace heap
|
||||||
|
|
||||||
namespace cppgc {
|
namespace cppgc {
|
||||||
|
namespace subtle {
|
||||||
|
class NoGarbageCollectionScope;
|
||||||
|
} // namespace subtle
|
||||||
|
|
||||||
class Platform;
|
class Platform;
|
||||||
|
|
||||||
@ -55,22 +58,6 @@ class V8_EXPORT_PRIVATE HeapBase : public cppgc::HeapHandle {
|
|||||||
public:
|
public:
|
||||||
using StackSupport = cppgc::Heap::StackSupport;
|
using StackSupport = cppgc::Heap::StackSupport;
|
||||||
|
|
||||||
// NoGCScope allows going over limits and avoids triggering garbage
|
|
||||||
// collection triggered through allocations or even explicitly.
|
|
||||||
class V8_EXPORT_PRIVATE V8_NODISCARD NoGCScope final {
|
|
||||||
CPPGC_STACK_ALLOCATED();
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit NoGCScope(HeapBase& heap);
|
|
||||||
~NoGCScope();
|
|
||||||
|
|
||||||
NoGCScope(const NoGCScope&) = delete;
|
|
||||||
NoGCScope& operator=(const NoGCScope&) = delete;
|
|
||||||
|
|
||||||
private:
|
|
||||||
HeapBase& heap_;
|
|
||||||
};
|
|
||||||
|
|
||||||
static HeapBase& From(cppgc::HeapHandle& heap_handle) {
|
static HeapBase& From(cppgc::HeapHandle& heap_handle) {
|
||||||
return static_cast<HeapBase&>(heap_handle);
|
return static_cast<HeapBase&>(heap_handle);
|
||||||
}
|
}
|
||||||
@ -199,6 +186,7 @@ class V8_EXPORT_PRIVATE HeapBase : public cppgc::HeapHandle {
|
|||||||
|
|
||||||
friend class MarkerBase::IncrementalMarkingTask;
|
friend class MarkerBase::IncrementalMarkingTask;
|
||||||
friend class testing::TestWithHeap;
|
friend class testing::TestWithHeap;
|
||||||
|
friend class cppgc::subtle::NoGarbageCollectionScope;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace internal
|
} // namespace internal
|
||||||
|
36
src/heap/cppgc/heap-consistency.cc
Normal file
36
src/heap/cppgc/heap-consistency.cc
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
// Copyright 2021 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/heap-consistency.h"
|
||||||
|
|
||||||
|
#include "include/cppgc/heap.h"
|
||||||
|
#include "src/base/logging.h"
|
||||||
|
#include "src/heap/cppgc/heap-base.h"
|
||||||
|
|
||||||
|
namespace cppgc {
|
||||||
|
namespace subtle {
|
||||||
|
|
||||||
|
// static
|
||||||
|
void NoGarbageCollectionScope::Enter(cppgc::HeapHandle& heap_handle) {
|
||||||
|
auto& heap_base = internal::HeapBase::From(heap_handle);
|
||||||
|
heap_base.no_gc_scope_++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
void NoGarbageCollectionScope::Leave(cppgc::HeapHandle& heap_handle) {
|
||||||
|
auto& heap_base = internal::HeapBase::From(heap_handle);
|
||||||
|
DCHECK_GT(heap_base.no_gc_scope_, 0);
|
||||||
|
heap_base.no_gc_scope_--;
|
||||||
|
}
|
||||||
|
|
||||||
|
NoGarbageCollectionScope::NoGarbageCollectionScope(
|
||||||
|
cppgc::HeapHandle& heap_handle)
|
||||||
|
: heap_handle_(heap_handle) {
|
||||||
|
Enter(heap_handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
NoGarbageCollectionScope::~NoGarbageCollectionScope() { Leave(heap_handle_); }
|
||||||
|
|
||||||
|
} // namespace subtle
|
||||||
|
} // namespace cppgc
|
@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
#include "src/heap/cppgc/heap.h"
|
#include "src/heap/cppgc/heap.h"
|
||||||
|
|
||||||
|
#include "include/cppgc/heap-consistency.h"
|
||||||
#include "src/heap/base/stack.h"
|
#include "src/heap/base/stack.h"
|
||||||
#include "src/heap/cppgc/garbage-collector.h"
|
#include "src/heap/cppgc/garbage-collector.h"
|
||||||
#include "src/heap/cppgc/gc-invoker.h"
|
#include "src/heap/cppgc/gc-invoker.h"
|
||||||
@ -101,7 +102,7 @@ Heap::Heap(std::shared_ptr<cppgc::Platform> platform,
|
|||||||
}
|
}
|
||||||
|
|
||||||
Heap::~Heap() {
|
Heap::~Heap() {
|
||||||
NoGCScope no_gc(*this);
|
subtle::NoGarbageCollectionScope no_gc(*this);
|
||||||
// Finish already running GC if any, but don't finalize live objects.
|
// Finish already running GC if any, but don't finalize live objects.
|
||||||
sweeper_.FinishIfRunning();
|
sweeper_.FinishIfRunning();
|
||||||
}
|
}
|
||||||
@ -189,7 +190,7 @@ void Heap::FinalizeGarbageCollection(Config::StackState stack_state) {
|
|||||||
verifier.Run(stack_state);
|
verifier.Run(stack_state);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
NoGCScope no_gc(*this);
|
subtle::NoGarbageCollectionScope no_gc(*this);
|
||||||
const Sweeper::SweepingConfig sweeping_config{
|
const Sweeper::SweepingConfig sweeping_config{
|
||||||
config_.sweeping_type,
|
config_.sweeping_type,
|
||||||
Sweeper::SweepingConfig::CompactableSpaceHandling::kSweep};
|
Sweeper::SweepingConfig::CompactableSpaceHandling::kSweep};
|
||||||
|
@ -583,6 +583,10 @@ class Sweeper::SweeperImpl final {
|
|||||||
if (concurrent_sweeper_handle_) concurrent_sweeper_handle_->Join();
|
if (concurrent_sweeper_handle_) concurrent_sweeper_handle_->Join();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool IsSweepingOnMutatorThread() const {
|
||||||
|
return is_sweeping_on_mutator_thread_;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
class MutatorThreadSweepingScope final {
|
class MutatorThreadSweepingScope final {
|
||||||
public:
|
public:
|
||||||
@ -713,6 +717,9 @@ void Sweeper::WaitForConcurrentSweepingForTesting() {
|
|||||||
impl_->WaitForConcurrentSweepingForTesting();
|
impl_->WaitForConcurrentSweepingForTesting();
|
||||||
}
|
}
|
||||||
void Sweeper::NotifyDoneIfNeeded() { impl_->NotifyDoneIfNeeded(); }
|
void Sweeper::NotifyDoneIfNeeded() { impl_->NotifyDoneIfNeeded(); }
|
||||||
|
bool Sweeper::IsSweepingOnMutatorThread() const {
|
||||||
|
return impl_->IsSweepingOnMutatorThread();
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace internal
|
} // namespace internal
|
||||||
} // namespace cppgc
|
} // namespace cppgc
|
||||||
|
@ -42,6 +42,8 @@ class V8_EXPORT_PRIVATE Sweeper final {
|
|||||||
void FinishIfRunning();
|
void FinishIfRunning();
|
||||||
void NotifyDoneIfNeeded();
|
void NotifyDoneIfNeeded();
|
||||||
|
|
||||||
|
bool IsSweepingOnMutatorThread() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void WaitForConcurrentSweepingForTesting();
|
void WaitForConcurrentSweepingForTesting();
|
||||||
|
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
#include "include/cppgc/allocation.h"
|
#include "include/cppgc/allocation.h"
|
||||||
#include "include/cppgc/garbage-collected.h"
|
#include "include/cppgc/garbage-collected.h"
|
||||||
|
#include "include/cppgc/heap-consistency.h"
|
||||||
#include "src/heap/cppgc/globals.h"
|
#include "src/heap/cppgc/globals.h"
|
||||||
#include "src/heap/cppgc/heap.h"
|
#include "src/heap/cppgc/heap.h"
|
||||||
#include "test/benchmarks/cpp/cppgc/utils.h"
|
#include "test/benchmarks/cpp/cppgc/utils.h"
|
||||||
@ -21,7 +22,7 @@ class TinyObject final : public cppgc::GarbageCollected<TinyObject> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
BENCHMARK_F(Allocate, Tiny)(benchmark::State& st) {
|
BENCHMARK_F(Allocate, Tiny)(benchmark::State& st) {
|
||||||
Heap::NoGCScope no_gc(*Heap::From(&heap()));
|
subtle::NoGarbageCollectionScope no_gc(*Heap::From(&heap()));
|
||||||
for (auto _ : st) {
|
for (auto _ : st) {
|
||||||
benchmark::DoNotOptimize(
|
benchmark::DoNotOptimize(
|
||||||
cppgc::MakeGarbageCollected<TinyObject>(heap().GetAllocationHandle()));
|
cppgc::MakeGarbageCollected<TinyObject>(heap().GetAllocationHandle()));
|
||||||
@ -36,7 +37,7 @@ class LargeObject final : public GarbageCollected<LargeObject> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
BENCHMARK_F(Allocate, Large)(benchmark::State& st) {
|
BENCHMARK_F(Allocate, Large)(benchmark::State& st) {
|
||||||
Heap::NoGCScope no_gc(*Heap::From(&heap()));
|
subtle::NoGarbageCollectionScope no_gc(*Heap::From(&heap()));
|
||||||
for (auto _ : st) {
|
for (auto _ : st) {
|
||||||
benchmark::DoNotOptimize(
|
benchmark::DoNotOptimize(
|
||||||
cppgc::MakeGarbageCollected<LargeObject>(heap().GetAllocationHandle()));
|
cppgc::MakeGarbageCollected<LargeObject>(heap().GetAllocationHandle()));
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
#include <numeric>
|
#include <numeric>
|
||||||
|
|
||||||
#include "include/cppgc/allocation.h"
|
#include "include/cppgc/allocation.h"
|
||||||
|
#include "include/cppgc/heap-consistency.h"
|
||||||
#include "include/cppgc/persistent.h"
|
#include "include/cppgc/persistent.h"
|
||||||
#include "src/heap/cppgc/globals.h"
|
#include "src/heap/cppgc/globals.h"
|
||||||
#include "test/unittests/heap/cppgc/tests.h"
|
#include "test/unittests/heap/cppgc/tests.h"
|
||||||
@ -95,7 +96,7 @@ TEST_F(GCHeapTest, ObjectPayloadSize) {
|
|||||||
Heap::From(GetHeap())->CollectGarbage(
|
Heap::From(GetHeap())->CollectGarbage(
|
||||||
GarbageCollector::Config::ConservativeAtomicConfig());
|
GarbageCollector::Config::ConservativeAtomicConfig());
|
||||||
|
|
||||||
Heap::NoGCScope no_gc_scope(*Heap::From(GetHeap()));
|
subtle::NoGarbageCollectionScope no_gc(*Heap::From(GetHeap()));
|
||||||
|
|
||||||
for (size_t k = 0; k < kNumberOfObjectsPerArena; ++k) {
|
for (size_t k = 0; k < kNumberOfObjectsPerArena; ++k) {
|
||||||
MakeGarbageCollected<GCed<kObjectSizes[0]>>(GetAllocationHandle());
|
MakeGarbageCollected<GCed<kObjectSizes[0]>>(GetAllocationHandle());
|
||||||
@ -156,6 +157,23 @@ TEST_F(GCHeapTest, AllocatedSizeDependOnAdditionalBytes) {
|
|||||||
HeapObjectHeader::FromPayload(object_with_more_bytes).GetSize());
|
HeapObjectHeader::FromPayload(object_with_more_bytes).GetSize());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(GCHeapTest, Epoch) {
|
||||||
|
const size_t epoch_before = internal::Heap::From(GetHeap())->epoch();
|
||||||
|
PreciseGC();
|
||||||
|
const size_t epoch_after_gc = internal::Heap::From(GetHeap())->epoch();
|
||||||
|
EXPECT_EQ(epoch_after_gc, epoch_before + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(GCHeapTest, NoGarbageCollectionScope) {
|
||||||
|
const size_t epoch_before = internal::Heap::From(GetHeap())->epoch();
|
||||||
|
{
|
||||||
|
subtle::NoGarbageCollectionScope scope(GetHeap()->GetHeapHandle());
|
||||||
|
PreciseGC();
|
||||||
|
}
|
||||||
|
const size_t epoch_after_gc = internal::Heap::From(GetHeap())->epoch();
|
||||||
|
EXPECT_EQ(epoch_after_gc, epoch_before);
|
||||||
|
}
|
||||||
|
|
||||||
TEST_F(GCHeapTest, TerminateEmptyHeap) { Heap::From(GetHeap())->Terminate(); }
|
TEST_F(GCHeapTest, TerminateEmptyHeap) { Heap::From(GetHeap())->Terminate(); }
|
||||||
|
|
||||||
TEST_F(GCHeapTest, TerminateClearsPersistent) {
|
TEST_F(GCHeapTest, TerminateClearsPersistent) {
|
||||||
|
@ -89,7 +89,7 @@ TYPED_TEST(MinorGCTestForType, MinorCollection) {
|
|||||||
EXPECT_EQ(1u, TestFixture::DestructedObjects());
|
EXPECT_EQ(1u, TestFixture::DestructedObjects());
|
||||||
|
|
||||||
{
|
{
|
||||||
Heap::NoGCScope no_gc_scope_(*Heap::From(this->GetHeap()));
|
subtle::NoGarbageCollectionScope no_gc_scope(*Heap::From(this->GetHeap()));
|
||||||
|
|
||||||
Type* prev = nullptr;
|
Type* prev = nullptr;
|
||||||
for (size_t i = 0; i < 64; ++i) {
|
for (size_t i = 0; i < 64; ++i) {
|
||||||
@ -144,7 +144,7 @@ void InterGenerationalPointerTest(MinorGCTest* test, cppgc::Heap* heap) {
|
|||||||
Type2* young = nullptr;
|
Type2* young = nullptr;
|
||||||
|
|
||||||
{
|
{
|
||||||
Heap::NoGCScope no_gc_scope_(*Heap::From(heap));
|
subtle::NoGarbageCollectionScope no_gc_scope(*Heap::From(heap));
|
||||||
|
|
||||||
// Allocate young objects.
|
// Allocate young objects.
|
||||||
for (size_t i = 0; i < 64; ++i) {
|
for (size_t i = 0; i < 64; ++i) {
|
||||||
|
@ -38,7 +38,7 @@ void TestWithHeap::ResetLinearAllocationBuffers() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TestSupportingAllocationOnly::TestSupportingAllocationOnly()
|
TestSupportingAllocationOnly::TestSupportingAllocationOnly()
|
||||||
: no_gc_scope_(*internal::Heap::From(GetHeap())) {}
|
: no_gc_scope_(GetHeap()->GetHeapHandle()) {}
|
||||||
|
|
||||||
} // namespace testing
|
} // namespace testing
|
||||||
} // namespace internal
|
} // namespace internal
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
#ifndef V8_UNITTESTS_HEAP_CPPGC_TESTS_H_
|
#ifndef V8_UNITTESTS_HEAP_CPPGC_TESTS_H_
|
||||||
#define V8_UNITTESTS_HEAP_CPPGC_TESTS_H_
|
#define V8_UNITTESTS_HEAP_CPPGC_TESTS_H_
|
||||||
|
|
||||||
|
#include "include/cppgc/heap-consistency.h"
|
||||||
#include "include/cppgc/heap.h"
|
#include "include/cppgc/heap.h"
|
||||||
#include "include/cppgc/platform.h"
|
#include "include/cppgc/platform.h"
|
||||||
#include "src/heap/cppgc/heap.h"
|
#include "src/heap/cppgc/heap.h"
|
||||||
@ -101,7 +102,7 @@ class TestSupportingAllocationOnly : public TestWithHeap {
|
|||||||
TestSupportingAllocationOnly();
|
TestSupportingAllocationOnly();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Heap::NoGCScope no_gc_scope_;
|
subtle::NoGarbageCollectionScope no_gc_scope_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace testing
|
} // namespace testing
|
||||||
|
Loading…
Reference in New Issue
Block a user