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 */ index(Object obj)50 public int index(Object obj) { 51 return hash.get(obj).index; 52 } 53 54 /** 55 * Add an entry 56 */ put(Object obj)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 */ write(Environment env, DataOutputStream out)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 sortKey(ConstantPoolData f)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 xsort(ConstantPoolData ff[], String ss[], int left, int right)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 } 177