Mercurial > emacs
comparison src/alloc.c @ 39572:715a67381594
(purebeg, pure_size, pure_bytes_used_before_overflow):
New variables.
(init_alloc_once): Initialize new variables.
(PURE_POINTER_P): Use new variables.
(pure_alloc): If pure storage overflows, allocate from the heap.
(check_pure_size): New function.
(Fgarbage_collect): Don't GC if pure storage has overflowed.
(Vpost_gc_hook, Qpost_gc_hook): New variables.
(syms_of_alloc): DEFVAR_LISP post-gc-hook, initialize
Qpost_gc_hook.
(Fgarbage_collect): Run post-gc-hook.
(Fmake_symbol): Adapt to changes of struct Lisp_Symbol.
| author | Gerd Moellmann <gerd@gnu.org> |
|---|---|
| date | Fri, 05 Oct 2001 09:42:02 +0000 |
| parents | aff361cfdccb |
| children | a0bf0cb8ff3e |
comparison
equal
deleted
inserted
replaced
| 39571:9b87a63bcb36 | 39572:715a67381594 |
|---|---|
| 189 /* Force it into data space! */ | 189 /* Force it into data space! */ |
| 190 | 190 |
| 191 EMACS_INT pure[PURESIZE / sizeof (EMACS_INT)] = {0,}; | 191 EMACS_INT pure[PURESIZE / sizeof (EMACS_INT)] = {0,}; |
| 192 #define PUREBEG (char *) pure | 192 #define PUREBEG (char *) pure |
| 193 | 193 |
| 194 #else /* not HAVE_SHM */ | 194 #else /* HAVE_SHM */ |
| 195 | 195 |
| 196 #define pure PURE_SEG_BITS /* Use shared memory segment */ | 196 #define pure PURE_SEG_BITS /* Use shared memory segment */ |
| 197 #define PUREBEG (char *)PURE_SEG_BITS | 197 #define PUREBEG (char *)PURE_SEG_BITS |
| 198 | 198 |
| 199 /* This variable is used only by the XPNTR macro when HAVE_SHM is | 199 #endif /* HAVE_SHM */ |
| 200 defined. If we used the PURESIZE macro directly there, that would | 200 |
| 201 make most of Emacs dependent on puresize.h, which we don't want - | 201 /* Pointer to the pure area, and its size. */ |
| 202 you should be able to change that without too much recompilation. | 202 |
| 203 So map_in_data initializes pure_size, and the dependencies work | 203 static char *purebeg; |
| 204 out. */ | 204 static size_t pure_size; |
| 205 | 205 |
| 206 EMACS_INT pure_size; | 206 /* Number of bytes of pure storage used before pure storage overflowed. |
| 207 | 207 If this is non-zero, this implies that an overflow occurred. */ |
| 208 #endif /* not HAVE_SHM */ | 208 |
| 209 static size_t pure_bytes_used_before_overflow; | |
| 209 | 210 |
| 210 /* Value is non-zero if P points into pure space. */ | 211 /* Value is non-zero if P points into pure space. */ |
| 211 | 212 |
| 212 #define PURE_POINTER_P(P) \ | 213 #define PURE_POINTER_P(P) \ |
| 213 (((PNTR_COMPARISON_TYPE) (P) \ | 214 (((PNTR_COMPARISON_TYPE) (P) \ |
| 214 < (PNTR_COMPARISON_TYPE) ((char *) pure + PURESIZE)) \ | 215 < (PNTR_COMPARISON_TYPE) ((char *) purebeg + pure_size)) \ |
| 215 && ((PNTR_COMPARISON_TYPE) (P) \ | 216 && ((PNTR_COMPARISON_TYPE) (P) \ |
| 216 >= (PNTR_COMPARISON_TYPE) pure)) | 217 >= (PNTR_COMPARISON_TYPE) purebeg)) |
| 217 | 218 |
| 218 /* Index in pure at which next pure object will be allocated.. */ | 219 /* Index in pure at which next pure object will be allocated.. */ |
| 219 | 220 |
| 220 int pure_bytes_used; | 221 int pure_bytes_used; |
| 221 | 222 |
| 243 Currently not used. */ | 244 Currently not used. */ |
| 244 | 245 |
| 245 int ignore_warnings; | 246 int ignore_warnings; |
| 246 | 247 |
| 247 Lisp_Object Qgc_cons_threshold, Qchar_table_extra_slots; | 248 Lisp_Object Qgc_cons_threshold, Qchar_table_extra_slots; |
| 249 | |
| 250 /* Hook run after GC has finished. */ | |
| 251 | |
| 252 Lisp_Object Vpost_gc_hook, Qpost_gc_hook; | |
| 248 | 253 |
| 249 static void mark_buffer P_ ((Lisp_Object)); | 254 static void mark_buffer P_ ((Lisp_Object)); |
| 250 static void mark_kboards P_ ((void)); | 255 static void mark_kboards P_ ((void)); |
| 251 static void gc_sweep P_ ((void)); | 256 static void gc_sweep P_ ((void)); |
| 252 static void mark_glyph_matrix P_ ((struct glyph_matrix *)); | 257 static void mark_glyph_matrix P_ ((struct glyph_matrix *)); |
| 2539 XSETSYMBOL (val, &symbol_block->symbols[symbol_block_index++]); | 2544 XSETSYMBOL (val, &symbol_block->symbols[symbol_block_index++]); |
| 2540 } | 2545 } |
| 2541 | 2546 |
| 2542 p = XSYMBOL (val); | 2547 p = XSYMBOL (val); |
| 2543 p->name = XSTRING (name); | 2548 p->name = XSTRING (name); |
| 2544 p->obarray = Qnil; | |
| 2545 p->plist = Qnil; | 2549 p->plist = Qnil; |
| 2546 p->value = Qunbound; | 2550 p->value = Qunbound; |
| 2547 p->function = Qunbound; | 2551 p->function = Qunbound; |
| 2548 p->next = 0; | 2552 p->next = NULL; |
| 2553 p->interned = SYMBOL_UNINTERNED; | |
| 2554 p->constant = 0; | |
| 2555 p->indirect_variable = 0; | |
| 2549 consing_since_gc += sizeof (struct Lisp_Symbol); | 2556 consing_since_gc += sizeof (struct Lisp_Symbol); |
| 2550 symbols_consed++; | 2557 symbols_consed++; |
| 2551 return val; | 2558 return val; |
| 2552 } | 2559 } |
| 2553 | 2560 |
| 3789 size_t size; | 3796 size_t size; |
| 3790 int type; | 3797 int type; |
| 3791 { | 3798 { |
| 3792 size_t nbytes; | 3799 size_t nbytes; |
| 3793 POINTER_TYPE *result; | 3800 POINTER_TYPE *result; |
| 3794 char *beg = PUREBEG; | 3801 char *beg = purebeg; |
| 3795 | 3802 |
| 3796 /* Give Lisp_Floats an extra alignment. */ | 3803 /* Give Lisp_Floats an extra alignment. */ |
| 3797 if (type == Lisp_Float) | 3804 if (type == Lisp_Float) |
| 3798 { | 3805 { |
| 3799 size_t alignment; | 3806 size_t alignment; |
| 3804 #endif | 3811 #endif |
| 3805 pure_bytes_used = ALIGN (pure_bytes_used, alignment); | 3812 pure_bytes_used = ALIGN (pure_bytes_used, alignment); |
| 3806 } | 3813 } |
| 3807 | 3814 |
| 3808 nbytes = ALIGN (size, sizeof (EMACS_INT)); | 3815 nbytes = ALIGN (size, sizeof (EMACS_INT)); |
| 3809 if (pure_bytes_used + nbytes > PURESIZE) | 3816 |
| 3810 error ("Pure Lisp storage exhausted"); | 3817 if (pure_bytes_used + nbytes > pure_size) |
| 3818 { | |
| 3819 beg = purebeg = (char *) xmalloc (PURESIZE); | |
| 3820 pure_size = PURESIZE; | |
| 3821 pure_bytes_used_before_overflow += pure_bytes_used; | |
| 3822 pure_bytes_used = 0; | |
| 3823 } | |
| 3811 | 3824 |
| 3812 result = (POINTER_TYPE *) (beg + pure_bytes_used); | 3825 result = (POINTER_TYPE *) (beg + pure_bytes_used); |
| 3813 pure_bytes_used += nbytes; | 3826 pure_bytes_used += nbytes; |
| 3814 return result; | 3827 return result; |
| 3828 } | |
| 3829 | |
| 3830 | |
| 3831 /* Signal an error if PURESIZE is too small. */ | |
| 3832 | |
| 3833 void | |
| 3834 check_pure_size () | |
| 3835 { | |
| 3836 if (pure_bytes_used_before_overflow) | |
| 3837 error ("Pure Lisp storage overflow (approx. %d bytes needed)", | |
| 3838 (int) (pure_bytes_used + pure_bytes_used_before_overflow)); | |
| 3815 } | 3839 } |
| 3816 | 3840 |
| 3817 | 3841 |
| 3818 /* Return a string allocated in pure space. DATA is a buffer holding | 3842 /* Return a string allocated in pure space. DATA is a buffer holding |
| 3819 NCHARS characters, and NBYTES bytes of string data. MULTIBYTE | 3843 NCHARS characters, and NBYTES bytes of string data. MULTIBYTE |
| 4018 char stack_top_variable; | 4042 char stack_top_variable; |
| 4019 register int i; | 4043 register int i; |
| 4020 int message_p; | 4044 int message_p; |
| 4021 Lisp_Object total[8]; | 4045 Lisp_Object total[8]; |
| 4022 int count = BINDING_STACK_SIZE (); | 4046 int count = BINDING_STACK_SIZE (); |
| 4047 | |
| 4048 /* Can't GC if pure storage overflowed because we can't determine | |
| 4049 if something is a pure object or not. */ | |
| 4050 if (pure_bytes_used_before_overflow) | |
| 4051 return Qnil; | |
| 4023 | 4052 |
| 4024 /* In case user calls debug_print during GC, | 4053 /* In case user calls debug_print during GC, |
| 4025 don't let that cause a recursive GC. */ | 4054 don't let that cause a recursive GC. */ |
| 4026 consing_since_gc = 0; | 4055 consing_since_gc = 0; |
| 4027 | 4056 |
| 4263 max_zombies = max (nzombies, max_zombies); | 4292 max_zombies = max (nzombies, max_zombies); |
| 4264 ++ngcs; | 4293 ++ngcs; |
| 4265 } | 4294 } |
| 4266 #endif | 4295 #endif |
| 4267 | 4296 |
| 4297 if (!NILP (Vpost_gc_hook)) | |
| 4298 { | |
| 4299 int count = inhibit_garbage_collection (); | |
| 4300 safe_run_hooks (Qpost_gc_hook); | |
| 4301 unbind_to (count, Qnil); | |
| 4302 } | |
| 4303 | |
| 4268 return Flist (sizeof total / sizeof *total, total); | 4304 return Flist (sizeof total / sizeof *total, total); |
| 4269 } | 4305 } |
| 4270 | 4306 |
| 4271 | 4307 |
| 4272 /* Mark Lisp objects in glyph matrix MATRIX. Currently the | 4308 /* Mark Lisp objects in glyph matrix MATRIX. Currently the |
| 5355 | 5391 |
| 5356 void | 5392 void |
| 5357 init_alloc_once () | 5393 init_alloc_once () |
| 5358 { | 5394 { |
| 5359 /* Used to do Vpurify_flag = Qt here, but Qt isn't set up yet! */ | 5395 /* Used to do Vpurify_flag = Qt here, but Qt isn't set up yet! */ |
| 5396 purebeg = PUREBEG; | |
| 5397 pure_size = PURESIZE; | |
| 5360 pure_bytes_used = 0; | 5398 pure_bytes_used = 0; |
| 5399 pure_bytes_used_before_overflow = 0; | |
| 5400 | |
| 5361 #if GC_MARK_STACK || defined GC_MALLOC_CHECK | 5401 #if GC_MARK_STACK || defined GC_MALLOC_CHECK |
| 5362 mem_init (); | 5402 mem_init (); |
| 5363 Vdead = make_pure_string ("DEAD", 4, 4, 0); | 5403 Vdead = make_pure_string ("DEAD", 4, 4, 0); |
| 5364 #endif | 5404 #endif |
| 5365 #ifdef HAVE_SHM | 5405 |
| 5366 pure_size = PURESIZE; | |
| 5367 #endif | |
| 5368 all_vectors = 0; | 5406 all_vectors = 0; |
| 5369 ignore_warnings = 1; | 5407 ignore_warnings = 1; |
| 5370 #ifdef DOUG_LEA_MALLOC | 5408 #ifdef DOUG_LEA_MALLOC |
| 5371 mallopt (M_TRIM_THRESHOLD, 128*1024); /* trim threshold */ | 5409 mallopt (M_TRIM_THRESHOLD, 128*1024); /* trim threshold */ |
| 5372 mallopt (M_MMAP_THRESHOLD, 64*1024); /* mmap threshold */ | 5410 mallopt (M_MMAP_THRESHOLD, 64*1024); /* mmap threshold */ |
| 5469 undo_strong_limit = 30000; | 5507 undo_strong_limit = 30000; |
| 5470 | 5508 |
| 5471 DEFVAR_BOOL ("garbage-collection-messages", &garbage_collection_messages, | 5509 DEFVAR_BOOL ("garbage-collection-messages", &garbage_collection_messages, |
| 5472 "Non-nil means display messages at start and end of garbage collection."); | 5510 "Non-nil means display messages at start and end of garbage collection."); |
| 5473 garbage_collection_messages = 0; | 5511 garbage_collection_messages = 0; |
| 5512 | |
| 5513 DEFVAR_LISP ("post-gc-hook", &Vpost_gc_hook, | |
| 5514 "Hook run after garbage collection has finished."); | |
| 5515 Vpost_gc_hook = Qnil; | |
| 5516 Qpost_gc_hook = intern ("post-gc-hook"); | |
| 5517 staticpro (&Qpost_gc_hook); | |
| 5474 | 5518 |
| 5475 /* We build this in advance because if we wait until we need it, we might | 5519 /* We build this in advance because if we wait until we need it, we might |
| 5476 not be able to allocate the memory to hold it. */ | 5520 not be able to allocate the memory to hold it. */ |
| 5477 memory_signal_data | 5521 memory_signal_data |
| 5478 = Fcons (Qerror, Fcons (build_string ("Memory exhausted--use M-x save-some-buffers RET"), Qnil)); | 5522 = Fcons (Qerror, Fcons (build_string ("Memory exhausted--use M-x save-some-buffers RET"), Qnil)); |
