1 /* Handle the constant pool of the Java(TM) Virtual Machine.
2 Copyright (C) 1997-2015 Free Software Foundation, Inc.
4 This file is part of GCC.
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 3, or (at your option)
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 You should have received a copy of the GNU General Public License
16 along with GCC; see the file COPYING3. If not see
17 <http://www.gnu.org/licenses/>.
19 Java and all Java-based marks are trademarks or registered trademarks
20 of Sun Microsystems, Inc. in the United States and other countries.
21 The Free Software Foundation is independent of Sun Microsystems, Inc. */
25 #include "coretypes.h"
31 #include "double-int.h"
38 #include "fold-const.h"
39 #include "stringpool.h"
40 #include "stor-layout.h"
41 #include "java-tree.h"
42 #include "diagnostic-core.h"
46 static void set_constant_entry (CPool
*, int, int, jword
);
47 static int find_tree_constant (CPool
*, int, tree
);
48 static int find_name_and_type_constant (CPool
*, tree
, tree
);
49 static tree
get_tag_node (int);
51 /* Set the INDEX'th constant in CPOOL to have the given TAG and VALUE. */
54 set_constant_entry (CPool
*cpool
, int index
, int tag
, jword value
)
56 if (cpool
->data
== NULL
)
58 cpool
->capacity
= 100;
59 cpool
->tags
= ggc_cleared_vec_alloc
<uint8
> (cpool
->capacity
);
60 cpool
->data
= ggc_cleared_vec_alloc
<cpool_entry
> (cpool
->capacity
);
63 if (index
>= cpool
->capacity
)
65 int old_cap
= cpool
->capacity
;
67 if (index
>= cpool
->capacity
)
68 cpool
->capacity
= index
+ 10;
69 cpool
->tags
= GGC_RESIZEVEC (uint8
, cpool
->tags
, cpool
->capacity
);
70 cpool
->data
= GGC_RESIZEVEC (union cpool_entry
, cpool
->data
,
73 /* Make sure GC never sees uninitialized tag values. */
74 memset (cpool
->tags
+ old_cap
, 0, cpool
->capacity
- old_cap
);
75 memset (cpool
->data
+ old_cap
, 0,
76 (cpool
->capacity
- old_cap
) * sizeof (union cpool_entry
));
78 if (index
>= cpool
->count
)
79 cpool
->count
= index
+ 1;
80 cpool
->tags
[index
] = tag
;
81 cpool
->data
[index
].w
= value
;
84 /* Find (or create) a constant pool entry matching TAG and VALUE. */
87 find_constant1 (CPool
*cpool
, int tag
, jword value
)
90 for (i
= cpool
->count
; --i
> 0; )
92 if (cpool
->tags
[i
] == tag
&& cpool
->data
[i
].w
== value
)
95 i
= cpool
->count
== 0 ? 1 : cpool
->count
;
96 set_constant_entry (cpool
, i
, tag
, value
);
100 /* Find a double-word constant pool entry matching TAG and WORD1/WORD2. */
103 find_constant2 (CPool
*cpool
, int tag
, jword word1
, jword word2
)
106 for (i
= cpool
->count
- 1; --i
> 0; )
108 if (cpool
->tags
[i
] == tag
109 && cpool
->data
[i
].w
== word1
110 && cpool
->data
[i
+1].w
== word2
)
113 i
= cpool
->count
== 0 ? 1 : cpool
->count
;
114 set_constant_entry (cpool
, i
, tag
, word1
);
115 set_constant_entry (cpool
, i
+1, 0, word2
);
120 find_tree_constant (CPool
*cpool
, int tag
, tree value
)
123 for (i
= cpool
->count
; --i
> 0; )
125 if (cpool
->tags
[i
] == tag
&& cpool
->data
[i
].t
== value
)
128 i
= cpool
->count
== 0 ? 1 : cpool
->count
;
129 set_constant_entry (cpool
, i
, tag
, 0);
130 cpool
->data
[i
].t
= value
;
136 find_utf8_constant (CPool
*cpool
, tree name
)
138 if (name
== NULL_TREE
)
140 return find_tree_constant (cpool
, CONSTANT_Utf8
, name
);
144 find_class_or_string_constant (CPool
*cpool
, int tag
, tree name
)
146 jword j
= find_utf8_constant (cpool
, name
);
148 for (i
= cpool
->count
; --i
> 0; )
150 if (cpool
->tags
[i
] == tag
&& cpool
->data
[i
].w
== j
)
154 set_constant_entry (cpool
, i
, tag
, j
);
159 find_class_constant (CPool
*cpool
, tree type
)
161 return find_class_or_string_constant (cpool
, CONSTANT_Class
,
162 build_internal_class_name (type
));
165 /* Allocate a CONSTANT_string entry given a STRING_CST. */
168 find_string_constant (CPool
*cpool
, tree string
)
170 string
= get_identifier (TREE_STRING_POINTER (string
));
171 return find_class_or_string_constant (cpool
, CONSTANT_String
, string
);
175 /* Find (or create) a CONSTANT_NameAndType matching NAME and TYPE.
176 Return its index in the constant pool CPOOL. */
179 find_name_and_type_constant (CPool
*cpool
, tree name
, tree type
)
181 int name_index
= find_utf8_constant (cpool
, name
);
182 int type_index
= find_utf8_constant (cpool
, build_java_signature (type
));
183 return find_constant1 (cpool
, CONSTANT_NameAndType
,
184 (name_index
<< 16) | type_index
);
187 /* Find (or create) a CONSTANT_Fieldref for DECL (a FIELD_DECL or VAR_DECL).
188 Return its index in the constant pool CPOOL. */
191 find_fieldref_index (CPool
*cpool
, tree decl
)
193 int class_index
= find_class_constant (cpool
, DECL_CONTEXT (decl
));
195 = find_name_and_type_constant (cpool
, DECL_NAME (decl
), TREE_TYPE (decl
));
196 return find_constant1 (cpool
, CONSTANT_Fieldref
,
197 (class_index
<< 16) | name_type_index
);
200 /* Find (or create) a CONSTANT_Methodref for DECL (a FUNCTION_DECL).
201 Return its index in the constant pool CPOOL. */
204 find_methodref_index (CPool
*cpool
, tree decl
)
206 return find_methodref_with_class_index (cpool
, decl
, DECL_CONTEXT (decl
));
210 find_methodref_with_class_index (CPool
*cpool
, tree decl
, tree mclass
)
212 int class_index
= find_class_constant (cpool
, mclass
);
213 tree name
= DECL_CONSTRUCTOR_P (decl
) ? init_identifier_node
217 find_name_and_type_constant (cpool
, name
, TREE_TYPE (decl
));
218 return find_constant1 (cpool
,
219 CLASS_INTERFACE (TYPE_NAME (mclass
))
220 ? CONSTANT_InterfaceMethodref
221 : CONSTANT_Methodref
,
222 (class_index
<< 16) | name_type_index
);
225 #define PUT1(X) (*ptr++ = (X))
226 #define PUT2(X) (PUT1((X) >> 8), PUT1(X))
227 #define PUT4(X) (PUT2((X) >> 16), PUT2(X))
228 #define PUTN(P, N) (memcpy(ptr, (P), (N)), ptr += (N))
230 /* Give the number of bytes needed in a .class file for the CPOOL
231 constant pool. Includes the 2-byte constant_pool_count. */
234 count_constant_pool_bytes (CPool
*cpool
)
238 for ( ; i
< cpool
->count
; i
++)
241 switch (cpool
->tags
[i
])
243 case CONSTANT_NameAndType
:
244 case CONSTANT_Fieldref
:
245 case CONSTANT_Methodref
:
246 case CONSTANT_InterfaceMethodref
:
248 case CONSTANT_Integer
:
252 case CONSTANT_String
:
256 case CONSTANT_Double
:
262 tree t
= cpool
->data
[i
].t
;
263 int len
= IDENTIFIER_LENGTH (t
);
268 /* Second word of CONSTANT_Long and CONSTANT_Double. */
275 /* Write the constant pool CPOOL into BUFFER.
276 The length of BUFFER is LENGTH, which must match the needed length. */
279 write_constant_pool (CPool
*cpool
, unsigned char *buffer
, int length
)
281 unsigned char *ptr
= buffer
;
283 union cpool_entry
*datap
= &cpool
->data
[1];
285 for ( ; i
< cpool
->count
; i
++, datap
++)
287 int tag
= cpool
->tags
[i
];
291 case CONSTANT_NameAndType
:
292 case CONSTANT_Fieldref
:
293 case CONSTANT_Methodref
:
294 case CONSTANT_InterfaceMethodref
:
296 case CONSTANT_Integer
:
300 case CONSTANT_String
:
305 case CONSTANT_Double
:
314 int len
= IDENTIFIER_LENGTH (t
);
316 PUTN (IDENTIFIER_POINTER (t
), len
);
322 gcc_assert (ptr
== buffer
+ length
);
325 static GTY(()) tree tag_nodes
[13];
327 get_tag_node (int tag
)
329 /* A Cache for build_int_cst (CONSTANT_XXX, 0). */
332 return build_int_cst (NULL_TREE
, tag
);
334 if (tag_nodes
[tag
] == NULL_TREE
)
335 tag_nodes
[tag
] = build_int_cst (NULL_TREE
, tag
);
336 return tag_nodes
[tag
];
339 /* Given a class, return its constant pool, creating one if necessary. */
342 cpool_for_class (tree klass
)
344 CPool
*cpool
= TYPE_CPOOL (klass
);
348 cpool
= ggc_cleared_alloc
<CPool
> ();
349 TYPE_CPOOL (klass
) = cpool
;
354 /* Look for a constant pool entry that matches TAG and NAME.
355 Creates a new entry if not found.
356 TAG is one of CONSTANT_Utf8, CONSTANT_String or CONSTANT_Class.
357 NAME is an IDENTIFIER_NODE naming the Utf8 constant, string, or class.
358 Returns the index of the entry. */
361 alloc_name_constant (int tag
, tree name
)
363 CPool
*outgoing_cpool
= cpool_for_class (output_class
);
364 return find_tree_constant (outgoing_cpool
, tag
, name
);
367 /* Create a constant pool entry for a name_and_type. This one has '.'
368 rather than '/' because it isn't going into a class file, it's
369 going into a compiled object. We don't use the '/' separator in
373 find_name_and_type_constant_tree (CPool
*cpool
, tree name
, tree type
)
375 int name_index
= find_utf8_constant (cpool
, name
);
377 = find_utf8_constant (cpool
,
378 identifier_subst (build_java_signature (type
),
380 return find_constant1 (cpool
, CONSTANT_NameAndType
,
381 (name_index
<< 16) | type_index
);
384 /* Look for a field ref that matches DECL in the constant pool of
386 Return the index of the entry. */
389 alloc_constant_fieldref (tree klass
, tree decl
)
391 CPool
*outgoing_cpool
= cpool_for_class (klass
);
393 = find_tree_constant (outgoing_cpool
, CONSTANT_Class
,
394 DECL_NAME (TYPE_NAME (DECL_CONTEXT (decl
))));
396 = find_name_and_type_constant_tree (outgoing_cpool
, DECL_NAME (decl
),
398 return find_constant1 (outgoing_cpool
, CONSTANT_Fieldref
,
399 (class_index
<< 16) | name_type_index
);
402 /* Build an identifier for the internal name of reference type TYPE. */
405 build_internal_class_name (tree type
)
408 if (TYPE_ARRAY_P (type
))
409 name
= build_java_signature (type
);
412 name
= TYPE_NAME (type
);
413 if (TREE_CODE (name
) != IDENTIFIER_NODE
)
414 name
= DECL_NAME (name
);
415 name
= identifier_subst (name
, "", '.', '/', "");
420 /* Look for a CONSTANT_Class entry for CLAS, creating a new one if needed. */
423 alloc_class_constant (tree clas
)
425 tree class_name
= build_internal_class_name (clas
);
427 return alloc_name_constant (CONSTANT_Class
,
429 (IDENTIFIER_POINTER(class_name
),
430 IDENTIFIER_LENGTH(class_name
))));
433 /* Return the decl of the data array of the current constant pool. */
436 build_constant_data_ref (bool indirect
)
441 tree cpool_type
= build_array_type (ptr_type_node
, NULL_TREE
);
442 tree decl
= build_class_ref (output_class
);
443 tree klass
= build1 (INDIRECT_REF
, TREE_TYPE (TREE_TYPE (decl
)),
445 tree constants
= build3 (COMPONENT_REF
,
446 TREE_TYPE (constants_field_decl_node
), klass
,
447 constants_field_decl_node
,
449 tree data
= build3 (COMPONENT_REF
,
450 TREE_TYPE (constants_data_field_decl_node
),
452 constants_data_field_decl_node
,
455 TREE_THIS_NOTRAP (klass
) = 1;
456 data
= fold_convert (build_pointer_type (cpool_type
), data
);
457 d
= build1 (INDIRECT_REF
, cpool_type
, data
);
463 tree decl_name
= mangled_classname ("_CD_", output_class
);
464 tree decl
= IDENTIFIER_GLOBAL_VALUE (decl_name
);
468 /* Build a type with unspecified bounds. The will make sure
469 that targets do the right thing with whatever size we end
470 up with at the end. Using bounds that are too small risks
471 assuming the data is in the small data section. */
472 tree type
= build_array_type (ptr_type_node
, NULL_TREE
);
474 /* We need to lay out the type ourselves, since build_array_type
475 thinks the type is incomplete. */
478 decl
= build_decl (input_location
, VAR_DECL
, decl_name
, type
);
479 TREE_STATIC (decl
) = 1;
480 IDENTIFIER_GLOBAL_VALUE (decl_name
) = decl
;
487 /* Get the pointer value at the INDEX'th element of the constant pool. */
490 build_ref_from_constant_pool (int index
)
493 tree d
= TYPE_CPOOL_DATA_REF (output_class
);
496 d
= build_constant_data_ref (flag_indirect_classes
);
498 i
= build_int_cst (NULL_TREE
, index
);
499 d
= build4 (ARRAY_REF
, TREE_TYPE (TREE_TYPE (d
)), d
, i
,
500 NULL_TREE
, NULL_TREE
);
504 /* Build an initializer for the constants field of the current constant pool.
505 Should only be called at top-level, since it may emit declarations. */
508 build_constants_constructor (void)
510 CPool
*outgoing_cpool
= cpool_for_class (current_class
);
511 tree tags_value
, data_value
;
513 vec
<constructor_elt
, va_gc
> *v
= NULL
;
515 vec
<constructor_elt
, va_gc
> *tags
= NULL
;
516 vec
<constructor_elt
, va_gc
> *data
= NULL
;
517 constructor_elt
*t
= NULL
;
518 constructor_elt
*d
= NULL
;
520 if (outgoing_cpool
->count
> 0)
522 int c
= outgoing_cpool
->count
;
523 vec_safe_grow_cleared (tags
, c
);
524 vec_safe_grow_cleared (data
, c
);
529 #define CONSTRUCTOR_PREPEND_VALUE(E, V) E->value = V, E--
530 for (i
= outgoing_cpool
->count
; --i
> 0; )
531 switch (outgoing_cpool
->tags
[i
] & ~CONSTANT_LazyFlag
)
533 case CONSTANT_None
: /* The second half of a Double or Long on a
535 case CONSTANT_Fieldref
:
536 case CONSTANT_NameAndType
:
538 case CONSTANT_Integer
:
539 case CONSTANT_Double
:
541 case CONSTANT_Methodref
:
542 case CONSTANT_InterfaceMethodref
:
544 unsigned HOST_WIDE_INT temp
= outgoing_cpool
->data
[i
].w
;
546 /* Make sure that on a big-endian machine with 64-bit
547 pointers this 32-bit jint appears in the first word.
548 FIXME: This is a kludge. The field we're initializing is
549 not a scalar but a union, and that's how we should
550 represent it in the compiler. We should fix this. */
551 if (BYTES_BIG_ENDIAN
)
552 temp
<<= ((POINTER_SIZE
> 32) ? POINTER_SIZE
- 32 : 0);
554 CONSTRUCTOR_PREPEND_VALUE (t
, get_tag_node (outgoing_cpool
->tags
[i
]));
555 CONSTRUCTOR_PREPEND_VALUE (d
, build_int_cst (ptr_type_node
, temp
));
560 case CONSTANT_String
:
561 case CONSTANT_Unicode
:
563 CONSTRUCTOR_PREPEND_VALUE (t
, get_tag_node (outgoing_cpool
->tags
[i
]));
564 CONSTRUCTOR_PREPEND_VALUE (d
, build_utf8_ref (outgoing_cpool
->data
[i
].t
));
570 #undef CONSTRUCTOR_PREPEND_VALUE
572 if (outgoing_cpool
->count
> 0)
574 tree data_decl
, tags_decl
, tags_type
;
575 tree max_index
= build_int_cst (sizetype
, outgoing_cpool
->count
- 1);
576 tree index_type
= build_index_type (max_index
);
579 /* Add dummy 0'th element of constant pool. */
580 gcc_assert (t
== tags
->address ());
581 gcc_assert (d
== data
->address ());
582 t
->value
= get_tag_node (0);
583 d
->value
= null_pointer_node
;
585 /* Change the type of the decl to have the proper array size.
586 ??? Make sure to transition the old type-pointer-to list to this
587 new type to not invalidate all build address expressions. */
588 data_decl
= build_constant_data_ref (false);
589 tem
= TYPE_POINTER_TO (TREE_TYPE (data_decl
));
591 tem
= build_pointer_type (TREE_TYPE (data_decl
));
592 TYPE_POINTER_TO (TREE_TYPE (data_decl
)) = NULL_TREE
;
593 TREE_TYPE (data_decl
) = build_array_type (ptr_type_node
, index_type
);
594 TYPE_POINTER_TO (TREE_TYPE (data_decl
)) = tem
;
595 DECL_INITIAL (data_decl
) = build_constructor (TREE_TYPE (data_decl
), data
);
596 DECL_SIZE (data_decl
) = TYPE_SIZE (TREE_TYPE (data_decl
));
597 DECL_SIZE_UNIT (data_decl
) = TYPE_SIZE_UNIT (TREE_TYPE (data_decl
));
598 rest_of_decl_compilation (data_decl
, 1, 0);
599 data_value
= build_address_of (data_decl
);
601 tags_type
= build_array_type (unsigned_byte_type_node
, index_type
);
602 tags_decl
= build_decl (input_location
,
603 VAR_DECL
, mangled_classname ("_CT_",
606 TREE_STATIC (tags_decl
) = 1;
607 DECL_INITIAL (tags_decl
) = build_constructor (tags_type
, tags
);
608 rest_of_decl_compilation (tags_decl
, 1, 0);
609 tags_value
= build_address_of (tags_decl
);
613 data_value
= null_pointer_node
;
614 tags_value
= null_pointer_node
;
616 START_RECORD_CONSTRUCTOR (v
, constants_type_node
);
617 PUSH_FIELD_VALUE (v
, "size",
618 build_int_cst (NULL_TREE
, outgoing_cpool
->count
));
619 PUSH_FIELD_VALUE (v
, "tags", tags_value
);
620 PUSH_FIELD_VALUE (v
, "data", data_value
);
621 FINISH_RECORD_CONSTRUCTOR (cons
, v
, constants_type_node
);
625 #include "gt-java-constants.h"