OSDN Git Service

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