View Javadoc
1   /*
2    * Copyright (c) 1994, 2013, Oracle and/or its affiliates. All rights reserved.
3    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4    *
5    * This code is free software; you can redistribute it and/or modify it
6    * under the terms of the GNU General Public License version 2 only, as
7    * published by the Free Software Foundation.  Oracle designates this
8    * particular file as subject to the "Classpath" exception as provided
9    * by Oracle in the LICENSE file that accompanied this code.
10   *
11   * This code is distributed in the hope that it will be useful, but WITHOUT
12   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13   * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14   * version 2 for more details (a copy is included in the LICENSE file that
15   * accompanied this code).
16   *
17   * You should have received a copy of the GNU General Public License version
18   * 2 along with this work; if not, write to the Free Software Foundation,
19   * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20   *
21   * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22   * or visit www.oracle.com if you need additional information or have any
23   * questions.
24   */
25  
26  package sun.tools.asm;
27  
28  import sun.tools.java.*;
29  import sun.tools.tree.StringExpression;
30  import java.util.Enumeration;
31  import java.util.Hashtable;
32  import java.util.Vector;
33  import java.io.IOException;
34  import java.io.DataOutputStream;
35  
36  /**
37   * A table of constants
38   *
39   * WARNING: The contents of this source file are not part of any
40   * supported API.  Code that depends on them does so at its own risk:
41   * they are subject to change or removal without notice.
42   */
43  public final
44  class ConstantPool implements RuntimeConstants {
45      Hashtable<Object,ConstantPoolData> hash = new Hashtable<>(101);
46  
47      /**
48       * Find an entry, may return 0
49       */
50      public int index(Object obj) {
51          return hash.get(obj).index;
52      }
53  
54      /**
55       * Add an entry
56       */
57      public void put(Object obj) {
58          ConstantPoolData data = hash.get(obj);
59          if (data == null) {
60              if (obj instanceof String) {
61                  data = new StringConstantData(this, (String)obj);
62              } else if (obj instanceof StringExpression) {
63                  data = new StringExpressionConstantData(this, (StringExpression)obj);
64              } else if (obj instanceof ClassDeclaration) {
65                  data = new ClassConstantData(this, (ClassDeclaration)obj);
66              } else if (obj instanceof Type) {
67                  data = new ClassConstantData(this, (Type)obj);
68              } else if (obj instanceof MemberDefinition) {
69                  data = new FieldConstantData(this, (MemberDefinition)obj);
70              } else if (obj instanceof NameAndTypeData) {
71                  data = new NameAndTypeConstantData(this, (NameAndTypeData)obj);
72              } else if (obj instanceof Number) {
73                  data = new NumberConstantData(this, (Number)obj);
74              }
75              hash.put(obj, data);
76          }
77      }
78  
79      /**
80       * Write to output
81       */
82      public void write(Environment env, DataOutputStream out) throws IOException {
83          ConstantPoolData list[] = new ConstantPoolData[hash.size()];
84          String keys[] = new String[list.length];
85          int index = 1, count = 0;
86  
87          // Make a list of all the constant pool items
88          for (int n = 0 ; n < 5 ; n++) {
89              int first = count;
90              for (Enumeration<ConstantPoolData> e = hash.elements() ; e.hasMoreElements() ;) {
91                  ConstantPoolData data = e.nextElement();
92                  if (data.order() == n) {
93                      keys[count] = sortKey(data);
94                      list[count++] = data;
95                  }
96              }
97              xsort(list, keys, first, count-1);
98          }
99  
100         // Assign an index to each constant pool item
101         for (int n = 0 ; n < list.length ; n++) {
102             ConstantPoolData data = list[n];
103             data.index = index;
104             index += data.width();
105         }
106 
107         // Write length
108         out.writeShort(index);
109 
110         // Write each constant pool item
111         for (int n = 0 ; n < count ; n++) {
112             list[n].write(env, out, this);
113         }
114     }
115 
116     private
117     static String sortKey(ConstantPoolData f) {
118         if (f instanceof NumberConstantData) {
119             Number num = ((NumberConstantData)f).num;
120             String str = num.toString();
121             int key = 3;
122             if (num instanceof Integer)  key = 0;
123             else if (num instanceof Float)  key = 1;
124             else if (num instanceof Long)  key = 2;
125             return "\0" + (char)(str.length() + key<<8) + str;
126         }
127         if (f instanceof StringExpressionConstantData)
128             return (String)((StringExpressionConstantData)f).str.getValue();
129         if (f instanceof FieldConstantData) {
130             MemberDefinition fd = ((FieldConstantData)f).field;
131             return fd.getName()+" "+fd.getType().getTypeSignature()
132                 +" "+fd.getClassDeclaration().getName();
133         }
134         if (f instanceof NameAndTypeConstantData)
135             return  ((NameAndTypeConstantData)f).name+
136                 " "+((NameAndTypeConstantData)f).type;
137         if (f instanceof ClassConstantData)
138             return ((ClassConstantData)f).name;
139         return ((StringConstantData)f).str;
140     }
141 
142     /**
143      * Quick sort an array of pool entries and a corresponding array of Strings
144      * that are the sort keys for the field.
145      */
146     private
147     static void xsort(ConstantPoolData ff[], String ss[], int left, int right) {
148         if (left >= right)
149             return;
150         String pivot = ss[left];
151         int l = left;
152         int r = right;
153         while (l < r) {
154             while (l <= right && ss[l].compareTo(pivot) <= 0)
155                 l++;
156             while (r >= left && ss[r].compareTo(pivot) > 0)
157                 r--;
158             if (l < r) {
159                 // swap items at l and at r
160                 ConstantPoolData def = ff[l];
161                 String name = ss[l];
162                 ff[l] = ff[r]; ff[r] = def;
163                 ss[l] = ss[r]; ss[r] = name;
164             }
165         }
166         int middle = r;
167         // swap left and middle
168         ConstantPoolData def = ff[left];
169         String name = ss[left];
170         ff[left] = ff[middle]; ff[middle] = def;
171         ss[left] = ss[middle]; ss[middle] = name;
172         xsort(ff, ss, left, middle-1);
173         xsort(ff, ss, middle + 1, right);
174     }
175 
176 }