Index: compiler/org/eclipse/jdt/internal/compiler/ClassFile.java =================================================================== RCS file: /home/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ClassFile.java,v retrieving revision 1.111 diff -u -r1.111 ClassFile.java --- compiler/org/eclipse/jdt/internal/compiler/ClassFile.java 30 May 2005 17:05:38 -0000 1.111 +++ compiler/org/eclipse/jdt/internal/compiler/ClassFile.java 21 Jul 2005 20:38:31 -0000 @@ -626,7 +626,7 @@ if (this.referenceBinding instanceof LocalTypeBinding) { MethodBinding methodBinding = ((LocalTypeBinding) this.referenceBinding).enclosingMethod; if (methodBinding != null) { - int enclosingMethodIndex = constantPool.literalIndexForMethod(methodBinding.selector, methodBinding.signature()); + int enclosingMethodIndex = constantPool.literalIndexForNameAndType(methodBinding.selector, methodBinding.signature()); methodIndexByte1 = (byte) (enclosingMethodIndex >> 8); methodIndexByte2 = (byte) enclosingMethodIndex; } @@ -2861,7 +2861,7 @@ * @return char[] */ public char[] fileName() { - return constantPool.UTF8Cache.returnKeyFor(1); + return constantPool.UTF8Cache.returnKeyFor(2); } private void generateAnnotation(Annotation annotation, int attributeOffset) { Index: compiler/org/eclipse/jdt/internal/compiler/codegen/CharArrayCache.java =================================================================== RCS file: /home/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/CharArrayCache.java,v retrieving revision 1.20 diff -u -r1.20 CharArrayCache.java --- compiler/org/eclipse/jdt/internal/compiler/codegen/CharArrayCache.java 23 Feb 2005 02:47:47 -0000 1.20 +++ compiler/org/eclipse/jdt/internal/compiler/codegen/CharArrayCache.java 21 Jul 2005 20:38:31 -0000 @@ -77,15 +77,40 @@ return -1; } private int hashCodeChar(char[] val) { - int length = val.length; + final int length = val.length; int hash = 0; - int n = 2; // number of characters skipped + final int n = 3; // number of characters skipped for (int i = 0; i < length; i += n) { hash += val[i]; } return (hash & 0x7FFFFFFF) % keyTable.length; } /** + * Puts the specified element into the hashtable if it wasn't there already, + * using the specified key. The element may be retrieved by doing a get() with the same key. + * The key and the element cannot be null. + * + * @param key the given key in the hashtable + * @param value the given value + * @return int the old value of the key, or -value if it did not have one. + */ +public int putIfAbsent(char[] key, int value) { + int index = hashCodeChar(key); + while (keyTable[index] != null) { + if (CharOperation.equals(keyTable[index], key)) + return valueTable[index]; + index = (index + 1) % keyTable.length; + } + keyTable[index] = key; + valueTable[index] = value; + + // assumes the threshold is never equal to the size of the table + if (++elementSize > threshold) + rehash(); + return -value; // negative when added (value is assumed to be > 0) +} + +/** * Puts the specified element into the hashtable, using the specified * key. The element may be retrieved by doing a get() with the same key. * The key and the element cannot be null. @@ -94,7 +119,7 @@ * @param value int the specified element * @return int the old value of the key, or -1 if it did not have one. */ -public int put(char[] key, int value) { +private int put(char[] key, int value) { int index = hashCodeChar(key); while (keyTable[index] != null) { if (CharOperation.equals(keyTable[index], key)) Index: compiler/org/eclipse/jdt/internal/compiler/codegen/CodeStream.java =================================================================== RCS file: /home/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/CodeStream.java,v retrieving revision 1.110 diff -u -r1.110 CodeStream.java --- compiler/org/eclipse/jdt/internal/compiler/codegen/CodeStream.java 13 Jul 2005 13:59:10 -0000 1.110 +++ compiler/org/eclipse/jdt/internal/compiler/codegen/CodeStream.java 21 Jul 2005 20:38:31 -0000 @@ -3334,7 +3334,12 @@ } position += 3; bCodeStream[classFileOffset++] = OPC_invokeinterface; - writeUnsignedShort(constantPool.literalIndex(methodBinding)); + writeUnsignedShort( + constantPool.literalIndexForMethod( + methodBinding.constantPoolDeclaringClass().constantPoolName(), + methodBinding.selector, + methodBinding.signature(), + true)); for (int i = methodBinding.parameters.length - 1; i >= 0; i--) if (((id = methodBinding.parameters[i].id) == T_double) || (id == T_long)) argCount += 2; @@ -3402,7 +3407,12 @@ } position++; bCodeStream[classFileOffset++] = OPC_invokespecial; - writeUnsignedShort(constantPool.literalIndex(methodBinding)); + writeUnsignedShort( + constantPool.literalIndexForMethod( + methodBinding.constantPoolDeclaringClass().constantPoolName(), + methodBinding.selector, + methodBinding.signature(), + false)); if (methodBinding.isConstructor() && methodBinding.declaringClass.isNestedType()) { // enclosing instances TypeBinding[] syntheticArgumentTypes = methodBinding.declaringClass.syntheticEnclosingInstanceTypes(); @@ -3454,7 +3464,12 @@ } position++; bCodeStream[classFileOffset++] = OPC_invokestatic; - writeUnsignedShort(constantPool.literalIndex(methodBinding)); + writeUnsignedShort( + constantPool.literalIndexForMethod( + methodBinding.constantPoolDeclaringClass().constantPoolName(), + methodBinding.selector, + methodBinding.signature(), + false)); for (int i = methodBinding.parameters.length - 1; i >= 0; i--) if (((id = methodBinding.parameters[i].id) == T_double) || (id == T_long)) argCount += 2; @@ -3873,7 +3888,12 @@ } position++; bCodeStream[classFileOffset++] = OPC_invokevirtual; - writeUnsignedShort(constantPool.literalIndex(methodBinding)); + writeUnsignedShort( + constantPool.literalIndexForMethod( + methodBinding.constantPoolDeclaringClass().constantPoolName(), + methodBinding.selector, + methodBinding.signature(), + false)); for (int i = methodBinding.parameters.length - 1; i >= 0; i--) if (((id = methodBinding.parameters[i].id) == T_double) || (id == T_long)) argCount += 2; Index: compiler/org/eclipse/jdt/internal/compiler/codegen/ConstantPool.java =================================================================== RCS file: /home/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/ConstantPool.java,v retrieving revision 1.44 diff -u -r1.44 ConstantPool.java --- compiler/org/eclipse/jdt/internal/compiler/codegen/ConstantPool.java 7 Jul 2005 10:44:03 -0000 1.44 +++ compiler/org/eclipse/jdt/internal/compiler/codegen/ConstantPool.java 21 Jul 2005 20:38:31 -0000 @@ -12,9 +12,6 @@ import org.eclipse.jdt.internal.compiler.ClassFile; import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants; -import org.eclipse.jdt.internal.compiler.lookup.FieldBinding; -import org.eclipse.jdt.internal.compiler.lookup.MethodBinding; -import org.eclipse.jdt.internal.compiler.lookup.TypeBinding; import org.eclipse.jdt.internal.compiler.lookup.TypeConstants; import org.eclipse.jdt.internal.compiler.lookup.TypeIds; import org.eclipse.jdt.internal.compiler.util.HashtableOfObject; @@ -264,37 +261,16 @@ System.arraycopy(poolContent, 0, (poolContent = new byte[currentOffset]), 0, currentOffset); return poolContent; } -private int getFromCache(char[] declaringClass, char[] name, char[] signature) { - HashtableOfObject value = (HashtableOfObject) this.methodsAndFieldsCache.get(declaringClass); - if (value == null) { - return -1; - } - CharArrayCache value2 = (CharArrayCache) value.get(name); - if (value2 == null) { - return -1; - } - return value2.get(signature); -} -private int getFromNameAndTypeCache(char[] name, char[] signature) { - CharArrayCache value = (CharArrayCache) this.nameAndTypeCacheForFieldsAndMethods.get(name); - if (value == null) { - return -1; - } - return value.get(signature); -} public int literalIndex(byte[] utf8encoding, char[] stringCharArray) { int index; - if ((index = UTF8Cache.get(stringCharArray)) < 0) { + if ((index = UTF8Cache.putIfAbsent(stringCharArray, this.currentIndex)) < 0) { // The entry doesn't exit yet - index = UTF8Cache.put(stringCharArray, currentIndex); - if (index > 0xFFFF){ + if ((index = -index)> 0xFFFF){ this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType()); } currentIndex++; // Write the tag first writeU1(Utf8Tag); - // Then the size of the stringName array - //writeU2(utf8Constant.length); int savedCurrentOffset = currentOffset; int utf8encodingLength = utf8encoding.length; if (currentOffset + 2 + utf8encodingLength >= poolContent.length) { @@ -321,7 +297,8 @@ */ public int literalIndex(char[] utf8Constant) { int index; - if ((index = UTF8Cache.get(utf8Constant)) < 0) { + if ((index = UTF8Cache.putIfAbsent(utf8Constant, this.currentIndex)) < 0) { + index = -index; // The entry doesn't exit yet // Write the tag first writeU1(Utf8Tag); @@ -359,7 +336,6 @@ currentOffset = savedCurrentOffset - 1; this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceForConstant(this.classFile.referenceBinding.scope.referenceType()); } - index = UTF8Cache.put(utf8Constant, currentIndex); if (index > 0xFFFF){ this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType()); } @@ -373,18 +349,24 @@ } public int literalIndex(char[] stringCharArray, byte[] utf8encoding) { int index; - int stringIndex; - if ((index = stringCache.get(stringCharArray)) < 0) { + if ((index = stringCache.putIfAbsent(stringCharArray, this.currentIndex)) < 0) { // The entry doesn't exit yet - stringIndex = literalIndex(utf8encoding, stringCharArray); - index = stringCache.put(stringCharArray, currentIndex++); - if (index > 0xFFFF){ + this.currentIndex++; + if ((index = -index) > 0xFFFF){ this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType()); } // Write the tag first writeU1(StringTag); // Then the string index - writeU2(stringIndex); + int stringIndexOffset = this.currentOffset; + if (currentOffset + 2 >= poolContent.length) { + resizePoolContents(2); + } + currentOffset+=2; + + final int stringIndex = literalIndex(utf8encoding, stringCharArray); + poolContent[stringIndexOffset++] = (byte) (stringIndex >> 8); + poolContent[stringIndexOffset] = (byte) stringIndex; } return index; } @@ -406,12 +388,11 @@ if (doubleCache == null) { doubleCache = new DoubleCache(DOUBLE_INITIAL_SIZE); } - if ((index = doubleCache.get(key)) < 0) { - index = doubleCache.put(key, currentIndex++); - if (index > 0xFFFF){ + if ((index = doubleCache.putIfAbsent(key, this.currentIndex)) < 0) { + if ((index = -index)> 0xFFFF){ this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType()); } - currentIndex++; // a double needs an extra place into the constant pool + this.currentIndex += 2; // a double needs an extra place into the constant pool // Write the double into the constant pool // First add the tag writeU1(DoubleTag); @@ -421,9 +402,14 @@ if (currentOffset + 8 >= length) { resizePoolContents(8); } - for (int i = 0; i < 8; i++) { - poolContent[currentOffset++] = (byte) (temp >>> (56 - (i << 3))); - } + poolContent[currentOffset++] = (byte) (temp >>> 56); + poolContent[currentOffset++] = (byte) (temp >>> 48); + poolContent[currentOffset++] = (byte) (temp >>> 40); + poolContent[currentOffset++] = (byte) (temp >>> 32); + poolContent[currentOffset++] = (byte) (temp >>> 24); + poolContent[currentOffset++] = (byte) (temp >>> 16); + poolContent[currentOffset++] = (byte) (temp >>> 8); + poolContent[currentOffset++] = (byte) temp; } return index; } @@ -443,11 +429,11 @@ if (floatCache == null) { floatCache = new FloatCache(FLOAT_INITIAL_SIZE); } - if ((index = floatCache.get(key)) < 0) { - index = floatCache.put(key, currentIndex++); - if (index > 0xFFFF){ + if ((index = floatCache.putIfAbsent(key, this.currentIndex)) < 0) { + if ((index = -index) > 0xFFFF){ this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType()); } + this.currentIndex++; // Write the float constant entry into the constant pool // First add the tag writeU1(FloatTag); @@ -456,9 +442,10 @@ if (currentOffset + 4 >= poolContent.length) { resizePoolContents(4); } - for (int i = 0; i < 4; i++) { - poolContent[currentOffset++] = (byte) (temp >>> (24 - i * 8)); - } + poolContent[currentOffset++] = (byte) (temp >>> 24); + poolContent[currentOffset++] = (byte) (temp >>> 16); + poolContent[currentOffset++] = (byte) (temp >>> 8); + poolContent[currentOffset++] = (byte) temp; } return index; } @@ -478,21 +465,22 @@ if (intCache == null) { intCache = new IntegerCache(INT_INITIAL_SIZE); } - if ((index = intCache.get(key)) < 0) { - index = intCache.put(key, currentIndex++); - if (index > 0xFFFF){ + if ((index = intCache.putIfAbsent(key, this.currentIndex)) < 0) { + this.currentIndex++; + if ((index = -index) > 0xFFFF){ this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType()); } - // Write the integer constant entry into the constant pool + // Write the integer constant entry into the constant pool // First add the tag writeU1(IntegerTag); // Then add the 4 bytes representing the int if (currentOffset + 4 >= poolContent.length) { resizePoolContents(4); } - for (int i = 0; i < 4; i++) { - poolContent[currentOffset++] = (byte) (key >>> (24 - i * 8)); - } + poolContent[currentOffset++] = (byte) (key >>> 24); + poolContent[currentOffset++] = (byte) (key >>> 16); + poolContent[currentOffset++] = (byte) (key >>> 8); + poolContent[currentOffset++] = (byte) key; } return index; } @@ -514,12 +502,11 @@ if (longCache == null) { longCache = new LongCache(LONG_INITIAL_SIZE); } - if ((index = longCache.get(key)) < 0) { - index = longCache.put(key, currentIndex++); - if (index > 0xFFFF){ + if ((index = longCache.putIfAbsent(key, this.currentIndex)) < 0) { + if ((index = -index) > 0xFFFF){ this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType()); } - currentIndex++; // long value need an extra place into thwe constant pool + this.currentIndex+= 2; // long value need an extra place into thwe constant pool // Write the long into the constant pool // First add the tag writeU1(LongTag); @@ -527,9 +514,14 @@ if (currentOffset + 8 >= poolContent.length) { resizePoolContents(8); } - for (int i = 0; i < 8; i++) { - poolContent[currentOffset++] = (byte) (key >>> (56 - (i << 3))); - } + poolContent[currentOffset++] = (byte) (key >>> 56); + poolContent[currentOffset++] = (byte) (key >>> 48); + poolContent[currentOffset++] = (byte) (key >>> 40); + poolContent[currentOffset++] = (byte) (key >>> 32); + poolContent[currentOffset++] = (byte) (key >>> 24); + poolContent[currentOffset++] = (byte) (key >>> 16); + poolContent[currentOffset++] = (byte) (key >>> 8); + poolContent[currentOffset++] = (byte) key; } return index; } @@ -542,75 +534,23 @@ public int literalIndex(String stringConstant) { int index; char[] stringCharArray = stringConstant.toCharArray(); - if ((index = stringCache.get(stringCharArray)) < 0) { + if ((index = stringCache.putIfAbsent(stringCharArray, this.currentIndex)) < 0) { // The entry doesn't exit yet - int stringIndex = literalIndex(stringCharArray); - index = stringCache.put(stringCharArray, currentIndex++); - if (index > 0xFFFF){ + currentIndex++; + if ((index = -index)> 0xFFFF){ this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType()); } // Write the tag first writeU1(StringTag); // Then the string index - writeU2(stringIndex); - } - return index; -} -/** - * This method returns the index into the constantPool - * corresponding to the field binding aFieldBinding. - * - * @param aFieldBinding FieldBinding - * @return int - */ -public int literalIndex(FieldBinding aFieldBinding) { - int index; - final char[] name = aFieldBinding.name; - final char[] signature = aFieldBinding.type.signature(); - final char[] declaringClassConstantPoolName = aFieldBinding.declaringClass.constantPoolName(); - if ((index = getFromCache(declaringClassConstantPoolName, name, signature)) < 0) { - // The entry doesn't exit yet - int classIndex = literalIndexForType(declaringClassConstantPoolName); - int nameAndTypeIndex = literalIndexForFields(literalIndex(name), literalIndex(signature), name, signature); - index = putInCache(declaringClassConstantPoolName, name, signature, currentIndex++); - if (index > 0xFFFF){ - this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType()); - } - writeU1(FieldRefTag); - writeU2(classIndex); - writeU2(nameAndTypeIndex); - } - return index; -} -/** - * This method returns the index into the constantPool corresponding to the - * method descriptor. It can be either an interface method reference constant - * or a method reference constant. - * Note: uses the method binding #constantPoolDeclaringClass which could be an array type - * for the array clone method (see UpdatedMethodDeclaration). - * @param aMethodBinding MethodBinding - * @return int - */ -public int literalIndex(MethodBinding aMethodBinding) { - int index; - final TypeBinding constantPoolDeclaringClass = aMethodBinding.constantPoolDeclaringClass(); - final char[] declaringClassConstantPoolName = constantPoolDeclaringClass.constantPoolName(); - final char[] selector = aMethodBinding.selector; - final char[] signature = aMethodBinding.signature(); - if ((index = getFromCache(declaringClassConstantPoolName, selector, signature)) < 0) { - int classIndex = literalIndexForType(constantPoolDeclaringClass.constantPoolName()); - int nameAndTypeIndex = literalIndexForMethods(literalIndex(selector), literalIndex(signature), selector, signature); - index = putInCache(declaringClassConstantPoolName, selector, signature, currentIndex++); - if (index > 0xFFFF){ - this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType()); + int stringIndexOffset = this.currentOffset; + if (currentOffset + 2 >= poolContent.length) { + resizePoolContents(2); } - // Write the interface method ref constant into the constant pool - // First add the tag - writeU1(constantPoolDeclaringClass.isInterface() || constantPoolDeclaringClass.isAnnotationType() ? InterfaceMethodRefTag : MethodRefTag); - // Then write the class index - writeU2(classIndex); - // The write the nameAndType index - writeU2(nameAndTypeIndex); + currentOffset+=2; + final int stringIndex = literalIndex(stringCharArray); + poolContent[stringIndexOffset++] = (byte) (stringIndex >> 8); + poolContent[stringIndexOffset] = (byte) stringIndex; } return index; } @@ -620,133 +560,102 @@ */ public int literalIndexForType(final char[] constantPoolName) { int index; - if ((index = classCache.get(constantPoolName)) < 0) { + if ((index = classCache.putIfAbsent(constantPoolName, this.currentIndex)) < 0) { // The entry doesn't exit yet - int nameIndex = literalIndex(constantPoolName); - index = classCache.put(constantPoolName, currentIndex++); - if (index > 0xFFFF){ + this.currentIndex++; + if ((index = -index) > 0xFFFF){ this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType()); } writeU1(ClassTag); - // Then add the 8 bytes representing the long - writeU2(nameIndex); + + // Then the name index + int nameIndexOffset = this.currentOffset; + if (currentOffset + 2 >= poolContent.length) { + resizePoolContents(2); + } + currentOffset+=2; + final int nameIndex = literalIndex(constantPoolName); + poolContent[nameIndexOffset++] = (byte) (nameIndex >> 8); + poolContent[nameIndexOffset] = (byte) nameIndex; } return index; } public int literalIndexForMethod(char[] declaringClass, char[] selector, char[] signature, boolean isInterface) { - int index = getFromCache(declaringClass, selector, signature); - if (index == -1) { - int classIndex; - if ((classIndex = classCache.get(declaringClass)) < 0) { - // The entry doesn't exit yet - int nameIndex = literalIndex(declaringClass); - classIndex = classCache.put(declaringClass, this.currentIndex++); - if (index > 0xFFFF){ - this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType()); - } - writeU1(ClassTag); - // Then add the 8 bytes representing the long - writeU2(nameIndex); - } - int nameAndTypeIndex = literalIndexForMethod(selector, signature); - index = putInCache(declaringClass, selector, signature, currentIndex++); - if (index > 0xFFFF){ + int index; + if ((index = putInCacheIfAbsent(declaringClass, selector, signature, this.currentIndex)) < 0) { + // it doesn't exist yet + this.currentIndex++; + if ((index = -index) > 0xFFFF){ this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType()); } // Write the interface method ref constant into the constant pool // First add the tag writeU1(isInterface ? InterfaceMethodRefTag : MethodRefTag); - // Then write the class index - writeU2(classIndex); - // The write the nameAndType index - writeU2(nameAndTypeIndex); - } - return index; -} -private int literalIndexForField(char[] name, char[] signature) { - int index = getFromNameAndTypeCache(name, signature); - if (index == -1) { - // The entry doesn't exit yet - int nameIndex = literalIndex(name); - int typeIndex = literalIndex(signature); - index = putInNameAndTypeCache(name, signature, currentIndex++); - if (index > 0xFFFF){ - this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType()); + + int classIndexOffset = this.currentOffset; + if (currentOffset + 4 >= poolContent.length) { + resizePoolContents(4); } - writeU1(NameAndTypeTag); - writeU2(nameIndex); - writeU2(typeIndex); + currentOffset+=4; + + final int classIndex = literalIndexForType(declaringClass); + final int nameAndTypeIndex = literalIndexForNameAndType(selector, signature); + + poolContent[classIndexOffset++] = (byte) (classIndex >> 8); + poolContent[classIndexOffset++] = (byte) classIndex; + poolContent[classIndexOffset++] = (byte) (nameAndTypeIndex >> 8); + poolContent[classIndexOffset] = (byte) nameAndTypeIndex; } return index; } -public int literalIndexForMethod(char[] selector, char[] signature) { - int index = getFromNameAndTypeCache(selector, signature); - if (index == -1) { +public int literalIndexForNameAndType(char[] name, char[] signature) { + int index; + if ((index = putInNameAndTypeCacheIfAbsent(name, signature, currentIndex)) < 0) { // The entry doesn't exit yet - int nameIndex = literalIndex(selector); - int typeIndex = literalIndex(signature); - index = putInNameAndTypeCache(selector, signature, currentIndex++); - if (index > 0xFFFF){ + currentIndex++; + if ((index = -index) > 0xFFFF){ this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType()); } writeU1(NameAndTypeTag); - writeU2(nameIndex); - writeU2(typeIndex); + int nameIndexOffset = this.currentOffset; + if (currentOffset + 4 >= poolContent.length) { + resizePoolContents(4); + } + currentOffset+=4; + + final int nameIndex = literalIndex(name); + final int typeIndex = literalIndex(signature); + poolContent[nameIndexOffset++] = (byte) (nameIndex >> 8); + poolContent[nameIndexOffset++] = (byte) nameIndex; + poolContent[nameIndexOffset++] = (byte) (typeIndex >> 8); + poolContent[nameIndexOffset] = (byte) typeIndex; } return index; } public int literalIndexForField(char[] declaringClass, char[] name, char[] signature) { - int index = getFromCache(declaringClass, name, signature); - if (index == -1) { - int classIndex; - if ((classIndex = classCache.get(declaringClass)) < 0) { - // The entry doesn't exit yet - int nameIndex = literalIndex(declaringClass); - classIndex = classCache.put(declaringClass, this.currentIndex++); - if (index > 0xFFFF){ - this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType()); - } - writeU1(ClassTag); - // Then add the 8 bytes representing the long - writeU2(nameIndex); - } - int nameAndTypeIndex = literalIndexForField(name, signature); - index = putInCache(declaringClass, name, signature, currentIndex++); - if (index > 0xFFFF){ + int index; + if ((index = putInCacheIfAbsent(declaringClass, name, signature, this.currentIndex)) < 0) { + this.currentIndex++; + // doesn't exist yet + if ((index = -index) > 0xFFFF){ this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType()); } // Write the interface method ref constant into the constant pool // First add the tag writeU1(FieldRefTag); - // Then write the class index - writeU2(classIndex); - // The write the nameAndType index - writeU2(nameAndTypeIndex); - } - return index; -} -/** - * This method returns the index into the constantPool corresponding - * nameAndType constant with nameIndex, typeIndex. - * - * @param nameIndex the given name index - * @param typeIndex the given type index - * @param name the given field name - * @param signature the given field signature - * @return the index into the constantPool corresponding - * nameAndType constant with nameIndex, typeInde - */ -private int literalIndexForFields(int nameIndex, int typeIndex, char[] name, char[] signature) { - int index; - if ((index = getFromNameAndTypeCache(name, signature)) == -1) { - // The entry doesn't exit yet - index = putInNameAndTypeCache(name, signature, currentIndex++); - if (index > 0xFFFF){ - this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType()); + int classIndexOffset = this.currentOffset; + if (currentOffset + 4 >= poolContent.length) { + resizePoolContents(4); } - writeU1(NameAndTypeTag); - writeU2(nameIndex); - writeU2(typeIndex); + currentOffset+=4; + + final int classIndex = literalIndexForType(declaringClass); + final int nameAndTypeIndex = literalIndexForNameAndType(name, signature); + + poolContent[classIndexOffset++] = (byte) (classIndex >> 8); + poolContent[classIndexOffset++] = (byte) classIndex; + poolContent[classIndexOffset++] = (byte) (nameAndTypeIndex >> 8); + poolContent[classIndexOffset] = (byte) nameAndTypeIndex; } return index; } @@ -758,11 +667,23 @@ */ public int literalIndexForLdc(char[] stringCharArray) { int index; - if ((index = stringCache.get(stringCharArray)) < 0) { - int stringIndex; + if ((index = stringCache.putIfAbsent(stringCharArray, this.currentIndex)) < 0) { // The entry doesn't exit yet - if ((stringIndex = UTF8Cache.get(stringCharArray)) < 0) { + this.currentIndex++; + // Write the tag first + writeU1(StringTag); + + // Then the string index + int stringIndexOffset = this.currentOffset; + if (currentOffset + 2 >= poolContent.length) { + resizePoolContents(2); + } + currentOffset+=2; + + int stringIndex; + if ((stringIndex = UTF8Cache.putIfAbsent(stringCharArray, this.currentIndex)) < 0) { // The entry doesn't exit yet + this.currentIndex++; // Write the tag first writeU1(Utf8Tag); // Then the size of the stringName array @@ -778,79 +699,68 @@ char current = stringCharArray[i]; if ((current >= 0x0001) && (current <= 0x007F)) { // we only need one byte: ASCII table - writeU1(current); length++; + if (currentOffset + 1 >= poolContent.length) { + // we need to resize the poolContent array because we won't have + // enough space to write the length + resizePoolContents(1); + } + poolContent[currentOffset++] = (byte)(current); } else if (current > 0x07FF) { // we need 3 bytes length += 3; - writeU1(0xE0 | ((current >> 12) & 0x0F)); // 0xE0 = 1110 0000 - writeU1(0x80 | ((current >> 6) & 0x3F)); // 0x80 = 1000 0000 - writeU1(0x80 | (current & 0x3F)); // 0x80 = 1000 0000 + if (currentOffset + 3 >= poolContent.length) { + // we need to resize the poolContent array because we won't have + // enough space to write the length + resizePoolContents(3); + } + poolContent[currentOffset++] = (byte) (0xE0 | ((current >> 12) & 0x0F)); // 0xE0 = 1110 0000 + poolContent[currentOffset++] = (byte) (0x80 | ((current >> 6) & 0x3F)); // 0x80 = 1000 0000 + poolContent[currentOffset++] = (byte) (0x80 | (current & 0x3F)); // 0x80 = 1000 0000 } else { + if (currentOffset + 2 >= poolContent.length) { + // we need to resize the poolContent array because we won't have + // enough space to write the length + resizePoolContents(2); + } // we can be 0 or between 0x0080 and 0x07FF // In that case we only need 2 bytes length += 2; - writeU1(0xC0 | ((current >> 6) & 0x1F)); // 0xC0 = 1100 0000 - writeU1(0x80 | (current & 0x3F)); // 0x80 = 1000 0000 + poolContent[currentOffset++] = (byte) (0xC0 | ((current >> 6) & 0x1F)); // 0xC0 = 1100 0000 + poolContent[currentOffset++] = (byte) (0x80 | (current & 0x3F)); // 0x80 = 1000 0000 } } if (length >= 65535) { currentOffset = savedCurrentOffset - 1; - return -1; + return 0; } - stringIndex = UTF8Cache.put(stringCharArray, currentIndex++); // Now we know the length that we have to write in the constant pool // we use savedCurrentOffset to do that if (length > 65535) { return 0; } - poolContent[savedCurrentOffset] = (byte) (length >> 8); - poolContent[savedCurrentOffset + 1] = (byte) length; - } - index = stringCache.put(stringCharArray, currentIndex++); - if (index > 0xFFFF){ - this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType()); + poolContent[savedCurrentOffset++] = (byte) (length >> 8); + poolContent[savedCurrentOffset] = (byte) length; + stringIndex = -stringIndex; } - // Write the tag first - writeU1(StringTag); - // Then the string index - writeU2(stringIndex); - } - return index; -} -/** - * This method returns the index into the constantPool corresponding - * nameAndType constant with nameIndex, typeIndex. - * - * @param nameIndex the given name index - * @param typeIndex the given type index - * @param selector the given method selector - * @param signature the given method signature - * @return int - */ -public int literalIndexForMethods(int nameIndex, int typeIndex, char[] selector, char[] signature) { - int index; - if ((index = getFromNameAndTypeCache(selector, signature)) == -1) { - // The entry doesn't exit yet - index = putInNameAndTypeCache(selector, signature, currentIndex++); - if (index > 0xFFFF){ + if ((index = -index) > 0xFFFF){ this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType()); } - writeU1(NameAndTypeTag); - writeU2(nameIndex); - writeU2(typeIndex); + poolContent[stringIndexOffset++] = (byte) (stringIndex >> 8); + poolContent[stringIndexOffset] = (byte) stringIndex; } return index; } -private int putInNameAndTypeCache(final char[] key1, final char[] key2, int index) { - CharArrayCache value = (CharArrayCache) this.nameAndTypeCacheForFieldsAndMethods.get(key1); - if (value == null) { +private int putInNameAndTypeCacheIfAbsent(final char[] key1, final char[] key2, int value) { + int index ; + CharArrayCache key1Value = (CharArrayCache) this.nameAndTypeCacheForFieldsAndMethods.get(key1); + if (key1Value == null) { CharArrayCache charArrayCache = new CharArrayCache(); - charArrayCache.put(key2, index); + index = charArrayCache.putIfAbsent(key2, value); this.nameAndTypeCacheForFieldsAndMethods.put(key1, charArrayCache); } else { - value.put(key2, index); + index = key1Value.putIfAbsent(key2, value); } return index; } @@ -858,25 +768,26 @@ * @param key1 * @param key2 * @param key3 - * @param index + * @param value * @return the given index */ -private int putInCache(final char[] key1, final char[] key2, final char[] key3, int index) { - HashtableOfObject value = (HashtableOfObject) this.methodsAndFieldsCache.get(key1); - if (value == null) { - value = new HashtableOfObject(); - this.methodsAndFieldsCache.put(key1, value); +private int putInCacheIfAbsent(final char[] key1, final char[] key2, final char[] key3, int value) { + int index; + HashtableOfObject key1Value = (HashtableOfObject) this.methodsAndFieldsCache.get(key1); + if (key1Value == null) { + key1Value = new HashtableOfObject(); + this.methodsAndFieldsCache.put(key1, key1Value); CharArrayCache charArrayCache = new CharArrayCache(); - charArrayCache.put(key3, index); - value.put(key2, charArrayCache); + index = charArrayCache.putIfAbsent(key3, value); + key1Value.put(key2, charArrayCache); } else { - CharArrayCache charArrayCache = (CharArrayCache) value.get(key2); + CharArrayCache charArrayCache = (CharArrayCache) key1Value.get(key2); if (charArrayCache == null) { charArrayCache = new CharArrayCache(); - charArrayCache.put(key3, index); - value.put(key2, charArrayCache); + index = charArrayCache.putIfAbsent(key3, value); + key1Value.put(key2, charArrayCache); } else { - charArrayCache.put(key3, index); + index = charArrayCache.putIfAbsent(key3, value); } } return index; @@ -931,8 +842,7 @@ if (currentOffset + 2 >= poolContent.length) { resizePoolContents(2); } - //first byte - poolContent[currentOffset++] = (byte) (value >> 8); + poolContent[currentOffset++] = (byte) (value >>> 8); poolContent[currentOffset++] = (byte) value; } } Index: compiler/org/eclipse/jdt/internal/compiler/codegen/DoubleCache.java =================================================================== RCS file: /home/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/DoubleCache.java,v retrieving revision 1.19 diff -u -r1.19 DoubleCache.java --- compiler/org/eclipse/jdt/internal/compiler/codegen/DoubleCache.java 23 Feb 2005 02:47:47 -0000 1.19 +++ compiler/org/eclipse/jdt/internal/compiler/codegen/DoubleCache.java 21 Jul 2005 20:38:31 -0000 @@ -69,13 +69,34 @@ } return false; } -/** Gets the object associated with the specified key in the - * hashtable. - * @param key double the specified key - * @return int the element for the key or -1 if the key is not - * defined in the hash table. +/** + * Puts the specified element into the hashtable, using the specified + * key. The element may be retrieved by doing a get() with the same key. + * + * @param key double the specified key in the hashtable + * @param value int the specified element + * @return int value */ -public int get(double key) { +public int put(double key, int value) { + if (elementSize == keyTable.length) { + // resize + System.arraycopy(keyTable, 0, (keyTable = new double[elementSize * 2]), 0, elementSize); + System.arraycopy(valueTable, 0, (valueTable = new int[elementSize * 2]), 0, elementSize); + } + keyTable[elementSize] = key; + valueTable[elementSize] = value; + elementSize++; + return value; +} +/** + * Puts the specified element into the hashtable, using the specified + * key. The element may be retrieved by doing a get() with the same key. + * + * @param key double the specified key in the hashtable + * @param value int the specified element + * @return int value + */ +public int putIfAbsent(double key, int value) { if (key == 0.0) { for (int i = 0, max = elementSize; i < max; i++) { if (keyTable[i] == 0.0) { @@ -94,17 +115,6 @@ } } } - return -1; -} -/** - * Puts the specified element into the hashtable, using the specified - * key. The element may be retrieved by doing a get() with the same key. - * - * @param key double the specified key in the hashtable - * @param value int the specified element - * @return int value - */ -public int put(double key, int value) { if (elementSize == keyTable.length) { // resize System.arraycopy(keyTable, 0, (keyTable = new double[elementSize * 2]), 0, elementSize); @@ -113,7 +123,7 @@ keyTable[elementSize] = key; valueTable[elementSize] = value; elementSize++; - return value; + return -value; // negative when added, assumes value is > 0 } /** * Converts to a rather lengthy String. Index: compiler/org/eclipse/jdt/internal/compiler/codegen/FloatCache.java =================================================================== RCS file: /home/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/FloatCache.java,v retrieving revision 1.19 diff -u -r1.19 FloatCache.java --- compiler/org/eclipse/jdt/internal/compiler/codegen/FloatCache.java 23 Feb 2005 02:47:47 -0000 1.19 +++ compiler/org/eclipse/jdt/internal/compiler/codegen/FloatCache.java 21 Jul 2005 20:38:31 -0000 @@ -69,13 +69,34 @@ } return false; } -/** Gets the object associated with the specified key in the - * hashtable. - * @param key float the specified key - * @return int the element for the key or -1 if the key is not - * defined in the hash table. +/** + * Puts the specified element into the hashtable, using the specified + * key. The element may be retrieved by doing a get() with the same key. + * + * @param key float the specified key in the hashtable + * @param value int the specified element + * @return int value */ -public int get(float key) { +public int put(float key, int value) { + if (elementSize == keyTable.length) { + // resize + System.arraycopy(keyTable, 0, (keyTable = new float[elementSize * 2]), 0, elementSize); + System.arraycopy(valueTable, 0, (valueTable = new int[elementSize * 2]), 0, elementSize); + } + keyTable[elementSize] = key; + valueTable[elementSize] = value; + elementSize++; + return value; +} +/** + * Puts the specified element into the hashtable, using the specified + * key. The element may be retrieved by doing a get() with the same key. + * + * @param key float the specified key in the hashtable + * @param value int the specified element + * @return int value + */ +public int putIfAbsent(float key, int value) { if (key == 0.0f) { for (int i = 0, max = elementSize; i < max; i++) { if (keyTable[i] == 0.0f) { @@ -94,17 +115,6 @@ } } } - return -1; -} -/** - * Puts the specified element into the hashtable, using the specified - * key. The element may be retrieved by doing a get() with the same key. - * - * @param key float the specified key in the hashtable - * @param value int the specified element - * @return int value - */ -public int put(float key, int value) { if (elementSize == keyTable.length) { // resize System.arraycopy(keyTable, 0, (keyTable = new float[elementSize * 2]), 0, elementSize); @@ -113,7 +123,7 @@ keyTable[elementSize] = key; valueTable[elementSize] = value; elementSize++; - return value; + return -value; // negative when added, assumes value is > 0 } /** * Converts to a rather lengthy String. Index: compiler/org/eclipse/jdt/internal/compiler/codegen/IntegerCache.java =================================================================== RCS file: /home/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/IntegerCache.java,v retrieving revision 1.19 diff -u -r1.19 IntegerCache.java --- compiler/org/eclipse/jdt/internal/compiler/codegen/IntegerCache.java 23 Feb 2005 02:47:47 -0000 1.19 +++ compiler/org/eclipse/jdt/internal/compiler/codegen/IntegerCache.java 21 Jul 2005 20:38:31 -0000 @@ -59,21 +59,6 @@ } return false; } -/** Gets the object associated with the specified key in the - * hashtable. - * @param key double the specified key - * @return int the element for the key or -1 if the key is not - * defined in the hash table. - */ -public int get(int key) { - int index = hash(key); - while ((keyTable[index] != 0) || ((keyTable[index] == 0) &&(valueTable[index] != 0))) { - if (keyTable[index] == key) - return valueTable[index]; - index = (index + 1) % keyTable.length; - } - return -1; -} /** * Return a hashcode for the value of the key parameter. * @param key int @@ -107,6 +92,30 @@ return value; } /** + * Puts the specified element into the hashtable if absent, using the specified + * key. The element may be retrieved by doing a get() with the same key. + * + * @param key int the specified key in the hashtable + * @param value int the specified element + * @return int value + */ +public int putIfAbsent(int key, int value) { + int index = hash(key); + while ((keyTable[index] != 0) || ((keyTable[index] == 0) && (valueTable[index] != 0))) { + if (keyTable[index] == key) + return valueTable[index]; + index = (index + 1) % keyTable.length; + } + keyTable[index] = key; + valueTable[index] = value; + + // assumes the threshold is never equal to the size of the table + if (++elementSize > threshold) { + rehash(); + } + return -value; // negative when added, assumes value is > 0 +} +/** * Rehashes the content of the table into a bigger table. * This method is called automatically when the hashtable's * size exceeds the threshold. Index: compiler/org/eclipse/jdt/internal/compiler/codegen/LongCache.java =================================================================== RCS file: /home/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/LongCache.java,v retrieving revision 1.19 diff -u -r1.19 LongCache.java --- compiler/org/eclipse/jdt/internal/compiler/codegen/LongCache.java 23 Feb 2005 02:47:47 -0000 1.19 +++ compiler/org/eclipse/jdt/internal/compiler/codegen/LongCache.java 21 Jul 2005 20:38:31 -0000 @@ -59,21 +59,6 @@ } return false; } -/** Gets the object associated with the specified key in the - * hashtable. - * @param key long the specified key - * @return int the element for the key or -1 if the key is not - * defined in the hash table. - */ -public int get(long key) { - int index = hash(key); - while ((keyTable[index] != 0) || ((keyTable[index] == 0) &&(valueTable[index] != 0))) { - if (keyTable[index] == key) - return valueTable[index]; - index = (index + 1) % keyTable.length; - } - return -1; -} /** * Return a hashcode for the value of the key parameter. * @param key long @@ -107,6 +92,30 @@ return value; } /** + * Puts the specified element into the hashtable, using the specified + * key. The element may be retrieved by doing a get() with the same key. + * + * @param key long the specified key in the hashtable + * @param value int the specified element + * @return int value + */ +public int putIfAbsent(long key, int value) { + int index = hash(key); + while ((keyTable[index] != 0) || ((keyTable[index] == 0) && (valueTable[index] != 0))) { + if (keyTable[index] == key) + return valueTable[index]; + index = (index + 1) % keyTable.length; + } + keyTable[index] = key; + valueTable[index] = value; + + // assumes the threshold is never equal to the size of the table + if (++elementSize > threshold) { + rehash(); + } + return -value; // negative when added, assumes value is > 0 +} +/** * Rehashes the content of the table into a bigger table. * This method is called automatically when the hashtable's * size exceeds the threshold.