view src/mc-alloc.h @ 5157:1fae11d56ad2

redo memory-usage mechanism, add way of dynamically initializing Lisp objects -------------------- ChangeLog entries follow: -------------------- lisp/ChangeLog addition: 2010-03-18 Ben Wing <ben@xemacs.org> * diagnose.el (show-memory-usage): Rewrite to take into account API changes in memory-usage functions. src/ChangeLog addition: 2010-03-18 Ben Wing <ben@xemacs.org> * alloc.c: * alloc.c (disksave_object_finalization_1): * alloc.c (lisp_object_storage_size): * alloc.c (listu): * alloc.c (listn): * alloc.c (Fobject_memory_usage_stats): * alloc.c (compute_memusage_stats_length): * alloc.c (Fobject_memory_usage): * alloc.c (Ftotal_object_memory_usage): * alloc.c (malloced_storage_size): * alloc.c (common_init_alloc_early): * alloc.c (reinit_alloc_objects_early): * alloc.c (reinit_alloc_early): * alloc.c (init_alloc_once_early): * alloc.c (syms_of_alloc): * alloc.c (reinit_vars_of_alloc): * buffer.c: * buffer.c (struct buffer_stats): * buffer.c (compute_buffer_text_usage): * buffer.c (compute_buffer_usage): * buffer.c (buffer_memory_usage): * buffer.c (buffer_objects_create): * buffer.c (syms_of_buffer): * buffer.c (vars_of_buffer): * console-impl.h (struct console_methods): * dynarr.c (Dynarr_memory_usage): * emacs.c (main_1): * events.c (clear_event_resource): * extents.c: * extents.c (compute_buffer_extent_usage): * extents.c (extent_objects_create): * extents.h: * faces.c: * faces.c (compute_face_cachel_usage): * faces.c (face_objects_create): * faces.h: * general-slots.h: * glyphs.c: * glyphs.c (compute_glyph_cachel_usage): * glyphs.c (glyph_objects_create): * glyphs.h: * lisp.h: * lisp.h (struct usage_stats): * lrecord.h: * lrecord.h (enum lrecord_type): * lrecord.h (struct lrecord_implementation): * lrecord.h (MC_ALLOC_CALL_FINALIZER_FOR_DISKSAVE): * lrecord.h (DEFINE_DUMPABLE_LISP_OBJECT): * lrecord.h (DEFINE_DUMPABLE_SIZABLE_LISP_OBJECT): * lrecord.h (DEFINE_DUMPABLE_FROB_BLOCK_LISP_OBJECT): * lrecord.h (DEFINE_DUMPABLE_FROB_BLOCK_SIZABLE_LISP_OBJECT): * lrecord.h (DEFINE_DUMPABLE_INTERNAL_LISP_OBJECT): * lrecord.h (DEFINE_DUMPABLE_SIZABLE_INTERNAL_LISP_OBJECT): * lrecord.h (DEFINE_NODUMP_LISP_OBJECT): * lrecord.h (DEFINE_NODUMP_SIZABLE_LISP_OBJECT): * lrecord.h (DEFINE_NODUMP_FROB_BLOCK_LISP_OBJECT): * lrecord.h (DEFINE_NODUMP_FROB_BLOCK_SIZABLE_LISP_OBJECT): * lrecord.h (DEFINE_NODUMP_INTERNAL_LISP_OBJECT): * lrecord.h (DEFINE_NODUMP_SIZABLE_INTERNAL_LISP_OBJECT): * lrecord.h (MAKE_LISP_OBJECT): * lrecord.h (DEFINE_DUMPABLE_MODULE_LISP_OBJECT): * lrecord.h (DEFINE_DUMPABLE_MODULE_SIZABLE_LISP_OBJECT): * lrecord.h (DEFINE_NODUMP_MODULE_LISP_OBJECT): * lrecord.h (DEFINE_NODUMP_MODULE_SIZABLE_LISP_OBJECT): * lrecord.h (MAKE_MODULE_LISP_OBJECT): * lrecord.h (INIT_LISP_OBJECT): * lrecord.h (INIT_MODULE_LISP_OBJECT): * lrecord.h (UNDEF_LISP_OBJECT): * lrecord.h (UNDEF_MODULE_LISP_OBJECT): * lrecord.h (DECLARE_LISP_OBJECT): * lrecord.h (DECLARE_MODULE_API_LISP_OBJECT): * lrecord.h (DECLARE_MODULE_LISP_OBJECT): * lstream.c: * lstream.c (syms_of_lstream): * lstream.c (vars_of_lstream): * marker.c: * marker.c (compute_buffer_marker_usage): * mc-alloc.c (mc_alloced_storage_size): * mc-alloc.h: * mule-charset.c: * mule-charset.c (struct charset_stats): * mule-charset.c (compute_charset_usage): * mule-charset.c (charset_memory_usage): * mule-charset.c (mule_charset_objects_create): * mule-charset.c (syms_of_mule_charset): * mule-charset.c (vars_of_mule_charset): * redisplay.c: * redisplay.c (compute_rune_dynarr_usage): * redisplay.c (compute_display_block_dynarr_usage): * redisplay.c (compute_glyph_block_dynarr_usage): * redisplay.c (compute_display_line_dynarr_usage): * redisplay.c (compute_line_start_cache_dynarr_usage): * redisplay.h: * scrollbar-gtk.c (gtk_compute_scrollbar_instance_usage): * scrollbar-msw.c (mswindows_compute_scrollbar_instance_usage): * scrollbar-x.c (x_compute_scrollbar_instance_usage): * scrollbar.c (compute_scrollbar_instance_usage): * scrollbar.h: * symbols.c: * symbols.c (reinit_symbol_objects_early): * symbols.c (init_symbols_once_early): * symbols.c (reinit_symbols_early): * symbols.c (defsymbol_massage_name_1): * symsinit.h: * ui-gtk.c: * ui-gtk.c (emacs_gtk_object_getprop): * ui-gtk.c (emacs_gtk_object_putprop): * ui-gtk.c (ui_gtk_objects_create): * unicode.c (compute_from_unicode_table_size_1): * unicode.c (compute_to_unicode_table_size_1): * unicode.c (compute_from_unicode_table_size): * unicode.c (compute_to_unicode_table_size): * window.c: * window.c (struct window_stats): * window.c (compute_window_mirror_usage): * window.c (compute_window_usage): * window.c (window_memory_usage): * window.c (window_objects_create): * window.c (syms_of_window): * window.c (vars_of_window): * window.h: Redo memory-usage mechanism, make it general; add way of dynamically initializing Lisp object types -- OBJECT_HAS_METHOD(), similar to CONSOLE_HAS_METHOD(). (1) Create OBJECT_HAS_METHOD(), OBJECT_HAS_PROPERTY() etc. for specifying that a Lisp object type has a particular method or property. Call such methods with OBJECT_METH, MAYBE_OBJECT_METH, OBJECT_METH_OR_GIVEN; retrieve properties with OBJECT_PROPERTY. Methods that formerly required a DEFINE_*GENERAL_LISP_OBJECT() to specify them (getprop, putprop, remprop, plist, disksave) now instead use the dynamic-method mechanism. The main benefit of this is that new methods or properties can be added without requiring that the declaration statements of all existing methods be modified. We have to make the `struct lrecord_implementation' non-const, but I don't think this should have any effect on speed -- the only possible method that's really speed-critical is the mark method, and we already extract those out into a separate (non-const) array for increased cache locality. Object methods need to be reinitialized after pdump, so we put them in separate functions such as face_objects_create(), extent_objects_create() and call them appropriately from emacs.c The only current object property (`memusage_stats_list') that objects can specify is a Lisp object and gets staticpro()ed so it only needs to be set during dump time, but because it references symbols that might not exist in a syms_of_() function, we initialize it in vars_of_(). There is also an object property (`num_extra_memusage_stats') that is automatically initialized based on `memusage_stats_list'; we do that in reinit_vars_of_alloc(), which is called after all vars_of_() functions are called. `disksaver' method was renamed `disksave' to correspond with the name normally given to the function (e.g. disksave_lstream()). (2) Generalize the memory-usage mechanism in `buffer-memory-usage', `window-memory-usage', `charset-memory-usage' into an object-type- specific mechanism called by a single function `object-memory-usage'. (Former function `object-memory-usage' renamed to `total-object-memory-usage'). Generalize the mechanism of different "slices" so that we can have different "classes" of memory described and different "slices" onto each class; `t' separates classes, `nil' separates slices. Currently we have three classes defined: the memory of an object itself, non-Lisp-object memory associated with the object (e.g. arrays or dynarrs stored as fields in the object), and Lisp-object memory associated with the object (other internal Lisp objects stored in the object). This isn't completely finished yet and we might need to further separate the "other internal Lisp objects" class into two classes. The memory-usage mechanism uses a `struct usage_stats' (renamed from `struct overhead_stats') to describe a malloc-view onto a set of allocated memory (listing how much was requested and various types of overhead) and a more general `struct generic_usage_stats' (with a `struct usage_stats' in it) to hold all statistics about object memory. `struct generic_usage_stats' contains an array of 32 Bytecounts, which are statistics of unspecified semantics. The intention is that individual types declare a corresponding struct (e.g. `struct window_stats') with the same structure but with specific fields in place of the array, corresponding to specific statistics. The number of such statistics is an object property computed from the list of tags (Lisp symbols describing the statistics) stored in `memusage_stats_list'. The idea here is to allow particular object types to customize the number and semantics of the statistics where completely avoiding consing. This doesn't matter so much yet, but the intention is to have the memory usage of all objects computed at the end of GC, at the same time as other statistics are currently computed. The values for all statistics for a single type would be added up to compute aggregate values for all objects of a specific type. To make this efficient, we can't allow any memory allocation at all. (3) Create some additional functions for creating lists that specify the elements directly as args rather than indirectly through an array: listn() (number of args given), listu() (list terminated by Qunbound). (4) Delete a bit of remaining unused C window_config stuff, also unused lrecord_type_popup_data.
author Ben Wing <ben@xemacs.org>
date Thu, 18 Mar 2010 10:50:06 -0500
parents 229bd619740a
children e374ea766cc1
line wrap: on
line source

/* New allocator for XEmacs.
   Copyright (C) 2005 Marcus Crestani.

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. */

#ifndef INCLUDED_mc_alloc_h_
#define INCLUDED_mc_alloc_h_

/*--- prototypes -------------------------------------------------------*/

BEGIN_C_DECLS

/* Set to 1 if memory becomes short. */
extern EMACS_INT memory_shortage;


/* Internal Allocator Functions: */

/* Initialize the allocator.  This has to be called prior to
   requesting memory. */
void init_mc_allocator (void);

/* Allocate a block of memory of given size and return the pointer to
   it. */
void *mc_alloc (size_t size);

/* Allocate a block of memory as an array with elemcount elements of
   given size and return the pointer to it.  Arrays contain several
   objects that are allocated in one consecutive block of memory with
   each element being a fully qualified object---that is, it has a
   Lisp object header and a mark bit.  Objects like hash tables and
   dynamic arrays use this function. */
void *mc_alloc_array (size_t size, EMACS_INT elemcount);

/* Modify the size of the memory block pointed to by ptr. Return the
   address of the new block of given size.  The content of the memory
   block will be unchanged to the minimum of the old and new sizes: if
   the new size is smaller, the overlaying data is cut off; if the new
   size is bigger, the newly allocated memory will be uninitialized.*/
void *mc_realloc (void *ptr, size_t size); 

/* Modify the size of the array pointed to by ptr. Return the address
   of the new array block with elemcount elements of given size.  The
   content of the memory block will be unchanged to the minimum of the
   old and new sizes: if the new size is smaller, the overlaying data
   is cut off; if the new size is bigger, the newly allocated memory
   will be uninitialized.*/
void *mc_realloc_array (void *ptr, size_t size, EMACS_INT elemcount);



/* Garbage collection related functions and macros: */

enum mark_bit_colors
{
  WHITE = 0,
  BLACK = 1,
  GREY = 2
};

/* Set the mark bit of the object pointed to by ptr to value.*/
void set_mark_bit (void *ptr, EMACS_INT value);

/* Return the mark bit of the object pointed to by ptr. */
EMACS_INT get_mark_bit (void *ptr);

/* mark bit macros */
/* Returns true if the mark bit of the object pointed to by ptr is set. */
#define MARKED_P(ptr) (get_mark_bit (ptr) != WHITE)

/* Marks the object pointed to by ptr (sets the mark bit to 1). */
#define MARK(ptr)     set_mark_bit (ptr, BLACK)

/* Unmarks the object pointed to by ptr (sets the mark bit to 0). */
#define UNMARK(ptr)   set_mark_bit (ptr, WHITE)

#define MARK_WHITE(ptr) set_mark_bit (ptr, WHITE)
#define MARK_GREY(ptr) set_mark_bit (ptr, GREY)
#define MARK_BLACK(ptr) set_mark_bit (ptr, BLACK)

#define MARKED_WHITE_P(ptr) (get_mark_bit (ptr) == WHITE)
#define MARKED_GREY_P(ptr) (get_mark_bit (ptr) == GREY)
#define MARKED_BLACK_P(ptr) (get_mark_bit (ptr) == BLACK)

/* The finalizer of every not marked object is called.  The macro
   MC_ALLOC_CALL_FINALIZER has to be defined and call the finalizer of
   the object.  Returns number of processed pages. */
EMACS_INT mc_finalize (void);

/* All not marked objects of the used heap are freed.  Returns number
   of processed pages. */
EMACS_INT mc_sweep (void);



/* Portable dumper related functions and macros: */

/* The finalizer for disksave of every object is called to shrink the
   dump image.  The macro MC_ALLOC_CALL_FINALIZER_FOR_DISKSAVE has to
   be defined and call the finalizer for disksave of the object.
   Returns number of processed pages. */
EMACS_INT mc_finalize_for_disksave (void);



/* Functions and macros related with allocation statistics: */

#ifdef MEMORY_USAGE_STATS
/* Returns the real size, including overhead, which is actually alloced
   for an object with given claimed_size. */
Bytecount mc_alloced_storage_size (Bytecount claimed_size,
				   struct usage_stats *stats);
#endif /* MEMORY_USAGE_STATS */


/* Incremental Garbage Collector / Write Barrier Support: */

/* Return the PAGESIZE the allocator uses.  Generally equals to the
   system's PAGESIZE. */
EMACS_INT mc_get_page_size (void);

/* Is the fault at ptr on a protected page? */
EMACS_INT fault_on_protected_page (void *ptr);

/* Remove protection (if there) of heap page of given page header ph.
   Returns number of processed pages. */
EMACS_INT protect_heap_pages (void);

/* Remove protection for all heap pages which are protected.  Returns
   number of processed pages. */
EMACS_INT unprotect_heap_pages (void);

/* Remove protection and mark page dirty. */
void unprotect_page_and_mark_dirty (void *ptr);

/* Repush all objects on dirty pages onto the mark stack. Return
   number of repushed objects. */
int repush_all_objects_on_page (void *ptr);

/* Mark black if object is currently grey. */
EMACS_INT maybe_mark_black (void *ptr);

/* Only for debugging---not used anywhere in the sources. */
EMACS_INT object_on_heap_p (void *ptr);

END_C_DECLS

#endif /* INCLUDED_mc_alloc_h_ */