Be lazier when capturing stack traces.
It turns out that capturing stack traces is cheap; converting them to strings is
what's so expensive.
R=rnystrom@google.com
Review URL: https://codereview.chromium.org//14647003
git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart/pkg/stack_trace@22205 260f80e4-7a28-3924-810f-c04153c831b5
diff --git a/pkgs/stack_trace/lib/src/lazy_trace.dart b/pkgs/stack_trace/lib/src/lazy_trace.dart
new file mode 100644
index 0000000..8c44829
--- /dev/null
+++ b/pkgs/stack_trace/lib/src/lazy_trace.dart
@@ -0,0 +1,34 @@
+// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library lazy_trace;
+
+import 'frame.dart';
+import 'trace.dart';
+
+/// A thunk for lazily constructing a [Trace].
+typedef Trace TraceThunk();
+
+/// A wrapper around a [TraceThunk]. This works around issue 9579 by avoiding
+/// the conversion of native [StackTrace]s to strings until it's absolutely
+/// necessary.
+class LazyTrace implements Trace {
+ final TraceThunk _thunk;
+ Trace _inner;
+
+ LazyTrace(this._thunk);
+
+ Trace get _trace {
+ if (_inner == null) _inner = _thunk();
+ return _inner;
+ }
+
+ List<Frame> get frames => _trace.frames;
+ String get stackTrace => _trace.stackTrace;
+ String get fullStackTrace => _trace.fullStackTrace;
+ Trace get terse => new LazyTrace(() => _trace.terse);
+ Trace foldFrames(bool predicate(frame)) =>
+ new LazyTrace(() => _trace.foldFrames(predicate));
+ String toString() => _trace.toString();
+}
diff --git a/pkgs/stack_trace/lib/src/trace.dart b/pkgs/stack_trace/lib/src/trace.dart
index 54f99db..ffea498 100644
--- a/pkgs/stack_trace/lib/src/trace.dart
+++ b/pkgs/stack_trace/lib/src/trace.dart
@@ -9,6 +9,7 @@
import 'dart:math' as math;
import 'frame.dart';
+import 'lazy_trace.dart';
final _patchRegExp = new RegExp(r"-patch$");
@@ -42,7 +43,7 @@
throw '';
} catch (_, nativeTrace) {
var trace = new Trace.from(nativeTrace);
- return new Trace(trace.frames.skip(level + 1));
+ return new LazyTrace(() => new Trace(trace.frames.skip(level + 1)));
}
}
@@ -52,7 +53,7 @@
/// a [Trace], it will be returned as-is.
factory Trace.from(StackTrace trace) {
if (trace is Trace) return trace;
- return new Trace.parse(trace.toString());
+ return new LazyTrace(() => new Trace.parse(trace.toString()));
}
/// Parses a string representation of a stack trace.