mirror of
https://github.com/yuzu-emu/unicorn
synced 2024-11-24 02:53:42 +00:00
memleak: refactor unicorn_common.h, move stuff to uc_close
This commit is contained in:
parent
ada1c13662
commit
6b9f17f2f7
2 changed files with 55 additions and 51 deletions
|
@ -2,6 +2,7 @@
|
|||
#define UNICORN_COMMON_H_
|
||||
|
||||
#include "tcg.h"
|
||||
#include <sys/mman.h>
|
||||
|
||||
// This header define common patterns/codes that will be included in all arch-sepcific
|
||||
// codes for unicorns purposes.
|
||||
|
@ -19,23 +20,12 @@ static inline bool cpu_physical_mem_write(AddressSpace *as, hwaddr addr,
|
|||
return !cpu_physical_memory_rw(as, addr, (void *)buf, len, 1);
|
||||
}
|
||||
|
||||
static void free_table(gpointer key, gpointer value, gpointer data)
|
||||
{
|
||||
TypeInfo *ti = (TypeInfo*) value;
|
||||
g_free((void*) ti->class);
|
||||
g_free((void*) ti->name);
|
||||
g_free((void*) ti->parent);
|
||||
g_free((void*) ti);
|
||||
}
|
||||
|
||||
void tb_cleanup(struct uc_struct *uc);
|
||||
|
||||
/** Freeing common resources */
|
||||
static void release_common(void *t)
|
||||
{
|
||||
TCGContext *s = (TCGContext *)t;
|
||||
struct uc_struct* uc = s->uc;
|
||||
CPUState *cpu;
|
||||
#if TCG_TARGET_REG_BITS == 32
|
||||
int i;
|
||||
#endif
|
||||
|
@ -45,7 +35,9 @@ static void release_common(void *t)
|
|||
g_free(def->args_ct);
|
||||
g_free(def->sorted_args);
|
||||
g_free(s->tcg_op_defs);
|
||||
g_free(s->code_gen_buffer);
|
||||
if (s->code_gen_buffer) {
|
||||
munmap(s->code_gen_buffer, s->code_gen_buffer_size);
|
||||
}
|
||||
|
||||
TCGPool *po, *to;
|
||||
for (po = s->pool_first; po; po = to) {
|
||||
|
@ -55,36 +47,11 @@ static void release_common(void *t)
|
|||
tcg_pool_reset(s);
|
||||
g_hash_table_destroy(s->helpers);
|
||||
|
||||
// Clean memory.
|
||||
phys_mem_clean(uc);
|
||||
address_space_destroy(&(uc->as));
|
||||
memory_free(uc);
|
||||
|
||||
// Clean CPU.
|
||||
CPU_FOREACH(cpu) {
|
||||
g_free(cpu->tcg_as_listener);
|
||||
g_free(cpu->thread);
|
||||
g_free(cpu->halt_cond);
|
||||
}
|
||||
|
||||
OBJECT(uc->machine_state->accelerator)->ref = 1;
|
||||
OBJECT(uc->machine_state)->ref = 1;
|
||||
OBJECT(uc->owner)->ref = 1;
|
||||
OBJECT(uc->root)->ref = 1;
|
||||
|
||||
object_unref(uc, OBJECT(uc->machine_state->accelerator));
|
||||
object_unref(uc, OBJECT(uc->machine_state));
|
||||
object_unref(uc, uc->cpu);
|
||||
object_unref(uc, OBJECT(&uc->io_mem_notdirty));
|
||||
object_unref(uc, OBJECT(&uc->io_mem_unassigned));
|
||||
object_unref(uc, OBJECT(&uc->io_mem_rom));
|
||||
object_unref(uc, OBJECT(uc->root));
|
||||
g_hash_table_foreach(uc->type_table, free_table, uc);
|
||||
|
||||
g_free(uc->system_memory);
|
||||
|
||||
if (uc->qemu_thread_data)
|
||||
free(uc->qemu_thread_data);
|
||||
// TODO(danghvu): these function is not available outside qemu
|
||||
// so we keep them here instead of outside uc_close.
|
||||
phys_mem_clean(s->uc);
|
||||
address_space_destroy(&(s->uc->as));
|
||||
memory_free(s->uc);
|
||||
|
||||
#if TCG_TARGET_REG_BITS == 32
|
||||
for(i = 0; i < s->nb_globals; i++) {
|
||||
|
@ -97,12 +64,6 @@ static void release_common(void *t)
|
|||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
qemu_mutex_destroy(&uc->qemu_global_mutex);
|
||||
qemu_cond_destroy(&uc->qemu_cpu_cond);
|
||||
|
||||
// Clean cache.
|
||||
tb_cleanup(uc);
|
||||
}
|
||||
|
||||
static inline void uc_common_init(struct uc_struct* uc)
|
||||
|
|
49
uc.c
49
uc.c
|
@ -29,7 +29,16 @@
|
|||
#include "qemu/target-sparc/unicorn.h"
|
||||
|
||||
#include "qemu/include/hw/boards.h"
|
||||
#include "qemu/include/qemu/queue.h"
|
||||
|
||||
static void free_table(gpointer key, gpointer value, gpointer data)
|
||||
{
|
||||
TypeInfo *ti = (TypeInfo*) value;
|
||||
g_free((void*) ti->class);
|
||||
g_free((void*) ti->name);
|
||||
g_free((void*) ti->parent);
|
||||
g_free((void*) ti);
|
||||
}
|
||||
|
||||
UNICORN_EXPORT
|
||||
unsigned int uc_version(unsigned int *major, unsigned int *minor)
|
||||
|
@ -283,19 +292,53 @@ uc_err uc_close(uc_engine *uc)
|
|||
int i;
|
||||
struct list_item *cur;
|
||||
struct hook *hook;
|
||||
CPUState *cpu;
|
||||
|
||||
// Cleanup internally.
|
||||
if (uc->release)
|
||||
uc->release(uc->tcg_ctx);
|
||||
g_free(uc->tcg_ctx);
|
||||
|
||||
// Cleanup CPU.
|
||||
CPU_FOREACH(cpu) {
|
||||
g_free(cpu->tcg_as_listener);
|
||||
g_free(cpu->thread);
|
||||
g_free(cpu->halt_cond);
|
||||
}
|
||||
|
||||
// Cleanup all objects.
|
||||
OBJECT(uc->machine_state->accelerator)->ref = 1;
|
||||
OBJECT(uc->machine_state)->ref = 1;
|
||||
OBJECT(uc->owner)->ref = 1;
|
||||
OBJECT(uc->root)->ref = 1;
|
||||
|
||||
object_unref(uc, OBJECT(uc->machine_state->accelerator));
|
||||
object_unref(uc, OBJECT(uc->machine_state));
|
||||
object_unref(uc, uc->cpu);
|
||||
object_unref(uc, OBJECT(&uc->io_mem_notdirty));
|
||||
object_unref(uc, OBJECT(&uc->io_mem_unassigned));
|
||||
object_unref(uc, OBJECT(&uc->io_mem_rom));
|
||||
object_unref(uc, OBJECT(uc->root));
|
||||
|
||||
// System memory.
|
||||
g_free(uc->system_memory);
|
||||
|
||||
// Thread relateds.
|
||||
if (uc->qemu_thread_data)
|
||||
free(uc->qemu_thread_data);
|
||||
|
||||
qemu_mutex_destroy(&uc->qemu_global_mutex);
|
||||
qemu_cond_destroy(&uc->qemu_cpu_cond);
|
||||
|
||||
// Other auxilaries.
|
||||
free(uc->l1_map);
|
||||
|
||||
if (uc->bounce.buffer) {
|
||||
free(uc->bounce.buffer);
|
||||
}
|
||||
|
||||
g_free(uc->tcg_ctx);
|
||||
|
||||
g_hash_table_destroy(uc->type_table);
|
||||
g_hash_table_foreach(uc->type_table, free_table, uc);
|
||||
g_hash_table_unref(uc->type_table);
|
||||
|
||||
for (i = 0; i < DIRTY_MEMORY_NUM; i++) {
|
||||
free(uc->ram_list.dirty_memory[i]);
|
||||
|
|
Loading…
Reference in a new issue