Mercurial > hg > xemacs-beta
comparison src/alloc.c @ 211:78478c60bfcd r20-4b4
Import from CVS: tag r20-4b4
author | cvs |
---|---|
date | Mon, 13 Aug 2007 10:05:51 +0200 |
parents | e45d5e7c476e |
children | 52952cbfc5b5 |
comparison
equal
deleted
inserted
replaced
210:49f55ca3ba57 | 211:78478c60bfcd |
---|---|
503 * After doing the mark phase, the GC will walk this linked | 503 * After doing the mark phase, the GC will walk this linked |
504 * list and free any record which hasn't been marked | 504 * list and free any record which hasn't been marked |
505 */ | 505 */ |
506 static struct lcrecord_header *all_lcrecords; | 506 static struct lcrecord_header *all_lcrecords; |
507 | 507 |
508 int lrecord_type_index (CONST struct lrecord_implementation *implementation); | |
509 | |
508 void * | 510 void * |
509 alloc_lcrecord (int size, CONST struct lrecord_implementation *implementation) | 511 alloc_lcrecord (int size, CONST struct lrecord_implementation *implementation) |
510 { | 512 { |
511 struct lcrecord_header *lcheader; | 513 struct lcrecord_header *lcheader; |
512 | 514 |
518 } | 520 } |
519 else if (implementation->static_size != size) | 521 else if (implementation->static_size != size) |
520 abort (); | 522 abort (); |
521 | 523 |
522 lcheader = (struct lcrecord_header *) allocate_lisp_storage (size); | 524 lcheader = (struct lcrecord_header *) allocate_lisp_storage (size); |
523 lcheader->lheader.implementation = implementation; | 525 set_lheader_implementation(&(lcheader->lheader), implementation); |
524 lcheader->next = all_lcrecords; | 526 lcheader->next = all_lcrecords; |
525 #if 1 /* mly prefers to see small ID numbers */ | 527 #if 1 /* mly prefers to see small ID numbers */ |
526 lcheader->uid = lrecord_uid_counter++; | 528 lcheader->uid = lrecord_uid_counter++; |
527 #else /* jwz prefers to see real addrs */ | 529 #else /* jwz prefers to see real addrs */ |
528 lcheader->uid = (int) &lcheader; | 530 lcheader->uid = (int) &lcheader; |
577 { | 579 { |
578 struct lcrecord_header *header; | 580 struct lcrecord_header *header; |
579 | 581 |
580 for (header = all_lcrecords; header; header = header->next) | 582 for (header = all_lcrecords; header; header = header->next) |
581 { | 583 { |
582 if (header->lheader.implementation->finalizer && !header->free) | 584 if (LHEADER_IMPLEMENTATION(&header->lheader)->finalizer && |
583 ((header->lheader.implementation->finalizer) (header, 1)); | 585 !header->free) |
586 ((LHEADER_IMPLEMENTATION(&header->lheader)->finalizer) | |
587 (header, 1)); | |
584 } | 588 } |
585 } | 589 } |
586 | 590 |
587 | 591 |
588 /* This must not be called -- it just serves as for EQ test | 592 /* This must not be called -- it just serves as for EQ test |
609 | 613 |
610 /* XGCTYPE for records */ | 614 /* XGCTYPE for records */ |
611 int | 615 int |
612 gc_record_type_p (Lisp_Object frob, CONST struct lrecord_implementation *type) | 616 gc_record_type_p (Lisp_Object frob, CONST struct lrecord_implementation *type) |
613 { | 617 { |
618 #ifdef USE_INDEXED_LRECORD_IMPLEMENTATION | |
619 return (XGCTYPE (frob) == Lisp_Type_Record | |
620 && XRECORD_LHEADER_IMPLEMENTATION (frob) == type); | |
621 #else | |
614 return (XGCTYPE (frob) == Lisp_Type_Record | 622 return (XGCTYPE (frob) == Lisp_Type_Record |
615 && (XRECORD_LHEADER (frob)->implementation == type || | 623 && (XRECORD_LHEADER (frob)->implementation == type || |
616 XRECORD_LHEADER (frob)->implementation == type + 1)); | 624 XRECORD_LHEADER (frob)->implementation == type + 1)); |
625 #endif | |
617 } | 626 } |
618 | 627 |
619 | 628 |
620 /**********************************************************************/ | 629 /**********************************************************************/ |
621 /* Fixed-size type macros */ | 630 /* Fixed-size type macros */ |
1157 { | 1166 { |
1158 Lisp_Object val; | 1167 Lisp_Object val; |
1159 struct Lisp_Float *f; | 1168 struct Lisp_Float *f; |
1160 | 1169 |
1161 ALLOCATE_FIXED_TYPE (float, struct Lisp_Float, f); | 1170 ALLOCATE_FIXED_TYPE (float, struct Lisp_Float, f); |
1162 f->lheader.implementation = lrecord_float; | 1171 set_lheader_implementation (&(f->lheader), lrecord_float); |
1163 float_next (f) = ((struct Lisp_Float *) -1); | 1172 float_next (f) = ((struct Lisp_Float *) -1); |
1164 float_data (f) = float_value; | 1173 float_data (f) = float_value; |
1165 XSETFLOAT (val, f); | 1174 XSETFLOAT (val, f); |
1166 return val; | 1175 return val; |
1167 } | 1176 } |
1557 | 1566 |
1558 if (make_pure && check_purespace (size)) | 1567 if (make_pure && check_purespace (size)) |
1559 { | 1568 { |
1560 b = (struct Lisp_Compiled_Function *) (PUREBEG + pureptr); | 1569 b = (struct Lisp_Compiled_Function *) (PUREBEG + pureptr); |
1561 set_lheader_implementation (&(b->lheader), lrecord_compiled_function); | 1570 set_lheader_implementation (&(b->lheader), lrecord_compiled_function); |
1571 #ifdef USE_INDEXED_LRECORD_IMPLEMENTATION | |
1572 b->lheader.pure = 1; | |
1573 #endif | |
1562 pureptr += size; | 1574 pureptr += size; |
1563 bump_purestat (&purestat_bytecode, size); | 1575 bump_purestat (&purestat_bytecode, size); |
1564 } | 1576 } |
1565 else | 1577 else |
1566 { | 1578 { |
2362 struct free_lcrecord_header *free_header = | 2374 struct free_lcrecord_header *free_header = |
2363 (struct free_lcrecord_header *) lheader; | 2375 (struct free_lcrecord_header *) lheader; |
2364 | 2376 |
2365 #ifdef ERROR_CHECK_GC | 2377 #ifdef ERROR_CHECK_GC |
2366 CONST struct lrecord_implementation *implementation | 2378 CONST struct lrecord_implementation *implementation |
2367 = lheader->implementation; | 2379 = LHEADER_IMPLEMENTATION(lheader); |
2368 | 2380 |
2369 /* There should be no other pointers to the free list. */ | 2381 /* There should be no other pointers to the free list. */ |
2370 assert (!MARKED_RECORD_HEADER_P (lheader)); | 2382 assert (!MARKED_RECORD_HEADER_P (lheader)); |
2371 /* Only lcrecords should be here. */ | 2383 /* Only lcrecords should be here. */ |
2372 assert (!implementation->basic_p); | 2384 assert (!implementation->basic_p); |
2413 | 2425 |
2414 #ifdef ERROR_CHECK_GC | 2426 #ifdef ERROR_CHECK_GC |
2415 struct lrecord_header *lheader = | 2427 struct lrecord_header *lheader = |
2416 (struct lrecord_header *) free_header; | 2428 (struct lrecord_header *) free_header; |
2417 CONST struct lrecord_implementation *implementation | 2429 CONST struct lrecord_implementation *implementation |
2418 = lheader->implementation; | 2430 = LHEADER_IMPLEMENTATION (lheader); |
2419 | 2431 |
2420 /* There should be no other pointers to the free list. */ | 2432 /* There should be no other pointers to the free list. */ |
2421 assert (!MARKED_RECORD_HEADER_P (lheader)); | 2433 assert (!MARKED_RECORD_HEADER_P (lheader)); |
2422 /* Only lcrecords should be here. */ | 2434 /* Only lcrecords should be here. */ |
2423 assert (!implementation->basic_p); | 2435 assert (!implementation->basic_p); |
2450 struct free_lcrecord_header *free_header = | 2462 struct free_lcrecord_header *free_header = |
2451 (struct free_lcrecord_header *) XPNTR (lcrecord); | 2463 (struct free_lcrecord_header *) XPNTR (lcrecord); |
2452 struct lrecord_header *lheader = | 2464 struct lrecord_header *lheader = |
2453 (struct lrecord_header *) free_header; | 2465 (struct lrecord_header *) free_header; |
2454 CONST struct lrecord_implementation *implementation | 2466 CONST struct lrecord_implementation *implementation |
2455 = lheader->implementation; | 2467 = LHEADER_IMPLEMENTATION (lheader); |
2456 | 2468 |
2457 #ifdef ERROR_CHECK_GC | 2469 #ifdef ERROR_CHECK_GC |
2458 /* Make sure the size is correct. This will catch, for example, | 2470 /* Make sure the size is correct. This will catch, for example, |
2459 putting a window configuration on the wrong free list. */ | 2471 putting a window configuration on the wrong free list. */ |
2460 if (implementation->size_in_bytes_method) | 2472 if (implementation->size_in_bytes_method) |
2507 return make_string (data, length); | 2519 return make_string (data, length); |
2508 | 2520 |
2509 s = (struct Lisp_String *) (PUREBEG + pureptr); | 2521 s = (struct Lisp_String *) (PUREBEG + pureptr); |
2510 #ifdef LRECORD_STRING | 2522 #ifdef LRECORD_STRING |
2511 set_lheader_implementation (&(s->lheader), lrecord_string); | 2523 set_lheader_implementation (&(s->lheader), lrecord_string); |
2524 #ifdef USE_INDEXED_LRECORD_IMPLEMENTATION | |
2525 s->lheader.pure = 1; | |
2526 #endif | |
2512 #endif | 2527 #endif |
2513 set_string_length (s, length); | 2528 set_string_length (s, length); |
2514 if (no_need_to_copy_data) | 2529 if (no_need_to_copy_data) |
2515 { | 2530 { |
2516 set_string_data (s, (Bufbyte *) data); | 2531 set_string_data (s, (Bufbyte *) data); |
2563 return Fcons (Fpurecopy (car), Fpurecopy (cdr)); | 2578 return Fcons (Fpurecopy (car), Fpurecopy (cdr)); |
2564 | 2579 |
2565 c = (struct Lisp_Cons *) (PUREBEG + pureptr); | 2580 c = (struct Lisp_Cons *) (PUREBEG + pureptr); |
2566 #ifdef LRECORD_CONS | 2581 #ifdef LRECORD_CONS |
2567 set_lheader_implementation (&(c->lheader), lrecord_cons); | 2582 set_lheader_implementation (&(c->lheader), lrecord_cons); |
2583 #ifdef USE_INDEXED_LRECORD_IMPLEMENTATION | |
2584 c->lheader.pure = 1; | |
2585 #endif | |
2568 #endif | 2586 #endif |
2569 pureptr += sizeof (struct Lisp_Cons); | 2587 pureptr += sizeof (struct Lisp_Cons); |
2570 bump_purestat (&purestat_cons, sizeof (struct Lisp_Cons)); | 2588 bump_purestat (&purestat_cons, sizeof (struct Lisp_Cons)); |
2571 | 2589 |
2572 c->car = Fpurecopy (car); | 2590 c->car = Fpurecopy (car); |
2623 if (!check_purespace (sizeof (struct Lisp_Float))) | 2641 if (!check_purespace (sizeof (struct Lisp_Float))) |
2624 return make_float (num); | 2642 return make_float (num); |
2625 | 2643 |
2626 f = (struct Lisp_Float *) (PUREBEG + pureptr); | 2644 f = (struct Lisp_Float *) (PUREBEG + pureptr); |
2627 set_lheader_implementation (&(f->lheader), lrecord_float); | 2645 set_lheader_implementation (&(f->lheader), lrecord_float); |
2646 #ifdef USE_INDEXED_LRECORD_IMPLEMENTATION | |
2647 f->lheader.pure = 1; | |
2648 #endif | |
2628 pureptr += sizeof (struct Lisp_Float); | 2649 pureptr += sizeof (struct Lisp_Float); |
2629 bump_purestat (&purestat_float, sizeof (struct Lisp_Float)); | 2650 bump_purestat (&purestat_float, sizeof (struct Lisp_Float)); |
2630 | 2651 |
2631 float_next (f) = ((struct Lisp_Float *) -1); | 2652 float_next (f) = ((struct Lisp_Float *) -1); |
2632 float_data (f) = num; | 2653 float_data (f) = num; |
2650 return make_vector (len, init); | 2671 return make_vector (len, init); |
2651 | 2672 |
2652 v = (struct Lisp_Vector *) (PUREBEG + pureptr); | 2673 v = (struct Lisp_Vector *) (PUREBEG + pureptr); |
2653 #ifdef LRECORD_VECTOR | 2674 #ifdef LRECORD_VECTOR |
2654 set_lheader_implementation (&(v->header.lheader), lrecord_vector); | 2675 set_lheader_implementation (&(v->header.lheader), lrecord_vector); |
2676 #ifdef USE_INDEXED_LRECORD_IMPLEMENTATION | |
2677 v->header.lheader.pure = 1; | |
2678 #endif | |
2655 #endif | 2679 #endif |
2656 pureptr += size; | 2680 pureptr += size; |
2657 bump_purestat (&purestat_vector_all, size); | 2681 bump_purestat (&purestat_vector_all, size); |
2658 | 2682 |
2659 v->size = len; | 2683 v->size = len; |
3000 case Lisp_Type_Record: | 3024 case Lisp_Type_Record: |
3001 /* case Lisp_Symbol_Value_Magic: */ | 3025 /* case Lisp_Symbol_Value_Magic: */ |
3002 { | 3026 { |
3003 struct lrecord_header *lheader = XRECORD_LHEADER (obj); | 3027 struct lrecord_header *lheader = XRECORD_LHEADER (obj); |
3004 CONST struct lrecord_implementation *implementation | 3028 CONST struct lrecord_implementation *implementation |
3005 = lheader->implementation; | 3029 = LHEADER_IMPLEMENTATION (lheader); |
3006 | 3030 |
3007 if (! MARKED_RECORD_HEADER_P (lheader) && | 3031 if (! MARKED_RECORD_HEADER_P (lheader) && |
3008 ! UNMARKABLE_RECORD_HEADER_P (lheader)) | 3032 ! UNMARKABLE_RECORD_HEADER_P (lheader)) |
3009 { | 3033 { |
3010 MARK_RECORD_HEADER (lheader); | 3034 MARK_RECORD_HEADER (lheader); |
3207 | 3231 |
3208 case Lisp_Type_Record: | 3232 case Lisp_Type_Record: |
3209 { | 3233 { |
3210 struct lrecord_header *lheader = XRECORD_LHEADER (obj); | 3234 struct lrecord_header *lheader = XRECORD_LHEADER (obj); |
3211 CONST struct lrecord_implementation *implementation | 3235 CONST struct lrecord_implementation *implementation |
3212 = lheader->implementation; | 3236 = LHEADER_IMPLEMENTATION (lheader); |
3213 | 3237 |
3214 #ifdef LRECORD_STRING | 3238 #ifdef LRECORD_STRING |
3215 if (STRINGP (obj)) | 3239 if (STRINGP (obj)) |
3216 total += pure_string_sizeof (obj); | 3240 total += pure_string_sizeof (obj); |
3217 else | 3241 else |
3291 | 3315 |
3292 | 3316 |
3293 /* This will be used more extensively In The Future */ | 3317 /* This will be used more extensively In The Future */ |
3294 static int last_lrecord_type_index_assigned; | 3318 static int last_lrecord_type_index_assigned; |
3295 | 3319 |
3296 static CONST struct lrecord_implementation *lrecord_implementations_table[128]; | 3320 CONST struct lrecord_implementation *lrecord_implementations_table[128]; |
3297 #define max_lrecord_type (countof (lrecord_implementations_table) - 1) | 3321 #define max_lrecord_type (countof (lrecord_implementations_table) - 1) |
3298 | 3322 |
3299 static int | 3323 int |
3300 lrecord_type_index (CONST struct lrecord_implementation *implementation) | 3324 lrecord_type_index (CONST struct lrecord_implementation *implementation) |
3301 { | 3325 { |
3302 int type_index = *(implementation->lrecord_type_index); | 3326 int type_index = *(implementation->lrecord_type_index); |
3303 /* Have to do this circuitous and validation test because of problems | 3327 /* Have to do this circuitous and validation test because of problems |
3304 dumping out initialized variables (ie can't set xxx_type_index to -1 | 3328 dumping out initialized variables (ie can't set xxx_type_index to -1 |
3342 } | 3366 } |
3343 | 3367 |
3344 static void | 3368 static void |
3345 tick_lcrecord_stats (CONST struct lrecord_header *h, int free_p) | 3369 tick_lcrecord_stats (CONST struct lrecord_header *h, int free_p) |
3346 { | 3370 { |
3347 CONST struct lrecord_implementation *implementation = h->implementation; | 3371 CONST struct lrecord_implementation *implementation = |
3372 LHEADER_IMPLEMENTATION (h); | |
3348 int type_index = lrecord_type_index (implementation); | 3373 int type_index = lrecord_type_index (implementation); |
3349 | 3374 |
3350 if (((struct lcrecord_header *) h)->free) | 3375 if (((struct lcrecord_header *) h)->free) |
3351 { | 3376 { |
3352 assert (!free_p); | 3377 assert (!free_p); |
3394 for (header = *prev; header; header = header->next) | 3419 for (header = *prev; header; header = header->next) |
3395 { | 3420 { |
3396 struct lrecord_header *h = &(header->lheader); | 3421 struct lrecord_header *h = &(header->lheader); |
3397 if (!MARKED_RECORD_HEADER_P (h) && ! (header->free)) | 3422 if (!MARKED_RECORD_HEADER_P (h) && ! (header->free)) |
3398 { | 3423 { |
3399 if (h->implementation->finalizer) | 3424 if (LHEADER_IMPLEMENTATION (h)->finalizer) |
3400 ((h->implementation->finalizer) (h, 0)); | 3425 ((LHEADER_IMPLEMENTATION (h)->finalizer) (h, 0)); |
3401 } | 3426 } |
3402 } | 3427 } |
3403 | 3428 |
3404 for (header = *prev; header; ) | 3429 for (header = *prev; header; ) |
3405 { | 3430 { |
4803 for (iii = 0; iii < countof (lrecord_implementations_table); iii++) | 4828 for (iii = 0; iii < countof (lrecord_implementations_table); iii++) |
4804 { | 4829 { |
4805 lrecord_implementations_table[iii] = 0; | 4830 lrecord_implementations_table[iii] = 0; |
4806 } | 4831 } |
4807 | 4832 |
4833 #ifdef USE_INDEXED_LRECORD_IMPLEMENTATION | |
4834 /* | |
4835 * If USE_INDEXED_LRECORD_IMPLEMENTATION is defined, all the staticly | |
4836 * defined subr lrecords were initialized with lheader->type == 0. | |
4837 * See subr_lheader_initializer in lisp.h. Force type index 0 to be | |
4838 * assigned to lrecord_subr so that those predefined indexes match | |
4839 * reality. | |
4840 */ | |
4841 (void) lrecord_type_index (lrecord_subr); | |
4842 assert (*(lrecord_subr[0].lrecord_type_index) == 0); | |
4843 /* | |
4844 * The same is true for symbol_value_forward objects, except the | |
4845 * type is 1. | |
4846 */ | |
4847 (void) lrecord_type_index (lrecord_symbol_value_forward); | |
4848 assert (*(lrecord_symbol_value_forward[0].lrecord_type_index) == 1); | |
4849 #endif | |
4850 | |
4808 symbols_initialized = 0; | 4851 symbols_initialized = 0; |
4809 | 4852 |
4810 gc_generation_number[0] = 0; | 4853 gc_generation_number[0] = 0; |
4811 /* purify_flag 1 is correct even if CANNOT_DUMP. | 4854 /* purify_flag 1 is correct even if CANNOT_DUMP. |
4812 * loadup.el will set to nil at end. */ | 4855 * loadup.el will set to nil at end. */ |