mirror of
https://github.com/yuzu-emu/unicorn.git
synced 2024-12-31 23:15:44 +00:00
memory: avoid unnecessary object_ref/unref
For the common case of DMA into non-hotplugged RAM, it is unnecessary but expensive to do object_ref/unref. Add back an owner field to MemoryRegion, so that these memory regions can skip the reference counting. Backports commit 612263cf33062f7441a5d0e3b37c65991fdc3210 from qemu
This commit is contained in:
parent
e6b25279f8
commit
077ffc3bd5
|
@ -162,6 +162,7 @@ struct MemoryRegion {
|
|||
uint8_t dirty_log_mask;
|
||||
ram_addr_t ram_addr;
|
||||
const MemoryRegionIOMMUOps *iommu_ops;
|
||||
Object *owner;
|
||||
|
||||
const MemoryRegionOps *ops;
|
||||
void *opaque;
|
||||
|
|
|
@ -861,11 +861,6 @@ void memory_region_init(struct uc_struct *uc, MemoryRegion *mr,
|
|||
const char *name,
|
||||
uint64_t size)
|
||||
{
|
||||
if (!owner) {
|
||||
owner = qdev_get_machine(uc);
|
||||
uc->owner = owner;
|
||||
}
|
||||
|
||||
object_initialize(uc, mr, sizeof(*mr), TYPE_MEMORY_REGION);
|
||||
mr->uc = uc;
|
||||
mr->size = int128_make64(size);
|
||||
|
@ -873,10 +868,17 @@ void memory_region_init(struct uc_struct *uc, MemoryRegion *mr,
|
|||
mr->size = int128_2_64();
|
||||
}
|
||||
mr->name = g_strdup(name);
|
||||
mr->owner = owner;
|
||||
|
||||
if (name) {
|
||||
char *escaped_name = memory_region_escape_name(name);
|
||||
char *name_array = g_strdup_printf("%s[*]", escaped_name);
|
||||
|
||||
if (!owner) {
|
||||
owner = qdev_get_machine(uc);
|
||||
uc->owner = owner;
|
||||
}
|
||||
|
||||
object_property_add_child(owner, name_array, OBJECT(mr), &error_abort);
|
||||
object_unref(uc, OBJECT(mr));
|
||||
g_free(name_array);
|
||||
|
@ -1260,24 +1262,18 @@ void memory_region_ref(MemoryRegion *mr)
|
|||
* The memory region is a child of its owner. As long as the
|
||||
* owner doesn't call unparent itself on the memory region,
|
||||
* ref-ing the owner will also keep the memory region alive.
|
||||
* Memory regions without an owner are supposed to never go away,
|
||||
* but we still ref/unref them for debugging purposes.
|
||||
* Memory regions without an owner are supposed to never go away;
|
||||
* we do not ref/unref them because it slows down DMA sensibly.
|
||||
*/
|
||||
Object *obj = OBJECT(mr);
|
||||
if (obj && obj->parent) {
|
||||
object_ref(obj->parent);
|
||||
} else {
|
||||
object_ref(obj);
|
||||
if (mr && mr->owner) {
|
||||
object_ref(mr->owner);
|
||||
}
|
||||
}
|
||||
|
||||
void memory_region_unref(MemoryRegion *mr)
|
||||
{
|
||||
Object *obj = OBJECT(mr);
|
||||
if (obj && obj->parent) {
|
||||
object_unref(mr->uc, obj->parent);
|
||||
} else {
|
||||
object_unref(mr->uc, obj);
|
||||
if (mr && mr->owner) {
|
||||
object_unref(mr->uc, mr->owner);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue