1 /* Functions related to the Boehm garbage collector.
2 Copyright (C) 2000, 2003, 2004, 2006, 2009, 2010
3 Free Software Foundation, Inc.
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3, or (at your option)
12 GCC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>.
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>. */
29 #include "coretypes.h"
30 #include "double-int.h"
33 #include "java-tree.h"
35 #include "diagnostic-core.h"
38 static void mark_reference_fields (tree
, double_int
*, unsigned int,
39 int *, int *, int *, HOST_WIDE_INT
*);
41 /* A procedure-based object descriptor. We know that our
42 `kind' is 0, and `env' is likewise 0, so we have a simple
43 computation. From the GC sources:
44 (((((env) << LOG_MAX_MARK_PROCS) | (proc_index)) << DS_TAG_BITS) \
47 #define PROCEDURE_OBJECT_DESCRIPTOR 2
49 /* Recursively mark reference fields. */
51 mark_reference_fields (tree field
,
54 int *pointer_after_end
,
57 HOST_WIDE_INT
*last_view_index
)
59 /* See if we have fields from our superclass. */
60 if (DECL_NAME (field
) == NULL_TREE
)
62 mark_reference_fields (TYPE_FIELDS (TREE_TYPE (field
)),
64 pointer_after_end
, all_bits_set
,
65 last_set_index
, last_view_index
);
66 field
= DECL_CHAIN (field
);
69 for (; field
!= NULL_TREE
; field
= DECL_CHAIN (field
))
72 HOST_WIDE_INT size_bytes
;
74 if (FIELD_STATIC (field
))
77 offset
= int_byte_position (field
);
78 size_bytes
= int_size_in_bytes (TREE_TYPE (field
));
80 if (JREFERENCE_TYPE_P (TREE_TYPE (field
))
81 /* An `object' of type gnu.gcj.RawData is actually non-Java
83 && TREE_TYPE (field
) != rawdata_ptr_type_node
)
86 unsigned int size_words
;
89 /* If this reference slot appears to overlay a slot we think
90 we already covered, then we are doomed. */
91 gcc_assert (offset
> *last_view_index
);
93 if (offset
% (HOST_WIDE_INT
) (POINTER_SIZE
/ BITS_PER_UNIT
))
96 *pointer_after_end
= 1;
100 count
= offset
* BITS_PER_UNIT
/ POINTER_SIZE
;
101 size_words
= size_bytes
* BITS_PER_UNIT
/ POINTER_SIZE
;
103 *last_set_index
= count
;
105 /* First word in object corresponds to most significant byte of
108 In the case of a multiple-word record, we set pointer
109 bits for all words in the record. This is conservative, but the
110 size_words != 1 case is impossible in regular java code. */
111 for (i
= 0; i
< size_words
; ++i
)
112 *mask
= double_int_setbit (*mask
, ubit
- count
- i
- 1);
114 if (count
>= ubit
- 2)
115 *pointer_after_end
= 1;
117 /* If we saw a non-reference field earlier, then we can't
118 use the count representation. We keep track of that in
123 else if (*all_bits_set
> 0)
126 *last_view_index
= offset
;
130 /* Return the marking bitmap for the class TYPE. For now this is a
131 single word describing the type. */
133 get_boehm_type_descriptor (tree type
)
135 unsigned int count
, log2_size
, ubit
;
137 int all_bits_set
= 1;
138 int last_set_index
= 0;
139 HOST_WIDE_INT last_view_index
= -1;
140 int pointer_after_end
= 0;
142 tree field
, value
, value_type
;
144 mask
= double_int_zero
;
146 /* If the GC wasn't requested, just use a null pointer. */
147 if (! flag_use_boehm_gc
)
148 return null_pointer_node
;
150 value_type
= java_type_for_mode (ptr_mode
, 1);
151 /* If we have a type of unknown size, use a proc. */
152 if (int_size_in_bytes (type
) == -1)
153 goto procedure_object_descriptor
;
155 bit
= POINTER_SIZE
/ BITS_PER_UNIT
;
156 /* The size of this node has to be known. And, we only support 32
157 and 64 bit targets, so we need to know that the log2 is one of
159 log2_size
= exact_log2 (bit
);
160 if (bit
== -1 || (log2_size
!= 2 && log2_size
!= 3))
162 /* This means the GC isn't supported. We should probably
163 abort or give an error. Instead, for now, we just silently
165 return null_pointer_node
;
167 bit
*= BITS_PER_UNIT
;
169 /* Warning avoidance. */
170 ubit
= (unsigned int) bit
;
172 if (type
== class_type_node
)
173 goto procedure_object_descriptor
;
175 field
= TYPE_FIELDS (type
);
176 mark_reference_fields (field
, &mask
, ubit
,
177 &pointer_after_end
, &all_bits_set
,
178 &last_set_index
, &last_view_index
);
180 /* If the object is all pointers, or if the part with pointers fits
181 in our bitmap, then we are ok. Otherwise we have to allocate it
183 if (all_bits_set
!= -1 || (pointer_after_end
&& flag_reduced_reflection
))
185 /* In this case the initial part of the object is all reference
186 fields, and the end of the object is all non-reference
187 fields. We represent the mark as a count of the fields,
188 shifted. In the GC the computation looks something like
190 value = DS_LENGTH | WORDS_TO_BYTES (last_set_index + 1);
192 WORDS_TO_BYTES shifts by log2(bytes-per-pointer).
194 In the case of flag_reduced_reflection and the bitmap would
195 overflow, we tell the gc that the object is all pointers so
196 that we don't have to emit reflection data for run time
199 mask
= double_int_zero
;
201 while (last_set_index
)
203 if ((last_set_index
& 1))
204 mask
= double_int_setbit (mask
, log2_size
+ count
);
205 last_set_index
>>= 1;
208 value
= double_int_to_tree (value_type
, mask
);
210 else if (! pointer_after_end
)
212 /* Bottom two bits for bitmap mark type are 01. */
213 mask
= double_int_setbit (mask
, 0);
214 value
= double_int_to_tree (value_type
, mask
);
218 procedure_object_descriptor
:
219 value
= build_int_cst (value_type
, PROCEDURE_OBJECT_DESCRIPTOR
);
225 /* The fourth (index of 3) element in the vtable is the GC descriptor.
226 A value of 2 indicates that the class uses _Jv_MarkObj. */
228 uses_jv_markobj_p (tree dtable
)
231 /* FIXME: what do we return if !flag_use_boehm_gc ? */
232 gcc_assert (flag_use_boehm_gc
);
233 /* FIXME: this is wrong if TARGET_VTABLE_USES_DESCRIPTORS. However,
234 this function is only used with flag_reduced_reflection. No
235 point in asserting unless we hit the bad case. */
236 gcc_assert (!flag_reduced_reflection
|| TARGET_VTABLE_USES_DESCRIPTORS
== 0);
237 v
= VEC_index (constructor_elt
, CONSTRUCTOR_ELTS (dtable
), 3)->value
;
238 return (PROCEDURE_OBJECT_DESCRIPTOR
== TREE_INT_CST_LOW (v
));