Skip to content
This repository was archived by the owner on Feb 22, 2018. It is now read-only.

Commit 23639c1

Browse files
mheverychirayuk
authored andcommitted
feat(WTF): Add support for WTF
1) Install https://chrome.google.com/webstore/detail/web-tracing-framework/gmdhhnlkjmknaopofnadmoamhmnlicme 2) Enjoy the visibility Closes #1354
1 parent a300adf commit 23639c1

22 files changed

+372
-126
lines changed

benchmark/launch_chrome.sh

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,10 @@ platform=`uname`
44
if [[ "$platform" == 'Linux' ]]; then
55
`google-chrome --js-flags="--expose-gc"`
66
elif [[ "$platform" == 'Darwin' ]]; then
7-
`/Applications/Google\ Chrome\ Canary.app/Contents/MacOS/Google\ Chrome\ Canary --enable-memory-info --enable-precise-memory-info --enable-memory-benchmarking --js-flags="--expose-gc"`
7+
`/Applications/Google\ Chrome\ Canary.app/Contents/MacOS/Google\ Chrome\ Canary \
8+
--enable-memory-info \
9+
--enable-precise-memory-info \
10+
--enable-memory-benchmarking \
11+
--js-flags="--expose-gc" \
12+
--remote-debugging-port=9222`
813
fi

benchmark/web/wtf.dart

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
library wtf_test_app;
2+
3+
import 'package:angular/wtf.dart';
4+
import 'dart:html';
5+
import 'dart:js' show context;
6+
7+
main() {
8+
traceInit(context);
9+
var _main = traceCreateScope('main()');
10+
var _querySelector = traceCreateScope('Node#querySelector()');
11+
var _DivElement = traceCreateScope('DivElement()');
12+
var _ElementText = traceCreateScope('Element#text');
13+
var _NodeAppend = traceCreateScope('Node#append()');
14+
var scope = traceEnter(_main);
15+
var s = traceEnter(_querySelector);
16+
BodyElement body = window.document.querySelector('body');
17+
traceLeave(s);
18+
19+
s = traceEnter(_DivElement);
20+
var div = new DivElement();
21+
traceLeave(s);
22+
23+
s = traceEnter(_ElementText);
24+
div.text = 'Hello WTF! (enabled: ${wtfEnabled})';
25+
traceLeave(s);
26+
27+
s = traceEnter(_NodeAppend);
28+
body.append(div);
29+
traceLeave(s);
30+
traceLeave(scope);
31+
}

benchmark/web/wtf.html

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head lang="en">
4+
<meta charset="UTF-8">
5+
<title>WTF Test page</title>
6+
<script src="wtf.dart" type="application/dart"></script>
7+
<script src="packages/browser/dart.js"></script>
8+
<script src="packages/browser/interop.js"></script>
9+
</head>
10+
<body>
11+
</body>
12+
</html>

lib/application.dart

Lines changed: 28 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@
6868
library angular.app;
6969

7070
import 'dart:html' as dom;
71+
import 'dart:js' show context;
7172

7273
import 'package:intl/date_symbol_data_local.dart';
7374
import 'package:di/di.dart';
@@ -76,12 +77,12 @@ import 'package:angular/perf/module.dart';
7677
import 'package:angular/cache/module.dart';
7778
import 'package:angular/cache/js_cache_register.dart';
7879
import 'package:angular/core/module_internal.dart';
79-
import 'package:angular/core/registry.dart';
8080
import 'package:angular/core_dom/module_internal.dart';
8181
import 'package:angular/directive/module.dart';
8282
import 'package:angular/formatter/module_internal.dart';
8383
import 'package:angular/routing/module.dart';
8484
import 'package:angular/introspection.dart';
85+
import 'package:angular/wtf.dart';
8586

8687
import 'package:angular/core_dom/static_keys.dart';
8788
import 'package:angular/core_dom/directive_injector.dart';
@@ -129,6 +130,7 @@ class AngularModule extends Module {
129130
* applicationFactory to bootstrap your Angular application.
130131
*
131132
*/
133+
var _Application_run = traceCreateScope('Application#run()');
132134
abstract class Application {
133135
static _find(String selector, [dom.Element defaultElement]) {
134136
var element = dom.document.querySelector(selector);
@@ -150,6 +152,7 @@ abstract class Application {
150152
dom.Element selector(String selector) => element = _find(selector);
151153

152154
Application(): element = _find('[ng-app]', dom.window.document.documentElement) {
155+
traceInit(context);
153156
modules.add(ngModule);
154157
ngModule..bind(VmTurnZone, toValue: zone)
155158
..bind(Application, toValue: this)
@@ -172,26 +175,31 @@ abstract class Application {
172175
}
173176

174177
Injector run() {
175-
publishToJavaScript();
176-
return zone.run(() {
177-
var rootElements = [element];
178-
Injector injector = createInjector();
179-
ExceptionHandler exceptionHandler = injector.getByKey(EXCEPTION_HANDLER_KEY);
180-
// Publish cache register interface
181-
injector.getByKey(JS_CACHE_REGISTER_KEY);
182-
initializeDateFormatting(null, null).then((_) {
183-
try {
184-
Compiler compiler = injector.getByKey(COMPILER_KEY);
185-
DirectiveMap directiveMap = injector.getByKey(DIRECTIVE_MAP_KEY);
186-
RootScope rootScope = injector.getByKey(ROOT_SCOPE_KEY);
187-
ViewFactory viewFactory = compiler(rootElements, directiveMap);
188-
viewFactory(rootScope, injector.get(DirectiveInjector), rootElements);
189-
} catch (e, s) {
190-
exceptionHandler(e, s);
191-
}
178+
var scope = traceEnter(_Application_run);
179+
try {
180+
publishToJavaScript();
181+
return zone.run(() {
182+
var rootElements = [element];
183+
Injector injector = createInjector();
184+
ExceptionHandler exceptionHandler = injector.getByKey(EXCEPTION_HANDLER_KEY);
185+
// Publish cache register interface
186+
injector.getByKey(JS_CACHE_REGISTER_KEY);
187+
initializeDateFormatting(null, null).then((_) {
188+
try {
189+
Compiler compiler = injector.getByKey(COMPILER_KEY);
190+
DirectiveMap directiveMap = injector.getByKey(DIRECTIVE_MAP_KEY);
191+
RootScope rootScope = injector.getByKey(ROOT_SCOPE_KEY);
192+
ViewFactory viewFactory = compiler(rootElements, directiveMap);
193+
viewFactory(rootScope, injector.get(DirectiveInjector), rootElements);
194+
} catch (e, s) {
195+
exceptionHandler(e, s);
196+
}
197+
});
198+
return injector;
192199
});
193-
return injector;
194-
});
200+
} finally {
201+
traceLeave(scope);
202+
}
195203
}
196204

197205
/**

lib/change_detection/watch_group.dart

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,18 @@ library angular.watch_group;
22

33
import 'package:angular/change_detection/change_detection.dart';
44
import 'dart:collection';
5+
import 'package:angular/wtf.dart';
56

67
part 'linked_list.dart';
78
part 'ast.dart';
89
part 'prototype_map.dart';
910

11+
var _WatchGroup_detect = traceCreateScope('WatchGroup#detect()');
12+
var _WatchGroup_fields = traceCreateScope('WatchGroup#field()');
13+
var _WatchGroup_field_handler = traceCreateScope('WatchGroup#field_handler()');
14+
var _WatchGroup_eval = traceCreateScope('WatchGroup#eval()');
15+
var _WatchGroup_reaction = traceCreateScope('WatchGroup#reaction()');
16+
1017
/**
1118
* A function that is notified of changes to the model.
1219
*
@@ -392,23 +399,29 @@ class RootWatchGroup extends WatchGroup {
392399
AvgStopwatch evalStopwatch,
393400
AvgStopwatch processStopwatch}) {
394401
// Process the Records from the change detector
402+
var sDetect = traceEnter(_WatchGroup_detect);
403+
var s = traceEnter(_WatchGroup_fields);
395404
Iterator<Record<_Handler>> changedRecordIterator =
396405
(_changeDetector as ChangeDetector<_Handler>).collectChanges(
397406
exceptionHandler:exceptionHandler,
398407
stopwatch: fieldStopwatch);
408+
traceLeave(s);
399409
if (processStopwatch != null) processStopwatch.start();
410+
s = traceEnter(_WatchGroup_field_handler);
400411
while (changedRecordIterator.moveNext()) {
401412
var record = changedRecordIterator.current;
402413
if (changeLog != null) changeLog(record.handler.expression,
403414
record.currentValue,
404415
record.previousValue);
405416
record.handler.onChange(record);
406417
}
418+
traceLeave(s);
407419
if (processStopwatch != null) processStopwatch.stop();
408420

409421
if (evalStopwatch != null) evalStopwatch.start();
410422
// Process our own function evaluations
411423
_EvalWatchRecord evalRecord = _evalWatchHead;
424+
s = traceEnter(_WatchGroup_eval);
412425
int evalCount = 0;
413426
while (evalRecord != null) {
414427
try {
@@ -423,11 +436,15 @@ class RootWatchGroup extends WatchGroup {
423436
}
424437
evalRecord = evalRecord._nextEvalWatch;
425438
}
439+
440+
traceLeave(s);
441+
traceLeave(sDetect);
426442
if (evalStopwatch != null) evalStopwatch..stop()..increment(evalCount);
427443

428444
// Because the handler can forward changes between each other synchronously
429445
// We need to call reaction functions asynchronously. This processes the
430446
// asynchronous reaction function queue.
447+
s = traceEnter(_WatchGroup_reaction);
431448
int count = 0;
432449
if (processStopwatch != null) processStopwatch.start();
433450
Watch dirtyWatch = _dirtyWatchHead;
@@ -451,6 +468,7 @@ class RootWatchGroup extends WatchGroup {
451468
_dirtyWatchTail = null;
452469
root._removeCount = 0;
453470
}
471+
traceLeave(s);
454472
if (processStopwatch != null) processStopwatch..stop()..increment(count);
455473
return count;
456474
}

lib/core/module_internal.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import 'package:di/annotations.dart';
1111
import 'package:angular/core/parser/parser.dart';
1212
import 'package:angular/core/parser/lexer.dart';
1313
import 'package:angular/utils.dart';
14+
import 'package:angular/wtf.dart';
1415

1516
import 'package:angular/core/annotation_src.dart';
1617

lib/core/parser/dynamic_parser.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ library angular.core.parser.dynamic_parser;
33
import 'package:di/annotations.dart';
44
import 'package:angular/cache/module.dart';
55
import 'package:angular/core/annotation_src.dart' hide Formatter;
6-
import 'package:angular/core/module_internal.dart' show FormatterMap;
6+
import 'package:angular/core/formatter.dart' show FormatterMap;
77

88
import 'package:angular/core/parser/parser.dart';
99
import 'package:angular/core/parser/lexer.dart';

lib/core/parser/eval.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ library angular.core.parser.eval;
22

33
import 'package:angular/core/parser/syntax.dart' as syntax;
44
import 'package:angular/core/parser/utils.dart';
5-
import 'package:angular/core/module_internal.dart';
5+
import 'package:angular/core/formatter.dart' show FormatterMap;
66

77
export 'package:angular/core/parser/eval_access.dart';
88
export 'package:angular/core/parser/eval_calls.dart';

lib/core/parser/eval_access.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ library angular.core.parser.eval_access;
33
import 'package:angular/core/parser/parser.dart';
44
import 'package:angular/core/parser/syntax.dart' as syntax;
55
import 'package:angular/core/parser/utils.dart';
6-
import 'package:angular/core/module_internal.dart';
6+
import 'package:angular/core/formatter.dart' show FormatterMap;
77

88
class AccessScopeFast extends syntax.AccessScope with AccessFast {
99
final Getter getter;

lib/core/parser/eval_calls.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ library angular.core.parser.eval_calls;
33
import 'package:angular/core/parser/parser.dart';
44
import 'package:angular/core/parser/syntax.dart' as syntax;
55
import 'package:angular/core/parser/utils.dart';
6-
import 'package:angular/core/module_internal.dart';
6+
import 'package:angular/core/formatter.dart' show FormatterMap;
77

88

99
class CallScope extends syntax.CallScope {

lib/core/parser/syntax.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ library angular.core.parser.syntax;
33
import 'package:angular/core/parser/parser.dart' show LocalsWrapper;
44
import 'package:angular/core/parser/unparser.dart' show Unparser;
55
import 'package:angular/core/parser/utils.dart' show EvalError;
6-
import 'package:angular/core/module_internal.dart';
6+
import 'package:angular/core/formatter.dart' show FormatterMap;
77

88
abstract class Visitor {
99
visit(Expression expression) => expression.accept(this);

lib/core/parser/utils.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
library angular.core.parser.utils;
22

33
import 'package:angular/core/parser/syntax.dart' show Expression;
4-
import 'package:angular/core/module_internal.dart';
4+
import 'package:angular/core/formatter.dart' show FormatterMap;
55
export 'package:angular/utils.dart' show relaxFnApply, relaxFnArgs, toBool;
66

77
/// Marker for an uninitialized value.

lib/core/scope.dart

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,14 @@ part of angular.core_internal;
33
typedef EvalFunction0();
44
typedef EvalFunction1(context);
55

6+
var _Scope_apply = traceCreateScope('Scope#apply()');
7+
var _Scope_digest = traceCreateScope('Scope#digest()');
8+
var _Scope_flush = traceCreateScope('Scope#flush()');
9+
var _Scope_domWrite = traceCreateScope('Scope#domWrite()');
10+
var _Scope_domRead = traceCreateScope('Scope#domRead()');
11+
var _Scope_assert = traceCreateScope('Scope#assert()');
12+
var _Scope_runAsync = traceCreateScope('Scope#runAsync()');
13+
var _Scope_createChild = traceCreateScope('Scope#createChild()');
614
/**
715
* Injected into the listener function within [Scope.on] to provide event-specific details to the
816
* scope listener.
@@ -330,6 +338,7 @@ class Scope {
330338

331339
/// Creates a child [Scope] with the given [childContext]
332340
Scope createChild(Object childContext) {
341+
var s = traceEnter(_Scope_createChild);
333342
assert(isAttached);
334343
var child = new Scope(childContext, rootScope, this,
335344
_readWriteGroup.newGroup(childContext),
@@ -341,6 +350,7 @@ class Scope {
341350
child._prev = prev;
342351
if (prev == null) _childHead = child; else prev._next = child;
343352
_childTail = child;
353+
traceLeave(s);
344354
return child;
345355
}
346356

@@ -593,6 +603,7 @@ class RootScope extends Scope {
593603
final ScopeStats _scopeStats;
594604

595605
String _state;
606+
var _state_wtf_scope;
596607

597608
/**
598609
* While processing data bindings, Angular passes through multiple states. When testing or
@@ -735,6 +746,7 @@ class RootScope extends Scope {
735746
try {
736747
do {
737748
if (_domWriteHead != null) _stats.domWriteStart();
749+
var s = traceEnter(_Scope_domWrite);
738750
while (_domWriteHead != null) {
739751
try {
740752
_domWriteHead.fn();
@@ -744,6 +756,7 @@ class RootScope extends Scope {
744756
_domWriteHead = _domWriteHead._next;
745757
if (_domWriteHead == null) _stats.domWriteEnd();
746758
}
759+
traceLeave(s);
747760
_domWriteTail = null;
748761
if (runObservers) {
749762
runObservers = false;
@@ -753,6 +766,7 @@ class RootScope extends Scope {
753766
processStopwatch: _scopeStats.processStopwatch);
754767
}
755768
if (_domReadHead != null) _stats.domReadStart();
769+
s = traceEnter(_Scope_domRead);
756770
while (_domReadHead != null) {
757771
try {
758772
_domReadHead.fn();
@@ -763,6 +777,7 @@ class RootScope extends Scope {
763777
if (_domReadHead == null) _stats.domReadEnd();
764778
}
765779
_domReadTail = null;
780+
traceLeave(s);
766781
_runAsyncFns();
767782
} while (_domWriteHead != null || _domReadHead != null || _runAsyncHead != null);
768783
_stats.flushEnd();
@@ -808,6 +823,7 @@ class RootScope extends Scope {
808823
}
809824

810825
_runAsyncFns() {
826+
var s = traceEnter(_Scope_runAsync);
811827
var count = 0;
812828
while (_runAsyncHead != null) {
813829
try {
@@ -819,6 +835,7 @@ class RootScope extends Scope {
819835
_runAsyncHead = _runAsyncHead._next;
820836
}
821837
_runAsyncTail = null;
838+
traceLeave(s);
822839
return count;
823840
}
824841

@@ -846,6 +863,13 @@ class RootScope extends Scope {
846863
assert(isAttached);
847864
if (_state != from) throw "$_state already in progress can not enter $to.";
848865
_state = to;
866+
if (_state_wtf_scope != null) traceLeave(_state_wtf_scope);
867+
var wtfScope = null;
868+
if (to == STATE_APPLY) wtfScope = _Scope_apply;
869+
else if (to == STATE_DIGEST) wtfScope = _Scope_digest;
870+
else if (to == STATE_FLUSH) wtfScope = _Scope_flush;
871+
else if (to == STATE_FLUSH_ASSERT) wtfScope = _Scope_assert;
872+
_state_wtf_scope = wtfScope == null ? null : traceEnter(wtfScope);
849873
}
850874
}
851875

0 commit comments

Comments
 (0)