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