Mercurial > hg > xemacs-beta
comparison src/alloc.c @ 70:131b0175ea99 r20-0b30
Import from CVS: tag r20-0b30
author | cvs |
---|---|
date | Mon, 13 Aug 2007 09:02:59 +0200 |
parents | 56c54cf7c5b6 |
children | 1ce6082ce73f |
comparison
equal
deleted
inserted
replaced
69:804d1389bcd6 | 70:131b0175ea99 |
---|---|
42 | 42 |
43 #ifndef standalone | 43 #ifndef standalone |
44 #include "backtrace.h" | 44 #include "backtrace.h" |
45 #include "buffer.h" | 45 #include "buffer.h" |
46 #include "bytecode.h" | 46 #include "bytecode.h" |
47 #include "chartab.h" | |
47 #include "device.h" | 48 #include "device.h" |
48 #include "elhash.h" | 49 #include "elhash.h" |
49 #include "events.h" | 50 #include "events.h" |
50 #include "extents.h" | 51 #include "extents.h" |
51 #include "frame.h" | 52 #include "frame.h" |
214 pure_lossage += size; | 215 pure_lossage += size; |
215 return (0); | 216 return (0); |
216 } | 217 } |
217 else if (pureptr + size > PURESIZE) | 218 else if (pureptr + size > PURESIZE) |
218 { | 219 { |
219 /* This can cause recursive bad behavior, we'll yell at the end */ | 220 message ("\nERROR: Pure Lisp storage exhausted!\n"); |
220 /* when we're done. */ | |
221 /* message ("\nERROR: Pure Lisp storage exhausted!\n"); */ | |
222 pure_lossage = size; | 221 pure_lossage = size; |
223 return (0); | 222 return (0); |
224 } | 223 } |
225 else | 224 else |
226 return (1); | 225 return (1); |
1602 b->annotated = Fpurecopy (Vcurrent_compiled_function_annotation); | 1601 b->annotated = Fpurecopy (Vcurrent_compiled_function_annotation); |
1603 else if (!NILP (Vload_file_name_internal_the_purecopy)) | 1602 else if (!NILP (Vload_file_name_internal_the_purecopy)) |
1604 b->annotated = Vload_file_name_internal_the_purecopy; | 1603 b->annotated = Vload_file_name_internal_the_purecopy; |
1605 else if (!NILP (Vload_file_name_internal)) | 1604 else if (!NILP (Vload_file_name_internal)) |
1606 { | 1605 { |
1607 struct gcpro gcpro1; | |
1608 GCPRO1(val); /* don't let val or b get reaped */ | |
1609 Vload_file_name_internal_the_purecopy = | 1606 Vload_file_name_internal_the_purecopy = |
1610 Fpurecopy (Ffile_name_nondirectory (Vload_file_name_internal)); | 1607 Fpurecopy (Ffile_name_nondirectory (Vload_file_name_internal)); |
1611 b->annotated = Vload_file_name_internal_the_purecopy; | 1608 b->annotated = Vload_file_name_internal_the_purecopy; |
1612 UNGCPRO; | |
1613 } | 1609 } |
1614 #endif | 1610 #endif |
1615 | 1611 |
1616 #ifdef I18N3 | 1612 #ifdef I18N3 |
1617 if (docp && intp && domp) | 1613 if (docp && intp && domp) |
2060 #ifdef VERIFY_STRING_CHARS_INTEGRITY | 2056 #ifdef VERIFY_STRING_CHARS_INTEGRITY |
2061 verify_string_chars_integrity (); | 2057 verify_string_chars_integrity (); |
2062 #endif | 2058 #endif |
2063 } | 2059 } |
2064 | 2060 |
2061 #ifdef MULE | |
2062 | |
2063 void | |
2064 set_string_char (struct Lisp_String *s, Charcount i, Emchar c) | |
2065 { | |
2066 Bytecount oldlen, newlen; | |
2067 Bufbyte newstr[MAX_EMCHAR_LEN]; | |
2068 Bytecount bytoff = charcount_to_bytecount (string_data (s), i); | |
2069 | |
2070 oldlen = charcount_to_bytecount (string_data (s) + bytoff, 1); | |
2071 newlen = set_charptr_emchar (newstr, c); | |
2072 | |
2073 if (oldlen != newlen) | |
2074 resize_string (s, bytoff, newlen - oldlen); | |
2075 /* Remember, string_data (s) might have changed so we can't | |
2076 cache it. */ | |
2077 memcpy (string_data (s) + bytoff, newstr, newlen); | |
2078 } | |
2079 | |
2080 #endif /* MULE */ | |
2081 | |
2065 DEFUN ("make-string", Fmake_string, 2, 2, 0, /* | 2082 DEFUN ("make-string", Fmake_string, 2, 2, 0, /* |
2066 Return a newly created string of length LENGTH, with each element being INIT. | 2083 Return a newly created string of length LENGTH, with each element being INIT. |
2067 LENGTH must be an integer and INIT must be a character. | 2084 LENGTH must be an integer and INIT must be a character. |
2068 */ | 2085 */ |
2069 (length, init)) | 2086 (length, init)) |
2098 and package it up it into a Lisp string. */ | 2115 and package it up it into a Lisp string. */ |
2099 Lisp_Object | 2116 Lisp_Object |
2100 make_string (CONST Bufbyte *contents, Bytecount length) | 2117 make_string (CONST Bufbyte *contents, Bytecount length) |
2101 { | 2118 { |
2102 Lisp_Object val; | 2119 Lisp_Object val; |
2120 | |
2121 /* Make sure we find out about bad make_string's when they happen */ | |
2122 #if defined (ERROR_CHECK_BUFPOS) && defined (MULE) | |
2123 bytecount_to_charcount (contents, length); /* Just for the assertions */ | |
2124 #endif | |
2103 | 2125 |
2104 val = make_uninit_string (length); | 2126 val = make_uninit_string (length); |
2105 memcpy (XSTRING_DATA (val), contents, length); | 2127 memcpy (XSTRING_DATA (val), contents, length); |
2106 return (val); | 2128 return (val); |
2107 } | 2129 } |
2204 (struct free_lcrecord_header *) lheader; | 2226 (struct free_lcrecord_header *) lheader; |
2205 | 2227 |
2206 #ifdef ERROR_CHECK_GC | 2228 #ifdef ERROR_CHECK_GC |
2207 CONST struct lrecord_implementation *implementation | 2229 CONST struct lrecord_implementation *implementation |
2208 = lheader->implementation; | 2230 = lheader->implementation; |
2209 | 2231 |
2210 /* There should be no other pointers to the free list. */ | 2232 /* There should be no other pointers to the free list. */ |
2211 assert (!MARKED_RECORD_HEADER_P (lheader)); | 2233 assert (!MARKED_RECORD_HEADER_P (lheader)); |
2212 /* Only lcrecords should be here. */ | 2234 /* Only lcrecords should be here. */ |
2213 assert (!implementation->basic_p); | 2235 assert (!implementation->basic_p); |
2214 /* Only free lcrecords should be here. */ | 2236 /* Only free lcrecords should be here. */ |
2217 assert (implementation == list->implementation); | 2239 assert (implementation == list->implementation); |
2218 /* So must the size. */ | 2240 /* So must the size. */ |
2219 assert (implementation->static_size == 0 | 2241 assert (implementation->static_size == 0 |
2220 || implementation->static_size == list->size); | 2242 || implementation->static_size == list->size); |
2221 #endif /* ERROR_CHECK_GC */ | 2243 #endif /* ERROR_CHECK_GC */ |
2222 | 2244 |
2223 MARK_RECORD_HEADER (lheader); | 2245 MARK_RECORD_HEADER (lheader); |
2224 chain = free_header->chain; | 2246 chain = free_header->chain; |
2225 } | 2247 } |
2226 | 2248 |
2227 return Qnil; | 2249 return Qnil; |
2550 { | 2572 { |
2551 if (COMPILED_FUNCTIONP (obj)) | 2573 if (COMPILED_FUNCTIONP (obj)) |
2552 { | 2574 { |
2553 struct Lisp_Compiled_Function *o = XCOMPILED_FUNCTION (obj); | 2575 struct Lisp_Compiled_Function *o = XCOMPILED_FUNCTION (obj); |
2554 Lisp_Object new = make_compiled_function (1); | 2576 Lisp_Object new = make_compiled_function (1); |
2555 /* How on earth could this code have worked before? -sb */ | 2577 struct Lisp_Compiled_Function *n = XCOMPILED_FUNCTION (obj); |
2556 struct Lisp_Compiled_Function *n = XCOMPILED_FUNCTION (new); | |
2557 n->flags = o->flags; | 2578 n->flags = o->flags; |
2558 n->bytecodes = Fpurecopy (o->bytecodes); | 2579 n->bytecodes = Fpurecopy (o->bytecodes); |
2559 n->constants = Fpurecopy (o->constants); | 2580 n->constants = Fpurecopy (o->constants); |
2560 n->arglist = Fpurecopy (o->arglist); | 2581 n->arglist = Fpurecopy (o->arglist); |
2561 n->doc_and_interactive = Fpurecopy (o->doc_and_interactive); | 2582 n->doc_and_interactive = Fpurecopy (o->doc_and_interactive); |
2562 n->maxdepth = o->maxdepth; | |
2563 return (new); | 2583 return (new); |
2564 } | 2584 } |
2565 #ifdef LISP_FLOAT_TYPE | 2585 #ifdef LISP_FLOAT_TYPE |
2566 else if (FLOATP (obj)) | 2586 else if (FLOATP (obj)) |
2567 return make_pure_float (float_data (XFLOAT (obj))); | 2587 return make_pure_float (float_data (XFLOAT (obj))); |
2573 return (obj); | 2593 return (obj); |
2574 } | 2594 } |
2575 | 2595 |
2576 | 2596 |
2577 | 2597 |
2578 static void | |
2579 PURESIZE_h(long int puresize) | |
2580 { | |
2581 int fd; | |
2582 char *PURESIZE_h_file = "puresize_adjust.h"; | |
2583 char *WARNING = "/* This file is generated by XEmacs, DO NOT MODIFY!!! */\n"; | |
2584 char define_PURESIZE[256]; | |
2585 | |
2586 if ((fd = open(PURESIZE_h_file, O_WRONLY|O_CREAT|O_TRUNC, 0666)) < 0) { | |
2587 report_file_error("Can't write PURESIZE_ADJUSTMENT", | |
2588 Fcons(build_ext_string(PURESIZE_h_file, FORMAT_FILENAME), | |
2589 Qnil)); | |
2590 } | |
2591 | |
2592 write(fd, WARNING, strlen(WARNING)); | |
2593 sprintf(define_PURESIZE, "# define PURESIZE_ADJUSTMENT %ld\n", | |
2594 puresize - RAW_PURESIZE); | |
2595 write(fd, define_PURESIZE, strlen(define_PURESIZE)); | |
2596 close(fd); | |
2597 } | |
2598 | |
2599 void | 2598 void |
2600 report_pure_usage (int report_impurities, | 2599 report_pure_usage (int report_impurities, |
2601 int die_if_pure_storage_exceeded) | 2600 int die_if_pure_storage_exceeded) |
2602 { | 2601 { |
2603 int rc = 0; | |
2604 | |
2605 if (pure_lossage) | 2602 if (pure_lossage) |
2606 { | 2603 { |
2607 CONST long report_round = 5000; | 2604 CONST long report_round = 5000; |
2608 | 2605 |
2609 message ("\n****\tPure Lisp storage exhausted!\n" | 2606 message ("\n****\tPure Lisp storage exhausted!\n" |
2610 "\tPurespace usage: %ld of %ld\n" | 2607 "\tCheck whether you are loading .el files when .elc files were intended.\n" |
2608 "\tOtherwise, increase PURESIZE in puresize.h and relink.\n\n" | |
2609 "\tPURESIZE is presently %ld.\n" | |
2610 "\tAn additional %ld bytes will guarantee enough pure space;\n" | |
2611 "\ta smaller increment may work (due to structure-sharing).\n" | |
2611 "****", | 2612 "****", |
2612 PURESIZE+pure_lossage, PURESIZE); | 2613 (long) PURESIZE, |
2613 if (die_if_pure_storage_exceeded) { | 2614 (((pure_lossage + report_round - 1) |
2614 PURESIZE_h(PURESIZE + pure_lossage); | 2615 / report_round) * report_round)); |
2615 rc = -1; | |
2616 } | |
2617 } | 2616 } |
2618 else | 2617 else |
2619 { | 2618 { |
2620 int lost = (PURESIZE - pureptr) / 1024; | 2619 int lost = (PURESIZE - pureptr) / 1024; |
2621 char buf[200]; | 2620 char buf[200]; |
2622 | 2621 |
2623 sprintf (buf, "Purespace usage: %ld of %ld (%d%%", | 2622 sprintf (buf, "Purespace usage: %ld of %ld (%d%%", |
2624 pureptr, (long) PURESIZE, | 2623 pureptr, (long) PURESIZE, |
2625 (int) (pureptr / (PURESIZE / 100.0) + 0.5)); | 2624 (int) (pureptr / (PURESIZE / 100.0) + 0.5)); |
2626 if (lost > 2) { | 2625 if (lost > 2) |
2627 sprintf (buf + strlen (buf), " -- %dk wasted", lost); | 2626 sprintf (buf + strlen (buf), " -- %dk wasted", lost); |
2628 if (die_if_pure_storage_exceeded) { | |
2629 PURESIZE_h(pureptr + 16); | |
2630 rc = -1; | |
2631 } | |
2632 } | |
2633 | |
2634 strcat (buf, ")."); | 2627 strcat (buf, ")."); |
2635 message ("%s", buf); | 2628 message ("%s", buf); |
2636 } | 2629 } |
2637 | 2630 |
2638 #ifdef PURESTAT | 2631 #ifdef PURESTAT |
2711 UNGCPRO; | 2704 UNGCPRO; |
2712 garbage_collect_1 (); /* GC garbage_collect's garbage */ | 2705 garbage_collect_1 (); /* GC garbage_collect's garbage */ |
2713 } | 2706 } |
2714 clear_message (); | 2707 clear_message (); |
2715 | 2708 |
2716 if (rc < 0) { | 2709 if (pure_lossage && die_if_pure_storage_exceeded) |
2717 (void)unlink("SATISFIED"); | |
2718 fatal ("Pure size adjusted, will restart `make'"); | |
2719 } else if (pure_lossage && die_if_pure_storage_exceeded) { | |
2720 fatal ("Pure storage exhausted"); | 2710 fatal ("Pure storage exhausted"); |
2721 } | |
2722 } | 2711 } |
2723 | 2712 |
2724 | 2713 |
2725 /**********************************************************************/ | 2714 /**********************************************************************/ |
2726 /* staticpro */ | 2715 /* staticpro */ |
3551 } | 3540 } |
3552 | 3541 |
3553 #endif /* not standalone */ | 3542 #endif /* not standalone */ |
3554 | 3543 |
3555 | 3544 |
3545 | |
3546 #if defined (MULE) && defined (VERIFY_STRING_CHARS_INTEGRITY) | |
3547 | |
3548 static void | |
3549 verify_string_chars_integrity (void) | |
3550 { | |
3551 struct string_chars_block *sb; | |
3552 | |
3553 /* Scan each existing string block sequentially, string by string. */ | |
3554 for (sb = first_string_chars_block; sb; sb = sb->next) | |
3555 { | |
3556 int pos = 0; | |
3557 /* POS is the index of the next string in the block. */ | |
3558 while (pos < sb->pos) | |
3559 { | |
3560 struct string_chars *s_chars = | |
3561 (struct string_chars *) &(sb->string_chars[pos]); | |
3562 struct Lisp_String *string; | |
3563 int size; | |
3564 int fullsize; | |
3565 | |
3566 /* If the string_chars struct is marked as free (i.e. the STRING | |
3567 pointer is 0xFFFFFFFF) then this is an unused chunk of string | |
3568 storage. (See below.) */ | |
3569 | |
3570 if (FREE_STRUCT_P (s_chars)) | |
3571 { | |
3572 fullsize = ((struct unused_string_chars *) s_chars)->fullsize; | |
3573 pos += fullsize; | |
3574 continue; | |
3575 } | |
3576 | |
3577 string = s_chars->string; | |
3578 /* Must be 32-bit aligned. */ | |
3579 assert ((((int) string) & 3) == 0); | |
3580 | |
3581 size = string_length (string); | |
3582 fullsize = STRING_FULLSIZE (size); | |
3583 | |
3584 assert (!BIG_STRING_FULLSIZE_P (fullsize)); | |
3585 assert (string_data (string) == s_chars->chars); | |
3586 pos += fullsize; | |
3587 } | |
3588 assert (pos == sb->pos); | |
3589 } | |
3590 } | |
3591 | |
3592 #endif /* MULE && ERROR_CHECK_GC */ | |
3593 | |
3556 /* Compactify string chars, relocating the reference to each -- | 3594 /* Compactify string chars, relocating the reference to each -- |
3557 free any empty string_chars_block we see. */ | 3595 free any empty string_chars_block we see. */ |
3558 static void | 3596 static void |
3559 compact_string_chars (void) | 3597 compact_string_chars (void) |
3560 { | 3598 { |
3824 | 3862 |
3825 /* Yeah, this list is pretty ad-hoc... */ | 3863 /* Yeah, this list is pretty ad-hoc... */ |
3826 Vprocess_environment = Qnil; | 3864 Vprocess_environment = Qnil; |
3827 Vexec_directory = Qnil; | 3865 Vexec_directory = Qnil; |
3828 Vdata_directory = Qnil; | 3866 Vdata_directory = Qnil; |
3829 Vsite_directory = Qnil; | |
3830 Vdoc_directory = Qnil; | 3867 Vdoc_directory = Qnil; |
3831 Vconfigure_info_directory = Qnil; | 3868 Vconfigure_info_directory = Qnil; |
3832 Vexec_path = Qnil; | 3869 Vexec_path = Qnil; |
3833 Vload_path = Qnil; | 3870 Vload_path = Qnil; |
3834 /* Vdump_load_path = Qnil; */ | 3871 /* Vdump_load_path = Qnil; */ |
4050 /* #### this is somewhat ad-hoc and should probably be an object | 4087 /* #### this is somewhat ad-hoc and should probably be an object |
4051 method */ | 4088 method */ |
4052 prune_weak_hashtables (marked_p); | 4089 prune_weak_hashtables (marked_p); |
4053 prune_weak_lists (marked_p); | 4090 prune_weak_lists (marked_p); |
4054 prune_specifiers (marked_p); | 4091 prune_specifiers (marked_p); |
4092 prune_syntax_tables (marked_p); | |
4055 | 4093 |
4056 gc_sweep (); | 4094 gc_sweep (); |
4057 | 4095 |
4058 consing_since_gc = 0; | 4096 consing_since_gc = 0; |
4059 #ifndef DEBUG_XEMACS | 4097 #ifndef DEBUG_XEMACS |
4150 ()) | 4188 ()) |
4151 { | 4189 { |
4152 Lisp_Object pl = Qnil; | 4190 Lisp_Object pl = Qnil; |
4153 Lisp_Object ret[6]; | 4191 Lisp_Object ret[6]; |
4154 int i; | 4192 int i; |
4155 | |
4156 if (purify_flag && pure_lossage) | |
4157 { | |
4158 return Qnil; | |
4159 } | |
4160 | 4193 |
4161 garbage_collect_1 (); | 4194 garbage_collect_1 (); |
4162 | 4195 |
4163 for (i = 0; i < last_lrecord_type_index_assigned; i++) | 4196 for (i = 0; i < last_lrecord_type_index_assigned; i++) |
4164 { | 4197 { |