diff --git a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/MethodEmitter.java b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/MethodEmitter.java index c6b473f3e54..962687c946f 100644 --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/MethodEmitter.java +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/MethodEmitter.java @@ -1591,7 +1591,7 @@ public class MethodEmitter implements Emitter { /** * Abstraction for performing a conditional jump of any type * - * @see MethodEmitter.Condition + * @see Condition * * @param cond the condition to test * @param trueLabel the destination label is condition is true @@ -2217,6 +2217,10 @@ public class MethodEmitter implements Emitter { * @return the method emitter */ MethodEmitter dynamicGet(final Type valueType, final String name, final int flags, final boolean isMethod) { + if (name.length() > LARGE_STRING_THRESHOLD) { // use getIndex for extremely long names + return load(name).dynamicGetIndex(valueType, flags, isMethod); + } + debug("dynamic_get", name, valueType, getProgramPoint(flags)); Type type = valueType; @@ -2240,9 +2244,14 @@ public class MethodEmitter implements Emitter { * @param name name of property * @param flags call site flags */ - void dynamicSet(final String name, final int flags) { - assert !isOptimistic(flags); - debug("dynamic_set", name, peekType()); + void dynamicSet(final String name, final int flags) { + if (name.length() > LARGE_STRING_THRESHOLD) { // use setIndex for extremely long names + load(name).swap().dynamicSetIndex(flags); + return; + } + + assert !isOptimistic(flags); + debug("dynamic_set", name, peekType()); Type type = peekType(); if (type.isObject() || type.isBoolean()) { //promote strings to objects etc diff --git a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/Namespace.java b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/Namespace.java index 5c5115a9f89..17304a905ab 100644 --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/Namespace.java +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/Namespace.java @@ -25,6 +25,8 @@ package jdk.nashorn.internal.codegen; +import static jdk.nashorn.internal.codegen.MethodEmitter.LARGE_STRING_THRESHOLD; + import java.util.HashMap; /** @@ -66,27 +68,28 @@ public class Namespace { } /** - * Create a uniqueName name in the namespace in the form base$n where n varies - * . - * @param base Base of name. Base will be returned if uniqueName. + * Create a uniqueName name in the namespace in the form base$n where n varies. + * Also truncates very long names that would otherwise break ASM. * + * @param base Base of name. Base will be returned if uniqueName. * @return Generated uniqueName name. */ public String uniqueName(final String base) { + final String truncatedBase = base.length() > LARGE_STRING_THRESHOLD ? base.substring(0, LARGE_STRING_THRESHOLD) : base; for (Namespace namespace = this; namespace != null; namespace = namespace.getParent()) { final HashMap namespaceDirectory = namespace.directory; - final Integer counter = namespaceDirectory.get(base); + final Integer counter = namespaceDirectory.get(truncatedBase); if (counter != null) { final int count = counter + 1; - namespaceDirectory.put(base, count); - return base + '-' + count; + namespaceDirectory.put(truncatedBase, count); + return truncatedBase + '-' + count; } } - directory.put(base, 0); + directory.put(truncatedBase, 0); - return base; + return truncatedBase; } @Override diff --git a/nashorn/test/script/basic/JDK-8047365.js b/nashorn/test/script/basic/JDK-8047365.js new file mode 100644 index 00000000000..63d0c18bc68 --- /dev/null +++ b/nashorn/test/script/basic/JDK-8047365.js @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2010, 2014, 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. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * JDK-8047365: Very long function names break codegen + * + * @test + * @run + */ + +// string of length 131071, twice the limit of UTF8 strings in ASM +var longId = Array(0x20000).join("a"); +print(longId.length); + +eval("function " + longId + "(){ print('hello world'); }"); +eval("print(typeof " + longId + ")"); +eval("print(" + longId + ".name === longId)"); +eval("print(/a+/.exec(" + longId + ".toString())[0] === longId)"); +eval(longId + "()"); diff --git a/nashorn/test/script/basic/JDK-8047365.js.EXPECTED b/nashorn/test/script/basic/JDK-8047365.js.EXPECTED new file mode 100644 index 00000000000..1bb1a01a1ac --- /dev/null +++ b/nashorn/test/script/basic/JDK-8047365.js.EXPECTED @@ -0,0 +1,5 @@ +131071 +function +true +true +hello world