diff options
| author | Paul Eggert | 2012-04-07 12:18:52 -0700 |
|---|---|---|
| committer | Paul Eggert | 2012-04-07 12:18:52 -0700 |
| commit | e3fb2efb80ee8beebf7963228c4508496ebf24fa (patch) | |
| tree | a33a72f2745695e3e328a24ca8bbcd43bf8499d1 /src | |
| parent | b5385551e363e616cc8bbe067d7a8b3587ac175e (diff) | |
| download | emacs-e3fb2efb80ee8beebf7963228c4508496ebf24fa.tar.gz emacs-e3fb2efb80ee8beebf7963228c4508496ebf24fa.zip | |
Avoid unnecessary pointer scanning in garbage collection (Bug#10780).
* alloc.c (POINTERS_MIGHT_HIDE_IN_OBJECTS): New macro.
(mark_memory): Mark Lisp_Objects only if pointers might hide in
objects, as mark_maybe_pointer will catch them otherwise.
(GC_LISP_OBJECT_ALIGNMENT): Remove; no longer needed.
* s/gnu-linux.h (GC_LISP_OBJECT_ALIGNMENT) [__mc68000__]: Likewise.
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog | 9 | ||||
| -rw-r--r-- | src/alloc.c | 53 | ||||
| -rw-r--r-- | src/s/gnu-linux.h | 3 |
3 files changed, 37 insertions, 28 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index 042048a96a3..d4a031baab3 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,5 +1,14 @@ | |||
| 1 | 2012-04-07 Paul Eggert <eggert@cs.ucla.edu> | 1 | 2012-04-07 Paul Eggert <eggert@cs.ucla.edu> |
| 2 | 2 | ||
| 3 | Avoid unnecessary pointer scanning in garbage collection (Bug#10780). | ||
| 4 | * alloc.c (POINTERS_MIGHT_HIDE_IN_OBJECTS): New macro. | ||
| 5 | (mark_memory): Mark Lisp_Objects only if pointers might hide in | ||
| 6 | objects, as mark_maybe_pointer will catch them otherwise. | ||
| 7 | (GC_LISP_OBJECT_ALIGNMENT): Remove; no longer needed. | ||
| 8 | * s/gnu-linux.h (GC_LISP_OBJECT_ALIGNMENT) [__mc68000__]: Likewise. | ||
| 9 | |||
| 10 | 2012-04-07 Paul Eggert <eggert@cs.ucla.edu> | ||
| 11 | |||
| 3 | Fix typo that broke non-Windows builds. | 12 | Fix typo that broke non-Windows builds. |
| 4 | * xml.c (libxml2_loaded_p) [!!WINDOWSNT]: 'inine' -> 'inline'. | 13 | * xml.c (libxml2_loaded_p) [!!WINDOWSNT]: 'inine' -> 'inline'. |
| 5 | 14 | ||
diff --git a/src/alloc.c b/src/alloc.c index f85661415cd..4cb0ae04664 100644 --- a/src/alloc.c +++ b/src/alloc.c | |||
| @@ -4251,23 +4251,38 @@ mark_maybe_pointer (void *p) | |||
| 4251 | } | 4251 | } |
| 4252 | 4252 | ||
| 4253 | 4253 | ||
| 4254 | /* Alignment of Lisp_Object and pointer values. Use offsetof, as it | 4254 | /* Alignment of pointer values. Use offsetof, as it sometimes returns |
| 4255 | sometimes returns a smaller alignment than GCC's __alignof__ and | 4255 | a smaller alignment than GCC's __alignof__ and mark_memory might |
| 4256 | mark_memory might miss objects if __alignof__ were used. For | 4256 | miss objects if __alignof__ were used. */ |
| 4257 | example, on x86 with WIDE_EMACS_INT, __alignof__ (Lisp_Object) is 8 | ||
| 4258 | but GC_LISP_OBJECT_ALIGNMENT should be 4. */ | ||
| 4259 | #ifndef GC_LISP_OBJECT_ALIGNMENT | ||
| 4260 | # define GC_LISP_OBJECT_ALIGNMENT offsetof (struct {char a; Lisp_Object b;}, b) | ||
| 4261 | #endif | ||
| 4262 | #define GC_POINTER_ALIGNMENT offsetof (struct {char a; void *b;}, b) | 4257 | #define GC_POINTER_ALIGNMENT offsetof (struct {char a; void *b;}, b) |
| 4263 | 4258 | ||
| 4259 | /* Define POINTERS_MIGHT_HIDE_IN_OBJECTS to 1 if marking via C pointers does | ||
| 4260 | not suffice, which is the typical case. A host where a Lisp_Object is | ||
| 4261 | wider than a pointer might allocate a Lisp_Object in non-adjacent halves. | ||
| 4262 | If USE_LSB_TAG, the bottom half is not a valid pointer, but it should | ||
| 4263 | suffice to widen it to to a Lisp_Object and check it that way. */ | ||
| 4264 | #if defined USE_LSB_TAG || UINTPTR_MAX >> VALBITS != 0 | ||
| 4265 | # if !defined USE_LSB_TAG && UINTPTR_MAX >> VALBITS >> GCTYPEBITS != 0 | ||
| 4266 | /* If tag bits straddle pointer-word boundaries, neither mark_maybe_pointer | ||
| 4267 | nor mark_maybe_object can follow the pointers. This should not occur on | ||
| 4268 | any practical porting target. */ | ||
| 4269 | # error "MSB type bits straddle pointer-word boundaries" | ||
| 4270 | # endif | ||
| 4271 | /* Marking via C pointers does not suffice, because Lisp_Objects contain | ||
| 4272 | pointer words that hold pointers ORed with type bits. */ | ||
| 4273 | # define POINTERS_MIGHT_HIDE_IN_OBJECTS 1 | ||
| 4274 | #else | ||
| 4275 | /* Marking via C pointers suffices, because Lisp_Objects contain pointer | ||
| 4276 | words that hold unmodified pointers. */ | ||
| 4277 | # define POINTERS_MIGHT_HIDE_IN_OBJECTS 0 | ||
| 4278 | #endif | ||
| 4279 | |||
| 4264 | /* Mark Lisp objects referenced from the address range START+OFFSET..END | 4280 | /* Mark Lisp objects referenced from the address range START+OFFSET..END |
| 4265 | or END+OFFSET..START. */ | 4281 | or END+OFFSET..START. */ |
| 4266 | 4282 | ||
| 4267 | static void | 4283 | static void |
| 4268 | mark_memory (void *start, void *end) | 4284 | mark_memory (void *start, void *end) |
| 4269 | { | 4285 | { |
| 4270 | Lisp_Object *p; | ||
| 4271 | void **pp; | 4286 | void **pp; |
| 4272 | int i; | 4287 | int i; |
| 4273 | 4288 | ||
| @@ -4284,11 +4299,6 @@ mark_memory (void *start, void *end) | |||
| 4284 | end = tem; | 4299 | end = tem; |
| 4285 | } | 4300 | } |
| 4286 | 4301 | ||
| 4287 | /* Mark Lisp_Objects. */ | ||
| 4288 | for (p = start; (void *) p < end; p++) | ||
| 4289 | for (i = 0; i < sizeof *p; i += GC_LISP_OBJECT_ALIGNMENT) | ||
| 4290 | mark_maybe_object (*(Lisp_Object *) ((char *) p + i)); | ||
| 4291 | |||
| 4292 | /* Mark Lisp data pointed to. This is necessary because, in some | 4302 | /* Mark Lisp data pointed to. This is necessary because, in some |
| 4293 | situations, the C compiler optimizes Lisp objects away, so that | 4303 | situations, the C compiler optimizes Lisp objects away, so that |
| 4294 | only a pointer to them remains. Example: | 4304 | only a pointer to them remains. Example: |
| @@ -4310,17 +4320,10 @@ mark_memory (void *start, void *end) | |||
| 4310 | for (pp = start; (void *) pp < end; pp++) | 4320 | for (pp = start; (void *) pp < end; pp++) |
| 4311 | for (i = 0; i < sizeof *pp; i += GC_POINTER_ALIGNMENT) | 4321 | for (i = 0; i < sizeof *pp; i += GC_POINTER_ALIGNMENT) |
| 4312 | { | 4322 | { |
| 4313 | void *w = *(void **) ((char *) pp + i); | 4323 | void *p = *(void **) ((char *) pp + i); |
| 4314 | mark_maybe_pointer (w); | 4324 | mark_maybe_pointer (p); |
| 4315 | 4325 | if (POINTERS_MIGHT_HIDE_IN_OBJECTS) | |
| 4316 | #ifdef USE_LSB_TAG | 4326 | mark_maybe_object (widen_to_Lisp_Object (p)); |
| 4317 | /* A host where a Lisp_Object is wider than a pointer might | ||
| 4318 | allocate a Lisp_Object in non-adjacent halves. If | ||
| 4319 | USE_LSB_TAG, the bottom half is not a valid pointer, so | ||
| 4320 | widen it to to a Lisp_Object and check it that way. */ | ||
| 4321 | if (sizeof w < sizeof (Lisp_Object)) | ||
| 4322 | mark_maybe_object (widen_to_Lisp_Object (w)); | ||
| 4323 | #endif | ||
| 4324 | } | 4327 | } |
| 4325 | } | 4328 | } |
| 4326 | 4329 | ||
diff --git a/src/s/gnu-linux.h b/src/s/gnu-linux.h index b54bd985e6b..c1233c0e6ce 100644 --- a/src/s/gnu-linux.h +++ b/src/s/gnu-linux.h | |||
| @@ -146,9 +146,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 146 | || defined __ia64__ || defined __sh__ | 146 | || defined __ia64__ || defined __sh__ |
| 147 | #define GC_SETJMP_WORKS 1 | 147 | #define GC_SETJMP_WORKS 1 |
| 148 | #define GC_MARK_STACK GC_MAKE_GCPROS_NOOPS | 148 | #define GC_MARK_STACK GC_MAKE_GCPROS_NOOPS |
| 149 | #ifdef __mc68000__ | ||
| 150 | #define GC_LISP_OBJECT_ALIGNMENT 2 | ||
| 151 | #endif | ||
| 152 | #ifdef __ia64__ | 149 | #ifdef __ia64__ |
| 153 | #define GC_MARK_SECONDARY_STACK() \ | 150 | #define GC_MARK_SECONDARY_STACK() \ |
| 154 | do { \ | 151 | do { \ |