Index: sdk/lib/_internal/js_runtime/lib/js_helper.dart |
diff --git a/sdk/lib/_internal/js_runtime/lib/js_helper.dart b/sdk/lib/_internal/js_runtime/lib/js_helper.dart |
index fc1987ad7e412cd56933c16459bf4cf28ffb2bd6..f44f922f49644d4db51a5b253ee0f4c1d98e8024 100644 |
--- a/sdk/lib/_internal/js_runtime/lib/js_helper.dart |
+++ b/sdk/lib/_internal/js_runtime/lib/js_helper.dart |
@@ -3653,27 +3653,32 @@ Future<Null> loadDeferredLibrary(String loadId) { |
// list of hashes. These are stored in the app-global scope. |
var urisMap = JS_EMBEDDED_GLOBAL('', DEFERRED_LIBRARY_URIS); |
List<String> uris = JS('JSExtendableArray|Null', '#[#]', urisMap, loadId); |
+ if (uris == null) return new Future.value(null); |
+ |
var hashesMap = JS_EMBEDDED_GLOBAL('', DEFERRED_LIBRARY_HASHES); |
List<String> hashes = JS('JSExtendableArray|Null', '#[#]', hashesMap, loadId); |
- if (uris == null) return new Future.value(null); |
- // The indices into `uris` and `hashes` that we want to load. |
- List<int> indices = new List.generate(uris.length, (i) => i); |
+ |
+ List<String> urisToLoad = <String>[]; |
+ |
var isHunkLoaded = JS_EMBEDDED_GLOBAL('', IS_HUNK_LOADED); |
- var isHunkInitialized = JS_EMBEDDED_GLOBAL('', IS_HUNK_INITIALIZED); |
- // Filter away indices for hunks that have already been loaded. |
- List<int> indicesToLoad = indices |
- .where((int i) => !JS('bool', '#(#)', isHunkLoaded, hashes[i])) |
- .toList(); |
- return Future |
- .wait(indicesToLoad.map((int i) => _loadHunk(uris[i]))) |
- .then((_) { |
+ for (int i = 0; i < uris.length; ++i) { |
+ if (JS('bool', '#(#)', isHunkLoaded, hashes[i])) continue; |
+ urisToLoad.add(uris[i]); |
+ } |
+ |
+ return Future.wait(urisToLoad.map(_loadHunk)).then((_) { |
// Now all hunks have been loaded, we run the needed initializers. |
- List<int> indicesToInitialize = indices |
- .where((int i) => !JS('bool', '#(#)', isHunkInitialized, hashes[i])) |
- .toList(); // Load the needed hunks. |
- for (int i in indicesToInitialize) { |
- var initializer = JS_EMBEDDED_GLOBAL('', INITIALIZE_LOADED_HUNK); |
- JS('void', '#(#)', initializer, hashes[i]); |
+ var isHunkInitialized = JS_EMBEDDED_GLOBAL('', IS_HUNK_INITIALIZED); |
+ var initializer = JS_EMBEDDED_GLOBAL('', INITIALIZE_LOADED_HUNK); |
+ for (String hash in hashes) { |
+ // It is possible for a hash to be repeated. This happens when two |
+ // different parts both end up empty. Checking in the loop rather than |
+ // pre-filtering prevents duplicate hashes leading to duplicated |
+ // initializations. |
+ // TODO(29572): Merge small parts. |
+ // TODO(29635): Remove duplicate parts from tables and output files. |
+ if (JS('bool', '#(#)', isHunkInitialized, hash)) continue; |
+ JS('void', '#(#)', initializer, hash); |
} |
bool updated = _loadedLibraries.add(loadId); |
if (updated && deferredLoadHook != null) { |