Mercurial > hg > xemacs-beta
annotate src/gc.c @ 5258:1ed4cefddd12
Add a couple of extra docstring backslashes, #'format-time-string
2010-09-05 Aidan Kehoe <kehoea@parhasard.net>
* editfns.c (Fformat_time_string):
Use two backslashes so that there is at least one present in the
output of describe function, when describing the Roman month
number syntax in this function's docstring. Thanks for provoking
me to look at this, Stephen Turnbull.
author | Aidan Kehoe <kehoea@parhasard.net> |
---|---|
date | Sun, 05 Sep 2010 19:22:37 +0100 |
parents | 2cc24c69446c |
children | 308d34e9f07d |
rev | line source |
---|---|
3092 | 1 /* New incremental garbage collector for XEmacs. |
2 Copyright (C) 2005 Marcus Crestani. | |
4934
714f7c9fabb1
make it easier to debug staticpro crashes.
Ben Wing <ben@xemacs.org>
parents:
4502
diff
changeset
|
3 Copyright (C) 2010 Ben Wing. |
3092 | 4 |
5 This file is part of XEmacs. | |
6 | |
7 XEmacs is free software; you can redistribute it and/or modify it | |
8 under the terms of the GNU General Public License as published by the | |
9 Free Software Foundation; either version 2, or (at your option) any | |
10 later version. | |
11 | |
12 XEmacs is distributed in the hope that it will be useful, but WITHOUT | |
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
15 for more details. | |
16 | |
17 You should have received a copy of the GNU General Public License | |
18 along with XEmacs; see the file COPYING. If not, write to | |
19 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, | |
20 Boston, MA 02111-1307, USA. */ | |
21 | |
22 /* Synched up with: Not in FSF. */ | |
23 | |
5238
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
24 /* |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
25 Garbage Collectors in XEmacs |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
26 |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
27 Currently, XEmacs comes with two garbage collectors: |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
28 |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
29 - The "old garbage collector": a simple mark and sweep collector, |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
30 its implementation is mainly spread out over gc.c and alloc.c. |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
31 It is used by the default configuration or if you configure |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
32 `--with-newgc=no'. |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
33 |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
34 - The "new garbage collector": an incremental mark and sweep collector, |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
35 its implementation is in gc.c. It is used if you configure |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
36 `--with-newgc'. It comes with a new allocator, see mc-alloc.c, and |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
37 with the KKCC mark algorith, see below. |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
38 |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
39 Additionally, the old garbage collectors comes with two mark algorithms: |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
40 |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
41 - The "recursive mark algorithm" marks live objects by recursively |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
42 calling mark_* functions on live objects. It is the default mark |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
43 algorithm of the old garbage collector. |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
44 |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
45 - The "KKCC mark algorithm" uses an explicit stack that to keep |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
46 track of the current progress of traversal and uses memory layout |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
47 descriptions (that are also used by the portable dumper) instead |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
48 of the mark_* functions. The old garbage collector uses it if |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
49 you configure `--with-kkcc'. It is the default and only mark |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
50 algorithm of the new garbage collector. |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
51 |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
52 |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
53 The New Incremental Garbage Collector |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
54 |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
55 An incremental garbage collector keeps garbage collection pause |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
56 times short by interleaving small amounts of collection work with |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
57 program execution, it does that by instrumenting write barrier |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
58 algorithms that essentially allow interrupting the mark phase. |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
59 |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
60 |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
61 Write Barrier |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
62 |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
63 A write barrier is the most important prerequisite for fancy |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
64 garbage collection techniques. We implement a "Virtual Dirty Bit |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
65 (short: vdb) Write Barrier" that makes uses of the operating |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
66 system's memory-protection mechanisms: The write barrier |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
67 write-protects memory pages containing heap objects. If the |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
68 mutator tries to modify these objects by writing into the |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
69 write-protected page, the operating system generates a fault. The |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
70 write barrier catches this fault, reads out the error-causing |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
71 address and can thus identify the updated object and page. |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
72 |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
73 Not all environments and operating systems provide the mechanism to |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
74 write-protect memory, catch resulting write faults, and read out |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
75 the faulting address. But luckily, most of today's operating |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
76 systems provide the features needed for the write-barrier |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
77 implementation. Currently, XEmacs includes write-barrier |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
78 implementations for the following platforms: |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
79 |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
80 - POSIX-compliant platforms like up-to-date UNIX, Linux, Solaris, |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
81 etc. use the system call `mprotect' for memory protection, |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
82 `sigaction' for signal handling and get the faulting address from |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
83 `struct siginfo'. See file vdb-posix.c. |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
84 |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
85 - Mach-based systems like Mac OS X use "Mach Exception Handlers". |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
86 See file vdb-mach.c. |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
87 |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
88 - Windows systems like native Windows and Cygwin use Microsoft's |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
89 so-called "Structured Exception Handling". See file vdb-win32.c. |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
90 |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
91 The configure script determines which write barrier implementation |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
92 to use for a system. If no write barrier implementation is working |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
93 on that system, a fall-back "fake" implementation is used: This |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
94 implementation simply turns of the incremental write barrier at |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
95 runtime and does not allow any incremental collection (see |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
96 vdb-fake.c). The garbage collector then acts like a traditional |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
97 mark-and-sweep garbage collector. Generally, the incremental |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
98 garbage collector can be turned of at runtime by the user or by |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
99 applications, see below. |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
100 |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
101 |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
102 Memory Protection and Object Layout |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
103 |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
104 Implementations of a memory-protection mechanism may restrict the |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
105 size and the alignment of the memory region to be on page-size |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
106 boundaries. All objects subject to be covered by the write barrier |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
107 have to be allocated on logical memory pages, so that they meet the |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
108 requirement to be write-protected. The new allocator mc-alloc is |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
109 aware of a system page size---it allocates all Lisp objects on |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
110 logical memory pages and is therefore defaulted to on when the new |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
111 garbage collector is enabled. |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
112 |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
113 Unfortunately, the Lisp object layout that works with the old |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
114 collector leads to holes in the write barrier: Not all data |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
115 structures containing pointers to Lisp objects are allocated on the |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
116 Lisp heap. Some Lisp objects do not carry all their information in |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
117 the object itself. External parts are kept in separately allocated |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
118 memory blocks that are not managed by the new Lisp allocator. |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
119 Examples for these objects are hash tables and dynamic arrays, two |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
120 objects that can dynamically grow and shrink. The separate memory |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
121 blocks are not guaranteed to reside on page boundaries, and thus |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
122 cannot be watched by the write barrier. |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
123 |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
124 Moreover, the separate parts can contain live pointers to other Lisp |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
125 objects. These pointers are not covered by the write barrier and |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
126 modifications by the client during garbage collection do escape. In |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
127 this case, the client changes the connectivity of the reachability |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
128 graph behind the collector's back, which eventually leads to |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
129 erroneous collection of live objects. To solve this problem, I |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
130 transformed the separately allocated parts to fully qualified Lisp |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
131 objects that are managed by the allocator and thus are covered by |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
132 the write barrier. This also removes a lot of special allocation |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
133 and removal code for the out-sourced parts. Generally, allocating |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
134 all data structures that contain pointers to Lisp objects on one |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
135 heap makes the whole memory layout more consistent. |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
136 |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
137 |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
138 Debugging |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
139 |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
140 The virtual-dirty-bit write barrier provokes signals on purpose, |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
141 namely SIGSEGV and SIGBUS. When debugging XEmacs with this write |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
142 barrier running, the debugger always breaks whenever a signal |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
143 occurs. This behavior is generally desired: A debugger has to break |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
144 on signals, to allow the user to examine the cause of the |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
145 signal---especially for illegal memory access, which is a common |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
146 programming error. But the debugger should not break for signals |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
147 caused by the write barrier. Therefore, most debuggers provide the |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
148 ability to turn of their fault handling for specific signals. The |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
149 configure script generates the debugger's settings .gdbinit and |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
150 .dbxrc, adding code to turn of signal handling for SIGSEGV and |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
151 SIGBUS, if the new garbage collector is used. |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
152 |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
153 But what happens if a bug in XEmacs causes an illegal memory access? |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
154 To maintain basic debugging abilities, we use another signal: First, |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
155 the write-barrier signal handler has to determine if the current |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
156 error situation is caused by the write-barrier memory protection or |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
157 not. Therefore, the signal handler checks if the faulting address |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
158 has been write-protected before. If it has not, the fault is caused |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
159 by a bug; the debugger has to break in this situation. To achieve |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
160 this, the signal handler raises SIGABRT to abort the program. Since |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
161 SIGABRT is not masked out by the debugger, XEmacs aborts and allows |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
162 the user to examine the problem. |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
163 |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
164 |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
165 Incremental Garbage Collection |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
166 |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
167 The new garbage collector is still a mark-and-sweep collector, but |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
168 now the mark phase no longer runs in one atomic action, it is |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
169 interleaved with program execution. The incremental garbage |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
170 collector needs an explicit mark stack to store the state of the |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
171 incremental traversal: the KKCC mark algorithm is a prerequisite and |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
172 is enabled by default when the new garbage collector is on. |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
173 |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
174 Garbage collection is invoked as before: After `gc-cons-threshold' |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
175 bytes have been allocated since the last garbage collection (or |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
176 after `gc-cons-percentage' percentage of the total amount of memory |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
177 used for Lisp data has been allocated since the last garbage |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
178 collection) a collection starts. After some initialization, the |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
179 marking begins. |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
180 |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
181 The variable `gc-incremental-traversal-threshold' contains how many |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
182 steps of incremental work have to be executed in one incremental |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
183 traversal cycle. After that many steps have been made, the mark |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
184 phase is interrupted and the client resumes. Now, the Lisp memory |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
185 is write-protected and the write barrier records modified objects. |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
186 Incremental traversal is resumed after |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
187 `gc-cons-incremental-threshold' bytes have been allocated since the |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
188 interruption of garbage collection. Then, the objects recorded by |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
189 the write-barrier have to be re-examined by the traversal, i.e. they |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
190 are re-pushed onto the mark stack and processed again. Once the |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
191 mark stack is empty, the traversal is done. |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
192 |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
193 A full incremental collection is slightly slower than a full garbage |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
194 collection before: There is an overhead for storing pointers into |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
195 objects when the write barrier is running, and an overhead for |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
196 repeated traversal of modified objects. However, the new |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
197 incremental garbage collector reduces client pause times to |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
198 one-third, so even when a garbage collection is running, XEmacs |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
199 stays reactive. |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
200 |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
201 |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
202 Tricolor Marking: White, Black, and Grey Mark Bits |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
203 |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
204 Garbage collection traverses the graph of reachable objects and |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
205 colors them. The objects subject to garbage collection are white at |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
206 the beginning. By the end of the collection, those that will be |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
207 retained are colored black. When there are no reachable objects left |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
208 to blacken, the traversal of live data structures is finished. In |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
209 traditional mark-and-sweep collectors, this black and white coloring |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
210 is sufficient. |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
211 |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
212 In an incremental collector, the intermediate state of the traversal |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
213 is im- portant because of ongoing mutator activity: the mutator |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
214 cannot be allowed to change things in such way that the collector |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
215 will fail to find all reachable objects. To understand and prevent |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
216 such interactions between the mutator and the collector, it is |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
217 useful to introduce a third color, grey. |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
218 |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
219 Grey objects have been reached by the traversal, but its descendants |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
220 may not have been. White objects are changed to grey when they are |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
221 reached by the traversal. Grey objects mark the current state of the |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
222 traversal: traversal pro- ceeds by processing the grey objects. The |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
223 KKCC mark stack holds all the currently grey-colored objects. |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
224 Processing a grey object means following its outgoing pointers, and |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
225 coloring it black afterwards. |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
226 |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
227 Intuitively, the traversal proceeds in a wavefront of grey objects |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
228 that separates the unreached objects, which are colored white, from |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
229 the already processed black objects. |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
230 |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
231 The allocator takes care of storing the mark bits: The mark bits are |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
232 kept in a tree like structure, for details see mc-alloc.c. |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
233 |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
234 |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
235 Internal States of the Incremental Garbage Collector |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
236 |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
237 To keep track of its current state, the collector holds it's current |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
238 phase in the global `gc_state' variable. A collector phase is one |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
239 of the following: |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
240 |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
241 NONE No incremental or full collection is currently running. |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
242 |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
243 INIT_GC The collector prepares for a new collection, e.g. sets some |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
244 global variables. |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
245 |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
246 PUSH_ROOT_SET The collector pushes the root set on the mark stack |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
247 to start the traversal of live objects. |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
248 |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
249 MARK The traversal of live objects colors the reachable objects |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
250 white, grey, or black, according to their lifeness. The mark |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
251 phase can be interrupted by the incremental collection algorithm: |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
252 Before the client (i.e. the non collector part of XEmacs) resumes, |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
253 the write barrier has to be installed so that the collector knows |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
254 what objects get modified during the collector's pause. |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
255 Installing a write barrier means protecting pages that only |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
256 contain black objects and recording write access to these objects. |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
257 Pages with white or grey objects do not need to be protected, |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
258 since these pages are due to marking anyways when the collector |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
259 resumes. Once the collector resumes, it has to re-scan all |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
260 objects that have been modified during the collector pause and |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
261 have been caught by the write barrier. The mark phase is done when |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
262 there are no more grey objects on the heap, i.e. the KKCC mark stack |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
263 is empty. |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
264 |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
265 REPUSH_ROOT_SET After the mark phase is done, the collector has to |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
266 traverse the root set pointers again, since modifications to the |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
267 objects in the root set can not all be covered by the write barrier |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
268 (e.g. root set objects that are on the call stack). Therefore, the |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
269 collector has to traverse the root set again without interruption. |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
270 |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
271 FINISH_MARK After the mark phase is finished, some objects with |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
272 special liveness semantics have to be treated separately, e.g. |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
273 ephemerons and the various flavors of weak objects. |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
274 |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
275 FINALIZE The collector registers all objects that have finalizers |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
276 for finalization. Finalizations happens asynchronously sometimes |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
277 after the collection has finished. |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
278 |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
279 SWEEP The allocator scans the entire heap and frees all white marked |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
280 objects. The freed memory is recycled and can be re-used for future |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
281 allocations. The sweep phase is carried out atomically. |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
282 |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
283 FINISH_GC The collector cleans up after the garbage collection by |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
284 resetting some global variables. |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
285 |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
286 |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
287 Lisp Interface |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
288 |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
289 The new garbage collector can be accessed directly from Emacs Lisp. |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
290 Basically, two functions invoke the garbage collector: |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
291 |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
292 (gc-full) starts a full garbage collection. If an incremental |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
293 garbage collection is already running, it is finished without |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
294 further interruption. This function guarantees that unused |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
295 objects have been freed when it returns. |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
296 |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
297 (gc-incremental) starts an incremental garbage collection. If an |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
298 incremental garbage collection is already running, the next cycle |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
299 of incremental traversal is started. The garbage collection is |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
300 finished if the traversal completes. Note that this function does |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
301 not necessarily free any memory. It only guarantees that the |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
302 traversal of the heap makes progress. |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
303 |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
304 The old garbage collector uses the function (garbage-collect) to |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
305 invoke a garbage collection. This function is still in use by some |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
306 applications that explicitly want to invoke a garbage collection. |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
307 Since these applications may expect that unused memory has really |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
308 been freed when (garbage-collect) returns, it maps to (gc-full). |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
309 |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
310 The new garbage collector is highly customizable during runtime; it |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
311 can even be switched back to the traditional mark-and-sweep garbage |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
312 collector: The variable allow-incremental-gc controls whether |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
313 garbage collections may be interrupted or if they have to be carried |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
314 out in one atomic action. Setting allow-incremental-gc to nil |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
315 prevents incremental garbage collection, and the garbage collector |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
316 then only does full collects, even if (gc-incremental) is called. |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
317 Non-nil allows incremental garbage collection. |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
318 |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
319 This way applications can freely decide what garbage collection |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
320 algorithm is best for the upcoming memory usage. How frequently a |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
321 garbage collection occurs and how much traversal work is done in one |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
322 incremental cycle can also be modified during runtime. See |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
323 |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
324 M-x customize RET alloc RET |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
325 |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
326 for an overview of all settings. |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
327 |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
328 |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
329 More Information |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
330 |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
331 More details can be found in |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
332 http://crestani.de/xemacs/pdf/thesis-newgc.pdf . |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
333 |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
334 */ |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
335 |
3092 | 336 #include <config.h> |
337 #include "lisp.h" | |
338 | |
339 #include "backtrace.h" | |
340 #include "buffer.h" | |
341 #include "bytecode.h" | |
342 #include "chartab.h" | |
343 #include "console-stream.h" | |
344 #include "device.h" | |
345 #include "elhash.h" | |
346 #include "events.h" | |
347 #include "extents-impl.h" | |
348 #include "file-coding.h" | |
349 #include "frame-impl.h" | |
350 #include "gc.h" | |
351 #include "glyphs.h" | |
352 #include "opaque.h" | |
353 #include "lrecord.h" | |
354 #include "lstream.h" | |
355 #include "process.h" | |
356 #include "profile.h" | |
357 #include "redisplay.h" | |
358 #include "specifier.h" | |
359 #include "sysfile.h" | |
360 #include "sysdep.h" | |
361 #include "window.h" | |
362 #include "vdb.h" | |
363 | |
364 | |
5238
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
365 /* Number of bytes of consing since gc before a full gc should happen. */ |
3092 | 366 #define GC_CONS_THRESHOLD 2000000 |
5238
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
367 |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
368 /* Number of bytes of consing since gc before another cycle of the gc |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
369 should happen in incremental mode. */ |
3092 | 370 #define GC_CONS_INCREMENTAL_THRESHOLD 200000 |
5238
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
371 |
2cc24c69446c
Document the new allocator and the new garbage collector in gc.c and mc-alloc.c.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5191
diff
changeset
|
372 /* Number of elements marked in one cycle of incremental GC. */ |
3092 | 373 #define GC_INCREMENTAL_TRAVERSAL_THRESHOLD 100000 |
374 | |
375 /* Number of bytes of consing done since the last GC. */ | |
376 EMACS_INT consing_since_gc; | |
377 | |
378 /* Number of bytes of consing done since startup. */ | |
379 EMACS_UINT total_consing; | |
380 | |
381 /* Number of bytes of current allocated heap objects. */ | |
382 EMACS_INT total_gc_usage; | |
383 | |
384 /* If the above is set. */ | |
385 int total_gc_usage_set; | |
386 | |
387 /* Number of bytes of consing since gc before another gc should be done. */ | |
388 EMACS_INT gc_cons_threshold; | |
389 | |
390 /* Nonzero during gc */ | |
391 int gc_in_progress; | |
392 | |
393 /* Percentage of consing of total data size before another GC. */ | |
394 EMACS_INT gc_cons_percentage; | |
395 | |
396 #ifdef NEW_GC | |
397 /* Number of bytes of consing since gc before another cycle of the gc | |
398 should be done in incremental mode. */ | |
399 EMACS_INT gc_cons_incremental_threshold; | |
400 | |
401 /* Number of elements marked in one cycle of incremental GC. */ | |
402 EMACS_INT gc_incremental_traversal_threshold; | |
403 | |
404 /* Nonzero during write barrier */ | |
405 int write_barrier_enabled; | |
406 #endif /* NEW_GC */ | |
407 | |
408 | |
409 | |
410 #ifdef NEW_GC | |
411 /************************************************************************/ | |
412 /* Incremental State and Statistics */ | |
413 /************************************************************************/ | |
414 | |
415 enum gc_phase | |
416 { | |
417 NONE, | |
418 INIT_GC, | |
419 PUSH_ROOT_SET, | |
420 MARK, | |
421 REPUSH_ROOT_SET, | |
422 FINISH_MARK, | |
423 FINALIZE, | |
424 SWEEP, | |
425 FINISH_GC | |
426 }; | |
427 | |
428 #ifndef ERROR_CHECK_GC | |
4124 | 429 typedef struct gc_state_type |
3092 | 430 { |
431 enum gc_phase phase; | |
4124 | 432 } gc_state_type; |
3092 | 433 #else /* ERROR_CHECK_GC */ |
434 enum gc_stat_id | |
435 { | |
436 GC_STAT_TOTAL, | |
437 GC_STAT_IN_LAST_GC, | |
438 GC_STAT_IN_THIS_GC, | |
439 GC_STAT_IN_LAST_CYCLE, | |
440 GC_STAT_IN_THIS_CYCLE, | |
441 GC_STAT_COUNT /* has to be last */ | |
442 }; | |
443 | |
4124 | 444 typedef struct gc_state_type |
3092 | 445 { |
446 enum gc_phase phase; | |
3313 | 447 double n_gc[GC_STAT_COUNT]; |
448 double n_cycles[GC_STAT_COUNT]; | |
449 double enqueued[GC_STAT_COUNT]; | |
450 double dequeued[GC_STAT_COUNT]; | |
451 double repushed[GC_STAT_COUNT]; | |
452 double enqueued2[GC_STAT_COUNT]; | |
453 double dequeued2[GC_STAT_COUNT]; | |
454 double finalized[GC_STAT_COUNT]; | |
455 double freed[GC_STAT_COUNT]; | |
4124 | 456 } gc_state_type; |
3092 | 457 #endif /* ERROR_CHECK_GC */ |
458 | |
4124 | 459 gc_state_type gc_state; |
460 | |
3092 | 461 #define GC_PHASE gc_state.phase |
462 #define GC_SET_PHASE(p) GC_PHASE = p | |
463 | |
464 #ifdef ERROR_CHECK_GC | |
465 # define GC_STAT_START_NEW_GC gc_stat_start_new_gc () | |
466 # define GC_STAT_RESUME_GC gc_stat_resume_gc () | |
467 | |
468 #define GC_STAT_TICK(STAT) \ | |
469 gc_state.STAT[GC_STAT_TOTAL]++; \ | |
470 gc_state.STAT[GC_STAT_IN_THIS_GC]++; \ | |
471 gc_state.STAT[GC_STAT_IN_THIS_CYCLE]++ | |
472 | |
473 # define GC_STAT_ENQUEUED \ | |
474 if (GC_PHASE == REPUSH_ROOT_SET) \ | |
475 { \ | |
476 GC_STAT_TICK (enqueued2); \ | |
477 } \ | |
478 else \ | |
479 { \ | |
480 GC_STAT_TICK (enqueued); \ | |
481 } | |
482 | |
483 # define GC_STAT_DEQUEUED \ | |
484 if (gc_state.phase == REPUSH_ROOT_SET) \ | |
485 { \ | |
486 GC_STAT_TICK (dequeued2); \ | |
487 } \ | |
488 else \ | |
489 { \ | |
490 GC_STAT_TICK (dequeued); \ | |
491 } | |
492 # define GC_STAT_REPUSHED GC_STAT_TICK (repushed) | |
493 | |
494 #define GC_STAT_RESUME(stat) \ | |
495 gc_state.stat[GC_STAT_IN_LAST_CYCLE] = \ | |
496 gc_state.stat[GC_STAT_IN_THIS_CYCLE]; \ | |
497 gc_state.stat[GC_STAT_IN_THIS_CYCLE] = 0 | |
498 | |
499 #define GC_STAT_RESTART(stat) \ | |
500 gc_state.stat[GC_STAT_IN_LAST_GC] = \ | |
501 gc_state.stat[GC_STAT_IN_THIS_GC]; \ | |
502 gc_state.stat[GC_STAT_IN_THIS_GC] = 0; \ | |
503 GC_STAT_RESUME (stat) | |
504 | |
5046 | 505 static void |
3092 | 506 gc_stat_start_new_gc (void) |
507 { | |
508 gc_state.n_gc[GC_STAT_TOTAL]++; | |
509 gc_state.n_cycles[GC_STAT_TOTAL]++; | |
510 gc_state.n_cycles[GC_STAT_IN_LAST_GC] = gc_state.n_cycles[GC_STAT_IN_THIS_GC]; | |
511 gc_state.n_cycles[GC_STAT_IN_THIS_GC] = 1; | |
512 | |
513 GC_STAT_RESTART (enqueued); | |
514 GC_STAT_RESTART (dequeued); | |
515 GC_STAT_RESTART (repushed); | |
516 GC_STAT_RESTART (finalized); | |
517 GC_STAT_RESTART (enqueued2); | |
518 GC_STAT_RESTART (dequeued2); | |
519 GC_STAT_RESTART (freed); | |
520 } | |
521 | |
5046 | 522 static void |
3092 | 523 gc_stat_resume_gc (void) |
524 { | |
525 gc_state.n_cycles[GC_STAT_TOTAL]++; | |
526 gc_state.n_cycles[GC_STAT_IN_THIS_GC]++; | |
527 GC_STAT_RESUME (enqueued); | |
528 GC_STAT_RESUME (dequeued); | |
529 GC_STAT_RESUME (repushed); | |
530 GC_STAT_RESUME (finalized); | |
531 GC_STAT_RESUME (enqueued2); | |
532 GC_STAT_RESUME (dequeued2); | |
533 GC_STAT_RESUME (freed); | |
534 } | |
535 | |
536 void | |
537 gc_stat_finalized (void) | |
538 { | |
539 GC_STAT_TICK (finalized); | |
540 } | |
541 | |
542 void | |
543 gc_stat_freed (void) | |
544 { | |
545 GC_STAT_TICK (freed); | |
546 } | |
547 | |
548 DEFUN("gc-stats", Fgc_stats, 0, 0 ,"", /* | |
549 Return statistics about garbage collection cycles in a property list. | |
550 */ | |
551 ()) | |
552 { | |
553 Lisp_Object pl = Qnil; | |
554 #define PL(name,value) \ | |
3313 | 555 pl = cons3 (intern (name), make_float (gc_state.value), pl) |
3092 | 556 |
557 PL ("freed-in-this-cycle", freed[GC_STAT_IN_THIS_CYCLE]); | |
558 PL ("freed-in-this-gc", freed[GC_STAT_IN_THIS_GC]); | |
559 PL ("freed-in-last-cycle", freed[GC_STAT_IN_LAST_CYCLE]); | |
560 PL ("freed-in-last-gc", freed[GC_STAT_IN_LAST_GC]); | |
561 PL ("freed-total", freed[GC_STAT_TOTAL]); | |
562 PL ("finalized-in-this-cycle", finalized[GC_STAT_IN_THIS_CYCLE]); | |
563 PL ("finalized-in-this-gc", finalized[GC_STAT_IN_THIS_GC]); | |
564 PL ("finalized-in-last-cycle", finalized[GC_STAT_IN_LAST_CYCLE]); | |
565 PL ("finalized-in-last-gc", finalized[GC_STAT_IN_LAST_GC]); | |
566 PL ("finalized-total", finalized[GC_STAT_TOTAL]); | |
567 PL ("repushed-in-this-cycle", repushed[GC_STAT_IN_THIS_CYCLE]); | |
568 PL ("repushed-in-this-gc", repushed[GC_STAT_IN_THIS_GC]); | |
569 PL ("repushed-in-last-cycle", repushed[GC_STAT_IN_LAST_CYCLE]); | |
570 PL ("repushed-in-last-gc", repushed[GC_STAT_IN_LAST_GC]); | |
571 PL ("repushed-total", repushed[GC_STAT_TOTAL]); | |
572 PL ("dequeued2-in-this-cycle", dequeued2[GC_STAT_IN_THIS_CYCLE]); | |
573 PL ("dequeued2-in-this-gc", dequeued2[GC_STAT_IN_THIS_GC]); | |
574 PL ("dequeued2-in-last-cycle", dequeued2[GC_STAT_IN_LAST_CYCLE]); | |
575 PL ("dequeued2-in-last-gc", dequeued2[GC_STAT_IN_LAST_GC]); | |
576 PL ("dequeued2-total", dequeued2[GC_STAT_TOTAL]); | |
577 PL ("enqueued2-in-this-cycle", enqueued2[GC_STAT_IN_THIS_CYCLE]); | |
578 PL ("enqueued2-in-this-gc", enqueued2[GC_STAT_IN_THIS_GC]); | |
579 PL ("enqueued2-in-last-cycle", enqueued2[GC_STAT_IN_LAST_CYCLE]); | |
580 PL ("enqueued2-in-last-gc", enqueued2[GC_STAT_IN_LAST_GC]); | |
581 PL ("enqueued2-total", enqueued2[GC_STAT_TOTAL]); | |
582 PL ("dequeued-in-this-cycle", dequeued[GC_STAT_IN_THIS_CYCLE]); | |
583 PL ("dequeued-in-this-gc", dequeued[GC_STAT_IN_THIS_GC]); | |
584 PL ("dequeued-in-last-cycle", dequeued[GC_STAT_IN_LAST_CYCLE]); | |
585 PL ("dequeued-in-last-gc", dequeued[GC_STAT_IN_LAST_GC]); | |
586 PL ("dequeued-total", dequeued[GC_STAT_TOTAL]); | |
587 PL ("enqueued-in-this-cycle", enqueued[GC_STAT_IN_THIS_CYCLE]); | |
588 PL ("enqueued-in-this-gc", enqueued[GC_STAT_IN_THIS_GC]); | |
589 PL ("enqueued-in-last-cycle", enqueued[GC_STAT_IN_LAST_CYCLE]); | |
590 PL ("enqueued-in-last-gc", enqueued[GC_STAT_IN_LAST_GC]); | |
591 PL ("enqueued-total", enqueued[GC_STAT_TOTAL]); | |
592 PL ("n-cycles-in-this-gc", n_cycles[GC_STAT_IN_THIS_GC]); | |
593 PL ("n-cycles-in-last-gc", n_cycles[GC_STAT_IN_LAST_GC]); | |
594 PL ("n-cycles-total", n_cycles[GC_STAT_TOTAL]); | |
595 PL ("n-gc-total", n_gc[GC_STAT_TOTAL]); | |
596 PL ("phase", phase); | |
597 return pl; | |
598 } | |
599 #else /* not ERROR_CHECK_GC */ | |
600 # define GC_STAT_START_NEW_GC | |
601 # define GC_STAT_RESUME_GC | |
602 # define GC_STAT_ENQUEUED | |
603 # define GC_STAT_DEQUEUED | |
604 # define GC_STAT_REPUSHED | |
605 # define GC_STAT_REMOVED | |
606 #endif /* not ERROR_CHECK_GC */ | |
607 #endif /* NEW_GC */ | |
608 | |
609 | |
610 /************************************************************************/ | |
611 /* Recompute need to garbage collect */ | |
612 /************************************************************************/ | |
613 | |
614 int need_to_garbage_collect; | |
615 | |
616 #ifdef ERROR_CHECK_GC | |
617 int always_gc = 0; /* Debugging hack; equivalent to | |
618 (setq gc-cons-thresold -1) */ | |
619 #else | |
620 #define always_gc 0 | |
621 #endif | |
622 | |
623 /* True if it's time to garbage collect now. */ | |
624 void | |
625 recompute_need_to_garbage_collect (void) | |
626 { | |
627 if (always_gc) | |
628 need_to_garbage_collect = 1; | |
629 else | |
630 need_to_garbage_collect = | |
631 #ifdef NEW_GC | |
632 write_barrier_enabled ? | |
633 (consing_since_gc > gc_cons_incremental_threshold) : | |
634 #endif /* NEW_GC */ | |
635 (consing_since_gc > gc_cons_threshold | |
636 && | |
637 #if 0 /* #### implement this better */ | |
4115 | 638 ((double)consing_since_gc) / total_data_usage()) >= |
639 ((double)gc_cons_percentage / 100) | |
3092 | 640 #else |
641 (!total_gc_usage_set || | |
4115 | 642 ((double)consing_since_gc / total_gc_usage) >= |
643 ((double)gc_cons_percentage / 100)) | |
3092 | 644 #endif |
645 ); | |
646 recompute_funcall_allocation_flag (); | |
647 } | |
648 | |
649 | |
650 | |
651 /************************************************************************/ | |
652 /* Mark Phase */ | |
653 /************************************************************************/ | |
654 | |
655 static const struct memory_description lisp_object_description_1[] = { | |
656 { XD_LISP_OBJECT, 0 }, | |
657 { XD_END } | |
658 }; | |
659 | |
660 const struct sized_memory_description lisp_object_description = { | |
661 sizeof (Lisp_Object), | |
662 lisp_object_description_1 | |
663 }; | |
664 | |
665 #if defined (USE_KKCC) || defined (PDUMP) | |
666 | |
667 /* This function extracts the value of a count variable described somewhere | |
668 else in the description. It is converted corresponding to the type */ | |
669 EMACS_INT | |
670 lispdesc_indirect_count_1 (EMACS_INT code, | |
671 const struct memory_description *idesc, | |
672 const void *idata) | |
673 { | |
674 EMACS_INT count; | |
675 const void *irdata; | |
676 | |
677 int line = XD_INDIRECT_VAL (code); | |
678 int delta = XD_INDIRECT_DELTA (code); | |
679 | |
680 irdata = ((char *) idata) + | |
681 lispdesc_indirect_count (idesc[line].offset, idesc, idata); | |
682 switch (idesc[line].type) | |
683 { | |
684 case XD_BYTECOUNT: | |
685 count = * (Bytecount *) irdata; | |
686 break; | |
687 case XD_ELEMCOUNT: | |
688 count = * (Elemcount *) irdata; | |
689 break; | |
690 case XD_HASHCODE: | |
691 count = * (Hashcode *) irdata; | |
692 break; | |
693 case XD_INT: | |
694 count = * (int *) irdata; | |
695 break; | |
696 case XD_LONG: | |
697 count = * (long *) irdata; | |
698 break; | |
699 default: | |
700 stderr_out ("Unsupported count type : %d (line = %d, code = %ld)\n", | |
701 idesc[line].type, line, (long) code); | |
5169
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
702 #if defined (USE_KKCC) && defined (DEBUG_XEMACS) |
3092 | 703 if (gc_in_progress) |
5169
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
704 kkcc_detailed_backtrace (); |
3092 | 705 #endif |
706 #ifdef PDUMP | |
707 if (in_pdump) | |
708 pdump_backtrace (); | |
709 #endif | |
710 count = 0; /* warning suppression */ | |
711 ABORT (); | |
712 } | |
713 count += delta; | |
714 return count; | |
715 } | |
716 | |
717 /* SDESC is a "description map" (basically, a list of offsets used for | |
718 successive indirections) and OBJ is the first object to indirect off of. | |
719 Return the description ultimately found. */ | |
720 | |
721 const struct sized_memory_description * | |
722 lispdesc_indirect_description_1 (const void *obj, | |
723 const struct sized_memory_description *sdesc) | |
724 { | |
725 int pos; | |
726 | |
727 for (pos = 0; sdesc[pos].size >= 0; pos++) | |
728 obj = * (const void **) ((const char *) obj + sdesc[pos].size); | |
729 | |
730 return (const struct sized_memory_description *) obj; | |
731 } | |
732 | |
733 /* Compute the size of the data at RDATA, described by a single entry | |
734 DESC1 in a description array. OBJ and DESC are used for | |
735 XD_INDIRECT references. */ | |
736 | |
737 static Bytecount | |
738 lispdesc_one_description_line_size (void *rdata, | |
739 const struct memory_description *desc1, | |
740 const void *obj, | |
741 const struct memory_description *desc) | |
742 { | |
743 union_switcheroo: | |
744 switch (desc1->type) | |
745 { | |
746 case XD_LISP_OBJECT_ARRAY: | |
747 { | |
748 EMACS_INT val = lispdesc_indirect_count (desc1->data1, desc, obj); | |
749 return (val * sizeof (Lisp_Object)); | |
750 } | |
751 case XD_LISP_OBJECT: | |
752 case XD_LO_LINK: | |
753 return sizeof (Lisp_Object); | |
754 case XD_OPAQUE_PTR: | |
755 return sizeof (void *); | |
756 #ifdef NEW_GC | |
5169
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
757 case XD_INLINE_LISP_OBJECT_BLOCK_PTR: |
3092 | 758 #endif /* NEW_GC */ |
759 case XD_BLOCK_PTR: | |
760 { | |
761 EMACS_INT val = lispdesc_indirect_count (desc1->data1, desc, obj); | |
762 return val * sizeof (void *); | |
763 } | |
764 case XD_BLOCK_ARRAY: | |
765 { | |
766 EMACS_INT val = lispdesc_indirect_count (desc1->data1, desc, obj); | |
767 | |
768 return (val * | |
769 lispdesc_block_size | |
770 (rdata, | |
771 lispdesc_indirect_description (obj, desc1->data2.descr))); | |
772 } | |
773 case XD_OPAQUE_DATA_PTR: | |
774 return sizeof (void *); | |
775 case XD_UNION_DYNAMIC_SIZE: | |
776 { | |
777 /* If an explicit size was given in the first-level structure | |
778 description, use it; else compute size based on current union | |
779 constant. */ | |
780 const struct sized_memory_description *sdesc = | |
781 lispdesc_indirect_description (obj, desc1->data2.descr); | |
782 if (sdesc->size) | |
783 return sdesc->size; | |
784 else | |
785 { | |
786 desc1 = lispdesc_process_xd_union (desc1, desc, obj); | |
787 if (desc1) | |
788 goto union_switcheroo; | |
789 break; | |
790 } | |
791 } | |
792 case XD_UNION: | |
793 { | |
794 /* If an explicit size was given in the first-level structure | |
795 description, use it; else compute size based on maximum of all | |
796 possible structures. */ | |
797 const struct sized_memory_description *sdesc = | |
798 lispdesc_indirect_description (obj, desc1->data2.descr); | |
799 if (sdesc->size) | |
800 return sdesc->size; | |
801 else | |
802 { | |
803 int count; | |
804 Bytecount max_size = -1, size; | |
805 | |
806 desc1 = sdesc->description; | |
807 | |
808 for (count = 0; desc1[count].type != XD_END; count++) | |
809 { | |
810 size = lispdesc_one_description_line_size (rdata, | |
811 &desc1[count], | |
812 obj, desc); | |
813 if (size > max_size) | |
814 max_size = size; | |
815 } | |
816 return max_size; | |
817 } | |
818 } | |
819 case XD_ASCII_STRING: | |
820 return sizeof (void *); | |
821 case XD_DOC_STRING: | |
822 return sizeof (void *); | |
823 case XD_INT_RESET: | |
824 return sizeof (int); | |
825 case XD_BYTECOUNT: | |
826 return sizeof (Bytecount); | |
827 case XD_ELEMCOUNT: | |
828 return sizeof (Elemcount); | |
829 case XD_HASHCODE: | |
830 return sizeof (Hashcode); | |
831 case XD_INT: | |
832 return sizeof (int); | |
833 case XD_LONG: | |
834 return sizeof (long); | |
835 default: | |
836 stderr_out ("Unsupported dump type : %d\n", desc1->type); | |
837 ABORT (); | |
838 } | |
839 | |
840 return 0; | |
841 } | |
842 | |
843 | |
844 /* Return the size of the memory block (NOT necessarily a structure!) | |
845 described by SDESC and pointed to by OBJ. If SDESC records an | |
846 explicit size (i.e. non-zero), it is simply returned; otherwise, | |
847 the size is calculated by the maximum offset and the size of the | |
848 object at that offset, rounded up to the maximum alignment. In | |
849 this case, we may need the object, for example when retrieving an | |
850 "indirect count" of an inlined array (the count is not constant, | |
851 but is specified by one of the elements of the memory block). (It | |
852 is generally not a problem if we return an overly large size -- we | |
853 will simply end up reserving more space than necessary; but if the | |
854 size is too small we could be in serious trouble, in particular | |
855 with nested inlined structures, where there may be alignment | |
856 padding in the middle of a block. #### In fact there is an (at | |
857 least theoretical) problem with an overly large size -- we may | |
858 trigger a protection fault when reading from invalid memory. We | |
859 need to handle this -- perhaps in a stupid but dependable way, | |
860 i.e. by trapping SIGSEGV and SIGBUS.) */ | |
861 | |
862 Bytecount | |
863 lispdesc_block_size_1 (const void *obj, Bytecount size, | |
864 const struct memory_description *desc) | |
865 { | |
866 EMACS_INT max_offset = -1; | |
867 int max_offset_pos = -1; | |
868 int pos; | |
869 | |
870 if (size) | |
871 return size; | |
872 | |
873 for (pos = 0; desc[pos].type != XD_END; pos++) | |
874 { | |
875 EMACS_INT offset = lispdesc_indirect_count (desc[pos].offset, desc, obj); | |
876 if (offset == max_offset) | |
877 { | |
5168
cf900a2f1fa3
extract gap array from extents.c, use in range tables
Ben Wing <ben@xemacs.org>
parents:
5158
diff
changeset
|
878 #if 0 |
cf900a2f1fa3
extract gap array from extents.c, use in range tables
Ben Wing <ben@xemacs.org>
parents:
5158
diff
changeset
|
879 /* This can legitimately happen with gap arrays -- if there are |
cf900a2f1fa3
extract gap array from extents.c, use in range tables
Ben Wing <ben@xemacs.org>
parents:
5158
diff
changeset
|
880 no elements in the array, and the gap size is 0, then both |
cf900a2f1fa3
extract gap array from extents.c, use in range tables
Ben Wing <ben@xemacs.org>
parents:
5158
diff
changeset
|
881 parts of the array will be of size 0 and in the same place. */ |
3092 | 882 stderr_out ("Two relocatable elements at same offset?\n"); |
883 ABORT (); | |
5168
cf900a2f1fa3
extract gap array from extents.c, use in range tables
Ben Wing <ben@xemacs.org>
parents:
5158
diff
changeset
|
884 #endif |
3092 | 885 } |
886 else if (offset > max_offset) | |
887 { | |
888 max_offset = offset; | |
889 max_offset_pos = pos; | |
890 } | |
891 } | |
892 | |
893 if (max_offset_pos < 0) | |
894 return 0; | |
895 | |
896 { | |
897 Bytecount size_at_max; | |
898 size_at_max = | |
899 lispdesc_one_description_line_size ((char *) obj + max_offset, | |
900 &desc[max_offset_pos], obj, desc); | |
901 | |
902 /* We have no way of knowing the required alignment for this structure, | |
903 so just make it maximally aligned. */ | |
904 return MAX_ALIGN_SIZE (max_offset + size_at_max); | |
905 } | |
906 } | |
907 #endif /* defined (USE_KKCC) || defined (PDUMP) */ | |
908 | |
3263 | 909 #ifdef NEW_GC |
3092 | 910 #define GC_CHECK_NOT_FREE(lheader) \ |
911 gc_checking_assert (! LRECORD_FREE_P (lheader)); | |
3263 | 912 #else /* not NEW_GC */ |
3092 | 913 #define GC_CHECK_NOT_FREE(lheader) \ |
914 gc_checking_assert (! LRECORD_FREE_P (lheader)); \ | |
5142
f965e31a35f0
reduce lcrecord headers to 2 words, rename printing_unreadable_object
Ben Wing <ben@xemacs.org>
parents:
5127
diff
changeset
|
915 gc_checking_assert (LHEADER_IMPLEMENTATION (lheader)->frob_block_p || \ |
f965e31a35f0
reduce lcrecord headers to 2 words, rename printing_unreadable_object
Ben Wing <ben@xemacs.org>
parents:
5127
diff
changeset
|
916 ! (lheader)->free) |
3263 | 917 #endif /* not NEW_GC */ |
3092 | 918 |
919 #ifdef USE_KKCC | |
920 /* The following functions implement the new mark algorithm. | |
921 They mark objects according to their descriptions. They | |
922 are modeled on the corresponding pdumper procedures. */ | |
923 | |
924 #if 0 | |
925 # define KKCC_STACK_AS_QUEUE 1 | |
926 #endif | |
927 | |
928 #ifdef DEBUG_XEMACS | |
929 /* The backtrace for the KKCC mark functions. */ | |
930 #define KKCC_INIT_BT_STACK_SIZE 4096 | |
931 | |
932 typedef struct | |
933 { | |
934 void *obj; | |
935 const struct memory_description *desc; | |
936 int pos; | |
5169
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
937 int is_lisp; |
3092 | 938 } kkcc_bt_stack_entry; |
939 | |
940 static kkcc_bt_stack_entry *kkcc_bt; | |
941 static int kkcc_bt_stack_size; | |
942 static int kkcc_bt_depth = 0; | |
943 | |
944 static void | |
945 kkcc_bt_init (void) | |
946 { | |
947 kkcc_bt_depth = 0; | |
948 kkcc_bt_stack_size = KKCC_INIT_BT_STACK_SIZE; | |
949 kkcc_bt = (kkcc_bt_stack_entry *) | |
950 xmalloc_and_zero (kkcc_bt_stack_size * sizeof (kkcc_bt_stack_entry)); | |
951 if (!kkcc_bt) | |
952 { | |
953 stderr_out ("KKCC backtrace stack init failed for size %d\n", | |
954 kkcc_bt_stack_size); | |
955 ABORT (); | |
956 } | |
957 } | |
958 | |
5169
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
959 /* Workhorse backtrace function. Not static because may potentially be |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
960 called from a debugger. */ |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
961 |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
962 void kkcc_backtrace_1 (int size, int detailed); |
3092 | 963 void |
5169
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
964 kkcc_backtrace_1 (int size, int detailed) |
3092 | 965 { |
966 int i; | |
967 stderr_out ("KKCC mark stack backtrace :\n"); | |
5169
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
968 for (i = kkcc_bt_depth - 1; i >= kkcc_bt_depth - size && i >= 0; i--) |
3092 | 969 { |
970 Lisp_Object obj = wrap_pointer_1 (kkcc_bt[i].obj); | |
5169
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
971 stderr_out (" [%d] ", i); |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
972 if (!kkcc_bt[i].is_lisp) |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
973 stderr_out ("non Lisp Object"); |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
974 else if (!LRECORDP (obj)) |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
975 stderr_out ("Lisp Object, non-record"); |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
976 else if (XRECORD_LHEADER (obj)->type >= lrecord_type_last_built_in_type |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
977 || (!XRECORD_LHEADER_IMPLEMENTATION (obj))) |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
978 stderr_out ("WARNING! Bad Lisp Object type %d", |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
979 XRECORD_LHEADER (obj)->type); |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
980 else |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
981 stderr_out ("%s", XRECORD_LHEADER_IMPLEMENTATION (obj)->name); |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
982 if (detailed && kkcc_bt[i].is_lisp) |
3092 | 983 { |
5169
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
984 stderr_out (" "); |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
985 debug_print (obj); |
3092 | 986 } |
3519 | 987 stderr_out (" (addr: %p, desc: %p, ", |
988 (void *) kkcc_bt[i].obj, | |
989 (void *) kkcc_bt[i].desc); | |
3092 | 990 if (kkcc_bt[i].pos >= 0) |
991 stderr_out ("pos: %d)\n", kkcc_bt[i].pos); | |
992 else | |
993 if (kkcc_bt[i].pos == -1) | |
994 stderr_out ("root set)\n"); | |
995 else if (kkcc_bt[i].pos == -2) | |
996 stderr_out ("dirty object)\n"); | |
997 } | |
998 } | |
999 | |
5169
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1000 /* Various front ends onto kkcc_backtrace_1(), meant to be called from |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1001 a debugger. |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1002 |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1003 The variants are: |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1004 |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1005 normal vs _full(): Normal displays up to the topmost 100 items on the |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1006 stack, whereas full displays all items (even if there are thousands) |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1007 |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1008 _detailed_() vs _short_(): Detailed here means print out the actual |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1009 Lisp objects on the stack using debug_print() in addition to their type, |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1010 whereas short means only show the type |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1011 */ |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1012 |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1013 void |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1014 kkcc_detailed_backtrace (void) |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1015 { |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1016 kkcc_backtrace_1 (100, 1); |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1017 } |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1018 |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1019 void kkcc_short_backtrace (void); |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1020 void |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1021 kkcc_short_backtrace (void) |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1022 { |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1023 kkcc_backtrace_1 (100, 0); |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1024 } |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1025 |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1026 void kkcc_detailed_backtrace_full (void); |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1027 void |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1028 kkcc_detailed_backtrace_full (void) |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1029 { |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1030 kkcc_backtrace_1 (kkcc_bt_depth, 1); |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1031 } |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1032 |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1033 void kkcc_short_backtrace_full (void); |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1034 void |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1035 kkcc_short_backtrace_full (void) |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1036 { |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1037 kkcc_backtrace_1 (kkcc_bt_depth, 0); |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1038 } |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1039 |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1040 /* Short versions for ease in calling from a debugger */ |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1041 |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1042 void kbt (void); |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1043 void |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1044 kbt (void) |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1045 { |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1046 kkcc_detailed_backtrace (); |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1047 } |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1048 |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1049 void kbts (void); |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1050 void |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1051 kbts (void) |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1052 { |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1053 kkcc_short_backtrace (); |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1054 } |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1055 |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1056 void kbtf (void); |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1057 void |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1058 kbtf (void) |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1059 { |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1060 kkcc_detailed_backtrace_full (); |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1061 } |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1062 |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1063 void kbtsf (void); |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1064 void |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1065 kbtsf (void) |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1066 { |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1067 kkcc_short_backtrace_full (); |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1068 } |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1069 |
3092 | 1070 static void |
1071 kkcc_bt_stack_realloc (void) | |
1072 { | |
1073 kkcc_bt_stack_size *= 2; | |
1074 kkcc_bt = (kkcc_bt_stack_entry *) | |
1075 xrealloc (kkcc_bt, kkcc_bt_stack_size * sizeof (kkcc_bt_stack_entry)); | |
1076 if (!kkcc_bt) | |
1077 { | |
1078 stderr_out ("KKCC backtrace stack realloc failed for size %d\n", | |
1079 kkcc_bt_stack_size); | |
1080 ABORT (); | |
1081 } | |
1082 } | |
1083 | |
1084 static void | |
1085 kkcc_bt_free (void) | |
1086 { | |
1087 xfree_1 (kkcc_bt); | |
1088 kkcc_bt = 0; | |
1089 kkcc_bt_stack_size = 0; | |
1090 } | |
1091 | |
1092 static void | |
5169
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1093 kkcc_bt_push (void *obj, const struct memory_description *desc, |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1094 int is_lisp DECLARE_KKCC_DEBUG_ARGS) |
3092 | 1095 { |
1096 kkcc_bt_depth = level; | |
1097 kkcc_bt[kkcc_bt_depth].obj = obj; | |
1098 kkcc_bt[kkcc_bt_depth].desc = desc; | |
1099 kkcc_bt[kkcc_bt_depth].pos = pos; | |
5169
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1100 kkcc_bt[kkcc_bt_depth].is_lisp = is_lisp; |
3092 | 1101 kkcc_bt_depth++; |
1102 if (kkcc_bt_depth >= kkcc_bt_stack_size) | |
1103 kkcc_bt_stack_realloc (); | |
1104 } | |
1105 | |
1106 #else /* not DEBUG_XEMACS */ | |
1107 #define kkcc_bt_init() | |
5169
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1108 #define kkcc_bt_push(obj, desc) |
3092 | 1109 #endif /* not DEBUG_XEMACS */ |
1110 | |
1111 /* Object memory descriptions are in the lrecord_implementation structure. | |
1112 But copying them to a parallel array is much more cache-friendly. */ | |
1113 const struct memory_description *lrecord_memory_descriptions[countof (lrecord_implementations_table)]; | |
1114 | |
1115 /* the initial stack size in kkcc_gc_stack_entries */ | |
1116 #define KKCC_INIT_GC_STACK_SIZE 16384 | |
1117 | |
1118 typedef struct | |
1119 { | |
1120 void *data; | |
1121 const struct memory_description *desc; | |
1122 #ifdef DEBUG_XEMACS | |
1123 int level; | |
1124 int pos; | |
5169
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1125 int is_lisp; |
3092 | 1126 #endif |
1127 } kkcc_gc_stack_entry; | |
1128 | |
1129 | |
1130 static kkcc_gc_stack_entry *kkcc_gc_stack_ptr; | |
1131 static int kkcc_gc_stack_front; | |
1132 static int kkcc_gc_stack_rear; | |
1133 static int kkcc_gc_stack_size; | |
1134 | |
1135 #define KKCC_INC(i) ((i + 1) % kkcc_gc_stack_size) | |
1136 #define KKCC_INC2(i) ((i + 2) % kkcc_gc_stack_size) | |
1137 | |
1138 #define KKCC_GC_STACK_FULL (KKCC_INC2 (kkcc_gc_stack_rear) == kkcc_gc_stack_front) | |
1139 #define KKCC_GC_STACK_EMPTY (KKCC_INC (kkcc_gc_stack_rear) == kkcc_gc_stack_front) | |
1140 | |
1141 static void | |
1142 kkcc_gc_stack_init (void) | |
1143 { | |
1144 kkcc_gc_stack_size = KKCC_INIT_GC_STACK_SIZE; | |
1145 kkcc_gc_stack_ptr = (kkcc_gc_stack_entry *) | |
1146 xmalloc_and_zero (kkcc_gc_stack_size * sizeof (kkcc_gc_stack_entry)); | |
1147 if (!kkcc_gc_stack_ptr) | |
1148 { | |
1149 stderr_out ("stack init failed for size %d\n", kkcc_gc_stack_size); | |
1150 ABORT (); | |
1151 } | |
1152 kkcc_gc_stack_front = 0; | |
1153 kkcc_gc_stack_rear = kkcc_gc_stack_size - 1; | |
1154 } | |
1155 | |
1156 static void | |
1157 kkcc_gc_stack_free (void) | |
1158 { | |
1159 xfree_1 (kkcc_gc_stack_ptr); | |
1160 kkcc_gc_stack_ptr = 0; | |
1161 kkcc_gc_stack_front = 0; | |
1162 kkcc_gc_stack_rear = 0; | |
1163 kkcc_gc_stack_size = 0; | |
1164 } | |
1165 | |
1166 static void | |
1167 kkcc_gc_stack_realloc (void) | |
1168 { | |
1169 kkcc_gc_stack_entry *old_ptr = kkcc_gc_stack_ptr; | |
1170 int old_size = kkcc_gc_stack_size; | |
1171 kkcc_gc_stack_size *= 2; | |
1172 kkcc_gc_stack_ptr = (kkcc_gc_stack_entry *) | |
1173 xmalloc_and_zero (kkcc_gc_stack_size * sizeof (kkcc_gc_stack_entry)); | |
1174 if (!kkcc_gc_stack_ptr) | |
1175 { | |
1176 stderr_out ("stack realloc failed for size %d\n", kkcc_gc_stack_size); | |
1177 ABORT (); | |
1178 } | |
1179 if (kkcc_gc_stack_rear >= kkcc_gc_stack_front) | |
1180 { | |
1181 int number_elements = kkcc_gc_stack_rear - kkcc_gc_stack_front + 1; | |
1182 memcpy (kkcc_gc_stack_ptr, &old_ptr[kkcc_gc_stack_front], | |
1183 number_elements * sizeof (kkcc_gc_stack_entry)); | |
1184 kkcc_gc_stack_front = 0; | |
1185 kkcc_gc_stack_rear = number_elements - 1; | |
1186 } | |
1187 else | |
1188 { | |
1189 int number_elements = old_size - kkcc_gc_stack_front; | |
1190 memcpy (kkcc_gc_stack_ptr, &old_ptr[kkcc_gc_stack_front], | |
1191 number_elements * sizeof (kkcc_gc_stack_entry)); | |
1192 memcpy (&kkcc_gc_stack_ptr[number_elements], &old_ptr[0], | |
1193 (kkcc_gc_stack_rear + 1) * sizeof (kkcc_gc_stack_entry)); | |
1194 kkcc_gc_stack_front = 0; | |
1195 kkcc_gc_stack_rear = kkcc_gc_stack_rear + number_elements; | |
1196 } | |
1197 xfree_1 (old_ptr); | |
1198 } | |
1199 | |
1200 static void | |
5169
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1201 kkcc_gc_stack_push (void *data, const struct memory_description *desc |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1202 DECLARE_KKCC_DEBUG_ARGS) |
3092 | 1203 { |
1204 #ifdef NEW_GC | |
1205 GC_STAT_ENQUEUED; | |
1206 #endif /* NEW_GC */ | |
1207 if (KKCC_GC_STACK_FULL) | |
1208 kkcc_gc_stack_realloc(); | |
1209 kkcc_gc_stack_rear = KKCC_INC (kkcc_gc_stack_rear); | |
1210 kkcc_gc_stack_ptr[kkcc_gc_stack_rear].data = data; | |
1211 kkcc_gc_stack_ptr[kkcc_gc_stack_rear].desc = desc; | |
1212 #ifdef DEBUG_XEMACS | |
1213 kkcc_gc_stack_ptr[kkcc_gc_stack_rear].level = level; | |
1214 kkcc_gc_stack_ptr[kkcc_gc_stack_rear].pos = pos; | |
1215 #endif | |
1216 } | |
1217 | |
1218 #ifdef DEBUG_XEMACS | |
5169
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1219 |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1220 static inline void |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1221 kkcc_gc_stack_push_0 (void *data, const struct memory_description *desc, |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1222 int is_lisp DECLARE_KKCC_DEBUG_ARGS) |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1223 { |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1224 kkcc_gc_stack_push (data, desc KKCC_DEBUG_ARGS); |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1225 kkcc_gc_stack_ptr[kkcc_gc_stack_rear].is_lisp = is_lisp; |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1226 } |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1227 |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1228 static inline void |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1229 kkcc_gc_stack_push_lisp (void *data, const struct memory_description *desc |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1230 DECLARE_KKCC_DEBUG_ARGS) |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1231 { |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1232 kkcc_gc_stack_push_0 (data, desc, 1 KKCC_DEBUG_ARGS); |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1233 } |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1234 |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1235 static inline void |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1236 kkcc_gc_stack_push_nonlisp (void *data, const struct memory_description *desc |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1237 DECLARE_KKCC_DEBUG_ARGS) |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1238 { |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1239 kkcc_gc_stack_push_0 (data, desc, 0 KKCC_DEBUG_ARGS); |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1240 } |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1241 |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1242 #else /* not DEBUG_XEMACS */ |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1243 |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1244 static inline void |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1245 kkcc_gc_stack_push_lisp (void *data, const struct memory_description *desc) |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1246 { |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1247 kkcc_gc_stack_push (data, desc); |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1248 } |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1249 |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1250 static inline void |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1251 kkcc_gc_stack_push_nonlisp (void *data, const struct memory_description *desc) |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1252 { |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1253 kkcc_gc_stack_push (data, desc); |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1254 } |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1255 |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1256 #endif /* (not) DEBUG_XEMACS */ |
3092 | 1257 |
1258 static kkcc_gc_stack_entry * | |
1259 kkcc_gc_stack_pop (void) | |
1260 { | |
1261 if (KKCC_GC_STACK_EMPTY) | |
1262 return 0; | |
1263 #ifdef NEW_GC | |
1264 GC_STAT_DEQUEUED; | |
1265 #endif /* NEW_GC */ | |
1266 #ifndef KKCC_STACK_AS_QUEUE | |
1267 /* stack behaviour */ | |
1268 return &kkcc_gc_stack_ptr[kkcc_gc_stack_rear--]; | |
1269 #else | |
1270 /* queue behaviour */ | |
1271 { | |
1272 int old_front = kkcc_gc_stack_front; | |
1273 kkcc_gc_stack_front = KKCC_INC (kkcc_gc_stack_front); | |
1274 return &kkcc_gc_stack_ptr[old_front]; | |
1275 } | |
1276 #endif | |
1277 } | |
1278 | |
1279 void | |
5169
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1280 kkcc_gc_stack_push_lisp_object (Lisp_Object obj DECLARE_KKCC_DEBUG_ARGS) |
3092 | 1281 { |
1282 if (XTYPE (obj) == Lisp_Type_Record) | |
1283 { | |
1284 struct lrecord_header *lheader = XRECORD_LHEADER (obj); | |
1285 const struct memory_description *desc; | |
1286 GC_CHECK_LHEADER_INVARIANTS (lheader); | |
1287 desc = RECORD_DESCRIPTION (lheader); | |
1288 if (! MARKED_RECORD_HEADER_P (lheader)) | |
1289 { | |
1290 #ifdef NEW_GC | |
1291 MARK_GREY (lheader); | |
1292 #else /* not NEW_GC */ | |
1293 MARK_RECORD_HEADER (lheader); | |
1294 #endif /* not NEW_GC */ | |
5169
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1295 kkcc_gc_stack_push_lisp ((void *) lheader, desc KKCC_DEBUG_ARGS); |
3092 | 1296 } |
1297 } | |
1298 } | |
1299 | |
1300 #ifdef NEW_GC | |
1301 | |
1302 void | |
5169
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1303 kkcc_gc_stack_repush_dirty_object (Lisp_Object obj DECLARE_KKCC_DEBUG_ARGS) |
3092 | 1304 { |
1305 if (XTYPE (obj) == Lisp_Type_Record) | |
1306 { | |
1307 struct lrecord_header *lheader = XRECORD_LHEADER (obj); | |
1308 const struct memory_description *desc; | |
1309 GC_STAT_REPUSHED; | |
1310 GC_CHECK_LHEADER_INVARIANTS (lheader); | |
1311 desc = RECORD_DESCRIPTION (lheader); | |
1312 MARK_GREY (lheader); | |
5169
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1313 kkcc_gc_stack_push_lisp ((void*) lheader, desc KKCC_DEBUG_ARGS); |
3092 | 1314 } |
1315 } | |
1316 #endif /* NEW_GC */ | |
1317 | |
1318 #ifdef ERROR_CHECK_GC | |
1319 #define KKCC_DO_CHECK_FREE(obj, allow_free) \ | |
1320 do \ | |
1321 { \ | |
1322 if (!allow_free && XTYPE (obj) == Lisp_Type_Record) \ | |
1323 { \ | |
1324 struct lrecord_header *lheader = XRECORD_LHEADER (obj); \ | |
1325 GC_CHECK_NOT_FREE (lheader); \ | |
1326 } \ | |
1327 } while (0) | |
1328 #else | |
5169
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1329 #define KKCC_DO_CHECK_FREE(obj, allow_free) DO_NOTHING |
3092 | 1330 #endif |
1331 | |
5169
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1332 static inline void |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1333 mark_object_maybe_checking_free (Lisp_Object obj, int allow_free |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1334 DECLARE_KKCC_DEBUG_ARGS) |
3092 | 1335 { |
1336 KKCC_DO_CHECK_FREE (obj, allow_free); | |
5169
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1337 kkcc_gc_stack_push_lisp_object (obj KKCC_DEBUG_ARGS); |
3092 | 1338 } |
1339 | |
1340 /* This function loops all elements of a struct pointer and calls | |
1341 mark_with_description with each element. */ | |
1342 static void | |
5169
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1343 mark_struct_contents (const void *data, |
3092 | 1344 const struct sized_memory_description *sdesc, |
5169
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1345 int count DECLARE_KKCC_DEBUG_ARGS) |
3092 | 1346 { |
1347 int i; | |
1348 Bytecount elsize; | |
1349 elsize = lispdesc_block_size (data, sdesc); | |
1350 | |
1351 for (i = 0; i < count; i++) | |
1352 { | |
5169
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1353 kkcc_gc_stack_push_nonlisp (((char *) data) + elsize * i, |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1354 sdesc->description |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1355 KKCC_DEBUG_ARGS); |
3092 | 1356 } |
1357 } | |
1358 | |
1359 #ifdef NEW_GC | |
1360 /* This function loops all elements of a struct pointer and calls | |
1361 mark_with_description with each element. */ | |
1362 static void | |
5169
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1363 mark_lisp_object_block_contents (const void *data, |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1364 const struct sized_memory_description *sdesc, |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1365 int count DECLARE_KKCC_DEBUG_ARGS) |
3092 | 1366 { |
1367 int i; | |
1368 Bytecount elsize; | |
1369 elsize = lispdesc_block_size (data, sdesc); | |
1370 | |
1371 for (i = 0; i < count; i++) | |
1372 { | |
1373 const Lisp_Object obj = wrap_pointer_1 (((char *) data) + elsize * i); | |
1374 if (XTYPE (obj) == Lisp_Type_Record) | |
1375 { | |
1376 struct lrecord_header *lheader = XRECORD_LHEADER (obj); | |
1377 const struct memory_description *desc; | |
1378 GC_CHECK_LHEADER_INVARIANTS (lheader); | |
1379 desc = sdesc->description; | |
1380 if (! MARKED_RECORD_HEADER_P (lheader)) | |
1381 { | |
1382 MARK_GREY (lheader); | |
5169
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1383 kkcc_gc_stack_push_lisp ((void *) lheader, desc KKCC_DEBUG_ARGS); |
3092 | 1384 } |
1385 } | |
1386 } | |
1387 } | |
1388 | |
1389 #endif /* not NEW_GC */ | |
1390 | |
1391 /* This function implements the KKCC mark algorithm. | |
1392 Instead of calling mark_object, all the alive Lisp_Objects are pushed | |
1393 on the kkcc_gc_stack. This function processes all elements on the stack | |
1394 according to their descriptions. */ | |
1395 static void | |
5054 | 1396 kkcc_marking (int USED_IF_NEW_GC (cnt)) |
3092 | 1397 { |
1398 kkcc_gc_stack_entry *stack_entry = 0; | |
1399 void *data = 0; | |
1400 const struct memory_description *desc = 0; | |
1401 int pos; | |
1402 #ifdef NEW_GC | |
5046 | 1403 int obj_count = cnt; |
3092 | 1404 #endif /* NEW_GC */ |
1405 #ifdef DEBUG_XEMACS | |
1406 int level = 0; | |
1407 #endif | |
1408 | |
1409 while ((stack_entry = kkcc_gc_stack_pop ()) != 0) | |
1410 { | |
1411 data = stack_entry->data; | |
1412 desc = stack_entry->desc; | |
1413 #ifdef DEBUG_XEMACS | |
1414 level = stack_entry->level + 1; | |
5169
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1415 kkcc_bt_push (data, desc, stack_entry->is_lisp, stack_entry->level, |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1416 stack_entry->pos); |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1417 #else |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1418 kkcc_bt_push (data, desc); |
3092 | 1419 #endif |
1420 | |
1421 #ifdef NEW_GC | |
1422 /* Mark black if object is currently grey. This first checks, | |
1423 if the object is really allocated on the mc-heap. If it is, | |
1424 it can be marked black; if it is not, it cannot be marked. */ | |
1425 maybe_mark_black (data); | |
1426 #endif /* NEW_GC */ | |
1427 | |
1428 if (!data) continue; | |
1429 | |
1430 gc_checking_assert (data); | |
1431 gc_checking_assert (desc); | |
1432 | |
1433 for (pos = 0; desc[pos].type != XD_END; pos++) | |
1434 { | |
1435 const struct memory_description *desc1 = &desc[pos]; | |
1436 const void *rdata = | |
1437 (const char *) data + lispdesc_indirect_count (desc1->offset, | |
1438 desc, data); | |
1439 union_switcheroo: | |
1440 | |
1441 /* If the flag says don't mark, then don't mark. */ | |
1442 if ((desc1->flags) & XD_FLAG_NO_KKCC) | |
1443 continue; | |
1444 | |
1445 switch (desc1->type) | |
1446 { | |
1447 case XD_BYTECOUNT: | |
1448 case XD_ELEMCOUNT: | |
1449 case XD_HASHCODE: | |
1450 case XD_INT: | |
1451 case XD_LONG: | |
1452 case XD_INT_RESET: | |
1453 case XD_LO_LINK: | |
1454 case XD_OPAQUE_PTR: | |
1455 case XD_OPAQUE_DATA_PTR: | |
1456 case XD_ASCII_STRING: | |
1457 case XD_DOC_STRING: | |
1458 break; | |
1459 case XD_LISP_OBJECT: | |
1460 { | |
1461 const Lisp_Object *stored_obj = (const Lisp_Object *) rdata; | |
1462 | |
1463 /* Because of the way that tagged objects work (pointers and | |
1464 Lisp_Objects have the same representation), XD_LISP_OBJECT | |
1465 can be used for untagged pointers. They might be NULL, | |
1466 though. */ | |
1467 if (EQ (*stored_obj, Qnull_pointer)) | |
1468 break; | |
3263 | 1469 #ifdef NEW_GC |
5169
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1470 mark_object_maybe_checking_free (*stored_obj, 0 |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1471 KKCC_DEBUG_ARGS); |
3263 | 1472 #else /* not NEW_GC */ |
3092 | 1473 mark_object_maybe_checking_free |
5169
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1474 (*stored_obj, (desc1->flags) & XD_FLAG_FREE_LISP_OBJECT |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1475 KKCC_DEBUG_ARGS); |
3263 | 1476 #endif /* not NEW_GC */ |
3092 | 1477 break; |
1478 } | |
1479 case XD_LISP_OBJECT_ARRAY: | |
1480 { | |
1481 int i; | |
1482 EMACS_INT count = | |
1483 lispdesc_indirect_count (desc1->data1, desc, data); | |
1484 | |
1485 for (i = 0; i < count; i++) | |
1486 { | |
1487 const Lisp_Object *stored_obj = | |
1488 (const Lisp_Object *) rdata + i; | |
1489 | |
1490 if (EQ (*stored_obj, Qnull_pointer)) | |
1491 break; | |
3263 | 1492 #ifdef NEW_GC |
3092 | 1493 mark_object_maybe_checking_free |
5169
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1494 (*stored_obj, 0 KKCC_DEBUG_ARGS); |
3263 | 1495 #else /* not NEW_GC */ |
3092 | 1496 mark_object_maybe_checking_free |
5169
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1497 (*stored_obj, (desc1->flags) & XD_FLAG_FREE_LISP_OBJECT |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1498 KKCC_DEBUG_ARGS); |
3263 | 1499 #endif /* not NEW_GC */ |
3092 | 1500 } |
1501 break; | |
1502 } | |
1503 #ifdef NEW_GC | |
5169
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1504 case XD_INLINE_LISP_OBJECT_BLOCK_PTR: |
3092 | 1505 { |
1506 EMACS_INT count = lispdesc_indirect_count (desc1->data1, desc, | |
1507 data); | |
1508 const struct sized_memory_description *sdesc = | |
1509 lispdesc_indirect_description (data, desc1->data2.descr); | |
1510 const char *dobj = * (const char **) rdata; | |
1511 if (dobj) | |
1512 mark_lisp_object_block_contents | |
5169
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1513 (dobj, sdesc, count KKCC_DEBUG_ARGS); |
3092 | 1514 break; |
1515 } | |
1516 #endif /* NEW_GC */ | |
1517 case XD_BLOCK_PTR: | |
1518 { | |
1519 EMACS_INT count = lispdesc_indirect_count (desc1->data1, desc, | |
1520 data); | |
1521 const struct sized_memory_description *sdesc = | |
1522 lispdesc_indirect_description (data, desc1->data2.descr); | |
1523 const char *dobj = * (const char **) rdata; | |
1524 if (dobj) | |
5169
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1525 mark_struct_contents (dobj, sdesc, count KKCC_DEBUG_ARGS); |
3092 | 1526 break; |
1527 } | |
1528 case XD_BLOCK_ARRAY: | |
1529 { | |
1530 EMACS_INT count = lispdesc_indirect_count (desc1->data1, desc, | |
1531 data); | |
1532 const struct sized_memory_description *sdesc = | |
1533 lispdesc_indirect_description (data, desc1->data2.descr); | |
1534 | |
5169
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1535 mark_struct_contents (rdata, sdesc, count KKCC_DEBUG_ARGS); |
3092 | 1536 break; |
1537 } | |
1538 case XD_UNION: | |
1539 case XD_UNION_DYNAMIC_SIZE: | |
1540 desc1 = lispdesc_process_xd_union (desc1, desc, data); | |
1541 if (desc1) | |
1542 goto union_switcheroo; | |
1543 break; | |
1544 | |
1545 default: | |
1546 stderr_out ("Unsupported description type : %d\n", desc1->type); | |
5169
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1547 kkcc_detailed_backtrace (); |
3092 | 1548 ABORT (); |
1549 } | |
1550 } | |
1551 | |
1552 #ifdef NEW_GC | |
1553 if (cnt) | |
5046 | 1554 if (!--obj_count) |
3092 | 1555 break; |
1556 #endif /* NEW_GC */ | |
1557 } | |
1558 } | |
1559 #endif /* USE_KKCC */ | |
1560 | |
1561 /* I hate duplicating all this crap! */ | |
1562 int | |
1563 marked_p (Lisp_Object obj) | |
1564 { | |
1565 /* Checks we used to perform. */ | |
1566 /* if (EQ (obj, Qnull_pointer)) return 1; */ | |
1567 /* if (!POINTER_TYPE_P (XGCTYPE (obj))) return 1; */ | |
1568 /* if (PURIFIED (XPNTR (obj))) return 1; */ | |
1569 | |
1570 if (XTYPE (obj) == Lisp_Type_Record) | |
1571 { | |
1572 struct lrecord_header *lheader = XRECORD_LHEADER (obj); | |
1573 | |
1574 GC_CHECK_LHEADER_INVARIANTS (lheader); | |
1575 | |
1576 return MARKED_RECORD_HEADER_P (lheader); | |
1577 } | |
1578 return 1; | |
1579 } | |
1580 | |
1581 | |
1582 /* Mark reference to a Lisp_Object. If the object referred to has not been | |
1583 seen yet, recursively mark all the references contained in it. */ | |
1584 void | |
1585 mark_object ( | |
1586 #ifdef USE_KKCC | |
1587 Lisp_Object UNUSED (obj) | |
1588 #else | |
1589 Lisp_Object obj | |
1590 #endif | |
1591 ) | |
1592 { | |
1593 #ifdef USE_KKCC | |
1594 /* this code should never be reached when configured for KKCC */ | |
1595 stderr_out ("KKCC: Invalid mark_object call.\n"); | |
1596 stderr_out ("Replace mark_object with kkcc_gc_stack_push_lisp_object.\n"); | |
1597 ABORT (); | |
1598 #else /* not USE_KKCC */ | |
1599 | |
1600 tail_recurse: | |
1601 | |
1602 /* Checks we used to perform */ | |
1603 /* if (EQ (obj, Qnull_pointer)) return; */ | |
1604 /* if (!POINTER_TYPE_P (XGCTYPE (obj))) return; */ | |
1605 /* if (PURIFIED (XPNTR (obj))) return; */ | |
1606 | |
1607 if (XTYPE (obj) == Lisp_Type_Record) | |
1608 { | |
1609 struct lrecord_header *lheader = XRECORD_LHEADER (obj); | |
1610 | |
1611 GC_CHECK_LHEADER_INVARIANTS (lheader); | |
1612 | |
1613 /* We handle this separately, above, so we can mark free objects */ | |
1614 GC_CHECK_NOT_FREE (lheader); | |
1615 | |
1616 /* All c_readonly objects have their mark bit set, | |
1617 so that we only need to check the mark bit here. */ | |
1618 if (! MARKED_RECORD_HEADER_P (lheader)) | |
1619 { | |
1620 MARK_RECORD_HEADER (lheader); | |
1621 | |
1622 if (RECORD_MARKER (lheader)) | |
1623 { | |
1624 obj = RECORD_MARKER (lheader) (obj); | |
1625 if (!NILP (obj)) goto tail_recurse; | |
1626 } | |
1627 } | |
1628 } | |
1629 #endif /* not KKCC */ | |
1630 } | |
1631 | |
1632 | |
1633 /************************************************************************/ | |
1634 /* Hooks */ | |
1635 /************************************************************************/ | |
1636 | |
1637 /* Nonzero when calling certain hooks or doing other things where a GC | |
1638 would be bad. It prevents infinite recursive calls to gc. */ | |
1639 int gc_currently_forbidden; | |
1640 | |
1641 int | |
1642 begin_gc_forbidden (void) | |
1643 { | |
1644 return internal_bind_int (&gc_currently_forbidden, 1); | |
1645 } | |
1646 | |
1647 void | |
1648 end_gc_forbidden (int count) | |
1649 { | |
1650 unbind_to (count); | |
1651 } | |
1652 | |
1653 /* Hooks. */ | |
1654 Lisp_Object Vpre_gc_hook, Qpre_gc_hook; | |
1655 Lisp_Object Vpost_gc_hook, Qpost_gc_hook; | |
1656 | |
1657 /* Maybe we want to use this when doing a "panic" gc after memory_full()? */ | |
1658 static int gc_hooks_inhibited; | |
1659 | |
1660 struct post_gc_action | |
1661 { | |
1662 void (*fun) (void *); | |
1663 void *arg; | |
1664 }; | |
1665 | |
1666 typedef struct post_gc_action post_gc_action; | |
1667 | |
1668 typedef struct | |
1669 { | |
1670 Dynarr_declare (post_gc_action); | |
1671 } post_gc_action_dynarr; | |
1672 | |
1673 static post_gc_action_dynarr *post_gc_actions; | |
1674 | |
1675 /* Register an action to be called at the end of GC. | |
1676 gc_in_progress is 0 when this is called. | |
1677 This is used when it is discovered that an action needs to be taken, | |
1678 but it's during GC, so it's not safe. (e.g. in a finalize method.) | |
1679 | |
1680 As a general rule, do not use Lisp objects here. | |
1681 And NEVER signal an error. | |
1682 */ | |
1683 | |
1684 void | |
1685 register_post_gc_action (void (*fun) (void *), void *arg) | |
1686 { | |
1687 post_gc_action action; | |
1688 | |
1689 if (!post_gc_actions) | |
1690 post_gc_actions = Dynarr_new (post_gc_action); | |
1691 | |
1692 action.fun = fun; | |
1693 action.arg = arg; | |
1694 | |
1695 Dynarr_add (post_gc_actions, action); | |
1696 } | |
1697 | |
1698 static void | |
1699 run_post_gc_actions (void) | |
1700 { | |
1701 int i; | |
1702 | |
1703 if (post_gc_actions) | |
1704 { | |
1705 for (i = 0; i < Dynarr_length (post_gc_actions); i++) | |
1706 { | |
1707 post_gc_action action = Dynarr_at (post_gc_actions, i); | |
1708 (action.fun) (action.arg); | |
1709 } | |
1710 | |
1711 Dynarr_reset (post_gc_actions); | |
1712 } | |
1713 } | |
1714 | |
3263 | 1715 #ifdef NEW_GC |
1716 /* Asynchronous finalization. */ | |
1717 typedef struct finalize_elem | |
1718 { | |
1719 Lisp_Object obj; | |
1720 struct finalize_elem *next; | |
1721 } finalize_elem; | |
1722 | |
1723 finalize_elem *Vall_finalizable_objs; | |
1724 Lisp_Object Vfinalizers_to_run; | |
1725 | |
1726 void | |
1727 add_finalizable_obj (Lisp_Object obj) | |
1728 { | |
1729 finalize_elem *next = Vall_finalizable_objs; | |
1730 Vall_finalizable_objs = | |
1731 (finalize_elem *) xmalloc_and_zero (sizeof (finalize_elem)); | |
1732 Vall_finalizable_objs->obj = obj; | |
1733 Vall_finalizable_objs->next = next; | |
1734 } | |
1735 | |
1736 void | |
1737 register_for_finalization (void) | |
1738 { | |
1739 finalize_elem *rest = Vall_finalizable_objs; | |
1740 | |
1741 if (!rest) | |
1742 return; | |
1743 | |
1744 while (!marked_p (rest->obj)) | |
1745 { | |
1746 finalize_elem *temp = rest; | |
1747 Vfinalizers_to_run = Fcons (rest->obj, Vfinalizers_to_run); | |
1748 Vall_finalizable_objs = rest->next; | |
4976
16112448d484
Rename xfree(FOO, TYPE) -> xfree(FOO)
Ben Wing <ben@xemacs.org>
parents:
4969
diff
changeset
|
1749 xfree (temp); |
3263 | 1750 rest = Vall_finalizable_objs; |
1751 } | |
1752 | |
1753 while (rest->next) | |
1754 { | |
1755 if (LRECORDP (rest->next->obj) | |
1756 && !marked_p (rest->next->obj)) | |
1757 { | |
1758 finalize_elem *temp = rest->next; | |
1759 Vfinalizers_to_run = Fcons (rest->next->obj, Vfinalizers_to_run); | |
1760 rest->next = rest->next->next; | |
4976
16112448d484
Rename xfree(FOO, TYPE) -> xfree(FOO)
Ben Wing <ben@xemacs.org>
parents:
4969
diff
changeset
|
1761 xfree (temp); |
3263 | 1762 } |
1763 else | |
1764 { | |
1765 rest = rest->next; | |
1766 } | |
1767 } | |
1768 /* Keep objects alive that need to be finalized by marking | |
1769 Vfinalizers_to_run transitively. */ | |
5169
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1770 kkcc_gc_stack_push_lisp_object_0 (Vfinalizers_to_run); |
3263 | 1771 kkcc_marking (0); |
1772 } | |
1773 | |
1774 void | |
1775 run_finalizers (void) | |
1776 { | |
1777 Lisp_Object rest; | |
1778 for (rest = Vfinalizers_to_run; !NILP (rest); rest = XCDR (rest)) | |
1779 { | |
1780 MC_ALLOC_CALL_FINALIZER (XPNTR (XCAR (rest))); | |
1781 } | |
1782 Vfinalizers_to_run = Qnil; | |
1783 } | |
1784 #endif /* not NEW_GC */ | |
3092 | 1785 |
1786 | |
1787 /************************************************************************/ | |
1788 /* Garbage Collection */ | |
1789 /************************************************************************/ | |
1790 | |
1791 /* Enable/disable incremental garbage collection during runtime. */ | |
1792 int allow_incremental_gc; | |
1793 | |
1794 /* For profiling. */ | |
1795 static Lisp_Object QSin_garbage_collection; | |
1796 | |
1797 /* Nonzero means display messages at beginning and end of GC. */ | |
1798 int garbage_collection_messages; | |
1799 | |
1800 /* "Garbage collecting" */ | |
1801 Lisp_Object Vgc_message; | |
1802 Lisp_Object Vgc_pointer_glyph; | |
1803 static const Ascbyte gc_default_message[] = "Garbage collecting"; | |
1804 Lisp_Object Qgarbage_collecting; | |
1805 | |
1806 /* "Locals" during GC. */ | |
1807 struct frame *f; | |
1808 int speccount; | |
1809 int cursor_changed; | |
1810 Lisp_Object pre_gc_cursor; | |
1811 | |
1812 /* PROFILE_DECLARE */ | |
1813 int do_backtrace; | |
1814 struct backtrace backtrace; | |
1815 | |
1816 /* Maximum amount of C stack to save when a GC happens. */ | |
1817 #ifndef MAX_SAVE_STACK | |
1818 #define MAX_SAVE_STACK 0 /* 16000 */ | |
1819 #endif | |
1820 | |
5016
2ade80e8c640
enable more warnings and fix them
Ben Wing <ben@xemacs.org>
parents:
5014
diff
changeset
|
1821 static void |
3267 | 1822 show_gc_cursor_and_message (void) |
3092 | 1823 { |
3267 | 1824 /* Now show the GC cursor/message. */ |
1825 pre_gc_cursor = Qnil; | |
1826 cursor_changed = 0; | |
3092 | 1827 |
1828 /* We used to call selected_frame() here. | |
1829 | |
1830 The following functions cannot be called inside GC | |
1831 so we move to after the above tests. */ | |
1832 { | |
1833 Lisp_Object frame; | |
1834 Lisp_Object device = Fselected_device (Qnil); | |
1835 if (NILP (device)) /* Could happen during startup, eg. if always_gc */ | |
1836 return; | |
1837 frame = Fselected_frame (device); | |
1838 if (NILP (frame)) | |
1839 invalid_state ("No frames exist on device", device); | |
1840 f = XFRAME (frame); | |
1841 } | |
1842 | |
1843 if (!noninteractive) | |
1844 { | |
1845 if (FRAME_WIN_P (f)) | |
1846 { | |
1847 Lisp_Object frame = wrap_frame (f); | |
1848 Lisp_Object cursor = glyph_image_instance (Vgc_pointer_glyph, | |
1849 FRAME_SELECTED_WINDOW (f), | |
1850 ERROR_ME_NOT, 1); | |
1851 pre_gc_cursor = f->pointer; | |
1852 if (POINTER_IMAGE_INSTANCEP (cursor) | |
1853 /* don't change if we don't know how to change back. */ | |
1854 && POINTER_IMAGE_INSTANCEP (pre_gc_cursor)) | |
1855 { | |
1856 cursor_changed = 1; | |
1857 Fset_frame_pointer (frame, cursor); | |
1858 } | |
1859 } | |
1860 | |
1861 /* Don't print messages to the stream device. */ | |
1862 if (!cursor_changed && !FRAME_STREAM_P (f)) | |
1863 { | |
1864 if (garbage_collection_messages) | |
1865 { | |
1866 Lisp_Object args[2], whole_msg; | |
1867 args[0] = (STRINGP (Vgc_message) ? Vgc_message : | |
1868 build_msg_string (gc_default_message)); | |
4952
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4934
diff
changeset
|
1869 args[1] = build_ascstring ("..."); |
3092 | 1870 whole_msg = Fconcat (2, args); |
1871 echo_area_message (f, (Ibyte *) 0, whole_msg, 0, -1, | |
1872 Qgarbage_collecting); | |
1873 } | |
1874 } | |
1875 } | |
3267 | 1876 } |
1877 | |
5016
2ade80e8c640
enable more warnings and fix them
Ben Wing <ben@xemacs.org>
parents:
5014
diff
changeset
|
1878 static void |
3267 | 1879 remove_gc_cursor_and_message (void) |
1880 { | |
1881 /* Now remove the GC cursor/message */ | |
1882 if (!noninteractive) | |
1883 { | |
1884 if (cursor_changed) | |
1885 Fset_frame_pointer (wrap_frame (f), pre_gc_cursor); | |
1886 else if (!FRAME_STREAM_P (f)) | |
1887 { | |
1888 /* Show "...done" only if the echo area would otherwise be empty. */ | |
1889 if (NILP (clear_echo_area (selected_frame (), | |
1890 Qgarbage_collecting, 0))) | |
1891 { | |
1892 if (garbage_collection_messages) | |
1893 { | |
1894 Lisp_Object args[2], whole_msg; | |
1895 args[0] = (STRINGP (Vgc_message) ? Vgc_message : | |
1896 build_msg_string (gc_default_message)); | |
1897 args[1] = build_msg_string ("... done"); | |
1898 whole_msg = Fconcat (2, args); | |
1899 echo_area_message (selected_frame (), (Ibyte *) 0, | |
1900 whole_msg, 0, -1, | |
1901 Qgarbage_collecting); | |
1902 } | |
1903 } | |
1904 } | |
1905 } | |
1906 } | |
1907 | |
5016
2ade80e8c640
enable more warnings and fix them
Ben Wing <ben@xemacs.org>
parents:
5014
diff
changeset
|
1908 static void |
3267 | 1909 gc_prepare (void) |
1910 { | |
1911 #if MAX_SAVE_STACK > 0 | |
1912 char stack_top_variable; | |
1913 extern char *stack_bottom; | |
1914 #endif | |
1915 | |
1916 #ifdef NEW_GC | |
1917 GC_STAT_START_NEW_GC; | |
1918 GC_SET_PHASE (INIT_GC); | |
1919 #endif /* NEW_GC */ | |
1920 | |
1921 do_backtrace = profiling_active || backtrace_with_internal_sections; | |
1922 | |
1923 assert (!gc_in_progress); | |
1924 assert (!in_display || gc_currently_forbidden); | |
1925 | |
1926 PROFILE_RECORD_ENTERING_SECTION (QSin_garbage_collection); | |
1927 | |
1928 need_to_signal_post_gc = 0; | |
1929 recompute_funcall_allocation_flag (); | |
1930 | |
1931 if (!gc_hooks_inhibited) | |
1932 run_hook_trapping_problems | |
1933 (Qgarbage_collecting, Qpre_gc_hook, | |
1934 INHIBIT_EXISTING_PERMANENT_DISPLAY_OBJECT_DELETION); | |
3092 | 1935 |
1936 /***** Now we actually start the garbage collection. */ | |
1937 | |
1938 gc_in_progress = 1; | |
1939 #ifndef NEW_GC | |
5014
c2e0c3af5fe3
cleanups to debug-print, try harder to make it work during GC
Ben Wing <ben@xemacs.org>
parents:
4976
diff
changeset
|
1940 inhibit_non_essential_conversion_operations++; |
3263 | 1941 #endif /* not NEW_GC */ |
3092 | 1942 |
1943 #if MAX_SAVE_STACK > 0 | |
1944 | |
1945 /* Save a copy of the contents of the stack, for debugging. */ | |
1946 if (!purify_flag) | |
1947 { | |
1948 /* Static buffer in which we save a copy of the C stack at each GC. */ | |
1949 static char *stack_copy; | |
1950 static Bytecount stack_copy_size; | |
1951 | |
1952 ptrdiff_t stack_diff = &stack_top_variable - stack_bottom; | |
1953 Bytecount stack_size = (stack_diff > 0 ? stack_diff : -stack_diff); | |
1954 if (stack_size < MAX_SAVE_STACK) | |
1955 { | |
1956 if (stack_copy_size < stack_size) | |
1957 { | |
1958 stack_copy = (char *) xrealloc (stack_copy, stack_size); | |
1959 stack_copy_size = stack_size; | |
1960 } | |
1961 | |
1962 memcpy (stack_copy, | |
1963 stack_diff > 0 ? stack_bottom : &stack_top_variable, | |
1964 stack_size); | |
1965 } | |
1966 } | |
1967 #endif /* MAX_SAVE_STACK > 0 */ | |
1968 | |
1969 /* Do some totally ad-hoc resource clearing. */ | |
1970 /* #### generalize this? */ | |
1971 clear_event_resource (); | |
1972 cleanup_specifiers (); | |
1973 cleanup_buffer_undo_lists (); | |
1974 } | |
1975 | |
5016
2ade80e8c640
enable more warnings and fix them
Ben Wing <ben@xemacs.org>
parents:
5014
diff
changeset
|
1976 static void |
3092 | 1977 gc_mark_root_set ( |
1978 #ifdef NEW_GC | |
1979 enum gc_phase phase | |
1980 #else /* not NEW_GC */ | |
1981 void | |
1982 #endif /* not NEW_GC */ | |
1983 ) | |
1984 { | |
1985 #ifdef NEW_GC | |
1986 GC_SET_PHASE (phase); | |
1987 #endif /* NEW_GC */ | |
1988 | |
1989 /* Mark all the special slots that serve as the roots of accessibility. */ | |
1990 | |
1991 #ifdef USE_KKCC | |
5169
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5168
diff
changeset
|
1992 # define mark_object(obj) kkcc_gc_stack_push_lisp_object_0 (obj) |
3092 | 1993 #endif /* USE_KKCC */ |
1994 | |
1995 { /* staticpro() */ | |
1996 Lisp_Object **p = Dynarr_begin (staticpros); | |
4921
17362f371cc2
add more byte-code assertions and better failure output
Ben Wing <ben@xemacs.org>
parents:
4502
diff
changeset
|
1997 Elemcount len = Dynarr_length (staticpros); |
3092 | 1998 Elemcount count; |
4921
17362f371cc2
add more byte-code assertions and better failure output
Ben Wing <ben@xemacs.org>
parents:
4502
diff
changeset
|
1999 for (count = 0; count < len; count++, p++) |
3092 | 2000 /* Need to check if the pointer in the staticpro array is not |
2001 NULL. A gc can occur after variable is added to the staticpro | |
2002 array and _before_ it is correctly initialized. In this case | |
2003 its value is NULL, which we have to catch here. */ | |
2004 if (*p) | |
3486 | 2005 mark_object (**p); |
3092 | 2006 } |
2007 | |
2008 { /* staticpro_nodump() */ | |
2009 Lisp_Object **p = Dynarr_begin (staticpros_nodump); | |
4921
17362f371cc2
add more byte-code assertions and better failure output
Ben Wing <ben@xemacs.org>
parents:
4502
diff
changeset
|
2010 Elemcount len = Dynarr_length (staticpros_nodump); |
3092 | 2011 Elemcount count; |
4921
17362f371cc2
add more byte-code assertions and better failure output
Ben Wing <ben@xemacs.org>
parents:
4502
diff
changeset
|
2012 for (count = 0; count < len; count++, p++) |
3092 | 2013 /* Need to check if the pointer in the staticpro array is not |
2014 NULL. A gc can occur after variable is added to the staticpro | |
2015 array and _before_ it is correctly initialized. In this case | |
2016 its value is NULL, which we have to catch here. */ | |
2017 if (*p) | |
3486 | 2018 mark_object (**p); |
3092 | 2019 } |
2020 | |
3263 | 2021 #ifdef NEW_GC |
3092 | 2022 { /* mcpro () */ |
2023 Lisp_Object *p = Dynarr_begin (mcpros); | |
4921
17362f371cc2
add more byte-code assertions and better failure output
Ben Wing <ben@xemacs.org>
parents:
4502
diff
changeset
|
2024 Elemcount len = Dynarr_length (mcpros); |
3092 | 2025 Elemcount count; |
4921
17362f371cc2
add more byte-code assertions and better failure output
Ben Wing <ben@xemacs.org>
parents:
4502
diff
changeset
|
2026 for (count = 0; count < len; count++, p++) |
17362f371cc2
add more byte-code assertions and better failure output
Ben Wing <ben@xemacs.org>
parents:
4502
diff
changeset
|
2027 mark_object (*p); |
3092 | 2028 } |
3263 | 2029 #endif /* NEW_GC */ |
3092 | 2030 |
2031 { /* GCPRO() */ | |
2032 struct gcpro *tail; | |
2033 int i; | |
2034 for (tail = gcprolist; tail; tail = tail->next) | |
2035 for (i = 0; i < tail->nvars; i++) | |
2036 mark_object (tail->var[i]); | |
2037 } | |
2038 | |
2039 { /* specbind() */ | |
2040 struct specbinding *bind; | |
2041 for (bind = specpdl; bind != specpdl_ptr; bind++) | |
2042 { | |
2043 mark_object (bind->symbol); | |
2044 mark_object (bind->old_value); | |
2045 } | |
2046 } | |
2047 | |
2048 { | |
2049 struct catchtag *c; | |
2050 for (c = catchlist; c; c = c->next) | |
2051 { | |
2052 mark_object (c->tag); | |
2053 mark_object (c->val); | |
2054 mark_object (c->actual_tag); | |
2055 mark_object (c->backtrace); | |
2056 } | |
2057 } | |
2058 | |
2059 { | |
2060 struct backtrace *backlist; | |
2061 for (backlist = backtrace_list; backlist; backlist = backlist->next) | |
2062 { | |
2063 int nargs = backlist->nargs; | |
2064 int i; | |
2065 | |
2066 mark_object (*backlist->function); | |
2067 if (nargs < 0 /* nargs == UNEVALLED || nargs == MANY */ | |
2068 /* might be fake (internal profiling entry) */ | |
2069 && backlist->args) | |
2070 mark_object (backlist->args[0]); | |
2071 else | |
2072 for (i = 0; i < nargs; i++) | |
2073 mark_object (backlist->args[i]); | |
2074 } | |
2075 } | |
2076 | |
2077 mark_profiling_info (); | |
5191
71ee43b8a74d
Add #'equalp as a hash test by default; add #'define-hash-table-test, GNU API
Aidan Kehoe <kehoea@parhasard.net>
parents:
5169
diff
changeset
|
2078 |
3092 | 2079 #ifdef USE_KKCC |
2080 # undef mark_object | |
2081 #endif | |
2082 } | |
2083 | |
5016
2ade80e8c640
enable more warnings and fix them
Ben Wing <ben@xemacs.org>
parents:
5014
diff
changeset
|
2084 static void |
3092 | 2085 gc_finish_mark (void) |
2086 { | |
2087 #ifdef NEW_GC | |
2088 GC_SET_PHASE (FINISH_MARK); | |
2089 #endif /* NEW_GC */ | |
2090 init_marking_ephemerons (); | |
2091 | |
2092 while (finish_marking_weak_hash_tables () > 0 || | |
2093 finish_marking_weak_lists () > 0 || | |
2094 continue_marking_ephemerons () > 0) | |
2095 #ifdef USE_KKCC | |
2096 { | |
2097 kkcc_marking (0); | |
2098 } | |
2099 #else /* not USE_KKCC */ | |
2100 ; | |
2101 #endif /* not USE_KKCC */ | |
2102 | |
2103 /* At this point, we know which objects need to be finalized: we | |
2104 still need to resurrect them */ | |
2105 | |
2106 while (finish_marking_ephemerons () > 0 || | |
2107 finish_marking_weak_lists () > 0 || | |
2108 finish_marking_weak_hash_tables () > 0) | |
2109 #ifdef USE_KKCC | |
2110 { | |
2111 kkcc_marking (0); | |
2112 } | |
2113 #else /* not USE_KKCC */ | |
2114 ; | |
2115 #endif /* not USE_KKCC */ | |
2116 | |
2117 /* And prune (this needs to be called after everything else has been | |
2118 marked and before we do any sweeping). */ | |
2119 /* #### this is somewhat ad-hoc and should probably be an object | |
2120 method */ | |
2121 prune_weak_hash_tables (); | |
2122 prune_weak_lists (); | |
2123 prune_specifiers (); | |
2124 prune_syntax_tables (); | |
2125 | |
2126 prune_ephemerons (); | |
2127 prune_weak_boxes (); | |
2128 } | |
2129 | |
2130 #ifdef NEW_GC | |
5016
2ade80e8c640
enable more warnings and fix them
Ben Wing <ben@xemacs.org>
parents:
5014
diff
changeset
|
2131 static void |
3092 | 2132 gc_finalize (void) |
2133 { | |
2134 GC_SET_PHASE (FINALIZE); | |
3263 | 2135 register_for_finalization (); |
3092 | 2136 } |
2137 | |
5016
2ade80e8c640
enable more warnings and fix them
Ben Wing <ben@xemacs.org>
parents:
5014
diff
changeset
|
2138 static void |
3092 | 2139 gc_sweep (void) |
2140 { | |
2141 GC_SET_PHASE (SWEEP); | |
2142 mc_sweep (); | |
2143 } | |
2144 #endif /* NEW_GC */ | |
2145 | |
2146 | |
5016
2ade80e8c640
enable more warnings and fix them
Ben Wing <ben@xemacs.org>
parents:
5014
diff
changeset
|
2147 static void |
3092 | 2148 gc_finish (void) |
2149 { | |
2150 #ifdef NEW_GC | |
2151 GC_SET_PHASE (FINISH_GC); | |
2152 #endif /* NEW_GC */ | |
5158
9e0b43d3095c
more cleanups to object-memory-usage stuff
Ben Wing <ben@xemacs.org>
parents:
5142
diff
changeset
|
2153 finish_object_memory_usage_stats (); |
3092 | 2154 consing_since_gc = 0; |
2155 #ifndef DEBUG_XEMACS | |
2156 /* Allow you to set it really fucking low if you really want ... */ | |
2157 if (gc_cons_threshold < 10000) | |
2158 gc_cons_threshold = 10000; | |
2159 #endif | |
2160 recompute_need_to_garbage_collect (); | |
2161 | |
2162 #ifndef NEW_GC | |
5014
c2e0c3af5fe3
cleanups to debug-print, try harder to make it work during GC
Ben Wing <ben@xemacs.org>
parents:
4976
diff
changeset
|
2163 inhibit_non_essential_conversion_operations--; |
3092 | 2164 #endif /* not NEW_GC */ |
2165 gc_in_progress = 0; | |
2166 | |
2167 run_post_gc_actions (); | |
2168 | |
2169 /******* End of garbage collection ********/ | |
2170 | |
3263 | 2171 #ifndef NEW_GC |
3092 | 2172 if (!breathing_space) |
2173 { | |
2174 breathing_space = malloc (4096 - MALLOC_OVERHEAD); | |
2175 } | |
3263 | 2176 #endif /* not NEW_GC */ |
3092 | 2177 |
2178 need_to_signal_post_gc = 1; | |
2179 funcall_allocation_flag = 1; | |
2180 | |
2181 PROFILE_RECORD_EXITING_SECTION (QSin_garbage_collection); | |
2182 | |
2183 #ifdef NEW_GC | |
2184 GC_SET_PHASE (NONE); | |
2185 #endif /* NEW_GC */ | |
2186 } | |
2187 | |
2188 #ifdef NEW_GC | |
5016
2ade80e8c640
enable more warnings and fix them
Ben Wing <ben@xemacs.org>
parents:
5014
diff
changeset
|
2189 static void |
3092 | 2190 gc_suspend_mark_phase (void) |
2191 { | |
2192 PROFILE_RECORD_EXITING_SECTION (QSin_garbage_collection); | |
2193 write_barrier_enabled = 1; | |
2194 consing_since_gc = 0; | |
2195 vdb_start_dirty_bits_recording (); | |
2196 } | |
2197 | |
5016
2ade80e8c640
enable more warnings and fix them
Ben Wing <ben@xemacs.org>
parents:
5014
diff
changeset
|
2198 static int |
3092 | 2199 gc_resume_mark_phase (void) |
2200 { | |
2201 PROFILE_RECORD_ENTERING_SECTION (QSin_garbage_collection); | |
2202 assert (write_barrier_enabled); | |
2203 vdb_stop_dirty_bits_recording (); | |
2204 write_barrier_enabled = 0; | |
2205 return vdb_read_dirty_bits (); | |
2206 } | |
2207 | |
5016
2ade80e8c640
enable more warnings and fix them
Ben Wing <ben@xemacs.org>
parents:
5014
diff
changeset
|
2208 static int |
3092 | 2209 gc_mark (int incremental) |
2210 { | |
2211 GC_SET_PHASE (MARK); | |
2212 if (!incremental) | |
2213 { | |
2214 kkcc_marking (0); | |
2215 } | |
2216 else | |
2217 { | |
2218 kkcc_marking (gc_incremental_traversal_threshold); | |
2219 if (!KKCC_GC_STACK_EMPTY) | |
2220 { | |
2221 gc_suspend_mark_phase (); | |
2222 return 0; | |
2223 } | |
2224 } | |
2225 return 1; | |
2226 } | |
2227 | |
5016
2ade80e8c640
enable more warnings and fix them
Ben Wing <ben@xemacs.org>
parents:
5014
diff
changeset
|
2228 static int |
3092 | 2229 gc_resume_mark (int incremental) |
2230 { | |
2231 if (!incremental) | |
2232 { | |
2233 if (!KKCC_GC_STACK_EMPTY) | |
2234 { | |
2235 GC_STAT_RESUME_GC; | |
2236 /* An incremental garbage collection is already running --- | |
2237 now wrap it up and resume it atomically. */ | |
2238 gc_resume_mark_phase (); | |
2239 gc_mark_root_set (REPUSH_ROOT_SET); | |
2240 kkcc_marking (0); | |
2241 } | |
2242 } | |
2243 else | |
2244 { | |
2245 int repushed_objects; | |
2246 int mark_work; | |
2247 GC_STAT_RESUME_GC; | |
2248 repushed_objects = gc_resume_mark_phase (); | |
2249 mark_work = (gc_incremental_traversal_threshold > repushed_objects) ? | |
2250 gc_incremental_traversal_threshold : repushed_objects; | |
2251 kkcc_marking (mark_work); | |
2252 if (KKCC_GC_STACK_EMPTY) | |
2253 { | |
2254 /* Mark root set again and finish up marking. */ | |
2255 gc_mark_root_set (REPUSH_ROOT_SET); | |
2256 kkcc_marking (0); | |
2257 } | |
2258 else | |
2259 { | |
2260 gc_suspend_mark_phase (); | |
2261 return 0; | |
2262 } | |
2263 } | |
2264 return 1; | |
2265 } | |
2266 | |
2267 | |
5046 | 2268 static void |
3092 | 2269 gc_1 (int incremental) |
2270 { | |
2271 switch (GC_PHASE) | |
2272 { | |
2273 case NONE: | |
2274 gc_prepare (); | |
2275 kkcc_gc_stack_init(); | |
2276 #ifdef DEBUG_XEMACS | |
2277 kkcc_bt_init (); | |
2278 #endif | |
2279 case INIT_GC: | |
2280 gc_mark_root_set (PUSH_ROOT_SET); | |
2281 case PUSH_ROOT_SET: | |
2282 if (!gc_mark (incremental)) | |
2283 return; /* suspend gc */ | |
2284 case MARK: | |
2285 if (!KKCC_GC_STACK_EMPTY) | |
2286 if (!gc_resume_mark (incremental)) | |
2287 return; /* suspend gc */ | |
2288 gc_finish_mark (); | |
3263 | 2289 case FINISH_MARK: |
2290 gc_finalize (); | |
3092 | 2291 kkcc_gc_stack_free (); |
2292 #ifdef DEBUG_XEMACS | |
2293 kkcc_bt_free (); | |
2294 #endif | |
2295 case FINALIZE: | |
2296 gc_sweep (); | |
2297 case SWEEP: | |
2298 gc_finish (); | |
2299 case FINISH_GC: | |
2300 break; | |
2301 } | |
2302 } | |
2303 | |
5046 | 2304 static void |
2305 gc (int incremental) | |
3092 | 2306 { |
2307 if (gc_currently_forbidden | |
2308 || in_display | |
2309 || preparing_for_armageddon) | |
2310 return; | |
2311 | |
2312 /* Very important to prevent GC during any of the following | |
2313 stuff that might run Lisp code; otherwise, we'll likely | |
2314 have infinite GC recursion. */ | |
2315 speccount = begin_gc_forbidden (); | |
2316 | |
3267 | 2317 show_gc_cursor_and_message (); |
2318 | |
3092 | 2319 gc_1 (incremental); |
2320 | |
3267 | 2321 remove_gc_cursor_and_message (); |
2322 | |
3092 | 2323 /* now stop inhibiting GC */ |
2324 unbind_to (speccount); | |
2325 } | |
2326 | |
2327 void | |
2328 gc_full (void) | |
2329 { | |
2330 gc (0); | |
2331 } | |
2332 | |
2333 DEFUN ("gc-full", Fgc_full, 0, 0, "", /* | |
2334 This function performs a full garbage collection. If an incremental | |
2335 garbage collection is already running, it completes without any | |
2336 further interruption. This function guarantees that unused objects | |
2337 are freed when it returns. Garbage collection happens automatically if | |
2338 the client allocates more than `gc-cons-threshold' bytes of Lisp data | |
2339 since the previous garbage collection. | |
2340 */ | |
2341 ()) | |
2342 { | |
2343 gc_full (); | |
2344 return Qt; | |
2345 } | |
2346 | |
2347 void | |
2348 gc_incremental (void) | |
2349 { | |
2350 gc (allow_incremental_gc); | |
2351 } | |
2352 | |
2353 DEFUN ("gc-incremental", Fgc_incremental, 0, 0, "", /* | |
2354 This function starts an incremental garbage collection. If an | |
2355 incremental garbage collection is already running, the next cycle | |
2356 starts. Note that this function has not necessarily freed any memory | |
2357 when it returns. This function only guarantees, that the traversal of | |
2358 the heap makes progress. The next cycle of incremental garbage | |
2359 collection happens automatically if the client allocates more than | |
2360 `gc-incremental-cons-threshold' bytes of Lisp data since previous | |
2361 garbage collection. | |
2362 */ | |
2363 ()) | |
2364 { | |
2365 gc_incremental (); | |
2366 return Qt; | |
2367 } | |
2368 #else /* not NEW_GC */ | |
2369 void garbage_collect_1 (void) | |
2370 { | |
2371 if (gc_in_progress | |
2372 || gc_currently_forbidden | |
2373 || in_display | |
2374 || preparing_for_armageddon) | |
2375 return; | |
2376 | |
2377 /* Very important to prevent GC during any of the following | |
2378 stuff that might run Lisp code; otherwise, we'll likely | |
2379 have infinite GC recursion. */ | |
2380 speccount = begin_gc_forbidden (); | |
2381 | |
3267 | 2382 show_gc_cursor_and_message (); |
2383 | |
3092 | 2384 gc_prepare (); |
2385 #ifdef USE_KKCC | |
2386 kkcc_gc_stack_init(); | |
2387 #ifdef DEBUG_XEMACS | |
2388 kkcc_bt_init (); | |
2389 #endif | |
2390 #endif /* USE_KKCC */ | |
2391 gc_mark_root_set (); | |
2392 #ifdef USE_KKCC | |
2393 kkcc_marking (0); | |
2394 #endif /* USE_KKCC */ | |
2395 gc_finish_mark (); | |
2396 #ifdef USE_KKCC | |
2397 kkcc_gc_stack_free (); | |
2398 #ifdef DEBUG_XEMACS | |
2399 kkcc_bt_free (); | |
2400 #endif | |
2401 #endif /* USE_KKCC */ | |
2402 gc_sweep_1 (); | |
2403 gc_finish (); | |
2404 | |
3267 | 2405 remove_gc_cursor_and_message (); |
2406 | |
3092 | 2407 /* now stop inhibiting GC */ |
2408 unbind_to (speccount); | |
2409 } | |
2410 #endif /* not NEW_GC */ | |
2411 | |
2412 | |
2413 /************************************************************************/ | |
2414 /* Initializations */ | |
2415 /************************************************************************/ | |
2416 | |
2417 /* Initialization */ | |
2418 static void | |
2419 common_init_gc_early (void) | |
2420 { | |
2421 Vgc_message = Qzero; | |
2422 | |
2423 gc_currently_forbidden = 0; | |
2424 gc_hooks_inhibited = 0; | |
2425 | |
2426 need_to_garbage_collect = always_gc; | |
2427 | |
2428 gc_cons_threshold = GC_CONS_THRESHOLD; | |
2429 gc_cons_percentage = 40; /* #### what is optimal? */ | |
2430 total_gc_usage_set = 0; | |
2431 #ifdef NEW_GC | |
2432 gc_cons_incremental_threshold = GC_CONS_INCREMENTAL_THRESHOLD; | |
2433 gc_incremental_traversal_threshold = GC_INCREMENTAL_TRAVERSAL_THRESHOLD; | |
3263 | 2434 #endif /* NEW_GC */ |
3092 | 2435 } |
2436 | |
2437 void | |
2438 init_gc_early (void) | |
2439 { | |
3263 | 2440 #ifdef NEW_GC |
2441 /* Reset the finalizers_to_run list after pdump_load. */ | |
2442 Vfinalizers_to_run = Qnil; | |
2443 #endif /* NEW_GC */ | |
3092 | 2444 } |
2445 | |
2446 void | |
2447 reinit_gc_early (void) | |
2448 { | |
2449 common_init_gc_early (); | |
2450 } | |
2451 | |
2452 void | |
2453 init_gc_once_early (void) | |
2454 { | |
2455 common_init_gc_early (); | |
2456 } | |
2457 | |
2458 void | |
2459 syms_of_gc (void) | |
2460 { | |
2461 DEFSYMBOL (Qpre_gc_hook); | |
2462 DEFSYMBOL (Qpost_gc_hook); | |
2463 #ifdef NEW_GC | |
2464 DEFSUBR (Fgc_full); | |
2465 DEFSUBR (Fgc_incremental); | |
2466 #ifdef ERROR_CHECK_GC | |
2467 DEFSUBR (Fgc_stats); | |
2468 #endif /* not ERROR_CHECK_GC */ | |
2469 #endif /* NEW_GC */ | |
2470 } | |
2471 | |
2472 void | |
2473 vars_of_gc (void) | |
2474 { | |
2475 staticpro_nodump (&pre_gc_cursor); | |
2476 | |
4952
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4934
diff
changeset
|
2477 QSin_garbage_collection = build_defer_string ("(in garbage collection)"); |
3092 | 2478 staticpro (&QSin_garbage_collection); |
2479 | |
2480 DEFVAR_INT ("gc-cons-threshold", &gc_cons_threshold /* | |
2481 *Number of bytes of consing between full garbage collections. | |
2482 \"Consing\" is a misnomer in that this actually counts allocation | |
2483 of all different kinds of objects, not just conses. | |
2484 Garbage collection can happen automatically once this many bytes have been | |
2485 allocated since the last garbage collection. All data types count. | |
2486 | |
2487 Garbage collection happens automatically when `eval' or `funcall' are | |
2488 called. (Note that `funcall' is called implicitly as part of evaluation.) | |
2489 By binding this temporarily to a large number, you can effectively | |
2490 prevent garbage collection during a part of the program. | |
2491 | |
2492 Normally, you cannot set this value less than 10,000 (if you do, it is | |
2493 automatically reset during the next garbage collection). However, if | |
2494 XEmacs was compiled with DEBUG_XEMACS, this does not happen, allowing | |
2495 you to set this value very low to track down problems with insufficient | |
2496 GCPRO'ing. If you set this to a negative number, garbage collection will | |
2497 happen at *EVERY* call to `eval' or `funcall'. This is an extremely | |
2498 effective way to check GCPRO problems, but be warned that your XEmacs | |
2499 will be unusable! You almost certainly won't have the patience to wait | |
2500 long enough to be able to set it back. | |
2501 | |
2502 See also `consing-since-gc' and `gc-cons-percentage'. | |
2503 */ ); | |
2504 | |
2505 DEFVAR_INT ("gc-cons-percentage", &gc_cons_percentage /* | |
2506 *Percentage of memory allocated between garbage collections. | |
2507 | |
2508 Garbage collection will happen if this percentage of the total amount of | |
2509 memory used for data (see `lisp-object-memory-usage') has been allocated | |
2510 since the last garbage collection. However, it will not happen if less | |
2511 than `gc-cons-threshold' bytes have been allocated -- this sets an absolute | |
2512 minimum in case very little data has been allocated or the percentage is | |
2513 set very low. Set this to 0 to have garbage collection always happen after | |
2514 `gc-cons-threshold' bytes have been allocated, regardless of current memory | |
2515 usage. | |
2516 | |
2517 See also `consing-since-gc' and `gc-cons-threshold'. | |
2518 */ ); | |
2519 | |
2520 #ifdef NEW_GC | |
2521 DEFVAR_INT ("gc-cons-incremental-threshold", | |
2522 &gc_cons_incremental_threshold /* | |
2523 *Number of bytes of consing between cycles of incremental garbage | |
2524 collections. \"Consing\" is a misnomer in that this actually counts | |
2525 allocation of all different kinds of objects, not just conses. The | |
2526 next garbage collection cycle can happen automatically once this many | |
2527 bytes have been allocated since the last garbage collection cycle. | |
2528 All data types count. | |
2529 | |
2530 See also `gc-cons-threshold'. | |
2531 */ ); | |
2532 | |
2533 DEFVAR_INT ("gc-incremental-traversal-threshold", | |
2534 &gc_incremental_traversal_threshold /* | |
2535 *Number of elements processed in one cycle of incremental travesal. | |
2536 */ ); | |
2537 #endif /* NEW_GC */ | |
2538 | |
2539 DEFVAR_BOOL ("purify-flag", &purify_flag /* | |
2540 Non-nil means loading Lisp code in order to dump an executable. | |
2541 This means that certain objects should be allocated in readonly space. | |
2542 */ ); | |
2543 | |
2544 DEFVAR_BOOL ("garbage-collection-messages", &garbage_collection_messages /* | |
4502
8748a3f7ceb4
Handle varalias chains, custom variables in #'user-variable-p.
Aidan Kehoe <kehoea@parhasard.net>
parents:
4124
diff
changeset
|
2545 *Non-nil means display messages at start and end of garbage collection. |
3092 | 2546 */ ); |
2547 garbage_collection_messages = 0; | |
2548 | |
2549 DEFVAR_LISP ("pre-gc-hook", &Vpre_gc_hook /* | |
2550 Function or functions to be run just before each garbage collection. | |
2551 Interrupts, garbage collection, and errors are inhibited while this hook | |
2552 runs, so be extremely careful in what you add here. In particular, avoid | |
2553 consing, and do not interact with the user. | |
2554 */ ); | |
2555 Vpre_gc_hook = Qnil; | |
2556 | |
2557 DEFVAR_LISP ("post-gc-hook", &Vpost_gc_hook /* | |
2558 Function or functions to be run just after each garbage collection. | |
2559 Interrupts, garbage collection, and errors are inhibited while this hook | |
2560 runs. Each hook is called with one argument which is an alist with | |
2561 finalization data. | |
2562 */ ); | |
2563 Vpost_gc_hook = Qnil; | |
2564 | |
2565 DEFVAR_LISP ("gc-message", &Vgc_message /* | |
2566 String to print to indicate that a garbage collection is in progress. | |
2567 This is printed in the echo area. If the selected frame is on a | |
2568 window system and `gc-pointer-glyph' specifies a value (i.e. a pointer | |
2569 image instance) in the domain of the selected frame, the mouse pointer | |
2570 will change instead of this message being printed. | |
2571 */ ); | |
4952
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4934
diff
changeset
|
2572 Vgc_message = build_defer_string (gc_default_message); |
3092 | 2573 |
2574 DEFVAR_LISP ("gc-pointer-glyph", &Vgc_pointer_glyph /* | |
2575 Pointer glyph used to indicate that a garbage collection is in progress. | |
2576 If the selected window is on a window system and this glyph specifies a | |
2577 value (i.e. a pointer image instance) in the domain of the selected | |
2578 window, the pointer will be changed as specified during garbage collection. | |
2579 Otherwise, a message will be printed in the echo area, as controlled | |
2580 by `gc-message'. | |
2581 */ ); | |
2582 | |
2583 #ifdef NEW_GC | |
2584 DEFVAR_BOOL ("allow-incremental-gc", &allow_incremental_gc /* | |
2585 *Non-nil means to allow incremental garbage collection. Nil prevents | |
2586 *incremental garbage collection, the garbage collector then only does | |
2587 *full collects (even if (gc-incremental) is called). | |
2588 */ ); | |
3263 | 2589 |
2590 Vfinalizers_to_run = Qnil; | |
2591 staticpro_nodump (&Vfinalizers_to_run); | |
3092 | 2592 #endif /* NEW_GC */ |
2593 } | |
2594 | |
2595 void | |
2596 complex_vars_of_gc (void) | |
2597 { | |
2598 Vgc_pointer_glyph = Fmake_glyph_internal (Qpointer); | |
2599 } |