diff options
| author | Tom Tromey | 2013-07-26 14:02:53 -0600 |
|---|---|---|
| committer | Tom Tromey | 2013-07-26 14:02:53 -0600 |
| commit | cc231cbe45d27a1906d268fb72d3b4105a2e9c65 (patch) | |
| tree | c011828e2a3a18e77eaa8849e3cccb805d798f42 /src/alloc.c | |
| parent | b34a529f177a6ea32da5cb1254f91bf9d71838db (diff) | |
| parent | fec9206062b420aca84f53d05a72c3ee43244022 (diff) | |
| download | emacs-cc231cbe45d27a1906d268fb72d3b4105a2e9c65.tar.gz emacs-cc231cbe45d27a1906d268fb72d3b4105a2e9c65.zip | |
merge from trunk
Diffstat (limited to 'src/alloc.c')
| -rw-r--r-- | src/alloc.c | 128 |
1 files changed, 76 insertions, 52 deletions
diff --git a/src/alloc.c b/src/alloc.c index 6ef6af1e3a1..0eb54f8b271 100644 --- a/src/alloc.c +++ b/src/alloc.c | |||
| @@ -209,7 +209,6 @@ Lisp_Object Qchar_table_extra_slots; | |||
| 209 | 209 | ||
| 210 | static Lisp_Object Qpost_gc_hook; | 210 | static Lisp_Object Qpost_gc_hook; |
| 211 | 211 | ||
| 212 | static void free_save_value (Lisp_Object); | ||
| 213 | static void mark_terminals (void); | 212 | static void mark_terminals (void); |
| 214 | static void gc_sweep (void); | 213 | static void gc_sweep (void); |
| 215 | static Lisp_Object make_pure_vector (ptrdiff_t); | 214 | static Lisp_Object make_pure_vector (ptrdiff_t); |
| @@ -334,7 +333,7 @@ static struct mem_node *mem_find (void *); | |||
| 334 | /* Addresses of staticpro'd variables. Initialize it to a nonzero | 333 | /* Addresses of staticpro'd variables. Initialize it to a nonzero |
| 335 | value; otherwise some compilers put it into BSS. */ | 334 | value; otherwise some compilers put it into BSS. */ |
| 336 | 335 | ||
| 337 | #define NSTATICS 0x800 | 336 | enum { NSTATICS = 2048 }; |
| 338 | static Lisp_Object *staticvec[NSTATICS] = {&Vpurify_flag}; | 337 | static Lisp_Object *staticvec[NSTATICS] = {&Vpurify_flag}; |
| 339 | 338 | ||
| 340 | /* Index of next unused slot in staticvec. */ | 339 | /* Index of next unused slot in staticvec. */ |
| @@ -805,22 +804,13 @@ xputenv (char const *string) | |||
| 805 | memory_full (0); | 804 | memory_full (0); |
| 806 | } | 805 | } |
| 807 | 806 | ||
| 808 | /* Unwind for SAFE_ALLOCA */ | ||
| 809 | |||
| 810 | Lisp_Object | ||
| 811 | safe_alloca_unwind (Lisp_Object arg) | ||
| 812 | { | ||
| 813 | free_save_value (arg); | ||
| 814 | return Qnil; | ||
| 815 | } | ||
| 816 | |||
| 817 | /* Return a newly allocated memory block of SIZE bytes, remembering | 807 | /* Return a newly allocated memory block of SIZE bytes, remembering |
| 818 | to free it when unwinding. */ | 808 | to free it when unwinding. */ |
| 819 | void * | 809 | void * |
| 820 | record_xmalloc (size_t size) | 810 | record_xmalloc (size_t size) |
| 821 | { | 811 | { |
| 822 | void *p = xmalloc (size); | 812 | void *p = xmalloc (size); |
| 823 | record_unwind_protect (safe_alloca_unwind, make_save_pointer (p)); | 813 | record_unwind_protect_ptr (xfree, p); |
| 824 | return p; | 814 | return p; |
| 825 | } | 815 | } |
| 826 | 816 | ||
| @@ -3351,67 +3341,101 @@ verify (((SAVE_INTEGER | SAVE_POINTER | SAVE_FUNCPOINTER | SAVE_OBJECT) | |||
| 3351 | >> SAVE_SLOT_BITS) | 3341 | >> SAVE_SLOT_BITS) |
| 3352 | == 0); | 3342 | == 0); |
| 3353 | 3343 | ||
| 3354 | /* Return a Lisp_Save_Value object with the data saved according to | 3344 | /* Return Lisp_Save_Value objects for the various combinations |
| 3355 | DATA_TYPE. DATA_TYPE should be one of SAVE_TYPE_INT_INT, etc. */ | 3345 | that callers need. */ |
| 3356 | 3346 | ||
| 3357 | Lisp_Object | 3347 | Lisp_Object |
| 3358 | make_save_value (enum Lisp_Save_Type save_type, ...) | 3348 | make_save_int_int_int (ptrdiff_t a, ptrdiff_t b, ptrdiff_t c) |
| 3359 | { | 3349 | { |
| 3360 | va_list ap; | ||
| 3361 | int i; | ||
| 3362 | Lisp_Object val = allocate_misc (Lisp_Misc_Save_Value); | 3350 | Lisp_Object val = allocate_misc (Lisp_Misc_Save_Value); |
| 3363 | struct Lisp_Save_Value *p = XSAVE_VALUE (val); | 3351 | struct Lisp_Save_Value *p = XSAVE_VALUE (val); |
| 3352 | p->save_type = SAVE_TYPE_INT_INT_INT; | ||
| 3353 | p->data[0].integer = a; | ||
| 3354 | p->data[1].integer = b; | ||
| 3355 | p->data[2].integer = c; | ||
| 3356 | return val; | ||
| 3357 | } | ||
| 3364 | 3358 | ||
| 3365 | eassert (0 < save_type | 3359 | Lisp_Object |
| 3366 | && (save_type < 1 << (SAVE_TYPE_BITS - 1) | 3360 | make_save_obj_obj_obj_obj (Lisp_Object a, Lisp_Object b, Lisp_Object c, |
| 3367 | || save_type == SAVE_TYPE_MEMORY)); | 3361 | Lisp_Object d) |
| 3368 | p->save_type = save_type; | 3362 | { |
| 3369 | va_start (ap, save_type); | 3363 | Lisp_Object val = allocate_misc (Lisp_Misc_Save_Value); |
| 3370 | save_type &= ~ (1 << (SAVE_TYPE_BITS - 1)); | 3364 | struct Lisp_Save_Value *p = XSAVE_VALUE (val); |
| 3371 | 3365 | p->save_type = SAVE_TYPE_OBJ_OBJ_OBJ_OBJ; | |
| 3372 | for (i = 0; save_type; i++, save_type >>= SAVE_SLOT_BITS) | 3366 | p->data[0].object = a; |
| 3373 | switch (save_type & ((1 << SAVE_SLOT_BITS) - 1)) | 3367 | p->data[1].object = b; |
| 3374 | { | 3368 | p->data[2].object = c; |
| 3375 | case SAVE_POINTER: | 3369 | p->data[3].object = d; |
| 3376 | p->data[i].pointer = va_arg (ap, void *); | 3370 | return val; |
| 3377 | break; | 3371 | } |
| 3378 | |||
| 3379 | case SAVE_FUNCPOINTER: | ||
| 3380 | p->data[i].funcpointer = va_arg (ap, voidfuncptr); | ||
| 3381 | break; | ||
| 3382 | 3372 | ||
| 3383 | case SAVE_INTEGER: | 3373 | #if defined HAVE_NS || defined HAVE_NTGUI |
| 3384 | p->data[i].integer = va_arg (ap, ptrdiff_t); | 3374 | Lisp_Object |
| 3385 | break; | 3375 | make_save_ptr (void *a) |
| 3376 | { | ||
| 3377 | Lisp_Object val = allocate_misc (Lisp_Misc_Save_Value); | ||
| 3378 | struct Lisp_Save_Value *p = XSAVE_VALUE (val); | ||
| 3379 | p->save_type = SAVE_POINTER; | ||
| 3380 | p->data[0].pointer = a; | ||
| 3381 | return val; | ||
| 3382 | } | ||
| 3383 | #endif | ||
| 3386 | 3384 | ||
| 3387 | case SAVE_OBJECT: | 3385 | Lisp_Object |
| 3388 | p->data[i].object = va_arg (ap, Lisp_Object); | 3386 | make_save_ptr_int (void *a, ptrdiff_t b) |
| 3389 | break; | 3387 | { |
| 3388 | Lisp_Object val = allocate_misc (Lisp_Misc_Save_Value); | ||
| 3389 | struct Lisp_Save_Value *p = XSAVE_VALUE (val); | ||
| 3390 | p->save_type = SAVE_TYPE_PTR_INT; | ||
| 3391 | p->data[0].pointer = a; | ||
| 3392 | p->data[1].integer = b; | ||
| 3393 | return val; | ||
| 3394 | } | ||
| 3390 | 3395 | ||
| 3391 | default: | 3396 | #if defined HAVE_MENUS && ! (defined USE_X_TOOLKIT || defined USE_GTK) |
| 3392 | emacs_abort (); | 3397 | Lisp_Object |
| 3393 | } | 3398 | make_save_ptr_ptr (void *a, void *b) |
| 3399 | { | ||
| 3400 | Lisp_Object val = allocate_misc (Lisp_Misc_Save_Value); | ||
| 3401 | struct Lisp_Save_Value *p = XSAVE_VALUE (val); | ||
| 3402 | p->save_type = SAVE_TYPE_PTR_PTR; | ||
| 3403 | p->data[0].pointer = a; | ||
| 3404 | p->data[1].pointer = b; | ||
| 3405 | return val; | ||
| 3406 | } | ||
| 3407 | #endif | ||
| 3394 | 3408 | ||
| 3395 | va_end (ap); | 3409 | Lisp_Object |
| 3410 | make_save_funcptr_ptr_obj (void (*a) (void), void *b, Lisp_Object c) | ||
| 3411 | { | ||
| 3412 | Lisp_Object val = allocate_misc (Lisp_Misc_Save_Value); | ||
| 3413 | struct Lisp_Save_Value *p = XSAVE_VALUE (val); | ||
| 3414 | p->save_type = SAVE_TYPE_FUNCPTR_PTR_OBJ; | ||
| 3415 | p->data[0].funcpointer = a; | ||
| 3416 | p->data[1].pointer = b; | ||
| 3417 | p->data[2].object = c; | ||
| 3396 | return val; | 3418 | return val; |
| 3397 | } | 3419 | } |
| 3398 | 3420 | ||
| 3399 | /* The most common task it to save just one C pointer. */ | 3421 | /* Return a Lisp_Save_Value object that represents an array A |
| 3422 | of N Lisp objects. */ | ||
| 3400 | 3423 | ||
| 3401 | Lisp_Object | 3424 | Lisp_Object |
| 3402 | make_save_pointer (void *pointer) | 3425 | make_save_memory (Lisp_Object *a, ptrdiff_t n) |
| 3403 | { | 3426 | { |
| 3404 | Lisp_Object val = allocate_misc (Lisp_Misc_Save_Value); | 3427 | Lisp_Object val = allocate_misc (Lisp_Misc_Save_Value); |
| 3405 | struct Lisp_Save_Value *p = XSAVE_VALUE (val); | 3428 | struct Lisp_Save_Value *p = XSAVE_VALUE (val); |
| 3406 | p->save_type = SAVE_POINTER; | 3429 | p->save_type = SAVE_TYPE_MEMORY; |
| 3407 | p->data[0].pointer = pointer; | 3430 | p->data[0].pointer = a; |
| 3431 | p->data[1].integer = n; | ||
| 3408 | return val; | 3432 | return val; |
| 3409 | } | 3433 | } |
| 3410 | 3434 | ||
| 3411 | /* Free a Lisp_Save_Value object. Do not use this function | 3435 | /* Free a Lisp_Save_Value object. Do not use this function |
| 3412 | if SAVE contains pointer other than returned by xmalloc. */ | 3436 | if SAVE contains pointer other than returned by xmalloc. */ |
| 3413 | 3437 | ||
| 3414 | static void | 3438 | void |
| 3415 | free_save_value (Lisp_Object save) | 3439 | free_save_value (Lisp_Object save) |
| 3416 | { | 3440 | { |
| 3417 | xfree (XSAVE_POINTER (save, 0)); | 3441 | xfree (XSAVE_POINTER (save, 0)); |
| @@ -4750,7 +4774,7 @@ valid_pointer_p (void *p) | |||
| 4750 | Unfortunately, we cannot use NULL_DEVICE here, as emacs_write may | 4774 | Unfortunately, we cannot use NULL_DEVICE here, as emacs_write may |
| 4751 | not validate p in that case. */ | 4775 | not validate p in that case. */ |
| 4752 | 4776 | ||
| 4753 | if (pipe2 (fd, O_CLOEXEC) == 0) | 4777 | if (emacs_pipe (fd) == 0) |
| 4754 | { | 4778 | { |
| 4755 | bool valid = emacs_write (fd[1], (char *) p, 16) == 16; | 4779 | bool valid = emacs_write (fd[1], (char *) p, 16) == 16; |
| 4756 | emacs_close (fd[1]); | 4780 | emacs_close (fd[1]); |
| @@ -5134,9 +5158,9 @@ Does not copy symbols. Copies strings without text properties. */) | |||
| 5134 | void | 5158 | void |
| 5135 | staticpro (Lisp_Object *varaddress) | 5159 | staticpro (Lisp_Object *varaddress) |
| 5136 | { | 5160 | { |
| 5137 | staticvec[staticidx++] = varaddress; | ||
| 5138 | if (staticidx >= NSTATICS) | 5161 | if (staticidx >= NSTATICS) |
| 5139 | fatal ("NSTATICS too small; try increasing and recompiling Emacs."); | 5162 | fatal ("NSTATICS too small; try increasing and recompiling Emacs."); |
| 5163 | staticvec[staticidx++] = varaddress; | ||
| 5140 | } | 5164 | } |
| 5141 | 5165 | ||
| 5142 | 5166 | ||
| @@ -5236,7 +5260,7 @@ See Info node `(elisp)Garbage Collection'. */) | |||
| 5236 | 5260 | ||
| 5237 | /* Save what's currently displayed in the echo area. */ | 5261 | /* Save what's currently displayed in the echo area. */ |
| 5238 | message_p = push_message (); | 5262 | message_p = push_message (); |
| 5239 | record_unwind_protect (pop_message_unwind, Qnil); | 5263 | record_unwind_protect_void (pop_message_unwind); |
| 5240 | 5264 | ||
| 5241 | /* Save a copy of the contents of the stack, for debugging. */ | 5265 | /* Save a copy of the contents of the stack, for debugging. */ |
| 5242 | #if MAX_SAVE_STACK > 0 | 5266 | #if MAX_SAVE_STACK > 0 |