Commit 06021c14 authored by Michael Lippautz's avatar Michael Lippautz Committed by V8 LUCI CQ

cppgc: Delegate Persistent node allocation failure to OOM handler

Persistent node slots are dynamically allocated and their allocation
may fail. Delegate to the proper OOM handler in this case.

Bug: chromium:1243257
Change-Id: I985f5b0c940f7ac4996f3f3243123a07119005b9
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3240786Reviewed-by: 's avatarOmer Katz <omerkatz@chromium.org>
Commit-Queue: Michael Lippautz <mlippautz@chromium.org>
Cr-Commit-Position: refs/heads/main@{#77523}
parent 293f2826
...@@ -20,6 +20,7 @@ class Visitor; ...@@ -20,6 +20,7 @@ class Visitor;
namespace internal { namespace internal {
class CrossThreadPersistentRegion; class CrossThreadPersistentRegion;
class FatalOutOfMemoryHandler;
// PersistentNode represents a variant of two states: // PersistentNode represents a variant of two states:
// 1) traceable node with a back pointer to the Persistent object; // 1) traceable node with a back pointer to the Persistent object;
...@@ -79,7 +80,7 @@ class V8_EXPORT PersistentRegionBase { ...@@ -79,7 +80,7 @@ class V8_EXPORT PersistentRegionBase {
using PersistentNodeSlots = std::array<PersistentNode, 256u>; using PersistentNodeSlots = std::array<PersistentNode, 256u>;
public: public:
PersistentRegionBase() = default; explicit PersistentRegionBase(const FatalOutOfMemoryHandler& oom_handler);
// Clears Persistent fields to avoid stale pointers after heap teardown. // Clears Persistent fields to avoid stale pointers after heap teardown.
~PersistentRegionBase(); ~PersistentRegionBase();
...@@ -89,6 +90,7 @@ class V8_EXPORT PersistentRegionBase { ...@@ -89,6 +90,7 @@ class V8_EXPORT PersistentRegionBase {
PersistentNode* AllocateNode(void* owner, TraceCallback trace) { PersistentNode* AllocateNode(void* owner, TraceCallback trace) {
if (!free_list_head_) { if (!free_list_head_) {
EnsureNodeSlots(); EnsureNodeSlots();
CPPGC_DCHECK(free_list_head_);
} }
PersistentNode* node = free_list_head_; PersistentNode* node = free_list_head_;
free_list_head_ = free_list_head_->FreeListNext(); free_list_head_ = free_list_head_->FreeListNext();
...@@ -122,6 +124,7 @@ class V8_EXPORT PersistentRegionBase { ...@@ -122,6 +124,7 @@ class V8_EXPORT PersistentRegionBase {
std::vector<std::unique_ptr<PersistentNodeSlots>> nodes_; std::vector<std::unique_ptr<PersistentNodeSlots>> nodes_;
PersistentNode* free_list_head_ = nullptr; PersistentNode* free_list_head_ = nullptr;
size_t nodes_in_use_ = 0; size_t nodes_in_use_ = 0;
const FatalOutOfMemoryHandler& oom_handler_;
friend class CrossThreadPersistentRegion; friend class CrossThreadPersistentRegion;
}; };
...@@ -130,7 +133,7 @@ class V8_EXPORT PersistentRegionBase { ...@@ -130,7 +133,7 @@ class V8_EXPORT PersistentRegionBase {
// freeing happens only on the thread that created the region. // freeing happens only on the thread that created the region.
class V8_EXPORT PersistentRegion final : public PersistentRegionBase { class V8_EXPORT PersistentRegion final : public PersistentRegionBase {
public: public:
PersistentRegion(); explicit PersistentRegion(const FatalOutOfMemoryHandler&);
// Clears Persistent fields to avoid stale pointers after heap teardown. // Clears Persistent fields to avoid stale pointers after heap teardown.
~PersistentRegion() = default; ~PersistentRegion() = default;
...@@ -172,7 +175,7 @@ class V8_EXPORT PersistentRegionLock final { ...@@ -172,7 +175,7 @@ class V8_EXPORT PersistentRegionLock final {
class V8_EXPORT CrossThreadPersistentRegion final class V8_EXPORT CrossThreadPersistentRegion final
: protected PersistentRegionBase { : protected PersistentRegionBase {
public: public:
CrossThreadPersistentRegion() = default; explicit CrossThreadPersistentRegion(const FatalOutOfMemoryHandler&);
// Clears Persistent fields to avoid stale pointers after heap teardown. // Clears Persistent fields to avoid stale pointers after heap teardown.
~CrossThreadPersistentRegion(); ~CrossThreadPersistentRegion();
......
...@@ -77,6 +77,10 @@ HeapBase::HeapBase( ...@@ -77,6 +77,10 @@ HeapBase::HeapBase(
object_allocator_(raw_heap_, *page_backend_, *stats_collector_, object_allocator_(raw_heap_, *page_backend_, *stats_collector_,
*prefinalizer_handler_), *prefinalizer_handler_),
sweeper_(*this), sweeper_(*this),
strong_persistent_region_(*oom_handler_.get()),
weak_persistent_region_(*oom_handler_.get()),
strong_cross_thread_persistent_region_(*oom_handler_.get()),
weak_cross_thread_persistent_region_(*oom_handler_.get()),
stack_support_(stack_support) { stack_support_(stack_support) {
stats_collector_->RegisterObserver( stats_collector_->RegisterObserver(
&allocation_observer_for_PROCESS_HEAP_STATISTICS_); &allocation_observer_for_PROCESS_HEAP_STATISTICS_);
......
...@@ -10,11 +10,16 @@ ...@@ -10,11 +10,16 @@
#include "include/cppgc/cross-thread-persistent.h" #include "include/cppgc/cross-thread-persistent.h"
#include "include/cppgc/persistent.h" #include "include/cppgc/persistent.h"
#include "src/base/platform/platform.h" #include "src/base/platform/platform.h"
#include "src/heap/cppgc/platform.h"
#include "src/heap/cppgc/process-heap.h" #include "src/heap/cppgc/process-heap.h"
namespace cppgc { namespace cppgc {
namespace internal { namespace internal {
PersistentRegionBase::PersistentRegionBase(
const FatalOutOfMemoryHandler& oom_handler)
: oom_handler_(oom_handler) {}
PersistentRegionBase::~PersistentRegionBase() { ClearAllUsedNodes(); } PersistentRegionBase::~PersistentRegionBase() { ClearAllUsedNodes(); }
template <typename PersistentBaseClass> template <typename PersistentBaseClass>
...@@ -59,7 +64,11 @@ size_t PersistentRegionBase::NodesInUse() const { ...@@ -59,7 +64,11 @@ size_t PersistentRegionBase::NodesInUse() const {
} }
void PersistentRegionBase::EnsureNodeSlots() { void PersistentRegionBase::EnsureNodeSlots() {
nodes_.push_back(std::make_unique<PersistentNodeSlots>()); auto node_slots = std::make_unique<PersistentNodeSlots>();
if (!node_slots.get()) {
oom_handler_("Oilpan: PersistentRegionBase::EnsureNodeSlots()");
}
nodes_.push_back(std::move(node_slots));
for (auto& node : *nodes_.back()) { for (auto& node : *nodes_.back()) {
node.InitializeAsFreeNode(free_list_head_); node.InitializeAsFreeNode(free_list_head_);
free_list_head_ = &node; free_list_head_ = &node;
...@@ -94,8 +103,9 @@ void PersistentRegionBase::Trace(Visitor* visitor) { ...@@ -94,8 +103,9 @@ void PersistentRegionBase::Trace(Visitor* visitor) {
nodes_.end()); nodes_.end());
} }
PersistentRegion::PersistentRegion() PersistentRegion::PersistentRegion(const FatalOutOfMemoryHandler& oom_handler)
: creation_thread_id_(v8::base::OS::GetCurrentThreadId()) { : PersistentRegionBase(oom_handler),
creation_thread_id_(v8::base::OS::GetCurrentThreadId()) {
USE(creation_thread_id_); USE(creation_thread_id_);
} }
...@@ -116,6 +126,10 @@ void PersistentRegionLock::AssertLocked() { ...@@ -116,6 +126,10 @@ void PersistentRegionLock::AssertLocked() {
return g_process_mutex.Pointer()->AssertHeld(); return g_process_mutex.Pointer()->AssertHeld();
} }
CrossThreadPersistentRegion::CrossThreadPersistentRegion(
const FatalOutOfMemoryHandler& oom_handler)
: PersistentRegionBase(oom_handler) {}
CrossThreadPersistentRegion::~CrossThreadPersistentRegion() { CrossThreadPersistentRegion::~CrossThreadPersistentRegion() {
PersistentRegionLock guard; PersistentRegionLock guard;
PersistentRegionBase::ClearAllUsedNodes<CrossThreadPersistentBase>(); PersistentRegionBase::ClearAllUsedNodes<CrossThreadPersistentBase>();
......
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