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/alloc.c | |
| 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/alloc.c')
| -rw-r--r-- | src/alloc.c | 53 |
1 files changed, 28 insertions, 25 deletions
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 | ||