Mercurial > emacs
comparison src/alloc.c @ 51907:4073a8ee4fc0
(BLOCK_PADDING): Rename from ABLOCKS_PADDING. Update users.
(lisp_align_malloc): Use posix_memalign is available.
(ABLOCKS_BASE): Use HAVE_POSIX_MEMALIGN as an optimization.
(STRING_BLOCK_SIZE): Rename from STRINGS_IN_STRING_BLOCK for consistency.
Update users.
| author | Stefan Monnier <monnier@iro.umontreal.ca> |
|---|---|
| date | Mon, 14 Jul 2003 02:51:08 +0000 |
| parents | 65772ad7d4e1 |
| children | cb3976b5e59f |
comparison
equal
deleted
inserted
replaced
| 51906:b4346da6617f | 51907:4073a8ee4fc0 |
|---|---|
| 642 /* BLOCK_BYTES and guarantees they are aligned on a BLOCK_ALIGN boundary. */ | 642 /* BLOCK_BYTES and guarantees they are aligned on a BLOCK_ALIGN boundary. */ |
| 643 | 643 |
| 644 | 644 |
| 645 /* BLOCK_ALIGN has to be a power of 2. */ | 645 /* BLOCK_ALIGN has to be a power of 2. */ |
| 646 #define BLOCK_ALIGN (1 << 10) | 646 #define BLOCK_ALIGN (1 << 10) |
| 647 #define BLOCK_BYTES \ | |
| 648 (BLOCK_ALIGN - sizeof (struct alinged_block *) - ABLOCKS_PADDING) | |
| 649 | |
| 650 /* Internal data structures and constants. */ | |
| 651 | 647 |
| 652 /* Padding to leave at the end of a malloc'd block. This is to give | 648 /* Padding to leave at the end of a malloc'd block. This is to give |
| 653 malloc a chance to minimize the amount of memory wasted to alignment. | 649 malloc a chance to minimize the amount of memory wasted to alignment. |
| 654 It should be tuned to the particular malloc library used. | 650 It should be tuned to the particular malloc library used. |
| 655 The current setting is based on glibc-2.3.2. */ | 651 On glibc-2.3.2, malloc never tries to align, so a padding of 0 is best. |
| 656 #define ABLOCKS_PADDING 0 | 652 posix_memalign on the other hand would ideally prefer a value of 4 |
| 653 because otherwise, there's 1020 bytes wasted between each ablocks. | |
| 654 But testing shows that those 1020 will most of the time be efficiently | |
| 655 used by malloc to place other objects, so a value of 0 is still preferable | |
| 656 unless you have a lot of cons&floats and virtually nothing else. */ | |
| 657 #define BLOCK_PADDING 0 | |
| 658 #define BLOCK_BYTES \ | |
| 659 (BLOCK_ALIGN - sizeof (struct aligned_block *) - BLOCK_PADDING) | |
| 660 | |
| 661 /* Internal data structures and constants. */ | |
| 662 | |
| 657 #define ABLOCKS_SIZE 16 | 663 #define ABLOCKS_SIZE 16 |
| 658 | 664 |
| 659 /* An aligned block of memory. */ | 665 /* An aligned block of memory. */ |
| 660 struct ablock | 666 struct ablock |
| 661 { | 667 { |
| 674 (if not, the word before the first ablock holds a pointer to the | 680 (if not, the word before the first ablock holds a pointer to the |
| 675 real base). */ | 681 real base). */ |
| 676 struct ablocks *abase; | 682 struct ablocks *abase; |
| 677 /* The padding of all but the last ablock is unused. The padding of | 683 /* The padding of all but the last ablock is unused. The padding of |
| 678 the last ablock in an ablocks is not allocated. */ | 684 the last ablock in an ablocks is not allocated. */ |
| 679 #if ABLOCKS_PADDING | 685 #if BLOCK_PADDING |
| 680 char padding[ABLOCKS_PADDING]; | 686 char padding[BLOCK_PADDING]; |
| 681 #endif | 687 #endif |
| 682 }; | 688 }; |
| 683 | 689 |
| 684 /* A bunch of consecutive aligned blocks. */ | 690 /* A bunch of consecutive aligned blocks. */ |
| 685 struct ablocks | 691 struct ablocks |
| 686 { | 692 { |
| 687 struct ablock blocks[ABLOCKS_SIZE]; | 693 struct ablock blocks[ABLOCKS_SIZE]; |
| 688 }; | 694 }; |
| 689 | 695 |
| 690 /* Size of the block requested from malloc or memalign. */ | 696 /* Size of the block requested from malloc or memalign. */ |
| 691 #define ABLOCKS_BYTES (sizeof (struct ablocks) - ABLOCKS_PADDING) | 697 #define ABLOCKS_BYTES (sizeof (struct ablocks) - BLOCK_PADDING) |
| 692 | 698 |
| 693 #define ABLOCK_ABASE(block) \ | 699 #define ABLOCK_ABASE(block) \ |
| 694 (((unsigned long) (block)->abase) <= (1 + 2 * ABLOCKS_SIZE) \ | 700 (((unsigned long) (block)->abase) <= (1 + 2 * ABLOCKS_SIZE) \ |
| 695 ? (struct ablocks *)(block) \ | 701 ? (struct ablocks *)(block) \ |
| 696 : (block)->abase) | 702 : (block)->abase) |
| 697 | 703 |
| 698 /* Virtual `busy' field. */ | 704 /* Virtual `busy' field. */ |
| 699 #define ABLOCKS_BUSY(abase) ((abase)->blocks[0].abase) | 705 #define ABLOCKS_BUSY(abase) ((abase)->blocks[0].abase) |
| 700 | 706 |
| 701 /* Pointer to the (not necessarily aligned) malloc block. */ | 707 /* Pointer to the (not necessarily aligned) malloc block. */ |
| 708 #ifdef HAVE_POSIX_MEMALIGN | |
| 709 #define ABLOCKS_BASE(abase) (abase) | |
| 710 #else | |
| 702 #define ABLOCKS_BASE(abase) \ | 711 #define ABLOCKS_BASE(abase) \ |
| 703 (1 & (int) ABLOCKS_BUSY (abase) ? abase : ((void**)abase)[-1]) | 712 (1 & (int) ABLOCKS_BUSY (abase) ? abase : ((void**)abase)[-1]) |
| 713 #endif | |
| 704 | 714 |
| 705 /* The list of free ablock. */ | 715 /* The list of free ablock. */ |
| 706 static struct ablock *free_ablock; | 716 static struct ablock *free_ablock; |
| 707 | 717 |
| 708 /* Allocate an aligned block of nbytes. | 718 /* Allocate an aligned block of nbytes. |
| 733 because mapped region contents are not preserved in | 743 because mapped region contents are not preserved in |
| 734 a dumped Emacs. */ | 744 a dumped Emacs. */ |
| 735 mallopt (M_MMAP_MAX, 0); | 745 mallopt (M_MMAP_MAX, 0); |
| 736 #endif | 746 #endif |
| 737 | 747 |
| 748 #ifdef HAVE_POSIX_MEMALIGN | |
| 749 { | |
| 750 int err = posix_memalign (&base, BLOCK_ALIGN, ABLOCKS_BYTES); | |
| 751 abase = err ? (base = NULL) : base; | |
| 752 } | |
| 753 #else | |
| 738 base = malloc (ABLOCKS_BYTES); | 754 base = malloc (ABLOCKS_BYTES); |
| 739 abase = ALIGN (base, BLOCK_ALIGN); | 755 abase = ALIGN (base, BLOCK_ALIGN); |
| 756 #endif | |
| 740 | 757 |
| 741 aligned = (base == abase); | 758 aligned = (base == abase); |
| 742 if (!aligned) | 759 if (!aligned) |
| 743 ((void**)abase)[-1] = base; | 760 ((void**)abase)[-1] = base; |
| 744 | 761 |
| 755 abase->blocks[i].x.next_free = free_ablock; | 772 abase->blocks[i].x.next_free = free_ablock; |
| 756 free_ablock = &abase->blocks[i]; | 773 free_ablock = &abase->blocks[i]; |
| 757 } | 774 } |
| 758 ABLOCKS_BUSY (abase) = (struct ablocks *) aligned; | 775 ABLOCKS_BUSY (abase) = (struct ablocks *) aligned; |
| 759 | 776 |
| 777 eassert (0 == ((EMACS_UINT)abase) % BLOCK_ALIGN); | |
| 760 eassert (ABLOCK_ABASE (&abase->blocks[3]) == abase); /* 3 is arbitrary */ | 778 eassert (ABLOCK_ABASE (&abase->blocks[3]) == abase); /* 3 is arbitrary */ |
| 761 eassert (ABLOCK_ABASE (&abase->blocks[0]) == abase); | 779 eassert (ABLOCK_ABASE (&abase->blocks[0]) == abase); |
| 762 eassert (ABLOCKS_BASE (abase) == base); | 780 eassert (ABLOCKS_BASE (abase) == base); |
| 763 eassert (aligned == (int)ABLOCKS_BUSY (abase)); | 781 eassert (aligned == (int)ABLOCKS_BUSY (abase)); |
| 764 } | 782 } |
| 1309 }; | 1327 }; |
| 1310 | 1328 |
| 1311 /* Number of Lisp strings in a string_block structure. The 1020 is | 1329 /* Number of Lisp strings in a string_block structure. The 1020 is |
| 1312 1024 minus malloc overhead. */ | 1330 1024 minus malloc overhead. */ |
| 1313 | 1331 |
| 1314 #define STRINGS_IN_STRING_BLOCK \ | 1332 #define STRING_BLOCK_SIZE \ |
| 1315 ((1020 - sizeof (struct string_block *)) / sizeof (struct Lisp_String)) | 1333 ((1020 - sizeof (struct string_block *)) / sizeof (struct Lisp_String)) |
| 1316 | 1334 |
| 1317 /* Structure describing a block from which Lisp_String structures | 1335 /* Structure describing a block from which Lisp_String structures |
| 1318 are allocated. */ | 1336 are allocated. */ |
| 1319 | 1337 |
| 1320 struct string_block | 1338 struct string_block |
| 1321 { | 1339 { |
| 1322 struct string_block *next; | 1340 struct string_block *next; |
| 1323 struct Lisp_String strings[STRINGS_IN_STRING_BLOCK]; | 1341 struct Lisp_String strings[STRING_BLOCK_SIZE]; |
| 1324 }; | 1342 }; |
| 1325 | 1343 |
| 1326 /* Head and tail of the list of sblock structures holding Lisp string | 1344 /* Head and tail of the list of sblock structures holding Lisp string |
| 1327 data. We always allocate from current_sblock. The NEXT pointers | 1345 data. We always allocate from current_sblock. The NEXT pointers |
| 1328 in the sblock structures go from oldest_sblock to current_sblock. */ | 1346 in the sblock structures go from oldest_sblock to current_sblock. */ |
| 1513 bzero (b, sizeof *b); | 1531 bzero (b, sizeof *b); |
| 1514 b->next = string_blocks; | 1532 b->next = string_blocks; |
| 1515 string_blocks = b; | 1533 string_blocks = b; |
| 1516 ++n_string_blocks; | 1534 ++n_string_blocks; |
| 1517 | 1535 |
| 1518 for (i = STRINGS_IN_STRING_BLOCK - 1; i >= 0; --i) | 1536 for (i = STRING_BLOCK_SIZE - 1; i >= 0; --i) |
| 1519 { | 1537 { |
| 1520 s = b->strings + i; | 1538 s = b->strings + i; |
| 1521 NEXT_FREE_LISP_STRING (s) = string_free_list; | 1539 NEXT_FREE_LISP_STRING (s) = string_free_list; |
| 1522 string_free_list = s; | 1540 string_free_list = s; |
| 1523 } | 1541 } |
| 1524 | 1542 |
| 1525 total_free_strings += STRINGS_IN_STRING_BLOCK; | 1543 total_free_strings += STRING_BLOCK_SIZE; |
| 1526 } | 1544 } |
| 1527 | 1545 |
| 1528 /* Pop a Lisp_String off the free-list. */ | 1546 /* Pop a Lisp_String off the free-list. */ |
| 1529 s = string_free_list; | 1547 s = string_free_list; |
| 1530 string_free_list = NEXT_FREE_LISP_STRING (s); | 1548 string_free_list = NEXT_FREE_LISP_STRING (s); |
| 1671 int i, nfree = 0; | 1689 int i, nfree = 0; |
| 1672 struct Lisp_String *free_list_before = string_free_list; | 1690 struct Lisp_String *free_list_before = string_free_list; |
| 1673 | 1691 |
| 1674 next = b->next; | 1692 next = b->next; |
| 1675 | 1693 |
| 1676 for (i = 0; i < STRINGS_IN_STRING_BLOCK; ++i) | 1694 for (i = 0; i < STRING_BLOCK_SIZE; ++i) |
| 1677 { | 1695 { |
| 1678 struct Lisp_String *s = b->strings + i; | 1696 struct Lisp_String *s = b->strings + i; |
| 1679 | 1697 |
| 1680 if (s->data) | 1698 if (s->data) |
| 1681 { | 1699 { |
| 1726 } | 1744 } |
| 1727 } | 1745 } |
| 1728 | 1746 |
| 1729 /* Free blocks that contain free Lisp_Strings only, except | 1747 /* Free blocks that contain free Lisp_Strings only, except |
| 1730 the first two of them. */ | 1748 the first two of them. */ |
| 1731 if (nfree == STRINGS_IN_STRING_BLOCK | 1749 if (nfree == STRING_BLOCK_SIZE |
| 1732 && total_free_strings > STRINGS_IN_STRING_BLOCK) | 1750 && total_free_strings > STRING_BLOCK_SIZE) |
| 1733 { | 1751 { |
| 1734 lisp_free (b); | 1752 lisp_free (b); |
| 1735 --n_string_blocks; | 1753 --n_string_blocks; |
| 1736 string_free_list = free_list_before; | 1754 string_free_list = free_list_before; |
| 1737 } | 1755 } |
