8134930: Defer stack trace walking of NashornException for extracting line number and file name
Reviewed-by: hannesw, sundar
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/scripting/NashornException.java Tue Sep 01 23:08:33 2015 +0530
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/scripting/NashornException.java Wed Sep 02 12:26:57 2015 +0200
@@ -51,6 +51,8 @@
private String fileName;
// script line number
private int line;
+ // are the line and fileName unknown?
+ private boolean lineAndFileNameUnknown;
// script column number
private int column;
// underlying ECMA error object - lazily initialized
@@ -92,27 +94,10 @@
*/
protected NashornException(final String msg, final Throwable cause) {
super(msg, cause == null ? null : cause);
- // This is not so pretty - but it gets the job done. Note that the stack
- // trace has been already filled by "fillInStackTrace" call from
- // Throwable
- // constructor and so we don't pay additional cost for it.
-
// Hard luck - no column number info
this.column = -1;
-
- // Find the first JavaScript frame by walking and set file, line from it
- // Usually, we should be able to find it in just few frames depth.
- for (final StackTraceElement ste : getStackTrace()) {
- if (ECMAErrors.isScriptFrame(ste)) {
- // Whatever here is compiled from JavaScript code
- this.fileName = ste.getFileName();
- this.line = ste.getLineNumber();
- return;
- }
- }
-
- this.fileName = null;
- this.line = 0;
+ // We can retrieve the line number and file name from the stack trace if needed
+ this.lineAndFileNameUnknown = true;
}
/**
@@ -121,6 +106,7 @@
* @return the file name
*/
public final String getFileName() {
+ ensureLineAndFileName();
return fileName;
}
@@ -131,6 +117,7 @@
*/
public final void setFileName(final String fileName) {
this.fileName = fileName;
+ lineAndFileNameUnknown = false;
}
/**
@@ -139,6 +126,7 @@
* @return the line number
*/
public final int getLineNumber() {
+ ensureLineAndFileName();
return line;
}
@@ -148,6 +136,7 @@
* @param line the line number
*/
public final void setLineNumber(final int line) {
+ lineAndFileNameUnknown = false;
this.line = line;
}
@@ -274,4 +263,19 @@
public void setEcmaError(final Object ecmaError) {
this.ecmaError = ecmaError;
}
+
+ private void ensureLineAndFileName() {
+ if (lineAndFileNameUnknown) {
+ for (final StackTraceElement ste : getStackTrace()) {
+ if (ECMAErrors.isScriptFrame(ste)) {
+ // Whatever here is compiled from JavaScript code
+ fileName = ste.getFileName();
+ line = ste.getLineNumber();
+ return;
+ }
+ }
+
+ lineAndFileNameUnknown = false;
+ }
+ }
}