--- old/src/jdk/nashorn/internal/codegen/CodeGenerator.java 2013-09-27 11:07:07.585989605 +0200 +++ new/src/jdk/nashorn/internal/codegen/CodeGenerator.java 2013-09-27 11:07:07.509989606 +0200 @@ -1956,7 +1956,7 @@ final Expression expression = throwNode.getExpression(); final int position = throwNode.position(); - final int line = source.getLine(position); + final int line = throwNode.getLineNumber(); final int column = source.getColumn(position); load(expression); --- old/src/jdk/nashorn/internal/ir/LexicalContext.java 2013-09-27 11:07:07.953989602 +0200 +++ new/src/jdk/nashorn/internal/ir/LexicalContext.java 2013-09-27 11:07:07.877989602 +0200 @@ -587,11 +587,11 @@ final FunctionNode fn = (FunctionNode)node; final Source source = fn.getSource(); String src = source.toString(); - if (src.indexOf(File.pathSeparator) != -1) { + if (src.contains(File.pathSeparator)) { src = src.substring(src.lastIndexOf(File.pathSeparator)); } src += ' '; - src += source.getLine(fn.getStart()); + src += fn.getLineNumber(); sb.append(src); } sb.append(' '); --- old/src/jdk/nashorn/internal/parser/Parser.java 2013-09-27 11:07:08.297989599 +0200 +++ new/src/jdk/nashorn/internal/parser/Parser.java 2013-09-27 11:07:08.217989600 +0200 @@ -2436,7 +2436,7 @@ // name is null, generate anonymous name boolean isAnonymous = false; if (name == null) { - final String tmpName = "_L" + source.getLine(Token.descPosition(token)); + final String tmpName = "_L" + functionLine; name = new IdentNode(functionToken, Token.descPosition(functionToken), tmpName); isAnonymous = true; } --- old/src/jdk/nashorn/internal/runtime/RecompilableScriptFunctionData.java 2013-09-27 11:07:08.661989595 +0200 +++ new/src/jdk/nashorn/internal/runtime/RecompilableScriptFunctionData.java 2013-09-27 11:07:08.585989596 +0200 @@ -132,7 +132,7 @@ if (source != null) { sb.append(source.getName()) .append(':') - .append(source.getLine(Token.descPosition(token))) + .append(functionNode.getLineNumber()) .append(' '); } --- old/src/jdk/nashorn/internal/runtime/Source.java 2013-09-27 11:07:08.989989592 +0200 +++ new/src/jdk/nashorn/internal/runtime/Source.java 2013-09-27 11:07:08.913989593 +0200 @@ -272,6 +272,10 @@ /** * Return line number of character position. + * + *

This method can be expensive for large sources as it iterates through + * all characters up to {@code position}.

+ * * @param position Position of character in source content. * @return Line number. */ --- /dev/null 2013-09-25 14:09:43.298588998 +0200 +++ new/test/script/basic/JDK-8025515.js 2013-09-27 11:07:09.245989590 +0200 @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2010, 2013, 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-8025515: Performance issues with Source.getLine() + * + * @test + * @run + */ + +// Make sure synthetic names of anonymous functions have correct line numbers + +function testMethodName(f, expected) { + try { + f(); + fail("expected error"); + } catch (e) { + var stack = e.getStackTrace(); + if (stack[0].methodName !== expected) { + fail("got " + stack[0].methodName + ", expected " + expected); + } + } +} + +testMethodName(function() { + return a.b.c; +}, "_L45"); + +testMethodName(function() { throw new Error() }, "_L49"); + +var f = (function() { + return function() { a.b.c; }; +})(); +testMethodName(f, "_L51$_L52"); + +testMethodName((function() { + return function() { return a.b.c; }; +})(), "_L56$_L57");