Lines 12-20
Link Here
|
12 |
|
12 |
|
13 |
import org.eclipse.jdt.internal.compiler.ClassFile; |
13 |
import org.eclipse.jdt.internal.compiler.ClassFile; |
14 |
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants; |
14 |
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants; |
15 |
import org.eclipse.jdt.internal.compiler.lookup.FieldBinding; |
|
|
16 |
import org.eclipse.jdt.internal.compiler.lookup.MethodBinding; |
17 |
import org.eclipse.jdt.internal.compiler.lookup.TypeBinding; |
18 |
import org.eclipse.jdt.internal.compiler.lookup.TypeConstants; |
15 |
import org.eclipse.jdt.internal.compiler.lookup.TypeConstants; |
19 |
import org.eclipse.jdt.internal.compiler.lookup.TypeIds; |
16 |
import org.eclipse.jdt.internal.compiler.lookup.TypeIds; |
20 |
import org.eclipse.jdt.internal.compiler.util.HashtableOfObject; |
17 |
import org.eclipse.jdt.internal.compiler.util.HashtableOfObject; |
Lines 264-300
Link Here
|
264 |
System.arraycopy(poolContent, 0, (poolContent = new byte[currentOffset]), 0, currentOffset); |
261 |
System.arraycopy(poolContent, 0, (poolContent = new byte[currentOffset]), 0, currentOffset); |
265 |
return poolContent; |
262 |
return poolContent; |
266 |
} |
263 |
} |
267 |
private int getFromCache(char[] declaringClass, char[] name, char[] signature) { |
|
|
268 |
HashtableOfObject value = (HashtableOfObject) this.methodsAndFieldsCache.get(declaringClass); |
269 |
if (value == null) { |
270 |
return -1; |
271 |
} |
272 |
CharArrayCache value2 = (CharArrayCache) value.get(name); |
273 |
if (value2 == null) { |
274 |
return -1; |
275 |
} |
276 |
return value2.get(signature); |
277 |
} |
278 |
private int getFromNameAndTypeCache(char[] name, char[] signature) { |
279 |
CharArrayCache value = (CharArrayCache) this.nameAndTypeCacheForFieldsAndMethods.get(name); |
280 |
if (value == null) { |
281 |
return -1; |
282 |
} |
283 |
return value.get(signature); |
284 |
} |
285 |
public int literalIndex(byte[] utf8encoding, char[] stringCharArray) { |
264 |
public int literalIndex(byte[] utf8encoding, char[] stringCharArray) { |
286 |
int index; |
265 |
int index; |
287 |
if ((index = UTF8Cache.get(stringCharArray)) < 0) { |
266 |
if ((index = UTF8Cache.putIfAbsent(stringCharArray, this.currentIndex)) < 0) { |
288 |
// The entry doesn't exit yet |
267 |
// The entry doesn't exit yet |
289 |
index = UTF8Cache.put(stringCharArray, currentIndex); |
268 |
if ((index = -index)> 0xFFFF){ |
290 |
if (index > 0xFFFF){ |
|
|
291 |
this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType()); |
269 |
this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType()); |
292 |
} |
270 |
} |
293 |
currentIndex++; |
271 |
currentIndex++; |
294 |
// Write the tag first |
272 |
// Write the tag first |
295 |
writeU1(Utf8Tag); |
273 |
writeU1(Utf8Tag); |
296 |
// Then the size of the stringName array |
|
|
297 |
//writeU2(utf8Constant.length); |
298 |
int savedCurrentOffset = currentOffset; |
274 |
int savedCurrentOffset = currentOffset; |
299 |
int utf8encodingLength = utf8encoding.length; |
275 |
int utf8encodingLength = utf8encoding.length; |
300 |
if (currentOffset + 2 + utf8encodingLength >= poolContent.length) { |
276 |
if (currentOffset + 2 + utf8encodingLength >= poolContent.length) { |
Lines 321-327
Link Here
|
321 |
*/ |
297 |
*/ |
322 |
public int literalIndex(char[] utf8Constant) { |
298 |
public int literalIndex(char[] utf8Constant) { |
323 |
int index; |
299 |
int index; |
324 |
if ((index = UTF8Cache.get(utf8Constant)) < 0) { |
300 |
if ((index = UTF8Cache.putIfAbsent(utf8Constant, this.currentIndex)) < 0) { |
|
|
301 |
index = -index; |
325 |
// The entry doesn't exit yet |
302 |
// The entry doesn't exit yet |
326 |
// Write the tag first |
303 |
// Write the tag first |
327 |
writeU1(Utf8Tag); |
304 |
writeU1(Utf8Tag); |
Lines 359-365
Link Here
|
359 |
currentOffset = savedCurrentOffset - 1; |
336 |
currentOffset = savedCurrentOffset - 1; |
360 |
this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceForConstant(this.classFile.referenceBinding.scope.referenceType()); |
337 |
this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceForConstant(this.classFile.referenceBinding.scope.referenceType()); |
361 |
} |
338 |
} |
362 |
index = UTF8Cache.put(utf8Constant, currentIndex); |
|
|
363 |
if (index > 0xFFFF){ |
339 |
if (index > 0xFFFF){ |
364 |
this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType()); |
340 |
this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType()); |
365 |
} |
341 |
} |
Lines 373-390
Link Here
|
373 |
} |
349 |
} |
374 |
public int literalIndex(char[] stringCharArray, byte[] utf8encoding) { |
350 |
public int literalIndex(char[] stringCharArray, byte[] utf8encoding) { |
375 |
int index; |
351 |
int index; |
376 |
int stringIndex; |
352 |
if ((index = stringCache.putIfAbsent(stringCharArray, this.currentIndex)) < 0) { |
377 |
if ((index = stringCache.get(stringCharArray)) < 0) { |
|
|
378 |
// The entry doesn't exit yet |
353 |
// The entry doesn't exit yet |
379 |
stringIndex = literalIndex(utf8encoding, stringCharArray); |
354 |
this.currentIndex++; |
380 |
index = stringCache.put(stringCharArray, currentIndex++); |
355 |
if ((index = -index) > 0xFFFF){ |
381 |
if (index > 0xFFFF){ |
|
|
382 |
this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType()); |
356 |
this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType()); |
383 |
} |
357 |
} |
384 |
// Write the tag first |
358 |
// Write the tag first |
385 |
writeU1(StringTag); |
359 |
writeU1(StringTag); |
386 |
// Then the string index |
360 |
// Then the string index |
387 |
writeU2(stringIndex); |
361 |
int stringIndexOffset = this.currentOffset; |
|
|
362 |
if (currentOffset + 2 >= poolContent.length) { |
363 |
resizePoolContents(2); |
364 |
} |
365 |
currentOffset+=2; |
366 |
|
367 |
final int stringIndex = literalIndex(utf8encoding, stringCharArray); |
368 |
poolContent[stringIndexOffset++] = (byte) (stringIndex >> 8); |
369 |
poolContent[stringIndexOffset] = (byte) stringIndex; |
388 |
} |
370 |
} |
389 |
return index; |
371 |
return index; |
390 |
} |
372 |
} |
Lines 406-417
Link Here
|
406 |
if (doubleCache == null) { |
388 |
if (doubleCache == null) { |
407 |
doubleCache = new DoubleCache(DOUBLE_INITIAL_SIZE); |
389 |
doubleCache = new DoubleCache(DOUBLE_INITIAL_SIZE); |
408 |
} |
390 |
} |
409 |
if ((index = doubleCache.get(key)) < 0) { |
391 |
if ((index = doubleCache.putIfAbsent(key, this.currentIndex)) < 0) { |
410 |
index = doubleCache.put(key, currentIndex++); |
392 |
if ((index = -index)> 0xFFFF){ |
411 |
if (index > 0xFFFF){ |
|
|
412 |
this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType()); |
393 |
this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType()); |
413 |
} |
394 |
} |
414 |
currentIndex++; // a double needs an extra place into the constant pool |
395 |
this.currentIndex += 2; // a double needs an extra place into the constant pool |
415 |
// Write the double into the constant pool |
396 |
// Write the double into the constant pool |
416 |
// First add the tag |
397 |
// First add the tag |
417 |
writeU1(DoubleTag); |
398 |
writeU1(DoubleTag); |
Lines 421-429
Link Here
|
421 |
if (currentOffset + 8 >= length) { |
402 |
if (currentOffset + 8 >= length) { |
422 |
resizePoolContents(8); |
403 |
resizePoolContents(8); |
423 |
} |
404 |
} |
424 |
for (int i = 0; i < 8; i++) { |
405 |
poolContent[currentOffset++] = (byte) (temp >>> 56); |
425 |
poolContent[currentOffset++] = (byte) (temp >>> (56 - (i << 3))); |
406 |
poolContent[currentOffset++] = (byte) (temp >>> 48); |
426 |
} |
407 |
poolContent[currentOffset++] = (byte) (temp >>> 40); |
|
|
408 |
poolContent[currentOffset++] = (byte) (temp >>> 32); |
409 |
poolContent[currentOffset++] = (byte) (temp >>> 24); |
410 |
poolContent[currentOffset++] = (byte) (temp >>> 16); |
411 |
poolContent[currentOffset++] = (byte) (temp >>> 8); |
412 |
poolContent[currentOffset++] = (byte) temp; |
427 |
} |
413 |
} |
428 |
return index; |
414 |
return index; |
429 |
} |
415 |
} |
Lines 443-453
Link Here
|
443 |
if (floatCache == null) { |
429 |
if (floatCache == null) { |
444 |
floatCache = new FloatCache(FLOAT_INITIAL_SIZE); |
430 |
floatCache = new FloatCache(FLOAT_INITIAL_SIZE); |
445 |
} |
431 |
} |
446 |
if ((index = floatCache.get(key)) < 0) { |
432 |
if ((index = floatCache.putIfAbsent(key, this.currentIndex)) < 0) { |
447 |
index = floatCache.put(key, currentIndex++); |
433 |
if ((index = -index) > 0xFFFF){ |
448 |
if (index > 0xFFFF){ |
|
|
449 |
this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType()); |
434 |
this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType()); |
450 |
} |
435 |
} |
|
|
436 |
this.currentIndex++; |
451 |
// Write the float constant entry into the constant pool |
437 |
// Write the float constant entry into the constant pool |
452 |
// First add the tag |
438 |
// First add the tag |
453 |
writeU1(FloatTag); |
439 |
writeU1(FloatTag); |
Lines 456-464
Link Here
|
456 |
if (currentOffset + 4 >= poolContent.length) { |
442 |
if (currentOffset + 4 >= poolContent.length) { |
457 |
resizePoolContents(4); |
443 |
resizePoolContents(4); |
458 |
} |
444 |
} |
459 |
for (int i = 0; i < 4; i++) { |
445 |
poolContent[currentOffset++] = (byte) (temp >>> 24); |
460 |
poolContent[currentOffset++] = (byte) (temp >>> (24 - i * 8)); |
446 |
poolContent[currentOffset++] = (byte) (temp >>> 16); |
461 |
} |
447 |
poolContent[currentOffset++] = (byte) (temp >>> 8); |
|
|
448 |
poolContent[currentOffset++] = (byte) temp; |
462 |
} |
449 |
} |
463 |
return index; |
450 |
return index; |
464 |
} |
451 |
} |
Lines 478-498
Link Here
|
478 |
if (intCache == null) { |
465 |
if (intCache == null) { |
479 |
intCache = new IntegerCache(INT_INITIAL_SIZE); |
466 |
intCache = new IntegerCache(INT_INITIAL_SIZE); |
480 |
} |
467 |
} |
481 |
if ((index = intCache.get(key)) < 0) { |
468 |
if ((index = intCache.putIfAbsent(key, this.currentIndex)) < 0) { |
482 |
index = intCache.put(key, currentIndex++); |
469 |
this.currentIndex++; |
483 |
if (index > 0xFFFF){ |
470 |
if ((index = -index) > 0xFFFF){ |
484 |
this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType()); |
471 |
this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType()); |
485 |
} |
472 |
} |
486 |
// Write the integer constant entry into the constant pool |
473 |
// Write the integer constant entry into the constant pool |
487 |
// First add the tag |
474 |
// First add the tag |
488 |
writeU1(IntegerTag); |
475 |
writeU1(IntegerTag); |
489 |
// Then add the 4 bytes representing the int |
476 |
// Then add the 4 bytes representing the int |
490 |
if (currentOffset + 4 >= poolContent.length) { |
477 |
if (currentOffset + 4 >= poolContent.length) { |
491 |
resizePoolContents(4); |
478 |
resizePoolContents(4); |
492 |
} |
479 |
} |
493 |
for (int i = 0; i < 4; i++) { |
480 |
poolContent[currentOffset++] = (byte) (key >>> 24); |
494 |
poolContent[currentOffset++] = (byte) (key >>> (24 - i * 8)); |
481 |
poolContent[currentOffset++] = (byte) (key >>> 16); |
495 |
} |
482 |
poolContent[currentOffset++] = (byte) (key >>> 8); |
|
|
483 |
poolContent[currentOffset++] = (byte) key; |
496 |
} |
484 |
} |
497 |
return index; |
485 |
return index; |
498 |
} |
486 |
} |
Lines 514-525
Link Here
|
514 |
if (longCache == null) { |
502 |
if (longCache == null) { |
515 |
longCache = new LongCache(LONG_INITIAL_SIZE); |
503 |
longCache = new LongCache(LONG_INITIAL_SIZE); |
516 |
} |
504 |
} |
517 |
if ((index = longCache.get(key)) < 0) { |
505 |
if ((index = longCache.putIfAbsent(key, this.currentIndex)) < 0) { |
518 |
index = longCache.put(key, currentIndex++); |
506 |
if ((index = -index) > 0xFFFF){ |
519 |
if (index > 0xFFFF){ |
|
|
520 |
this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType()); |
507 |
this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType()); |
521 |
} |
508 |
} |
522 |
currentIndex++; // long value need an extra place into thwe constant pool |
509 |
this.currentIndex+= 2; // long value need an extra place into thwe constant pool |
523 |
// Write the long into the constant pool |
510 |
// Write the long into the constant pool |
524 |
// First add the tag |
511 |
// First add the tag |
525 |
writeU1(LongTag); |
512 |
writeU1(LongTag); |
Lines 527-535
Link Here
|
527 |
if (currentOffset + 8 >= poolContent.length) { |
514 |
if (currentOffset + 8 >= poolContent.length) { |
528 |
resizePoolContents(8); |
515 |
resizePoolContents(8); |
529 |
} |
516 |
} |
530 |
for (int i = 0; i < 8; i++) { |
517 |
poolContent[currentOffset++] = (byte) (key >>> 56); |
531 |
poolContent[currentOffset++] = (byte) (key >>> (56 - (i << 3))); |
518 |
poolContent[currentOffset++] = (byte) (key >>> 48); |
532 |
} |
519 |
poolContent[currentOffset++] = (byte) (key >>> 40); |
|
|
520 |
poolContent[currentOffset++] = (byte) (key >>> 32); |
521 |
poolContent[currentOffset++] = (byte) (key >>> 24); |
522 |
poolContent[currentOffset++] = (byte) (key >>> 16); |
523 |
poolContent[currentOffset++] = (byte) (key >>> 8); |
524 |
poolContent[currentOffset++] = (byte) key; |
533 |
} |
525 |
} |
534 |
return index; |
526 |
return index; |
535 |
} |
527 |
} |
Lines 542-616
Link Here
|
542 |
public int literalIndex(String stringConstant) { |
534 |
public int literalIndex(String stringConstant) { |
543 |
int index; |
535 |
int index; |
544 |
char[] stringCharArray = stringConstant.toCharArray(); |
536 |
char[] stringCharArray = stringConstant.toCharArray(); |
545 |
if ((index = stringCache.get(stringCharArray)) < 0) { |
537 |
if ((index = stringCache.putIfAbsent(stringCharArray, this.currentIndex)) < 0) { |
546 |
// The entry doesn't exit yet |
538 |
// The entry doesn't exit yet |
547 |
int stringIndex = literalIndex(stringCharArray); |
539 |
currentIndex++; |
548 |
index = stringCache.put(stringCharArray, currentIndex++); |
540 |
if ((index = -index)> 0xFFFF){ |
549 |
if (index > 0xFFFF){ |
|
|
550 |
this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType()); |
541 |
this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType()); |
551 |
} |
542 |
} |
552 |
// Write the tag first |
543 |
// Write the tag first |
553 |
writeU1(StringTag); |
544 |
writeU1(StringTag); |
554 |
// Then the string index |
545 |
// Then the string index |
555 |
writeU2(stringIndex); |
546 |
int stringIndexOffset = this.currentOffset; |
556 |
} |
547 |
if (currentOffset + 2 >= poolContent.length) { |
557 |
return index; |
548 |
resizePoolContents(2); |
558 |
} |
|
|
559 |
/** |
560 |
* This method returns the index into the constantPool |
561 |
* corresponding to the field binding aFieldBinding. |
562 |
* |
563 |
* @param aFieldBinding FieldBinding |
564 |
* @return <CODE>int</CODE> |
565 |
*/ |
566 |
public int literalIndex(FieldBinding aFieldBinding) { |
567 |
int index; |
568 |
final char[] name = aFieldBinding.name; |
569 |
final char[] signature = aFieldBinding.type.signature(); |
570 |
final char[] declaringClassConstantPoolName = aFieldBinding.declaringClass.constantPoolName(); |
571 |
if ((index = getFromCache(declaringClassConstantPoolName, name, signature)) < 0) { |
572 |
// The entry doesn't exit yet |
573 |
int classIndex = literalIndexForType(declaringClassConstantPoolName); |
574 |
int nameAndTypeIndex = literalIndexForFields(literalIndex(name), literalIndex(signature), name, signature); |
575 |
index = putInCache(declaringClassConstantPoolName, name, signature, currentIndex++); |
576 |
if (index > 0xFFFF){ |
577 |
this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType()); |
578 |
} |
579 |
writeU1(FieldRefTag); |
580 |
writeU2(classIndex); |
581 |
writeU2(nameAndTypeIndex); |
582 |
} |
583 |
return index; |
584 |
} |
585 |
/** |
586 |
* This method returns the index into the constantPool corresponding to the |
587 |
* method descriptor. It can be either an interface method reference constant |
588 |
* or a method reference constant. |
589 |
* Note: uses the method binding #constantPoolDeclaringClass which could be an array type |
590 |
* for the array clone method (see UpdatedMethodDeclaration). |
591 |
* @param aMethodBinding MethodBinding |
592 |
* @return <CODE>int</CODE> |
593 |
*/ |
594 |
public int literalIndex(MethodBinding aMethodBinding) { |
595 |
int index; |
596 |
final TypeBinding constantPoolDeclaringClass = aMethodBinding.constantPoolDeclaringClass(); |
597 |
final char[] declaringClassConstantPoolName = constantPoolDeclaringClass.constantPoolName(); |
598 |
final char[] selector = aMethodBinding.selector; |
599 |
final char[] signature = aMethodBinding.signature(); |
600 |
if ((index = getFromCache(declaringClassConstantPoolName, selector, signature)) < 0) { |
601 |
int classIndex = literalIndexForType(constantPoolDeclaringClass.constantPoolName()); |
602 |
int nameAndTypeIndex = literalIndexForMethods(literalIndex(selector), literalIndex(signature), selector, signature); |
603 |
index = putInCache(declaringClassConstantPoolName, selector, signature, currentIndex++); |
604 |
if (index > 0xFFFF){ |
605 |
this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType()); |
606 |
} |
549 |
} |
607 |
// Write the interface method ref constant into the constant pool |
550 |
currentOffset+=2; |
608 |
// First add the tag |
551 |
final int stringIndex = literalIndex(stringCharArray); |
609 |
writeU1(constantPoolDeclaringClass.isInterface() || constantPoolDeclaringClass.isAnnotationType() ? InterfaceMethodRefTag : MethodRefTag); |
552 |
poolContent[stringIndexOffset++] = (byte) (stringIndex >> 8); |
610 |
// Then write the class index |
553 |
poolContent[stringIndexOffset] = (byte) stringIndex; |
611 |
writeU2(classIndex); |
|
|
612 |
// The write the nameAndType index |
613 |
writeU2(nameAndTypeIndex); |
614 |
} |
554 |
} |
615 |
return index; |
555 |
return index; |
616 |
} |
556 |
} |
Lines 620-752
Link Here
|
620 |
*/ |
560 |
*/ |
621 |
public int literalIndexForType(final char[] constantPoolName) { |
561 |
public int literalIndexForType(final char[] constantPoolName) { |
622 |
int index; |
562 |
int index; |
623 |
if ((index = classCache.get(constantPoolName)) < 0) { |
563 |
if ((index = classCache.putIfAbsent(constantPoolName, this.currentIndex)) < 0) { |
624 |
// The entry doesn't exit yet |
564 |
// The entry doesn't exit yet |
625 |
int nameIndex = literalIndex(constantPoolName); |
565 |
this.currentIndex++; |
626 |
index = classCache.put(constantPoolName, currentIndex++); |
566 |
if ((index = -index) > 0xFFFF){ |
627 |
if (index > 0xFFFF){ |
|
|
628 |
this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType()); |
567 |
this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType()); |
629 |
} |
568 |
} |
630 |
writeU1(ClassTag); |
569 |
writeU1(ClassTag); |
631 |
// Then add the 8 bytes representing the long |
570 |
|
632 |
writeU2(nameIndex); |
571 |
// Then the name index |
|
|
572 |
int nameIndexOffset = this.currentOffset; |
573 |
if (currentOffset + 2 >= poolContent.length) { |
574 |
resizePoolContents(2); |
575 |
} |
576 |
currentOffset+=2; |
577 |
final int nameIndex = literalIndex(constantPoolName); |
578 |
poolContent[nameIndexOffset++] = (byte) (nameIndex >> 8); |
579 |
poolContent[nameIndexOffset] = (byte) nameIndex; |
633 |
} |
580 |
} |
634 |
return index; |
581 |
return index; |
635 |
} |
582 |
} |
636 |
public int literalIndexForMethod(char[] declaringClass, char[] selector, char[] signature, boolean isInterface) { |
583 |
public int literalIndexForMethod(char[] declaringClass, char[] selector, char[] signature, boolean isInterface) { |
637 |
int index = getFromCache(declaringClass, selector, signature); |
584 |
int index; |
638 |
if (index == -1) { |
585 |
if ((index = putInCacheIfAbsent(declaringClass, selector, signature, this.currentIndex)) < 0) { |
639 |
int classIndex; |
586 |
// it doesn't exist yet |
640 |
if ((classIndex = classCache.get(declaringClass)) < 0) { |
587 |
this.currentIndex++; |
641 |
// The entry doesn't exit yet |
588 |
if ((index = -index) > 0xFFFF){ |
642 |
int nameIndex = literalIndex(declaringClass); |
|
|
643 |
classIndex = classCache.put(declaringClass, this.currentIndex++); |
644 |
if (index > 0xFFFF){ |
645 |
this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType()); |
646 |
} |
647 |
writeU1(ClassTag); |
648 |
// Then add the 8 bytes representing the long |
649 |
writeU2(nameIndex); |
650 |
} |
651 |
int nameAndTypeIndex = literalIndexForMethod(selector, signature); |
652 |
index = putInCache(declaringClass, selector, signature, currentIndex++); |
653 |
if (index > 0xFFFF){ |
654 |
this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType()); |
589 |
this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType()); |
655 |
} |
590 |
} |
656 |
// Write the interface method ref constant into the constant pool |
591 |
// Write the interface method ref constant into the constant pool |
657 |
// First add the tag |
592 |
// First add the tag |
658 |
writeU1(isInterface ? InterfaceMethodRefTag : MethodRefTag); |
593 |
writeU1(isInterface ? InterfaceMethodRefTag : MethodRefTag); |
659 |
// Then write the class index |
594 |
|
660 |
writeU2(classIndex); |
595 |
int classIndexOffset = this.currentOffset; |
661 |
// The write the nameAndType index |
596 |
if (currentOffset + 4 >= poolContent.length) { |
662 |
writeU2(nameAndTypeIndex); |
597 |
resizePoolContents(4); |
663 |
} |
|
|
664 |
return index; |
665 |
} |
666 |
private int literalIndexForField(char[] name, char[] signature) { |
667 |
int index = getFromNameAndTypeCache(name, signature); |
668 |
if (index == -1) { |
669 |
// The entry doesn't exit yet |
670 |
int nameIndex = literalIndex(name); |
671 |
int typeIndex = literalIndex(signature); |
672 |
index = putInNameAndTypeCache(name, signature, currentIndex++); |
673 |
if (index > 0xFFFF){ |
674 |
this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType()); |
675 |
} |
598 |
} |
676 |
writeU1(NameAndTypeTag); |
599 |
currentOffset+=4; |
677 |
writeU2(nameIndex); |
600 |
|
678 |
writeU2(typeIndex); |
601 |
final int classIndex = literalIndexForType(declaringClass); |
|
|
602 |
final int nameAndTypeIndex = literalIndexForNameAndType(selector, signature); |
603 |
|
604 |
poolContent[classIndexOffset++] = (byte) (classIndex >> 8); |
605 |
poolContent[classIndexOffset++] = (byte) classIndex; |
606 |
poolContent[classIndexOffset++] = (byte) (nameAndTypeIndex >> 8); |
607 |
poolContent[classIndexOffset] = (byte) nameAndTypeIndex; |
679 |
} |
608 |
} |
680 |
return index; |
609 |
return index; |
681 |
} |
610 |
} |
682 |
public int literalIndexForMethod(char[] selector, char[] signature) { |
611 |
public int literalIndexForNameAndType(char[] name, char[] signature) { |
683 |
int index = getFromNameAndTypeCache(selector, signature); |
612 |
int index; |
684 |
if (index == -1) { |
613 |
if ((index = putInNameAndTypeCacheIfAbsent(name, signature, currentIndex)) < 0) { |
685 |
// The entry doesn't exit yet |
614 |
// The entry doesn't exit yet |
686 |
int nameIndex = literalIndex(selector); |
615 |
currentIndex++; |
687 |
int typeIndex = literalIndex(signature); |
616 |
if ((index = -index) > 0xFFFF){ |
688 |
index = putInNameAndTypeCache(selector, signature, currentIndex++); |
|
|
689 |
if (index > 0xFFFF){ |
690 |
this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType()); |
617 |
this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType()); |
691 |
} |
618 |
} |
692 |
writeU1(NameAndTypeTag); |
619 |
writeU1(NameAndTypeTag); |
693 |
writeU2(nameIndex); |
620 |
int nameIndexOffset = this.currentOffset; |
694 |
writeU2(typeIndex); |
621 |
if (currentOffset + 4 >= poolContent.length) { |
|
|
622 |
resizePoolContents(4); |
623 |
} |
624 |
currentOffset+=4; |
625 |
|
626 |
final int nameIndex = literalIndex(name); |
627 |
final int typeIndex = literalIndex(signature); |
628 |
poolContent[nameIndexOffset++] = (byte) (nameIndex >> 8); |
629 |
poolContent[nameIndexOffset++] = (byte) nameIndex; |
630 |
poolContent[nameIndexOffset++] = (byte) (typeIndex >> 8); |
631 |
poolContent[nameIndexOffset] = (byte) typeIndex; |
695 |
} |
632 |
} |
696 |
return index; |
633 |
return index; |
697 |
} |
634 |
} |
698 |
public int literalIndexForField(char[] declaringClass, char[] name, char[] signature) { |
635 |
public int literalIndexForField(char[] declaringClass, char[] name, char[] signature) { |
699 |
int index = getFromCache(declaringClass, name, signature); |
636 |
int index; |
700 |
if (index == -1) { |
637 |
if ((index = putInCacheIfAbsent(declaringClass, name, signature, this.currentIndex)) < 0) { |
701 |
int classIndex; |
638 |
this.currentIndex++; |
702 |
if ((classIndex = classCache.get(declaringClass)) < 0) { |
639 |
// doesn't exist yet |
703 |
// The entry doesn't exit yet |
640 |
if ((index = -index) > 0xFFFF){ |
704 |
int nameIndex = literalIndex(declaringClass); |
|
|
705 |
classIndex = classCache.put(declaringClass, this.currentIndex++); |
706 |
if (index > 0xFFFF){ |
707 |
this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType()); |
708 |
} |
709 |
writeU1(ClassTag); |
710 |
// Then add the 8 bytes representing the long |
711 |
writeU2(nameIndex); |
712 |
} |
713 |
int nameAndTypeIndex = literalIndexForField(name, signature); |
714 |
index = putInCache(declaringClass, name, signature, currentIndex++); |
715 |
if (index > 0xFFFF){ |
716 |
this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType()); |
641 |
this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType()); |
717 |
} |
642 |
} |
718 |
// Write the interface method ref constant into the constant pool |
643 |
// Write the interface method ref constant into the constant pool |
719 |
// First add the tag |
644 |
// First add the tag |
720 |
writeU1(FieldRefTag); |
645 |
writeU1(FieldRefTag); |
721 |
// Then write the class index |
646 |
int classIndexOffset = this.currentOffset; |
722 |
writeU2(classIndex); |
647 |
if (currentOffset + 4 >= poolContent.length) { |
723 |
// The write the nameAndType index |
648 |
resizePoolContents(4); |
724 |
writeU2(nameAndTypeIndex); |
|
|
725 |
} |
726 |
return index; |
727 |
} |
728 |
/** |
729 |
* This method returns the index into the constantPool corresponding |
730 |
* nameAndType constant with nameIndex, typeIndex. |
731 |
* |
732 |
* @param nameIndex the given name index |
733 |
* @param typeIndex the given type index |
734 |
* @param name the given field name |
735 |
* @param signature the given field signature |
736 |
* @return the index into the constantPool corresponding |
737 |
* nameAndType constant with nameIndex, typeInde |
738 |
*/ |
739 |
private int literalIndexForFields(int nameIndex, int typeIndex, char[] name, char[] signature) { |
740 |
int index; |
741 |
if ((index = getFromNameAndTypeCache(name, signature)) == -1) { |
742 |
// The entry doesn't exit yet |
743 |
index = putInNameAndTypeCache(name, signature, currentIndex++); |
744 |
if (index > 0xFFFF){ |
745 |
this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType()); |
746 |
} |
649 |
} |
747 |
writeU1(NameAndTypeTag); |
650 |
currentOffset+=4; |
748 |
writeU2(nameIndex); |
651 |
|
749 |
writeU2(typeIndex); |
652 |
final int classIndex = literalIndexForType(declaringClass); |
|
|
653 |
final int nameAndTypeIndex = literalIndexForNameAndType(name, signature); |
654 |
|
655 |
poolContent[classIndexOffset++] = (byte) (classIndex >> 8); |
656 |
poolContent[classIndexOffset++] = (byte) classIndex; |
657 |
poolContent[classIndexOffset++] = (byte) (nameAndTypeIndex >> 8); |
658 |
poolContent[classIndexOffset] = (byte) nameAndTypeIndex; |
750 |
} |
659 |
} |
751 |
return index; |
660 |
return index; |
752 |
} |
661 |
} |
Lines 758-768
Link Here
|
758 |
*/ |
667 |
*/ |
759 |
public int literalIndexForLdc(char[] stringCharArray) { |
668 |
public int literalIndexForLdc(char[] stringCharArray) { |
760 |
int index; |
669 |
int index; |
761 |
if ((index = stringCache.get(stringCharArray)) < 0) { |
670 |
if ((index = stringCache.putIfAbsent(stringCharArray, this.currentIndex)) < 0) { |
762 |
int stringIndex; |
|
|
763 |
// The entry doesn't exit yet |
671 |
// The entry doesn't exit yet |
764 |
if ((stringIndex = UTF8Cache.get(stringCharArray)) < 0) { |
672 |
this.currentIndex++; |
|
|
673 |
// Write the tag first |
674 |
writeU1(StringTag); |
675 |
|
676 |
// Then the string index |
677 |
int stringIndexOffset = this.currentOffset; |
678 |
if (currentOffset + 2 >= poolContent.length) { |
679 |
resizePoolContents(2); |
680 |
} |
681 |
currentOffset+=2; |
682 |
|
683 |
int stringIndex; |
684 |
if ((stringIndex = UTF8Cache.putIfAbsent(stringCharArray, this.currentIndex)) < 0) { |
765 |
// The entry doesn't exit yet |
685 |
// The entry doesn't exit yet |
|
|
686 |
this.currentIndex++; |
766 |
// Write the tag first |
687 |
// Write the tag first |
767 |
writeU1(Utf8Tag); |
688 |
writeU1(Utf8Tag); |
768 |
// Then the size of the stringName array |
689 |
// Then the size of the stringName array |
Lines 778-856
Link Here
|
778 |
char current = stringCharArray[i]; |
699 |
char current = stringCharArray[i]; |
779 |
if ((current >= 0x0001) && (current <= 0x007F)) { |
700 |
if ((current >= 0x0001) && (current <= 0x007F)) { |
780 |
// we only need one byte: ASCII table |
701 |
// we only need one byte: ASCII table |
781 |
writeU1(current); |
|
|
782 |
length++; |
702 |
length++; |
|
|
703 |
if (currentOffset + 1 >= poolContent.length) { |
704 |
// we need to resize the poolContent array because we won't have |
705 |
// enough space to write the length |
706 |
resizePoolContents(1); |
707 |
} |
708 |
poolContent[currentOffset++] = (byte)(current); |
783 |
} else |
709 |
} else |
784 |
if (current > 0x07FF) { |
710 |
if (current > 0x07FF) { |
785 |
// we need 3 bytes |
711 |
// we need 3 bytes |
786 |
length += 3; |
712 |
length += 3; |
787 |
writeU1(0xE0 | ((current >> 12) & 0x0F)); // 0xE0 = 1110 0000 |
713 |
if (currentOffset + 3 >= poolContent.length) { |
788 |
writeU1(0x80 | ((current >> 6) & 0x3F)); // 0x80 = 1000 0000 |
714 |
// we need to resize the poolContent array because we won't have |
789 |
writeU1(0x80 | (current & 0x3F)); // 0x80 = 1000 0000 |
715 |
// enough space to write the length |
|
|
716 |
resizePoolContents(3); |
717 |
} |
718 |
poolContent[currentOffset++] = (byte) (0xE0 | ((current >> 12) & 0x0F)); // 0xE0 = 1110 0000 |
719 |
poolContent[currentOffset++] = (byte) (0x80 | ((current >> 6) & 0x3F)); // 0x80 = 1000 0000 |
720 |
poolContent[currentOffset++] = (byte) (0x80 | (current & 0x3F)); // 0x80 = 1000 0000 |
790 |
} else { |
721 |
} else { |
|
|
722 |
if (currentOffset + 2 >= poolContent.length) { |
723 |
// we need to resize the poolContent array because we won't have |
724 |
// enough space to write the length |
725 |
resizePoolContents(2); |
726 |
} |
791 |
// we can be 0 or between 0x0080 and 0x07FF |
727 |
// we can be 0 or between 0x0080 and 0x07FF |
792 |
// In that case we only need 2 bytes |
728 |
// In that case we only need 2 bytes |
793 |
length += 2; |
729 |
length += 2; |
794 |
writeU1(0xC0 | ((current >> 6) & 0x1F)); // 0xC0 = 1100 0000 |
730 |
poolContent[currentOffset++] = (byte) (0xC0 | ((current >> 6) & 0x1F)); // 0xC0 = 1100 0000 |
795 |
writeU1(0x80 | (current & 0x3F)); // 0x80 = 1000 0000 |
731 |
poolContent[currentOffset++] = (byte) (0x80 | (current & 0x3F)); // 0x80 = 1000 0000 |
796 |
} |
732 |
} |
797 |
} |
733 |
} |
798 |
if (length >= 65535) { |
734 |
if (length >= 65535) { |
799 |
currentOffset = savedCurrentOffset - 1; |
735 |
currentOffset = savedCurrentOffset - 1; |
800 |
return -1; |
736 |
return 0; |
801 |
} |
737 |
} |
802 |
stringIndex = UTF8Cache.put(stringCharArray, currentIndex++); |
|
|
803 |
// Now we know the length that we have to write in the constant pool |
738 |
// Now we know the length that we have to write in the constant pool |
804 |
// we use savedCurrentOffset to do that |
739 |
// we use savedCurrentOffset to do that |
805 |
if (length > 65535) { |
740 |
if (length > 65535) { |
806 |
return 0; |
741 |
return 0; |
807 |
} |
742 |
} |
808 |
poolContent[savedCurrentOffset] = (byte) (length >> 8); |
743 |
poolContent[savedCurrentOffset++] = (byte) (length >> 8); |
809 |
poolContent[savedCurrentOffset + 1] = (byte) length; |
744 |
poolContent[savedCurrentOffset] = (byte) length; |
810 |
} |
745 |
stringIndex = -stringIndex; |
811 |
index = stringCache.put(stringCharArray, currentIndex++); |
|
|
812 |
if (index > 0xFFFF){ |
813 |
this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType()); |
814 |
} |
746 |
} |
815 |
// Write the tag first |
747 |
if ((index = -index) > 0xFFFF){ |
816 |
writeU1(StringTag); |
|
|
817 |
// Then the string index |
818 |
writeU2(stringIndex); |
819 |
} |
820 |
return index; |
821 |
} |
822 |
/** |
823 |
* This method returns the index into the constantPool corresponding |
824 |
* nameAndType constant with nameIndex, typeIndex. |
825 |
* |
826 |
* @param nameIndex the given name index |
827 |
* @param typeIndex the given type index |
828 |
* @param selector the given method selector |
829 |
* @param signature the given method signature |
830 |
* @return <CODE>int</CODE> |
831 |
*/ |
832 |
public int literalIndexForMethods(int nameIndex, int typeIndex, char[] selector, char[] signature) { |
833 |
int index; |
834 |
if ((index = getFromNameAndTypeCache(selector, signature)) == -1) { |
835 |
// The entry doesn't exit yet |
836 |
index = putInNameAndTypeCache(selector, signature, currentIndex++); |
837 |
if (index > 0xFFFF){ |
838 |
this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType()); |
748 |
this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType()); |
839 |
} |
749 |
} |
840 |
writeU1(NameAndTypeTag); |
750 |
poolContent[stringIndexOffset++] = (byte) (stringIndex >> 8); |
841 |
writeU2(nameIndex); |
751 |
poolContent[stringIndexOffset] = (byte) stringIndex; |
842 |
writeU2(typeIndex); |
|
|
843 |
} |
752 |
} |
844 |
return index; |
753 |
return index; |
845 |
} |
754 |
} |
846 |
private int putInNameAndTypeCache(final char[] key1, final char[] key2, int index) { |
755 |
private int putInNameAndTypeCacheIfAbsent(final char[] key1, final char[] key2, int value) { |
847 |
CharArrayCache value = (CharArrayCache) this.nameAndTypeCacheForFieldsAndMethods.get(key1); |
756 |
int index ; |
848 |
if (value == null) { |
757 |
CharArrayCache key1Value = (CharArrayCache) this.nameAndTypeCacheForFieldsAndMethods.get(key1); |
|
|
758 |
if (key1Value == null) { |
849 |
CharArrayCache charArrayCache = new CharArrayCache(); |
759 |
CharArrayCache charArrayCache = new CharArrayCache(); |
850 |
charArrayCache.put(key2, index); |
760 |
index = charArrayCache.putIfAbsent(key2, value); |
851 |
this.nameAndTypeCacheForFieldsAndMethods.put(key1, charArrayCache); |
761 |
this.nameAndTypeCacheForFieldsAndMethods.put(key1, charArrayCache); |
852 |
} else { |
762 |
} else { |
853 |
value.put(key2, index); |
763 |
index = key1Value.putIfAbsent(key2, value); |
854 |
} |
764 |
} |
855 |
return index; |
765 |
return index; |
856 |
} |
766 |
} |
Lines 858-882
Link Here
|
858 |
* @param key1 |
768 |
* @param key1 |
859 |
* @param key2 |
769 |
* @param key2 |
860 |
* @param key3 |
770 |
* @param key3 |
861 |
* @param index |
771 |
* @param value |
862 |
* @return the given index |
772 |
* @return the given index |
863 |
*/ |
773 |
*/ |
864 |
private int putInCache(final char[] key1, final char[] key2, final char[] key3, int index) { |
774 |
private int putInCacheIfAbsent(final char[] key1, final char[] key2, final char[] key3, int value) { |
865 |
HashtableOfObject value = (HashtableOfObject) this.methodsAndFieldsCache.get(key1); |
775 |
int index; |
866 |
if (value == null) { |
776 |
HashtableOfObject key1Value = (HashtableOfObject) this.methodsAndFieldsCache.get(key1); |
867 |
value = new HashtableOfObject(); |
777 |
if (key1Value == null) { |
868 |
this.methodsAndFieldsCache.put(key1, value); |
778 |
key1Value = new HashtableOfObject(); |
|
|
779 |
this.methodsAndFieldsCache.put(key1, key1Value); |
869 |
CharArrayCache charArrayCache = new CharArrayCache(); |
780 |
CharArrayCache charArrayCache = new CharArrayCache(); |
870 |
charArrayCache.put(key3, index); |
781 |
index = charArrayCache.putIfAbsent(key3, value); |
871 |
value.put(key2, charArrayCache); |
782 |
key1Value.put(key2, charArrayCache); |
872 |
} else { |
783 |
} else { |
873 |
CharArrayCache charArrayCache = (CharArrayCache) value.get(key2); |
784 |
CharArrayCache charArrayCache = (CharArrayCache) key1Value.get(key2); |
874 |
if (charArrayCache == null) { |
785 |
if (charArrayCache == null) { |
875 |
charArrayCache = new CharArrayCache(); |
786 |
charArrayCache = new CharArrayCache(); |
876 |
charArrayCache.put(key3, index); |
787 |
index = charArrayCache.putIfAbsent(key3, value); |
877 |
value.put(key2, charArrayCache); |
788 |
key1Value.put(key2, charArrayCache); |
878 |
} else { |
789 |
} else { |
879 |
charArrayCache.put(key3, index); |
790 |
index = charArrayCache.putIfAbsent(key3, value); |
880 |
} |
791 |
} |
881 |
} |
792 |
} |
882 |
return index; |
793 |
return index; |
Lines 931-938
Link Here
|
931 |
if (currentOffset + 2 >= poolContent.length) { |
842 |
if (currentOffset + 2 >= poolContent.length) { |
932 |
resizePoolContents(2); |
843 |
resizePoolContents(2); |
933 |
} |
844 |
} |
934 |
//first byte |
845 |
poolContent[currentOffset++] = (byte) (value >>> 8); |
935 |
poolContent[currentOffset++] = (byte) (value >> 8); |
|
|
936 |
poolContent[currentOffset++] = (byte) value; |
846 |
poolContent[currentOffset++] = (byte) value; |
937 |
} |
847 |
} |
938 |
} |
848 |
} |