Mercurial > hg > xemacs-beta
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;