diff --git a/src/alloc.c b/src/alloc.c
index dd783863be..21aba9e7a9 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -633,7 +633,7 @@ display_malloc_warning (void)
/* Called if we can't allocate relocatable space for a buffer. */
-void
+_Cold void
buffer_memory_full (ptrdiff_t nbytes)
{
/* If buffers use the relocating allocator, no need to free
@@ -2325,7 +2325,7 @@ compact_small_strings (void)
current_sblock = tb;
}
-void
+_Cold void
string_overflow (void)
{
error ("Maximum string size exceeded");
@@ -4085,7 +4085,7 @@ set_interval_marked (INTERVAL i)
either case this counts as memory being full even though malloc did
not fail. */
-void
+_Cold void
memory_full (size_t nbytes)
{
/* Do not go into hysterics merely because a large request failed. */
diff --git a/src/bytecode.c b/src/bytecode.c
index 40977799bf..e2fe7153b0 100644
--- a/src/bytecode.c
+++ b/src/bytecode.c
@@ -336,7 +336,7 @@ bcall0 (Lisp_Object f)
ARGS are pushed on the stack according to ARGS_TEMPLATE before
executing BYTESTR. */
-Lisp_Object
+_Hot Lisp_Object
exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth,
Lisp_Object args_template, ptrdiff_t nargs, Lisp_Object *args)
{
diff --git a/src/data.c b/src/data.c
index 11cd598ed8..1291a92955 100644
--- a/src/data.c
+++ b/src/data.c
@@ -130,7 +130,7 @@ set_blv_valcell (struct Lisp_Buffer_Local_Value *blv, Lisp_Object val)
blv->valcell = val;
}
-static _Noreturn void
+static _Cold _Noreturn void
wrong_length_argument (Lisp_Object a1, Lisp_Object a2, Lisp_Object a3)
{
Lisp_Object size1 = make_fixnum (bool_vector_size (a1));
@@ -142,7 +142,7 @@ wrong_length_argument (Lisp_Object a1, Lisp_Object a2, Lisp_Object a3)
make_fixnum (bool_vector_size (a3)));
}
-_Noreturn void
+_Cold _Noreturn void
wrong_type_argument (register Lisp_Object predicate, register Lisp_Object value)
{
/* If VALUE is not even a valid Lisp object, we'd want to abort here
@@ -155,25 +155,25 @@ wrong_type_argument (register Lisp_Object predicate, register Lisp_Object value)
xsignal2 (Qwrong_type_argument, predicate, value);
}
-void
+_Cold void
pure_write_error (Lisp_Object obj)
{
xsignal2 (Qerror, build_string ("Attempt to modify read-only object"), obj);
}
-void
+_Cold void
args_out_of_range (Lisp_Object a1, Lisp_Object a2)
{
xsignal2 (Qargs_out_of_range, a1, a2);
}
-void
+_Cold void
args_out_of_range_3 (Lisp_Object a1, Lisp_Object a2, Lisp_Object a3)
{
xsignal3 (Qargs_out_of_range, a1, a2, a3);
}
-void
+_Cold void
circular_list (Lisp_Object list)
{
xsignal1 (Qcircular_list, list);
@@ -1018,7 +1018,7 @@ do_symval_forwarding (lispfwd valcontents)
/* Used to signal a user-friendly error when symbol WRONG is
not a member of CHOICE, which should be a list of symbols. */
-void
+_Cold void
wrong_choice (Lisp_Object choice, Lisp_Object wrong)
{
ptrdiff_t i = 0, len = list_length (choice);
@@ -1051,7 +1051,7 @@ wrong_choice (Lisp_Object choice, Lisp_Object wrong)
/* Used to signal a user-friendly error if WRONG is not a number or
integer/floating-point number outsize of inclusive MIN..MAX range. */
-static void
+static _Cold void
wrong_range (Lisp_Object min, Lisp_Object max, Lisp_Object wrong)
{
AUTO_STRING (value_should_be_from, "Value should be from ");
diff --git a/src/dispnew.c b/src/dispnew.c
index ccb08ec1b9..db9166cbe6 100644
--- a/src/dispnew.c
+++ b/src/dispnew.c
@@ -360,7 +360,7 @@ verify_row_hash (struct glyph_row *row)
what is displayed on the screen. While this is usually fast, it
leads to screen flickering. */
-static void
+static _Hot void
adjust_glyph_matrix (struct window *w, struct glyph_matrix *matrix, int x, int y, struct dim dim)
{
int i;
@@ -2994,7 +2994,7 @@ window_to_frame_hpos (struct window *w, int hpos)
/* Redraw frame F. */
-void
+_Hot void
redraw_frame (struct frame *f)
{
/* Error if F has no glyphs. */
@@ -3048,7 +3048,7 @@ DEFUN ("redraw-display", Fredraw_display, Sredraw_display, 0, 0, "",
Value is true if redisplay was stopped due to pending input. */
-bool
+_Hot bool
update_frame (struct frame *f, bool force_p, bool inhibit_hairy_id_p)
{
/* True means display has been paused because of pending input. */
@@ -3384,7 +3384,7 @@ check_current_matrix_flags (struct window *w)
/* Update display of window W.
If FORCE_P, don't stop updating when input is pending. */
-static bool
+static _Hot bool
update_window (struct window *w, bool force_p)
{
struct glyph_matrix *desired_matrix = w->desired_matrix;
@@ -3580,7 +3580,7 @@ update_marginal_area (struct window *w, struct glyph_row *updated_row,
/* Update the display of the text area of row VPOS in window W.
Value is true if display has changed. */
-static bool
+static _Hot bool
update_text_area (struct window *w, struct glyph_row *updated_row, int vpos)
{
struct glyph_row *current_row = MATRIX_ROW (w->current_matrix, vpos);
@@ -4476,7 +4476,7 @@ scrolling_window (struct window *w, bool header_line_p)
Value is true if update was stopped due to pending input. */
-static bool
+static _Hot bool
update_frame_1 (struct frame *f, bool force_p, bool inhibit_id_p,
bool set_cursor_p, bool updating_menu_p)
{
@@ -4779,7 +4779,7 @@ count_match (struct glyph *str1, struct glyph *end1, struct glyph *str2, struct
/* Perform a frame-based update on line VPOS in frame FRAME. */
-static void
+static _Hot void
update_frame_line (struct frame *f, int vpos, bool updating_menu_p)
{
struct glyph *obody, *nbody, *op1, *op2, *np1, *nend;
diff --git a/src/eval.c b/src/eval.c
index e9f118c5cb..eb3d856a8f 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -1707,25 +1707,25 @@ signal_or_quit (Lisp_Object error_symbol, Lisp_Object data, bool keyboard_quit)
/* Like xsignal, but takes 0, 1, 2, or 3 args instead of a list. */
-void
+_Cold void
xsignal0 (Lisp_Object error_symbol)
{
xsignal (error_symbol, Qnil);
}
-void
+_Cold void
xsignal1 (Lisp_Object error_symbol, Lisp_Object arg)
{
xsignal (error_symbol, list1 (arg));
}
-void
+_Cold void
xsignal2 (Lisp_Object error_symbol, Lisp_Object arg1, Lisp_Object arg2)
{
xsignal (error_symbol, list2 (arg1, arg2));
}
-void
+_Cold void
xsignal3 (Lisp_Object error_symbol, Lisp_Object arg1, Lisp_Object arg2, Lisp_Object arg3)
{
xsignal (error_symbol, list3 (arg1, arg2, arg3));
@@ -1734,7 +1734,7 @@ xsignal3 (Lisp_Object error_symbol, Lisp_Object arg1, Lisp_Object arg2, Lisp_Obj
/* Signal `error' with message S, and additional arg ARG.
If ARG is not a proper list, make it a one-element list. */
-void
+_Cold void
signal_error (const char *s, Lisp_Object arg)
{
if (NILP (Fproper_list_p (arg)))
@@ -1745,7 +1745,7 @@ signal_error (const char *s, Lisp_Object arg)
/* Use this for arithmetic overflow, e.g., when an integer result is
too large even for a bignum. */
-void
+_Cold void
overflow_error (void)
{
xsignal0 (Qoverflow_error);
@@ -1892,7 +1892,7 @@ vformat_string (const char *m, va_list ap)
}
/* Dump an error message; called like vprintf. */
-void
+_Cold void
verror (const char *m, va_list ap)
{
xsignal1 (Qerror, vformat_string (m, ap));
@@ -1902,7 +1902,7 @@ verror (const char *m, va_list ap)
/* Dump an error message; called like printf. */
/* VARARGS 1 */
-void
+_Cold void
error (const char *m, ...)
{
va_list ap;
@@ -2171,7 +2171,7 @@ record_in_backtrace (Lisp_Object function, Lisp_Object *args, ptrdiff_t nargs)
/* Eval a sub-expression of the current expression (i.e. in the same
lexical scope). */
-Lisp_Object
+_Hot Lisp_Object
eval_sub (Lisp_Object form)
{
Lisp_Object fun, val, original_fun, original_args;
@@ -2863,7 +2863,7 @@ usage: (funcall FUNCTION &rest ARGUMENTS) */)
/* Apply a C subroutine SUBR to the NUMARGS evaluated arguments in ARG_VECTOR
and return the result of evaluation. */
-Lisp_Object
+_Hot Lisp_Object
funcall_subr (struct Lisp_Subr *subr, ptrdiff_t numargs, Lisp_Object *args)
{
if (numargs < subr->min_args
@@ -2942,7 +2942,7 @@ funcall_subr (struct Lisp_Subr *subr, ptrdiff_t numargs, Lisp_Object *args)
}
}
-static Lisp_Object
+static _Hot Lisp_Object
apply_lambda (Lisp_Object fun, Lisp_Object args, ptrdiff_t count)
{
Lisp_Object *arg_vector;
@@ -2978,7 +2978,7 @@ apply_lambda (Lisp_Object fun, Lisp_Object args, ptrdiff_t count)
FUN must be either a lambda-expression, a compiled-code object,
or a module function. */
-static Lisp_Object
+static _Hot Lisp_Object
funcall_lambda (Lisp_Object fun, ptrdiff_t nargs,
register Lisp_Object *arg_vector)
{
@@ -3322,7 +3322,7 @@ do_specbind (struct Lisp_Symbol *sym, union specbinding *bind,
i.e. bindings to the default value of a variable which can be
buffer-local. */
-void
+_Hot void
specbind (Lisp_Object symbol, Lisp_Object value)
{
struct Lisp_Symbol *sym;
@@ -3580,7 +3580,7 @@ set_unwind_protect_ptr (ptrdiff_t count, void (*func) (void *), void *arg)
/* Pop and execute entries from the unwind-protect stack until the
depth COUNT is reached. Return VALUE. */
-Lisp_Object
+_Hot Lisp_Object
unbind_to (ptrdiff_t count, Lisp_Object value)
{
Lisp_Object quitf = Vquit_flag;
diff --git a/src/keyboard.c b/src/keyboard.c
index 8fb6db987b..5569d0db2c 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -1038,7 +1038,7 @@ static Lisp_Object top_level_1 (Lisp_Object);
This level has the catches for exiting/returning to editor command loop.
It returns nil to exit recursive edit, t to abort it. */
-Lisp_Object
+_Hot Lisp_Object
command_loop (void)
{
#ifdef HAVE_STACK_OVERFLOW_HANDLING
@@ -8856,7 +8856,7 @@ void init_raw_keybuf_count (void)
If FIX_CURRENT_BUFFER, we restore current_buffer
from the selected window's buffer. */
-static int
+static _Hot int
read_key_sequence (Lisp_Object *keybuf, Lisp_Object prompt,
bool dont_downcase_last, bool can_return_switch_frame,
bool fix_current_buffer, bool prevent_redisplay)
diff --git a/src/lisp.h b/src/lisp.h
index 681efc3b52..b98cad5e8e 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -34,6 +34,9 @@ along with GNU Emacs. If not, see . */
#include
#include
+#define _Cold __attribute__((cold))
+#define _Hot __attribute__((hot))
+
INLINE_HEADER_BEGIN
/* Define a TYPE constant ID as an externally visible name. Use like this:
@@ -621,7 +624,7 @@ extern Lisp_Object char_table_ref (Lisp_Object, int);
extern void char_table_set (Lisp_Object, int, Lisp_Object);
/* Defined in data.c. */
-extern _Noreturn void wrong_type_argument (Lisp_Object, Lisp_Object);
+extern _Cold _Noreturn void wrong_type_argument (Lisp_Object, Lisp_Object);
/* Defined in emacs.c. */
@@ -4095,18 +4098,18 @@ extern Lisp_Object run_hook_with_args (ptrdiff_t nargs, Lisp_Object *args,
Lisp_Object (*funcall)
(ptrdiff_t nargs, Lisp_Object *args));
extern Lisp_Object quit (void);
-INLINE _Noreturn void
+INLINE _Cold _Noreturn void
xsignal (Lisp_Object error_symbol, Lisp_Object data)
{
Fsignal (error_symbol, data);
}
-extern _Noreturn void xsignal0 (Lisp_Object);
-extern _Noreturn void xsignal1 (Lisp_Object, Lisp_Object);
-extern _Noreturn void xsignal2 (Lisp_Object, Lisp_Object, Lisp_Object);
-extern _Noreturn void xsignal3 (Lisp_Object, Lisp_Object, Lisp_Object,
+extern _Cold _Noreturn void xsignal0 (Lisp_Object);
+extern _Cold _Noreturn void xsignal1 (Lisp_Object, Lisp_Object);
+extern _Cold _Noreturn void xsignal2 (Lisp_Object, Lisp_Object, Lisp_Object);
+extern _Cold _Noreturn void xsignal3 (Lisp_Object, Lisp_Object, Lisp_Object,
Lisp_Object);
-extern _Noreturn void signal_error (const char *, Lisp_Object);
-extern _Noreturn void overflow_error (void);
+extern _Cold _Noreturn void signal_error (const char *, Lisp_Object);
+extern _Cold _Noreturn void overflow_error (void);
extern bool FUNCTIONP (Lisp_Object);
extern Lisp_Object funcall_subr (struct Lisp_Subr *subr, ptrdiff_t numargs, Lisp_Object *arg_vector);
extern Lisp_Object eval_sub (Lisp_Object form);
@@ -4145,8 +4148,8 @@ extern void set_unwind_protect_ptr (ptrdiff_t, void (*) (void *), void *);
extern Lisp_Object unbind_to (ptrdiff_t, Lisp_Object);
extern void rebind_for_thread_switch (void);
extern void unbind_for_thread_switch (struct thread_state *);
-extern _Noreturn void error (const char *, ...) ATTRIBUTE_FORMAT_PRINTF (1, 2);
-extern _Noreturn void verror (const char *, va_list)
+extern _Cold _Noreturn void error (const char *, ...) ATTRIBUTE_FORMAT_PRINTF (1, 2);
+extern _Cold _Noreturn void verror (const char *, va_list)
ATTRIBUTE_FORMAT_PRINTF (1, 0);
extern Lisp_Object vformat_string (const char *, va_list)
ATTRIBUTE_FORMAT_PRINTF (1, 0);
diff --git a/src/lread.c b/src/lread.c
index 5f33fcd695..16ce4afd21 100644
--- a/src/lread.c
+++ b/src/lread.c
@@ -1912,7 +1912,7 @@ readevalloop_eager_expand_eval (Lisp_Object val, Lisp_Object macroexpand)
START, END specify region to read in current buffer (from eval-region).
If the input is not from a buffer, they must be nil. */
-static void
+static _Hot void
readevalloop (Lisp_Object readcharfun,
struct infile *infile0,
Lisp_Object sourcename,
@@ -2736,7 +2736,7 @@ read_integer (Lisp_Object readcharfun, EMACS_INT radix)
FIRST_IN_LIST is true if this is the first element of a list. */
-static Lisp_Object
+static _Hot Lisp_Object
read1 (Lisp_Object readcharfun, int *pch, bool first_in_list)
{
int c;
@@ -4092,7 +4092,7 @@ check_obarray (Lisp_Object obarray)
/* Intern symbol SYM in OBARRAY using bucket INDEX. */
-static Lisp_Object
+static _Hot Lisp_Object
intern_sym (Lisp_Object sym, Lisp_Object obarray, Lisp_Object index)
{
Lisp_Object *ptr;
@@ -4116,7 +4116,7 @@ intern_sym (Lisp_Object sym, Lisp_Object obarray, Lisp_Object index)
/* Intern a symbol with name STRING in OBARRAY using bucket INDEX. */
-Lisp_Object
+_Hot Lisp_Object
intern_driver (Lisp_Object string, Lisp_Object obarray, Lisp_Object index)
{
return intern_sym (Fmake_symbol (string), obarray, index);
@@ -4125,7 +4125,7 @@ intern_driver (Lisp_Object string, Lisp_Object obarray, Lisp_Object index)
/* Intern the C string STR: return a symbol with that name,
interned in the current obarray. */
-Lisp_Object
+_Hot Lisp_Object
intern_1 (const char *str, ptrdiff_t len)
{
Lisp_Object obarray = check_obarray (Vobarray);
diff --git a/src/sysdep.c b/src/sysdep.c
index 57ea8220ca..84e118c250 100644
--- a/src/sysdep.c
+++ b/src/sysdep.c
@@ -2447,7 +2447,7 @@ emacs_backtrace (int backtrace_limit)
}
#ifndef HAVE_NTGUI
-void
+_Cold void
emacs_abort (void)
{
terminate_due_to_signal (SIGABRT, 40);
diff --git a/src/term.c b/src/term.c
index a492276c88..472d8d19e5 100644
--- a/src/term.c
+++ b/src/term.c
@@ -4393,8 +4393,7 @@ use the Bourne shell command 'TERM=...; export TERM' (C-shell:\n\
return terminal;
}
-
-static void
+static _Cold void
vfatal (const char *str, va_list ap)
{
fprintf (stderr, "emacs: ");
@@ -4410,7 +4409,7 @@ vfatal (const char *str, va_list ap)
Delete TERMINAL, then call error or fatal with str1 or str2,
respectively, according to whether MUST_SUCCEED is true. */
-static void
+static _Cold void
maybe_fatal (bool must_succeed, struct terminal *terminal,
const char *str1, const char *str2, ...)
{
@@ -4425,7 +4424,7 @@ maybe_fatal (bool must_succeed, struct terminal *terminal,
verror (str1, ap);
}
-void
+_Cold void
fatal (const char *str, ...)
{
va_list ap;
diff --git a/src/xdisp.c b/src/xdisp.c
index a88fc698b8..aca6f09b05 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -13906,7 +13906,7 @@ do { if (polling_stopped_here) start_polling (); \
/* Perhaps in the future avoid recentering windows if it
is not necessary; currently that causes some problems. */
-static void
+static _Hot void
redisplay_internal (void)
{
struct window *w = XWINDOW (selected_window);
@@ -14925,7 +14925,7 @@ buffer_flipping_blocked_p (void)
/* Redisplay all leaf windows in the window tree rooted at WINDOW. */
-static void
+static _Hot void
redisplay_windows (Lisp_Object window)
{
while (!NILP (window))
@@ -16684,7 +16684,7 @@ set_horizontal_scroll_bar (struct window *w)
showing point will be fully (as opposed to partially) visible on
display. */
-static void
+static _Hot void
redisplay_window (Lisp_Object window, bool just_this_one_p)
{
struct window *w = XWINDOW (window);