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