Skip to content

Commit ee070dc

Browse files
committed
remove --prof-modules-flag, adopt new loader, microsoft#62643
1 parent 98c36e8 commit ee070dc

7 files changed

Lines changed: 71 additions & 106 deletions

File tree

src/typings/require.d.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,12 @@ declare const enum LoaderEventType {
1717
NodeEndEvaluatingScript = 32,
1818

1919
NodeBeginNativeRequire = 33,
20-
NodeEndNativeRequire = 34
20+
NodeEndNativeRequire = 34,
21+
22+
CachedDataFound = 60,
23+
CachedDataMissed = 61,
24+
CachedDataRejected = 62,
25+
CachedDataCreated = 63,
2126
}
2227

2328
declare class LoaderEvent {

src/vs/code/electron-browser/workbench/workbench.js

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -35,13 +35,7 @@ bootstrapWindow.load([
3535
showPartsSplash(windowConfig);
3636
},
3737
beforeLoaderConfig: function (windowConfig, loaderConfig) {
38-
loaderConfig.recordStats = !!windowConfig['prof-modules'];
39-
if (loaderConfig.nodeCachedData) {
40-
const onNodeCachedData = window['MonacoEnvironment'].onNodeCachedData = [];
41-
loaderConfig.nodeCachedData.onData = function () {
42-
onNodeCachedData.push(arguments);
43-
};
44-
}
38+
loaderConfig.recordStats = true;
4539
},
4640
beforeRequire: function () {
4741
perf.mark('willLoadWorkbenchMain');

src/vs/loader.js

Lines changed: 54 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,7 @@ var AMDLoader;
235235
*--------------------------------------------------------------------------------------------*/
236236
var AMDLoader;
237237
(function (AMDLoader) {
238+
;
238239
var ConfigurationOptionsUtil = (function () {
239240
function ConfigurationOptionsUtil() {
240241
}
@@ -305,22 +306,8 @@ var AMDLoader;
305306
if (typeof options.nodeCachedData.writeDelay !== 'number' || options.nodeCachedData.writeDelay < 0) {
306307
options.nodeCachedData.writeDelay = 1000 * 7;
307308
}
308-
if (typeof options.nodeCachedData.onData !== 'function') {
309-
options.nodeCachedData.onData = function (err) {
310-
if (err && err.errorCode === 'cachedDataRejected') {
311-
console.warn('Rejected cached data from file: ' + err.path);
312-
}
313-
else if (err && err.errorCode) {
314-
console.error('Problems handling cached data file: ' + err.path);
315-
console.error(err.detail);
316-
}
317-
else if (err) {
318-
console.error(err);
319-
}
320-
};
321-
}
322309
if (!options.nodeCachedData.path || typeof options.nodeCachedData.path !== 'string') {
323-
options.nodeCachedData.onData('INVALID cached data configuration, \'path\' MUST be set');
310+
options.onError('INVALID cached data configuration, \'path\' MUST be set');
324311
options.nodeCachedData = undefined;
325312
}
326313
}
@@ -660,7 +647,6 @@ var AMDLoader;
660647
this._env = env;
661648
this._didInitialize = false;
662649
this._didPatchNodeRequire = false;
663-
this._hasCreateCachedData = false;
664650
}
665651
NodeScriptLoader.prototype._init = function (nodeRequire) {
666652
if (this._didInitialize) {
@@ -672,14 +658,17 @@ var AMDLoader;
672658
this._vm = nodeRequire('vm');
673659
this._path = nodeRequire('path');
674660
this._crypto = nodeRequire('crypto');
675-
// check for `createCachedData`-api
676-
this._hasCreateCachedData = typeof (new this._vm.Script('').createCachedData) === 'function';
677661
};
678662
// patch require-function of nodejs such that we can manually create a script
679663
// from cached data. this is done by overriding the `Module._compile` function
680664
NodeScriptLoader.prototype._initNodeRequire = function (nodeRequire, moduleManager) {
665+
// It is important to check for `nodeCachedData` first and then set `_didPatchNodeRequire`.
666+
// That's because `nodeCachedData` is set _after_ calling this for the first time...
681667
var nodeCachedData = moduleManager.getConfig().getOptionsLiteral().nodeCachedData;
682-
if (!nodeCachedData || this._didPatchNodeRequire) {
668+
if (!nodeCachedData) {
669+
return;
670+
}
671+
if (this._didPatchNodeRequire) {
683672
return;
684673
}
685674
this._didPatchNodeRequire = true;
@@ -708,21 +697,21 @@ var AMDLoader;
708697
content = content.replace(/^#!.*/, '');
709698
// create wrapper function
710699
var wrapper = Module.wrap(content);
711-
var cachedDataPath = that._getCachedDataPath(nodeCachedData.seed, nodeCachedData.path, filename);
700+
var cachedDataPath = that._getCachedDataPath(nodeCachedData, filename);
712701
var options = { filename: filename };
713702
try {
714703
options.cachedData = that._fs.readFileSync(cachedDataPath);
715704
}
716705
catch (e) {
717-
options.produceCachedData = !that._hasCreateCachedData;
706+
// ignore
718707
}
719708
var script = new that._vm.Script(wrapper, options);
720709
var compileWrapper = script.runInThisContext(options);
721710
var dirname = that._path.dirname(filename);
722711
var require = makeRequireFunction(this);
723712
var args = [this.exports, require, this, filename, dirname, process, _commonjsGlobal, Buffer];
724713
var result = compileWrapper.apply(this.exports, args);
725-
that._processCachedData(moduleManager, script, wrapper, cachedDataPath, !options.cachedData);
714+
that._processCachedData(script, cachedDataPath, Boolean(options.cachedData), moduleManager.getConfig(), moduleManager.getRecorder());
726715
return result;
727716
};
728717
};
@@ -780,16 +769,16 @@ var AMDLoader;
780769
_this._loadAndEvalScript(moduleManager, scriptSrc, vmScriptSrc, contents, { filename: vmScriptSrc }, recorder, callback, errorback);
781770
}
782771
else {
783-
var cachedDataPath_1 = _this._getCachedDataPath(opts.nodeCachedData.seed, opts.nodeCachedData.path, scriptSrc);
772+
var cachedDataPath_1 = _this._getCachedDataPath(opts.nodeCachedData, scriptSrc);
784773
_this._fs.readFile(cachedDataPath_1, function (_err, cachedData) {
785774
// create script options
786775
var options = {
787776
filename: vmScriptSrc,
788-
produceCachedData: !_this._hasCreateCachedData && typeof cachedData === 'undefined',
789777
cachedData: cachedData
790778
};
779+
recorder.record(cachedData ? 60 /* CachedDataFound */ : 61 /* CachedDataMissed */, scriptSrc);
791780
var script = _this._loadAndEvalScript(moduleManager, scriptSrc, vmScriptSrc, contents, options, recorder, callback, errorback);
792-
_this._processCachedData(moduleManager, script, contents, cachedDataPath_1, !options.cachedData);
781+
_this._processCachedData(script, cachedDataPath_1, Boolean(cachedData), moduleManager.getConfig(), recorder);
793782
});
794783
}
795784
});
@@ -818,74 +807,56 @@ var AMDLoader;
818807
}
819808
return script;
820809
};
821-
NodeScriptLoader.prototype._getCachedDataPath = function (seed, basedir, filename) {
822-
var hash = this._crypto.createHash('md5').update(filename, 'utf8').update(seed, 'utf8').digest('hex');
810+
NodeScriptLoader.prototype._getCachedDataPath = function (config, filename) {
811+
var hash = this._crypto.createHash('md5').update(filename, 'utf8').update(config.seed, 'utf8').digest('hex');
823812
var basename = this._path.basename(filename).replace(/\.js$/, '');
824-
return this._path.join(basedir, basename + "-" + hash + ".code");
813+
return this._path.join(config.path, basename + "-" + hash + ".code");
825814
};
826-
NodeScriptLoader.prototype._processCachedData = function (moduleManager, script, contents, cachedDataPath, createCachedData) {
815+
NodeScriptLoader.prototype._processCachedData = function (script, cachedDataPath, hadCachedData, config, recorder) {
827816
var _this = this;
828817
if (script.cachedDataRejected) {
829-
// data rejected => delete cache file
830-
moduleManager.getConfig().getOptionsLiteral().nodeCachedData.onData({
831-
errorCode: 'cachedDataRejected',
832-
path: cachedDataPath
818+
// rejected cached data
819+
// (1) delete data
820+
// (2) create new data
821+
recorder.record(62 /* CachedDataRejected */, cachedDataPath);
822+
this._fs.unlink(cachedDataPath, function (err) {
823+
if (err) {
824+
config.onError(err);
825+
}
826+
_this._createCachedData(script, cachedDataPath, config, recorder);
833827
});
834-
NodeScriptLoader._runSoon(function () {
835-
return _this._fs.unlink(cachedDataPath, function (err) {
836-
if (err) {
837-
moduleManager.getConfig().getOptionsLiteral().nodeCachedData.onData({
838-
errorCode: 'unlink',
839-
path: cachedDataPath,
840-
detail: err
841-
});
842-
}
843-
});
844-
}, moduleManager.getConfig().getOptionsLiteral().nodeCachedData.writeDelay / 2);
845828
}
846-
else if (script.cachedDataProduced) {
847-
// data produced => tell outside world
848-
moduleManager.getConfig().getOptionsLiteral().nodeCachedData.onData(undefined, {
849-
path: cachedDataPath
850-
});
851-
// data produced => write cache file
852-
NodeScriptLoader._runSoon(function () {
853-
return _this._fs.writeFile(cachedDataPath, script.cachedData, function (err) {
854-
if (err) {
855-
moduleManager.getConfig().getOptionsLiteral().nodeCachedData.onData({
856-
errorCode: 'writeFile',
857-
path: cachedDataPath,
858-
detail: err
859-
});
860-
}
861-
});
862-
}, moduleManager.getConfig().getOptionsLiteral().nodeCachedData.writeDelay);
829+
else if (!hadCachedData) {
830+
// create cached data unless we already had
831+
// and accepted cached data
832+
this._createCachedData(script, cachedDataPath, config, recorder);
863833
}
864-
else if (this._hasCreateCachedData && createCachedData) {
865-
// NEW world
866-
// data produced => tell outside world
867-
moduleManager.getConfig().getOptionsLiteral().nodeCachedData.onData(undefined, {
868-
path: cachedDataPath
869-
});
870-
// soon'ish create and save cached data
871-
NodeScriptLoader._runSoon(function () {
872-
var data = script.createCachedData(contents);
834+
};
835+
NodeScriptLoader.prototype._createCachedData = function (script, cachedDataPath, config, recorder) {
836+
var _this = this;
837+
var timeout = Math.ceil(config.getOptionsLiteral().nodeCachedData.writeDelay * (1 + Math.random()));
838+
var lastSize = -1;
839+
var iteration = 0;
840+
var createLoop = function () {
841+
setTimeout(function () {
842+
var data = script.createCachedData();
843+
if (data.length === lastSize) {
844+
return;
845+
}
846+
lastSize = data.length;
873847
_this._fs.writeFile(cachedDataPath, data, function (err) {
874-
if (!err) {
875-
return;
848+
if (err) {
849+
config.onError(err);
876850
}
877-
moduleManager.getConfig().getOptionsLiteral().nodeCachedData.onData({
878-
errorCode: 'writeFile',
879-
path: cachedDataPath,
880-
detail: err
881-
});
851+
recorder.record(63 /* CachedDataCreated */, cachedDataPath);
852+
createLoop();
882853
});
883-
}, moduleManager.getConfig().getOptionsLiteral().nodeCachedData.writeDelay);
884-
}
885-
};
886-
NodeScriptLoader._runSoon = function (callback, minTimeout) {
887-
var timeout = minTimeout + Math.ceil(Math.random() * minTimeout);
888-
setTimeout(callback, timeout);
854+
}, timeout * (Math.pow(4, iteration++)));
855+
};
856+
// with some delay (`timeout`) create cached data
857+
// and repeat that (with backoff delay) until the
858+
// data seems to be not changing anymore
859+
createLoop();
889860
};
890861
return NodeScriptLoader;
891862
}());

src/vs/platform/environment/common/environment.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ export interface ParsedArgs {
2727
'prof-startup'?: string;
2828
'prof-startup-prefix'?: string;
2929
'prof-append-timers'?: string;
30-
'prof-modules'?: string;
3130
verbose?: boolean;
3231
trace?: boolean;
3332
'trace-category-filter'?: string;

src/vs/platform/environment/node/argv.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,6 @@ export const options: Option[] = [
5454
{ id: 'verbose', type: 'boolean', cat: 't', description: localize('verbose', "Print verbose output (implies --wait).") },
5555
{ id: 'log', type: 'string', cat: 't', args: 'level', description: localize('log', "Log level to use. Default is 'info'. Allowed values are 'critical', 'error', 'warn', 'info', 'debug', 'trace', 'off'.") },
5656
{ id: 'status', type: 'boolean', alias: 's', cat: 't', description: localize('status', "Print process usage and diagnostics information.") },
57-
{ id: 'prof-modules', type: 'boolean', alias: 'p', cat: 't', description: localize('prof-modules', "Capture performance markers while loading JS modules and print them with 'F1 > Developer: Startup Performance") },
5857
{ id: 'prof-startup', type: 'boolean', cat: 't', description: localize('prof-startup', "Run CPU profiler during startup") },
5958
{ id: 'disable-extensions', type: 'boolean', deprecates: 'disableExtensions', cat: 't', description: localize('disableExtensions', "Disable all installed extensions.") },
6059
{ id: 'disable-extension', type: 'string', cat: 't', args: 'extension-id', description: localize('disableExtension', "Disable an extension.") },
@@ -275,4 +274,4 @@ export function createWaitMarkerFile(verbose?: boolean): string | undefined {
275274
}
276275
return undefined;
277276
}
278-
}
277+
}

src/vs/workbench/contrib/performance/electron-browser/perfviewEditor.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ import { IDisposable, dispose } from 'vs/base/common/lifecycle';
2020
import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService';
2121
import { writeTransientState } from 'vs/workbench/contrib/codeEditor/browser/toggleWordWrap';
2222
import { mergeSort } from 'vs/base/common/arrays';
23-
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
2423
import product from 'vs/platform/product/node/product';
2524
import pkg from 'vs/platform/product/node/package';
2625

@@ -73,7 +72,6 @@ class PerfModelContentProvider implements ITextModelContentProvider {
7372
@ICodeEditorService private readonly _editorService: ICodeEditorService,
7473
@ILifecycleService private readonly _lifecycleService: ILifecycleService,
7574
@ITimerService private readonly _timerService: ITimerService,
76-
@IEnvironmentService private readonly _envService: IEnvironmentService,
7775
@IExtensionService private readonly _extensionService: IExtensionService,
7876
) { }
7977

@@ -107,7 +105,7 @@ class PerfModelContentProvider implements ITextModelContentProvider {
107105
]).then(([metrics]) => {
108106
if (this._model && !this._model.isDisposed()) {
109107

110-
let stats = this._envService.args['prof-modules'] ? LoaderStats.get() : undefined;
108+
let stats = LoaderStats.get();
111109
let md = new MarkdownBuilder();
112110
this._addSummary(md, metrics);
113111
md.blank();

src/vs/workbench/services/timer/electron-browser/timerService.ts

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/
1212
import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace';
1313
import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions';
1414
import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
15-
import { isNonEmptyArray } from 'vs/base/common/arrays';
1615
import { IUpdateService } from 'vs/platform/update/common/update';
1716
import { ILifecycleService } from 'vs/platform/lifecycle/common/lifecycle';
1817
import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet';
@@ -432,16 +431,16 @@ export function didUseCachedData(): boolean {
432431
if (!Boolean((<any>global).require.getConfig().nodeCachedData)) {
433432
return false;
434433
}
435-
// whenever cached data is produced or rejected a onNodeCachedData-callback is invoked. That callback
436-
// stores data in the `MonacoEnvironment.onNodeCachedData` global. See:
437-
// https://github.com/Microsoft/vscode/blob/efe424dfe76a492eab032343e2fa4cfe639939f0/src/vs/workbench/electron-browser/bootstrap/index.js#L299
438-
if (isNonEmptyArray(MonacoEnvironment.onNodeCachedData)) {
439-
return false;
434+
// There are loader events that signal if cached data was missing, rejected,
435+
// or used. The former two mean no cached data.
436+
for (const event of require.getStats()) {
437+
switch (event.type) {
438+
case LoaderEventType.CachedDataRejected:
439+
case LoaderEventType.CachedDataMissed:
440+
return false;
441+
}
440442
}
441443
return true;
442444
}
443445

444-
declare type OnNodeCachedDataArgs = [{ errorCode: string, path: string, detail?: string }, { path: string, length: number }];
445-
declare const MonacoEnvironment: { onNodeCachedData: OnNodeCachedDataArgs[] };
446-
447446
//#endregion

0 commit comments

Comments
 (0)