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.
5 This file is part of GCC.
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)
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/>.
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. */
26 #include "coretypes.h"
30 #include "java-tree.h"
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);
39 /* Set the INDEX'th constant in CPOOL to have the given TAG and VALUE. */
42 set_constant_entry (CPool *cpool, int index, int tag, jword value)
44 if (cpool->data == NULL)
46 cpool->capacity = 100;
47 cpool->tags = GGC_CNEWVEC (uint8, cpool->capacity);
48 cpool->data = GGC_CNEWVEC (union cpool_entry, cpool->capacity);
51 if (index >= cpool->capacity)
53 int old_cap = cpool->capacity;
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,
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));
66 if (index >= cpool->count)
67 cpool->count = index + 1;
68 cpool->tags[index] = tag;
69 cpool->data[index].w = value;
72 /* Find (or create) a constant pool entry matching TAG and VALUE. */
75 find_constant1 (CPool *cpool, int tag, jword value)
78 for (i = cpool->count; --i > 0; )
80 if (cpool->tags[i] == tag && cpool->data[i].w == value)
83 i = cpool->count == 0 ? 1 : cpool->count;
84 set_constant_entry (cpool, i, tag, value);
88 /* Find a double-word constant pool entry matching TAG and WORD1/WORD2. */
91 find_constant2 (CPool *cpool, int tag, jword word1, jword word2)
94 for (i = cpool->count - 1; --i > 0; )
96 if (cpool->tags[i] == tag
97 && cpool->data[i].w == word1
98 && cpool->data[i+1].w == word2)
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);
108 find_tree_constant (CPool *cpool, int tag, tree value)
111 for (i = cpool->count; --i > 0; )
113 if (cpool->tags[i] == tag && cpool->data[i].t == value)
116 i = cpool->count == 0 ? 1 : cpool->count;
117 set_constant_entry (cpool, i, tag, 0);
118 cpool->data[i].t = value;
124 find_utf8_constant (CPool *cpool, tree name)
126 if (name == NULL_TREE)
128 return find_tree_constant (cpool, CONSTANT_Utf8, name);
132 find_class_or_string_constant (CPool *cpool, int tag, tree name)
134 jword j = find_utf8_constant (cpool, name);
136 for (i = cpool->count; --i > 0; )
138 if (cpool->tags[i] == tag && cpool->data[i].w == j)
142 set_constant_entry (cpool, i, tag, j);
147 find_class_constant (CPool *cpool, tree type)
149 return find_class_or_string_constant (cpool, CONSTANT_Class,
150 build_internal_class_name (type));
153 /* Allocate a CONSTANT_string entry given a STRING_CST. */
156 find_string_constant (CPool *cpool, tree string)
158 string = get_identifier (TREE_STRING_POINTER (string));
159 return find_class_or_string_constant (cpool, CONSTANT_String, string);
163 /* Find (or create) a CONSTANT_NameAndType matching NAME and TYPE.
164 Return its index in the constant pool CPOOL. */
167 find_name_and_type_constant (CPool *cpool, tree name, tree type)
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);
175 /* Find (or create) a CONSTANT_Fieldref for DECL (a FIELD_DECL or VAR_DECL).
176 Return its index in the constant pool CPOOL. */
179 find_fieldref_index (CPool *cpool, tree decl)
181 int class_index = find_class_constant (cpool, DECL_CONTEXT (decl));
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);
188 /* Find (or create) a CONSTANT_Methodref for DECL (a FUNCTION_DECL).
189 Return its index in the constant pool CPOOL. */
192 find_methodref_index (CPool *cpool, tree decl)
194 return find_methodref_with_class_index (cpool, decl, DECL_CONTEXT (decl));
198 find_methodref_with_class_index (CPool *cpool, tree decl, tree mclass)
200 int class_index = find_class_constant (cpool, mclass);
201 tree name = DECL_CONSTRUCTOR_P (decl) ? init_identifier_node
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);
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))
218 /* Give the number of bytes needed in a .class file for the CPOOL
219 constant pool. Includes the 2-byte constant_pool_count. */
222 count_constant_pool_bytes (CPool *cpool)
226 for ( ; i < cpool->count; i++)
229 switch (cpool->tags[i])
231 case CONSTANT_NameAndType:
232 case CONSTANT_Fieldref:
233 case CONSTANT_Methodref:
234 case CONSTANT_InterfaceMethodref:
236 case CONSTANT_Integer:
240 case CONSTANT_String:
244 case CONSTANT_Double:
250 tree t = cpool->data[i].t;
251 int len = IDENTIFIER_LENGTH (t);
256 /* Second word of CONSTANT_Long and CONSTANT_Double. */
263 /* Write the constant pool CPOOL into BUFFER.
264 The length of BUFFER is LENGTH, which must match the needed length. */
267 write_constant_pool (CPool *cpool, unsigned char *buffer, int length)
269 unsigned char *ptr = buffer;
271 union cpool_entry *datap = &cpool->data[1];
273 for ( ; i < cpool->count; i++, datap++)
275 int tag = cpool->tags[i];
279 case CONSTANT_NameAndType:
280 case CONSTANT_Fieldref:
281 case CONSTANT_Methodref:
282 case CONSTANT_InterfaceMethodref:
284 case CONSTANT_Integer:
288 case CONSTANT_String:
293 case CONSTANT_Double:
302 int len = IDENTIFIER_LENGTH (t);
304 PUTN (IDENTIFIER_POINTER (t), len);
310 gcc_assert (ptr == buffer + length);
313 static GTY(()) tree tag_nodes[13];
315 get_tag_node (int tag)
317 /* A Cache for build_int_cst (CONSTANT_XXX, 0). */
320 return build_int_cst (NULL_TREE, tag);
322 if (tag_nodes[tag] == NULL_TREE)
323 tag_nodes[tag] = build_int_cst (NULL_TREE, tag);
324 return tag_nodes[tag];
327 /* Given a class, return its constant pool, creating one if necessary. */
330 cpool_for_class (tree klass)
332 CPool *cpool = TYPE_CPOOL (klass);
336 cpool = GGC_CNEW (struct CPool);
337 TYPE_CPOOL (klass) = cpool;
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. */
349 alloc_name_constant (int tag, tree name)
351 CPool *outgoing_cpool = cpool_for_class (output_class);
352 return find_tree_constant (outgoing_cpool, tag, name);
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
361 find_name_and_type_constant_tree (CPool *cpool, tree name, tree type)
363 int name_index = find_utf8_constant (cpool, name);
365 = find_utf8_constant (cpool,
366 identifier_subst (build_java_signature (type),
368 return find_constant1 (cpool, CONSTANT_NameAndType,
369 (name_index << 16) | type_index);
372 /* Look for a field ref that matches DECL in the constant pool of
374 Return the index of the entry. */
377 alloc_constant_fieldref (tree klass, tree decl)
379 CPool *outgoing_cpool = cpool_for_class (klass);
381 = find_tree_constant (outgoing_cpool, CONSTANT_Class,
382 DECL_NAME (TYPE_NAME (DECL_CONTEXT (decl))));
384 = find_name_and_type_constant_tree (outgoing_cpool, DECL_NAME (decl),
386 return find_constant1 (outgoing_cpool, CONSTANT_Fieldref,
387 (class_index << 16) | name_type_index);
390 /* Build an identifier for the internal name of reference type TYPE. */
393 build_internal_class_name (tree type)
396 if (TYPE_ARRAY_P (type))
397 name = build_java_signature (type);
400 name = TYPE_NAME (type);
401 if (TREE_CODE (name) != IDENTIFIER_NODE)
402 name = DECL_NAME (name);
403 name = identifier_subst (name, "", '.', '/', "");
408 /* Look for a CONSTANT_Class entry for CLAS, creating a new one if needed. */
411 alloc_class_constant (tree clas)
413 tree class_name = build_internal_class_name (clas);
415 return alloc_name_constant (CONSTANT_Class,
417 (IDENTIFIER_POINTER(class_name),
418 IDENTIFIER_LENGTH(class_name))));
421 /* Return the decl of the data array of the current constant pool. */
424 build_constant_data_ref (bool indirect)
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)),
433 tree constants = build3 (COMPONENT_REF,
434 TREE_TYPE (constants_field_decl_node), klass,
435 constants_field_decl_node,
437 tree data = build3 (COMPONENT_REF,
438 TREE_TYPE (constants_data_field_decl_node),
440 constants_data_field_decl_node,
443 TREE_THIS_NOTRAP (klass) = 1;
444 data = fold_convert (build_pointer_type (cpool_type), data);
445 d = build1 (INDIRECT_REF, cpool_type, data);
451 tree decl_name = mangled_classname ("_CD_", output_class);
452 tree decl = IDENTIFIER_GLOBAL_VALUE (decl_name);
456 /* Build a type with unspecified bounds. The will make sure
457 that targets do the right thing with whatever size we end
458 up with at the end. Using bounds that are too small risks
459 assuming the data is in the small data section. */
460 tree type = build_array_type (ptr_type_node, NULL_TREE);
462 /* We need to lay out the type ourselves, since build_array_type
463 thinks the type is incomplete. */
466 decl = build_decl (VAR_DECL, decl_name, type);
467 TREE_STATIC (decl) = 1;
468 IDENTIFIER_GLOBAL_VALUE (decl_name) = decl;
475 /* Get the pointer value at the INDEX'th element of the constant pool. */
478 build_ref_from_constant_pool (int index)
481 tree d = TYPE_CPOOL_DATA_REF (output_class);
484 d = build_constant_data_ref (flag_indirect_classes);
486 i = build_int_cst (NULL_TREE, index);
487 d = build4 (ARRAY_REF, TREE_TYPE (TREE_TYPE (d)), d, i,
488 NULL_TREE, NULL_TREE);
492 /* Build an initializer for the constants field of the current constant pool.
493 Should only be called at top-level, since it may emit declarations. */
496 build_constants_constructor (void)
498 CPool *outgoing_cpool = cpool_for_class (current_class);
499 tree tags_value, data_value;
501 tree tags_list = NULL_TREE;
502 tree data_list = NULL_TREE;
505 for (i = outgoing_cpool->count; --i > 0; )
506 switch (outgoing_cpool->tags[i] & ~CONSTANT_LazyFlag)
508 case CONSTANT_None: /* The second half of a Double or Long on a
510 case CONSTANT_Fieldref:
511 case CONSTANT_NameAndType:
513 case CONSTANT_Integer:
514 case CONSTANT_Double:
516 case CONSTANT_Methodref:
517 case CONSTANT_InterfaceMethodref:
519 unsigned HOST_WIDE_INT temp = outgoing_cpool->data[i].w;
521 /* Make sure that on a big-endian machine with 64-bit
522 pointers this 32-bit jint appears in the first word.
523 FIXME: This is a kludge. The field we're initializing is
524 not a scalar but a union, and that's how we should
525 represent it in the compiler. We should fix this. */
526 if (BYTES_BIG_ENDIAN && POINTER_SIZE > 32)
527 temp <<= POINTER_SIZE - 32;
530 = tree_cons (NULL_TREE, get_tag_node (outgoing_cpool->tags[i]),
533 = tree_cons (NULL_TREE,
534 fold_convert (ptr_type_node,
535 (build_int_cst (NULL_TREE, temp))),
541 case CONSTANT_String:
542 case CONSTANT_Unicode:
545 = tree_cons (NULL_TREE, get_tag_node (outgoing_cpool->tags[i]),
548 = tree_cons (NULL_TREE, build_utf8_ref (outgoing_cpool->data[i].t),
555 if (outgoing_cpool->count > 0)
557 tree data_decl, tags_decl, tags_type;
558 tree max_index = build_int_cst (sizetype, outgoing_cpool->count - 1);
559 tree index_type = build_index_type (max_index);
562 /* Add dummy 0'th element of constant pool. */
563 tags_list = tree_cons (NULL_TREE, get_tag_node (0), tags_list);
564 data_list = tree_cons (NULL_TREE, null_pointer_node, data_list);
566 /* Change the type of the decl to have the proper array size.
567 ??? Make sure to transition the old type-pointer-to list to this
568 new type to not invalidate all build address expressions. */
569 data_decl = build_constant_data_ref (false);
570 tem = TYPE_POINTER_TO (TREE_TYPE (data_decl));
572 tem = build_pointer_type (TREE_TYPE (data_decl));
573 TYPE_POINTER_TO (TREE_TYPE (data_decl)) = NULL_TREE;
574 TREE_TYPE (data_decl) = build_array_type (ptr_type_node, index_type);
575 TYPE_POINTER_TO (TREE_TYPE (data_decl)) = tem;
576 DECL_INITIAL (data_decl) = build_constructor_from_list
577 (TREE_TYPE (data_decl), data_list);
578 DECL_SIZE (data_decl) = TYPE_SIZE (TREE_TYPE (data_decl));
579 DECL_SIZE_UNIT (data_decl) = TYPE_SIZE_UNIT (TREE_TYPE (data_decl));
580 rest_of_decl_compilation (data_decl, 1, 0);
581 data_value = build_address_of (data_decl);
583 tags_type = build_array_type (unsigned_byte_type_node, index_type);
584 tags_decl = build_decl (VAR_DECL, mangled_classname ("_CT_",
587 TREE_STATIC (tags_decl) = 1;
588 DECL_INITIAL (tags_decl) = build_constructor_from_list
589 (tags_type, tags_list);
590 rest_of_decl_compilation (tags_decl, 1, 0);
591 tags_value = build_address_of (tags_decl);
595 data_value = null_pointer_node;
596 tags_value = null_pointer_node;
598 START_RECORD_CONSTRUCTOR (cons, constants_type_node);
599 PUSH_FIELD_VALUE (cons, "size",
600 build_int_cst (NULL_TREE, outgoing_cpool->count));
601 PUSH_FIELD_VALUE (cons, "tags", tags_value);
602 PUSH_FIELD_VALUE (cons, "data", data_value);
603 FINISH_RECORD_CONSTRUCTOR (cons);
607 #include "gt-java-constants.h"