|
47 | 47 | import static jdk.internal.org.objectweb.asm.Opcodes.T_LONG; |
48 | 48 |
|
49 | 49 | import java.lang.invoke.MethodHandle; |
50 | | -import java.util.Collections; |
51 | | -import java.util.HashMap; |
52 | | -import java.util.Map; |
| 50 | +import java.util.concurrent.ConcurrentHashMap; |
| 51 | +import java.util.concurrent.ConcurrentMap; |
53 | 52 | import jdk.internal.org.objectweb.asm.MethodVisitor; |
54 | 53 | import jdk.nashorn.internal.codegen.CompilerConstants.Call; |
55 | 54 |
|
@@ -548,19 +547,19 @@ public String toString() { |
548 | 547 | * @return the Type representing this class |
549 | 548 | */ |
550 | 549 | public static Type typeFor(final Class<?> clazz) { |
551 | | - Type type = cache.get(clazz); |
552 | | - |
553 | | - if (type == null) { |
554 | | - assert !clazz.isPrimitive() || clazz == void.class; |
555 | | - if (clazz.isArray()) { |
556 | | - type = new ArrayType(clazz); |
557 | | - } else { |
558 | | - type = new ObjectType(clazz); |
559 | | - } |
560 | | - cache.put(clazz, type); |
| 550 | + final Type type = cache.get(clazz); |
| 551 | + if(type != null) { |
| 552 | + return type; |
| 553 | + } |
| 554 | + assert !clazz.isPrimitive() || clazz == void.class; |
| 555 | + final Type newType; |
| 556 | + if (clazz.isArray()) { |
| 557 | + newType = new ArrayType(clazz); |
| 558 | + } else { |
| 559 | + newType = new ObjectType(clazz); |
561 | 560 | } |
562 | | - |
563 | | - return type; |
| 561 | + final Type existingType = cache.putIfAbsent(clazz, newType); |
| 562 | + return existingType == null ? newType : existingType; |
564 | 563 | } |
565 | 564 |
|
566 | 565 | @Override |
@@ -663,35 +662,38 @@ private static void swap(final MethodVisitor method, final Type above, final Typ |
663 | 662 | } |
664 | 663 | } |
665 | 664 |
|
| 665 | + /** Mappings between java classes and their Type singletons */ |
| 666 | + private static final ConcurrentMap<Class<?>, Type> cache = new ConcurrentHashMap<>(); |
| 667 | + |
666 | 668 | /** |
667 | 669 | * This is the boolean singleton, used for all boolean types |
668 | 670 | */ |
669 | | - public static final Type BOOLEAN = new BooleanType(); |
| 671 | + public static final Type BOOLEAN = putInCache(new BooleanType()); |
670 | 672 |
|
671 | 673 | /** |
672 | 674 | * This is an integer type, i.e INT, INT32. |
673 | 675 | */ |
674 | | - public static final Type INT = new IntType(); |
| 676 | + public static final Type INT = putInCache(new IntType()); |
675 | 677 |
|
676 | 678 | /** |
677 | 679 | * This is the number singleton, used for all number types |
678 | 680 | */ |
679 | | - public static final Type NUMBER = new NumberType(); |
| 681 | + public static final Type NUMBER = putInCache(new NumberType()); |
680 | 682 |
|
681 | 683 | /** |
682 | 684 | * This is the long singleton, used for all long types |
683 | 685 | */ |
684 | | - public static final Type LONG = new LongType(); |
| 686 | + public static final Type LONG = putInCache(new LongType()); |
685 | 687 |
|
686 | 688 | /** |
687 | 689 | * A string singleton |
688 | 690 | */ |
689 | | - public static final Type STRING = new ObjectType(String.class); |
| 691 | + public static final Type STRING = putInCache(new ObjectType(String.class)); |
690 | 692 |
|
691 | 693 | /** |
692 | 694 | * This is the object singleton, used for all object types |
693 | 695 | */ |
694 | | - public static final Type OBJECT = new ObjectType(); |
| 696 | + public static final Type OBJECT = putInCache(new ObjectType()); |
695 | 697 |
|
696 | 698 | /** |
697 | 699 | * This is the singleton for integer arrays |
@@ -775,13 +777,13 @@ public Type getElementType() { |
775 | 777 | }; |
776 | 778 |
|
777 | 779 | /** Singleton for method handle arrays used for properties etc. */ |
778 | | - public static final ArrayType METHODHANDLE_ARRAY = new ArrayType(MethodHandle[].class); |
| 780 | + public static final ArrayType METHODHANDLE_ARRAY = putInCache(new ArrayType(MethodHandle[].class)); |
779 | 781 |
|
780 | 782 | /** This is the singleton for string arrays */ |
781 | | - public static final ArrayType STRING_ARRAY = new ArrayType(String[].class); |
| 783 | + public static final ArrayType STRING_ARRAY = putInCache(new ArrayType(String[].class)); |
782 | 784 |
|
783 | 785 | /** This is the singleton for object arrays */ |
784 | | - public static final ArrayType OBJECT_ARRAY = new ArrayType(Object[].class); |
| 786 | + public static final ArrayType OBJECT_ARRAY = putInCache(new ArrayType(Object[].class)); |
785 | 787 |
|
786 | 788 | /** This type, always an object type, just a toString override */ |
787 | 789 | public static final Type THIS = new ObjectType() { |
@@ -855,18 +857,8 @@ public Type add(final MethodVisitor method) { |
855 | 857 | } |
856 | 858 | }; |
857 | 859 |
|
858 | | - /** Mappings between java classes and their Type singletons */ |
859 | | - private static final Map<Class<?>, Type> cache = Collections.synchronizedMap(new HashMap<Class<?>, Type>()); |
860 | | - |
861 | | - //TODO may need to be cleared, as all types are retained throughout code generation |
862 | | - static { |
863 | | - cache.put(BOOLEAN.getTypeClass(), BOOLEAN); |
864 | | - cache.put(INT.getTypeClass(), INT); |
865 | | - cache.put(LONG.getTypeClass(), LONG); |
866 | | - cache.put(NUMBER.getTypeClass(), NUMBER); |
867 | | - cache.put(STRING.getTypeClass(), STRING); |
868 | | - cache.put(OBJECT.getTypeClass(), OBJECT); |
869 | | - cache.put(OBJECT_ARRAY.getTypeClass(), OBJECT_ARRAY); |
| 860 | + private static <T extends Type> T putInCache(T type) { |
| 861 | + cache.put(type.getTypeClass(), type); |
| 862 | + return type; |
870 | 863 | } |
871 | | - |
872 | 864 | } |
0 commit comments