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

Commit 6aa7407

Browse files
jensjohacommit-bot@chromium.org
authored andcommitted
[CFE] Proof of concept of using vm service to find leaks
Use the VM service to find leaks in the incremental compiler via the incremental compiler test suite. Currently the following tests leak: incremental_load_from_dill/no_outline_change_2 incremental_load_from_dill/no_outline_change_6 incremental_load_from_dill/no_outline_change_7 incremental_load_from_dill/no_outline_change_10 incremental_load_from_dill/no_outline_change_34 Change-Id: Ie05ad5994f518422c553dc52bd57908ebbf1b16b Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/132283 Commit-Queue: Jens Johansen <jensj@google.com> Reviewed-by: Johnni Winther <johnniwinther@google.com>
1 parent ef7ae27 commit 6aa7407

File tree

7 files changed

+681
-2
lines changed

7 files changed

+681
-2
lines changed

pkg/front_end/lib/src/fasta/incremental_compiler.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -432,6 +432,7 @@ class IncrementalCompiler implements IncrementalKernelGenerator {
432432
hierarchy.applyTreeChanges(removedLibraries, const []);
433433
}
434434
notReusedLibraries = null;
435+
directlyInvalidated = null;
435436

436437
if (userCode != null) {
437438
ticker.logMs("Decided to reuse ${reusedLibraries.length}"

pkg/front_end/pubspec.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,3 +24,5 @@ dev_dependencies:
2424
test_reflective_loader: ^0.1.0
2525
web_socket_channel: ^1.0.4
2626
yaml: '^2.1.12'
27+
vm_service:
28+
path: ../vm_service
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
import 'dart:collection';
6+
7+
/// Dijkstra's algorithm for single source shortest path.
8+
///
9+
/// Adopted from https://en.wikipedia.org/wiki/Dijkstra%27s_algorithm#Pseudocode
10+
///
11+
/// Note that this is not an optimal implementation in that it uses a
12+
/// (Splay) Tree as the priority queue which takes O(log n) time to (fake) a
13+
/// decrease of priority whereas e.g. a fibonacci heap would have done it in
14+
/// (amortized) O(1).
15+
class DijkstrasAlgorithm<E> {
16+
Map<GraphNode<E>, int> dist = new Map<GraphNode<E>, int>();
17+
Map<GraphNode<E>, GraphNode<E>> prev = new Map<GraphNode<E>, GraphNode<E>>();
18+
19+
DijkstrasAlgorithm(Iterable<GraphNode<E>> graphNodes, GraphNode<E> source,
20+
int Function(E, E) comparator, int Function(E, E) distance) {
21+
SplayTreeSet<GraphNode<E>> q = new SplayTreeSet<GraphNode<E>>((a, b) {
22+
int distA = dist[a];
23+
int distB = dist[b];
24+
25+
int when0() {
26+
if (identical(a, b)) return 0;
27+
int result = comparator(a.node, b.node);
28+
if (result == 0) {
29+
throw "The nodes ${b.node} and ${a.node} are not the same but "
30+
"compares to the same. That's not allowed!";
31+
}
32+
return result;
33+
}
34+
35+
if (distA != null && distB == null) return -1;
36+
if (distA == null && distB != null) return 1;
37+
if (distA == null && distB == null) {
38+
return when0();
39+
}
40+
if (distA < distB) return -1;
41+
if (distA > distB) return 1;
42+
return when0();
43+
});
44+
45+
dist[source] = 0;
46+
int index = 0;
47+
for (GraphNode<E> g in graphNodes) {
48+
// dist and prev not set, we see "null" as "infinity" and "undefined".
49+
if (!q.add(g)) {
50+
throw "Couldn't add ${g.node} (index $index).";
51+
}
52+
index++;
53+
}
54+
55+
while (q.isNotEmpty) {
56+
GraphNode<E> u = q.first;
57+
int distToU = dist[u];
58+
if (distToU == null) {
59+
// No path to any of the remaining ${q.length} nodes.
60+
break;
61+
}
62+
q.remove(u);
63+
for (GraphNode<E> v in u.outgoing) {
64+
// Wikipedia says "only v that are still in Q" but it shouldn't matter
65+
// --- the length via u would be longer.
66+
int distanceUToV = distance(u.node, v.node);
67+
if (distanceUToV < 0) throw "Got negative distance. That's not allowed";
68+
int alt = distToU + distanceUToV;
69+
int distToV = dist[v];
70+
if (distToV == null || alt < distToV) {
71+
// Decrease length (decrease priority in priority queue).
72+
q.remove(v);
73+
dist[v] = alt;
74+
prev[v] = u;
75+
q.add(v);
76+
}
77+
}
78+
}
79+
}
80+
81+
List<E> getPathFromTarget(GraphNode<E> source, GraphNode<E> target) {
82+
List<E> path = new List<E>();
83+
GraphNode<E> u = target;
84+
while (u == source || prev[u] != null) {
85+
path.add(u.node);
86+
u = prev[u];
87+
}
88+
return path.reversed.toList();
89+
}
90+
}
91+
92+
class GraphNode<E> {
93+
final E node;
94+
final Set<GraphNode<E>> outgoing = new Set<GraphNode<E>>();
95+
final Set<GraphNode<E>> incoming = new Set<GraphNode<E>>();
96+
97+
GraphNode(this.node);
98+
99+
void addOutgoing(GraphNode<E> other) {
100+
if (outgoing.add(other)) {
101+
other.incoming.add(this);
102+
}
103+
}
104+
105+
String toString() {
106+
return "GraphNode[$node]";
107+
}
108+
}

pkg/front_end/test/incremental_load_from_dill_suite.dart

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44

55
import 'dart:async' show Future;
66

7+
import 'dart:developer' show debugger;
8+
79
import 'dart:io' show Directory, File;
810

911
import 'package:_fe_analyzer_shared/src/messages/diagnostic_message.dart'
@@ -82,7 +84,8 @@ Future<Context> createContext(
8284
// Disable colors to ensure that expectation files are the same across
8385
// platforms and independent of stdin/stderr.
8486
colors.enableColors = false;
85-
return new Context(environment["updateExpectations"] == "true");
87+
return new Context(environment["updateExpectations"] == "true",
88+
environment["addDebugBreaks"] == "true");
8689
}
8790

8891
class Context extends ChainContext {
@@ -92,7 +95,12 @@ class Context extends ChainContext {
9295
];
9396

9497
final bool updateExpectations;
95-
Context(this.updateExpectations);
98+
99+
/// Add a debug break (via dart:developers `debugger()` call) after each
100+
/// iteration (or 'world run') when doing a "new world test".
101+
final bool breakBetween;
102+
103+
Context(this.updateExpectations, this.breakBetween);
96104

97105
@override
98106
Future<void> cleanUp(TestDescription description, Result result) async {
@@ -775,6 +783,7 @@ Future<Null> newWorldTest(
775783
Component component3 = await compilerFromScratch.computeDelta(
776784
entryPoints: entries,
777785
simulateTransformer: world["simulateTransformer"]);
786+
compilerFromScratch = null;
778787
performErrorAndWarningCheck(
779788
world, gotError, formattedErrors, gotWarning, formattedWarnings);
780789
util.throwOnEmptyMixinBodies(component3);
@@ -809,6 +818,11 @@ Future<Null> newWorldTest(
809818
newestWholeComponentData = incrementalSerializationBytes;
810819
}
811820
}
821+
822+
if (context.breakBetween) {
823+
debugger();
824+
print("Continuing after debug break");
825+
}
812826
}
813827
}
814828

pkg/front_end/test/spell_checking_list_tests.txt

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,19 @@ aaa
1717
abc
1818
abcompile
1919
actions
20+
adopted
2021
affected
2122
albeit
2223
allocations
24+
alt
25+
amortized
2326
anon
2427
approval
2528
approximation
2629
asdf
2730
asserter
2831
auth
32+
authority
2933
auto
3034
autobianchi
3135
b0x
@@ -78,6 +82,7 @@ codepath
7882
collisions
7983
commit
8084
companion
85+
comparator
8186
comparer
8287
comparisons
8388
compilations
@@ -96,14 +101,17 @@ cov
96101
crashes
97102
cumulative
98103
dacoharkes
104+
dadd
99105
daemon
100106
dartanalyzer
101107
dartfile
102108
dashes
103109
day
104110
db
111+
decrease
105112
decrements
106113
def
114+
deleting
107115
depended
108116
depfile
109117
desc
@@ -112,6 +120,8 @@ dfast
112120
dictionaries
113121
dictionary
114122
differs
123+
dijkstra
124+
dijkstras
115125
dillfile
116126
dills
117127
dinteractive
@@ -121,6 +131,7 @@ disallowed
121131
disconnect
122132
discovering
123133
dispatcher
134+
dist
124135
doctype
125136
doesnt
126137
dog
@@ -174,6 +185,7 @@ func
174185
futures
175186
gallery
176187
gamma
188+
gc
177189
gen
178190
generators
179191
git
@@ -202,6 +214,7 @@ inclosure
202214
increased
203215
incrementally
204216
increments
217+
infinity
205218
inspect
206219
insufficient
207220
intact
@@ -258,28 +271,34 @@ observable
258271
observatory
259272
oh
260273
okay
274+
optimal
261275
oracle
276+
outbound
262277
overlay
263278
party
264279
pause
280+
paused
265281
periodic
266282
periodically
267283
person
268284
phrase
269285
pink
270286
places
287+
pointed
271288
policy
272289
portions
273290
pp
274291
preliminary
275292
prematurely
276293
pretends
277294
producer
295+
profile
278296
profiler
279297
promotes
280298
propagated
281299
protected
282300
provider
301+
pseudocode
283302
pubspec
284303
pv
285304
px
@@ -321,7 +340,9 @@ sdkroot
321340
sdks
322341
secondary
323342
segment
343+
severe
324344
shipped
345+
shortest
325346
shot
326347
signalled
327348
somehow
@@ -331,8 +352,10 @@ spellcheck
331352
spelled
332353
spelling
333354
spent
355+
splay
334356
splitting
335357
sqrt
358+
sssp
336359
std
337360
stdio
338361
strip
@@ -397,6 +420,7 @@ whitelist
397420
whitelisting
398421
wins
399422
workflow
423+
ws
400424
x's
401425
xxx
402426
y's
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import 'dart:io';
2+
3+
import "vm_service_heap_helper.dart" as helper;
4+
5+
main(List<String> args) async {
6+
List<helper.Interest> interests = new List<helper.Interest>();
7+
interests.add(new helper.Interest(
8+
Uri.parse(
9+
"package:front_end/src/fasta/source/source_library_builder.dart"),
10+
"SourceLibraryBuilder",
11+
["fileUri"]));
12+
interests.add(new helper.Interest(
13+
Uri.parse(
14+
"package:front_end/src/fasta/source/source_extension_builder.dart"),
15+
"SourceExtensionBuilder",
16+
["_extension"]));
17+
helper.VMServiceHeapHelper heapHelper = new helper.VMServiceHeapHelper(
18+
interests,
19+
[
20+
new helper.Interest(
21+
Uri.parse(
22+
"package:front_end/src/fasta/source/source_extension_builder.dart"),
23+
"SourceExtensionBuilder",
24+
["_extension"]),
25+
new helper.Interest(Uri.parse("package:kernel/ast.dart"), "Extension",
26+
["name", "fileUri"]),
27+
],
28+
false);
29+
heapHelper.start([
30+
Platform.script.resolve("incremental_load_from_dill_suite.dart").toString(),
31+
"-DaddDebugBreaks=true",
32+
// "--",
33+
// "incremental_load_from_dill/no_outline_change_34"
34+
// "incremental_load_from_dill/no_outline_change_10"
35+
"incremental_load_from_dill/deleting_file"
36+
// "incremental_load_from_dill/no_outline_change_2"
37+
// "incremental_load_from_dill/incremental_serialization_1"
38+
]);
39+
}

0 commit comments

Comments
 (0)