vmalloc.cpp 22.4 KB
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777
/* vmalloc.c ***********************************************

                      Anubis Virtual Machine
               The virtual machine's memory allocator.

***********************************************************/

#include "AnubisSupport.h"
#include <stdlib.h>
#include <malloc.h>   
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include "vm.h"
#include "dependencies.h"


int debug_mem = 0; 
int memory_in_use = 0; 
int heap_test = 0; 

#ifdef record_allocations   
static void free_allocation_record(U32 *seg)
{
  int i; 
  for (i = 0; i < max_seg_descr; i++)
    if (seg_descrs[i].seg == seg)
      {
        seg_descrs[i].seg = NULL;
        return;
      }
  fprintf(stdout,"freeing segment %p which was not allocated.\n",seg);
  if (seg_descrs[i].filename != NULL)
    {
      fprintf(stdout,"previously allocated by %s line %d IP=%d.\n",
              seg_descrs[i].filename,
              seg_descrs[i].line,
              seg_descrs[i].IP);
    }
  my_exit(1); 
}
#endif                                   
   



/* 
   *** Description. 

   This is  the memory  allocator for Anubis  virtual machines.  It works as  follows. Let
   'allocator' be a pointer to an allocator structure (see 'vm.h').

   Each allocator  has a pointer  to a  'chain of free  memory segments'. This  pointer is
   'allocator->ffss'.  It is  either NULL  (the chain  is empty)  or points  to  the first
   segment in the chain.

   Each segment  is an  array of  U32s. The  first two U32s  in the  array have  a special
   purpose. Others do not contain any significant data. If 'ptr' point to a segment in the
   chain ('ptr' has  type (U32 *)), then 'ptr[0]'  is the size of the  segment (counted in
   U32s), and 'ptr[1]'  is the pointer to the  next segment. Of course 'ptr[1]'  has to be
   cast in  order to be used:  (U32 *)(ptr[1]). Hence, here  is a picture of  the chain of
   segments for a given allocator:

     allocator->ffss
             |
             |
             v
             |size| *  |....... first segment .......|
                    |
                    |
                    v
                    |size| *  |....... second segment .......|
                           |
                           :
                  ( more segments )
                           :
                           |
                           v
                           |size|NULL|....... last segment .......|

   Notice  that  'size' is  the  total  size of  the  segment  including  the two  leading
   words. For example, we may have a segment like this:

                  |  5  |  *  |  w1  |  w2  |  w3  |

   with only 3 words of non significant data. 


   *** Testing the chain of segments. 

   The following works only is the flag 'heap_test' is on.

   Each allocator has the  fields 'ffss_seg_num', ffss_size_sum' and 'ffss_ptr_sum', whose
   purpose is just verification. These variables contain respectively (all are U32s):

        ffss_seg_num:   the number of segments in the chain, 
        ffss_size_sum:  the sum of the sizes of all segments
        ffss_ptr_num:   the sum (check sum) of all the addresses of
                   the segments. 

   Of course, 'ffss_size_sum' is not only a check  sum of the sizes of the segments, it is
   also  the total size  of the  chain. However,  it cannot  be used  as such  in general,
   because 'heap_test' must be set.

   These data may be checked by the function:

        test_memory_check_sums(allocator)

   They are updated by:

        compute_memory_check_sums(allocator). 

*/



//Allocator new_allocator(void)
//{
//  Allocator result = (Allocator)malloc(sizeof(struct Allocator_struct)); 
//
//  if (result == NULL) return NULL; 
//
//  if ((result->memory = (U32 *)malloc((6+memory_seg_size)*sizeof(U32))) == NULL)
//    {
//      free(result);
//      return NULL; 
//    }
//  result->word_size = 6+memory_seg_size; 
//  (result->memory)[0] = (U32)NULL;  /* only one segment of memory */ 
//  (result->memory)[1] = (U32)NULL;  /* duplicated chaining for redundancy */ 
//  (result->memory)[2] = (U32)NULL;  /* duplicated chaining for redundancy */ 
//  (result->memory)[3] = (U32)memory_seg_size;  /* useful size of segment */ 
//  (result->memory)[4] = (U32)memory_seg_size;  /* duplicated for redundancy */ 
//  (result->memory)[5] = (U32)memory_seg_size;  /* duplicated for redundancy */ 
//
//   
//  /* initialize the chain of memory segments */ 
//  result->ffss = (result->memory)+6; 
//  (result->ffss)[0] = memory_seg_size;
//  (result->ffss)[1] = (U32)NULL; 
//
//  result->allocated_segments = 0; 
//   
//#ifdef debug_vm   
//  /* cannot test heap_test here (too early) */ 
//  compute_memory_check_sums(result);
//  test_memory_check_sums(result); 
//#endif
//   
//  return result; 
//}


//U32 destroy_allocator(Allocator allocator)
//{
//  if (allocator == NULL) return 0; 
//  {
//    U32 *first = NULL; 
//    U32 *others = allocator->memory; 
//    U32 size = allocator->word_size; 
//   
//    while (others != NULL)
//      {
//        first = others; 
//        others = (U32 *)(others[0]); 
//   
//        free(first); 
//      }
//    free(allocator); 
//    return size; 
//  }
//}
   

   
   

//#define the_ffss    (allocator->ffss)


///* How a virtual machine allocates a data segment */ 
//U32 _allocate_data_segment(int words,      /* requested size in U32s */ 
//#ifdef record_allocations
//                          char *filename, 
//                          int line, 
//                          int IP,
//#endif   
//     Allocator allocator)
//{
//  U32 *  ptr = the_ffss;              /* ptr points to current segment */ 
//  U32 *  prev = NULL;                 /* prev points to previous segment */ 
//  U32    result;                      /* NULL or address of a full segment */ 
//
//  if (words < 1) words = 1;  
//
//  words += security_zone_size;
//   
//  if (memory_seg_size < (U32)(words+64)) 
//    {
//      memory_seg_size = (U32)(words+64);
//      //fprintf(stderr,"memory_seg_size augmented to %d words\n",memory_seg_size); 
//      //     if (!enlarge_memory(allocator))   // this may generate a segment violation !
//      return 0; 
//    }
//
//  //printf("memory_seg_size = %d\n",memory_seg_size); 
//
//#ifdef debug_vm    
//  if (heap_test) test_memory_check_sums(allocator);
//#endif   
//
//  /* the chain of segments may be empty */ 
//  if (ptr == NULL) 
//    {
//      return 0;
//    }
//
//  /* need one more (invisible) word for size of allocated segment */ 
//  words++; 
//
//  //printf("ptr = %p\n",ptr); fflush(stdout); 
//   
//  /* find a segment big enough */ 
//  while (ptr[0] < (U32)words)
//    {
//      //printf("1 prev = %p ptr = %p\n",prev,ptr); fflush(stdout); 
//    if ((prev = ptr, ptr = (U32 *)(ptr[1])) == NULL)
//      {
//        return 0; /* all segments are too small */
//      }     
//    //printf("2 prev = %p ptr = %p\n",prev,ptr); fflush(stdout); 
//    }
//
//  /* if here, a segment which is big enough has been found. In any
//     case the allocated segment will have this address, hence:  */ 
//  result = (U32)(ptr+1); /* make size word invisible */ 
//
//  if (ptr[0] <= (U32)(words+2))  
//  {
//      /* don't cut the segment, because the rest will be too
//  small. Don't change the size of segment. */ 
//    if (prev == NULL)
//   the_ffss = (U32 *)(ptr[1]);  
//    else
//   prev[1] = ptr[1];   /* shorten the chain */ 
//  }
//  else 
//  {
//      /* the segment is big enough to be cut */ 
//      assert(words >= 2); 
//      ptr[words] = ptr[0] - words;   /* size of rest */ 
//      ptr[0] = words;                /* size of allocated segment */ 
//      ptr[words+1] = ptr[1];         /* pointer to next segment */ 
//
//      /* we must update information in previous segment */ 
//    if (prev == NULL)   /* no previous segment */ 
// {
//   the_ffss += words;  /* increment free segments pointer */ 
// }
//    else
//    {
//   prev[1] =  prev[1] + (words * sizeof(U32)); /* update 'next' in previous segment */ 
////   ((U32 *)(prev[1])) += words; /* update 'next' in previous segment */ 
// }
////   ((U32 *)(prev[1])) += words; /* update 'next' in previous segment */ 
//  }
//  ptr[1] = 1; /* initialize reference counter */ 
//
//#ifdef debug_vm   
//  if (heap_test) compute_memory_check_sums(allocator);
//#endif   
//
//  memory_in_use += ptr[0]; 
//  (allocator->allocated_segments)++; 
//   
//#ifdef record_allocations
//  record_data_segment(filename,line,(U32 *)result,IP); 
//  //fprintf(stderr,"allocation for %s:%d at %p\n",filename,line,(U32 *)result); 
//#endif   
//  return result; 
//}




///* how a virtual machine frees a data segment */ 
//U32 *_free_data_segment(U32 *ss,       /* freed segment */ 
//#ifdef record_allocations
//                        char *filename,
//                        int line,
//#endif   
//                       Allocator allocator)    
//{
//  U32 *ptr;            /* current segment */ 
//  U32 *prev = NULL;    /* previous of current */ 
//  U32 *ss_prev = NULL; 
//
//#ifdef debug_vm   
//  if (heap_test) test_memory_check_sums(allocator); 
//#endif   
//
//#ifdef record_allocations
//  free_allocation_record(ss); 
//  //fprintf(stderr,"freeing for %s:%d at %p\n",filename,line,ss); 
//#endif   
//   
//  ptr = the_ffss; 
//
//  ss--; /* recover invisible size word */ 
//
//  memory_in_use -= ss[0]; 
//  (allocator->allocated_segments)--; 
//  //printf("freeing %d words (%d) [%p].\n",ss[0],memory_in_use,ss+1); 
//
//  /* if memory was empty, just make a new chain with the segment */ 
//  if (ptr == NULL)
//    {
//      ss[1] = (U32)NULL; 
//      the_ffss = ss; 
//
//#ifdef debug_vm   
//      if (heap_test) compute_memory_check_sums(allocator); 
//#endif   
//
//      if (ss[0] == max_data_seg_size)   /* if whole big segment
//        recovered, return it */ 
// return ss;
//      else
// return NULL; 
//    }
//
//  /* state_0:  (commented out, because not used) */ 
//  /* the freed segment is neither left glued nor right glued. We must
//     try to glue it, and then jump to state_1. */
//  while (ptr != NULL)
//    {
//      /* try to glue the freed segment to the right of a segment */
//      if (ptr+ptr[0] == ss)
// {
//   /* Freed segment will now be glued to the right of current
//      segment. Current segment remains the same (but bigger),
//      and previous segment remains the same, even if NULL. Now
//      ss will point to this bigger segment, so that it may be
//      glued later to the left of a segment. */ 
//   ptr[0] += ss[0];   /* enlarge current segment */ 
//   ss = ptr;          /* remember this enlarged segment */ 
//   goto state_1; 
// }
//
//      /* try to glue the freed segment to the left of a segment */ 
//      if (ss+ss[0] == ptr)
// {
//   /* freed segment will now be glued to the left of the
//      current segment. We must enlarge the freed segment, set
//      its 'next' field, and update information in the previous
//      segment. We remember the enlarged segment in ss (which is
//      already pointing to it). */ 
//   ss[0] += ptr[0];    /* enlarge freed segment */
//   assert(ss != ptr); 
//   ss[1] = ptr[1];     /* set 'next' field */ 
//   if (prev == NULL)
//     {
//       the_ffss = ss;    /* new chain of free segments */
//     }
//   else
//     {
//       assert(ss != prev); 
//       prev[1] = (U32)ss; 
//     }
//   ptr = ss; 
//   goto state_1; 
// }
//
//      /* if here, the current segment cannot be glued neither to the
//  left of top the right of the freed segment. Update 'prev' and
//  'ptr', and try again. */  
//      prev = ptr; 
//      ptr = (U32 *)(ptr[1]);
//      assert(ptr != prev);  
//    }
//  /* if here, ptr is NULL, and the freed segment has not been glued
//     neither on the right nor on the left of a segment. The freed
//     segment is chained to other segments in front of the chain. */   
//  ss[1] = (U32)(the_ffss); 
//  the_ffss = ss; 
//
//#ifdef debug_vm   
//  if (heap_test) compute_memory_check_sums(allocator); 
//#endif   
//
//  if (ss[0] == max_data_seg_size)
//    return ss;
//  else 
//    return NULL;
//
//
// state_1:
//  /* the freed segment has been glued either to the left or to the
//     right of a segment of the chain, but not on both sides. 'ss' and 'ptr'
//     point to the enlarged segment. The first candidate to get ss
//     glued to it is the successor of current segment. */ 
//  ss_prev = prev; 
//  prev = ptr; 
//  ptr = (U32 *)(ptr[1]); 
//  assert(prev == ss); 
//  assert(ptr != prev); 
//
//  while (ptr != NULL)
//    {
//      /* here the problem is that we may have to glue two segments
//  which are both already in the chain. The two segments are
//  distinct, and 'ptr' points to a segment which is after 'ss'
//  in the chain. 'ss' may be glued either to the left or to the
//  right of a segment. 'ptr' is known to have a 'previous'
//  segment. On the contrary, it is possible that 'ss' is the
//  first one in the chain. Furthermore, we know that at most one
//  gluing is possible. */
//      if (ss+ss[0] == ptr)
// {
//   /* 'ptr' must be removed from the chain */ 
//   ss[0] += ptr[0];     /* reenlarge ss */ 
//   prev[1] = ptr[1];    /* remove ptr from the chain (this
//      works even if prev == ss) */ 
//
//#ifdef debug_vm   
//   if (heap_test) compute_memory_check_sums(allocator); 
//#endif
//   
//   if (ss[0] == max_data_seg_size)
//     return ss; 
//   else
//     return NULL; 
// }
//
//      if (ptr+ptr[0] == ss)
// {
//   /* we enlarge 'ptr' and remove 'ss' */ 
//   ptr[0] += ss[0]; /* enlarge ptr */ 
//   if (the_ffss == ss)
//     the_ffss = (U32 *)ss[1];  /* this works even if ss == prev */  
//   else
//     ss_prev[1] = ss[1];     /* this works even if ss == prev */ 
//   ss = ptr; 
//
//#ifdef debug_vm
//   if (heap_test) 
//      compute_memory_check_sums(allocator); 
//#endif   
//
//   if (ss[0] == max_data_seg_size)
//     return ss; 
//   else
//     return NULL; 
// }
//      prev = ptr;
//      ptr = (U32 *)(ptr[1]);    
//      assert(ptr != prev); 
//    }
//  /* if here, ptr is NULL, and the enlarged segment will not be glued
//     again. Since it is already glued to a segment, we just have to
//     return. */  
//
//#ifdef debug_vm   
//  if (heap_test) compute_memory_check_sums(allocator); 
//#endif
//   
//  if (ss[0] == max_data_seg_size)
//    return ss; 
//  else
//    return NULL; 
//}


/* This function is use when we do not want to actually free data segments. */ 
   
//U32 *do_not_free_data_segment(U32 *ss,       /* freed segment */ 
//                              Allocator allocator)    
//{
//  return NULL; 
//}
   
   
   
///* reallocating a data segment. */ 
//U32 _reallocate_data_segment(U32 data_seg,
//       int words,
//#ifdef record_allocations
//                            char *filename, 
//                            int line, 
//#endif   
//       Allocator allocator)
//{
//  /* compare size of segment with requested size */ 
//  U32 *seg;
//
//  /* the segment should not be shared */ 
//  // assert(*((U32 *)data_seg) == 1);
//
//  //assert(0); 
//
//  seg = (U32 *)data_seg;
//  seg--;      /* recover size word */ 
//  words++;    /* need one more word for size */ 
//
// begin:
//  if ((U32)words <= seg[0]-2)
//    {
//      /* the segment can be cut down */ 
//      U32 *cut_down = seg+words;
//
//      cut_down[0] = seg[0]-words;
//      cut_down[1] = (U32)the_ffss;
//      the_ffss = cut_down;
//
//      //printf("reallocating %d -> %d words\n",seg[0],words); 
//      memory_in_use += words; 
//      memory_in_use -= seg[0]; 
//     
//      seg[0] = words; 
//
//      //printf("segment has been cut down.\n"); fflush(stdout); 
//
//#ifdef debug_vm   
//      if (heap_test) compute_memory_check_sums(allocator); 
//#endif   
//   
//      return data_seg; 
//    }
//  else if ((U32)words <= seg[0])
//    {
//      /* the size does not change */ 
//
//#ifdef debug_vm   
//      if (heap_test) compute_memory_check_sums(allocator); 
//#endif   
//   
//      //printf("segment unchanged.\n"); fflush(stdout); 
//      return data_seg; 
//    }
//  else 
//    {
//      /* the segment must be enlarged. It may happen that a free segment of the allocator
//         chain is just on the right of our segment. In that case we may try to enlarge
//         our segment using this one. This works only if the concatenated segment is big
//         enough. Otherwise, we must allocate a new segment, copy the old one in the new one, 
//         and free the old one. */ 
//
//      /* find the segment on the right of 'seg'. */ 
//      U32 *right_one = seg+seg[0]; 
//      U32 *previous = NULL; 
//      U32 *aux = the_ffss; 
//
//      while (aux != NULL)
// {
//   if (aux == right_one) break; 
//   previous = aux; 
//   aux = (U32 *)(aux[1]); 
// }
//
//      if (aux != NULL)
// {
//   /* the segment on the right has been found. Check the total size. */
//   U32 total_size = seg[0]+aux[0];
//   assert(aux == right_one); 
//   /* since aux == right_one, we may use 'aux' for anything else */ 
//   if ((U32)words <= total_size)
//     {
//       /* segment need not be copied. glue the two segments, and reallocate
//                 again in order to cut down (maybe) the unused end */ 
//       if (previous == NULL)
//  {
//    /* the segment on the right is the first one in the chain */ 
//    the_ffss = (U32 *)(the_ffss[1]);
//    seg[0] = total_size; 
//                  memory_in_use += aux[0]; 
//    goto begin; 
//  }
//       else
//  {
//    /* the segment on the right follows 'previous' in the chain */ 
//    previous[1] = right_one[1]; 
//    seg[0] = total_size; 
//                  memory_in_use += aux[0]; 
//    goto begin; 
//  }
//     }
// }
//      /* the segment needs to be copied */ 
//      {
// U32 new_seg;
// int i; 
//
// if ((new_seg = allocate_data_segment(words-1,allocator)) == 0)
//   {
//     // printf("allocate_data_segment returned 0.\n"); fflush(stdout); 
//
//#ifdef debug_vm   
//          if (heap_test) compute_memory_check_sums(allocator); 
//#endif
//   
//   return 0;    /* try next time */ 
//   }
//
// /* copy old segment to new segment */ 
// for (i = 0; i < (int)(seg[0]-1); i++)
//   ((U32 *)new_seg)[i] = ((U32 *)data_seg)[i]; 
//
//        /* free old segment */ 
// free_data_segment((U32 *)data_seg,allocator); 
//
// //printf("segment has been enlarged.\n"); fflush(stdout); 
//
// /* return new segment (size word is already cached) */ 
//#ifdef debug_vm   
//        if (heap_test) compute_memory_check_sums(allocator); 
//#endif
//   
// return (U32)new_seg;
//      }
//    }
//}


/* enlarging a data segment. This works like reallocate_data_segment, except that the 
   segment is never shortened. Also, when copying a segment to a larger one, it does
   not free the first one. This function has been created to avoid problems with the
   probably buggy memory allocation of OpenSSL. */ 
//U32 _enlarge_data_segment(U32 data_seg,
//       int words,
//#ifdef record_allocations
//                            char *filename, 
//                            int line, 
//#endif   
//       Allocator allocator)
//{
//  /* compare size of segment with requested size */ 
//  U32 *seg;
//
//  //assert(0); 
//   
//  /* the segment should not be shared */ 
//  // assert(*((U32 *)data_seg) == 1);
//
//
//  seg = (U32 *)data_seg;
//  seg--;      /* recover size word */ 
//  words++;    /* need one more word for size */ 
//   
// begin:
//   if ((U32)words <= seg[0])
//    {
//      /* the segment should not be shortened */ 
//#ifdef debug_vm   
//      if (heap_test) compute_memory_check_sums(allocator); 
//#endif   
//      return data_seg; 
//    }
//  else 
//    {
//      /* the segment must be enlarged. It may happen that a free segment of the allocator
//         chain is just on the right of our segment. In that case we may try to enlarge
//         our segment using this one. This works only if the concatenated segment is big
//         enough. Otherwise, we must allocate a new segment, copy the old one in the new one, 
//         and free the old one. */ 
//
//      /* find the segment on the right of 'seg'. */ 
//      U32 *right_one = seg+seg[0]; 
//      U32 *previous = NULL; 
//      U32 *aux = the_ffss; 
//
//      while (aux != NULL)
// {
//   if (aux == right_one) break; 
//   previous = aux; 
//   aux = (U32 *)(aux[1]); 
// }
//
//      if (aux != NULL)
// {
//   /* the segment on the right has been found. Check the total size. */
//   U32 total_size = seg[0]+aux[0];
//   assert(aux == right_one); 
//   /* since aux == right_one, we may use 'aux' for anything else */ 
//   if ((U32)words <= total_size)
//     {
//       /* segment need not be copied. glue the two segments, and reallocate
//                 again in order to cut down (maybe) the unused end */ 
//       if (previous == NULL)
//  {
//    /* the segment on the right is the first one in the chain */ 
//    the_ffss = (U32 *)(the_ffss[1]);
//    seg[0] = total_size; 
//                  memory_in_use += aux[0]; 
//    goto begin; 
//  }
//       else
//  {
//    /* the segment on the right follows 'previous' in the chain */ 
//    previous[1] = right_one[1]; 
//    seg[0] = total_size; 
//                  memory_in_use += aux[0]; 
//    goto begin; 
//  }
//     }
// }
//      /* the segment needs be copied */ 
//      {
// U32 new_seg;
// int i; 
//
// if ((new_seg = allocate_data_segment(words-1,allocator)) == 0)
//   {
//     // printf("allocate_data_segment returned 0.\n"); fflush(stdout); 
//
//#ifdef debug_vm   
//      if (heap_test) compute_memory_check_sums(allocator); 
//#endif
//   
//   return 0;    /* try next time */ 
//   }
//
// /* copy old segment to new segment */ 
// for (i = 0; i < (int)(seg[0]-1); i++)
//   ((U32 *)new_seg)[i] = ((U32 *)data_seg)[i]; 
//
//        /* free old segment */ 
// free_data_segment((U32 *)data_seg,allocator); 
//
// //printf("segment has been enlarged.\n"); fflush(stdout); 
//
// /* return new segment (size word is already cached) */ 
//#ifdef debug_vm   
//      if (heap_test) compute_memory_check_sums(allocator); 
//#endif   
// return (U32)new_seg;
//      }
//    }
//}

extern AnubisAllocator *the_default_ssl_allocator; 
extern AnubisAllocator *current_ssl_allocator; 


void *alloc_for_ssl(size_t n)
{
   U32 result; 
   
   result = current_ssl_allocator->AllocateDataSegment(byte_size_to_word_size(n)); 
   
   
   if (result == 0)
     {
       if (current_ssl_allocator->EnlargeMemory() != 0)
         result = current_ssl_allocator->AllocateDataSegment(byte_size_to_word_size(n));
     }
   
   return (void *)result; 
}
   
   
void *realloc_for_ssl(void *old, size_t n)
{
  return (void *)current_ssl_allocator->EnlargeDataSegment((U32)old,byte_size_to_word_size(n)); 
}
     
   
void dont_free_for_ssl(void *s)
{
  return; 
}

void free_for_ssl(void *s)
{
  current_ssl_allocator->FreeDataSegment((U32 *)s); 
}