mirror of
https://github.com/yuzu-emu/unicorn.git
synced 2024-12-23 00:45:40 +00:00
memory: Share special empty FlatView
This shares an cached empty FlatView among address spaces. The empty FV is used every time when a root MR renders into a FV without memory sections which happens when MR or its children are not enabled or zero-sized. The empty_view is not NULL to keep the rest of memory API intact; it also has a dispatch tree for the same reason. On POWER8 with 255 CPUs, 255 virtio-net, 40 PCI bridges guest this halves the amount of FlatView's in use (557 -> 260) and dispatch tables (~800000 -> ~370000). In an unrelated experiment with 112 non-virtio devices on x86 ("-M pc"), only 4 FlatViews are alive, and about ~2000 are created at startup. Backports commit 092aa2fc65b7a35121616aad8f39d47b8f921618 from qemu
This commit is contained in:
parent
20b1bd767f
commit
b90333a531
|
@ -199,6 +199,7 @@ struct uc_struct {
|
||||||
uintptr_t helper_retaddr;
|
uintptr_t helper_retaddr;
|
||||||
|
|
||||||
// qemu/memory.c
|
// qemu/memory.c
|
||||||
|
FlatView *empty_view;
|
||||||
GHashTable *flat_views;
|
GHashTable *flat_views;
|
||||||
bool global_dirty_log;
|
bool global_dirty_log;
|
||||||
|
|
||||||
|
|
|
@ -2998,6 +2998,7 @@
|
||||||
#define unassigned_mem_ops unassigned_mem_ops_aarch64
|
#define unassigned_mem_ops unassigned_mem_ops_aarch64
|
||||||
#define unassigned_mem_read unassigned_mem_read_aarch64
|
#define unassigned_mem_read unassigned_mem_read_aarch64
|
||||||
#define unassigned_mem_write unassigned_mem_write_aarch64
|
#define unassigned_mem_write unassigned_mem_write_aarch64
|
||||||
|
#define unicorn_free_empty_flat_view unicorn_free_empty_flat_view_aarch64
|
||||||
#define update_spsel update_spsel_aarch64
|
#define update_spsel update_spsel_aarch64
|
||||||
#define use_idiv_instructions_rt use_idiv_instructions_rt_aarch64
|
#define use_idiv_instructions_rt use_idiv_instructions_rt_aarch64
|
||||||
#define v6_cp_reginfo v6_cp_reginfo_aarch64
|
#define v6_cp_reginfo v6_cp_reginfo_aarch64
|
||||||
|
|
|
@ -2998,6 +2998,7 @@
|
||||||
#define unassigned_mem_ops unassigned_mem_ops_aarch64eb
|
#define unassigned_mem_ops unassigned_mem_ops_aarch64eb
|
||||||
#define unassigned_mem_read unassigned_mem_read_aarch64eb
|
#define unassigned_mem_read unassigned_mem_read_aarch64eb
|
||||||
#define unassigned_mem_write unassigned_mem_write_aarch64eb
|
#define unassigned_mem_write unassigned_mem_write_aarch64eb
|
||||||
|
#define unicorn_free_empty_flat_view unicorn_free_empty_flat_view_aarch64eb
|
||||||
#define update_spsel update_spsel_aarch64eb
|
#define update_spsel update_spsel_aarch64eb
|
||||||
#define use_idiv_instructions_rt use_idiv_instructions_rt_aarch64eb
|
#define use_idiv_instructions_rt use_idiv_instructions_rt_aarch64eb
|
||||||
#define v6_cp_reginfo v6_cp_reginfo_aarch64eb
|
#define v6_cp_reginfo v6_cp_reginfo_aarch64eb
|
||||||
|
|
|
@ -2998,6 +2998,7 @@
|
||||||
#define unassigned_mem_ops unassigned_mem_ops_arm
|
#define unassigned_mem_ops unassigned_mem_ops_arm
|
||||||
#define unassigned_mem_read unassigned_mem_read_arm
|
#define unassigned_mem_read unassigned_mem_read_arm
|
||||||
#define unassigned_mem_write unassigned_mem_write_arm
|
#define unassigned_mem_write unassigned_mem_write_arm
|
||||||
|
#define unicorn_free_empty_flat_view unicorn_free_empty_flat_view_arm
|
||||||
#define update_spsel update_spsel_arm
|
#define update_spsel update_spsel_arm
|
||||||
#define use_idiv_instructions_rt use_idiv_instructions_rt_arm
|
#define use_idiv_instructions_rt use_idiv_instructions_rt_arm
|
||||||
#define v6_cp_reginfo v6_cp_reginfo_arm
|
#define v6_cp_reginfo v6_cp_reginfo_arm
|
||||||
|
|
|
@ -2998,6 +2998,7 @@
|
||||||
#define unassigned_mem_ops unassigned_mem_ops_armeb
|
#define unassigned_mem_ops unassigned_mem_ops_armeb
|
||||||
#define unassigned_mem_read unassigned_mem_read_armeb
|
#define unassigned_mem_read unassigned_mem_read_armeb
|
||||||
#define unassigned_mem_write unassigned_mem_write_armeb
|
#define unassigned_mem_write unassigned_mem_write_armeb
|
||||||
|
#define unicorn_free_empty_flat_view unicorn_free_empty_flat_view_armeb
|
||||||
#define update_spsel update_spsel_armeb
|
#define update_spsel update_spsel_armeb
|
||||||
#define use_idiv_instructions_rt use_idiv_instructions_rt_armeb
|
#define use_idiv_instructions_rt use_idiv_instructions_rt_armeb
|
||||||
#define v6_cp_reginfo v6_cp_reginfo_armeb
|
#define v6_cp_reginfo v6_cp_reginfo_armeb
|
||||||
|
|
|
@ -3004,6 +3004,7 @@ symbols = (
|
||||||
'unassigned_mem_ops',
|
'unassigned_mem_ops',
|
||||||
'unassigned_mem_read',
|
'unassigned_mem_read',
|
||||||
'unassigned_mem_write',
|
'unassigned_mem_write',
|
||||||
|
'unicorn_free_empty_flat_view',
|
||||||
'update_spsel',
|
'update_spsel',
|
||||||
'use_idiv_instructions_rt',
|
'use_idiv_instructions_rt',
|
||||||
'v6_cp_reginfo',
|
'v6_cp_reginfo',
|
||||||
|
|
|
@ -1379,6 +1379,8 @@ address_space_write_cached(MemoryRegionCache *cache, hwaddr addr,
|
||||||
address_space_write(cache->as, cache->xlat + addr, MEMTXATTRS_UNSPECIFIED, buf, len);
|
address_space_write(cache->as, cache->xlat + addr, MEMTXATTRS_UNSPECIFIED, buf, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void unicorn_free_empty_flat_view(struct uc_struct *uc);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -2998,6 +2998,7 @@
|
||||||
#define unassigned_mem_ops unassigned_mem_ops_m68k
|
#define unassigned_mem_ops unassigned_mem_ops_m68k
|
||||||
#define unassigned_mem_read unassigned_mem_read_m68k
|
#define unassigned_mem_read unassigned_mem_read_m68k
|
||||||
#define unassigned_mem_write unassigned_mem_write_m68k
|
#define unassigned_mem_write unassigned_mem_write_m68k
|
||||||
|
#define unicorn_free_empty_flat_view unicorn_free_empty_flat_view_m68k
|
||||||
#define update_spsel update_spsel_m68k
|
#define update_spsel update_spsel_m68k
|
||||||
#define use_idiv_instructions_rt use_idiv_instructions_rt_m68k
|
#define use_idiv_instructions_rt use_idiv_instructions_rt_m68k
|
||||||
#define v6_cp_reginfo v6_cp_reginfo_m68k
|
#define v6_cp_reginfo v6_cp_reginfo_m68k
|
||||||
|
|
|
@ -346,6 +346,15 @@ static void flatview_unref(FlatView *view)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void unicorn_free_empty_flat_view(struct uc_struct *uc)
|
||||||
|
{
|
||||||
|
if (!uc->empty_view) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
flatview_destroy(uc->empty_view);
|
||||||
|
}
|
||||||
|
|
||||||
FlatView *address_space_to_flatview(AddressSpace *as)
|
FlatView *address_space_to_flatview(AddressSpace *as)
|
||||||
{
|
{
|
||||||
// Unicorn: atomic_read used instead of atomic_rcu_read
|
// Unicorn: atomic_read used instead of atomic_rcu_read
|
||||||
|
@ -728,7 +737,7 @@ static MemoryRegion *memory_region_get_flatview_root(MemoryRegion *mr)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Render a memory topology into a list of disjoint absolute ranges. */
|
/* Render a memory topology into a list of disjoint absolute ranges. */
|
||||||
static FlatView *generate_memory_topology(MemoryRegion *mr)
|
static FlatView *generate_memory_topology(struct uc_struct *uc, MemoryRegion *mr)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
FlatView *view;
|
FlatView *view;
|
||||||
|
@ -741,14 +750,14 @@ static FlatView *generate_memory_topology(MemoryRegion *mr)
|
||||||
}
|
}
|
||||||
flatview_simplify(view);
|
flatview_simplify(view);
|
||||||
|
|
||||||
view->dispatch = address_space_dispatch_new(mr->uc, view);
|
view->dispatch = address_space_dispatch_new(uc, view);
|
||||||
for (i = 0; i < view->nr; i++) {
|
for (i = 0; i < view->nr; i++) {
|
||||||
MemoryRegionSection mrs =
|
MemoryRegionSection mrs =
|
||||||
section_from_flat_range(&view->ranges[i], view);
|
section_from_flat_range(&view->ranges[i], view);
|
||||||
flatview_add_to_dispatch(view, &mrs);
|
flatview_add_to_dispatch(view, &mrs);
|
||||||
}
|
}
|
||||||
address_space_dispatch_compact(view->dispatch);
|
address_space_dispatch_compact(view->dispatch);
|
||||||
g_hash_table_replace(mr->uc->flat_views, mr, view);
|
g_hash_table_replace(uc->flat_views, mr, view);
|
||||||
|
|
||||||
return view;
|
return view;
|
||||||
}
|
}
|
||||||
|
@ -838,6 +847,15 @@ static void flatviews_init(struct uc_struct *uc)
|
||||||
|
|
||||||
uc->flat_views = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL,
|
uc->flat_views = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL,
|
||||||
(GDestroyNotify) flatview_unref);
|
(GDestroyNotify) flatview_unref);
|
||||||
|
|
||||||
|
if (!uc->empty_view) {
|
||||||
|
uc->empty_view = generate_memory_topology(uc, NULL);
|
||||||
|
/* We keep it alive forever in the global variable. */
|
||||||
|
flatview_ref(uc->empty_view);
|
||||||
|
} else {
|
||||||
|
g_hash_table_replace(uc->flat_views, NULL, uc->empty_view);
|
||||||
|
flatview_ref(uc->empty_view);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void flatviews_reset(struct uc_struct *uc)
|
static void flatviews_reset(struct uc_struct *uc)
|
||||||
|
@ -858,7 +876,7 @@ static void flatviews_reset(struct uc_struct *uc)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
generate_memory_topology(physmr);
|
generate_memory_topology(uc, physmr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -915,7 +933,7 @@ static void address_space_update_topology(AddressSpace *as)
|
||||||
|
|
||||||
flatviews_init(uc);
|
flatviews_init(uc);
|
||||||
if (!g_hash_table_lookup(uc->flat_views, physmr)) {
|
if (!g_hash_table_lookup(uc->flat_views, physmr)) {
|
||||||
generate_memory_topology(physmr);
|
generate_memory_topology(uc, physmr);
|
||||||
}
|
}
|
||||||
address_space_set_flatview(as);
|
address_space_set_flatview(as);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2998,6 +2998,7 @@
|
||||||
#define unassigned_mem_ops unassigned_mem_ops_mips
|
#define unassigned_mem_ops unassigned_mem_ops_mips
|
||||||
#define unassigned_mem_read unassigned_mem_read_mips
|
#define unassigned_mem_read unassigned_mem_read_mips
|
||||||
#define unassigned_mem_write unassigned_mem_write_mips
|
#define unassigned_mem_write unassigned_mem_write_mips
|
||||||
|
#define unicorn_free_empty_flat_view unicorn_free_empty_flat_view_mips
|
||||||
#define update_spsel update_spsel_mips
|
#define update_spsel update_spsel_mips
|
||||||
#define use_idiv_instructions_rt use_idiv_instructions_rt_mips
|
#define use_idiv_instructions_rt use_idiv_instructions_rt_mips
|
||||||
#define v6_cp_reginfo v6_cp_reginfo_mips
|
#define v6_cp_reginfo v6_cp_reginfo_mips
|
||||||
|
|
|
@ -2998,6 +2998,7 @@
|
||||||
#define unassigned_mem_ops unassigned_mem_ops_mips64
|
#define unassigned_mem_ops unassigned_mem_ops_mips64
|
||||||
#define unassigned_mem_read unassigned_mem_read_mips64
|
#define unassigned_mem_read unassigned_mem_read_mips64
|
||||||
#define unassigned_mem_write unassigned_mem_write_mips64
|
#define unassigned_mem_write unassigned_mem_write_mips64
|
||||||
|
#define unicorn_free_empty_flat_view unicorn_free_empty_flat_view_mips64
|
||||||
#define update_spsel update_spsel_mips64
|
#define update_spsel update_spsel_mips64
|
||||||
#define use_idiv_instructions_rt use_idiv_instructions_rt_mips64
|
#define use_idiv_instructions_rt use_idiv_instructions_rt_mips64
|
||||||
#define v6_cp_reginfo v6_cp_reginfo_mips64
|
#define v6_cp_reginfo v6_cp_reginfo_mips64
|
||||||
|
|
|
@ -2998,6 +2998,7 @@
|
||||||
#define unassigned_mem_ops unassigned_mem_ops_mips64el
|
#define unassigned_mem_ops unassigned_mem_ops_mips64el
|
||||||
#define unassigned_mem_read unassigned_mem_read_mips64el
|
#define unassigned_mem_read unassigned_mem_read_mips64el
|
||||||
#define unassigned_mem_write unassigned_mem_write_mips64el
|
#define unassigned_mem_write unassigned_mem_write_mips64el
|
||||||
|
#define unicorn_free_empty_flat_view unicorn_free_empty_flat_view_mips64el
|
||||||
#define update_spsel update_spsel_mips64el
|
#define update_spsel update_spsel_mips64el
|
||||||
#define use_idiv_instructions_rt use_idiv_instructions_rt_mips64el
|
#define use_idiv_instructions_rt use_idiv_instructions_rt_mips64el
|
||||||
#define v6_cp_reginfo v6_cp_reginfo_mips64el
|
#define v6_cp_reginfo v6_cp_reginfo_mips64el
|
||||||
|
|
|
@ -2998,6 +2998,7 @@
|
||||||
#define unassigned_mem_ops unassigned_mem_ops_mipsel
|
#define unassigned_mem_ops unassigned_mem_ops_mipsel
|
||||||
#define unassigned_mem_read unassigned_mem_read_mipsel
|
#define unassigned_mem_read unassigned_mem_read_mipsel
|
||||||
#define unassigned_mem_write unassigned_mem_write_mipsel
|
#define unassigned_mem_write unassigned_mem_write_mipsel
|
||||||
|
#define unicorn_free_empty_flat_view unicorn_free_empty_flat_view_mipsel
|
||||||
#define update_spsel update_spsel_mipsel
|
#define update_spsel update_spsel_mipsel
|
||||||
#define use_idiv_instructions_rt use_idiv_instructions_rt_mipsel
|
#define use_idiv_instructions_rt use_idiv_instructions_rt_mipsel
|
||||||
#define v6_cp_reginfo v6_cp_reginfo_mipsel
|
#define v6_cp_reginfo v6_cp_reginfo_mipsel
|
||||||
|
|
|
@ -2998,6 +2998,7 @@
|
||||||
#define unassigned_mem_ops unassigned_mem_ops_powerpc
|
#define unassigned_mem_ops unassigned_mem_ops_powerpc
|
||||||
#define unassigned_mem_read unassigned_mem_read_powerpc
|
#define unassigned_mem_read unassigned_mem_read_powerpc
|
||||||
#define unassigned_mem_write unassigned_mem_write_powerpc
|
#define unassigned_mem_write unassigned_mem_write_powerpc
|
||||||
|
#define unicorn_free_empty_flat_view unicorn_free_empty_flat_view_powerpc
|
||||||
#define update_spsel update_spsel_powerpc
|
#define update_spsel update_spsel_powerpc
|
||||||
#define use_idiv_instructions_rt use_idiv_instructions_rt_powerpc
|
#define use_idiv_instructions_rt use_idiv_instructions_rt_powerpc
|
||||||
#define v6_cp_reginfo v6_cp_reginfo_powerpc
|
#define v6_cp_reginfo v6_cp_reginfo_powerpc
|
||||||
|
|
|
@ -2998,6 +2998,7 @@
|
||||||
#define unassigned_mem_ops unassigned_mem_ops_sparc
|
#define unassigned_mem_ops unassigned_mem_ops_sparc
|
||||||
#define unassigned_mem_read unassigned_mem_read_sparc
|
#define unassigned_mem_read unassigned_mem_read_sparc
|
||||||
#define unassigned_mem_write unassigned_mem_write_sparc
|
#define unassigned_mem_write unassigned_mem_write_sparc
|
||||||
|
#define unicorn_free_empty_flat_view unicorn_free_empty_flat_view_sparc
|
||||||
#define update_spsel update_spsel_sparc
|
#define update_spsel update_spsel_sparc
|
||||||
#define use_idiv_instructions_rt use_idiv_instructions_rt_sparc
|
#define use_idiv_instructions_rt use_idiv_instructions_rt_sparc
|
||||||
#define v6_cp_reginfo v6_cp_reginfo_sparc
|
#define v6_cp_reginfo v6_cp_reginfo_sparc
|
||||||
|
|
|
@ -2998,6 +2998,7 @@
|
||||||
#define unassigned_mem_ops unassigned_mem_ops_sparc64
|
#define unassigned_mem_ops unassigned_mem_ops_sparc64
|
||||||
#define unassigned_mem_read unassigned_mem_read_sparc64
|
#define unassigned_mem_read unassigned_mem_read_sparc64
|
||||||
#define unassigned_mem_write unassigned_mem_write_sparc64
|
#define unassigned_mem_write unassigned_mem_write_sparc64
|
||||||
|
#define unicorn_free_empty_flat_view unicorn_free_empty_flat_view_sparc64
|
||||||
#define update_spsel update_spsel_sparc64
|
#define update_spsel update_spsel_sparc64
|
||||||
#define use_idiv_instructions_rt use_idiv_instructions_rt_sparc64
|
#define use_idiv_instructions_rt use_idiv_instructions_rt_sparc64
|
||||||
#define v6_cp_reginfo v6_cp_reginfo_sparc64
|
#define v6_cp_reginfo v6_cp_reginfo_sparc64
|
||||||
|
|
|
@ -80,6 +80,7 @@ static void release_common(void *t)
|
||||||
|
|
||||||
// Destory flat view hash table
|
// Destory flat view hash table
|
||||||
g_hash_table_destroy(s->uc->flat_views);
|
g_hash_table_destroy(s->uc->flat_views);
|
||||||
|
unicorn_free_empty_flat_view(s->uc);
|
||||||
|
|
||||||
// TODO(danghvu): these function is not available outside qemu
|
// TODO(danghvu): these function is not available outside qemu
|
||||||
// so we keep them here instead of outside uc_close.
|
// so we keep them here instead of outside uc_close.
|
||||||
|
|
|
@ -2998,6 +2998,7 @@
|
||||||
#define unassigned_mem_ops unassigned_mem_ops_x86_64
|
#define unassigned_mem_ops unassigned_mem_ops_x86_64
|
||||||
#define unassigned_mem_read unassigned_mem_read_x86_64
|
#define unassigned_mem_read unassigned_mem_read_x86_64
|
||||||
#define unassigned_mem_write unassigned_mem_write_x86_64
|
#define unassigned_mem_write unassigned_mem_write_x86_64
|
||||||
|
#define unicorn_free_empty_flat_view unicorn_free_empty_flat_view_x86_64
|
||||||
#define update_spsel update_spsel_x86_64
|
#define update_spsel update_spsel_x86_64
|
||||||
#define use_idiv_instructions_rt use_idiv_instructions_rt_x86_64
|
#define use_idiv_instructions_rt use_idiv_instructions_rt_x86_64
|
||||||
#define v6_cp_reginfo v6_cp_reginfo_x86_64
|
#define v6_cp_reginfo v6_cp_reginfo_x86_64
|
||||||
|
|
Loading…
Reference in a new issue