js_runtime: loadDeferredLibrary: don't call initializer of repeated empty parts

Pre-filtering hunks to initialized ended up calling some initializations multiple times. This happened for empty parts, so was harmless after 4af03b1a65

Simplify logic to reduce use of corelib functions. There is no real need to be creating closures and calling all of List.generate, where, and map.

BUG=
R=sigmund@google.com

Review-Url: https://codereview.chromium.org/2893653005 .
This commit is contained in:
Stephen Adams 2017-05-18 14:16:40 -07:00
parent 9aafded095
commit 7983454299

View file

@ -3653,27 +3653,32 @@ Future<Null> loadDeferredLibrary(String loadId) {
// list of hashes. These are stored in the app-global scope. // list of hashes. These are stored in the app-global scope.
var urisMap = JS_EMBEDDED_GLOBAL('', DEFERRED_LIBRARY_URIS); var urisMap = JS_EMBEDDED_GLOBAL('', DEFERRED_LIBRARY_URIS);
List<String> uris = JS('JSExtendableArray|Null', '#[#]', urisMap, loadId); List<String> uris = JS('JSExtendableArray|Null', '#[#]', urisMap, loadId);
if (uris == null) return new Future.value(null);
var hashesMap = JS_EMBEDDED_GLOBAL('', DEFERRED_LIBRARY_HASHES); var hashesMap = JS_EMBEDDED_GLOBAL('', DEFERRED_LIBRARY_HASHES);
List<String> hashes = JS('JSExtendableArray|Null', '#[#]', hashesMap, loadId); 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<String> urisToLoad = <String>[];
List<int> indices = new List.generate(uris.length, (i) => i);
var isHunkLoaded = JS_EMBEDDED_GLOBAL('', IS_HUNK_LOADED); var isHunkLoaded = JS_EMBEDDED_GLOBAL('', IS_HUNK_LOADED);
var isHunkInitialized = JS_EMBEDDED_GLOBAL('', IS_HUNK_INITIALIZED); for (int i = 0; i < uris.length; ++i) {
// Filter away indices for hunks that have already been loaded. if (JS('bool', '#(#)', isHunkLoaded, hashes[i])) continue;
List<int> indicesToLoad = indices urisToLoad.add(uris[i]);
.where((int i) => !JS('bool', '#(#)', isHunkLoaded, hashes[i])) }
.toList();
return Future return Future.wait(urisToLoad.map(_loadHunk)).then((_) {
.wait(indicesToLoad.map((int i) => _loadHunk(uris[i])))
.then((_) {
// Now all hunks have been loaded, we run the needed initializers. // Now all hunks have been loaded, we run the needed initializers.
List<int> indicesToInitialize = indices var isHunkInitialized = JS_EMBEDDED_GLOBAL('', IS_HUNK_INITIALIZED);
.where((int i) => !JS('bool', '#(#)', isHunkInitialized, hashes[i])) var initializer = JS_EMBEDDED_GLOBAL('', INITIALIZE_LOADED_HUNK);
.toList(); // Load the needed hunks. for (String hash in hashes) {
for (int i in indicesToInitialize) { // It is possible for a hash to be repeated. This happens when two
var initializer = JS_EMBEDDED_GLOBAL('', INITIALIZE_LOADED_HUNK); // different parts both end up empty. Checking in the loop rather than
JS('void', '#(#)', initializer, hashes[i]); // 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); bool updated = _loadedLibraries.add(loadId);
if (updated && deferredLoadHook != null) { if (updated && deferredLoadHook != null) {