001: /*
002: * @(#)CVMSigForm.java 1.13 06/10/10
003: *
004: * Copyright 1990-2006 Sun Microsystems, Inc. All Rights Reserved.
005: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
006: *
007: * This program is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License version
009: * 2 only, as published by the Free Software Foundation.
010: *
011: * This program is distributed in the hope that it will be useful, but
012: * WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * General Public License version 2 for more details (a copy is
015: * included at /legal/license.txt).
016: *
017: * You should have received a copy of the GNU General Public License
018: * version 2 along with this work; if not, write to the Free Software
019: * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA
021: *
022: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
023: * Clara, CA 95054 or visit www.sun.com if you need additional
024: * information or have any questions.
025: *
026: */
027: package vm;
028:
029: /*
030: * A "form" is the same as a terse signature.
031: * It allows sharing of parts of method signatures,
032: * as well as facilitating JNI parameter passing.
033: */
034:
035: public class CVMSigForm {
036: /* instance data is all public for printing purposes */
037: public CVMSigForm hashNext; // hash chain
038: public CVMSigForm listNext; // enumeration chain
039: public int nSyllables;
040: public int data[];
041: public int listNo;
042: public int entryNo;
043:
044: /* static data, public for same reason */
045:
046: // the two hash tables we use to look these things up.
047: // the first is for instances for which data.length==1
048: // the second is for all others.
049: public final static int NSINGLETONHASH = 100;
050: public static CVMSigForm singletonHash[] = new CVMSigForm[NSINGLETONHASH];
051:
052: public final static int NBIGHASH = 1;
053: public static CVMSigForm bigHash[] = new CVMSigForm[NBIGHASH];
054:
055: public final static int SYLLABLESPERDATUM = 8;
056:
057: // the multiple lists of forms,
058: // which is how the writer would just as soon see them.
059: // make sure to call "enumerate" to fill in formNo.
060:
061: public static CVMSigForm formList[] = new CVMSigForm[2];
062: public static int listLength[] = new int[2];
063:
064: // for computing the "formNo", we assume that if data.length==1,
065: // a form takes a single slot. Then for each wordSizeIncrement additional
066: // words (or parts thereof), we allocate an additional slot.
067: // It would be nice if we had target-system information (such as
068: // the size of the structs we're union-ing with) at this point,
069: // but we don't so make some assumptions.
070:
071: static int wordSizeIncrement = 3;
072:
073: // statistics
074: static int nSingletonForms = 0;
075: static int nBigForms = 0;
076:
077: /* constructor and constructor-related */
078:
079: private CVMSigForm(int nSyl, int datawords[]) {
080: nSyllables = nSyl;
081: // COPY the data, as it is probably in a reusable temporary
082: // buffer
083: data = new int[(nSyl + SYLLABLESPERDATUM - 1)
084: / SYLLABLESPERDATUM];
085: System.arraycopy(datawords, 0, data, 0, data.length);
086: enlist(this );
087: }
088:
089: private static synchronized void enlist(CVMSigForm thing) {
090: int listNo = thing.nSlots() - 1;
091: if (formList.length <= listNo) {
092: CVMSigForm newList[] = new CVMSigForm[listNo + 1];
093: System.arraycopy(formList, 0, newList, 0, formList.length);
094: formList = newList;
095: int newLength[] = new int[listNo + 1];
096: System.arraycopy(listLength, 0, newLength, 0,
097: listLength.length);
098: listLength = newLength;
099: }
100: thing.listNext = formList[listNo];
101: formList[listNo] = thing;
102: listLength[listNo] += 1;
103: thing.listNo = listNo;
104: }
105:
106: /* instance methods */
107: public int nSlots() {
108: int nDataWords = (this .nSyllables + SYLLABLESPERDATUM - 1)
109: / SYLLABLESPERDATUM;
110: return nDataWords;
111: }
112:
113: /* static methods */
114:
115: public static void setWordSizeIncrement(int n) {
116: wordSizeIncrement = n;
117: }
118:
119: public static CVMSigForm lookup(int nSyl, int d[]) {
120: int hashbucket;
121: CVMSigForm hashTable[];
122: CVMSigForm f;
123: /*
124: * If we cared more about performance, we'd specialize
125: * the singleton search further. For now, just get it right!
126: */
127: if (nSyl <= SYLLABLESPERDATUM) {
128: hashbucket = (int) (((long) d[0] & 0xffffffffL) % NSINGLETONHASH);
129: hashTable = singletonHash;
130: } else {
131: hashbucket = 0; // kill me.
132: hashTable = bigHash;
133: }
134: searchloop: for (f = hashTable[hashbucket]; f != null; f = f.hashNext) {
135: if (f.nSyllables != nSyl)
136: continue;
137: for (int i = 0; i < f.data.length; i++) {
138: if (f.data[i] != d[i]) {
139: continue searchloop;
140: }
141: }
142: // found it!
143: return f;
144: }
145: // fell out of the loop because it wasn't there.
146: // put it there.
147: f = new CVMSigForm(nSyl, d);
148: f.hashNext = hashTable[hashbucket];
149: hashTable[hashbucket] = f;
150: if (nSyl <= SYLLABLESPERDATUM) {
151: nSingletonForms += 1;
152: } else {
153: nBigForms += 1;
154: }
155: return f;
156: }
157:
158: }
|