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

Subversion Repositories scarts

[/] [scarts/] [trunk/] [toolchain/] [scarts-gcc/] [gcc-4.1.1/] [gcc/] [java/] [boehm.c] - Blame information for rev 12

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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