mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-09-20 09:49:15 +03:00
UserspaceEmulator: Add a page-address-to-MMU-region lookup map
To make SoftMMU::find_region() O(1), this patch invests 3MiB into a lookup table where we track each possible page base address and map them to the SoftMMU::Region corresponding to that address. This is another large improvement to general emulation performance. :^)
This commit is contained in:
parent
a4a389156d
commit
59b4874443
Notes:
sideshowbarker
2024-07-19 01:22:50 +09:00
Author: https://github.com/awesomekling Commit: https://github.com/SerenityOS/serenity/commit/59b48744431
@ -37,24 +37,33 @@ SoftMMU::Region* SoftMMU::find_region(X86::LogicalAddress address)
|
||||
if (address.selector() == 0x28)
|
||||
return m_tls_region.ptr();
|
||||
|
||||
for (auto& region : m_regions) {
|
||||
if (region.contains(address.offset()))
|
||||
return ®ion;
|
||||
}
|
||||
return nullptr;
|
||||
size_t page_index = (address.offset() & ~(PAGE_SIZE - 1)) / PAGE_SIZE;
|
||||
return m_page_to_region_map[page_index];
|
||||
}
|
||||
|
||||
void SoftMMU::add_region(NonnullOwnPtr<Region> region)
|
||||
{
|
||||
ASSERT(!find_region({ 0x20, region->base() }));
|
||||
|
||||
// FIXME: More sanity checks pls
|
||||
if (region->is_shared_buffer())
|
||||
m_shbuf_regions.set(static_cast<SharedBufferRegion*>(region.ptr())->shbuf_id(), region.ptr());
|
||||
|
||||
size_t first_page_in_region = region->base() / PAGE_SIZE;
|
||||
for (size_t i = 0; i < ceil_div(region->size(), PAGE_SIZE); ++i) {
|
||||
m_page_to_region_map[first_page_in_region + i] = region.ptr();
|
||||
}
|
||||
|
||||
m_regions.append(move(region));
|
||||
}
|
||||
|
||||
void SoftMMU::remove_region(Region& region)
|
||||
{
|
||||
size_t first_page_in_region = region.base() / PAGE_SIZE;
|
||||
for (size_t i = 0; i < ceil_div(region.size(), PAGE_SIZE); ++i) {
|
||||
m_page_to_region_map[first_page_in_region + i] = nullptr;
|
||||
}
|
||||
|
||||
if (region.is_shared_buffer())
|
||||
m_shbuf_regions.remove(static_cast<SharedBufferRegion&>(region).shbuf_id());
|
||||
m_regions.remove_first_matching([&](auto& entry) { return entry.ptr() == ®ion; });
|
||||
|
@ -125,6 +125,8 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
Region* m_page_to_region_map[786432];
|
||||
|
||||
OwnPtr<Region> m_tls_region;
|
||||
NonnullOwnPtrVector<Region> m_regions;
|
||||
HashMap<int, Region*> m_shbuf_regions;
|
||||
|
Loading…
Reference in New Issue
Block a user