1 /* Functions related to the Boehm garbage collector.
2 Copyright (C) 2000, 2003 Free Software Foundation, Inc.
4 This file is part of GCC.
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)
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.
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, 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>. */
30 #include "coretypes.h"
33 #include "java-tree.h"
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 *,
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. */
46 set_bit (low, high, n)
47 unsigned HOST_WIDE_INT *low, *high;
52 if (n >= HOST_BITS_PER_WIDE_INT)
54 n -= HOST_BITS_PER_WIDE_INT;
60 *which |= (HOST_WIDE_INT) 1 << n;
63 /* Recursively mark reference fields. */
65 mark_reference_fields (field, low, high, ubit,
66 pointer_after_end, all_bits_set,
67 last_set_index, last_view_index)
69 unsigned HOST_WIDE_INT *low, *high;
71 int *pointer_after_end, *all_bits_set;
73 HOST_WIDE_INT *last_view_index;
75 /* See if we have fields from our superclass. */
76 if (DECL_NAME (field) == NULL_TREE)
78 mark_reference_fields (TYPE_FIELDS (TREE_TYPE (field)),
80 pointer_after_end, all_bits_set,
81 last_set_index, last_view_index);
82 field = TREE_CHAIN (field);
85 for (; field != NULL_TREE; field = TREE_CHAIN (field))
88 HOST_WIDE_INT size_bytes;
90 if (FIELD_STATIC (field))
93 offset = int_byte_position (field);
94 size_bytes = int_size_in_bytes (TREE_TYPE (field));
95 if (JREFERENCE_TYPE_P (TREE_TYPE (field))
96 /* An `object' of type gnu.gcj.RawData is actually non-Java
98 && TREE_TYPE (field) != rawdata_ptr_type_node)
101 unsigned int size_words;
104 /* If this reference slot appears to overlay a slot we think
105 we already covered, then we are doomed. */
106 if (offset <= *last_view_index)
109 count = offset * BITS_PER_UNIT / POINTER_SIZE;
110 size_words = size_bytes * BITS_PER_UNIT / POINTER_SIZE;
112 *last_set_index = count;
114 /* First word in object corresponds to most significant byte of
117 In the case of a multiple-word record, we set pointer
118 bits for all words in the record. This is conservative, but the
119 size_words != 1 case is impossible in regular java code. */
120 for (i = 0; i < size_words; ++i)
121 set_bit (low, high, ubit - count - i - 1);
123 if (count >= ubit - 2)
124 *pointer_after_end = 1;
126 /* If we saw a non-reference field earlier, then we can't
127 use the count representation. We keep track of that in
132 else if (*all_bits_set > 0)
135 *last_view_index = offset;
139 /* Return the marking bitmap for the class TYPE. For now this is a
140 single word describing the type. */
142 get_boehm_type_descriptor (tree type)
144 unsigned int count, log2_size, ubit;
146 int all_bits_set = 1;
147 int last_set_index = 0;
148 HOST_WIDE_INT last_view_index = -1;
149 int pointer_after_end = 0;
150 unsigned HOST_WIDE_INT low = 0, high = 0;
153 /* If the GC wasn't requested, just use a null pointer. */
154 if (! flag_use_boehm_gc)
155 return null_pointer_node;
157 /* If we have a type of unknown size, use a proc. */
158 if (int_size_in_bytes (type) == -1)
159 goto procedure_object_descriptor;
161 bit = POINTER_SIZE / BITS_PER_UNIT;
162 /* The size of this node has to be known. And, we only support 32
163 and 64 bit targets, so we need to know that the log2 is one of
165 log2_size = exact_log2 (bit);
166 if (bit == -1 || (log2_size != 2 && log2_size != 3))
168 /* This means the GC isn't supported. We should probably
169 abort or give an error. Instead, for now, we just silently
171 return null_pointer_node;
173 bit *= BITS_PER_UNIT;
175 /* Warning avoidance. */
176 ubit = (unsigned int) bit;
178 if (type == class_type_node)
179 goto procedure_object_descriptor;
181 field = TYPE_FIELDS (type);
182 mark_reference_fields (field, &low, &high, ubit,
183 &pointer_after_end, &all_bits_set,
184 &last_set_index, &last_view_index);
186 /* If the object is all pointers, or if the part with pointers fits
187 in our bitmap, then we are ok. Otherwise we have to allocate it
189 if (all_bits_set != -1)
191 /* In this case the initial part of the object is all reference
192 fields, and the end of the object is all non-reference
193 fields. We represent the mark as a count of the fields,
194 shifted. In the GC the computation looks something like
196 value = DS_LENGTH | WORDS_TO_BYTES (last_set_index + 1);
198 WORDS_TO_BYTES shifts by log2(bytes-per-pointer). */
203 while (last_set_index)
205 if ((last_set_index & 1))
206 set_bit (&low, &high, log2_size + count);
207 last_set_index >>= 1;
210 value = build_int_2 (low, high);
212 else if (! pointer_after_end)
214 /* Bottom two bits for bitmap mark type are 01. */
215 set_bit (&low, &high, 0);
216 value = build_int_2 (low, high);
220 /* Compute a procedure-based object descriptor. We know that our
221 `kind' is 0, and `env' is likewise 0, so we have a simple
222 computation. From the GC sources:
223 (((((env) << LOG_MAX_MARK_PROCS) | (proc_index)) << DS_TAG_BITS) \
225 Here DS_PROC == 2. */
226 procedure_object_descriptor:
227 value = build_int_2 (2, 0);
230 TREE_TYPE (value) = java_type_for_mode (ptr_mode, 1);