diff options
| author | Gareth Rees | 2013-05-31 16:29:26 +0100 |
|---|---|---|
| committer | Gareth Rees | 2013-05-31 16:29:26 +0100 |
| commit | db9328da7a3c506983b8027f094dd5234062fea4 (patch) | |
| tree | 0ff1a55e78e6e5dcac9fef16cbd84458a8f731b7 /mps/code | |
| parent | 83aff660e27fe56ba6f5c4b898aa00da206c6c9e (diff) | |
| download | emacs-db9328da7a3c506983b8027f094dd5234062fea4.tar.gz emacs-db9328da7a3c506983b8027f094dd5234062fea4.zip | |
Use range objects in the cbs interface instead of base, limit pairs. the idea is that freelist and cbs should offer similar interfaces so that the testing code can be shared.
Copied from Perforce
Change: 182364
ServerID: perforce.ravenbrook.com
Diffstat (limited to 'mps/code')
| -rw-r--r-- | mps/code/cbs.c | 173 | ||||
| -rw-r--r-- | mps/code/cbs.h | 20 | ||||
| -rw-r--r-- | mps/code/cbstest.c | 42 | ||||
| -rw-r--r-- | mps/code/poolmv2.c | 70 | ||||
| -rw-r--r-- | mps/code/poolmvff.c | 53 | ||||
| -rw-r--r-- | mps/code/range.c | 16 | ||||
| -rw-r--r-- | mps/code/range.h | 2 |
7 files changed, 189 insertions, 187 deletions
diff --git a/mps/code/cbs.c b/mps/code/cbs.c index 45a708f2ba7..8bf9a4300df 100644 --- a/mps/code/cbs.c +++ b/mps/code/cbs.c | |||
| @@ -339,7 +339,7 @@ static void cbsBlockGrew(CBS cbs, CBSBlock block, Size oldSize) | |||
| 339 | /* cbsBlockAlloc -- allocate a new block and set its base and limit, | 339 | /* cbsBlockAlloc -- allocate a new block and set its base and limit, |
| 340 | but do not insert it into the splay tree yet */ | 340 | but do not insert it into the splay tree yet */ |
| 341 | 341 | ||
| 342 | static Res cbsBlockAlloc(CBSBlock *blockReturn, CBS cbs, Addr base, Addr limit) | 342 | static Res cbsBlockAlloc(CBSBlock *blockReturn, CBS cbs, Range range) |
| 343 | { | 343 | { |
| 344 | Res res; | 344 | Res res; |
| 345 | CBSBlock block; | 345 | CBSBlock block; |
| @@ -347,6 +347,7 @@ static Res cbsBlockAlloc(CBSBlock *blockReturn, CBS cbs, Addr base, Addr limit) | |||
| 347 | 347 | ||
| 348 | AVER(blockReturn != NULL); | 348 | AVER(blockReturn != NULL); |
| 349 | AVERT(CBS, cbs); | 349 | AVERT(CBS, cbs); |
| 350 | AVERT(Range, range); | ||
| 350 | 351 | ||
| 351 | res = PoolAlloc(&p, cbs->blockPool, sizeof(CBSBlockStruct), | 352 | res = PoolAlloc(&p, cbs->blockPool, sizeof(CBSBlockStruct), |
| 352 | /* withReservoirPermit */ FALSE); | 353 | /* withReservoirPermit */ FALSE); |
| @@ -355,8 +356,8 @@ static Res cbsBlockAlloc(CBSBlock *blockReturn, CBS cbs, Addr base, Addr limit) | |||
| 355 | block = (CBSBlock)p; | 356 | block = (CBSBlock)p; |
| 356 | 357 | ||
| 357 | SplayNodeInit(splayNodeOfCBSBlock(block)); | 358 | SplayNodeInit(splayNodeOfCBSBlock(block)); |
| 358 | block->base = base; | 359 | block->base = RangeBase(range); |
| 359 | block->limit = limit; | 360 | block->limit = RangeLimit(range); |
| 360 | block->maxSize = CBSBlockSize(block); | 361 | block->maxSize = CBSBlockSize(block); |
| 361 | 362 | ||
| 362 | AVERT(CBSBlock, block); | 363 | AVERT(CBSBlock, block); |
| @@ -387,21 +388,22 @@ static void cbsBlockInsert(CBS cbs, CBSBlock block) | |||
| 387 | 388 | ||
| 388 | /* cbsInsertIntoTree -- Insert a range into the splay tree */ | 389 | /* cbsInsertIntoTree -- Insert a range into the splay tree */ |
| 389 | 390 | ||
| 390 | static Res cbsInsertIntoTree(Addr *baseReturn, Addr *limitReturn, | 391 | static Res cbsInsertIntoTree(Range rangeReturn, CBS cbs, Range range) |
| 391 | CBS cbs, Addr base, Addr limit) | ||
| 392 | { | 392 | { |
| 393 | Res res; | 393 | Res res; |
| 394 | Addr newBase, newLimit; | 394 | Addr base, limit, newBase, newLimit; |
| 395 | SplayNode leftSplay, rightSplay; | 395 | SplayNode leftSplay, rightSplay; |
| 396 | CBSBlock leftCBS, rightCBS; | 396 | CBSBlock leftCBS, rightCBS; |
| 397 | Bool leftMerge, rightMerge; | 397 | Bool leftMerge, rightMerge; |
| 398 | Size oldSize; | 398 | Size oldSize; |
| 399 | 399 | ||
| 400 | AVER(rangeReturn != NULL); | ||
| 400 | AVERT(CBS, cbs); | 401 | AVERT(CBS, cbs); |
| 401 | AVER(base != (Addr)0); | 402 | AVERT(Range, range); |
| 402 | AVER(base < limit); | 403 | AVER(RangeIsAligned(range, cbs->alignment)); |
| 403 | AVER(AddrIsAligned(base, cbs->alignment)); | 404 | |
| 404 | AVER(AddrIsAligned(limit, cbs->alignment)); | 405 | base = RangeBase(range); |
| 406 | limit = RangeLimit(range); | ||
| 405 | 407 | ||
| 406 | METER_ACC(cbs->splaySearch, cbs->splayTreeSize); | 408 | METER_ACC(cbs->splaySearch, cbs->splayTreeSize); |
| 407 | res = SplayTreeNeighbours(&leftSplay, &rightSplay, | 409 | res = SplayTreeNeighbours(&leftSplay, &rightSplay, |
| @@ -461,7 +463,7 @@ static Res cbsInsertIntoTree(Addr *baseReturn, Addr *limitReturn, | |||
| 461 | 463 | ||
| 462 | } else { | 464 | } else { |
| 463 | CBSBlock block; | 465 | CBSBlock block; |
| 464 | res = cbsBlockAlloc(&block, cbs, base, limit); | 466 | res = cbsBlockAlloc(&block, cbs, range); |
| 465 | if (res != ResOK) | 467 | if (res != ResOK) |
| 466 | goto fail; | 468 | goto fail; |
| 467 | cbsBlockInsert(cbs, block); | 469 | cbsBlockInsert(cbs, block); |
| @@ -469,8 +471,7 @@ static Res cbsInsertIntoTree(Addr *baseReturn, Addr *limitReturn, | |||
| 469 | 471 | ||
| 470 | AVER(newBase <= base); | 472 | AVER(newBase <= base); |
| 471 | AVER(newLimit >= limit); | 473 | AVER(newLimit >= limit); |
| 472 | *baseReturn = newBase; | 474 | RangeInit(rangeReturn, newBase, newLimit); |
| 473 | *limitReturn = newLimit; | ||
| 474 | 475 | ||
| 475 | return ResOK; | 476 | return ResOK; |
| 476 | 477 | ||
| @@ -485,29 +486,18 @@ fail: | |||
| 485 | * See <design/cbs/#functions.cbs.insert>. | 486 | * See <design/cbs/#functions.cbs.insert>. |
| 486 | */ | 487 | */ |
| 487 | 488 | ||
| 488 | Res CBSInsert(Addr *baseReturn, Addr *limitReturn, | 489 | Res CBSInsert(Range rangeReturn, CBS cbs, Range range) |
| 489 | CBS cbs, Addr base, Addr limit) | ||
| 490 | { | 490 | { |
| 491 | Addr newBase, newLimit; | ||
| 492 | Res res; | 491 | Res res; |
| 493 | 492 | ||
| 494 | AVER(baseReturn != NULL); | ||
| 495 | AVER(limitReturn != NULL); | ||
| 496 | AVERT(CBS, cbs); | 493 | AVERT(CBS, cbs); |
| 497 | CBSEnter(cbs); | 494 | CBSEnter(cbs); |
| 498 | 495 | ||
| 499 | AVER(base != (Addr)0); | 496 | AVER(rangeReturn != NULL); |
| 500 | AVER(base < limit); | 497 | AVERT(Range, range); |
| 501 | AVER(AddrIsAligned(base, cbs->alignment)); | 498 | AVER(RangeIsAligned(range, cbs->alignment)); |
| 502 | AVER(AddrIsAligned(limit, cbs->alignment)); | 499 | |
| 503 | 500 | res = cbsInsertIntoTree(rangeReturn, cbs, range); | |
| 504 | res = cbsInsertIntoTree(&newBase, &newLimit, cbs, base, limit); | ||
| 505 | if (res == ResOK) { | ||
| 506 | AVER(newBase <= base); | ||
| 507 | AVER(limit <= newLimit); | ||
| 508 | *baseReturn = newBase; | ||
| 509 | *limitReturn = newLimit; | ||
| 510 | } | ||
| 511 | 501 | ||
| 512 | CBSLeave(cbs); | 502 | CBSLeave(cbs); |
| 513 | return res; | 503 | return res; |
| @@ -516,22 +506,21 @@ Res CBSInsert(Addr *baseReturn, Addr *limitReturn, | |||
| 516 | 506 | ||
| 517 | /* cbsDeleteFromTree -- delete blocks from the splay tree */ | 507 | /* cbsDeleteFromTree -- delete blocks from the splay tree */ |
| 518 | 508 | ||
| 519 | static Res cbsDeleteFromTree(Addr *baseReturn, Addr *limitReturn, | 509 | static Res cbsDeleteFromTree(Range rangeReturn, CBS cbs, Range range) |
| 520 | CBS cbs, Addr base, Addr limit) | ||
| 521 | { | 510 | { |
| 522 | Res res; | 511 | Res res; |
| 523 | CBSBlock cbsBlock; | 512 | CBSBlock cbsBlock; |
| 524 | SplayNode splayNode; | 513 | SplayNode splayNode; |
| 525 | Addr oldBase, oldLimit; | 514 | Addr base, limit, oldBase, oldLimit; |
| 526 | Size oldSize; | 515 | Size oldSize; |
| 527 | 516 | ||
| 528 | AVER(baseReturn != NULL); | 517 | AVER(rangeReturn != NULL); |
| 529 | AVER(limitReturn != NULL); | ||
| 530 | AVERT(CBS, cbs); | 518 | AVERT(CBS, cbs); |
| 531 | AVER(base != NULL); | 519 | AVERT(Range, range); |
| 532 | AVER(limit > base); | 520 | AVER(RangeIsAligned(range, cbs->alignment)); |
| 533 | AVER(AddrIsAligned(base, cbs->alignment)); | 521 | |
| 534 | AVER(AddrIsAligned(limit, cbs->alignment)); | 522 | base = RangeBase(range); |
| 523 | limit = RangeLimit(range); | ||
| 535 | 524 | ||
| 536 | METER_ACC(cbs->splaySearch, cbs->splayTreeSize); | 525 | METER_ACC(cbs->splaySearch, cbs->splayTreeSize); |
| 537 | res = SplayTreeSearch(&splayNode, splayTreeOfCBS(cbs), (void *)&base); | 526 | res = SplayTreeSearch(&splayNode, splayTreeOfCBS(cbs), (void *)&base); |
| @@ -567,10 +556,12 @@ static Res cbsDeleteFromTree(Addr *baseReturn, Addr *limitReturn, | |||
| 567 | } else { | 556 | } else { |
| 568 | /* two remaining fragments. shrink block to represent fragment at | 557 | /* two remaining fragments. shrink block to represent fragment at |
| 569 | left, and create new block for fragment at right. */ | 558 | left, and create new block for fragment at right. */ |
| 559 | RangeStruct newRange; | ||
| 570 | CBSBlock newBlock; | 560 | CBSBlock newBlock; |
| 571 | AVER(base > oldBase); | 561 | AVER(base > oldBase); |
| 572 | AVER(limit < oldLimit); | 562 | AVER(limit < oldLimit); |
| 573 | res = cbsBlockAlloc(&newBlock, cbs, limit, oldLimit); | 563 | RangeInit(&newRange, limit, oldLimit); |
| 564 | res = cbsBlockAlloc(&newBlock, cbs, &newRange); | ||
| 574 | if (res != ResOK) { | 565 | if (res != ResOK) { |
| 575 | goto failAlloc; | 566 | goto failAlloc; |
| 576 | } | 567 | } |
| @@ -579,8 +570,7 @@ static Res cbsDeleteFromTree(Addr *baseReturn, Addr *limitReturn, | |||
| 579 | cbsBlockInsert(cbs, newBlock); | 570 | cbsBlockInsert(cbs, newBlock); |
| 580 | } | 571 | } |
| 581 | 572 | ||
| 582 | *baseReturn = oldBase; | 573 | RangeInit(rangeReturn, oldBase, oldLimit); |
| 583 | *limitReturn = oldLimit; | ||
| 584 | return ResOK; | 574 | return ResOK; |
| 585 | 575 | ||
| 586 | failAlloc: | 576 | failAlloc: |
| @@ -596,20 +586,18 @@ failSplayTreeSearch: | |||
| 596 | * See <design/cbs/#function.cbs.delete>. | 586 | * See <design/cbs/#function.cbs.delete>. |
| 597 | */ | 587 | */ |
| 598 | 588 | ||
| 599 | Res CBSDelete(Addr *baseReturn, Addr *limitReturn, | 589 | Res CBSDelete(Range rangeReturn, CBS cbs, Range range) |
| 600 | CBS cbs, Addr base, Addr limit) | ||
| 601 | { | 590 | { |
| 602 | Res res; | 591 | Res res; |
| 603 | 592 | ||
| 604 | AVERT(CBS, cbs); | 593 | AVERT(CBS, cbs); |
| 605 | CBSEnter(cbs); | 594 | CBSEnter(cbs); |
| 606 | 595 | ||
| 607 | AVER(base != NULL); | 596 | AVER(rangeReturn != NULL); |
| 608 | AVER(limit > base); | 597 | AVERT(Range, range); |
| 609 | AVER(AddrIsAligned(base, cbs->alignment)); | 598 | AVER(RangeIsAligned(range, cbs->alignment)); |
| 610 | AVER(AddrIsAligned(limit, cbs->alignment)); | ||
| 611 | 599 | ||
| 612 | res = cbsDeleteFromTree(baseReturn, limitReturn, cbs, base, limit); | 600 | res = cbsDeleteFromTree(rangeReturn, cbs, range); |
| 613 | 601 | ||
| 614 | CBSLeave(cbs); | 602 | CBSLeave(cbs); |
| 615 | return res; | 603 | return res; |
| @@ -666,10 +654,11 @@ static void cbsIterateInternal(CBS cbs, CBSIterateMethod iterate, | |||
| 666 | METER_ACC(cbs->splaySearch, cbs->splayTreeSize); | 654 | METER_ACC(cbs->splaySearch, cbs->splayTreeSize); |
| 667 | splayNode = SplayTreeFirst(splayTree, NULL); | 655 | splayNode = SplayTreeFirst(splayTree, NULL); |
| 668 | while(splayNode != NULL) { | 656 | while(splayNode != NULL) { |
| 657 | RangeStruct range; | ||
| 669 | cbsBlock = cbsBlockOfSplayNode(splayNode); | 658 | cbsBlock = cbsBlockOfSplayNode(splayNode); |
| 670 | if (!(*iterate)(cbs, CBSBlockBase(cbsBlock), CBSBlockLimit(cbsBlock), closureP, closureS)) { | 659 | RangeInit(&range, CBSBlockBase(cbsBlock), CBSBlockLimit(cbsBlock)); |
| 660 | if (!(*iterate)(cbs, &range, closureP, closureS)) | ||
| 671 | break; | 661 | break; |
| 672 | } | ||
| 673 | METER_ACC(cbs->splaySearch, cbs->splayTreeSize); | 662 | METER_ACC(cbs->splaySearch, cbs->splayTreeSize); |
| 674 | splayNode = SplayTreeNext(splayTree, splayNode, keyOfCBSBlock(cbsBlock)); | 663 | splayNode = SplayTreeNext(splayTree, splayNode, keyOfCBSBlock(cbsBlock)); |
| 675 | } | 664 | } |
| @@ -680,9 +669,10 @@ void CBSIterate(CBS cbs, CBSIterateMethod iterate, | |||
| 680 | void *closureP, Size closureS) | 669 | void *closureP, Size closureS) |
| 681 | { | 670 | { |
| 682 | AVERT(CBS, cbs); | 671 | AVERT(CBS, cbs); |
| 683 | AVER(FUNCHECK(iterate)); | ||
| 684 | CBSEnter(cbs); | 672 | CBSEnter(cbs); |
| 685 | 673 | ||
| 674 | AVER(FUNCHECK(iterate)); | ||
| 675 | |||
| 686 | cbsIterateInternal(cbs, iterate, closureP, closureS); | 676 | cbsIterateInternal(cbs, iterate, closureP, closureS); |
| 687 | 677 | ||
| 688 | CBSLeave(cbs); | 678 | CBSLeave(cbs); |
| @@ -706,21 +696,26 @@ Bool FindDeleteCheck(FindDelete findDelete) | |||
| 706 | 696 | ||
| 707 | /* cbsFindDeleteRange -- delete appropriate range of block found */ | 697 | /* cbsFindDeleteRange -- delete appropriate range of block found */ |
| 708 | 698 | ||
| 709 | static void cbsFindDeleteRange(Addr *baseReturn, Addr *limitReturn, | 699 | static void cbsFindDeleteRange(Range rangeReturn, Range oldRangeReturn, |
| 710 | Addr *oldBaseReturn, Addr *oldLimitReturn, | 700 | CBS cbs, Range range, Size size, |
| 711 | CBS cbs, Addr base, Addr limit, Size size, | ||
| 712 | FindDelete findDelete) | 701 | FindDelete findDelete) |
| 713 | { | 702 | { |
| 714 | Bool callDelete = TRUE; | 703 | Bool callDelete = TRUE; |
| 704 | Addr base, limit; | ||
| 715 | 705 | ||
| 716 | AVER(baseReturn != NULL); | 706 | AVER(rangeReturn != NULL); |
| 717 | AVER(limitReturn != NULL); | 707 | AVER(oldRangeReturn != NULL); |
| 718 | AVERT(CBS, cbs); | 708 | AVERT(CBS, cbs); |
| 719 | AVER(base < limit); | 709 | AVERT(Range, range); |
| 710 | AVER(RangeIsAligned(range, cbs->alignment)); | ||
| 720 | AVER(size > 0); | 711 | AVER(size > 0); |
| 721 | AVER(AddrOffset(base, limit) >= size); | 712 | AVER(SizeIsAligned(size, cbs->alignment)); |
| 713 | AVER(RangeSize(range) >= size); | ||
| 722 | AVERT(FindDelete, findDelete); | 714 | AVERT(FindDelete, findDelete); |
| 723 | 715 | ||
| 716 | base = RangeBase(range); | ||
| 717 | limit = RangeLimit(range); | ||
| 718 | |||
| 724 | switch(findDelete) { | 719 | switch(findDelete) { |
| 725 | 720 | ||
| 726 | case FindDeleteNONE: | 721 | case FindDeleteNONE: |
| @@ -744,25 +739,23 @@ static void cbsFindDeleteRange(Addr *baseReturn, Addr *limitReturn, | |||
| 744 | break; | 739 | break; |
| 745 | } | 740 | } |
| 746 | 741 | ||
| 742 | RangeInit(rangeReturn, base, limit); | ||
| 743 | |||
| 747 | if (callDelete) { | 744 | if (callDelete) { |
| 748 | Res res; | 745 | Res res; |
| 749 | res = cbsDeleteFromTree(oldBaseReturn, oldLimitReturn, cbs, base, limit); | 746 | res = cbsDeleteFromTree(oldRangeReturn, cbs, rangeReturn); |
| 750 | /* Can't have run out of memory, because all our callers pass in | 747 | /* Can't have run out of memory, because all our callers pass in |
| 751 | blocks that were just found in the splay tree, and we only | 748 | blocks that were just found in the splay tree, and we only |
| 752 | deleted from one end of the block, so cbsDeleteFromTree did not | 749 | deleted from one end of the block, so cbsDeleteFromTree did not |
| 753 | need to allocate a new block. */ | 750 | need to allocate a new block. */ |
| 754 | AVER(res == ResOK); | 751 | AVER(res == ResOK); |
| 755 | } | 752 | } |
| 756 | |||
| 757 | *baseReturn = base; | ||
| 758 | *limitReturn = limit; | ||
| 759 | } | 753 | } |
| 760 | 754 | ||
| 761 | 755 | ||
| 762 | /* CBSFindFirst -- find the first block of at least the given size */ | 756 | /* CBSFindFirst -- find the first block of at least the given size */ |
| 763 | 757 | ||
| 764 | Bool CBSFindFirst(Addr *baseReturn, Addr *limitReturn, | 758 | Bool CBSFindFirst(Range rangeReturn, Range oldRangeReturn, |
| 765 | Addr *oldBaseReturn, Addr *oldLimitReturn, | ||
| 766 | CBS cbs, Size size, FindDelete findDelete) | 759 | CBS cbs, Size size, FindDelete findDelete) |
| 767 | { | 760 | { |
| 768 | Bool found; | 761 | Bool found; |
| @@ -771,8 +764,8 @@ Bool CBSFindFirst(Addr *baseReturn, Addr *limitReturn, | |||
| 771 | AVERT(CBS, cbs); | 764 | AVERT(CBS, cbs); |
| 772 | CBSEnter(cbs); | 765 | CBSEnter(cbs); |
| 773 | 766 | ||
| 774 | AVER(baseReturn != NULL); | 767 | AVER(rangeReturn != NULL); |
| 775 | AVER(limitReturn != NULL); | 768 | AVER(oldRangeReturn != NULL); |
| 776 | AVER(size > 0); | 769 | AVER(size > 0); |
| 777 | AVER(SizeIsAligned(size, cbs->alignment)); | 770 | AVER(SizeIsAligned(size, cbs->alignment)); |
| 778 | AVER(cbs->fastFind); | 771 | AVER(cbs->fastFind); |
| @@ -783,14 +776,13 @@ Bool CBSFindFirst(Addr *baseReturn, Addr *limitReturn, | |||
| 783 | &cbsTestTree, NULL, size); | 776 | &cbsTestTree, NULL, size); |
| 784 | if (found) { | 777 | if (found) { |
| 785 | CBSBlock block; | 778 | CBSBlock block; |
| 786 | Addr base, limit; | 779 | RangeStruct range; |
| 787 | block = cbsBlockOfSplayNode(node); | 780 | block = cbsBlockOfSplayNode(node); |
| 788 | AVER(CBSBlockSize(block) >= size); | 781 | AVER(CBSBlockSize(block) >= size); |
| 789 | base = CBSBlockBase(block); | 782 | RangeInit(&range, CBSBlockBase(block), CBSBlockLimit(block)); |
| 790 | limit = CBSBlockLimit(block); | 783 | AVER(RangeSize(&range) >= size); |
| 791 | AVER(AddrOffset(base, limit) >= size); | 784 | cbsFindDeleteRange(rangeReturn, oldRangeReturn, cbs, &range, |
| 792 | cbsFindDeleteRange(baseReturn, limitReturn, oldBaseReturn, oldLimitReturn, | 785 | size, findDelete); |
| 793 | cbs, base, limit, size, findDelete); | ||
| 794 | } | 786 | } |
| 795 | 787 | ||
| 796 | CBSLeave(cbs); | 788 | CBSLeave(cbs); |
| @@ -800,8 +792,7 @@ Bool CBSFindFirst(Addr *baseReturn, Addr *limitReturn, | |||
| 800 | 792 | ||
| 801 | /* CBSFindLast -- find the last block of at least the given size */ | 793 | /* CBSFindLast -- find the last block of at least the given size */ |
| 802 | 794 | ||
| 803 | Bool CBSFindLast(Addr *baseReturn, Addr *limitReturn, | 795 | Bool CBSFindLast(Range rangeReturn, Range oldRangeReturn, |
| 804 | Addr *oldBaseReturn, Addr *oldLimitReturn, | ||
| 805 | CBS cbs, Size size, FindDelete findDelete) | 796 | CBS cbs, Size size, FindDelete findDelete) |
| 806 | { | 797 | { |
| 807 | Bool found; | 798 | Bool found; |
| @@ -810,8 +801,8 @@ Bool CBSFindLast(Addr *baseReturn, Addr *limitReturn, | |||
| 810 | AVERT(CBS, cbs); | 801 | AVERT(CBS, cbs); |
| 811 | CBSEnter(cbs); | 802 | CBSEnter(cbs); |
| 812 | 803 | ||
| 813 | AVER(baseReturn != NULL); | 804 | AVER(rangeReturn != NULL); |
| 814 | AVER(limitReturn != NULL); | 805 | AVER(oldRangeReturn != NULL); |
| 815 | AVER(size > 0); | 806 | AVER(size > 0); |
| 816 | AVER(SizeIsAligned(size, cbs->alignment)); | 807 | AVER(SizeIsAligned(size, cbs->alignment)); |
| 817 | AVER(cbs->fastFind); | 808 | AVER(cbs->fastFind); |
| @@ -822,14 +813,13 @@ Bool CBSFindLast(Addr *baseReturn, Addr *limitReturn, | |||
| 822 | &cbsTestTree, NULL, size); | 813 | &cbsTestTree, NULL, size); |
| 823 | if (found) { | 814 | if (found) { |
| 824 | CBSBlock block; | 815 | CBSBlock block; |
| 825 | Addr base, limit; | 816 | RangeStruct range; |
| 826 | block = cbsBlockOfSplayNode(node); | 817 | block = cbsBlockOfSplayNode(node); |
| 827 | AVER(CBSBlockSize(block) >= size); | 818 | AVER(CBSBlockSize(block) >= size); |
| 828 | base = CBSBlockBase(block); | 819 | RangeInit(&range, CBSBlockBase(block), CBSBlockLimit(block)); |
| 829 | limit = CBSBlockLimit(block); | 820 | AVER(RangeSize(&range) >= size); |
| 830 | AVER(AddrOffset(base, limit) >= size); | 821 | cbsFindDeleteRange(rangeReturn, oldRangeReturn, cbs, &range, |
| 831 | cbsFindDeleteRange(baseReturn, limitReturn, oldBaseReturn, oldLimitReturn, | 822 | size, findDelete); |
| 832 | cbs, base, limit, size, findDelete); | ||
| 833 | } | 823 | } |
| 834 | 824 | ||
| 835 | CBSLeave(cbs); | 825 | CBSLeave(cbs); |
| @@ -839,8 +829,7 @@ Bool CBSFindLast(Addr *baseReturn, Addr *limitReturn, | |||
| 839 | 829 | ||
| 840 | /* CBSFindLargest -- find the largest block in the CBS */ | 830 | /* CBSFindLargest -- find the largest block in the CBS */ |
| 841 | 831 | ||
| 842 | Bool CBSFindLargest(Addr *baseReturn, Addr *limitReturn, | 832 | Bool CBSFindLargest(Range rangeReturn, Range oldRangeReturn, |
| 843 | Addr *oldBaseReturn, Addr *oldLimitReturn, | ||
| 844 | CBS cbs, FindDelete findDelete) | 833 | CBS cbs, FindDelete findDelete) |
| 845 | { | 834 | { |
| 846 | Bool found = FALSE; | 835 | Bool found = FALSE; |
| @@ -850,16 +839,16 @@ Bool CBSFindLargest(Addr *baseReturn, Addr *limitReturn, | |||
| 850 | AVERT(CBS, cbs); | 839 | AVERT(CBS, cbs); |
| 851 | CBSEnter(cbs); | 840 | CBSEnter(cbs); |
| 852 | 841 | ||
| 853 | AVER(baseReturn != NULL); | 842 | AVER(rangeReturn != NULL); |
| 854 | AVER(limitReturn != NULL); | 843 | AVER(oldRangeReturn != NULL); |
| 855 | AVER(cbs->fastFind); | 844 | AVER(cbs->fastFind); |
| 856 | AVERT(FindDelete, findDelete); | 845 | AVERT(FindDelete, findDelete); |
| 857 | 846 | ||
| 858 | notEmpty = SplayRoot(&root, splayTreeOfCBS(cbs)); | 847 | notEmpty = SplayRoot(&root, splayTreeOfCBS(cbs)); |
| 859 | if (notEmpty) { | 848 | if (notEmpty) { |
| 849 | RangeStruct range; | ||
| 860 | CBSBlock block; | 850 | CBSBlock block; |
| 861 | SplayNode node = NULL; /* suppress "may be used uninitialized" */ | 851 | SplayNode node = NULL; /* suppress "may be used uninitialized" */ |
| 862 | Addr base, limit; | ||
| 863 | Size size; | 852 | Size size; |
| 864 | 853 | ||
| 865 | size = cbsBlockOfSplayNode(root)->maxSize; | 854 | size = cbsBlockOfSplayNode(root)->maxSize; |
| @@ -869,10 +858,10 @@ Bool CBSFindLargest(Addr *baseReturn, Addr *limitReturn, | |||
| 869 | AVER(found); /* maxSize is exact, so we will find it. */ | 858 | AVER(found); /* maxSize is exact, so we will find it. */ |
| 870 | block = cbsBlockOfSplayNode(node); | 859 | block = cbsBlockOfSplayNode(node); |
| 871 | AVER(CBSBlockSize(block) >= size); | 860 | AVER(CBSBlockSize(block) >= size); |
| 872 | base = CBSBlockBase(block); | 861 | RangeInit(&range, CBSBlockBase(block), CBSBlockLimit(block)); |
| 873 | limit = CBSBlockLimit(block); | 862 | AVER(RangeSize(&range) >= size); |
| 874 | cbsFindDeleteRange(baseReturn, limitReturn, oldBaseReturn, oldLimitReturn, | 863 | cbsFindDeleteRange(rangeReturn, oldRangeReturn, cbs, &range, |
| 875 | cbs, base, limit, size, findDelete); | 864 | size, findDelete); |
| 876 | } | 865 | } |
| 877 | 866 | ||
| 878 | CBSLeave(cbs); | 867 | CBSLeave(cbs); |
diff --git a/mps/code/cbs.h b/mps/code/cbs.h index 544df0a0586..5b651c1aaf8 100644 --- a/mps/code/cbs.h +++ b/mps/code/cbs.h | |||
| @@ -11,12 +11,13 @@ | |||
| 11 | 11 | ||
| 12 | #include "arg.h" | 12 | #include "arg.h" |
| 13 | #include "meter.h" | 13 | #include "meter.h" |
| 14 | #include "splay.h" | ||
| 15 | #include "mpmtypes.h" | 14 | #include "mpmtypes.h" |
| 15 | #include "range.h" | ||
| 16 | #include "splay.h" | ||
| 16 | 17 | ||
| 17 | 18 | ||
| 18 | typedef struct CBSStruct *CBS; | 19 | typedef struct CBSStruct *CBS; |
| 19 | typedef Bool (*CBSIterateMethod)(CBS cbs, Addr base, Addr limit, | 20 | typedef Bool (*CBSIterateMethod)(CBS cbs, Range range, |
| 20 | void *closureP, Size closureS); | 21 | void *closureP, Size closureS); |
| 21 | 22 | ||
| 22 | 23 | ||
| @@ -40,23 +41,18 @@ extern Res CBSInit(Arena arena, CBS cbs, void *owner, | |||
| 40 | Align alignment, Bool fastFind, ArgList args); | 41 | Align alignment, Bool fastFind, ArgList args); |
| 41 | extern void CBSFinish(CBS cbs); | 42 | extern void CBSFinish(CBS cbs); |
| 42 | 43 | ||
| 43 | extern Res CBSInsert(Addr *baseReturn, Addr *limitReturn, | 44 | extern Res CBSInsert(Range rangeReturn, CBS cbs, Range range); |
| 44 | CBS cbs, Addr base, Addr limit); | 45 | extern Res CBSDelete(Range rangeReturn, CBS cbs, Range range); |
| 45 | extern Res CBSDelete(Addr *baseReturn, Addr *limitReturn, | ||
| 46 | CBS cbs, Addr base, Addr limit); | ||
| 47 | extern void CBSIterate(CBS cbs, CBSIterateMethod iterate, | 46 | extern void CBSIterate(CBS cbs, CBSIterateMethod iterate, |
| 48 | void *closureP, Size closureS); | 47 | void *closureP, Size closureS); |
| 49 | 48 | ||
| 50 | extern Res CBSDescribe(CBS cbs, mps_lib_FILE *stream); | 49 | extern Res CBSDescribe(CBS cbs, mps_lib_FILE *stream); |
| 51 | 50 | ||
| 52 | extern Bool CBSFindFirst(Addr *baseReturn, Addr *limitReturn, | 51 | extern Bool CBSFindFirst(Range rangeReturn, Range oldRangeReturn, |
| 53 | Addr *oldBaseReturn, Addr *oldLimitReturn, | ||
| 54 | CBS cbs, Size size, FindDelete findDelete); | 52 | CBS cbs, Size size, FindDelete findDelete); |
| 55 | extern Bool CBSFindLast(Addr *baseReturn, Addr *limitReturn, | 53 | extern Bool CBSFindLast(Range rangeReturn, Range oldRangeReturn, |
| 56 | Addr *oldBaseReturn, Addr *oldLimitReturn, | ||
| 57 | CBS cbs, Size size, FindDelete findDelete); | 54 | CBS cbs, Size size, FindDelete findDelete); |
| 58 | extern Bool CBSFindLargest(Addr *baseReturn, Addr *limitReturn, | 55 | extern Bool CBSFindLargest(Range rangeReturn, Range oldRangeReturn, |
| 59 | Addr *oldBaseReturn, Addr *oldLimitReturn, | ||
| 60 | CBS cbs, FindDelete findDelete); | 56 | CBS cbs, FindDelete findDelete); |
| 61 | 57 | ||
| 62 | 58 | ||
diff --git a/mps/code/cbstest.c b/mps/code/cbstest.c index 3588d488204..4f60880a756 100644 --- a/mps/code/cbstest.c +++ b/mps/code/cbstest.c | |||
| @@ -47,9 +47,9 @@ static Index (indexOfAddr)(Addr block, Addr a) | |||
| 47 | } | 47 | } |
| 48 | 48 | ||
| 49 | 49 | ||
| 50 | static Bool checkCBSAction(CBS cbs, Addr base, Addr limit, void *closureP, | 50 | static Bool checkCBSAction(CBS cbs, Range range, void *closureP, Size closureS) |
| 51 | Size closureS) | ||
| 52 | { | 51 | { |
| 52 | Addr base, limit; | ||
| 53 | CheckCBSClosure closure = (CheckCBSClosure)closureP; | 53 | CheckCBSClosure closure = (CheckCBSClosure)closureP; |
| 54 | 54 | ||
| 55 | /* Don't need to check cbs every time */ | 55 | /* Don't need to check cbs every time */ |
| @@ -57,6 +57,9 @@ static Bool checkCBSAction(CBS cbs, Addr base, Addr limit, void *closureP, | |||
| 57 | UNUSED(closureS); | 57 | UNUSED(closureS); |
| 58 | Insist(closure != NULL); | 58 | Insist(closure != NULL); |
| 59 | 59 | ||
| 60 | base = RangeBase(range); | ||
| 61 | limit = RangeLimit(range); | ||
| 62 | |||
| 60 | if (base > closure->oldLimit) { | 63 | if (base > closure->oldLimit) { |
| 61 | Insist(BTIsSetRange(closure->allocTable, | 64 | Insist(BTIsSetRange(closure->allocTable, |
| 62 | indexOfAddr(closure->base, closure->oldLimit), | 65 | indexOfAddr(closure->base, closure->oldLimit), |
| @@ -70,7 +73,6 @@ static Bool checkCBSAction(CBS cbs, Addr base, Addr limit, void *closureP, | |||
| 70 | indexOfAddr(closure->base, base), | 73 | indexOfAddr(closure->base, base), |
| 71 | indexOfAddr(closure->base, limit))); | 74 | indexOfAddr(closure->base, limit))); |
| 72 | 75 | ||
| 73 | |||
| 74 | closure->oldLimit = limit; | 76 | closure->oldLimit = limit; |
| 75 | 77 | ||
| 76 | return TRUE; | 78 | return TRUE; |
| @@ -201,7 +203,7 @@ static void allocate(CBS cbs, Addr block, BT allocTable, | |||
| 201 | Res res; | 203 | Res res; |
| 202 | Index ib, il; /* Indexed for base and limit */ | 204 | Index ib, il; /* Indexed for base and limit */ |
| 203 | Bool isFree; | 205 | Bool isFree; |
| 204 | Addr oldBase, oldLimit; | 206 | RangeStruct range, oldRange; |
| 205 | Addr outerBase, outerLimit; /* interval containing [ib, il) */ | 207 | Addr outerBase, outerLimit; /* interval containing [ib, il) */ |
| 206 | 208 | ||
| 207 | ib = indexOfAddr(block, base); | 209 | ib = indexOfAddr(block, base); |
| @@ -234,7 +236,8 @@ static void allocate(CBS cbs, Addr block, BT allocTable, | |||
| 234 | UNUSED(total); | 236 | UNUSED(total); |
| 235 | } | 237 | } |
| 236 | 238 | ||
| 237 | res = CBSDelete(&oldBase, &oldLimit, cbs, base, limit); | 239 | RangeInit(&range, base, limit); |
| 240 | res = CBSDelete(&oldRange, cbs, &range); | ||
| 238 | 241 | ||
| 239 | if (!isFree) { | 242 | if (!isFree) { |
| 240 | die_expect((mps_res_t)res, MPS_RES_FAIL, | 243 | die_expect((mps_res_t)res, MPS_RES_FAIL, |
| @@ -242,8 +245,8 @@ static void allocate(CBS cbs, Addr block, BT allocTable, | |||
| 242 | } else { /* isFree */ | 245 | } else { /* isFree */ |
| 243 | die_expect((mps_res_t)res, MPS_RES_OK, | 246 | die_expect((mps_res_t)res, MPS_RES_OK, |
| 244 | "failed to delete free block"); | 247 | "failed to delete free block"); |
| 245 | Insist(oldBase == outerBase); | 248 | Insist(RangeBase(&oldRange) == outerBase); |
| 246 | Insist(oldLimit == outerLimit); | 249 | Insist(RangeLimit(&oldRange) == outerLimit); |
| 247 | NAllocateSucceeded++; | 250 | NAllocateSucceeded++; |
| 248 | BTSetRange(allocTable, ib, il); | 251 | BTSetRange(allocTable, ib, il); |
| 249 | } | 252 | } |
| @@ -257,7 +260,7 @@ static void deallocate(CBS cbs, Addr block, BT allocTable, | |||
| 257 | Index ib, il; | 260 | Index ib, il; |
| 258 | Bool isAllocated; | 261 | Bool isAllocated; |
| 259 | Addr outerBase = base, outerLimit = limit; /* interval containing [ib, il) */ | 262 | Addr outerBase = base, outerLimit = limit; /* interval containing [ib, il) */ |
| 260 | Addr freeBase, freeLimit; /* interval returned by CBS */ | 263 | RangeStruct range, freeRange; /* interval returned by CBS */ |
| 261 | 264 | ||
| 262 | ib = indexOfAddr(block, base); | 265 | ib = indexOfAddr(block, base); |
| 263 | il = indexOfAddr(block, limit); | 266 | il = indexOfAddr(block, limit); |
| @@ -299,7 +302,8 @@ static void deallocate(CBS cbs, Addr block, BT allocTable, | |||
| 299 | UNUSED(total); | 302 | UNUSED(total); |
| 300 | } | 303 | } |
| 301 | 304 | ||
| 302 | res = CBSInsert(&freeBase, &freeLimit, cbs, base, limit); | 305 | RangeInit(&range, base, limit); |
| 306 | res = CBSInsert(&freeRange, cbs, &range); | ||
| 303 | 307 | ||
| 304 | if (!isAllocated) { | 308 | if (!isAllocated) { |
| 305 | die_expect((mps_res_t)res, MPS_RES_FAIL, | 309 | die_expect((mps_res_t)res, MPS_RES_FAIL, |
| @@ -310,8 +314,8 @@ static void deallocate(CBS cbs, Addr block, BT allocTable, | |||
| 310 | 314 | ||
| 311 | NDeallocateSucceeded++; | 315 | NDeallocateSucceeded++; |
| 312 | BTResRange(allocTable, ib, il); | 316 | BTResRange(allocTable, ib, il); |
| 313 | Insist(freeBase == outerBase); | 317 | Insist(RangeBase(&freeRange) == outerBase); |
| 314 | Insist(freeLimit == outerLimit); | 318 | Insist(RangeLimit(&freeRange) == outerLimit); |
| 315 | } | 319 | } |
| 316 | } | 320 | } |
| 317 | 321 | ||
| @@ -321,8 +325,9 @@ static void find(CBS cbs, void *block, BT alloc, Size size, Bool high, | |||
| 321 | { | 325 | { |
| 322 | Bool expected, found; | 326 | Bool expected, found; |
| 323 | Index expectedBase, expectedLimit; | 327 | Index expectedBase, expectedLimit; |
| 324 | Addr foundBase, foundLimit, remainderBase, remainderLimit; | 328 | RangeStruct foundRange, oldRange; |
| 325 | Addr oldBase, oldLimit, origBase, origLimit; | 329 | Addr remainderBase, remainderLimit; |
| 330 | Addr origBase, origLimit; | ||
| 326 | Size oldSize, newSize; | 331 | Size oldSize, newSize; |
| 327 | 332 | ||
| 328 | origBase = origLimit = NULL; | 333 | origBase = origLimit = NULL; |
| @@ -362,18 +367,17 @@ static void find(CBS cbs, void *block, BT alloc, Size size, Bool high, | |||
| 362 | } | 367 | } |
| 363 | 368 | ||
| 364 | found = (high ? CBSFindLast : CBSFindFirst) | 369 | found = (high ? CBSFindLast : CBSFindFirst) |
| 365 | (&foundBase, &foundLimit, &oldBase, &oldLimit, | 370 | (&foundRange, &oldRange, cbs, size * Alignment, findDelete); |
| 366 | cbs, size * Alignment, findDelete); | ||
| 367 | 371 | ||
| 368 | Insist(found == expected); | 372 | Insist(found == expected); |
| 369 | 373 | ||
| 370 | if (found) { | 374 | if (found) { |
| 371 | Insist(expectedBase == indexOfAddr(block, foundBase)); | 375 | Insist(expectedBase == indexOfAddr(block, RangeBase(&foundRange))); |
| 372 | Insist(expectedLimit == indexOfAddr(block, foundLimit)); | 376 | Insist(expectedLimit == indexOfAddr(block, RangeLimit(&foundRange))); |
| 373 | 377 | ||
| 374 | if (findDelete != FindDeleteNONE) { | 378 | if (findDelete != FindDeleteNONE) { |
| 375 | Insist(oldBase == origBase); | 379 | Insist(RangeBase(&oldRange) == origBase); |
| 376 | Insist(oldLimit == origLimit); | 380 | Insist(RangeLimit(&oldRange) == origLimit); |
| 377 | BTSetRange(alloc, expectedBase, expectedLimit); | 381 | BTSetRange(alloc, expectedBase, expectedLimit); |
| 378 | } | 382 | } |
| 379 | } | 383 | } |
diff --git a/mps/code/poolmv2.c b/mps/code/poolmv2.c index e2642f23c43..bdcfd2a69ae 100644 --- a/mps/code/poolmv2.c +++ b/mps/code/poolmv2.c | |||
| @@ -46,10 +46,10 @@ static Bool MVTReturnRangeSegs(MVT mvt, Range range, Arena arena); | |||
| 46 | static Res MVTInsert(MVT mvt, Addr base, Addr limit); | 46 | static Res MVTInsert(MVT mvt, Addr base, Addr limit); |
| 47 | static Res MVTDelete(MVT mvt, Addr base, Addr limit); | 47 | static Res MVTDelete(MVT mvt, Addr base, Addr limit); |
| 48 | static void ABQRefillIfNecessary(MVT mvt, Size size); | 48 | static void ABQRefillIfNecessary(MVT mvt, Size size); |
| 49 | static Bool ABQRefillCallback(CBS cbs, Addr base, Addr limit, | 49 | static Bool ABQRefillCallback(CBS cbs, Range range, |
| 50 | void *closureP, Size closureS); | 50 | void *closureP, Size closureS); |
| 51 | static Res MVTContingencySearch(Addr *baseReturn, Addr *limitReturn, CBS cbs, Size min); | 51 | static Res MVTContingencySearch(Addr *baseReturn, Addr *limitReturn, CBS cbs, Size min); |
| 52 | static Bool MVTContingencyCallback(CBS cbs, Addr base, Addr limit, | 52 | static Bool MVTContingencyCallback(CBS cbs, Range range, |
| 53 | void *closureP, Size closureS); | 53 | void *closureP, Size closureS); |
| 54 | static Bool MVTCheckFit(Addr base, Addr limit, Size min, Arena arena); | 54 | static Bool MVTCheckFit(Addr base, Addr limit, Size min, Arena arena); |
| 55 | static ABQ MVTABQ(MVT mvt); | 55 | static ABQ MVTABQ(MVT mvt); |
| @@ -652,24 +652,23 @@ failOverflow: | |||
| 652 | static Res MVTInsert(MVT mvt, Addr base, Addr limit) | 652 | static Res MVTInsert(MVT mvt, Addr base, Addr limit) |
| 653 | { | 653 | { |
| 654 | Res res; | 654 | Res res; |
| 655 | Addr newBase, newLimit; | 655 | RangeStruct range, newRange; |
| 656 | RangeStruct range; | ||
| 657 | 656 | ||
| 658 | AVERT(MVT, mvt); | 657 | AVERT(MVT, mvt); |
| 659 | AVER(base < limit); | 658 | AVER(base < limit); |
| 660 | 659 | ||
| 661 | res = CBSInsert(&newBase, &newLimit, MVTCBS(mvt), base, limit); | 660 | RangeInit(&range, base, limit); |
| 661 | res = CBSInsert(&newRange, MVTCBS(mvt), &range); | ||
| 662 | if (res != ResOK) | 662 | if (res != ResOK) |
| 663 | return res; | 663 | return res; |
| 664 | 664 | ||
| 665 | RangeInit(&range, newBase, newLimit); | 665 | if (RangeSize(&newRange) >= mvt->reuseSize) { |
| 666 | if (RangeSize(&range) >= mvt->reuseSize) { | ||
| 667 | /* The new range is big enough that it might have been coalesced | 666 | /* The new range is big enough that it might have been coalesced |
| 668 | * with ranges on the ABQ, so ensure that they are removed before | 667 | * with ranges on the ABQ, so ensure that they are removed before |
| 669 | * reserving the new range. | 668 | * reserving the new range. |
| 670 | */ | 669 | */ |
| 671 | ABQIterate(MVTABQ(mvt), MVTDeleteOverlapping, &range, 0); | 670 | ABQIterate(MVTABQ(mvt), MVTDeleteOverlapping, &newRange, 0); |
| 672 | MVTReserve(mvt, &range); | 671 | MVTReserve(mvt, &newRange); |
| 673 | } | 672 | } |
| 674 | 673 | ||
| 675 | return ResOK; | 674 | return ResOK; |
| @@ -681,32 +680,31 @@ static Res MVTInsert(MVT mvt, Addr base, Addr limit) | |||
| 681 | */ | 680 | */ |
| 682 | static Res MVTDelete(MVT mvt, Addr base, Addr limit) | 681 | static Res MVTDelete(MVT mvt, Addr base, Addr limit) |
| 683 | { | 682 | { |
| 684 | Addr oldBase, oldLimit; | 683 | RangeStruct range, rangeOld, rangeLeft, rangeRight; |
| 685 | RangeStruct range, rangeLeft, rangeRight; | ||
| 686 | Res res; | 684 | Res res; |
| 687 | 685 | ||
| 688 | AVERT(MVT, mvt); | 686 | AVERT(MVT, mvt); |
| 689 | AVER(base < limit); | 687 | AVER(base < limit); |
| 690 | 688 | ||
| 691 | res = CBSDelete(&oldBase, &oldLimit, MVTCBS(mvt), base, limit); | 689 | RangeInit(&range, base, limit); |
| 690 | res = CBSDelete(&rangeOld, MVTCBS(mvt), &range); | ||
| 692 | if (res != ResOK) | 691 | if (res != ResOK) |
| 693 | return res; | 692 | return res; |
| 694 | 693 | ||
| 695 | /* If the old address range was larger than the reuse size, then it | 694 | /* If the old address range was larger than the reuse size, then it |
| 696 | * might be on the ABQ, so ensure it is removed. | 695 | * might be on the ABQ, so ensure it is removed. |
| 697 | */ | 696 | */ |
| 698 | RangeInit(&range, oldBase, oldLimit); | 697 | if (RangeSize(&rangeOld) >= mvt->reuseSize) |
| 699 | if (RangeSize(&range) >= mvt->reuseSize) | 698 | ABQIterate(MVTABQ(mvt), MVTDeleteOverlapping, &rangeOld, 0); |
| 700 | ABQIterate(MVTABQ(mvt), MVTDeleteOverlapping, &range, 0); | ||
| 701 | 699 | ||
| 702 | /* There might be fragments at the left or the right of the deleted | 700 | /* There might be fragments at the left or the right of the deleted |
| 703 | * range, and either might be big enough to go back on the ABQ. | 701 | * range, and either might be big enough to go back on the ABQ. |
| 704 | */ | 702 | */ |
| 705 | RangeInit(&rangeLeft, oldBase, base); | 703 | RangeInit(&rangeLeft, RangeBase(&rangeOld), base); |
| 706 | if (RangeSize(&rangeLeft) >= mvt->reuseSize) | 704 | if (RangeSize(&rangeLeft) >= mvt->reuseSize) |
| 707 | MVTReserve(mvt, &rangeLeft); | 705 | MVTReserve(mvt, &rangeLeft); |
| 708 | 706 | ||
| 709 | RangeInit(&rangeRight, limit, oldLimit); | 707 | RangeInit(&rangeRight, limit, RangeLimit(&rangeOld)); |
| 710 | if (RangeSize(&rangeRight) >= mvt->reuseSize) | 708 | if (RangeSize(&rangeRight) >= mvt->reuseSize) |
| 711 | MVTReserve(mvt, &rangeRight); | 709 | MVTReserve(mvt, &rangeRight); |
| 712 | 710 | ||
| @@ -1109,29 +1107,25 @@ static void ABQRefillIfNecessary(MVT mvt, Size size) | |||
| 1109 | /* ABQRefillCallback -- called from CBSIterate at the behest of | 1107 | /* ABQRefillCallback -- called from CBSIterate at the behest of |
| 1110 | * ABQRefillIfNecessary | 1108 | * ABQRefillIfNecessary |
| 1111 | */ | 1109 | */ |
| 1112 | static Bool ABQRefillCallback(CBS cbs, Addr base, Addr limit, | 1110 | static Bool ABQRefillCallback(CBS cbs, Range range, |
| 1113 | void *closureP, Size closureS) | 1111 | void *closureP, Size closureS) |
| 1114 | { | 1112 | { |
| 1115 | Res res; | 1113 | Res res; |
| 1116 | MVT mvt; | 1114 | MVT mvt; |
| 1117 | Size size; | ||
| 1118 | RangeStruct range; | ||
| 1119 | 1115 | ||
| 1120 | AVERT(CBS, cbs); | 1116 | AVERT(CBS, cbs); |
| 1121 | mvt = CBSMVT(cbs); | 1117 | mvt = CBSMVT(cbs); |
| 1122 | AVERT(MVT, mvt); | 1118 | AVERT(MVT, mvt); |
| 1123 | AVERT(ABQ, MVTABQ(mvt)); | 1119 | AVERT(ABQ, MVTABQ(mvt)); |
| 1124 | AVER(base < limit); | 1120 | AVERT(Range, range); |
| 1125 | UNUSED(closureP); | 1121 | UNUSED(closureP); |
| 1126 | UNUSED(closureS); | 1122 | UNUSED(closureS); |
| 1127 | 1123 | ||
| 1128 | size = AddrOffset(base, limit); | 1124 | if (RangeSize(range) < mvt->reuseSize) |
| 1129 | if (size < mvt->reuseSize) | ||
| 1130 | return TRUE; | 1125 | return TRUE; |
| 1131 | 1126 | ||
| 1132 | METER_ACC(mvt->refillPushes, ABQDepth(MVTABQ(mvt))); | 1127 | METER_ACC(mvt->refillPushes, ABQDepth(MVTABQ(mvt))); |
| 1133 | RangeInit(&range, base, limit); | 1128 | res = MVTReserve(mvt, range); |
| 1134 | res = MVTReserve(mvt, &range); | ||
| 1135 | if (res != ResOK) | 1129 | if (res != ResOK) |
| 1136 | return FALSE; | 1130 | return FALSE; |
| 1137 | 1131 | ||
| @@ -1145,8 +1139,7 @@ typedef struct MVTContigencyStruct *MVTContigency; | |||
| 1145 | typedef struct MVTContigencyStruct | 1139 | typedef struct MVTContigencyStruct |
| 1146 | { | 1140 | { |
| 1147 | Bool found; | 1141 | Bool found; |
| 1148 | Addr base; | 1142 | RangeStruct range; |
| 1149 | Addr limit; | ||
| 1150 | Arena arena; | 1143 | Arena arena; |
| 1151 | Size min; | 1144 | Size min; |
| 1152 | /* meters */ | 1145 | /* meters */ |
| @@ -1169,13 +1162,13 @@ static Res MVTContingencySearch(Addr *baseReturn, Addr *limitReturn, CBS cbs, Si | |||
| 1169 | 1162 | ||
| 1170 | CBSIterate(cbs, MVTContingencyCallback, (void *)&cls, 0); | 1163 | CBSIterate(cbs, MVTContingencyCallback, (void *)&cls, 0); |
| 1171 | if (cls.found) { | 1164 | if (cls.found) { |
| 1172 | AVER(AddrOffset(cls.base, cls.limit) >= min); | 1165 | AVER(RangeSize(&cls.range) >= min); |
| 1173 | METER_ACC(CBSMVT(cbs)->contingencySearches, cls.steps); | 1166 | METER_ACC(CBSMVT(cbs)->contingencySearches, cls.steps); |
| 1174 | if (cls.hardSteps) { | 1167 | if (cls.hardSteps) { |
| 1175 | METER_ACC(CBSMVT(cbs)->contingencyHardSearches, cls.hardSteps); | 1168 | METER_ACC(CBSMVT(cbs)->contingencyHardSearches, cls.hardSteps); |
| 1176 | } | 1169 | } |
| 1177 | *baseReturn = cls.base; | 1170 | *baseReturn = RangeBase(&cls.range); |
| 1178 | *limitReturn = cls.limit; | 1171 | *limitReturn = RangeLimit(&cls.range); |
| 1179 | return ResOK; | 1172 | return ResOK; |
| 1180 | } | 1173 | } |
| 1181 | 1174 | ||
| @@ -1186,28 +1179,30 @@ static Res MVTContingencySearch(Addr *baseReturn, Addr *limitReturn, CBS cbs, Si | |||
| 1186 | /* MVTContingencyCallback -- called from CBSIterate at the behest of | 1179 | /* MVTContingencyCallback -- called from CBSIterate at the behest of |
| 1187 | * MVTContingencySearch | 1180 | * MVTContingencySearch |
| 1188 | */ | 1181 | */ |
| 1189 | static Bool MVTContingencyCallback(CBS cbs, Addr base, Addr limit, | 1182 | static Bool MVTContingencyCallback(CBS cbs, Range range, |
| 1190 | void *closureP, Size closureS) | 1183 | void *closureP, Size closureS) |
| 1191 | { | 1184 | { |
| 1192 | MVTContigency cl; | 1185 | MVTContigency cl; |
| 1193 | Size size; | 1186 | Size size; |
| 1187 | Addr base, limit; | ||
| 1194 | 1188 | ||
| 1195 | AVERT(CBS, cbs); | 1189 | AVERT(CBS, cbs); |
| 1196 | AVER(base < limit); | 1190 | AVERT(Range, range); |
| 1197 | AVER(closureP != NULL); | 1191 | AVER(closureP != NULL); |
| 1198 | UNUSED(closureS); | 1192 | UNUSED(closureS); |
| 1199 | 1193 | ||
| 1200 | cl = (MVTContigency)closureP; | 1194 | cl = (MVTContigency)closureP; |
| 1201 | size = AddrOffset(base, limit); | 1195 | base = RangeBase(range); |
| 1202 | 1196 | limit = RangeLimit(range); | |
| 1197 | size = RangeSize(range); | ||
| 1198 | |||
| 1203 | cl->steps++; | 1199 | cl->steps++; |
| 1204 | if (size < cl->min) | 1200 | if (size < cl->min) |
| 1205 | return TRUE; | 1201 | return TRUE; |
| 1206 | 1202 | ||
| 1207 | /* verify that min will fit when seg-aligned */ | 1203 | /* verify that min will fit when seg-aligned */ |
| 1208 | if (size >= 2 * cl->min) { | 1204 | if (size >= 2 * cl->min) { |
| 1209 | cl->base = base; | 1205 | RangeInit(&cl->range, base, limit); |
| 1210 | cl->limit = limit; | ||
| 1211 | cl->found = TRUE; | 1206 | cl->found = TRUE; |
| 1212 | return FALSE; | 1207 | return FALSE; |
| 1213 | } | 1208 | } |
| @@ -1215,8 +1210,7 @@ static Bool MVTContingencyCallback(CBS cbs, Addr base, Addr limit, | |||
| 1215 | /* do it the hard way */ | 1210 | /* do it the hard way */ |
| 1216 | cl->hardSteps++; | 1211 | cl->hardSteps++; |
| 1217 | if (MVTCheckFit(base, limit, cl->min, cl->arena)) { | 1212 | if (MVTCheckFit(base, limit, cl->min, cl->arena)) { |
| 1218 | cl->base = base; | 1213 | RangeInit(&cl->range, base, limit); |
| 1219 | cl->limit = limit; | ||
| 1220 | cl->found = TRUE; | 1214 | cl->found = TRUE; |
| 1221 | return FALSE; | 1215 | return FALSE; |
| 1222 | } | 1216 | } |
diff --git a/mps/code/poolmvff.c b/mps/code/poolmvff.c index e5335377175..89b0160105d 100644 --- a/mps/code/poolmvff.c +++ b/mps/code/poolmvff.c | |||
| @@ -84,22 +84,22 @@ typedef MVFFDebugStruct *MVFFDebug; | |||
| 84 | */ | 84 | */ |
| 85 | static void MVFFAddToFreeList(Addr *baseIO, Addr *limitIO, MVFF mvff) { | 85 | static void MVFFAddToFreeList(Addr *baseIO, Addr *limitIO, MVFF mvff) { |
| 86 | Res res; | 86 | Res res; |
| 87 | Addr base, limit; | 87 | RangeStruct range, newRange; |
| 88 | 88 | ||
| 89 | AVER(baseIO != NULL); | 89 | AVER(baseIO != NULL); |
| 90 | AVER(limitIO != NULL); | 90 | AVER(limitIO != NULL); |
| 91 | AVERT(MVFF, mvff); | 91 | AVERT(MVFF, mvff); |
| 92 | base = *baseIO; | 92 | RangeInit(&range, *baseIO, *limitIO); |
| 93 | limit = *limitIO; | ||
| 94 | AVER(limit > base); | ||
| 95 | 93 | ||
| 96 | res = CBSInsert(baseIO, limitIO, CBSOfMVFF(mvff), base, limit); | 94 | res = CBSInsert(&newRange, CBSOfMVFF(mvff), &range); |
| 97 | if (ResIsAllocFailure(res)) | 95 | if (ResIsAllocFailure(res)) |
| 98 | /* CBS ran out of memory for splay nodes: lose freed range. */ | 96 | /* CBS ran out of memory for splay nodes: lose freed range. */ |
| 99 | return; | 97 | return; |
| 100 | 98 | ||
| 101 | AVER(res == ResOK); | 99 | AVER(res == ResOK); |
| 102 | mvff->free += AddrOffset(base, limit); | 100 | mvff->free += RangeSize(&range); |
| 101 | *baseIO = RangeBase(&newRange); | ||
| 102 | *limitIO = RangeLimit(&newRange); | ||
| 103 | 103 | ||
| 104 | return; | 104 | return; |
| 105 | } | 105 | } |
| @@ -140,15 +140,15 @@ static void MVFFFreeSegs(MVFF mvff, Addr base, Addr limit) | |||
| 140 | 140 | ||
| 141 | while(segLimit <= limit) { /* segment ends in range */ | 141 | while(segLimit <= limit) { /* segment ends in range */ |
| 142 | if (segBase >= base) { /* segment starts in range */ | 142 | if (segBase >= base) { /* segment starts in range */ |
| 143 | Addr oldBase, oldLimit; | 143 | RangeStruct range, oldRange; |
| 144 | res = CBSDelete(&oldBase, &oldLimit, CBSOfMVFF(mvff), segBase, segLimit); | 144 | RangeInit(&range, segBase, segLimit); |
| 145 | res = CBSDelete(&oldRange, CBSOfMVFF(mvff), &range); | ||
| 145 | if (ResIsAllocFailure(res)) | 146 | if (ResIsAllocFailure(res)) |
| 146 | /* CBS ran out of memory for splay nodes: can't delete. */ | 147 | /* CBS ran out of memory for splay nodes: can't delete. */ |
| 147 | return; | 148 | return; |
| 148 | 149 | ||
| 149 | AVER(res == ResOK); | 150 | AVER(res == ResOK); |
| 150 | AVER(oldBase <= segBase); | 151 | AVER(RangesNest(&oldRange, &range)); |
| 151 | AVER(segLimit <= oldLimit); | ||
| 152 | mvff->free -= AddrOffset(segBase, segLimit); | 152 | mvff->free -= AddrOffset(segBase, segLimit); |
| 153 | mvff->total -= AddrOffset(segBase, segLimit); | 153 | mvff->total -= AddrOffset(segBase, segLimit); |
| 154 | SegFree(seg); | 154 | SegFree(seg); |
| @@ -248,7 +248,7 @@ static Bool MVFFFindFirstFree(Addr *baseReturn, Addr *limitReturn, | |||
| 248 | { | 248 | { |
| 249 | Bool foundBlock; | 249 | Bool foundBlock; |
| 250 | FindDelete findDelete; | 250 | FindDelete findDelete; |
| 251 | Addr oldBase, oldLimit; | 251 | RangeStruct range, oldRange; |
| 252 | 252 | ||
| 253 | AVER(baseReturn != NULL); | 253 | AVER(baseReturn != NULL); |
| 254 | AVER(limitReturn != NULL); | 254 | AVER(limitReturn != NULL); |
| @@ -260,11 +260,13 @@ static Bool MVFFFindFirstFree(Addr *baseReturn, Addr *limitReturn, | |||
| 260 | 260 | ||
| 261 | foundBlock = | 261 | foundBlock = |
| 262 | (mvff->firstFit ? CBSFindFirst : CBSFindLast) | 262 | (mvff->firstFit ? CBSFindFirst : CBSFindLast) |
| 263 | (baseReturn, limitReturn, &oldBase, &oldLimit, | 263 | (&range, &oldRange, CBSOfMVFF(mvff), size, findDelete); |
| 264 | CBSOfMVFF(mvff), size, findDelete); | ||
| 265 | 264 | ||
| 266 | if (foundBlock) | 265 | if (foundBlock) { |
| 266 | *baseReturn = RangeBase(&range); | ||
| 267 | *limitReturn = RangeLimit(&range); | ||
| 267 | mvff->free -= size; | 268 | mvff->free -= size; |
| 269 | } | ||
| 268 | 270 | ||
| 269 | return foundBlock; | 271 | return foundBlock; |
| 270 | } | 272 | } |
| @@ -354,7 +356,7 @@ static Res MVFFBufferFill(Addr *baseReturn, Addr *limitReturn, | |||
| 354 | { | 356 | { |
| 355 | Res res; | 357 | Res res; |
| 356 | MVFF mvff; | 358 | MVFF mvff; |
| 357 | Addr base, limit, oldBase, oldLimit; | 359 | RangeStruct range, oldRange; |
| 358 | Bool foundBlock; | 360 | Bool foundBlock; |
| 359 | Seg seg = NULL; | 361 | Seg seg = NULL; |
| 360 | 362 | ||
| @@ -369,34 +371,33 @@ static Res MVFFBufferFill(Addr *baseReturn, Addr *limitReturn, | |||
| 369 | AVERT(Bool, withReservoirPermit); | 371 | AVERT(Bool, withReservoirPermit); |
| 370 | 372 | ||
| 371 | /* Hoping the largest is big enough, delete it and return if small. */ | 373 | /* Hoping the largest is big enough, delete it and return if small. */ |
| 372 | foundBlock = CBSFindLargest(&base, &limit, &oldBase, &oldLimit, | 374 | foundBlock = CBSFindLargest(&range, &oldRange, |
| 373 | CBSOfMVFF(mvff), FindDeleteENTIRE); | 375 | CBSOfMVFF(mvff), FindDeleteENTIRE); |
| 374 | if (foundBlock && AddrOffset(base, limit) < size) { | 376 | if (foundBlock && RangeSize(&range) < size) { |
| 375 | Addr newBase, newLimit; | 377 | RangeStruct newRange; |
| 376 | foundBlock = FALSE; | 378 | foundBlock = FALSE; |
| 377 | res = CBSInsert(&newBase, &newLimit, CBSOfMVFF(mvff), base, limit); | 379 | res = CBSInsert(&newRange, CBSOfMVFF(mvff), &range); |
| 378 | if (ResIsAllocFailure(res)) | 380 | if (ResIsAllocFailure(res)) |
| 379 | /* CBS ran out of memory for splay nodes: lose block. */ | 381 | /* CBS ran out of memory for splay nodes: lose block. */ |
| 380 | return res; | 382 | return res; |
| 381 | 383 | ||
| 382 | AVER(newBase == base); | ||
| 383 | AVER(newLimit == limit); | ||
| 384 | AVER(res == ResOK); | 384 | AVER(res == ResOK); |
| 385 | AVER(RangesEqual(&newRange, &range)); | ||
| 385 | } | 386 | } |
| 386 | if (!foundBlock) { | 387 | if (!foundBlock) { |
| 387 | res = MVFFAddSeg(&seg, mvff, size, withReservoirPermit); | 388 | res = MVFFAddSeg(&seg, mvff, size, withReservoirPermit); |
| 388 | if (res != ResOK) | 389 | if (res != ResOK) |
| 389 | return res; | 390 | return res; |
| 390 | foundBlock = CBSFindLargest(&base, &limit, &oldBase, &oldLimit, | 391 | foundBlock = CBSFindLargest(&range, &oldRange, |
| 391 | CBSOfMVFF(mvff), FindDeleteENTIRE); | 392 | CBSOfMVFF(mvff), FindDeleteENTIRE); |
| 392 | AVER(foundBlock); /* We will find the new segment. */ | 393 | AVER(foundBlock); /* We will find the new segment. */ |
| 393 | } | 394 | } |
| 394 | 395 | ||
| 395 | AVER(AddrOffset(base, limit) >= size); | 396 | AVER(RangeSize(&range) >= size); |
| 396 | mvff->free -= AddrOffset(base, limit); | 397 | mvff->free -= RangeSize(&range); |
| 397 | 398 | ||
| 398 | *baseReturn = base; | 399 | *baseReturn = RangeBase(&range); |
| 399 | *limitReturn = limit; | 400 | *limitReturn = RangeLimit(&range); |
| 400 | return ResOK; | 401 | return ResOK; |
| 401 | } | 402 | } |
| 402 | 403 | ||
diff --git a/mps/code/range.c b/mps/code/range.c index 60a8b0da367..4cd61d7b04d 100644 --- a/mps/code/range.c +++ b/mps/code/range.c | |||
| @@ -70,6 +70,22 @@ Bool RangesOverlap(Range range1, Range range2) | |||
| 70 | && RangeBase(range2) < RangeLimit(range1); | 70 | && RangeBase(range2) < RangeLimit(range1); |
| 71 | } | 71 | } |
| 72 | 72 | ||
| 73 | Bool RangesNest(Range outer, Range inner) | ||
| 74 | { | ||
| 75 | AVERT(Range, outer); | ||
| 76 | AVERT(Range, inner); | ||
| 77 | return RangeBase(outer) <= RangeBase(inner) | ||
| 78 | && RangeLimit(inner) <= RangeLimit(outer); | ||
| 79 | } | ||
| 80 | |||
| 81 | Bool RangesEqual(Range range1, Range range2) | ||
| 82 | { | ||
| 83 | AVERT(Range, range1); | ||
| 84 | AVERT(Range, range2); | ||
| 85 | return RangeBase(range1) == RangeBase(range2) | ||
| 86 | && RangeLimit(range1) == RangeLimit(range2); | ||
| 87 | } | ||
| 88 | |||
| 73 | Bool RangeIsAligned(Range range, Align alignment) | 89 | Bool RangeIsAligned(Range range, Align alignment) |
| 74 | { | 90 | { |
| 75 | AVERT(Range, range); | 91 | AVERT(Range, range); |
diff --git a/mps/code/range.h b/mps/code/range.h index c6c70ddb1c4..42ab4167715 100644 --- a/mps/code/range.h +++ b/mps/code/range.h | |||
| @@ -33,6 +33,8 @@ extern Res RangeDescribe(Range range, mps_lib_FILE *stream); | |||
| 33 | extern Bool RangeCheck(Range range); | 33 | extern Bool RangeCheck(Range range); |
| 34 | extern Bool RangeIsAligned(Range range, Align align); | 34 | extern Bool RangeIsAligned(Range range, Align align); |
| 35 | extern Bool RangesOverlap(Range range1, Range range2); | 35 | extern Bool RangesOverlap(Range range1, Range range2); |
| 36 | extern Bool RangesNest(Range outer, Range inner); | ||
| 37 | extern Bool RangesEqual(Range range1, Range range2); | ||
| 36 | extern Addr (RangeBase)(Range range); | 38 | extern Addr (RangeBase)(Range range); |
| 37 | extern Addr (RangeLimit)(Range range); | 39 | extern Addr (RangeLimit)(Range range); |
| 38 | extern Size (RangeSize)(Range range); | 40 | extern Size (RangeSize)(Range range); |