OSDN Git Service

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