Print this page
11972 resync smatch
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/tools/smatch/src/allocate.c
+++ new/usr/src/tools/smatch/src/allocate.c
1 1 /*
2 2 * allocate.c - simple space-efficient blob allocator.
3 3 *
4 4 * Copyright (C) 2003 Transmeta Corp.
5 5 * 2003-2004 Linus Torvalds
6 6 *
7 7 * Permission is hereby granted, free of charge, to any person obtaining a copy
8 8 * of this software and associated documentation files (the "Software"), to deal
9 9 * in the Software without restriction, including without limitation the rights
10 10 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 11 * copies of the Software, and to permit persons to whom the Software is
12 12 * furnished to do so, subject to the following conditions:
13 13 *
14 14 * The above copyright notice and this permission notice shall be included in
15 15 * all copies or substantial portions of the Software.
16 16 *
17 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 20 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23 23 * THE SOFTWARE.
24 24 *
25 25 * Simple allocator for data that doesn't get partially free'd.
26 26 * The tokenizer and parser allocate a _lot_ of small data structures
27 27 * (often just two-three bytes for things like small integers),
28 28 * and since they all depend on each other you can't free them
29 29 * individually _anyway_. So do something that is very space-
30 30 * efficient: allocate larger "blobs", and give out individual
31 31 * small bits and pieces of it with no maintenance overhead.
32 32 */
33 33 #include <stdlib.h>
34 34 #include <stddef.h>
35 35 #include <stdio.h>
36 36
37 37 #include "lib.h"
38 38 #include "allocate.h"
39 39 #include "compat.h"
40 40 #include "token.h"
41 41 #include "symbol.h"
42 42 #include "scope.h"
43 43 #include "expression.h"
44 44 #include "linearize.h"
45 45
46 46 void protect_allocations(struct allocator_struct *desc)
47 47 {
48 48 desc->blobs = NULL;
49 49 }
50 50
51 51 void drop_all_allocations(struct allocator_struct *desc)
52 52 {
53 53 struct allocation_blob *blob = desc->blobs;
54 54
55 55 desc->blobs = NULL;
56 56 desc->allocations = 0;
57 57 desc->total_bytes = 0;
58 58 desc->useful_bytes = 0;
59 59 desc->freelist = NULL;
60 60 while (blob) {
61 61 struct allocation_blob *next = blob->next;
62 62 blob_free(blob, desc->chunking);
63 63 blob = next;
64 64 }
65 65 }
66 66
67 67 void free_one_entry(struct allocator_struct *desc, void *entry)
68 68 {
69 69 void **p = entry;
70 70 *p = desc->freelist;
71 71 desc->freelist = p;
72 72 }
73 73
74 74 void *allocate(struct allocator_struct *desc, unsigned int size)
75 75 {
76 76 unsigned long alignment = desc->alignment;
77 77 struct allocation_blob *blob = desc->blobs;
78 78 void *retval;
79 79
80 80 /*
81 81 * NOTE! The freelist only works with things that are
82 82 * (a) sufficiently aligned
83 83 * (b) use a constant size
84 84 * Don't try to free allocators that don't follow
85 85 * these rules.
86 86 */
87 87 if (desc->freelist) {
88 88 void **p = desc->freelist;
89 89 retval = p;
90 90 desc->freelist = *p;
91 91 do {
92 92 *p = NULL;
93 93 p++;
94 94 } while ((size -= sizeof(void *)) > 0);
95 95 return retval;
↓ open down ↓ |
95 lines elided |
↑ open up ↑ |
96 96 }
97 97
98 98 desc->allocations++;
99 99 desc->useful_bytes += size;
100 100 size = (size + alignment - 1) & ~(alignment-1);
101 101 if (!blob || blob->left < size) {
102 102 unsigned int offset, chunking = desc->chunking;
103 103 struct allocation_blob *newblob = blob_alloc(chunking);
104 104 if (!newblob)
105 105 die("out of memory");
106 + if (size > chunking)
107 + die("alloc too big");
106 108 desc->total_bytes += chunking;
107 109 newblob->next = blob;
108 110 blob = newblob;
109 111 desc->blobs = newblob;
110 112 offset = offsetof(struct allocation_blob, data);
111 113 offset = (offset + alignment - 1) & ~(alignment-1);
112 114 blob->left = chunking - offset;
113 115 blob->offset = offset - offsetof(struct allocation_blob, data);
114 116 }
115 117 retval = blob->data + blob->offset;
116 118 blob->offset += size;
117 119 blob->left -= size;
118 120 return retval;
119 121 }
120 122
121 123 void show_allocations(struct allocator_struct *x)
122 124 {
123 125 fprintf(stderr, "%s: %lu allocations, %lu bytes (%lu total bytes, "
124 126 "%6.2f%% usage, %6.2f average size)\n",
125 127 x->name, x->allocations, x->useful_bytes, x->total_bytes,
126 128 100 * (double) x->useful_bytes / x->total_bytes,
127 129 (double) x->useful_bytes / x->allocations);
128 130 }
129 131
130 132 void get_allocator_stats(struct allocator_struct *x, struct allocator_stats *s)
131 133 {
132 134 s->name = x->name;
133 135 s->allocations = x->allocations;
134 136 s->useful_bytes = x->useful_bytes;
135 137 s->total_bytes = x->total_bytes;
136 138 }
137 139
138 140 ALLOCATOR(ident, "identifiers");
139 141 ALLOCATOR(token, "tokens");
140 142 ALLOCATOR(context, "contexts");
141 143 ALLOCATOR(symbol, "symbols");
142 144 ALLOCATOR(expression, "expressions");
143 145 ALLOCATOR(statement, "statements");
144 146 ALLOCATOR(string, "strings");
145 147 ALLOCATOR(scope, "scopes");
146 148 __DO_ALLOCATOR(void, 0, 1, "bytes", bytes);
147 149 ALLOCATOR(basic_block, "basic_block");
148 150 ALLOCATOR(entrypoint, "entrypoint");
149 151 ALLOCATOR(instruction, "instruction");
150 152 ALLOCATOR(multijmp, "multijmp");
151 153 ALLOCATOR(pseudo, "pseudo");
152 154
153 155
↓ open down ↓ |
38 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX