OpenCores
URL https://opencores.org/ocsvn/openrisc_me/openrisc_me/trunk

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [gcc-4.5.1/] [gcc/] [java/] [boehm.c] - Blame information for rev 294

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.