emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emacs-diffs] trunk r115139: Always allocate at least one bits_word per


From: Paul Eggert
Subject: [Emacs-diffs] trunk r115139: Always allocate at least one bits_word per bool vector.
Date: Mon, 18 Nov 2013 18:37:29 +0000
User-agent: Bazaar (2.6b2)

------------------------------------------------------------
revno: 115139
revision-id: address@hidden
parent: address@hidden
committer: Paul Eggert <address@hidden>
branch nick: trunk
timestamp: Mon 2013-11-18 10:37:25 -0800
message:
  Always allocate at least one bits_word per bool vector.
  
  See Daniel Colascione in:
  http://lists.gnu.org/archive/html/emacs-devel/2013-11/msg00518.html
  * alloc.c (make_uninit_bool_vector): Always allocate at least one word.
  * data.c (bool_vector_binop_driver): Rely on this.  Tune.
  * lisp.h (struct Lisp_Bool_vector): Document this.
modified:
  src/ChangeLog                  changelog-20091113204419-o5vbwnq5f7feedwu-1438
  src/alloc.c                    alloc.c-20091113204419-o5vbwnq5f7feedwu-252
  src/data.c                     data.c-20091113204419-o5vbwnq5f7feedwu-251
  src/lisp.h                     lisp.h-20091113204419-o5vbwnq5f7feedwu-253
=== modified file 'src/ChangeLog'
--- a/src/ChangeLog     2013-11-18 16:29:49 +0000
+++ b/src/ChangeLog     2013-11-18 18:37:25 +0000
@@ -1,3 +1,12 @@
+2013-11-18  Paul Eggert  <address@hidden>
+
+       Always allocate at least one bits_word per bool vector.
+       See Daniel Colascione in:
+       http://lists.gnu.org/archive/html/emacs-devel/2013-11/msg00518.html
+       * alloc.c (make_uninit_bool_vector): Always allocate at least one word.
+       * data.c (bool_vector_binop_driver): Rely on this.  Tune.
+       * lisp.h (struct Lisp_Bool_vector): Document this.
+
 2013-11-18  Eli Zaretskii  <address@hidden>
 
        * insdel.c (invalidate_buffer_caches): New function, consolidated

=== modified file 'src/alloc.c'
--- a/src/alloc.c       2013-11-14 02:39:28 +0000
+++ b/src/alloc.c       2013-11-18 18:37:25 +0000
@@ -2066,20 +2066,21 @@
 make_uninit_bool_vector (EMACS_INT nbits)
 {
   Lisp_Object val;
-  struct Lisp_Bool_Vector *p;
-  EMACS_INT word_bytes, needed_elements;
-  word_bytes = bool_vector_words (nbits) * sizeof (bits_word);
-  needed_elements = ((bool_header_size - header_size + word_bytes
-                     + word_size - 1)
-                    / word_size);
-  p = (struct Lisp_Bool_Vector *) allocate_vector (needed_elements);
+  EMACS_INT words0 = bool_vector_words (nbits);
+  EMACS_INT words = words0 + !words0;  /* Allocate at least one word.  */
+  EMACS_INT word_bytes = words * sizeof (bits_word);
+  EMACS_INT needed_elements = ((bool_header_size - header_size + word_bytes
+                               + word_size - 1)
+                              / word_size);
+  struct Lisp_Bool_Vector *p
+    = (struct Lisp_Bool_Vector *) allocate_vector (needed_elements);
   XSETVECTOR (val, p);
   XSETPVECTYPESIZE (XVECTOR (val), PVEC_BOOL_VECTOR, 0, 0);
   p->size = nbits;
 
-  /* Clear padding at the end.  */
-  if (nbits)
-    p->data[bool_vector_words (nbits) - 1] = 0;
+  /* Clear padding at the end.  If NBITS != 0 this initializes more
+     than it needs to, but that's OK.  */
+  p->data[words - 1] = 0;
 
   return val;
 }

=== modified file 'src/data.c'
--- a/src/data.c        2013-11-15 18:01:04 +0000
+++ b/src/data.c        2013-11-18 18:37:25 +0000
@@ -3025,9 +3025,7 @@
 {
   EMACS_INT nr_bits;
   bits_word *adata, *bdata, *cdata;
-  ptrdiff_t i;
-  bool changed = 0;
-  bits_word mword;
+  ptrdiff_t i = 0;
   ptrdiff_t nr_words;
 
   CHECK_BOOL_VECTOR (op1);
@@ -3037,45 +3035,82 @@
   if (bool_vector_size (op2) != nr_bits)
     wrong_length_argument (op1, op2, dest);
 
+  nr_words = bool_vector_words (nr_bits);
+  bdata = bool_vector_data (op1);
+  cdata = bool_vector_data (op2);
+
   if (NILP (dest))
     {
       dest = make_uninit_bool_vector (nr_bits);
-      changed = 1;
+      adata = bool_vector_data (dest);
     }
   else
     {
       CHECK_BOOL_VECTOR (dest);
+      adata = bool_vector_data (dest);
       if (bool_vector_size (dest) != nr_bits)
        wrong_length_argument (op1, op2, dest);
+
+      switch (op)
+       {
+       case bool_vector_exclusive_or:
+         while (adata[i] == (bdata[i] ^ cdata[i]))
+           if (! (++i < nr_words))
+             return Qnil;
+         break;
+
+       case bool_vector_subsetp:
+       case bool_vector_union:
+         while (adata[i] == (bdata[i] | cdata[i]))
+           if (! (++i < nr_words))
+             return Qnil;
+         break;
+
+       case bool_vector_intersection:
+         while (adata[i] == (bdata[i] & cdata[i]))
+           if (! (++i < nr_words))
+             return Qnil;
+         break;
+
+       case bool_vector_set_difference:
+         while (adata[i] == (bdata[i] &~ cdata[i]))
+           if (! (++i < nr_words))
+             return Qnil;
+         break;
+       }
     }
 
-  nr_words = bool_vector_words (nr_bits);
-
-  adata = bool_vector_data (dest);
-  bdata = bool_vector_data (op1);
-  cdata = bool_vector_data (op2);
-
-  for (i = 0; i < nr_words; i++)
+  switch (op)
     {
-      if (op == bool_vector_exclusive_or)
-        mword = bdata[i] ^ cdata[i];
-      else if (op == bool_vector_union || op == bool_vector_subsetp)
-        mword = bdata[i] | cdata[i];
-      else if (op == bool_vector_intersection)
-        mword = bdata[i] & cdata[i];
-      else if (op == bool_vector_set_difference)
-        mword = bdata[i] &~ cdata[i];
-      else
-        abort ();
-
-      if (! changed)
-       changed = adata[i] != mword;
-
-      if (op != bool_vector_subsetp)
-        adata[i] = mword;
+    case bool_vector_exclusive_or:
+      do
+       adata[i] = bdata[i] ^ cdata[i];
+      while (++i < nr_words);
+      break;
+
+    case bool_vector_subsetp:
+      break;
+
+    case bool_vector_union:
+      do
+       adata[i] = bdata[i] | cdata[i];
+      while (++i < nr_words);
+      break;
+
+    case bool_vector_intersection:
+      do
+       adata[i] = bdata[i] & cdata[i];
+      while (++i < nr_words);
+      break;
+
+    case bool_vector_set_difference:
+      do
+       adata[i] = bdata[i] &~ cdata[i];
+      while (++i < nr_words);
+      break;
     }
 
-  return changed ? dest : Qnil;
+  return dest;
 }
 
 /* PRECONDITION must be true.  Return VALUE.  This odd construction
@@ -3314,7 +3349,10 @@
       mword = bits_word_to_host_endian (adata[pos]);
       mword ^= twiddle;
       mword >>= offset;
+
+      /* Do not count the pad bits.  */
       mword |= (bits_word) 1 << (BITS_PER_BITS_WORD - offset);
+
       count = count_trailing_zero_bits (mword);
       pos++;
       if (count + offset < BITS_PER_BITS_WORD)

=== modified file 'src/lisp.h'
--- a/src/lisp.h        2013-11-18 16:29:49 +0000
+++ b/src/lisp.h        2013-11-18 18:37:25 +0000
@@ -1213,6 +1213,7 @@
     /* This is the size in bits.  */
     EMACS_INT size;
     /* The actual bits, packed into bytes.
+       Zeros fill out the last word as needed; there's always at least one 
word.
        The bits are in little-endian order in the bytes, and
        the bytes are in little-endian order in the words.  */
     bits_word data[FLEXIBLE_ARRAY_MEMBER];


reply via email to

[Prev in Thread] Current Thread [Next in Thread]