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

Side by Side Diff: pkg/compiler/lib/src/js_backend/backend.dart

Issue 962703004: Add "force inline" to internal annotations. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Address comments. Created 5 years, 9 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 | Annotate | Revision Log
« no previous file with comments | « no previous file | pkg/compiler/lib/src/ssa/builder.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) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, 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 part of js_backend; 5 part of js_backend;
6 6
7 const VERBOSE_OPTIMIZER_HINTS = false; 7 const VERBOSE_OPTIMIZER_HINTS = false;
8 8
9 const bool USE_CPS_IR = const bool.fromEnvironment("USE_CPS_IR"); 9 const bool USE_CPS_IR = const bool.fromEnvironment("USE_CPS_IR");
10 10
11 class JavaScriptItemCompilationContext extends ItemCompilationContext { 11 class JavaScriptItemCompilationContext extends ItemCompilationContext {
12 final Set<HInstruction> boundsChecked = new Set<HInstruction>(); 12 final Set<HInstruction> boundsChecked = new Set<HInstruction>();
13 final Set<HInstruction> allocatedFixedLists = new Set<HInstruction>(); 13 final Set<HInstruction> allocatedFixedLists = new Set<HInstruction>();
14 } 14 }
15 15
16 abstract class FunctionCompiler { 16 abstract class FunctionCompiler {
17 /// Generates JavaScript code for `work.element`. 17 /// Generates JavaScript code for `work.element`.
18 jsAst.Fun compile(CodegenWorkItem work); 18 jsAst.Fun compile(CodegenWorkItem work);
19 19
20 Iterable get tasks; 20 Iterable get tasks;
21 } 21 }
22 22
23 /* 23 /*
24 * Invariants: 24 * Invariants:
25 * canInline(function) implies canInline(function, insideLoop:true) 25 * canInline(function) implies canInline(function, insideLoop:true)
26 * !canInline(function, insideLoop: true) implies !canInline(function) 26 * !canInline(function, insideLoop: true) implies !canInline(function)
27 */ 27 */
28 class FunctionInlineCache { 28 class FunctionInlineCache {
29 final Map<FunctionElement, bool> canBeInlined = 29 static const int _unknown = -1;
30 new Map<FunctionElement, bool>(); 30 static const int _mustNotInline = 0;
31 // May-inline-in-loop means that the function may not be inlined outside loops
32 // but may be inlined in a loop.
33 static const int _mayInlineInLoopMustNotOutside = 1;
34 // The function can be inlined in a loop, but not outside.
35 static const int _canInlineInLoopMustNotOutside = 2;
36 // May-inline means that we know that it can be inlined inside a loop, but
37 // don't know about the general case yet.
38 static const int _canInlineInLoopMayInlineOutside = 3;
39 static const int _canInline = 4;
40 static const int _mustInline = 5;
31 41
32 final Map<FunctionElement, bool> canBeInlinedInsideLoop = 42 final Map<FunctionElement, int> _cachedDecisions =
33 new Map<FunctionElement, bool>(); 43 new Map<FunctionElement, int>();
34 44
35 // Returns [:true:]/[:false:] if we have a cached decision. 45 // Returns `true`/`false` if we have a cached decision.
36 // Returns [:null:] otherwise. 46 // Returns `null` otherwise.
37 bool canInline(FunctionElement element, {bool insideLoop}) { 47 bool canInline(FunctionElement element, {bool insideLoop}) {
38 return insideLoop ? canBeInlinedInsideLoop[element] : canBeInlined[element]; 48 int decision = _cachedDecisions[element];
49
50 if (decision == null) {
51 decision = _unknown;
52 }
53
54 if (insideLoop) {
55 switch (decision) {
56 case _mustNotInline:
57 return false;
58
59 case _unknown:
60 case _mayInlineInLoopMustNotOutside:
61 // We know we can't inline outside a loop, but don't know for the
62 // loop case. Return `null` to indicate that we don't know yet.
63 return null;
64
65 case _canInlineInLoopMustNotOutside:
66 case _canInlineInLoopMayInlineOutside:
67 case _canInline:
68 case _mustInline:
69 return true;
70 }
71 } else {
72 switch (decision) {
73 case _mustNotInline:
74 case _mayInlineInLoopMustNotOutside:
75 case _canInlineInLoopMustNotOutside:
76 return false;
77
78 case _unknown:
79 case _canInlineInLoopMayInlineOutside:
80 // We know we can inline inside a loop, but don't know for the
81 // non-loop case. Return `null` to indicate that we don't know yet.
82 return null;
83
84 case _canInline:
85 case _mustInline:
86 return true;
87 }
88 }
89
90 // Quiet static checker.
91 return null;
39 } 92 }
40 93
41 void markAsInlinable(FunctionElement element, {bool insideLoop}) { 94 void markAsInlinable(FunctionElement element, {bool insideLoop}) {
95 int oldDecision = _cachedDecisions[element];
96
97 if (oldDecision == null) {
98 oldDecision = _unknown;
99 }
100
42 if (insideLoop) { 101 if (insideLoop) {
43 canBeInlinedInsideLoop[element] = true; 102 switch (oldDecision) {
103 case _mustNotInline:
104 throw new SpannableAssertionFailure(element,
105 "Can't mark a function as non-inlinable and inlinable at the "
106 "same time.");
107
108 case _unknown:
109 // We know that it can be inlined in a loop, but don't know about the
110 // non-loop case yet.
111 _cachedDecisions[element] = _canInlineInLoopMayInlineOutside;
112 break;
113
114 case _mayInlineInLoopMustNotOutside:
115 _cachedDecisions[element] = _canInlineInLoopMustNotOutside;
116 break;
117
118 case _canInlineInLoopMustNotOutside:
119 case _canInlineInLoopMayInlineOutside:
120 case _canInline:
121 case _mustInline:
122 // Do nothing.
123 break;
124 }
44 } else { 125 } else {
45 // If we can inline a function outside a loop then we should do it inside 126 switch (oldDecision) {
46 // a loop as well. 127 case _mustNotInline:
47 canBeInlined[element] = true; 128 case _mayInlineInLoopMustNotOutside:
48 canBeInlinedInsideLoop[element] = true; 129 case _canInlineInLoopMustNotOutside:
130 throw new SpannableAssertionFailure(element,
131 "Can't mark a function as non-inlinable and inlinable at the "
132 "same time.");
133
134 case _unknown:
135 case _canInlineInLoopMayInlineOutside:
136 _cachedDecisions[element] = _canInline;
137 break;
138
139 case _canInline:
140 case _mustInline:
141 // Do nothing.
142 break;
143
144 }
49 } 145 }
50 } 146 }
51 147
52 void markAsNonInlinable(FunctionElement element, {bool insideLoop}) { 148 void markAsNonInlinable(FunctionElement element, {bool insideLoop: true}) {
53 if (insideLoop == null || insideLoop) { 149 int oldDecision = _cachedDecisions[element];
54 // If we can't inline a function inside a loop, then we should not inline 150
55 // it outside a loop either. 151 if (oldDecision == null) {
56 canBeInlined[element] = false; 152 oldDecision = _unknown;
57 canBeInlinedInsideLoop[element] = false; 153 }
154
155 if (insideLoop) {
156 switch (oldDecision) {
157 case _canInlineInLoopMustNotOutside:
158 case _canInlineInLoopMayInlineOutside:
159 case _canInline:
160 case _mustInline:
161 throw new SpannableAssertionFailure(element,
162 "Can't mark a function as non-inlinable and inlinable at the "
163 "same time.");
164
165 case _mayInlineInLoopMustNotOutside:
166 case _unknown:
167 _cachedDecisions[element] = _mustNotInline;
168 break;
169
170 case _mustNotInline:
171 // Do nothing.
172 break;
173 }
58 } else { 174 } else {
59 canBeInlined[element] = false; 175 switch (oldDecision) {
176 case _canInline:
177 case _mustInline:
178 throw new SpannableAssertionFailure(element,
179 "Can't mark a function as non-inlinable and inlinable at the "
180 "same time.");
181
182 case _unknown:
183 // We can't inline outside a loop, but we might still be allowed to do
184 // so outside.
185 _cachedDecisions[element] = _mayInlineInLoopMustNotOutside;
186 break;
187
188 case _canInlineInLoopMayInlineOutside:
189 // We already knew that the function could be inlined inside a loop,
190 // but didn't have information about the non-loop case. Now we know
191 // that it can't be inlined outside a loop.
192 _cachedDecisions[element] = _canInlineInLoopMustNotOutside;
193 break;
194
195 case _mayInlineInLoopMustNotOutside:
196 case _canInlineInLoopMustNotOutside:
197 case _mustNotInline:
198 // Do nothing.
199 break;
200 }
60 } 201 }
61 } 202 }
203
204 void markAsMustInline(FunctionElement element) {
205 _cachedDecisions[element] = _mustInline;
206 }
62 } 207 }
63 208
64 class JavaScriptBackend extends Backend { 209 class JavaScriptBackend extends Backend {
65 static final Uri DART_JS_HELPER = new Uri(scheme: 'dart', path: '_js_helper'); 210 static final Uri DART_JS_HELPER = new Uri(scheme: 'dart', path: '_js_helper');
66 static final Uri DART_INTERCEPTORS = 211 static final Uri DART_INTERCEPTORS =
67 new Uri(scheme: 'dart', path: '_interceptors'); 212 new Uri(scheme: 'dart', path: '_interceptors');
68 static final Uri DART_INTERNAL = 213 static final Uri DART_INTERNAL =
69 new Uri(scheme: 'dart', path: '_internal'); 214 new Uri(scheme: 'dart', path: '_internal');
70 static final Uri DART_FOREIGN_HELPER = 215 static final Uri DART_FOREIGN_HELPER =
71 new Uri(scheme: 'dart', path: '_foreign_helper'); 216 new Uri(scheme: 'dart', path: '_foreign_helper');
72 static final Uri DART_JS_MIRRORS = 217 static final Uri DART_JS_MIRRORS =
73 new Uri(scheme: 'dart', path: '_js_mirrors'); 218 new Uri(scheme: 'dart', path: '_js_mirrors');
74 static final Uri DART_JS_NAMES = 219 static final Uri DART_JS_NAMES =
75 new Uri(scheme: 'dart', path: '_js_names'); 220 new Uri(scheme: 'dart', path: '_js_names');
76 static final Uri DART_EMBEDDED_NAMES = 221 static final Uri DART_EMBEDDED_NAMES =
77 new Uri(scheme: 'dart', path: '_js_embedded_names'); 222 new Uri(scheme: 'dart', path: '_js_embedded_names');
78 static final Uri DART_ISOLATE_HELPER = 223 static final Uri DART_ISOLATE_HELPER =
79 new Uri(scheme: 'dart', path: '_isolate_helper'); 224 new Uri(scheme: 'dart', path: '_isolate_helper');
80 static final Uri DART_HTML = 225 static final Uri DART_HTML =
81 new Uri(scheme: 'dart', path: 'html'); 226 new Uri(scheme: 'dart', path: 'html');
82 227
83 static const String INVOKE_ON = '_getCachedInvocation'; 228 static const String INVOKE_ON = '_getCachedInvocation';
84 static const String START_ROOT_ISOLATE = 'startRootIsolate'; 229 static const String START_ROOT_ISOLATE = 'startRootIsolate';
85 230
86 231
87 /// The list of functions for classes in the [internalLibrary] that we want
88 /// to inline always. Any function in this list must be inlinable with
89 /// respect to the conditions used in [InlineWeeder.canInline], except for
90 /// size/complexity heuristics.
91 static const Map<String, List<String>> ALWAYS_INLINE =
92 const <String, List<String>> {
93 };
94
95 String get patchVersion => USE_NEW_EMITTER ? 'new' : 'old'; 232 String get patchVersion => USE_NEW_EMITTER ? 'new' : 'old';
96 233
97 final Annotations annotations = new Annotations(); 234 final Annotations annotations = new Annotations();
98 235
99 /// List of [FunctionElement]s that we want to inline always. This list is
100 /// filled when resolution is complete by looking up in [internalLibrary].
101 List<FunctionElement> functionsToAlwaysInline;
102
103 /// Reference to the internal library to lookup functions to always inline. 236 /// Reference to the internal library to lookup functions to always inline.
104 LibraryElement internalLibrary; 237 LibraryElement internalLibrary;
105 238
106 239
107 /// Set of classes that need to be considered for reflection although not 240 /// Set of classes that need to be considered for reflection although not
108 /// otherwise visible during resolution. 241 /// otherwise visible during resolution.
109 Iterable<ClassElement> get classesRequiredForReflection { 242 Iterable<ClassElement> get classesRequiredForReflection {
110 // TODO(herhut): Clean this up when classes needed for rti are tracked. 243 // TODO(herhut): Clean this up when classes needed for rti are tracked.
111 return [closureClass, jsIndexableClass]; 244 return [closureClass, jsIndexableClass];
112 } 245 }
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
167 ClassElement typeLiteralClass; 300 ClassElement typeLiteralClass;
168 ClassElement mapLiteralClass; 301 ClassElement mapLiteralClass;
169 ClassElement constMapLiteralClass; 302 ClassElement constMapLiteralClass;
170 ClassElement typeVariableClass; 303 ClassElement typeVariableClass;
171 ConstructorElement mapLiteralConstructor; 304 ConstructorElement mapLiteralConstructor;
172 ConstructorElement mapLiteralConstructorEmpty; 305 ConstructorElement mapLiteralConstructorEmpty;
173 306
174 ClassElement noSideEffectsClass; 307 ClassElement noSideEffectsClass;
175 ClassElement noThrowsClass; 308 ClassElement noThrowsClass;
176 ClassElement noInlineClass; 309 ClassElement noInlineClass;
310 ClassElement forceInlineClass;
177 ClassElement irRepresentationClass; 311 ClassElement irRepresentationClass;
178 312
179 Element getInterceptorMethod; 313 Element getInterceptorMethod;
180 314
181 ClassElement jsInvocationMirrorClass; 315 ClassElement jsInvocationMirrorClass;
182 316
183 /// If [true], the compiler will emit code that writes the name of the current 317 /// If [true], the compiler will emit code that writes the name of the current
184 /// method together with its class and library to the console the first time 318 /// method together with its class and library to the console the first time
185 /// the method is called. 319 /// the method is called.
186 static const bool TRACE_CALLS = false; 320 static const bool TRACE_CALLS = false;
(...skipping 767 matching lines...) Expand 10 before | Expand all | Expand 10 after
954 assert(traceHelper != null); 1088 assert(traceHelper != null);
955 enqueueInResolution(traceHelper, registry); 1089 enqueueInResolution(traceHelper, registry);
956 } 1090 }
957 registerCheckedModeHelpers(registry); 1091 registerCheckedModeHelpers(registry);
958 } 1092 }
959 1093
960 onResolutionComplete() { 1094 onResolutionComplete() {
961 super.onResolutionComplete(); 1095 super.onResolutionComplete();
962 computeMembersNeededForReflection(); 1096 computeMembersNeededForReflection();
963 rti.computeClassesNeedingRti(); 1097 rti.computeClassesNeedingRti();
964 computeFunctionsToAlwaysInline();
965 }
966
967 void computeFunctionsToAlwaysInline() {
968 functionsToAlwaysInline = <FunctionElement>[];
969 if (internalLibrary == null) return;
970
971 // Try to find all functions intended to always inline. If their enclosing
972 // class is not resolved we skip the methods, but it is an error to mention
973 // a function or class that cannot be found.
974 for (String className in ALWAYS_INLINE.keys) {
975 ClassElement cls = find(internalLibrary, className);
976 if (cls.resolutionState != STATE_DONE) continue;
977 for (String functionName in ALWAYS_INLINE[className]) {
978 Element function = cls.lookupMember(functionName);
979 assert(invariant(cls, function is FunctionElement,
980 message: 'unable to find function $functionName in $className'));
981 functionsToAlwaysInline.add(function);
982 }
983 }
984 } 1098 }
985 1099
986 void registerGetRuntimeTypeArgument(Registry registry) { 1100 void registerGetRuntimeTypeArgument(Registry registry) {
987 enqueueInResolution(getGetRuntimeTypeArgument(), registry); 1101 enqueueInResolution(getGetRuntimeTypeArgument(), registry);
988 enqueueInResolution(getGetTypeArgumentByIndex(), registry); 1102 enqueueInResolution(getGetTypeArgumentByIndex(), registry);
989 enqueueInResolution(getCopyTypeArguments(), registry); 1103 enqueueInResolution(getCopyTypeArguments(), registry);
990 } 1104 }
991 1105
992 void registerCallMethodWithFreeTypeVariables( 1106 void registerCallMethodWithFreeTypeVariables(
993 Element callMethod, 1107 Element callMethod,
(...skipping 868 matching lines...) Expand 10 before | Expand all | Expand 10 after
1862 1976
1863 typeLiteralClass = findClass('TypeImpl'); 1977 typeLiteralClass = findClass('TypeImpl');
1864 constMapLiteralClass = findClass('ConstantMap'); 1978 constMapLiteralClass = findClass('ConstantMap');
1865 typeVariableClass = findClass('TypeVariable'); 1979 typeVariableClass = findClass('TypeVariable');
1866 1980
1867 jsIndexingBehaviorInterface = findClass('JavaScriptIndexingBehavior'); 1981 jsIndexingBehaviorInterface = findClass('JavaScriptIndexingBehavior');
1868 1982
1869 noSideEffectsClass = findClass('NoSideEffects'); 1983 noSideEffectsClass = findClass('NoSideEffects');
1870 noThrowsClass = findClass('NoThrows'); 1984 noThrowsClass = findClass('NoThrows');
1871 noInlineClass = findClass('NoInline'); 1985 noInlineClass = findClass('NoInline');
1986 forceInlineClass = findClass('ForceInline');
1872 irRepresentationClass = findClass('IrRepresentation'); 1987 irRepresentationClass = findClass('IrRepresentation');
1873 1988
1874 getIsolateAffinityTagMarker = findMethod('getIsolateAffinityTag'); 1989 getIsolateAffinityTagMarker = findMethod('getIsolateAffinityTag');
1875 1990
1876 requiresPreambleMarker = findMethod('requiresPreamble'); 1991 requiresPreambleMarker = findMethod('requiresPreamble');
1877 } else if (uri == DART_JS_MIRRORS) { 1992 } else if (uri == DART_JS_MIRRORS) {
1878 disableTreeShakingMarker = find(library, 'disableTreeShaking'); 1993 disableTreeShakingMarker = find(library, 'disableTreeShaking');
1879 preserveMetadataMarker = find(library, 'preserveMetadata'); 1994 preserveMetadataMarker = find(library, 'preserveMetadata');
1880 preserveUrisMarker = find(library, 'preserveUris'); 1995 preserveUrisMarker = find(library, 'preserveUris');
1881 preserveLibraryNamesMarker = find(library, 'preserveLibraryNames'); 1996 preserveLibraryNamesMarker = find(library, 'preserveLibraryNames');
(...skipping 436 matching lines...) Expand 10 before | Expand all | Expand 10 after
2318 } 2433 }
2319 2434
2320 void onElementResolved(Element element, TreeElements elements) { 2435 void onElementResolved(Element element, TreeElements elements) {
2321 if (element.isFunction && annotations.noInline(element)) { 2436 if (element.isFunction && annotations.noInline(element)) {
2322 inlineCache.markAsNonInlinable(element); 2437 inlineCache.markAsNonInlinable(element);
2323 } 2438 }
2324 2439
2325 LibraryElement library = element.library; 2440 LibraryElement library = element.library;
2326 if (!library.isPlatformLibrary && !library.canUseNative) return; 2441 if (!library.isPlatformLibrary && !library.canUseNative) return;
2327 bool hasNoInline = false; 2442 bool hasNoInline = false;
2443 bool hasForceInline = false;
2328 bool hasNoThrows = false; 2444 bool hasNoThrows = false;
2329 bool hasNoSideEffects = false; 2445 bool hasNoSideEffects = false;
2330 for (MetadataAnnotation metadata in element.metadata) { 2446 for (MetadataAnnotation metadata in element.metadata) {
2331 metadata.ensureResolved(compiler); 2447 metadata.ensureResolved(compiler);
2332 if (!metadata.constant.value.isConstructedObject) continue; 2448 if (!metadata.constant.value.isConstructedObject) continue;
2333 ObjectConstantValue value = metadata.constant.value; 2449 ObjectConstantValue value = metadata.constant.value;
2334 ClassElement cls = value.type.element; 2450 ClassElement cls = value.type.element;
2335 if (cls == noInlineClass) { 2451 if (cls == forceInlineClass) {
2452 hasForceInline = true;
2453 if (VERBOSE_OPTIMIZER_HINTS) {
2454 compiler.reportHint(element,
2455 MessageKind.GENERIC,
2456 {'text': "Must inline"});
2457 }
2458 inlineCache.markAsMustInline(element);
2459 } else if (cls == noInlineClass) {
2336 hasNoInline = true; 2460 hasNoInline = true;
2337 if (VERBOSE_OPTIMIZER_HINTS) { 2461 if (VERBOSE_OPTIMIZER_HINTS) {
2338 compiler.reportHint(element, 2462 compiler.reportHint(element,
2339 MessageKind.GENERIC, 2463 MessageKind.GENERIC,
2340 {'text': "Cannot inline"}); 2464 {'text': "Cannot inline"});
2341 } 2465 }
2342 inlineCache.markAsNonInlinable(element); 2466 inlineCache.markAsNonInlinable(element);
2343 } else if (cls == noThrowsClass) { 2467 } else if (cls == noThrowsClass) {
2344 hasNoThrows = true; 2468 hasNoThrows = true;
2345 if (!Elements.isStaticOrTopLevelFunction(element)) { 2469 if (!Elements.isStaticOrTopLevelFunction(element)) {
(...skipping 10 matching lines...) Expand all
2356 } else if (cls == noSideEffectsClass) { 2480 } else if (cls == noSideEffectsClass) {
2357 hasNoSideEffects = true; 2481 hasNoSideEffects = true;
2358 if (VERBOSE_OPTIMIZER_HINTS) { 2482 if (VERBOSE_OPTIMIZER_HINTS) {
2359 compiler.reportHint(element, 2483 compiler.reportHint(element,
2360 MessageKind.GENERIC, 2484 MessageKind.GENERIC,
2361 {'text': "Has no side effects"}); 2485 {'text': "Has no side effects"});
2362 } 2486 }
2363 compiler.world.registerSideEffectsFree(element); 2487 compiler.world.registerSideEffectsFree(element);
2364 } 2488 }
2365 } 2489 }
2490 if (hasForceInline && hasNoInline) {
2491 compiler.internalError(element,
2492 "@ForceInline() must not be used with @NoInline.");
2493 }
2366 if (hasNoThrows && !hasNoInline) { 2494 if (hasNoThrows && !hasNoInline) {
2367 compiler.internalError(element, 2495 compiler.internalError(element,
2368 "@NoThrows() should always be combined with @NoInline."); 2496 "@NoThrows() should always be combined with @NoInline.");
2369 } 2497 }
2370 if (hasNoSideEffects && !hasNoInline) { 2498 if (hasNoSideEffects && !hasNoInline) {
2371 compiler.internalError(element, 2499 compiler.internalError(element,
2372 "@NoSideEffects() should always be combined with @NoInline."); 2500 "@NoSideEffects() should always be combined with @NoInline.");
2373 } 2501 }
2374 if (element == invokeOnMethod) { 2502 if (element == invokeOnMethod) {
2375 compiler.enabledInvokeOn = true; 2503 compiler.enabledInvokeOn = true;
(...skipping 330 matching lines...) Expand 10 before | Expand all | Expand 10 after
2706 } 2834 }
2707 } 2835 }
2708 2836
2709 /// Records that [constant] is used by the element behind [registry]. 2837 /// Records that [constant] is used by the element behind [registry].
2710 class Dependency { 2838 class Dependency {
2711 final ConstantValue constant; 2839 final ConstantValue constant;
2712 final Element annotatedElement; 2840 final Element annotatedElement;
2713 2841
2714 const Dependency(this.constant, this.annotatedElement); 2842 const Dependency(this.constant, this.annotatedElement);
2715 } 2843 }
OLDNEW
« no previous file with comments | « no previous file | pkg/compiler/lib/src/ssa/builder.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698