FEinvalid_function and FEundefined_function marked as __attribute((noreturn)).
authorJuan Jose Garcia Ripoll <jjgarcia@jjgr-2.local>
Wed, 3 Feb 2010 23:05:01 +0000 (00:05 +0100)
committerJuan Jose Garcia Ripoll <jjgarcia@jjgr-2.local>
Wed, 3 Feb 2010 23:05:01 +0000 (00:05 +0100)
src/CHANGELOG
src/c/eval.d
src/c/interpreter.d
src/h/external.h

index ead274d..3fe3145 100755 (executable)
@@ -54,6 +54,10 @@ ECL 10.1.1:
    and the linker. Note, however, that the flags that ECL uses may take
    priority.
 
+ - In the C code we are beginning to use GCC's attributes (__attribute__) and
+   branch annotation (__builtin_expect) to decrease the size of code that
+   checks for errors and improve overall speed.
+
 ;;; Local Variables: ***
 ;;; mode:text ***
 ;;; fill-column:79 ***
index 5b260f9..06294e2 100644 (file)
@@ -43,11 +43,11 @@ ecl_apply_from_stack_frame(cl_object frame, cl_object x)
        cl_object fun = x;
       AGAIN:
         frame->frame.env->function = fun;
-       if (fun == OBJNULL || fun == Cnil)
+       if (__builtin_expect(fun == OBJNULL || fun == Cnil, 0))
                FEundefined_function(x);
        switch (type_of(fun)) {
        case t_cfunfixed:
-               if (narg != (cl_index)fun->cfun.narg)
+               if (__builtin_expect(narg != (cl_index)fun->cfun.narg, 0))
                        FEwrong_num_arguments(fun);
                return APPLY_fixed(narg, fun->cfunfixed.entry_fixed, sp);
        case t_cfun:
@@ -68,7 +68,7 @@ ecl_apply_from_stack_frame(cl_object frame, cl_object x)
                goto AGAIN;
 #endif
        case t_symbol:
-               if (fun->symbol.stype & stp_macro)
+               if (__builtin_expect(fun->symbol.stype & stp_macro, 0))
                        FEundefined_function(x);
                fun = SYM_FUN(fun);
                goto AGAIN;
@@ -85,8 +85,8 @@ cl_objectfn
 ecl_function_dispatch(cl_env_ptr env, cl_object x)
 {
        cl_object fun = x;
     AGAIN:
-       if (fun == OBJNULL || fun == Cnil)
+ AGAIN:
+       if (__builtin_expect(fun == OBJNULL || fun == Cnil, 0))
                FEundefined_function(x);
        switch (type_of(fun)) {
        case t_cfunfixed:
@@ -104,7 +104,7 @@ ecl_function_dispatch(cl_env_ptr env, cl_object x)
                 return fun->instance.entry;
 #endif
        case t_symbol:
-               if (fun->symbol.stype & stp_macro)
+               if (__builtin_expect(fun->symbol.stype & stp_macro, 0))
                        FEundefined_function(x);
                fun = SYM_FUN(fun);
                goto AGAIN;
index c7dd115..ae2c363 100644 (file)
@@ -233,6 +233,20 @@ close_around(cl_object fun, cl_object lex) {
         reg0 = ecl_apply_from_stack_frame((cl_object)&frame, fun);      \
         the_env->stack_top -= __n; }
 
+static void
+undefined_function(cl_object fname)
+{
+       cl_error(3, @'undefined-function', @':name', fname);
+}
+
+static void
+invalid_function(cl_object obj)
+{
+       FEwrong_type_argument(@'function', obj);
+}
+
+
+
 /* -------------------- THE INTERPRETER -------------------- */
 
 cl_object
@@ -452,7 +466,7 @@ ecl_interpret(cl_object frame, cl_object env, cl_object bytecodes)
                SETUP_ENV(the_env);
        AGAIN:
                if (reg0 == OBJNULL || reg0 == Cnil) {
-                       FEundefined_function(x);
+                       undefined_function(x);
                }
                switch (type_of(reg0)) {
                case t_cfunfixed:
@@ -478,13 +492,13 @@ ecl_interpret(cl_object frame, cl_object env, cl_object bytecodes)
                                reg0 = reg0->instance.slots[reg0->instance.length - 1];
                                goto AGAIN;
                        default:
-                               FEinvalid_function(reg0);
+                               invalid_function(reg0);
                        }
                        break;
 #endif
                case t_symbol:
                        if (reg0->symbol.stype & stp_macro)
-                               FEundefined_function(x);
+                               undefined_function(x);
                        reg0 = SYM_FUN(reg0);
                        goto AGAIN;
                case t_bytecodes:
@@ -494,7 +508,7 @@ ecl_interpret(cl_object frame, cl_object env, cl_object bytecodes)
                        reg0 = ecl_interpret(frame, reg0->bclosure.lex, reg0->bclosure.code);
                        break;
                default:
-                       FEinvalid_function(reg0);
+                       invalid_function(reg0);
                }
                ECL_STACK_POP_N_UNSAFE(the_env, narg);
                THREAD_NEXT;
index 2cacf79..4a116da 100755 (executable)
@@ -555,8 +555,8 @@ 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))*/;
 extern ECL_API void FEassignment_to_constant(cl_object v) /*__attribute__((noreturn))*/;
-extern ECL_API void FEundefined_function(cl_object fname) /*__attribute__((noreturn))*/;
-extern ECL_API void FEinvalid_function(cl_object obj) /*__attribute__((noreturn))*/;
+extern ECL_API void FEundefined_function(cl_object fname) __attribute__((noreturn));
+extern ECL_API void FEinvalid_function(cl_object obj) __attribute__((noreturn));
 extern ECL_API void FEinvalid_function_name(cl_object obj) /*__attribute__((noreturn))*/;
 extern ECL_API cl_object CEerror(cl_object c, const char *err_str, int narg, ...);
 extern ECL_API void FEillegal_index(cl_object x, cl_object i);