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.