annotate src/=old-ralloc.c @ 8275:4fdf77f4e45c

type-break-mode: New variable and function. type-break-interval: Increase default to 1 hour. type-break-query-interval: Variable renamed from type-break-delay-interval. type-break-keystroke-interval: Variable deleted. type-break-keystroke-threshold: New variable. type-break-demo-life: Function renamed from type-break-life. type-break-demo-hanoi: Function renamed from type-break-hanoi. type-break-alarm-p: Variable renamed from type-break-p. type-break: Don't query. type-break-query: (New function) query here. type-break-check: Call type-break-query, not type-break. Do nothing if type-break-mode is nil. Increment type-break-keystroke-count with the length of this-command-keys, not just 1. Query for break when keystroke count exceeds cdr of keystroke threshold variable. Query for break after an alarm only if keystroke count exceeds car of keystroke threshold variable. type-break-select: Function deleted. type-break: Move that code here. type-break-cancel-schedule: Function renamed from cancel-type-break. Reset type-break-alarm-p. type-break-alarm: Function renamed from type-break-soon. (top level): Call type-break-mode; don't set up hook explicitly.
author Noah Friedman <friedman@splode.com>
date Mon, 18 Jul 1994 07:37:18 +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 }