@Override public InlineInfo shouldInlineInvoke(GraphBuilderContext builder, ResolvedJavaMethod original, ValueNode[] arguments) { if (neverInline.contains(original)) { return InlineInfo.DO_NOT_INLINE_WITH_EXCEPTION; } if (original.getCode() != null && original.getCodeSize() < maxCodeSize && builder.getDepth() <= maxDepth) { return createStandardInlineInfo(original); } return null; } }
@Override public InlineInfo shouldInlineInvoke(GraphBuilderContext b, ResolvedJavaMethod method, ValueNode[] args) { /* Avoid infinite recursion with a (more or less random) maximum depth. */ if (b.getDepth() > 20) { return null; } String className = method.getDeclaringClass().toJavaName(true); if (className.startsWith("java.lang.invoke.VarHandle")) { /* * Do not inline implementation methods of various VarHandle implementation classes. * They are too complex and cannot be reduced to a single invoke or field access. * There is also no need to inline them, because they are not related to any * MethodHandle mechanism. */ return null; } else if (className.startsWith("java.lang.invoke")) { /* * Inline all helper methods used by method handles. We do not know exactly which * ones they are, but they are all be from the same package. */ return createStandardInlineInfo(method); } return null; } }
private static boolean checkInliningDepth(GraphBuilderContext b) { int nodeCount = b.getGraph().getNodeCount(); int maxDepth = InlineDuringParsingMaxDepth.getValue(b.getOptions()); if (nodeCount > NodeBudget && MaxDepthAfterBudgetExceeded < maxDepth) { maxDepth = MaxDepthAfterBudgetExceeded; } return b.getDepth() < maxDepth; }
@Override public InlineInfo shouldInlineInvoke(GraphBuilderContext builder, ResolvedJavaMethod original, ValueNode[] arguments) { if (original.getAnnotation(NeverInline.class) != null) { return InlineInfo.DO_NOT_INLINE_WITH_EXCEPTION; } else if (invocationPlugins.lookupInvocation(original) != null) { return InlineInfo.DO_NOT_INLINE_WITH_EXCEPTION; } else if (original.getAnnotation(ExplodeLoop.class) != null) { return InlineInfo.DO_NOT_INLINE_WITH_EXCEPTION; } else if (replacements.hasSubstitution(original, builder.bci())) { return InlineInfo.DO_NOT_INLINE_WITH_EXCEPTION; } for (ResolvedJavaMethod m : partialEvaluator.getNeverInlineMethods()) { if (original.equals(m)) { return InlineInfo.DO_NOT_INLINE_WITH_EXCEPTION; } } StructuredGraph graph = ((AnalysisMethod) original).getTypeFlow().getGraph(); if (graph != null && original.getCode() != null && includeMethodPredicate.test(original) && InliningUtilities.isTrivialMethod(graph) && builder.getDepth() < InlineDuringParsingMaxDepth.getValue(HostedOptionValues.singleton())) { return createStandardInlineInfo(original); } return null; } }
/** * Determines whether a given method should be inlined based on whether it has a substitution or * whether the inlining context is already within a substitution. * * @return an object specifying how {@code method} is to be inlined or null if it should not be * inlined based on substitution related criteria */ @Override public InlineInfo shouldInlineInvoke(GraphBuilderContext b, ResolvedJavaMethod method, ValueNode[] args) { Bytecode subst = getSubstitutionBytecode(method); if (subst != null) { if (b.parsingIntrinsic() || InlineDuringParsing.getValue(b.getOptions()) || InlineIntrinsicsDuringParsing.getValue(b.getOptions())) { // Forced inlining of intrinsics return createIntrinsicInlineInfo(subst.getMethod(), method, subst.getOrigin()); } return null; } if (b.parsingIntrinsic()) { assert b.getDepth() < MAX_GRAPH_INLINING_DEPTH : "inlining limit exceeded"; // Force inlining when parsing replacements return createIntrinsicInlineInfo(method, null, defaultBytecodeProvider); } else { assert IS_BUILDING_NATIVE_IMAGE || method.getAnnotation(NodeIntrinsic.class) == null : String.format("@%s method %s must only be called from within a replacement%n%s", NodeIntrinsic.class.getSimpleName(), method.format("%h.%n"), b); } return null; }