re PR tree-optimization/26830 (Repeated SSA update during loop header copying)
[gcc.git] / gcc / java / boehm.c
1 /* Functions related to the Boehm garbage collector.
2 Copyright (C) 2000, 2003, 2004, 2006 Free Software Foundation, Inc.
3
4 This file is part of GCC.
5
6 GCC is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10
11 GCC is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING. If not, write to
18 the Free Software Foundation, 51 Franklin Street, Fifth Floor,
19 Boston, MA 02110-1301, USA.
20
21 Java and all Java-based marks are trademarks or registered trademarks
22 of Sun Microsystems, Inc. in the United States and other countries.
23 The 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"
30 #include "coretypes.h"
31 #include "tm.h"
32 #include "tree.h"
33 #include "java-tree.h"
34 #include "parse.h"
35 #include "toplev.h"
36
37 static void mark_reference_fields (tree, unsigned HOST_WIDE_INT *,
38 unsigned HOST_WIDE_INT *, unsigned int,
39 int *, int *, int *, HOST_WIDE_INT *);
40 static void set_bit (unsigned HOST_WIDE_INT *, unsigned HOST_WIDE_INT *,
41 unsigned int);
42
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. */
45 static void
46 set_bit (unsigned HOST_WIDE_INT *low, unsigned HOST_WIDE_INT *high,
47 unsigned int n)
48 {
49 unsigned HOST_WIDE_INT *which;
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
59 *which |= (unsigned HOST_WIDE_INT) 1 << n;
60 }
61
62 /* Recursively mark reference fields. */
63 static void
64 mark_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)
72 {
73 /* See if we have fields from our superclass. */
74 if (DECL_NAME (field) == NULL_TREE)
75 {
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);
80 field = TREE_CHAIN (field);
81 }
82
83 for (; field != NULL_TREE; field = TREE_CHAIN (field))
84 {
85 HOST_WIDE_INT offset;
86 HOST_WIDE_INT size_bytes;
87
88 if (FIELD_STATIC (field))
89 continue;
90
91 offset = int_byte_position (field);
92 size_bytes = int_size_in_bytes (TREE_TYPE (field));
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)
97 {
98 unsigned int count;
99 unsigned int size_words;
100 unsigned int i;
101
102 /* If this reference slot appears to overlay a slot we think
103 we already covered, then we are doomed. */
104 gcc_assert (offset > *last_view_index);
105
106 count = offset * BITS_PER_UNIT / POINTER_SIZE;
107 size_words = size_bytes * BITS_PER_UNIT / POINTER_SIZE;
108
109 *last_set_index = count;
110
111 /* First word in object corresponds to most significant byte of
112 bitmap.
113
114 In the case of a multiple-word record, we set pointer
115 bits for all words in the record. This is conservative, but the
116 size_words != 1 case is impossible in regular java code. */
117 for (i = 0; i < size_words; ++i)
118 set_bit (low, high, ubit - count - i - 1);
119
120 if (count >= ubit - 2)
121 *pointer_after_end = 1;
122
123 /* If we saw a non-reference field earlier, then we can't
124 use the count representation. We keep track of that in
125 *ALL_BITS_SET. */
126 if (! *all_bits_set)
127 *all_bits_set = -1;
128 }
129 else if (*all_bits_set > 0)
130 *all_bits_set = 0;
131
132 *last_view_index = offset;
133 }
134 }
135
136 /* Return the marking bitmap for the class TYPE. For now this is a
137 single word describing the type. */
138 tree
139 get_boehm_type_descriptor (tree type)
140 {
141 unsigned int count, log2_size, ubit;
142 int bit;
143 int all_bits_set = 1;
144 int last_set_index = 0;
145 HOST_WIDE_INT last_view_index = -1;
146 int pointer_after_end = 0;
147 unsigned HOST_WIDE_INT low = 0, high = 0;
148 tree field, value, value_type;
149
150 /* If the GC wasn't requested, just use a null pointer. */
151 if (! flag_use_boehm_gc)
152 return null_pointer_node;
153
154 value_type = java_type_for_mode (ptr_mode, 1);
155 /* If we have a type of unknown size, use a proc. */
156 if (int_size_in_bytes (type) == -1)
157 goto procedure_object_descriptor;
158
159 bit = POINTER_SIZE / BITS_PER_UNIT;
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
176 if (type == class_type_node)
177 goto procedure_object_descriptor;
178
179 field = TYPE_FIELDS (type);
180 mark_reference_fields (field, &low, &high, ubit,
181 &pointer_after_end, &all_bits_set,
182 &last_set_index, &last_view_index);
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. */
187 if (all_bits_set != -1 || (pointer_after_end && flag_reduced_reflection))
188 {
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:
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
198 In the case of flag_reduced_reflection and the bitmap would
199 overflow, we tell the gc that the object is all pointers so
200 that we don't have to emit reflection data for run time
201 marking. */
202 count = 0;
203 low = 0;
204 high = 0;
205 ++last_set_index;
206 while (last_set_index)
207 {
208 if ((last_set_index & 1))
209 set_bit (&low, &high, log2_size + count);
210 last_set_index >>= 1;
211 ++count;
212 }
213 value = build_int_cst_wide (value_type, low, high);
214 }
215 else if (! pointer_after_end)
216 {
217 /* Bottom two bits for bitmap mark type are 01. */
218 set_bit (&low, &high, 0);
219 value = build_int_cst_wide (value_type, low, high);
220 }
221 else
222 {
223 /* Compute a procedure-based object descriptor. We know that our
224 `kind' is 0, and `env' is likewise 0, so we have a simple
225 computation. From the GC sources:
226 (((((env) << LOG_MAX_MARK_PROCS) | (proc_index)) << DS_TAG_BITS) \
227 | DS_PROC)
228 Here DS_PROC == 2. */
229 procedure_object_descriptor:
230 value = build_int_cst (value_type, 2);
231 }
232
233 return value;
234 }