From e405b052705c1a5ba58c0e05b852e8d811a1aef6 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Sat, 4 Apr 2009 14:47:08 +0300 Subject: [PATCH] Free all data_info at the end of a function. Signed-off-by: Dan Carpenter --- smatch_extra.c | 2 ++ smatch_extra.h | 1 + smatch_extra_helper.c | 36 ++++++++++++++++++++++++++++++++++++ 3 files changed, 39 insertions(+) diff --git a/smatch_extra.c b/smatch_extra.c index 4aaaa4eb..44ef10d3 100644 --- a/smatch_extra.c +++ b/smatch_extra.c @@ -418,6 +418,8 @@ void register_smatch_extra(int id) add_hook(&match_assign, ASSIGNMENT_HOOK); add_hook(&match_declarations, DECLARATION_HOOK); add_hook(&match_unop, OP_HOOK); + add_hook(&free_data_info_allocs, END_FUNC_HOOK); + #ifdef KERNEL /* I don't know how to test for the ATTRIB_NORET attribute. :( */ add_function_hook("panic", &__match_nullify_path_hook, NULL); diff --git a/smatch_extra.h b/smatch_extra.h index f915259b..7ab87e4c 100644 --- a/smatch_extra.h +++ b/smatch_extra.h @@ -28,6 +28,7 @@ int num_matches(struct data_info *dinfo, long long num); long long get_single_value(struct data_info *dinfo); int possibly_true(int comparison, struct data_info *dinfo, int num, int left); int possibly_false(int comparison, struct data_info *dinfo, int num, int left); +void free_data_info_allocs(void); /* used in smatch_slist. implemented in smatch_extra.c */ struct sm_state *__extra_merge(struct sm_state *one, struct state_list *slist1, diff --git a/smatch_extra_helper.c b/smatch_extra_helper.c index 166282c7..1b884fd3 100644 --- a/smatch_extra_helper.c +++ b/smatch_extra_helper.c @@ -155,3 +155,39 @@ int possibly_false(int comparison, struct data_info *dinfo, int num, int left) } END_FOR_EACH_PTR(tmp); return ret; } + +static void free_single_dinfo(struct data_info *dinfo) +{ + __free_ptr_list((struct ptr_list **)&dinfo->values); +} + +static void free_dinfos(struct allocation_blob *blob) +{ + unsigned int size = sizeof(struct data_info); + unsigned int offset = 0; + + while (offset < blob->offset) { + free_single_dinfo((struct data_info *)(blob->data + offset)); + offset += size; + } +} + +void free_data_info_allocs(void) +{ + struct allocator_struct *desc = &data_info_allocator; + struct allocation_blob *blob = desc->blobs; + + desc->blobs = NULL; + desc->allocations = 0; + desc->total_bytes = 0; + desc->useful_bytes = 0; + desc->freelist = NULL; + while (blob) { + struct allocation_blob *next = blob->next; + free_dinfos(blob); + blob_free(blob, desc->chunking); + blob = next; + } + clear_sm_num_alloc(); +} + -- 2.11.4.GIT