]> gcc.gnu.org Git - gcc.git/blame - gcc/java/boehm.c
boehm.c (set_bit): Improve type safety wrt unsignedness.
[gcc.git] / gcc / java / boehm.c
CommitLineData
5830574a 1/* Functions related to the Boehm garbage collector.
f309ff0a 2 Copyright (C) 2000, 2003 Free Software Foundation, Inc.
5830574a 3
f309ff0a 4This file is part of GCC.
5830574a 5
f309ff0a 6GCC is free software; you can redistribute it and/or modify
5830574a
TT
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 2, or (at your option)
9any later version.
10
f309ff0a 11GCC is distributed in the hope that it will be useful,
5830574a
TT
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
f309ff0a 17along with GCC; see the file COPYING. If not, write to
5830574a
TT
18the Free Software Foundation, 59 Temple Place - Suite 330,
19Boston, MA 02111-1307, USA.
20
21Java and all Java-based marks are trademarks or registered trademarks
22of Sun Microsystems, Inc. in the United States and other countries.
23The Free Software Foundation is independent of Sun Microsystems, Inc. */
24
25/* Written by Tom Tromey <tromey@cygnus.com>. */
26
27#include <config.h>
28
29#include "system.h"
4977bab6
ZW
30#include "coretypes.h"
31#include "tm.h"
5830574a
TT
32#include "tree.h"
33#include "java-tree.h"
34#include "parse.h"
d6684bc8 35#include "toplev.h"
5830574a 36
d2097937
KG
37static void mark_reference_fields (tree, unsigned HOST_WIDE_INT *,
38 unsigned HOST_WIDE_INT *, unsigned int,
39 int *, int *, int *, HOST_WIDE_INT *);
40static void set_bit (unsigned HOST_WIDE_INT *, unsigned HOST_WIDE_INT *,
41 unsigned int);
c0b864fc 42
5830574a
TT
43/* Treat two HOST_WIDE_INT's as a contiguous bitmap, with bit 0 being
44 the least significant. This function sets bit N in the bitmap. */
45static void
0a2f0c54
KG
46set_bit (unsigned HOST_WIDE_INT *low, unsigned HOST_WIDE_INT *high,
47 unsigned int n)
5830574a 48{
0e7d217a 49 unsigned HOST_WIDE_INT *which;
5830574a
TT
50
51 if (n >= HOST_BITS_PER_WIDE_INT)
52 {
53 n -= HOST_BITS_PER_WIDE_INT;
54 which = high;
55 }
56 else
57 which = low;
58
0e7d217a 59 *which |= (unsigned HOST_WIDE_INT) 1 << n;
5830574a
TT
60}
61
2c6c322a 62/* Recursively mark reference fields. */
d5f76aba 63static void
0a2f0c54
KG
64mark_reference_fields (tree field,
65 unsigned HOST_WIDE_INT *low,
66 unsigned HOST_WIDE_INT *high,
67 unsigned int ubit,
68 int *pointer_after_end,
69 int *all_bits_set,
70 int *last_set_index,
71 HOST_WIDE_INT *last_view_index)
2c6c322a 72{
2c6c322a
TT
73 /* See if we have fields from our superclass. */
74 if (DECL_NAME (field) == NULL_TREE)
75 {
d5f76aba
TT
76 mark_reference_fields (TYPE_FIELDS (TREE_TYPE (field)),
77 low, high, ubit,
78 pointer_after_end, all_bits_set,
79 last_set_index, last_view_index);
2c6c322a
TT
80 field = TREE_CHAIN (field);
81 }
82
83 for (; field != NULL_TREE; field = TREE_CHAIN (field))
84 {
8a008c41 85 HOST_WIDE_INT offset;
7c097ee9 86 HOST_WIDE_INT size_bytes;
d5f76aba 87
2c6c322a
TT
88 if (FIELD_STATIC (field))
89 continue;
90
3c8c10b8 91 offset = int_byte_position (field);
7c097ee9 92 size_bytes = int_size_in_bytes (TREE_TYPE (field));
652f2504
TT
93 if (JREFERENCE_TYPE_P (TREE_TYPE (field))
94 /* An `object' of type gnu.gcj.RawData is actually non-Java
95 data. */
96 && TREE_TYPE (field) != rawdata_ptr_type_node)
2c6c322a 97 {
d5f76aba 98 unsigned int count;
7c097ee9
HB
99 unsigned int size_words;
100 unsigned int i;
d5f76aba
TT
101
102 /* If this reference slot appears to overlay a slot we think
103 we already covered, then we are doomed. */
104 if (offset <= *last_view_index)
105 abort ();
106
107 count = offset * BITS_PER_UNIT / POINTER_SIZE;
7c097ee9 108 size_words = size_bytes * BITS_PER_UNIT / POINTER_SIZE;
d5f76aba 109
2c6c322a 110 *last_set_index = count;
7c097ee9
HB
111
112 /* First word in object corresponds to most significant byte of
113 bitmap.
114
115 In the case of a multiple-word record, we set pointer
116 bits for all words in the record. This is conservative, but the
117 size_words != 1 case is impossible in regular java code. */
118 for (i = 0; i < size_words; ++i)
119 set_bit (low, high, ubit - count - i - 1);
120
e35990c4 121 if (count >= ubit - 2)
2c6c322a 122 *pointer_after_end = 1;
652f2504
TT
123
124 /* If we saw a non-reference field earlier, then we can't
125 use the count representation. We keep track of that in
126 *ALL_BITS_SET. */
127 if (! *all_bits_set)
128 *all_bits_set = -1;
2c6c322a 129 }
652f2504 130 else if (*all_bits_set > 0)
2c6c322a
TT
131 *all_bits_set = 0;
132
d5f76aba 133 *last_view_index = offset;
2c6c322a 134 }
2c6c322a
TT
135}
136
5830574a
TT
137/* Return the marking bitmap for the class TYPE. For now this is a
138 single word describing the type. */
139tree
140get_boehm_type_descriptor (tree type)
141{
142 unsigned int count, log2_size, ubit;
143 int bit;
144 int all_bits_set = 1;
145 int last_set_index = 0;
d5f76aba 146 HOST_WIDE_INT last_view_index = -1;
5830574a
TT
147 int pointer_after_end = 0;
148 unsigned HOST_WIDE_INT low = 0, high = 0;
149 tree field, value;
150
151 /* If the GC wasn't requested, just use a null pointer. */
152 if (! flag_use_boehm_gc)
153 return null_pointer_node;
154
155 /* If we have a type of unknown size, use a proc. */
156 if (int_size_in_bytes (type) == -1)
9a07cfaf 157 goto procedure_object_descriptor;
5830574a 158
2c6c322a 159 bit = POINTER_SIZE / BITS_PER_UNIT;
5830574a
TT
160 /* The size of this node has to be known. And, we only support 32
161 and 64 bit targets, so we need to know that the log2 is one of
162 our values. */
163 log2_size = exact_log2 (bit);
164 if (bit == -1 || (log2_size != 2 && log2_size != 3))
165 {
166 /* This means the GC isn't supported. We should probably
167 abort or give an error. Instead, for now, we just silently
168 revert. FIXME. */
169 return null_pointer_node;
170 }
171 bit *= BITS_PER_UNIT;
172
173 /* Warning avoidance. */
174 ubit = (unsigned int) bit;
175
7c097ee9 176 if (type == class_type_node)
9a07cfaf 177 goto procedure_object_descriptor;
7c097ee9 178
5830574a 179 field = TYPE_FIELDS (type);
d5f76aba
TT
180 mark_reference_fields (field, &low, &high, ubit,
181 &pointer_after_end, &all_bits_set,
182 &last_set_index, &last_view_index);
5830574a
TT
183
184 /* If the object is all pointers, or if the part with pointers fits
185 in our bitmap, then we are ok. Otherwise we have to allocate it
186 a different way. */
652f2504 187 if (all_bits_set != -1)
5830574a 188 {
652f2504
TT
189 /* In this case the initial part of the object is all reference
190 fields, and the end of the object is all non-reference
191 fields. We represent the mark as a count of the fields,
192 shifted. In the GC the computation looks something like
193 this:
5830574a
TT
194 value = DS_LENGTH | WORDS_TO_BYTES (last_set_index + 1);
195 DS_LENGTH is 0.
196 WORDS_TO_BYTES shifts by log2(bytes-per-pointer). */
197 count = 0;
2c6c322a
TT
198 low = 0;
199 high = 0;
5830574a
TT
200 ++last_set_index;
201 while (last_set_index)
202 {
203 if ((last_set_index & 1))
204 set_bit (&low, &high, log2_size + count);
205 last_set_index >>= 1;
206 ++count;
207 }
208 value = build_int_2 (low, high);
209 }
210 else if (! pointer_after_end)
211 {
212 /* Bottom two bits for bitmap mark type are 01. */
213 set_bit (&low, &high, 0);
214 value = build_int_2 (low, high);
215 }
216 else
9a07cfaf
RH
217 {
218 /* Compute a procedure-based object descriptor. We know that our
219 `kind' is 0, and `env' is likewise 0, so we have a simple
220 computation. From the GC sources:
221 (((((env) << LOG_MAX_MARK_PROCS) | (proc_index)) << DS_TAG_BITS) \
222 | DS_PROC)
223 Here DS_PROC == 2. */
224 procedure_object_descriptor:
225 value = build_int_2 (2, 0);
226 }
5830574a 227
b0c48229 228 TREE_TYPE (value) = java_type_for_mode (ptr_mode, 1);
5830574a
TT
229 return value;
230}
This page took 1.305677 seconds and 5 git commands to generate.