JDK-8186646 : Nashorn: "duplicate code" assertion when binding a vararg function that just passes arguments along
  • Type: Bug
  • Component: core-libs
  • Sub-Component: jdk.nashorn
  • Affected Version: 8u72,9
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • OS: generic
  • CPU: generic
  • Submitted: 2017-08-22
  • Updated: 2019-01-14
  • Resolved: 2017-09-21
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 10 JDK 8
10 b25Fixed 8u192Fixed
Description
FULL PRODUCT VERSION :
java version "1.8.0_144"
Java(TM) SE Runtime Environment (build 1.8.0_144-b01)
Java HotSpot(TM) 64-Bit Server VM (build 25.144-b01, mixed mode)

ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows [Version 10.0.14393]

A DESCRIPTION OF THE PROBLEM :
If a varargs function that only passes the arguments to another function rather than using them directly is bound after the first time it is called, binding fails with a "duplicate code" assertion if assertions are enabled.

REGRESSION.  Last worked in version 8u121

ADDITIONAL REGRESSION INFORMATION: 
The code does not assert in version 1.8.0_40; however, that is before the assertion was added, so I do not know if the underlying issue of generating duplicate function specializations is a regression.

java version "1.8.0_40"
Java(TM) SE Runtime Environment (build 1.8.0_40-b26)
Java HotSpot(TM) 64-Bit Server VM (build 25.40-b25, mixed mode)

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Run the code listed in the "Source code for an executable test case" field with assertions enabled.

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Only one function specialization should be generated when binding.
ACTUAL -
Two identical function specializations were generated, resulting in a "duplicate code" assertion.

ERROR MESSAGES/STACK TRACES THAT OCCUR :
Exception in thread "main" java.lang.AssertionError: duplicate code
	at jdk.nashorn.internal.runtime.RecompilableScriptFunctionData.addCode(RecompilableScriptFunctionData.java:831)
	at jdk.nashorn.internal.runtime.RecompilableScriptFunctionData.addCode(RecompilableScriptFunctionData.java:848)
	at jdk.nashorn.internal.runtime.RecompilableScriptFunctionData.getBest(RecompilableScriptFunctionData.java:922)
	at jdk.nashorn.internal.runtime.ScriptFunctionData.getGeneric(ScriptFunctionData.java:384)
	at jdk.nashorn.internal.runtime.ScriptFunctionData.createGenericConstructor(ScriptFunctionData.java:298)
	at jdk.nashorn.internal.runtime.ScriptFunctionData.getGenericConstructor(ScriptFunctionData.java:292)
	at jdk.nashorn.internal.runtime.ScriptFunctionData.makeBoundFunctionData(ScriptFunctionData.java:429)
	at jdk.nashorn.internal.runtime.ScriptFunction.createBound(ScriptFunction.java:392)
	at jdk.nashorn.internal.runtime.linker.Bootstrap.bindCallable(Bootstrap.java:384)
	at jdk.nashorn.internal.objects.NativeFunction.bind(NativeFunction.java:219)
	at jdk.nashorn.internal.scripts.Script$\^eval\_.:program(<eval>:8)
	at jdk.nashorn.internal.runtime.ScriptFunctionData.invoke(ScriptFunctionData.java:637)
	at jdk.nashorn.internal.runtime.ScriptFunction.invoke(ScriptFunction.java:494)
	at jdk.nashorn.internal.runtime.ScriptRuntime.apply(ScriptRuntime.java:393)
	at jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(NashornScriptEngine.java:449)
	at jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(NashornScriptEngine.java:406)
	at jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(NashornScriptEngine.java:402)
	at jdk.nashorn.api.scripting.NashornScriptEngine.eval(NashornScriptEngine.java:155)
	at javax.script.AbstractScriptEngine.eval(AbstractScriptEngine.java:264)
	at BindErrorTest.main(BindErrorTest.java:7)


REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;

public class BindErrorTest {
    public static void main(String[] args) throws Exception {
        ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn");
        engine.eval("var fn2 = function () {};\n" +
                "\n" +
                "var fn = function () {\n" +
                "   fn2.apply(null, arguments);\n" +
                "};\n" +
                "\n" +
                "fn();\n" +
                "fn.bind();\n");
    }
}
---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
Create a new function that calls the desired function with the correct "this" and arguments instead of binding. Alternatively, don't enable assertions.


Comments
This started from JDK 8u72 onwards, probably due to the fix for JDK-8131340. To reproduce , run the attached test case. Following are the results : JDK 8u71 - Pass JDK 8u72 - Fail JDK 8u144- fail JDK 9-ea + 181 - Fail Following is the stacktrace after running on JDK 9-ea+181: java version "9" Java(TM) SE Runtime Environment (build 9+181) Java HotSpot(TM) 64-Bit Server VM (build 9+181, mixed mode) Exception in thread "main" java.lang.AssertionError: duplicate code at jdk.scripting.nashorn/jdk.nashorn.internal.runtime.RecompilableScriptFunctionData.addCode(RecompilableScriptFunctionData.java:833) at jdk.scripting.nashorn/jdk.nashorn.internal.runtime.RecompilableScriptFunctionData.addCode(RecompilableScriptFunctionData.java:850) at jdk.scripting.nashorn/jdk.nashorn.internal.runtime.RecompilableScriptFunctionData.getBest(RecompilableScriptFunctionData.java:924) at jdk.scripting.nashorn/jdk.nashorn.internal.runtime.ScriptFunctionData.getGeneric(ScriptFunctionData.java:399) at jdk.scripting.nashorn/jdk.nashorn.internal.runtime.ScriptFunctionData.createGenericConstructor(ScriptFunctionData.java:313) at jdk.scripting.nashorn/jdk.nashorn.internal.runtime.ScriptFunctionData.getGenericConstructor(ScriptFunctionData.java:307) at jdk.scripting.nashorn/jdk.nashorn.internal.runtime.ScriptFunctionData.makeBoundFunctionData(ScriptFunctionData.java:444) at jdk.scripting.nashorn/jdk.nashorn.internal.runtime.ScriptFunction.createBound(ScriptFunction.java:402) at jdk.scripting.nashorn/jdk.nashorn.internal.runtime.linker.Bootstrap.bindCallable(Bootstrap.java:389) at jdk.scripting.nashorn/jdk.nashorn.internal.objects.NativeFunction.bind(NativeFunction.java:218) at jdk.scripting.nashorn.scripts/jdk.nashorn.internal.scripts.Script$Recompilation$1$\^eval\_/1998767043.:program(<eval>:8) at jdk.scripting.nashorn/jdk.nashorn.internal.runtime.ScriptFunctionData.invoke(ScriptFunctionData.java:652) at jdk.scripting.nashorn/jdk.nashorn.internal.runtime.ScriptFunction.invoke(ScriptFunction.java:513) at jdk.scripting.nashorn/jdk.nashorn.internal.runtime.ScriptRuntime.apply(ScriptRuntime.java:517) at jdk.scripting.nashorn/jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(NashornScriptEngine.java:448) at jdk.scripting.nashorn/jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(NashornScriptEngine.java:405) at jdk.scripting.nashorn/jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(NashornScriptEngine.java:401) at jdk.scripting.nashorn/jdk.nashorn.api.scripting.NashornScriptEngine.eval(NashornScriptEngine.java:154) at java.scripting/javax.script.AbstractScriptEngine.eval(AbstractScriptEngine.java:264) at JI9050584.main(JI9050584.java:9)
23-08-2017