mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-21 23:20:20 +00:00
AK: Make Bitmap construction OOM-fallible
This commit is contained in:
parent
1667a80ade
commit
871a53db76
Notes:
sideshowbarker
2024-07-18 02:13:10 +09:00
Author: https://github.com/IdanHo Commit: https://github.com/SerenityOS/serenity/commit/871a53db76 Pull-request: https://github.com/SerenityOS/serenity/pull/12422
6 changed files with 44 additions and 32 deletions
24
AK/Bitmap.h
24
AK/Bitmap.h
|
@ -7,10 +7,12 @@
|
|||
#pragma once
|
||||
|
||||
#include <AK/BitmapView.h>
|
||||
#include <AK/Error.h>
|
||||
#include <AK/Noncopyable.h>
|
||||
#include <AK/Optional.h>
|
||||
#include <AK/Platform.h>
|
||||
#include <AK/StdLibExtras.h>
|
||||
#include <AK/Try.h>
|
||||
#include <AK/Types.h>
|
||||
#include <AK/kmalloc.h>
|
||||
|
||||
|
@ -20,16 +22,26 @@ class Bitmap : public BitmapView {
|
|||
AK_MAKE_NONCOPYABLE(Bitmap);
|
||||
|
||||
public:
|
||||
Bitmap() = default;
|
||||
|
||||
Bitmap(size_t size, bool default_value)
|
||||
: BitmapView(static_cast<u8*>(kmalloc(ceil_div(size, static_cast<size_t>(8)))), size)
|
||||
, m_is_owning(true)
|
||||
static ErrorOr<Bitmap> try_create(size_t size, bool default_value)
|
||||
{
|
||||
VERIFY(size != 0);
|
||||
fill(default_value);
|
||||
|
||||
auto* data = kmalloc(ceil_div(size, static_cast<size_t>(8)));
|
||||
if (!data)
|
||||
return Error::from_errno(ENOMEM);
|
||||
|
||||
auto bitmap = Bitmap { (u8*)data, size, true };
|
||||
bitmap.fill(default_value);
|
||||
return bitmap;
|
||||
}
|
||||
|
||||
static Bitmap must_create(size_t size, bool default_value)
|
||||
{
|
||||
return MUST(try_create(size, default_value));
|
||||
}
|
||||
|
||||
Bitmap() = default;
|
||||
|
||||
Bitmap(u8* data, size_t size, bool is_owning = false)
|
||||
: BitmapView(data, size)
|
||||
, m_is_owning(is_owning)
|
||||
|
|
|
@ -19,7 +19,7 @@ NonnullOwnPtr<HostBridge> HostBridge::must_create_with_io_access()
|
|||
|
||||
HostBridge::HostBridge(PCI::Domain const& domain)
|
||||
: HostController(domain)
|
||||
, m_enumerated_buses(256, false)
|
||||
, m_enumerated_buses(Bitmap::try_create(256, false).release_value_but_fixme_should_propagate_errors())
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -253,7 +253,7 @@ NonnullRefPtr<PhysicalPage> AnonymousVMObject::allocate_committed_page(Badge<Reg
|
|||
Bitmap& AnonymousVMObject::ensure_cow_map()
|
||||
{
|
||||
if (m_cow_map.is_null())
|
||||
m_cow_map = Bitmap { page_count(), true };
|
||||
m_cow_map = Bitmap::try_create(page_count(), true).release_value_but_fixme_should_propagate_errors();
|
||||
return m_cow_map;
|
||||
}
|
||||
|
||||
|
|
|
@ -12,14 +12,14 @@ namespace Kernel::Memory {
|
|||
InodeVMObject::InodeVMObject(Inode& inode, FixedArray<RefPtr<PhysicalPage>>&& new_physical_pages)
|
||||
: VMObject(move(new_physical_pages))
|
||||
, m_inode(inode)
|
||||
, m_dirty_pages(page_count(), false)
|
||||
, m_dirty_pages(Bitmap::try_create(page_count(), false).release_value_but_fixme_should_propagate_errors())
|
||||
{
|
||||
}
|
||||
|
||||
InodeVMObject::InodeVMObject(InodeVMObject const& other, FixedArray<RefPtr<PhysicalPage>>&& new_physical_pages)
|
||||
: VMObject(move(new_physical_pages))
|
||||
, m_inode(other.m_inode)
|
||||
, m_dirty_pages(page_count(), false)
|
||||
, m_dirty_pages(Bitmap::try_create(page_count(), false).release_value_but_fixme_should_propagate_errors())
|
||||
{
|
||||
for (size_t i = 0; i < page_count(); ++i)
|
||||
m_dirty_pages.set(i, other.m_dirty_pages.get(i));
|
||||
|
|
|
@ -16,14 +16,14 @@ TEST_CASE(construct_empty)
|
|||
|
||||
TEST_CASE(find_first_set)
|
||||
{
|
||||
Bitmap bitmap(128, false);
|
||||
auto bitmap = Bitmap::must_create(128, false);
|
||||
bitmap.set(69, true);
|
||||
EXPECT_EQ(bitmap.find_first_set().value(), 69u);
|
||||
}
|
||||
|
||||
TEST_CASE(find_first_unset)
|
||||
{
|
||||
Bitmap bitmap(128, true);
|
||||
auto bitmap = Bitmap::must_create(128, true);
|
||||
bitmap.set(51, false);
|
||||
EXPECT_EQ(bitmap.find_first_unset().value(), 51u);
|
||||
}
|
||||
|
@ -31,7 +31,7 @@ TEST_CASE(find_first_unset)
|
|||
TEST_CASE(find_one_anywhere_set)
|
||||
{
|
||||
{
|
||||
Bitmap bitmap(168, false);
|
||||
auto bitmap = Bitmap::must_create(168, false);
|
||||
bitmap.set(34, true);
|
||||
bitmap.set(97, true);
|
||||
EXPECT_EQ(bitmap.find_one_anywhere_set(0).value(), 34u);
|
||||
|
@ -48,7 +48,7 @@ TEST_CASE(find_one_anywhere_set)
|
|||
EXPECT_EQ(bitmap.find_one_anywhere_set(128).value(), 34u);
|
||||
}
|
||||
{
|
||||
Bitmap bitmap(128 + 24, false);
|
||||
auto bitmap = Bitmap::must_create(128 + 24, false);
|
||||
bitmap.set(34, true);
|
||||
bitmap.set(126, true);
|
||||
EXPECT_EQ(bitmap.find_one_anywhere_set(0).value(), 34u);
|
||||
|
@ -56,7 +56,7 @@ TEST_CASE(find_one_anywhere_set)
|
|||
EXPECT_EQ(bitmap.find_one_anywhere_set(64).value(), 126u);
|
||||
}
|
||||
{
|
||||
Bitmap bitmap(32, false);
|
||||
auto bitmap = Bitmap::must_create(32, false);
|
||||
bitmap.set(12, true);
|
||||
bitmap.set(24, true);
|
||||
auto got = bitmap.find_one_anywhere_set(0).value();
|
||||
|
@ -67,7 +67,7 @@ TEST_CASE(find_one_anywhere_set)
|
|||
TEST_CASE(find_one_anywhere_unset)
|
||||
{
|
||||
{
|
||||
Bitmap bitmap(168, true);
|
||||
auto bitmap = Bitmap::must_create(168, true);
|
||||
bitmap.set(34, false);
|
||||
bitmap.set(97, false);
|
||||
EXPECT_EQ(bitmap.find_one_anywhere_unset(0).value(), 34u);
|
||||
|
@ -84,7 +84,7 @@ TEST_CASE(find_one_anywhere_unset)
|
|||
EXPECT_EQ(bitmap.find_one_anywhere_unset(128).value(), 34u);
|
||||
}
|
||||
{
|
||||
Bitmap bitmap(128 + 24, true);
|
||||
auto bitmap = Bitmap::must_create(128 + 24, true);
|
||||
bitmap.set(34, false);
|
||||
bitmap.set(126, false);
|
||||
EXPECT_EQ(bitmap.find_one_anywhere_unset(0).value(), 34u);
|
||||
|
@ -92,7 +92,7 @@ TEST_CASE(find_one_anywhere_unset)
|
|||
EXPECT_EQ(bitmap.find_one_anywhere_unset(64).value(), 126u);
|
||||
}
|
||||
{
|
||||
Bitmap bitmap(32, true);
|
||||
auto bitmap = Bitmap::must_create(32, true);
|
||||
bitmap.set(12, false);
|
||||
bitmap.set(24, false);
|
||||
auto got = bitmap.find_one_anywhere_unset(0).value();
|
||||
|
@ -102,7 +102,7 @@ TEST_CASE(find_one_anywhere_unset)
|
|||
|
||||
TEST_CASE(find_first_range)
|
||||
{
|
||||
Bitmap bitmap(128, true);
|
||||
auto bitmap = Bitmap::must_create(128, true);
|
||||
bitmap.set(47, false);
|
||||
bitmap.set(48, false);
|
||||
bitmap.set(49, false);
|
||||
|
@ -118,7 +118,7 @@ TEST_CASE(find_first_range)
|
|||
TEST_CASE(set_range)
|
||||
{
|
||||
{
|
||||
Bitmap bitmap(128, false);
|
||||
auto bitmap = Bitmap::must_create(128, false);
|
||||
bitmap.set_range(41, 10, true);
|
||||
EXPECT_EQ(bitmap.get(40), false);
|
||||
EXPECT_EQ(bitmap.get(41), true);
|
||||
|
@ -134,7 +134,7 @@ TEST_CASE(set_range)
|
|||
EXPECT_EQ(bitmap.get(51), false);
|
||||
}
|
||||
{
|
||||
Bitmap bitmap(288, false);
|
||||
auto bitmap = Bitmap::must_create(288, false);
|
||||
bitmap.set_range(48, 32, true);
|
||||
bitmap.set_range(94, 39, true);
|
||||
bitmap.set_range(190, 71, true);
|
||||
|
@ -152,12 +152,12 @@ TEST_CASE(set_range)
|
|||
TEST_CASE(find_first_fit)
|
||||
{
|
||||
{
|
||||
Bitmap bitmap(32, true);
|
||||
auto bitmap = Bitmap::must_create(32, true);
|
||||
auto fit = bitmap.find_first_fit(1);
|
||||
EXPECT_EQ(fit.has_value(), false);
|
||||
}
|
||||
{
|
||||
Bitmap bitmap(32, true);
|
||||
auto bitmap = Bitmap::must_create(32, true);
|
||||
bitmap.set(31, false);
|
||||
auto fit = bitmap.find_first_fit(1);
|
||||
EXPECT_EQ(fit.has_value(), true);
|
||||
|
@ -165,7 +165,7 @@ TEST_CASE(find_first_fit)
|
|||
}
|
||||
|
||||
for (size_t i = 0; i < 128; ++i) {
|
||||
Bitmap bitmap(128, true);
|
||||
auto bitmap = Bitmap::must_create(128, true);
|
||||
bitmap.set(i, false);
|
||||
auto fit = bitmap.find_first_fit(1);
|
||||
EXPECT_EQ(fit.has_value(), true);
|
||||
|
@ -173,7 +173,7 @@ TEST_CASE(find_first_fit)
|
|||
}
|
||||
|
||||
for (size_t i = 0; i < 127; ++i) {
|
||||
Bitmap bitmap(128, true);
|
||||
auto bitmap = Bitmap::must_create(128, true);
|
||||
bitmap.set(i, false);
|
||||
bitmap.set(i + 1, false);
|
||||
auto fit = bitmap.find_first_fit(2);
|
||||
|
@ -184,7 +184,7 @@ TEST_CASE(find_first_fit)
|
|||
size_t bitmap_size = 1024;
|
||||
for (size_t chunk_size = 1; chunk_size < 64; ++chunk_size) {
|
||||
for (size_t i = 0; i < bitmap_size - chunk_size; ++i) {
|
||||
Bitmap bitmap(bitmap_size, true);
|
||||
auto bitmap = Bitmap::must_create(bitmap_size, true);
|
||||
for (size_t c = 0; c < chunk_size; ++c)
|
||||
bitmap.set(i + c, false);
|
||||
auto fit = bitmap.find_first_fit(chunk_size);
|
||||
|
@ -196,7 +196,7 @@ TEST_CASE(find_first_fit)
|
|||
|
||||
TEST_CASE(find_longest_range_of_unset_bits_edge)
|
||||
{
|
||||
Bitmap bitmap(36, true);
|
||||
auto bitmap = Bitmap::must_create(36, true);
|
||||
bitmap.set_range(32, 4, false);
|
||||
size_t found_range_size = 0;
|
||||
auto result = bitmap.find_longest_range_of_unset_bits(1, found_range_size);
|
||||
|
@ -206,7 +206,7 @@ TEST_CASE(find_longest_range_of_unset_bits_edge)
|
|||
|
||||
TEST_CASE(count_in_range)
|
||||
{
|
||||
Bitmap bitmap(256, false);
|
||||
auto bitmap = Bitmap::must_create(256, false);
|
||||
bitmap.set(14, true);
|
||||
bitmap.set(17, true);
|
||||
bitmap.set(19, true);
|
||||
|
@ -252,14 +252,14 @@ TEST_CASE(count_in_range)
|
|||
TEST_CASE(byte_aligned_access)
|
||||
{
|
||||
{
|
||||
Bitmap bitmap(16, true);
|
||||
auto bitmap = Bitmap::must_create(16, true);
|
||||
EXPECT_EQ(bitmap.count_in_range(0, 16, true), 16u);
|
||||
EXPECT_EQ(bitmap.count_in_range(8, 8, true), 8u);
|
||||
EXPECT_EQ(bitmap.count_in_range(0, 8, true), 8u);
|
||||
EXPECT_EQ(bitmap.count_in_range(4, 8, true), 8u);
|
||||
}
|
||||
{
|
||||
Bitmap bitmap(16, false);
|
||||
auto bitmap = Bitmap::must_create(16, false);
|
||||
bitmap.set_range(4, 8, true);
|
||||
EXPECT_EQ(bitmap.count_in_range(0, 16, true), 8u);
|
||||
EXPECT_EQ(bitmap.count_in_range(8, 8, true), 4u);
|
||||
|
@ -267,7 +267,7 @@ TEST_CASE(byte_aligned_access)
|
|||
EXPECT_EQ(bitmap.count_in_range(4, 8, true), 8u);
|
||||
}
|
||||
{
|
||||
Bitmap bitmap(8, false);
|
||||
auto bitmap = Bitmap::must_create(8, false);
|
||||
bitmap.set(2, true);
|
||||
bitmap.set(4, true);
|
||||
EXPECT_EQ(bitmap.count_in_range(0, 2, true), 0u);
|
||||
|
|
|
@ -47,7 +47,7 @@ public:
|
|||
void will_track_seen_events(size_t profile_event_count)
|
||||
{
|
||||
if (m_seen_events.size() != profile_event_count)
|
||||
m_seen_events = Bitmap { profile_event_count, false };
|
||||
m_seen_events = Bitmap::must_create(profile_event_count, false);
|
||||
}
|
||||
bool has_seen_event(size_t event_index) const { return m_seen_events.get(event_index); }
|
||||
void did_see_event(size_t event_index) { m_seen_events.set(event_index, true); }
|
||||
|
|
Loading…
Reference in a new issue