diff options
| author | Andrea Corallo | 2020-05-30 11:52:27 +0100 |
|---|---|---|
| committer | Andrea Corallo | 2020-05-30 11:52:27 +0100 |
| commit | eeebbd5fcbdf2827689311b3751437670bfc2e22 (patch) | |
| tree | b0b6c946b5fc2743006a476d2df29025f2c57cc7 /src/alloc.c | |
| parent | 15c121ee0b5cbe005548eeba09dd54b145b2e258 (diff) | |
| parent | f42db4b6e1598c12924cce4bbe4d67e6d86b7963 (diff) | |
| download | emacs-eeebbd5fcbdf2827689311b3751437670bfc2e22.tar.gz emacs-eeebbd5fcbdf2827689311b3751437670bfc2e22.zip | |
Merge remote-tracking branch 'savannah/master' into HEAD
Diffstat (limited to 'src/alloc.c')
| -rw-r--r-- | src/alloc.c | 94 |
1 files changed, 73 insertions, 21 deletions
diff --git a/src/alloc.c b/src/alloc.c index b892022125e..dc92d67f163 100644 --- a/src/alloc.c +++ b/src/alloc.c | |||
| @@ -104,6 +104,46 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */ | |||
| 104 | #include "w32heap.h" /* for sbrk */ | 104 | #include "w32heap.h" /* for sbrk */ |
| 105 | #endif | 105 | #endif |
| 106 | 106 | ||
| 107 | /* A type with alignment at least as large as any object that Emacs | ||
| 108 | allocates. This is not max_align_t because some platforms (e.g., | ||
| 109 | mingw) have buggy malloc implementations that do not align for | ||
| 110 | max_align_t. This union contains types of all GCALIGNED_STRUCT | ||
| 111 | components visible here. */ | ||
| 112 | union emacs_align_type | ||
| 113 | { | ||
| 114 | struct frame frame; | ||
| 115 | struct Lisp_Bignum Lisp_Bignum; | ||
| 116 | struct Lisp_Bool_Vector Lisp_Bool_Vector; | ||
| 117 | struct Lisp_Char_Table Lisp_Char_Table; | ||
| 118 | struct Lisp_CondVar Lisp_CondVar; | ||
| 119 | struct Lisp_Finalizer Lisp_Finalizer; | ||
| 120 | struct Lisp_Float Lisp_Float; | ||
| 121 | struct Lisp_Hash_Table Lisp_Hash_Table; | ||
| 122 | struct Lisp_Marker Lisp_Marker; | ||
| 123 | struct Lisp_Misc_Ptr Lisp_Misc_Ptr; | ||
| 124 | struct Lisp_Mutex Lisp_Mutex; | ||
| 125 | struct Lisp_Overlay Lisp_Overlay; | ||
| 126 | struct Lisp_Sub_Char_Table Lisp_Sub_Char_Table; | ||
| 127 | struct Lisp_Subr Lisp_Subr; | ||
| 128 | struct Lisp_User_Ptr Lisp_User_Ptr; | ||
| 129 | struct Lisp_Vector Lisp_Vector; | ||
| 130 | struct terminal terminal; | ||
| 131 | struct thread_state thread_state; | ||
| 132 | struct window window; | ||
| 133 | |||
| 134 | /* Omit the following since they would require including process.h | ||
| 135 | etc. In practice their alignments never exceed that of the | ||
| 136 | structs already listed. */ | ||
| 137 | #if 0 | ||
| 138 | struct Lisp_Module_Function Lisp_Module_Function; | ||
| 139 | struct Lisp_Process Lisp_Process; | ||
| 140 | struct save_window_data save_window_data; | ||
| 141 | struct scroll_bar scroll_bar; | ||
| 142 | struct xwidget_view xwidget_view; | ||
| 143 | struct xwidget xwidget; | ||
| 144 | #endif | ||
| 145 | }; | ||
| 146 | |||
| 107 | /* MALLOC_SIZE_NEAR (N) is a good number to pass to malloc when | 147 | /* MALLOC_SIZE_NEAR (N) is a good number to pass to malloc when |
| 108 | allocating a block of memory with size close to N bytes. | 148 | allocating a block of memory with size close to N bytes. |
| 109 | For best results N should be a power of 2. | 149 | For best results N should be a power of 2. |
| @@ -112,9 +152,9 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */ | |||
| 112 | adds sizeof (size_t) to SIZE for internal overhead, and then rounds | 152 | adds sizeof (size_t) to SIZE for internal overhead, and then rounds |
| 113 | up to a multiple of MALLOC_ALIGNMENT. Emacs can improve | 153 | up to a multiple of MALLOC_ALIGNMENT. Emacs can improve |
| 114 | performance a bit on GNU platforms by arranging for the resulting | 154 | performance a bit on GNU platforms by arranging for the resulting |
| 115 | size to be a power of two. This heuristic is good for glibc 2.0 | 155 | size to be a power of two. This heuristic is good for glibc 2.26 |
| 116 | (1997) through at least glibc 2.31 (2020), and does not affect | 156 | (2017) and later, and does not affect correctness on other |
| 117 | correctness on other platforms. */ | 157 | platforms. */ |
| 118 | 158 | ||
| 119 | #define MALLOC_SIZE_NEAR(n) \ | 159 | #define MALLOC_SIZE_NEAR(n) \ |
| 120 | (ROUNDUP (max (n, sizeof (size_t)), MALLOC_ALIGNMENT) - sizeof (size_t)) | 160 | (ROUNDUP (max (n, sizeof (size_t)), MALLOC_ALIGNMENT) - sizeof (size_t)) |
| @@ -655,25 +695,19 @@ buffer_memory_full (ptrdiff_t nbytes) | |||
| 655 | #define COMMON_MULTIPLE(a, b) \ | 695 | #define COMMON_MULTIPLE(a, b) \ |
| 656 | ((a) % (b) == 0 ? (a) : (b) % (a) == 0 ? (b) : (a) * (b)) | 696 | ((a) % (b) == 0 ? (a) : (b) % (a) == 0 ? (b) : (a) * (b)) |
| 657 | 697 | ||
| 658 | /* LISP_ALIGNMENT is the alignment of Lisp objects. It must be at | 698 | /* Alignment needed for memory blocks that are allocated via malloc |
| 659 | least GCALIGNMENT so that pointers can be tagged. It also must be | 699 | and that contain Lisp objects. On typical hosts malloc already |
| 660 | at least as strict as the alignment of all the C types used to | 700 | aligns sufficiently, but extra work is needed on oddball hosts |
| 661 | implement Lisp objects; since pseudovectors can contain any C type, | 701 | where Emacs would crash if malloc returned a non-GCALIGNED pointer. */ |
| 662 | this is max_align_t. On recent GNU/Linux x86 and x86-64 this can | 702 | enum { LISP_ALIGNMENT = alignof (union { union emacs_align_type x; |
| 663 | often waste up to 8 bytes, since alignof (max_align_t) is 16 but | ||
| 664 | typical vectors need only an alignment of 8. Although shrinking | ||
| 665 | the alignment to 8 would save memory, it cost a 20% hit to Emacs | ||
| 666 | CPU performance on Fedora 28 x86-64 when compiled with gcc -m32. */ | ||
| 667 | enum { LISP_ALIGNMENT = alignof (union { max_align_t x; | ||
| 668 | GCALIGNED_UNION_MEMBER }) }; | 703 | GCALIGNED_UNION_MEMBER }) }; |
| 669 | verify (LISP_ALIGNMENT % GCALIGNMENT == 0); | 704 | verify (LISP_ALIGNMENT % GCALIGNMENT == 0); |
| 670 | 705 | ||
| 671 | /* True if malloc (N) is known to return storage suitably aligned for | 706 | /* True if malloc (N) is known to return storage suitably aligned for |
| 672 | Lisp objects whenever N is a multiple of LISP_ALIGNMENT. In | 707 | Lisp objects whenever N is a multiple of LISP_ALIGNMENT. In |
| 673 | practice this is true whenever alignof (max_align_t) is also a | 708 | practice this is true whenever alignof (max_align_t) is also a |
| 674 | multiple of LISP_ALIGNMENT. This works even for x86, where some | 709 | multiple of LISP_ALIGNMENT. This works even for buggy platforms |
| 675 | platform combinations (e.g., GCC 7 and later, glibc 2.25 and | 710 | like MinGW circa 2020, where alignof (max_align_t) is 16 even though |
| 676 | earlier) have bugs where alignof (max_align_t) is 16 even though | ||
| 677 | the malloc alignment is only 8, and where Emacs still works because | 711 | the malloc alignment is only 8, and where Emacs still works because |
| 678 | it never does anything that requires an alignment of 16. */ | 712 | it never does anything that requires an alignment of 16. */ |
| 679 | enum { MALLOC_IS_LISP_ALIGNED = alignof (max_align_t) % LISP_ALIGNMENT == 0 }; | 713 | enum { MALLOC_IS_LISP_ALIGNED = alignof (max_align_t) % LISP_ALIGNMENT == 0 }; |
| @@ -4660,16 +4694,33 @@ mark_maybe_objects (Lisp_Object const *array, ptrdiff_t nelts) | |||
| 4660 | mark_maybe_object (*array); | 4694 | mark_maybe_object (*array); |
| 4661 | } | 4695 | } |
| 4662 | 4696 | ||
| 4697 | /* A lower bound on the alignment of Lisp objects that need marking. | ||
| 4698 | Although 1 is safe, higher values speed up mark_maybe_pointer. | ||
| 4699 | If USE_LSB_TAG, this value is typically GCALIGNMENT; otherwise, | ||
| 4700 | it's determined by the natural alignment of Lisp structs. | ||
| 4701 | All vectorlike objects have alignment at least that of union | ||
| 4702 | vectorlike_header and it's unlikely they all have alignment greater, | ||
| 4703 | so use the union as a safe and likely-accurate standin for | ||
| 4704 | vectorlike objects. */ | ||
| 4705 | |||
| 4706 | enum { GC_OBJECT_ALIGNMENT_MINIMUM | ||
| 4707 | = max (GCALIGNMENT, | ||
| 4708 | min (alignof (union vectorlike_header), | ||
| 4709 | min (min (alignof (struct Lisp_Cons), | ||
| 4710 | alignof (struct Lisp_Float)), | ||
| 4711 | min (alignof (struct Lisp_String), | ||
| 4712 | alignof (struct Lisp_Symbol))))) }; | ||
| 4713 | |||
| 4663 | /* Return true if P might point to Lisp data that can be garbage | 4714 | /* Return true if P might point to Lisp data that can be garbage |
| 4664 | collected, and false otherwise (i.e., false if it is easy to see | 4715 | collected, and false otherwise (i.e., false if it is easy to see |
| 4665 | that P cannot point to Lisp data that can be garbage collected). | 4716 | that P cannot point to Lisp data that can be garbage collected). |
| 4666 | Symbols are implemented via offsets not pointers, but the offsets | 4717 | Symbols are implemented via offsets not pointers, but the offsets |
| 4667 | are also multiples of LISP_ALIGNMENT. */ | 4718 | are also multiples of GC_OBJECT_ALIGNMENT_MINIMUM. */ |
| 4668 | 4719 | ||
| 4669 | static bool | 4720 | static bool |
| 4670 | maybe_lisp_pointer (void *p) | 4721 | maybe_lisp_pointer (void *p) |
| 4671 | { | 4722 | { |
| 4672 | return (uintptr_t) p % LISP_ALIGNMENT == 0; | 4723 | return (uintptr_t) p % GC_OBJECT_ALIGNMENT_MINIMUM == 0; |
| 4673 | } | 4724 | } |
| 4674 | 4725 | ||
| 4675 | /* If P points to Lisp data, mark that as live if it isn't already | 4726 | /* If P points to Lisp data, mark that as live if it isn't already |
| @@ -4892,9 +4943,10 @@ test_setjmp (void) | |||
| 4892 | as a stack scan limit. */ | 4943 | as a stack scan limit. */ |
| 4893 | typedef union | 4944 | typedef union |
| 4894 | { | 4945 | { |
| 4895 | /* Align the stack top properly. Even if !HAVE___BUILTIN_UNWIND_INIT, | 4946 | /* Make sure stack_top and m_stack_bottom are properly aligned as GC |
| 4896 | jmp_buf may not be aligned enough on darwin-ppc64. */ | 4947 | expects. */ |
| 4897 | max_align_t o; | 4948 | Lisp_Object o; |
| 4949 | void *p; | ||
| 4898 | #ifndef HAVE___BUILTIN_UNWIND_INIT | 4950 | #ifndef HAVE___BUILTIN_UNWIND_INIT |
| 4899 | sys_jmp_buf j; | 4951 | sys_jmp_buf j; |
| 4900 | char c; | 4952 | char c; |