diff options
| author | Paul Eggert | 2017-08-29 14:20:47 -0700 |
|---|---|---|
| committer | Paul Eggert | 2017-08-29 14:58:49 -0700 |
| commit | 9baeed3514fe60189f3bf935c380da92659b7f59 (patch) | |
| tree | eb542d01212b4085203456beb62d15e5a2cb0f3d /lib-src | |
| parent | f1fdb5bc575728bd6c9f13a18939d9c271a74e83 (diff) | |
| download | emacs-9baeed3514fe60189f3bf935c380da92659b7f59.tar.gz emacs-9baeed3514fe60189f3bf935c380da92659b7f59.zip | |
Improve stack-top heuristic
This is needed for gcc -Os -flto on x86-64; otherwise, GC misses part
of the stack when scanning for heap roots, causing Emacs to crash
later (Bug#28213). The problem is that Emacs's hack for getting an
address near the stack top does not work when link-time optimization
moves stack variables around.
* configure.ac (HAVE___BUILTIN_FRAME_ADDRESS): New macro.
* lib-src/make-docfile.c (DEFUN_noinline): New constant.
(write_globals, scan_c_stream): Support noinline.
* src/alloc.c (NEAR_STACK_TOP): New macro.
(SET_STACK_TOP_ADDRESS): Use it.
(flush_stack_call_func, Fgarbage_collect): Now noinline.
Diffstat (limited to 'lib-src')
| -rw-r--r-- | lib-src/make-docfile.c | 9 |
1 files changed, 7 insertions, 2 deletions
diff --git a/lib-src/make-docfile.c b/lib-src/make-docfile.c index ecd6447ab78..c48f202a511 100644 --- a/lib-src/make-docfile.c +++ b/lib-src/make-docfile.c | |||
| @@ -592,7 +592,7 @@ struct global | |||
| 592 | }; | 592 | }; |
| 593 | 593 | ||
| 594 | /* Bit values for FLAGS field from the above. Applied for DEFUNs only. */ | 594 | /* Bit values for FLAGS field from the above. Applied for DEFUNs only. */ |
| 595 | enum { DEFUN_noreturn = 1, DEFUN_const = 2 }; | 595 | enum { DEFUN_noreturn = 1, DEFUN_const = 2, DEFUN_noinline = 4 }; |
| 596 | 596 | ||
| 597 | /* All the variable names we saw while scanning C sources in `-g' | 597 | /* All the variable names we saw while scanning C sources in `-g' |
| 598 | mode. */ | 598 | mode. */ |
| @@ -742,6 +742,8 @@ write_globals (void) | |||
| 742 | { | 742 | { |
| 743 | if (globals[i].flags & DEFUN_noreturn) | 743 | if (globals[i].flags & DEFUN_noreturn) |
| 744 | fputs ("_Noreturn ", stdout); | 744 | fputs ("_Noreturn ", stdout); |
| 745 | if (globals[i].flags & DEFUN_noinline) | ||
| 746 | fputs ("NO_INLINE ", stdout); | ||
| 745 | 747 | ||
| 746 | printf ("EXFUN (%s, ", globals[i].name); | 748 | printf ("EXFUN (%s, ", globals[i].name); |
| 747 | if (globals[i].v.value == -1) | 749 | if (globals[i].v.value == -1) |
| @@ -1062,7 +1064,8 @@ scan_c_stream (FILE *infile) | |||
| 1062 | attributes: attribute1 attribute2 ...) | 1064 | attributes: attribute1 attribute2 ...) |
| 1063 | (Lisp_Object arg...) | 1065 | (Lisp_Object arg...) |
| 1064 | 1066 | ||
| 1065 | Now only 'noreturn' and 'const' attributes are used. */ | 1067 | Now only ’const’, ’noinline’ and 'noreturn' attributes |
| 1068 | are used. */ | ||
| 1066 | 1069 | ||
| 1067 | /* Advance to the end of docstring. */ | 1070 | /* Advance to the end of docstring. */ |
| 1068 | c = getc (infile); | 1071 | c = getc (infile); |
| @@ -1108,6 +1111,8 @@ scan_c_stream (FILE *infile) | |||
| 1108 | g->flags |= DEFUN_noreturn; | 1111 | g->flags |= DEFUN_noreturn; |
| 1109 | if (strstr (input_buffer, "const")) | 1112 | if (strstr (input_buffer, "const")) |
| 1110 | g->flags |= DEFUN_const; | 1113 | g->flags |= DEFUN_const; |
| 1114 | if (strstr (input_buffer, "noinline")) | ||
| 1115 | g->flags |= DEFUN_noinline; | ||
| 1111 | } | 1116 | } |
| 1112 | continue; | 1117 | continue; |
| 1113 | } | 1118 | } |