Mercurial > hg > xemacs-beta
comparison src/alloc.c @ 2994:ec5f23ea6d2e
[xemacs-hg @ 2005-10-14 01:21:57 by ben]
add gc percentage threshold to mc-alloc
config.h.in, alloc.c, dumper.c, emacs.c, lrecord.h, mc-alloc.c, mc-alloc.h, symbols.c: Rename MC_ALLOC_TYPE_STATS to ALLOC_TYPE_STATS, since
(with refactoring) this is not really specific to mc-alloc.
Generalize code to implement the GC % threshold for garbage
collecting. Rename `lrecord-stats' to `object-memory-usage-stats'
(defined when not mc-alloc, too). Rename `memory-usage' to
`total-memory-usage' and add `object-memory-usage'. Bump
gc_cons_threshold to 2,000,000 (suggestion by Stephen Turnbull).
Avoid use of C++ reserved word `catch'.
Change address for crash reporting to xemacs-beta@xemacs.org from
crashes@xemacs.org.
new -> new_ in emacs.c.
Turn on _CRT_SECURE_NO_DEPRECATE under Visual C++ to avoid tons of
warnings in VC8.
author | ben |
---|---|
date | Fri, 14 Oct 2005 01:22:01 +0000 |
parents | fb22a4eb2694 |
children | 1e7cc382eb16 |
comparison
equal
deleted
inserted
replaced
2993:49316578f12d | 2994:ec5f23ea6d2e |
---|---|
1 /* Storage allocation and gc for XEmacs Lisp interpreter. | 1 /* Storage allocation and gc for XEmacs Lisp interpreter. |
2 Copyright (C) 1985-1998 Free Software Foundation, Inc. | 2 Copyright (C) 1985-1998 Free Software Foundation, Inc. |
3 Copyright (C) 1995 Sun Microsystems, Inc. | 3 Copyright (C) 1995 Sun Microsystems, Inc. |
4 Copyright (C) 1995, 1996, 2001, 2002, 2003, 2004 Ben Wing. | 4 Copyright (C) 1995, 1996, 2001, 2002, 2003, 2004, 2005 Ben Wing. |
5 | 5 |
6 This file is part of XEmacs. | 6 This file is part of XEmacs. |
7 | 7 |
8 XEmacs is free software; you can redistribute it and/or modify it | 8 XEmacs is free software; you can redistribute it and/or modify it |
9 under the terms of the GNU General Public License as published by the | 9 under the terms of the GNU General Public License as published by the |
92 #endif | 92 #endif |
93 | 93 |
94 /* Number of bytes of consing done since the last gc */ | 94 /* Number of bytes of consing done since the last gc */ |
95 static EMACS_INT consing_since_gc; | 95 static EMACS_INT consing_since_gc; |
96 EMACS_UINT total_consing; | 96 EMACS_UINT total_consing; |
97 EMACS_INT total_gc_usage; | |
98 int total_gc_usage_set; | |
97 | 99 |
98 int need_to_garbage_collect; | 100 int need_to_garbage_collect; |
99 int need_to_check_c_alloca; | 101 int need_to_check_c_alloca; |
100 int need_to_signal_post_gc; | 102 int need_to_signal_post_gc; |
101 int funcall_allocation_flag; | 103 int funcall_allocation_flag; |
508 | 510 |
509 return val; | 511 return val; |
510 } | 512 } |
511 #endif /* not MC_ALLOC */ | 513 #endif /* not MC_ALLOC */ |
512 | 514 |
513 #ifdef MC_ALLOC_TYPE_STATS | 515 #if defined (MC_ALLOC) && defined (ALLOC_TYPE_STATS) |
514 static struct | 516 static struct |
515 { | 517 { |
516 int instances_in_use; | 518 int instances_in_use; |
517 int bytes_in_use; | 519 int bytes_in_use; |
518 int bytes_in_use_including_overhead; | 520 int bytes_in_use_including_overhead; |
577 lrecord_stats[type_index].bytes_in_use_including_overhead | 579 lrecord_stats[type_index].bytes_in_use_including_overhead |
578 -= size_including_overhead; | 580 -= size_including_overhead; |
579 | 581 |
580 DECREMENT_CONS_COUNTER (size); | 582 DECREMENT_CONS_COUNTER (size); |
581 } | 583 } |
582 #endif /* not MC_ALLOC_TYPE_STATS */ | 584 #endif /* not (MC_ALLOC && ALLOC_TYPE_STATS) */ |
583 | 585 |
584 #ifndef MC_ALLOC | 586 #ifndef MC_ALLOC |
585 /* lcrecords are chained together through their "next" field. | 587 /* lcrecords are chained together through their "next" field. |
586 After doing the mark phase, GC will walk this linked list | 588 After doing the mark phase, GC will walk this linked list |
587 and free any lcrecord which hasn't been marked. */ | 589 and free any lcrecord which hasn't been marked. */ |
603 | 605 |
604 lheader = (struct lrecord_header *) mc_alloc (size); | 606 lheader = (struct lrecord_header *) mc_alloc (size); |
605 gc_checking_assert (LRECORD_FREE_P (lheader)); | 607 gc_checking_assert (LRECORD_FREE_P (lheader)); |
606 set_lheader_implementation (lheader, implementation); | 608 set_lheader_implementation (lheader, implementation); |
607 lheader->uid = lrecord_uid_counter++; | 609 lheader->uid = lrecord_uid_counter++; |
608 #ifdef MC_ALLOC_TYPE_STATS | 610 #ifdef ALLOC_TYPE_STATS |
609 inc_lrecord_stats (size, lheader); | 611 inc_lrecord_stats (size, lheader); |
610 #endif /* not MC_ALLOC_TYPE_STATS */ | 612 #endif /* ALLOC_TYPE_STATS */ |
611 INCREMENT_CONS_COUNTER (size, implementation->name); | 613 INCREMENT_CONS_COUNTER (size, implementation->name); |
612 return lheader; | 614 return lheader; |
613 } | 615 } |
614 | 616 |
615 void * | 617 void * |
625 | 627 |
626 lheader = (struct lrecord_header *) mc_alloc (size); | 628 lheader = (struct lrecord_header *) mc_alloc (size); |
627 gc_checking_assert (LRECORD_FREE_P (lheader)); | 629 gc_checking_assert (LRECORD_FREE_P (lheader)); |
628 set_lheader_implementation (lheader, implementation); | 630 set_lheader_implementation (lheader, implementation); |
629 lheader->uid = lrecord_uid_counter++; | 631 lheader->uid = lrecord_uid_counter++; |
630 #ifdef MC_ALLOC_TYPE_STATS | 632 #ifdef ALLOC_TYPE_STATS |
631 inc_lrecord_stats (size, lheader); | 633 inc_lrecord_stats (size, lheader); |
632 #endif /* not MC_ALLOC_TYPE_STATS */ | 634 #endif /* ALLOC_TYPE_STATS */ |
633 NOSEEUM_INCREMENT_CONS_COUNTER (size, implementation->name); | 635 NOSEEUM_INCREMENT_CONS_COUNTER (size, implementation->name); |
634 return lheader; | 636 return lheader; |
635 } | 637 } |
636 | 638 |
637 void | 639 void |
2490 { | 2492 { |
2491 if (!for_disksave) | 2493 if (!for_disksave) |
2492 { | 2494 { |
2493 Lisp_String *s = (Lisp_String *) header; | 2495 Lisp_String *s = (Lisp_String *) header; |
2494 Bytecount size = s->size_; | 2496 Bytecount size = s->size_; |
2495 #ifdef MC_ALLOC_TYPE_STATS | 2497 #ifdef ALLOC_TYPE_STATS |
2496 dec_lrecord_string_data_stats (size); | 2498 dec_lrecord_string_data_stats (size); |
2497 #endif /* MC_ALLOC_TYPE_STATS */ | 2499 #endif /* ALLOC_TYPE_STATS */ |
2498 if (BIG_STRING_SIZE_P (size)) | 2500 if (BIG_STRING_SIZE_P (size)) |
2499 xfree (s->data_, Ibyte *); | 2501 xfree (s->data_, Ibyte *); |
2500 } | 2502 } |
2501 } | 2503 } |
2502 | 2504 |
2612 | 2614 |
2613 assert (length >= 0 && fullsize > 0); | 2615 assert (length >= 0 && fullsize > 0); |
2614 | 2616 |
2615 #ifdef MC_ALLOC | 2617 #ifdef MC_ALLOC |
2616 s = alloc_lrecord_type (Lisp_String, &lrecord_string); | 2618 s = alloc_lrecord_type (Lisp_String, &lrecord_string); |
2617 #ifdef MC_ALLOC_TYPE_STATS | 2619 #ifdef ALLOC_TYPE_STATS |
2618 inc_lrecord_string_data_stats (length); | 2620 inc_lrecord_string_data_stats (length); |
2619 #endif /* MC_ALLOC_TYPE_STATS */ | 2621 #endif /* ALLOC_TYPE_STATS */ |
2620 #else /* not MC_ALLOC */ | 2622 #else /* not MC_ALLOC */ |
2621 /* Allocate the string header */ | 2623 /* Allocate the string header */ |
2622 ALLOCATE_FIXED_TYPE (string, Lisp_String, s); | 2624 ALLOCATE_FIXED_TYPE (string, Lisp_String, s); |
2623 xzero (*s); | 2625 xzero (*s); |
2624 set_lheader_implementation (&s->u.lheader, &lrecord_string); | 2626 set_lheader_implementation (&s->u.lheader, &lrecord_string); |
2998 bytecount_to_charcount (contents, length); /* Just for the assertions */ | 3000 bytecount_to_charcount (contents, length); /* Just for the assertions */ |
2999 #endif | 3001 #endif |
3000 | 3002 |
3001 #ifdef MC_ALLOC | 3003 #ifdef MC_ALLOC |
3002 s = alloc_lrecord_type (Lisp_String, &lrecord_string); | 3004 s = alloc_lrecord_type (Lisp_String, &lrecord_string); |
3003 #ifdef MC_ALLOC_TYPE_STATS | 3005 #ifdef ALLOC_TYPE_STATS |
3004 inc_lrecord_string_data_stats (length); | 3006 inc_lrecord_string_data_stats (length); |
3005 #endif /* MC_ALLOC_TYPE_STATS */ | 3007 #endif /* ALLOC_TYPE_STATS */ |
3006 mcpro (wrap_pointer_1 (s)); /* otherwise nocopy_strings get | 3008 mcpro (wrap_pointer_1 (s)); /* otherwise nocopy_strings get |
3007 collected and static data is tried to | 3009 collected and static data is tried to |
3008 be freed. */ | 3010 be freed. */ |
3009 #else /* not MC_ALLOC */ | 3011 #else /* not MC_ALLOC */ |
3010 /* Allocate the string header */ | 3012 /* Allocate the string header */ |
5523 mark_object (bind->old_value); | 5525 mark_object (bind->old_value); |
5524 } | 5526 } |
5525 } | 5527 } |
5526 | 5528 |
5527 { | 5529 { |
5528 struct catchtag *catch; | 5530 struct catchtag *c; |
5529 for (catch = catchlist; catch; catch = catch->next) | 5531 for (c = catchlist; c; c = c->next) |
5530 { | 5532 { |
5531 mark_object (catch->tag); | 5533 mark_object (c->tag); |
5532 mark_object (catch->val); | 5534 mark_object (c->val); |
5533 mark_object (catch->actual_tag); | 5535 mark_object (c->actual_tag); |
5534 mark_object (catch->backtrace); | 5536 mark_object (c->backtrace); |
5535 } | 5537 } |
5536 } | 5538 } |
5537 | 5539 |
5538 { | 5540 { |
5539 struct backtrace *backlist; | 5541 struct backtrace *backlist; |
5665 PROFILE_RECORD_EXITING_SECTION (QSin_garbage_collection); | 5667 PROFILE_RECORD_EXITING_SECTION (QSin_garbage_collection); |
5666 | 5668 |
5667 return; | 5669 return; |
5668 } | 5670 } |
5669 | 5671 |
5670 #ifdef MC_ALLOC | 5672 #ifdef ALLOC_TYPE_STATS |
5671 #ifdef MC_ALLOC_TYPE_STATS | 5673 |
5672 static Lisp_Object | 5674 static Lisp_Object |
5673 gc_plist_hack (const Ascbyte *name, int value, Lisp_Object tail) | 5675 gc_plist_hack (const Ascbyte *name, EMACS_INT value, Lisp_Object tail) |
5674 { | 5676 { |
5675 /* C doesn't have local functions (or closures, or GC, or readable syntax, | 5677 /* C doesn't have local functions (or closures, or GC, or readable syntax, |
5676 or portable numeric datatypes, or bit-vectors, or characters, or | 5678 or portable numeric datatypes, or bit-vectors, or characters, or |
5677 arrays, or exceptions, or ...) */ | 5679 arrays, or exceptions, or ...) */ |
5678 return cons3 (intern (name), make_int (value), tail); | 5680 return cons3 (intern (name), make_int (value), tail); |
5679 } | 5681 } |
5680 | 5682 |
5681 DEFUN("lrecord-stats", Flrecord_stats, 0, 0 ,"", /* | 5683 static Lisp_Object |
5682 Return statistics about lrecords in a property list. | 5684 object_memory_usage_stats (int set_total_gc_usage) |
5683 */ | |
5684 ()) | |
5685 { | 5685 { |
5686 Lisp_Object pl = Qnil; | 5686 Lisp_Object pl = Qnil; |
5687 int i; | 5687 int i; |
5688 EMACS_INT tgu_val = 0; | |
5689 | |
5690 #ifdef MC_ALLOC | |
5688 | 5691 |
5689 for (i = 0; i < (countof (lrecord_implementations_table) | 5692 for (i = 0; i < (countof (lrecord_implementations_table) |
5690 + MODULE_DEFINABLE_TYPE_COUNT); i++) | 5693 + MODULE_DEFINABLE_TYPE_COUNT); i++) |
5691 { | 5694 { |
5692 if (lrecord_stats[i].instances_in_use != 0) | 5695 if (lrecord_stats[i].instances_in_use != 0) |
5707 | 5710 |
5708 sprintf (buf, "%s-storage", name); | 5711 sprintf (buf, "%s-storage", name); |
5709 pl = gc_plist_hack (buf, | 5712 pl = gc_plist_hack (buf, |
5710 lrecord_stats[i].bytes_in_use, | 5713 lrecord_stats[i].bytes_in_use, |
5711 pl); | 5714 pl); |
5715 tgu_val += lrecord_stats[i].bytes_in_use_including_overhead; | |
5712 | 5716 |
5713 if (name[len-1] == 's') | 5717 if (name[len-1] == 's') |
5714 sprintf (buf, "%ses-used", name); | 5718 sprintf (buf, "%ses-used", name); |
5715 else | 5719 else |
5716 sprintf (buf, "%ss-used", name); | 5720 sprintf (buf, "%ss-used", name); |
5721 lrecord_string_data_bytes_in_use_including_overhead, pl); | 5725 lrecord_string_data_bytes_in_use_including_overhead, pl); |
5722 pl = gc_plist_hack ("string-data-storage-additional", | 5726 pl = gc_plist_hack ("string-data-storage-additional", |
5723 lrecord_string_data_bytes_in_use, pl); | 5727 lrecord_string_data_bytes_in_use, pl); |
5724 pl = gc_plist_hack ("string-data-used", | 5728 pl = gc_plist_hack ("string-data-used", |
5725 lrecord_string_data_instances_in_use, pl); | 5729 lrecord_string_data_instances_in_use, pl); |
5726 | 5730 tgu_val += lrecord_string_data_bytes_in_use_including_overhead; |
5727 return pl; | 5731 |
5728 } | |
5729 #endif /* not MC_ALLOC_TYPE_STATS */ | |
5730 | |
5731 DEFUN ("garbage-collect", Fgarbage_collect, 0, 0, "", /* | |
5732 Reclaim storage for Lisp objects no longer needed. | |
5733 Return info on amount of space in use: | |
5734 ((USED-CONSES . STORAGE-CONSES) (USED-SYMS . STORAGE-SYMS) | |
5735 (USED-MARKERS . STORAGE-MARKERS) USED-STRING-CHARS USED-VECTOR-SLOTS | |
5736 PLIST) | |
5737 where `PLIST' is a list of alternating keyword/value pairs providing | |
5738 more detailed information. | |
5739 Garbage collection happens automatically if you cons more than | |
5740 `gc-cons-threshold' bytes of Lisp data since previous garbage collection. | |
5741 */ | |
5742 ()) | |
5743 { | |
5744 garbage_collect_1 (); | |
5745 | |
5746 #ifdef MC_ALLOC_TYPE_STATS | |
5747 /* The things we do for backwards-compatibility */ | |
5748 return | |
5749 list6 | |
5750 (Fcons (make_int (lrecord_stats[lrecord_type_cons].instances_in_use), | |
5751 make_int (lrecord_stats[lrecord_type_cons] | |
5752 .bytes_in_use_including_overhead)), | |
5753 Fcons (make_int (lrecord_stats[lrecord_type_symbol].instances_in_use), | |
5754 make_int (lrecord_stats[lrecord_type_symbol] | |
5755 .bytes_in_use_including_overhead)), | |
5756 Fcons (make_int (lrecord_stats[lrecord_type_marker].instances_in_use), | |
5757 make_int (lrecord_stats[lrecord_type_marker] | |
5758 .bytes_in_use_including_overhead)), | |
5759 make_int (lrecord_stats[lrecord_type_string] | |
5760 .bytes_in_use_including_overhead), | |
5761 make_int (lrecord_stats[lrecord_type_vector] | |
5762 .bytes_in_use_including_overhead), | |
5763 Flrecord_stats ()); | |
5764 #else /* not MC_ALLOC_TYPE_STATS */ | |
5765 return Qnil; | |
5766 #endif /* not MC_ALLOC_TYPE_STATS */ | |
5767 } | |
5768 #else /* not MC_ALLOC */ | 5732 #else /* not MC_ALLOC */ |
5769 /* Debugging aids. */ | |
5770 | |
5771 static Lisp_Object | |
5772 gc_plist_hack (const Ascbyte *name, int value, Lisp_Object tail) | |
5773 { | |
5774 /* C doesn't have local functions (or closures, or GC, or readable syntax, | |
5775 or portable numeric datatypes, or bit-vectors, or characters, or | |
5776 arrays, or exceptions, or ...) */ | |
5777 return cons3 (intern (name), make_int (value), tail); | |
5778 } | |
5779 | 5733 |
5780 #define HACK_O_MATIC(type, name, pl) do { \ | 5734 #define HACK_O_MATIC(type, name, pl) do { \ |
5781 int s = 0; \ | 5735 EMACS_INT s = 0; \ |
5782 struct type##_block *x = current_##type##_block; \ | 5736 struct type##_block *x = current_##type##_block; \ |
5783 while (x) { s += sizeof (*x) + MALLOC_OVERHEAD; x = x->prev; } \ | 5737 while (x) { s += sizeof (*x) + MALLOC_OVERHEAD; x = x->prev; } \ |
5738 tgu_val += s; \ | |
5784 (pl) = gc_plist_hack ((name), s, (pl)); \ | 5739 (pl) = gc_plist_hack ((name), s, (pl)); \ |
5785 } while (0) | 5740 } while (0) |
5786 | |
5787 DEFUN ("garbage-collect", Fgarbage_collect, 0, 0, "", /* | |
5788 Reclaim storage for Lisp objects no longer needed. | |
5789 Return info on amount of space in use: | |
5790 ((USED-CONSES . FREE-CONSES) (USED-SYMS . FREE-SYMS) | |
5791 (USED-MARKERS . FREE-MARKERS) USED-STRING-CHARS USED-VECTOR-SLOTS | |
5792 PLIST) | |
5793 where `PLIST' is a list of alternating keyword/value pairs providing | |
5794 more detailed information. | |
5795 Garbage collection happens automatically if you cons more than | |
5796 `gc-cons-threshold' bytes of Lisp data since previous garbage collection. | |
5797 */ | |
5798 ()) | |
5799 { | |
5800 Lisp_Object pl = Qnil; | |
5801 int i; | |
5802 int gc_count_vector_total_size = 0; | |
5803 garbage_collect_1 (); | |
5804 | 5741 |
5805 for (i = 0; i < lrecord_type_count; i++) | 5742 for (i = 0; i < lrecord_type_count; i++) |
5806 { | 5743 { |
5807 if (lcrecord_stats[i].bytes_in_use != 0 | 5744 if (lcrecord_stats[i].bytes_in_use != 0 |
5808 || lcrecord_stats[i].bytes_freed != 0 | 5745 || lcrecord_stats[i].bytes_freed != 0 |
5809 || lcrecord_stats[i].instances_on_free_list != 0) | 5746 || lcrecord_stats[i].instances_on_free_list != 0) |
5810 { | 5747 { |
5811 char buf [255]; | 5748 char buf [255]; |
5812 const char *name = lrecord_implementations_table[i]->name; | 5749 const char *name = lrecord_implementations_table[i]->name; |
5813 int len = strlen (name); | 5750 int len = strlen (name); |
5814 /* save this for the FSFmacs-compatible part of the summary */ | |
5815 if (i == lrecord_type_vector) | |
5816 gc_count_vector_total_size = | |
5817 lcrecord_stats[i].bytes_in_use + lcrecord_stats[i].bytes_freed; | |
5818 | 5751 |
5819 sprintf (buf, "%s-storage", name); | 5752 sprintf (buf, "%s-storage", name); |
5820 pl = gc_plist_hack (buf, lcrecord_stats[i].bytes_in_use, pl); | 5753 pl = gc_plist_hack (buf, lcrecord_stats[i].bytes_in_use, pl); |
5754 tgu_val += lcrecord_stats[i].bytes_in_use; | |
5821 /* Okay, simple pluralization check for `symbol-value-varalias' */ | 5755 /* Okay, simple pluralization check for `symbol-value-varalias' */ |
5822 if (name[len-1] == 's') | 5756 if (name[len-1] == 's') |
5823 sprintf (buf, "%ses-freed", name); | 5757 sprintf (buf, "%ses-freed", name); |
5824 else | 5758 else |
5825 sprintf (buf, "%ss-freed", name); | 5759 sprintf (buf, "%ss-freed", name); |
5893 | 5827 |
5894 HACK_O_MATIC (cons, "cons-storage", pl); | 5828 HACK_O_MATIC (cons, "cons-storage", pl); |
5895 pl = gc_plist_hack ("conses-free", gc_count_num_cons_freelist, pl); | 5829 pl = gc_plist_hack ("conses-free", gc_count_num_cons_freelist, pl); |
5896 pl = gc_plist_hack ("conses-used", gc_count_num_cons_in_use, pl); | 5830 pl = gc_plist_hack ("conses-used", gc_count_num_cons_in_use, pl); |
5897 | 5831 |
5832 #undef HACK_O_MATIC | |
5833 | |
5834 #endif /* MC_ALLOC */ | |
5835 | |
5836 if (set_total_gc_usage) | |
5837 { | |
5838 total_gc_usage = tgu_val; | |
5839 total_gc_usage_set = 1; | |
5840 } | |
5841 | |
5842 return pl; | |
5843 } | |
5844 | |
5845 DEFUN("object-memory-usage-stats", Fobject_memory_usage_stats, 0, 0 ,"", /* | |
5846 Return statistics about memory usage of Lisp objects. | |
5847 */ | |
5848 ()) | |
5849 { | |
5850 return object_memory_usage_stats (0); | |
5851 } | |
5852 | |
5853 #endif /* ALLOC_TYPE_STATS */ | |
5854 | |
5855 /* Debugging aids. */ | |
5856 | |
5857 DEFUN ("garbage-collect", Fgarbage_collect, 0, 0, "", /* | |
5858 Reclaim storage for Lisp objects no longer needed. | |
5859 Return info on amount of space in use: | |
5860 ((USED-CONSES . FREE-CONSES) (USED-SYMS . FREE-SYMS) | |
5861 (USED-MARKERS . FREE-MARKERS) USED-STRING-CHARS USED-VECTOR-SLOTS | |
5862 PLIST) | |
5863 where `PLIST' is a list of alternating keyword/value pairs providing | |
5864 more detailed information. | |
5865 Garbage collection happens automatically if you cons more than | |
5866 `gc-cons-threshold' bytes of Lisp data since previous garbage collection. | |
5867 */ | |
5868 ()) | |
5869 { | |
5870 /* Record total usage for purposes of determining next GC */ | |
5871 garbage_collect_1 (); | |
5872 | |
5873 /* This will get set to 1, and total_gc_usage computed, as part of the | |
5874 call to object_memory_usage_stats() -- if ALLOC_TYPE_STATS is enabled. */ | |
5875 total_gc_usage_set = 0; | |
5876 #ifdef ALLOC_TYPE_STATS | |
5898 /* The things we do for backwards-compatibility */ | 5877 /* The things we do for backwards-compatibility */ |
5878 #ifdef MC_ALLOC | |
5879 return | |
5880 list6 | |
5881 (Fcons (make_int (lrecord_stats[lrecord_type_cons].instances_in_use), | |
5882 make_int (lrecord_stats[lrecord_type_cons] | |
5883 .bytes_in_use_including_overhead)), | |
5884 Fcons (make_int (lrecord_stats[lrecord_type_symbol].instances_in_use), | |
5885 make_int (lrecord_stats[lrecord_type_symbol] | |
5886 .bytes_in_use_including_overhead)), | |
5887 Fcons (make_int (lrecord_stats[lrecord_type_marker].instances_in_use), | |
5888 make_int (lrecord_stats[lrecord_type_marker] | |
5889 .bytes_in_use_including_overhead)), | |
5890 make_int (lrecord_stats[lrecord_type_string] | |
5891 .bytes_in_use_including_overhead), | |
5892 make_int (lrecord_stats[lrecord_type_vector] | |
5893 .bytes_in_use_including_overhead), | |
5894 object_memory_usage_stats (1)); | |
5895 #else /* not MC_ALLOC */ | |
5899 return | 5896 return |
5900 list6 (Fcons (make_int (gc_count_num_cons_in_use), | 5897 list6 (Fcons (make_int (gc_count_num_cons_in_use), |
5901 make_int (gc_count_num_cons_freelist)), | 5898 make_int (gc_count_num_cons_freelist)), |
5902 Fcons (make_int (gc_count_num_symbol_in_use), | 5899 Fcons (make_int (gc_count_num_symbol_in_use), |
5903 make_int (gc_count_num_symbol_freelist)), | 5900 make_int (gc_count_num_symbol_freelist)), |
5904 Fcons (make_int (gc_count_num_marker_in_use), | 5901 Fcons (make_int (gc_count_num_marker_in_use), |
5905 make_int (gc_count_num_marker_freelist)), | 5902 make_int (gc_count_num_marker_freelist)), |
5906 make_int (gc_count_string_total_size), | 5903 make_int (gc_count_string_total_size), |
5907 make_int (gc_count_vector_total_size), | 5904 make_int (lcrecord_stats[lrecord_type_vector].bytes_in_use + |
5908 pl); | 5905 lcrecord_stats[lrecord_type_vector].bytes_freed), |
5909 } | 5906 object_memory_usage_stats (1)); |
5910 #undef HACK_O_MATIC | 5907 #endif /* not MC_ALLOC */ |
5911 #endif /* not MC_ALLOC */ | 5908 #else /* not ALLOC_TYPE_STATS */ |
5909 return Qnil; | |
5910 #endif /* ALLOC_TYPE_STATS */ | |
5911 } | |
5912 | 5912 |
5913 DEFUN ("consing-since-gc", Fconsing_since_gc, 0, 0, "", /* | 5913 DEFUN ("consing-since-gc", Fconsing_since_gc, 0, 0, "", /* |
5914 Return the number of bytes consed since the last garbage collection. | 5914 Return the number of bytes consed since the last garbage collection. |
5915 \"Consed\" is a misnomer in that this actually counts allocation | 5915 \"Consed\" is a misnomer in that this actually counts allocation |
5916 of all different kinds of objects, not just conses. | 5916 of all different kinds of objects, not just conses. |
5932 { | 5932 { |
5933 return make_int ((EMACS_INT) sbrk (0) / 1024); | 5933 return make_int ((EMACS_INT) sbrk (0) / 1024); |
5934 } | 5934 } |
5935 #endif | 5935 #endif |
5936 | 5936 |
5937 DEFUN ("memory-usage", Fmemory_usage, 0, 0, 0, /* | 5937 DEFUN ("total-memory-usage", Ftotal_memory_usage, 0, 0, 0, /* |
5938 Return the total number of bytes used by the data segment in XEmacs. | 5938 Return the total number of bytes used by the data segment in XEmacs. |
5939 This may be helpful in debugging XEmacs's memory usage. | 5939 This may be helpful in debugging XEmacs's memory usage. |
5940 NOTE: This may or may not be accurate! It is hard to determine this | |
5941 value in a system-independent fashion. On Windows, for example, the | |
5942 returned number tends to be much greater than reality. | |
5940 */ | 5943 */ |
5941 ()) | 5944 ()) |
5942 { | 5945 { |
5943 return make_int (total_data_usage ()); | 5946 return make_int (total_data_usage ()); |
5944 } | 5947 } |
5948 | |
5949 #ifdef ALLOC_TYPE_STATS | |
5950 DEFUN ("object-memory-usage", Fobject_memory_usage, 0, 0, 0, /* | |
5951 Return total number of bytes used for object storage in XEmacs. | |
5952 This may be helpful in debugging XEmacs's memory usage. | |
5953 See also `consing-since-gc' and `object-memory-usage-stats'. | |
5954 */ | |
5955 ()) | |
5956 { | |
5957 return make_int (total_gc_usage + consing_since_gc); | |
5958 } | |
5959 #endif /* ALLOC_TYPE_STATS */ | |
5945 | 5960 |
5946 void | 5961 void |
5947 recompute_funcall_allocation_flag (void) | 5962 recompute_funcall_allocation_flag (void) |
5948 { | 5963 { |
5949 funcall_allocation_flag = | 5964 funcall_allocation_flag = |
5959 if (always_gc) | 5974 if (always_gc) |
5960 need_to_garbage_collect = 1; | 5975 need_to_garbage_collect = 1; |
5961 else | 5976 else |
5962 need_to_garbage_collect = | 5977 need_to_garbage_collect = |
5963 (consing_since_gc > gc_cons_threshold | 5978 (consing_since_gc > gc_cons_threshold |
5979 && | |
5964 #if 0 /* #### implement this better */ | 5980 #if 0 /* #### implement this better */ |
5965 && | |
5966 (100 * consing_since_gc) / total_data_usage () >= | 5981 (100 * consing_since_gc) / total_data_usage () >= |
5967 gc_cons_percentage | 5982 gc_cons_percentage |
5968 #endif /* 0 */ | 5983 #else |
5984 (!total_gc_usage_set || | |
5985 (100 * consing_since_gc) / total_gc_usage >= | |
5986 gc_cons_percentage) | |
5987 #endif | |
5969 ); | 5988 ); |
5970 recompute_funcall_allocation_flag (); | 5989 recompute_funcall_allocation_flag (); |
5971 } | 5990 } |
5972 | 5991 |
5973 | 5992 |
6214 need_to_check_c_alloca = 0; | 6233 need_to_check_c_alloca = 0; |
6215 funcall_allocation_flag = 0; | 6234 funcall_allocation_flag = 0; |
6216 funcall_alloca_count = 0; | 6235 funcall_alloca_count = 0; |
6217 | 6236 |
6218 #if 1 | 6237 #if 1 |
6219 gc_cons_threshold = 500000; /* XEmacs change */ | 6238 gc_cons_threshold = 2000000; /* XEmacs change */ |
6220 #else | 6239 #else |
6221 gc_cons_threshold = 15000; /* debugging */ | 6240 gc_cons_threshold = 15000; /* debugging */ |
6222 #endif | 6241 #endif |
6223 gc_cons_percentage = 0; /* #### 20; Don't have an accurate measure of | 6242 gc_cons_percentage = 40; /* #### what is optimal? */ |
6224 memory usage on Windows; not verified on other | 6243 total_gc_usage_set = 0; |
6225 systems */ | |
6226 lrecord_uid_counter = 259; | 6244 lrecord_uid_counter = 259; |
6227 #ifndef MC_ALLOC | 6245 #ifndef MC_ALLOC |
6228 debug_string_purity = 0; | 6246 debug_string_purity = 0; |
6229 #endif /* not MC_ALLOC */ | 6247 #endif /* not MC_ALLOC */ |
6230 | 6248 |
6345 DEFSUBR (Fmake_string); | 6363 DEFSUBR (Fmake_string); |
6346 DEFSUBR (Fstring); | 6364 DEFSUBR (Fstring); |
6347 DEFSUBR (Fmake_symbol); | 6365 DEFSUBR (Fmake_symbol); |
6348 DEFSUBR (Fmake_marker); | 6366 DEFSUBR (Fmake_marker); |
6349 DEFSUBR (Fpurecopy); | 6367 DEFSUBR (Fpurecopy); |
6350 #ifdef MC_ALLOC_TYPE_STATS | 6368 #ifdef ALLOC_TYPE_STATS |
6351 DEFSUBR (Flrecord_stats); | 6369 DEFSUBR (Fobject_memory_usage_stats); |
6352 #endif /* MC_ALLOC_TYPE_STATS */ | 6370 DEFSUBR (Fobject_memory_usage); |
6371 #endif /* ALLOC_TYPE_STATS */ | |
6353 DEFSUBR (Fgarbage_collect); | 6372 DEFSUBR (Fgarbage_collect); |
6354 #if 0 | 6373 #if 0 |
6355 DEFSUBR (Fmemory_limit); | 6374 DEFSUBR (Fmemory_limit); |
6356 #endif | 6375 #endif |
6357 DEFSUBR (Fmemory_usage); | 6376 DEFSUBR (Ftotal_memory_usage); |
6358 DEFSUBR (Fconsing_since_gc); | 6377 DEFSUBR (Fconsing_since_gc); |
6359 } | 6378 } |
6360 | 6379 |
6361 void | 6380 void |
6362 vars_of_alloc (void) | 6381 vars_of_alloc (void) |
6384 happen at *EVERY* call to `eval' or `funcall'. This is an extremely | 6403 happen at *EVERY* call to `eval' or `funcall'. This is an extremely |
6385 effective way to check GCPRO problems, but be warned that your XEmacs | 6404 effective way to check GCPRO problems, but be warned that your XEmacs |
6386 will be unusable! You almost certainly won't have the patience to wait | 6405 will be unusable! You almost certainly won't have the patience to wait |
6387 long enough to be able to set it back. | 6406 long enough to be able to set it back. |
6388 | 6407 |
6389 See also `consing-since-gc'. | 6408 See also `consing-since-gc' and `gc-cons-percentage'. |
6390 */ ); | 6409 */ ); |
6391 | 6410 |
6392 DEFVAR_INT ("gc-cons-percentage", &gc_cons_percentage /* | 6411 DEFVAR_INT ("gc-cons-percentage", &gc_cons_percentage /* |
6393 *Percentage of memory allocated between garbage collections. | 6412 *Percentage of memory allocated between garbage collections. |
6394 | 6413 |
6395 Garbage collection will happen if this percentage of the total amount of | 6414 Garbage collection will happen if this percentage of the total amount of |
6396 memory used for data has been allocated since the last garbage collection. | 6415 memory used for data (see `lisp-object-memory-usage') has been allocated |
6397 However, it will not happen if less than `gc-cons-threshold' bytes have | 6416 since the last garbage collection. However, it will not happen if less |
6398 been allocated -- this sets an absolute minimum in case very little data | 6417 than `gc-cons-threshold' bytes have been allocated -- this sets an absolute |
6399 has been allocated or the percentage is set very low. Set this to 0 to | 6418 minimum in case very little data has been allocated or the percentage is |
6400 have garbage collection always happen after `gc-cons-threshold' bytes have | 6419 set very low. Set this to 0 to have garbage collection always happen after |
6401 been allocated, regardless of current memory usage. | 6420 `gc-cons-threshold' bytes have been allocated, regardless of current memory |
6402 | 6421 usage. |
6403 Garbage collection happens automatically when `eval' or `funcall' are | 6422 |
6404 called. (Note that `funcall' is called implicitly as part of evaluation.) | 6423 See also `consing-since-gc' and `gc-cons-threshold'. |
6405 By binding this temporarily to a large number, you can effectively | |
6406 prevent garbage collection during a part of the program. | |
6407 | |
6408 See also `consing-since-gc'. | |
6409 */ ); | 6424 */ ); |
6410 | 6425 |
6411 #ifdef DEBUG_XEMACS | 6426 #ifdef DEBUG_XEMACS |
6412 DEFVAR_INT ("debug-allocation", &debug_allocation /* | 6427 DEFVAR_INT ("debug-allocation", &debug_allocation /* |
6413 If non-zero, print out information to stderr about all objects allocated. | 6428 If non-zero, print out information to stderr about all objects allocated. |