diff --git a/lib/generate.js b/lib/generate.js index 862bee5..0e263ef 100644 --- a/lib/generate.js +++ b/lib/generate.js @@ -340,7 +340,7 @@ const resolveEntrySource = (entry, sourceMapCache, sourceCache) => { const url = entry.url; // source from `source-id.json` - const sourceData = sourceCache[url]; + const sourceData = sourceCache.get(url); if (sourceData) { entry.source = sourceData.source; return; @@ -424,7 +424,7 @@ const readCoverageData = async (dir, filename, entryFilter, sourceCache) => { }; const readSourceList = async (dir, sourceList) => { - const sourceCache = {}; + const sourceCache = new Map(); for (const filename of sourceList) { const content = await Util.readFile(path.resolve(dir, filename)); @@ -436,7 +436,7 @@ const readSourceList = async (dir, sourceList) => { continue; } if (json.url) { - sourceCache[json.url] = json; + sourceCache.set(json.url, json); } } @@ -476,16 +476,16 @@ const readFromDir = async (mcr, dir) => { const entryFilter = mcr.getEntryFilter(); - const results = []; for (const filename of coverageList) { const coverageData = await readCoverageData(dir, filename, entryFilter, sourceCache); if (coverageData) { - const res = await mcr.add(coverageData); - results.push(res); + await mcr.add(coverageData); } } - return results; + // GC + sourceCache.clear(); + }; module.exports = { diff --git a/lib/index.js b/lib/index.js index 5d945e7..7fe4c95 100644 --- a/lib/index.js +++ b/lib/index.js @@ -124,9 +124,8 @@ class CoverageReport { // add coverage from dir async addFromDir(dir) { const time_start = Date.now(); - const results = await readFromDir(this, dir); + await readFromDir(this, dir); Util.logTime(`added from dir: ${dir}`, time_start); - return results; } // generate report diff --git a/lib/utils/util.js b/lib/utils/util.js index 1d1de34..2fc35ec 100644 --- a/lib/utils/util.js +++ b/lib/utils/util.js @@ -3,6 +3,9 @@ const { writeFile, readFile } = require('fs/promises'); const path = require('path'); const os = require('os'); const crypto = require('crypto'); +const v8 = require('node:v8'); +const vm = require('node:vm'); + const EC = require('eight-colors'); const CG = require('console-grid'); const acornWalk = require('acorn-walk'); @@ -788,6 +791,15 @@ const Util = { return major1 - major2; }, + forceGC: () => { + if (!Util.expose_gc) { + v8.setFlagsFromString('--expose_gc'); + Util.expose_gc = true; + } + const gc = vm.runInNewContext('gc'); + gc(); + }, + // ========================================================================================== loggingLevels: { diff --git a/lib/v8/v8.js b/lib/v8/v8.js index 62839db..c46fdaf 100644 --- a/lib/v8/v8.js +++ b/lib/v8/v8.js @@ -164,7 +164,7 @@ const mergeCssRanges = (itemList) => { // ranges: [ {start, end} ] const ranges = dedupeFlatRanges(concatRanges); - resolve(ranges || []); + resolve(ranges); }); }; @@ -174,14 +174,19 @@ const mergeJsFunctions = async (itemList) => { }; const mergeV8DataList = async (dataList) => { - let allList = []; - dataList.forEach((d) => { - allList = allList.concat(d.data); + const allList = dataList.map((d) => d.data).flat(); + + // separate coverage and empty items + const coverageList = []; + const allEmptyList = []; + allList.forEach((it) => { + if (it.empty) { + allEmptyList.push(it); + } else { + coverageList.push(it); + } }); - // remove empty items - const coverageList = allList.filter((it) => !it.empty); - // connect all functions and ranges const itemMap = {}; const sourcePathMap = {}; @@ -215,7 +220,7 @@ const mergeV8DataList = async (dataList) => { // first time filter for empty, (not for sources) // empty and not in item map - const emptyList = allList.filter((it) => it.empty).filter((it) => { + const emptyList = allEmptyList.filter((it) => { if (itemMap[it.id]) { return false; } @@ -225,9 +230,10 @@ const mergeV8DataList = async (dataList) => { return true; }); - // empty list + merged list - const mergedList = emptyList.concat(Object.values(itemMap)); + // merged list + empty list + const mergedList = Object.values(itemMap).concat(emptyList); + // Util.forceGC(); return mergedList; }; @@ -254,6 +260,9 @@ const mergeV8Coverage = async (dataList, sourceCache, options) => { } + // GC + sourceCache.clear(); + return mergedList; };