blob: 54c5b80f5ae89492bc667a170ee6d42f5a06b183 [file] [log] [blame]
// Copyright (c) 2015, 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.
part of dart.developer;
typedef dynamic TimelineSyncFunction();
/// Add to the timeline.
class Timeline {
/// Start a synchronous operation labeled [name]. Optionally takes
/// a [Map] of [arguments]. This operation must be finished before
/// returning to the event queue.
static void startSync(String name, {Map arguments}) {
if (name is! String) {
throw new ArgumentError.value(name,
'name',
'Must be a String');
}
var block = new _SyncBlock._(name, _getTraceClock());
if (arguments is Map) {
block.arguments.addAll(arguments);
}
_stack.add(block);
}
/// Finish the last synchronous operation that was started.
static void finishSync() {
if (_stack.length == 0) {
throw new StateError(
'Uneven calls to startSync and finishSync');
}
// Pop top item off of stack.
var block = _stack.removeLast();
// Close it.
block.close();
}
/// A utility method to time a synchronous [function]. Internally calls
/// [function] bracketed by calls to [startSync] and [finishSync].
static dynamic timeSync(String name,
TimelineSyncFunction function,
{Map arguments}) {
startSync(name, arguments: arguments);
try {
return function();
} finally {
finishSync();
}
}
static final List<_SyncBlock> _stack = new List<_SyncBlock>();
}
/// A synchronous block of time on the timeline. This block should not be
/// kept open across isolate messages.
class _SyncBlock {
/// The category this block belongs to.
final String category = 'Dart';
/// The name of this block.
final String name;
/// An (optional) set of arguments which will be serialized to JSON and
/// associated with this block.
final Map arguments = {};
// The start time stamp.
final int _start;
// Has this block been closed?
bool _closed = false;
_SyncBlock._(this.name,
this._start);
/// Close this block of time. At this point, this block can no longer be
/// used.
void close() {
if (_closed) {
throw new StateError(
'It is illegal to call close twice on the same _SyncBlock');
}
_closed = true;
var end = _getTraceClock();
// Encode arguments map as JSON before reporting.
var argumentsAsJson = JSON.encode(arguments);
// Report event to runtime.
_reportCompleteEvent(_start,
end,
category,
name,
argumentsAsJson);
}
}
/// Returns the current value from the trace clock.
external int _getTraceClock();
/// Reports a complete synchronous event.
external void _reportCompleteEvent(int start,
int end,
String category,
String name,
String argumentsAsJson);