提交 bb2f0304 编写于 作者: T twisti

8019192: StringIndexOutOfBoundsException: in Class.getSimpleName()

Reviewed-by: jrose
上级 f364cf4e
...@@ -98,7 +98,9 @@ import java.util.Objects; ...@@ -98,7 +98,9 @@ import java.util.Objects;
public String getName() { public String getName() {
if (name == null) { if (name == null) {
expandFromVM(); expandFromVM();
if (name == null) return null; if (name == null) {
return null;
}
} }
return name; return name;
} }
...@@ -119,28 +121,39 @@ import java.util.Objects; ...@@ -119,28 +121,39 @@ import java.util.Objects;
public MethodType getMethodType() { public MethodType getMethodType() {
if (type == null) { if (type == null) {
expandFromVM(); expandFromVM();
if (type == null) return null; if (type == null) {
return null;
} }
if (!isInvocable()) }
if (!isInvocable()) {
throw newIllegalArgumentException("not invocable, no method type"); throw newIllegalArgumentException("not invocable, no method type");
}
{
// Get a snapshot of type which doesn't get changed by racing threads.
final Object type = this.type;
if (type instanceof MethodType) { if (type instanceof MethodType) {
return (MethodType) type; return (MethodType) type;
} }
}
// type is not a MethodType yet. Convert it thread-safely.
synchronized (this) {
if (type instanceof String) { if (type instanceof String) {
String sig = (String) type; String sig = (String) type;
MethodType res = MethodType.fromMethodDescriptorString(sig, getClassLoader()); MethodType res = MethodType.fromMethodDescriptorString(sig, getClassLoader());
this.type = res; type = res;
return res; } else if (type instanceof Object[]) {
}
if (type instanceof Object[]) {
Object[] typeInfo = (Object[]) type; Object[] typeInfo = (Object[]) type;
Class<?>[] ptypes = (Class<?>[]) typeInfo[1]; Class<?>[] ptypes = (Class<?>[]) typeInfo[1];
Class<?> rtype = (Class<?>) typeInfo[0]; Class<?> rtype = (Class<?>) typeInfo[0];
MethodType res = MethodType.methodType(rtype, ptypes); MethodType res = MethodType.methodType(rtype, ptypes);
this.type = res; type = res;
return res;
} }
throw new InternalError("bad method type "+type); // Make sure type is a MethodType for racing threads.
assert type instanceof MethodType : "bad method type " + type;
}
return (MethodType) type;
} }
/** Return the actual type under which this method or constructor must be invoked. /** Return the actual type under which this method or constructor must be invoked.
...@@ -173,21 +186,34 @@ import java.util.Objects; ...@@ -173,21 +186,34 @@ import java.util.Objects;
public Class<?> getFieldType() { public Class<?> getFieldType() {
if (type == null) { if (type == null) {
expandFromVM(); expandFromVM();
if (type == null) return null; if (type == null) {
return null;
} }
if (isInvocable()) }
if (isInvocable()) {
throw newIllegalArgumentException("not a field or nested class, no simple type"); throw newIllegalArgumentException("not a field or nested class, no simple type");
}
{
// Get a snapshot of type which doesn't get changed by racing threads.
final Object type = this.type;
if (type instanceof Class<?>) { if (type instanceof Class<?>) {
return (Class<?>) type; return (Class<?>) type;
} }
}
// type is not a Class yet. Convert it thread-safely.
synchronized (this) {
if (type instanceof String) { if (type instanceof String) {
String sig = (String) type; String sig = (String) type;
MethodType mtype = MethodType.fromMethodDescriptorString("()"+sig, getClassLoader()); MethodType mtype = MethodType.fromMethodDescriptorString("()"+sig, getClassLoader());
Class<?> res = mtype.returnType(); Class<?> res = mtype.returnType();
this.type = res; type = res;
return res;
} }
throw new InternalError("bad field type "+type); // Make sure type is a Class for racing threads.
assert type instanceof Class<?> : "bad field type " + type;
}
return (Class<?>) type;
} }
/** Utility method to produce either the method type or field type of this member. */ /** Utility method to produce either the method type or field type of this member. */
...@@ -201,10 +227,10 @@ import java.util.Objects; ...@@ -201,10 +227,10 @@ import java.util.Objects;
public String getSignature() { public String getSignature() {
if (type == null) { if (type == null) {
expandFromVM(); expandFromVM();
if (type == null) return null; if (type == null) {
return null;
}
} }
if (type instanceof String)
return (String) type;
if (isInvocable()) if (isInvocable())
return BytecodeDescriptor.unparse(getMethodType()); return BytecodeDescriptor.unparse(getMethodType());
else else
...@@ -463,10 +489,17 @@ import java.util.Objects; ...@@ -463,10 +489,17 @@ import java.util.Objects;
//assert(referenceKindIsConsistent()); // do this after resolution //assert(referenceKindIsConsistent()); // do this after resolution
} }
/**
* Calls down to the VM to fill in the fields. This method is
* synchronized to avoid racing calls.
*/
private void expandFromVM() { private void expandFromVM() {
if (!isResolved()) return; if (type != null) {
if (type instanceof Object[]) return;
type = null; // don't saddle JVM w/ typeInfo }
if (!isResolved()) {
return;
}
MethodHandleNatives.expand(this); MethodHandleNatives.expand(this);
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册