< prev index next >
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.java/src/org/graalvm/compiler/java/BytecodeParser.java
Print this page
*** 1,7 ****
/*
! * Copyright (c) 2009, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
--- 1,7 ----
/*
! * Copyright (c) 2009, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*** 372,381 ****
--- 372,382 ----
import org.graalvm.compiler.nodes.extended.LoadMethodNode;
import org.graalvm.compiler.nodes.extended.MembarNode;
import org.graalvm.compiler.nodes.extended.StateSplitProxyNode;
import org.graalvm.compiler.nodes.extended.ValueAnchorNode;
import org.graalvm.compiler.nodes.graphbuilderconf.ClassInitializationPlugin;
+ import org.graalvm.compiler.nodes.graphbuilderconf.InvokeDynamicPlugin;
import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration;
import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration.BytecodeExceptionMode;
import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderContext;
import org.graalvm.compiler.nodes.graphbuilderconf.InlineInvokePlugin;
import org.graalvm.compiler.nodes.graphbuilderconf.InlineInvokePlugin.InlineInfo;
*** 931,1027 ****
/**
* @param type the unresolved type of the constant
*/
protected void handleUnresolvedLoadConstant(JavaType type) {
! assert !graphBuilderConfig.eagerResolving();
! append(new DeoptimizeNode(InvalidateRecompile, Unresolved));
}
/**
* @param type the unresolved type of the type check
* @param object the object value whose type is being checked against {@code type}
*/
protected void handleUnresolvedCheckCast(JavaType type, ValueNode object) {
! assert !graphBuilderConfig.eagerResolving();
append(new FixedGuardNode(graph.addOrUniqueWithInputs(IsNullNode.create(object)), Unresolved, InvalidateRecompile));
frameState.push(JavaKind.Object, appendConstant(JavaConstant.NULL_POINTER));
}
/**
* @param type the unresolved type of the type check
* @param object the object value whose type is being checked against {@code type}
*/
protected void handleUnresolvedInstanceOf(JavaType type, ValueNode object) {
! assert !graphBuilderConfig.eagerResolving();
AbstractBeginNode successor = graph.add(new BeginNode());
DeoptimizeNode deopt = graph.add(new DeoptimizeNode(InvalidateRecompile, Unresolved));
append(new IfNode(graph.addOrUniqueWithInputs(IsNullNode.create(object)), successor, deopt, 1));
lastInstr = successor;
frameState.push(JavaKind.Int, appendConstant(JavaConstant.INT_0));
}
/**
* @param type the type being instantiated
*/
protected void handleUnresolvedNewInstance(JavaType type) {
! assert !graphBuilderConfig.eagerResolving();
! append(new DeoptimizeNode(InvalidateRecompile, Unresolved));
}
/**
* @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.eagerResolving();
! append(new DeoptimizeNode(InvalidateRecompile, Unresolved));
}
/**
* @param type the type being instantiated
* @param dims the dimensions for the multi-array
*/
protected void handleUnresolvedNewMultiArray(JavaType type, ValueNode[] dims) {
! assert !graphBuilderConfig.eagerResolving();
! append(new DeoptimizeNode(InvalidateRecompile, Unresolved));
}
/**
* @param field the unresolved field
* @param receiver the object containing the field or {@code null} if {@code field} is static
*/
protected void handleUnresolvedLoadField(JavaField field, ValueNode receiver) {
! assert !graphBuilderConfig.eagerResolving();
! append(new DeoptimizeNode(InvalidateRecompile, Unresolved));
}
/**
* @param field the unresolved field
* @param value the value being stored to the field
* @param receiver the object containing the field or {@code null} if {@code field} is static
*/
protected void handleUnresolvedStoreField(JavaField field, ValueNode value, ValueNode receiver) {
! assert !graphBuilderConfig.eagerResolving();
! append(new DeoptimizeNode(InvalidateRecompile, Unresolved));
}
/**
* @param type
*/
protected void handleUnresolvedExceptionType(JavaType type) {
! assert !graphBuilderConfig.eagerResolving();
! append(new DeoptimizeNode(InvalidateRecompile, Unresolved));
}
/**
* @param javaMethod
* @param invokeKind
*/
protected void handleUnresolvedInvoke(JavaMethod javaMethod, InvokeKind invokeKind) {
! assert !graphBuilderConfig.eagerResolving();
! append(new DeoptimizeNode(InvalidateRecompile, Unresolved));
}
private AbstractBeginNode handleException(ValueNode exceptionObject, int bci) {
assert bci == BytecodeFrame.BEFORE_BCI || bci == bci() : "invalid bci";
debug.log("Creating exception dispatch edges at %d, exception object=%s, exception seen=%s", bci, exceptionObject, (profilingInfo == null ? "" : profilingInfo.getExceptionSeen(bci)));
--- 932,1041 ----
/**
* @param type the unresolved type of the constant
*/
protected void handleUnresolvedLoadConstant(JavaType type) {
! assert !graphBuilderConfig.unresolvedIsError();
! DeoptimizeNode deopt = append(new DeoptimizeNode(InvalidateRecompile, Unresolved));
! /*
! * Track source position for deopt nodes even if
! * GraphBuilderConfiguration.trackNodeSourcePosition is not set.
! */
! deopt.updateNodeSourcePosition(() -> createBytecodePosition());
}
/**
* @param type the unresolved type of the type check
* @param object the object value whose type is being checked against {@code type}
*/
protected void handleUnresolvedCheckCast(JavaType type, ValueNode object) {
! assert !graphBuilderConfig.unresolvedIsError();
append(new FixedGuardNode(graph.addOrUniqueWithInputs(IsNullNode.create(object)), Unresolved, InvalidateRecompile));
frameState.push(JavaKind.Object, appendConstant(JavaConstant.NULL_POINTER));
}
/**
* @param type the unresolved type of the type check
* @param object the object value whose type is being checked against {@code type}
*/
protected void handleUnresolvedInstanceOf(JavaType type, ValueNode object) {
! assert !graphBuilderConfig.unresolvedIsError();
AbstractBeginNode successor = graph.add(new BeginNode());
DeoptimizeNode deopt = graph.add(new DeoptimizeNode(InvalidateRecompile, Unresolved));
+ deopt.updateNodeSourcePosition(() -> createBytecodePosition());
append(new IfNode(graph.addOrUniqueWithInputs(IsNullNode.create(object)), successor, deopt, 1));
lastInstr = successor;
frameState.push(JavaKind.Int, appendConstant(JavaConstant.INT_0));
}
/**
* @param type the type being instantiated
*/
protected void handleUnresolvedNewInstance(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();
! DeoptimizeNode deopt = append(new DeoptimizeNode(InvalidateRecompile, Unresolved));
! deopt.updateNodeSourcePosition(() -> createBytecodePosition());
}
/**
* @param type the type being instantiated
* @param dims the dimensions for the multi-array
*/
protected void handleUnresolvedNewMultiArray(JavaType type, ValueNode[] dims) {
! assert !graphBuilderConfig.unresolvedIsError();
! DeoptimizeNode deopt = append(new DeoptimizeNode(InvalidateRecompile, Unresolved));
! deopt.updateNodeSourcePosition(() -> createBytecodePosition());
}
/**
* @param field the unresolved field
* @param receiver the object containing the field or {@code null} if {@code field} is static
*/
protected void handleUnresolvedLoadField(JavaField field, ValueNode receiver) {
! assert !graphBuilderConfig.unresolvedIsError();
! DeoptimizeNode deopt = append(new DeoptimizeNode(InvalidateRecompile, Unresolved));
! deopt.updateNodeSourcePosition(() -> createBytecodePosition());
}
/**
* @param field the unresolved field
* @param value the value being stored to the field
* @param receiver the object containing the field or {@code null} if {@code field} is static
*/
protected void handleUnresolvedStoreField(JavaField field, ValueNode value, ValueNode receiver) {
! assert !graphBuilderConfig.unresolvedIsError();
! DeoptimizeNode deopt = append(new DeoptimizeNode(InvalidateRecompile, Unresolved));
! deopt.updateNodeSourcePosition(() -> createBytecodePosition());
}
/**
* @param type
*/
protected void handleUnresolvedExceptionType(JavaType type) {
! assert !graphBuilderConfig.unresolvedIsError();
! DeoptimizeNode deopt = append(new DeoptimizeNode(InvalidateRecompile, Unresolved));
! deopt.updateNodeSourcePosition(() -> createBytecodePosition());
}
/**
* @param javaMethod
* @param invokeKind
*/
protected void handleUnresolvedInvoke(JavaMethod javaMethod, InvokeKind invokeKind) {
! assert !graphBuilderConfig.unresolvedIsError();
! DeoptimizeNode deopt = append(new DeoptimizeNode(InvalidateRecompile, Unresolved));
! deopt.updateNodeSourcePosition(() -> createBytecodePosition());
}
private AbstractBeginNode handleException(ValueNode exceptionObject, int bci) {
assert bci == BytecodeFrame.BEFORE_BCI || bci == bci() : "invalid bci";
debug.log("Creating exception dispatch edges at %d, exception object=%s, exception seen=%s", bci, exceptionObject, (profilingInfo == null ? "" : profilingInfo.getExceptionSeen(bci)));
*** 1305,1315 ****
return resolvedType.isInterface() || resolvedType.isLinked();
}
return false;
}
! protected void genInvokeStatic(JavaMethod target) {
if (callTargetIsResolved(target)) {
ResolvedJavaMethod resolvedTarget = (ResolvedJavaMethod) target;
ResolvedJavaType holder = resolvedTarget.getDeclaringClass();
if (!holder.isInitialized() && ResolveClassBeforeStaticInvoke.getValue(options)) {
handleUnresolvedInvoke(target, InvokeKind.Static);
--- 1319,1334 ----
return resolvedType.isInterface() || resolvedType.isLinked();
}
return false;
}
! protected void genInvokeStatic(int cpi, int opcode) {
! JavaMethod target = lookupMethod(cpi, opcode);
! genInvokeStatic(target);
! }
!
! void genInvokeStatic(JavaMethod target) {
if (callTargetIsResolved(target)) {
ResolvedJavaMethod resolvedTarget = (ResolvedJavaMethod) target;
ResolvedJavaType holder = resolvedTarget.getDeclaringClass();
if (!holder.isInitialized() && ResolveClassBeforeStaticInvoke.getValue(options)) {
handleUnresolvedInvoke(target, InvokeKind.Static);
*** 1330,1386 ****
} else {
handleUnresolvedInvoke(target, InvokeKind.Static);
}
}
protected void genInvokeInterface(JavaMethod target) {
if (callTargetIsResolved(target)) {
ValueNode[] args = frameState.popArguments(target.getSignature().getParameterCount(true));
appendInvoke(InvokeKind.Interface, (ResolvedJavaMethod) target, args);
} else {
handleUnresolvedInvoke(target, InvokeKind.Interface);
}
}
! protected void genInvokeDynamic(JavaMethod target) {
! if (target instanceof ResolvedJavaMethod) {
! JavaConstant appendix = constantPool.lookupAppendix(stream.readCPI4(), Bytecodes.INVOKEDYNAMIC);
! if (appendix != null) {
! frameState.push(JavaKind.Object, ConstantNode.forConstant(appendix, metaAccess, graph));
}
! ValueNode[] args = frameState.popArguments(target.getSignature().getParameterCount(false));
! appendInvoke(InvokeKind.Static, (ResolvedJavaMethod) target, args);
! } else {
handleUnresolvedInvoke(target, InvokeKind.Static);
}
}
! protected void genInvokeVirtual(JavaMethod target) {
! if (callTargetIsResolved(target)) {
! /*
! * Special handling for runtimes that rewrite an invocation of MethodHandle.invoke(...)
! * or MethodHandle.invokeExact(...) to a static adapter. HotSpot does this - see
! * https://wikis.oracle.com/display/HotSpotInternals/Method+handles +and+invokedynamic
! */
! boolean hasReceiver = !((ResolvedJavaMethod) target).isStatic();
! JavaConstant appendix = constantPool.lookupAppendix(stream.readCPI(), Bytecodes.INVOKEVIRTUAL);
if (appendix != null) {
! frameState.push(JavaKind.Object, ConstantNode.forConstant(appendix, metaAccess, graph));
}
ValueNode[] args = frameState.popArguments(target.getSignature().getParameterCount(hasReceiver));
if (hasReceiver) {
! appendInvoke(InvokeKind.Virtual, (ResolvedJavaMethod) target, args);
} else {
! appendInvoke(InvokeKind.Static, (ResolvedJavaMethod) target, args);
}
! } else {
handleUnresolvedInvoke(target, InvokeKind.Virtual);
}
}
! protected void genInvokeSpecial(JavaMethod target) {
if (callTargetIsResolved(target)) {
assert target != null;
assert target.getSignature() != null;
ValueNode[] args = frameState.popArguments(target.getSignature().getParameterCount(true));
appendInvoke(InvokeKind.Special, (ResolvedJavaMethod) target, args);
--- 1349,1474 ----
} else {
handleUnresolvedInvoke(target, InvokeKind.Static);
}
}
+ protected void genInvokeInterface(int cpi, int opcode) {
+ JavaMethod target = lookupMethod(cpi, opcode);
+ genInvokeInterface(target);
+ }
+
protected void genInvokeInterface(JavaMethod target) {
if (callTargetIsResolved(target)) {
ValueNode[] args = frameState.popArguments(target.getSignature().getParameterCount(true));
appendInvoke(InvokeKind.Interface, (ResolvedJavaMethod) target, args);
} else {
handleUnresolvedInvoke(target, InvokeKind.Interface);
}
}
! protected void genInvokeDynamic(int cpi, int opcode) {
! JavaMethod target = lookupMethod(cpi, opcode);
! genInvokeDynamic(target);
}
!
! void genInvokeDynamic(JavaMethod target) {
! if (!(target instanceof ResolvedJavaMethod) || !genDynamicInvokeHelper((ResolvedJavaMethod) target, stream.readCPI4(), INVOKEDYNAMIC)) {
handleUnresolvedInvoke(target, InvokeKind.Static);
}
}
! protected void genInvokeVirtual(int cpi, int opcode) {
! JavaMethod target = lookupMethod(cpi, opcode);
! genInvokeVirtual(target);
! }
!
! private boolean genDynamicInvokeHelper(ResolvedJavaMethod target, int cpi, int opcode) {
! assert opcode == INVOKEDYNAMIC || opcode == INVOKEVIRTUAL;
!
! InvokeDynamicPlugin invokeDynamicPlugin = graphBuilderConfig.getPlugins().getInvokeDynamicPlugin();
!
! if (opcode == INVOKEVIRTUAL && invokeDynamicPlugin != null && !invokeDynamicPlugin.isResolvedDynamicInvoke(this, cpi, opcode)) {
! // regular invokevirtual, let caller handle it
! return false;
! }
!
! if (GeneratePIC.getValue(options) && (invokeDynamicPlugin == null || !invokeDynamicPlugin.supportsDynamicInvoke(this, cpi, opcode))) {
! // bail out if static compiler and no dynamic type support
! append(new DeoptimizeNode(InvalidateRecompile, Unresolved));
! return true;
! }
!
! JavaConstant appendix = constantPool.lookupAppendix(cpi, opcode);
! ValueNode appendixNode = null;
!
if (appendix != null) {
! if (invokeDynamicPlugin != null) {
! invokeDynamicPlugin.recordDynamicMethod(this, cpi, opcode, target);
!
! // Will perform runtime type checks and static initialization
! FrameState stateBefore = frameState.create(bci(), getNonIntrinsicAncestor(), false, null, null);
! appendixNode = invokeDynamicPlugin.genAppendixNode(this, cpi, opcode, appendix, stateBefore);
! } else {
! appendixNode = ConstantNode.forConstant(appendix, metaAccess, graph);
! }
!
! frameState.push(JavaKind.Object, appendixNode);
!
! } else if (GeneratePIC.getValue(options)) {
! // Need to emit runtime guard and perform static initialization.
! // Not implemented yet.
! append(new DeoptimizeNode(InvalidateRecompile, Unresolved));
! return true;
}
+
+ boolean hasReceiver = (opcode == INVOKEDYNAMIC) ? false : !target.isStatic();
ValueNode[] args = frameState.popArguments(target.getSignature().getParameterCount(hasReceiver));
if (hasReceiver) {
! appendInvoke(InvokeKind.Virtual, target, args);
} else {
! appendInvoke(InvokeKind.Static, target, args);
}
!
! 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);
! }
!
! void genInvokeSpecial(JavaMethod target) {
if (callTargetIsResolved(target)) {
assert target != null;
assert target.getSignature() != null;
ValueNode[] args = frameState.popArguments(target.getSignature().getParameterCount(true));
appendInvoke(InvokeKind.Special, (ResolvedJavaMethod) target, args);
*** 2147,2167 ****
String s = format("%s%s (%s:%d) %s", nSpaces(getDepth()), method.isConstructor() ? method.format("%h.%n") : method.getName(), where.getFileName(), where.getLineNumber(),
format(format, args));
TTY.println(s);
}
! protected BytecodeParserError asParserError(Throwable e) {
if (e instanceof BytecodeParserError) {
! return (BytecodeParserError) e;
}
BytecodeParser bp = this;
BytecodeParserError res = new BytecodeParserError(e);
while (bp != null) {
res.addContext("parsing " + bp.code.asStackTraceElement(bp.bci()));
bp = bp.parent;
}
! return res;
}
protected void parseAndInlineCallee(ResolvedJavaMethod targetMethod, ValueNode[] args, IntrinsicContext calleeIntrinsicContext) {
try (IntrinsicScope s = calleeIntrinsicContext != null && !parsingIntrinsic() ? new IntrinsicScope(this, targetMethod.getSignature().toParameterKinds(!targetMethod.isStatic()), args) : null) {
--- 2235,2255 ----
String s = format("%s%s (%s:%d) %s", nSpaces(getDepth()), method.isConstructor() ? method.format("%h.%n") : method.getName(), where.getFileName(), where.getLineNumber(),
format(format, args));
TTY.println(s);
}
! protected RuntimeException throwParserError(Throwable e) {
if (e instanceof BytecodeParserError) {
! throw (BytecodeParserError) e;
}
BytecodeParser bp = this;
BytecodeParserError res = new BytecodeParserError(e);
while (bp != null) {
res.addContext("parsing " + bp.code.asStackTraceElement(bp.bci()));
bp = bp.parent;
}
! throw res;
}
protected void parseAndInlineCallee(ResolvedJavaMethod targetMethod, ValueNode[] args, IntrinsicContext calleeIntrinsicContext) {
try (IntrinsicScope s = calleeIntrinsicContext != null && !parsingIntrinsic() ? new IntrinsicScope(this, targetMethod.getSignature().toParameterKinds(!targetMethod.isStatic()), args) : null) {
*** 2835,2845 ****
processBytecode(bci, opcode);
} catch (BailoutException e) {
// Don't wrap bailouts as parser errors
throw e;
} catch (Throwable e) {
! throw asParserError(e);
}
if (lastInstr == null || lastInstr.next() != null) {
break;
}
--- 2923,2933 ----
processBytecode(bci, opcode);
} catch (BailoutException e) {
// Don't wrap bailouts as parser errors
throw e;
} catch (Throwable e) {
! throw throwParserError(e);
}
if (lastInstr == null || lastInstr.next() != null) {
break;
}
*** 3255,3265 ****
int nextBCI = stream.nextBCI();
int nextBC = stream.readUByte(nextBCI);
if (nextBCI <= currentBlock.endBci && nextBC == Bytecodes.GETFIELD) {
stream.next();
! genGetField(lookupField(stream.readCPI(), Bytecodes.GETFIELD), value);
} else {
frameState.push(JavaKind.Object, value);
}
}
--- 3343,3353 ----
int nextBCI = stream.nextBCI();
int nextBC = stream.readUByte(nextBCI);
if (nextBCI <= currentBlock.endBci && nextBC == Bytecodes.GETFIELD) {
stream.next();
! genGetField(stream.readCPI(), Bytecodes.GETFIELD, value);
} else {
frameState.push(JavaKind.Object, value);
}
}
*** 3504,3536 ****
assert !graphBuilderConfig.unresolvedIsError() ||
(result instanceof ResolvedJavaMethod && (opcode != INVOKESTATIC || ((ResolvedJavaMethod) result).getDeclaringClass().isInitialized())) : result;
return result;
}
! private JavaField lookupField(int cpi, int opcode) {
maybeEagerlyResolve(cpi, opcode);
JavaField result = constantPool.lookupField(cpi, method, opcode);
if (graphBuilderConfig.eagerResolving()) {
! assert result instanceof ResolvedJavaField : "Not resolved: " + result;
ResolvedJavaType declaringClass = ((ResolvedJavaField) result).getDeclaringClass();
if (!declaringClass.isInitialized()) {
assert declaringClass.isInterface() : "Declaring class not initialized but not an interface? " + declaringClass;
declaringClass.initialize();
}
}
assert !graphBuilderConfig.unresolvedIsError() || (result instanceof ResolvedJavaField && ((ResolvedJavaField) result).getDeclaringClass().isInitialized()) : result;
return result;
}
private Object lookupConstant(int cpi, int opcode) {
maybeEagerlyResolve(cpi, opcode);
Object result = constantPool.lookupConstant(cpi);
! assert !graphBuilderConfig.eagerResolving() || !(result instanceof JavaType) || (result instanceof ResolvedJavaType) : result;
return result;
}
! private void maybeEagerlyResolve(int cpi, int bytecode) {
if (intrinsicContext != null) {
constantPool.loadReferencedType(cpi, bytecode);
} else if (graphBuilderConfig.eagerResolving()) {
/*
* Since we're potentially triggering class initialization here, we need synchronization
--- 3592,3627 ----
assert !graphBuilderConfig.unresolvedIsError() ||
(result instanceof ResolvedJavaMethod && (opcode != INVOKESTATIC || ((ResolvedJavaMethod) result).getDeclaringClass().isInitialized())) : result;
return result;
}
! protected JavaField lookupField(int cpi, int opcode) {
maybeEagerlyResolve(cpi, opcode);
JavaField result = constantPool.lookupField(cpi, method, opcode);
+
if (graphBuilderConfig.eagerResolving()) {
! assert !graphBuilderConfig.unresolvedIsError() || result instanceof ResolvedJavaField : "Not resolved: " + result;
! if (result instanceof ResolvedJavaField) {
ResolvedJavaType declaringClass = ((ResolvedJavaField) result).getDeclaringClass();
if (!declaringClass.isInitialized()) {
assert declaringClass.isInterface() : "Declaring class not initialized but not an interface? " + declaringClass;
declaringClass.initialize();
}
}
+ }
assert !graphBuilderConfig.unresolvedIsError() || (result instanceof ResolvedJavaField && ((ResolvedJavaField) result).getDeclaringClass().isInitialized()) : result;
return result;
}
private Object lookupConstant(int cpi, int opcode) {
maybeEagerlyResolve(cpi, opcode);
Object result = constantPool.lookupConstant(cpi);
! assert !graphBuilderConfig.unresolvedIsError() || !(result instanceof JavaType) || (result instanceof ResolvedJavaType) : result;
return result;
}
! protected void maybeEagerlyResolve(int cpi, int bytecode) {
if (intrinsicContext != null) {
constantPool.loadReferencedType(cpi, bytecode);
} else if (graphBuilderConfig.eagerResolving()) {
/*
* Since we're potentially triggering class initialization here, we need synchronization
*** 3651,3663 ****
// Most frequent for value is IRETURN, followed by ISTORE.
frameState.push(JavaKind.Int, append(genConditional(logicNode)));
}
}
! void genNewInstance(int cpi) {
JavaType type = lookupType(cpi, NEW);
if (!(type instanceof ResolvedJavaType) || !((ResolvedJavaType) type).isInitialized()) {
handleUnresolvedNewInstance(type);
return;
}
ResolvedJavaType resolvedType = (ResolvedJavaType) type;
--- 3742,3757 ----
// Most frequent for value is IRETURN, followed by ISTORE.
frameState.push(JavaKind.Int, append(genConditional(logicNode)));
}
}
! protected void genNewInstance(int cpi) {
JavaType type = lookupType(cpi, NEW);
+ genNewInstance(type);
+ }
+ void genNewInstance(JavaType type) {
if (!(type instanceof ResolvedJavaType) || !((ResolvedJavaType) type).isInitialized()) {
handleUnresolvedNewInstance(type);
return;
}
ResolvedJavaType resolvedType = (ResolvedJavaType) type;
*** 3788,3799 ****
}
frameState.push(JavaKind.Object, append(createNewMultiArray(resolvedType, dims)));
}
! private void genGetField(JavaField field) {
! genGetField(field, frameState.pop(JavaKind.Object));
}
private void genGetField(JavaField field, ValueNode receiverInput) {
ValueNode receiver = emitExplicitExceptions(receiverInput);
if (field instanceof ResolvedJavaField) {
--- 3882,3898 ----
}
frameState.push(JavaKind.Object, append(createNewMultiArray(resolvedType, dims)));
}
! protected void genGetField(int cpi, int opcode) {
! genGetField(cpi, opcode, frameState.pop(JavaKind.Object));
! }
!
! protected void genGetField(int cpi, int opcode, ValueNode receiverInput) {
! JavaField field = lookupField(cpi, opcode);
! genGetField(field, receiverInput);
}
private void genGetField(JavaField field, ValueNode receiverInput) {
ValueNode receiver = emitExplicitExceptions(receiverInput);
if (field instanceof ResolvedJavaField) {
*** 3865,3875 ****
return profilingInfo.getExceptionSeen(bci()) == TriState.TRUE;
}
return false;
}
! private void genPutField(JavaField field) {
genPutField(field, frameState.pop(field.getJavaKind()));
}
private void genPutField(JavaField field, ValueNode value) {
ValueNode receiver = emitExplicitExceptions(frameState.pop(JavaKind.Object));
--- 3964,3979 ----
return profilingInfo.getExceptionSeen(bci()) == TriState.TRUE;
}
return false;
}
! protected void genPutField(int cpi, int opcode) {
! JavaField field = lookupField(cpi, opcode);
! genPutField(field);
! }
!
! protected void genPutField(JavaField field) {
genPutField(field, frameState.pop(field.getJavaKind()));
}
private void genPutField(JavaField field, ValueNode value) {
ValueNode receiver = emitExplicitExceptions(frameState.pop(JavaKind.Object));
*** 3893,3902 ****
--- 3997,4011 ----
} else {
handleUnresolvedStoreField(field, value, receiver);
}
}
+ protected void genGetStatic(int cpi, int opcode) {
+ JavaField field = lookupField(cpi, opcode);
+ genGetStatic(field);
+ }
+
private void genGetStatic(JavaField field) {
ResolvedJavaField resolvedField = resolveStaticFieldAccess(field, null);
if (resolvedField == null) {
return;
}
*** 3954,3964 ****
}
return null;
}
! private void genPutStatic(JavaField field) {
ValueNode value = frameState.pop(field.getJavaKind());
ResolvedJavaField resolvedField = resolveStaticFieldAccess(field, value);
if (resolvedField == null) {
return;
}
--- 4063,4078 ----
}
return null;
}
! protected void genPutStatic(int cpi, int opcode) {
! JavaField field = lookupField(cpi, opcode);
! genPutStatic(field);
! }
!
! protected void genPutStatic(JavaField field) {
ValueNode value = frameState.pop(field.getJavaKind());
ResolvedJavaField resolvedField = resolveStaticFieldAccess(field, value);
if (resolvedField == null) {
return;
}
*** 4318,4336 ****
case LRETURN : genReturn(frameState.pop(JavaKind.Long), JavaKind.Long); break;
case FRETURN : genReturn(frameState.pop(JavaKind.Float), JavaKind.Float); break;
case DRETURN : genReturn(frameState.pop(JavaKind.Double), JavaKind.Double); break;
case ARETURN : genReturn(frameState.pop(JavaKind.Object), JavaKind.Object); break;
case RETURN : genReturn(null, JavaKind.Void); break;
! case GETSTATIC : cpi = stream.readCPI(); genGetStatic(lookupField(cpi, opcode)); break;
! case PUTSTATIC : cpi = stream.readCPI(); genPutStatic(lookupField(cpi, opcode)); break;
! case GETFIELD : cpi = stream.readCPI(); genGetField(lookupField(cpi, opcode)); break;
! case PUTFIELD : cpi = stream.readCPI(); genPutField(lookupField(cpi, opcode)); break;
! case INVOKEVIRTUAL : cpi = stream.readCPI(); genInvokeVirtual(lookupMethod(cpi, opcode)); break;
! case INVOKESPECIAL : cpi = stream.readCPI(); genInvokeSpecial(lookupMethod(cpi, opcode)); break;
! case INVOKESTATIC : cpi = stream.readCPI(); genInvokeStatic(lookupMethod(cpi, opcode)); break;
! case INVOKEINTERFACE: cpi = stream.readCPI(); genInvokeInterface(lookupMethod(cpi, opcode)); break;
! case INVOKEDYNAMIC : cpi = stream.readCPI4(); genInvokeDynamic(lookupMethod(cpi, opcode)); break;
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;
--- 4432,4450 ----
case LRETURN : genReturn(frameState.pop(JavaKind.Long), JavaKind.Long); break;
case FRETURN : genReturn(frameState.pop(JavaKind.Float), JavaKind.Float); break;
case DRETURN : genReturn(frameState.pop(JavaKind.Double), JavaKind.Double); break;
case ARETURN : genReturn(frameState.pop(JavaKind.Object), JavaKind.Object); break;
case RETURN : genReturn(null, JavaKind.Void); break;
! case GETSTATIC : cpi = stream.readCPI(); genGetStatic(cpi, opcode); break;
! case PUTSTATIC : cpi = stream.readCPI(); genPutStatic(cpi, opcode); break;
! case GETFIELD : cpi = stream.readCPI(); genGetField(cpi, opcode); break;
! case PUTFIELD : cpi = stream.readCPI(); genPutField(cpi, opcode); break;
! case INVOKEVIRTUAL : cpi = stream.readCPI(); genInvokeVirtual(cpi, opcode); break;
! case INVOKESPECIAL : cpi = stream.readCPI(); genInvokeSpecial(cpi, opcode); break;
! case INVOKESTATIC : cpi = stream.readCPI(); genInvokeStatic(cpi, opcode); break;
! case INVOKEINTERFACE: cpi = stream.readCPI(); genInvokeInterface(cpi, opcode); break;
! case INVOKEDYNAMIC : cpi = stream.readCPI4(); genInvokeDynamic(cpi, opcode); break;
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;
< prev index next >