1 /* 2 * Copyright (c) 1999, 2008, 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 com.sun.tools.javac.jvm; 27 28 import java.util; 29 30 import com.sun.tools.javac.code.Symbol; 31 32 /** An internal structure that corresponds to the constant pool of a classfile. 33 * 34 * <p><b>This is NOT part of any supported API. 35 * If you write code that depends on this, you do so at your own risk. 36 * This code and its internal interfaces are subject to change or 37 * deletion without notice.</b> 38 */ 39 public class Pool { 40 41 public static final int MAX_ENTRIES = 0xFFFF; 42 public static final int MAX_STRING_LENGTH = 0xFFFF; 43 44 /** Index of next constant to be entered. 45 */ 46 int pp; 47 48 /** The initial pool buffer. 49 */ 50 Object[] pool; 51 52 /** A hashtable containing all constants in the pool. 53 */ 54 Map<Object,Integer> indices; 55 56 /** Construct a pool with given number of elements and element array. 57 */ 58 public Pool(int pp, Object[] pool) { 59 this.pp = pp; 60 this.pool = pool; 61 this.indices = new HashMap<Object,Integer>(pool.length); 62 for (int i = 1; i < pp; i++) { 63 if (pool[i] != null) indices.put(pool[i], i); 64 } 65 } 66 67 /** Construct an empty pool. 68 */ 69 public Pool() { 70 this(1, new Object[64]); 71 } 72 73 /** Return the number of entries in the constant pool. 74 */ 75 public int numEntries() { 76 return pp; 77 } 78 79 /** Remove everything from this pool. 80 */ 81 public void reset() { 82 pp = 1; 83 indices.clear(); 84 } 85 86 /** Double pool buffer in size. 87 */ 88 private void doublePool() { 89 Object[] newpool = new Object[pool.length * 2]; 90 System.arraycopy(pool, 0, newpool, 0, pool.length); 91 pool = newpool; 92 } 93 94 /** Place an object in the pool, unless it is already there. 95 * If object is a symbol also enter its owner unless the owner is a 96 * package. Return the object's index in the pool. 97 */ 98 public int put(Object value) { 99 if (value instanceof MethodSymbol) 100 value = new Method((MethodSymbol)value); 101 else if (value instanceof VarSymbol) 102 value = new Variable((VarSymbol)value); 103 // assert !(value instanceof Type.TypeVar); 104 Integer index = indices.get(value); 105 if (index == null) { 106 // System.err.println("put " + value + " " + value.getClass());//DEBUG 107 index = pp; 108 indices.put(value, index); 109 if (pp == pool.length) doublePool(); 110 pool[pp++] = value; 111 if (value instanceof Long || value instanceof Double) { 112 if (pp == pool.length) doublePool(); 113 pool[pp++] = null; 114 } 115 } 116 return index.intValue(); 117 } 118 119 /** Return the given object's index in the pool, 120 * or -1 if object is not in there. 121 */ 122 public int get(Object o) { 123 Integer n = indices.get(o); 124 return n == null ? -1 : n.intValue(); 125 } 126 127 static class Method extends DelegatedSymbol { 128 MethodSymbol m; 129 Method(MethodSymbol m) { 130 super(m); 131 this.m = m; 132 } 133 public boolean equals(Object other) { 134 if (!(other instanceof Method)) return false; 135 MethodSymbol o = ((Method)other).m; 136 return 137 o.name == m.name && 138 o.owner == m.owner && 139 o.type.equals(m.type); 140 } 141 public int hashCode() { 142 return 143 m.name.hashCode() * 33 + 144 m.owner.hashCode() * 9 + 145 m.type.hashCode(); 146 } 147 } 148 149 static class Variable extends DelegatedSymbol { 150 VarSymbol v; 151 Variable(VarSymbol v) { 152 super(v); 153 this.v = v; 154 } 155 public boolean equals(Object other) { 156 if (!(other instanceof Variable)) return false; 157 VarSymbol o = ((Variable)other).v; 158 return 159 o.name == v.name && 160 o.owner == v.owner && 161 o.type.equals(v.type); 162 } 163 public int hashCode() { 164 return 165 v.name.hashCode() * 33 + 166 v.owner.hashCode() * 9 + 167 v.type.hashCode(); 168 } 169 } 170 }