+ return 0;
+}
+
+static ssize_t heap_comparison_ignore_size(xbt_dynar_t ignore_list, void *address){
+
+ unsigned int cursor = 0;
+ int start = 0;
+ int end = xbt_dynar_length(ignore_list) - 1;
+ mc_heap_ignore_region_t region;
+
+ while(start <= end){
+ cursor = (start + end) / 2;
+ region = (mc_heap_ignore_region_t)xbt_dynar_get_as(ignore_list, cursor, mc_heap_ignore_region_t);
+ if(region->address == address)
+ return region->size;
+ if(region->address < address)
+ start = cursor + 1;
+ if(region->address > address)
+ end = cursor - 1;
+ }
+
+ return -1;
+}
+
+static int is_stack(void *address){
+ unsigned int cursor = 0;
+ stack_region_t stack;
+
+ xbt_dynar_foreach(stacks_areas, cursor, stack){
+ if(address == stack->address)
+ return 1;
+ }
+
+ return 0;
+}
+
+static int is_block_stack(int block){
+ unsigned int cursor = 0;
+ stack_region_t stack;
+
+ xbt_dynar_foreach(stacks_areas, cursor, stack){
+ if(block == stack->block)
+ return 1;
+ }
+
+ return 0;
+}
+
+static void match_equals(struct s_mm_diff *state, xbt_dynar_t list){
+
+ unsigned int cursor = 0;
+ heap_area_pair_t current_pair;
+ heap_area_t previous_area;
+
+ xbt_dynar_foreach(list, cursor, current_pair){
+
+ if(current_pair->fragment1 != -1){
+
+ if(state->equals_to1[current_pair->block1][current_pair->fragment1] != NULL){
+ previous_area = state->equals_to1[current_pair->block1][current_pair->fragment1];
+ heap_area_free(state->equals_to2[previous_area->block][previous_area->fragment]);
+ state->equals_to2[previous_area->block][previous_area->fragment] = NULL;
+ heap_area_free(previous_area);
+ }
+ if(state->equals_to2[current_pair->block2][current_pair->fragment2] != NULL){
+ previous_area = state->equals_to2[current_pair->block2][current_pair->fragment2];
+ heap_area_free(state->equals_to1[previous_area->block][previous_area->fragment]);
+ state->equals_to1[previous_area->block][previous_area->fragment] = NULL;
+ heap_area_free(previous_area);
+ }
+
+ state->equals_to1[current_pair->block1][current_pair->fragment1] = new_heap_area(current_pair->block2, current_pair->fragment2);
+ state->equals_to2[current_pair->block2][current_pair->fragment2] = new_heap_area(current_pair->block1, current_pair->fragment1);
+
+ }else{
+
+ if(state->equals_to1[current_pair->block1][0] != NULL){
+ previous_area = state->equals_to1[current_pair->block1][0];
+ heap_area_free(state->equals_to2[previous_area->block][0]);
+ state->equals_to2[previous_area->block][0] = NULL;
+ heap_area_free(previous_area);
+ }
+ if(state->equals_to2[current_pair->block2][0] != NULL){
+ previous_area = state->equals_to2[current_pair->block2][0];
+ heap_area_free(state->equals_to1[previous_area->block][0]);
+ state->equals_to1[previous_area->block][0] = NULL;
+ heap_area_free(previous_area);
+ }
+
+ state->equals_to1[current_pair->block1][0] = new_heap_area(current_pair->block2, current_pair->fragment2);
+ state->equals_to2[current_pair->block2][0] = new_heap_area(current_pair->block1, current_pair->fragment1);
+
+ }
+
+ }
+}
+
+/** Check whether two blocks are known to be matching
+ *
+ * @param state State used
+ * @param b1 Block of state 1
+ * @param b2 Block of state 2
+ * @return if the blocks are known to be matching
+ */
+static int equal_blocks(struct s_mm_diff *state, int b1, int b2){
+
+ if(state->equals_to1[b1][0]->block == b2 && state->equals_to2[b2][0]->block == b1)
+ return 1;
+
+ return 0;
+}
+
+/** Check whether two fragments are known to be matching
+ *
+ * @param state State used
+ * @param b1 Block of state 1
+ * @param f1 Fragment of state 1
+ * @param b2 Block of state 2
+ * @param f2 Fragment of state 2
+ * @return if the fragments are known to be matching
+ */
+static int equal_fragments(struct s_mm_diff *state, int b1, int f1, int b2, int f2){
+
+ if(state->equals_to1[b1][f1]->block == b2
+ && state->equals_to1[b1][f1]->fragment == f2
+ && state->equals_to2[b2][f2]->block == b1
+ && state->equals_to2[b2][f2]->fragment == f1)
+ return 1;
+
+ return 0;
+}
+
+int init_heap_information(xbt_mheap_t heap1, xbt_mheap_t heap2, xbt_dynar_t i1, xbt_dynar_t i2){
+ if(mm_diff_info==NULL) {
+ mm_diff_info = xbt_new0(struct s_mm_diff, 1);
+ }
+ struct s_mm_diff *state = mm_diff_info;
+
+ if((((struct mdesc *)heap1)->heaplimit != ((struct mdesc *)heap2)->heaplimit)
+ || ((((struct mdesc *)heap1)->heapsize != ((struct mdesc *)heap2)->heapsize) ))
+ return -1;
+
+ int i, j;
+
+ state->heaplimit = ((struct mdesc *)heap1)->heaplimit;
+
+ state->s_heap = (char *)mmalloc_get_current_heap() - STD_HEAP_SIZE - getpagesize();
+
+ state->heapbase1 = (char *)heap1 + BLOCKSIZE;
+ state->heapbase2 = (char *)heap2 + BLOCKSIZE;
+
+ state->heapinfo1 = (malloc_info *)((char *)heap1 + ((uintptr_t)((char *)((struct mdesc *)heap1)->heapinfo - (char *)state->s_heap)));
+ state->heapinfo2 = (malloc_info *)((char *)heap2 + ((uintptr_t)((char *)((struct mdesc *)heap2)->heapinfo - (char *)state->s_heap)));
+
+ state->heapsize1 = heap1->heapsize;
+ state->heapsize2 = heap2->heapsize;
+
+ state->to_ignore1 = i1;
+ state-> to_ignore2 = i2;
+
+ state->equals_to1 = malloc(state->heaplimit * sizeof(heap_area_t *));
+ state->types1 = malloc(state->heaplimit * sizeof(type_name *));
+ for(i=0; i<=state->heaplimit; i++){
+ state->equals_to1[i] = malloc(MAX_FRAGMENT_PER_BLOCK * sizeof(heap_area_t));
+ state->types1[i] = malloc(MAX_FRAGMENT_PER_BLOCK * sizeof(type_name));
+ for(j=0; j<MAX_FRAGMENT_PER_BLOCK; j++){
+ state->equals_to1[i][j] = NULL;
+ state->types1[i][j] = NULL;
+ }
+ }
+
+ state->equals_to2 = malloc(state->heaplimit * sizeof(heap_area_t *));
+ state->types2 = malloc(state->heaplimit * sizeof(type_name *));
+ for(i=0; i<=state->heaplimit; i++){
+ state->equals_to2[i] = malloc(MAX_FRAGMENT_PER_BLOCK * sizeof(heap_area_t));
+ state->types2[i] = malloc(MAX_FRAGMENT_PER_BLOCK * sizeof(type_name));
+ for(j=0; j<MAX_FRAGMENT_PER_BLOCK; j++){
+ state->equals_to2[i][j] = NULL;
+ state->types2[i][j] = NULL;
+ }
+ }
+
+ if(MC_is_active()){
+ MC_ignore_global_variable("mm_diff_info");
+ }
+
+ return 0;
+
+}
+
+void reset_heap_information(){
+
+ struct s_mm_diff *state = mm_diff_info;
+
+ size_t i = 0, j;