OSDN Git Service

* boehm.c (mark_reference_fields, set_bit): Prototype.
[pf3gnuchains/gcc-fork.git] / gcc / java / boehm.c
1 /* Functions related to the Boehm garbage collector.
2    Copyright (C) 2000 Free Software Foundation, Inc.
3
4 This file is part of GNU CC.
5
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)
9 any later version.
10
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.
15
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.
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
29 #include "system.h"
30 #include "tree.h"
31 #include "java-tree.h"
32 #include "parse.h"
33
34 static unsigned int mark_reference_fields PARAMS ((tree,
35                                                    unsigned HOST_WIDE_INT *,
36                                                    unsigned HOST_WIDE_INT *,
37                                                    unsigned int,
38                                                    int *, int *, int *));
39 static void set_bit PARAMS ((unsigned HOST_WIDE_INT *,
40                              unsigned HOST_WIDE_INT *,
41                              unsigned int));
42
43 /* Compute 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) \
47             | DS_PROC)
48    Here DS_PROC == 2.  */
49 #define PROCEDURE_OBJECT_DESCRIPTOR integer_two_node
50
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.  */
53 static void
54 set_bit (low, high, n)
55      unsigned HOST_WIDE_INT *low, *high;
56      unsigned int n;
57 {
58   HOST_WIDE_INT *which;
59
60   if (n >= HOST_BITS_PER_WIDE_INT)
61     {
62       n -= HOST_BITS_PER_WIDE_INT;
63       which = high;
64     }
65   else
66     which = low;
67
68   *which |= (HOST_WIDE_INT) 1 << n;
69 }
70
71 /* Recursively mark reference fields.  */
72 static unsigned int
73 mark_reference_fields (field, low, high, ubit,
74                        pointer_after_end, all_bits_set, last_set_index)
75      tree field;
76      unsigned HOST_WIDE_INT *low, *high;
77      unsigned int ubit;
78      int *pointer_after_end, *all_bits_set, *last_set_index;
79 {
80   unsigned int count = 0;
81
82   /* See if we have fields from our superclass.  */
83   if (DECL_NAME (field) == NULL_TREE)
84     {
85       count += mark_reference_fields (TYPE_FIELDS (TREE_TYPE (field)),
86                                       low, high, ubit,
87                                       pointer_after_end, all_bits_set,
88                                       last_set_index);
89       field = TREE_CHAIN (field);
90     }
91
92   for (; field != NULL_TREE; field = TREE_CHAIN (field))
93     {
94       if (FIELD_STATIC (field))
95         continue;
96
97       if (JREFERENCE_TYPE_P (TREE_TYPE (field)))
98         {
99           *last_set_index = count;
100           /* First word in object corresponds to most significant byte
101              of bitmap.  */
102           set_bit (low, high, ubit - count - 1);
103           if (count > ubit - 2)
104             *pointer_after_end = 1;
105         }
106       else
107         *all_bits_set = 0;
108
109       ++count;
110     }
111
112   return count;
113 }
114
115 /* Return the marking bitmap for the class TYPE.  For now this is a
116    single word describing the type.  */
117 tree
118 get_boehm_type_descriptor (tree type)
119 {
120   unsigned int count, log2_size, ubit;
121   int bit;
122   int all_bits_set = 1;
123   int last_set_index = 0;
124   int pointer_after_end = 0;
125   unsigned HOST_WIDE_INT low = 0, high = 0;
126   tree field, value;
127
128   /* If the GC wasn't requested, just use a null pointer.  */
129   if (! flag_use_boehm_gc)
130     return null_pointer_node;
131
132   /* If we have a type of unknown size, use a proc.  */
133   if (int_size_in_bytes (type) == -1)
134     return PROCEDURE_OBJECT_DESCRIPTOR;
135
136   bit = POINTER_SIZE / BITS_PER_UNIT;
137   /* The size of this node has to be known.  And, we only support 32
138      and 64 bit targets, so we need to know that the log2 is one of
139      our values.  */
140   log2_size = exact_log2 (bit);
141   if (bit == -1 || (log2_size != 2 && log2_size != 3))
142     {
143       /* This means the GC isn't supported.  We should probably
144          abort or give an error.  Instead, for now, we just silently
145          revert.  FIXME.  */
146       return null_pointer_node;
147     }
148   bit *= BITS_PER_UNIT;
149
150   /* Warning avoidance.  */
151   ubit = (unsigned int) bit;
152
153   field = TYPE_FIELDS (type);
154   count = mark_reference_fields (field, &low, &high, ubit,
155                                  &pointer_after_end, &all_bits_set,
156                                  &last_set_index);
157
158   /* If the object is all pointers, or if the part with pointers fits
159      in our bitmap, then we are ok.  Otherwise we have to allocate it
160      a different way.  */
161   if (all_bits_set)
162     {
163       /* In the GC the computation looks something like this:
164          value = DS_LENGTH | WORDS_TO_BYTES (last_set_index + 1);
165          DS_LENGTH is 0.
166          WORDS_TO_BYTES shifts by log2(bytes-per-pointer).  */
167       count = 0;
168       low = 0;
169       high = 0;
170       ++last_set_index;
171       while (last_set_index)
172         {
173           if ((last_set_index & 1))
174             set_bit (&low, &high, log2_size + count);
175           last_set_index >>= 1;
176           ++count;
177         }
178       value = build_int_2 (low, high);
179     }
180   else if (! pointer_after_end)
181     {
182       /* Bottom two bits for bitmap mark type are 01.  */
183       set_bit (&low, &high, 0);
184       value = build_int_2 (low, high);
185     }
186   else
187     value = PROCEDURE_OBJECT_DESCRIPTOR;
188
189   return value;
190 }