Author: [email protected]
Date: Thu Jul  2 05:26:31 2009
New Revision: 2338

Modified:
    branches/bleeding_edge/src/bootstrapper.cc
    branches/bleeding_edge/src/flag-definitions.h
    branches/bleeding_edge/src/messages.js
    branches/bleeding_edge/src/runtime.cc
    branches/bleeding_edge/src/runtime.h
    branches/bleeding_edge/test/mjsunit/stack-traces.js

Log:
Enable capture of the top of the stack on error instantiation.
Performance impact on v8 benchmarks seems limited.  Will be backed out
if chrome performance regresses.


Modified: branches/bleeding_edge/src/bootstrapper.cc
==============================================================================
--- branches/bleeding_edge/src/bootstrapper.cc  (original)
+++ branches/bleeding_edge/src/bootstrapper.cc  Thu Jul  2 05:26:31 2009
@@ -1206,15 +1206,13 @@
                  Handle<JSObject>(js_global->builtins()), DONT_ENUM);
    }

-  if (FLAG_capture_stack_traces) {
-    Handle<Object> Error = GetProperty(js_global, "Error");
-    if (Error->IsJSObject()) {
-      Handle<String> name =  
Factory::LookupAsciiSymbol("captureStackTraces");
-      SetProperty(Handle<JSObject>::cast(Error),
-                  name,
-                  Factory::true_value(),
-                  NONE);
-    }
+  Handle<Object> Error = GetProperty(js_global, "Error");
+  if (Error->IsJSObject()) {
+    Handle<String> name = Factory::LookupAsciiSymbol("stackTraceLimit");
+    SetProperty(Handle<JSObject>::cast(Error),
+                name,
+                Handle<Smi>(Smi::FromInt(FLAG_stack_trace_limit)),
+                NONE);
    }

  #ifdef ENABLE_DEBUGGER_SUPPORT

Modified: branches/bleeding_edge/src/flag-definitions.h
==============================================================================
--- branches/bleeding_edge/src/flag-definitions.h       (original)
+++ branches/bleeding_edge/src/flag-definitions.h       Thu Jul  2 05:26:31 2009
@@ -110,7 +110,7 @@
  DEFINE_string(expose_debug_as, NULL, "expose debug in global object")
  DEFINE_string(natives_file, NULL, "alternative natives file")
  DEFINE_bool(expose_gc, false, "expose gc extension")
-DEFINE_bool(capture_stack_traces, false, "capture stack traces")
+DEFINE_int(stack_trace_limit, 10, "number of stack frames to capture")

  // builtins-ia32.cc
  DEFINE_bool(inline_new, true, "use fast inline allocation")

Modified: branches/bleeding_edge/src/messages.js
==============================================================================
--- branches/bleeding_edge/src/messages.js      (original)
+++ branches/bleeding_edge/src/messages.js      Thu Jul  2 05:26:31 2009
@@ -629,10 +629,22 @@
  CallSite.prototype.getFunctionName = function () {
    // See if the function knows its own name
    var name = this.fun.name;
-  if (name)
+  if (name) {
      return name;
+  } else {
+    return %FunctionGetInferredName(this.fun);
+  }
+  // Maybe this is an evaluation?
+  var script = %FunctionGetScript(this.fun);
+  if (script && script.compilation_type == 1)
+    return "eval";
+  return null;
+};
+
+CallSite.prototype.getMethodName = function () {
    // See if we can find a unique property on the receiver that holds
    // this function.
+  var name = null;
    for (var prop in this.receiver) {
      if (this.receiver[prop] === this.fun) {
        // If we find more than one match bail out to avoid confusion
@@ -643,10 +655,6 @@
    }
    if (name)
      return name;
-  // Maybe this is an evaluation?
-  var script = %FunctionGetScript(this.fun);
-  if (script && script.compilation_type == 1)
-    return "eval";
    return null;
  };

@@ -717,18 +725,27 @@
      fileLocation = "unknown source";
    }
    var line = "";
+  var methodName = frame.getMethodName();
    var functionName = frame.getFunctionName();
-  if (functionName) {
-    if (frame.isToplevel()) {
-      line += functionName;
-    } else if (frame.isConstructor()) {
-      line += "new " + functionName;
-    } else {
-      line += frame.getTypeName() + "." + functionName;
-    }
-    line += " (" + fileLocation + ")";
+  var addPrefix = true;
+  if (frame.isToplevel()) {
+    line += functionName;
+  } else if (frame.isConstructor()) {
+    line += "new " + functionName;
+  } else if (methodName) {
+    line += frame.getTypeName() + "." + methodName;
+  } else if (functionName) {
+    line += functionName;
    } else {
      line += fileLocation;
+    addPrefix = false;
+  }
+  if (addPrefix) {
+    line += " (";
+    if (functionName) {
+      line += functionName + " @ ";
+    }
+    line += fileLocation + ")";
    }
    return line;
  }
@@ -812,8 +829,12 @@
        } else if (!IS_UNDEFINED(m)) {
          this.message = ToString(m);
        }
-      if ($Error.captureStackTraces) {
-        var raw_stack = %CollectStackTrace(f);
+      var stackTraceLimit = $Error.stackTraceLimit;
+      if (stackTraceLimit) {
+        // Cap the limit to avoid extremely big traces
+        if (stackTraceLimit < 0 || stackTraceLimit > 10000)
+          stackTraceLimit = 10000;
+        var raw_stack = %CollectStackTrace(f, stackTraceLimit);
          DefineOneShotAccessor(this, 'stack', function (obj) {
            return FormatRawStackTrace(obj, raw_stack);
          });

Modified: branches/bleeding_edge/src/runtime.cc
==============================================================================
--- branches/bleeding_edge/src/runtime.cc       (original)
+++ branches/bleeding_edge/src/runtime.cc       Thu Jul  2 05:26:31 2009
@@ -7420,32 +7420,46 @@
  // element segments each containing a receiver, function and native
  // code offset.
  static Object* Runtime_CollectStackTrace(Arguments args) {
-  ASSERT_EQ(args.length(), 1);
+  ASSERT_EQ(args.length(), 2);
    Object* caller = args[0];
+  CONVERT_NUMBER_CHECKED(int32_t, limit, Int32, args[1]);
+
+  HandleScope scope;
+
+  int initial_size = limit < 10 ? limit : 10;
+  Handle<JSArray> result = Factory::NewJSArray(initial_size * 3);

    StackFrameIterator iter;
-  int frame_count = 0;
    bool seen_caller = false;
-  while (!iter.done()) {
-    if (ShowFrameInStackTrace(iter.frame(), caller, &seen_caller))
-      frame_count++;
-    iter.Advance();
-  }
-  HandleScope scope;
-  Handle<JSArray> result = Factory::NewJSArray(frame_count * 3);
-  int i = 0;
-  seen_caller = false;
-  for (iter.Reset(); !iter.done(); iter.Advance()) {
+  int cursor = 0;
+  int frames_seen = 0;
+  while (!iter.done() && frames_seen < limit) {
      StackFrame* raw_frame = iter.frame();
      if (ShowFrameInStackTrace(raw_frame, caller, &seen_caller)) {
+      frames_seen++;
        JavaScriptFrame* frame = JavaScriptFrame::cast(raw_frame);
-      result->SetElement(i++, frame->receiver());
-      result->SetElement(i++, frame->function());
+      Object* recv = frame->receiver();
+      Object* fun = frame->function();
        Address pc = frame->pc();
        Address start = frame->code()->address();
-      result->SetElement(i++, Smi::FromInt(pc - start));
+      Smi* offset = Smi::FromInt(pc - start);
+      FixedArray* elements = result->elements();
+      if (cursor + 2 < elements->length()) {
+        elements->set(cursor++, recv);
+        elements->set(cursor++, fun);
+        elements->set(cursor++, offset, SKIP_WRITE_BARRIER);
+      } else {
+        HandleScope scope;
+        SetElement(result, cursor++, Handle<Object>(recv));
+        SetElement(result, cursor++, Handle<Object>(fun));
+        SetElement(result, cursor++, Handle<Smi>(offset));
+      }
      }
+    iter.Advance();
    }
+
+  result->set_length(Smi::FromInt(cursor), SKIP_WRITE_BARRIER);
+
    return *result;
  }


Modified: branches/bleeding_edge/src/runtime.h
==============================================================================
--- branches/bleeding_edge/src/runtime.h        (original)
+++ branches/bleeding_edge/src/runtime.h        Thu Jul  2 05:26:31 2009
@@ -172,7 +172,7 @@
    F(FunctionGetPositionForOffset, 2) \
    F(FunctionIsAPIFunction, 1) \
    F(GetScript, 1) \
-  F(CollectStackTrace, 1) \
+  F(CollectStackTrace, 2) \
    \
    F(ClassOf, 1) \
    F(SetCode, 2) \

Modified: branches/bleeding_edge/test/mjsunit/stack-traces.js
==============================================================================
--- branches/bleeding_edge/test/mjsunit/stack-traces.js (original)
+++ branches/bleeding_edge/test/mjsunit/stack-traces.js Thu Jul  2 05:26:31  
2009
@@ -25,8 +25,6 @@
  // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

-Error.captureStackTraces = true;
-
  function testMethodNameInference() {
    function Foo() { }
    Foo.prototype.bar = function () { FAIL; };

--~--~---------~--~----~------------~-------~--~----~
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
-~----------~----~----~----~------~----~------~--~---

Reply via email to