mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-12-28 13:43:45 +03:00
Kernel: Make AnonymousVMObject construction OOM-aware
This commit moves the allocation of the resources required for AnonymousVMObject from its constructors to its factory functions. We're making this change to expose the fallibility of the allocation.
This commit is contained in:
parent
d1f265e851
commit
3879e70447
Notes:
sideshowbarker
2024-07-17 20:50:18 +09:00
Author: https://github.com/creator1creeper1 Commit: https://github.com/SerenityOS/serenity/commit/3879e70447a Pull-request: https://github.com/SerenityOS/serenity/pull/11843 Reviewed-by: https://github.com/IdanHo ✅ Reviewed-by: https://github.com/bgianfo
@ -43,7 +43,8 @@ ErrorOr<NonnullRefPtr<VMObject>> AnonymousVMObject::try_clone()
|
|||||||
// one and this one, as well as the clone have sufficient resources
|
// one and this one, as well as the clone have sufficient resources
|
||||||
// to cow all pages as needed
|
// to cow all pages as needed
|
||||||
auto new_shared_committed_cow_pages = TRY(adopt_nonnull_ref_or_enomem(new (nothrow) SharedCommittedCowPages(move(committed_pages))));
|
auto new_shared_committed_cow_pages = TRY(adopt_nonnull_ref_or_enomem(new (nothrow) SharedCommittedCowPages(move(committed_pages))));
|
||||||
auto clone = TRY(adopt_nonnull_ref_or_enomem(new (nothrow) AnonymousVMObject(*this, *new_shared_committed_cow_pages)));
|
auto new_physical_pages = TRY(this->try_clone_physical_pages());
|
||||||
|
auto clone = TRY(adopt_nonnull_ref_or_enomem(new (nothrow) AnonymousVMObject(*this, *new_shared_committed_cow_pages, move(new_physical_pages))));
|
||||||
|
|
||||||
m_shared_committed_cow_pages = move(new_shared_committed_cow_pages);
|
m_shared_committed_cow_pages = move(new_shared_committed_cow_pages);
|
||||||
|
|
||||||
@ -73,7 +74,9 @@ ErrorOr<NonnullRefPtr<AnonymousVMObject>> AnonymousVMObject::try_create_with_siz
|
|||||||
committed_pages = TRY(MM.commit_user_physical_pages(ceil_div(size, static_cast<size_t>(PAGE_SIZE))));
|
committed_pages = TRY(MM.commit_user_physical_pages(ceil_div(size, static_cast<size_t>(PAGE_SIZE))));
|
||||||
}
|
}
|
||||||
|
|
||||||
return adopt_nonnull_ref_or_enomem(new (nothrow) AnonymousVMObject(size, strategy, move(committed_pages)));
|
auto new_physical_pages = TRY(VMObject::try_create_physical_pages(size));
|
||||||
|
|
||||||
|
return adopt_nonnull_ref_or_enomem(new (nothrow) AnonymousVMObject(move(new_physical_pages), strategy, move(committed_pages)));
|
||||||
}
|
}
|
||||||
|
|
||||||
ErrorOr<NonnullRefPtr<AnonymousVMObject>> AnonymousVMObject::try_create_physically_contiguous_with_size(size_t size)
|
ErrorOr<NonnullRefPtr<AnonymousVMObject>> AnonymousVMObject::try_create_physically_contiguous_with_size(size_t size)
|
||||||
@ -82,7 +85,9 @@ ErrorOr<NonnullRefPtr<AnonymousVMObject>> AnonymousVMObject::try_create_physical
|
|||||||
if (contiguous_physical_pages.is_empty())
|
if (contiguous_physical_pages.is_empty())
|
||||||
return ENOMEM;
|
return ENOMEM;
|
||||||
|
|
||||||
return adopt_nonnull_ref_or_enomem(new (nothrow) AnonymousVMObject(contiguous_physical_pages.span()));
|
auto new_physical_pages = TRY(FixedArray<RefPtr<PhysicalPage>>::try_create(contiguous_physical_pages.span()));
|
||||||
|
|
||||||
|
return adopt_nonnull_ref_or_enomem(new (nothrow) AnonymousVMObject(move(new_physical_pages)));
|
||||||
}
|
}
|
||||||
|
|
||||||
ErrorOr<NonnullRefPtr<AnonymousVMObject>> AnonymousVMObject::try_create_purgeable_with_size(size_t size, AllocationStrategy strategy)
|
ErrorOr<NonnullRefPtr<AnonymousVMObject>> AnonymousVMObject::try_create_purgeable_with_size(size_t size, AllocationStrategy strategy)
|
||||||
@ -92,14 +97,17 @@ ErrorOr<NonnullRefPtr<AnonymousVMObject>> AnonymousVMObject::try_create_purgeabl
|
|||||||
committed_pages = TRY(MM.commit_user_physical_pages(ceil_div(size, static_cast<size_t>(PAGE_SIZE))));
|
committed_pages = TRY(MM.commit_user_physical_pages(ceil_div(size, static_cast<size_t>(PAGE_SIZE))));
|
||||||
}
|
}
|
||||||
|
|
||||||
auto vmobject = TRY(adopt_nonnull_ref_or_enomem(new (nothrow) AnonymousVMObject(size, strategy, move(committed_pages))));
|
auto new_physical_pages = TRY(VMObject::try_create_physical_pages(size));
|
||||||
|
|
||||||
|
auto vmobject = TRY(adopt_nonnull_ref_or_enomem(new (nothrow) AnonymousVMObject(move(new_physical_pages), strategy, move(committed_pages))));
|
||||||
vmobject->m_purgeable = true;
|
vmobject->m_purgeable = true;
|
||||||
return vmobject;
|
return vmobject;
|
||||||
}
|
}
|
||||||
|
|
||||||
ErrorOr<NonnullRefPtr<AnonymousVMObject>> AnonymousVMObject::try_create_with_physical_pages(Span<NonnullRefPtr<PhysicalPage>> physical_pages)
|
ErrorOr<NonnullRefPtr<AnonymousVMObject>> AnonymousVMObject::try_create_with_physical_pages(Span<NonnullRefPtr<PhysicalPage>> physical_pages)
|
||||||
{
|
{
|
||||||
return adopt_nonnull_ref_or_enomem(new (nothrow) AnonymousVMObject(physical_pages));
|
auto new_physical_pages = TRY(FixedArray<RefPtr<PhysicalPage>>::try_create(physical_pages));
|
||||||
|
return adopt_nonnull_ref_or_enomem(new (nothrow) AnonymousVMObject(move(new_physical_pages)));
|
||||||
}
|
}
|
||||||
|
|
||||||
ErrorOr<NonnullRefPtr<AnonymousVMObject>> AnonymousVMObject::try_create_for_physical_range(PhysicalAddress paddr, size_t size)
|
ErrorOr<NonnullRefPtr<AnonymousVMObject>> AnonymousVMObject::try_create_for_physical_range(PhysicalAddress paddr, size_t size)
|
||||||
@ -110,11 +118,13 @@ ErrorOr<NonnullRefPtr<AnonymousVMObject>> AnonymousVMObject::try_create_for_phys
|
|||||||
return ENOMEM;
|
return ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
return adopt_nonnull_ref_or_enomem(new (nothrow) AnonymousVMObject(paddr, size));
|
auto new_physical_pages = TRY(VMObject::try_create_physical_pages(size));
|
||||||
|
|
||||||
|
return adopt_nonnull_ref_or_enomem(new (nothrow) AnonymousVMObject(paddr, move(new_physical_pages)));
|
||||||
}
|
}
|
||||||
|
|
||||||
AnonymousVMObject::AnonymousVMObject(size_t size, AllocationStrategy strategy, Optional<CommittedPhysicalPageSet> committed_pages)
|
AnonymousVMObject::AnonymousVMObject(FixedArray<RefPtr<PhysicalPage>>&& new_physical_pages, AllocationStrategy strategy, Optional<CommittedPhysicalPageSet> committed_pages)
|
||||||
: VMObject(VMObject::must_create_physical_pages_but_fixme_should_propagate_errors(size))
|
: VMObject(move(new_physical_pages))
|
||||||
, m_unused_committed_pages(move(committed_pages))
|
, m_unused_committed_pages(move(committed_pages))
|
||||||
{
|
{
|
||||||
if (strategy == AllocationStrategy::AllocateNow) {
|
if (strategy == AllocationStrategy::AllocateNow) {
|
||||||
@ -128,24 +138,21 @@ AnonymousVMObject::AnonymousVMObject(size_t size, AllocationStrategy strategy, O
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
AnonymousVMObject::AnonymousVMObject(PhysicalAddress paddr, size_t size)
|
AnonymousVMObject::AnonymousVMObject(PhysicalAddress paddr, FixedArray<RefPtr<PhysicalPage>>&& new_physical_pages)
|
||||||
: VMObject(VMObject::must_create_physical_pages_but_fixme_should_propagate_errors(size))
|
: VMObject(move(new_physical_pages))
|
||||||
{
|
{
|
||||||
VERIFY(paddr.page_base() == paddr);
|
VERIFY(paddr.page_base() == paddr);
|
||||||
for (size_t i = 0; i < page_count(); ++i)
|
for (size_t i = 0; i < page_count(); ++i)
|
||||||
physical_pages()[i] = PhysicalPage::create(paddr.offset(i * PAGE_SIZE), MayReturnToFreeList::No);
|
physical_pages()[i] = PhysicalPage::create(paddr.offset(i * PAGE_SIZE), MayReturnToFreeList::No);
|
||||||
}
|
}
|
||||||
|
|
||||||
AnonymousVMObject::AnonymousVMObject(Span<NonnullRefPtr<PhysicalPage>> physical_pages)
|
AnonymousVMObject::AnonymousVMObject(FixedArray<RefPtr<PhysicalPage>>&& new_physical_pages)
|
||||||
: VMObject(VMObject::must_create_physical_pages_but_fixme_should_propagate_errors(physical_pages.size() * PAGE_SIZE))
|
: VMObject(move(new_physical_pages))
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < physical_pages.size(); ++i) {
|
|
||||||
m_physical_pages[i] = physical_pages[i];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
AnonymousVMObject::AnonymousVMObject(AnonymousVMObject const& other, NonnullRefPtr<SharedCommittedCowPages> shared_committed_cow_pages)
|
AnonymousVMObject::AnonymousVMObject(AnonymousVMObject const& other, NonnullRefPtr<SharedCommittedCowPages> shared_committed_cow_pages, FixedArray<RefPtr<PhysicalPage>>&& new_physical_pages)
|
||||||
: VMObject(other.must_clone_physical_pages_but_fixme_should_propagate_errors())
|
: VMObject(move(new_physical_pages))
|
||||||
, m_shared_committed_cow_pages(move(shared_committed_cow_pages))
|
, m_shared_committed_cow_pages(move(shared_committed_cow_pages))
|
||||||
, m_purgeable(other.m_purgeable)
|
, m_purgeable(other.m_purgeable)
|
||||||
{
|
{
|
||||||
|
@ -41,10 +41,10 @@ public:
|
|||||||
private:
|
private:
|
||||||
class SharedCommittedCowPages;
|
class SharedCommittedCowPages;
|
||||||
|
|
||||||
explicit AnonymousVMObject(size_t, AllocationStrategy, Optional<CommittedPhysicalPageSet>);
|
explicit AnonymousVMObject(FixedArray<RefPtr<PhysicalPage>>&&, AllocationStrategy, Optional<CommittedPhysicalPageSet>);
|
||||||
explicit AnonymousVMObject(PhysicalAddress, size_t);
|
explicit AnonymousVMObject(PhysicalAddress, FixedArray<RefPtr<PhysicalPage>>&&);
|
||||||
explicit AnonymousVMObject(Span<NonnullRefPtr<PhysicalPage>>);
|
explicit AnonymousVMObject(FixedArray<RefPtr<PhysicalPage>>&&);
|
||||||
explicit AnonymousVMObject(AnonymousVMObject const&, NonnullRefPtr<SharedCommittedCowPages>);
|
explicit AnonymousVMObject(AnonymousVMObject const&, NonnullRefPtr<SharedCommittedCowPages>, FixedArray<RefPtr<PhysicalPage>>&&);
|
||||||
|
|
||||||
virtual StringView class_name() const override { return "AnonymousVMObject"sv; }
|
virtual StringView class_name() const override { return "AnonymousVMObject"sv; }
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user