Remove old autovect-branch by moving to "dead" directory.
[official-gcc.git] / old-autovect-branch / gcc / java / boehm.c
bloba4ceea63e555f1412102c944e83209c316fd99e7
1 /* Functions related to the Boehm garbage collector.
2 Copyright (C) 2000, 2003, 2004 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)
9 any later version.
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, 51 Franklin Street, Fifth Floor,
19 Boston, MA 02110-1301, 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 "coretypes.h"
31 #include "tm.h"
32 #include "tree.h"
33 #include "java-tree.h"
34 #include "parse.h"
35 #include "toplev.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 *,
41 unsigned 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. */
45 static void
46 set_bit (unsigned HOST_WIDE_INT *low, unsigned HOST_WIDE_INT *high,
47 unsigned int n)
49 unsigned HOST_WIDE_INT *which;
51 if (n >= HOST_BITS_PER_WIDE_INT)
53 n -= HOST_BITS_PER_WIDE_INT;
54 which = high;
56 else
57 which = low;
59 *which |= (unsigned HOST_WIDE_INT) 1 << n;
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)
73 /* See if we have fields from our superclass. */
74 if (DECL_NAME (field) == NULL_TREE)
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);
83 for (; field != NULL_TREE; field = TREE_CHAIN (field))
85 HOST_WIDE_INT offset;
86 HOST_WIDE_INT size_bytes;
88 if (FIELD_STATIC (field))
89 continue;
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)
98 unsigned int count;
99 unsigned int size_words;
100 unsigned int i;
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 ();
107 count = offset * BITS_PER_UNIT / POINTER_SIZE;
108 size_words = size_bytes * BITS_PER_UNIT / POINTER_SIZE;
110 *last_set_index = count;
112 /* First word in object corresponds to most significant byte of
113 bitmap.
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);
121 if (count >= ubit - 2)
122 *pointer_after_end = 1;
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;
130 else if (*all_bits_set > 0)
131 *all_bits_set = 0;
133 *last_view_index = offset;
137 /* Return the marking bitmap for the class TYPE. For now this is a
138 single word describing the type. */
139 tree
140 get_boehm_type_descriptor (tree type)
142 unsigned int count, log2_size, ubit;
143 int bit;
144 int all_bits_set = 1;
145 int last_set_index = 0;
146 HOST_WIDE_INT last_view_index = -1;
147 int pointer_after_end = 0;
148 unsigned HOST_WIDE_INT low = 0, high = 0;
149 tree field, value, value_type;
151 /* If the GC wasn't requested, just use a null pointer. */
152 if (! flag_use_boehm_gc)
153 return null_pointer_node;
155 value_type = java_type_for_mode (ptr_mode, 1);
156 /* If we have a type of unknown size, use a proc. */
157 if (int_size_in_bytes (type) == -1)
158 goto procedure_object_descriptor;
160 bit = POINTER_SIZE / BITS_PER_UNIT;
161 /* The size of this node has to be known. And, we only support 32
162 and 64 bit targets, so we need to know that the log2 is one of
163 our values. */
164 log2_size = exact_log2 (bit);
165 if (bit == -1 || (log2_size != 2 && log2_size != 3))
167 /* This means the GC isn't supported. We should probably
168 abort or give an error. Instead, for now, we just silently
169 revert. FIXME. */
170 return null_pointer_node;
172 bit *= BITS_PER_UNIT;
174 /* Warning avoidance. */
175 ubit = (unsigned int) bit;
177 if (type == class_type_node)
178 goto procedure_object_descriptor;
180 field = TYPE_FIELDS (type);
181 mark_reference_fields (field, &low, &high, ubit,
182 &pointer_after_end, &all_bits_set,
183 &last_set_index, &last_view_index);
185 /* If the object is all pointers, or if the part with pointers fits
186 in our bitmap, then we are ok. Otherwise we have to allocate it
187 a different way. */
188 if (all_bits_set != -1)
190 /* In this case the initial part of the object is all reference
191 fields, and the end of the object is all non-reference
192 fields. We represent the mark as a count of the fields,
193 shifted. In the GC the computation looks something like
194 this:
195 value = DS_LENGTH | WORDS_TO_BYTES (last_set_index + 1);
196 DS_LENGTH is 0.
197 WORDS_TO_BYTES shifts by log2(bytes-per-pointer). */
198 count = 0;
199 low = 0;
200 high = 0;
201 ++last_set_index;
202 while (last_set_index)
204 if ((last_set_index & 1))
205 set_bit (&low, &high, log2_size + count);
206 last_set_index >>= 1;
207 ++count;
209 value = build_int_cst_wide (value_type, low, high);
211 else if (! pointer_after_end)
213 /* Bottom two bits for bitmap mark type are 01. */
214 set_bit (&low, &high, 0);
215 value = build_int_cst_wide (value_type, low, high);
217 else
219 /* Compute a procedure-based object descriptor. We know that our
220 `kind' is 0, and `env' is likewise 0, so we have a simple
221 computation. From the GC sources:
222 (((((env) << LOG_MAX_MARK_PROCS) | (proc_index)) << DS_TAG_BITS) \
223 | DS_PROC)
224 Here DS_PROC == 2. */
225 procedure_object_descriptor:
226 value = build_int_cst (value_type, 2);
229 return value;