< prev index next >
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.java/src/org/graalvm/compiler/java/BytecodeParser.java
Print this page
rev 52509 : [mq]: graal2
@@ -422,10 +422,11 @@
import org.graalvm.compiler.nodes.type.StampTool;
import org.graalvm.compiler.nodes.util.GraphUtil;
import org.graalvm.compiler.options.OptionValues;
import org.graalvm.compiler.phases.OptimisticOptimizations;
import org.graalvm.compiler.phases.util.ValueMergeUtil;
+import org.graalvm.compiler.serviceprovider.GraalServices;
import jdk.internal.vm.compiler.word.LocationIdentity;
import jdk.vm.ci.code.BailoutException;
import jdk.vm.ci.code.BytecodeFrame;
import jdk.vm.ci.code.CodeUtil;
@@ -1035,10 +1036,19 @@
DeoptimizeNode deopt = append(new DeoptimizeNode(InvalidateRecompile, Unresolved));
deopt.updateNodeSourcePosition(() -> createBytecodePosition());
}
/**
+ * @param type the type being instantiated
+ */
+ protected void handleIllegalNewInstance(JavaType type) {
+ assert !graphBuilderConfig.unresolvedIsError();
+ DeoptimizeNode deopt = append(new DeoptimizeNode(InvalidateRecompile, Unresolved));
+ deopt.updateNodeSourcePosition(() -> createBytecodePosition());
+ }
+
+ /**
* @param type the type of the array being instantiated
* @param length the length of the array
*/
protected void handleUnresolvedNewObjectArray(JavaType type, ValueNode length) {
assert !graphBuilderConfig.unresolvedIsError();
@@ -1416,10 +1426,18 @@
return resolvedType.isInterface() || resolvedType.isLinked();
}
return false;
}
+ /**
+ * Check if a type is resolved. Can be overwritten by sub-classes to implement different type
+ * resolution rules.
+ */
+ protected boolean typeIsResolved(JavaType type) {
+ return type instanceof ResolvedJavaType;
+ }
+
protected void genInvokeStatic(int cpi, int opcode) {
JavaMethod target = lookupMethod(cpi, opcode);
assert !uninitializedIsError ||
(target instanceof ResolvedJavaMethod && ((ResolvedJavaMethod) target).getDeclaringClass().isInitialized()) : target;
genInvokeStatic(target);
@@ -1475,11 +1493,32 @@
}
}
protected void genInvokeVirtual(int cpi, int opcode) {
JavaMethod target = lookupMethod(cpi, opcode);
- genInvokeVirtual(target);
+ if (callTargetIsResolved(target)) {
+ genInvokeVirtual((ResolvedJavaMethod) target);
+ } else {
+ handleUnresolvedInvoke(target, InvokeKind.Virtual);
+ }
+ }
+
+ protected void genInvokeVirtual(ResolvedJavaMethod resolvedTarget) {
+ int cpi = stream.readCPI();
+
+ /*
+ * Special handling for runtimes that rewrite an invocation of MethodHandle.invoke(...) or
+ * MethodHandle.invokeExact(...) to a static adapter. HotSpot does this - see
+ * https://wiki.openjdk.java.net/display/HotSpot/Method+handles+and+invokedynamic
+ */
+
+ if (genDynamicInvokeHelper(resolvedTarget, cpi, INVOKEVIRTUAL)) {
+ return;
+ }
+
+ ValueNode[] args = frameState.popArguments(resolvedTarget.getSignature().getParameterCount(true));
+ appendInvoke(InvokeKind.Virtual, resolvedTarget, args);
}
private boolean genDynamicInvokeHelper(ResolvedJavaMethod target, int cpi, int opcode) {
assert opcode == INVOKEDYNAMIC || opcode == INVOKEVIRTUAL;
@@ -1528,40 +1567,10 @@
}
return true;
}
- void genInvokeVirtual(JavaMethod target) {
- if (!genInvokeVirtualHelper(target)) {
- handleUnresolvedInvoke(target, InvokeKind.Virtual);
- }
- }
-
- private boolean genInvokeVirtualHelper(JavaMethod target) {
- if (!callTargetIsResolved(target)) {
- return false;
- }
-
- ResolvedJavaMethod resolvedTarget = (ResolvedJavaMethod) target;
- int cpi = stream.readCPI();
-
- /*
- * Special handling for runtimes that rewrite an invocation of MethodHandle.invoke(...) or
- * MethodHandle.invokeExact(...) to a static adapter. HotSpot does this - see
- * https://wiki.openjdk.java.net/display/HotSpot/Method+handles+and+invokedynamic
- */
-
- if (genDynamicInvokeHelper(resolvedTarget, cpi, INVOKEVIRTUAL)) {
- return true;
- }
-
- ValueNode[] args = frameState.popArguments(target.getSignature().getParameterCount(true));
- appendInvoke(InvokeKind.Virtual, (ResolvedJavaMethod) target, args);
-
- return true;
- }
-
protected void genInvokeSpecial(int cpi, int opcode) {
JavaMethod target = lookupMethod(cpi, opcode);
genInvokeSpecial(target);
}
@@ -3016,11 +3025,11 @@
JavaType catchType = block.handler.getCatchType();
if (graphBuilderConfig.eagerResolving()) {
catchType = lookupType(block.handler.catchTypeCPI(), INSTANCEOF);
}
- if (catchType instanceof ResolvedJavaType) {
+ if (typeIsResolved(catchType)) {
TypeReference checkedCatchType = TypeReference.createTrusted(graph.getAssumptions(), (ResolvedJavaType) catchType);
if (graphBuilderConfig.getSkippedExceptionTypes() != null) {
for (ResolvedJavaType skippedType : graphBuilderConfig.getSkippedExceptionTypes()) {
if (skippedType.isAssignableFrom(checkedCatchType.getType())) {
@@ -3665,11 +3674,11 @@
Object con = lookupConstant(cpi, opcode);
if (con instanceof JavaType) {
// this is a load of class constant which might be unresolved
JavaType type = (JavaType) con;
- if (type instanceof ResolvedJavaType) {
+ if (typeIsResolved(type)) {
frameState.push(JavaKind.Object, appendConstant(getConstantReflection().asJavaClass((ResolvedJavaType) type)));
} else {
handleUnresolvedLoadConstant(type);
}
} else if (con instanceof JavaConstant) {
@@ -3921,20 +3930,60 @@
JavaType result = constantPool.lookupType(cpi, bytecode);
assert !graphBuilderConfig.unresolvedIsError() || result instanceof ResolvedJavaType;
return result;
}
+ private String unresolvedMethodAssertionMessage(JavaMethod result) {
+ String message = result.format("%H.%n(%P)%R");
+ if (GraalServices.Java8OrEarlier) {
+ JavaType declaringClass = result.getDeclaringClass();
+ String className = declaringClass.getName();
+ switch (className) {
+ case "Ljava/nio/ByteBuffer;":
+ case "Ljava/nio/ShortBuffer;":
+ case "Ljava/nio/CharBuffer;":
+ case "Ljava/nio/IntBuffer;":
+ case "Ljava/nio/LongBuffer;":
+ case "Ljava/nio/FloatBuffer;":
+ case "Ljava/nio/DoubleBuffer;":
+ case "Ljava/nio/MappedByteBuffer;": {
+ switch (result.getName()) {
+ case "position":
+ case "limit":
+ case "mark":
+ case "reset":
+ case "clear":
+ case "flip":
+ case "rewind": {
+ String returnType = result.getSignature().getReturnType(null).toJavaName();
+ if (returnType.equals(declaringClass.toJavaName())) {
+ message += String.format(" [Probably cause: %s was compiled with javac from JDK 9+ using " +
+ "`-target 8` and `-source 8` options. See https://bugs.openjdk.java.net/browse/JDK-4774077 for details.]", method.getDeclaringClass().toClassName());
+ }
+ }
+ }
+ break;
+ }
+ }
+ }
+ return message;
+ }
+
private JavaMethod lookupMethod(int cpi, int opcode) {
maybeEagerlyResolve(cpi, opcode);
JavaMethod result = constantPool.lookupMethod(cpi, opcode);
- assert !graphBuilderConfig.unresolvedIsError() || result instanceof ResolvedJavaMethod : result;
+ assert !graphBuilderConfig.unresolvedIsError() || result instanceof ResolvedJavaMethod : unresolvedMethodAssertionMessage(result);
return result;
}
protected JavaField lookupField(int cpi, int opcode) {
maybeEagerlyResolve(cpi, opcode);
JavaField result = constantPool.lookupField(cpi, method, opcode);
+ return lookupField(result);
+ }
+
+ protected JavaField lookupField(JavaField result) {
assert !graphBuilderConfig.unresolvedIsError() || result instanceof ResolvedJavaField : "Not resolved: " + result;
if (parsingIntrinsic() || eagerInitializing) {
if (result instanceof ResolvedJavaField) {
ResolvedJavaType declaringClass = ((ResolvedJavaField) result).getDeclaringClass();
if (!declaringClass.isInitialized()) {
@@ -3982,20 +4031,26 @@
} else {
return profilingInfo.getTypeProfile(bci());
}
}
- private void genCheckCast() {
- int cpi = getStream().readCPI();
+ private void genCheckCast(int cpi) {
JavaType type = lookupType(cpi, CHECKCAST);
ValueNode object = frameState.pop(JavaKind.Object);
+ genCheckCast(type, object);
+ }
- if (!(type instanceof ResolvedJavaType)) {
+ protected void genCheckCast(JavaType type, ValueNode object) {
+ if (typeIsResolved(type)) {
+ genCheckCast((ResolvedJavaType) type, object);
+ } else {
handleUnresolvedCheckCast(type, object);
- return;
}
- ResolvedJavaType resolvedType = (ResolvedJavaType) type;
+ }
+
+ protected void genCheckCast(ResolvedJavaType resolvedType, ValueNode objectIn) {
+ ValueNode object = objectIn;
TypeReference checkedType = TypeReference.createTrusted(graph.getAssumptions(), resolvedType);
JavaTypeProfile profile = getProfileForTypeCheck(checkedType);
for (NodePlugin plugin : graphBuilderConfig.getPlugins().getNodePlugins()) {
if (plugin.handleCheckCast(this, object, checkedType.getType(), profile)) {
@@ -4039,24 +4094,31 @@
}
}
frameState.push(JavaKind.Object, castNode);
}
- private void genInstanceOf() {
- int cpi = getStream().readCPI();
+ private void genInstanceOf(int cpi) {
JavaType type = lookupType(cpi, INSTANCEOF);
ValueNode object = frameState.pop(JavaKind.Object);
+ genInstanceOf(type, object);
+ }
- if (!(type instanceof ResolvedJavaType)) {
+ protected void genInstanceOf(JavaType type, ValueNode object) {
+ if (typeIsResolved(type)) {
+ genInstanceOf((ResolvedJavaType) type, object);
+ } else {
handleUnresolvedInstanceOf(type, object);
- return;
}
- TypeReference resolvedType = TypeReference.createTrusted(graph.getAssumptions(), (ResolvedJavaType) type);
- JavaTypeProfile profile = getProfileForTypeCheck(resolvedType);
+ }
+
+ protected void genInstanceOf(ResolvedJavaType resolvedType, ValueNode objectIn) {
+ ValueNode object = objectIn;
+ TypeReference checkedType = TypeReference.createTrusted(graph.getAssumptions(), resolvedType);
+ JavaTypeProfile profile = getProfileForTypeCheck(checkedType);
for (NodePlugin plugin : graphBuilderConfig.getPlugins().getNodePlugins()) {
- if (plugin.handleInstanceOf(this, object, resolvedType.getType(), profile)) {
+ if (plugin.handleInstanceOf(this, object, checkedType.getType(), profile)) {
return;
}
}
LogicNode instanceOfNode = null;
@@ -4067,16 +4129,16 @@
if (singleType != null) {
LogicNode typeCheck = append(createInstanceOf(TypeReference.createExactTrusted(singleType), object, profile));
if (!typeCheck.isTautology()) {
append(new FixedGuardNode(typeCheck, DeoptimizationReason.TypeCheckedInliningViolated, DeoptimizationAction.InvalidateReprofile));
}
- instanceOfNode = LogicConstantNode.forBoolean(resolvedType.getType().isAssignableFrom(singleType));
+ instanceOfNode = LogicConstantNode.forBoolean(checkedType.getType().isAssignableFrom(singleType));
}
}
}
if (instanceOfNode == null) {
- instanceOfNode = createInstanceOf(resolvedType, object, null);
+ instanceOfNode = createInstanceOf(checkedType, object, null);
}
LogicNode logicNode = genUnique(instanceOfNode);
int next = getStream().nextBCI();
int value = getStream().readUByte(next);
@@ -4104,24 +4166,27 @@
protected void genNewInstance(int cpi) {
JavaType type = lookupType(cpi, NEW);
genNewInstance(type);
}
- void genNewInstance(JavaType type) {
- if (!(type instanceof ResolvedJavaType)) {
+ protected void genNewInstance(JavaType type) {
+ if (typeIsResolved(type)) {
+ genNewInstance((ResolvedJavaType) type);
+ } else {
handleUnresolvedNewInstance(type);
- return;
}
- ResolvedJavaType resolvedType = (ResolvedJavaType) type;
+ }
+
+ protected void genNewInstance(ResolvedJavaType resolvedType) {
if (resolvedType.isAbstract() || resolvedType.isInterface()) {
- handleUnresolvedNewInstance(type);
+ handleIllegalNewInstance(resolvedType);
return;
}
ClassInitializationPlugin classInitializationPlugin = graphBuilderConfig.getPlugins().getClassInitializationPlugin();
if (!resolvedType.isInitialized() && classInitializationPlugin == null) {
- handleUnresolvedNewInstance(type);
+ handleIllegalNewInstance(resolvedType);
return;
}
ResolvedJavaType[] skippedExceptionTypes = this.graphBuilderConfig.getSkippedExceptionTypes();
if (skippedExceptionTypes != null) {
@@ -4190,18 +4255,23 @@
frameState.push(JavaKind.Object, append(createNewArray(elementType, length, true)));
}
private void genNewObjectArray(int cpi) {
JavaType type = lookupType(cpi, ANEWARRAY);
+ genNewObjectArray(type);
+ }
- if (!(type instanceof ResolvedJavaType)) {
+ private void genNewObjectArray(JavaType type) {
+ if (typeIsResolved(type)) {
+ genNewObjectArray((ResolvedJavaType) type);
+ } else {
ValueNode length = frameState.pop(JavaKind.Int);
handleUnresolvedNewObjectArray(type, length);
- return;
+ }
}
- ResolvedJavaType resolvedType = (ResolvedJavaType) type;
+ private void genNewObjectArray(ResolvedJavaType resolvedType) {
ClassInitializationPlugin classInitializationPlugin = this.graphBuilderConfig.getPlugins().getClassInitializationPlugin();
if (classInitializationPlugin != null && classInitializationPlugin.shouldApply(this, resolvedType.getArrayClass())) {
FrameState stateBefore = frameState.create(bci(), getNonIntrinsicAncestor(), false, null, null);
classInitializationPlugin.apply(this, resolvedType.getArrayClass(), stateBefore);
@@ -4219,19 +4289,25 @@
private void genNewMultiArray(int cpi) {
JavaType type = lookupType(cpi, MULTIANEWARRAY);
int rank = getStream().readUByte(bci() + 3);
ValueNode[] dims = new ValueNode[rank];
+ genNewMultiArray(type, rank, dims);
+ }
- if (!(type instanceof ResolvedJavaType)) {
+ private void genNewMultiArray(JavaType type, int rank, ValueNode[] dims) {
+ if (typeIsResolved(type)) {
+ genNewMultiArray((ResolvedJavaType) type, rank, dims);
+ } else {
for (int i = rank - 1; i >= 0; i--) {
dims[i] = frameState.pop(JavaKind.Int);
}
handleUnresolvedNewMultiArray(type, dims);
- return;
}
- ResolvedJavaType resolvedType = (ResolvedJavaType) type;
+ }
+
+ private void genNewMultiArray(ResolvedJavaType resolvedType, int rank, ValueNode[] dims) {
ClassInitializationPlugin classInitializationPlugin = this.graphBuilderConfig.getPlugins().getClassInitializationPlugin();
if (classInitializationPlugin != null && classInitializationPlugin.shouldApply(this, resolvedType)) {
FrameState stateBefore = frameState.create(bci(), getNonIntrinsicAncestor(), false, null, null);
classInitializationPlugin.apply(this, resolvedType, stateBefore);
@@ -4258,16 +4334,16 @@
JavaField field = lookupField(cpi, opcode);
genGetField(field, receiverInput);
}
private void genGetField(JavaField field, ValueNode receiverInput) {
- ValueNode receiver = maybeEmitExplicitNullCheck(receiverInput);
if (field instanceof ResolvedJavaField) {
+ ValueNode receiver = maybeEmitExplicitNullCheck(receiverInput);
ResolvedJavaField resolvedField = (ResolvedJavaField) field;
genGetField(resolvedField, receiver);
} else {
- handleUnresolvedLoadField(field, receiver);
+ handleUnresolvedLoadField(field, receiverInput);
}
}
private void genGetField(ResolvedJavaField resolvedField, ValueNode receiver) {
if (!parsingIntrinsic() && GeneratePIC.getValue(getOptions())) {
@@ -4368,13 +4444,14 @@
protected void genPutField(JavaField field) {
genPutField(field, frameState.pop(field.getJavaKind()));
}
private void genPutField(JavaField field, ValueNode value) {
- ValueNode receiver = maybeEmitExplicitNullCheck(frameState.pop(JavaKind.Object));
+ ValueNode receiverInput = frameState.pop(JavaKind.Object);
if (field instanceof ResolvedJavaField) {
+ ValueNode receiver = maybeEmitExplicitNullCheck(receiverInput);
ResolvedJavaField resolvedField = (ResolvedJavaField) field;
if (!parsingIntrinsic() && GeneratePIC.getValue(getOptions())) {
graph.recordField(resolvedField);
}
@@ -4388,11 +4465,11 @@
if (resolvedField.isFinal() && method.isConstructor()) {
finalBarrierRequired = true;
}
genStoreField(receiver, resolvedField, value);
} else {
- handleUnresolvedStoreField(field, value, receiver);
+ handleUnresolvedStoreField(field, value, receiverInput);
}
}
protected void genGetStatic(int cpi, int opcode) {
JavaField field = lookupField(cpi, opcode);
@@ -4482,10 +4559,11 @@
JavaField field = lookupField(cpi, opcode);
genPutStatic(field);
}
protected void genPutStatic(JavaField field) {
+ int stackSizeBefore = frameState.stackSize();
ValueNode value = frameState.pop(field.getJavaKind());
ResolvedJavaField resolvedField = resolveStaticFieldAccess(field, value);
if (resolvedField == null) {
return;
}
@@ -4494,11 +4572,14 @@
graph.recordField(resolvedField);
}
ClassInitializationPlugin classInitializationPlugin = this.graphBuilderConfig.getPlugins().getClassInitializationPlugin();
if (classInitializationPlugin != null && classInitializationPlugin.shouldApply(this, resolvedField.getDeclaringClass())) {
- FrameState stateBefore = frameState.create(bci(), getNonIntrinsicAncestor(), false, null, null);
+ JavaKind[] pushedSlotKinds = {field.getJavaKind()};
+ ValueNode[] pushedValues = {value};
+ FrameState stateBefore = frameState.create(bci(), getNonIntrinsicAncestor(), false, pushedSlotKinds, pushedValues);
+ assert stackSizeBefore == stateBefore.stackSize();
classInitializationPlugin.apply(this, resolvedField.getDeclaringClass(), stateBefore);
}
for (NodePlugin plugin : graphBuilderConfig.getPlugins().getNodePlugins()) {
if (plugin.handleStoreStaticField(this, resolvedField, value)) {
@@ -4867,12 +4948,12 @@
case NEW : genNewInstance(stream.readCPI()); break;
case NEWARRAY : genNewPrimitiveArray(stream.readLocalIndex()); break;
case ANEWARRAY : genNewObjectArray(stream.readCPI()); break;
case ARRAYLENGTH : genArrayLength(); break;
case ATHROW : genThrow(); break;
- case CHECKCAST : genCheckCast(); break;
- case INSTANCEOF : genInstanceOf(); break;
+ case CHECKCAST : genCheckCast(stream.readCPI()); break;
+ case INSTANCEOF : genInstanceOf(stream.readCPI()); break;
case MONITORENTER : genMonitorEnter(frameState.pop(JavaKind.Object), stream.nextBCI()); break;
case MONITOREXIT : genMonitorExit(frameState.pop(JavaKind.Object), null, stream.nextBCI()); break;
case MULTIANEWARRAY : genNewMultiArray(stream.readCPI()); break;
case IFNULL : genIfNull(Condition.EQ); break;
case IFNONNULL : genIfNull(Condition.NE); break;
< prev index next >