91 default: 92 return false; 93 } 94 } 95 } 96 97 /** 98 * Enum of all {@code JVM_CONSTANT} constants used in the VM. This includes the public and 99 * internal ones. 100 */ 101 private enum JVM_CONSTANT { 102 // @formatter:off 103 Utf8(config().jvmConstantUtf8), 104 Integer(config().jvmConstantInteger), 105 Long(config().jvmConstantLong), 106 Float(config().jvmConstantFloat), 107 Double(config().jvmConstantDouble), 108 Class(config().jvmConstantClass), 109 UnresolvedClass(config().jvmConstantUnresolvedClass), 110 UnresolvedClassInError(config().jvmConstantUnresolvedClassInError), 111 Value(config().jvmConstantValue), 112 UnresolvedValue(config().jvmConstantUnresolvedValue), 113 UnresolvedValueInError(config().jvmConstantUnresolvedValueInError), 114 String(config().jvmConstantString), 115 Fieldref(config().jvmConstantFieldref), 116 MethodRef(config().jvmConstantMethodref), 117 InterfaceMethodref(config().jvmConstantInterfaceMethodref), 118 NameAndType(config().jvmConstantNameAndType), 119 MethodHandle(config().jvmConstantMethodHandle), 120 MethodHandleInError(config().jvmConstantMethodHandleInError), 121 MethodType(config().jvmConstantMethodType), 122 MethodTypeInError(config().jvmConstantMethodTypeInError), 123 InvokeDynamic(config().jvmConstantInvokeDynamic); 124 // @formatter:on 125 126 private final int tag; 127 128 private static final int ExternalMax = config().jvmConstantExternalMax; 129 private static final int InternalMin = config().jvmConstantInternalMin; 130 private static final int InternalMax = config().jvmConstantInternalMax; 131 132 JVM_CONSTANT(int tag) { 133 this.tag = tag; 501 private int flags() { 502 return UNSAFE.getInt(getMetaspaceConstantPool() + config().constantPoolFlagsOffset); 503 } 504 505 @Override 506 public Object lookupConstant(int cpi) { 507 assert cpi != 0; 508 final JVM_CONSTANT tag = getTagAt(cpi); 509 switch (tag) { 510 case Integer: 511 return JavaConstant.forInt(getIntAt(cpi)); 512 case Long: 513 return JavaConstant.forLong(getLongAt(cpi)); 514 case Float: 515 return JavaConstant.forFloat(getFloatAt(cpi)); 516 case Double: 517 return JavaConstant.forDouble(getDoubleAt(cpi)); 518 case Class: 519 case UnresolvedClass: 520 case UnresolvedClassInError: 521 case Value: 522 case UnresolvedValue: 523 case UnresolvedValueInError: 524 final int opcode = -1; // opcode is not used 525 return lookupType(cpi, opcode); 526 case String: 527 /* 528 * Normally, we would expect a String here, but anonymous classes can have 529 * "pseudo strings" (arbitrary live objects) patched into a String entry. Such 530 * entries do not have a symbol in the constant pool slot. 531 */ 532 Object string = compilerToVM().resolvePossiblyCachedConstantInPool(this, cpi); 533 return HotSpotObjectConstantImpl.forObject(string); 534 case MethodHandle: 535 case MethodHandleInError: 536 case MethodType: 537 case MethodTypeInError: 538 Object obj = compilerToVM().resolveConstantInPool(this, cpi); 539 return HotSpotObjectConstantImpl.forObject(obj); 540 default: 541 throw new JVMCIError("Unknown constant pool tag %s", tag); 542 } 543 } 701 index = rawIndexToConstantPoolCacheIndex(cpi, opcode); 702 index = compilerToVM().constantPoolRemapInstructionOperandFromCache(this, index); 703 break; 704 } 705 default: 706 throw JVMCIError.shouldNotReachHere("Unexpected opcode " + opcode); 707 } 708 709 final JVM_CONSTANT tag = getTagAt(index); 710 if (tag == null) { 711 assert getTagAt(index - 1) == JVM_CONSTANT.Double || getTagAt(index - 1) == JVM_CONSTANT.Long; 712 return; 713 } 714 switch (tag) { 715 case MethodRef: 716 case Fieldref: 717 case InterfaceMethodref: 718 index = getUncachedKlassRefIndexAt(index); 719 // Read the tag only once because it could change between multiple reads. 720 final JVM_CONSTANT klassTag = getTagAt(index); 721 assert klassTag == JVM_CONSTANT.Class || klassTag == JVM_CONSTANT.UnresolvedClass || klassTag == JVM_CONSTANT.UnresolvedClassInError || 722 klassTag == JVM_CONSTANT.Value || klassTag == JVM_CONSTANT.UnresolvedValue || klassTag == JVM_CONSTANT.UnresolvedValueInError : klassTag; 723 // fall through 724 case Class: 725 case UnresolvedClass: 726 case UnresolvedClassInError: 727 case Value: 728 case UnresolvedValue: 729 case UnresolvedValueInError: 730 final HotSpotResolvedObjectTypeImpl type = compilerToVM().resolveTypeInPool(this, index); 731 Class<?> klass = type.mirror(); 732 if (!klass.isPrimitive() && !klass.isArray()) { 733 UNSAFE.ensureClassInitialized(klass); 734 } 735 if (tag == JVM_CONSTANT.MethodRef) { 736 if (Bytecodes.isInvokeHandleAlias(opcode) && isSignaturePolymorphicHolder(type)) { 737 final int methodRefCacheIndex = rawIndexToConstantPoolCacheIndex(cpi, opcode); 738 assert checkTag(compilerToVM().constantPoolRemapInstructionOperandFromCache(this, methodRefCacheIndex), JVM_CONSTANT.MethodRef); 739 compilerToVM().resolveInvokeHandleInPool(this, methodRefCacheIndex); 740 } 741 } 742 743 break; 744 case InvokeDynamic: 745 if (isInvokedynamicIndex(cpi)) { 746 compilerToVM().resolveInvokeDynamicInPool(this, cpi); 747 } 748 break; 749 default: | 91 default: 92 return false; 93 } 94 } 95 } 96 97 /** 98 * Enum of all {@code JVM_CONSTANT} constants used in the VM. This includes the public and 99 * internal ones. 100 */ 101 private enum JVM_CONSTANT { 102 // @formatter:off 103 Utf8(config().jvmConstantUtf8), 104 Integer(config().jvmConstantInteger), 105 Long(config().jvmConstantLong), 106 Float(config().jvmConstantFloat), 107 Double(config().jvmConstantDouble), 108 Class(config().jvmConstantClass), 109 UnresolvedClass(config().jvmConstantUnresolvedClass), 110 UnresolvedClassInError(config().jvmConstantUnresolvedClassInError), 111 String(config().jvmConstantString), 112 Fieldref(config().jvmConstantFieldref), 113 MethodRef(config().jvmConstantMethodref), 114 InterfaceMethodref(config().jvmConstantInterfaceMethodref), 115 NameAndType(config().jvmConstantNameAndType), 116 MethodHandle(config().jvmConstantMethodHandle), 117 MethodHandleInError(config().jvmConstantMethodHandleInError), 118 MethodType(config().jvmConstantMethodType), 119 MethodTypeInError(config().jvmConstantMethodTypeInError), 120 InvokeDynamic(config().jvmConstantInvokeDynamic); 121 // @formatter:on 122 123 private final int tag; 124 125 private static final int ExternalMax = config().jvmConstantExternalMax; 126 private static final int InternalMin = config().jvmConstantInternalMin; 127 private static final int InternalMax = config().jvmConstantInternalMax; 128 129 JVM_CONSTANT(int tag) { 130 this.tag = tag; 498 private int flags() { 499 return UNSAFE.getInt(getMetaspaceConstantPool() + config().constantPoolFlagsOffset); 500 } 501 502 @Override 503 public Object lookupConstant(int cpi) { 504 assert cpi != 0; 505 final JVM_CONSTANT tag = getTagAt(cpi); 506 switch (tag) { 507 case Integer: 508 return JavaConstant.forInt(getIntAt(cpi)); 509 case Long: 510 return JavaConstant.forLong(getLongAt(cpi)); 511 case Float: 512 return JavaConstant.forFloat(getFloatAt(cpi)); 513 case Double: 514 return JavaConstant.forDouble(getDoubleAt(cpi)); 515 case Class: 516 case UnresolvedClass: 517 case UnresolvedClassInError: 518 final int opcode = -1; // opcode is not used 519 return lookupType(cpi, opcode); 520 case String: 521 /* 522 * Normally, we would expect a String here, but anonymous classes can have 523 * "pseudo strings" (arbitrary live objects) patched into a String entry. Such 524 * entries do not have a symbol in the constant pool slot. 525 */ 526 Object string = compilerToVM().resolvePossiblyCachedConstantInPool(this, cpi); 527 return HotSpotObjectConstantImpl.forObject(string); 528 case MethodHandle: 529 case MethodHandleInError: 530 case MethodType: 531 case MethodTypeInError: 532 Object obj = compilerToVM().resolveConstantInPool(this, cpi); 533 return HotSpotObjectConstantImpl.forObject(obj); 534 default: 535 throw new JVMCIError("Unknown constant pool tag %s", tag); 536 } 537 } 695 index = rawIndexToConstantPoolCacheIndex(cpi, opcode); 696 index = compilerToVM().constantPoolRemapInstructionOperandFromCache(this, index); 697 break; 698 } 699 default: 700 throw JVMCIError.shouldNotReachHere("Unexpected opcode " + opcode); 701 } 702 703 final JVM_CONSTANT tag = getTagAt(index); 704 if (tag == null) { 705 assert getTagAt(index - 1) == JVM_CONSTANT.Double || getTagAt(index - 1) == JVM_CONSTANT.Long; 706 return; 707 } 708 switch (tag) { 709 case MethodRef: 710 case Fieldref: 711 case InterfaceMethodref: 712 index = getUncachedKlassRefIndexAt(index); 713 // Read the tag only once because it could change between multiple reads. 714 final JVM_CONSTANT klassTag = getTagAt(index); 715 assert klassTag == JVM_CONSTANT.Class || klassTag == JVM_CONSTANT.UnresolvedClass || klassTag == JVM_CONSTANT.UnresolvedClassInError 716 : klassTag; 717 // fall through 718 case Class: 719 case UnresolvedClass: 720 case UnresolvedClassInError: 721 final HotSpotResolvedObjectTypeImpl type = compilerToVM().resolveTypeInPool(this, index); 722 Class<?> klass = type.mirror(); 723 if (!klass.isPrimitive() && !klass.isArray()) { 724 UNSAFE.ensureClassInitialized(klass); 725 } 726 if (tag == JVM_CONSTANT.MethodRef) { 727 if (Bytecodes.isInvokeHandleAlias(opcode) && isSignaturePolymorphicHolder(type)) { 728 final int methodRefCacheIndex = rawIndexToConstantPoolCacheIndex(cpi, opcode); 729 assert checkTag(compilerToVM().constantPoolRemapInstructionOperandFromCache(this, methodRefCacheIndex), JVM_CONSTANT.MethodRef); 730 compilerToVM().resolveInvokeHandleInPool(this, methodRefCacheIndex); 731 } 732 } 733 734 break; 735 case InvokeDynamic: 736 if (isInvokedynamicIndex(cpi)) { 737 compilerToVM().resolveInvokeDynamicInPool(this, cpi); 738 } 739 break; 740 default: |