(enum lrecord_type): Add `lrecord_type_uint16_byte_table' and
[chise/xemacs-chise.git-] / src / alloc.c
index 0c4325d..f10c14b 100644 (file)
@@ -368,6 +368,9 @@ 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)
@@ -397,6 +400,37 @@ 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.
@@ -447,6 +481,14 @@ 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
@@ -1082,7 +1124,8 @@ mark_vector (Lisp_Object obj)
 static size_t
 size_vector (const void *lheader)
 {
-  return offsetof (Lisp_Vector, contents[((Lisp_Vector *) lheader)->size]);
+  return FLEXIBLE_ARRAY_STRUCT_SIZEOF (Lisp_Vector, contents,
+                                      ((Lisp_Vector *) lheader)->size);
 }
 
 static int
@@ -1129,7 +1172,7 @@ static Lisp_Vector *
 make_vector_internal (size_t sizei)
 {
   /* no vector_next */
-  size_t sizem = offsetof (Lisp_Vector, contents[sizei]);
+  size_t sizem = FLEXIBLE_ARRAY_STRUCT_SIZEOF (Lisp_Vector, contents, sizei);
   Lisp_Vector *p = (Lisp_Vector *) alloc_lcrecord (sizem, &lrecord_vector);
 
   p->size = sizei;
@@ -1152,6 +1195,74 @@ make_vector (size_t length, Lisp_Object init)
   }
 }
 
+#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 INIT.
 See also the function `vector'.
@@ -1292,7 +1403,7 @@ static Lisp_Bit_Vector *
 make_bit_vector_internal (size_t sizei)
 {
   size_t num_longs = BIT_VECTOR_LONG_STORAGE (sizei);
-  size_t sizem = offsetof (Lisp_Bit_Vector, bits[num_longs]);
+  size_t sizem = FLEXIBLE_ARRAY_STRUCT_SIZEOF (Lisp_Bit_Vector, bits, num_longs);
   Lisp_Bit_Vector *p = (Lisp_Bit_Vector *) allocate_lisp_storage (sizem);
   set_lheader_implementation (&p->lheader, &lrecord_bit_vector);
 
@@ -2070,6 +2181,10 @@ LENGTH must be an integer and INIT must be a character.
            Bufbyte *init_ptr = init_str;
            switch (len)
              {
+#ifdef UTF2000
+             case 6: *ptr++ = *init_ptr++;
+             case 5: *ptr++ = *init_ptr++;
+#endif
              case 4: *ptr++ = *init_ptr++;
              case 3: *ptr++ = *init_ptr++;
              case 2: *ptr++ = *init_ptr++;
@@ -2490,7 +2605,11 @@ 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))
+      if ( (!MARKED_RECORD_HEADER_P (lheader))
+#ifdef UTF2000
+          && (!OLDER_RECORD_HEADER_P (lheader))
+#endif
+          )
        {
          MARK_RECORD_HEADER (lheader);
 
@@ -2663,7 +2782,8 @@ sweep_bit_vectors_1 (Lisp_Object *prev,
          total_size += len;
           total_storage +=
            MALLOC_OVERHEAD +
-           offsetof (Lisp_Bit_Vector, bits[BIT_VECTOR_LONG_STORAGE (len)]);
+           FLEXIBLE_ARRAY_STRUCT_SIZEOF (Lisp_Bit_Vector, bits,
+                                         BIT_VECTOR_LONG_STORAGE (len));
          num_used++;
          /* #### May modify next on a C_READONLY bitvector */
          prev = &(bit_vector_next (v));
@@ -3140,8 +3260,9 @@ sweep_strings (void)
     UNMARK_RECORD_HEADER (&(p->lheader));      \
     num_bytes += size;                         \
     if (!BIG_STRING_SIZE_P (size))             \
-      { num_small_bytes += size;               \
-      num_small_used++;                                \
+      {                                                \
+       num_small_bytes += size;                \
+        num_small_used++;                      \
       }                                                \
     if (debug)                                 \
       debug_string_purity_print (p);           \
@@ -3887,6 +4008,9 @@ 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 */