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;
namespace internal {
class CrossThreadPersistentRegion;
class FatalOutOfMemoryHandler;
// PersistentNode represents a variant of two states:
// 1) traceable node with a back pointer to the Persistent object;
......@@ -79,7 +80,7 @@ class V8_EXPORT PersistentRegionBase {
using PersistentNodeSlots = std::array<PersistentNode, 256u>;
public:
PersistentRegionBase() = default;
explicit PersistentRegionBase(const FatalOutOfMemoryHandler& oom_handler);
// Clears Persistent fields to avoid stale pointers after heap teardown.
~PersistentRegionBase();
......@@ -89,6 +90,7 @@ class V8_EXPORT PersistentRegionBase {
PersistentNode* AllocateNode(void* owner, TraceCallback trace) {
if (!free_list_head_) {
EnsureNodeSlots();
CPPGC_DCHECK(free_list_head_);
}
PersistentNode* node = free_list_head_;
free_list_head_ = free_list_head_->FreeListNext();
......@@ -122,6 +124,7 @@ class V8_EXPORT PersistentRegionBase {
std::vector<std::unique_ptr<PersistentNodeSlots>> nodes_;
PersistentNode* free_list_head_ = nullptr;
size_t nodes_in_use_ = 0;
const FatalOutOfMemoryHandler& oom_handler_;
friend class CrossThreadPersistentRegion;
};
......@@ -130,7 +133,7 @@ class V8_EXPORT PersistentRegionBase {
// freeing happens only on the thread that created the region.
class V8_EXPORT PersistentRegion final : public PersistentRegionBase {
public:
PersistentRegion();
explicit PersistentRegion(const FatalOutOfMemoryHandler&);
// Clears Persistent fields to avoid stale pointers after heap teardown.
~PersistentRegion() = default;
......@@ -172,7 +175,7 @@ class V8_EXPORT PersistentRegionLock final {
class V8_EXPORT CrossThreadPersistentRegion final
: protected PersistentRegionBase {
public:
CrossThreadPersistentRegion() = default;
explicit CrossThreadPersistentRegion(const FatalOutOfMemoryHandler&);
// Clears Persistent fields to avoid stale pointers after heap teardown.
~CrossThreadPersistentRegion();
......
......@@ -77,6 +77,10 @@ HeapBase::HeapBase(
object_allocator_(raw_heap_, *page_backend_, *stats_collector_,
*prefinalizer_handler_),
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) {
stats_collector_->RegisterObserver(
&allocation_observer_for_PROCESS_HEAP_STATISTICS_);
......
......@@ -10,11 +10,16 @@
#include "include/cppgc/cross-thread-persistent.h"
#include "include/cppgc/persistent.h"
#include "src/base/platform/platform.h"
#include "src/heap/cppgc/platform.h"
#include "src/heap/cppgc/process-heap.h"
namespace cppgc {
namespace internal {
PersistentRegionBase::PersistentRegionBase(
const FatalOutOfMemoryHandler& oom_handler)
: oom_handler_(oom_handler) {}
PersistentRegionBase::~PersistentRegionBase() { ClearAllUsedNodes(); }
template <typename PersistentBaseClass>
......@@ -59,7 +64,11 @@ size_t PersistentRegionBase::NodesInUse() const {
}
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()) {
node.InitializeAsFreeNode(free_list_head_);
free_list_head_ = &node;
......@@ -94,8 +103,9 @@ void PersistentRegionBase::Trace(Visitor* visitor) {
nodes_.end());
}
PersistentRegion::PersistentRegion()
: creation_thread_id_(v8::base::OS::GetCurrentThreadId()) {
PersistentRegion::PersistentRegion(const FatalOutOfMemoryHandler& oom_handler)
: PersistentRegionBase(oom_handler),
creation_thread_id_(v8::base::OS::GetCurrentThreadId()) {
USE(creation_thread_id_);
}
......@@ -116,6 +126,10 @@ void PersistentRegionLock::AssertLocked() {
return g_process_mutex.Pointer()->AssertHeld();
}
CrossThreadPersistentRegion::CrossThreadPersistentRegion(
const FatalOutOfMemoryHandler& oom_handler)
: PersistentRegionBase(oom_handler) {}
CrossThreadPersistentRegion::~CrossThreadPersistentRegion() {
PersistentRegionLock guard;
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