]> code.delx.au - gnu-emacs/blobdiff - src/ralloc.c
* custom.texi (Init Examples): Add example of changing load-path.
[gnu-emacs] / src / ralloc.c
index 1c988283dbc787ba43b0093efa240ba6e5cb5ced..f5ebb8449ca57374d50f399803f9475807c96792 100644 (file)
@@ -1,6 +1,6 @@
 /* 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  Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
@@ -177,9 +177,9 @@ static heap_ptr first_heap, last_heap;
    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
 {
@@ -402,6 +402,11 @@ find_bloc (ptr)
 
   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;
 
@@ -939,8 +944,8 @@ r_alloc_sbrk (size)
    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.  */
@@ -981,7 +986,7 @@ r_alloc_free (ptr)
 
   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;
@@ -996,7 +1001,7 @@ r_alloc_free (ptr)
    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.
 
@@ -1025,7 +1030,7 @@ r_re_alloc (ptr, size)
 
   bloc = find_bloc (ptr);
   if (bloc == NIL_BLOC)
-    abort ();
+    abort (); /* Already freed? PTR not originally used to allocate?  */
 
   if (size < bloc->size)
     {
@@ -1223,6 +1228,34 @@ r_alloc_check ()
 
 #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
 /***********************************************************************