From e61be1bfae982b991828d3edd64a0eaea8bc2d55 Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Mon, 8 Jan 2024 12:00:40 -0700 Subject: [PATCH] rustdoc-search: reuse empty map/array in function signatures Map is implemented as a pointer to a mutable object. Rustdoc never mutates function signatures after constructing them, but the JS engine doesn't know that. To save a bunch of memory, use a single immutable map for every decoded type object with no bindings or generics. --- src/librustdoc/html/static/js/search.js | 26 ++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/src/librustdoc/html/static/js/search.js b/src/librustdoc/html/static/js/search.js index a5e2bc1c7af..5bd375a86a7 100644 --- a/src/librustdoc/html/static/js/search.js +++ b/src/librustdoc/html/static/js/search.js @@ -2717,9 +2717,25 @@ ${item.displayPath}${name}\ * @return {Array} */ function buildItemSearchTypeAll(types, lowercasePaths) { - return types.map(type => buildItemSearchType(type, lowercasePaths)); + return types.length > 0 ? + types.map(type => buildItemSearchType(type, lowercasePaths)) : + EMPTY_GENERICS_ARRAY; } + /** + * Empty, immutable map used in item search types with no bindings. + * + * @type {Map>} + */ + const EMPTY_BINDINGS_MAP = new Map(); + + /** + * Empty, immutable map used in item search types with no bindings. + * + * @type {Array} + */ + const EMPTY_GENERICS_ARRAY = []; + /** * Converts a single type. * @@ -2732,15 +2748,15 @@ ${item.displayPath}${name}\ let pathIndex, generics, bindings; if (typeof type === "number") { pathIndex = type; - generics = []; - bindings = new Map(); + generics = EMPTY_GENERICS_ARRAY; + bindings = EMPTY_BINDINGS_MAP; } else { pathIndex = type[PATH_INDEX_DATA]; generics = buildItemSearchTypeAll( type[GENERICS_DATA], lowercasePaths ); - if (type.length > BINDINGS_DATA) { + if (type.length > BINDINGS_DATA && type[BINDINGS_DATA].length > 0) { bindings = new Map(type[BINDINGS_DATA].map(binding => { const [assocType, constraints] = binding; // Associated type constructors are represented sloppily in rustdoc's @@ -2759,7 +2775,7 @@ ${item.displayPath}${name}\ ]; })); } else { - bindings = new Map(); + bindings = EMPTY_BINDINGS_MAP; } } if (pathIndex < 0) {