diff src/lisp.h @ 3092:141c2920ea48

[xemacs-hg @ 2005-11-25 01:41:31 by crestani] Incremental Garbage Collector
author crestani
date Fri, 25 Nov 2005 01:42:08 +0000
parents d9ca850d40de
children ad2f4ae9895b
line wrap: on
line diff
--- a/src/lisp.h	Thu Nov 24 22:51:25 2005 +0000
+++ b/src/lisp.h	Fri Nov 25 01:42:08 2005 +0000
@@ -1253,6 +1253,7 @@
 
 /* ------------------------ dynamic arrays ------------------- */
 
+#ifndef NEW_GC
 #ifdef ERROR_CHECK_STRUCTURES
 #define Dynarr_declare(type)	\
   type *base;			\
@@ -1380,6 +1381,7 @@
 
 void *stack_like_malloc (Bytecount size);
 void stack_like_free (void *val);
+#endif /* not NEW_GC */
 
 /************************************************************************/
 /**                 Definitions of more complex types                  **/
@@ -1466,6 +1468,7 @@
 typedef struct Lisp_Image_Instance Lisp_Image_Instance; /* glyphs.h */
 typedef struct Lisp_Gui_Item Lisp_Gui_Item;
 
+#ifndef NEW_GC
 /* ------------------------------- */
 /*         Dynarr typedefs         */
 /* ------------------------------- */
@@ -1550,6 +1553,7 @@
 {
   Dynarr_declare (struct console_type_entry);
 } console_type_entry_dynarr;
+#endif /* not NEW_GC */
 
 /* ------------------------------- */
 /*          enum typedefs          */
@@ -1666,6 +1670,7 @@
 
 #define XPNTR(x) ((void *) XPNTRVAL(x))
 
+#ifndef NEW_GC
 /* WARNING WARNING WARNING.  You must ensure on your own that proper
    GC protection is provided for the elements in this array. */
 typedef struct
@@ -1677,6 +1682,7 @@
 {
   Dynarr_declare (Lisp_Object *);
 } Lisp_Object_ptr_dynarr;
+#endif /* not NEW_GC */
 
 /* Close your eyes now lest you vomit or spontaneously combust ... */
 
@@ -1707,6 +1713,284 @@
 
 BEGIN_C_DECLS
 
+#ifdef NEW_GC
+/* ------------------------ dynamic arrays ------------------- */
+
+#ifdef ERROR_CHECK_STRUCTURES
+#define Dynarr_declare(type)				\
+  struct lrecord_header header;				\
+  type *base;						\
+  const struct lrecord_implementation *lisp_imp;	\
+  int locked;						\
+  int elsize;						\
+  int cur;						\
+  int largest;						\
+  int max
+#else
+#define Dynarr_declare(type)				\
+  struct lrecord_header header;				\
+  type *base;						\
+  const struct lrecord_implementation *lisp_imp;	\
+  int elsize;						\
+  int cur;						\
+  int largest;						\
+  int max
+#endif /* ERROR_CHECK_STRUCTURES */
+
+typedef struct dynarr
+{
+  Dynarr_declare (void);
+} Dynarr;
+
+MODULE_API void *Dynarr_newf (int elsize);
+MODULE_API void Dynarr_resize (void *dy, Elemcount size);
+MODULE_API void Dynarr_insert_many (void *d, const void *el, int len, int start);
+MODULE_API void Dynarr_delete_many (void *d, int start, int len);
+MODULE_API void Dynarr_free (void *d);
+
+MODULE_API void *Dynarr_lisp_newf (int elsize,
+				   const struct lrecord_implementation 
+				   *dynarr_imp,
+				   const struct lrecord_implementation *imp);
+
+#define Dynarr_lisp_new(type, dynarr_imp, imp)			\
+  ((type##_dynarr *) Dynarr_lisp_newf (sizeof (type), dynarr_imp, imp))
+#define Dynarr_lisp_new2(dynarr_type, type, dynarr_imp, imp)	\
+  ((dynarr_type *) Dynarr_lisp_newf (sizeof (type)), dynarr_imp, imp)
+#define Dynarr_new(type) ((type##_dynarr *) Dynarr_newf (sizeof (type)))
+#define Dynarr_new2(dynarr_type, type) \
+  ((dynarr_type *) Dynarr_newf (sizeof (type)))
+#define Dynarr_at(d, pos) ((d)->base[pos])
+#define Dynarr_atp(d, pos) (&Dynarr_at (d, pos))
+#define Dynarr_begin(d) Dynarr_atp (d, 0)
+#define Dynarr_end(d) Dynarr_atp (d, Dynarr_length (d) - 1)
+#define Dynarr_sizeof(d) ((d)->cur * (d)->elsize)
+
+#ifdef ERROR_CHECK_STRUCTURES
+DECLARE_INLINE_HEADER (
+Dynarr *
+Dynarr_verify_1 (void *d, const Ascbyte *file, int line)
+)
+{
+  Dynarr *dy = (Dynarr *) d;
+  assert_at_line (dy->cur >= 0 && dy->cur <= dy->largest &&
+		  dy->largest <= dy->max, file, line);
+  return dy;
+}
+
+DECLARE_INLINE_HEADER (
+Dynarr *
+Dynarr_verify_mod_1 (void *d, const Ascbyte *file, int line)
+)
+{
+  Dynarr *dy = (Dynarr *) d;
+  assert_at_line (!dy->locked, file, line);
+  assert_at_line (dy->cur >= 0 && dy->cur <= dy->largest &&
+		  dy->largest <= dy->max, file, line);
+  return dy;
+}
+
+#define Dynarr_verify(d) Dynarr_verify_1 (d, __FILE__, __LINE__)
+#define Dynarr_verify_mod(d) Dynarr_verify_mod_1 (d, __FILE__, __LINE__)
+#define Dynarr_lock(d) (Dynarr_verify_mod (d)->locked = 1)
+#define Dynarr_unlock(d) ((d)->locked = 0)
+#else
+#define Dynarr_verify(d) (d)
+#define Dynarr_verify_mod(d) (d)
+#define Dynarr_lock(d)
+#define Dynarr_unlock(d)
+#endif /* ERROR_CHECK_STRUCTURES */
+
+#define Dynarr_length(d) (Dynarr_verify (d)->cur)
+#define Dynarr_largest(d) (Dynarr_verify (d)->largest)
+#define Dynarr_reset(d) (Dynarr_verify_mod (d)->cur = 0)
+#define Dynarr_add_many(d, el, len) Dynarr_insert_many (d, el, len, (d)->cur)
+#define Dynarr_insert_many_at_start(d, el, len)	\
+  Dynarr_insert_many (d, el, len, 0)
+#define Dynarr_add_literal_string(d, s) Dynarr_add_many (d, s, sizeof (s) - 1)
+#define Dynarr_add_lisp_string(d, s, codesys)			\
+do {								\
+  Lisp_Object dyna_ls_s = (s);					\
+  Lisp_Object dyna_ls_cs = (codesys);				\
+  Extbyte *dyna_ls_eb;						\
+  Bytecount dyna_ls_bc;						\
+								\
+  LISP_STRING_TO_SIZED_EXTERNAL (dyna_ls_s, dyna_ls_eb,		\
+				 dyna_ls_bc, dyna_ls_cs);	\
+  Dynarr_add_many (d, dyna_ls_eb, dyna_ls_bc);			\
+} while (0)
+
+#if 1
+#define Dynarr_add(d, el)					\
+do {								\
+  if (Dynarr_verify_mod (d)->cur >= (d)->max)			\
+    Dynarr_resize ((d), (d)->cur+1);				\
+  ((d)->base)[(d)->cur] = (el);					\
+								\
+  if ((d)->lisp_imp)						\
+    set_lheader_implementation					\
+     ((struct lrecord_header *)&(((d)->base)[(d)->cur]),	\
+      (d)->lisp_imp);						\
+								\
+  (d)->cur++;							\
+  if ((d)->cur > (d)->largest)					\
+    (d)->largest = (d)->cur;					\
+} while (0)
+#else
+#define Dynarr_add(d, el) (						     \
+  Dynarr_verify_mod (d)->cur >= (d)->max ? Dynarr_resize ((d), (d)->cur+1) : \
+      (void) 0,								     \
+  ((d)->base)[(d)->cur++] = (el),					     \
+  (d)->cur > (d)->largest ? (d)->largest = (d)->cur : (int) 0)
+#endif  
+    
+
+/* The following defines will get you into real trouble if you aren't
+   careful.  But they can save a lot of execution time when used wisely. */
+#define Dynarr_increment(d) (Dynarr_verify_mod (d)->cur++)
+#define Dynarr_set_size(d, n) (Dynarr_verify_mod (d)->cur = n)
+
+#define Dynarr_pop(d)					\
+  (assert ((d)->cur > 0), Dynarr_verify_mod (d)->cur--,	\
+   Dynarr_at (d, (d)->cur))
+#define Dynarr_delete(d, i) Dynarr_delete_many (d, i, 1)
+#define Dynarr_delete_by_pointer(d, p) \
+  Dynarr_delete_many (d, (p) - ((d)->base), 1)
+
+#define Dynarr_delete_object(d, el)		\
+do						\
+{						\
+  REGISTER int i;				\
+  for (i = Dynarr_length (d) - 1; i >= 0; i--)	\
+    {						\
+      if (el == Dynarr_at (d, i))		\
+	Dynarr_delete_many (d, i, 1);		\
+    }						\
+} while (0)
+
+#ifdef MEMORY_USAGE_STATS
+struct overhead_stats;
+Bytecount Dynarr_memory_usage (void *d, struct overhead_stats *stats);
+#endif
+
+void *stack_like_malloc (Bytecount size);
+void stack_like_free (void *val);
+
+/* ------------------------------- */
+/*         Dynarr typedefs         */
+/* ------------------------------- */
+
+/* Dynarr typedefs -- basic types first */
+
+typedef struct
+{
+  Dynarr_declare (Ibyte);
+} Ibyte_dynarr;
+
+typedef struct
+{
+  Dynarr_declare (Extbyte);
+} Extbyte_dynarr;
+
+typedef struct
+{
+  Dynarr_declare (Ichar);
+} Ichar_dynarr;
+
+typedef struct
+{
+  Dynarr_declare (char);
+} char_dynarr;
+
+typedef struct
+{
+  Dynarr_declare (char *);
+} char_ptr_dynarr;
+
+typedef unsigned char unsigned_char;
+typedef struct
+{
+  Dynarr_declare (unsigned char);
+} unsigned_char_dynarr;
+
+typedef unsigned long unsigned_long;
+typedef struct
+{
+  Dynarr_declare (unsigned long);
+} unsigned_long_dynarr;
+
+typedef struct
+{
+  Dynarr_declare (int);
+} int_dynarr;
+
+typedef struct
+{
+  Dynarr_declare (Charbpos);
+} Charbpos_dynarr;
+
+typedef struct
+{
+  Dynarr_declare (Bytebpos);
+} Bytebpos_dynarr;
+
+typedef struct
+{
+  Dynarr_declare (Charcount);
+} Charcount_dynarr;
+
+typedef struct
+{
+  Dynarr_declare (Bytecount);
+} Bytecount_dynarr;
+
+/* Dynarr typedefs -- more complex types */
+
+typedef struct
+{
+  Dynarr_declare (struct face_cachel);
+} face_cachel_dynarr;
+
+DECLARE_LRECORD (face_cachel_dynarr, face_cachel_dynarr);
+#define XFACE_CACHEL_DYNARR(x) \
+  XRECORD (x, face_cachel_dynarr, face_cachel_dynarr)
+#define wrap_face_cachel_dynarr(p) wrap_record (p, face_cachel_dynarr)
+#define FACE_CACHEL_DYNARRP(x) RECORDP (x, face_cachel_dynarr)
+#define CHECK_FACE_CACHEL_DYNARR(x) CHECK_RECORD (x, face_cachel_dynarr)
+#define CONCHECK_FACE_CACHEL_DYNARR(x) CONCHECK_RECORD (x, face_cachel_dynarr)
+
+typedef struct
+{
+  Dynarr_declare (struct glyph_cachel);
+} glyph_cachel_dynarr;
+
+DECLARE_LRECORD (glyph_cachel_dynarr, glyph_cachel_dynarr);
+#define XGLYPH_CACHEL_DYNARR(x) \
+  XRECORD (x, glyph_cachel_dynarr, glyph_cachel_dynarr)
+#define wrap_glyph_cachel_dynarr(p) wrap_record (p, glyph_cachel_dynarr)
+#define GLYPH_CACHEL_DYNARRP(x) RECORDP (x, glyph_cachel_dynarr)
+#define CHECK_GLYPH_CACHEL_DYNARR(x) CHECK_RECORD (x, glyph_cachel_dynarr)
+#define CONCHECK_GLYPH_CACHEL_DYNARR(x) \
+  CONCHECK_RECORD (x, glyph_cachel_dynarr)
+
+typedef struct
+{
+  Dynarr_declare (struct console_type_entry);
+} console_type_entry_dynarr;
+
+/* WARNING WARNING WARNING.  You must ensure on your own that proper
+   GC protection is provided for the elements in this array. */
+typedef struct
+{
+  Dynarr_declare (Lisp_Object);
+} Lisp_Object_dynarr;
+
+typedef struct
+{
+  Dynarr_declare (Lisp_Object *);
+} Lisp_Object_ptr_dynarr;
+#endif /* NEW_GC */
+
 /*------------------------------ unbound -------------------------------*/
 
 /* Qunbound is a special Lisp_Object (actually of type
@@ -2282,6 +2566,67 @@
 
 /*------------------------------ string --------------------------------*/
 
+#ifdef NEW_GC
+struct Lisp_String_Direct_Data
+{
+  struct lrecord_header header;
+  Bytecount size;
+  Ibyte data[1];
+};
+typedef struct Lisp_String_Direct_Data Lisp_String_Direct_Data;
+
+DECLARE_MODULE_API_LRECORD (string_direct_data, Lisp_String_Direct_Data);
+#define XSTRING_DIRECT_DATA(x) \
+  XRECORD (x, string_direct_data, Lisp_String_Direct_Data)
+#define wrap_string_direct_data(p) wrap_record (p, string_direct_data)
+#define STRING_DIRECT_DATAP(x) RECORDP (x, string_direct_data)
+#define CHECK_STRING_DIRECT_DATA(x) CHECK_RECORD (x, string_direct_data)
+#define CONCHECK_STRING_DIRECT_DATA(x) CONCHECK_RECORD (x, string_direct_data)
+
+#define XSTRING_DIRECT_DATA_SIZE(x) XSTRING_DIRECT_DATA (x)->size
+#define XSTRING_DIRECT_DATA_DATA(x) XSTRING_DIRECT_DATA (x)->data
+
+
+struct Lisp_String_Indirect_Data
+{
+  struct lrecord_header header;
+  Bytecount size;
+  Ibyte *data;
+};
+typedef struct Lisp_String_Indirect_Data Lisp_String_Indirect_Data;
+
+DECLARE_MODULE_API_LRECORD (string_indirect_data, Lisp_String_Indirect_Data);
+#define XSTRING_INDIRECT_DATA(x) \
+  XRECORD (x, string_indirect_data, Lisp_String_Indirect_Data)
+#define wrap_string_indirect_data(p) wrap_record (p, string_indirect_data)
+#define STRING_INDIRECT_DATAP(x) RECORDP (x, string_indirect_data)
+#define CHECK_STRING_INDIRECT_DATA(x) CHECK_RECORD (x, string_indirect_data)
+#define CONCHECK_STRING_INDIRECT_DATA(x) \
+  CONCHECK_RECORD (x, string_indirect_data)
+
+#define XSTRING_INDIRECT_DATA_SIZE(x) XSTRING_INDIRECT_DATA (x)->size
+#define XSTRING_INDIRECT_DATA_DATA(x) XSTRING_INDIRECT_DATA (x)->data
+
+
+#define XSTRING_DATA_SIZE(s) ((s)->indirect)?		\
+  XSTRING_INDIRECT_DATA_SIZE ((s)->data_object):	\
+  XSTRING_DIRECT_DATA_SIZE ((s)->data_object)
+#define XSTRING_DATA_DATA(s) ((s)->indirect)?		\
+  XSTRING_INDIRECT_DATA_DATA ((s)->data_object):	\
+  XSTRING_DIRECT_DATA_DATA ((s)->data_object)
+
+#define XSET_STRING_DATA_SIZE(s, len)				\
+  if ((s)->indirect)						\
+    XSTRING_INDIRECT_DATA_SIZE ((s)->data_object) = len;	\
+  else								\
+    XSTRING_DIRECT_DATA_SIZE ((s)->data_object) = len
+#define XSET_STRING_DATA_DATA(s, ptr)				\
+  if ((s)->indirect)						\
+    XSTRING_INDIRECT_DATA_DATA ((s)->data_object) = ptr;	\
+  else								\
+    XSTRING_DIRECT_DATA_DATA ((s)->data_object) = ptr
+#endif /* NEW_GC */
+
 struct Lisp_String
 {
   union
@@ -2308,8 +2653,13 @@
 #endif /* not MC_ALLOC */
 	} v;
     } u;
+#ifdef NEW_GC
+  int indirect;
+  Lisp_Object data_object;
+#else /* not NEW_GC */
   Bytecount size_;
   Ibyte *data_;
+#endif /* not NEW_GC */
   Lisp_Object plist;
 };
 typedef struct Lisp_String Lisp_String;
@@ -2332,14 +2682,30 @@
    stuff there. */
 
 /* Operations on Lisp_String *'s; only ones left */
+#ifdef NEW_GC
+#define set_lispstringp_indirect(s) ((s)->indirect = 1)
+#define set_lispstringp_length(s, len) XSET_STRING_DATA_SIZE (s, len)
+#define set_lispstringp_data(s, ptr) XSET_STRING_DATA_DATA (s, ptr)
+#else /* not NEW_GC */
 #define set_lispstringp_length(s, len) ((void) ((s)->size_ = (len)))
 #define set_lispstringp_data(s, ptr) ((void) ((s)->data_ = (ptr)))
+#endif /* not NEW_GC */
 
 /* Operations on strings as Lisp_Objects.  Don't manipulate Lisp_String *'s
    in any new code. */
+#ifdef NEW_GC
+#define STRING_DATA_OBJECT(s) ((s)->data_object)
+#define XSTRING_DATA_OBJECT(s) (STRING_DATA_OBJECT (XSTRING (s)))
+#define XSTRING_LENGTH(s) (XSTRING_DATA_SIZE (XSTRING (s)))
+#else /* not NEW_GC */
 #define XSTRING_LENGTH(s) (XSTRING (s)->size_)
+#endif /* not NEW_GC */
 #define XSTRING_PLIST(s) (XSTRING (s)->plist)
+#ifdef NEW_GC
+#define XSTRING_DATA(s) (XSTRING_DATA_DATA (XSTRING (s)))
+#else /* not NEW_GC */
 #define XSTRING_DATA(s) (XSTRING (s)->data_ + 0)
+#endif /* not NEW_GC */
 #define XSTRING_ASCII_BEGIN(s) (XSTRING (s)->u.v.ascii_begin + 0)
 #define XSET_STRING_LENGTH(s, ptr) set_lispstringp_length (XSTRING (s), ptr)
 #define XSET_STRING_DATA(s, ptr) set_lispstringp_data (XSTRING (s), ptr)
@@ -3624,7 +3990,7 @@
 } while (0)
 
 extern Lisp_Object_ptr_dynarr *staticpros;
-
+extern Lisp_Object_ptr_dynarr *staticpros_nodump;
 #ifdef DEBUG_XEMACS
 
 /* Help debug crashes gc-marking a staticpro'ed object. */
@@ -3734,7 +4100,9 @@
 Lisp_Object make_bit_vector (Elemcount, Lisp_Object);
 Lisp_Object make_bit_vector_from_byte_vector (unsigned char *, Elemcount);
 Lisp_Object noseeum_make_marker (void);
+#ifndef NEW_GC
 void garbage_collect_1 (void);
+#endif /* not NEW_GC */
 MODULE_API Lisp_Object acons (Lisp_Object, Lisp_Object, Lisp_Object);
 MODULE_API Lisp_Object cons3 (Lisp_Object, Lisp_Object, Lisp_Object);
 MODULE_API Lisp_Object list1 (Lisp_Object);
@@ -3749,7 +4117,9 @@
 DECLARE_DOESNT_RETURN (memory_full (void));
 void disksave_object_finalization (void);
 extern int purify_flag;
+#ifndef NEW_GC
 extern EMACS_INT gc_generation_number[1];
+#endif /* not NEW_GC */
 int c_readonly (Lisp_Object);
 int lisp_readonly (Lisp_Object);
 MODULE_API void copy_lisp_object (Lisp_Object dst, Lisp_Object src);
@@ -3770,6 +4140,7 @@
 void free_marker (Lisp_Object);
 int object_dead_p (Lisp_Object);
 void mark_object (Lisp_Object obj);
+#ifndef NEW_GC
 #ifdef USE_KKCC
 #ifdef DEBUG_XEMACS
 void kkcc_gc_stack_push_lisp_object_1 (Lisp_Object obj, int level, int pos);
@@ -3783,6 +4154,7 @@
 #define kkcc_backtrace()
 #endif
 #endif /* USE_KKCC */
+#endif /* not NEW_GC */
 int marked_p (Lisp_Object obj);
 extern int funcall_allocation_flag;
 extern int need_to_garbage_collect;