mirror of
https://github.com/yuzu-emu/unicorn
synced 2024-11-24 05:18:08 +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_
|
#define UNICORN_COMMON_H_
|
||||||
|
|
||||||
#include "tcg.h"
|
#include "tcg.h"
|
||||||
|
#include <sys/mman.h>
|
||||||
|
|
||||||
// This header define common patterns/codes that will be included in all arch-sepcific
|
// This header define common patterns/codes that will be included in all arch-sepcific
|
||||||
// codes for unicorns purposes.
|
// 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);
|
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);
|
void tb_cleanup(struct uc_struct *uc);
|
||||||
|
|
||||||
/** Freeing common resources */
|
/** Freeing common resources */
|
||||||
static void release_common(void *t)
|
static void release_common(void *t)
|
||||||
{
|
{
|
||||||
TCGContext *s = (TCGContext *)t;
|
TCGContext *s = (TCGContext *)t;
|
||||||
struct uc_struct* uc = s->uc;
|
|
||||||
CPUState *cpu;
|
|
||||||
#if TCG_TARGET_REG_BITS == 32
|
#if TCG_TARGET_REG_BITS == 32
|
||||||
int i;
|
int i;
|
||||||
#endif
|
#endif
|
||||||
|
@ -45,7 +35,9 @@ static void release_common(void *t)
|
||||||
g_free(def->args_ct);
|
g_free(def->args_ct);
|
||||||
g_free(def->sorted_args);
|
g_free(def->sorted_args);
|
||||||
g_free(s->tcg_op_defs);
|
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;
|
TCGPool *po, *to;
|
||||||
for (po = s->pool_first; po; po = to) {
|
for (po = s->pool_first; po; po = to) {
|
||||||
|
@ -55,36 +47,11 @@ static void release_common(void *t)
|
||||||
tcg_pool_reset(s);
|
tcg_pool_reset(s);
|
||||||
g_hash_table_destroy(s->helpers);
|
g_hash_table_destroy(s->helpers);
|
||||||
|
|
||||||
// Clean memory.
|
// TODO(danghvu): these function is not available outside qemu
|
||||||
phys_mem_clean(uc);
|
// so we keep them here instead of outside uc_close.
|
||||||
address_space_destroy(&(uc->as));
|
phys_mem_clean(s->uc);
|
||||||
memory_free(uc);
|
address_space_destroy(&(s->uc->as));
|
||||||
|
memory_free(s->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);
|
|
||||||
|
|
||||||
#if TCG_TARGET_REG_BITS == 32
|
#if TCG_TARGET_REG_BITS == 32
|
||||||
for(i = 0; i < s->nb_globals; i++) {
|
for(i = 0; i < s->nb_globals; i++) {
|
||||||
|
@ -97,12 +64,6 @@ static void release_common(void *t)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#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)
|
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/target-sparc/unicorn.h"
|
||||||
|
|
||||||
#include "qemu/include/hw/boards.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
|
UNICORN_EXPORT
|
||||||
unsigned int uc_version(unsigned int *major, unsigned int *minor)
|
unsigned int uc_version(unsigned int *major, unsigned int *minor)
|
||||||
|
@ -283,19 +292,53 @@ uc_err uc_close(uc_engine *uc)
|
||||||
int i;
|
int i;
|
||||||
struct list_item *cur;
|
struct list_item *cur;
|
||||||
struct hook *hook;
|
struct hook *hook;
|
||||||
|
CPUState *cpu;
|
||||||
|
|
||||||
|
// Cleanup internally.
|
||||||
if (uc->release)
|
if (uc->release)
|
||||||
uc->release(uc->tcg_ctx);
|
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);
|
free(uc->l1_map);
|
||||||
|
|
||||||
if (uc->bounce.buffer) {
|
if (uc->bounce.buffer) {
|
||||||
free(uc->bounce.buffer);
|
free(uc->bounce.buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
g_free(uc->tcg_ctx);
|
g_hash_table_foreach(uc->type_table, free_table, uc);
|
||||||
|
g_hash_table_unref(uc->type_table);
|
||||||
g_hash_table_destroy(uc->type_table);
|
|
||||||
|
|
||||||
for (i = 0; i < DIRTY_MEMORY_NUM; i++) {
|
for (i = 0; i < DIRTY_MEMORY_NUM; i++) {
|
||||||
free(uc->ram_list.dirty_memory[i]);
|
free(uc->ram_list.dirty_memory[i]);
|
||||||
|
|
Loading…
Reference in a new issue