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