Index: pkg/dev_compiler/tool/input_sdk/lib/developer/profiler.dart |
diff --git a/pkg/dev_compiler/tool/input_sdk/lib/developer/profiler.dart b/pkg/dev_compiler/tool/input_sdk/lib/developer/profiler.dart |
new file mode 100644 |
index 0000000000000000000000000000000000000000..566d0158318b3110393e148adea893da1785b170 |
--- /dev/null |
+++ b/pkg/dev_compiler/tool/input_sdk/lib/developer/profiler.dart |
@@ -0,0 +1,197 @@ |
+// Copyright (c) 2014, 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; |
+ |
+/// A UserTag can be used to group samples in the Observatory profiler. |
+abstract class UserTag { |
+ /// The maximum number of UserTag instances that can be created by a program. |
+ static const MAX_USER_TAGS = 64; |
+ |
+ factory UserTag(String label) => new _FakeUserTag(label); |
+ |
+ /// Label of [this]. |
+ String get label; |
+ |
+ /// Make [this] the current tag for the isolate. Returns the current tag |
+ /// before setting. |
+ UserTag makeCurrent(); |
+ |
+ /// The default [UserTag] with label 'Default'. |
+ static UserTag get defaultTag => _FakeUserTag._defaultTag; |
+} |
+ |
+// This is a fake implementation of UserTag so that code can compile and run |
+// in dart2js. |
+class _FakeUserTag implements UserTag { |
+ static Map _instances = {}; |
+ |
+ _FakeUserTag.real(this.label); |
+ |
+ factory _FakeUserTag(String label) { |
+ // Canonicalize by name. |
+ var existingTag = _instances[label]; |
+ if (existingTag != null) { |
+ return existingTag; |
+ } |
+ // Throw an exception if we've reached the maximum number of user tags. |
+ if (_instances.length == UserTag.MAX_USER_TAGS) { |
+ throw new UnsupportedError( |
+ 'UserTag instance limit (${UserTag.MAX_USER_TAGS}) reached.'); |
+ } |
+ // Create a new instance and add it to the instance map. |
+ var instance = new _FakeUserTag.real(label); |
+ _instances[label] = instance; |
+ return instance; |
+ } |
+ |
+ final String label; |
+ |
+ UserTag makeCurrent() { |
+ var old = _currentTag; |
+ _currentTag = this; |
+ return old; |
+ } |
+ |
+ static final UserTag _defaultTag = new _FakeUserTag('Default'); |
+} |
+ |
+var _currentTag = _FakeUserTag._defaultTag; |
+ |
+/// Returns the current [UserTag] for the isolate. |
+UserTag getCurrentTag() { |
+ return _currentTag; |
+} |
+ |
+/// Abstract [Metric] class. Metric names must be unique, are hierarchical, |
+/// and use periods as separators. For example, 'a.b.c'. Uniqueness is only |
+/// enforced when a Metric is registered. The name of a metric cannot contain |
+/// the slash ('/') character. |
+abstract class Metric { |
+ /// [name] of this metric. |
+ final String name; |
+ /// [description] of this metric. |
+ final String description; |
+ |
+ Metric(this.name, this.description) { |
+ if ((name == 'vm') || name.contains('/')) { |
+ throw new ArgumentError('Invalid Metric name.'); |
+ } |
+ |
+ } |
+ |
+ Map _toJSON(); |
+} |
+ |
+/// A measured value with a min and max. Initial value is min. Value will |
+/// be clamped to the interval [min, max]. |
+class Gauge extends Metric { |
+ final double min; |
+ final double max; |
+ |
+ double _value; |
+ double get value => _value; |
+ set value(double v) { |
+ if (v < min) { |
+ v = min; |
+ } else if (v > max) { |
+ v = max; |
+ } |
+ _value = v; |
+ } |
+ |
+ Gauge(String name, String description, this.min, this.max) |
+ : super(name, description) { |
+ if (min is! double) { |
+ throw new ArgumentError('min must be a double'); |
+ } |
+ if (max is! double) { |
+ throw new ArgumentError('max must be a double'); |
+ } |
+ if (!(min < max)) { |
+ throw new ArgumentError('min must be less than max'); |
+ } |
+ _value = min; |
+ } |
+ |
+ Map _toJSON() { |
+ var map = { |
+ 'type': 'Gauge', |
+ 'id': 'metrics/$name', |
+ 'name': name, |
+ 'description': description, |
+ 'value': value, |
+ 'min': min, |
+ 'max': max, |
+ }; |
+ return map; |
+ } |
+} |
+ |
+ |
+/// A changing value. Initial value is 0.0. |
+class Counter extends Metric { |
+ Counter(String name, String description) |
+ : super(name, description); |
+ |
+ double _value = 0.0; |
+ double get value => _value; |
+ set value(double v) { |
+ _value = v; |
+ } |
+ |
+ Map _toJSON() { |
+ var map = { |
+ 'type': 'Counter', |
+ 'id': 'metrics/$name', |
+ 'name': name, |
+ 'description': description, |
+ 'value': value, |
+ }; |
+ return map; |
+ } |
+} |
+ |
+class Metrics { |
+ static final Map<String, Metric> _metrics = new Map<String, Metric>(); |
+ |
+ /// Register [Metric]s to make them visible to Observatory. |
+ static void register(Metric metric) { |
+ if (metric is! Metric) { |
+ throw new ArgumentError('metric must be a Metric'); |
+ } |
+ if (_metrics[metric.name] != null) { |
+ throw new ArgumentError('Registered metrics have unique names'); |
+ } |
+ _metrics[metric.name] = metric; |
+ } |
+ |
+ /// Deregister [Metric]s to make them not visible to Observatory. |
+ static void deregister(Metric metric) { |
+ if (metric is! Metric) { |
+ throw new ArgumentError('metric must be a Metric'); |
+ } |
+ _metrics.remove(metric.name); |
+ } |
+ |
+ static String _printMetric(String id) { |
+ var metric = _metrics[id]; |
+ if (metric == null) { |
+ return null; |
+ } |
+ return JSON.encode(metric._toJSON()); |
+ } |
+ |
+ static String _printMetrics() { |
+ var metrics = []; |
+ for (var metric in _metrics.values) { |
+ metrics.add(metric._toJSON()); |
+ } |
+ var map = { |
+ 'type': 'MetricList', |
+ 'metrics': metrics, |
+ }; |
+ return JSON.encode(map); |
+ } |
+} |