OSDN Git Service

Backport from 2012-06-04 mainline r188172
[pf3gnuchains/gcc-fork.git] / gcc / java / boehm.c
1 /* Functions related to the Boehm garbage collector.
2    Copyright (C) 2000, 2003, 2004, 2006, 2009, 2010
3    Free Software Foundation, Inc.
4
5 This file is part of GCC.
6
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)
10 any later version.
11
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.
16
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/>.
20
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.  */
24
25 /* Written by Tom Tromey <tromey@cygnus.com>.  */
26
27 #include "config.h"
28 #include "system.h"
29 #include "coretypes.h"
30 #include "double-int.h"
31 #include "tm.h"
32 #include "tree.h"
33 #include "java-tree.h"
34 #include "parse.h"
35 #include "diagnostic-core.h"
36
37 static void mark_reference_fields (tree, double_int *, unsigned int,
38                                    int *, int *, int *, HOST_WIDE_INT *);
39
40 /* A procedure-based object descriptor.  We know that our
41    `kind' is 0, and `env' is likewise 0, so we have a simple
42    computation.  From the GC sources:
43    (((((env) << LOG_MAX_MARK_PROCS) | (proc_index)) << DS_TAG_BITS)     \
44    | DS_PROC)
45    Here DS_PROC == 2.  */
46 #define PROCEDURE_OBJECT_DESCRIPTOR 2
47
48 /* Recursively mark reference fields.  */
49 static void
50 mark_reference_fields (tree field,
51                        double_int *mask,
52                        unsigned int ubit,
53                        int *pointer_after_end,
54                        int *all_bits_set,
55                        int *last_set_index,
56                        HOST_WIDE_INT *last_view_index)
57 {
58   /* See if we have fields from our superclass.  */
59   if (DECL_NAME (field) == NULL_TREE)
60     {
61       mark_reference_fields (TYPE_FIELDS (TREE_TYPE (field)),
62                              mask, ubit,
63                              pointer_after_end, all_bits_set,
64                              last_set_index, last_view_index);
65       field = DECL_CHAIN (field);
66     }
67
68   for (; field != NULL_TREE; field = DECL_CHAIN (field))
69     {
70       HOST_WIDE_INT offset;
71       HOST_WIDE_INT size_bytes;
72
73       if (FIELD_STATIC (field))
74         continue;
75
76       offset = int_byte_position (field);
77       size_bytes = int_size_in_bytes (TREE_TYPE (field));
78
79       if (JREFERENCE_TYPE_P (TREE_TYPE (field))
80           /* An `object' of type gnu.gcj.RawData is actually non-Java
81              data.  */
82           && TREE_TYPE (field) != rawdata_ptr_type_node)
83         {
84           unsigned int count;
85           unsigned int size_words;
86           unsigned int i;
87
88           /* If this reference slot appears to overlay a slot we think
89              we already covered, then we are doomed.  */
90           gcc_assert (offset > *last_view_index);
91
92           if (offset % (HOST_WIDE_INT) (POINTER_SIZE / BITS_PER_UNIT))
93             {
94               *all_bits_set = -1;
95               *pointer_after_end = 1;
96               break;
97             }
98
99           count = offset * BITS_PER_UNIT / POINTER_SIZE;
100           size_words = size_bytes * BITS_PER_UNIT / POINTER_SIZE;
101
102           *last_set_index = count;
103              
104           /* First word in object corresponds to most significant byte of 
105              bitmap. 
106              
107              In the case of a multiple-word record, we set pointer 
108              bits for all words in the record. This is conservative, but the 
109              size_words != 1 case is impossible in regular java code. */
110           for (i = 0; i < size_words; ++i)
111             *mask = double_int_setbit (*mask, ubit - count - i - 1);
112
113           if (count >= ubit - 2)
114             *pointer_after_end = 1;
115
116           /* If we saw a non-reference field earlier, then we can't
117              use the count representation.  We keep track of that in
118              *ALL_BITS_SET.  */
119           if (! *all_bits_set)
120             *all_bits_set = -1;
121         }
122       else if (*all_bits_set > 0)
123         *all_bits_set = 0;
124
125       *last_view_index = offset;
126     }
127 }
128
129 /* Return the marking bitmap for the class TYPE.  For now this is a
130    single word describing the type.  */
131 tree
132 get_boehm_type_descriptor (tree type)
133 {
134   unsigned int count, log2_size, ubit;
135   int bit;
136   int all_bits_set = 1;
137   int last_set_index = 0;
138   HOST_WIDE_INT last_view_index = -1;
139   int pointer_after_end = 0;
140   double_int mask;
141   tree field, value, value_type;
142
143   mask = double_int_zero;
144
145   /* If the GC wasn't requested, just use a null pointer.  */
146   if (! flag_use_boehm_gc)
147     return null_pointer_node;
148
149   value_type = java_type_for_mode (ptr_mode, 1);
150   /* If we have a type of unknown size, use a proc.  */
151   if (int_size_in_bytes (type) == -1)
152     goto procedure_object_descriptor;
153
154   bit = POINTER_SIZE / BITS_PER_UNIT;
155   /* The size of this node has to be known.  And, we only support 32
156      and 64 bit targets, so we need to know that the log2 is one of
157      our values.  */
158   log2_size = exact_log2 (bit);
159   if (bit == -1 || (log2_size != 2 && log2_size != 3))
160     {
161       /* This means the GC isn't supported.  We should probably
162          abort or give an error.  Instead, for now, we just silently
163          revert.  FIXME.  */
164       return null_pointer_node;
165     }
166   bit *= BITS_PER_UNIT;
167
168   /* Warning avoidance.  */
169   ubit = (unsigned int) bit;
170
171   if (type == class_type_node)
172     goto procedure_object_descriptor;
173
174   field = TYPE_FIELDS (type);
175   mark_reference_fields (field, &mask, ubit,
176                          &pointer_after_end, &all_bits_set,
177                          &last_set_index, &last_view_index);
178
179   /* If the object is all pointers, or if the part with pointers fits
180      in our bitmap, then we are ok.  Otherwise we have to allocate it
181      a different way.  */
182   if (all_bits_set != -1 || (pointer_after_end && flag_reduced_reflection))
183     {
184       /* In this case the initial part of the object is all reference
185          fields, and the end of the object is all non-reference
186          fields.  We represent the mark as a count of the fields,
187          shifted.  In the GC the computation looks something like
188          this:
189          value = DS_LENGTH | WORDS_TO_BYTES (last_set_index + 1);
190          DS_LENGTH is 0.
191          WORDS_TO_BYTES shifts by log2(bytes-per-pointer).
192
193          In the case of flag_reduced_reflection and the bitmap would
194          overflow, we tell the gc that the object is all pointers so
195          that we don't have to emit reflection data for run time
196          marking. */
197       count = 0;
198       mask = double_int_zero;
199       ++last_set_index;
200       while (last_set_index)
201         {
202           if ((last_set_index & 1))
203             mask = double_int_setbit (mask, log2_size + count);
204           last_set_index >>= 1;
205           ++count;
206         }
207       value = double_int_to_tree (value_type, mask);
208     }
209   else if (! pointer_after_end)
210     {
211       /* Bottom two bits for bitmap mark type are 01.  */
212       mask = double_int_setbit (mask, 0);
213       value = double_int_to_tree (value_type, mask);
214     }
215   else
216     {
217     procedure_object_descriptor:
218       value = build_int_cst (value_type, PROCEDURE_OBJECT_DESCRIPTOR);
219     }
220
221   return value;
222 }
223
224 /* The fourth (index of 3) element in the vtable is the GC descriptor.
225    A value of 2 indicates that the class uses _Jv_MarkObj. */
226 bool
227 uses_jv_markobj_p (tree dtable)
228 {
229   tree v;
230   /* FIXME: what do we return if !flag_use_boehm_gc ? */
231   gcc_assert (flag_use_boehm_gc);
232   /* FIXME: this is wrong if TARGET_VTABLE_USES_DESCRIPTORS.  However,
233      this function is only used with flag_reduced_reflection.  No
234      point in asserting unless we hit the bad case.  */
235   gcc_assert (!flag_reduced_reflection || TARGET_VTABLE_USES_DESCRIPTORS == 0);
236   v = VEC_index (constructor_elt, CONSTRUCTOR_ELTS (dtable), 3)->value;
237   return (PROCEDURE_OBJECT_DESCRIPTOR == TREE_INT_CST_LOW (v));
238 }