annotate src/=old-ralloc.c @ 35091:bc80b0ab1630

(update_end): Don't check updating_frame; for some reason this can be 0 sometimes, such as after dismissing a popup menu, and isn't necessary given the explicit frame argument.
author Andrew Innes <andrewi@gnu.org>
date Fri, 05 Jan 2001 21:26:40 +0000
parents c7c930b84dbb
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
115
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
1 /* Block-relocating memory allocator.
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
2 Copyright (C) 1990 Free Software Foundation, Inc.
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
3
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
4 This file is part of GNU Emacs.
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
5
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
6 GNU Emacs is free software; you can redistribute it and/or modify
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
7 it under the terms of the GNU General Public License as published by
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
8 the Free Software Foundation; either version 1, or (at your option)
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
9 any later version.
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
10
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
11 GNU Emacs is distributed in the hope that it will be useful,
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
14 GNU General Public License for more details.
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
15
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
16 You should have received a copy of the GNU General Public License
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
17 along with GNU Emacs; see the file COPYING. If not, write to
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
18 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
19
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
20 /* This package works by allocating blocks from a zone of memory
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
21 above that used by malloc (). When malloc needs more space that
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
22 would enter our zone, we relocate blocks upward. The bottom of
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
23 our zone is kept in the variable `virtual_break_value'. The top
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
24 of our zone is indicated by `real_break_value'.
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
25
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
26 As blocks are freed, a free list is maintained and we attempt
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
27 to satisfy further requests for space using a first-fit policy.
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
28 If there are holes, but none fit, memory is compacted and a new
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
29 block is obtained at the top of the zone.
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
30
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
31 NOTE that our blocks are always rounded to page boundaries. */
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
32
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
33 /*
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
34 NOTES:
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
35
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
36 Once this is stable, I can speed things up by intially leaving a large
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
37 gap between real_break_value and true_break_value, or maybe making
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
38 a large hole before the first block.
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
39
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
40 If we also kept track of size_wanted, we could gain some
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
41 extra space upon compactification.
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
42
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
43 Perhaps we should just note a hole when malloc does doing sbrk(-n)?
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
44
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
45 Relocating downward upon freeing the first block would simplify
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
46 other things.
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
47
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
48 When r_alloc places a block in a hole, we could easily check if there's
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
49 much more than required, and leave a hole.
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
50 */
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
51
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
52 #include "mem_limits.h"
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
53
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
54 static POINTER r_alloc_sbrk ();
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
55 static POINTER sbrk ();
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
56 static POINTER brk ();
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
57
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
58 /* Variable `malloc' uses for the function which gets more space
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
59 from the system. */
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
60 extern POINTER (*__morecore) ();
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
61
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
62 /* List of variables which point into the associated data block. */
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
63 struct other_pointer
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
64 {
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
65 POINTER *location;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
66 struct other_pointer *next;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
67 };
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
68
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
69 /* List describing all the user's pointers to relocatable blocks. */
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
70 typedef struct rel_pointers
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
71 {
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
72 struct rel_pointers *next;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
73 struct rel_pointers *prev;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
74 struct other_pointer *others; /* Other variables which use this block. */
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
75 POINTER *location; /* Location of the block's pointer. */
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
76 POINTER block; /* Address of the actual data. */
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
77 int size; /* The size of the block. */
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
78 } relocatable_pointer;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
79
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
80 #define REL_NIL ((struct rel_pointers *) 0)
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
81
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
82 static relocatable_pointer *pointer_list;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
83 static relocatable_pointer *last_pointer;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
84
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
85 #define MAX_HOLES 2
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
86
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
87 /* Vector of available holes among allocated blocks. This can include
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
88 a hole at the beginning of the list, but never the end. */
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
89 typedef struct
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
90 {
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
91 POINTER address;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
92 unsigned int size;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
93 } hole_descriptor;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
94
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
95 static hole_descriptor r_alloc_holes[MAX_HOLES];
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
96
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
97 /* Number of holes currently available. */
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
98 static int holes;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
99
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
100 /* The process break value (i.e., curbrk) */
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
101 static POINTER real_break_value;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
102
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
103 /* The REAL (i.e., page aligned) break value. */
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
104 static POINTER true_break_value;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
105
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
106 /* Address of start of data space in use by relocatable blocks.
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
107 This is what `malloc' thinks is the process break value. */
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
108 static POINTER virtual_break_value;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
109
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
110 /* Nonzero if we have told `malloc' to start using `r_alloc_sbrk'
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
111 instead of calling `sbrk' directly. */
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
112 int r_alloc_in_use;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
113
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
114 #define PAGE (getpagesize ())
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
115 #define ALIGNED(addr) (((unsigned int) (addr) & (PAGE - 1)) == 0)
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
116 #define ROUNDUP(size) (((unsigned int) (size) + PAGE) & ~(PAGE - 1))
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
117
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
118 /*
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
119 Level number of warnings already issued.
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
120 0 -- no warnings issued.
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
121 1 -- 75% warning already issued.
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
122 2 -- 85% warning already issued.
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
123 */
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
124 static int warnlevel;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
125
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
126 /* Function to call to issue a warning;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
127 0 means don't issue them. */
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
128 static void (*warnfunction) ();
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
129
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
130 /* Call this to start things off. It determines the current process
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
131 break value, as well as the `true' break value--because the system
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
132 allocates memory in page increments, if the break value is not page
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
133 aligned it means that space up to the next page boundary is actually
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
134 available. */
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
135
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
136 void
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
137 malloc_init (start, warn_func)
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
138 POINTER start;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
139 void (*warn_func) ();
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
140 {
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
141 r_alloc_in_use = 1;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
142 __morecore = r_alloc_sbrk;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
143
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
144 virtual_break_value = real_break_value = sbrk (0);
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
145 if (ALIGNED (real_break_value))
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
146 true_break_value = real_break_value;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
147 else
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
148 true_break_value = (POINTER) ROUNDUP (real_break_value);
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
149
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
150 if (start)
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
151 data_space_start = start;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
152 lim_data = 0;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
153 warnlevel = 0;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
154 warnfunction = warn_func;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
155
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
156 get_lim_data ();
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
157 }
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
158
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
159 /* Get more space for us to use. Return a pointer to SIZE more
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
160 bytes of space. SIZE is internally rounded up to a page boundary,
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
161 and requests for integral pages prefetch an extra page. */
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
162
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
163 static POINTER
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
164 get_more_space (size)
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
165 unsigned int size;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
166 {
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
167 unsigned int margin = true_break_value - real_break_value;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
168 unsigned int get;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
169 POINTER old_break = real_break_value;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
170
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
171 if (size == 0)
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
172 return real_break_value;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
173
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
174 if (size <= margin)
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
175 {
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
176 real_break_value += size;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
177 return old_break;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
178 }
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
179
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
180 get = ROUNDUP (size - margin);
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
181 if (sbrk (get) < (POINTER) 0)
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
182 return NULL;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
183
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
184 true_break_value += get;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
185 real_break_value = (old_break + size);
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
186
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
187 return old_break;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
188 }
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
189
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
190 /* Relinquish size bytes of space to the system. Space is only returned
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
191 in page increments. If successful, return real_break_value. */
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
192
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
193 static POINTER
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
194 return_space (size)
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
195 unsigned int size;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
196 {
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
197 unsigned int margin = (true_break_value - real_break_value) + size;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
198 unsigned int to_return = (margin / PAGE) * PAGE;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
199 unsigned new_margin = margin % PAGE;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
200
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
201 true_break_value -= to_return;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
202 if (! brk (true_break_value))
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
203 return NULL;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
204
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
205 real_break_value = true_break_value - new_margin;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
206 return real_break_value;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
207 }
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
208
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
209 /* Record a new hole in memory beginning at ADDRESS of size SIZE.
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
210 Holes are ordered by location. Adjacent holes are merged.
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
211 Holes are zero filled before being noted. */
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
212
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
213 static void
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
214 note_hole (address, size)
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
215 POINTER address;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
216 int size;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
217 {
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
218 register int this_hole = holes - 1; /* Start at the last hole. */
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
219 register POINTER end = address + size; /* End of the hole. */
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
220 register int i;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
221
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
222 if (holes)
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
223 {
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
224 /* Find the hole which should precede this new one. */
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
225 while (this_hole >= 0 && r_alloc_holes[this_hole].address > address)
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
226 this_hole--;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
227
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
228 /* Can we merge with preceding? */
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
229 if (this_hole >= 0
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
230 && r_alloc_holes[this_hole].address + r_alloc_holes[this_hole].size
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
231 == address)
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
232 {
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
233 r_alloc_holes[this_hole].size += size;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
234
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
235 if (this_hole == holes - 1)
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
236 return;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
237
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
238 /* Can we also merge with following? */
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
239 if (end == r_alloc_holes[this_hole + 1].address)
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
240 {
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
241 r_alloc_holes[this_hole].size
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
242 += r_alloc_holes[this_hole + 1].size;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
243
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
244 for (i = this_hole + 1; i < holes - 1; i++)
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
245 r_alloc_holes[i] = r_alloc_holes[i + 1];
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
246 holes--;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
247 }
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
248
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
249 return;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
250 }
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
251
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
252 if (this_hole < holes - 1) /* there are following holes */
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
253 {
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
254 register int next_hole = this_hole + 1;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
255
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
256 /* Can we merge with the next hole? */
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
257 if (end == r_alloc_holes[next_hole].address)
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
258 {
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
259 r_alloc_holes[next_hole].address = address;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
260 r_alloc_holes[next_hole].size += size;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
261 return;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
262 }
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
263
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
264 /* Can't merge, so insert. */
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
265 for (i = holes; i > next_hole; i--)
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
266 r_alloc_holes[i] = r_alloc_holes[i - 1];
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
267 r_alloc_holes[next_hole].address = address;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
268 r_alloc_holes[next_hole].size = size;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
269 holes++;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
270
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
271 return;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
272 }
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
273 else /* Simply add this hole at the end. */
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
274 {
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
275 r_alloc_holes[holes].address = address;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
276 r_alloc_holes[holes].size = size;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
277 holes++;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
278
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
279 return;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
280 }
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
281
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
282 abort ();
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
283 }
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
284 else /* Make the first hole. */
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
285 {
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
286 holes = 1;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
287 r_alloc_holes[0].address = address;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
288 r_alloc_holes[0].size = size;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
289 }
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
290 }
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
291
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
292 /* Mark hole HOLE as no longer available by re-organizing the vector.
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
293 HOLE is the Nth hole, beginning with 0. This doesn *not* affect memory
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
294 organization. */
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
295
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
296 static void
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
297 delete_hole (hole)
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
298 int hole;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
299 {
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
300 register int i;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
301
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
302 for (i = hole; i < holes - 1; i++)
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
303 r_alloc_holes[i] = r_alloc_holes[i + 1];
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
304
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
305 holes--;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
306 }
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
307
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
308 /* Insert a newly allocated pointer, NEW_PTR, at the appropriate
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
309 place in our list. */
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
310
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
311 static void
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
312 insert (new_ptr)
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
313 register relocatable_pointer *new_ptr;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
314 {
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
315 register relocatable_pointer *this_ptr = pointer_list;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
316
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
317 while (this_ptr != REL_NIL && this_ptr->block < new_ptr->block)
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
318 this_ptr = this_ptr->next;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
319
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
320 if (this_ptr == REL_NIL)
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
321 abort (); /* Use `attach' for appending. */
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
322
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
323 new_ptr->next = this_ptr;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
324 new_ptr->prev = this_ptr->prev;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
325 this_ptr->prev = new_ptr;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
326
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
327 if (this_ptr == pointer_list)
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
328 pointer_list = new_ptr;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
329 else
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
330 new_ptr->prev->next = new_ptr;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
331 }
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
332
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
333 /* Attach a newly allocated pointer, NEW_PTR, to the end of our list. */
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
334
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
335 static void
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
336 attach (new_ptr)
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
337 relocatable_pointer *new_ptr;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
338 {
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
339 if (pointer_list == REL_NIL)
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
340 {
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
341 pointer_list = new_ptr;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
342 last_pointer = new_ptr;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
343 new_ptr->next = new_ptr->prev = REL_NIL;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
344 }
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
345 else
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
346 {
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
347 new_ptr->next = REL_NIL;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
348 last_pointer->next = new_ptr;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
349 new_ptr->prev = last_pointer;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
350 last_pointer = new_ptr;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
351 }
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
352 }
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
353
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
354 static relocatable_pointer *
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
355 find_block (block)
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
356 POINTER block;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
357 {
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
358 register relocatable_pointer *this_ptr = pointer_list;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
359
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
360 while (this_ptr != REL_NIL && this_ptr->block != block)
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
361 this_ptr = this_ptr->next;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
362
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
363 return this_ptr;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
364 }
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
365
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
366 static relocatable_pointer *
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
367 find_location (address)
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
368 POINTER *address;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
369 {
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
370 register relocatable_pointer *this_ptr = pointer_list;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
371
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
372 while (this_ptr != REL_NIL && this_ptr->location != address)
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
373 {
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
374 struct other_pointer *op = this_ptr->others;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
375
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
376 while (op != (struct other_pointer *) 0)
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
377 {
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
378 if (op->location == address)
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
379 return this_ptr;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
380
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
381 op = op->next;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
382 }
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
383
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
384 this_ptr = this_ptr->next;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
385 }
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
386
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
387 return this_ptr;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
388 }
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
389
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
390
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
391 static void compactify ();
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
392
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
393 /* Record of last new block allocated. */
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
394 static relocatable_pointer *last_record;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
395
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
396 /* Allocate a block of size SIZE and record that PTR points to it.
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
397 If successful, store the address of the block in *PTR and return
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
398 it as well. Otherwise return NULL. */
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
399
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
400 POINTER
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
401 r_alloc (ptr, size)
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
402 POINTER *ptr;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
403 int size;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
404 {
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
405 register relocatable_pointer *record
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
406 = (relocatable_pointer *) malloc (sizeof (relocatable_pointer));
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
407 register POINTER block;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
408
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
409 /* If we can't get space to record this pointer, fail. */
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
410 if (record == 0)
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
411 return NULL;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
412
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
413 last_record = record;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
414
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
415 if (holes) /* Search for a hole the right size. */
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
416 {
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
417 int i;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
418
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
419 for (i = 0; i < holes; i++)
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
420 if (r_alloc_holes[i].size >= size)
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
421 {
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
422 record->location = ptr;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
423 record->others = (struct other_pointer *) 0;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
424 record->block = *ptr = r_alloc_holes[i].address;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
425 if (r_alloc_holes[i].size > ROUNDUP (size))
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
426 {
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
427 record->size = ROUNDUP (size);
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
428 r_alloc_holes[i].size -= ROUNDUP (size);
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
429 r_alloc_holes[i].address += ROUNDUP (size);
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
430 }
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
431 else
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
432 {
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
433 record->size = r_alloc_holes[i].size;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
434 delete_hole (i);
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
435 }
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
436 insert (record);
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
437
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
438 *ptr = record->block;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
439 return record->block;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
440 }
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
441
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
442 /* No holes large enough. Burp. */
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
443 compactify ();
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
444 }
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
445
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
446 /* No holes: grow the process. */
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
447 block = get_more_space (size);
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
448 if (block == NULL)
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
449 {
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
450 free (record);
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
451 return NULL;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
452 }
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
453
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
454 /* Return the address of the block. */
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
455 *ptr = block;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
456
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
457 /* Record and append this pointer to our list. */
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
458 record->location = ptr;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
459 record->others = (struct other_pointer *) 0;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
460 record->block = block;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
461 record->size = size;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
462 attach (record);
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
463
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
464 return block;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
465 }
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
466
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
467 /* Declare VAR to be a pointer which points into the block of r_alloc'd
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
468 memory at BLOCK.
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
469
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
470 If VAR is already delcared for this block, simply return.
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
471 If VAR currently points to some other block, remove that declaration
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
472 of it, then install the new one.
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
473
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
474 Return 0 if successful, -1 otherwise. */
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
475
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
476 int
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
477 r_alloc_declare (var, block)
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
478 POINTER *var;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
479 register POINTER block;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
480 {
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
481 register relocatable_pointer *block_ptr = find_block (block);
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
482 relocatable_pointer *var_ptr = find_location (var);
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
483 register struct other_pointer *other;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
484
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
485 if (block_ptr == REL_NIL)
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
486 abort ();
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
487
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
488 if (var_ptr != REL_NIL) /* Var already declared somewhere. */
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
489 {
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
490 register struct other_pointer *po;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
491
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
492 if (var_ptr == block_ptr) /* Var already points to this block. */
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
493 return 0;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
494
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
495 po = (struct other_pointer *) 0;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
496 other = var_ptr->others;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
497 while (other && other->location != var)
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
498 {
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
499 po = other;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
500 other = other->next;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
501 }
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
502
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
503 if (!other) /* This only happens if the location is */
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
504 abort (); /* the main pointer and not an `other' */
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
505
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
506 if (po) /* In the chain */
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
507 {
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
508 po->next = other->next;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
509 free (other);
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
510 }
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
511 else /* Only element of the chain */
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
512 {
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
513 free (var_ptr->others);
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
514 var_ptr->others = (struct other_pointer *) 0;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
515 }
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
516 }
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
517
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
518 /* Install this variable as an `other' element */
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
519
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
520 other = (struct other_pointer *) malloc (sizeof (struct other_pointer));
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
521
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
522 if (other == 0)
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
523 return -1;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
524
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
525 /* If the malloc relocated this data block, adjust this variable. */
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
526 if (block != block_ptr->block)
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
527 {
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
528 int offset = block_ptr->block - block;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
529
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
530 *var += offset;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
531 }
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
532
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
533 other->location = var;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
534 other->next = (struct other_pointer *) 0;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
535
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
536 if (block_ptr->others == (struct other_pointer *) 0)
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
537 block_ptr->others = other;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
538 else
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
539 {
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
540 register struct other_pointer *op = block_ptr->others;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
541
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
542 while (op->next != (struct other_pointer *) 0)
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
543 op = op->next;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
544 op->next = other;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
545 }
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
546
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
547 return 0;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
548 }
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
549
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
550 /* Recursively free the linked list of `other' pointers to a block. */
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
551
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
552 static void
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
553 free_others (another)
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
554 struct other_pointer *another;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
555 {
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
556 if (another == (struct other_pointer *) 0)
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
557 return;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
558
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
559 free_others (another->next);
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
560 free (another);
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
561 }
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
562
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
563 /* Remove the element pointed to by PTR from the doubly linked list.
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
564 Record the newly freed space in `holes', unless it was at the end,
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
565 in which case return that space to the system. Return 0 if successful,
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
566 -1 otherwise. */
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
567
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
568 int
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
569 r_alloc_free (ptr)
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
570 register POINTER *ptr;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
571 {
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
572 register relocatable_pointer *this_ptr = find_block (*ptr);
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
573
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
574 if (this_ptr == REL_NIL)
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
575 return -1;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
576 else
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
577 {
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
578 register relocatable_pointer *prev = this_ptr->prev;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
579 register relocatable_pointer *next = this_ptr->next;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
580 if (next && prev) /* Somewhere in the middle */
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
581 {
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
582 next->prev = prev;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
583 prev->next = next;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
584 }
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
585 else if (prev) /* Last block */
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
586 {
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
587 prev->next = REL_NIL;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
588 last_pointer = prev;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
589 return_space (this_ptr->size);
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
590 free_others (this_ptr->others);
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
591 free (this_ptr);
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
592
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
593 return 0;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
594 }
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
595 else if (next) /* First block */
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
596 {
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
597 next->prev = REL_NIL;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
598 pointer_list = next;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
599 }
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
600 else if (this_ptr = pointer_list) /* ONLY block */
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
601 {
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
602 pointer_list = REL_NIL;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
603 last_pointer = REL_NIL;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
604 if (holes) /* A hole precedes this block. */
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
605 {
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
606 holes = 0;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
607 return_space (real_break_value - virtual_break_value);
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
608 }
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
609 else
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
610 return_space (this_ptr->size);
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
611
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
612 if (real_break_value != virtual_break_value)
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
613 abort ();
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
614
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
615 free_others (this_ptr->others);
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
616 free (this_ptr);
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
617 /* Turn off r_alloc_in_use? */
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
618
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
619 return 0;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
620 }
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
621 else
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
622 abort (); /* Weird shit */
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
623
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
624 free_others (this_ptr->others);
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
625 free (this_ptr);
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
626 bzero (this_ptr->block, this_ptr->size);
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
627 note_hole (this_ptr->block, this_ptr->size);
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
628
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
629 if (holes == MAX_HOLES)
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
630 compactify ();
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
631 }
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
632
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
633 return 0;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
634 }
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
635
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
636 /* Change the size of the block pointed to by the thing in PTR.
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
637 If neccessary, r_alloc a new block and copy the data there.
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
638 Return a pointer to the block if successfull, NULL otherwise.
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
639
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
640 Note that if the size requested is less than the actual bloc size,
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
641 nothing is done and the pointer is simply returned. */
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
642
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
643 POINTER
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
644 r_re_alloc (ptr, size)
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
645 POINTER *ptr;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
646 int size;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
647 {
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
648 register relocatable_pointer *this_ptr = find_block (*ptr);
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
649 POINTER block;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
650
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
651 if (! this_ptr)
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
652 return NULL;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
653
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
654 if (this_ptr->size >= size) /* Already have enough space. */
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
655 return *ptr;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
656
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
657 /* Here we could try relocating the blocks just above... */
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
658 block = r_alloc (ptr, size);
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
659 if (block)
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
660 {
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
661 bcopy (this_ptr->block, block, this_ptr->size);
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
662 if (this_ptr->others)
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
663 last_record->others = this_ptr->others;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
664
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
665 if (! r_alloc_free (this_ptr->block))
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
666 abort ();
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
667
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
668 *ptr = block;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
669 return block;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
670 }
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
671
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
672 return NULL;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
673 }
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
674
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
675
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
676 /* Move and relocate all blocks from FIRST_PTR to LAST_PTR, inclusive,
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
677 downwards to space starting at ADDRESS. */
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
678
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
679 static int
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
680 move_blocks_downward (first_ptr, last_ptr, address)
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
681 relocatable_pointer *first_ptr, *last_ptr;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
682 POINTER address;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
683 {
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
684 int size = (last_ptr->block + last_ptr->size) - first_ptr->block;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
685 register relocatable_pointer *this_ptr = first_ptr;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
686 register offset = first_ptr->block - address;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
687 register struct other_pointer *op;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
688
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
689 /* Move all the data. */
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
690 bcopy (first_ptr->block, address, size);
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
691
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
692 /* Now relocate all the pointers to those blocks. */
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
693 while (1)
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
694 {
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
695 this_ptr->block -= offset;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
696 *this_ptr->location = this_ptr->block;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
697
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
698 op = this_ptr->others;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
699 while (op != (struct other_pointer *) 0)
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
700 {
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
701 *op->location -= offset;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
702 op = op->next;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
703 }
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
704
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
705 if (this_ptr == last_ptr)
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
706 return;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
707 else
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
708 this_ptr = this_ptr->next;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
709 }
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
710
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
711 return size;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
712 }
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
713
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
714 /* Burp our memory zone. */
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
715
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
716 static void
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
717 compactify ()
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
718 {
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
719 register relocatable_pointer *this_ptr = pointer_list;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
720 relocatable_pointer *first_to_move;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
721 register relocatable_pointer *last_to_move;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
722 hole_descriptor *this_hole = &r_alloc_holes[0];
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
723 register hole_descriptor *next_hole;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
724 register POINTER end; /* First address after hole */
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
725 unsigned int space_regained = 0;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
726
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
727 while (holes) /* While there are holes */
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
728 {
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
729 /* Find the first block after this hole. */
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
730 end = this_hole->address + this_hole->size;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
731 while (this_ptr && this_ptr->block != end)
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
732 this_ptr = this_ptr->next;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
733
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
734 if (! this_ptr)
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
735 abort ();
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
736
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
737 next_hole = this_hole + 1;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
738 last_to_move = first_to_move = this_ptr;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
739 this_ptr = this_ptr->next;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
740
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
741 /* Note all blocks located before the next hole. */
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
742 while (this_ptr && this_ptr->block < next_hole->address)
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
743 {
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
744 last_to_move = this_ptr;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
745 this_ptr = this_ptr->next;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
746 }
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
747 space_regained +=
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
748 move_blocks_downward (first_to_move, last_to_move, this_hole->address);
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
749
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
750 holes--;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
751 this_hole = next_hole;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
752 }
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
753
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
754 return_space (space_regained);
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
755 }
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
756
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
757 /* Relocate the list elements from the beginning of the list up to and
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
758 including UP_TO_THIS_PTR to the area beginning at FREE_SPACE, which is
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
759 after all current blocks.
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
760
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
761 First copy all the data, then adjust the pointers and reorganize
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
762 the list. NOTE that this *only* works for contiguous blocks. */
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
763
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
764 static unsigned int
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
765 relocate_to_end (up_to_this_ptr, free_space)
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
766 register relocatable_pointer *up_to_this_ptr;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
767 POINTER free_space;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
768 {
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
769 register relocatable_pointer *this_ptr;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
770 POINTER block_start = pointer_list->block;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
771 POINTER block_end = up_to_this_ptr->block + up_to_this_ptr->size;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
772 unsigned int total_size = block_end - block_start;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
773 unsigned int offset = (int) (free_space - block_start);
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
774
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
775 bcopy (block_start, free_space, total_size);
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
776 for (this_ptr = up_to_this_ptr; this_ptr; this_ptr = this_ptr->prev)
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
777 {
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
778 struct other_pointer *op = this_ptr->others;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
779
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
780 *this_ptr->location += offset;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
781 this_ptr->block += offset;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
782
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
783 while (op != (struct other_pointer *) 0)
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
784 {
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
785 *op->location += offset;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
786 op = op->next;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
787 }
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
788 }
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
789
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
790 /* Connect the head to the tail. */
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
791 last_pointer->next = pointer_list;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
792 pointer_list->prev = last_pointer;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
793
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
794 /* Disconnect */
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
795 up_to_this_ptr->next->prev = REL_NIL;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
796 pointer_list = up_to_this_ptr->next;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
797 up_to_this_ptr->next = REL_NIL;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
798 last_pointer = up_to_this_ptr;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
799
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
800 return total_size; /* of space relocated. */
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
801 }
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
802
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
803 /* Relocate the list elements from FROM_THIS_PTR to (and including)
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
804 the last to the zone beginning at FREE_SPACE, which is located
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
805 before any blocks.
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
806
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
807 First copy all the data, then adjust the pointers and reorganize
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
808 the list. NOTE that this *only* works for contiguous blocks. */
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
809
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
810 static unsigned int
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
811 relocate_to_beginning (from_this_ptr, free_space)
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
812 register relocatable_pointer *from_this_ptr;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
813 POINTER free_space;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
814 {
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
815 POINTER block_start = from_this_ptr->block;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
816 POINTER block_end = last_pointer->block + last_pointer->size;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
817 unsigned int total_size = (int) (block_end - block_start);
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
818 unsigned int offset = (int) (from_this_ptr->block - free_space);
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
819 register relocatable_pointer *this_ptr;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
820
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
821 bcopy (block_start, free_space, total_size);
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
822 for (this_ptr = from_this_ptr; this_ptr; this_ptr = this_ptr->next)
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
823 {
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
824 struct other_pointer *op = this_ptr->others;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
825
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
826 *this_ptr->location -= offset;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
827 this_ptr->block -= offset;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
828
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
829 while (op != (struct other_pointer *) 0)
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
830 {
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
831 *op->location -= offset;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
832 op = op->next;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
833 }
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
834 }
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
835
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
836 /* Connect the end to the beginning. */
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
837 last_pointer->next = pointer_list;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
838 pointer_list->prev = last_pointer;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
839
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
840 /* Disconnect and reset first and last. */
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
841 from_this_ptr->prev->next = REL_NIL;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
842 last_pointer = from_this_ptr->prev;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
843 pointer_list = from_this_ptr;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
844 pointer_list->prev = REL_NIL;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
845
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
846 return total_size; /* of space moved. */
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
847 }
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
848
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
849 /* Relocate any blocks neccessary, either upwards or downwards,
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
850 to obtain a space of SIZE bytes. Assumes we have at least one block. */
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
851
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
852 static unsigned int
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
853 relocate (size)
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
854 register int size;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
855 {
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
856 register relocatable_pointer *ptr;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
857 register int got = 0;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
858
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
859 if (size > 0) /* Up: Relocate enough blocs to get SIZE. */
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
860 {
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
861 register POINTER new_space;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
862
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
863 for (ptr = pointer_list; got < size && ptr; ptr = ptr->next)
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
864 got += ptr->size;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
865
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
866 if (ptr == REL_NIL)
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
867 ptr = last_pointer;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
868
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
869 new_space = get_more_space (size);
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
870 if (!new_space)
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
871 return 0;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
872
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
873 return (relocate_to_end (ptr, pointer_list->block + size));
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
874 }
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
875
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
876 if (size < 0) /* Down: relocate as many blocs as will
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
877 fit in SIZE bytes of space. */
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
878 {
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
879 register POINTER to_zone;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
880 unsigned int moved;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
881
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
882 for (ptr = last_pointer; got >= size && ptr; ptr = ptr->prev)
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
883 got -= ptr->size;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
884
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
885 if (ptr == REL_NIL)
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
886 ptr = pointer_list;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
887 else
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
888 {
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
889 /* Back off one block to be <= size */
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
890 got += ptr->size;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
891 ptr = ptr->next;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
892 }
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
893
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
894 if (got >= size)
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
895 {
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
896 to_zone = virtual_break_value - size + got;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
897 moved = relocate_to_beginning (ptr, to_zone);
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
898 if (moved)
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
899 return_space (moved);
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
900
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
901 return moved;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
902 }
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
903
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
904 return 0;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
905 }
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
906
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
907 abort ();
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
908 }
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
909
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
910 /* This function encapsulates `sbrk' to preserve the relocatable blocks.
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
911 It is called just like `sbrk'. When relocatable blocks are in use,
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
912 `malloc' must use this function instead of `sbrk'. */
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
913
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
914 POINTER
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
915 r_alloc_sbrk (size)
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
916 unsigned int size;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
917 {
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
918 POINTER new_zone; /* Start of the zone we will return. */
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
919
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
920 #if 0
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
921 if (! r_alloc_in_use)
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
922 return (POINTER) sbrk (size);
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
923 #endif
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
924
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
925 if (size == 0)
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
926 return virtual_break_value;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
927
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
928 if (size > 0) /* Get more space */
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
929 {
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
930 register unsigned int space;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
931
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
932 if (pointer_list == REL_NIL)
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
933 {
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
934 POINTER space = get_more_space (size);
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
935
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
936 virtual_break_value = real_break_value;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
937 return space;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
938 }
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
939
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
940 new_zone = virtual_break_value;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
941
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
942 /* Check if there is a hole just before the buffer zone. */
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
943 if (holes && r_alloc_holes[0].address == virtual_break_value)
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
944 {
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
945 if (r_alloc_holes[0].size > size)
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
946 {
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
947 /* Adjust the hole size. */
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
948 r_alloc_holes[0].size -= size;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
949 r_alloc_holes[0].address += size;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
950 virtual_break_value += size;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
951
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
952 return new_zone;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
953 }
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
954
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
955 if (r_alloc_holes[0].size == size)
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
956 {
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
957 virtual_break_value += size;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
958 delete_hole (0);
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
959
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
960 return new_zone;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
961 }
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
962
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
963 /* Adjust the size requested by space
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
964 already available in this hole. */
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
965 size -= r_alloc_holes[0].size;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
966 virtual_break_value += r_alloc_holes[0].size;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
967 delete_hole (0);
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
968 }
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
969
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
970 space = relocate (size);
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
971 if (!space)
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
972 return (POINTER) -1;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
973
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
974 #ifdef REL_ALLOC_SAVE_SPACE
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
975 move_blocks_downward
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
976 #else
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
977 bzero (new_zone, space);
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
978 if (space > size)
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
979 note_hole (new_zone + size, space - size);
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
980 #endif /* REL_ALLOC_SAVE_SPACE */
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
981
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
982 virtual_break_value += size;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
983 return new_zone;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
984 }
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
985 else /* Return space to system */
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
986 {
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
987 int moved;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
988 int left_over;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
989 POINTER old_break_value;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
990
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
991 if (pointer_list == REL_NIL)
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
992 {
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
993 POINTER space = return_space (-size);
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
994 virtual_break_value = real_break_value;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
995
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
996 return space;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
997 }
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
998
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
999 if (holes && r_alloc_holes[0].address == virtual_break_value)
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
1000 {
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
1001 size -= r_alloc_holes[0].size;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
1002 delete_hole (0);
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
1003 }
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
1004
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
1005 moved = relocate (size);
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
1006 old_break_value = virtual_break_value;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
1007
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
1008 if (!moved)
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
1009 return (POINTER) -1;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
1010
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
1011 left_over = moved + size;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
1012 virtual_break_value += size;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
1013
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
1014 if (left_over)
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
1015 {
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
1016 #ifdef REL_ALLOC_SAVE_SPACE
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
1017 move_blocks_downward
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
1018 #else
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
1019 bzero (virtual_break_value, left_over);
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
1020 note_hole (virtual_break_value, left_over);
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
1021 #endif /* not REL_ALLOC_SAVE_SPACE */
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
1022 }
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
1023
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
1024 return old_break_value;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
1025 }
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
1026 }
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
1027
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
1028 /* For debugging */
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
1029
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
1030 #include <stdio.h>
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
1031
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
1032 void
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
1033 memory_trace ()
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
1034 {
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
1035 relocatable_pointer *ptr;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
1036 int i;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
1037
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
1038 fprintf (stderr, "virtual: 0x%x\n real: 0x%x\n true: 0x%x\n\n",
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
1039 virtual_break_value, real_break_value, true_break_value);
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
1040 fprintf (stderr, "Blocks:\n");
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
1041 for (ptr = pointer_list; ptr; ptr = ptr->next)
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
1042 {
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
1043 fprintf (stderr, " address: 0x%x\n", ptr->block);
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
1044 fprintf (stderr, " size: 0x%x\n", ptr->size);
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
1045 if (ptr->others)
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
1046 {
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
1047 struct other_pointer *op = ptr->others;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
1048 fprintf (stderr, " others:", ptr->size);
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
1049 while (op)
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
1050 {
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
1051 fprintf (stderr, " 0x%x", op->location);
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
1052 op = op->next;
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
1053 }
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
1054 fprintf (stderr, "\n");
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
1055 }
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
1056 }
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
1057
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
1058 if (holes)
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
1059 {
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
1060 fprintf (stderr, "\nHoles:\n");
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
1061 for (i = 0; i < holes; i++)
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
1062 {
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
1063 fprintf (stderr, " address: 0x%x\n", r_alloc_holes[i].address);
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
1064 fprintf (stderr, " size: 0x%x\n", r_alloc_holes[i].size);
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
1065 }
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
1066 }
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
1067
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
1068 fprintf (stderr, "\n\n");
c7c930b84dbb entered into RCS
Jim Blandy <jimb@redhat.com>
parents:
diff changeset
1069 }