aboutsummaryrefslogtreecommitdiffstats
path: root/src/alloc.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/alloc.c')
-rw-r--r--src/alloc.c121
1 files changed, 66 insertions, 55 deletions
diff --git a/src/alloc.c b/src/alloc.c
index a8830684580..859961781e0 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -69,6 +69,9 @@ extern void *sbrk ();
69 69
70#include <fcntl.h> 70#include <fcntl.h>
71 71
72#ifdef USE_GTK
73# include "gtkutil.h"
74#endif
72#ifdef WINDOWSNT 75#ifdef WINDOWSNT
73#include "w32.h" 76#include "w32.h"
74#endif 77#endif
@@ -173,15 +176,15 @@ EMACS_INT gc_relative_threshold;
173 176
174EMACS_INT memory_full_cons_threshold; 177EMACS_INT memory_full_cons_threshold;
175 178
176/* Nonzero during GC. */ 179/* True during GC. */
177 180
178int gc_in_progress; 181bool gc_in_progress;
179 182
180/* Nonzero means abort if try to GC. 183/* True means abort if try to GC.
181 This is for code which is written on the assumption that 184 This is for code which is written on the assumption that
182 no GC will happen, so as to verify that assumption. */ 185 no GC will happen, so as to verify that assumption. */
183 186
184int abort_on_gc; 187bool abort_on_gc;
185 188
186/* Number of live and free conses etc. */ 189/* Number of live and free conses etc. */
187 190
@@ -223,7 +226,7 @@ static ptrdiff_t pure_size;
223 226
224static ptrdiff_t pure_bytes_used_before_overflow; 227static ptrdiff_t pure_bytes_used_before_overflow;
225 228
226/* Value is non-zero if P points into pure space. */ 229/* True if P points into pure space. */
227 230
228#define PURE_POINTER_P(P) \ 231#define PURE_POINTER_P(P) \
229 ((uintptr_t) (P) - (uintptr_t) purebeg <= pure_size) 232 ((uintptr_t) (P) - (uintptr_t) purebeg <= pure_size)
@@ -305,7 +308,9 @@ enum mem_type
305 and runtime slowdown. Minor but pointless. */ 308 and runtime slowdown. Minor but pointless. */
306 MEM_TYPE_VECTORLIKE, 309 MEM_TYPE_VECTORLIKE,
307 /* Special type to denote vector blocks. */ 310 /* Special type to denote vector blocks. */
308 MEM_TYPE_VECTOR_BLOCK 311 MEM_TYPE_VECTOR_BLOCK,
312 /* Special type to denote reserved memory. */
313 MEM_TYPE_SPARE
309}; 314};
310 315
311static void *lisp_malloc (size_t, enum mem_type); 316static void *lisp_malloc (size_t, enum mem_type);
@@ -387,13 +392,13 @@ static struct mem_node mem_z;
387 392
388static struct Lisp_Vector *allocate_vectorlike (ptrdiff_t); 393static struct Lisp_Vector *allocate_vectorlike (ptrdiff_t);
389static void lisp_free (void *); 394static void lisp_free (void *);
390static int live_vector_p (struct mem_node *, void *); 395static bool live_vector_p (struct mem_node *, void *);
391static int live_buffer_p (struct mem_node *, void *); 396static bool live_buffer_p (struct mem_node *, void *);
392static int live_string_p (struct mem_node *, void *); 397static bool live_string_p (struct mem_node *, void *);
393static int live_cons_p (struct mem_node *, void *); 398static bool live_cons_p (struct mem_node *, void *);
394static int live_symbol_p (struct mem_node *, void *); 399static bool live_symbol_p (struct mem_node *, void *);
395static int live_float_p (struct mem_node *, void *); 400static bool live_float_p (struct mem_node *, void *);
396static int live_misc_p (struct mem_node *, void *); 401static bool live_misc_p (struct mem_node *, void *);
397static void mark_maybe_object (Lisp_Object); 402static void mark_maybe_object (Lisp_Object);
398static void mark_memory (void *, void *); 403static void mark_memory (void *, void *);
399#if GC_MARK_STACK || defined GC_MALLOC_CHECK 404#if GC_MARK_STACK || defined GC_MALLOC_CHECK
@@ -1232,7 +1237,7 @@ static void (*old_free_hook) (void*, const void*);
1232#endif 1237#endif
1233 1238
1234#ifdef GC_MALLOC_CHECK 1239#ifdef GC_MALLOC_CHECK
1235static int dont_register_blocks; 1240static bool dont_register_blocks;
1236#endif 1241#endif
1237 1242
1238static size_t bytes_used_when_reconsidered; 1243static size_t bytes_used_when_reconsidered;
@@ -1819,11 +1824,11 @@ check_sblock (struct sblock *b)
1819 1824
1820 1825
1821/* Check validity of Lisp strings' string_bytes member. ALL_P 1826/* Check validity of Lisp strings' string_bytes member. ALL_P
1822 non-zero means check all strings, otherwise check only most 1827 means check all strings, otherwise check only most
1823 recently allocated strings. Used for hunting a bug. */ 1828 recently allocated strings. Used for hunting a bug. */
1824 1829
1825static void 1830static void
1826check_string_bytes (int all_p) 1831check_string_bytes (bool all_p)
1827{ 1832{
1828 if (all_p) 1833 if (all_p)
1829 { 1834 {
@@ -2428,9 +2433,9 @@ make_string_from_bytes (const char *contents,
2428 2433
2429Lisp_Object 2434Lisp_Object
2430make_specified_string (const char *contents, 2435make_specified_string (const char *contents,
2431 ptrdiff_t nchars, ptrdiff_t nbytes, int multibyte) 2436 ptrdiff_t nchars, ptrdiff_t nbytes, bool multibyte)
2432{ 2437{
2433 register Lisp_Object val; 2438 Lisp_Object val;
2434 2439
2435 if (nchars < 0) 2440 if (nchars < 0)
2436 { 2441 {
@@ -3085,7 +3090,7 @@ sweep_vectors (void)
3085 3090
3086 for (block = vector_blocks; block; block = *bprev) 3091 for (block = vector_blocks; block; block = *bprev)
3087 { 3092 {
3088 int free_this_block = 0; 3093 bool free_this_block = 0;
3089 3094
3090 for (vector = (struct Lisp_Vector *) block->data; 3095 for (vector = (struct Lisp_Vector *) block->data;
3091 VECTOR_IN_BLOCK (vector, block); vector = next) 3096 VECTOR_IN_BLOCK (vector, block); vector = next)
@@ -3751,7 +3756,7 @@ void
3751memory_full (size_t nbytes) 3756memory_full (size_t nbytes)
3752{ 3757{
3753 /* Do not go into hysterics merely because a large request failed. */ 3758 /* Do not go into hysterics merely because a large request failed. */
3754 int enough_free_memory = 0; 3759 bool enough_free_memory = 0;
3755 if (SPARE_MEMORY < nbytes) 3760 if (SPARE_MEMORY < nbytes)
3756 { 3761 {
3757 void *p; 3762 void *p;
@@ -3814,22 +3819,22 @@ refill_memory_reserve (void)
3814 spare_memory[0] = malloc (SPARE_MEMORY); 3819 spare_memory[0] = malloc (SPARE_MEMORY);
3815 if (spare_memory[1] == 0) 3820 if (spare_memory[1] == 0)
3816 spare_memory[1] = lisp_align_malloc (sizeof (struct cons_block), 3821 spare_memory[1] = lisp_align_malloc (sizeof (struct cons_block),
3817 MEM_TYPE_CONS); 3822 MEM_TYPE_SPARE);
3818 if (spare_memory[2] == 0) 3823 if (spare_memory[2] == 0)
3819 spare_memory[2] = lisp_align_malloc (sizeof (struct cons_block), 3824 spare_memory[2] = lisp_align_malloc (sizeof (struct cons_block),
3820 MEM_TYPE_CONS); 3825 MEM_TYPE_SPARE);
3821 if (spare_memory[3] == 0) 3826 if (spare_memory[3] == 0)
3822 spare_memory[3] = lisp_align_malloc (sizeof (struct cons_block), 3827 spare_memory[3] = lisp_align_malloc (sizeof (struct cons_block),
3823 MEM_TYPE_CONS); 3828 MEM_TYPE_SPARE);
3824 if (spare_memory[4] == 0) 3829 if (spare_memory[4] == 0)
3825 spare_memory[4] = lisp_align_malloc (sizeof (struct cons_block), 3830 spare_memory[4] = lisp_align_malloc (sizeof (struct cons_block),
3826 MEM_TYPE_CONS); 3831 MEM_TYPE_SPARE);
3827 if (spare_memory[5] == 0) 3832 if (spare_memory[5] == 0)
3828 spare_memory[5] = lisp_malloc (sizeof (struct string_block), 3833 spare_memory[5] = lisp_malloc (sizeof (struct string_block),
3829 MEM_TYPE_STRING); 3834 MEM_TYPE_SPARE);
3830 if (spare_memory[6] == 0) 3835 if (spare_memory[6] == 0)
3831 spare_memory[6] = lisp_malloc (sizeof (struct string_block), 3836 spare_memory[6] = lisp_malloc (sizeof (struct string_block),
3832 MEM_TYPE_STRING); 3837 MEM_TYPE_SPARE);
3833 if (spare_memory[0] && spare_memory[1] && spare_memory[5]) 3838 if (spare_memory[0] && spare_memory[1] && spare_memory[5])
3834 Vmemory_full = Qnil; 3839 Vmemory_full = Qnil;
3835#endif 3840#endif
@@ -4244,7 +4249,7 @@ mem_delete_fixup (struct mem_node *x)
4244/* Value is non-zero if P is a pointer to a live Lisp string on 4249/* Value is non-zero if P is a pointer to a live Lisp string on
4245 the heap. M is a pointer to the mem_block for P. */ 4250 the heap. M is a pointer to the mem_block for P. */
4246 4251
4247static inline int 4252static inline bool
4248live_string_p (struct mem_node *m, void *p) 4253live_string_p (struct mem_node *m, void *p)
4249{ 4254{
4250 if (m->type == MEM_TYPE_STRING) 4255 if (m->type == MEM_TYPE_STRING)
@@ -4267,7 +4272,7 @@ live_string_p (struct mem_node *m, void *p)
4267/* Value is non-zero if P is a pointer to a live Lisp cons on 4272/* Value is non-zero if P is a pointer to a live Lisp cons on
4268 the heap. M is a pointer to the mem_block for P. */ 4273 the heap. M is a pointer to the mem_block for P. */
4269 4274
4270static inline int 4275static inline bool
4271live_cons_p (struct mem_node *m, void *p) 4276live_cons_p (struct mem_node *m, void *p)
4272{ 4277{
4273 if (m->type == MEM_TYPE_CONS) 4278 if (m->type == MEM_TYPE_CONS)
@@ -4293,7 +4298,7 @@ live_cons_p (struct mem_node *m, void *p)
4293/* Value is non-zero if P is a pointer to a live Lisp symbol on 4298/* Value is non-zero if P is a pointer to a live Lisp symbol on
4294 the heap. M is a pointer to the mem_block for P. */ 4299 the heap. M is a pointer to the mem_block for P. */
4295 4300
4296static inline int 4301static inline bool
4297live_symbol_p (struct mem_node *m, void *p) 4302live_symbol_p (struct mem_node *m, void *p)
4298{ 4303{
4299 if (m->type == MEM_TYPE_SYMBOL) 4304 if (m->type == MEM_TYPE_SYMBOL)
@@ -4319,7 +4324,7 @@ live_symbol_p (struct mem_node *m, void *p)
4319/* Value is non-zero if P is a pointer to a live Lisp float on 4324/* Value is non-zero if P is a pointer to a live Lisp float on
4320 the heap. M is a pointer to the mem_block for P. */ 4325 the heap. M is a pointer to the mem_block for P. */
4321 4326
4322static inline int 4327static inline bool
4323live_float_p (struct mem_node *m, void *p) 4328live_float_p (struct mem_node *m, void *p)
4324{ 4329{
4325 if (m->type == MEM_TYPE_FLOAT) 4330 if (m->type == MEM_TYPE_FLOAT)
@@ -4343,7 +4348,7 @@ live_float_p (struct mem_node *m, void *p)
4343/* Value is non-zero if P is a pointer to a live Lisp Misc on 4348/* Value is non-zero if P is a pointer to a live Lisp Misc on
4344 the heap. M is a pointer to the mem_block for P. */ 4349 the heap. M is a pointer to the mem_block for P. */
4345 4350
4346static inline int 4351static inline bool
4347live_misc_p (struct mem_node *m, void *p) 4352live_misc_p (struct mem_node *m, void *p)
4348{ 4353{
4349 if (m->type == MEM_TYPE_MISC) 4354 if (m->type == MEM_TYPE_MISC)
@@ -4369,7 +4374,7 @@ live_misc_p (struct mem_node *m, void *p)
4369/* Value is non-zero if P is a pointer to a live vector-like object. 4374/* Value is non-zero if P is a pointer to a live vector-like object.
4370 M is a pointer to the mem_block for P. */ 4375 M is a pointer to the mem_block for P. */
4371 4376
4372static inline int 4377static inline bool
4373live_vector_p (struct mem_node *m, void *p) 4378live_vector_p (struct mem_node *m, void *p)
4374{ 4379{
4375 if (m->type == MEM_TYPE_VECTOR_BLOCK) 4380 if (m->type == MEM_TYPE_VECTOR_BLOCK)
@@ -4405,7 +4410,7 @@ live_vector_p (struct mem_node *m, void *p)
4405/* Value is non-zero if P is a pointer to a live buffer. M is a 4410/* Value is non-zero if P is a pointer to a live buffer. M is a
4406 pointer to the mem_block for P. */ 4411 pointer to the mem_block for P. */
4407 4412
4408static inline int 4413static inline bool
4409live_buffer_p (struct mem_node *m, void *p) 4414live_buffer_p (struct mem_node *m, void *p)
4410{ 4415{
4411 /* P must point to the start of the block, and the buffer 4416 /* P must point to the start of the block, and the buffer
@@ -4485,7 +4490,7 @@ mark_maybe_object (Lisp_Object obj)
4485 4490
4486 if (m != MEM_NIL) 4491 if (m != MEM_NIL)
4487 { 4492 {
4488 int mark_p = 0; 4493 bool mark_p = 0;
4489 4494
4490 switch (XTYPE (obj)) 4495 switch (XTYPE (obj))
4491 { 4496 {
@@ -4559,6 +4564,7 @@ mark_maybe_pointer (void *p)
4559 switch (m->type) 4564 switch (m->type)
4560 { 4565 {
4561 case MEM_TYPE_NON_LISP: 4566 case MEM_TYPE_NON_LISP:
4567 case MEM_TYPE_SPARE:
4562 /* Nothing to do; not a pointer to Lisp memory. */ 4568 /* Nothing to do; not a pointer to Lisp memory. */
4563 break; 4569 break;
4564 4570
@@ -4705,7 +4711,8 @@ mark_memory (void *start, void *end)
4705 4711
4706#if !defined GC_SAVE_REGISTERS_ON_STACK && !defined GC_SETJMP_WORKS 4712#if !defined GC_SAVE_REGISTERS_ON_STACK && !defined GC_SETJMP_WORKS
4707 4713
4708static int setjmp_tested_p, longjmps_done; 4714static bool setjmp_tested_p;
4715static int longjmps_done;
4709 4716
4710#define SETJMP_WILL_LIKELY_WORK "\ 4717#define SETJMP_WILL_LIKELY_WORK "\
4711\n\ 4718\n\
@@ -4749,14 +4756,13 @@ test_setjmp (void)
4749 char buf[10]; 4756 char buf[10];
4750 register int x; 4757 register int x;
4751 jmp_buf jbuf; 4758 jmp_buf jbuf;
4752 int result = 0;
4753 4759
4754 /* Arrange for X to be put in a register. */ 4760 /* Arrange for X to be put in a register. */
4755 sprintf (buf, "1"); 4761 sprintf (buf, "1");
4756 x = strlen (buf); 4762 x = strlen (buf);
4757 x = 2 * x - 1; 4763 x = 2 * x - 1;
4758 4764
4759 setjmp (jbuf); 4765 _setjmp (jbuf);
4760 if (longjmps_done == 1) 4766 if (longjmps_done == 1)
4761 { 4767 {
4762 /* Came here after the longjmp at the end of the function. 4768 /* Came here after the longjmp at the end of the function.
@@ -4781,7 +4787,7 @@ test_setjmp (void)
4781 ++longjmps_done; 4787 ++longjmps_done;
4782 x = 2; 4788 x = 2;
4783 if (longjmps_done == 1) 4789 if (longjmps_done == 1)
4784 longjmp (jbuf, 1); 4790 _longjmp (jbuf, 1);
4785} 4791}
4786 4792
4787#endif /* not GC_SAVE_REGISTERS_ON_STACK && not GC_SETJMP_WORKS */ 4793#endif /* not GC_SAVE_REGISTERS_ON_STACK && not GC_SETJMP_WORKS */
@@ -4908,7 +4914,7 @@ flush_stack_call_func (void (*func) (void *arg), void *arg)
4908 Lisp_Object o; 4914 Lisp_Object o;
4909 jmp_buf j; 4915 jmp_buf j;
4910 } j; 4916 } j;
4911 volatile int stack_grows_down_p = (char *) &j > (char *) stack_bottom; 4917 volatile bool stack_grows_down_p = (char *) &j > (char *) stack_bottom;
4912#endif 4918#endif
4913 /* This trick flushes the register windows so that all the state of 4919 /* This trick flushes the register windows so that all the state of
4914 the process is contained in the stack. */ 4920 the process is contained in the stack. */
@@ -4942,7 +4948,7 @@ flush_stack_call_func (void (*func) (void *arg), void *arg)
4942 } 4948 }
4943#endif /* GC_SETJMP_WORKS */ 4949#endif /* GC_SETJMP_WORKS */
4944 4950
4945 setjmp (j.j); 4951 _setjmp (j.j);
4946 end = stack_grows_down_p ? (char *) &j + sizeof j : (char *) &j; 4952 end = stack_grows_down_p ? (char *) &j + sizeof j : (char *) &j;
4947#endif /* not GC_SAVE_REGISTERS_ON_STACK */ 4953#endif /* not GC_SAVE_REGISTERS_ON_STACK */
4948#endif /* not HAVE___BUILTIN_UNWIND_INIT */ 4954#endif /* not HAVE___BUILTIN_UNWIND_INIT */
@@ -4970,7 +4976,7 @@ valid_pointer_p (void *p)
4970 4976
4971 if (pipe (fd) == 0) 4977 if (pipe (fd) == 0)
4972 { 4978 {
4973 int valid = (emacs_write (fd[1], (char *) p, 16) == 16); 4979 bool valid = emacs_write (fd[1], (char *) p, 16) == 16;
4974 emacs_close (fd[1]); 4980 emacs_close (fd[1]);
4975 emacs_close (fd[0]); 4981 emacs_close (fd[0]);
4976 return valid; 4982 return valid;
@@ -5022,6 +5028,7 @@ valid_lisp_object_p (Lisp_Object obj)
5022 switch (m->type) 5028 switch (m->type)
5023 { 5029 {
5024 case MEM_TYPE_NON_LISP: 5030 case MEM_TYPE_NON_LISP:
5031 case MEM_TYPE_SPARE:
5025 return 0; 5032 return 0;
5026 5033
5027 case MEM_TYPE_BUFFER: 5034 case MEM_TYPE_BUFFER:
@@ -5191,7 +5198,7 @@ find_string_data_in_pure (const char *data, ptrdiff_t nbytes)
5191 5198
5192/* Return a string allocated in pure space. DATA is a buffer holding 5199/* Return a string allocated in pure space. DATA is a buffer holding
5193 NCHARS characters, and NBYTES bytes of string data. MULTIBYTE 5200 NCHARS characters, and NBYTES bytes of string data. MULTIBYTE
5194 non-zero means make the result string multibyte. 5201 means make the result string multibyte.
5195 5202
5196 Must get an error if pure storage is full, since if it cannot hold 5203 Must get an error if pure storage is full, since if it cannot hold
5197 a large string it may be able to hold conses that point to that 5204 a large string it may be able to hold conses that point to that
@@ -5199,7 +5206,7 @@ find_string_data_in_pure (const char *data, ptrdiff_t nbytes)
5199 5206
5200Lisp_Object 5207Lisp_Object
5201make_pure_string (const char *data, 5208make_pure_string (const char *data,
5202 ptrdiff_t nchars, ptrdiff_t nbytes, int multibyte) 5209 ptrdiff_t nchars, ptrdiff_t nbytes, bool multibyte)
5203{ 5210{
5204 Lisp_Object string; 5211 Lisp_Object string;
5205 struct Lisp_String *s = pure_alloc (sizeof *s, Lisp_String); 5212 struct Lisp_String *s = pure_alloc (sizeof *s, Lisp_String);
@@ -5394,11 +5401,11 @@ returns nil, because real GC can't be done.
5394See Info node `(elisp)Garbage Collection'. */) 5401See Info node `(elisp)Garbage Collection'. */)
5395 (void) 5402 (void)
5396{ 5403{
5397 register struct specbinding *bind; 5404 struct specbinding *bind;
5398 register struct buffer *nextb; 5405 struct buffer *nextb;
5399 char stack_top_variable; 5406 char stack_top_variable;
5400 ptrdiff_t i; 5407 ptrdiff_t i;
5401 int message_p; 5408 bool message_p;
5402 ptrdiff_t count = SPECPDL_INDEX (); 5409 ptrdiff_t count = SPECPDL_INDEX ();
5403 EMACS_TIME start; 5410 EMACS_TIME start;
5404 Lisp_Object retval = Qnil; 5411 Lisp_Object retval = Qnil;
@@ -5473,13 +5480,9 @@ See Info node `(elisp)Garbage Collection'. */)
5473 mark_threads (); 5480 mark_threads ();
5474 mark_terminals (); 5481 mark_terminals ();
5475 mark_kboards (); 5482 mark_kboards ();
5476 mark_ttys ();
5477 5483
5478#ifdef USE_GTK 5484#ifdef USE_GTK
5479 { 5485 xg_mark_data ();
5480 extern void xg_mark_data (void);
5481 xg_mark_data ();
5482 }
5483#endif 5486#endif
5484 5487
5485#ifdef HAVE_WINDOW_SYSTEM 5488#ifdef HAVE_WINDOW_SYSTEM
@@ -6181,10 +6184,10 @@ mark_terminals (void)
6181/* Value is non-zero if OBJ will survive the current GC because it's 6184/* Value is non-zero if OBJ will survive the current GC because it's
6182 either marked or does not need to be marked to survive. */ 6185 either marked or does not need to be marked to survive. */
6183 6186
6184int 6187bool
6185survives_gc_p (Lisp_Object obj) 6188survives_gc_p (Lisp_Object obj)
6186{ 6189{
6187 int survives_p; 6190 bool survives_p;
6188 6191
6189 switch (XTYPE (obj)) 6192 switch (XTYPE (obj))
6190 { 6193 {
@@ -6429,7 +6432,7 @@ gc_sweep (void)
6429 /* Check if the symbol was created during loadup. In such a case 6432 /* Check if the symbol was created during loadup. In such a case
6430 it might be pointed to by pure bytecode which we don't trace, 6433 it might be pointed to by pure bytecode which we don't trace,
6431 so we conservatively assume that it is live. */ 6434 so we conservatively assume that it is live. */
6432 int pure_p = PURE_POINTER_P (XSTRING (sym->s.name)); 6435 bool pure_p = PURE_POINTER_P (XSTRING (sym->s.name));
6433 6436
6434 if (!sym->s.gcmarkbit && !pure_p) 6437 if (!sym->s.gcmarkbit && !pure_p)
6435 { 6438 {
@@ -6654,13 +6657,21 @@ which_symbols (Lisp_Object obj, EMACS_INT find_max)
6654} 6657}
6655 6658
6656#ifdef ENABLE_CHECKING 6659#ifdef ENABLE_CHECKING
6657int suppress_checking; 6660
6661# include <execinfo.h>
6662
6663bool suppress_checking;
6658 6664
6659void 6665void
6660die (const char *msg, const char *file, int line) 6666die (const char *msg, const char *file, int line)
6661{ 6667{
6668 enum { NPOINTERS_MAX = 500 };
6669 void *buffer[NPOINTERS_MAX];
6670 int npointers;
6662 fprintf (stderr, "\r\n%s:%d: Emacs fatal error: %s\r\n", 6671 fprintf (stderr, "\r\n%s:%d: Emacs fatal error: %s\r\n",
6663 file, line, msg); 6672 file, line, msg);
6673 npointers = backtrace (buffer, NPOINTERS_MAX);
6674 backtrace_symbols_fd (buffer, npointers, STDERR_FILENO);
6664 abort (); 6675 abort ();
6665} 6676}
6666#endif 6677#endif