Skip to content

Commit 5b92678

Browse files
authored
Optimize sourcemap application more (microsoft#25425)
* Optimize sourcemap application more * Remove test-only memory hog sourceMapDecodedMappings field * Update for style, remove unused function that triggers warnings in node 10 * Avoid all raw buffer constructor calls * Small TDZ fix
1 parent 065e695 commit 5b92678

File tree

11 files changed

+37
-50
lines changed

11 files changed

+37
-50
lines changed

src/compiler/sourcemap.ts

Lines changed: 29 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,6 @@ namespace ts {
156156
sourceMapNames: [],
157157
sourceMapMappings: "",
158158
sourceMapSourcesContent: compilerOptions.inlineSources ? [] : undefined,
159-
sourceMapDecodedMappings: []
160159
};
161160

162161
// Normalize source root and make sure it has trailing "/" so that it can be used to combine paths with the
@@ -299,7 +298,6 @@ namespace ts {
299298
}
300299

301300
lastEncodedSourceMapSpan = lastRecordedSourceMapSpan;
302-
sourceMapData.sourceMapDecodedMappings.push(lastEncodedSourceMapSpan);
303301
}
304302

305303
/**
@@ -393,24 +391,29 @@ namespace ts {
393391

394392
const sourcesDirectoryPath = compilerOptions.sourceRoot ? host.getCommonSourceDirectory() : sourceMapDir;
395393
const resolvedPathCache = createMap<string>();
396-
sourcemaps.calculateDecodedMappings(originalMap, (raw): void => {
394+
const absolutePathCache = createMap<string>();
395+
const sourcemapIterator = sourcemaps.decodeMappings(originalMap);
396+
for (let { value: raw, done } = sourcemapIterator.next(); !done; { value: raw, done } = sourcemapIterator.next()) {
397+
const pathCacheKey = "" + raw.sourceIndex;
397398
// Apply offsets to each position and fixup source entries
398-
const rawPath = originalMap.sources[raw.sourceIndex];
399-
const relativePath = originalMap.sourceRoot ? combinePaths(originalMap.sourceRoot, rawPath) : rawPath;
400-
const combinedPath = combinePaths(getDirectoryPath(node.sourceMapPath!), relativePath);
401-
if (!resolvedPathCache.has(combinedPath)) {
402-
resolvedPathCache.set(combinedPath, getRelativePathToDirectoryOrUrl(
399+
if (!resolvedPathCache.has(pathCacheKey)) {
400+
const rawPath = originalMap.sources[raw.sourceIndex];
401+
const relativePath = originalMap.sourceRoot ? combinePaths(originalMap.sourceRoot, rawPath) : rawPath;
402+
const combinedPath = combinePaths(getDirectoryPath(node.sourceMapPath!), relativePath);
403+
const resolvedPath = getRelativePathToDirectoryOrUrl(
403404
sourcesDirectoryPath,
404405
combinedPath,
405406
host.getCurrentDirectory(),
406407
host.getCanonicalFileName,
407408
/*isAbsolutePathAnUrl*/ true
408-
));
409+
);
410+
resolvedPathCache.set(pathCacheKey, resolvedPath);
411+
absolutePathCache.set(pathCacheKey, getNormalizedAbsolutePath(resolvedPath, sourcesDirectoryPath));
409412
}
410-
const resolvedPath = resolvedPathCache.get(combinedPath)!;
411-
const absolutePath = getNormalizedAbsolutePath(resolvedPath, sourcesDirectoryPath);
413+
const resolvedPath = resolvedPathCache.get(pathCacheKey)!;
414+
const absolutePath = absolutePathCache.get(pathCacheKey)!;
412415
// tslint:disable-next-line:no-null-keyword
413-
setupSourceEntry(absolutePath, originalMap.sourcesContent ? originalMap.sourcesContent[raw.sourceIndex] : null); // TODO: Lookup content for inlining?
416+
setupSourceEntry(absolutePath, originalMap.sourcesContent ? originalMap.sourcesContent[raw.sourceIndex] : null, resolvedPath); // TODO: Lookup content for inlining?
414417
const newIndex = sourceMapData.sourceMapSources.indexOf(resolvedPath);
415418
// Then reencode all the updated spans into the overall map
416419
encodeLastRecordedSourceMapSpan();
@@ -420,7 +423,7 @@ namespace ts {
420423
emittedColumn: raw.emittedLine === 0 ? (raw.emittedColumn + firstLineColumnOffset) : raw.emittedColumn,
421424
sourceIndex: newIndex,
422425
};
423-
});
426+
}
424427
// And actually emit the text these sourcemaps are for
425428
return emitCallback(hint, node);
426429
}
@@ -519,17 +522,19 @@ namespace ts {
519522
setupSourceEntry(sourceFile.fileName, sourceFile.text);
520523
}
521524

522-
function setupSourceEntry(fileName: string, content: string | null) {
523-
// Add the file to tsFilePaths
524-
// If sourceroot option: Use the relative path corresponding to the common directory path
525-
// otherwise source locations relative to map file location
526-
const sourcesDirectoryPath = compilerOptions.sourceRoot ? host.getCommonSourceDirectory() : sourceMapDir;
527-
528-
const source = getRelativePathToDirectoryOrUrl(sourcesDirectoryPath,
529-
fileName,
530-
host.getCurrentDirectory(),
531-
host.getCanonicalFileName,
532-
/*isAbsolutePathAnUrl*/ true);
525+
function setupSourceEntry(fileName: string, content: string | null, source?: string) {
526+
if (!source) {
527+
// Add the file to tsFilePaths
528+
// If sourceroot option: Use the relative path corresponding to the common directory path
529+
// otherwise source locations relative to map file location
530+
const sourcesDirectoryPath = compilerOptions.sourceRoot ? host.getCommonSourceDirectory() : sourceMapDir;
531+
532+
source = getRelativePathToDirectoryOrUrl(sourcesDirectoryPath,
533+
fileName,
534+
host.getCurrentDirectory(),
535+
host.getCanonicalFileName,
536+
/*isAbsolutePathAnUrl*/ true);
537+
}
533538

534539
sourceMapSourceIndex = sourceMapData.sourceMapSources.indexOf(source);
535540
if (sourceMapSourceIndex === -1) {

src/compiler/sourcemapDecoder.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,7 @@ namespace ts.sourcemaps {
190190
};
191191
}
192192

193-
export function calculateDecodedMappings<T>(map: SourceMapData, processPosition: (position: RawSourceMapPosition) => T, host?: { log?(s: string): void }): T[] {
193+
function calculateDecodedMappings<T>(map: SourceMapData, processPosition: (position: RawSourceMapPosition) => T, host?: { log?(s: string): void }): T[] {
194194
const decoder = decodeMappings(map);
195195
const positions = arrayFrom(decoder, processPosition);
196196
if (decoder.error) {

src/compiler/types.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2844,7 +2844,6 @@ namespace ts {
28442844
inputSourceFileNames: string[]; // Input source file (which one can use on program to get the file), 1:1 mapping with the sourceMapSources list
28452845
sourceMapNames?: string[]; // Source map's names field - list of names that can be indexed in this source map
28462846
sourceMapMappings: string; // Source map's mapping field - encoded source map spans
2847-
sourceMapDecodedMappings: SourceMapSpan[]; // Raw source map spans that were encoded into the sourceMapMappings
28482847
}
28492848

28502849
/** Return code used by getEmitOutput function to indicate status of the function */

src/harness/documents.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ namespace documents {
148148

149149
public static fromUrl(url: string) {
150150
const match = SourceMap._dataURLRegExp.exec(url);
151-
return match ? new SourceMap(/*mapFile*/ undefined, new Buffer(match[1], "base64").toString("utf8")) : undefined;
151+
return match ? new SourceMap(/*mapFile*/ undefined, (Buffer.from ? Buffer.from(match[1], "base64") : new Buffer(match[1], "base64")).toString("utf8")) : undefined;
152152
}
153153

154154
public static fromSource(text: string): SourceMap | undefined {

src/harness/sourceMapRecorder.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -305,7 +305,8 @@ namespace Harness.SourceMapRecorder {
305305
}
306306

307307
SourceMapSpanWriter.initializeSourceMapSpanWriter(sourceMapRecorder, sourceMapData, currentFile);
308-
for (const decodedSourceMapping of sourceMapData.sourceMapDecodedMappings) {
308+
const mapper = ts.sourcemaps.decodeMappings({ mappings: sourceMapData.sourceMapMappings, sources: sourceMapData.sourceMapSources });
309+
for (let { value: decodedSourceMapping, done } = mapper.next(); !done; { value: decodedSourceMapping, done } = mapper.next()) {
309310
const currentSourceFile = program.getSourceFile(sourceMapData.inputSourceFileNames[decodedSourceMapping.sourceIndex])!;
310311
if (currentSourceFile !== prevSourceFile) {
311312
SourceMapSpanWriter.recordNewSourceFileSpan(decodedSourceMapping, currentSourceFile.text);

src/harness/utils.ts

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -63,10 +63,6 @@ namespace utils {
6363
return indentation;
6464
}
6565

66-
export function toUtf8(text: string): string {
67-
return new Buffer(text).toString("utf8");
68-
}
69-
7066
export function getByteOrderMarkLength(text: string): number {
7167
if (text.length >= 1) {
7268
const ch0 = text.charCodeAt(0);

src/testRunner/parallel/host.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ namespace Harness.Parallel.Host {
2020
// tslint:disable-next-line:variable-name
2121
const FailedTestReporter = require(path.resolve(__dirname, "../../scripts/failed-tests")) as typeof import("../../../scripts/failed-tests");
2222

23+
const perfdataFileNameFragment = ".parallelperf";
2324
const perfData = readSavedPerfData(configOption);
2425
const newTasks: Task[] = [];
2526
let tasks: Task[] = [];
@@ -175,8 +176,6 @@ namespace Harness.Parallel.Host {
175176
}
176177
}
177178

178-
const perfdataFileNameFragment = ".parallelperf";
179-
180179
function perfdataFileName(target?: string) {
181180
return `${perfdataFileNameFragment}${target ? `.${target}` : ""}.json`;
182181
}

src/testRunner/unittests/convertToBase64.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ namespace ts {
22
describe("convertToBase64", () => {
33
function runTest(input: string): void {
44
const actual = convertToBase64(input);
5-
const expected = new Buffer(input).toString("base64");
5+
const expected = (Buffer.from ? Buffer.from(input) : new Buffer(input)).toString("base64");
66
assert.equal(actual, expected, "Encoded string using convertToBase64 does not match buffer.toString('base64')");
77
}
88

src/tsserver/server.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,7 @@ namespace ts.server {
199199

200200
private write(s: string) {
201201
if (this.fd >= 0) {
202-
const buf = new Buffer(s);
202+
const buf = Buffer.from ? Buffer.from(s) : new Buffer(s);
203203
// tslint:disable-next-line no-null-keyword
204204
fs.writeSync(this.fd, buf, 0, buf.length, /*position*/ null!); // TODO: GH#18217
205205
}
@@ -869,7 +869,7 @@ namespace ts.server {
869869
}
870870

871871
// Override sys.write because fs.writeSync is not reliable on Node 4
872-
sys.write = (s: string) => writeMessage(new Buffer(s, "utf8"));
872+
sys.write = (s: string) => writeMessage(Buffer.from ? Buffer.from(s, "utf8") : new Buffer(s, "utf8"));
873873
sys.watchFile = (fileName, callback) => {
874874
const watchedFile = pollingWatchedFileSet.addFile(fileName, callback);
875875
return {

tests/baselines/reference/api/tsserverlibrary.d.ts

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2544,7 +2544,6 @@ declare namespace ts {
25442544
inputSourceFileNames: string[];
25452545
sourceMapNames?: string[];
25462546
sourceMapMappings: string;
2547-
sourceMapDecodedMappings: SourceMapSpan[];
25482547
}
25492548
/** Return code used by getEmitOutput function to indicate status of the function */
25502549
enum ExitStatus {
@@ -8604,17 +8603,6 @@ declare namespace ts.sourcemaps {
86048603
readonly lastSpan: SourceMapSpan;
86058604
}
86068605
function decodeMappings(map: SourceMapData): MappingsDecoder;
8607-
function calculateDecodedMappings<T>(map: SourceMapData, processPosition: (position: RawSourceMapPosition) => T, host?: {
8608-
log?(s: string): void;
8609-
}): T[];
8610-
interface RawSourceMapPosition {
8611-
emittedLine: number;
8612-
emittedColumn: number;
8613-
sourceLine: number;
8614-
sourceColumn: number;
8615-
sourceIndex: number;
8616-
nameIndex?: number;
8617-
}
86188606
}
86198607
declare namespace ts {
86208608
function getOriginalNodeId(node: Node): number;

0 commit comments

Comments
 (0)