Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(158)

Side by Side Diff: pkg/compiler/lib/src/serialization/system.dart

Issue 1975153002: Support (de)serialization from command-line (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: Updated cf. comments. Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « pkg/compiler/lib/src/options.dart ('k') | pkg/compiler/lib/src/serialization/task.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 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. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 library dart2js.serialization_helper; 5 library dart2js.serialization_system;
6 6
7 import 'dart:async'; 7 import 'dart:async';
8 import 'dart:io'; 8 import '../commandline_options.dart';
9 import '../common.dart';
10 import '../common/backend_api.dart';
11 import '../common/names.dart';
12 import '../common/resolution.dart';
13 import '../compiler.dart';
14 import '../elements/elements.dart';
15 import '../io/source_file.dart';
16 import '../scanner/scanner.dart';
17 import '../script.dart';
18 import '../serialization/impact_serialization.dart';
19 import '../tokens/token.dart';
20 import '../universe/call_structure.dart';
21 import '../universe/world_impact.dart';
22 import '../universe/use.dart';
23 import 'json_serializer.dart';
24 import 'modelz.dart';
25 import 'resolved_ast_serialization.dart';
26 import 'serialization.dart';
27 import 'task.dart';
9 28
10 import 'package:compiler/src/commandline_options.dart'; 29 class DeserializerSystemImpl extends DeserializerSystem {
11 import 'package:compiler/src/common.dart';
12 import 'package:compiler/src/common/backend_api.dart';
13 import 'package:compiler/src/common/names.dart';
14 import 'package:compiler/src/common/resolution.dart';
15 import 'package:compiler/src/compiler.dart';
16 import 'package:compiler/src/elements/elements.dart';
17 import 'package:compiler/src/io/source_file.dart';
18 import 'package:compiler/src/scanner/scanner.dart';
19 import 'package:compiler/src/script.dart';
20 import 'package:compiler/src/serialization/impact_serialization.dart';
21 import 'package:compiler/src/serialization/json_serializer.dart';
22 import 'package:compiler/src/serialization/modelz.dart';
23 import 'package:compiler/src/serialization/resolved_ast_serialization.dart';
24 import 'package:compiler/src/serialization/serialization.dart';
25 import 'package:compiler/src/serialization/task.dart';
26 import 'package:compiler/src/tokens/token.dart';
27 import 'package:compiler/src/universe/call_structure.dart';
28 import 'package:compiler/src/universe/world_impact.dart';
29 import 'package:compiler/src/universe/use.dart';
30
31 import '../memory_compiler.dart';
32
33 class Arguments {
34 final String filename;
35 final int index;
36 final bool loadSerializedData;
37 final bool saveSerializedData;
38 final String serializedDataFileName;
39 final bool verbose;
40
41 const Arguments({
42 this.filename,
43 this.index,
44 this.loadSerializedData: false,
45 this.saveSerializedData: false,
46 this.serializedDataFileName: 'out.data',
47 this.verbose: false});
48
49 factory Arguments.from(List<String> arguments) {
50 String filename;
51 int index;
52 for (String arg in arguments) {
53 if (!arg.startsWith('-')) {
54 index = int.parse(arg);
55 if (index == null) {
56 filename = arg;
57 }
58 }
59 }
60 bool verbose = arguments.contains('-v');
61 bool loadSerializedData = arguments.contains('-l');
62 bool saveSerializedData = arguments.contains('-s');
63 return new Arguments(
64 filename: filename,
65 index: index,
66 verbose: verbose,
67 loadSerializedData: loadSerializedData,
68 saveSerializedData: saveSerializedData);
69 }
70 }
71
72
73 Future<String> serializeDartCore(
74 {Arguments arguments: const Arguments()}) async {
75 print('------------------------------------------------------------------');
76 print('serialize dart:core');
77 print('------------------------------------------------------------------');
78 String serializedData;
79 if (arguments.loadSerializedData) {
80 File file = new File(arguments.serializedDataFileName);
81 if (file.existsSync()) {
82 print('Loading data from $file');
83 serializedData = file.readAsStringSync();
84 }
85 }
86 if (serializedData == null) {
87 Compiler compiler = compilerFor(
88 options: [Flags.analyzeAll]);
89 compiler.serialization.supportSerialization = true;
90 await compiler.run(Uris.dart_core);
91 serializedData = serialize(
92 compiler,
93 compiler.libraryLoader.libraries)
94 .toText(const JsonSerializationEncoder());
95 if (arguments.saveSerializedData) {
96 File file = new File(arguments.serializedDataFileName);
97 print('Saving data to $file');
98 file.writeAsStringSync(serializedData);
99 }
100 }
101 return serializedData;
102 }
103
104 Serializer serialize(
105 Compiler compiler,
106 Iterable<LibraryElement> libraries) {
107 assert(compiler.serialization.supportSerialization);
108
109 Serializer serializer = new Serializer();
110 SerializerPlugin backendSerializer =
111 compiler.backend.serialization.serializer;
112 serializer.plugins.add(backendSerializer);
113 serializer.plugins.add(new ResolutionImpactSerializer(
114 compiler.resolution, backendSerializer));
115 serializer.plugins.add(new ResolvedAstSerializerPlugin(
116 compiler.resolution, backendSerializer));
117
118 for (LibraryElement library in libraries) {
119 serializer.serialize(library);
120 }
121 return serializer;
122 }
123
124 void deserialize(Compiler compiler,
125 String serializedData) {
126 Deserializer deserializer = new Deserializer.fromText(
127 new DeserializationContext(),
128 serializedData,
129 const JsonSerializationDecoder());
130 deserializer.plugins.add(compiler.backend.serialization.deserializer);
131 compiler.serialization.deserializer =
132 new _DeserializerSystem(
133 compiler,
134 deserializer,
135 compiler.backend.impactTransformer);
136 }
137
138
139 const String WORLD_IMPACT_TAG = 'worldImpact';
140
141 class ResolutionImpactSerializer extends SerializerPlugin {
142 final Resolution resolution;
143 final SerializerPlugin nativeDataSerializer;
144
145 ResolutionImpactSerializer(this.resolution, this.nativeDataSerializer);
146
147 @override
148 void onElement(Element element, ObjectEncoder createEncoder(String tag)) {
149 if (resolution.hasBeenResolved(element)) {
150 ResolutionImpact impact = resolution.getResolutionImpact(element);
151 ObjectEncoder encoder = createEncoder(WORLD_IMPACT_TAG);
152 new ImpactSerializer(element, encoder, nativeDataSerializer)
153 .serialize(impact);
154 }
155 }
156 }
157
158 class ResolutionImpactDeserializer extends DeserializerPlugin {
159 Map<Element, ResolutionImpact> impactMap = <Element, ResolutionImpact>{};
160 final DeserializerPlugin nativeDataDeserializer;
161
162 ResolutionImpactDeserializer(this.nativeDataDeserializer);
163
164 @override
165 void onElement(Element element, ObjectDecoder getDecoder(String tag)) {
166 ObjectDecoder decoder = getDecoder(WORLD_IMPACT_TAG);
167 if (decoder != null) {
168 impactMap[element] =
169 ImpactDeserializer.deserializeImpact(
170 element, decoder, nativeDataDeserializer);
171 }
172 }
173 }
174
175 class _DeserializerSystem extends DeserializerSystem {
176 final Compiler _compiler; 30 final Compiler _compiler;
177 final Deserializer _deserializer; 31 final Deserializer _deserializer;
178 final List<LibraryElement> deserializedLibraries = <LibraryElement>[]; 32 final List<LibraryElement> deserializedLibraries = <LibraryElement>[];
179 final ResolutionImpactDeserializer _resolutionImpactDeserializer; 33 final ResolutionImpactDeserializer _resolutionImpactDeserializer;
180 final ResolvedAstDeserializerPlugin _resolvedAstDeserializer; 34 final ResolvedAstDeserializerPlugin _resolvedAstDeserializer;
181 final ImpactTransformer _impactTransformer; 35 final ImpactTransformer _impactTransformer;
182 36
183 factory _DeserializerSystem( 37 factory DeserializerSystemImpl(Compiler compiler, Deserializer deserializer,
184 Compiler compiler,
185 Deserializer deserializer,
186 ImpactTransformer impactTransformer) { 38 ImpactTransformer impactTransformer) {
187 List<DeserializerPlugin> plugins = <DeserializerPlugin>[]; 39 List<DeserializerPlugin> plugins = <DeserializerPlugin>[];
188 DeserializerPlugin backendDeserializer = 40 DeserializerPlugin backendDeserializer =
189 compiler.backend.serialization.deserializer; 41 compiler.backend.serialization.deserializer;
190 deserializer.plugins.add(backendDeserializer); 42 deserializer.plugins.add(backendDeserializer);
191 ResolutionImpactDeserializer resolutionImpactDeserializer = 43 ResolutionImpactDeserializer resolutionImpactDeserializer =
192 new ResolutionImpactDeserializer(backendDeserializer); 44 new ResolutionImpactDeserializer(backendDeserializer);
193 deserializer.plugins.add(resolutionImpactDeserializer); 45 deserializer.plugins.add(resolutionImpactDeserializer);
194 ResolvedAstDeserializerPlugin resolvedAstDeserializer 46 ResolvedAstDeserializerPlugin resolvedAstDeserializer =
195 = new ResolvedAstDeserializerPlugin( 47 new ResolvedAstDeserializerPlugin(
196 compiler.parsingContext, backendDeserializer); 48 compiler.parsingContext, backendDeserializer);
197 deserializer.plugins.add(resolvedAstDeserializer); 49 deserializer.plugins.add(resolvedAstDeserializer);
198 return new _DeserializerSystem._( 50 return new DeserializerSystemImpl._(
199 compiler, 51 compiler,
200 deserializer, 52 deserializer,
201 impactTransformer, 53 impactTransformer,
202 resolutionImpactDeserializer, 54 resolutionImpactDeserializer,
203 resolvedAstDeserializer); 55 resolvedAstDeserializer);
204 } 56 }
205 57
206 _DeserializerSystem._( 58 DeserializerSystemImpl._(
207 this._compiler, 59 this._compiler,
208 this._deserializer, 60 this._deserializer,
209 this._impactTransformer, 61 this._impactTransformer,
210 this._resolutionImpactDeserializer, 62 this._resolutionImpactDeserializer,
211 this._resolvedAstDeserializer); 63 this._resolvedAstDeserializer);
212 64
213
214 @override 65 @override
215 Future<LibraryElement> readLibrary(Uri resolvedUri) { 66 Future<LibraryElement> readLibrary(Uri resolvedUri) {
216 LibraryElement library = _deserializer.lookupLibrary(resolvedUri); 67 LibraryElement library = _deserializer.lookupLibrary(resolvedUri);
217 if (library != null) { 68 if (library != null) {
218 deserializedLibraries.add(library); 69 deserializedLibraries.add(library);
219 return Future.forEach(library.compilationUnits, 70 return Future.forEach(library.compilationUnits,
220 (CompilationUnitElement compilationUnit) { 71 (CompilationUnitElement compilationUnit) {
221 ScriptZ script = compilationUnit.script; 72 ScriptZ script = compilationUnit.script;
222 return _compiler.readScript(script.readableUri) 73 return _compiler
74 .readScript(script.readableUri)
223 .then((Script newScript) { 75 .then((Script newScript) {
224 script.file = newScript.file; 76 script.file = newScript.file;
225 _resolvedAstDeserializer.sourceFiles[script.resourceUri] = 77 _resolvedAstDeserializer.sourceFiles[script.resourceUri] =
226 newScript.file; 78 newScript.file;
227 }); 79 });
228 }).then((_) => library); 80 }).then((_) => library);
229 } 81 }
230 return new Future<LibraryElement>.value(library); 82 return new Future<LibraryElement>.value(library);
231 } 83 }
232 84
233 // TODO(johnniwinther): Remove the need for this method. 85 // TODO(johnniwinther): Remove the need for this method.
234 @override 86 @override
235 bool hasResolvedAst(ExecutableElement element) { 87 bool hasResolvedAst(ExecutableElement element) {
236 return getResolvedAst(element) != null; 88 return getResolvedAst(element) != null;
237 } 89 }
238 90
239 @override 91 @override
240 ResolvedAst getResolvedAst(ExecutableElement element) { 92 ResolvedAst getResolvedAst(ExecutableElement element) {
241 return _resolvedAstDeserializer.getResolvedAst(element); 93 return _resolvedAstDeserializer.getResolvedAst(element);
242 } 94 }
243 95
244 @override 96 @override
245 bool hasResolutionImpact(Element element) { 97 bool hasResolutionImpact(Element element) {
246 if (element.isConstructor && 98 if (element.isConstructor &&
247 element.enclosingClass.isUnnamedMixinApplication) { 99 element.enclosingClass.isUnnamedMixinApplication) {
248 return true; 100 return true;
249 } 101 }
250 return _resolutionImpactDeserializer.impactMap.containsKey(element); 102 return _resolutionImpactDeserializer.impactMap.containsKey(element);
251 } 103 }
252 104
253 @override 105 @override
254 ResolutionImpact getResolutionImpact(Element element) { 106 ResolutionImpact getResolutionImpact(Element element) {
255 if (element.isConstructor && 107 if (element.isConstructor &&
256 element.enclosingClass.isUnnamedMixinApplication) { 108 element.enclosingClass.isUnnamedMixinApplication) {
257 ClassElement superclass = element.enclosingClass.superclass; 109 ClassElement superclass = element.enclosingClass.superclass;
258 ConstructorElement superclassConstructor = 110 ConstructorElement superclassConstructor =
259 superclass.lookupConstructor(element.name); 111 superclass.lookupConstructor(element.name);
260 assert(invariant(element, superclassConstructor != null, 112 assert(invariant(element, superclassConstructor != null,
261 message: "Superclass constructor '${element.name}' called from " 113 message: "Superclass constructor '${element.name}' called from "
262 "${element} not found in ${superclass}.")); 114 "${element} not found in ${superclass}."));
263 // TODO(johnniwinther): Compute callStructure. Currently not used. 115 // TODO(johnniwinther): Compute callStructure. Currently not used.
264 CallStructure callStructure; 116 CallStructure callStructure;
265 return _resolutionImpactDeserializer.impactMap.putIfAbsent(element, () { 117 return _resolutionImpactDeserializer.impactMap.putIfAbsent(element, () {
266 return new DeserializedResolutionImpact( 118 return new DeserializedResolutionImpact(staticUses: <StaticUse>[
267 staticUses: <StaticUse>[new StaticUse.superConstructorInvoke( 119 new StaticUse.superConstructorInvoke(
268 superclassConstructor, callStructure)]); 120 superclassConstructor, callStructure)
121 ]);
269 }); 122 });
270 } 123 }
271 return _resolutionImpactDeserializer.impactMap[element]; 124 return _resolutionImpactDeserializer.impactMap[element];
272 } 125 }
273 126
274 @override 127 @override
275 WorldImpact computeWorldImpact(Element element) { 128 WorldImpact computeWorldImpact(Element element) {
276 ResolutionImpact resolutionImpact = getResolutionImpact(element); 129 ResolutionImpact resolutionImpact = getResolutionImpact(element);
277 assert(invariant(element, resolutionImpact != null, 130 assert(invariant(element, resolutionImpact != null,
278 message: 'No impact found for $element (${element.library})')); 131 message: 'No impact found for $element (${element.library})'));
279 if (element is ExecutableElement) { 132 if (element is ExecutableElement) {
280 getResolvedAst(element); 133 getResolvedAst(element);
281 } 134 }
282 return _impactTransformer.transformResolutionImpact(resolutionImpact); 135 return _impactTransformer.transformResolutionImpact(resolutionImpact);
283 } 136 }
284 137
285 @override 138 @override
286 bool isDeserialized(Element element) { 139 bool isDeserialized(Element element) {
287 return deserializedLibraries.contains(element.library); 140 return deserializedLibraries.contains(element.library);
288 } 141 }
289 } 142 }
290 143
144 const String WORLD_IMPACT_TAG = 'worldImpact';
145
146 class ResolutionImpactSerializer extends SerializerPlugin {
147 final Resolution resolution;
148 final SerializerPlugin nativeDataSerializer;
149
150 ResolutionImpactSerializer(this.resolution, this.nativeDataSerializer);
151
152 @override
153 void onElement(Element element, ObjectEncoder createEncoder(String tag)) {
154 if (resolution.hasBeenResolved(element)) {
155 ResolutionImpact impact = resolution.getResolutionImpact(element);
156 ObjectEncoder encoder = createEncoder(WORLD_IMPACT_TAG);
157 new ImpactSerializer(element, encoder, nativeDataSerializer)
158 .serialize(impact);
159 }
160 }
161 }
162
163 class ResolutionImpactDeserializer extends DeserializerPlugin {
164 Map<Element, ResolutionImpact> impactMap = <Element, ResolutionImpact>{};
165 final DeserializerPlugin nativeDataDeserializer;
166
167 ResolutionImpactDeserializer(this.nativeDataDeserializer);
168
169 @override
170 void onElement(Element element, ObjectDecoder getDecoder(String tag)) {
171 ObjectDecoder decoder = getDecoder(WORLD_IMPACT_TAG);
172 if (decoder != null) {
173 impactMap[element] = ImpactDeserializer.deserializeImpact(
174 element, decoder, nativeDataDeserializer);
175 }
176 }
177 }
178
291 const String RESOLVED_AST_TAG = 'resolvedAst'; 179 const String RESOLVED_AST_TAG = 'resolvedAst';
292 180
293 class ResolvedAstSerializerPlugin extends SerializerPlugin { 181 class ResolvedAstSerializerPlugin extends SerializerPlugin {
294 final Resolution resolution; 182 final Resolution resolution;
295 final SerializerPlugin nativeDataSerializer; 183 final SerializerPlugin nativeDataSerializer;
296 184
297 ResolvedAstSerializerPlugin(this.resolution, this.nativeDataSerializer); 185 ResolvedAstSerializerPlugin(this.resolution, this.nativeDataSerializer);
298 186
299 @override 187 @override
300 void onElement(Element element, ObjectEncoder createEncoder(String tag)) { 188 void onElement(Element element, ObjectEncoder createEncoder(String tag)) {
301 assert(invariant(element, element.isDeclaration, 189 assert(invariant(element, element.isDeclaration,
302 message: "Element $element must be the declaration")); 190 message: "Element $element must be the declaration"));
303 if (element is MemberElement) { 191 if (element is MemberElement) {
304 assert(invariant(element, resolution.hasResolvedAst(element), 192 assert(invariant(element, resolution.hasResolvedAst(element),
305 message: "Element $element must have a resolved ast")); 193 message: "Element $element must have a resolved ast"));
306 ResolvedAst resolvedAst = resolution.getResolvedAst(element); 194 ResolvedAst resolvedAst = resolution.getResolvedAst(element);
307 ObjectEncoder objectEncoder = createEncoder(RESOLVED_AST_TAG); 195 ObjectEncoder objectEncoder = createEncoder(RESOLVED_AST_TAG);
308 new ResolvedAstSerializer( 196 new ResolvedAstSerializer(
309 objectEncoder, 197 objectEncoder, resolvedAst, nativeDataSerializer)
310 resolvedAst, 198 .serialize();
311 nativeDataSerializer).serialize();
312 } 199 }
313 } 200 }
314 } 201 }
315 202
316 class ResolvedAstDeserializerPlugin extends DeserializerPlugin { 203 class ResolvedAstDeserializerPlugin extends DeserializerPlugin {
317 final ParsingContext parsingContext; 204 final ParsingContext parsingContext;
318 final DeserializerPlugin nativeDataDeserializer; 205 final DeserializerPlugin nativeDataDeserializer;
319 final Map<Uri, SourceFile> sourceFiles = <Uri, SourceFile>{}; 206 final Map<Uri, SourceFile> sourceFiles = <Uri, SourceFile>{};
320 207
321 Map<MemberElement, ObjectDecoder> _decoderMap = 208 Map<MemberElement, ObjectDecoder> _decoderMap =
322 <MemberElement, ObjectDecoder>{}; 209 <MemberElement, ObjectDecoder>{};
323 Map<Uri, Token> beginTokenMap = <Uri, Token>{}; 210 Map<Uri, Token> beginTokenMap = <Uri, Token>{};
324 211
325 ResolvedAstDeserializerPlugin( 212 ResolvedAstDeserializerPlugin(
326 this.parsingContext, this.nativeDataDeserializer); 213 this.parsingContext, this.nativeDataDeserializer);
327 214
328 bool hasResolvedAst(ExecutableElement element) { 215 bool hasResolvedAst(ExecutableElement element) {
329 return getResolvedAst(element) != null; 216 return getResolvedAst(element) != null;
330 } 217 }
331 218
332 ResolvedAst getResolvedAst(ExecutableElement element) { 219 ResolvedAst getResolvedAst(ExecutableElement element) {
333 if (element.hasResolvedAst) { 220 if (element.hasResolvedAst) {
334 return element.resolvedAst; 221 return element.resolvedAst;
335 } 222 }
336 223
337 ObjectDecoder decoder = _decoderMap[element.memberContext]; 224 ObjectDecoder decoder = _decoderMap[element.memberContext];
338 if (decoder != null) { 225 if (decoder != null) {
339 ResolvedAstDeserializer.deserialize( 226 ResolvedAstDeserializer.deserialize(element.memberContext, decoder,
340 element.memberContext, decoder, parsingContext, findToken, 227 parsingContext, findToken, nativeDataDeserializer);
341 nativeDataDeserializer);
342 _decoderMap.remove(element); 228 _decoderMap.remove(element);
343 assert(invariant(element, element.hasResolvedAst, 229 assert(invariant(element, element.hasResolvedAst,
344 message: "ResolvedAst not computed for $element.")); 230 message: "ResolvedAst not computed for $element."));
345 return element.resolvedAst; 231 return element.resolvedAst;
346 } 232 }
347 return null; 233 return null;
348 } 234 }
349 235
350 Token findToken(Uri uri, int offset) { 236 Token findToken(Uri uri, int offset) {
351 Token beginToken = beginTokenMap.putIfAbsent(uri, () { 237 Token beginToken = beginTokenMap.putIfAbsent(uri, () {
352 SourceFile sourceFile = sourceFiles[uri]; 238 SourceFile sourceFile = sourceFiles[uri];
353 if (sourceFile == null) { 239 if (sourceFile == null) {
354 throw 'No source file found for $uri in:\n ' 240 throw 'No source file found for $uri in:\n '
355 '${sourceFiles.keys.join('\n ')}'; 241 '${sourceFiles.keys.join('\n ')}';
356 } 242 }
357 return new Scanner(sourceFile).tokenize(); 243 return new Scanner(sourceFile).tokenize();
358 }); 244 });
359 return ResolvedAstDeserializer.findTokenInStream(beginToken, offset); 245 return ResolvedAstDeserializer.findTokenInStream(beginToken, offset);
360 } 246 }
361 247
362 @override 248 @override
363 void onElement(Element element, ObjectDecoder getDecoder(String tag)) { 249 void onElement(Element element, ObjectDecoder getDecoder(String tag)) {
364 ObjectDecoder decoder = getDecoder(RESOLVED_AST_TAG); 250 ObjectDecoder decoder = getDecoder(RESOLVED_AST_TAG);
365 if (decoder != null) { 251 if (decoder != null) {
366 _decoderMap[element] = decoder; 252 _decoderMap[element] = decoder;
367 } 253 }
368 } 254 }
369 } 255 }
370
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/options.dart ('k') | pkg/compiler/lib/src/serialization/task.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698