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)
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>. */
31 #include "java-tree.h"
34 static void mark_reference_fields PARAMS ((tree,
35 unsigned HOST_WIDE_INT *,
36 unsigned HOST_WIDE_INT *,
41 static void set_bit PARAMS ((unsigned HOST_WIDE_INT *,
42 unsigned HOST_WIDE_INT *,
45 /* Compute a procedure-based object descriptor. We know that our
46 `kind' is 0, and `env' is likewise 0, so we have a simple
47 computation. From the GC sources:
48 (((((env) << LOG_MAX_MARK_PROCS) | (proc_index)) << DS_TAG_BITS) \
51 #define PROCEDURE_OBJECT_DESCRIPTOR integer_two_node
53 /* Treat two HOST_WIDE_INT's as a contiguous bitmap, with bit 0 being
54 the least significant. This function sets bit N in the bitmap. */
56 set_bit (low, high, n)
57 unsigned HOST_WIDE_INT *low, *high;
62 if (n >= HOST_BITS_PER_WIDE_INT)
64 n -= HOST_BITS_PER_WIDE_INT;
70 *which |= (HOST_WIDE_INT) 1 << n;
73 /* Recursively mark reference fields. */
75 mark_reference_fields (field, low, high, ubit,
76 pointer_after_end, all_bits_set,
77 last_set_index, last_view_index)
79 unsigned HOST_WIDE_INT *low, *high;
81 int *pointer_after_end, *all_bits_set;
83 HOST_WIDE_INT *last_view_index;
85 /* See if we have fields from our superclass. */
86 if (DECL_NAME (field) == NULL_TREE)
88 mark_reference_fields (TYPE_FIELDS (TREE_TYPE (field)),
90 pointer_after_end, all_bits_set,
91 last_set_index, last_view_index);
92 field = TREE_CHAIN (field);
95 for (; field != NULL_TREE; field = TREE_CHAIN (field))
97 HOST_WIDE_INT offset = tree_low_cst (byte_position (field), 1);
99 if (FIELD_STATIC (field))
102 if (JREFERENCE_TYPE_P (TREE_TYPE (field)))
106 /* If this reference slot appears to overlay a slot we think
107 we already covered, then we are doomed. */
108 if (offset <= *last_view_index)
111 count = offset * BITS_PER_UNIT / POINTER_SIZE;
113 *last_set_index = count;
114 /* First word in object corresponds to most significant byte
116 set_bit (low, high, ubit - count - 1);
117 if (count > ubit - 2)
118 *pointer_after_end = 1;
123 *last_view_index = offset;
127 /* Return the marking bitmap for the class TYPE. For now this is a
128 single word describing the type. */
130 get_boehm_type_descriptor (tree type)
132 unsigned int count, log2_size, ubit;
134 int all_bits_set = 1;
135 int last_set_index = 0;
136 HOST_WIDE_INT last_view_index = -1;
137 int pointer_after_end = 0;
138 unsigned HOST_WIDE_INT low = 0, high = 0;
141 /* If the GC wasn't requested, just use a null pointer. */
142 if (! flag_use_boehm_gc)
143 return null_pointer_node;
145 /* If we have a type of unknown size, use a proc. */
146 if (int_size_in_bytes (type) == -1)
147 return PROCEDURE_OBJECT_DESCRIPTOR;
149 bit = POINTER_SIZE / BITS_PER_UNIT;
150 /* The size of this node has to be known. And, we only support 32
151 and 64 bit targets, so we need to know that the log2 is one of
153 log2_size = exact_log2 (bit);
154 if (bit == -1 || (log2_size != 2 && log2_size != 3))
156 /* This means the GC isn't supported. We should probably
157 abort or give an error. Instead, for now, we just silently
159 return null_pointer_node;
161 bit *= BITS_PER_UNIT;
163 /* Warning avoidance. */
164 ubit = (unsigned int) bit;
166 field = TYPE_FIELDS (type);
167 mark_reference_fields (field, &low, &high, ubit,
168 &pointer_after_end, &all_bits_set,
169 &last_set_index, &last_view_index);
171 /* If the object is all pointers, or if the part with pointers fits
172 in our bitmap, then we are ok. Otherwise we have to allocate it
176 /* In the GC the computation looks something like this:
177 value = DS_LENGTH | WORDS_TO_BYTES (last_set_index + 1);
179 WORDS_TO_BYTES shifts by log2(bytes-per-pointer). */
184 while (last_set_index)
186 if ((last_set_index & 1))
187 set_bit (&low, &high, log2_size + count);
188 last_set_index >>= 1;
191 value = build_int_2 (low, high);
193 else if (! pointer_after_end)
195 /* Bottom two bits for bitmap mark type are 01. */
196 set_bit (&low, &high, 0);
197 value = build_int_2 (low, high);
200 value = PROCEDURE_OBJECT_DESCRIPTOR;