Repository: SerenityOS/serenity
File: Kernel/Memory/Region.cpp (C++)

Code before:
        page_slot = static_cast<AnonymousVMObject&>(*m_vmobject).allocate_committed_page({});
        if (!remap_vmobject_page(page_index_in_vmobject, *page_slot))
            return PageFaultResponse::OutOfMemory;
        return PageFaultResponse::Continue;
    }

    dbgln("Unexpected page fault in Region({})[{}] at {}", this, page_index_in_region, fault.vaddr());
    return PageFaultResponse::ShouldCrash;
#endif
}

PageFaultResponse Region::handle_zero_fault(size_t page_index_in_region, PhysicalRAMPage& page_in_slot_at_time_of_fault)
{
    VERIFY(vmobject().is_anonymous());

    auto& anon_vmobject = static_cast<AnonymousVMObject&>(vmobject());
    auto page_index_in_vmobject = translate_to_vmobject_page(page_index_in_region);

    auto current_thread = Thread::current();
    if (current_thread != nullptr)
        current_thread->did_zero_fault();

    RefPtr<PhysicalRAMPage> new_physical_page;

    if (page_in_slot_at_time_of_fault.is_lazy_committed_page()) {
        new_physical_page = anon_vmobject.allocate_committed_page({});
        dbgln_if(PAGE_FAULT_DEBUG, "      >> ALLOCATED COMMITTED {}", new_physical_page->paddr());
    } else {
        auto page_or_error = MM.allocate_physical_page(MemoryManager::ShouldZeroFill::Yes);
        if (page_or_error.is_error()) {
            dmesgln("MM: handle_zero_fault was unable to allocate a physical page");
            return PageFaultResponse::OutOfMemory;
        }
        new_physical_page = page_or_error.release_value();
        dbgln_if(PAGE_FAULT_DEBUG, "      >> ALLOCATED {}", new_physical_page->paddr());
    }

    {
        SpinlockLocker locker(anon_vmobject.m_lock);
        auto& page_slot = physical_page_slot(page_index_in_region);
        bool already_handled = !page_slot.is_null() && !page_slot->is_shared_zero_page() && !page_slot->is_lazy_committed_page();
        if (already_handled) {
            // Someone else already faulted in a new page in this slot. That's fine, we'll just remap with their page.
            new_physical_page = page_slot;
        } else {
            // Install the newly allocated page into the VMObject.
            page_slot = new_physical_page;
        }
    }

    if (!remap_vmobject_page(page_index_in_vmobject, *new_physical_page)) {

Review comment (refactor):
This change and the change below look more like a general refactoring, maybe move them into a separate commit

Code after:
    }

    if (vmobject().is_inode()) {
        dbgln_if(PAGE_FAULT_DEBUG, "Inode page fault in Region({})[{}]", this, page_index_in_region);
        return handle_inode_fault(page_index_in_region);
    }

    SpinlockLocker vmobject_locker(vmobject().m_lock);
    auto& page_slot = physical_page_slot(page_index_in_region);
    if (page_slot->is_lazy_committed_page()) {
        auto page_index_in_vmobject = translate_to_vmobject_page(page_index_in_region);
        VERIFY(m_vmobject->is_anonymous());
        page_slot = static_cast<AnonymousVMObject&>(*m_vmobject).allocate_committed_page({});
        if (!remap_vmobject_page(page_index_in_vmobject, *page_slot))
            return PageFaultResponse::OutOfMemory;
        return PageFaultResponse::Continue;
    }

    dbgln("Unexpected page fault in Region({})[{}] at {}", this, page_index_in_region, fault.vaddr());
    return PageFaultResponse::ShouldCrash;
#endif
}

PageFaultResponse Region::handle_zero_fault(size_t page_index_in_region, PhysicalRAMPage& page_in_slot_at_time_of_fault)
{
    VERIFY(vmobject().is_anonymous());

    auto& anonymous_vmobject = static_cast<AnonymousVMObject&>(vmobject());
    auto page_index_in_vmobject = translate_to_vmobject_page(page_index_in_region);

    auto current_thread = Thread::current();
    if (current_thread != nullptr)
        current_thread->did_zero_fault();

    RefPtr<PhysicalRAMPage> new_physical_page;

    if (page_in_slot_at_time_of_fault.is_lazy_committed_page()) {
        new_physical_page = anonymous_vmobject.allocate_committed_page({});
        dbgln_if(PAGE_FAULT_DEBUG, "      >> ALLOCATED COMMITTED {}", new_physical_page->paddr());
    } else {
        auto page_or_error = MM.allocate_physical_page(MemoryManager::ShouldZeroFill::Yes);
        if (page_or_error.is_error()) {
            dmesgln("MM: handle_zero_fault was unable to allocate a physical page");
            return PageFaultResponse::OutOfMemory;
        }
        new_physical_page = page_or_error.release_value();
        dbgln_if(PAGE_FAULT_DEBUG, "      >> ALLOCATED {}", new_physical_page->paddr());
    }

    {
        SpinlockLocker locker(anonymous_vmobject.m_lock);