From 40ee2b29eb3f08f1e182f7146df02f5dd7ac4f08 Mon Sep 17 00:00:00 2001 From: Juan Jose Garcia Ripoll Date: Wed, 3 Feb 2010 23:30:16 +0100 Subject: [PATCH] Use of __builtin_expect() to mark rare error conditions. Use of __attribute__((noreturn)) on error functions which are used at the beginning of a function and do not have possibility of triggering a longjmp int the same function. --- src/c/alloc_2.d | 8 -------- src/c/dpp.c | 6 +++--- src/cmp/cmplam.lsp | 6 +++--- src/h/ecl.h | 7 +++++++ src/h/external.h | 4 ++-- 5 files changed, 15 insertions(+), 16 deletions(-) diff --git a/src/c/alloc_2.d b/src/c/alloc_2.d index 13ceec232..e4bf51478 100755 --- a/src/c/alloc_2.d +++ b/src/c/alloc_2.d @@ -25,14 +25,6 @@ #include #endif -#if !defined(__GNUC__) -# define __builtin_expect(form,value) (form) -#else -# if (__GNUC__ < 3) -# define __builtin_expect(form,value) (form) -# endif -#endif - #ifdef GBC_BOEHM static void finalize_queued(); diff --git a/src/c/dpp.c b/src/c/dpp.c index 75c80fe2e..bbf46cf6d 100755 --- a/src/c/dpp.c +++ b/src/c/dpp.c @@ -675,7 +675,7 @@ put_declaration(void) } if (nopt == 0 && !rest_flag && !key_flag) { put_lineno(); - fprintf(out, "\tif (narg!=%d) FEwrong_num_arguments(MAKE_FIXNUM(%d));\n", nreq, function_code); + fprintf(out, "\tif (__builtin_expect(narg!=%d,0)) FEwrong_num_arguments(MAKE_FIXNUM(%d));\n", nreq, function_code); } else { simple_varargs = !rest_flag && !key_flag && ((nreq + nopt) < 32); if (key_flag) { @@ -696,11 +696,11 @@ put_declaration(void) rest_var, rest_var, ((nreq > 0) ? required[nreq-1] : "narg"), nreq); put_lineno(); - fprintf(out, "\tif (narg < %d", nreq); + fprintf(out, "\tif (__builtin_expect(narg < %d", nreq); if (nopt > 0 && !rest_flag && !key_flag) { fprintf(out, "|| narg > %d", nreq + nopt); } - fprintf(out, ") FEwrong_num_arguments(MAKE_FIXNUM(%d));\n", function_code); + fprintf(out, ",0)) FEwrong_num_arguments(MAKE_FIXNUM(%d));\n", function_code); for (i = 0; i < nopt; i++) { put_lineno(); fprintf(out, "\tif (narg > %d) {\n", nreq+i); diff --git a/src/cmp/cmplam.lsp b/src/cmp/cmplam.lsp index e797db6e7..35e429a06 100644 --- a/src/cmp/cmplam.lsp +++ b/src/cmp/cmplam.lsp @@ -354,12 +354,12 @@ The function thus belongs to the type of functions that ecl_make_cfun accepts." (unless (or local-entry-p (not (compiler-check-args))) (incf *inline-blocks*) (if (and use-narg (not varargs)) - (wt-nl "if(narg!=" nreq ") FEwrong_num_arguments_anonym();") + (wt-nl "if (__builtin_expect(narg!=" nreq ",0)) FEwrong_num_arguments_anonym();") (when varargs (when requireds - (wt-nl "if(narg<" nreq ") FEwrong_num_arguments_anonym();")) + (wt-nl "if (__builtin_expect(narg<" nreq ",0)) FEwrong_num_arguments_anonym();")) (unless (or rest keywords allow-other-keys) - (wt-nl "if(narg>" (+ nreq nopt) ") FEwrong_num_arguments_anonym();")))) + (wt-nl "if (__builtin_expect(narg>" (+ nreq nopt) ",0)) FEwrong_num_arguments_anonym();")))) (wt-nl "{")) ;; If the number of required arguments exceeds the number of variables we diff --git a/src/h/ecl.h b/src/h/ecl.h index afb522d93..6096b9c87 100644 --- a/src/h/ecl.h +++ b/src/h/ecl.h @@ -86,6 +86,13 @@ #else #define ECL_INLINE #endif +#if !defined(__GNUC__) +# define __builtin_expect(form,value) (form) +#else +# if (__GNUC__ < 3) +# define __builtin_expect(form,value) (form) +# endif +#endif typedef void (*ecl_init_function_t)(cl_object block); diff --git a/src/h/external.h b/src/h/external.h index 422c521cd..2cacf791a 100755 --- a/src/h/external.h +++ b/src/h/external.h @@ -549,8 +549,8 @@ extern ECL_API void FEcannot_open(cl_object fn) /*__attribute__((noreturn))*/; extern ECL_API void FEend_of_file(cl_object strm) /*__attribute__((noreturn))*/; extern ECL_API void FEclosed_stream(cl_object strm) /*__attribute__ ((noreturn))*/; extern ECL_API void FEwrong_type_argument(cl_object type, cl_object value) /*__attribute__((noreturn))*/; -extern ECL_API void FEwrong_num_arguments(cl_object fun) /*__attribute__((noreturn))*/; -extern ECL_API void FEwrong_num_arguments_anonym(void) /*__attribute__((noreturn))*/; +extern ECL_API void FEwrong_num_arguments(cl_object fun) __attribute__((noreturn)); +extern ECL_API void FEwrong_num_arguments_anonym(void) __attribute__((noreturn)); extern ECL_API void FEunbound_variable(cl_object sym) /*__attribute__((noreturn))*/; extern ECL_API void FEinvalid_macro_call(cl_object obj) /*__attribute__((noreturn))*/; extern ECL_API void FEinvalid_variable(const char *s, cl_object obj) /*__attribute__((noreturn))*/;