{"record":{"id":"271adfd3f480fe4f","repo":"oracle/graal","slug":"all-non-recursive-calls-in-the-intrinsic-s-must-b","errorCode":null,"errorMessage":"All non-recursive calls in the intrinsic %s must be inlined or intrinsified: found call to %s","messagePattern":"All non-recursive calls in the intrinsic (.+?) must be inlined or intrinsified: found call to (.+?)","errorType":"exception","errorClass":"GraalError","httpStatus":null,"severity":"error","filePath":"compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/replacements/ReplacementsImpl.java","lineNumber":236,"sourceCode":"        }\n        return null;\n    }\n\n    @Override\n    public void notifyNotInlined(GraphBuilderContext b, ResolvedJavaMethod method, Invoke invoke) {\n        if (b.parsingIntrinsic()) {\n            IntrinsicContext intrinsic = b.getIntrinsic();\n            if (!intrinsic.isCallToOriginal(method)) {\n                Class<? extends GraphBuilderPlugin> pluginClass = getIntrinsifyingPlugin(method);\n                if (pluginClass != null) {\n                    String methodDesc = method.format(\"%H.%n(%p)\");\n                    throw new GraalError(\"Call to %s should have been intrinsified by a %s. \" +\n                                    \"This is typically caused by Eclipse failing to run an annotation \" +\n                                    \"processor. This can usually be fixed by forcing Eclipse to rebuild \" +\n                                    \"the source file in which %s is declared\",\n                                    methodDesc, pluginClass.getSimpleName(), methodDesc);\n                }\n                throw new GraalError(\"All non-recursive calls in the intrinsic %s must be inlined or intrinsified: found call to %s\",\n                                intrinsic.getIntrinsicMethod().format(\"%H.%n(%p)\"), method.format(\"%h.%n(%p)\"));\n            }\n        }\n    }\n\n    // This map is key'ed by a class name instead of a Class object so that\n    // it is stable across VM executions (in support of replay compilation).\n    private final EconomicMap<String, SnippetTemplateCache> snippetTemplateCache;\n\n    @SuppressWarnings(\"this-escape\")\n    public ReplacementsImpl(DebugDumpHandlersFactory debugHandlersFactory, Providers providers, BytecodeProvider bytecodeProvider, TargetDescription target) {\n        this.providers = providers.copyWith(this);\n        this.target = target;\n        this.snippetGraphs = new ConcurrentHashMap<>();\n        this.snippetTemplateCache = EconomicMap.create(Equivalence.DEFAULT);\n        this.defaultBytecodeProvider = bytecodeProvider;\n        this.debugHandlersFactory = debugHandlersFactory;\n        this.templatesCache = Collections.synchronizedMap(new SnippetTemplate.LRUCache<>());","sourceCodeStart":218,"sourceCodeEnd":254,"githubUrl":"https://github.com/oracle/graal/blob/a66e9ccd1d7bf2552883939aa0788dfd0e294aab/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/replacements/ReplacementsImpl.java#L218-L254","documentation":"The companion check in ReplacementsImpl.notifyNotInlined (ReplacementsImpl.java:236): a call inside an intrinsic's graph was not inlined and has no intrinsifying plugin. Unlike error 218, the callee is an ordinary method — intrinsic graphs must be self-contained except for calls to the original method, so any leftover ordinary call is rejected.","triggerScenarios":"Writing an @MethodSubstitution/intrinsic that calls a helper method that is neither inlined by the bytecode parser (too large, not force-inline) nor a node intrinsic; calling library methods (Math.max, etc.) that lack a registered plugin in this context.","commonSituations":"New hand-written intrinsics that forget @Inline/force-inline on helpers; refactoring shared logic out of an intrinsic into a utility method; relying on JVM intrinsics (like String/Matrix methods) that Graal must re-provide.","solutions":["Make the called method a @NodeIntrinsic, mark it for forced inlining (e.g., @Inline/@ForceInline or must-inline mechanism) so the parser inlines it","Reimplement the call using Graal graph nodes directly inside the intrinsic","If the call is meant to hit the substituted method itself, use the intrinsic's isCallToOriginal escape hatch (invoke the original via the intrinsic context)"],"exampleFix":"// before\n@MethodSubstitution static int sub(int x) { return helper(x); } // helper not inlined\n\n// after\n@Inline static int helper(int x) { ... } // forced inline, call disappears from intrinsic graph","handlingStrategy":"validation","validationCode":"// before shipping an intrinsic, grep its body for ordinary calls:\n// every invoked method must be @NodeIntrinsic, force-inlined, or the substituted original\nif (!callee.isIntrinsicCandidate() && !isForceInlined(callee) && !intrinsic.isCallToOriginal(callee)) fail();","typeGuard":null,"tryCatchPattern":"try {\n    replacements.registerSubstitution(MySubstitution.class);\n} catch (GraalError e) {\n    // message names the offending call; fix the intrinsic body, don't suppress\n    throw e;\n}","preventionTips":["Mark every helper called from an intrinsic as force-inline or convert it to a node intrinsic","Assume no JVM built-ins are available inside intrinsic graphs — express them with Graal nodes"],"tags":["graal","intrinsics","inlining","method-substitution"],"backgroundTag":null,"analyzedSha":"a66e9ccd1d7bf2552883939aa0788dfd0e294aab","analyzedAt":"2026-08-14T13:58:47.161Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}