00001 /* 00002 * $Id: override.h,v 1.11 2006/02/02 05:35:31 cbiere Exp $ 00003 * 00004 * Copyright (c) 2004, Raphael Manfredi 00005 * 00006 *---------------------------------------------------------------------- 00007 * This file is part of gtk-gnutella. 00008 * 00009 * gtk-gnutella is free software; you can redistribute it and/or modify 00010 * it under the terms of the GNU General Public License as published by 00011 * the Free Software Foundation; either version 2 of the License, or 00012 * (at your option) any later version. 00013 * 00014 * gtk-gnutella is distributed in the hope that it will be useful, 00015 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00016 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00017 * GNU General Public License for more details. 00018 * 00019 * You should have received a copy of the GNU General Public License 00020 * along with gtk-gnutella; if not, write to the Free Software 00021 * Foundation, Inc.: 00022 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00023 *---------------------------------------------------------------------- 00024 */ 00025 00039 #ifndef _override_h_ 00040 #define _override_h_ 00041 00042 #ifdef FAST_ASSERTIONS 00043 /* 00044 * The following variant should be faster than the usual g_assert() because 00045 * leaf functions stay leaf functions as it does not add function calls and the 00046 * generated code is smaller which allows better optimization. However, it 00047 * abuses deferencing a null pointer to cause a SIGSEGV or for x86 the "int 00048 * 0x03" assembler opcode to cause a SIGTRAP which is then caught by a signal 00049 * handler. This is provokes undefined behaviour and is not portable but 00050 * happens to work usually. 00051 * 00052 * Look at the generated code for functions which use assertion checks to see 00053 * the difference. It does not seem to make a significant difference in 00054 * performance overall though as it seems but that might be heavily 00055 * architecture-dependent. 00056 * 00057 * Taking advantage of it may require using -momit-leaf-frame-pointer or 00058 * -fomit-frame-pointer for GCC and an appropriate -march option is also 00059 * recommended. 00060 */ 00061 #undef g_assert 00062 #undef g_assert_not_reached 00063 00068 static inline G_GNUC_NORETURN NON_NULL_PARAM((1)) void 00069 eject_(const gchar *msg) 00070 { 00071 extern const char *assert_msg_; 00072 00073 assert_msg_ = msg; 00074 00075 #if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) 00076 { 00077 /* This should raise a SIGTRAP with minimum code */ 00078 __asm__ __volatile__ ("int $03"); 00079 } 00080 #else 00081 { 00082 static volatile gint *assert_trigger_; 00083 *assert_trigger_ = 0; /* ignite a SIGSEGV */ 00084 } 00085 #endif /* GCC/x86 */ 00086 } 00087 00088 #define g_assert(x) \ 00089 G_STMT_START { \ 00090 if (G_UNLIKELY(!(x))) \ 00091 eject_("\nAssertion failure \"" STRINGIFY(x) "\" in " G_STRLOC "\n"); \ 00092 } G_STMT_END 00093 00094 #define g_assert_not_reached() \ 00095 eject_("\nCode should not have been reached in " G_STRLOC "\n"); \ 00096 00097 #endif /* FAST_ASSERTIONS */ 00098 00099 #include "malloc.h" /* Must be the last header included */ 00100 00101 #endif /* _override_h_ */ 00102 /* vi: set ts=4 sw=4 cindent: */