annotate gc/stubborn.c @ 51488:5de98dce4bd1

*** empty log message ***
author Dave Love <fx@gnu.org>
date Thu, 05 Jun 2003 17:49:22 +0000
parents
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
51488
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
1 /*
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
2 * Copyright 1988, 1989 Hans-J. Boehm, Alan J. Demers
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
3 * Copyright (c) 1991-1994 by Xerox Corporation. All rights reserved.
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
4 *
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
5 * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
6 * OR IMPLIED. ANY USE IS AT YOUR OWN RISK.
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
7 *
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
8 * Permission is hereby granted to use or copy this program
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
9 * for any purpose, provided the above notices are retained on all copies.
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
10 * Permission to modify the code and to distribute modified code is granted,
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
11 * provided the above notices are retained, and a notice that the code was
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
12 * modified is included with the above copyright notice.
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
13 */
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
14 /* Boehm, July 31, 1995 5:02 pm PDT */
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
15
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
16
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
17 #include "private/gc_priv.h"
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
18
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
19 # ifdef STUBBORN_ALLOC
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
20 /* Stubborn object (hard to change, nearly immutable) allocation. */
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
21
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
22 extern ptr_t GC_clear_stack(); /* in misc.c, behaves like identity */
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
23
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
24 #define GENERAL_MALLOC(lb,k) \
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
25 (GC_PTR)GC_clear_stack(GC_generic_malloc((word)lb, k))
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
26
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
27 /* Data structure representing immutable objects that */
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
28 /* are still being initialized. */
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
29 /* This is a bit baroque in order to avoid acquiring */
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
30 /* the lock twice for a typical allocation. */
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
31
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
32 GC_PTR * GC_changing_list_start;
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
33
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
34 void GC_push_stubborn_structures GC_PROTO((void))
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
35 {
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
36 GC_push_all((ptr_t)(&GC_changing_list_start),
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
37 (ptr_t)(&GC_changing_list_start) + sizeof(GC_PTR *));
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
38 }
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
39
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
40 # ifdef THREADS
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
41 VOLATILE GC_PTR * VOLATILE GC_changing_list_current;
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
42 # else
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
43 GC_PTR * GC_changing_list_current;
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
44 # endif
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
45 /* Points at last added element. Also (ab)used for */
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
46 /* synchronization. Updates and reads are assumed atomic. */
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
47
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
48 GC_PTR * GC_changing_list_limit;
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
49 /* Points at the last word of the buffer, which is always 0 */
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
50 /* All entries in (GC_changing_list_current, */
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
51 /* GC_changing_list_limit] are 0 */
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
52
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
53
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
54 void GC_stubborn_init()
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
55 {
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
56 # define INIT_SIZE 10
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
57
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
58 GC_changing_list_start = (GC_PTR *)
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
59 GC_INTERNAL_MALLOC(
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
60 (word)(INIT_SIZE * sizeof(GC_PTR)),
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
61 PTRFREE);
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
62 BZERO(GC_changing_list_start,
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
63 INIT_SIZE * sizeof(GC_PTR));
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
64 if (GC_changing_list_start == 0) {
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
65 GC_err_printf0("Insufficient space to start up\n");
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
66 ABORT("GC_stubborn_init: put of space");
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
67 }
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
68 GC_changing_list_current = GC_changing_list_start;
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
69 GC_changing_list_limit = GC_changing_list_start + INIT_SIZE - 1;
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
70 * GC_changing_list_limit = 0;
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
71 }
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
72
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
73 /* Compact and possibly grow GC_uninit_list. The old copy is */
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
74 /* left alone. Lock must be held. */
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
75 /* When called GC_changing_list_current == GC_changing_list_limit */
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
76 /* which is one past the current element. */
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
77 /* When we finish GC_changing_list_current again points one past last */
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
78 /* element. */
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
79 /* Invariant while this is running: GC_changing_list_current */
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
80 /* points at a word containing 0. */
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
81 /* Returns FALSE on failure. */
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
82 GC_bool GC_compact_changing_list()
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
83 {
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
84 register GC_PTR *p, *q;
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
85 register word count = 0;
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
86 word old_size = (char **)GC_changing_list_limit
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
87 - (char **)GC_changing_list_start+1;
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
88 /* The casts are needed as a workaround for an Amiga bug */
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
89 register word new_size = old_size;
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
90 GC_PTR * new_list;
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
91
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
92 for (p = GC_changing_list_start; p < GC_changing_list_limit; p++) {
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
93 if (*p != 0) count++;
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
94 }
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
95 if (2 * count > old_size) new_size = 2 * count;
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
96 new_list = (GC_PTR *)
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
97 GC_INTERNAL_MALLOC(
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
98 new_size * sizeof(GC_PTR), PTRFREE);
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
99 /* PTRFREE is a lie. But we don't want the collector to */
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
100 /* consider these. We do want the list itself to be */
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
101 /* collectable. */
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
102 if (new_list == 0) return(FALSE);
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
103 BZERO(new_list, new_size * sizeof(GC_PTR));
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
104 q = new_list;
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
105 for (p = GC_changing_list_start; p < GC_changing_list_limit; p++) {
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
106 if (*p != 0) *q++ = *p;
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
107 }
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
108 GC_changing_list_start = new_list;
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
109 GC_changing_list_limit = new_list + new_size - 1;
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
110 GC_changing_list_current = q;
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
111 return(TRUE);
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
112 }
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
113
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
114 /* Add p to changing list. Clear p on failure. */
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
115 # define ADD_CHANGING(p) \
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
116 { \
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
117 register struct hblk * h = HBLKPTR(p); \
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
118 register word index = PHT_HASH(h); \
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
119 \
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
120 set_pht_entry_from_index(GC_changed_pages, index); \
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
121 } \
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
122 if (*GC_changing_list_current != 0 \
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
123 && ++GC_changing_list_current == GC_changing_list_limit) { \
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
124 if (!GC_compact_changing_list()) (p) = 0; \
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
125 } \
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
126 *GC_changing_list_current = p;
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
127
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
128 void GC_change_stubborn(p)
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
129 GC_PTR p;
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
130 {
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
131 DCL_LOCK_STATE;
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
132
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
133 DISABLE_SIGNALS();
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
134 LOCK();
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
135 ADD_CHANGING(p);
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
136 UNLOCK();
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
137 ENABLE_SIGNALS();
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
138 }
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
139
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
140 void GC_end_stubborn_change(p)
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
141 GC_PTR p;
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
142 {
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
143 # ifdef THREADS
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
144 register VOLATILE GC_PTR * my_current = GC_changing_list_current;
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
145 # else
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
146 register GC_PTR * my_current = GC_changing_list_current;
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
147 # endif
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
148 register GC_bool tried_quick;
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
149 DCL_LOCK_STATE;
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
150
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
151 if (*my_current == p) {
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
152 /* Hopefully the normal case. */
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
153 /* Compaction could not have been running when we started. */
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
154 *my_current = 0;
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
155 # ifdef THREADS
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
156 if (my_current == GC_changing_list_current) {
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
157 /* Compaction can't have run in the interim. */
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
158 /* We got away with the quick and dirty approach. */
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
159 return;
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
160 }
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
161 tried_quick = TRUE;
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
162 # else
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
163 return;
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
164 # endif
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
165 } else {
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
166 tried_quick = FALSE;
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
167 }
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
168 DISABLE_SIGNALS();
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
169 LOCK();
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
170 my_current = GC_changing_list_current;
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
171 for (; my_current >= GC_changing_list_start; my_current--) {
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
172 if (*my_current == p) {
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
173 *my_current = 0;
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
174 UNLOCK();
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
175 ENABLE_SIGNALS();
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
176 return;
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
177 }
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
178 }
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
179 if (!tried_quick) {
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
180 GC_err_printf1("Bad arg to GC_end_stubborn_change: 0x%lx\n",
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
181 (unsigned long)p);
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
182 ABORT("Bad arg to GC_end_stubborn_change");
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
183 }
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
184 UNLOCK();
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
185 ENABLE_SIGNALS();
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
186 }
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
187
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
188 /* Allocate lb bytes of composite (pointerful) data */
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
189 /* No pointer fields may be changed after a call to */
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
190 /* GC_end_stubborn_change(p) where p is the value */
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
191 /* returned by GC_malloc_stubborn. */
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
192 # ifdef __STDC__
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
193 GC_PTR GC_malloc_stubborn(size_t lb)
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
194 # else
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
195 GC_PTR GC_malloc_stubborn(lb)
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
196 size_t lb;
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
197 # endif
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
198 {
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
199 register ptr_t op;
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
200 register ptr_t *opp;
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
201 register word lw;
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
202 ptr_t result;
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
203 DCL_LOCK_STATE;
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
204
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
205 if( SMALL_OBJ(lb) ) {
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
206 # ifdef MERGE_SIZES
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
207 lw = GC_size_map[lb];
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
208 # else
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
209 lw = ALIGNED_WORDS(lb);
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
210 # endif
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
211 opp = &(GC_sobjfreelist[lw]);
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
212 FASTLOCK();
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
213 if( !FASTLOCK_SUCCEEDED() || (op = *opp) == 0 ) {
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
214 FASTUNLOCK();
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
215 result = GC_generic_malloc((word)lb, STUBBORN);
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
216 goto record;
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
217 }
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
218 *opp = obj_link(op);
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
219 obj_link(op) = 0;
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
220 GC_words_allocd += lw;
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
221 result = (GC_PTR) op;
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
222 ADD_CHANGING(result);
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
223 FASTUNLOCK();
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
224 return((GC_PTR)result);
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
225 } else {
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
226 result = (GC_PTR)
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
227 GC_generic_malloc((word)lb, STUBBORN);
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
228 }
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
229 record:
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
230 DISABLE_SIGNALS();
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
231 LOCK();
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
232 ADD_CHANGING(result);
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
233 UNLOCK();
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
234 ENABLE_SIGNALS();
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
235 return((GC_PTR)GC_clear_stack(result));
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
236 }
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
237
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
238
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
239 /* Functions analogous to GC_read_dirty and GC_page_was_dirty. */
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
240 /* Report pages on which stubborn objects were changed. */
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
241 void GC_read_changed()
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
242 {
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
243 register GC_PTR * p = GC_changing_list_start;
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
244 register GC_PTR q;
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
245 register struct hblk * h;
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
246 register word index;
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
247
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
248 if (p == 0) /* initializing */ return;
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
249 BCOPY(GC_changed_pages, GC_prev_changed_pages,
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
250 (sizeof GC_changed_pages));
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
251 BZERO(GC_changed_pages, (sizeof GC_changed_pages));
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
252 for (; p <= GC_changing_list_current; p++) {
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
253 if ((q = *p) != 0) {
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
254 h = HBLKPTR(q);
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
255 index = PHT_HASH(h);
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
256 set_pht_entry_from_index(GC_changed_pages, index);
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
257 }
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
258 }
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
259 }
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
260
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
261 GC_bool GC_page_was_changed(h)
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
262 struct hblk * h;
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
263 {
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
264 register word index = PHT_HASH(h);
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
265
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
266 return(get_pht_entry_from_index(GC_prev_changed_pages, index));
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
267 }
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
268
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
269 /* Remove unreachable entries from changed list. Should only be */
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
270 /* called with mark bits consistent and lock held. */
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
271 void GC_clean_changing_list()
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
272 {
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
273 register GC_PTR * p = GC_changing_list_start;
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
274 register GC_PTR q;
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
275 register ptr_t r;
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
276 register unsigned long count = 0;
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
277 register unsigned long dropped_count = 0;
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
278
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
279 if (p == 0) /* initializing */ return;
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
280 for (; p <= GC_changing_list_current; p++) {
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
281 if ((q = *p) != 0) {
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
282 count++;
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
283 r = (ptr_t)GC_base(q);
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
284 if (r == 0 || !GC_is_marked(r)) {
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
285 *p = 0;
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
286 dropped_count++;
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
287 }
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
288 }
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
289 }
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
290 # ifdef PRINTSTATS
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
291 if (count > 0) {
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
292 GC_printf2("%lu entries in changing list: reclaimed %lu\n",
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
293 (unsigned long)count, (unsigned long)dropped_count);
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
294 }
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
295 # endif
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
296 }
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
297
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
298 #else /* !STUBBORN_ALLOC */
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
299
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
300 # ifdef __STDC__
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
301 GC_PTR GC_malloc_stubborn(size_t lb)
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
302 # else
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
303 GC_PTR GC_malloc_stubborn(lb)
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
304 size_t lb;
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
305 # endif
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
306 {
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
307 return(GC_malloc(lb));
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
308 }
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
309
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
310 /*ARGSUSED*/
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
311 void GC_end_stubborn_change(p)
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
312 GC_PTR p;
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
313 {
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
314 }
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
315
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
316 /*ARGSUSED*/
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
317 void GC_change_stubborn(p)
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
318 GC_PTR p;
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
319 {
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
320 }
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
321
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
322 void GC_push_stubborn_structures GC_PROTO((void))
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
323 {
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
324 }
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
325
5de98dce4bd1 *** empty log message ***
Dave Love <fx@gnu.org>
parents:
diff changeset
326 #endif