Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Merge branch 'master' of git+ssh://scm.gforge.inria.fr//gitroot/simgrid/simgrid
[simgrid.git] / src / xbt / mmalloc / mm_diff.c
1 /* mm_diff - Memory snapshooting and comparison                             */
2
3 /* Copyright (c) 2008-2012. The SimGrid Team. All rights reserved.          */
4
5 /* This program is free software; you can redistribute it and/or modify it
6  * under the terms of the license (GNU LGPL) which comes with this package. */
7
8 #include "xbt/ex_interface.h" /* internals of backtrace setup */
9 #include "xbt/str.h"
10 #include "mc/mc.h"
11 #include "xbt/mmalloc.h"
12 #include "mc/datatypes.h"
13
14 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mm_diff, xbt,
15                                 "Logging specific to mm_diff in mmalloc");
16
17 xbt_dynar_t mc_heap_comparison_ignore;
18 xbt_dynar_t stacks_areas;
19 void *maestro_stack_start, *maestro_stack_end;
20
21
22 /********************************* Backtrace ***********************************/
23 /******************************************************************************/
24
25 static void mmalloc_backtrace_block_display(void* heapinfo, int block){
26
27   /* xbt_ex_t e; */
28
29   /* if (((malloc_info *)heapinfo)[block].busy_block.bt_size == 0) { */
30   /*   fprintf(stderr, "No backtrace available for that block, sorry.\n"); */
31   /*   return; */
32   /* } */
33
34   /* memcpy(&e.bt,&(((malloc_info *)heapinfo)[block].busy_block.bt),sizeof(void*)*XBT_BACKTRACE_SIZE); */
35   /* e.used = ((malloc_info *)heapinfo)[block].busy_block.bt_size; */
36
37   /* xbt_ex_setup_backtrace(&e); */
38   /* if (e.used == 0) { */
39   /*   fprintf(stderr, "(backtrace not set)\n"); */
40   /* } else if (e.bt_strings == NULL) { */
41   /*   fprintf(stderr, "(backtrace not ready to be computed. %s)\n",xbt_binary_name?"Dunno why":"xbt_binary_name not setup yet"); */
42   /* } else { */
43   /*   int i; */
44
45   /*   fprintf(stderr, "Backtrace of where the block %d was malloced (%d frames):\n", block ,e.used); */
46   /*   for (i = 0; i < e.used; i++)       /\* no need to display "xbt_backtrace_display" *\/{ */
47   /*     fprintf(stderr, "%d ---> %s\n",i, e.bt_strings[i] + 4); */
48   /*   } */
49   /* } */
50 }
51
52 static void mmalloc_backtrace_fragment_display(void* heapinfo, int block, int frag){
53
54   /* xbt_ex_t e; */
55
56   /* memcpy(&e.bt,&(((malloc_info *)heapinfo)[block].busy_frag.bt[frag]),sizeof(void*)*XBT_BACKTRACE_SIZE); */
57   /* e.used = XBT_BACKTRACE_SIZE; */
58
59   /* xbt_ex_setup_backtrace(&e); */
60   /* if (e.used == 0) { */
61   /*   fprintf(stderr, "(backtrace not set)\n"); */
62   /* } else if (e.bt_strings == NULL) { */
63   /*   fprintf(stderr, "(backtrace not ready to be computed. %s)\n",xbt_binary_name?"Dunno why":"xbt_binary_name not setup yet"); */
64   /* } else { */
65   /*   int i; */
66
67   /*   fprintf(stderr, "Backtrace of where the fragment %d in block %d was malloced (%d frames):\n", frag, block ,e.used); */
68   /*   for (i = 0; i < e.used; i++)       /\* no need to display "xbt_backtrace_display" *\/{ */
69   /*     fprintf(stderr, "%d ---> %s\n",i, e.bt_strings[i] + 4); */
70   /*   } */
71   /* } */
72
73 }
74
75 static void mmalloc_backtrace_display(void *addr){
76
77   /* size_t block, frag_nb; */
78   /* int type; */
79   
80   /* xbt_mheap_t heap = __mmalloc_current_heap ?: (xbt_mheap_t) mmalloc_preinit(); */
81
82   /* block = (((char*) (addr) - (char*) heap -> heapbase) / BLOCKSIZE + 1); */
83
84   /* type = heap->heapinfo[block].type; */
85
86   /* switch(type){ */
87   /* case -1 : /\* Free block *\/ */
88   /*   fprintf(stderr, "Asked to display the backtrace of a block that is free. I'm puzzled\n"); */
89   /*   xbt_abort(); */
90   /*   break;  */
91   /* case 0: /\* Large block *\/ */
92   /*   mmalloc_backtrace_block_display(heap->heapinfo, block); */
93   /*   break; */
94   /* default: /\* Fragmented block *\/ */
95   /*   frag_nb = RESIDUAL(addr, BLOCKSIZE) >> type; */
96   /*   if(heap->heapinfo[block].busy_frag.frag_size[frag_nb] == -1){ */
97   /*     fprintf(stderr , "Asked to display the backtrace of a fragment that is free. I'm puzzled\n"); */
98   /*     xbt_abort(); */
99   /*   } */
100   /*   mmalloc_backtrace_fragment_display(heap->heapinfo, block, frag_nb); */
101   /*   break; */
102   /* } */
103 }
104
105
106 static int compare_backtrace(int b1, int f1, int b2, int f2){
107   /*int i = 0;
108   if(f1 != -1){
109     for(i=0; i< XBT_BACKTRACE_SIZE; i++){
110       if(heapinfo1[b1].busy_frag.bt[f1][i] != heapinfo2[b2].busy_frag.bt[f2][i]){
111         //mmalloc_backtrace_fragment_display((void*)heapinfo1, b1, f1);
112         //mmalloc_backtrace_fragment_display((void*)heapinfo2, b2, f2);
113         return 1;
114       }
115     }
116   }else{
117     for(i=0; i< heapinfo1[b1].busy_block.bt_size; i++){
118       if(heapinfo1[b1].busy_block.bt[i] != heapinfo2[b2].busy_block.bt[i]){
119         //mmalloc_backtrace_block_display((void*)heapinfo1, b1);
120         //mmalloc_backtrace_block_display((void*)heapinfo2, b2);
121         return 1;
122       }
123     }
124     }*/
125   return 0;
126 }
127
128
129 /*********************************** Heap comparison ***********************************/
130 /***************************************************************************************/
131
132 void *s_heap = NULL, *heapbase1 = NULL, *heapbase2 = NULL;
133 malloc_info *heapinfo1 = NULL, *heapinfo2 = NULL;
134 size_t heaplimit = 0, heapsize1 = 0, heapsize2 = 0;
135 xbt_dynar_t to_ignore1 = NULL, to_ignore2 = NULL;
136
137 /*********************************** Free functions ************************************/
138
139 static void heap_area_pair_free(heap_area_pair_t pair){
140   xbt_free(pair);
141   pair = NULL;
142 }
143
144 static void heap_area_pair_free_voidp(void *d){
145   heap_area_pair_free((heap_area_pair_t) * (void **) d);
146 }
147
148 static void heap_area_free(heap_area_t area){
149   xbt_free(area);
150   area = NULL;
151 }
152
153 /************************************************************************************/
154
155 static heap_area_t new_heap_area(int block, int fragment){
156   heap_area_t area = NULL;
157   area = xbt_new0(s_heap_area_t, 1);
158   area->block = block;
159   area->fragment = fragment;
160   return area;
161 }
162
163  
164 static int is_new_heap_area_pair(xbt_dynar_t list, int block1, int fragment1, int block2, int fragment2){
165   
166   unsigned int cursor = 0;
167   heap_area_pair_t current_pair;
168
169   xbt_dynar_foreach(list, cursor, current_pair){
170     if(current_pair->block1 == block1 && current_pair->block2 == block2 && current_pair->fragment1 == fragment1 && current_pair->fragment2 == fragment2)
171       return 0; 
172   }
173   
174   return 1;
175 }
176
177 static int add_heap_area_pair(xbt_dynar_t list, int block1, int fragment1, int block2, int fragment2){
178
179   if(is_new_heap_area_pair(list, block1, fragment1, block2, fragment2)){
180     heap_area_pair_t pair = NULL;
181     pair = xbt_new0(s_heap_area_pair_t, 1);
182     pair->block1 = block1;
183     pair->fragment1 = fragment1;
184     pair->block2 = block2;
185     pair->fragment2 = fragment2;
186     
187     xbt_dynar_push(list, &pair); 
188
189     return 1;
190   }
191
192   return 0;
193 }
194
195 static size_t heap_comparison_ignore_size(xbt_dynar_t ignore_list, void *address){
196
197   unsigned int cursor = 0;
198   int start = 0;
199   int end = xbt_dynar_length(ignore_list) - 1;
200   mc_heap_ignore_region_t region;
201
202   while(start <= end){
203     cursor = (start + end) / 2;
204     region = (mc_heap_ignore_region_t)xbt_dynar_get_as(ignore_list, cursor, mc_heap_ignore_region_t);
205     if(region->address == address)
206       return region->size;
207     if(region->address < address)
208       start = cursor + 1;
209     if(region->address > address)
210       end = cursor - 1;   
211   }
212
213   return 0;
214 }
215
216 static int is_stack(void *address){
217   unsigned int cursor = 0;
218   stack_region_t stack;
219
220   xbt_dynar_foreach(stacks_areas, cursor, stack){
221     if(address == stack->address)
222       return 1;
223   }
224
225   return 0;
226 }
227
228 static int is_block_stack(int block){
229   unsigned int cursor = 0;
230   stack_region_t stack;
231
232   xbt_dynar_foreach(stacks_areas, cursor, stack){
233     if(block == stack->block)
234       return 1;
235   }
236
237   return 0;
238 }
239
240 static void match_equals(xbt_dynar_t list){
241
242   unsigned int cursor = 0;
243   heap_area_pair_t current_pair;
244   heap_area_t previous_area;
245
246   xbt_dynar_foreach(list, cursor, current_pair){
247
248     if(current_pair->fragment1 != -1){
249       
250       if(heapinfo1[current_pair->block1].busy_frag.equal_to[current_pair->fragment1] != NULL){    
251         previous_area = heapinfo1[current_pair->block1].busy_frag.equal_to[current_pair->fragment1];
252         heap_area_free(heapinfo2[previous_area->block].busy_frag.equal_to[previous_area->fragment]);
253         heapinfo2[previous_area->block].busy_frag.equal_to[previous_area->fragment] = NULL;
254         heap_area_free(previous_area); 
255       }
256       if(heapinfo2[current_pair->block2].busy_frag.equal_to[current_pair->fragment2] != NULL){        
257         previous_area = heapinfo2[current_pair->block2].busy_frag.equal_to[current_pair->fragment2];
258         heap_area_free(heapinfo1[previous_area->block].busy_frag.equal_to[previous_area->fragment]);
259         heapinfo1[previous_area->block].busy_frag.equal_to[previous_area->fragment] = NULL;
260         heap_area_free(previous_area);
261       }
262
263       heapinfo1[current_pair->block1].busy_frag.equal_to[current_pair->fragment1] = new_heap_area(current_pair->block2, current_pair->fragment2);
264       heapinfo2[current_pair->block2].busy_frag.equal_to[current_pair->fragment2] = new_heap_area(current_pair->block1, current_pair->fragment1);
265       
266     }else{
267
268       if(heapinfo1[current_pair->block1].busy_block.equal_to != NULL){
269         previous_area = heapinfo1[current_pair->block1].busy_block.equal_to;
270         heap_area_free(heapinfo2[previous_area->block].busy_block.equal_to);
271         heapinfo2[previous_area->block].busy_block.equal_to = NULL;
272         heap_area_free(previous_area);
273       }
274       if(heapinfo2[current_pair->block2].busy_block.equal_to != NULL){
275         previous_area = heapinfo2[current_pair->block2].busy_block.equal_to;
276         heap_area_free(heapinfo1[previous_area->block].busy_block.equal_to);
277         heapinfo1[previous_area->block].busy_block.equal_to = NULL;
278         heap_area_free(previous_area);
279       }
280
281       heapinfo1[current_pair->block1].busy_block.equal_to = new_heap_area(current_pair->block2, current_pair->fragment2);
282       heapinfo2[current_pair->block2].busy_block.equal_to = new_heap_area(current_pair->block1, current_pair->fragment1);
283
284     }
285
286   }
287 }
288
289 static int equal_blocks(int b1, int b2){
290   if(heapinfo1[b1].busy_block.equal_to != NULL){
291     if(heapinfo2[b2].busy_block.equal_to != NULL){
292       if(((heap_area_t)(heapinfo1[b1].busy_block.equal_to))->block == b2 && ((heap_area_t)(heapinfo2[b2].busy_block.equal_to))->block == b1)
293         return 1;
294     }
295   }
296   return 0;
297 }
298
299 static int equal_fragments(int b1, int f1, int b2, int f2){
300   if(heapinfo1[b1].busy_frag.equal_to[f1] != NULL){
301     if(heapinfo2[b2].busy_frag.equal_to[f2] != NULL){
302       if(((heap_area_t)(heapinfo1[b1].busy_frag.equal_to[f1]))->block == b2 && ((heap_area_t)(heapinfo2[b2].busy_frag.equal_to[f2]))->block == b1 && ((heap_area_t)(heapinfo1[b1].busy_frag.equal_to[f1]))->fragment == f2 && ((heap_area_t)(heapinfo2[b2].busy_frag.equal_to[f2]))->fragment == f1)
303         return 1;
304     }
305   }
306   return 0;
307 }
308
309 void init_heap_information(xbt_mheap_t heap1, xbt_mheap_t heap2, xbt_dynar_t i1, xbt_dynar_t i2){
310
311   heaplimit = ((struct mdesc *)heap1)->heaplimit;
312
313   s_heap = (char *)mmalloc_get_current_heap() - STD_HEAP_SIZE - getpagesize();
314
315   heapbase1 = (char *)heap1 + BLOCKSIZE;
316   heapbase2 = (char *)heap2 + BLOCKSIZE;
317
318   heapinfo1 = (malloc_info *)((char *)heap1 + ((uintptr_t)((char *)((struct mdesc *)heap1)->heapinfo - (char *)s_heap)));
319   heapinfo2 = (malloc_info *)((char *)heap2 + ((uintptr_t)((char *)((struct mdesc *)heap2)->heapinfo - (char *)s_heap)));
320
321   heapsize1 = heap1->heapsize;
322   heapsize2 = heap2->heapsize;
323
324   to_ignore1 = i1;
325   to_ignore2 = i2;
326
327   if(MC_is_active()){
328     MC_ignore_global_variable("heaplimit");
329     MC_ignore_global_variable("s_heap");
330     MC_ignore_global_variable("heapbase1");
331     MC_ignore_global_variable("heapbase2");
332     MC_ignore_global_variable("heapinfo1");
333     MC_ignore_global_variable("heapinfo2");
334     MC_ignore_global_variable("heapsize1");
335     MC_ignore_global_variable("heapsize2");
336     MC_ignore_global_variable("to_ignore1");
337     MC_ignore_global_variable("to_ignore2");
338   }
339
340 }
341
342 void reset_heap_information(){
343
344   size_t i = 0, j;
345
346   while(i<=heaplimit){
347     if(heapinfo1[i].type == 0){
348       heap_area_free(heapinfo1[i].busy_block.equal_to);
349       heapinfo1[i].busy_block.equal_to = NULL;
350     }else if(heapinfo1[i].type > 0){
351       for(j=0; j < (size_t) (BLOCKSIZE >> heapinfo1[i].type); j++){
352         heap_area_free(heapinfo1[i].busy_frag.equal_to[j]);
353         heapinfo1[i].busy_frag.equal_to[j] = NULL;
354       }
355     }
356     i++; 
357   }
358
359   i = 0;
360
361   while(i<=heaplimit){
362     if(heapinfo2[i].type == 0){
363       heap_area_free(heapinfo2[i].busy_block.equal_to);
364       heapinfo2[i].busy_block.equal_to = NULL;
365     }else if(heapinfo2[i].type > 0){
366       for(j=0; j < (size_t) (BLOCKSIZE >> heapinfo2[i].type); j++){
367         heap_area_free(heapinfo2[i].busy_frag.equal_to[j]);
368         heapinfo2[i].busy_frag.equal_to[j] = NULL;
369       }
370     }
371     i++; 
372   }
373
374   s_heap = NULL, heapbase1 = NULL, heapbase2 = NULL;
375   heapinfo1 = NULL, heapinfo2 = NULL;
376   heaplimit = 0, heapsize1 = 0, heapsize2 = 0;
377   to_ignore1 = NULL, to_ignore2 = NULL;
378
379 }
380
381 int mmalloc_compare_heap(xbt_mheap_t heap1, xbt_mheap_t heap2){
382
383   if(heap1 == NULL && heap1 == NULL){
384     XBT_DEBUG("Malloc descriptors null");
385     return 0;
386   }
387
388   if(heap1->heaplimit != heap2->heaplimit){
389     XBT_DEBUG("Different limit of valid info table indices");
390     return 1;
391   }
392
393   /* Start comparison */
394   size_t i1, i2, j1, j2, k;
395   size_t current_block = -1;    /* avoid "maybe uninitialized" warning */
396   size_t current_fragment;
397   void *addr_block1, *addr_block2, *addr_frag1, *addr_frag2;
398   int nb_diff1 = 0, nb_diff2 = 0;
399
400   xbt_dynar_t previous = xbt_dynar_new(sizeof(heap_area_pair_t), heap_area_pair_free_voidp);
401
402   int equal, res_compare = 0;
403
404   /* Check busy blocks*/
405
406   i1 = 1;
407
408   while(i1 <= heaplimit){
409
410     current_block = i1;
411
412     if(heapinfo1[i1].type == -1){ /* Free block */
413       i1++;
414       continue;
415     }
416
417     addr_block1 = ((void*) (((ADDR2UINT(i1)) - 1) * BLOCKSIZE + (char*)((xbt_mheap_t)s_heap)->heapbase));
418
419     if(heapinfo1[i1].type == 0){  /* Large block */
420       
421       if(is_stack(addr_block1)){
422         for(k=0; k < heapinfo1[i1].busy_block.size; k++)
423           heapinfo1[i1+k].busy_block.equal_to = new_heap_area(i1, -1);
424         for(k=0; k < heapinfo2[i1].busy_block.size; k++)
425           heapinfo2[i1+k].busy_block.equal_to = new_heap_area(i1, -1);
426         i1 = i1 + heapinfo1[current_block].busy_block.size;
427         continue;
428       }
429
430       if(heapinfo1[i1].busy_block.equal_to != NULL){
431         i1++;
432         continue;
433       }
434     
435       i2 = 1;
436       equal = 0;
437       res_compare = 0;
438   
439       /* Try first to associate to same block in the other heap */
440       if(heapinfo2[current_block].type == heapinfo1[current_block].type){
441
442         if(heapinfo2[current_block].busy_block.equal_to == NULL){  
443         
444           addr_block2 = ((void*) (((ADDR2UINT(current_block)) - 1) * BLOCKSIZE + (char*)((xbt_mheap_t)s_heap)->heapbase));
445         
446           res_compare = compare_heap_area(addr_block1, addr_block2, NULL, NULL, NULL, NULL, 0); /*FIXME*/
447         
448           if(res_compare == 0){
449             for(k=1; k < heapinfo2[current_block].busy_block.size; k++)
450               heapinfo2[current_block+k].busy_block.equal_to = new_heap_area(i1, -1);
451             for(k=1; k < heapinfo1[current_block].busy_block.size; k++)
452               heapinfo1[current_block+k].busy_block.equal_to = new_heap_area(i1, -1);
453             equal = 1;
454             i1 = i1 + heapinfo1[current_block].busy_block.size;
455           }
456         
457           xbt_dynar_reset(previous);
458         
459         }
460         
461       }
462
463       while(i2 <= heaplimit && !equal){
464
465         addr_block2 = ((void*) (((ADDR2UINT(i2)) - 1) * BLOCKSIZE + (char*)((xbt_mheap_t)s_heap)->heapbase));        
466            
467         if(i2 == current_block){
468           i2++;
469           continue;
470         }
471
472         if(heapinfo2[i2].type != 0){
473           i2++;
474           continue;
475         }
476
477         if(heapinfo2[i2].busy_block.equal_to != NULL){         
478           i2++;
479           continue;
480         }
481           
482         res_compare = compare_heap_area(addr_block1, addr_block2, NULL, NULL, NULL, NULL, 0); /*FIXME */
483         
484         if(res_compare == 0){
485           for(k=1; k < heapinfo2[i2].busy_block.size; k++)
486             heapinfo2[i2+k].busy_block.equal_to = new_heap_area(i1, -1);
487           for(k=1; k < heapinfo1[i1].busy_block.size; k++)
488             heapinfo1[i1+k].busy_block.equal_to = new_heap_area(i2, -1);
489           equal = 1;
490           i1 = i1 + heapinfo1[i1].busy_block.size;
491         }
492
493         xbt_dynar_reset(previous);
494
495         i2++;
496
497       }
498
499       if(!equal){
500         XBT_DEBUG("Block %zu not found (size_used = %zu, addr = %p)", i1, heapinfo1[i1].busy_block.busy_size, addr_block1);
501         i1 = heaplimit + 1;
502         nb_diff1++;
503           //i1++;
504       }
505       
506     }else{ /* Fragmented block */
507
508       for(j1=0; j1 < (size_t) (BLOCKSIZE >> heapinfo1[i1].type); j1++){
509
510         current_fragment = j1;
511
512         if(heapinfo1[i1].busy_frag.frag_size[j1] == -1) /* Free fragment */
513           continue;
514
515         if(heapinfo1[i1].busy_frag.equal_to[j1] != NULL)
516           continue;
517
518         addr_frag1 = (void*) ((char *)addr_block1 + (j1 << heapinfo1[i1].type));
519
520         i2 = 1;
521         equal = 0;
522         
523         /* Try first to associate to same fragment in the other heap */
524         if(heapinfo2[current_block].type == heapinfo1[current_block].type){
525
526           if(heapinfo2[current_block].busy_frag.equal_to[current_fragment] == NULL){  
527           
528             addr_block2 = ((void*) (((ADDR2UINT(current_block)) - 1) * BLOCKSIZE + (char*)((xbt_mheap_t)s_heap)->heapbase));
529             addr_frag2 = (void*) ((char *)addr_block2 + (current_fragment << ((xbt_mheap_t)s_heap)->heapinfo[current_block].type));
530
531             res_compare = compare_heap_area(addr_frag1, addr_frag2, NULL, NULL, NULL, NULL, 0); /*FIXME*/
532
533             if(res_compare == 0)
534               equal = 1;
535         
536             xbt_dynar_reset(previous);
537
538           }
539
540         }
541
542         while(i2 <= heaplimit && !equal){
543
544           
545           if(heapinfo2[i2].type <= 0){
546             i2++;
547             continue;
548           }
549
550           for(j2=0; j2 < (size_t) (BLOCKSIZE >> heapinfo2[i2].type); j2++){
551
552             if(i2 == current_block && j2 == current_fragment)
553               continue;
554
555             if(heapinfo2[i2].busy_frag.equal_to[j2] != NULL)                
556               continue;            
557                           
558             addr_block2 = ((void*) (((ADDR2UINT(i2)) - 1) * BLOCKSIZE + (char*)((xbt_mheap_t)s_heap)->heapbase));
559             addr_frag2 = (void*) ((char *)addr_block2 + (j2 << ((xbt_mheap_t)s_heap)->heapinfo[i2].type));
560
561             res_compare = compare_heap_area(addr_frag1, addr_frag2, NULL, NULL, NULL, NULL, 0); /*FIXME*/
562             
563             if(res_compare == 0){
564               equal = 1;
565               xbt_dynar_reset(previous);
566               break;
567             }
568
569             xbt_dynar_reset(previous);
570
571           }
572
573           i2++;
574
575         }
576
577         if(heapinfo1[i1].busy_frag.equal_to[j1] == NULL){
578           XBT_DEBUG("Block %zu, fragment %zu not found (size_used = %zd, address = %p, ignore %d)\n", i1, j1, heapinfo1[i1].busy_frag.frag_size[j1], addr_frag1, heapinfo1[i1].busy_frag.ignore[j1]);
579           i2 = heaplimit + 1;
580           i1 = heaplimit + 1;
581           nb_diff1++;
582           break;
583         }
584
585       }
586
587       i1++;
588       
589     }
590
591   }
592
593   /* All blocks/fragments are equal to another block/fragment ? */
594   size_t i = 1, j = 0;
595   void *real_addr_frag1 = NULL, *real_addr_block1 = NULL, *real_addr_block2 = NULL, *real_addr_frag2 = NULL;
596  
597   while(i<=heaplimit){
598     if(heapinfo1[i].type == 0){
599       if(current_block == heaplimit){
600         if(heapinfo1[i].busy_block.busy_size > 0){
601           if(heapinfo1[i].busy_block.equal_to == NULL){
602             if(XBT_LOG_ISENABLED(mm_diff, xbt_log_priority_debug)){
603               addr_block1 = ((void*) (((ADDR2UINT(i)) - 1) * BLOCKSIZE + (char*)heapbase1));
604               XBT_DEBUG("Block %zu (%p) not found (size used = %zu)", i, addr_block1, heapinfo1[i].busy_block.busy_size);
605               //mmalloc_backtrace_block_display((void*)heapinfo1, i);
606             }
607             nb_diff1++;
608           }
609         }
610       }
611     }
612     if(heapinfo1[i].type > 0){
613       addr_block1 = ((void*) (((ADDR2UINT(i)) - 1) * BLOCKSIZE + (char*)heapbase1));
614       real_addr_block1 =  ((void*) (((ADDR2UINT(i)) - 1) * BLOCKSIZE + (char*)((struct mdesc *)s_heap)->heapbase));
615       for(j=0; j < (size_t) (BLOCKSIZE >> heapinfo1[i].type); j++){
616         if(current_block == heaplimit){
617           if(heapinfo1[i].busy_frag.frag_size[j] > 0){
618             if(heapinfo1[i].busy_frag.equal_to[j] == NULL){
619               if(XBT_LOG_ISENABLED(mm_diff, xbt_log_priority_debug)){
620                 addr_frag1 = (void*) ((char *)addr_block1 + (j << heapinfo1[i].type));
621                 real_addr_frag1 = (void*) ((char *)real_addr_block1 + (j << ((struct mdesc *)s_heap)->heapinfo[i].type));
622                 XBT_DEBUG("Block %zu, Fragment %zu (%p - %p) not found (size used = %zd)", i, j, addr_frag1, real_addr_frag1, heapinfo1[i].busy_frag.frag_size[j]);
623                 //mmalloc_backtrace_fragment_display((void*)heapinfo1, i, j);
624               }
625               nb_diff1++;
626             }
627           }
628         }
629       }
630     }
631     i++; 
632   }
633
634   if(current_block == heaplimit)
635     XBT_DEBUG("Number of blocks/fragments not found in heap1 : %d", nb_diff1);
636
637   i = 1;
638
639   while(i<=heaplimit){
640     if(heapinfo2[i].type == 0){
641       if(current_block == heaplimit){
642         if(heapinfo2[i].busy_block.busy_size > 0){
643           if(heapinfo2[i].busy_block.equal_to == NULL){
644             if(XBT_LOG_ISENABLED(mm_diff, xbt_log_priority_debug)){
645               addr_block2 = ((void*) (((ADDR2UINT(i)) - 1) * BLOCKSIZE + (char*)heapbase2));
646               XBT_DEBUG("Block %zu (%p) not found (size used = %zu)", i, addr_block2, heapinfo2[i].busy_block.busy_size);
647               //mmalloc_backtrace_block_display((void*)heapinfo2, i);
648             }
649             nb_diff2++;
650           }
651         }
652       }
653     }
654     if(heapinfo2[i].type > 0){
655       addr_block2 = ((void*) (((ADDR2UINT(i)) - 1) * BLOCKSIZE + (char*)heapbase2));
656       real_addr_block2 =  ((void*) (((ADDR2UINT(i)) - 1) * BLOCKSIZE + (char*)((struct mdesc *)s_heap)->heapbase));
657       for(j=0; j < (size_t) (BLOCKSIZE >> heapinfo2[i].type); j++){
658         if(current_block == heaplimit){
659           if(heapinfo2[i].busy_frag.frag_size[j] > 0){
660             if(heapinfo2[i].busy_frag.equal_to[j] == NULL){
661               if(XBT_LOG_ISENABLED(mm_diff, xbt_log_priority_debug)){
662                 addr_frag2 = (void*) ((char *)addr_block2 + (j << heapinfo2[i].type));
663                 real_addr_frag2 = (void*) ((char *)real_addr_block2 + (j << ((struct mdesc *)s_heap)->heapinfo[i].type));
664                 XBT_DEBUG( "Block %zu, Fragment %zu (%p - %p) not found (size used = %zd)", i, j, addr_frag2, real_addr_frag2, heapinfo2[i].busy_frag.frag_size[j]);
665                 //mmalloc_backtrace_fragment_display((void*)heapinfo2, i, j);
666               }
667               nb_diff2++;
668             }
669           }
670         }
671       }
672     }
673     i++; 
674   }
675
676   if(current_block == heaplimit)
677     XBT_DEBUG("Number of blocks/fragments not found in heap2 : %d", nb_diff2);
678
679   xbt_dynar_free(&previous);
680   real_addr_frag1 = NULL, real_addr_block1 = NULL, real_addr_block2 = NULL, real_addr_frag2 = NULL;
681
682   return ((nb_diff1 > 0) || (nb_diff2 > 0));
683 }
684
685 static int compare_heap_area_without_type(void *real_area1, void *real_area2, void *area1, void *area2, xbt_dynar_t previous, xbt_dict_t all_types, xbt_dict_t other_types, int size, int check_ignore){
686
687   int i = 0;
688   void *addr_pointed1, *addr_pointed2;
689   int pointer_align, ignore1, ignore2, res_compare;
690
691   while(i<size){
692
693     if(check_ignore > 0){
694       if((ignore1 = heap_comparison_ignore_size(to_ignore1, (char *)real_area1 + i)) > 0){
695         if((ignore2 = heap_comparison_ignore_size(to_ignore2, (char *)real_area2 + i))  == ignore1){
696           i = i + ignore2;
697           check_ignore--;
698           continue;
699         }
700       }
701     }
702
703     if(memcmp(((char *)area1) + i, ((char *)area2) + i, 1) != 0){
704
705       pointer_align = (i / sizeof(void*)) * sizeof(void*);
706       addr_pointed1 = *((void **)((char *)area1 + pointer_align));
707       addr_pointed2 = *((void **)((char *)area2 + pointer_align));
708       
709       if(addr_pointed1 > maestro_stack_start && addr_pointed1 < maestro_stack_end && addr_pointed2 > maestro_stack_start && addr_pointed2 < maestro_stack_end){
710         i = pointer_align + sizeof(void *);
711         continue;
712       }else if((addr_pointed1 > s_heap) && ((char *)addr_pointed1 < (char *)s_heap + STD_HEAP_SIZE) 
713                && (addr_pointed2 > s_heap) && ((char *)addr_pointed2 < (char *)s_heap + STD_HEAP_SIZE)){
714         res_compare = compare_heap_area(addr_pointed1, addr_pointed2, previous, all_types, other_types, NULL, 0); 
715         if(res_compare != 0){
716           return res_compare;
717         }
718         i = pointer_align + sizeof(void *);
719         continue;
720       }else{
721         return 1;
722       }
723       
724     }
725     
726     i++;
727
728   }
729
730   return 0;
731  
732 }
733
734
735 static int compare_heap_area_with_type(void *real_area1, void *real_area2, void *area1, void *area2, 
736                                        xbt_dynar_t previous, xbt_dict_t all_types, xbt_dict_t other_types, char *type_id, 
737                                        int area_size, int check_ignore, int pointer_level){
738
739   if(is_stack(real_area1) && is_stack(real_area2))
740     return 0;
741
742   size_t ignore1, ignore2;
743
744   if((check_ignore > 0) && ((ignore1 = heap_comparison_ignore_size(to_ignore1, real_area1)) > 0) && ((ignore2 = heap_comparison_ignore_size(to_ignore2, real_area2))  == ignore1))
745     return 0;
746   
747   dw_type_t type = xbt_dict_get_or_null(all_types, type_id);
748   dw_type_t subtype, subsubtype;
749   int res, elm_size, i, switch_types = 0;
750   unsigned int cursor = 0;
751   dw_type_t member;
752   void *addr_pointed1, *addr_pointed2;;
753   char *type_desc;
754
755   switch(type->type){
756   case e_dw_base_type:
757     if((check_ignore > 0) && ((ignore1 = heap_comparison_ignore_size(to_ignore1, real_area1)) > 0) && ((ignore2 = heap_comparison_ignore_size(to_ignore2, real_area2))  == ignore1))
758       return 0;
759     if(strcmp(type->name, "char") == 0){ /* String, hence random (arbitrary ?) size */
760       return (memcmp(area1, area2, area_size) != 0);
761     }else{
762       if(area_size != -1 && type->size != area_size)
763         return -1;
764       else
765         return (memcmp(area1, area2, type->size) != 0);
766     }
767     break;
768   case e_dw_enumeration_type:
769     if((check_ignore > 0) && ((ignore1 = heap_comparison_ignore_size(to_ignore1, real_area1)) > 0) && ((ignore2 = heap_comparison_ignore_size(to_ignore2, real_area2))  == ignore1))
770       return 0;
771     if(area_size != -1 && type->size != area_size)
772       return -1;
773     else
774       return (memcmp(area1, area2, type->size) != 0);
775     break;
776   case e_dw_typedef:
777     return compare_heap_area_with_type(real_area1, real_area2, area1, area2, previous, all_types, other_types, type->dw_type_id, area_size, check_ignore, pointer_level);
778     break;
779   case e_dw_const_type:
780     return 0;
781     break;
782   case e_dw_array_type:
783     subtype = xbt_dict_get_or_null(all_types, type->dw_type_id);
784     switch(subtype->type){
785     case e_dw_base_type:
786     case e_dw_enumeration_type:
787     case e_dw_pointer_type:
788     case e_dw_structure_type:
789     case e_dw_union_type:
790       if(subtype->size == 0){ /*declaration of the type, need the complete description */
791         type_desc = get_type_description(all_types, subtype->name);
792         if(type_desc){
793           subtype = xbt_dict_get_or_null(all_types, type_desc);
794         }else{
795           subtype = xbt_dict_get_or_null(other_types, get_type_description(other_types, subtype->name));
796           switch_types = 1;
797         }
798       }
799       elm_size = subtype->size;
800       break;
801     case e_dw_typedef:
802     case e_dw_volatile_type:
803       subsubtype = xbt_dict_get_or_null(all_types, subtype->dw_type_id);
804       if(subsubtype->size == 0){ /*declaration of the type, need the complete description */
805         type_desc = get_type_description(all_types, subsubtype->name);
806         if(type_desc){
807           subsubtype = xbt_dict_get_or_null(all_types, type_desc);
808         }else{
809           subsubtype = xbt_dict_get_or_null(other_types, get_type_description(other_types, subtype->name));
810           switch_types = 1;
811         }
812       }
813       elm_size = subsubtype->size;
814       break;
815     default : 
816       return 0;
817       break;
818     }
819     for(i=0; i<type->size; i++){
820       if(switch_types)
821         res = compare_heap_area_with_type((char *)real_area1 + (i*elm_size), (char *)real_area2 + (i*elm_size), (char *)area1 + (i*elm_size), (char *)area2 + (i*elm_size), previous, other_types, all_types, type->dw_type_id, type->size, check_ignore, pointer_level);
822       else
823         res = compare_heap_area_with_type((char *)real_area1 + (i*elm_size), (char *)real_area2 + (i*elm_size), (char *)area1 + (i*elm_size), (char *)area2 + (i*elm_size), previous, all_types, other_types, type->dw_type_id, type->size, check_ignore, pointer_level);
824       if(res != 0)
825         return res;
826     }
827     break;
828   case e_dw_pointer_type:
829     if(type->dw_type_id && ((dw_type_t)xbt_dict_get_or_null(all_types, type->dw_type_id))->type == e_dw_subroutine_type){
830       addr_pointed1 = *((void **)(area1)); 
831       addr_pointed2 = *((void **)(area2));
832       return (addr_pointed1 != addr_pointed2);;
833     }else{
834       pointer_level++;
835       if(pointer_level > 1){ /* Array of pointers */
836         for(i=0; i<(area_size/sizeof(void *)); i++){
837           addr_pointed1 = *((void **)((char *)area1 + (i*sizeof(void *)))); 
838           addr_pointed2 = *((void **)((char *)area2 + (i*sizeof(void *)))); 
839           if(addr_pointed1 > s_heap && (char *)addr_pointed1 < (char*) s_heap + STD_HEAP_SIZE && addr_pointed2 > s_heap && (char *)addr_pointed2 < (char*) s_heap + STD_HEAP_SIZE)
840             res =  compare_heap_area(addr_pointed1, addr_pointed2, previous, all_types, other_types, type->dw_type_id, pointer_level); 
841           else
842             res =  (addr_pointed1 != addr_pointed2);
843           if(res != 0)
844             return res;
845         }
846       }else{
847         addr_pointed1 = *((void **)(area1)); 
848         addr_pointed2 = *((void **)(area2));
849         if(addr_pointed1 > s_heap && (char *)addr_pointed1 < (char*) s_heap + STD_HEAP_SIZE && addr_pointed2 > s_heap && (char *)addr_pointed2 < (char*) s_heap + STD_HEAP_SIZE)
850           return compare_heap_area(addr_pointed1, addr_pointed2, previous, all_types, other_types, type->dw_type_id, pointer_level); 
851         else
852           return  (addr_pointed1 != addr_pointed2);
853       }
854     }
855     break;
856   case e_dw_structure_type:
857     if(type->size == 0){ /*declaration of the structure, need the complete description */
858       type_desc = get_type_description(all_types, type->name);
859       if(type_desc){
860         type = xbt_dict_get_or_null(all_types, type_desc);
861       }else{
862         type = xbt_dict_get_or_null(other_types, get_type_description(other_types, type->name));
863         switch_types = 1;
864       }
865     }
866     if(area_size != -1 && type->size != area_size){
867       if(area_size>type->size && area_size%type->size == 0){
868         for(i=0; i<(area_size/type->size); i++){
869           if(switch_types)
870             res = compare_heap_area_with_type((char *)real_area1 + (i*type->size), (char *)real_area2 + (i*type->size), (char *)area1 + (i*type->size), (char *)area2 + (i*type->size), previous, other_types, all_types, type_id, -1, check_ignore, 0); 
871           else
872             res = compare_heap_area_with_type((char *)real_area1 + (i*type->size), (char *)real_area2 + (i*type->size), (char *)area1 + (i*type->size), (char *)area2 + (i*type->size), previous, all_types, other_types, type_id, -1, check_ignore, 0); 
873           if(res != 0)
874             return res;
875         }
876       }else{
877         return -1;
878       }
879     }else{
880       cursor = 0;
881       xbt_dynar_foreach(type->members, cursor, member){
882         if(switch_types)
883           res = compare_heap_area_with_type((char *)real_area1 + member->offset, (char *)real_area2 + member->offset, (char *)area1 + member->offset, (char *)area2 + member->offset, previous, other_types, all_types, member->dw_type_id, -1, check_ignore, 0);
884         else
885           res = compare_heap_area_with_type((char *)real_area1 + member->offset, (char *)real_area2 + member->offset, (char *)area1 + member->offset, (char *)area2 + member->offset, previous, all_types, other_types, member->dw_type_id, -1, check_ignore, 0);  
886         if(res != 0)
887           return res;        
888       }
889     }
890     break;
891   case e_dw_union_type:
892     if((check_ignore > 0) && ((ignore1 = heap_comparison_ignore_size(to_ignore1, real_area1)) > 0) && ((ignore2 = heap_comparison_ignore_size(to_ignore2, real_area2))  == ignore1))
893       return 0;
894     return compare_heap_area_without_type(real_area1, real_area2, area1, area2, previous, all_types, other_types, type->size, check_ignore);
895     break;
896   case e_dw_volatile_type:
897     return compare_heap_area_with_type(real_area1, real_area2, area1, area2, previous, all_types, other_types, type->dw_type_id, area_size, check_ignore, pointer_level);
898     break;
899   default:
900     break;
901   }
902
903   return 0;
904
905 }
906
907 int compare_heap_area(void *area1, void* area2, xbt_dynar_t previous, xbt_dict_t all_types, xbt_dict_t other_types, char *type_id, int pointer_level){
908
909   int res_compare;
910   ssize_t block1, frag1, block2, frag2;
911   ssize_t size;
912   int check_ignore = 0;
913
914   void *addr_block1, *addr_block2, *addr_frag1, *addr_frag2;
915   void *area1_to_compare, *area2_to_compare;
916
917   int match_pairs = 0;
918
919   if(previous == NULL){
920     previous = xbt_dynar_new(sizeof(heap_area_pair_t), heap_area_pair_free_voidp);
921     match_pairs = 1;
922   }
923
924   block1 = ((char*)area1 - (char*)((xbt_mheap_t)s_heap)->heapbase) / BLOCKSIZE + 1;
925   block2 = ((char*)area2 - (char*)((xbt_mheap_t)s_heap)->heapbase) / BLOCKSIZE + 1;
926
927   if(is_block_stack((int)block1) && is_block_stack((int)block2)){
928     add_heap_area_pair(previous, block1, -1, block2, -1);
929     if(match_pairs){
930       match_equals(previous);
931       xbt_dynar_free(&previous);
932     }
933     return 0;
934   }
935
936   if(((char *)area1 < (char*)((xbt_mheap_t)s_heap)->heapbase)  || (block1 > heapsize1) || (block1 < 1) || ((char *)area2 < (char*)((xbt_mheap_t)s_heap)->heapbase) || (block2 > heapsize2) || (block2 < 1)){
937     if(match_pairs){
938       xbt_dynar_free(&previous);
939     }
940     return 1;
941   }
942
943   addr_block1 = ((void*) (((ADDR2UINT(block1)) - 1) * BLOCKSIZE + (char*)heapbase1));
944   addr_block2 = ((void*) (((ADDR2UINT(block2)) - 1) * BLOCKSIZE + (char*)heapbase2));
945   
946   if(heapinfo1[block1].type == heapinfo2[block2].type){
947     
948     if(heapinfo1[block1].type == -1){ /* Free block */
949       if(match_pairs){
950         match_equals(previous);
951         xbt_dynar_free(&previous);
952       }
953       return 0;
954
955     }else if(heapinfo1[block1].type == 0){ /* Complete block */
956
957       if(heapinfo1[block1].busy_block.equal_to != NULL && heapinfo2[block2].busy_block.equal_to != NULL){
958         if(equal_blocks(block1, block2)){
959           if(match_pairs){
960             match_equals(previous);
961             xbt_dynar_free(&previous);
962           }
963           return 0;
964         }
965       }
966
967       if(heapinfo1[block1].busy_block.size != heapinfo2[block2].busy_block.size){
968         if(match_pairs){
969           xbt_dynar_free(&previous);
970         }
971         return 1;
972       }
973
974       if(heapinfo1[block1].busy_block.busy_size != heapinfo2[block2].busy_block.busy_size){
975         if(match_pairs){
976           xbt_dynar_free(&previous);
977         }
978         return 1;
979       }
980
981       if(!add_heap_area_pair(previous, block1, -1, block2, -1)){
982         if(match_pairs){
983           match_equals(previous);
984           xbt_dynar_free(&previous);
985         }
986         return 0;
987       }
988  
989       size = heapinfo1[block1].busy_block.busy_size;
990
991       if(size <= 0){
992         if(match_pairs){
993           match_equals(previous);
994           xbt_dynar_free(&previous);
995         }
996         return 0;
997       }
998
999       frag1 = -1;
1000       frag2 = -1;
1001
1002       area1_to_compare = addr_block1;
1003       area2_to_compare = addr_block2;
1004
1005       if((heapinfo1[block1].busy_block.ignore > 0) && (heapinfo2[block2].busy_block.ignore == heapinfo1[block1].busy_block.ignore))
1006         check_ignore = heapinfo1[block1].busy_block.ignore;
1007       
1008     }else{ /* Frgamented block */
1009
1010       frag1 = ((uintptr_t) (ADDR2UINT (area1) % (BLOCKSIZE))) >> heapinfo1[block1].type;
1011       frag2 = ((uintptr_t) (ADDR2UINT (area2) % (BLOCKSIZE))) >> heapinfo2[block2].type;
1012       
1013       addr_frag1 = (void*) ((char *)addr_block1 + (frag1 << heapinfo1[block1].type));
1014       addr_frag2 = (void*) ((char *)addr_block2 + (frag2 << heapinfo2[block2].type));
1015       
1016       area1_to_compare = addr_frag1;
1017       area2_to_compare = addr_frag2;
1018
1019       if(heapinfo1[block1].busy_frag.equal_to[frag1] != NULL && heapinfo2[block2].busy_frag.equal_to[frag2] != NULL){
1020         if(equal_fragments(block1, frag1, block2, frag2)){
1021           if(match_pairs){
1022             match_equals(previous);
1023             xbt_dynar_free(&previous);
1024           }
1025           return 0;
1026         }
1027       }
1028
1029       if(heapinfo1[block1].busy_frag.frag_size[frag1] != heapinfo2[block2].busy_frag.frag_size[frag2]){
1030         if(match_pairs){
1031           xbt_dynar_free(&previous);
1032         }
1033         return 1;  
1034       }
1035       
1036       if(!add_heap_area_pair(previous, block1, frag1, block2, frag2)){
1037         if(match_pairs){
1038           match_equals(previous);
1039           xbt_dynar_free(&previous);
1040         }
1041         return 0;
1042       }
1043
1044       size = heapinfo1[block1].busy_frag.frag_size[frag1];
1045
1046       if(size <= 0){
1047         if(match_pairs){
1048           match_equals(previous);
1049           xbt_dynar_free(&previous);
1050         }
1051         return 0;
1052       }
1053       
1054       if((heapinfo1[block1].busy_frag.ignore[frag1] > 0) && ( heapinfo2[block2].busy_frag.ignore[frag2] == heapinfo1[block1].busy_frag.ignore[frag1]))
1055         check_ignore = heapinfo1[block1].busy_frag.ignore[frag1];
1056       
1057     }
1058
1059   }else if((heapinfo1[block1].type > 0) && (heapinfo2[block2].type > 0)){
1060
1061     frag1 = ((uintptr_t) (ADDR2UINT (area1) % (BLOCKSIZE))) >> heapinfo1[block1].type;
1062     frag2 = ((uintptr_t) (ADDR2UINT (area2) % (BLOCKSIZE))) >> heapinfo2[block2].type;
1063
1064     if(heapinfo1[block1].busy_frag.equal_to[frag1] != NULL || heapinfo2[block2].busy_frag.equal_to[frag2] != NULL){
1065       if(equal_fragments(block1, frag1, block2, frag2)){
1066         if(match_pairs){
1067           match_equals(previous);
1068           xbt_dynar_free(&previous);
1069         }
1070         return 0;
1071       }
1072     }
1073
1074     if(heapinfo1[block1].busy_frag.frag_size[frag1] != heapinfo2[block2].busy_frag.frag_size[frag2]){
1075       if(match_pairs){
1076         xbt_dynar_free(&previous);
1077       }
1078       return 1;
1079     }
1080     
1081     if(!add_heap_area_pair(previous, block1, frag1, block2, frag2)){
1082       if(match_pairs){
1083         match_equals(previous);
1084         xbt_dynar_free(&previous);
1085       }
1086       return 0;
1087     }
1088
1089     addr_frag1 = (void*) ((char *)addr_block1 + (frag1 << heapinfo1[block1].type));
1090     addr_frag2 = (void*) ((char *)addr_block2 + (frag2 << heapinfo2[block2].type));
1091
1092     area1_to_compare = addr_frag1;
1093     area2_to_compare = addr_frag2;
1094       
1095     size = heapinfo1[block1].busy_frag.frag_size[frag1];
1096
1097     if(size <= 0){
1098       if(match_pairs){
1099         match_equals(previous);
1100         xbt_dynar_free(&previous);
1101       }
1102       return 0;
1103     }
1104
1105     if((heapinfo1[block1].busy_frag.ignore[frag1] > 0) && (heapinfo2[block2].busy_frag.ignore[frag2] == heapinfo1[block1].busy_frag.ignore[frag1]))
1106       check_ignore = heapinfo1[block1].busy_frag.ignore[frag1];   
1107     
1108   }else{
1109     if(match_pairs){
1110       xbt_dynar_free(&previous);
1111     }
1112     return 1;
1113   }
1114
1115
1116   /* Start comparison*/
1117   if(type_id != NULL){
1118     res_compare = compare_heap_area_with_type(area1, area2, area1_to_compare, area2_to_compare, previous, all_types, other_types, type_id, size, check_ignore, pointer_level);
1119     if(res_compare != 0){
1120       if(match_pairs)
1121         xbt_dynar_free(&previous);
1122       return res_compare;
1123     }
1124   }else{
1125     res_compare = compare_heap_area_without_type(area1, area2, area1_to_compare, area2_to_compare, previous, all_types, other_types, size, check_ignore);
1126       if(res_compare != 0){
1127         if(match_pairs)
1128           xbt_dynar_free(&previous);
1129         return res_compare;
1130       }
1131   }
1132
1133   if(match_pairs){
1134     match_equals(previous);
1135     xbt_dynar_free(&previous);
1136   }
1137
1138   return 0;
1139 }
1140
1141 /*********************************************** Miscellaneous ***************************************************/
1142 /****************************************************************************************************************/
1143
1144
1145 int get_pointed_area_size(void *area, int heap){
1146
1147   int block, frag;
1148   malloc_info *heapinfo;
1149
1150   if(heap == 1)
1151     heapinfo = heapinfo1;
1152   else
1153     heapinfo = heapinfo2;
1154
1155   block = ((char*)area - (char*)((xbt_mheap_t)s_heap)->heapbase) / BLOCKSIZE + 1;
1156
1157   if(((char *)area < (char*)((xbt_mheap_t)s_heap)->heapbase)  || (block > heapsize1) || (block < 1))
1158     return -1;
1159
1160   if(heapinfo[block].type == -1){ /* Free block */
1161     return -1;  
1162   }else if(heapinfo[block].type == 0){ /* Complete block */
1163     return (int)heapinfo[block].busy_block.busy_size;
1164   }else{
1165     frag = ((uintptr_t) (ADDR2UINT (area) % (BLOCKSIZE))) >> heapinfo[block].type;
1166     return (int)heapinfo[block].busy_frag.frag_size[frag];
1167   }
1168
1169 }
1170
1171 char *get_type_description(xbt_dict_t types, char *type_name){
1172
1173   xbt_dict_cursor_t dict_cursor;
1174   char *type_origin;
1175   dw_type_t type;
1176
1177   xbt_dict_foreach(types, dict_cursor, type_origin, type){
1178     if(type->name && (strcmp(type->name, type_name) == 0) && type->size > 0){
1179       xbt_dict_cursor_free(&dict_cursor);
1180       return type_origin;
1181     }
1182   }
1183
1184   xbt_dict_cursor_free(&dict_cursor);
1185   return NULL;
1186 }
1187
1188
1189 #ifndef max
1190 #define max( a, b ) ( ((a) > (b)) ? (a) : (b) )
1191 #endif
1192
1193 int mmalloc_linear_compare_heap(xbt_mheap_t heap1, xbt_mheap_t heap2){
1194
1195   if(heap1 == NULL && heap1 == NULL){
1196     XBT_DEBUG("Malloc descriptors null");
1197     return 0;
1198   }
1199
1200   if(heap1->heaplimit != heap2->heaplimit){
1201     XBT_DEBUG("Different limit of valid info table indices");
1202     return 1;
1203   }
1204
1205   /* Heap information */
1206   heaplimit = ((struct mdesc *)heap1)->heaplimit;
1207
1208   s_heap = (char *)mmalloc_get_current_heap() - STD_HEAP_SIZE - getpagesize();
1209
1210   heapbase1 = (char *)heap1 + BLOCKSIZE;
1211   heapbase2 = (char *)heap2 + BLOCKSIZE;
1212
1213   heapinfo1 = (malloc_info *)((char *)heap1 + ((uintptr_t)((char *)heap1->heapinfo - (char *)s_heap)));
1214   heapinfo2 = (malloc_info *)((char *)heap2 + ((uintptr_t)((char *)heap2->heapinfo - (char *)s_heap)));
1215
1216   heapsize1 = heap1->heapsize;
1217   heapsize2 = heap2->heapsize;
1218
1219   /* Start comparison */
1220   size_t i, j, k;
1221   void *addr_block1, *addr_block2, *addr_frag1, *addr_frag2;
1222
1223   int distance = 0;
1224
1225   /* Check busy blocks*/
1226
1227   i = 1;
1228
1229   while(i <= heaplimit){
1230
1231     addr_block1 = ((void*) (((ADDR2UINT(i)) - 1) * BLOCKSIZE + (char*)heapbase1));
1232     addr_block2 = ((void*) (((ADDR2UINT(i)) - 1) * BLOCKSIZE + (char*)heapbase2));
1233
1234     if(heapinfo1[i].type != heapinfo2[i].type){
1235   
1236       distance += BLOCKSIZE;
1237       XBT_DEBUG("Different type of blocks (%zu) : %d - %d -> distance = %d", i, heapinfo1[i].type, heapinfo2[i].type, distance);
1238       i++;
1239     
1240     }else{
1241
1242       if(heapinfo1[i].type == -1){ /* Free block */
1243         i++;
1244         continue;
1245       }
1246
1247       if(heapinfo1[i].type == 0){ /* Large block */
1248        
1249         if(heapinfo1[i].busy_block.size != heapinfo2[i].busy_block.size){
1250           distance += BLOCKSIZE * max(heapinfo1[i].busy_block.size, heapinfo2[i].busy_block.size);
1251           i += max(heapinfo1[i].busy_block.size, heapinfo2[i].busy_block.size);
1252           XBT_DEBUG("Different larger of cluster at block %zu : %zu - %zu -> distance = %d", i, heapinfo1[i].busy_block.size, heapinfo2[i].busy_block.size, distance);
1253           continue;
1254         }
1255
1256         /*if(heapinfo1[i].busy_block.busy_size != heapinfo2[i].busy_block.busy_size){
1257           distance += max(heapinfo1[i].busy_block.busy_size, heapinfo2[i].busy_block.busy_size);
1258           i += max(heapinfo1[i].busy_block.size, heapinfo2[i].busy_block.size);
1259           XBT_DEBUG("Different size used oin large cluster at block %zu : %zu - %zu -> distance = %d", i, heapinfo1[i].busy_block.busy_size, heapinfo2[i].busy_block.busy_size, distance);
1260           continue;
1261           }*/
1262
1263         k = 0;
1264
1265         //while(k < (heapinfo1[i].busy_block.busy_size)){
1266         while(k < heapinfo1[i].busy_block.size * BLOCKSIZE){
1267           if(memcmp((char *)addr_block1 + k, (char *)addr_block2 + k, 1) != 0){
1268             distance ++;
1269           }
1270           k++;
1271         } 
1272
1273         i++;
1274
1275       }else { /* Fragmented block */
1276
1277         for(j=0; j < (size_t) (BLOCKSIZE >> heapinfo1[i].type); j++){
1278
1279           addr_frag1 = (void*) ((char *)addr_block1 + (j << heapinfo1[i].type));
1280           addr_frag2 = (void*) ((char *)addr_block2 + (j << heapinfo2[i].type));
1281
1282           if(heapinfo1[i].busy_frag.frag_size[j] == 0 && heapinfo2[i].busy_frag.frag_size[j] == 0){
1283             continue;
1284           }
1285           
1286           
1287           /*if(heapinfo1[i].busy_frag.frag_size[j] != heapinfo2[i].busy_frag.frag_size[j]){
1288             distance += max(heapinfo1[i].busy_frag.frag_size[j], heapinfo2[i].busy_frag.frag_size[j]);
1289             XBT_DEBUG("Different size used in fragment %zu in block %zu : %d - %d -> distance = %d", j, i, heapinfo1[i].busy_frag.frag_size[j], heapinfo2[i].busy_frag.frag_size[j], distance); 
1290             continue;
1291             }*/
1292    
1293           k=0;
1294
1295           //while(k < max(heapinfo1[i].busy_frag.frag_size[j], heapinfo2[i].busy_frag.frag_size[j])){
1296           while(k < (BLOCKSIZE / (BLOCKSIZE >> heapinfo1[i].type))){
1297             if(memcmp((char *)addr_frag1 + k, (char *)addr_frag2 + k, 1) != 0){
1298               distance ++;
1299             }
1300             k++;
1301           }
1302
1303         }
1304
1305         i++;
1306
1307       }
1308       
1309     }
1310
1311   }
1312
1313   return distance;
1314   
1315 }
1316