(pure_alloc): Corrected last change; now align the
[bpt/emacs.git] / src / alloc.c
index 29cb1de..f19c232 100644 (file)
@@ -1,5 +1,5 @@
 /* Storage allocation and gc for GNU Emacs Lisp interpreter.
-   Copyright (C) 1985, 86, 88, 93, 94, 95, 97, 98, 1999, 2000, 2001, 2002
+   Copyright (C) 1985, 86, 88, 93, 94, 95, 97, 98, 1999, 2000, 2001, 2002, 2003
       Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
@@ -341,7 +341,12 @@ int dont_register_blocks;
 
 struct mem_node
 {
-  struct mem_node *left, *right, *parent;
+  /* Children of this node.  These pointers are never NULL.  When there
+     is no child, the value is MEM_NIL, which points to a dummy node.  */
+  struct mem_node *left, *right;
+
+  /* The parent of this node.  In the root node, this is NULL.  */
+  struct mem_node *parent;
 
   /* Start and end of allocated region.  */
   void *start, *end;
@@ -2626,6 +2631,26 @@ allocate_misc ()
   return val;
 }
 
+/* Return a Lisp_Misc_Save_Value object containing POINTER and
+   INTEGER.  This is used to package C values to call record_unwind_protect.
+   The unwind function can get the C values back using XSAVE_VALUE.  */
+
+Lisp_Object
+make_save_value (pointer, integer)
+     void *pointer;
+     int integer;
+{
+  register Lisp_Object val;
+  register struct Lisp_Save_Value *p;
+
+  val = allocate_misc ();
+  XMISCTYPE (val) = Lisp_Misc_Save_Value;
+  p = XSAVE_VALUE (val);
+  p->pointer = pointer;
+  p->integer = integer;
+  return val;
+}
+
 DEFUN ("make-marker", Fmake_marker, Smake_marker, 0, 0, 0,
        doc: /* Return a newly allocated marker which does not point at any place.  */)
      ()
@@ -3808,34 +3833,42 @@ pure_alloc (size, type)
 {
   size_t nbytes;
   POINTER_TYPE *result;
-  char *beg = purebeg;
+  char *beg;
+
+ again:
+  beg = purebeg;
+  result = (POINTER_TYPE *) (beg + pure_bytes_used);
+  nbytes = ALIGN (size, sizeof (EMACS_INT));
 
   /* Give Lisp_Floats an extra alignment.  */
   if (type == Lisp_Float)
     {
+      POINTER_TYPE *orig = result;
       size_t alignment;
 #if defined __GNUC__ && __GNUC__ >= 2
       alignment = __alignof (struct Lisp_Float);
 #else
       alignment = sizeof (struct Lisp_Float);
 #endif
-      pure_bytes_used = ALIGN (pure_bytes_used, alignment);
+      /* Make sure result is correctly aligned for a
+        Lisp_Float, which might need stricter alignment than
+        EMACS_INT.  */
+      result = (POINTER_TYPE *)ALIGN((EMACS_UINT)result, alignment);
+      nbytes += (char *)result - (char *)orig;
     }
     
-  nbytes = ALIGN (size, sizeof (EMACS_INT));
-  
   if (pure_bytes_used + nbytes > pure_size)
     {
       /* Don't allocate a large amount here,
         because it might get mmap'd and then its address
         might not be usable.  */
-      beg = purebeg = (char *) xmalloc (10000);
+      purebeg = (char *) xmalloc (10000);
       pure_size = 10000;
       pure_bytes_used_before_overflow += pure_bytes_used;
       pure_bytes_used = 0;
+      goto again;
     }
 
-  result = (POINTER_TYPE *) (beg + pure_bytes_used);
   pure_bytes_used += nbytes;
   return result;
 }