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.
This commit is contained in:
Michael Howell 2024-01-08 12:00:40 -07:00
parent 0ee9cfd54d
commit e61be1bfae

View File

@ -2717,9 +2717,25 @@ ${item.displayPath}<span class="${type}">${name}</span>\
* @return {Array<FunctionSearchType>} * @return {Array<FunctionSearchType>}
*/ */
function buildItemSearchTypeAll(types, lowercasePaths) { 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<integer, Array<Functiontype>>}
*/
const EMPTY_BINDINGS_MAP = new Map();
/**
* Empty, immutable map used in item search types with no bindings.
*
* @type {Array<Functiontype>}
*/
const EMPTY_GENERICS_ARRAY = [];
/** /**
* Converts a single type. * Converts a single type.
* *
@ -2732,15 +2748,15 @@ ${item.displayPath}<span class="${type}">${name}</span>\
let pathIndex, generics, bindings; let pathIndex, generics, bindings;
if (typeof type === "number") { if (typeof type === "number") {
pathIndex = type; pathIndex = type;
generics = []; generics = EMPTY_GENERICS_ARRAY;
bindings = new Map(); bindings = EMPTY_BINDINGS_MAP;
} else { } else {
pathIndex = type[PATH_INDEX_DATA]; pathIndex = type[PATH_INDEX_DATA];
generics = buildItemSearchTypeAll( generics = buildItemSearchTypeAll(
type[GENERICS_DATA], type[GENERICS_DATA],
lowercasePaths lowercasePaths
); );
if (type.length > BINDINGS_DATA) { if (type.length > BINDINGS_DATA && type[BINDINGS_DATA].length > 0) {
bindings = new Map(type[BINDINGS_DATA].map(binding => { bindings = new Map(type[BINDINGS_DATA].map(binding => {
const [assocType, constraints] = binding; const [assocType, constraints] = binding;
// Associated type constructors are represented sloppily in rustdoc's // Associated type constructors are represented sloppily in rustdoc's
@ -2759,7 +2775,7 @@ ${item.displayPath}<span class="${type}">${name}</span>\
]; ];
})); }));
} else { } else {
bindings = new Map(); bindings = EMPTY_BINDINGS_MAP;
} }
} }
if (pathIndex < 0) { if (pathIndex < 0) {