]> code.delx.au - gnu-emacs/blobdiff - src/alloc.c
* nsterm.m (windowDidEnterFullScreen:): setPresentationOptions only
[gnu-emacs] / src / alloc.c
index 564faa18aa87fa14bbea1a65e13e52a6b62971cd..990390f5a364946065fd33a830ee6a945a7c71c5 100644 (file)
@@ -45,16 +45,16 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include <verify.h>
 
-#if (defined ENABLE_CHECKING &&               \
-     defined HAVE_VALGRIND_VALGRIND_H &&      \
-     !defined USE_VALGRIND)
+#if (defined ENABLE_CHECKING                   \
+     && defined HAVE_VALGRIND_VALGRIND_H       \
+     && !defined USE_VALGRIND)
 # define USE_VALGRIND 1
 #endif
 
 #if USE_VALGRIND
 #include <valgrind/valgrind.h>
 #include <valgrind/memcheck.h>
-static int valgrind_p;
+static bool valgrind_p;
 #endif
 
 /* GC_CHECK_MARKED_OBJECTS means do sanity checks on allocated objects.
@@ -981,7 +981,7 @@ struct ablocks
 #define ABLOCKS_BASE(abase) (abase)
 #else
 #define ABLOCKS_BASE(abase) \
-  (1 & (intptr_t) ABLOCKS_BUSY (abase) ? abase : ((void**)abase)[-1])
+  (1 & (intptr_t) ABLOCKS_BUSY (abase) ? abase : ((void **)abase)[-1])
 #endif
 
 /* The list of free ablock.   */
@@ -1036,7 +1036,7 @@ lisp_align_malloc (size_t nbytes, enum mem_type type)
 
       aligned = (base == abase);
       if (!aligned)
-       ((void**)abase)[-1] = base;
+       ((void **) abase)[-1] = base;
 
 #ifdef DOUG_LEA_MALLOC
       /* Back to a reasonable maximum of mmap'ed areas.  */
@@ -1973,7 +1973,6 @@ INIT must be an integer that represents a character.  */)
   (Lisp_Object length, Lisp_Object init)
 {
   register Lisp_Object val;
-  register unsigned char *p, *end;
   int c;
   EMACS_INT nbytes;
 
@@ -1985,46 +1984,50 @@ INIT must be an integer that represents a character.  */)
     {
       nbytes = XINT (length);
       val = make_uninit_string (nbytes);
-      p = SDATA (val);
-      end = p + SCHARS (val);
-      while (p != end)
-       *p++ = c;
+      memset (SDATA (val), c, nbytes);
+      SDATA (val)[nbytes] = 0;
     }
   else
     {
       unsigned char str[MAX_MULTIBYTE_LENGTH];
-      int len = CHAR_STRING (c, str);
+      ptrdiff_t len = CHAR_STRING (c, str);
       EMACS_INT string_len = XINT (length);
+      unsigned char *p, *beg, *end;
 
       if (string_len > STRING_BYTES_MAX / len)
        string_overflow ();
       nbytes = len * string_len;
       val = make_uninit_multibyte_string (string_len, nbytes);
-      p = SDATA (val);
-      end = p + nbytes;
-      while (p != end)
+      for (beg = SDATA (val), p = beg, end = beg + nbytes; p < end; p += len)
        {
-         memcpy (p, str, len);
-         p += len;
+         /* First time we just copy `str' to the data of `val'.  */
+         if (p == beg)
+           memcpy (p, str, len);
+         else
+           {
+             /* Next time we copy largest possible chunk from
+                initialized to uninitialized part of `val'.  */
+             len = min (p - beg, end - p);
+             memcpy (p, beg, len);
+           }
        }
+      *p = 0;
     }
 
-  *p = 0;
   return val;
 }
 
 verify (sizeof (size_t) * CHAR_BIT == BITS_PER_SIZE_T);
 verify ((BITS_PER_SIZE_T & (BITS_PER_SIZE_T - 1)) == 0);
 
-static
-ptrdiff_t
+static ptrdiff_t
 bool_vector_payload_bytes (ptrdiff_t nr_bits,
-                           ptrdiff_texact_needed_bytes_out)
+                           ptrdiff_t *exact_needed_bytes_out)
 {
   ptrdiff_t exact_needed_bytes;
   ptrdiff_t needed_bytes;
 
-  eassert_and_assume (nr_bits >= 0);
+  eassert (nr_bits >= 0);
 
   exact_needed_bytes = ROUNDUP ((size_t) nr_bits, CHAR_BIT) / CHAR_BIT;
   needed_bytes = ROUNDUP ((size_t) nr_bits, BITS_PER_SIZE_T) / CHAR_BIT;
@@ -2061,14 +2064,14 @@ LENGTH must be a number.  INIT matters only in whether it is t or nil.  */)
   total_payload_bytes = bool_vector_payload_bytes
     (XFASTINT (length), &exact_payload_bytes);
 
-  eassert_and_assume (exact_payload_bytes <= total_payload_bytes);
-  eassert_and_assume (0 <= exact_payload_bytes);
+  eassert (exact_payload_bytes <= total_payload_bytes);
+  eassert (0 <= exact_payload_bytes);
 
   needed_elements = ROUNDUP ((size_t) ((bool_header_size - header_size)
                                        + total_payload_bytes),
                              word_size) / word_size;
 
-  p = (struct Lisp_Bool_Vector) allocate_vector (needed_elements);
+  p = (struct Lisp_Bool_Vector *) allocate_vector (needed_elements);
   XSETVECTOR (val, p);
   XSETPVECTYPESIZE (XVECTOR (val), PVEC_BOOL_VECTOR, 0, 0);
 
@@ -2617,9 +2620,9 @@ verify ((VECTOR_BLOCK_SIZE % roundup_size) == 0);
 verify (VECTOR_BLOCK_SIZE <= (1 << PSEUDOVECTOR_SIZE_BITS));
 
 /* Round up X to nearest mult-of-ROUNDUP_SIZE --- use at compile time.  */
-#define vroundup_ct(x) ROUNDUP((size_t)(x), roundup_size)
+#define vroundup_ct(x) ROUNDUP ((size_t) (x), roundup_size)
 /* Round up X to nearest mult-of-ROUNDUP_SIZE --- use at runtime.  */
-#define vroundup(x) (assume((x) >= 0), vroundup_ct(x))
+#define vroundup(x) (assume ((x) >= 0), vroundup_ct (x))
 
 /* Rounding helps to maintain alignment constraints if USE_LSB_TAG.  */
 
@@ -2648,22 +2651,6 @@ verify (VECTOR_BLOCK_SIZE <= (1 << PSEUDOVECTOR_SIZE_BITS));
 
 #define VINDEX(nbytes) (((nbytes) - VBLOCK_BYTES_MIN) / roundup_size)
 
-/* Get and set the next field in block-allocated vectorlike objects on
-   the free list.  Doing it this way respects C's aliasing rules.
-   We could instead make 'contents' a union, but that would mean
-   changes everywhere that the code uses 'contents'.  */
-static struct Lisp_Vector *
-next_in_free_list (struct Lisp_Vector *v)
-{
-  intptr_t i = XLI (v->contents[0]);
-  return (struct Lisp_Vector *) i;
-}
-static void
-set_next_in_free_list (struct Lisp_Vector *v, struct Lisp_Vector *next)
-{
-  v->contents[0] = XIL ((intptr_t) next);
-}
-
 /* Common shortcut to setup vector on a free list.  */
 
 #define SETUP_ON_FREE_LIST(v, nbytes, tmp)             \
@@ -2673,7 +2660,7 @@ set_next_in_free_list (struct Lisp_Vector *v, struct Lisp_Vector *next)
     eassert ((nbytes) % roundup_size == 0);            \
     (tmp) = VINDEX (nbytes);                           \
     eassert ((tmp) < VECTOR_MAX_FREE_LIST_INDEX);      \
-    set_next_in_free_list (v, vector_free_lists[tmp]); \
+    v->u.next = vector_free_lists[tmp];                        \
     vector_free_lists[tmp] = (v);                      \
     total_free_vector_slots += (nbytes) / word_size;   \
   } while (0)
@@ -2770,7 +2757,7 @@ allocate_vector_from_block (size_t nbytes)
   if (vector_free_lists[index])
     {
       vector = vector_free_lists[index];
-      vector_free_lists[index] = next_in_free_list (vector);
+      vector_free_lists[index] = vector->u.next;
       total_free_vector_slots -= nbytes / word_size;
       return vector;
     }
@@ -2784,7 +2771,7 @@ allocate_vector_from_block (size_t nbytes)
       {
        /* This vector is larger than requested.  */
        vector = vector_free_lists[index];
-       vector_free_lists[index] = next_in_free_list (vector);
+       vector_free_lists[index] = vector->u.next;
        total_free_vector_slots -= nbytes / word_size;
 
        /* Excess bytes are used for the smaller vector,
@@ -2833,7 +2820,7 @@ vector_nbytes (struct Lisp_Vector *v)
           ptrdiff_t payload_bytes =
               bool_vector_payload_bytes (bv->size, NULL);
 
-          eassert_and_assume (payload_bytes >= 0);
+          eassert (payload_bytes >= 0);
           size = bool_header_size + ROUNDUP (payload_bytes, word_size);
         }
       else
@@ -2906,7 +2893,7 @@ sweep_vectors (void)
                free_this_block = 1;
              else
                {
-                 int tmp;
+                 size_t tmp;
                  SETUP_ON_FREE_LIST (vector, total_bytes, tmp);
                }
            }
@@ -2982,7 +2969,7 @@ allocate_vectorlike (ptrdiff_t len)
       else
        {
          struct large_vector *lv
-           = lisp_malloc ((offsetof (struct large_vector, v.contents)
+           = lisp_malloc ((offsetof (struct large_vector, v.u.contents)
                            + len * word_size),
                           MEM_TYPE_VECTORLIKE);
          lv->next.vector = large_vectors;
@@ -3036,7 +3023,7 @@ allocate_pseudovector (int memlen, int lisplen, enum pvec_type tag)
 
   /* Only the first lisplen slots will be traced normally by the GC.  */
   for (i = 0; i < lisplen; ++i)
-    v->contents[i] = Qnil;
+    v->u.contents[i] = Qnil;
 
   XSETPVECTYPESIZE (v, tag, lisplen, memlen - lisplen);
   return v;
@@ -3124,7 +3111,7 @@ See also the function `vector'.  */)
   p = allocate_vector (XFASTINT (length));
   sizei = XFASTINT (length);
   for (i = 0; i < sizei; i++)
-    p->contents[i] = init;
+    p->u.contents[i] = init;
 
   XSETVECTOR (vector, p);
   return vector;
@@ -3142,21 +3129,23 @@ usage: (vector &rest OBJECTS)  */)
   register struct Lisp_Vector *p = XVECTOR (val);
 
   for (i = 0; i < nargs; i++)
-    p->contents[i] = args[i];
+    p->u.contents[i] = args[i];
   return val;
 }
 
 void
 make_byte_code (struct Lisp_Vector *v)
 {
-  if (v->header.size > 1 && STRINGP (v->contents[1])
-      && STRING_MULTIBYTE (v->contents[1]))
+  /* Don't allow the global zero_vector to become a byte code object. */
+  eassert(0 < v->header.size);
+  if (v->header.size > 1 && STRINGP (v->u.contents[1])
+      && STRING_MULTIBYTE (v->u.contents[1]))
     /* BYTECODE-STRING must have been produced by Emacs 20.2 or the
        earlier because they produced a raw 8-bit string for byte-code
        and now such a byte-code string is loaded as multibyte while
        raw 8-bit characters converted to multibyte form.  Thus, now we
        must convert them back to the original unibyte form.  */
-    v->contents[1] = Fstring_as_unibyte (v->contents[1]);
+    v->u.contents[1] = Fstring_as_unibyte (v->u.contents[1]);
   XSETPVECTYPE (v, PVEC_COMPILED);
 }
 
@@ -3191,7 +3180,7 @@ usage: (make-byte-code ARGLIST BYTE-CODE CONSTANTS DEPTH &optional DOCSTRING INT
      to be setcar'd).  */
 
   for (i = 0; i < nargs; i++)
-    p->contents[i] = args[i];
+    p->u.contents[i] = args[i];
   make_byte_code (p);
   XSETCOMPILED (val, p);
   return val;
@@ -4835,7 +4824,7 @@ valid_pointer_p (void *p)
 
   if (emacs_pipe (fd) == 0)
     {
-      bool valid = emacs_write (fd[1], (char *) p, 16) == 16;
+      bool valid = emacs_write (fd[1], p, 16) == 16;
       emacs_close (fd[1]);
       emacs_close (fd[0]);
       return valid;
@@ -5184,7 +5173,7 @@ Does not copy symbols.  Copies strings without text properties.  */)
        size &= PSEUDOVECTOR_SIZE_MASK;
       vec = XVECTOR (make_pure_vector (size));
       for (i = 0; i < size; i++)
-       vec->contents[i] = Fpurecopy (AREF (obj, i));
+       vec->u.contents[i] = Fpurecopy (AREF (obj, i));
       if (COMPILEDP (obj))
        {
          XSETPVECTYPE (vec, PVEC_COMPILED);
@@ -5385,23 +5374,15 @@ See Info node `(elisp)Garbage Collection'.  */)
        mark_object (tail->var[i]);
   }
   mark_byte_stack ();
+#endif
   {
-    struct catchtag *catch;
     struct handler *handler;
-
-  for (catch = catchlist; catch; catch = catch->next)
-    {
-      mark_object (catch->tag);
-      mark_object (catch->val);
-    }
-  for (handler = handlerlist; handler; handler = handler->next)
-    {
-      mark_object (handler->handler);
-      mark_object (handler->var);
-    }
+    for (handler = handlerlist; handler; handler = handler->next)
+      {
+       mark_object (handler->tag_or_ch);
+       mark_object (handler->val);
+      }
   }
-#endif
-
 #ifdef HAVE_WINDOW_SYSTEM
   mark_fringe_data ();
 #endif
@@ -5675,7 +5656,7 @@ mark_vectorlike (struct Lisp_Vector *ptr)
      The distinction is used e.g. by Lisp_Process which places extra
      non-Lisp_Object fields at the end of the structure...  */
   for (i = 0; i < size; i++) /* ...and then mark its elements.  */
-    mark_object (ptr->contents[i]);
+    mark_object (ptr->u.contents[i]);
 }
 
 /* Like mark_vectorlike but optimized for char-tables (and
@@ -5692,7 +5673,7 @@ mark_char_table (struct Lisp_Vector *ptr)
   VECTOR_MARK (ptr);
   for (i = 0; i < size; i++)
     {
-      Lisp_Object val = ptr->contents[i];
+      Lisp_Object val = ptr->u.contents[i];
 
       if (INTEGERP (val) || (SYMBOLP (val) && XSYMBOL (val)->gcmarkbit))
        continue;
@@ -5897,10 +5878,10 @@ mark_object (Lisp_Object arg)
              VECTOR_MARK (ptr);
              for (i = 0; i < size; i++)
                if (i != COMPILED_CONSTANTS)
-                 mark_object (ptr->contents[i]);
+                 mark_object (ptr->u.contents[i]);
              if (size > COMPILED_CONSTANTS)
                {
-                 obj = ptr->contents[COMPILED_CONSTANTS];
+                 obj = ptr->u.contents[COMPILED_CONSTANTS];
                  goto loop;
                }
            }
@@ -6667,7 +6648,7 @@ init_alloc (void)
   gcs_done = 0;
 
 #if USE_VALGRIND
-  valgrind_p = RUNNING_ON_VALGRIND;
+  valgrind_p = RUNNING_ON_VALGRIND != 0;
 #endif
 }