1 11 package org.eclipse.jdt.internal.compiler.codegen; 12 13 import org.eclipse.jdt.core.compiler.CharOperation; 14 import org.eclipse.jdt.internal.compiler.ClassFile; 15 import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants; 16 import org.eclipse.jdt.internal.compiler.lookup.TypeBinding; 17 import org.eclipse.jdt.internal.compiler.lookup.TypeConstants; 18 import org.eclipse.jdt.internal.compiler.lookup.TypeIds; 19 import org.eclipse.jdt.internal.compiler.util.HashtableOfObject; 20 23 public class ConstantPool implements ClassFileConstants, TypeIds { 24 public static final int DOUBLE_INITIAL_SIZE = 5; 25 public static final int FLOAT_INITIAL_SIZE = 3; 26 public static final int INT_INITIAL_SIZE = 248; 27 public static final int LONG_INITIAL_SIZE = 5; 28 public static final int UTF8_INITIAL_SIZE = 778; 29 public static final int STRING_INITIAL_SIZE = 761; 30 public static final int METHODS_AND_FIELDS_INITIAL_SIZE = 450; 31 public static final int CLASS_INITIAL_SIZE = 86; 32 public static final int NAMEANDTYPE_INITIAL_SIZE = 272; 33 public static final int CONSTANTPOOL_INITIAL_SIZE = 2000; 34 public static final int CONSTANTPOOL_GROW_SIZE = 6000; 35 protected DoubleCache doubleCache; 36 protected FloatCache floatCache; 37 protected IntegerCache intCache; 38 protected LongCache longCache; 39 public CharArrayCache UTF8Cache; 40 protected CharArrayCache stringCache; 41 protected HashtableOfObject methodsAndFieldsCache; 42 protected CharArrayCache classCache; 43 protected HashtableOfObject nameAndTypeCacheForFieldsAndMethods; 44 public byte[] poolContent; 45 public int currentIndex = 1; 46 public int currentOffset; 47 48 public ClassFile classFile; 49 public static final char[] Append = "append".toCharArray(); public static final char[] ARRAY_NEWINSTANCE_NAME = "newInstance".toCharArray(); public static final char[] ARRAY_NEWINSTANCE_SIGNATURE = "(Ljava/lang/Class;[I)Ljava/lang/Object;".toCharArray(); public static final char[] ArrayCopy = "arraycopy".toCharArray(); public static final char[] ArrayCopySignature = "(Ljava/lang/Object;ILjava/lang/Object;II)V".toCharArray(); public static final char[] ArrayJavaLangClassConstantPoolName = "[Ljava/lang/Class;".toCharArray(); public static final char[] ArrayJavaLangObjectConstantPoolName = "[Ljava/lang/Object;".toCharArray(); public static final char[] booleanBooleanSignature = "(Z)Ljava/lang/Boolean;".toCharArray(); public static final char[] BooleanConstrSignature = "(Z)V".toCharArray(); public static final char[] BOOLEANVALUE_BOOLEAN_METHOD_NAME = "booleanValue".toCharArray(); public static final char[] BOOLEANVALUE_BOOLEAN_METHOD_SIGNATURE = "()Z".toCharArray(); public static final char[] byteByteSignature = "(B)Ljava/lang/Byte;".toCharArray(); public static final char[] ByteConstrSignature = "(B)V".toCharArray(); public static final char[] BYTEVALUE_BYTE_METHOD_NAME = "byteValue".toCharArray(); public static final char[] BYTEVALUE_BYTE_METHOD_SIGNATURE = "()B".toCharArray(); public static final char[] charCharacterSignature = "(C)Ljava/lang/Character;".toCharArray(); public static final char[] CharConstrSignature = "(C)V".toCharArray(); public static final char[] CHARVALUE_CHARACTER_METHOD_NAME = "charValue".toCharArray(); public static final char[] CHARVALUE_CHARACTER_METHOD_SIGNATURE = "()C".toCharArray(); public static final char[] Clinit = "<clinit>".toCharArray(); public static final char[] DefaultConstructorSignature = "()V".toCharArray(); public static final char[] ClinitSignature = DefaultConstructorSignature; 71 public static final char[] DesiredAssertionStatus = "desiredAssertionStatus".toCharArray(); public static final char[] DesiredAssertionStatusSignature = "()Z".toCharArray(); public static final char[] DoubleConstrSignature = "(D)V".toCharArray(); public static final char[] doubleDoubleSignature = "(D)Ljava/lang/Double;".toCharArray(); public static final char[] DOUBLEVALUE_DOUBLE_METHOD_NAME = "doubleValue".toCharArray(); public static final char[] DOUBLEVALUE_DOUBLE_METHOD_SIGNATURE = "()D".toCharArray(); public static final char[] Exit = "exit".toCharArray(); public static final char[] ExitIntSignature = "(I)V".toCharArray(); public static final char[] FloatConstrSignature = "(F)V".toCharArray(); public static final char[] floatFloatSignature = "(F)Ljava/lang/Float;".toCharArray(); public static final char[] FLOATVALUE_FLOAT_METHOD_NAME = "floatValue".toCharArray(); public static final char[] FLOATVALUE_FLOAT_METHOD_SIGNATURE = "()F".toCharArray(); public static final char[] ForName = "forName".toCharArray(); public static final char[] ForNameSignature = "(Ljava/lang/String;)Ljava/lang/Class;".toCharArray(); public static final char[] GET_BOOLEAN_METHOD_NAME = "getBoolean".toCharArray(); public static final char[] GET_BOOLEAN_METHOD_SIGNATURE = "(Ljava/lang/Object;)Z".toCharArray(); public static final char[] GET_BYTE_METHOD_NAME = "getByte".toCharArray(); public static final char[] GET_BYTE_METHOD_SIGNATURE = "(Ljava/lang/Object;)B".toCharArray(); public static final char[] GET_CHAR_METHOD_NAME = "getChar".toCharArray(); public static final char[] GET_CHAR_METHOD_SIGNATURE = "(Ljava/lang/Object;)C".toCharArray(); public static final char[] GET_DOUBLE_METHOD_NAME = "getDouble".toCharArray(); public static final char[] GET_DOUBLE_METHOD_SIGNATURE = "(Ljava/lang/Object;)D".toCharArray(); public static final char[] GET_FLOAT_METHOD_NAME = "getFloat".toCharArray(); public static final char[] GET_FLOAT_METHOD_SIGNATURE = "(Ljava/lang/Object;)F".toCharArray(); public static final char[] GET_INT_METHOD_NAME = "getInt".toCharArray(); public static final char[] GET_INT_METHOD_SIGNATURE = "(Ljava/lang/Object;)I".toCharArray(); public static final char[] GET_LONG_METHOD_NAME = "getLong".toCharArray(); public static final char[] GET_LONG_METHOD_SIGNATURE = "(Ljava/lang/Object;)J".toCharArray(); public static final char[] GET_OBJECT_METHOD_NAME = "get".toCharArray(); public static final char[] GET_OBJECT_METHOD_SIGNATURE = "(Ljava/lang/Object;)Ljava/lang/Object;".toCharArray(); public static final char[] GET_SHORT_METHOD_NAME = "getShort".toCharArray(); public static final char[] GET_SHORT_METHOD_SIGNATURE = "(Ljava/lang/Object;)S".toCharArray(); public static final char[] GetClass = "getClass".toCharArray(); public static final char[] GetClassSignature = "()Ljava/lang/Class;".toCharArray(); public static final char[] GetComponentType = "getComponentType".toCharArray(); public static final char[] GetComponentTypeSignature = GetClassSignature; 107 public static final char[] GetConstructor = "getConstructor".toCharArray(); public static final char[] GetConstructorSignature = "([Ljava/lang/Class;)Ljava/lang/reflect/Constructor;".toCharArray(); public static final char[] GETDECLAREDCONSTRUCTOR_NAME = "getDeclaredConstructor".toCharArray(); public static final char[] GETDECLAREDCONSTRUCTOR_SIGNATURE = "([Ljava/lang/Class;)Ljava/lang/reflect/Constructor;".toCharArray(); public static final char[] GETDECLAREDFIELD_NAME = "getDeclaredField".toCharArray(); public static final char[] GETDECLAREDFIELD_SIGNATURE = "(Ljava/lang/String;)Ljava/lang/reflect/Field;".toCharArray(); public static final char[] GETDECLAREDMETHOD_NAME = "getDeclaredMethod".toCharArray(); public static final char[] GETDECLAREDMETHOD_SIGNATURE = "(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;".toCharArray(); public static final char[] GetMessage = "getMessage".toCharArray(); public static final char[] GetMessageSignature = "()Ljava/lang/String;".toCharArray(); public static final char[] HasNext = "hasNext".toCharArray(); public static final char[] HasNextSignature = "()Z".toCharArray(); public static final char[] Init = "<init>".toCharArray(); public static final char[] IntConstrSignature = "(I)V".toCharArray(); public static final char[] Intern = "intern".toCharArray(); public static final char[] InternSignature = GetMessageSignature; 124 public static final char[] IntIntegerSignature = "(I)Ljava/lang/Integer;".toCharArray(); public static final char[] INTVALUE_INTEGER_METHOD_NAME = "intValue".toCharArray(); public static final char[] INTVALUE_INTEGER_METHOD_SIGNATURE = "()I".toCharArray(); public static final char[] INVOKE_METHOD_METHOD_NAME = "invoke".toCharArray(); public static final char[] INVOKE_METHOD_METHOD_SIGNATURE = "(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;".toCharArray(); public static final char[][] JAVA_LANG_REFLECT_ACCESSIBLEOBJECT = new char[][] {TypeConstants.JAVA, TypeConstants.LANG, TypeConstants.REFLECT, "AccessibleObject".toCharArray()}; public static final char[][] JAVA_LANG_REFLECT_ARRAY = new char[][] {TypeConstants.JAVA, TypeConstants.LANG, TypeConstants.REFLECT, "Array".toCharArray()}; public static final char[] JavaIoPrintStreamSignature = "Ljava/io/PrintStream;".toCharArray(); public static final char[] JavaLangAssertionErrorConstantPoolName = "java/lang/AssertionError".toCharArray(); public static final char[] JavaLangBooleanConstantPoolName = "java/lang/Boolean".toCharArray(); public static final char[] JavaLangByteConstantPoolName = "java/lang/Byte".toCharArray(); public static final char[] JavaLangCharacterConstantPoolName = "java/lang/Character".toCharArray(); public static final char[] JavaLangClassConstantPoolName = "java/lang/Class".toCharArray(); public static final char[] JavaLangClassNotFoundExceptionConstantPoolName = "java/lang/ClassNotFoundException".toCharArray(); public static final char[] JavaLangClassSignature = "Ljava/lang/Class;".toCharArray(); public static final char[] JavaLangDoubleConstantPoolName = "java/lang/Double".toCharArray(); public static final char[] JavaLangEnumConstantPoolName = "java/lang/Enum".toCharArray(); public static final char[] JavaLangErrorConstantPoolName = "java/lang/Error".toCharArray(); public static final char[] JavaLangExceptionConstantPoolName = "java/lang/Exception".toCharArray(); public static final char[] JavaLangFloatConstantPoolName = "java/lang/Float".toCharArray(); public static final char[] JavaLangIntegerConstantPoolName = "java/lang/Integer".toCharArray(); public static final char[] JavaLangLongConstantPoolName = "java/lang/Long".toCharArray(); public static final char[] JavaLangNoClassDefFoundErrorConstantPoolName = "java/lang/NoClassDefFoundError".toCharArray(); public static final char[] JavaLangNoSuchFieldErrorConstantPoolName = "java/lang/NoSuchFieldError".toCharArray(); public static final char[] JavaLangObjectConstantPoolName = "java/lang/Object".toCharArray(); public static final char[] JAVALANGREFLECTACCESSIBLEOBJECT_CONSTANTPOOLNAME = "java/lang/reflect/AccessibleObject".toCharArray(); public static final char[] JAVALANGREFLECTARRAY_CONSTANTPOOLNAME = "java/lang/reflect/Array".toCharArray(); public static final char[] JavaLangReflectConstructorConstantPoolName = "java/lang/reflect/Constructor".toCharArray(); public static final char[] JavaLangReflectConstructorNewInstanceSignature = "([Ljava/lang/Object;)Ljava/lang/Object;".toCharArray(); public static final char[] JAVALANGREFLECTFIELD_CONSTANTPOOLNAME = "java/lang/reflect/Field".toCharArray(); public static final char[] JAVALANGREFLECTMETHOD_CONSTANTPOOLNAME = "java/lang/reflect/Method".toCharArray(); public static final char[] JavaLangShortConstantPoolName = "java/lang/Short".toCharArray(); public static final char[] JavaLangStringBufferConstantPoolName = "java/lang/StringBuffer".toCharArray(); public static final char[] JavaLangStringBuilderConstantPoolName = "java/lang/StringBuilder".toCharArray(); public static final char[] JavaLangStringConstantPoolName = "java/lang/String".toCharArray(); public static final char[] JavaLangStringSignature = "Ljava/lang/String;".toCharArray(); public static final char[] JavaLangObjectSignature = "Ljava/lang/Object;".toCharArray(); public static final char[] JavaLangSystemConstantPoolName = "java/lang/System".toCharArray(); public static final char[] JavaLangThrowableConstantPoolName = "java/lang/Throwable".toCharArray(); public static final char[] JavaLangVoidConstantPoolName = "java/lang/Void".toCharArray(); public static final char[] JavaUtilIteratorConstantPoolName = "java/util/Iterator".toCharArray(); public static final char[] LongConstrSignature = "(J)V".toCharArray(); public static final char[] longLongSignature = "(J)Ljava/lang/Long;".toCharArray(); public static final char[] LONGVALUE_LONG_METHOD_NAME = "longValue".toCharArray(); public static final char[] LONGVALUE_LONG_METHOD_SIGNATURE = "()J".toCharArray(); public static final char[] NewInstance = "newInstance".toCharArray(); public static final char[] NewInstanceSignature = "(Ljava/lang/Class;[I)Ljava/lang/Object;".toCharArray(); public static final char[] Next = "next".toCharArray(); public static final char[] NextSignature = "()Ljava/lang/Object;".toCharArray(); public static final char[] ObjectConstrSignature = "(Ljava/lang/Object;)V".toCharArray(); public static final char[] ObjectSignature = "Ljava/lang/Object;".toCharArray(); public static final char[] Ordinal = "ordinal".toCharArray(); public static final char[] OrdinalSignature = "()I".toCharArray(); public static final char[] Out = "out".toCharArray(); public static final char[] SET_BOOLEAN_METHOD_NAME = "setBoolean".toCharArray(); public static final char[] SET_BOOLEAN_METHOD_SIGNATURE = "(Ljava/lang/Object;Z)V".toCharArray(); public static final char[] SET_BYTE_METHOD_NAME = "setByte".toCharArray(); public static final char[] SET_BYTE_METHOD_SIGNATURE = "(Ljava/lang/Object;B)V".toCharArray(); public static final char[] SET_CHAR_METHOD_NAME = "setChar".toCharArray(); public static final char[] SET_CHAR_METHOD_SIGNATURE = "(Ljava/lang/Object;C)V".toCharArray(); public static final char[] SET_DOUBLE_METHOD_NAME = "setDouble".toCharArray(); public static final char[] SET_DOUBLE_METHOD_SIGNATURE = "(Ljava/lang/Object;D)V".toCharArray(); public static final char[] SET_FLOAT_METHOD_NAME = "setFloat".toCharArray(); public static final char[] SET_FLOAT_METHOD_SIGNATURE = "(Ljava/lang/Object;F)V".toCharArray(); public static final char[] SET_INT_METHOD_NAME = "setInt".toCharArray(); public static final char[] SET_INT_METHOD_SIGNATURE = "(Ljava/lang/Object;I)V".toCharArray(); public static final char[] SET_LONG_METHOD_NAME = "setLong".toCharArray(); public static final char[] SET_LONG_METHOD_SIGNATURE = "(Ljava/lang/Object;J)V".toCharArray(); public static final char[] SET_OBJECT_METHOD_NAME = "set".toCharArray(); public static final char[] SET_OBJECT_METHOD_SIGNATURE = "(Ljava/lang/Object;Ljava/lang/Object;)V".toCharArray(); public static final char[] SET_SHORT_METHOD_NAME = "setShort".toCharArray(); public static final char[] SET_SHORT_METHOD_SIGNATURE = "(Ljava/lang/Object;S)V".toCharArray(); public static final char[] SETACCESSIBLE_NAME = "setAccessible".toCharArray(); public static final char[] SETACCESSIBLE_SIGNATURE = "(Z)V".toCharArray(); public static final char[] ShortConstrSignature = "(S)V".toCharArray(); public static final char[] shortShortSignature = "(S)Ljava/lang/Short;".toCharArray(); public static final char[] SHORTVALUE_SHORT_METHOD_NAME = "shortValue".toCharArray(); public static final char[] SHORTVALUE_SHORT_METHOD_SIGNATURE = "()S".toCharArray(); public static final char[] StringBufferAppendBooleanSignature = "(Z)Ljava/lang/StringBuffer;".toCharArray(); public static final char[] StringBufferAppendCharSignature = "(C)Ljava/lang/StringBuffer;".toCharArray(); public static final char[] StringBufferAppendDoubleSignature = "(D)Ljava/lang/StringBuffer;".toCharArray(); public static final char[] StringBufferAppendFloatSignature = "(F)Ljava/lang/StringBuffer;".toCharArray(); public static final char[] StringBufferAppendIntSignature = "(I)Ljava/lang/StringBuffer;".toCharArray(); public static final char[] StringBufferAppendLongSignature = "(J)Ljava/lang/StringBuffer;".toCharArray(); public static final char[] StringBufferAppendObjectSignature = "(Ljava/lang/Object;)Ljava/lang/StringBuffer;".toCharArray(); public static final char[] StringBufferAppendStringSignature = "(Ljava/lang/String;)Ljava/lang/StringBuffer;".toCharArray(); public static final char[] StringBuilderAppendBooleanSignature = "(Z)Ljava/lang/StringBuilder;".toCharArray(); public static final char[] StringBuilderAppendCharSignature = "(C)Ljava/lang/StringBuilder;".toCharArray(); public static final char[] StringBuilderAppendDoubleSignature = "(D)Ljava/lang/StringBuilder;".toCharArray(); public static final char[] StringBuilderAppendFloatSignature = "(F)Ljava/lang/StringBuilder;".toCharArray(); public static final char[] StringBuilderAppendIntSignature = "(I)Ljava/lang/StringBuilder;".toCharArray(); public static final char[] StringBuilderAppendLongSignature = "(J)Ljava/lang/StringBuilder;".toCharArray(); public static final char[] StringBuilderAppendObjectSignature = "(Ljava/lang/Object;)Ljava/lang/StringBuilder;".toCharArray(); public static final char[] StringBuilderAppendStringSignature = "(Ljava/lang/String;)Ljava/lang/StringBuilder;".toCharArray(); public static final char[] StringConstructorSignature = "(Ljava/lang/String;)V".toCharArray(); public static final char[] This = "this".toCharArray(); public static final char[] ToString = "toString".toCharArray(); public static final char[] ToStringSignature = GetMessageSignature; 223 public static final char[] TYPE = "TYPE".toCharArray(); public static final char[] ValueOf = "valueOf".toCharArray(); public static final char[] ValueOfBooleanSignature = "(Z)Ljava/lang/String;".toCharArray(); public static final char[] ValueOfCharSignature = "(C)Ljava/lang/String;".toCharArray(); public static final char[] ValueOfDoubleSignature = "(D)Ljava/lang/String;".toCharArray(); public static final char[] ValueOfFloatSignature = "(F)Ljava/lang/String;".toCharArray(); public static final char[] ValueOfIntSignature = "(I)Ljava/lang/String;".toCharArray(); public static final char[] ValueOfLongSignature = "(J)Ljava/lang/String;".toCharArray(); public static final char[] ValueOfObjectSignature = "(Ljava/lang/Object;)Ljava/lang/String;".toCharArray(); public static final char[] ValueOfStringClassSignature = "(Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/Enum;".toCharArray(); public static final char[] JAVA_LANG_ANNOTATION_DOCUMENTED = "Ljava/lang/annotation/Documented;".toCharArray(); public static final char[] JAVA_LANG_ANNOTATION_ELEMENTTYPE = "Ljava/lang/annotation/ElementType;".toCharArray(); public static final char[] JAVA_LANG_ANNOTATION_RETENTION = "Ljava/lang/annotation/Retention;".toCharArray(); public static final char[] JAVA_LANG_ANNOTATION_RETENTIONPOLICY = "Ljava/lang/annotation/RetentionPolicy;".toCharArray(); public static final char[] JAVA_LANG_ANNOTATION_TARGET = "Ljava/lang/annotation/Target;".toCharArray(); public static final char[] JAVA_LANG_DEPRECATED = "Ljava/lang/Deprecated;".toCharArray(); public static final char[] JAVA_LANG_ANNOTATION_INHERITED = "Ljava/lang/annotation/Inherited;".toCharArray(); 243 public ConstantPool(ClassFile classFile) { 244 this.UTF8Cache = new CharArrayCache(UTF8_INITIAL_SIZE); 245 this.stringCache = new CharArrayCache(STRING_INITIAL_SIZE); 246 this.methodsAndFieldsCache = new HashtableOfObject(METHODS_AND_FIELDS_INITIAL_SIZE); 247 this.classCache = new CharArrayCache(CLASS_INITIAL_SIZE); 248 this.nameAndTypeCacheForFieldsAndMethods = new HashtableOfObject(NAMEANDTYPE_INITIAL_SIZE); 249 initialize(classFile); 250 } 251 public void initialize(ClassFile givenClassFile) { 252 this.poolContent = givenClassFile.header; 253 this.currentOffset = givenClassFile.headerOffset; 254 this.currentIndex = 1; 256 this.classFile = givenClassFile; 257 } 258 261 public byte[] dumpBytes() { 262 System.arraycopy(poolContent, 0, (poolContent = new byte[currentOffset]), 0, currentOffset); 263 return poolContent; 264 } 265 public int literalIndex(byte[] utf8encoding, char[] stringCharArray) { 266 int index; 267 if ((index = UTF8Cache.putIfAbsent(stringCharArray, this.currentIndex)) < 0) { 268 if ((index = -index)> 0xFFFF) { 270 this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType()); 271 } 272 currentIndex++; 273 writeU1(Utf8Tag); 275 int utf8encodingLength = utf8encoding.length; 276 if (currentOffset + 2 + utf8encodingLength >= poolContent.length) { 277 resizePoolContents(2 + utf8encodingLength); 280 } 281 poolContent[currentOffset++] = (byte) (utf8encodingLength >> 8); 282 poolContent[currentOffset++] = (byte) utf8encodingLength; 283 System.arraycopy(utf8encoding, 0, poolContent, currentOffset, utf8encodingLength); 285 currentOffset += utf8encodingLength; 286 } 287 return index; 288 } 289 public int literalIndex(TypeBinding binding) { 290 TypeBinding typeBinding = binding.leafComponentType(); 291 if (typeBinding.isNestedType()) { 292 this.classFile.recordInnerClasses(typeBinding); 293 } 294 return literalIndex(binding.signature()); 295 } 296 302 public int literalIndex(char[] utf8Constant) { 303 int index; 304 if ((index = UTF8Cache.putIfAbsent(utf8Constant, this.currentIndex)) < 0) { 305 index = -index; 306 writeU1(Utf8Tag); 309 int savedCurrentOffset = currentOffset; 311 if (currentOffset + 2 >= poolContent.length) { 312 resizePoolContents(2); 315 } 316 currentOffset += 2; 317 int length = 0; 318 for (int i = 0; i < utf8Constant.length; i++) { 319 char current = utf8Constant[i]; 320 if ((current >= 0x0001) && (current <= 0x007F)) { 321 writeU1(current); 323 length++; 324 } else { 325 if (current > 0x07FF) { 326 length += 3; 328 writeU1(0xE0 | ((current >> 12) & 0x0F)); writeU1(0x80 | ((current >> 6) & 0x3F)); writeU1(0x80 | (current & 0x3F)); } else { 332 length += 2; 335 writeU1(0xC0 | ((current >> 6) & 0x1F)); writeU1(0x80 | (current & 0x3F)); } 338 } 339 } 340 if (length >= 65535) { 341 currentOffset = savedCurrentOffset - 1; 342 this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceForConstant(this.classFile.referenceBinding.scope.referenceType()); 343 } 344 if (index > 0xFFFF){ 345 this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType()); 346 } 347 currentIndex++; 348 poolContent[savedCurrentOffset] = (byte) (length >> 8); 351 poolContent[savedCurrentOffset + 1] = (byte) length; 352 } 353 return index; 354 } 355 public int literalIndex(char[] stringCharArray, byte[] utf8encoding) { 356 int index; 357 if ((index = stringCache.putIfAbsent(stringCharArray, this.currentIndex)) < 0) { 358 this.currentIndex++; 360 if ((index = -index) > 0xFFFF){ 361 this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType()); 362 } 363 writeU1(StringTag); 365 int stringIndexOffset = this.currentOffset; 367 if (currentOffset + 2 >= poolContent.length) { 368 resizePoolContents(2); 369 } 370 currentOffset+=2; 371 372 final int stringIndex = literalIndex(utf8encoding, stringCharArray); 373 poolContent[stringIndexOffset++] = (byte) (stringIndex >> 8); 374 poolContent[stringIndexOffset] = (byte) stringIndex; 375 } 376 return index; 377 } 378 386 public int literalIndex(double key) { 387 int index; 391 if (doubleCache == null) { 394 doubleCache = new DoubleCache(DOUBLE_INITIAL_SIZE); 395 } 396 if ((index = doubleCache.putIfAbsent(key, this.currentIndex)) < 0) { 397 if ((index = -index)> 0xFFFF){ 398 this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType()); 399 } 400 this.currentIndex += 2; writeU1(DoubleTag); 404 long temp = java.lang.Double.doubleToLongBits(key); 406 int length = poolContent.length; 407 if (currentOffset + 8 >= length) { 408 resizePoolContents(8); 409 } 410 poolContent[currentOffset++] = (byte) (temp >>> 56); 411 poolContent[currentOffset++] = (byte) (temp >>> 48); 412 poolContent[currentOffset++] = (byte) (temp >>> 40); 413 poolContent[currentOffset++] = (byte) (temp >>> 32); 414 poolContent[currentOffset++] = (byte) (temp >>> 24); 415 poolContent[currentOffset++] = (byte) (temp >>> 16); 416 poolContent[currentOffset++] = (byte) (temp >>> 8); 417 poolContent[currentOffset++] = (byte) temp; 418 } 419 return index; 420 } 421 429 public int literalIndex(float key) { 430 int index; 432 if (floatCache == null) { 435 floatCache = new FloatCache(FLOAT_INITIAL_SIZE); 436 } 437 if ((index = floatCache.putIfAbsent(key, this.currentIndex)) < 0) { 438 if ((index = -index) > 0xFFFF){ 439 this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType()); 440 } 441 this.currentIndex++; 442 writeU1(FloatTag); 445 int temp = java.lang.Float.floatToIntBits(key); 447 if (currentOffset + 4 >= poolContent.length) { 448 resizePoolContents(4); 449 } 450 poolContent[currentOffset++] = (byte) (temp >>> 24); 451 poolContent[currentOffset++] = (byte) (temp >>> 16); 452 poolContent[currentOffset++] = (byte) (temp >>> 8); 453 poolContent[currentOffset++] = (byte) temp; 454 } 455 return index; 456 } 457 465 public int literalIndex(int key) { 466 int index; 468 if (intCache == null) { 471 intCache = new IntegerCache(INT_INITIAL_SIZE); 472 } 473 if ((index = intCache.putIfAbsent(key, this.currentIndex)) < 0) { 474 this.currentIndex++; 475 if ((index = -index) > 0xFFFF){ 476 this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType()); 477 } 478 writeU1(IntegerTag); 481 if (currentOffset + 4 >= poolContent.length) { 483 resizePoolContents(4); 484 } 485 poolContent[currentOffset++] = (byte) (key >>> 24); 486 poolContent[currentOffset++] = (byte) (key >>> 16); 487 poolContent[currentOffset++] = (byte) (key >>> 8); 488 poolContent[currentOffset++] = (byte) key; 489 } 490 return index; 491 } 492 500 public int literalIndex(long key) { 501 int index; 505 if (longCache == null) { 508 longCache = new LongCache(LONG_INITIAL_SIZE); 509 } 510 if ((index = longCache.putIfAbsent(key, this.currentIndex)) < 0) { 511 if ((index = -index) > 0xFFFF){ 512 this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType()); 513 } 514 this.currentIndex+= 2; writeU1(LongTag); 518 if (currentOffset + 8 >= poolContent.length) { 520 resizePoolContents(8); 521 } 522 poolContent[currentOffset++] = (byte) (key >>> 56); 523 poolContent[currentOffset++] = (byte) (key >>> 48); 524 poolContent[currentOffset++] = (byte) (key >>> 40); 525 poolContent[currentOffset++] = (byte) (key >>> 32); 526 poolContent[currentOffset++] = (byte) (key >>> 24); 527 poolContent[currentOffset++] = (byte) (key >>> 16); 528 poolContent[currentOffset++] = (byte) (key >>> 8); 529 poolContent[currentOffset++] = (byte) key; 530 } 531 return index; 532 } 533 539 public int literalIndex(String stringConstant) { 540 int index; 541 char[] stringCharArray = stringConstant.toCharArray(); 542 if ((index = stringCache.putIfAbsent(stringCharArray, this.currentIndex)) < 0) { 543 currentIndex++; 545 if ((index = -index)> 0xFFFF){ 546 this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType()); 547 } 548 writeU1(StringTag); 550 int stringIndexOffset = this.currentOffset; 552 if (currentOffset + 2 >= poolContent.length) { 553 resizePoolContents(2); 554 } 555 currentOffset+=2; 556 final int stringIndex = literalIndex(stringCharArray); 557 poolContent[stringIndexOffset++] = (byte) (stringIndex >> 8); 558 poolContent[stringIndexOffset] = (byte) stringIndex; 559 } 560 return index; 561 } 562 public int literalIndexForType(final char[] constantPoolName) { 563 int index; 564 if ((index = classCache.putIfAbsent(constantPoolName, this.currentIndex)) < 0) { 565 this.currentIndex++; 567 if ((index = -index) > 0xFFFF){ 568 this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType()); 569 } 570 writeU1(ClassTag); 571 572 int nameIndexOffset = this.currentOffset; 574 if (currentOffset + 2 >= poolContent.length) { 575 resizePoolContents(2); 576 } 577 currentOffset+=2; 578 final int nameIndex = literalIndex(constantPoolName); 579 poolContent[nameIndexOffset++] = (byte) (nameIndex >> 8); 580 poolContent[nameIndexOffset] = (byte) nameIndex; 581 } 582 return index; 583 } 584 589 public int literalIndexForType(final TypeBinding binding) { 590 TypeBinding typeBinding = binding.leafComponentType(); 591 if (typeBinding.isNestedType()) { 592 this.classFile.recordInnerClasses(typeBinding); 593 } 594 return this.literalIndexForType(binding.constantPoolName()); 595 } 596 public int literalIndexForMethod(char[] declaringClass, char[] selector, char[] signature, boolean isInterface) { 597 int index; 598 if ((index = putInCacheIfAbsent(declaringClass, selector, signature, this.currentIndex)) < 0) { 599 this.currentIndex++; 601 if ((index = -index) > 0xFFFF){ 602 this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType()); 603 } 604 writeU1(isInterface ? InterfaceMethodRefTag : MethodRefTag); 607 608 int classIndexOffset = this.currentOffset; 609 if (currentOffset + 4 >= poolContent.length) { 610 resizePoolContents(4); 611 } 612 currentOffset+=4; 613 614 final int classIndex = literalIndexForType(declaringClass); 615 final int nameAndTypeIndex = literalIndexForNameAndType(selector, signature); 616 617 poolContent[classIndexOffset++] = (byte) (classIndex >> 8); 618 poolContent[classIndexOffset++] = (byte) classIndex; 619 poolContent[classIndexOffset++] = (byte) (nameAndTypeIndex >> 8); 620 poolContent[classIndexOffset] = (byte) nameAndTypeIndex; 621 } 622 return index; 623 } 624 public int literalIndexForMethod(TypeBinding binding, char[] selector, char[] signature, boolean isInterface) { 625 if (binding.isNestedType()) { 626 this.classFile.recordInnerClasses(binding); 627 } 628 return this.literalIndexForMethod(binding.constantPoolName(), selector, signature, isInterface); 629 } 630 public int literalIndexForNameAndType(char[] name, char[] signature) { 631 int index; 632 if ((index = putInNameAndTypeCacheIfAbsent(name, signature, currentIndex)) < 0) { 633 currentIndex++; 635 if ((index = -index) > 0xFFFF){ 636 this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType()); 637 } 638 writeU1(NameAndTypeTag); 639 int nameIndexOffset = this.currentOffset; 640 if (currentOffset + 4 >= poolContent.length) { 641 resizePoolContents(4); 642 } 643 currentOffset+=4; 644 645 final int nameIndex = literalIndex(name); 646 final int typeIndex = literalIndex(signature); 647 poolContent[nameIndexOffset++] = (byte) (nameIndex >> 8); 648 poolContent[nameIndexOffset++] = (byte) nameIndex; 649 poolContent[nameIndexOffset++] = (byte) (typeIndex >> 8); 650 poolContent[nameIndexOffset] = (byte) typeIndex; 651 } 652 return index; 653 } 654 public int literalIndexForField(char[] declaringClass, char[] name, char[] signature) { 655 int index; 656 if ((index = putInCacheIfAbsent(declaringClass, name, signature, this.currentIndex)) < 0) { 657 this.currentIndex++; 658 if ((index = -index) > 0xFFFF){ 660 this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType()); 661 } 662 writeU1(FieldRefTag); 665 int classIndexOffset = this.currentOffset; 666 if (currentOffset + 4 >= poolContent.length) { 667 resizePoolContents(4); 668 } 669 currentOffset+=4; 670 671 final int classIndex = literalIndexForType(declaringClass); 672 final int nameAndTypeIndex = literalIndexForNameAndType(name, signature); 673 674 poolContent[classIndexOffset++] = (byte) (classIndex >> 8); 675 poolContent[classIndexOffset++] = (byte) classIndex; 676 poolContent[classIndexOffset++] = (byte) (nameAndTypeIndex >> 8); 677 poolContent[classIndexOffset] = (byte) nameAndTypeIndex; 678 } 679 return index; 680 } 681 687 public int literalIndexForLdc(char[] stringCharArray) { 688 int savedCurrentIndex = this.currentIndex; 689 int savedCurrentOffset = this.currentOffset; 690 int index; 691 if ((index = stringCache.putIfAbsent(stringCharArray, this.currentIndex)) < 0) { 692 this.currentIndex++; 694 writeU1(StringTag); 696 697 int stringIndexOffset = this.currentOffset; 699 if (currentOffset + 2 >= poolContent.length) { 700 resizePoolContents(2); 701 } 702 currentOffset+=2; 703 704 int stringIndex; 705 if ((stringIndex = UTF8Cache.putIfAbsent(stringCharArray, this.currentIndex)) < 0) { 706 this.currentIndex++; 708 writeU1(Utf8Tag); 710 int lengthOffset = currentOffset; 712 if (currentOffset + 2 >= poolContent.length) { 713 resizePoolContents(2); 716 } 717 currentOffset += 2; 718 int length = 0; 719 for (int i = 0; i < stringCharArray.length; i++) { 720 char current = stringCharArray[i]; 721 if ((current >= 0x0001) && (current <= 0x007F)) { 722 length++; 724 if (currentOffset + 1 >= poolContent.length) { 725 resizePoolContents(1); 728 } 729 poolContent[currentOffset++] = (byte)(current); 730 } else 731 if (current > 0x07FF) { 732 length += 3; 734 if (currentOffset + 3 >= poolContent.length) { 735 resizePoolContents(3); 738 } 739 poolContent[currentOffset++] = (byte) (0xE0 | ((current >> 12) & 0x0F)); poolContent[currentOffset++] = (byte) (0x80 | ((current >> 6) & 0x3F)); poolContent[currentOffset++] = (byte) (0x80 | (current & 0x3F)); } else { 743 if (currentOffset + 2 >= poolContent.length) { 744 resizePoolContents(2); 747 } 748 length += 2; 751 poolContent[currentOffset++] = (byte) (0xC0 | ((current >> 6) & 0x1F)); poolContent[currentOffset++] = (byte) (0x80 | (current & 0x3F)); } 754 } 755 if (length >= 65535) { 756 this.currentOffset = savedCurrentOffset; 757 this.currentIndex = savedCurrentIndex; 758 this.stringCache.remove(stringCharArray); 759 this.UTF8Cache.remove(stringCharArray); 760 return 0; 761 } 762 poolContent[lengthOffset++] = (byte) (length >> 8); 763 poolContent[lengthOffset] = (byte) length; 764 stringIndex = -stringIndex; 765 } 766 if ((index = -index) > 0xFFFF){ 767 this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType()); 768 } 769 poolContent[stringIndexOffset++] = (byte) (stringIndex >> 8); 770 poolContent[stringIndexOffset] = (byte) stringIndex; 771 } 772 return index; 773 } 774 780 private int putInNameAndTypeCacheIfAbsent(final char[] key1, final char[] key2, int value) { 781 int index ; 782 Object key1Value = this.nameAndTypeCacheForFieldsAndMethods.get(key1); 783 if (key1Value == null) { 784 CachedIndexEntry cachedIndexEntry = new CachedIndexEntry(key2, value); 785 index = -value; 786 this.nameAndTypeCacheForFieldsAndMethods.put(key1, cachedIndexEntry); 787 } else if (key1Value instanceof CachedIndexEntry) { 788 CachedIndexEntry entry = (CachedIndexEntry) key1Value; 790 if (CharOperation.equals(key2, entry.signature)) { 791 index = entry.index; 792 } else { 793 CharArrayCache charArrayCache = new CharArrayCache(); 794 charArrayCache.putIfAbsent(entry.signature, entry.index); 795 index = charArrayCache.putIfAbsent(key2, value); 796 this.nameAndTypeCacheForFieldsAndMethods.put(key1, charArrayCache); 797 } 798 } else { 799 CharArrayCache charArrayCache = (CharArrayCache) key1Value; 800 index = charArrayCache.putIfAbsent(key2, value); 801 } 802 return index; 803 } 804 811 private int putInCacheIfAbsent(final char[] key1, final char[] key2, final char[] key3, int value) { 812 int index; 813 HashtableOfObject key1Value = (HashtableOfObject) this.methodsAndFieldsCache.get(key1); 814 if (key1Value == null) { 815 key1Value = new HashtableOfObject(); 816 this.methodsAndFieldsCache.put(key1, key1Value); 817 CachedIndexEntry cachedIndexEntry = new CachedIndexEntry(key3, value); 818 index = -value; 819 key1Value.put(key2, cachedIndexEntry); 820 } else { 821 Object key2Value = key1Value.get(key2); 822 if (key2Value == null) { 823 CachedIndexEntry cachedIndexEntry = new CachedIndexEntry(key3, value); 824 index = -value; 825 key1Value.put(key2, cachedIndexEntry); 826 } else if (key2Value instanceof CachedIndexEntry) { 827 CachedIndexEntry entry = (CachedIndexEntry) key2Value; 829 if (CharOperation.equals(key3, entry.signature)) { 830 index = entry.index; 831 } else { 832 CharArrayCache charArrayCache = new CharArrayCache(); 833 charArrayCache.putIfAbsent(entry.signature, entry.index); 834 index = charArrayCache.putIfAbsent(key3, value); 835 key1Value.put(key2, charArrayCache); 836 } 837 } else { 838 CharArrayCache charArrayCache = (CharArrayCache) key2Value; 839 index = charArrayCache.putIfAbsent(key3, value); 840 } 841 } 842 return index; 843 } 844 850 public void resetForClinit(int constantPoolIndex, int constantPoolOffset) { 851 currentIndex = constantPoolIndex; 852 currentOffset = constantPoolOffset; 853 if (UTF8Cache.get(AttributeNamesConstants.CodeName) >= constantPoolIndex) { 854 UTF8Cache.remove(AttributeNamesConstants.CodeName); 855 } 856 if (UTF8Cache.get(ConstantPool.ClinitSignature) >= constantPoolIndex) { 857 UTF8Cache.remove(ConstantPool.ClinitSignature); 858 } 859 if (UTF8Cache.get(ConstantPool.Clinit) >= constantPoolIndex) { 860 UTF8Cache.remove(ConstantPool.Clinit); 861 } 862 } 863 864 867 private final void resizePoolContents(int minimalSize) { 868 int length = poolContent.length; 869 int toAdd = length; 870 if (toAdd < minimalSize) 871 toAdd = minimalSize; 872 System.arraycopy(poolContent, 0, poolContent = new byte[length + toAdd], 0, length); 873 } 874 879 protected final void writeU1(int value) { 880 if (currentOffset + 1 >= poolContent.length) { 881 resizePoolContents(1); 882 } 883 poolContent[currentOffset++] = (byte) value; 884 } 885 890 protected final void writeU2(int value) { 891 if (currentOffset + 2 >= poolContent.length) { 892 resizePoolContents(2); 893 } 894 poolContent[currentOffset++] = (byte) (value >>> 8); 895 poolContent[currentOffset++] = (byte) value; 896 } 897 public void reset() { 898 if (this.doubleCache != null) this.doubleCache.clear(); 899 if (this.floatCache != null) this.floatCache.clear(); 900 if (this.intCache != null) this.intCache.clear(); 901 if (this.longCache != null) this.longCache.clear(); 902 this.UTF8Cache.clear(); 903 this.stringCache.clear(); 904 this.methodsAndFieldsCache.clear(); 905 this.classCache.clear(); 906 this.nameAndTypeCacheForFieldsAndMethods.clear(); 907 this.currentIndex = 1; 908 this.currentOffset = 0; 909 } 910 } 911 | Popular Tags |