+int mmalloc_compare_heap(mc_snapshot_t snapshot1, mc_snapshot_t snapshot2, xbt_mheap_t heap1, xbt_mheap_t heap2){
+
+ struct s_mm_diff *state = mm_diff_info;
+
+ if(heap1 == NULL && heap2 == NULL){
+ XBT_DEBUG("Malloc descriptors null");
+ return 0;
+ }
+
+ /* Start comparison */
+ size_t i1, i2, j1, j2, k;
+ void *addr_block1, *addr_block2, *addr_frag1, *addr_frag2;
+ int nb_diff1 = 0, nb_diff2 = 0;
+
+ xbt_dynar_t previous = xbt_dynar_new(sizeof(heap_area_pair_t), heap_area_pair_free_voidp);
+
+ int equal, res_compare = 0;
+
+ /* Check busy blocks*/
+
+ i1 = 1;
+
+ while(i1 <= state->heaplimit){
+
+ if(state->heapinfo1[i1].type == -1){ /* Free block */
+ i1++;
+ continue;
+ }
+
+ addr_block1 = ((void*) (((ADDR2UINT(i1)) - 1) * BLOCKSIZE + (char*)((xbt_mheap_t)state->s_heap)->heapbase));
+
+ if(state->heapinfo1[i1].type == 0){ /* Large block */
+
+ if(is_stack(addr_block1)){
+ for(k=0; k < state->heapinfo1[i1].busy_block.size; k++)
+ state->equals_to1[i1+k][0] = new_heap_area(i1, -1);
+ for(k=0; k < state->heapinfo2[i1].busy_block.size; k++)
+ state->equals_to2[i1+k][0] = new_heap_area(i1, -1);
+ i1 += state->heapinfo1[i1].busy_block.size;
+ continue;
+ }
+
+ if(state->equals_to1[i1][0] != NULL){
+ i1++;
+ continue;
+ }
+
+ i2 = 1;
+ equal = 0;
+ res_compare = 0;
+
+ /* Try first to associate to same block in the other heap */
+ if(state->heapinfo2[i1].type == state->heapinfo1[i1].type){
+
+ if(state->equals_to2[i1][0] == NULL){
+
+ addr_block2 = ((void*) (((ADDR2UINT(i1)) - 1) * BLOCKSIZE + (char*)((xbt_mheap_t)state->s_heap)->heapbase));
+
+ res_compare = compare_heap_area(addr_block1, addr_block2, snapshot1, snapshot2, NULL, NULL, 0);
+
+ if(res_compare != 1){
+ for(k=1; k < state->heapinfo2[i1].busy_block.size; k++)
+ state->equals_to2[i1+k][0] = new_heap_area(i1, -1);
+ for(k=1; k < state->heapinfo1[i1].busy_block.size; k++)
+ state->equals_to1[i1+k][0] = new_heap_area(i1, -1);
+ equal = 1;
+ i1 += state->heapinfo1[i1].busy_block.size;
+ }
+
+ xbt_dynar_reset(previous);
+
+ }
+
+ }
+
+ while(i2 <= state->heaplimit && !equal){
+
+ addr_block2 = ((void*) (((ADDR2UINT(i2)) - 1) * BLOCKSIZE + (char*)((xbt_mheap_t)state->s_heap)->heapbase));
+
+ if(i2 == i1){
+ i2++;
+ continue;
+ }
+
+ if(state->heapinfo2[i2].type != 0){
+ i2++;
+ continue;
+ }
+
+ if(state->equals_to2[i2][0] != NULL){
+ i2++;
+ continue;
+ }
+
+ res_compare = compare_heap_area(addr_block1, addr_block2, snapshot1, snapshot2, NULL, NULL, 0);
+
+ if(res_compare != 1 ){
+ for(k=1; k < state->heapinfo2[i2].busy_block.size; k++)
+ state->equals_to2[i2+k][0] = new_heap_area(i1, -1);
+ for(k=1; k < state->heapinfo1[i1].busy_block.size; k++)
+ state->equals_to1[i1+k][0] = new_heap_area(i2, -1);
+ equal = 1;
+ i1 += state->heapinfo1[i1].busy_block.size;
+ }
+
+ xbt_dynar_reset(previous);
+
+ i2++;
+
+ }
+
+ if(!equal){
+ XBT_DEBUG("Block %zu not found (size_used = %zu, addr = %p)", i1, state->heapinfo1[i1].busy_block.busy_size, addr_block1);
+ i1 = state->heaplimit + 1;
+ nb_diff1++;
+ //i1++;
+ }
+
+ }else{ /* Fragmented block */
+
+ for(j1=0; j1 < (size_t) (BLOCKSIZE >> state->heapinfo1[i1].type); j1++){
+
+ if(state->heapinfo1[i1].busy_frag.frag_size[j1] == -1) /* Free fragment */
+ continue;
+
+ if(state->equals_to1[i1][j1] != NULL)
+ continue;
+
+ addr_frag1 = (void*) ((char *)addr_block1 + (j1 << state->heapinfo1[i1].type));
+
+ i2 = 1;
+ equal = 0;
+
+ /* Try first to associate to same fragment in the other heap */
+ if(state->heapinfo2[i1].type == state->heapinfo1[i1].type){
+
+ if(state->equals_to2[i1][j1] == NULL){
+
+ addr_block2 = ((void*) (((ADDR2UINT(i1)) - 1) * BLOCKSIZE + (char*)((xbt_mheap_t)state->s_heap)->heapbase));
+ addr_frag2 = (void*) ((char *)addr_block2 + (j1 << ((xbt_mheap_t)state->s_heap)->heapinfo[i1].type));
+
+ res_compare = compare_heap_area(addr_frag1, addr_frag2, snapshot1, snapshot2, NULL, NULL, 0);
+
+ if(res_compare != 1)
+ equal = 1;
+
+ xbt_dynar_reset(previous);
+
+ }
+
+ }
+
+ while(i2 <= state->heaplimit && !equal){
+
+ if(state->heapinfo2[i2].type <= 0){
+ i2++;
+ continue;
+ }
+
+ for(j2=0; j2 < (size_t) (BLOCKSIZE >> state->heapinfo2[i2].type); j2++){
+
+ if(i2 == i1 && j2 == j1)
+ continue;
+
+ if(state->equals_to2[i2][j2] != NULL)
+ continue;
+
+ addr_block2 = ((void*) (((ADDR2UINT(i2)) - 1) * BLOCKSIZE + (char*)((xbt_mheap_t)state->s_heap)->heapbase));
+ addr_frag2 = (void*) ((char *)addr_block2 + (j2 <<((xbt_mheap_t)state->s_heap)->heapinfo[i2].type));
+
+ res_compare = compare_heap_area(addr_frag1, addr_frag2, snapshot2, snapshot2, NULL, NULL, 0);
+
+ if(res_compare != 1){
+ equal = 1;
+ xbt_dynar_reset(previous);
+ break;
+ }
+
+ xbt_dynar_reset(previous);
+
+ }
+
+ i2++;
+
+ }
+
+ if(!equal){
+ XBT_DEBUG("Block %zu, fragment %zu not found (size_used = %zd, address = %p)\n", i1, j1, state->heapinfo1[i1].busy_frag.frag_size[j1], addr_frag1);
+ i2 = state->heaplimit + 1;
+ i1 = state->heaplimit + 1;
+ nb_diff1++;
+ break;
+ }
+
+ }
+
+ i1++;
+
+ }
+
+ }
+
+ /* All blocks/fragments are equal to another block/fragment ? */
+ size_t i = 1, j = 0;
+ void *real_addr_frag1 = NULL, *real_addr_block1 = NULL, *real_addr_block2 = NULL, *real_addr_frag2 = NULL;
+
+ while(i<=state->heaplimit){
+ if(state->heapinfo1[i].type == 0){
+ if(i1 == state->heaplimit){
+ if(state->heapinfo1[i].busy_block.busy_size > 0){
+ if(state->equals_to1[i][0] == NULL){
+ if(XBT_LOG_ISENABLED(mm_diff, xbt_log_priority_debug)){
+ addr_block1 = ((void*) (((ADDR2UINT(i)) - 1) * BLOCKSIZE + (char*)state->heapbase1));
+ XBT_DEBUG("Block %zu (%p) not found (size used = %zu)", i, addr_block1, state->heapinfo1[i].busy_block.busy_size);
+ //mmalloc_backtrace_block_display((void*)heapinfo1, i);
+ }
+ nb_diff1++;
+ }
+ }
+ }
+ }
+ if(state->heapinfo1[i].type > 0){
+ addr_block1 = ((void*) (((ADDR2UINT(i)) - 1) * BLOCKSIZE + (char*)state->heapbase1));
+ real_addr_block1 = ((void*) (((ADDR2UINT(i)) - 1) * BLOCKSIZE + (char*)((struct mdesc *)state->s_heap)->heapbase));
+ for(j=0; j < (size_t) (BLOCKSIZE >> state->heapinfo1[i].type); j++){
+ if(i1== state->heaplimit){
+ if(state->heapinfo1[i].busy_frag.frag_size[j] > 0){
+ if(state->equals_to1[i][j] == NULL){
+ if(XBT_LOG_ISENABLED(mm_diff, xbt_log_priority_debug)){
+ addr_frag1 = (void*) ((char *)addr_block1 + (j << state->heapinfo1[i].type));
+ real_addr_frag1 = (void*) ((char *)real_addr_block1 + (j << ((struct mdesc *)state->s_heap)->heapinfo[i].type));
+ XBT_DEBUG("Block %zu, Fragment %zu (%p - %p) not found (size used = %zd)", i, j, addr_frag1, real_addr_frag1, state->heapinfo1[i].busy_frag.frag_size[j]);
+ //mmalloc_backtrace_fragment_display((void*)heapinfo1, i, j);
+ }
+ nb_diff1++;
+ }
+ }
+ }
+ }
+ }
+ i++;
+ }