Mercurial > emacs
comparison src/ralloc.c @ 9666:d50850d0c8f8
(struct heap): New fields first_bloc, last_bloc.
(struct bp): New field heap.
(get_bloc, free_bloc, obtain, r_alloc_sbrk): Update new fields.
(reorder_bloc): New function.
(update_heap_bloc_correspondence):
Renamed from update_heap_free_pointers. Update new fields.
(relinquish): Add error check for new fields.
| author | Richard M. Stallman <rms@gnu.org> |
|---|---|
| date | Sun, 23 Oct 1994 06:16:43 +0000 |
| parents | 134f7085c56b |
| children | 15d01ad97928 |
comparison
equal
deleted
inserted
replaced
| 9665:36bdda3a1dc9 | 9666:d50850d0c8f8 |
|---|---|
| 141 POINTER end; | 141 POINTER end; |
| 142 /* Start of relocatable data in this heap. */ | 142 /* Start of relocatable data in this heap. */ |
| 143 POINTER bloc_start; | 143 POINTER bloc_start; |
| 144 /* Start of unused space in this heap. */ | 144 /* Start of unused space in this heap. */ |
| 145 POINTER free; | 145 POINTER free; |
| 146 /* First bloc in this heap. */ | |
| 147 struct bp *first_bloc; | |
| 148 /* Last bloc in this heap. */ | |
| 149 struct bp *last_bloc; | |
| 146 } *heap_ptr; | 150 } *heap_ptr; |
| 147 | 151 |
| 148 #define NIL_HEAP ((heap_ptr) 0) | 152 #define NIL_HEAP ((heap_ptr) 0) |
| 149 #define HEAP_PTR_SIZE (sizeof (struct heap)) | 153 #define HEAP_PTR_SIZE (sizeof (struct heap)) |
| 150 | 154 |
| 166 struct bp *prev; | 170 struct bp *prev; |
| 167 POINTER *variable; | 171 POINTER *variable; |
| 168 POINTER data; | 172 POINTER data; |
| 169 SIZE size; | 173 SIZE size; |
| 170 POINTER new_data; /* tmporarily used for relocation */ | 174 POINTER new_data; /* tmporarily used for relocation */ |
| 175 /* Heap this bloc is in. */ | |
| 176 struct heap *heap; | |
| 171 } *bloc_ptr; | 177 } *bloc_ptr; |
| 172 | 178 |
| 173 #define NIL_BLOC ((bloc_ptr) 0) | 179 #define NIL_BLOC ((bloc_ptr) 0) |
| 174 #define BLOC_PTR_SIZE (sizeof (struct bp)) | 180 #define BLOC_PTR_SIZE (sizeof (struct bp)) |
| 175 | 181 |
| 265 new_heap->end = bloc_start; | 271 new_heap->end = bloc_start; |
| 266 new_heap->bloc_start = bloc_start; | 272 new_heap->bloc_start = bloc_start; |
| 267 new_heap->free = bloc_start; | 273 new_heap->free = bloc_start; |
| 268 new_heap->next = NIL_HEAP; | 274 new_heap->next = NIL_HEAP; |
| 269 new_heap->prev = last_heap; | 275 new_heap->prev = last_heap; |
| 276 new_heap->first_bloc = NIL_BLOC; | |
| 277 new_heap->last_bloc = NIL_BLOC; | |
| 270 last_heap->next = new_heap; | 278 last_heap->next = new_heap; |
| 271 last_heap = new_heap; | 279 last_heap = new_heap; |
| 272 | 280 |
| 273 address = bloc_start; | 281 address = bloc_start; |
| 274 already_available = 0; | 282 already_available = 0; |
| 316 And don't free anything unless we can free at least extra_bytes. */ | 324 And don't free anything unless we can free at least extra_bytes. */ |
| 317 excess -= extra_bytes; | 325 excess -= extra_bytes; |
| 318 | 326 |
| 319 if ((char *)last_heap->end - (char *)last_heap->bloc_start <= excess) | 327 if ((char *)last_heap->end - (char *)last_heap->bloc_start <= excess) |
| 320 { | 328 { |
| 329 /* This heap should have no blocs in it. */ | |
| 330 if (last_heap->first_bloc != NIL_BLOC | |
| 331 || last_heap->last_bloc != NIL_BLOC) | |
| 332 abort (); | |
| 333 | |
| 321 /* Return the last heap, with its header, to the system. */ | 334 /* Return the last heap, with its header, to the system. */ |
| 322 excess = (char *)last_heap->end - (char *)last_heap->start; | 335 excess = (char *)last_heap->end - (char *)last_heap->start; |
| 323 last_heap = last_heap->prev; | 336 last_heap = last_heap->prev; |
| 324 last_heap->next = NIL_HEAP; | 337 last_heap->next = NIL_HEAP; |
| 325 } | 338 } |
| 386 | 399 |
| 387 /* Record in the heap that this space is in use. */ | 400 /* Record in the heap that this space is in use. */ |
| 388 heap = find_heap (new_bloc->data); | 401 heap = find_heap (new_bloc->data); |
| 389 heap->free = break_value; | 402 heap->free = break_value; |
| 390 | 403 |
| 404 /* Maintain the correspondence between heaps and blocs. */ | |
| 405 new_bloc->heap = heap; | |
| 406 heap->last_bloc = new_bloc; | |
| 407 if (heap->first_bloc == NIL_BLOC) | |
| 408 heap->first_bloc = new_bloc; | |
| 409 | |
| 391 /* Put this bloc on the doubly-linked list of blocs. */ | 410 /* Put this bloc on the doubly-linked list of blocs. */ |
| 392 if (first_bloc) | 411 if (first_bloc) |
| 393 { | 412 { |
| 394 new_bloc->prev = last_bloc; | 413 new_bloc->prev = last_bloc; |
| 395 last_bloc->next = new_bloc; | 414 last_bloc->next = new_bloc; |
| 401 new_bloc->prev = NIL_BLOC; | 420 new_bloc->prev = NIL_BLOC; |
| 402 } | 421 } |
| 403 | 422 |
| 404 return new_bloc; | 423 return new_bloc; |
| 405 } | 424 } |
| 406 | 425 |
| 407 /* Calculate new locations of blocs in the list beginning with BLOC, | 426 /* Calculate new locations of blocs in the list beginning with BLOC, |
| 408 relocating it to start at ADDRESS, in heap HEAP. If enough space is | 427 relocating it to start at ADDRESS, in heap HEAP. If enough space is |
| 409 not presently available in our reserve, call obtain for | 428 not presently available in our reserve, call obtain for |
| 410 more space. | 429 more space. |
| 411 | 430 |
| 462 } | 481 } |
| 463 | 482 |
| 464 return 1; | 483 return 1; |
| 465 } | 484 } |
| 466 | 485 |
| 467 /* Update the free pointers of all heaps starting with HEAP | 486 /* Reorder the bloc BLOC to go before bloc BEFORE in the doubly linked list. |
| 468 based on the blocs starting with BLOC. BLOC should be in | 487 This is necessary if we put the memory of space of BLOC |
| 469 heap HEAP. */ | 488 before that of BEFORE. */ |
| 470 | 489 |
| 471 static | 490 static void |
| 472 update_heap_free_pointers (bloc, heap) | 491 reorder_bloc (bloc, before) |
| 492 bloc_ptr bloc, before; | |
| 493 { | |
| 494 bloc_ptr prev, next; | |
| 495 | |
| 496 /* Splice BLOC out from where it is. */ | |
| 497 prev = bloc->prev; | |
| 498 next = bloc->next; | |
| 499 | |
| 500 if (prev) | |
| 501 prev->next = next; | |
| 502 if (next) | |
| 503 next->prev = prev; | |
| 504 | |
| 505 /* Splice it in before BEFORE. */ | |
| 506 prev = before->prev; | |
| 507 | |
| 508 if (prev) | |
| 509 prev->next = bloc; | |
| 510 bloc->prev = prev; | |
| 511 | |
| 512 before->prev = bloc; | |
| 513 bloc->next = before; | |
| 514 } | |
| 515 | |
| 516 /* Update the records of which heaps contain which blocs, starting | |
| 517 with heap HEAP and bloc BLOC. */ | |
| 518 | |
| 519 static void | |
| 520 update_heap_bloc_correspondence (bloc, heap) | |
| 473 bloc_ptr bloc; | 521 bloc_ptr bloc; |
| 474 heap_ptr heap; | 522 heap_ptr heap; |
| 475 { | 523 { |
| 476 register bloc_ptr b; | 524 register bloc_ptr b; |
| 477 | 525 |
| 526 /* Initialize HEAP's status to reflect blocs before BLOC. */ | |
| 527 if (bloc != NIL_BLOC && bloc->prev != NIL_BLOC && bloc->prev->heap == heap) | |
| 528 { | |
| 529 /* The previous bloc is in HEAP. */ | |
| 530 heap->last_bloc = bloc->prev; | |
| 531 heap->free = bloc->prev->data + bloc->prev->size; | |
| 532 } | |
| 533 else | |
| 534 { | |
| 535 /* HEAP contains no blocs before BLOC. */ | |
| 536 heap->first_bloc = NIL_BLOC; | |
| 537 heap->last_bloc = NIL_BLOC; | |
| 538 heap->free = heap->bloc_start; | |
| 539 } | |
| 540 | |
| 478 /* Advance through blocs one by one. */ | 541 /* Advance through blocs one by one. */ |
| 479 for (b = bloc; b != NIL_BLOC; b = b->next) | 542 for (b = bloc; b != NIL_BLOC; b = b->next) |
| 480 { | 543 { |
| 481 /* Advance through heaps in sync with the blocs that are in them. */ | 544 /* Advance through heaps, marking them empty, |
| 545 till we get to the one that B is in. */ | |
| 482 while (heap) | 546 while (heap) |
| 483 { | 547 { |
| 484 if (heap->bloc_start <= b->data && b->data <= heap->end) | 548 if (heap->bloc_start <= b->data && b->data <= heap->end) |
| 485 break; | 549 break; |
| 486 heap = heap->next; | 550 heap = heap->next; |
| 551 /* We know HEAP is not null now, | |
| 552 because there has to be space for bloc B. */ | |
| 553 heap->first_bloc = NIL_BLOC; | |
| 554 heap->last_bloc = NIL_BLOC; | |
| 487 heap->free = heap->bloc_start; | 555 heap->free = heap->bloc_start; |
| 488 } | 556 } |
| 489 /* In each heap, record the end of the last bloc in it. */ | 557 |
| 558 /* Update HEAP's status for bloc B. */ | |
| 490 heap->free = b->data + b->size; | 559 heap->free = b->data + b->size; |
| 560 heap->last_bloc = b; | |
| 561 if (heap->first_bloc == NIL_BLOC) | |
| 562 heap->first_bloc = b; | |
| 563 | |
| 564 /* Record that B is in HEAP. */ | |
| 565 b->heap = heap; | |
| 491 } | 566 } |
| 492 | 567 |
| 493 /* If there are any remaining heaps and no blocs left, | 568 /* If there are any remaining heaps and no blocs left, |
| 494 update the `free' slot assuming they contain no blocs. */ | 569 mark those heaps as empty. */ |
| 495 heap = heap->next; | 570 heap = heap->next; |
| 496 while (heap) | 571 while (heap) |
| 497 { | 572 { |
| 573 heap->first_bloc = NIL_BLOC; | |
| 574 heap->last_bloc = NIL_BLOC; | |
| 498 heap->free = heap->bloc_start; | 575 heap->free = heap->bloc_start; |
| 499 heap = heap->next; | 576 heap = heap->next; |
| 500 } | 577 } |
| 501 } | 578 } |
| 502 | 579 |
| 503 /* Resize BLOC to SIZE bytes. This relocates the blocs | 580 /* Resize BLOC to SIZE bytes. This relocates the blocs |
| 504 that come after BLOC in memory. */ | 581 that come after BLOC in memory. */ |
| 505 | 582 |
| 506 static int | 583 static int |
| 507 resize_bloc (bloc, size) | 584 resize_bloc (bloc, size) |
| 562 safe_bcopy (b->data, b->new_data, b->size); | 639 safe_bcopy (b->data, b->new_data, b->size); |
| 563 *b->variable = b->data = b->new_data; | 640 *b->variable = b->data = b->new_data; |
| 564 } | 641 } |
| 565 } | 642 } |
| 566 | 643 |
| 567 update_heap_free_pointers (bloc, heap); | 644 update_heap_bloc_correspondence (bloc, heap); |
| 568 | 645 |
| 569 break_value = (last_bloc ? last_bloc->data + last_bloc->size | 646 break_value = (last_bloc ? last_bloc->data + last_bloc->size |
| 570 : first_heap->bloc_start); | 647 : first_heap->bloc_start); |
| 571 return 1; | 648 return 1; |
| 572 } | 649 } |
| 573 | 650 |
| 574 /* Free BLOC from the chain of blocs, relocating any blocs above it. | 651 /* Free BLOC from the chain of blocs, relocating any blocs above it. |
| 575 This may return space to the system. */ | 652 This may return space to the system. */ |
| 576 | 653 |
| 577 static void | 654 static void |
| 578 free_bloc (bloc) | 655 free_bloc (bloc) |
| 579 bloc_ptr bloc; | 656 bloc_ptr bloc; |
| 580 { | 657 { |
| 658 heap_ptr heap = bloc->heap; | |
| 659 | |
| 581 resize_bloc (bloc, 0); | 660 resize_bloc (bloc, 0); |
| 582 | 661 |
| 583 if (bloc == first_bloc && bloc == last_bloc) | 662 if (bloc == first_bloc && bloc == last_bloc) |
| 584 { | 663 { |
| 585 first_bloc = last_bloc = NIL_BLOC; | 664 first_bloc = last_bloc = NIL_BLOC; |
| 596 } | 675 } |
| 597 else | 676 else |
| 598 { | 677 { |
| 599 bloc->next->prev = bloc->prev; | 678 bloc->next->prev = bloc->prev; |
| 600 bloc->prev->next = bloc->next; | 679 bloc->prev->next = bloc->next; |
| 680 } | |
| 681 | |
| 682 /* Update the records of which blocs are in HEAP. */ | |
| 683 if (heap->first_bloc == bloc) | |
| 684 { | |
| 685 if (bloc->next->heap == heap) | |
| 686 heap->first_bloc = bloc->next; | |
| 687 else | |
| 688 heap->first_bloc = heap->last_bloc = NIL_BLOC; | |
| 689 } | |
| 690 if (heap->last_bloc == bloc) | |
| 691 { | |
| 692 if (bloc->prev->heap == heap) | |
| 693 heap->last_bloc = bloc->prev; | |
| 694 else | |
| 695 heap->first_bloc = heap->last_bloc = NIL_BLOC; | |
| 601 } | 696 } |
| 602 | 697 |
| 603 relinquish (); | 698 relinquish (); |
| 604 free (bloc); | 699 free (bloc); |
| 605 } | 700 } |
| 686 *b->variable = b->data = b->new_data; | 781 *b->variable = b->data = b->new_data; |
| 687 } | 782 } |
| 688 | 783 |
| 689 h->bloc_start = new_bloc_start; | 784 h->bloc_start = new_bloc_start; |
| 690 | 785 |
| 691 update_heap_free_pointers (first_bloc, h); | 786 update_heap_bloc_correspondence (first_bloc, h); |
| 692 } | 787 } |
| 693 | 788 |
| 694 if (h != first_heap) | 789 if (h != first_heap) |
| 695 { | 790 { |
| 696 /* Give up managing heaps below the one the new | 791 /* Give up managing heaps below the one the new |
| 698 first_heap->prev = NIL_HEAP; | 793 first_heap->prev = NIL_HEAP; |
| 699 first_heap->next = h->next; | 794 first_heap->next = h->next; |
| 700 first_heap->start = h->start; | 795 first_heap->start = h->start; |
| 701 first_heap->end = h->end; | 796 first_heap->end = h->end; |
| 702 first_heap->free = h->free; | 797 first_heap->free = h->free; |
| 798 first_heap->first_bloc = h->first_bloc; | |
| 799 first_heap->last_bloc = h->last_bloc; | |
| 703 first_heap->bloc_start = h->bloc_start; | 800 first_heap->bloc_start = h->bloc_start; |
| 704 | 801 |
| 705 if (first_heap->next) | 802 if (first_heap->next) |
| 706 first_heap->next->prev = first_heap; | 803 first_heap->next->prev = first_heap; |
| 707 else | 804 else |
| 719 | 816 |
| 720 if (r_alloc_freeze_level == 0 && excess > 2 * extra_bytes) | 817 if (r_alloc_freeze_level == 0 && excess > 2 * extra_bytes) |
| 721 { | 818 { |
| 722 excess -= extra_bytes; | 819 excess -= extra_bytes; |
| 723 first_heap->bloc_start | 820 first_heap->bloc_start |
| 724 = (POINTER) MEM_ROUNDUP ((char *)first_heap->bloc_start - excess); | 821 = (POINTER) MEM_ROUNDUP ((char *)first_heap->bloc_start - excess); |
| 725 | 822 |
| 726 relocate_blocs (first_bloc, first_heap, first_heap->bloc_start); | 823 relocate_blocs (first_bloc, first_heap, first_heap->bloc_start); |
| 727 | 824 |
| 728 for (b = first_bloc; b != NIL_BLOC; b = b->next) | 825 for (b = first_bloc; b != NIL_BLOC; b = b->next) |
| 729 { | 826 { |
| 738 first_heap->start = (POINTER) ((char *)virtual_break_value + size); | 835 first_heap->start = (POINTER) ((char *)virtual_break_value + size); |
| 739 } | 836 } |
| 740 } | 837 } |
| 741 | 838 |
| 742 virtual_break_value = (POINTER) ((char *)address + size); | 839 virtual_break_value = (POINTER) ((char *)address + size); |
| 743 break_value = last_bloc ? last_bloc->data + last_bloc->size | 840 break_value = (last_bloc |
| 744 : first_heap->bloc_start; | 841 ? last_bloc->data + last_bloc->size |
| 842 : first_heap->bloc_start); | |
| 745 if (size < 0) | 843 if (size < 0) |
| 746 relinquish (); | 844 relinquish (); |
| 747 | 845 |
| 748 return address; | 846 return address; |
| 749 } | 847 } |
