Optimize memory handling (#1963)
* optimize ram block handling Save the last element of the ram_list. This allows to faster find where to add new elements when they are not bigger then page size. * save ram_list freed this keeps the optimization for find_ram_offset() intact after snapshot restore. * cow only clear the tlb of affected pages * update flatview when possible Building each flatview new when the memory has changed is quite expensive when many MemoryRegions are used. This is an issue when using snapshots. * update benchmark for new api * save flatview in context this avoids rebuilding the flatview when restore a context. * init context flatview with zero * address_space_dispatch_clear remove subpage with higher priority * docutemnt the options for UC_CTL_CONTEXT_MODE Specialy stress that with UC_CTL_CONTEXT_MEMORY it is not possible to use the context with a different unicorn object.
This commit is contained in:
23
uc.c
23
uc.c
@@ -2106,6 +2106,7 @@ uc_err uc_context_alloc(uc_engine *uc, uc_context **context)
|
||||
(*_context)->context_size = size - sizeof(uc_context);
|
||||
(*_context)->arch = uc->arch;
|
||||
(*_context)->mode = uc->mode;
|
||||
(*_context)->fv = NULL;
|
||||
restore_jit_state(uc);
|
||||
return UC_ERR_OK;
|
||||
} else {
|
||||
@@ -2142,11 +2143,23 @@ uc_err uc_context_save(uc_engine *uc, uc_context *context)
|
||||
uc_err ret = UC_ERR_OK;
|
||||
|
||||
if (uc->context_content & UC_CTL_CONTEXT_MEMORY) {
|
||||
if (!context->fv) {
|
||||
context->fv = g_malloc0(sizeof(*context->fv));
|
||||
}
|
||||
if (!context->fv) {
|
||||
return UC_ERR_NOMEM;
|
||||
}
|
||||
if (!uc->flatview_copy(uc, context->fv, uc->address_space_memory.current_map, false)) {
|
||||
restore_jit_state(uc);
|
||||
return UC_ERR_NOMEM;
|
||||
}
|
||||
ret = uc_snapshot(uc);
|
||||
if (ret != UC_ERR_OK) {
|
||||
restore_jit_state(uc);
|
||||
return ret;
|
||||
}
|
||||
context->ramblock_freed = uc->ram_list.freed;
|
||||
context->last_block = uc->ram_list.last_block;
|
||||
}
|
||||
|
||||
context->snapshot_level = uc->snapshot_level;
|
||||
@@ -2418,6 +2431,11 @@ uc_err uc_context_restore(uc_engine *uc, uc_context *context)
|
||||
return ret;
|
||||
}
|
||||
uc_snapshot(uc);
|
||||
uc->ram_list.freed = context->ramblock_freed;
|
||||
uc->ram_list.last_block = context->last_block;
|
||||
if (!uc->flatview_copy(uc, uc->address_space_memory.current_map, context->fv, true)) {
|
||||
return UC_ERR_NOMEM;
|
||||
}
|
||||
}
|
||||
|
||||
if (uc->context_content & UC_CTL_CONTEXT_CPU) {
|
||||
@@ -2434,6 +2452,10 @@ uc_err uc_context_restore(uc_engine *uc, uc_context *context)
|
||||
UNICORN_EXPORT
|
||||
uc_err uc_context_free(uc_context *context)
|
||||
{
|
||||
if (context->fv) {
|
||||
free(context->fv->ranges);
|
||||
g_free(context->fv);
|
||||
}
|
||||
return uc_free(context);
|
||||
}
|
||||
|
||||
@@ -2870,6 +2892,7 @@ static uc_err uc_restore_latest_snapshot(struct uc_struct *uc)
|
||||
g_array_remove_range(uc->unmapped_regions, i, 1);
|
||||
}
|
||||
uc->snapshot_level--;
|
||||
|
||||
return UC_ERR_OK;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user