Use UriCache to ensure there is only one instance of Uri for each string.

I tested this on rwf-materials/01-setting-up-your-environment

Short version:
1. 475060 less live objects.
2. 37.5 MB less heap usage.

Before:
[Analysis contexts: 35]
[time: 20575 ms]
  [4781 ms] Downloaded heap snapshot, 641.5832576751709 MB.
  [26763 ms] Created HeapSnapshotGraph.
  externalSize: 7168
  shallowSize: 1796013552
  Objects: 23954314
  [26764 ms] Created Analysis.
All objects.
size        count     class
--------    --------  --------
284017 kb   2194914   _OneByteString dart:core
269992 kb   2088293   _List dart:core
229846 kb   2066511   _Uint32List dart:typed_data
154248 kb   4935956   _GrowableList dart:core
 63042 kb   158891    _Uint8List dart:typed_data
 56224 kb   1199459   Reference package:analyzer/src/summary2/reference.dart
 42643 kb   682297    _InfoMethodDeclaration package:analyzer/src/summary2/informative_data.dart
 40358 kb   234812    PropertyAccessorElementImpl_ImplicitGetter package:analyzer/src/dart/element/element.dart
 38075 kb   203067    ConstFieldElementImpl package:analyzer/src/dart/element/element.dart
 34247 kb   438367    _SimpleUri dart:core
 32181 kb   686528    _InfoFormalParameter package:analyzer/src/summary2/informative_data.dart
 29730 kb   475686    _Closure dart:core
 27722 kb     6868    _TwoByteString dart:core
 25594 kb   409517    _Map dart:collection
 17778 kb    81273    ClassElementImpl package:analyzer/src/dart/element/element.dart
 16479 kb   411893    Context
 14672 kb    93903    LibraryImportElementImpl package:analyzer/src/dart/element/element.dart
 14074 kb    90077    ParameterElementImpl package:analyzer/src/dart/element/element.dart
 13316 kb   284078    _InfoFieldDeclaration package:analyzer/src/summary2/informative_data.dart
 12932 kb    19671    Instructions
--------    --------
1739370 kb  23741574

Instances of: _SimpleUri
size       count     class
--------   --------  --------
 34247 kb  438367    _SimpleUri dart:core

size       unique-size  count     class           data
--------   --------     --------  --------        --------
   313 kb       0 kb     10024    _OneByteString  dart:core
   189 kb       0 kb      4033    _OneByteString  package:flutter/foundation.dart
   100 kb       0 kb      2137    _OneByteString  package:flutter/widgets.dart
    76 kb       0 kb      1626    _OneByteString  package:flutter/rendering.dart
    68 kb       0 kb      2207    _OneByteString  dart:ui
    62 kb       0 kb      1994    _OneByteString  dart:async
    62 kb       0 kb      1989    _OneByteString  dart:math
    43 kb       0 kb       935    _OneByteString  package:flutter/services.dart
    43 kb       0 kb      1378    _OneByteString  theme.dart
    42 kb       0 kb       907    _OneByteString  package:flutter/gestures.dart
    39 kb       0 kb      1278    _OneByteString  framework.dart
    38 kb       0 kb      1243    _OneByteString  debug.dart
    29 kb       0 kb       466    _OneByteString  package:vector_math/vector_math_64.dart
    27 kb       0 kb       594    _OneByteString  package:flutter/scheduler.dart
    27 kb       0 kb       577    _OneByteString  package:meta/meta.dart
    25 kb       0 kb       549    _OneByteString  material_state.dart
    25 kb       0 kb       549    _OneByteString  material_localizations.dart
    25 kb       0 kb       822    _OneByteString  colors.dart
    23 kb       0 kb       510    _OneByteString  package:flutter/material.dart
    23 kb       0 kb       752    _OneByteString  basic.dart
--------   --------     --------
 11153 kb     258 kb    201628

After:
[Analysis contexts: 35]
[time: 20763 ms]
  [4711 ms] Downloaded heap snapshot, 620.3819370269775 MB.
  [25756 ms] Created HeapSnapshotGraph.
  externalSize: 5984
  shallowSize: 1758470480
  Objects: 23479254
  [25756 ms] Created Analysis.
All objects.
size        count     class
--------    --------  --------
278669 kb   2110355   _OneByteString dart:core
270129 kb   2088300   _List dart:core
229910 kb   2066512   _Uint32List dart:typed_data
154248 kb   4935956   _GrowableList dart:core
 63049 kb   159021    _Uint8List dart:typed_data
 56224 kb   1199459   Reference package:analyzer/src/summary2/reference.dart
 42643 kb   682297    _InfoMethodDeclaration package:analyzer/src/summary2/informative_data.dart
 40358 kb   234812    PropertyAccessorElementImpl_ImplicitGetter package:analyzer/src/dart/element/element.dart
 38075 kb   203067    ConstFieldElementImpl package:analyzer/src/dart/element/element.dart
 32181 kb   686528    _InfoFormalParameter package:analyzer/src/summary2/informative_data.dart
 29730 kb   475686    _Closure dart:core
 27722 kb     6868    _TwoByteString dart:core
 25594 kb   409517    _Map dart:collection
 17778 kb    81273    ClassElementImpl package:analyzer/src/dart/element/element.dart
 16479 kb   411893    Context
 14672 kb    93903    LibraryImportElementImpl package:analyzer/src/dart/element/element.dart
 14074 kb    90077    ParameterElementImpl package:analyzer/src/dart/element/element.dart
 13316 kb   284078    _InfoFieldDeclaration package:analyzer/src/summary2/informative_data.dart
 12937 kb    19673    Instructions
 11985 kb   191772    InterfaceTypeImpl package:analyzer/src/dart/element/type.dart
--------    --------
1700325 kb  23223116

Instances of: _SimpleUri
size       count     class
--------   --------  --------
   359 kb    4598    _SimpleUri dart:core

size       unique-size  count     class           data
--------   --------     --------  --------        --------
     0 kb       0 kb         1    _OneByteString  file:///Users/scheglov/dart/rwf-materials/01-setting-up-your-environment/project
     0 kb       0 kb         1    _OneByteString  file:///Users/scheglov/dart/rwf-materials/01-setting-up-your-environment/project
     0 kb       0 kb         1    _OneByteString  package:firebase_dynamic_links_platform_interface/src/platform_interface/platfor
     0 kb       0 kb         1    _OneByteString  package:infinite_scroll_pagination/src/widgets/helpers/default_status_indicators
     0 kb       0 kb         1    _OneByteString  package:infinite_scroll_pagination/src/widgets/helpers/default_status_indicators
     0 kb       0 kb         1    _OneByteString  package:infinite_scroll_pagination/src/widgets/helpers/default_status_indicators
     0 kb       0 kb         1    _OneByteString  package:firebase_remote_config_platform_interface/src/platform_interface/platfor
     0 kb       0 kb         1    _OneByteString  package:firebase_dynamic_links_platform_interface/src/method_channel/method_chan
     0 kb       0 kb         1    _OneByteString  package:firebase_core_platform_interface/src/platform_interface/platform_interfa
     0 kb       0 kb         1    _OneByteString  package:infinite_scroll_pagination/src/widgets/helpers/default_status_indicators
     0 kb       0 kb         1    _OneByteString  package:infinite_scroll_pagination/src/widgets/helpers/default_status_indicators
     0 kb       0 kb         1    _OneByteString  package:firebase_analytics_platform_interface/src/method_channel/method_channel_
     0 kb       0 kb         1    _OneByteString  package:firebase_remote_config_platform_interface/src/method_channel/method_chan
     0 kb       0 kb         1    _OneByteString  package:infinite_scroll_pagination/src/widgets/helpers/default_status_indicators
     0 kb       0 kb         1    _OneByteString  package:firebase_crashlytics_platform_interface/src/platform_interface/platform_
     0 kb       0 kb         1    _OneByteString  package:firebase_crashlytics_platform_interface/src/method_channel/method_channe
     0 kb       0 kb         1    _OneByteString  package:firebase_analytics_platform_interface/src/platform_interface/platform_in
     0 kb       0 kb         1    _OneByteString  package:firebase_dynamic_links_platform_interface/src/method_channel/utils/conve
     0 kb       0 kb         1    _OneByteString  package:infinite_scroll_pagination/src/widgets/helpers/default_status_indicators
     0 kb       0 kb         1    _OneByteString  package:firebase_core_platform_interface/src/platform_interface/platform_interfa
--------   --------     --------
   260 kb     260 kb      4598

Change-Id: I31e0c5ee979e360021bf65a532424f0bd19a0820
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/279450
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>

https://dart.googlesource.com/sdk/+/777ce9b3687cfb9398b2a280055c8b78ad742ecc
2 files changed
tree: 6235d94cb164734fc52a8f324f01d9846320e6be
  1. ci/
  2. tools/
  3. .gitignore
  4. commits.json
  5. DEPS
  6. README.md
README.md

Monorepo

A gclient solution for checking out Dart and Flutter source trees

Monorepo is:

  • Optimized for Tip-of-Tree testing: The Monorepo DEPS used to check out Dart and Flutter dependencies comes from the Flutter engine DEPS with updated dependencies from Dart.

Checking out Monorepo

With depot_tools installed and on your path, create a directory for your monorepo checkout and run these commands to create a gclient solution in that directory:

mkdir monorepo
cd monorepo
gclient config --unmanaged https://dart.googlesource.com/monorepo
gclient sync -D

This gives you a checkout in the monorepo directory that contains:

monorepo/
  DEPS - the DEPS used for this gclient checkout
  commits.json - the pinned commits for Dart, flutter/engine,
                 and flutter/flutter
  tools/ - scripts used to create monorepo DEPS
engine/src/ - the flutter/buildroot repo
    flutter/ - the flutter/engine repo
    out/ - the build directory, where Flutter engine builds are created
    third_party/ - Flutter dependencies checked out by DEPS
      dart/ - the Dart SDK checkout.
        third_party - Dart dependencies, also used by Flutter
flutter/ - the flutter/flutter repo

Building Flutter engine

Flutter's instructions for building the engine are at Compiling the engine

They can be followed closely, with a few changes:

  • Googlers working on Dart do not need to switch to Fuchsia's Goma RBE, except for Windows. The GOMA_DIR enviroment variable can just point to the .cipd_bin directory in a depot_tools installation, and just goma_ctl ensure_start is sufficient.
  • The --no-prebuilt-dart-sdk option has to be added to every gn command, so that the build is set up to build and use a local Dart SDK.
  • The --full-dart-sdk option must be added to gn for the host build target if you will be building web or desktop apps.

Example build commands that work on linux:

MONOREPO_PATH=$PWD
if [[ ! $PATH =~ (^|:)$MONOREPO_PATH/flutter/bin(:|$) ]]; then
  PATH=$MONOREPO_PATH/flutter/bin:$PATH
fi

export GOMA_DIR=$(dirname $(command -v gclient))/.cipd_bin
goma_ctl ensure_start

pushd engine/src
flutter/tools/gn --goma --no-prebuilt-dart-sdk --unoptimized --full-dart-sdk
autoninja -C out/host_debug_unopt
popd

Building Flutter apps

The Flutter commands used to build and run apps will use the locally built Flutter engine and Dart SDK, instead of the one downloaded by the Flutter tool, if the --local-engine option is provided.

For example, to build and run the Flutter spinning square sample on the web platform,

MONOREPO_PATH=$PWD
cd flutter/examples/layers
flutter --local-engine=host_debug_unopt \
  -d chrome run widgets/spinning_square.dart
cd $MONOREPO_PATH

To build for desktop, specify the desktop platform device in flutter run as -d macos or -d linux or -d windows. You may also need to run the command

flutter create --platforms=windows,macos,linux

on existing apps, such as sample apps. New apps created with flutter create already include these support files. Details of desktop support are at Desktop Support for Flutter

Testing

Tests in the Flutter source tree can be run with the flutter test command, run in the directory of a package containing tests. For example:

MONOREPO_PATH=$PWD
cd flutter/packages/flutter
flutter test --local-engine=host_debug_unopt
cd $MONOREPO_PATH

Troubleshooting

Please file an issue or email the dart-engprod team with any problems with or questions about using monorepo.

We will update this documentation to address them.

  • flutter commands may download the engine and Dart SDK files for the configured channel, even though they will be using the local engine and its SDK.

Windows

  • On Windows, gclient sync needs to be run in an administrator session, because some installed dependencies create symlinks.