mirror of
https://github.com/yuzu-emu/unicorn.git
synced 2025-02-24 23:46:58 +00:00
memory: Open code FlatView rendering
We are going to share FlatView's between AddressSpace's and per-AS memory listeners won't suit the purpose anymore so open code the dispatch tree rendering. Since there is a good chance that dispatch_listener was the only listener, this avoids address_space_update_topology_pass() if there is no registered listeners; this should improve starting time. This should cause no behavioural change. Backports commit 1b04a1580917d9e41fd37ca62cbff9b4bf061e96 from qemu
This commit is contained in:
parent
f74fcb194f
commit
e723b8dd49
30
qemu/exec.c
30
qemu/exec.c
|
@ -1080,9 +1080,8 @@ static void register_multipage(struct uc_struct *uc,
|
|||
phys_page_set(uc, d, start_addr >> TARGET_PAGE_BITS, num_pages, section_index);
|
||||
}
|
||||
|
||||
static void mem_add(MemoryListener *listener, MemoryRegionSection *section)
|
||||
void mem_add(AddressSpace *as, MemoryRegionSection *section)
|
||||
{
|
||||
AddressSpace *as = container_of(listener, AddressSpace, dispatch_listener);
|
||||
AddressSpaceDispatch *d = as->next_dispatch;
|
||||
MemoryRegionSection now = *section, remain = *section;
|
||||
Int128 page_size = int128_make64(TARGET_PAGE_SIZE);
|
||||
|
@ -1845,9 +1844,8 @@ void phys_mem_clean(AddressSpace *as)
|
|||
g_free(d->map.sections);
|
||||
}
|
||||
|
||||
static void mem_begin(MemoryListener *listener)
|
||||
void mem_begin(AddressSpace *as)
|
||||
{
|
||||
AddressSpace *as = container_of(listener, AddressSpace, dispatch_listener);
|
||||
AddressSpaceDispatch *d = g_new0(AddressSpaceDispatch, 1);
|
||||
uint16_t n;
|
||||
PhysPageEntry ppe = { 1, PHYS_MAP_NODE_NIL };
|
||||
|
@ -1867,9 +1865,8 @@ static void mem_begin(MemoryListener *listener)
|
|||
as->next_dispatch = d;
|
||||
}
|
||||
|
||||
static void mem_commit(MemoryListener *listener)
|
||||
void mem_commit(AddressSpace *as)
|
||||
{
|
||||
AddressSpace *as = container_of(listener, AddressSpace, dispatch_listener);
|
||||
AddressSpaceDispatch *cur = as->dispatch;
|
||||
AddressSpaceDispatch *next = as->next_dispatch;
|
||||
|
||||
|
@ -1903,31 +1900,10 @@ static void tcg_commit(MemoryListener *listener)
|
|||
tlb_flush(cpuas->cpu);
|
||||
}
|
||||
|
||||
void address_space_init_dispatch(AddressSpace *as)
|
||||
{
|
||||
MemoryListener ml = { 0 };
|
||||
|
||||
ml.begin = mem_begin;
|
||||
ml.commit = mem_commit;
|
||||
ml.region_add = mem_add;
|
||||
ml.region_nop = mem_add;
|
||||
ml.priority = 0;
|
||||
|
||||
as->dispatch = NULL;
|
||||
as->dispatch_listener = ml;
|
||||
memory_listener_register(as->uc, &as->dispatch_listener, as);
|
||||
}
|
||||
|
||||
void address_space_unregister(AddressSpace *as)
|
||||
{
|
||||
memory_listener_unregister(as->uc, &as->dispatch_listener);
|
||||
}
|
||||
|
||||
void address_space_destroy_dispatch(AddressSpace *as)
|
||||
{
|
||||
AddressSpaceDispatch *d = as->dispatch;
|
||||
|
||||
memory_listener_unregister(as->uc, &as->dispatch_listener);
|
||||
g_free(d->map.nodes);
|
||||
g_free(d);
|
||||
|
||||
|
|
|
@ -22,7 +22,6 @@
|
|||
#ifndef CONFIG_USER_ONLY
|
||||
typedef struct AddressSpaceDispatch AddressSpaceDispatch;
|
||||
|
||||
void address_space_init_dispatch(AddressSpace *as);
|
||||
void address_space_destroy_dispatch(AddressSpace *as);
|
||||
|
||||
extern const MemoryRegionOps unassigned_mem_ops;
|
||||
|
@ -30,7 +29,9 @@ extern const MemoryRegionOps unassigned_mem_ops;
|
|||
bool memory_region_access_valid(MemoryRegion *mr, hwaddr addr,
|
||||
unsigned size, bool is_write);
|
||||
|
||||
void address_space_unregister(AddressSpace *as);
|
||||
void mem_add(AddressSpace *as, MemoryRegionSection *section);
|
||||
void mem_begin(AddressSpace *as);
|
||||
void mem_commit(AddressSpace *as);
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -236,7 +236,6 @@ struct AddressSpace {
|
|||
struct FlatView *current_map;
|
||||
struct AddressSpaceDispatch *dispatch;
|
||||
struct AddressSpaceDispatch *next_dispatch;
|
||||
MemoryListener dispatch_listener;
|
||||
struct uc_struct* uc;
|
||||
|
||||
QTAILQ_HEAD(memory_listeners_as, MemoryListener) listeners;
|
||||
|
|
|
@ -757,9 +757,20 @@ static void address_space_update_topology(AddressSpace *as)
|
|||
{
|
||||
FlatView *old_view = address_space_get_flatview(as);
|
||||
FlatView *new_view = generate_memory_topology(as->root);
|
||||
int i;
|
||||
|
||||
address_space_update_topology_pass(as, old_view, new_view, false);
|
||||
address_space_update_topology_pass(as, old_view, new_view, true);
|
||||
mem_begin(as);
|
||||
for (i = 0; i < new_view->nr; i++) {
|
||||
MemoryRegionSection mrs =
|
||||
section_from_flat_range(&new_view->ranges[i], as);
|
||||
mem_add(as, &mrs);
|
||||
}
|
||||
mem_commit(as);
|
||||
|
||||
if (!QTAILQ_EMPTY(&as->listeners)) {
|
||||
address_space_update_topology_pass(as, old_view, new_view, false);
|
||||
address_space_update_topology_pass(as, old_view, new_view, true);
|
||||
}
|
||||
|
||||
flatview_unref(as->current_map);
|
||||
as->current_map = new_view;
|
||||
|
@ -1798,7 +1809,7 @@ void address_space_init(struct uc_struct *uc, AddressSpace *as, MemoryRegion *ro
|
|||
QTAILQ_INIT(&as->listeners);
|
||||
QTAILQ_INSERT_TAIL(&uc->address_spaces, as, address_spaces_link);
|
||||
as->name = g_strdup(name ? name : "anonymous");
|
||||
address_space_init_dispatch(as);
|
||||
as->dispatch = NULL;
|
||||
uc->memory_region_update_pending |= root->enabled;
|
||||
memory_region_transaction_commit(uc);
|
||||
}
|
||||
|
@ -1856,7 +1867,6 @@ void address_space_destroy(AddressSpace *as)
|
|||
as->root = NULL;
|
||||
memory_region_transaction_commit(as->uc);
|
||||
QTAILQ_REMOVE(&as->uc->address_spaces, as, address_spaces_link);
|
||||
address_space_unregister(as);
|
||||
|
||||
/* At this point, as->dispatch and as->current_map are dummy
|
||||
* entries that the guest should never use. Wait for the old
|
||||
|
|
Loading…
Reference in a new issue