1659 args[0] = maybeEmitExplicitNullCheck(args[0]); |
1659 args[0] = maybeEmitExplicitNullCheck(args[0]); |
1660 } |
1660 } |
1661 |
1661 |
1662 if (initialInvokeKind == InvokeKind.Special && !targetMethod.isConstructor()) { |
1662 if (initialInvokeKind == InvokeKind.Special && !targetMethod.isConstructor()) { |
1663 emitCheckForInvokeSuperSpecial(args); |
1663 emitCheckForInvokeSuperSpecial(args); |
|
1664 } else if (initialInvokeKind == InvokeKind.Interface && targetMethod.isPrivate()) { |
|
1665 emitCheckForDeclaringClassChange(targetMethod.getDeclaringClass(), args); |
1664 } |
1666 } |
1665 |
1667 |
1666 InlineInfo inlineInfo = null; |
1668 InlineInfo inlineInfo = null; |
1667 try { |
1669 try { |
1668 currentInvoke = new CurrentInvoke(args, invokeKind, returnType); |
1670 currentInvoke = new CurrentInvoke(args, invokeKind, returnType); |
1743 // Until there is a mechanism to guarantee that any late inlining will not select |
1745 // Until there is a mechanism to guarantee that any late inlining will not select |
1744 // the intrinsic graph, prevent this invoke from being inlined. |
1746 // the intrinsic graph, prevent this invoke from being inlined. |
1745 invoke.setUseForInlining(false); |
1747 invoke.setUseForInlining(false); |
1746 } |
1748 } |
1747 return invoke; |
1749 return invoke; |
|
1750 } |
|
1751 |
|
1752 /** |
|
1753 * Checks that the class of the receiver of an {@link Bytecodes#INVOKEINTERFACE} invocation of a |
|
1754 * private method is assignable to the interface that declared the method. If not, then |
|
1755 * deoptimize so that the interpreter can throw an {@link IllegalAccessError}. |
|
1756 * |
|
1757 * This is a check not performed by the verifier and so must be performed at runtime. |
|
1758 * |
|
1759 * @param declaringClass interface declaring the callee |
|
1760 * @param args arguments to an {@link Bytecodes#INVOKEINTERFACE} call to a private method |
|
1761 * declared in a interface |
|
1762 */ |
|
1763 private void emitCheckForDeclaringClassChange(ResolvedJavaType declaringClass, ValueNode[] args) { |
|
1764 ValueNode receiver = args[0]; |
|
1765 TypeReference checkedType = TypeReference.createTrusted(graph.getAssumptions(), declaringClass); |
|
1766 LogicNode condition = genUnique(createInstanceOf(checkedType, receiver, null)); |
|
1767 FixedGuardNode fixedGuard = append(new FixedGuardNode(condition, ClassCastException, None, false)); |
|
1768 args[0] = append(PiNode.create(receiver, StampFactory.object(checkedType, true), fixedGuard)); |
1748 } |
1769 } |
1749 |
1770 |
1750 /** |
1771 /** |
1751 * Checks that the class of the receiver of an {@link Bytecodes#INVOKESPECIAL} in a method |
1772 * Checks that the class of the receiver of an {@link Bytecodes#INVOKESPECIAL} in a method |
1752 * declared in an interface (i.e., a default method) is assignable to the interface. If not, |
1773 * declared in an interface (i.e., a default method) is assignable to the interface. If not, |