OSDN Git Service

* c-common.c (fname_as_string, c_type_hash): Constify.
[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    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 2, 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 COPYING.  If not, write to
18 the Free Software Foundation, 51 Franklin Street, Fifth Floor,
19 Boston, MA 02110-1301, USA. 
20
21 Java and all Java-based marks are trademarks or registered trademarks
22 of Sun Microsystems, Inc. in the United States and other countries.
23 The Free Software Foundation is independent of Sun Microsystems, Inc.  */
24
25 #include "config.h"
26 #include "system.h"
27 #include "coretypes.h"
28 #include "tm.h"
29 #include "jcf.h"
30 #include "tree.h"
31 #include "java-tree.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 = ggc_alloc_cleared (sizeof(uint8) * cpool->capacity);
49       cpool->data = ggc_alloc_cleared (sizeof(union cpool_entry)
50                                        * cpool->capacity);
51       cpool->count = 1;
52     }
53   if (index >= cpool->capacity)
54     {
55       int old_cap = cpool->capacity;
56       cpool->capacity *= 2;
57       if (index >= cpool->capacity)
58         cpool->capacity = index + 10;
59       cpool->tags = ggc_realloc (cpool->tags, 
60                                  sizeof(uint8) * cpool->capacity);
61       cpool->data = ggc_realloc (cpool->data,
62                                  sizeof(union cpool_entry) * 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 class)
334 {
335   CPool *cpool = TYPE_CPOOL (class);
336
337   if (cpool == NULL)
338     {
339       cpool = ggc_alloc_cleared (sizeof (struct CPool));
340       TYPE_CPOOL (class) = 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    CLASS.  
377    Return the index of the entry.  */
378
379 int
380 alloc_constant_fieldref (tree class, tree decl)
381 {
382   CPool *outgoing_cpool = cpool_for_class (class);
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       TREE_INVARIANT (d) = 1;
450
451       return d;
452     }
453   else
454     {
455       tree type, decl;
456       tree decl_name = mangled_classname ("_CD_", output_class);
457
458       /* Build a type with unspecified bounds.  The will make sure
459          that targets do the right thing with whatever size we end
460          up with at the end.  Using bounds that are too small risks
461          assuming the data is in the small data section.  */
462       type = build_array_type (ptr_type_node, NULL_TREE);
463
464       /* We need to lay out the type ourselves, since build_array_type
465          thinks the type is incomplete.  */
466       layout_type (type);
467
468       decl = build_decl (VAR_DECL, decl_name, type);
469       TREE_STATIC (decl) = 1;
470
471       return decl;
472     }
473 }
474
475 /* Get the pointer value at the INDEX'th element of the constant pool. */
476
477 tree
478 build_ref_from_constant_pool (int index)
479 {
480   tree i;
481   tree d = TYPE_CPOOL_DATA_REF (output_class);
482
483   if (d == NULL_TREE)
484     d = build_constant_data_ref (flag_indirect_classes);
485
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);
489   TREE_INVARIANT (d) = 1;
490   return d;
491 }
492
493 /* Build an initializer for the constants field of the current constant pool.
494    Should only be called at top-level, since it may emit declarations. */
495
496 tree
497 build_constants_constructor (void)
498 {
499   CPool *outgoing_cpool = cpool_for_class (current_class);
500   tree tags_value, data_value;
501   tree cons;
502   tree tags_list = NULL_TREE;
503   tree data_list = NULL_TREE;
504   int i;
505
506   for (i = outgoing_cpool->count;  --i > 0; )
507     switch (outgoing_cpool->tags[i] & ~CONSTANT_LazyFlag)
508       {
509       case CONSTANT_None:  /* The second half of a Double or Long on a
510                               32-bit target.  */
511       case CONSTANT_Fieldref:
512       case CONSTANT_NameAndType:
513       case CONSTANT_Float:
514       case CONSTANT_Integer:
515       case CONSTANT_Double:
516       case CONSTANT_Long:
517       case CONSTANT_Methodref:
518       case CONSTANT_InterfaceMethodref:
519         {
520           unsigned HOST_WIDE_INT temp = outgoing_cpool->data[i].w;
521
522           /* Make sure that on a 64-bit big-endian machine this
523              32-bit jint appears in the first word.  
524              FIXME: This is a kludge.  The field we're initializing is
525              not a scalar but a union, and that's how we should
526              represent it in the compiler.  We should fix this.  */
527           if (BYTES_BIG_ENDIAN && BITS_PER_WORD > 32)
528             temp <<= BITS_PER_WORD - 32;
529
530           tags_list
531             = tree_cons (NULL_TREE, get_tag_node (outgoing_cpool->tags[i]),
532                          tags_list);
533           data_list
534             = tree_cons (NULL_TREE, 
535                          fold_convert (ptr_type_node, 
536                                        (build_int_cst (NULL_TREE, temp))),
537                          data_list);
538         }
539         break;
540
541       case CONSTANT_Class:
542       case CONSTANT_String:
543       case CONSTANT_Unicode:
544       case CONSTANT_Utf8:
545         tags_list
546           = tree_cons (NULL_TREE, get_tag_node (outgoing_cpool->tags[i]),
547                        tags_list);
548         data_list
549           = tree_cons (NULL_TREE, build_utf8_ref (outgoing_cpool->data[i].t),
550                        data_list);
551         break;
552
553       default:
554         gcc_assert (false);
555       }
556   if (outgoing_cpool->count > 0)
557     {
558       tree data_decl, tags_decl, tags_type;
559       tree max_index = build_int_cst (sizetype, outgoing_cpool->count - 1);
560       tree index_type = build_index_type (max_index);
561
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);
565   
566       data_decl = build_constant_data_ref (false);
567       TREE_TYPE (data_decl) = build_array_type (ptr_type_node, index_type);
568       DECL_INITIAL (data_decl) = build_constructor_from_list
569                                   (TREE_TYPE (data_decl), data_list);
570       DECL_SIZE (data_decl) = TYPE_SIZE (TREE_TYPE (data_decl));
571       DECL_SIZE_UNIT (data_decl) = TYPE_SIZE_UNIT (TREE_TYPE (data_decl));
572       rest_of_decl_compilation (data_decl, 1, 0);
573       data_value = build_address_of (data_decl);
574
575       tags_type = build_array_type (unsigned_byte_type_node, index_type);
576       tags_decl = build_decl (VAR_DECL, mangled_classname ("_CT_", 
577                                                            current_class),
578                               tags_type);
579       TREE_STATIC (tags_decl) = 1;
580       DECL_INITIAL (tags_decl) = build_constructor_from_list
581                                  (tags_type, tags_list);
582       rest_of_decl_compilation (tags_decl, 1, 0);
583       tags_value = build_address_of (tags_decl);
584     }
585   else
586     {
587       data_value = null_pointer_node;
588       tags_value = null_pointer_node;
589     }
590   START_RECORD_CONSTRUCTOR (cons, constants_type_node);
591   PUSH_FIELD_VALUE (cons, "size",
592                     build_int_cst (NULL_TREE, outgoing_cpool->count));
593   PUSH_FIELD_VALUE (cons, "tags", tags_value);
594   PUSH_FIELD_VALUE (cons, "data", data_value);
595   FINISH_RECORD_CONSTRUCTOR (cons);
596   return cons;
597 }
598
599 #include "gt-java-constants.h"