mirror of
https://github.com/yuzu-emu/unicorn.git
synced 2025-01-05 19:15:40 +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;
|
uint8_t dirty_log_mask;
|
||||||
ram_addr_t ram_addr;
|
ram_addr_t ram_addr;
|
||||||
const MemoryRegionIOMMUOps *iommu_ops;
|
const MemoryRegionIOMMUOps *iommu_ops;
|
||||||
|
Object *owner;
|
||||||
|
|
||||||
const MemoryRegionOps *ops;
|
const MemoryRegionOps *ops;
|
||||||
void *opaque;
|
void *opaque;
|
||||||
|
|
|
@ -861,11 +861,6 @@ void memory_region_init(struct uc_struct *uc, MemoryRegion *mr,
|
||||||
const char *name,
|
const char *name,
|
||||||
uint64_t size)
|
uint64_t size)
|
||||||
{
|
{
|
||||||
if (!owner) {
|
|
||||||
owner = qdev_get_machine(uc);
|
|
||||||
uc->owner = owner;
|
|
||||||
}
|
|
||||||
|
|
||||||
object_initialize(uc, mr, sizeof(*mr), TYPE_MEMORY_REGION);
|
object_initialize(uc, mr, sizeof(*mr), TYPE_MEMORY_REGION);
|
||||||
mr->uc = uc;
|
mr->uc = uc;
|
||||||
mr->size = int128_make64(size);
|
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->size = int128_2_64();
|
||||||
}
|
}
|
||||||
mr->name = g_strdup(name);
|
mr->name = g_strdup(name);
|
||||||
|
mr->owner = owner;
|
||||||
|
|
||||||
if (name) {
|
if (name) {
|
||||||
char *escaped_name = memory_region_escape_name(name);
|
char *escaped_name = memory_region_escape_name(name);
|
||||||
char *name_array = g_strdup_printf("%s[*]", escaped_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_property_add_child(owner, name_array, OBJECT(mr), &error_abort);
|
||||||
object_unref(uc, OBJECT(mr));
|
object_unref(uc, OBJECT(mr));
|
||||||
g_free(name_array);
|
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
|
* The memory region is a child of its owner. As long as the
|
||||||
* owner doesn't call unparent itself on the memory region,
|
* owner doesn't call unparent itself on the memory region,
|
||||||
* ref-ing the owner will also keep the memory region alive.
|
* ref-ing the owner will also keep the memory region alive.
|
||||||
* Memory regions without an owner are supposed to never go away,
|
* Memory regions without an owner are supposed to never go away;
|
||||||
* but we still ref/unref them for debugging purposes.
|
* we do not ref/unref them because it slows down DMA sensibly.
|
||||||
*/
|
*/
|
||||||
Object *obj = OBJECT(mr);
|
if (mr && mr->owner) {
|
||||||
if (obj && obj->parent) {
|
object_ref(mr->owner);
|
||||||
object_ref(obj->parent);
|
|
||||||
} else {
|
|
||||||
object_ref(obj);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void memory_region_unref(MemoryRegion *mr)
|
void memory_region_unref(MemoryRegion *mr)
|
||||||
{
|
{
|
||||||
Object *obj = OBJECT(mr);
|
if (mr && mr->owner) {
|
||||||
if (obj && obj->parent) {
|
object_unref(mr->uc, mr->owner);
|
||||||
object_unref(mr->uc, obj->parent);
|
|
||||||
} else {
|
|
||||||
object_unref(mr->uc, obj);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue