1 /* Functions related to the Boehm garbage collector.
2 Copyright (C) 2000, 2003, 2004, 2006 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, 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>. */
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 /* A procedure-based object descriptor. We know that our
44 `kind' is 0, and `env' is likewise 0, so we have a simple
45 computation. From the GC sources:
46 (((((env) << LOG_MAX_MARK_PROCS) | (proc_index)) << DS_TAG_BITS) \
49 #define PROCEDURE_OBJECT_DESCRIPTOR 2
51 /* Treat two HOST_WIDE_INT's as a contiguous bitmap, with bit 0 being
52 the least significant. This function sets bit N in the bitmap. */
54 set_bit (unsigned HOST_WIDE_INT
*low
, unsigned HOST_WIDE_INT
*high
,
57 unsigned HOST_WIDE_INT
*which
;
59 if (n
>= HOST_BITS_PER_WIDE_INT
)
61 n
-= HOST_BITS_PER_WIDE_INT
;
67 *which
|= (unsigned HOST_WIDE_INT
) 1 << n
;
70 /* Recursively mark reference fields. */
72 mark_reference_fields (tree field
,
73 unsigned HOST_WIDE_INT
*low
,
74 unsigned HOST_WIDE_INT
*high
,
76 int *pointer_after_end
,
79 HOST_WIDE_INT
*last_view_index
)
81 /* See if we have fields from our superclass. */
82 if (DECL_NAME (field
) == NULL_TREE
)
84 mark_reference_fields (TYPE_FIELDS (TREE_TYPE (field
)),
86 pointer_after_end
, all_bits_set
,
87 last_set_index
, last_view_index
);
88 field
= TREE_CHAIN (field
);
91 for (; field
!= NULL_TREE
; field
= TREE_CHAIN (field
))
94 HOST_WIDE_INT size_bytes
;
96 if (FIELD_STATIC (field
))
99 offset
= int_byte_position (field
);
100 size_bytes
= int_size_in_bytes (TREE_TYPE (field
));
101 if (JREFERENCE_TYPE_P (TREE_TYPE (field
))
102 /* An `object' of type gnu.gcj.RawData is actually non-Java
104 && TREE_TYPE (field
) != rawdata_ptr_type_node
)
107 unsigned int size_words
;
110 /* If this reference slot appears to overlay a slot we think
111 we already covered, then we are doomed. */
112 gcc_assert (offset
> *last_view_index
);
114 count
= offset
* BITS_PER_UNIT
/ POINTER_SIZE
;
115 size_words
= size_bytes
* BITS_PER_UNIT
/ POINTER_SIZE
;
117 *last_set_index
= count
;
119 /* First word in object corresponds to most significant byte of
122 In the case of a multiple-word record, we set pointer
123 bits for all words in the record. This is conservative, but the
124 size_words != 1 case is impossible in regular java code. */
125 for (i
= 0; i
< size_words
; ++i
)
126 set_bit (low
, high
, ubit
- count
- i
- 1);
128 if (count
>= ubit
- 2)
129 *pointer_after_end
= 1;
131 /* If we saw a non-reference field earlier, then we can't
132 use the count representation. We keep track of that in
137 else if (*all_bits_set
> 0)
140 *last_view_index
= offset
;
144 /* Return the marking bitmap for the class TYPE. For now this is a
145 single word describing the type. */
147 get_boehm_type_descriptor (tree type
)
149 unsigned int count
, log2_size
, ubit
;
151 int all_bits_set
= 1;
152 int last_set_index
= 0;
153 HOST_WIDE_INT last_view_index
= -1;
154 int pointer_after_end
= 0;
155 unsigned HOST_WIDE_INT low
= 0, high
= 0;
156 tree field
, value
, value_type
;
158 /* If the GC wasn't requested, just use a null pointer. */
159 if (! flag_use_boehm_gc
)
160 return null_pointer_node
;
162 value_type
= java_type_for_mode (ptr_mode
, 1);
163 /* If we have a type of unknown size, use a proc. */
164 if (int_size_in_bytes (type
) == -1)
165 goto procedure_object_descriptor
;
167 bit
= POINTER_SIZE
/ BITS_PER_UNIT
;
168 /* The size of this node has to be known. And, we only support 32
169 and 64 bit targets, so we need to know that the log2 is one of
171 log2_size
= exact_log2 (bit
);
172 if (bit
== -1 || (log2_size
!= 2 && log2_size
!= 3))
174 /* This means the GC isn't supported. We should probably
175 abort or give an error. Instead, for now, we just silently
177 return null_pointer_node
;
179 bit
*= BITS_PER_UNIT
;
181 /* Warning avoidance. */
182 ubit
= (unsigned int) bit
;
184 if (type
== class_type_node
)
185 goto procedure_object_descriptor
;
187 field
= TYPE_FIELDS (type
);
188 mark_reference_fields (field
, &low
, &high
, ubit
,
189 &pointer_after_end
, &all_bits_set
,
190 &last_set_index
, &last_view_index
);
192 /* If the object is all pointers, or if the part with pointers fits
193 in our bitmap, then we are ok. Otherwise we have to allocate it
195 if (all_bits_set
!= -1 || (pointer_after_end
&& flag_reduced_reflection
))
197 /* In this case the initial part of the object is all reference
198 fields, and the end of the object is all non-reference
199 fields. We represent the mark as a count of the fields,
200 shifted. In the GC the computation looks something like
202 value = DS_LENGTH | WORDS_TO_BYTES (last_set_index + 1);
204 WORDS_TO_BYTES shifts by log2(bytes-per-pointer).
206 In the case of flag_reduced_reflection and the bitmap would
207 overflow, we tell the gc that the object is all pointers so
208 that we don't have to emit reflection data for run time
214 while (last_set_index
)
216 if ((last_set_index
& 1))
217 set_bit (&low
, &high
, log2_size
+ count
);
218 last_set_index
>>= 1;
221 value
= build_int_cst_wide (value_type
, 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_cst_wide (value_type
, low
, high
);
231 procedure_object_descriptor
:
232 value
= build_int_cst (value_type
, PROCEDURE_OBJECT_DESCRIPTOR
);
238 /* The fourth (index of 3) element in the vtable is the GC descriptor.
239 A value of 2 indicates that the class uses _Jv_MarkObj. */
241 uses_jv_markobj_p (tree dtable
)
244 /* FIXME: what do we return if !flag_use_boehm_gc ? */
245 gcc_assert (flag_use_boehm_gc
);
246 /* FIXME: this is wrong if TARGET_VTABLE_USES_DESCRIPTORS. However,
247 this function is only used with flag_reduced_reflection. No
248 point in asserting unless we hit the bad case. */
249 gcc_assert (!flag_reduced_reflection
|| TARGET_VTABLE_USES_DESCRIPTORS
== 0);
250 v
= VEC_index (constructor_elt
, CONSTRUCTOR_ELTS (dtable
), 3)->value
;
251 return (PROCEDURE_OBJECT_DESCRIPTOR
== TREE_INT_CST_LOW (v
));