Mercurial > hg > openjdk > aarch64-port > nashorn
changeset 1376:201b37681668
8047365: Very long function names break codegen
Reviewed-by: attila, lagergren
author | hannesw |
---|---|
date | Thu, 14 May 2015 15:35:38 +0200 |
parents | 02421b7112bb |
children | bf44ade6c2c2 |
files | src/jdk/nashorn/internal/codegen/MethodEmitter.java src/jdk/nashorn/internal/codegen/Namespace.java test/script/basic/JDK-8047365.js test/script/basic/JDK-8047365.js.EXPECTED |
diffstat | 4 files changed, 67 insertions(+), 11 deletions(-) [+] |
line wrap: on
line diff
--- a/src/jdk/nashorn/internal/codegen/MethodEmitter.java Wed Dec 03 11:43:57 2014 +0100 +++ b/src/jdk/nashorn/internal/codegen/MethodEmitter.java Thu May 14 15:35:38 2015 +0200 @@ -1581,7 +1581,7 @@ /** * 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 @@ -2179,6 +2179,10 @@ * @return the method emitter */ MethodEmitter dynamicGet(final Type valueType, final String name, final int flags, final boolean isMethod, final boolean isIndex) { + 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; @@ -2204,8 +2208,13 @@ * @param isIndex is this an index operation? */ void dynamicSet(final String name, final int flags, final boolean isIndex) { - assert !isOptimistic(flags); - debug("dynamic_set", name, peekType()); + 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
--- a/src/jdk/nashorn/internal/codegen/Namespace.java Wed Dec 03 11:43:57 2014 +0100 +++ b/src/jdk/nashorn/internal/codegen/Namespace.java Thu May 14 15:35:38 2015 +0200 @@ -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 @@ } /** - * Create a uniqueName name in the namespace in the form base$n where n varies - * . + * 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<String, Integer> 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
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/script/basic/JDK-8047365.js Thu May 14 15:35:38 2015 +0200 @@ -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 + "()");