(GT-K02180): New character.
[chise/xemacs-chise.git-] / src / alloc.c
index 9e0174d..48b0eab 100644 (file)
@@ -85,8 +85,8 @@ EXFUN (Fgarbage_collect, 0);
 #endif
 
 #ifdef DEBUG_XEMACS
-static int debug_allocation;
-static int debug_allocation_backtrace_length;
+static Fixnum debug_allocation;
+static Fixnum debug_allocation_backtrace_length;
 #endif
 
 /* Number of bytes of consing done since the last gc */
@@ -357,9 +357,6 @@ allocate_lisp_storage (size_t size)
    After doing the mark phase, GC will walk this linked list
    and free any lcrecord which hasn't been marked. */
 static struct lcrecord_header *all_lcrecords;
-#ifdef UTF2000
-static struct lcrecord_header *all_older_lcrecords;
-#endif
 
 void *
 alloc_lcrecord (size_t size, const struct lrecord_implementation *implementation)
@@ -389,37 +386,6 @@ alloc_lcrecord (size_t size, const struct lrecord_implementation *implementation
   return lcheader;
 }
 
-#ifdef UTF2000
-void *
-alloc_older_lcrecord (size_t size,
-                     const struct lrecord_implementation *implementation)
-{
-  struct lcrecord_header *lcheader;
-
-  type_checking_assert
-    ((implementation->static_size == 0 ?
-      implementation->size_in_bytes_method != NULL :
-      implementation->static_size == size)
-     &&
-     (! implementation->basic_p)
-     &&
-     (! (implementation->hash == NULL && implementation->equal != NULL)));
-
-  lcheader = (struct lcrecord_header *) allocate_lisp_storage (size);
-  set_lheader_older_implementation (&lcheader->lheader, implementation);
-  lcheader->next = all_older_lcrecords;
-#if 1                           /* mly prefers to see small ID numbers */
-  lcheader->uid = lrecord_uid_counter++;
-#else                          /* jwz prefers to see real addrs */
-  lcheader->uid = (int) &lcheader;
-#endif
-  lcheader->free = 0;
-  all_older_lcrecords = lcheader;
-  INCREMENT_CONS_COUNTER (size, implementation->name);
-  return lcheader;
-}
-#endif
-
 #if 0 /* Presently unused */
 /* Very, very poor man's EGC?
  * This may be slow and thrash pages all over the place.
@@ -470,14 +436,6 @@ disksave_object_finalization_1 (void)
          !header->free)
        LHEADER_IMPLEMENTATION (&header->lheader)->finalizer (header, 1);
     }
-#ifdef UTF2000
-  for (header = all_older_lcrecords; header; header = header->next)
-    {
-      if (LHEADER_IMPLEMENTATION (&header->lheader)->finalizer &&
-         !header->free)
-       LHEADER_IMPLEMENTATION (&header->lheader)->finalizer (header, 1);
-    }
-#endif
 }
 
 \f
@@ -489,17 +447,31 @@ disksave_object_finalization_1 (void)
    about expressions in src/.gdbinit.  See src/.gdbinit or src/.dbxrc
    to see how this is used.  */
 
-const EMACS_UINT dbg_valmask = ((1UL << VALBITS) - 1) << GCBITS;
-const EMACS_UINT dbg_typemask = (1UL << GCTYPEBITS) - 1;
+EMACS_UINT dbg_valmask = ((1UL << VALBITS) - 1) << GCBITS;
+EMACS_UINT dbg_typemask = (1UL << GCTYPEBITS) - 1;
 
 #ifdef USE_UNION_TYPE
-const unsigned char dbg_USE_UNION_TYPE = 1;
+unsigned char dbg_USE_UNION_TYPE = 1;
 #else
-const unsigned char dbg_USE_UNION_TYPE = 0;
+unsigned char dbg_USE_UNION_TYPE = 0;
 #endif
 
-const unsigned char dbg_valbits = VALBITS;
-const unsigned char dbg_gctypebits = GCTYPEBITS;
+unsigned char dbg_valbits = VALBITS;
+unsigned char dbg_gctypebits = GCTYPEBITS;
+
+/* On some systems, the above definitions will be optimized away by
+   the compiler or linker unless they are referenced in some function. */
+long dbg_inhibit_dbg_symbol_deletion (void);
+long
+dbg_inhibit_dbg_symbol_deletion (void)
+{
+  return
+    (dbg_valmask +
+     dbg_typemask +
+     dbg_USE_UNION_TYPE +
+     dbg_valbits +
+     dbg_gctypebits);
+}
 
 /* Macros turned into functions for ease of debugging.
    Debuggers don't know about macros! */
@@ -1085,7 +1057,7 @@ mark_vector (Lisp_Object obj)
 static size_t
 size_vector (const void *lheader)
 {
-  return FLEXIBLE_ARRAY_STRUCT_SIZEOF (Lisp_Vector, contents,
+  return FLEXIBLE_ARRAY_STRUCT_SIZEOF (Lisp_Vector, Lisp_Object, contents,
                                       ((Lisp_Vector *) lheader)->size);
 }
 
@@ -1133,7 +1105,8 @@ static Lisp_Vector *
 make_vector_internal (size_t sizei)
 {
   /* no vector_next */
-  size_t sizem = FLEXIBLE_ARRAY_STRUCT_SIZEOF (Lisp_Vector, contents, sizei);
+  size_t sizem = FLEXIBLE_ARRAY_STRUCT_SIZEOF (Lisp_Vector, Lisp_Object,
+                                              contents, sizei);
   Lisp_Vector *p = (Lisp_Vector *) alloc_lcrecord (sizem, &lrecord_vector);
 
   p->size = sizei;
@@ -1156,74 +1129,6 @@ make_vector (size_t length, Lisp_Object object)
   }
 }
 
-#ifdef HAVE_GGC
-Lisp_Object
-make_older_vector (size_t length, Lisp_Object init)
-{
-  struct lcrecord_header* orig_all_lcrecords = all_lcrecords;
-  Lisp_Object obj;
-
-  all_lcrecords = all_older_lcrecords;
-  obj = make_vector (length, init);
-  all_older_lcrecords = all_lcrecords;
-  all_lcrecords = orig_all_lcrecords;
-  return obj;
-}
-
-void make_vector_newer_1 (Lisp_Object v);
-void
-make_vector_newer_1 (Lisp_Object v)
-{
-  struct lcrecord_header* lcrecords = all_older_lcrecords;
-
-  if (lcrecords != NULL)
-    {
-      if (lcrecords == XPNTR (v))
-       {
-         lcrecords->lheader.older = 0;
-         all_older_lcrecords = all_older_lcrecords->next;
-         lcrecords->next = all_lcrecords;
-         all_lcrecords = lcrecords;
-         return;
-       }
-      else
-       {
-         struct lcrecord_header* plcrecords = lcrecords;
-
-         lcrecords = lcrecords->next;
-         while (lcrecords != NULL)
-           {
-             if (lcrecords == XPNTR (v))
-               {
-                 lcrecords->lheader.older = 0;
-                 plcrecords->next = lcrecords->next;
-                 lcrecords->next = all_lcrecords;
-                 all_lcrecords = lcrecords;
-                 return;
-               }
-             plcrecords = lcrecords;
-             lcrecords = lcrecords->next;
-           }
-       }
-    }
-}
-
-void
-make_vector_newer (Lisp_Object v)
-{
-  int i;
-
-  for (i = 0; i < XVECTOR_LENGTH (v); i++)
-    {
-      Lisp_Object obj = XVECTOR_DATA (v)[i];
-
-      if (VECTORP (obj) && !EQ (obj, v))
-       make_vector_newer (obj);
-    }
-  make_vector_newer_1 (v);
-}
-#endif
-
 DEFUN ("make-vector", Fmake_vector, 2, 2, 0, /*
 Return a new vector of length LENGTH, with each element being OBJECT.
 See also the function `vector'.
@@ -1364,7 +1269,8 @@ static Lisp_Bit_Vector *
 make_bit_vector_internal (size_t sizei)
 {
   size_t num_longs = BIT_VECTOR_LONG_STORAGE (sizei);
-  size_t sizem = FLEXIBLE_ARRAY_STRUCT_SIZEOF (Lisp_Bit_Vector, bits, num_longs);
+  size_t sizem = FLEXIBLE_ARRAY_STRUCT_SIZEOF (Lisp_Bit_Vector, unsigned long,
+                                              bits, num_longs);
   Lisp_Bit_Vector *p = (Lisp_Bit_Vector *) allocate_lisp_storage (sizem);
   set_lheader_implementation (&p->lheader, &lrecord_bit_vector);
 
@@ -1409,7 +1315,7 @@ make_bit_vector (size_t length, Lisp_Object bit)
 Lisp_Object
 make_bit_vector_from_byte_vector (unsigned char *bytevec, size_t length)
 {
-  int i;
+  size_t i;
   Lisp_Bit_Vector *p = make_bit_vector_internal (length);
 
   for (i = 0; i < length; i++)
@@ -2516,11 +2422,7 @@ mark_object (Lisp_Object obj)
 
       /* All c_readonly objects have their mark bit set,
         so that we only need to check the mark bit here. */
-      if ( (!MARKED_RECORD_HEADER_P (lheader))
-#ifdef UTF2000
-          && (!OLDER_RECORD_HEADER_P (lheader))
-#endif
-          )
+      if (! MARKED_RECORD_HEADER_P (lheader))
        {
          MARK_RECORD_HEADER (lheader);
 
@@ -2575,7 +2477,8 @@ static struct
   int instances_freed;
   int bytes_freed;
   int instances_on_free_list;
-} lcrecord_stats [countof (lrecord_implementations_table)];
+} lcrecord_stats [countof (lrecord_implementations_table)
+                 + MODULE_DEFINABLE_TYPE_COUNT];
 
 static void
 tick_lcrecord_stats (const struct lrecord_header *h, int free_p)
@@ -2693,8 +2596,8 @@ sweep_bit_vectors_1 (Lisp_Object *prev,
          total_size += len;
           total_storage +=
            MALLOC_OVERHEAD +
-           FLEXIBLE_ARRAY_STRUCT_SIZEOF (Lisp_Bit_Vector, bits,
-                                         BIT_VECTOR_LONG_STORAGE (len));
+           FLEXIBLE_ARRAY_STRUCT_SIZEOF (Lisp_Bit_Vector, unsigned long,
+                                         bits, BIT_VECTOR_LONG_STORAGE (len));
          num_used++;
          /* #### May modify next on a C_READONLY bitvector */
          prev = &(bit_vector_next (v));
@@ -3344,6 +3247,61 @@ restore_gc_inhibit (Lisp_Object val)
 /* Maybe we want to use this when doing a "panic" gc after memory_full()? */
 static int gc_hooks_inhibited;
 
+struct post_gc_action
+{
+  void (*fun) (void *);
+  void *arg;
+};
+
+typedef struct post_gc_action post_gc_action;
+
+typedef struct
+{
+  Dynarr_declare (post_gc_action);
+} post_gc_action_dynarr;
+
+static post_gc_action_dynarr *post_gc_actions;
+
+/* Register an action to be called at the end of GC.
+   gc_in_progress is 0 when this is called.
+   This is used when it is discovered that an action needs to be taken,
+   but it's during GC, so it's not safe. (e.g. in a finalize method.)
+
+   As a general rule, do not use Lisp objects here.
+   And NEVER signal an error.
+*/
+
+void
+register_post_gc_action (void (*fun) (void *), void *arg)
+{
+  post_gc_action action;
+
+  if (!post_gc_actions)
+    post_gc_actions = Dynarr_new (post_gc_action);
+
+  action.fun = fun;
+  action.arg = arg;
+
+  Dynarr_add (post_gc_actions, action);
+}
+
+static void
+run_post_gc_actions (void)
+{
+  int i;
+
+  if (post_gc_actions)
+    {
+      for (i = 0; i < Dynarr_length (post_gc_actions); i++)
+       {
+         post_gc_action action = Dynarr_at (post_gc_actions, i);
+         (action.fun) (action.arg);
+       }
+
+      Dynarr_reset (post_gc_actions);
+    }
+}
+
 \f
 void
 garbage_collect_1 (void)
@@ -3559,6 +3517,8 @@ garbage_collect_1 (void)
 
   gc_in_progress = 0;
 
+  run_post_gc_actions ();
+
   /******* End of garbage collection ********/
 
   run_hook_trapping_errors ("Error in post-gc-hook", Qpost_gc_hook);
@@ -3635,7 +3595,7 @@ Garbage collection happens automatically if you cons more than
        ())
 {
   Lisp_Object pl = Qnil;
-  int i;
+  unsigned int i;
   int gc_count_vector_total_size = 0;
 
   garbage_collect_1 ();
@@ -3650,7 +3610,7 @@ Garbage collection happens automatically if you cons more than
           const char *name = lrecord_implementations_table[i]->name;
          int len = strlen (name);
          /* save this for the FSFmacs-compatible part of the summary */
-         if (i == lrecord_vector.lrecord_type_index)
+         if (i == lrecord_type_vector)
            gc_count_vector_total_size =
              lcrecord_stats[i].bytes_in_use + lcrecord_stats[i].bytes_freed;
 
@@ -3922,9 +3882,6 @@ reinit_alloc_once_early (void)
   XSETINT (all_bit_vectors, 0); /* Qzero may not be set yet. */
   XSETINT (Vgc_message, 0);
   all_lcrecords = 0;
-#ifdef UTF2000
-  all_older_lcrecords = 0;
-#endif
   ignore_malloc_warnings = 1;
 #ifdef DOUG_LEA_MALLOC
   mallopt (M_TRIM_THRESHOLD, 128*1024); /* trim threshold */