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