* Makefile.in (ifcvt.o): Depend on toplev.h.
[official-gcc.git] / gcc / java / boehm.c
blobe92b4402b3803902fbbb0d2e3ca0eda555470b02
1 /* Functions related to the Boehm garbage collector.
2 Copyright (C) 2000 Free Software Foundation, Inc.
4 This file is part of GNU CC.
6 GNU CC 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.
11 GNU CC 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.
16 You should have received a copy of the GNU General Public License
17 along with GNU CC; see the file COPYING. If not, write to
18 the Free Software Foundation, 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA.
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. */
25 /* Written by Tom Tromey <tromey@cygnus.com>. */
27 #include <config.h>
29 #include "system.h"
30 #include "tree.h"
31 #include "java-tree.h"
32 #include "parse.h"
33 #include "toplev.h"
35 static void mark_reference_fields PARAMS ((tree,
36 unsigned HOST_WIDE_INT *,
37 unsigned HOST_WIDE_INT *,
38 unsigned int,
39 int *, int *,
40 int *,
41 HOST_WIDE_INT *));
42 static void set_bit PARAMS ((unsigned HOST_WIDE_INT *,
43 unsigned HOST_WIDE_INT *,
44 unsigned int));
46 /* Compute a procedure-based object descriptor. We know that our
47 `kind' is 0, and `env' is likewise 0, so we have a simple
48 computation. From the GC sources:
49 (((((env) << LOG_MAX_MARK_PROCS) | (proc_index)) << DS_TAG_BITS) \
50 | DS_PROC)
51 Here DS_PROC == 2. */
52 #define PROCEDURE_OBJECT_DESCRIPTOR build_int_2 (2, 0)
54 /* Treat two HOST_WIDE_INT's as a contiguous bitmap, with bit 0 being
55 the least significant. This function sets bit N in the bitmap. */
56 static void
57 set_bit (low, high, n)
58 unsigned HOST_WIDE_INT *low, *high;
59 unsigned int n;
61 HOST_WIDE_INT *which;
63 if (n >= HOST_BITS_PER_WIDE_INT)
65 n -= HOST_BITS_PER_WIDE_INT;
66 which = high;
68 else
69 which = low;
71 *which |= (HOST_WIDE_INT) 1 << n;
74 /* Recursively mark reference fields. */
75 static void
76 mark_reference_fields (field, low, high, ubit,
77 pointer_after_end, all_bits_set,
78 last_set_index, last_view_index)
79 tree field;
80 unsigned HOST_WIDE_INT *low, *high;
81 unsigned int ubit;
82 int *pointer_after_end, *all_bits_set;
83 int *last_set_index;
84 HOST_WIDE_INT *last_view_index;
86 /* See if we have fields from our superclass. */
87 if (DECL_NAME (field) == NULL_TREE)
89 mark_reference_fields (TYPE_FIELDS (TREE_TYPE (field)),
90 low, high, ubit,
91 pointer_after_end, all_bits_set,
92 last_set_index, last_view_index);
93 field = TREE_CHAIN (field);
96 for (; field != NULL_TREE; field = TREE_CHAIN (field))
98 HOST_WIDE_INT offset;
99 HOST_WIDE_INT size_bytes;
101 if (FIELD_STATIC (field))
102 continue;
104 offset = int_byte_position (field);
105 size_bytes = int_size_in_bytes (TREE_TYPE (field));
106 if (JREFERENCE_TYPE_P (TREE_TYPE (field))
107 /* An `object' of type gnu.gcj.RawData is actually non-Java
108 data. */
109 && TREE_TYPE (field) != rawdata_ptr_type_node)
111 unsigned int count;
112 unsigned int size_words;
113 unsigned int i;
115 /* If this reference slot appears to overlay a slot we think
116 we already covered, then we are doomed. */
117 if (offset <= *last_view_index)
118 abort ();
120 count = offset * BITS_PER_UNIT / POINTER_SIZE;
121 size_words = size_bytes * BITS_PER_UNIT / POINTER_SIZE;
123 *last_set_index = count;
125 /* First word in object corresponds to most significant byte of
126 bitmap.
128 In the case of a multiple-word record, we set pointer
129 bits for all words in the record. This is conservative, but the
130 size_words != 1 case is impossible in regular java code. */
131 for (i = 0; i < size_words; ++i)
132 set_bit (low, high, ubit - count - i - 1);
134 if (count >= ubit - 2)
135 *pointer_after_end = 1;
137 /* If we saw a non-reference field earlier, then we can't
138 use the count representation. We keep track of that in
139 *ALL_BITS_SET. */
140 if (! *all_bits_set)
141 *all_bits_set = -1;
143 else if (*all_bits_set > 0)
144 *all_bits_set = 0;
146 *last_view_index = offset;
150 /* Return the marking bitmap for the class TYPE. For now this is a
151 single word describing the type. */
152 tree
153 get_boehm_type_descriptor (tree type)
155 unsigned int count, log2_size, ubit;
156 int bit;
157 int all_bits_set = 1;
158 int last_set_index = 0;
159 HOST_WIDE_INT last_view_index = -1;
160 int pointer_after_end = 0;
161 unsigned HOST_WIDE_INT low = 0, high = 0;
162 tree field, value;
164 /* If the GC wasn't requested, just use a null pointer. */
165 if (! flag_use_boehm_gc)
166 return null_pointer_node;
168 /* If we have a type of unknown size, use a proc. */
169 if (int_size_in_bytes (type) == -1)
170 return PROCEDURE_OBJECT_DESCRIPTOR;
172 bit = POINTER_SIZE / BITS_PER_UNIT;
173 /* The size of this node has to be known. And, we only support 32
174 and 64 bit targets, so we need to know that the log2 is one of
175 our values. */
176 log2_size = exact_log2 (bit);
177 if (bit == -1 || (log2_size != 2 && log2_size != 3))
179 /* This means the GC isn't supported. We should probably
180 abort or give an error. Instead, for now, we just silently
181 revert. FIXME. */
182 return null_pointer_node;
184 bit *= BITS_PER_UNIT;
186 /* Warning avoidance. */
187 ubit = (unsigned int) bit;
189 if (type == class_type_node)
190 return PROCEDURE_OBJECT_DESCRIPTOR;
192 field = TYPE_FIELDS (type);
193 mark_reference_fields (field, &low, &high, ubit,
194 &pointer_after_end, &all_bits_set,
195 &last_set_index, &last_view_index);
197 /* If the object is all pointers, or if the part with pointers fits
198 in our bitmap, then we are ok. Otherwise we have to allocate it
199 a different way. */
200 if (all_bits_set != -1)
202 /* In this case the initial part of the object is all reference
203 fields, and the end of the object is all non-reference
204 fields. We represent the mark as a count of the fields,
205 shifted. In the GC the computation looks something like
206 this:
207 value = DS_LENGTH | WORDS_TO_BYTES (last_set_index + 1);
208 DS_LENGTH is 0.
209 WORDS_TO_BYTES shifts by log2(bytes-per-pointer). */
210 count = 0;
211 low = 0;
212 high = 0;
213 ++last_set_index;
214 while (last_set_index)
216 if ((last_set_index & 1))
217 set_bit (&low, &high, log2_size + count);
218 last_set_index >>= 1;
219 ++count;
221 value = build_int_2 (low, high);
223 else if (! pointer_after_end)
225 /* Bottom two bits for bitmap mark type are 01. */
226 set_bit (&low, &high, 0);
227 value = build_int_2 (low, high);
229 else
230 value = PROCEDURE_OBJECT_DESCRIPTOR;
232 TREE_TYPE (value) = type_for_mode (ptr_mode, 1);
233 return value;