/* Block-relocating memory allocator.
Copyright (C) 1993, 1995, 2000, 2001, 2002, 2003, 2004,
- 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+ 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
This file is part of GNU Emacs.
#ifdef emacs
#include <config.h>
+#include <setjmp.h>
#include "lisp.h" /* Needed for VALBITS. */
#include "blockinput.h"
b->data + b->size == b->next->data.
An element with variable==NIL denotes a freed block, which has not yet
- been collected. They may only appear while r_alloc_freeze > 0, and will be
- freed when the arena is thawed. Currently, these blocs are not reusable,
- while the arena is frozen. Very inefficient. */
+ been collected. They may only appear while r_alloc_freeze_level > 0,
+ and will be freed when the arena is thawed. Currently, these blocs are
+ not reusable, while the arena is frozen. Very inefficient. */
typedef struct bp
{
while (p != NIL_BLOC)
{
+ /* Consistency check. Don't return inconsistent blocs.
+ Don't abort here, as callers might be expecting this, but
+ callers that always expect a bloc to be returned should abort
+ if one isn't to avoid a memory corruption bug that is
+ difficult to track down. */
if (p->variable == ptr && p->data == *ptr)
return p;
which will use the data area.
The allocation of 0 bytes is valid.
- In case r_alloc_freeze is set, a best fit of unused blocs could be done
- before allocating a new area. Not yet done.
+ In case r_alloc_freeze_level is set, a best fit of unused blocs could be
+ done before allocating a new area. Not yet done.
If we can't allocate the necessary memory, set *PTR to zero, and
return zero. */
dead_bloc = find_bloc (ptr);
if (dead_bloc == NIL_BLOC)
- abort ();
+ abort (); /* Double free? PTR not originally used to allocate? */
free_bloc (dead_bloc);
*ptr = 0;
SIZE is less than or equal to the current bloc size, in which case
do nothing.
- In case r_alloc_freeze is set, a new bloc is allocated, and the
+ In case r_alloc_freeze_level is set, a new bloc is allocated, and the
memory copied to it. Not very efficient. We could traverse the
bloc_list for a best fit of free blocs first.
bloc = find_bloc (ptr);
if (bloc == NIL_BLOC)
- abort ();
+ abort (); /* Already freed? PTR not originally used to allocate? */
if (size < bloc->size)
{
#endif /* DEBUG */
+/* Update the internal record of which variable points to some data to NEW.
+ Used by buffer-swap-text in Emacs to restore consistency after it
+ swaps the buffer text between two buffer objects. The OLD pointer
+ is checked to ensure that memory corruption does not occur due to
+ misuse. */
+void
+r_alloc_reset_variable (old, new)
+ POINTER *old, *new;
+{
+ bloc_ptr bloc = first_bloc;
+
+ /* Find the bloc that corresponds to the data pointed to by pointer.
+ find_bloc cannot be used, as it has internal consistency checks
+ which fail when the variable needs reseting. */
+ while (bloc != NIL_BLOC)
+ {
+ if (bloc->data == *new)
+ break;
+
+ bloc = bloc->next;
+ }
+
+ if (bloc == NIL_BLOC || bloc->variable != old)
+ abort (); /* Already freed? OLD not originally used to allocate? */
+
+ /* Update variable to point to the new location. */
+ bloc->variable = new;
+}
\f
/***********************************************************************