optabs.c (libfunc_decl_hash, [...]): Fix -Wcast-qual warnings.
[gcc.git] / gcc / java / constants.c
1 /* Handle the constant pool of the Java(TM) Virtual Machine.
2 Copyright (C) 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006,
3 2007, 2008 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 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 #include "config.h"
25 #include "system.h"
26 #include "coretypes.h"
27 #include "tm.h"
28 #include "jcf.h"
29 #include "tree.h"
30 #include "java-tree.h"
31 #include "toplev.h"
32 #include "ggc.h"
33
34 static void set_constant_entry (CPool *, int, int, jword);
35 static int find_tree_constant (CPool *, int, tree);
36 static int find_name_and_type_constant (CPool *, tree, tree);
37 static tree get_tag_node (int);
38
39 /* Set the INDEX'th constant in CPOOL to have the given TAG and VALUE. */
40
41 static void
42 set_constant_entry (CPool *cpool, int index, int tag, jword value)
43 {
44 if (cpool->data == NULL)
45 {
46 cpool->capacity = 100;
47 cpool->tags = GGC_CNEWVEC (uint8, cpool->capacity);
48 cpool->data = GGC_CNEWVEC (union cpool_entry, cpool->capacity);
49 cpool->count = 1;
50 }
51 if (index >= cpool->capacity)
52 {
53 int old_cap = cpool->capacity;
54 cpool->capacity *= 2;
55 if (index >= cpool->capacity)
56 cpool->capacity = index + 10;
57 cpool->tags = GGC_RESIZEVEC (uint8, cpool->tags, cpool->capacity);
58 cpool->data = GGC_RESIZEVEC (union cpool_entry, cpool->data,
59 cpool->capacity);
60
61 /* Make sure GC never sees uninitialized tag values. */
62 memset (cpool->tags + old_cap, 0, cpool->capacity - old_cap);
63 memset (cpool->data + old_cap, 0,
64 (cpool->capacity - old_cap) * sizeof (union cpool_entry));
65 }
66 if (index >= cpool->count)
67 cpool->count = index + 1;
68 cpool->tags[index] = tag;
69 cpool->data[index].w = value;
70 }
71
72 /* Find (or create) a constant pool entry matching TAG and VALUE. */
73
74 int
75 find_constant1 (CPool *cpool, int tag, jword value)
76 {
77 int i;
78 for (i = cpool->count; --i > 0; )
79 {
80 if (cpool->tags[i] == tag && cpool->data[i].w == value)
81 return i;
82 }
83 i = cpool->count == 0 ? 1 : cpool->count;
84 set_constant_entry (cpool, i, tag, value);
85 return i;
86 }
87
88 /* Find a double-word constant pool entry matching TAG and WORD1/WORD2. */
89
90 int
91 find_constant2 (CPool *cpool, int tag, jword word1, jword word2)
92 {
93 int i;
94 for (i = cpool->count - 1; --i > 0; )
95 {
96 if (cpool->tags[i] == tag
97 && cpool->data[i].w == word1
98 && cpool->data[i+1].w == word2)
99 return i;
100 }
101 i = cpool->count == 0 ? 1 : cpool->count;
102 set_constant_entry (cpool, i, tag, word1);
103 set_constant_entry (cpool, i+1, 0, word2);
104 return i;
105 }
106
107 static int
108 find_tree_constant (CPool *cpool, int tag, tree value)
109 {
110 int i;
111 for (i = cpool->count; --i > 0; )
112 {
113 if (cpool->tags[i] == tag && cpool->data[i].t == value)
114 return i;
115 }
116 i = cpool->count == 0 ? 1 : cpool->count;
117 set_constant_entry (cpool, i, tag, 0);
118 cpool->data[i].t = value;
119 return i;
120 }
121
122
123 int
124 find_utf8_constant (CPool *cpool, tree name)
125 {
126 if (name == NULL_TREE)
127 return 0;
128 return find_tree_constant (cpool, CONSTANT_Utf8, name);
129 }
130
131 int
132 find_class_or_string_constant (CPool *cpool, int tag, tree name)
133 {
134 jword j = find_utf8_constant (cpool, name);
135 int i;
136 for (i = cpool->count; --i > 0; )
137 {
138 if (cpool->tags[i] == tag && cpool->data[i].w == j)
139 return i;
140 }
141 i = cpool->count;
142 set_constant_entry (cpool, i, tag, j);
143 return i;
144 }
145
146 int
147 find_class_constant (CPool *cpool, tree type)
148 {
149 return find_class_or_string_constant (cpool, CONSTANT_Class,
150 build_internal_class_name (type));
151 }
152
153 /* Allocate a CONSTANT_string entry given a STRING_CST. */
154
155 int
156 find_string_constant (CPool *cpool, tree string)
157 {
158 string = get_identifier (TREE_STRING_POINTER (string));
159 return find_class_or_string_constant (cpool, CONSTANT_String, string);
160
161 }
162
163 /* Find (or create) a CONSTANT_NameAndType matching NAME and TYPE.
164 Return its index in the constant pool CPOOL. */
165
166 static int
167 find_name_and_type_constant (CPool *cpool, tree name, tree type)
168 {
169 int name_index = find_utf8_constant (cpool, name);
170 int type_index = find_utf8_constant (cpool, build_java_signature (type));
171 return find_constant1 (cpool, CONSTANT_NameAndType,
172 (name_index << 16) | type_index);
173 }
174
175 /* Find (or create) a CONSTANT_Fieldref for DECL (a FIELD_DECL or VAR_DECL).
176 Return its index in the constant pool CPOOL. */
177
178 int
179 find_fieldref_index (CPool *cpool, tree decl)
180 {
181 int class_index = find_class_constant (cpool, DECL_CONTEXT (decl));
182 int name_type_index
183 = find_name_and_type_constant (cpool, DECL_NAME (decl), TREE_TYPE (decl));
184 return find_constant1 (cpool, CONSTANT_Fieldref,
185 (class_index << 16) | name_type_index);
186 }
187
188 /* Find (or create) a CONSTANT_Methodref for DECL (a FUNCTION_DECL).
189 Return its index in the constant pool CPOOL. */
190
191 int
192 find_methodref_index (CPool *cpool, tree decl)
193 {
194 return find_methodref_with_class_index (cpool, decl, DECL_CONTEXT (decl));
195 }
196
197 int
198 find_methodref_with_class_index (CPool *cpool, tree decl, tree mclass)
199 {
200 int class_index = find_class_constant (cpool, mclass);
201 tree name = DECL_CONSTRUCTOR_P (decl) ? init_identifier_node
202 : DECL_NAME (decl);
203 int name_type_index;
204 name_type_index =
205 find_name_and_type_constant (cpool, name, TREE_TYPE (decl));
206 return find_constant1 (cpool,
207 CLASS_INTERFACE (TYPE_NAME (mclass))
208 ? CONSTANT_InterfaceMethodref
209 : CONSTANT_Methodref,
210 (class_index << 16) | name_type_index);
211 }
212
213 #define PUT1(X) (*ptr++ = (X))
214 #define PUT2(X) (PUT1((X) >> 8), PUT1(X))
215 #define PUT4(X) (PUT2((X) >> 16), PUT2(X))
216 #define PUTN(P, N) (memcpy(ptr, (P), (N)), ptr += (N))
217
218 /* Give the number of bytes needed in a .class file for the CPOOL
219 constant pool. Includes the 2-byte constant_pool_count. */
220
221 int
222 count_constant_pool_bytes (CPool *cpool)
223 {
224 int size = 2;
225 int i = 1;
226 for ( ; i < cpool->count; i++)
227 {
228 size++;
229 switch (cpool->tags[i])
230 {
231 case CONSTANT_NameAndType:
232 case CONSTANT_Fieldref:
233 case CONSTANT_Methodref:
234 case CONSTANT_InterfaceMethodref:
235 case CONSTANT_Float:
236 case CONSTANT_Integer:
237 size += 4;
238 break;
239 case CONSTANT_Class:
240 case CONSTANT_String:
241 size += 2;
242 break;
243 case CONSTANT_Long:
244 case CONSTANT_Double:
245 size += 8;
246 i++;
247 break;
248 case CONSTANT_Utf8:
249 {
250 tree t = cpool->data[i].t;
251 int len = IDENTIFIER_LENGTH (t);
252 size += len + 2;
253 }
254 break;
255 default:
256 /* Second word of CONSTANT_Long and CONSTANT_Double. */
257 size--;
258 }
259 }
260 return size;
261 }
262
263 /* Write the constant pool CPOOL into BUFFER.
264 The length of BUFFER is LENGTH, which must match the needed length. */
265
266 void
267 write_constant_pool (CPool *cpool, unsigned char *buffer, int length)
268 {
269 unsigned char *ptr = buffer;
270 int i = 1;
271 union cpool_entry *datap = &cpool->data[1];
272 PUT2 (cpool->count);
273 for ( ; i < cpool->count; i++, datap++)
274 {
275 int tag = cpool->tags[i];
276 PUT1 (tag);
277 switch (tag)
278 {
279 case CONSTANT_NameAndType:
280 case CONSTANT_Fieldref:
281 case CONSTANT_Methodref:
282 case CONSTANT_InterfaceMethodref:
283 case CONSTANT_Float:
284 case CONSTANT_Integer:
285 PUT4 (datap->w);
286 break;
287 case CONSTANT_Class:
288 case CONSTANT_String:
289 PUT2 (datap->w);
290 break;
291 break;
292 case CONSTANT_Long:
293 case CONSTANT_Double:
294 PUT4(datap->w);
295 i++;
296 datap++;
297 PUT4 (datap->w);
298 break;
299 case CONSTANT_Utf8:
300 {
301 tree t = datap->t;
302 int len = IDENTIFIER_LENGTH (t);
303 PUT2 (len);
304 PUTN (IDENTIFIER_POINTER (t), len);
305 }
306 break;
307 }
308 }
309
310 gcc_assert (ptr == buffer + length);
311 }
312
313 static GTY(()) tree tag_nodes[13];
314 static tree
315 get_tag_node (int tag)
316 {
317 /* A Cache for build_int_cst (CONSTANT_XXX, 0). */
318
319 if (tag >= 13)
320 return build_int_cst (NULL_TREE, tag);
321
322 if (tag_nodes[tag] == NULL_TREE)
323 tag_nodes[tag] = build_int_cst (NULL_TREE, tag);
324 return tag_nodes[tag];
325 }
326
327 /* Given a class, return its constant pool, creating one if necessary. */
328
329 CPool *
330 cpool_for_class (tree klass)
331 {
332 CPool *cpool = TYPE_CPOOL (klass);
333
334 if (cpool == NULL)
335 {
336 cpool = GGC_CNEW (struct CPool);
337 TYPE_CPOOL (klass) = cpool;
338 }
339 return cpool;
340 }
341
342 /* Look for a constant pool entry that matches TAG and NAME.
343 Creates a new entry if not found.
344 TAG is one of CONSTANT_Utf8, CONSTANT_String or CONSTANT_Class.
345 NAME is an IDENTIFIER_NODE naming the Utf8 constant, string, or class.
346 Returns the index of the entry. */
347
348 int
349 alloc_name_constant (int tag, tree name)
350 {
351 CPool *outgoing_cpool = cpool_for_class (output_class);
352 return find_tree_constant (outgoing_cpool, tag, name);
353 }
354
355 /* Create a constant pool entry for a name_and_type. This one has '.'
356 rather than '/' because it isn't going into a class file, it's
357 going into a compiled object. We don't use the '/' separator in
358 compiled objects. */
359
360 static int
361 find_name_and_type_constant_tree (CPool *cpool, tree name, tree type)
362 {
363 int name_index = find_utf8_constant (cpool, name);
364 int type_index
365 = find_utf8_constant (cpool,
366 identifier_subst (build_java_signature (type),
367 "", '/', '.', ""));
368 return find_constant1 (cpool, CONSTANT_NameAndType,
369 (name_index << 16) | type_index);
370 }
371
372 /* Look for a field ref that matches DECL in the constant pool of
373 KLASS.
374 Return the index of the entry. */
375
376 int
377 alloc_constant_fieldref (tree klass, tree decl)
378 {
379 CPool *outgoing_cpool = cpool_for_class (klass);
380 int class_index
381 = find_tree_constant (outgoing_cpool, CONSTANT_Class,
382 DECL_NAME (TYPE_NAME (DECL_CONTEXT (decl))));
383 int name_type_index
384 = find_name_and_type_constant_tree (outgoing_cpool, DECL_NAME (decl),
385 TREE_TYPE (decl));
386 return find_constant1 (outgoing_cpool, CONSTANT_Fieldref,
387 (class_index << 16) | name_type_index);
388 }
389
390 /* Build an identifier for the internal name of reference type TYPE. */
391
392 tree
393 build_internal_class_name (tree type)
394 {
395 tree name;
396 if (TYPE_ARRAY_P (type))
397 name = build_java_signature (type);
398 else
399 {
400 name = TYPE_NAME (type);
401 if (TREE_CODE (name) != IDENTIFIER_NODE)
402 name = DECL_NAME (name);
403 name = identifier_subst (name, "", '.', '/', "");
404 }
405 return name;
406 }
407
408 /* Look for a CONSTANT_Class entry for CLAS, creating a new one if needed. */
409
410 int
411 alloc_class_constant (tree clas)
412 {
413 tree class_name = build_internal_class_name (clas);
414
415 return alloc_name_constant (CONSTANT_Class,
416 (unmangle_classname
417 (IDENTIFIER_POINTER(class_name),
418 IDENTIFIER_LENGTH(class_name))));
419 }
420
421 /* Return the decl of the data array of the current constant pool. */
422
423 tree
424 build_constant_data_ref (bool indirect)
425 {
426 if (indirect)
427 {
428 tree d;
429 tree cpool_type = build_array_type (ptr_type_node, NULL_TREE);
430 tree decl = build_class_ref (output_class);
431 tree klass = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (decl)),
432 decl);
433 tree constants = build3 (COMPONENT_REF,
434 TREE_TYPE (constants_field_decl_node), klass,
435 constants_field_decl_node,
436 NULL_TREE);
437 tree data = build3 (COMPONENT_REF,
438 TREE_TYPE (constants_data_field_decl_node),
439 constants,
440 constants_data_field_decl_node,
441 NULL_TREE);
442
443 TREE_THIS_NOTRAP (klass) = 1;
444 data = fold_convert (build_pointer_type (cpool_type), data);
445 d = build1 (INDIRECT_REF, cpool_type, data);
446
447 return d;
448 }
449 else
450 {
451 tree type, decl;
452 tree decl_name = mangled_classname ("_CD_", output_class);
453
454 /* Build a type with unspecified bounds. The will make sure
455 that targets do the right thing with whatever size we end
456 up with at the end. Using bounds that are too small risks
457 assuming the data is in the small data section. */
458 type = build_array_type (ptr_type_node, NULL_TREE);
459
460 /* We need to lay out the type ourselves, since build_array_type
461 thinks the type is incomplete. */
462 layout_type (type);
463
464 decl = build_decl (VAR_DECL, decl_name, type);
465 TREE_STATIC (decl) = 1;
466
467 return decl;
468 }
469 }
470
471 /* Get the pointer value at the INDEX'th element of the constant pool. */
472
473 tree
474 build_ref_from_constant_pool (int index)
475 {
476 tree i;
477 tree d = TYPE_CPOOL_DATA_REF (output_class);
478
479 if (d == NULL_TREE)
480 d = build_constant_data_ref (flag_indirect_classes);
481
482 i = build_int_cst (NULL_TREE, index);
483 d = build4 (ARRAY_REF, TREE_TYPE (TREE_TYPE (d)), d, i,
484 NULL_TREE, NULL_TREE);
485 return d;
486 }
487
488 /* Build an initializer for the constants field of the current constant pool.
489 Should only be called at top-level, since it may emit declarations. */
490
491 tree
492 build_constants_constructor (void)
493 {
494 CPool *outgoing_cpool = cpool_for_class (current_class);
495 tree tags_value, data_value;
496 tree cons;
497 tree tags_list = NULL_TREE;
498 tree data_list = NULL_TREE;
499 int i;
500
501 for (i = outgoing_cpool->count; --i > 0; )
502 switch (outgoing_cpool->tags[i] & ~CONSTANT_LazyFlag)
503 {
504 case CONSTANT_None: /* The second half of a Double or Long on a
505 32-bit target. */
506 case CONSTANT_Fieldref:
507 case CONSTANT_NameAndType:
508 case CONSTANT_Float:
509 case CONSTANT_Integer:
510 case CONSTANT_Double:
511 case CONSTANT_Long:
512 case CONSTANT_Methodref:
513 case CONSTANT_InterfaceMethodref:
514 {
515 unsigned HOST_WIDE_INT temp = outgoing_cpool->data[i].w;
516
517 /* Make sure that on a big-endian machine with 64-bit
518 pointers this 32-bit jint appears in the first word.
519 FIXME: This is a kludge. The field we're initializing is
520 not a scalar but a union, and that's how we should
521 represent it in the compiler. We should fix this. */
522 if (BYTES_BIG_ENDIAN && POINTER_SIZE > 32)
523 temp <<= POINTER_SIZE - 32;
524
525 tags_list
526 = tree_cons (NULL_TREE, get_tag_node (outgoing_cpool->tags[i]),
527 tags_list);
528 data_list
529 = tree_cons (NULL_TREE,
530 fold_convert (ptr_type_node,
531 (build_int_cst (NULL_TREE, temp))),
532 data_list);
533 }
534 break;
535
536 case CONSTANT_Class:
537 case CONSTANT_String:
538 case CONSTANT_Unicode:
539 case CONSTANT_Utf8:
540 tags_list
541 = tree_cons (NULL_TREE, get_tag_node (outgoing_cpool->tags[i]),
542 tags_list);
543 data_list
544 = tree_cons (NULL_TREE, build_utf8_ref (outgoing_cpool->data[i].t),
545 data_list);
546 break;
547
548 default:
549 gcc_assert (false);
550 }
551 if (outgoing_cpool->count > 0)
552 {
553 tree data_decl, tags_decl, tags_type;
554 tree max_index = build_int_cst (sizetype, outgoing_cpool->count - 1);
555 tree index_type = build_index_type (max_index);
556
557 /* Add dummy 0'th element of constant pool. */
558 tags_list = tree_cons (NULL_TREE, get_tag_node (0), tags_list);
559 data_list = tree_cons (NULL_TREE, null_pointer_node, data_list);
560
561 data_decl = build_constant_data_ref (false);
562 TREE_TYPE (data_decl) = build_array_type (ptr_type_node, index_type);
563 DECL_INITIAL (data_decl) = build_constructor_from_list
564 (TREE_TYPE (data_decl), data_list);
565 DECL_SIZE (data_decl) = TYPE_SIZE (TREE_TYPE (data_decl));
566 DECL_SIZE_UNIT (data_decl) = TYPE_SIZE_UNIT (TREE_TYPE (data_decl));
567 rest_of_decl_compilation (data_decl, 1, 0);
568 data_value = build_address_of (data_decl);
569
570 tags_type = build_array_type (unsigned_byte_type_node, index_type);
571 tags_decl = build_decl (VAR_DECL, mangled_classname ("_CT_",
572 current_class),
573 tags_type);
574 TREE_STATIC (tags_decl) = 1;
575 DECL_INITIAL (tags_decl) = build_constructor_from_list
576 (tags_type, tags_list);
577 rest_of_decl_compilation (tags_decl, 1, 0);
578 tags_value = build_address_of (tags_decl);
579 }
580 else
581 {
582 data_value = null_pointer_node;
583 tags_value = null_pointer_node;
584 }
585 START_RECORD_CONSTRUCTOR (cons, constants_type_node);
586 PUSH_FIELD_VALUE (cons, "size",
587 build_int_cst (NULL_TREE, outgoing_cpool->count));
588 PUSH_FIELD_VALUE (cons, "tags", tags_value);
589 PUSH_FIELD_VALUE (cons, "data", data_value);
590 FINISH_RECORD_CONSTRUCTOR (cons);
591 return cons;
592 }
593
594 #include "gt-java-constants.h"