]> code.delx.au - gnu-emacs/blobdiff - src/alloc.c
* chartab.c (char_table_translate): Move to...
[gnu-emacs] / src / alloc.c
index 98a35853e02ef7fa55444ca70ebf8cb9a307a321..6eb2e756ed110bc760f55384548830a4aa882460 100644 (file)
@@ -2974,9 +2974,16 @@ cleanup_vector (struct Lisp_Vector *vector)
       && ((vector->header.size & PSEUDOVECTOR_SIZE_MASK)
          == FONT_OBJECT_MAX))
     {
-      /* Attempt to catch subtle bugs like Bug#16140.  */
-      eassert (valid_font_driver (((struct font *) vector)->driver));
-      ((struct font *) vector)->driver->close ((struct font *) vector);
+      struct font_driver *drv = ((struct font *) vector)->driver;
+
+      /* The font driver might sometimes be NULL, e.g. if Emacs was
+        interrupted before it had time to set it up.  */
+      if (drv)
+       {
+         /* Attempt to catch subtle bugs like Bug#16140.  */
+         eassert (valid_font_driver (drv));
+         drv->close ((struct font *) vector);
+       }
     }
 }
 
@@ -4556,7 +4563,7 @@ maybe_lisp_pointer (void *p)
 {
   return !((intptr_t) p % (USE_LSB_TAG ? GCALIGNMENT : 2));
 }
-  
+
 /* If P points to Lisp data, mark that as live if it isn't already
    marked.  */
 
@@ -5023,7 +5030,7 @@ relocatable_string_data_p (const char *str)
 {
   if (PURE_POINTER_P (str))
     return 0;
-#if GC_MARK_STACK  
+#if GC_MARK_STACK
   if (str)
     {
       struct sdata *sdata
@@ -5037,7 +5044,7 @@ relocatable_string_data_p (const char *str)
                && (const char *) sdata->string->data == str);
     }
   return 0;
-#endif /* GC_MARK_STACK */  
+#endif /* GC_MARK_STACK */
   return -1;
 }
 
@@ -5882,9 +5889,9 @@ See Info node `(elisp)Garbage Collection'.  */)
 #elif (GC_MARK_STACK == GC_USE_GCPROS_AS_BEFORE)
   /* Old GCPROs-based method without stack marking.  */
   return garbage_collect_1 (NULL);
-#else  
+#else
   emacs_abort ();
-#endif /* GC_MARK_STACK */  
+#endif /* GC_MARK_STACK */
 }
 
 /* Mark Lisp objects in glyph matrix MATRIX.  Currently the
@@ -5951,14 +5958,15 @@ mark_vectorlike (struct Lisp_Vector *ptr)
    symbols.  */
 
 static void
-mark_char_table (struct Lisp_Vector *ptr)
+mark_char_table (struct Lisp_Vector *ptr, enum pvec_type pvectype)
 {
   int size = ptr->header.size & PSEUDOVECTOR_SIZE_MASK;
-  int i;
+  /* Consult the Lisp_Sub_Char_Table layout before changing this.  */
+  int i, idx = (pvectype == PVEC_SUB_CHAR_TABLE ? SUB_CHAR_TABLE_OFFSET : 0);
 
   eassert (!VECTOR_MARKED_P (ptr));
   VECTOR_MARK (ptr);
-  for (i = 0; i < size; i++)
+  for (i = idx; i < size; i++)
     {
       Lisp_Object val = ptr->contents[i];
 
@@ -5967,7 +5975,7 @@ mark_char_table (struct Lisp_Vector *ptr)
       if (SUB_CHAR_TABLE_P (val))
        {
          if (! VECTOR_MARKED_P (XVECTOR (val)))
-           mark_char_table (XVECTOR (val));
+           mark_char_table (XVECTOR (val), PVEC_SUB_CHAR_TABLE);
        }
       else
        mark_object (val);
@@ -5979,7 +5987,7 @@ static Lisp_Object
 mark_compiled (struct Lisp_Vector *ptr)
 {
   int i, size = ptr->header.size & PSEUDOVECTOR_SIZE_MASK;
-  
+
   VECTOR_MARK (ptr);
   for (i = 0; i < size; i++)
     if (i != COMPILED_CONSTANTS)
@@ -6057,7 +6065,7 @@ mark_localized_symbol (struct Lisp_Symbol *ptr)
   struct Lisp_Buffer_Local_Value *blv = SYMBOL_BLV (ptr);
   Lisp_Object where = blv->where;
   /* If the value is set up for a killed buffer or deleted
-     frame, restore it's global binding.  If the value is
+     frame, restore its global binding.  If the value is
      forwarded to a C variable, either it's not a Lisp_Object
      var, or it's staticpro'd already.  */
   if ((BUFFERP (where) && !BUFFER_LIVE_P (XBUFFER (where)))
@@ -6068,6 +6076,30 @@ mark_localized_symbol (struct Lisp_Symbol *ptr)
   mark_object (blv->defcell);
 }
 
+NO_INLINE /* To reduce stack depth in mark_object.  */
+static void
+mark_save_value (struct Lisp_Save_Value *ptr)
+{
+  /* If `save_type' is zero, `data[0].pointer' is the address
+     of a memory area containing `data[1].integer' potential
+     Lisp_Objects.  */
+  if (GC_MARK_STACK && ptr->save_type == SAVE_TYPE_MEMORY)
+    {
+      Lisp_Object *p = ptr->data[0].pointer;
+      ptrdiff_t nelt;
+      for (nelt = ptr->data[1].integer; nelt > 0; nelt--, p++)
+       mark_maybe_object (*p);
+    }
+  else
+    {
+      /* Find Lisp_Objects in `data[N]' slots and mark them.  */
+      int i;
+      for (i = 0; i < SAVE_VALUE_SLOTS; i++)
+       if (save_type (ptr, i) == SAVE_OBJECT)
+         mark_object (ptr->data[i].object);
+    }
+}
+
 /* Remove killed buffers or items whose car is a killed buffer from
    LIST, and mark other items.  Return changed LIST, which is marked.  */
 
@@ -6095,7 +6127,13 @@ mark_discard_killed_buffers (Lisp_Object list)
   return list;
 }
 
-/* Determine type of generic Lisp_Object and mark it accordingly.  */
+/* Determine type of generic Lisp_Object and mark it accordingly.
+
+   This function implements a straightforward depth-first marking
+   algorithm and so the recursion depth may be very high (a few
+   tens of thousands is not uncommon).  To minimize stack usage,
+   a few cold paths are moved out to NO_INLINE functions above.
+   In general, inlining them doesn't help you to gain more speed.  */
 
 void
 mark_object (Lisp_Object arg)
@@ -6283,7 +6321,8 @@ mark_object (Lisp_Object arg)
            break;
 
          case PVEC_CHAR_TABLE:
-           mark_char_table (ptr);
+         case PVEC_SUB_CHAR_TABLE:
+           mark_char_table (ptr, (enum pvec_type) pvectype);
            break;
 
          case PVEC_BOOL_VECTOR:
@@ -6363,27 +6402,7 @@ mark_object (Lisp_Object arg)
 
        case Lisp_Misc_Save_Value:
          XMISCANY (obj)->gcmarkbit = 1;
-         {
-           struct Lisp_Save_Value *ptr = XSAVE_VALUE (obj);
-           /* If `save_type' is zero, `data[0].pointer' is the address
-              of a memory area containing `data[1].integer' potential
-              Lisp_Objects.  */
-           if (GC_MARK_STACK && ptr->save_type == SAVE_TYPE_MEMORY)
-             {
-               Lisp_Object *p = ptr->data[0].pointer;
-               ptrdiff_t nelt;
-               for (nelt = ptr->data[1].integer; nelt > 0; nelt--, p++)
-                 mark_maybe_object (*p);
-             }
-           else
-             {
-               /* Find Lisp_Objects in `data[N]' slots and mark them.  */
-               int i;
-               for (i = 0; i < SAVE_VALUE_SLOTS; i++)
-                 if (save_type (ptr, i) == SAVE_OBJECT)
-                   mark_object (ptr->data[i].object);
-             }
-         }
+         mark_save_value (XSAVE_VALUE (obj));
          break;
 
        case Lisp_Misc_Overlay:
@@ -7201,7 +7220,7 @@ The time is in seconds as a floating point value.  */);
 union
 {
   enum CHARTAB_SIZE_BITS CHARTAB_SIZE_BITS;
-  enum CHAR_TABLE_STANDARD_SLOTS CHAR_TABLE_STANDARD_SLOTS;
+  enum char_table_specials char_table_specials;
   enum char_bits char_bits;
   enum CHECK_LISP_OBJECT_TYPE CHECK_LISP_OBJECT_TYPE;
   enum DEFAULT_HASH_SIZE DEFAULT_HASH_SIZE;