]> code.delx.au - gnu-emacs/blobdiff - src/alloc.c
Rework C source files to avoid ^(
[gnu-emacs] / src / alloc.c
index 8816411bcafe8e0e98ed95e328edd2a599d0ca88..b5be0f6e69c543a12b1732c65d10c6a406071825 100644 (file)
@@ -7,8 +7,8 @@ This file is part of GNU Emacs.
 
 GNU Emacs 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 3 of the License, or
-(at your option) any later version.
+the Free Software Foundation, either version 3 of the License, or (at
+your option) any later version.
 
 GNU Emacs is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -1375,12 +1375,25 @@ lisp_align_free (void *block)
 static bool
 laligned (void *p, size_t size)
 {
-  return (MALLOC_IS_GC_ALIGNED || size % GCALIGNMENT != 0
-         || (intptr_t) p % GCALIGNMENT == 0);
+  return (MALLOC_IS_GC_ALIGNED || (intptr_t) p % GCALIGNMENT == 0
+         || size % GCALIGNMENT != 0);
 }
 
 /* Like malloc and realloc except that if SIZE is Lisp-aligned, make
-   sure the result is too.  */
+   sure the result is too, if necessary by reallocating (typically
+   with larger and larger sizes) until the allocator returns a
+   Lisp-aligned pointer.  Code that needs to allocate C heap memory
+   for a Lisp object should use one of these functions to obtain a
+   pointer P; that way, if T is an enum Lisp_Type value and L ==
+   make_lisp_ptr (P, T), then XPNTR (L) == P and XTYPE (L) == T.
+
+   On typical modern platforms these functions' loops do not iterate.
+   On now-rare (and perhaps nonexistent) platforms, the loops in
+   theory could repeat forever.  If an infinite loop is possible on a
+   platform, a build would surely loop and the builder can then send
+   us a bug report.  Adding a counter to try to detect any such loop
+   would complicate the code (and possibly introduce bugs, in code
+   that's never really exercised) for little benefit.  */
 
 static void *
 lmalloc (size_t size)
@@ -1397,6 +1410,9 @@ lmalloc (size_t size)
       if (laligned (p, size))
        break;
       free (p);
+      size_t bigger;
+      if (! INT_ADD_WRAPV (size, GCALIGNMENT, &bigger))
+       size = bigger;
     }
 
   eassert ((intptr_t) p % GCALIGNMENT == 0);
@@ -1406,9 +1422,15 @@ lmalloc (size_t size)
 static void *
 lrealloc (void *p, size_t size)
 {
-  do
-    p = realloc (p, size);
-  while (! laligned (p, size));
+  while (true)
+    {
+      p = realloc (p, size);
+      if (laligned (p, size))
+       break;
+      size_t bigger;
+      if (! INT_ADD_WRAPV (size, GCALIGNMENT, &bigger))
+       size = bigger;
+    }
 
   eassert ((intptr_t) p % GCALIGNMENT == 0);
   return p;