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 = &current_##typename##_block, \ 3669 for (SFTB_prev = &current_##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 */