From 1c6d709571a4371b1268d844704dffed57b80cba Mon Sep 17 00:00:00 2001 From: Gabriel Corona Date: Tue, 4 Feb 2014 11:18:38 +0100 Subject: [PATCH] [mc] Preprocess type lookup Avoid looking up the types in the dictionnaries. --- src/include/mc/datatypes.h | 7 +++++-- src/mc/mc_checkpoint.c | 39 +++++++++++++++++++++++++++++++++++++- src/mc/mc_compare.c | 39 +++++++++++++++++++------------------- src/mc/mc_dwarf.c | 5 ++++- src/mc/mc_global.c | 3 +++ src/mc/mc_hash.c | 17 ++++++----------- src/mc/mc_private.h | 1 + 7 files changed, 76 insertions(+), 35 deletions(-) diff --git a/src/include/mc/datatypes.h b/src/include/mc/datatypes.h index d13ce8c2d2..24c94e67a1 100644 --- a/src/include/mc/datatypes.h +++ b/src/include/mc/datatypes.h @@ -44,7 +44,9 @@ void heap_ignore_region_free_voidp(void *r); typedef int e_dw_type_type; -typedef struct s_dw_type{ +typedef struct s_dw_type s_dw_type_t, *dw_type_t; + +struct s_dw_type{ e_dw_type_type type; void *id; /* Offset in the section (in hexadecimal form) */ char *name; /* Name of the type */ @@ -54,7 +56,8 @@ typedef struct s_dw_type{ xbt_dynar_t members; /* if DW_TAG_structure_type, DW_TAG_union_type*/ int is_pointer_type; int offset; -}s_dw_type_t, *dw_type_t; + dw_type_t subtype; +}; char* get_type_description(xbt_dict_t types, char *type_name); diff --git a/src/mc/mc_checkpoint.c b/src/mc/mc_checkpoint.c index 1d6c71db51..27503965cc 100644 --- a/src/mc/mc_checkpoint.c +++ b/src/mc/mc_checkpoint.c @@ -239,8 +239,45 @@ void MC_init_memory_map_info(){ } +/** \brief Fill/llokup the "subtype" field. + */ +static void MC_resolve_subtype(mc_object_info_t info, dw_type_t type) { + + if(type->dw_type_id==NULL) + return; + type->subtype = xbt_dict_get_or_null(info->types, type->dw_type_id); + if(type->subtype==NULL) + return; + if(type->subtype->byte_size != 0) + return; + if(type->subtype->name==NULL) + return; + // Try to find a more complete description of the type: + // We need to fix in order to support C++. + + dw_type_t subtype = xbt_dict_get_or_null(info->types_by_name, type->subtype->name); + if(subtype!=NULL) { + type->subtype = subtype; + } + + // TODO, support "switch type" (looking up the type in another lib) when possible +} + static void MC_post_process_types(mc_object_info_t info) { - // Nothing here + xbt_dict_cursor_t cursor = NULL; + char *origin; + dw_type_t type; + + // Lookup "subtype" field: + xbt_dict_foreach(info->types, cursor, origin, type){ + MC_resolve_subtype(info, type); + + dw_type_t member; + unsigned int i = 0; + if(type->members!=NULL) xbt_dynar_foreach(type->members, i, member) { + MC_resolve_subtype(info, member); + } + } } /** \brief Finds informations about a given shared object/executable */ diff --git a/src/mc/mc_compare.c b/src/mc/mc_compare.c index 5e8bb31968..919858f13c 100644 --- a/src/mc/mc_compare.c +++ b/src/mc/mc_compare.c @@ -124,9 +124,8 @@ static void add_compared_pointers(void *p1, void *p2){ } -static int compare_areas_with_type(void *area1, void *area2, xbt_dict_t types, xbt_dict_t other_types, char *type_id, int region_size, int region_type, void *start_data, int pointer_level){ +static int compare_areas_with_type(void *area1, void *area2, xbt_dict_t types, xbt_dict_t other_types, dw_type_t type, int region_size, int region_type, void *start_data, int pointer_level){ - dw_type_t type = xbt_dict_get_or_null(types, type_id);; unsigned int cursor = 0; dw_type_t member, subtype, subsubtype; int elm_size, i, res, switch_types = 0; @@ -141,10 +140,10 @@ static int compare_areas_with_type(void *area1, void *area2, xbt_dict_t types, x case DW_TAG_typedef: case DW_TAG_volatile_type: case DW_TAG_const_type: - return compare_areas_with_type(area1, area2, types, other_types, type->dw_type_id, region_size, region_type, start_data, pointer_level); + return compare_areas_with_type(area1, area2, types, other_types, type->subtype, region_size, region_type, start_data, pointer_level); break; case DW_TAG_array_type: - subtype = xbt_dict_get_or_null(types, type->dw_type_id); + subtype = type->subtype; switch(subtype->type){ case DW_TAG_base_type: case DW_TAG_enumeration_type: @@ -152,24 +151,18 @@ static int compare_areas_with_type(void *area1, void *area2, xbt_dict_t types, x case DW_TAG_structure_type: case DW_TAG_union_type: if(subtype->byte_size == 0){ /*declaration of the type, need the complete description */ - subtype = xbt_dict_get_or_null(types, get_type_description(types, subtype->name)); - if(subtype == NULL){ subtype = xbt_dict_get_or_null(other_types, get_type_description(other_types, subtype->name)); switch_types = 1; - } } elm_size = subtype->byte_size; break; case DW_TAG_const_type: case DW_TAG_typedef: case DW_TAG_volatile_type: - subsubtype = xbt_dict_get_or_null(types, subtype->dw_type_id); + subsubtype = subtype->subtype; if(subsubtype->byte_size == 0){ /*declaration of the type, need the complete description */ - subsubtype = xbt_dict_get_or_null(types, get_type_description(types, subsubtype->name)); - if(subsubtype == NULL){ subsubtype = xbt_dict_get_or_null(other_types, get_type_description(other_types, subsubtype->name)); switch_types = 1; - } } elm_size = subsubtype->byte_size; break; @@ -179,9 +172,9 @@ static int compare_areas_with_type(void *area1, void *area2, xbt_dict_t types, x } for(i=0; ielement_count; i++){ if(switch_types) - res = compare_areas_with_type((char *)area1 + (i*elm_size), (char *)area2 + (i*elm_size), other_types, types, type->dw_type_id, region_size, region_type, start_data, pointer_level); + res = compare_areas_with_type((char *)area1 + (i*elm_size), (char *)area2 + (i*elm_size), other_types, types, type->subtype, region_size, region_type, start_data, pointer_level); else - res = compare_areas_with_type((char *)area1 + (i*elm_size), (char *)area2 + (i*elm_size), types, other_types, type->dw_type_id, region_size, region_type, start_data, pointer_level); + res = compare_areas_with_type((char *)area1 + (i*elm_size), (char *)area2 + (i*elm_size), types, other_types, type->subtype, region_size, region_type, start_data, pointer_level); if(res == 1) return res; } @@ -222,7 +215,7 @@ static int compare_areas_with_type(void *area1, void *area2, xbt_dict_t types, x if(type->dw_type_id == NULL) return (addr_pointed1 != addr_pointed2); else - return compare_areas_with_type(addr_pointed1, addr_pointed2, types, other_types, type->dw_type_id, region_size, region_type, start_data, pointer_level); + return compare_areas_with_type(addr_pointed1, addr_pointed2, types, other_types, type->subtype, region_size, region_type, start_data, pointer_level); } else{ @@ -233,7 +226,7 @@ static int compare_areas_with_type(void *area1, void *area2, xbt_dict_t types, x case DW_TAG_structure_type: xbt_dynar_foreach(type->members, cursor, member){ XBT_DEBUG("Compare member %s", member->name); - res = compare_areas_with_type((char *)area1 + member->offset, (char *)area2 + member->offset, types, other_types, member->dw_type_id, region_size, region_type, start_data, pointer_level); + res = compare_areas_with_type((char *)area1 + member->offset, (char *)area2 + member->offset, types, other_types, member->subtype, region_size, region_type, start_data, pointer_level); if(res == 1) return res; } @@ -294,7 +287,8 @@ static int compare_global_variables(int region_type, mc_mem_region_t r1, mc_mem_ offset = (char *)current_var->address.address - (char *)object_info->start_rw; - res = compare_areas_with_type((char *)r1->data + offset, (char *)r2->data + offset, types, other_types, current_var->type_origin, r1->size, region_type, start_data, 0); + dw_type_t bvariable_type = xbt_dict_get_or_null(types, current_var->type_origin); + res = compare_areas_with_type((char *)r1->data + offset, (char *)r2->data + offset, types, other_types, bvariable_type, r1->size, region_type, start_data, 0); if(res == 1){ XBT_VERB("Global variable %s (%p - %p) is different between snapshots", current_var->name, (char *)r1->data + offset, (char *)r2->data + offset); xbt_dynar_free(&compared_pointers); @@ -342,10 +336,15 @@ static int compare_local_variables(mc_snapshot_stack_t stack1, mc_snapshot_stack offset1 = (char *)current_var1->address - (char *)std_heap; offset2 = (char *)current_var2->address - (char *)std_heap; XBT_DEBUG("Compare local variable %s of frame %s", current_var1->name, current_var1->frame); - if(current_var1->region == 1) - res = compare_areas_with_type( (char *)heap1 + offset1, (char *)heap2 + offset2, mc_libsimgrid_info->types, mc_binary_info->types, current_var1->type, 0, 1, start_data_libsimgrid, 0); - else - res = compare_areas_with_type( (char *)heap1 + offset1, (char *)heap2 + offset2, mc_binary_info->types, mc_libsimgrid_info->types, current_var1->type, 0, 2, start_data_binary, 0); + + + if(current_var1->region == 1) { + dw_type_t subtype = xbt_dict_get_or_null(mc_libsimgrid_info->types, current_var1->type); + res = compare_areas_with_type( (char *)heap1 + offset1, (char *)heap2 + offset2, mc_libsimgrid_info->types, mc_binary_info->types, subtype, 0, 1, start_data_libsimgrid, 0); + } else { + dw_type_t subtype = xbt_dict_get_or_null(mc_binary_info->types, current_var1->type); + res = compare_areas_with_type( (char *)heap1 + offset1, (char *)heap2 + offset2, mc_binary_info->types, mc_libsimgrid_info->types, subtype, 0, 2, start_data_binary, 0); + } if(res == 1){ XBT_VERB("Local variable %s (%p - %p) in frame %s is different between snapshots", current_var1->name,(char *)heap1 + offset1, (char *)heap2 + offset2, current_var1->frame); xbt_dynar_free(&compared_pointers); diff --git a/src/mc/mc_dwarf.c b/src/mc/mc_dwarf.c index 025f31058d..d830f23e73 100644 --- a/src/mc/mc_dwarf.c +++ b/src/mc/mc_dwarf.c @@ -1,6 +1,5 @@ /* Copyright (c) 2008-2013. The SimGrid Team. * All rights reserved. */ - /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -634,6 +633,10 @@ static void MC_dwarf_handle_type_die(mc_object_info_t info, Dwarf_Die* die, Dwar char* key = bprintf("%" PRIx64, (uint64_t) type->id); xbt_dict_set(info->types, key, type, NULL); + + if(type->name && type->byte_size!=0) { + xbt_dict_set(info->types_by_name, type->name, type, NULL); + } } /** \brief Convert libdw location expresion elment into native one (or NULL in some cases) */ diff --git a/src/mc/mc_global.c b/src/mc/mc_global.c index b3cc8baac2..6c48aba9e8 100644 --- a/src/mc/mc_global.c +++ b/src/mc/mc_global.c @@ -180,6 +180,7 @@ mc_object_info_t MC_new_object_info(void) { res->local_variables = xbt_dict_new_homogeneous(NULL); res->global_variables = xbt_dynar_new(sizeof(dw_variable_t), dw_variable_free_voidp); res->types = xbt_dict_new_homogeneous(NULL); + res->types_by_name = xbt_dict_new_homogeneous(NULL); return res; } @@ -188,6 +189,7 @@ void MC_free_object_info(mc_object_info_t* info) { xbt_dict_free(&(*info)->local_variables); xbt_dynar_free(&(*info)->global_variables); xbt_dict_free(&(*info)->types); + xbt_dict_free(&(*info)->types_by_name); xbt_free(info); *info = NULL; } @@ -433,6 +435,7 @@ void MC_dwarf_register_variable(mc_object_info_t info, dw_frame_t frame, dw_vari MC_dwarf_register_non_global_variable(info, frame, variable); } + /******************************* Ignore mechanism *******************************/ /*********************************************************************************/ diff --git a/src/mc/mc_hash.c b/src/mc/mc_hash.c index 86847a9ba5..5bba2ff0d7 100644 --- a/src/mc/mc_hash.c +++ b/src/mc/mc_hash.c @@ -93,7 +93,7 @@ static void mc_hash_value(mc_hash_t* hash, mc_hashing_state* state, mc_object_in return; long element_count = type->element_count; - dw_type_t subtype = xbt_dict_get_or_null(info->types, type->dw_type_id); + dw_type_t subtype = type->subtype; if(subtype==NULL) { XBT_DEBUG("Hash array without subtype"); return; @@ -113,10 +113,7 @@ static void mc_hash_value(mc_hash_t* hash, mc_hashing_state* state, mc_object_in case DW_TAG_const_type: case DW_TAG_restrict_type: { - if(type->dw_type_id==NULL) { - return; - } - type = xbt_dict_get_or_null(info->types, type->dw_type_id); + type = type->subtype; if(type==NULL) return; else @@ -133,10 +130,9 @@ static void mc_hash_value(mc_hash_t* hash, mc_hashing_state* state, mc_object_in dw_type_t member; xbt_dynar_foreach(type->members, cursor, member){ XBT_DEBUG("Hash struct member %s", member->name); - dw_type_t subtype = xbt_dict_get_or_null(info->types, member->dw_type_id); - if(subtype==NULL) + if(type->subtype==NULL) return; - mc_hash_value(hash, state, info, ((char*)address) + member->offset, subtype); + mc_hash_value(hash, state, info, ((char*)address) + member->offset, type->subtype); } return; } @@ -171,14 +167,13 @@ static void mc_hash_value(mc_hash_t* hash, mc_hashing_state* state, mc_object_in return; } - dw_type_t subtype = type->dw_type_id == NULL ? NULL : xbt_dict_get_or_null(info->types, type->dw_type_id); - if(subtype==NULL) { + if(type->subtype==NULL) { XBT_DEBUG("Missing type for %p (type=%s)", pointed, type->dw_type_id); return; } address = pointed; - type = subtype; + type = type->subtype; goto top; } diff --git a/src/mc/mc_private.h b/src/mc/mc_private.h index bf1cf119b5..a7398cb25d 100644 --- a/src/mc/mc_private.h +++ b/src/mc/mc_private.h @@ -330,6 +330,7 @@ typedef struct s_mc_object_info { xbt_dict_t local_variables; // xbt_dict_t xbt_dynar_t global_variables; // xbt_dynar_t xbt_dict_t types; // xbt_dict_t + xbt_dict_t types_by_name; // xbt_dict_t (full defined type only) } s_mc_object_info_t, *mc_object_info_t; mc_object_info_t MC_new_object_info(void); -- 2.20.1