00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include <config.h>
00028
00029 #include "system.h"
00030 #include "tree.h"
00031 #include "java-tree.h"
00032 #include "parse.h"
00033 #include "toplev.h"
00034
00035 static void mark_reference_fields PARAMS ((tree,
00036 unsigned HOST_WIDE_INT *,
00037 unsigned HOST_WIDE_INT *,
00038 unsigned int,
00039 int *, int *,
00040 int *,
00041 HOST_WIDE_INT *));
00042 static void set_bit PARAMS ((unsigned HOST_WIDE_INT *,
00043 unsigned HOST_WIDE_INT *,
00044 unsigned int));
00045
00046
00047
00048 static void
00049 set_bit (low, high, n)
00050 unsigned HOST_WIDE_INT *low, *high;
00051 unsigned int n;
00052 {
00053 HOST_WIDE_INT *which;
00054
00055 if (n >= HOST_BITS_PER_WIDE_INT)
00056 {
00057 n -= HOST_BITS_PER_WIDE_INT;
00058 which = high;
00059 }
00060 else
00061 which = low;
00062
00063 *which |= (HOST_WIDE_INT) 1 << n;
00064 }
00065
00066
00067 static void
00068 mark_reference_fields (field, low, high, ubit,
00069 pointer_after_end, all_bits_set,
00070 last_set_index, last_view_index)
00071 tree field;
00072 unsigned HOST_WIDE_INT *low, *high;
00073 unsigned int ubit;
00074 int *pointer_after_end, *all_bits_set;
00075 int *last_set_index;
00076 HOST_WIDE_INT *last_view_index;
00077 {
00078
00079 if (DECL_NAME (field) == NULL_TREE)
00080 {
00081 mark_reference_fields (TYPE_FIELDS (TREE_TYPE (field)),
00082 low, high, ubit,
00083 pointer_after_end, all_bits_set,
00084 last_set_index, last_view_index);
00085 field = TREE_CHAIN (field);
00086 }
00087
00088 for (; field != NULL_TREE; field = TREE_CHAIN (field))
00089 {
00090 HOST_WIDE_INT offset;
00091 HOST_WIDE_INT size_bytes;
00092
00093 if (FIELD_STATIC (field))
00094 continue;
00095
00096 offset = int_byte_position (field);
00097 size_bytes = int_size_in_bytes (TREE_TYPE (field));
00098 if (JREFERENCE_TYPE_P (TREE_TYPE (field))
00099
00100
00101 && TREE_TYPE (field) != rawdata_ptr_type_node)
00102 {
00103 unsigned int count;
00104 unsigned int size_words;
00105 unsigned int i;
00106
00107
00108
00109 if (offset <= *last_view_index)
00110 abort ();
00111
00112 count = offset * BITS_PER_UNIT / POINTER_SIZE;
00113 size_words = size_bytes * BITS_PER_UNIT / POINTER_SIZE;
00114
00115 *last_set_index = count;
00116
00117
00118
00119
00120
00121
00122
00123 for (i = 0; i < size_words; ++i)
00124 set_bit (low, high, ubit - count - i - 1);
00125
00126 if (count >= ubit - 2)
00127 *pointer_after_end = 1;
00128
00129
00130
00131
00132 if (! *all_bits_set)
00133 *all_bits_set = -1;
00134 }
00135 else if (*all_bits_set > 0)
00136 *all_bits_set = 0;
00137
00138 *last_view_index = offset;
00139 }
00140 }
00141
00142
00143
00144 tree
00145 get_boehm_type_descriptor (tree type)
00146 {
00147 unsigned int count, log2_size, ubit;
00148 int bit;
00149 int all_bits_set = 1;
00150 int last_set_index = 0;
00151 HOST_WIDE_INT last_view_index = -1;
00152 int pointer_after_end = 0;
00153 unsigned HOST_WIDE_INT low = 0, high = 0;
00154 tree field, value;
00155
00156
00157 if (! flag_use_boehm_gc)
00158 return null_pointer_node;
00159
00160
00161 if (int_size_in_bytes (type) == -1)
00162 goto procedure_object_descriptor;
00163
00164 bit = POINTER_SIZE / BITS_PER_UNIT;
00165
00166
00167
00168 log2_size = exact_log2 (bit);
00169 if (bit == -1 || (log2_size != 2 && log2_size != 3))
00170 {
00171
00172
00173
00174 return null_pointer_node;
00175 }
00176 bit *= BITS_PER_UNIT;
00177
00178
00179 ubit = (unsigned int) bit;
00180
00181 if (type == class_type_node)
00182 goto procedure_object_descriptor;
00183
00184 field = TYPE_FIELDS (type);
00185 mark_reference_fields (field, &low, &high, ubit,
00186 &pointer_after_end, &all_bits_set,
00187 &last_set_index, &last_view_index);
00188
00189
00190
00191
00192 if (all_bits_set != -1)
00193 {
00194
00195
00196
00197
00198
00199
00200
00201
00202 count = 0;
00203 low = 0;
00204 high = 0;
00205 ++last_set_index;
00206 while (last_set_index)
00207 {
00208 if ((last_set_index & 1))
00209 set_bit (&low, &high, log2_size + count);
00210 last_set_index >>= 1;
00211 ++count;
00212 }
00213 value = build_int_2 (low, high);
00214 }
00215 else if (! pointer_after_end)
00216 {
00217
00218 set_bit (&low, &high, 0);
00219 value = build_int_2 (low, high);
00220 }
00221 else
00222 {
00223
00224
00225
00226
00227
00228
00229 procedure_object_descriptor:
00230 value = build_int_2 (2, 0);
00231 }
00232
00233 TREE_TYPE (value) = type_for_mode (ptr_mode, 1);
00234 return value;
00235 }