Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(121)

Unified Diff: src/messages.js

Issue 11880018: Reland r13188, r13194, r13256 (Deferred formatting of error stack trace during GC). (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Fix Created 7 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/mark-compact.cc ('k') | src/runtime.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/messages.js
diff --git a/src/messages.js b/src/messages.js
index 5d065d098434f39743d7d35a20524e22d973f22a..4a8143e611162a447436ecb64aefb670e10c14fb 100644
--- a/src/messages.js
+++ b/src/messages.js
@@ -820,7 +820,7 @@ function CallSiteGetMethodName() {
%_CallFunction(this.receiver,
ownName,
ObjectLookupSetter) === this.fun ||
- this.receiver[ownName] === this.fun)) {
+ %GetDataProperty(this.receiver, ownName) === this.fun)) {
// To handle DontEnum properties we guess that the method has
// the same name as the function.
return ownName;
@@ -829,8 +829,7 @@ function CallSiteGetMethodName() {
for (var prop in this.receiver) {
if (%_CallFunction(this.receiver, prop, ObjectLookupGetter) === this.fun ||
%_CallFunction(this.receiver, prop, ObjectLookupSetter) === this.fun ||
- (!%_CallFunction(this.receiver, prop, ObjectLookupGetter) &&
- this.receiver[prop] === this.fun)) {
+ %GetDataProperty(this.receiver, prop) === this.fun) {
// If we find more than one match bail out to avoid confusion.
if (name) {
return null;
@@ -883,7 +882,8 @@ function CallSiteGetPosition() {
}
function CallSiteIsConstructor() {
- var constructor = this.receiver ? this.receiver.constructor : null;
+ var receiver = this.receiver;
+ var constructor = receiver ? %GetDataProperty(receiver, "constructor") : null;
if (!constructor) {
return false;
}
@@ -933,12 +933,14 @@ function CallSiteToString() {
var typeName = GetTypeName(this, true);
var methodName = this.getMethodName();
if (functionName) {
- if (typeName && functionName.indexOf(typeName) != 0) {
+ if (typeName &&
+ %_CallFunction(functionName, typeName, StringIndexOf) != 0) {
line += typeName + ".";
}
line += functionName;
- if (methodName && functionName.lastIndexOf("." + methodName) !=
- functionName.length - methodName.length - 1) {
+ if (methodName &&
+ (%_CallFunction(functionName, "." + methodName, StringIndexOf) !=
+ functionName.length - methodName.length - 1)) {
line += " [as " + methodName + "]";
}
} else {
@@ -1016,17 +1018,37 @@ function FormatEvalOrigin(script) {
return eval_origin;
}
-function FormatStackTrace(error, frames) {
- var lines = [];
+
+function FormatErrorString(error) {
try {
- lines.push(error.toString());
+ return %_CallFunction(error, ErrorToString);
} catch (e) {
try {
- lines.push("<error: " + e + ">");
+ return "<error: " + e + ">";
} catch (ee) {
- lines.push("<error>");
+ return "<error>";
}
}
+}
+
+
+function GetStackFrames(raw_stack) {
+ var frames = new InternalArray();
+ for (var i = 0; i < raw_stack.length; i += 4) {
+ var recv = raw_stack[i];
+ var fun = raw_stack[i + 1];
+ var code = raw_stack[i + 2];
+ var pc = raw_stack[i + 3];
+ var pos = %FunctionGetPositionForOffset(code, pc);
+ frames.push(new CallSite(recv, fun, pos));
+ }
+ return frames;
+}
+
+
+function FormatStackTrace(error_string, frames) {
+ var lines = new InternalArray();
+ lines.push(error_string);
for (var i = 0; i < frames.length; i++) {
var frame = frames[i];
var line;
@@ -1042,25 +1064,9 @@ function FormatStackTrace(error, frames) {
}
lines.push(" at " + line);
}
- return lines.join("\n");
+ return %_CallFunction(lines, "\n", ArrayJoin);
}
-function FormatRawStackTrace(error, raw_stack) {
- var frames = [ ];
- for (var i = 0; i < raw_stack.length; i += 4) {
- var recv = raw_stack[i];
- var fun = raw_stack[i + 1];
- var code = raw_stack[i + 2];
- var pc = raw_stack[i + 3];
- var pos = %FunctionGetPositionForOffset(code, pc);
- frames.push(new CallSite(recv, fun, pos));
- }
- if (IS_FUNCTION($Error.prepareStackTrace)) {
- return $Error.prepareStackTrace(error, frames);
- } else {
- return FormatStackTrace(error, frames);
- }
-}
function GetTypeName(obj, requireConstructor) {
var constructor = obj.receiver.constructor;
@@ -1076,23 +1082,51 @@ function GetTypeName(obj, requireConstructor) {
return constructorName;
}
+
+// Flag to prevent recursive call of Error.prepareStackTrace.
+var formatting_custom_stack_trace = false;
+
+
function captureStackTrace(obj, cons_opt) {
var stackTraceLimit = $Error.stackTraceLimit;
if (!stackTraceLimit || !IS_NUMBER(stackTraceLimit)) return;
if (stackTraceLimit < 0 || stackTraceLimit > 10000) {
stackTraceLimit = 10000;
}
- var raw_stack = %CollectStackTrace(obj,
- cons_opt ? cons_opt : captureStackTrace,
- stackTraceLimit);
+ var stack = %CollectStackTrace(obj,
+ cons_opt ? cons_opt : captureStackTrace,
+ stackTraceLimit);
+
+ // Don't be lazy if the error stack formatting is custom (observable).
+ if (IS_FUNCTION($Error.prepareStackTrace) && !formatting_custom_stack_trace) {
+ var array = [];
+ %MoveArrayContents(GetStackFrames(stack), array);
+ formatting_custom_stack_trace = true;
+ try {
+ obj.stack = $Error.prepareStackTrace(obj, array);
+ } catch (e) {
+ throw e; // The custom formatting function threw. Rethrow.
+ } finally {
+ formatting_custom_stack_trace = false;
+ }
+ return;
+ }
+
+ var error_string = FormatErrorString(obj);
// Note that 'obj' and 'this' maybe different when called on objects that
// have the error object on its prototype chain. The getter replaces itself
// with a data property as soon as the stack trace has been formatted.
+ // The getter must not change the object layout as it may be called after GC.
var getter = function() {
- var value = FormatRawStackTrace(obj, raw_stack);
- %DefineOrRedefineDataProperty(obj, 'stack', value, NONE);
- return value;
+ if (IS_STRING(stack)) return stack;
+ // Stack is still a raw array awaiting to be formatted.
+ stack = FormatStackTrace(error_string, GetStackFrames(stack));
+ // Release context value.
+ error_string = void 0;
+ return stack;
};
+ %MarkOneShotGetter(getter);
+
// The 'stack' property of the receiver is set as data property. If
// the receiver is the same as holder, this accessor pair is replaced.
var setter = function(v) {
@@ -1239,23 +1273,32 @@ function SetUpStackOverflowBoilerplate() {
// error object copy, but can be found on the prototype chain of 'this'.
// When the stack trace is formatted, this accessor property is replaced by
// a data property.
+ var error_string = boilerplate.name + ": " + boilerplate.message;
+
+ // The getter must not change the object layout as it may be called after GC.
function getter() {
var holder = this;
while (!IS_ERROR(holder)) {
holder = %GetPrototype(holder);
if (holder == null) return MakeSyntaxError('illegal_access', []);
}
- var raw_stack = %GetOverflowedRawStackTrace(holder);
- var result = IS_ARRAY(raw_stack) ? FormatRawStackTrace(holder, raw_stack)
- : void 0;
- %DefineOrRedefineDataProperty(holder, 'stack', result, NONE);
- return result;
+ var stack = %GetOverflowedStackTrace(holder);
+ if (IS_STRING(stack)) return stack;
+ if (IS_ARRAY(stack)) {
+ var result = FormatStackTrace(error_string, GetStackFrames(stack));
+ %SetOverflowedStackTrace(holder, result);
+ return result;
+ }
+ return void 0;
}
+ %MarkOneShotGetter(getter);
// The 'stack' property of the receiver is set as data property. If
// the receiver is the same as holder, this accessor pair is replaced.
function setter(v) {
%DefineOrRedefineDataProperty(this, 'stack', v, NONE);
+ // Release the stack trace that is stored as hidden property, if exists.
+ %SetOverflowedStackTrace(this, void 0);
}
%DefineOrRedefineAccessorProperty(
« no previous file with comments | « src/mark-compact.cc ('k') | src/runtime.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698