]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/java/boehm.c
Merge basic-improvements-branch to trunk
[thirdparty/gcc.git] / gcc / java / boehm.c
CommitLineData
4576deab 1/* Functions related to the Boehm garbage collector.
2 Copyright (C) 2000 Free Software Foundation, Inc.
3
4This file is part of GNU CC.
5
6GNU CC is free software; you can redistribute it and/or modify
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
11GNU CC is distributed in the hope that it will be useful,
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
17along with GNU CC; see the file COPYING. If not, write to
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"
805e22b2 30#include "coretypes.h"
31#include "tm.h"
4576deab 32#include "tree.h"
33#include "java-tree.h"
34#include "parse.h"
2ade676b 35#include "toplev.h"
4576deab 36
7e263192 37static void mark_reference_fields PARAMS ((tree,
38 unsigned HOST_WIDE_INT *,
39 unsigned HOST_WIDE_INT *,
40 unsigned int,
41 int *, int *,
42 int *,
43 HOST_WIDE_INT *));
d7739d8e 44static void set_bit PARAMS ((unsigned HOST_WIDE_INT *,
45 unsigned HOST_WIDE_INT *,
46 unsigned int));
47
4576deab 48/* Treat two HOST_WIDE_INT's as a contiguous bitmap, with bit 0 being
49 the least significant. This function sets bit N in the bitmap. */
50static void
d7739d8e 51set_bit (low, high, n)
52 unsigned HOST_WIDE_INT *low, *high;
53 unsigned int n;
4576deab 54{
55 HOST_WIDE_INT *which;
56
57 if (n >= HOST_BITS_PER_WIDE_INT)
58 {
59 n -= HOST_BITS_PER_WIDE_INT;
60 which = high;
61 }
62 else
63 which = low;
64
65 *which |= (HOST_WIDE_INT) 1 << n;
66}
67
61cac2b4 68/* Recursively mark reference fields. */
7e263192 69static void
61cac2b4 70mark_reference_fields (field, low, high, ubit,
7e263192 71 pointer_after_end, all_bits_set,
72 last_set_index, last_view_index)
61cac2b4 73 tree field;
74 unsigned HOST_WIDE_INT *low, *high;
75 unsigned int ubit;
7e263192 76 int *pointer_after_end, *all_bits_set;
77 int *last_set_index;
78 HOST_WIDE_INT *last_view_index;
61cac2b4 79{
61cac2b4 80 /* See if we have fields from our superclass. */
81 if (DECL_NAME (field) == NULL_TREE)
82 {
7e263192 83 mark_reference_fields (TYPE_FIELDS (TREE_TYPE (field)),
84 low, high, ubit,
85 pointer_after_end, all_bits_set,
86 last_set_index, last_view_index);
61cac2b4 87 field = TREE_CHAIN (field);
88 }
89
90 for (; field != NULL_TREE; field = TREE_CHAIN (field))
91 {
eccca0e0 92 HOST_WIDE_INT offset;
64aa5c15 93 HOST_WIDE_INT size_bytes;
7e263192 94
61cac2b4 95 if (FIELD_STATIC (field))
96 continue;
97
99c7b888 98 offset = int_byte_position (field);
64aa5c15 99 size_bytes = int_size_in_bytes (TREE_TYPE (field));
9d45d2f2 100 if (JREFERENCE_TYPE_P (TREE_TYPE (field))
101 /* An `object' of type gnu.gcj.RawData is actually non-Java
102 data. */
103 && TREE_TYPE (field) != rawdata_ptr_type_node)
61cac2b4 104 {
7e263192 105 unsigned int count;
64aa5c15 106 unsigned int size_words;
107 unsigned int i;
7e263192 108
109 /* If this reference slot appears to overlay a slot we think
110 we already covered, then we are doomed. */
111 if (offset <= *last_view_index)
112 abort ();
113
114 count = offset * BITS_PER_UNIT / POINTER_SIZE;
64aa5c15 115 size_words = size_bytes * BITS_PER_UNIT / POINTER_SIZE;
7e263192 116
61cac2b4 117 *last_set_index = count;
64aa5c15 118
119 /* First word in object corresponds to most significant byte of
120 bitmap.
121
122 In the case of a multiple-word record, we set pointer
123 bits for all words in the record. This is conservative, but the
124 size_words != 1 case is impossible in regular java code. */
125 for (i = 0; i < size_words; ++i)
126 set_bit (low, high, ubit - count - i - 1);
127
d189542b 128 if (count >= ubit - 2)
61cac2b4 129 *pointer_after_end = 1;
9d45d2f2 130
131 /* If we saw a non-reference field earlier, then we can't
132 use the count representation. We keep track of that in
133 *ALL_BITS_SET. */
134 if (! *all_bits_set)
135 *all_bits_set = -1;
61cac2b4 136 }
9d45d2f2 137 else if (*all_bits_set > 0)
61cac2b4 138 *all_bits_set = 0;
139
7e263192 140 *last_view_index = offset;
61cac2b4 141 }
61cac2b4 142}
143
4576deab 144/* Return the marking bitmap for the class TYPE. For now this is a
145 single word describing the type. */
146tree
147get_boehm_type_descriptor (tree type)
148{
149 unsigned int count, log2_size, ubit;
150 int bit;
151 int all_bits_set = 1;
152 int last_set_index = 0;
7e263192 153 HOST_WIDE_INT last_view_index = -1;
4576deab 154 int pointer_after_end = 0;
155 unsigned HOST_WIDE_INT low = 0, high = 0;
156 tree field, value;
157
158 /* If the GC wasn't requested, just use a null pointer. */
159 if (! flag_use_boehm_gc)
160 return null_pointer_node;
161
162 /* If we have a type of unknown size, use a proc. */
163 if (int_size_in_bytes (type) == -1)
7e7c835c 164 goto procedure_object_descriptor;
4576deab 165
61cac2b4 166 bit = POINTER_SIZE / BITS_PER_UNIT;
4576deab 167 /* The size of this node has to be known. And, we only support 32
168 and 64 bit targets, so we need to know that the log2 is one of
169 our values. */
170 log2_size = exact_log2 (bit);
171 if (bit == -1 || (log2_size != 2 && log2_size != 3))
172 {
173 /* This means the GC isn't supported. We should probably
174 abort or give an error. Instead, for now, we just silently
175 revert. FIXME. */
176 return null_pointer_node;
177 }
178 bit *= BITS_PER_UNIT;
179
180 /* Warning avoidance. */
181 ubit = (unsigned int) bit;
182
64aa5c15 183 if (type == class_type_node)
7e7c835c 184 goto procedure_object_descriptor;
64aa5c15 185
4576deab 186 field = TYPE_FIELDS (type);
7e263192 187 mark_reference_fields (field, &low, &high, ubit,
188 &pointer_after_end, &all_bits_set,
189 &last_set_index, &last_view_index);
4576deab 190
191 /* If the object is all pointers, or if the part with pointers fits
192 in our bitmap, then we are ok. Otherwise we have to allocate it
193 a different way. */
9d45d2f2 194 if (all_bits_set != -1)
4576deab 195 {
9d45d2f2 196 /* In this case the initial part of the object is all reference
197 fields, and the end of the object is all non-reference
198 fields. We represent the mark as a count of the fields,
199 shifted. In the GC the computation looks something like
200 this:
4576deab 201 value = DS_LENGTH | WORDS_TO_BYTES (last_set_index + 1);
202 DS_LENGTH is 0.
203 WORDS_TO_BYTES shifts by log2(bytes-per-pointer). */
204 count = 0;
61cac2b4 205 low = 0;
206 high = 0;
4576deab 207 ++last_set_index;
208 while (last_set_index)
209 {
210 if ((last_set_index & 1))
211 set_bit (&low, &high, log2_size + count);
212 last_set_index >>= 1;
213 ++count;
214 }
215 value = build_int_2 (low, high);
216 }
217 else if (! pointer_after_end)
218 {
219 /* Bottom two bits for bitmap mark type are 01. */
220 set_bit (&low, &high, 0);
221 value = build_int_2 (low, high);
222 }
223 else
7e7c835c 224 {
225 /* Compute a procedure-based object descriptor. We know that our
226 `kind' is 0, and `env' is likewise 0, so we have a simple
227 computation. From the GC sources:
228 (((((env) << LOG_MAX_MARK_PROCS) | (proc_index)) << DS_TAG_BITS) \
229 | DS_PROC)
230 Here DS_PROC == 2. */
231 procedure_object_descriptor:
232 value = build_int_2 (2, 0);
233 }
4576deab 234
771d21fa 235 TREE_TYPE (value) = java_type_for_mode (ptr_mode, 1);
4576deab 236 return value;
237}