Mercurial > hg > xemacs-beta
view src/compiler.h @ 5169:6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
-------------------- ChangeLog entries follow: --------------------
src/ChangeLog addition:
2010-03-24 Ben Wing <ben@xemacs.org>
* array.h:
* array.h (XD_LISP_DYNARR_DESC):
* dumper.c (pdump_register_sub):
* dumper.c (pdump_store_new_pointer_offsets):
* dumper.c (pdump_reloc_one_mc):
* elhash.c:
* gc.c (lispdesc_one_description_line_size):
* gc.c (kkcc_marking):
* lrecord.h:
* lrecord.h (IF_NEW_GC):
* lrecord.h (enum memory_description_type):
* lrecord.h (enum data_description_entry_flags):
* lrecord.h (struct opaque_convert_functions):
Rename XD_LISP_OBJECT_BLOCK_PTR to XD_INLINE_LISP_OBJECT_BLOCK_PTR
and document it in lrecord.h.
* data.c:
* data.c (finish_marking_weak_lists):
* data.c (continue_marking_ephemerons):
* data.c (finish_marking_ephemerons):
* elhash.c (MARK_OBJ):
* gc.c:
* gc.c (lispdesc_indirect_count_1):
* gc.c (struct):
* gc.c (kkcc_bt_push):
* gc.c (kkcc_gc_stack_push):
* gc.c (kkcc_gc_stack_push_lisp_object):
* gc.c (kkcc_gc_stack_repush_dirty_object):
* gc.c (KKCC_DO_CHECK_FREE):
* gc.c (mark_object_maybe_checking_free):
* gc.c (mark_struct_contents):
* gc.c (mark_lisp_object_block_contents):
* gc.c (register_for_finalization):
* gc.c (mark_object):
* gc.h:
* lisp.h:
* profile.c:
* profile.c (mark_profiling_info_maphash):
Clean up KKCC code related to DEBUG_XEMACS. Rename
kkcc_backtrace() to kkcc_backtrace_1() and add two params: a
`size' arg to control how many stack elements to print and a
`detailed' arg to control whether Lisp objects are printed using
`debug_print()'. Create front-ends to kkcc_backtrace_1() --
kkcc_detailed_backtrace(), kkcc_short_backtrace(),
kkcc_detailed_backtrace_full(), kkcc_short_backtrace_full(), as
well as shortened versions kbt(), kbts(), kbtf(), kbtsf() -- to
call it with various parameter values. Add an `is_lisp' field to
the stack and backtrace structures and use it to keep track of
whether an object pushed onto the stack is a Lisp object or a
non-Lisp structure; in kkcc_backtrace_1(), don't try to print a
non-Lisp structure as a Lisp object.
* elhash.c:
* extents.c:
* file-coding.c:
* lrecord.h:
* lrecord.h (IF_NEW_GC):
* marker.c:
* marker.c (Fmarker_buffer):
* mule-coding.c:
* number.c:
* rangetab.c:
* specifier.c:
New macros IF_OLD_GC(), IF_NEW_GC() to simplify declaration of
Lisp objects when a finalizer may exist in one but not the other.
Use them appropriately.
* extents.c (finalize_extent_info):
Don't zero out data->soe and data->extents before trying to free,
else we get memory leaks.
* lrecord.h (enum lrecord_type):
Make the first lrecord type have value 1 not 0 so that 0 remains
without implementation and attempts to interpret zeroed memory
as a Lisp object will be more obvious.
* array.c (Dynarr_free):
* device-msw.c (msprinter_delete_device):
* device-tty.c (free_tty_device_struct):
* device-tty.c (tty_delete_device):
* dialog-msw.c (handle_directory_dialog_box):
* dialog-x.c:
* emacs.c (free_argc_argv):
* emodules.c (attempt_module_delete):
* file-coding.c (chain_finalize_coding_stream_1):
* file-coding.c (chain_finalize_coding_stream):
* glyphs-eimage.c:
* glyphs-eimage.c (jpeg_instantiate_unwind):
* glyphs-eimage.c (gif_instantiate_unwind):
* glyphs-eimage.c (png_instantiate_unwind):
* glyphs-eimage.c (tiff_instantiate_unwind):
* imgproc.c:
* imgproc.c (build_EImage_quantable):
* insdel.c (uninit_buffer_text):
* mule-coding.c (iso2022_finalize_detection_state):
* objects-tty.c (tty_finalize_color_instance):
* objects-tty.c (tty_finalize_font_instance):
* objects-tty.c (tty_font_list):
* process.c:
* process.c (finalize_process):
* redisplay.c (add_propagation_runes):
* scrollbar-gtk.c:
* scrollbar-gtk.c (gtk_free_scrollbar_instance):
* scrollbar-gtk.c (gtk_release_scrollbar_instance):
* scrollbar-msw.c:
* scrollbar-msw.c (mswindows_free_scrollbar_instance):
* scrollbar-msw.c (unshow_that_mofo):
* scrollbar-x.c (x_free_scrollbar_instance):
* scrollbar-x.c (x_release_scrollbar_instance):
* select-x.c:
* select-x.c (x_handle_selection_request):
* syntax.c:
* syntax.c (uninit_buffer_syntax_cache):
* text.h (eifree):
If possible, whenever we call xfree() on a field in a structure,
set the field to 0 afterwards. A lot of code is written so that
it checks the value being freed to see if it is non-zero before
freeing it -- doing this and setting the value to 0 afterwards
ensures (a) we won't try to free twice if the cleanup code is
called twice; (b) if the object itself stays around, KKCC won't
crash when attempting to mark the freed field.
* rangetab.c:
Add a finalization method when not NEW_GC to avoid memory leaks.
(#### We still get memory leaks when NEW_GC; need to convert gap
array to Lisp object).
author | Ben Wing <ben@xemacs.org> |
---|---|
date | Wed, 24 Mar 2010 01:22:51 -0500 |
parents | d4f666cda5e6 |
children | 308d34e9f07d |
line wrap: on
line source
/* Compiler-specific definitions for XEmacs. Copyright (C) 1998-1999, 2003 Free Software Foundation, Inc. Copyright (C) 1994 Richard Mlynarik. Copyright (C) 1995, 1996, 2000-2004, 2010 Ben Wing. This file is part of XEmacs. XEmacs is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. XEmacs is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with XEmacs; see the file COPYING. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* Synched up with: not in FSF. */ /* Authorship: NOT_REACHED, DOESNT_RETURN, PRINTF_ARGS by Richard Mlynarik, c. 1994. RETURN_SANS_WARNING by Martin buchholz, 1998 or 1999. Many changes and improvements by Jerry James, 2003. Split out of lisp.h, reorganized, and modernized. {BEGIN,END}_C_DECLS, NEED_GCC, GCC_VERSION ATTRIBUTE_MALLOC, ATTRIBUTE_CONST, ATTRIBUTE_PURE, UNUSED */ #ifndef INCLUDED_compiler_h #define INCLUDED_compiler_h /* Define min() and max(). (Some compilers put them in strange places that won't be referenced by include files used by XEmacs, such as `macros.h' under Solaris.) */ #ifndef min # define min(a,b) (((a) <= (b)) ? (a) : (b)) #endif #ifndef max # define max(a,b) (((a) > (b)) ? (a) : (b)) #endif /* Regular C complains about possible clobbering of local vars NOT declared as volatile if there's a longjmp() in a function. C++ complains if such vars ARE volatile; or more correctly, sans volatile no problem even when you longjmp, avec volatile you get unfixable compile errors like /src/xemacs/lilfix/src/process-unix.c: In function `void unix_send_process(Lisp_Object, lstream*)': /src/xemacs/lilfix/src/process-unix.c:1577: no matching function for call to ` Lisp_Object::Lisp_Object(volatile Lisp_Object&)' /src/xemacs/lilfix/src/lisp-union.h:32: candidates are: Lisp_Object::Lisp_Object(const Lisp_Object&) */ #ifdef __cplusplus # define VOLATILE_IF_NOT_CPP #else # define VOLATILE_IF_NOT_CPP volatile #endif /* Avoid indentation problems when XEmacs sees the curly braces */ #ifndef BEGIN_C_DECLS # ifdef __cplusplus # define BEGIN_C_DECLS extern "C" { # define END_C_DECLS } # else # define BEGIN_C_DECLS # define END_C_DECLS # endif #endif /* Guard against older gccs that did not define all of these symbols */ #ifdef __GNUC__ # ifndef __GNUC_MINOR__ # define __GNUC_MINOR__ 0 # endif # ifndef __GNUC_PATCHLEVEL__ # define __GNUC_PATCHLEVEL__ 0 # endif #endif /* __GNUC__ */ /* Simplify testing for specific GCC versions. For non-GNU compilers, GCC_VERSION evaluates to zero. */ #ifndef NEED_GCC # define NEED_GCC(major,minor,patch) (major * 1000000 + minor * 1000 + patch) #endif /* NEED_GCC */ #ifndef GCC_VERSION # ifdef __GNUC__ # define GCC_VERSION NEED_GCC (__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__) # else # define GCC_VERSION 0 # endif /* __GNUC__ */ #endif /* GCC_VERSION */ #ifdef _MSC_VER #define MSC_VERSION _MSC_VER #else #define MSC_VERSION 0 #endif /* GCC < 2.6.0 could only declare one attribute per function. In that case, we define DOESNT_RETURN in preference to PRINTF_ARGS, which is only used for checking args against the string spec. */ #ifndef PRINTF_ARGS # if (GCC_VERSION >= NEED_GCC (2, 6, 0)) # define PRINTF_ARGS(string_index,first_to_check) \ __attribute__ ((format (printf, string_index, first_to_check))) # else # define PRINTF_ARGS(string_index,first_to_check) # endif /* GNUC */ #endif #ifndef DOESNT_RETURN_TYPE # if (GCC_VERSION > NEED_GCC (0, 0, 0)) # if (GCC_VERSION >= NEED_GCC (2, 5, 0)) # ifndef __INTEL_COMPILER # define RETURN_NOT_REACHED(value) DO_NOTHING # endif # define DOESNT_RETURN_TYPE(rettype) rettype # define DECLARE_DOESNT_RETURN_TYPE(rettype,decl) rettype decl \ __attribute__ ((noreturn)) # else /* GCC_VERSION < NEED_GCC (2, 5, 0) */ # define DOESNT_RETURN_TYPE(rettype) rettype volatile # define DECLARE_DOESNT_RETURN_TYPE(rettype,decl) rettype volatile decl # endif /* GCC_VERSION >= NEED_GCC (2, 5, 0) */ # elif (MSC_VERSION >= 1200) /* MSVC 6.0 has a mechanism to declare functions which never return */ # define DOESNT_RETURN_TYPE(rettype) __declspec(noreturn) rettype # define DECLARE_DOESNT_RETURN_TYPE(rettype,decl) \ __declspec(noreturn) rettype XCDECL decl # if (MSC_VERSION >= 1300) /* VC++ 7 issues warnings about return statements in __declspec(noreturn) functions; this problem didn't exist under VC++ 6 */ # define RETURN_NOT_REACHED(value) DO_NOTHING # endif # else /* not gcc, VC++ */ # define DOESNT_RETURN_TYPE(rettype) rettype # define DECLARE_DOESNT_RETURN_TYPE(rettype,decl) rettype decl # endif /* GCC_VERSION > NEED_GCC (0, 0, 0) */ #endif /* DOESNT_RETURN_TYPE */ #ifndef DOESNT_RETURN # define DOESNT_RETURN DOESNT_RETURN_TYPE (void) # define DECLARE_DOESNT_RETURN(decl) DECLARE_DOESNT_RETURN_TYPE (void, decl) #endif /* DOESNT_RETURN */ /* Another try to fix SunPro C compiler warnings */ /* "end-of-loop code not reached" */ /* "statement not reached */ #if defined __SUNPRO_C || defined __USLC__ # define RETURN_SANS_WARNINGS if (1) return # define RETURN_NOT_REACHED(value) DO_NOTHING #endif /* More ways to shut up compiler. This works in Fcommand_loop_1(), where there's an infinite loop in a function returning a Lisp object. */ #if (defined (_MSC_VER) && MSC_VERSION < 1300) || defined (__SUNPRO_C) || \ defined (__SUNPRO_CC) # define DO_NOTHING_DISABLING_NO_RETURN_WARNINGS if (0) return Qnil #else # define DO_NOTHING_DISABLING_NO_RETURN_WARNINGS DO_NOTHING #endif #ifndef RETURN_NOT_REACHED # define RETURN_NOT_REACHED(value) return (value) #endif #ifndef RETURN_SANS_WARNINGS # define RETURN_SANS_WARNINGS return #endif #ifndef DO_NOTHING # define DO_NOTHING do {} while (0) #endif #ifndef DECLARE_NOTHING # define DECLARE_NOTHING struct nosuchstruct #endif #ifndef ATTRIBUTE_MALLOC # if (GCC_VERSION >= NEED_GCC (2, 96, 0)) # define ATTRIBUTE_MALLOC __attribute__ ((__malloc__)) # else # define ATTRIBUTE_MALLOC # endif /* GCC_VERSION >= NEED_GCC (2, 96, 0) */ #endif /* ATTRIBUTE_MALLOC */ #ifndef ATTRIBUTE_PURE # if (GCC_VERSION >= NEED_GCC (2, 96, 0)) # define ATTRIBUTE_PURE __attribute__ ((pure)) # else # define ATTRIBUTE_PURE # endif /* GCC_VERSION >= NEED_GCC (2, 96, 0) */ #endif /* ATTRIBUTE_PURE */ #ifndef ATTRIBUTE_CONST # if (GCC_VERSION >= NEED_GCC (2, 5, 0)) # define ATTRIBUTE_CONST __attribute__ ((const)) # define CONST_FUNC # else # define ATTRIBUTE_CONST # define CONST_FUNC const # endif /* GCC_VERSION >= NEED_GCC (2, 5, 0) */ #endif /* ATTRIBUTE_CONST */ /* NOTE: These macros MUST be named UNUSED (exactly) or something prefixed with USED_IF_, or DEFUN docstrings will be parsed incorrectly. See comments in make_docfile.c (write_c_args). You'd think that this wouldn't happen, but unfortunately we do indeed have some arguments of DEFUNs unused for GNU compatibility or because features are missing. #### At one time, __attribute__ ((unused)) confused G++. We don't know which versions. Please report problems and fix conditionals. #### A similar issue arose with the Intel CC. We know that v7 didn't work and v9 does. Let us know if v8 works or not, please. See <m34plsmh88.fsf@jerrypc.cs.usu.edu>. */ #ifndef UNUSED_ARG # define UNUSED_ARG(decl) unused_##decl #endif #ifndef UNUSED # if defined(__GNUC__) && (!defined(__INTEL_COMPILER) || __INTEL_COMPILER >= 800) # define ATTRIBUTE_UNUSED __attribute__ ((unused)) # else # define ATTRIBUTE_UNUSED # endif # define UNUSED(decl) UNUSED_ARG (decl) ATTRIBUTE_UNUSED #endif /* UNUSED */ /* Various macros for params/variables used or unused depending on config flags. */ #ifdef MULE # define USED_IF_MULE(decl) decl #else # define USED_IF_MULE(decl) UNUSED (decl) #endif #ifdef HAVE_XFT # define USED_IF_XFT(decl) decl #else # define USED_IF_XFT(decl) UNUSED (decl) #endif #ifdef HAVE_SCROLLBARS # define USED_IF_SCROLLBARS(decl) decl #else # define USED_IF_SCROLLBARS(decl) UNUSED (decl) #endif #ifdef NEW_GC # define USED_IF_NEW_GC(decl) decl # define UNUSED_IF_NEW_GC(decl) UNUSED (decl) #else # define USED_IF_NEW_GC(decl) UNUSED (decl) # define UNUSED_IF_NEW_GC(decl) decl #endif #ifdef HAVE_TTY #define USED_IF_TTY(decl) decl #else #define USED_IF_TTY(decl) UNUSED (decl) #endif #ifdef HAVE_TOOLBARS #define USED_IF_TOOLBARS(decl) decl #else #define USED_IF_TOOLBARS(decl) UNUSED (decl) #endif /* Declaration that variable or expression X is "used" to defeat "unused variable" warnings. DON'T DO THIS FOR PARAMETERS IF IT ALL POSSIBLE. Use an UNUSED() or USED_IF_*() declaration on the parameter instead. Don't do this for unused local variables that should really just be deleted. */ #define USED(x) ((void) (x)) #ifdef DEBUG_XEMACS # define REGISTER # define register #else # define REGISTER register #endif #if defined(HAVE_MS_WINDOWS) && defined(HAVE_SHLIB) # ifdef EMACS_MODULE # define MODULE_API __declspec(dllimport) # else # define MODULE_API __declspec(dllexport) # endif #else # define MODULE_API #endif /* Under "strict-aliasing" assumptions, you're not necessarily allowed to access the same memory address as two different types. The proper way around that is with a union. The macros below help out, e.g. the definition of XE_MAKEPOINTS(val) is ANSI_ALIASING_TYPEDEF (POINTS, POINTS); #define XE_MAKEPOINTS(l) ANSI_ALIASING_CAST (POINTS, l) replacing BAD!!! #define XE_MAKEPOINTS(l) (* (POINTS *) &(l)) On the other hand, if you are just casting from one pointer to the other in order to pass a pointer to another function, it's probably OK to just trick GCC by inserting an intermediate cast to (void *), to avoid warnings about "dereferencing type-punned pointer". #### I don't know how kosher this is, but do strict-aliasing rules really apply across functions? Note that the input to e.g. VOIDP_CAST must be an lvalue (i.e. not &(something)), but the value of the macro is also an lvalue, so in place of `(void **) &foo' you could write `& VOIDP_CAST (foo)' if you are subsequently dereferencing the value or don't feel comfortable doing a trick like `(void **) (void *) &foo'. Unfortunately, it does not work to just define the union type on the fly in the cast -- otherwise, we could avoid the need for a typedef. Or rather, it does work under gcc but not under Visual C++. --ben */ #define ANSI_ALIASING_TYPEDEF(name, type) typedef union { char c; type p; } *ANSI_ALIASING_##name #define ANSI_ALIASING_CAST(name, val) (((ANSI_ALIASING_##name) &(val))->p) ANSI_ALIASING_TYPEDEF (voidp, void *); /* VOIDP_CAST: Cast an lvalue to (void *) in a way that is ANSI-aliasing safe and will not result in GCC warnings. The result is still an lvalue, so you can assign to it or take its address. */ #define VOIDP_CAST(l) ANSI_ALIASING_CAST (voidp, l) #endif /* INCLUDED_compiler_h */