Mercurial > hg > xemacs-beta
annotate src/gc.c @ 5773:94a6b8fbd56e
Use a face, show more context around open parenthesis, #'blink-matching-open
lisp/ChangeLog addition:
2013-12-17 Aidan Kehoe <kehoea@parhasard.net>
* simple.el (blink-matching-open):
When showing the opening parenthesis in the minibiffer, use the
isearch face for it, in case there are multiple parentheses in the
text shown.
When writing moderately involved macros, it's often not enough
just to show the backquote context before the parenthesis
(e.g. @,.`). Skip over that when searching for useful context in
the same way we skip over space and tab.
* simple.el (message):
* simple.el (lmessage):
If there are no ARGS, don't call #'format. This allows extent
information to be passed through to the minibuffer.
It's probably better still to update #'format to preserve extent
info.
author | Aidan Kehoe <kehoea@parhasard.net> |
---|---|
date | Tue, 17 Dec 2013 20:49:52 +0200 |
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 } |