Mercurial > hg > xemacs-beta
comparison src/alloc.c @ 5059:c8f90d61dcf3
fix memory usage stats to include pdumped objects
-------------------- ChangeLog entries follow: --------------------
lisp/ChangeLog addition:
2010-02-21 Ben Wing <ben@xemacs.org>
* diagnose.el:
* diagnose.el (show-object-memory-usage-stats):
Fix errors preventing this from working properly, account for
words like "entry" pluralized to "entries".
src/ChangeLog addition:
2010-02-21 Ben Wing <ben@xemacs.org>
* alloc.c:
* alloc.c (FREE_FIXED_TYPE_WHEN_NOT_IN_GC):
* alloc.c (struct):
* alloc.c (tick_lrecord_stats):
* alloc.c (tick_lcrecord_stats):
* alloc.c (sweep_lcrecords_1):
* alloc.c (COUNT_FROB_BLOCK_USAGE):
* alloc.c (SWEEP_FIXED_TYPE_BLOCK_1):
* alloc.c (free_cons):
* alloc.c (free_key_data):
* alloc.c (free_button_data):
* alloc.c (free_motion_data):
* alloc.c (free_process_data):
* alloc.c (free_timeout_data):
* alloc.c (free_magic_data):
* alloc.c (free_magic_eval_data):
* alloc.c (free_eval_data):
* alloc.c (free_misc_user_data):
* alloc.c (free_marker):
* alloc.c (gc_sweep_1):
* alloc.c (HACK_O_MATIC):
* alloc.c (FROB):
* alloc.c (object_memory_usage_stats):
* alloc.c (Fgarbage_collect):
* dumper.c:
* dumper.c (pdump_objects_unmark):
* lrecord.h:
* lrecord.h (enum lrecord_alloc_status):
Fixes to memory-usage-tracking code, etc.
(1) Incorporate NEW_GC stuff into FREE_FIXED_TYPE_WHEN_NOT_IN_GC
to avoid duplication.
(2) Rewrite tick_lcrecord_stats() to include separate
tick_lrecord_stats(); use in dumper.c to note pdumped objects.
(3) Instead of handling frob-block objects specially in
object_memory_usage_stats(), have SWEEP_FIXED_TYPE_BLOCK_1
increment the stats in lrecord_stats[] so that they get handled
like other objects.
(4) Pluralize entry as entries, etc.
author | Ben Wing <ben@xemacs.org> |
---|---|
date | Sun, 21 Feb 2010 15:29:12 -0600 |
parents | eb17f0c176ac |
children | 151d425f8ef0 |
comparison
equal
deleted
inserted
replaced
5058:eb17f0c176ac | 5059:c8f90d61dcf3 |
---|---|
1148 ADDITIONAL_FREE_##type (FFT_ptr); \ | 1148 ADDITIONAL_FREE_##type (FFT_ptr); \ |
1149 deadbeef_memory (FFT_ptr, sizeof (structtype)); \ | 1149 deadbeef_memory (FFT_ptr, sizeof (structtype)); \ |
1150 PUT_FIXED_TYPE_ON_FREE_LIST (type, structtype, FFT_ptr); \ | 1150 PUT_FIXED_TYPE_ON_FREE_LIST (type, structtype, FFT_ptr); \ |
1151 MARK_LRECORD_AS_FREE (FFT_ptr); \ | 1151 MARK_LRECORD_AS_FREE (FFT_ptr); \ |
1152 } while (0) | 1152 } while (0) |
1153 | 1153 #endif /* NEW_GC */ |
1154 | |
1155 #ifdef NEW_GC | |
1156 #define FREE_FIXED_TYPE_WHEN_NOT_IN_GC(lo, type, structtype, ptr) \ | |
1157 free_lrecord (lo) | |
1158 #else /* not NEW_GC */ | |
1154 /* Like FREE_FIXED_TYPE() but used when we are explicitly | 1159 /* Like FREE_FIXED_TYPE() but used when we are explicitly |
1155 freeing a structure through free_cons(), free_marker(), etc. | 1160 freeing a structure through free_cons(), free_marker(), etc. |
1156 rather than through the normal process of sweeping. | 1161 rather than through the normal process of sweeping. |
1157 We attempt to undo the changes made to the allocation counters | 1162 We attempt to undo the changes made to the allocation counters |
1158 as a result of this structure being allocated. This is not | 1163 as a result of this structure being allocated. This is not |
1163 | 1168 |
1164 We also disable this mechanism entirely when ALLOC_NO_POOLS is | 1169 We also disable this mechanism entirely when ALLOC_NO_POOLS is |
1165 set, which is used for Purify and the like. */ | 1170 set, which is used for Purify and the like. */ |
1166 | 1171 |
1167 #ifndef ALLOC_NO_POOLS | 1172 #ifndef ALLOC_NO_POOLS |
1168 #define FREE_FIXED_TYPE_WHEN_NOT_IN_GC(type, structtype, ptr) \ | 1173 #define FREE_FIXED_TYPE_WHEN_NOT_IN_GC(lo, type, structtype, ptr) \ |
1169 do { FREE_FIXED_TYPE (type, structtype, ptr); \ | 1174 do { FREE_FIXED_TYPE (type, structtype, ptr); \ |
1170 DECREMENT_CONS_COUNTER (sizeof (structtype)); \ | 1175 DECREMENT_CONS_COUNTER (sizeof (structtype)); \ |
1171 gc_count_num_##type##_freelist++; \ | 1176 gc_count_num_##type##_freelist++; \ |
1172 } while (0) | 1177 } while (0) |
1173 #else | 1178 #else |
1174 #define FREE_FIXED_TYPE_WHEN_NOT_IN_GC(type, structtype, ptr) | 1179 #define FREE_FIXED_TYPE_WHEN_NOT_IN_GC(lo, type, structtype, ptr) |
1175 #endif | 1180 #endif |
1176 #endif /* NEW_GC */ | 1181 #endif /* (not) NEW_GC */ |
1177 | 1182 |
1178 #ifdef NEW_GC | 1183 #ifdef NEW_GC |
1179 #define ALLOCATE_FIXED_TYPE_AND_SET_IMPL(type, lisp_type, var, lrec_ptr) \ | 1184 #define ALLOCATE_FIXED_TYPE_AND_SET_IMPL(type, lisp_type, var, lrec_ptr) \ |
1180 do { \ | 1185 do { \ |
1181 (var) = alloc_lrecord_type (lisp_type, lrec_ptr); \ | 1186 (var) = alloc_lrecord_type (lisp_type, lrec_ptr); \ |
3479 int instances_in_use; | 3484 int instances_in_use; |
3480 int bytes_in_use; | 3485 int bytes_in_use; |
3481 int instances_freed; | 3486 int instances_freed; |
3482 int bytes_freed; | 3487 int bytes_freed; |
3483 int instances_on_free_list; | 3488 int instances_on_free_list; |
3484 } lcrecord_stats [countof (lrecord_implementations_table)]; | 3489 int bytes_on_free_list; |
3485 | 3490 } lrecord_stats [countof (lrecord_implementations_table)]; |
3486 static void | 3491 |
3492 void | |
3493 tick_lrecord_stats (const struct lrecord_header *h, | |
3494 enum lrecord_alloc_status status) | |
3495 { | |
3496 int type_index = h->type; | |
3497 Bytecount sz = detagged_lisp_object_size (h); | |
3498 | |
3499 switch (status) | |
3500 { | |
3501 case ALLOC_IN_USE: | |
3502 lrecord_stats[type_index].instances_in_use++; | |
3503 lrecord_stats[type_index].bytes_in_use += sz; | |
3504 break; | |
3505 case ALLOC_FREE: | |
3506 lrecord_stats[type_index].instances_freed++; | |
3507 lrecord_stats[type_index].bytes_freed += sz; | |
3508 break; | |
3509 case ALLOC_ON_FREE_LIST: | |
3510 lrecord_stats[type_index].instances_on_free_list++; | |
3511 lrecord_stats[type_index].bytes_on_free_list += sz; | |
3512 break; | |
3513 default: | |
3514 ABORT (); | |
3515 } | |
3516 } | |
3517 | |
3518 inline static void | |
3487 tick_lcrecord_stats (const struct lrecord_header *h, int free_p) | 3519 tick_lcrecord_stats (const struct lrecord_header *h, int free_p) |
3488 { | 3520 { |
3489 int type_index = h->type; | |
3490 | |
3491 if (((struct old_lcrecord_header *) h)->free) | 3521 if (((struct old_lcrecord_header *) h)->free) |
3492 { | 3522 { |
3493 gc_checking_assert (!free_p); | 3523 gc_checking_assert (!free_p); |
3494 lcrecord_stats[type_index].instances_on_free_list++; | 3524 tick_lrecord_stats (h, ALLOC_ON_FREE_LIST); |
3495 } | 3525 } |
3496 else | 3526 else |
3497 { | 3527 tick_lrecord_stats (h, free_p ? ALLOC_FREE : ALLOC_IN_USE); |
3498 Bytecount sz = detagged_lisp_object_size (h); | |
3499 | |
3500 if (free_p) | |
3501 { | |
3502 lcrecord_stats[type_index].instances_freed++; | |
3503 lcrecord_stats[type_index].bytes_freed += sz; | |
3504 } | |
3505 else | |
3506 { | |
3507 lcrecord_stats[type_index].instances_in_use++; | |
3508 lcrecord_stats[type_index].bytes_in_use += sz; | |
3509 } | |
3510 } | |
3511 } | 3528 } |
3512 #endif /* not NEW_GC */ | 3529 #endif /* not NEW_GC */ |
3513 | 3530 |
3514 | 3531 |
3515 #ifndef NEW_GC | 3532 #ifndef NEW_GC |
3518 sweep_lcrecords_1 (struct old_lcrecord_header **prev, int *used) | 3535 sweep_lcrecords_1 (struct old_lcrecord_header **prev, int *used) |
3519 { | 3536 { |
3520 struct old_lcrecord_header *header; | 3537 struct old_lcrecord_header *header; |
3521 int num_used = 0; | 3538 int num_used = 0; |
3522 /* int total_size = 0; */ | 3539 /* int total_size = 0; */ |
3523 | |
3524 xzero (lcrecord_stats); /* Reset all statistics to 0. */ | |
3525 | 3540 |
3526 /* First go through and call all the finalize methods. | 3541 /* First go through and call all the finalize methods. |
3527 Then go through and free the objects. There used to | 3542 Then go through and free the objects. There used to |
3528 be only one loop here, with the call to the finalizer | 3543 be only one loop here, with the call to the finalizer |
3529 occurring directly before the xfree() below. That | 3544 occurring directly before the xfree() below. That |
3574 /* *total = total_size; */ | 3589 /* *total = total_size; */ |
3575 } | 3590 } |
3576 | 3591 |
3577 /* And the Lord said: Thou shalt use the `c-backslash-region' command | 3592 /* And the Lord said: Thou shalt use the `c-backslash-region' command |
3578 to make macros prettier. */ | 3593 to make macros prettier. */ |
3594 | |
3595 #define COUNT_FROB_BLOCK_USAGE(type) \ | |
3596 EMACS_INT s = 0; \ | |
3597 struct type##_block *x = current_##type##_block; \ | |
3598 while (x) { s += sizeof (*x) + MALLOC_OVERHEAD; x = x->prev; } \ | |
3599 DO_NOTHING | |
3600 | |
3601 #define COPY_INTO_LRECORD_STATS(type) \ | |
3602 do { \ | |
3603 COUNT_FROB_BLOCK_USAGE (type); \ | |
3604 lrecord_stats[lrecord_type_##type].bytes_in_use += s; \ | |
3605 lrecord_stats[lrecord_type_##type].instances_on_free_list += \ | |
3606 gc_count_num_##type##_freelist; \ | |
3607 lrecord_stats[lrecord_type_##type].instances_in_use += \ | |
3608 gc_count_num_##type##_in_use; \ | |
3609 } while (0) | |
3579 | 3610 |
3580 #ifdef ERROR_CHECK_GC | 3611 #ifdef ERROR_CHECK_GC |
3581 | 3612 |
3582 #define SWEEP_FIXED_TYPE_BLOCK_1(typename, obj_type, lheader) \ | 3613 #define SWEEP_FIXED_TYPE_BLOCK_1(typename, obj_type, lheader) \ |
3583 do { \ | 3614 do { \ |
3619 SFTB_limit = countof (current_##typename##_block->block); \ | 3650 SFTB_limit = countof (current_##typename##_block->block); \ |
3620 } \ | 3651 } \ |
3621 \ | 3652 \ |
3622 gc_count_num_##typename##_in_use = num_used; \ | 3653 gc_count_num_##typename##_in_use = num_used; \ |
3623 gc_count_num_##typename##_freelist = num_free; \ | 3654 gc_count_num_##typename##_freelist = num_free; \ |
3655 COPY_INTO_LRECORD_STATS (typename); \ | |
3624 } while (0) | 3656 } while (0) |
3625 | 3657 |
3626 #else /* !ERROR_CHECK_GC */ | 3658 #else /* !ERROR_CHECK_GC */ |
3627 | 3659 |
3628 #define SWEEP_FIXED_TYPE_BLOCK_1(typename, obj_type, lheader) \ | 3660 #define SWEEP_FIXED_TYPE_BLOCK_1(typename, obj_type, lheader) \ |
3629 do { \ | 3661 do { \ |
3630 struct typename##_block *SFTB_current; \ | 3662 struct typename##_block *SFTB_current; \ |
3631 struct typename##_block **SFTB_prev; \ | 3663 struct typename##_block **SFTB_prev; \ |
3632 int SFTB_limit; \ | 3664 int SFTB_limit; \ |
3633 int num_free = 0, num_used = 0; \ | 3665 int num_free = 0, num_used = 0; \ |
3634 \ | 3666 \ |
3635 typename##_free_list = 0; \ | 3667 typename##_free_list = 0; \ |
3636 \ | 3668 \ |
3637 for (SFTB_prev = ¤t_##typename##_block, \ | 3669 for (SFTB_prev = ¤t_##typename##_block, \ |
3638 SFTB_current = current_##typename##_block, \ | 3670 SFTB_current = current_##typename##_block, \ |
3639 SFTB_limit = current_##typename##_block_index; \ | 3671 SFTB_limit = current_##typename##_block_index; \ |
3640 SFTB_current; \ | 3672 SFTB_current; \ |
3641 ) \ | 3673 ) \ |
3642 { \ | 3674 { \ |
3643 int SFTB_iii; \ | 3675 int SFTB_iii; \ |
3644 int SFTB_empty = 1; \ | 3676 int SFTB_empty = 1; \ |
3645 Lisp_Free *SFTB_old_free_list = typename##_free_list; \ | 3677 Lisp_Free *SFTB_old_free_list = typename##_free_list; \ |
3646 \ | 3678 \ |
3647 for (SFTB_iii = 0; SFTB_iii < SFTB_limit; SFTB_iii++) \ | 3679 for (SFTB_iii = 0; SFTB_iii < SFTB_limit; SFTB_iii++) \ |
3648 { \ | 3680 { \ |
3649 obj_type *SFTB_victim = &(SFTB_current->block[SFTB_iii]); \ | 3681 obj_type *SFTB_victim = &(SFTB_current->block[SFTB_iii]); \ |
3650 \ | 3682 \ |
3651 if (LRECORD_FREE_P (SFTB_victim)) \ | 3683 if (LRECORD_FREE_P (SFTB_victim)) \ |
3652 { \ | 3684 { \ |
3653 num_free++; \ | 3685 num_free++; \ |
3654 PUT_FIXED_TYPE_ON_FREE_LIST (typename, obj_type, SFTB_victim); \ | 3686 PUT_FIXED_TYPE_ON_FREE_LIST (typename, obj_type, SFTB_victim); \ |
3655 } \ | 3687 } \ |
3656 else if (C_READONLY_RECORD_HEADER_P (&SFTB_victim->lheader)) \ | 3688 else if (C_READONLY_RECORD_HEADER_P (&SFTB_victim->lheader)) \ |
3657 { \ | 3689 { \ |
3658 SFTB_empty = 0; \ | 3690 SFTB_empty = 0; \ |
3659 num_used++; \ | 3691 num_used++; \ |
3660 } \ | 3692 } \ |
3661 else if (! MARKED_RECORD_HEADER_P (&SFTB_victim->lheader)) \ | 3693 else if (! MARKED_RECORD_HEADER_P (&SFTB_victim->lheader)) \ |
3662 { \ | 3694 { \ |
3663 num_free++; \ | 3695 num_free++; \ |
3664 FREE_FIXED_TYPE (typename, obj_type, SFTB_victim); \ | 3696 FREE_FIXED_TYPE (typename, obj_type, SFTB_victim); \ |
3665 } \ | 3697 } \ |
3666 else \ | 3698 else \ |
3667 { \ | 3699 { \ |
3668 SFTB_empty = 0; \ | 3700 SFTB_empty = 0; \ |
3669 num_used++; \ | 3701 num_used++; \ |
3670 UNMARK_##typename (SFTB_victim); \ | 3702 UNMARK_##typename (SFTB_victim); \ |
3671 } \ | 3703 } \ |
3672 } \ | 3704 } \ |
3673 if (!SFTB_empty) \ | 3705 if (!SFTB_empty) \ |
3674 { \ | 3706 { \ |
3675 SFTB_prev = &(SFTB_current->prev); \ | 3707 SFTB_prev = &(SFTB_current->prev); \ |
3676 SFTB_current = SFTB_current->prev; \ | 3708 SFTB_current = SFTB_current->prev; \ |
3677 } \ | 3709 } \ |
3678 else if (SFTB_current == current_##typename##_block \ | 3710 else if (SFTB_current == current_##typename##_block \ |
3679 && !SFTB_current->prev) \ | 3711 && !SFTB_current->prev) \ |
3680 { \ | 3712 { \ |
3681 /* No real point in freeing sole allocation block */ \ | 3713 /* No real point in freeing sole allocation block */ \ |
3682 break; \ | 3714 break; \ |
3683 } \ | 3715 } \ |
3684 else \ | 3716 else \ |
3685 { \ | 3717 { \ |
3686 struct typename##_block *SFTB_victim_block = SFTB_current; \ | 3718 struct typename##_block *SFTB_victim_block = SFTB_current; \ |
3687 if (SFTB_victim_block == current_##typename##_block) \ | 3719 if (SFTB_victim_block == current_##typename##_block) \ |
3688 current_##typename##_block_index \ | 3720 current_##typename##_block_index \ |
3689 = countof (current_##typename##_block->block); \ | 3721 = countof (current_##typename##_block->block); \ |
3690 SFTB_current = SFTB_current->prev; \ | 3722 SFTB_current = SFTB_current->prev; \ |
3691 { \ | 3723 { \ |
3692 *SFTB_prev = SFTB_current; \ | 3724 *SFTB_prev = SFTB_current; \ |
3693 xfree (SFTB_victim_block); \ | 3725 xfree (SFTB_victim_block); \ |
3694 /* Restore free list to what it was before victim was swept */ \ | 3726 /* Restore free list to what it was before victim was swept */ \ |
3695 typename##_free_list = SFTB_old_free_list; \ | 3727 typename##_free_list = SFTB_old_free_list; \ |
3696 num_free -= SFTB_limit; \ | 3728 num_free -= SFTB_limit; \ |
3697 } \ | 3729 } \ |
3698 } \ | 3730 } \ |
3699 SFTB_limit = countof (current_##typename##_block->block); \ | 3731 SFTB_limit = countof (current_##typename##_block->block); \ |
3700 } \ | 3732 } \ |
3701 \ | 3733 \ |
3702 gc_count_num_##typename##_in_use = num_used; \ | 3734 gc_count_num_##typename##_in_use = num_used; \ |
3703 gc_count_num_##typename##_freelist = num_free; \ | 3735 gc_count_num_##typename##_freelist = num_free; \ |
3736 COPY_INTO_LRECORD_STATS (typename); \ | |
3704 } while (0) | 3737 } while (0) |
3705 | 3738 |
3706 #endif /* !ERROR_CHECK_GC */ | 3739 #endif /* !ERROR_CHECK_GC */ |
3707 | 3740 |
3708 #define SWEEP_FIXED_TYPE_BLOCK(typename, obj_type) \ | 3741 #define SWEEP_FIXED_TYPE_BLOCK(typename, obj_type) \ |
3746 well as a check in FREE_FIXED_TYPE(). */ | 3779 well as a check in FREE_FIXED_TYPE(). */ |
3747 if (POINTER_TYPE_P (XTYPE (cons_car (ptr)))) | 3780 if (POINTER_TYPE_P (XTYPE (cons_car (ptr)))) |
3748 ASSERT_VALID_POINTER (XPNTR (cons_car (ptr))); | 3781 ASSERT_VALID_POINTER (XPNTR (cons_car (ptr))); |
3749 #endif /* ERROR_CHECK_GC */ | 3782 #endif /* ERROR_CHECK_GC */ |
3750 | 3783 |
3751 #ifdef NEW_GC | 3784 FREE_FIXED_TYPE_WHEN_NOT_IN_GC (cons, cons, Lisp_Cons, ptr); |
3752 free_lrecord (cons); | |
3753 #else /* not NEW_GC */ | |
3754 FREE_FIXED_TYPE_WHEN_NOT_IN_GC (cons, Lisp_Cons, ptr); | |
3755 #endif /* not NEW_GC */ | |
3756 } | 3785 } |
3757 | 3786 |
3758 /* explicitly free a list. You **must make sure** that you have | 3787 /* explicitly free a list. You **must make sure** that you have |
3759 created all the cons cells that make up this list and that there | 3788 created all the cons cells that make up this list and that there |
3760 are no pointers to any of these cons cells anywhere else. If there | 3789 are no pointers to any of these cons cells anywhere else. If there |
3885 #endif /* not NEW_GC */ | 3914 #endif /* not NEW_GC */ |
3886 | 3915 |
3887 void | 3916 void |
3888 free_key_data (Lisp_Object ptr) | 3917 free_key_data (Lisp_Object ptr) |
3889 { | 3918 { |
3890 #ifdef NEW_GC | 3919 FREE_FIXED_TYPE_WHEN_NOT_IN_GC (ptr, key_data, Lisp_Key_Data, |
3891 free_lrecord (ptr); | 3920 XKEY_DATA (ptr)); |
3892 #else /* not NEW_GC */ | |
3893 FREE_FIXED_TYPE_WHEN_NOT_IN_GC (key_data, Lisp_Key_Data, XKEY_DATA (ptr)); | |
3894 #endif /* not NEW_GC */ | |
3895 } | 3921 } |
3896 | 3922 |
3897 #ifndef NEW_GC | 3923 #ifndef NEW_GC |
3898 static void | 3924 static void |
3899 sweep_button_data (void) | 3925 sweep_button_data (void) |
3906 #endif /* not NEW_GC */ | 3932 #endif /* not NEW_GC */ |
3907 | 3933 |
3908 void | 3934 void |
3909 free_button_data (Lisp_Object ptr) | 3935 free_button_data (Lisp_Object ptr) |
3910 { | 3936 { |
3911 #ifdef NEW_GC | 3937 FREE_FIXED_TYPE_WHEN_NOT_IN_GC (ptr, button_data, Lisp_Button_Data, |
3912 free_lrecord (ptr); | 3938 XBUTTON_DATA (ptr)); |
3913 #else /* not NEW_GC */ | |
3914 FREE_FIXED_TYPE_WHEN_NOT_IN_GC (button_data, Lisp_Button_Data, XBUTTON_DATA (ptr)); | |
3915 #endif /* not NEW_GC */ | |
3916 } | 3939 } |
3917 | 3940 |
3918 #ifndef NEW_GC | 3941 #ifndef NEW_GC |
3919 static void | 3942 static void |
3920 sweep_motion_data (void) | 3943 sweep_motion_data (void) |
3927 #endif /* not NEW_GC */ | 3950 #endif /* not NEW_GC */ |
3928 | 3951 |
3929 void | 3952 void |
3930 free_motion_data (Lisp_Object ptr) | 3953 free_motion_data (Lisp_Object ptr) |
3931 { | 3954 { |
3932 #ifdef NEW_GC | 3955 FREE_FIXED_TYPE_WHEN_NOT_IN_GC (ptr, motion_data, Lisp_Motion_Data, |
3933 free_lrecord (ptr); | 3956 XMOTION_DATA (ptr)); |
3934 #else /* not NEW_GC */ | |
3935 FREE_FIXED_TYPE_WHEN_NOT_IN_GC (motion_data, Lisp_Motion_Data, XMOTION_DATA (ptr)); | |
3936 #endif /* not NEW_GC */ | |
3937 } | 3957 } |
3938 | 3958 |
3939 #ifndef NEW_GC | 3959 #ifndef NEW_GC |
3940 static void | 3960 static void |
3941 sweep_process_data (void) | 3961 sweep_process_data (void) |
3948 #endif /* not NEW_GC */ | 3968 #endif /* not NEW_GC */ |
3949 | 3969 |
3950 void | 3970 void |
3951 free_process_data (Lisp_Object ptr) | 3971 free_process_data (Lisp_Object ptr) |
3952 { | 3972 { |
3953 #ifdef NEW_GC | 3973 FREE_FIXED_TYPE_WHEN_NOT_IN_GC (ptr, process_data, Lisp_Process_Data, |
3954 free_lrecord (ptr); | 3974 XPROCESS_DATA (ptr)); |
3955 #else /* not NEW_GC */ | |
3956 FREE_FIXED_TYPE_WHEN_NOT_IN_GC (process_data, Lisp_Process_Data, XPROCESS_DATA (ptr)); | |
3957 #endif /* not NEW_GC */ | |
3958 } | 3975 } |
3959 | 3976 |
3960 #ifndef NEW_GC | 3977 #ifndef NEW_GC |
3961 static void | 3978 static void |
3962 sweep_timeout_data (void) | 3979 sweep_timeout_data (void) |
3969 #endif /* not NEW_GC */ | 3986 #endif /* not NEW_GC */ |
3970 | 3987 |
3971 void | 3988 void |
3972 free_timeout_data (Lisp_Object ptr) | 3989 free_timeout_data (Lisp_Object ptr) |
3973 { | 3990 { |
3974 #ifdef NEW_GC | 3991 FREE_FIXED_TYPE_WHEN_NOT_IN_GC (ptr, timeout_data, Lisp_Timeout_Data, |
3975 free_lrecord (ptr); | 3992 XTIMEOUT_DATA (ptr)); |
3976 #else /* not NEW_GC */ | |
3977 FREE_FIXED_TYPE_WHEN_NOT_IN_GC (timeout_data, Lisp_Timeout_Data, XTIMEOUT_DATA (ptr)); | |
3978 #endif /* not NEW_GC */ | |
3979 } | 3993 } |
3980 | 3994 |
3981 #ifndef NEW_GC | 3995 #ifndef NEW_GC |
3982 static void | 3996 static void |
3983 sweep_magic_data (void) | 3997 sweep_magic_data (void) |
3990 #endif /* not NEW_GC */ | 4004 #endif /* not NEW_GC */ |
3991 | 4005 |
3992 void | 4006 void |
3993 free_magic_data (Lisp_Object ptr) | 4007 free_magic_data (Lisp_Object ptr) |
3994 { | 4008 { |
3995 #ifdef NEW_GC | 4009 FREE_FIXED_TYPE_WHEN_NOT_IN_GC (ptr, magic_data, Lisp_Magic_Data, |
3996 free_lrecord (ptr); | 4010 XMAGIC_DATA (ptr)); |
3997 #else /* not NEW_GC */ | |
3998 FREE_FIXED_TYPE_WHEN_NOT_IN_GC (magic_data, Lisp_Magic_Data, XMAGIC_DATA (ptr)); | |
3999 #endif /* not NEW_GC */ | |
4000 } | 4011 } |
4001 | 4012 |
4002 #ifndef NEW_GC | 4013 #ifndef NEW_GC |
4003 static void | 4014 static void |
4004 sweep_magic_eval_data (void) | 4015 sweep_magic_eval_data (void) |
4011 #endif /* not NEW_GC */ | 4022 #endif /* not NEW_GC */ |
4012 | 4023 |
4013 void | 4024 void |
4014 free_magic_eval_data (Lisp_Object ptr) | 4025 free_magic_eval_data (Lisp_Object ptr) |
4015 { | 4026 { |
4016 #ifdef NEW_GC | 4027 FREE_FIXED_TYPE_WHEN_NOT_IN_GC (ptr, magic_eval_data, Lisp_Magic_Eval_Data, |
4017 free_lrecord (ptr); | 4028 XMAGIC_EVAL_DATA (ptr)); |
4018 #else /* not NEW_GC */ | |
4019 FREE_FIXED_TYPE_WHEN_NOT_IN_GC (magic_eval_data, Lisp_Magic_Eval_Data, XMAGIC_EVAL_DATA (ptr)); | |
4020 #endif /* not NEW_GC */ | |
4021 } | 4029 } |
4022 | 4030 |
4023 #ifndef NEW_GC | 4031 #ifndef NEW_GC |
4024 static void | 4032 static void |
4025 sweep_eval_data (void) | 4033 sweep_eval_data (void) |
4032 #endif /* not NEW_GC */ | 4040 #endif /* not NEW_GC */ |
4033 | 4041 |
4034 void | 4042 void |
4035 free_eval_data (Lisp_Object ptr) | 4043 free_eval_data (Lisp_Object ptr) |
4036 { | 4044 { |
4037 #ifdef NEW_GC | 4045 FREE_FIXED_TYPE_WHEN_NOT_IN_GC (ptr, eval_data, Lisp_Eval_Data, |
4038 free_lrecord (ptr); | 4046 XEVAL_DATA (ptr)); |
4039 #else /* not NEW_GC */ | |
4040 FREE_FIXED_TYPE_WHEN_NOT_IN_GC (eval_data, Lisp_Eval_Data, XEVAL_DATA (ptr)); | |
4041 #endif /* not NEW_GC */ | |
4042 } | 4047 } |
4043 | 4048 |
4044 #ifndef NEW_GC | 4049 #ifndef NEW_GC |
4045 static void | 4050 static void |
4046 sweep_misc_user_data (void) | 4051 sweep_misc_user_data (void) |
4053 #endif /* not NEW_GC */ | 4058 #endif /* not NEW_GC */ |
4054 | 4059 |
4055 void | 4060 void |
4056 free_misc_user_data (Lisp_Object ptr) | 4061 free_misc_user_data (Lisp_Object ptr) |
4057 { | 4062 { |
4058 #ifdef NEW_GC | 4063 FREE_FIXED_TYPE_WHEN_NOT_IN_GC (ptr, misc_user_data, Lisp_Misc_User_Data, |
4059 free_lrecord (ptr); | 4064 XMISC_USER_DATA (ptr)); |
4060 #else /* not NEW_GC */ | |
4061 FREE_FIXED_TYPE_WHEN_NOT_IN_GC (misc_user_data, Lisp_Misc_User_Data, XMISC_USER_DATA (ptr)); | |
4062 #endif /* not NEW_GC */ | |
4063 } | 4065 } |
4064 | 4066 |
4065 #endif /* EVENT_DATA_AS_OBJECTS */ | 4067 #endif /* EVENT_DATA_AS_OBJECTS */ |
4066 | 4068 |
4067 #ifndef NEW_GC | 4069 #ifndef NEW_GC |
4081 | 4083 |
4082 /* Explicitly free a marker. */ | 4084 /* Explicitly free a marker. */ |
4083 void | 4085 void |
4084 free_marker (Lisp_Object ptr) | 4086 free_marker (Lisp_Object ptr) |
4085 { | 4087 { |
4086 #ifdef NEW_GC | 4088 FREE_FIXED_TYPE_WHEN_NOT_IN_GC (ptr, marker, Lisp_Marker, XMARKER (ptr)); |
4087 free_lrecord (ptr); | |
4088 #else /* not NEW_GC */ | |
4089 FREE_FIXED_TYPE_WHEN_NOT_IN_GC (marker, Lisp_Marker, XMARKER (ptr)); | |
4090 #endif /* not NEW_GC */ | |
4091 } | 4089 } |
4092 | 4090 |
4093 | 4091 |
4094 #if defined (MULE) && defined (VERIFY_STRING_CHARS_INTEGRITY) | 4092 #if defined (MULE) && defined (VERIFY_STRING_CHARS_INTEGRITY) |
4095 | 4093 |
4302 | 4300 |
4303 #ifndef NEW_GC | 4301 #ifndef NEW_GC |
4304 void | 4302 void |
4305 gc_sweep_1 (void) | 4303 gc_sweep_1 (void) |
4306 { | 4304 { |
4305 /* Reset all statistics to 0. They will be incremented when | |
4306 sweeping lcrecords, frob-block lrecords and dumped objects. */ | |
4307 xzero (lrecord_stats); | |
4308 | |
4307 /* Free all unmarked records. Do this at the very beginning, | 4309 /* Free all unmarked records. Do this at the very beginning, |
4308 before anything else, so that the finalize methods can safely | 4310 before anything else, so that the finalize methods can safely |
4309 examine items in the objects. sweep_lcrecords_1() makes | 4311 examine items in the objects. sweep_lcrecords_1() makes |
4310 sure to call all the finalize methods *before* freeing anything, | 4312 sure to call all the finalize methods *before* freeing anything, |
4311 to complete the safety. */ | 4313 to complete the safety. */ |
4558 } | 4560 } |
4559 } | 4561 } |
4560 | 4562 |
4561 #else /* not NEW_GC */ | 4563 #else /* not NEW_GC */ |
4562 | 4564 |
4563 #define HACK_O_MATIC(type, name, pl) do { \ | 4565 #define HACK_O_MATIC(type, name, pl) \ |
4564 EMACS_INT s = 0; \ | 4566 do { \ |
4565 struct type##_block *x = current_##type##_block; \ | 4567 COUNT_FROB_BLOCK_USAGE (type); \ |
4566 while (x) { s += sizeof (*x) + MALLOC_OVERHEAD; x = x->prev; } \ | 4568 tgu_val += s; \ |
4567 tgu_val += s; \ | 4569 (pl) = gc_plist_hack ((name), s, (pl)); \ |
4568 (pl) = gc_plist_hack ((name), s, (pl)); \ | |
4569 } while (0) | 4570 } while (0) |
4570 | 4571 |
4571 for (i = 0; i < lrecord_type_count; i++) | 4572 #define FROB(type) \ |
4572 { | 4573 do { \ |
4573 if (lcrecord_stats[i].bytes_in_use != 0 | 4574 COUNT_FROB_BLOCK_USAGE (type); \ |
4574 || lcrecord_stats[i].bytes_freed != 0 | 4575 tgu_val += s; \ |
4575 || lcrecord_stats[i].instances_on_free_list != 0) | 4576 } while (0) |
4576 { | |
4577 Ascbyte buf[255]; | |
4578 const Ascbyte *name = lrecord_implementations_table[i]->name; | |
4579 | |
4580 sprintf (buf, "%s-storage", name); | |
4581 pl = gc_plist_hack (buf, lcrecord_stats[i].bytes_in_use, pl); | |
4582 tgu_val += lcrecord_stats[i].bytes_in_use; | |
4583 pluralize_and_append (buf, name, "-freed"); | |
4584 if (lcrecord_stats[i].instances_freed != 0) | |
4585 pl = gc_plist_hack (buf, lcrecord_stats[i].instances_freed, pl); | |
4586 pluralize_and_append (buf, name, "-on-free-list"); | |
4587 if (lcrecord_stats[i].instances_on_free_list != 0) | |
4588 pl = gc_plist_hack (buf, lcrecord_stats[i].instances_on_free_list, | |
4589 pl); | |
4590 pluralize_and_append (buf, name, "-used"); | |
4591 pl = gc_plist_hack (buf, lcrecord_stats[i].instances_in_use, pl); | |
4592 } | |
4593 } | |
4594 | |
4595 /* The most general version -- handle TYPE, with strings using ENGTYPE | |
4596 instead (generally the same, but with hyphen in place of underscore) | |
4597 and ENGTYPES as the plural of ENGTYPE. */ | |
4598 #define FROB3(type, engtype, engtypes) \ | |
4599 HACK_O_MATIC (type, engtype "-storage", pl); \ | |
4600 pl = gc_plist_hack (engtypes "-free", gc_count_num_##type##_freelist, pl); \ | |
4601 pl = gc_plist_hack (engtypes "-used", gc_count_num_##type##_in_use, pl) | |
4602 | |
4603 #define FROB(type) FROB3(type, #type, #type "s") | |
4604 | 4577 |
4605 FROB (extent); | 4578 FROB (extent); |
4606 FROB (event); | 4579 FROB (event); |
4607 FROB (marker); | 4580 FROB (marker); |
4608 FROB (float); | 4581 FROB (float); |
4613 FROB (ratio); | 4586 FROB (ratio); |
4614 #endif /* HAVE_RATIO */ | 4587 #endif /* HAVE_RATIO */ |
4615 #ifdef HAVE_BIGFLOAT | 4588 #ifdef HAVE_BIGFLOAT |
4616 FROB (bigfloat); | 4589 FROB (bigfloat); |
4617 #endif /* HAVE_BIGFLOAT */ | 4590 #endif /* HAVE_BIGFLOAT */ |
4591 FROB (compiled_function); | |
4592 FROB (symbol); | |
4593 FROB (cons); | |
4594 | |
4595 #undef FROB | |
4596 | |
4597 for (i = 0; i < lrecord_type_count; i++) | |
4598 { | |
4599 if (lrecord_stats[i].bytes_in_use != 0 | |
4600 || lrecord_stats[i].bytes_freed != 0 | |
4601 || lrecord_stats[i].instances_on_free_list != 0) | |
4602 { | |
4603 Ascbyte buf[255]; | |
4604 const Ascbyte *name = lrecord_implementations_table[i]->name; | |
4605 | |
4606 sprintf (buf, "%s-storage", name); | |
4607 pl = gc_plist_hack (buf, lrecord_stats[i].bytes_in_use, pl); | |
4608 tgu_val += lrecord_stats[i].bytes_in_use; | |
4609 pluralize_and_append (buf, name, "-freed"); | |
4610 if (lrecord_stats[i].instances_freed != 0) | |
4611 pl = gc_plist_hack (buf, lrecord_stats[i].instances_freed, pl); | |
4612 pluralize_and_append (buf, name, "-on-free-list"); | |
4613 if (lrecord_stats[i].instances_on_free_list != 0) | |
4614 pl = gc_plist_hack (buf, lrecord_stats[i].instances_on_free_list, | |
4615 pl); | |
4616 pluralize_and_append (buf, name, "-used"); | |
4617 pl = gc_plist_hack (buf, lrecord_stats[i].instances_in_use, pl); | |
4618 } | |
4619 } | |
4620 | |
4618 HACK_O_MATIC (string, "string-header-storage", pl); | 4621 HACK_O_MATIC (string, "string-header-storage", pl); |
4619 pl = gc_plist_hack ("long-strings-total-length", | 4622 pl = gc_plist_hack ("long-strings-total-length", |
4620 gc_count_string_total_size | 4623 gc_count_string_total_size |
4621 - gc_count_short_string_total_size, pl); | 4624 - gc_count_short_string_total_size, pl); |
4622 HACK_O_MATIC (string_chars, "short-string-storage", pl); | 4625 HACK_O_MATIC (string_chars, "short-string-storage", pl); |
4626 pl = gc_plist_hack ("long-strings-used", | 4629 pl = gc_plist_hack ("long-strings-used", |
4627 gc_count_num_string_in_use | 4630 gc_count_num_string_in_use |
4628 - gc_count_num_short_string_in_use, pl); | 4631 - gc_count_num_short_string_in_use, pl); |
4629 pl = gc_plist_hack ("short-strings-used", | 4632 pl = gc_plist_hack ("short-strings-used", |
4630 gc_count_num_short_string_in_use, pl); | 4633 gc_count_num_short_string_in_use, pl); |
4631 | |
4632 FROB3 (compiled_function, "compiled-function", "compiled-functions"); | |
4633 FROB (symbol); | |
4634 FROB3 (cons, "cons", "conses"); | |
4635 | 4634 |
4636 #undef HACK_O_MATIC | 4635 #undef HACK_O_MATIC |
4637 | 4636 |
4638 #endif /* NEW_GC */ | 4637 #endif /* NEW_GC */ |
4639 | 4638 |
4707 Fcons (make_int (gc_count_num_symbol_in_use), | 4706 Fcons (make_int (gc_count_num_symbol_in_use), |
4708 make_int (gc_count_num_symbol_freelist)), | 4707 make_int (gc_count_num_symbol_freelist)), |
4709 Fcons (make_int (gc_count_num_marker_in_use), | 4708 Fcons (make_int (gc_count_num_marker_in_use), |
4710 make_int (gc_count_num_marker_freelist)), | 4709 make_int (gc_count_num_marker_freelist)), |
4711 make_int (gc_count_string_total_size), | 4710 make_int (gc_count_string_total_size), |
4712 make_int (lcrecord_stats[lrecord_type_vector].bytes_in_use + | 4711 make_int (lrecord_stats[lrecord_type_vector].bytes_in_use + |
4713 lcrecord_stats[lrecord_type_vector].bytes_freed), | 4712 lrecord_stats[lrecord_type_vector].bytes_freed + |
4713 lrecord_stats[lrecord_type_vector].bytes_on_free_list), | |
4714 object_memory_usage_stats (1)); | 4714 object_memory_usage_stats (1)); |
4715 #endif /* not NEW_GC */ | 4715 #endif /* not NEW_GC */ |
4716 #else /* not ALLOC_TYPE_STATS */ | 4716 #else /* not ALLOC_TYPE_STATS */ |
4717 return Qnil; | 4717 return Qnil; |
4718 #endif /* ALLOC_TYPE_STATS */ | 4718 #endif /* ALLOC_TYPE_STATS */ |