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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [gcc/] [java/] [boehm.c] - Blame information for rev 750

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

Line No. Rev Author Line
1 715 jeremybenn
/* 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
}

powered by: WebSVN 2.1.0

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