OLD | NEW |
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 class JavaScriptItemCompilationContext extends ItemCompilationContext { | 7 class JavaScriptItemCompilationContext extends ItemCompilationContext { |
8 final Set<HInstruction> boundsChecked; | 8 final Set<HInstruction> boundsChecked; |
9 | 9 |
10 JavaScriptItemCompilationContext() | 10 JavaScriptItemCompilationContext() |
(...skipping 290 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
301 /// example, if [mustRetainMetadata] is true but there is no metadata in the | 301 /// example, if [mustRetainMetadata] is true but there is no metadata in the |
302 /// program, this variable will stil be false. | 302 /// program, this variable will stil be false. |
303 bool hasRetainedMetadata = false; | 303 bool hasRetainedMetadata = false; |
304 | 304 |
305 /// True if a call to preserveNames has been seen. | 305 /// True if a call to preserveNames has been seen. |
306 bool mustPreserveNames = false; | 306 bool mustPreserveNames = false; |
307 | 307 |
308 /// True if a call to disableTreeShaking has been seen. | 308 /// True if a call to disableTreeShaking has been seen. |
309 bool isTreeShakingDisabled = false; | 309 bool isTreeShakingDisabled = false; |
310 | 310 |
| 311 /// True if there isn't sufficient @MirrorsUsed data. |
| 312 bool hasInsufficientMirrorsUsed = false; |
| 313 |
311 /// List of instantiated types from metadata. If metadata must be preserved, | 314 /// List of instantiated types from metadata. If metadata must be preserved, |
312 /// these types must registered. | 315 /// these types must registered. |
313 final List<Dependency> metadataInstantiatedTypes = <Dependency>[]; | 316 final List<Dependency> metadataInstantiatedTypes = <Dependency>[]; |
314 | 317 |
315 /// List of elements used from metadata. If metadata must be preserved, | 318 /// List of elements used from metadata. If metadata must be preserved, |
316 /// these elements must be compiled. | 319 /// these elements must be compiled. |
317 final List<Element> metadataStaticUse = <Element>[]; | 320 final List<Element> metadataStaticUse = <Element>[]; |
318 | 321 |
319 /// List of tear-off functions referenced from metadata. If metadata must be | 322 /// List of tear-off functions referenced from metadata. If metadata must be |
320 /// preserved, these elements must be compiled. | 323 /// preserved, these elements must be compiled. |
(...skipping 1031 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1352 ClassElement get fixedListImplementation => jsFixedArrayClass; | 1355 ClassElement get fixedListImplementation => jsFixedArrayClass; |
1353 ClassElement get growableListImplementation => jsExtendableArrayClass; | 1356 ClassElement get growableListImplementation => jsExtendableArrayClass; |
1354 ClassElement get mapImplementation => mapLiteralClass; | 1357 ClassElement get mapImplementation => mapLiteralClass; |
1355 ClassElement get constMapImplementation => constMapLiteralClass; | 1358 ClassElement get constMapImplementation => constMapLiteralClass; |
1356 ClassElement get typeImplementation => typeLiteralClass; | 1359 ClassElement get typeImplementation => typeLiteralClass; |
1357 ClassElement get boolImplementation => jsBoolClass; | 1360 ClassElement get boolImplementation => jsBoolClass; |
1358 ClassElement get nullImplementation => jsNullClass; | 1361 ClassElement get nullImplementation => jsNullClass; |
1359 | 1362 |
1360 void registerStaticUse(Element element, Enqueuer enqueuer) { | 1363 void registerStaticUse(Element element, Enqueuer enqueuer) { |
1361 if (element == disableTreeShakingMarker) { | 1364 if (element == disableTreeShakingMarker) { |
1362 enqueuer.enqueueEverything(); | |
1363 if (isTreeShakingDisabled) return; | |
1364 compiler.disableTypeInferenceForMirrors = true; | 1365 compiler.disableTypeInferenceForMirrors = true; |
1365 isTreeShakingDisabled = true; | 1366 isTreeShakingDisabled = true; |
| 1367 enqueuer.enqueueEverything(); |
1366 } else if (element == preserveNamesMarker) { | 1368 } else if (element == preserveNamesMarker) { |
1367 if (mustPreserveNames) return; | 1369 if (mustPreserveNames) return; |
1368 mustPreserveNames = true; | 1370 mustPreserveNames = true; |
1369 compiler.log('Preserving names.'); | 1371 compiler.log('Preserving names.'); |
1370 } else if (element == preserveMetadataMarker) { | 1372 } else if (element == preserveMetadataMarker) { |
1371 if (mustRetainMetadata) return; | 1373 if (mustRetainMetadata) return; |
1372 compiler.log('Retaining metadata.'); | 1374 compiler.log('Retaining metadata.'); |
1373 mustRetainMetadata = true; | 1375 mustRetainMetadata = true; |
1374 for (LibraryElement library in compiler.libraries.values) { | 1376 for (LibraryElement library in compiler.libraries.values) { |
1375 if (retainMetadataOf(library)) { | 1377 if (retainMetadataOf(library)) { |
(...skipping 12 matching lines...) Expand all Loading... |
1388 metadataStaticUse.clear(); | 1390 metadataStaticUse.clear(); |
1389 for (Element e in metadataGetOfStaticFunction) { | 1391 for (Element e in metadataGetOfStaticFunction) { |
1390 registerMetadataGetOfStaticFunction(e); | 1392 registerMetadataGetOfStaticFunction(e); |
1391 } | 1393 } |
1392 metadataGetOfStaticFunction.clear(); | 1394 metadataGetOfStaticFunction.clear(); |
1393 } | 1395 } |
1394 } | 1396 } |
1395 | 1397 |
1396 /// Called when [:const Symbol(name):] is seen. | 1398 /// Called when [:const Symbol(name):] is seen. |
1397 void registerConstSymbol(String name, TreeElements elements) { | 1399 void registerConstSymbol(String name, TreeElements elements) { |
| 1400 symbolsUsed.add(name); |
1398 } | 1401 } |
1399 | 1402 |
1400 /// Called when [:new Symbol(...):] is seen. | 1403 /// Called when [:new Symbol(...):] is seen. |
1401 void registerNewSymbol(TreeElements elements) { | 1404 void registerNewSymbol(TreeElements elements) { |
1402 } | 1405 } |
1403 | 1406 |
1404 bool retainGetter(Element element) => isTreeShakingDisabled; | 1407 /// Should [element] (a getter) be retained for reflection? |
| 1408 bool shouldRetainGetter(Element element) => isNeededForReflection(element); |
1405 | 1409 |
1406 bool retainSetter(Element element) => isTreeShakingDisabled; | 1410 /// Should [element] (a setter) be retained for reflection? |
| 1411 bool shouldRetainSetter(Element element) => isNeededForReflection(element); |
1407 | 1412 |
1408 bool retainName(SourceString name) => mustPreserveNames; | 1413 /// Should [name] be retained for reflection? |
| 1414 bool shouldRetainName(SourceString name) { |
| 1415 if (hasInsufficientMirrorsUsed) return mustPreserveNames; |
| 1416 if (name == const SourceString('')) return false; |
| 1417 return symbolsUsed.contains(name.slowToString()); |
| 1418 } |
1409 | 1419 |
1410 bool get rememberLazies => isTreeShakingDisabled; | 1420 bool get rememberLazies => isTreeShakingDisabled; |
1411 | 1421 |
1412 bool retainMetadataOf(Element element) { | 1422 bool retainMetadataOf(Element element) { |
1413 if (mustRetainMetadata) { | 1423 if (mustRetainMetadata) { |
1414 // TODO(ahe): This is a little hacky, but I'll have to rewrite this when | 1424 // TODO(ahe): This is a little hacky, but I'll have to rewrite this when |
1415 // implementing @MirrorsUsed anyways. | 1425 // implementing @MirrorsUsed anyways. |
1416 compiler.constantHandler.compiledConstants.addAll( | 1426 compiler.constantHandler.compiledConstants.addAll( |
1417 compiler.metadataHandler.compiledConstants); | 1427 compiler.metadataHandler.compiledConstants); |
1418 compiler.metadataHandler.compiledConstants.clear(); | 1428 compiler.metadataHandler.compiledConstants.clear(); |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1453 if (mustRetainMetadata) { | 1463 if (mustRetainMetadata) { |
1454 compiler.constantHandler.registerGetOfStaticFunction(element); | 1464 compiler.constantHandler.registerGetOfStaticFunction(element); |
1455 } else { | 1465 } else { |
1456 metadataGetOfStaticFunction.add(element); | 1466 metadataGetOfStaticFunction.add(element); |
1457 } | 1467 } |
1458 } | 1468 } |
1459 | 1469 |
1460 void registerMirrorUsage(Set<String> symbols, | 1470 void registerMirrorUsage(Set<String> symbols, |
1461 Set<Element> targets, | 1471 Set<Element> targets, |
1462 Set<Element> metaTargets) { | 1472 Set<Element> metaTargets) { |
| 1473 if (symbols == null && targets == null && metaTargets == null) { |
| 1474 // The user didn't specify anything, or there are imports of |
| 1475 // 'dart:mirrors' without @MirrorsUsed. |
| 1476 hasInsufficientMirrorsUsed = true; |
| 1477 return; |
| 1478 } |
1463 if (symbols != null) symbolsUsed.addAll(symbols); | 1479 if (symbols != null) symbolsUsed.addAll(symbols); |
1464 if (targets != null) { | 1480 if (targets != null) { |
1465 for (Element target in targets) { | 1481 for (Element target in targets) { |
1466 if (target.isAbstractField()) { | 1482 if (target.isAbstractField()) { |
1467 AbstractFieldElement field = target; | 1483 AbstractFieldElement field = target; |
1468 targetsUsed.add(field.getter); | 1484 targetsUsed.add(field.getter); |
1469 targetsUsed.add(field.setter); | 1485 targetsUsed.add(field.setter); |
1470 } else { | 1486 } else { |
1471 targetsUsed.add(target); | 1487 targetsUsed.add(target); |
1472 } | 1488 } |
1473 } | 1489 } |
1474 } | 1490 } |
1475 if (metaTargets != null) metaTargetsUsed.addAll(metaTargets); | 1491 if (metaTargets != null) metaTargetsUsed.addAll(metaTargets); |
1476 } | 1492 } |
1477 | 1493 |
1478 bool isNeededForReflection(Element element) { | 1494 bool isNeededForReflection(Element element) { |
1479 // TODO(ahe): Implement this. | 1495 if (hasInsufficientMirrorsUsed) return isTreeShakingDisabled; |
1480 if (!metaTargetsUsed.isEmpty) return true; | 1496 /// Record the name of [element] in [symbolsUsed]. Return true for |
| 1497 /// convenience. |
| 1498 bool registerNameOf(Element element) { |
| 1499 symbolsUsed.add(element.name.slowToString()); |
| 1500 if (element.isConstructor()) { |
| 1501 symbolsUsed.add(element.getEnclosingClass().name.slowToString()); |
| 1502 } |
| 1503 return true; |
| 1504 } |
| 1505 |
| 1506 if (!metaTargetsUsed.isEmpty) { |
| 1507 // TODO(ahe): Implement this. |
| 1508 return registerNameOf(element); |
| 1509 } |
| 1510 |
1481 if (!targetsUsed.isEmpty) { | 1511 if (!targetsUsed.isEmpty) { |
1482 for (Element e = element; e != null; e = e.enclosingElement) { | 1512 for (Element e = element; e != null; e = e.enclosingElement) { |
1483 if (targetsUsed.contains(e)) return true; | 1513 if (targetsUsed.contains(e)) return registerNameOf(element); |
1484 } | 1514 } |
1485 } | 1515 } |
1486 return false; | 1516 return false; |
1487 } | 1517 } |
1488 } | 1518 } |
1489 | 1519 |
1490 /// Records that [type] is used by [user.element]. | 1520 /// Records that [type] is used by [user.element]. |
1491 class Dependency { | 1521 class Dependency { |
1492 final DartType type; | 1522 final DartType type; |
1493 final TreeElements user; | 1523 final TreeElements user; |
1494 | 1524 |
1495 const Dependency(this.type, this.user); | 1525 const Dependency(this.type, this.user); |
1496 } | 1526 } |
OLD | NEW |