diff options
Diffstat (limited to 'src/alloc.c')
| -rw-r--r-- | src/alloc.c | 153 |
1 files changed, 78 insertions, 75 deletions
diff --git a/src/alloc.c b/src/alloc.c index 47e75f50a8e..a50eaa0a560 100644 --- a/src/alloc.c +++ b/src/alloc.c | |||
| @@ -215,7 +215,7 @@ EMACS_INT pure_size; | |||
| 215 | 215 | ||
| 216 | /* Index in pure at which next pure object will be allocated.. */ | 216 | /* Index in pure at which next pure object will be allocated.. */ |
| 217 | 217 | ||
| 218 | int pureptr; | 218 | int pure_bytes_used; |
| 219 | 219 | ||
| 220 | /* If nonzero, this is a warning delivered by malloc and not yet | 220 | /* If nonzero, this is a warning delivered by malloc and not yet |
| 221 | displayed. */ | 221 | displayed. */ |
| @@ -318,6 +318,28 @@ static void check_gcpros P_ ((void)); | |||
| 318 | 318 | ||
| 319 | #endif /* GC_MARK_STACK != 0 */ | 319 | #endif /* GC_MARK_STACK != 0 */ |
| 320 | 320 | ||
| 321 | /* Recording what needs to be marked for gc. */ | ||
| 322 | |||
| 323 | struct gcpro *gcprolist; | ||
| 324 | |||
| 325 | /* Addresses of staticpro'd variables. */ | ||
| 326 | |||
| 327 | #define NSTATICS 1024 | ||
| 328 | Lisp_Object *staticvec[NSTATICS] = {0}; | ||
| 329 | |||
| 330 | /* Index of next unused slot in staticvec. */ | ||
| 331 | |||
| 332 | int staticidx = 0; | ||
| 333 | |||
| 334 | static POINTER_TYPE *pure_alloc P_ ((size_t, int)); | ||
| 335 | |||
| 336 | |||
| 337 | /* Value is SZ rounded up to the next multiple of ALIGNMENT. | ||
| 338 | ALIGNMENT must be a power of 2. */ | ||
| 339 | |||
| 340 | #define ALIGN(SZ, ALIGNMENT) \ | ||
| 341 | (((SZ) + (ALIGNMENT) - 1) & ~((ALIGNMENT) - 1)) | ||
| 342 | |||
| 321 | 343 | ||
| 322 | /************************************************************************ | 344 | /************************************************************************ |
| 323 | Malloc | 345 | Malloc |
| @@ -3320,6 +3342,44 @@ mark_stack () | |||
| 3320 | Pure Storage Management | 3342 | Pure Storage Management |
| 3321 | ***********************************************************************/ | 3343 | ***********************************************************************/ |
| 3322 | 3344 | ||
| 3345 | /* Allocate room for SIZE bytes from pure Lisp storage and return a | ||
| 3346 | pointer to it. TYPE is the Lisp type for which the memory is | ||
| 3347 | allocated. TYPE < 0 means it's not used for a Lisp object. | ||
| 3348 | |||
| 3349 | If store_pure_type_info is set and TYPE is >= 0, the type of | ||
| 3350 | the allocated object is recorded in pure_types. */ | ||
| 3351 | |||
| 3352 | static POINTER_TYPE * | ||
| 3353 | pure_alloc (size, type) | ||
| 3354 | size_t size; | ||
| 3355 | int type; | ||
| 3356 | { | ||
| 3357 | size_t nbytes; | ||
| 3358 | POINTER_TYPE *result; | ||
| 3359 | char *beg = PUREBEG; | ||
| 3360 | |||
| 3361 | /* Give Lisp_Floats an extra alignment. */ | ||
| 3362 | if (type == Lisp_Float) | ||
| 3363 | { | ||
| 3364 | size_t alignment; | ||
| 3365 | #if defined __GNUC__ && __GNUC__ >= 2 | ||
| 3366 | alignment = __alignof (struct Lisp_Float); | ||
| 3367 | #else | ||
| 3368 | alignment = sizeof (struct Lisp_Float); | ||
| 3369 | #endif | ||
| 3370 | pure_bytes_used = ALIGN (pure_bytes_used, alignment); | ||
| 3371 | } | ||
| 3372 | |||
| 3373 | nbytes = ALIGN (size, sizeof (EMACS_INT)); | ||
| 3374 | if (pure_bytes_used + nbytes > PURESIZE) | ||
| 3375 | error ("Pure Lisp storage exhausted"); | ||
| 3376 | |||
| 3377 | result = (POINTER_TYPE *) (beg + pure_bytes_used); | ||
| 3378 | pure_bytes_used += nbytes; | ||
| 3379 | return result; | ||
| 3380 | } | ||
| 3381 | |||
| 3382 | |||
| 3323 | /* Return a string allocated in pure space. DATA is a buffer holding | 3383 | /* Return a string allocated in pure space. DATA is a buffer holding |
| 3324 | NCHARS characters, and NBYTES bytes of string data. MULTIBYTE | 3384 | NCHARS characters, and NBYTES bytes of string data. MULTIBYTE |
| 3325 | non-zero means make the result string multibyte. | 3385 | non-zero means make the result string multibyte. |
| @@ -3336,29 +3396,14 @@ make_pure_string (data, nchars, nbytes, multibyte) | |||
| 3336 | { | 3396 | { |
| 3337 | Lisp_Object string; | 3397 | Lisp_Object string; |
| 3338 | struct Lisp_String *s; | 3398 | struct Lisp_String *s; |
| 3339 | int string_size, data_size; | ||
| 3340 | 3399 | ||
| 3341 | #define PAD(SZ) (((SZ) + sizeof (EMACS_INT) - 1) & ~(sizeof (EMACS_INT) - 1)) | 3400 | s = (struct Lisp_String *) pure_alloc (sizeof *s, Lisp_String); |
| 3342 | 3401 | s->data = (unsigned char *) pure_alloc (nbytes + 1, -1); | |
| 3343 | string_size = PAD (sizeof (struct Lisp_String)); | ||
| 3344 | data_size = PAD (nbytes + 1); | ||
| 3345 | |||
| 3346 | #undef PAD | ||
| 3347 | |||
| 3348 | if (pureptr + string_size + data_size > PURESIZE) | ||
| 3349 | error ("Pure Lisp storage exhausted"); | ||
| 3350 | |||
| 3351 | s = (struct Lisp_String *) (PUREBEG + pureptr); | ||
| 3352 | pureptr += string_size; | ||
| 3353 | s->data = (unsigned char *) (PUREBEG + pureptr); | ||
| 3354 | pureptr += data_size; | ||
| 3355 | |||
| 3356 | s->size = nchars; | 3402 | s->size = nchars; |
| 3357 | s->size_byte = multibyte ? nbytes : -1; | 3403 | s->size_byte = multibyte ? nbytes : -1; |
| 3358 | bcopy (data, s->data, nbytes); | 3404 | bcopy (data, s->data, nbytes); |
| 3359 | s->data[nbytes] = '\0'; | 3405 | s->data[nbytes] = '\0'; |
| 3360 | s->intervals = NULL_INTERVAL; | 3406 | s->intervals = NULL_INTERVAL; |
| 3361 | |||
| 3362 | XSETSTRING (string, s); | 3407 | XSETSTRING (string, s); |
| 3363 | return string; | 3408 | return string; |
| 3364 | } | 3409 | } |
| @@ -3372,11 +3417,10 @@ pure_cons (car, cdr) | |||
| 3372 | Lisp_Object car, cdr; | 3417 | Lisp_Object car, cdr; |
| 3373 | { | 3418 | { |
| 3374 | register Lisp_Object new; | 3419 | register Lisp_Object new; |
| 3420 | struct Lisp_Cons *p; | ||
| 3375 | 3421 | ||
| 3376 | if (pureptr + sizeof (struct Lisp_Cons) > PURESIZE) | 3422 | p = (struct Lisp_Cons *) pure_alloc (sizeof *p, Lisp_Cons); |
| 3377 | error ("Pure Lisp storage exhausted"); | 3423 | XSETCONS (new, p); |
| 3378 | XSETCONS (new, PUREBEG + pureptr); | ||
| 3379 | pureptr += sizeof (struct Lisp_Cons); | ||
| 3380 | XCAR (new) = Fpurecopy (car); | 3424 | XCAR (new) = Fpurecopy (car); |
| 3381 | XCDR (new) = Fpurecopy (cdr); | 3425 | XCDR (new) = Fpurecopy (cdr); |
| 3382 | return new; | 3426 | return new; |
| @@ -3390,34 +3434,11 @@ make_pure_float (num) | |||
| 3390 | double num; | 3434 | double num; |
| 3391 | { | 3435 | { |
| 3392 | register Lisp_Object new; | 3436 | register Lisp_Object new; |
| 3437 | struct Lisp_Float *p; | ||
| 3393 | 3438 | ||
| 3394 | /* Make sure that PUREBEG + pureptr is aligned on at least a sizeof | 3439 | p = (struct Lisp_Float *) pure_alloc (sizeof *p, Lisp_Float); |
| 3395 | (double) boundary. Some architectures (like the sparc) require | 3440 | XSETFLOAT (new, p); |
| 3396 | this, and I suspect that floats are rare enough that it's no | ||
| 3397 | tragedy for those that do. */ | ||
| 3398 | { | ||
| 3399 | size_t alignment; | ||
| 3400 | char *p = PUREBEG + pureptr; | ||
| 3401 | |||
| 3402 | #ifdef __GNUC__ | ||
| 3403 | #if __GNUC__ >= 2 | ||
| 3404 | alignment = __alignof (struct Lisp_Float); | ||
| 3405 | #else | ||
| 3406 | alignment = sizeof (struct Lisp_Float); | ||
| 3407 | #endif | ||
| 3408 | #else | ||
| 3409 | alignment = sizeof (struct Lisp_Float); | ||
| 3410 | #endif | ||
| 3411 | p = (char *) (((unsigned long) p + alignment - 1) & - alignment); | ||
| 3412 | pureptr = p - PUREBEG; | ||
| 3413 | } | ||
| 3414 | |||
| 3415 | if (pureptr + sizeof (struct Lisp_Float) > PURESIZE) | ||
| 3416 | error ("Pure Lisp storage exhausted"); | ||
| 3417 | XSETFLOAT (new, PUREBEG + pureptr); | ||
| 3418 | pureptr += sizeof (struct Lisp_Float); | ||
| 3419 | XFLOAT_DATA (new) = num; | 3441 | XFLOAT_DATA (new) = num; |
| 3420 | XSETFASTINT (XFLOAT (new)->type, 0); /* bug chasing -wsr */ | ||
| 3421 | return new; | 3442 | return new; |
| 3422 | } | 3443 | } |
| 3423 | 3444 | ||
| @@ -3429,15 +3450,12 @@ Lisp_Object | |||
| 3429 | make_pure_vector (len) | 3450 | make_pure_vector (len) |
| 3430 | EMACS_INT len; | 3451 | EMACS_INT len; |
| 3431 | { | 3452 | { |
| 3432 | register Lisp_Object new; | 3453 | Lisp_Object new; |
| 3433 | register EMACS_INT size = (sizeof (struct Lisp_Vector) | 3454 | struct Lisp_Vector *p; |
| 3434 | + (len - 1) * sizeof (Lisp_Object)); | 3455 | size_t size = sizeof *p + (len - 1) * sizeof (Lisp_Object); |
| 3435 | |||
| 3436 | if (pureptr + size > PURESIZE) | ||
| 3437 | error ("Pure Lisp storage exhausted"); | ||
| 3438 | 3456 | ||
| 3439 | XSETVECTOR (new, PUREBEG + pureptr); | 3457 | p = (struct Lisp_Vector *) pure_alloc (size, Lisp_Vectorlike); |
| 3440 | pureptr += size; | 3458 | XSETVECTOR (new, p); |
| 3441 | XVECTOR (new)->size = len; | 3459 | XVECTOR (new)->size = len; |
| 3442 | return new; | 3460 | return new; |
| 3443 | } | 3461 | } |
| @@ -3453,8 +3471,7 @@ Does not copy symbols. Copies strings without text properties.") | |||
| 3453 | if (NILP (Vpurify_flag)) | 3471 | if (NILP (Vpurify_flag)) |
| 3454 | return obj; | 3472 | return obj; |
| 3455 | 3473 | ||
| 3456 | if ((PNTR_COMPARISON_TYPE) XPNTR (obj) < (PNTR_COMPARISON_TYPE) ((char *) pure + PURESIZE) | 3474 | if (PURE_POINTER_P (XPNTR (obj))) |
| 3457 | && (PNTR_COMPARISON_TYPE) XPNTR (obj) >= (PNTR_COMPARISON_TYPE) pure) | ||
| 3458 | return obj; | 3475 | return obj; |
| 3459 | 3476 | ||
| 3460 | if (CONSP (obj)) | 3477 | if (CONSP (obj)) |
| @@ -3494,20 +3511,6 @@ Does not copy symbols. Copies strings without text properties.") | |||
| 3494 | Protection from GC | 3511 | Protection from GC |
| 3495 | ***********************************************************************/ | 3512 | ***********************************************************************/ |
| 3496 | 3513 | ||
| 3497 | /* Recording what needs to be marked for gc. */ | ||
| 3498 | |||
| 3499 | struct gcpro *gcprolist; | ||
| 3500 | |||
| 3501 | /* Addresses of staticpro'd variables. */ | ||
| 3502 | |||
| 3503 | #define NSTATICS 1024 | ||
| 3504 | Lisp_Object *staticvec[NSTATICS] = {0}; | ||
| 3505 | |||
| 3506 | /* Index of next unused slot in staticvec. */ | ||
| 3507 | |||
| 3508 | int staticidx = 0; | ||
| 3509 | |||
| 3510 | |||
| 3511 | /* Put an entry in staticvec, pointing at the variable with address | 3514 | /* Put an entry in staticvec, pointing at the variable with address |
| 3512 | VARADDRESS. */ | 3515 | VARADDRESS. */ |
| 3513 | 3516 | ||
| @@ -3933,7 +3936,7 @@ mark_object (argptr) | |||
| 3933 | loop2: | 3936 | loop2: |
| 3934 | XUNMARK (obj); | 3937 | XUNMARK (obj); |
| 3935 | 3938 | ||
| 3936 | if (PURE_POINTER_P ((PNTR_COMPARISON_TYPE) XPNTR (obj))) | 3939 | if (PURE_POINTER_P (XPNTR (obj))) |
| 3937 | return; | 3940 | return; |
| 3938 | 3941 | ||
| 3939 | last_marked[last_marked_index++] = objptr; | 3942 | last_marked[last_marked_index++] = objptr; |
| @@ -4903,7 +4906,7 @@ void | |||
| 4903 | init_alloc_once () | 4906 | init_alloc_once () |
| 4904 | { | 4907 | { |
| 4905 | /* Used to do Vpurify_flag = Qt here, but Qt isn't set up yet! */ | 4908 | /* Used to do Vpurify_flag = Qt here, but Qt isn't set up yet! */ |
| 4906 | pureptr = 0; | 4909 | pure_bytes_used = 0; |
| 4907 | #if GC_MARK_STACK | 4910 | #if GC_MARK_STACK |
| 4908 | mem_init (); | 4911 | mem_init (); |
| 4909 | Vdead = make_pure_string ("DEAD", 4, 4, 0); | 4912 | Vdead = make_pure_string ("DEAD", 4, 4, 0); |
| @@ -4968,7 +4971,7 @@ Garbage collection happens automatically only when `eval' is called.\n\n\ | |||
| 4968 | By binding this temporarily to a large number, you can effectively\n\ | 4971 | By binding this temporarily to a large number, you can effectively\n\ |
| 4969 | prevent garbage collection during a part of the program."); | 4972 | prevent garbage collection during a part of the program."); |
| 4970 | 4973 | ||
| 4971 | DEFVAR_INT ("pure-bytes-used", &pureptr, | 4974 | DEFVAR_INT ("pure-bytes-used", &pure_bytes_used, |
| 4972 | "Number of bytes of sharable Lisp data allocated so far."); | 4975 | "Number of bytes of sharable Lisp data allocated so far."); |
| 4973 | 4976 | ||
| 4974 | DEFVAR_INT ("cons-cells-consed", &cons_cells_consed, | 4977 | DEFVAR_INT ("cons-cells-consed", &cons_cells_consed, |