OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [gdb-5.0/] [libiberty/] [objalloc.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 106 markom
/* objalloc.c -- routines to allocate memory for objects
2
   Copyright 1997 Free Software Foundation, Inc.
3
   Written by Ian Lance Taylor, Cygnus Solutions.
4
 
5
This program is free software; you can redistribute it and/or modify it
6
under the terms of the GNU General Public License as published by the
7
Free Software Foundation; either version 2, or (at your option) any
8
later version.
9
 
10
This program is distributed in the hope that it will be useful,
11
but WITHOUT ANY WARRANTY; without even the implied warranty of
12
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
GNU General Public License for more details.
14
 
15
You should have received a copy of the GNU General Public License
16
along with this program; if not, write to the Free Software
17
Foundation, 59 Temple Place - Suite 330,
18
Boston, MA 02111-1307, USA.  */
19
 
20
#include "ansidecl.h"
21
#include "objalloc.h"
22
 
23
/* Get a definition for NULL.  */
24
#include <stdio.h>
25
 
26
#if VMS
27
#include <stdlib.h>
28
#include <unixlib.h>
29
#else
30
 
31
#ifdef ANSI_PROTOTYPES
32
/* Get a definition for size_t.  */
33
#include <stddef.h>
34
#endif
35
 
36
/* For systems with larger pointers than ints, this must be declared.  */
37
extern PTR malloc PARAMS ((size_t));
38
extern void free PARAMS ((PTR));
39
#endif
40
 
41
/* These routines allocate space for an object.  Freeing allocated
42
   space may or may not free all more recently allocated space.
43
 
44
   We handle large and small allocation requests differently.  If we
45
   don't have enough space in the current block, and the allocation
46
   request is for more than 512 bytes, we simply pass it through to
47
   malloc.  */
48
 
49
/* The objalloc structure is defined in objalloc.h.  */
50
 
51
/* This structure appears at the start of each chunk.  */
52
 
53
struct objalloc_chunk
54
{
55
  /* Next chunk.  */
56
  struct objalloc_chunk *next;
57
  /* If this chunk contains large objects, this is the value of
58
     current_ptr when this chunk was allocated.  If this chunk
59
     contains small objects, this is NULL.  */
60
  char *current_ptr;
61
};
62
 
63
/* The aligned size of objalloc_chunk.  */
64
 
65
#define CHUNK_HEADER_SIZE                                       \
66
  ((sizeof (struct objalloc_chunk) + OBJALLOC_ALIGN - 1)        \
67
   &~ (OBJALLOC_ALIGN - 1))
68
 
69
/* We ask for this much memory each time we create a chunk which is to
70
   hold small objects.  */
71
 
72
#define CHUNK_SIZE (4096 - 32)
73
 
74
/* A request for this amount or more is just passed through to malloc.  */
75
 
76
#define BIG_REQUEST (512)
77
 
78
/* Create an objalloc structure.  */
79
 
80
struct objalloc *
81
objalloc_create ()
82
{
83
  struct objalloc *ret;
84
  struct objalloc_chunk *chunk;
85
 
86
  ret = (struct objalloc *) malloc (sizeof *ret);
87
  if (ret == NULL)
88
    return NULL;
89
 
90
  ret->chunks = (PTR) malloc (CHUNK_SIZE);
91
  if (ret->chunks == NULL)
92
    {
93
      free (ret);
94
      return NULL;
95
    }
96
 
97
  chunk = (struct objalloc_chunk *) ret->chunks;
98
  chunk->next = NULL;
99
  chunk->current_ptr = NULL;
100
 
101
  ret->current_ptr = (char *) chunk + CHUNK_HEADER_SIZE;
102
  ret->current_space = CHUNK_SIZE - CHUNK_HEADER_SIZE;
103
 
104
  return ret;
105
}
106
 
107
/* Allocate space from an objalloc structure.  */
108
 
109
PTR
110
_objalloc_alloc (o, len)
111
     struct objalloc *o;
112
     unsigned long len;
113
{
114
  /* We avoid confusion from zero sized objects by always allocating
115
     at least 1 byte.  */
116
  if (len == 0)
117
    len = 1;
118
 
119
  len = (len + OBJALLOC_ALIGN - 1) &~ (OBJALLOC_ALIGN - 1);
120
 
121
  if (len <= o->current_space)
122
    {
123
      o->current_ptr += len;
124
      o->current_space -= len;
125
      return (PTR) (o->current_ptr - len);
126
    }
127
 
128
  if (len >= BIG_REQUEST)
129
    {
130
      char *ret;
131
      struct objalloc_chunk *chunk;
132
 
133
      ret = (char *) malloc (CHUNK_HEADER_SIZE + len);
134
      if (ret == NULL)
135
        return NULL;
136
 
137
      chunk = (struct objalloc_chunk *) ret;
138
      chunk->next = (struct objalloc_chunk *) o->chunks;
139
      chunk->current_ptr = o->current_ptr;
140
 
141
      o->chunks = (PTR) chunk;
142
 
143
      return (PTR) (ret + CHUNK_HEADER_SIZE);
144
    }
145
  else
146
    {
147
      struct objalloc_chunk *chunk;
148
 
149
      chunk = (struct objalloc_chunk *) malloc (CHUNK_SIZE);
150
      if (chunk == NULL)
151
        return NULL;
152
      chunk->next = (struct objalloc_chunk *) o->chunks;
153
      chunk->current_ptr = NULL;
154
 
155
      o->current_ptr = (char *) chunk + CHUNK_HEADER_SIZE;
156
      o->current_space = CHUNK_SIZE - CHUNK_HEADER_SIZE;
157
 
158
      o->chunks = (PTR) chunk;
159
 
160
      return objalloc_alloc (o, len);
161
    }
162
}
163
 
164
/* Free an entire objalloc structure.  */
165
 
166
void
167
objalloc_free (o)
168
     struct objalloc *o;
169
{
170
  struct objalloc_chunk *l;
171
 
172
  l = (struct objalloc_chunk *) o->chunks;
173
  while (l != NULL)
174
    {
175
      struct objalloc_chunk *next;
176
 
177
      next = l->next;
178
      free (l);
179
      l = next;
180
    }
181
 
182
  free (o);
183
}
184
 
185
/* Free a block from an objalloc structure.  This also frees all more
186
   recently allocated blocks.  */
187
 
188
void
189
objalloc_free_block (o, block)
190
     struct objalloc *o;
191
     PTR block;
192
{
193
  struct objalloc_chunk *p, *small;
194
  char *b = (char *) block;
195
 
196
  /* First set P to the chunk which contains the block we are freeing,
197
     and set Q to the last small object chunk we see before P.  */
198
  small = NULL;
199
  for (p = (struct objalloc_chunk *) o->chunks; p != NULL; p = p->next)
200
    {
201
      if (p->current_ptr == NULL)
202
        {
203
          if (b > (char *) p && b < (char *) p + CHUNK_SIZE)
204
            break;
205
          small = p;
206
        }
207
      else
208
        {
209
          if (b == (char *) p + CHUNK_HEADER_SIZE)
210
            break;
211
        }
212
    }
213
 
214
  /* If we can't find the chunk, the caller has made a mistake.  */
215
  if (p == NULL)
216
    abort ();
217
 
218
  if (p->current_ptr == NULL)
219
    {
220
      struct objalloc_chunk *q;
221
      struct objalloc_chunk *first;
222
 
223
      /* The block is in a chunk containing small objects.  We can
224
         free every chunk through SMALL, because they have certainly
225
         been allocated more recently.  After SMALL, we will not see
226
         any chunks containing small objects; we can free any big
227
         chunk if the current_ptr is greater than or equal to B.  We
228
         can then reset the new current_ptr to B.  */
229
 
230
      first = NULL;
231
      q = (struct objalloc_chunk *) o->chunks;
232
      while (q != p)
233
        {
234
          struct objalloc_chunk *next;
235
 
236
          next = q->next;
237
          if (small != NULL)
238
            {
239
              if (small == q)
240
                small = NULL;
241
              free (q);
242
            }
243
          else if (q->current_ptr > b)
244
            free (q);
245
          else if (first == NULL)
246
            first = q;
247
 
248
          q = next;
249
        }
250
 
251
      if (first == NULL)
252
        first = p;
253
      o->chunks = (PTR) first;
254
 
255
      /* Now start allocating from this small block again.  */
256
      o->current_ptr = b;
257
      o->current_space = ((char *) p + CHUNK_SIZE) - b;
258
    }
259
  else
260
    {
261
      struct objalloc_chunk *q;
262
      char *current_ptr;
263
 
264
      /* This block is in a large chunk by itself.  We can free
265
         everything on the list up to and including this block.  We
266
         then start allocating from the next chunk containing small
267
         objects, setting current_ptr from the value stored with the
268
         large chunk we are freeing.  */
269
 
270
      current_ptr = p->current_ptr;
271
      p = p->next;
272
 
273
      q = (struct objalloc_chunk *) o->chunks;
274
      while (q != p)
275
        {
276
          struct objalloc_chunk *next;
277
 
278
          next = q->next;
279
          free (q);
280
          q = next;
281
        }
282
 
283
      o->chunks = (PTR) p;
284
 
285
      while (p->current_ptr != NULL)
286
        p = p->next;
287
 
288
      o->current_ptr = current_ptr;
289
      o->current_space = ((char *) p + CHUNK_SIZE) - current_ptr;
290
    }
291
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.