From 0b31e487c27c6a8e2bb9b922ca0aea985a56e38b Mon Sep 17 00:00:00 2001 From: Andrew Casey Date: Thu, 8 Oct 2020 17:08:21 -0700 Subject: [PATCH 1/3] Add tracepoints within createProgram These were useful during the Midgard investigation. --- src/compiler/program.ts | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/src/compiler/program.ts b/src/compiler/program.ts index 5095c055e23e6..984e3d4527969 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -867,11 +867,15 @@ namespace ts { forEachResolvedProjectReference }); + tracing.begin(tracing.Phase.Program, "shouldProgramCreateNewSourceFiles", { hasOldProgram: !!oldProgram }); const shouldCreateNewSourceFile = shouldProgramCreateNewSourceFiles(oldProgram, options); + tracing.end(); // We set `structuralIsReused` to `undefined` because `tryReuseStructureFromOldProgram` calls `tryReuseStructureFromOldProgram` which checks // `structuralIsReused`, which would be a TDZ violation if it was not set in advance to `undefined`. let structureIsReused: StructureIsReused; + tracing.begin(tracing.Phase.Program, "tryReuseStructureFromOldProgram", {}); structureIsReused = tryReuseStructureFromOldProgram(); // eslint-disable-line prefer-const + tracing.end(); if (structureIsReused !== StructureIsReused.Completely) { processingDefaultLibFiles = []; processingOtherFiles = []; @@ -907,12 +911,15 @@ namespace ts { } } + tracing.begin(tracing.Phase.Program, "processRootFiles", { count: rootNames.length }); forEach(rootNames, name => processRootFile(name, /*isDefaultLib*/ false, /*ignoreNoDefaultLib*/ false)); + tracing.end(); // load type declarations specified via 'types' argument or implicitly from types/ and node_modules/@types folders const typeReferences: string[] = rootNames.length ? getAutomaticTypeDirectiveNames(options, host) : emptyArray; if (typeReferences.length) { + tracing.begin(tracing.Phase.Program, "processTypeReferences", { count: typeReferences.length }); // This containingFilename needs to match with the one used in managed-side const containingDirectory = options.configFilePath ? getDirectoryPath(options.configFilePath) : host.getCurrentDirectory(); const containingFilename = combinePaths(containingDirectory, inferredTypesContainingFile); @@ -920,6 +927,7 @@ namespace ts { for (let i = 0; i < typeReferences.length; i++) { processTypeReferenceDirective(typeReferences[i], resolutions[i]); } + tracing.end(); } // Do not process the default library if: @@ -1041,10 +1049,12 @@ namespace ts { if (!moduleNames.length) return emptyArray; const containingFileName = getNormalizedAbsolutePath(containingFile.originalFileName, currentDirectory); const redirectedReference = getRedirectReferenceForResolution(containingFile); + tracing.begin(tracing.Phase.Program, "resolveModuleNamesWorker", { containingFileName }); performance.mark("beforeResolveModule"); const result = actualResolveModuleNamesWorker(moduleNames, containingFileName, reusedNames, redirectedReference); performance.mark("afterResolveModule"); performance.measure("ResolveModule", "beforeResolveModule", "afterResolveModule"); + tracing.end(); return result; } @@ -2426,6 +2436,17 @@ namespace ts { // Get source file from normalized fileName function findSourceFile(fileName: string, path: Path, isDefaultLib: boolean, ignoreNoDefaultLib: boolean, refFile: RefFile | undefined, packageId: PackageId | undefined): SourceFile | undefined { + tracing.begin(tracing.Phase.Program, "findSourceFile", { + fileName, + isDefaultLib: isDefaultLib || undefined, + refKind: refFile ? (RefFileKind as any)[refFile.kind] : undefined, + }); + const result = findSourceFileWorker(fileName, path, isDefaultLib, ignoreNoDefaultLib, refFile, packageId); + tracing.end(); + return result; + } + + function findSourceFileWorker(fileName: string, path: Path, isDefaultLib: boolean, ignoreNoDefaultLib: boolean, refFile: RefFile | undefined, packageId: PackageId | undefined): SourceFile | undefined { if (useSourceOfProjectReferenceRedirect) { let source = getSourceOfProjectReferenceRedirect(fileName); // If preserveSymlinks is true, module resolution wont jump the symlink @@ -2750,6 +2771,16 @@ namespace ts { resolvedTypeReferenceDirective?: ResolvedTypeReferenceDirective, refFile?: RefFile ): void { + tracing.begin(tracing.Phase.Program, "processTypeReferenceDirective", { directive: typeReferenceDirective, hasResolved: !!resolveModuleNamesReusingOldState, refKind: refFile?.kind, refPath: refFile?.file.path }); + processTypeReferenceDirectiveWorker(typeReferenceDirective, resolvedTypeReferenceDirective, refFile); + tracing.end(); + } + + function processTypeReferenceDirectiveWorker( + typeReferenceDirective: string, + resolvedTypeReferenceDirective?: ResolvedTypeReferenceDirective, + refFile?: RefFile + ): void { // If we already found this library as a primary reference - nothing to do const previousResolution = resolvedTypeReferenceDirectives.get(typeReferenceDirective); From 9ad9ec984e1c7bd373329977a4f6f27cd28f27e3 Mon Sep 17 00:00:00 2001 From: Andrew Casey Date: Wed, 21 Oct 2020 10:38:09 -0700 Subject: [PATCH 2/3] Add tracepoint in resolveTypeReferenceDirectiveNamesWorker --- src/compiler/program.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/compiler/program.ts b/src/compiler/program.ts index 984e3d4527969..2572ed5f7e153 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -1060,12 +1060,14 @@ namespace ts { function resolveTypeReferenceDirectiveNamesWorker(typeDirectiveNames: string[], containingFile: string | SourceFile): readonly (ResolvedTypeReferenceDirective | undefined)[] { if (!typeDirectiveNames.length) return []; - performance.mark("beforeResolveTypeReference"); const containingFileName = !isString(containingFile) ? getNormalizedAbsolutePath(containingFile.originalFileName, currentDirectory) : containingFile; const redirectedReference = !isString(containingFile) ? getRedirectReferenceForResolution(containingFile) : undefined; + tracing.begin(tracing.Phase.Program, "resolveTypeReferenceDirectiveNamesWorker", { containingFileName }); + performance.mark("beforeResolveTypeReference"); const result = actualResolveTypeReferenceDirectiveNamesWorker(typeDirectiveNames, containingFileName, redirectedReference); performance.mark("afterResolveTypeReference"); performance.measure("ResolveTypeReference", "beforeResolveTypeReference", "afterResolveTypeReference"); + tracing.end(); return result; } From dcb18d6f1872b04867abdd61a9b8087f8c6b3eff Mon Sep 17 00:00:00 2001 From: Andrew Casey Date: Thu, 22 Oct 2020 11:01:42 -0700 Subject: [PATCH 3/3] Adopt push-pop API --- src/compiler/program.ts | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/src/compiler/program.ts b/src/compiler/program.ts index 2572ed5f7e153..396c4d8d84cef 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -867,15 +867,15 @@ namespace ts { forEachResolvedProjectReference }); - tracing.begin(tracing.Phase.Program, "shouldProgramCreateNewSourceFiles", { hasOldProgram: !!oldProgram }); + tracing.push(tracing.Phase.Program, "shouldProgramCreateNewSourceFiles", { hasOldProgram: !!oldProgram }); const shouldCreateNewSourceFile = shouldProgramCreateNewSourceFiles(oldProgram, options); - tracing.end(); + tracing.pop(); // We set `structuralIsReused` to `undefined` because `tryReuseStructureFromOldProgram` calls `tryReuseStructureFromOldProgram` which checks // `structuralIsReused`, which would be a TDZ violation if it was not set in advance to `undefined`. let structureIsReused: StructureIsReused; - tracing.begin(tracing.Phase.Program, "tryReuseStructureFromOldProgram", {}); + tracing.push(tracing.Phase.Program, "tryReuseStructureFromOldProgram", {}); structureIsReused = tryReuseStructureFromOldProgram(); // eslint-disable-line prefer-const - tracing.end(); + tracing.pop(); if (structureIsReused !== StructureIsReused.Completely) { processingDefaultLibFiles = []; processingOtherFiles = []; @@ -911,15 +911,15 @@ namespace ts { } } - tracing.begin(tracing.Phase.Program, "processRootFiles", { count: rootNames.length }); + tracing.push(tracing.Phase.Program, "processRootFiles", { count: rootNames.length }); forEach(rootNames, name => processRootFile(name, /*isDefaultLib*/ false, /*ignoreNoDefaultLib*/ false)); - tracing.end(); + tracing.pop(); // load type declarations specified via 'types' argument or implicitly from types/ and node_modules/@types folders const typeReferences: string[] = rootNames.length ? getAutomaticTypeDirectiveNames(options, host) : emptyArray; if (typeReferences.length) { - tracing.begin(tracing.Phase.Program, "processTypeReferences", { count: typeReferences.length }); + tracing.push(tracing.Phase.Program, "processTypeReferences", { count: typeReferences.length }); // This containingFilename needs to match with the one used in managed-side const containingDirectory = options.configFilePath ? getDirectoryPath(options.configFilePath) : host.getCurrentDirectory(); const containingFilename = combinePaths(containingDirectory, inferredTypesContainingFile); @@ -927,7 +927,7 @@ namespace ts { for (let i = 0; i < typeReferences.length; i++) { processTypeReferenceDirective(typeReferences[i], resolutions[i]); } - tracing.end(); + tracing.pop(); } // Do not process the default library if: @@ -1049,12 +1049,12 @@ namespace ts { if (!moduleNames.length) return emptyArray; const containingFileName = getNormalizedAbsolutePath(containingFile.originalFileName, currentDirectory); const redirectedReference = getRedirectReferenceForResolution(containingFile); - tracing.begin(tracing.Phase.Program, "resolveModuleNamesWorker", { containingFileName }); + tracing.push(tracing.Phase.Program, "resolveModuleNamesWorker", { containingFileName }); performance.mark("beforeResolveModule"); const result = actualResolveModuleNamesWorker(moduleNames, containingFileName, reusedNames, redirectedReference); performance.mark("afterResolveModule"); performance.measure("ResolveModule", "beforeResolveModule", "afterResolveModule"); - tracing.end(); + tracing.pop(); return result; } @@ -1062,12 +1062,12 @@ namespace ts { if (!typeDirectiveNames.length) return []; const containingFileName = !isString(containingFile) ? getNormalizedAbsolutePath(containingFile.originalFileName, currentDirectory) : containingFile; const redirectedReference = !isString(containingFile) ? getRedirectReferenceForResolution(containingFile) : undefined; - tracing.begin(tracing.Phase.Program, "resolveTypeReferenceDirectiveNamesWorker", { containingFileName }); + tracing.push(tracing.Phase.Program, "resolveTypeReferenceDirectiveNamesWorker", { containingFileName }); performance.mark("beforeResolveTypeReference"); const result = actualResolveTypeReferenceDirectiveNamesWorker(typeDirectiveNames, containingFileName, redirectedReference); performance.mark("afterResolveTypeReference"); performance.measure("ResolveTypeReference", "beforeResolveTypeReference", "afterResolveTypeReference"); - tracing.end(); + tracing.pop(); return result; } @@ -2438,13 +2438,13 @@ namespace ts { // Get source file from normalized fileName function findSourceFile(fileName: string, path: Path, isDefaultLib: boolean, ignoreNoDefaultLib: boolean, refFile: RefFile | undefined, packageId: PackageId | undefined): SourceFile | undefined { - tracing.begin(tracing.Phase.Program, "findSourceFile", { + tracing.push(tracing.Phase.Program, "findSourceFile", { fileName, isDefaultLib: isDefaultLib || undefined, refKind: refFile ? (RefFileKind as any)[refFile.kind] : undefined, }); const result = findSourceFileWorker(fileName, path, isDefaultLib, ignoreNoDefaultLib, refFile, packageId); - tracing.end(); + tracing.pop(); return result; } @@ -2773,9 +2773,9 @@ namespace ts { resolvedTypeReferenceDirective?: ResolvedTypeReferenceDirective, refFile?: RefFile ): void { - tracing.begin(tracing.Phase.Program, "processTypeReferenceDirective", { directive: typeReferenceDirective, hasResolved: !!resolveModuleNamesReusingOldState, refKind: refFile?.kind, refPath: refFile?.file.path }); + tracing.push(tracing.Phase.Program, "processTypeReferenceDirective", { directive: typeReferenceDirective, hasResolved: !!resolveModuleNamesReusingOldState, refKind: refFile?.kind, refPath: refFile?.file.path }); processTypeReferenceDirectiveWorker(typeReferenceDirective, resolvedTypeReferenceDirective, refFile); - tracing.end(); + tracing.pop(); } function processTypeReferenceDirectiveWorker(