add performance-startup-profile flag
This commit is contained in:
parent
a8d477482e
commit
b76c8bea27
5
npm-shrinkwrap.json
generated
5
npm-shrinkwrap.json
generated
|
@ -399,6 +399,11 @@
|
|||
"from": "util-deprecate@>=1.0.1 <1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz"
|
||||
},
|
||||
"v8-profiler": {
|
||||
"version": "5.6.5",
|
||||
"from": "v8-profiler@5.6.5",
|
||||
"resolved": "git://github.com/jrieken/v8-profiler.git#bc0803a4d4b2150b8a1bbffa80270769007036c2"
|
||||
},
|
||||
"vscode-debugprotocol": {
|
||||
"version": "1.17.0",
|
||||
"from": "vscode-debugprotocol@1.17.0",
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
"native-keymap": "0.4.0",
|
||||
"node-pty": "0.6.2",
|
||||
"semver": "4.3.6",
|
||||
"v8-profiler": "git://github.com/jrieken/v8-profiler.git#bc0803a4d4b2150b8a1bbffa80270769007036c2",
|
||||
"vscode-debugprotocol": "1.17.0",
|
||||
"vscode-textmate": "^3.1.1",
|
||||
"winreg": "1.2.0",
|
||||
|
|
|
@ -5,6 +5,11 @@
|
|||
|
||||
'use strict';
|
||||
|
||||
if (process.argv.indexOf('--performance-startup-profile') >= 0) {
|
||||
var profiler = require('v8-profiler');
|
||||
profiler.startProfiling('startup-main', true);
|
||||
}
|
||||
|
||||
// Perf measurements
|
||||
global.perfStartTime = Date.now();
|
||||
|
||||
|
|
58
src/vs/base/node/profiler.ts
Normal file
58
src/vs/base/node/profiler.ts
Normal file
|
@ -0,0 +1,58 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
'use strict';
|
||||
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import { homedir } from 'os';
|
||||
import { join } from 'path';
|
||||
import { writeFile } from 'vs/base/node/pfs';
|
||||
|
||||
export function startProfiling(name: string): TPromise<boolean> {
|
||||
return lazyV8Profiler.value.then(profiler => {
|
||||
profiler.startProfiling(name);
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
export function stopProfiling(name: string): TPromise<string> {
|
||||
return lazyV8Profiler.value.then(profiler => {
|
||||
return profiler.stopProfiling();
|
||||
}).then(profile => {
|
||||
return new TPromise<any>((resolve, reject) => {
|
||||
profile.export(function (error, result) {
|
||||
profile.delete();
|
||||
if (error) {
|
||||
reject(error);
|
||||
return;
|
||||
}
|
||||
const filepath = join(homedir(), `${name}-${Date.now()}.cpuprofile`);
|
||||
writeFile(filepath, result).then(() => resolve(filepath), reject);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
declare interface Profiler {
|
||||
startProfiling(name: string);
|
||||
stopProfiling(): Profile;
|
||||
}
|
||||
|
||||
declare interface Profile {
|
||||
export(callback: (err, data) => void);
|
||||
delete();
|
||||
}
|
||||
|
||||
const lazyV8Profiler = new class {
|
||||
private _value: TPromise<Profiler>;
|
||||
get value() {
|
||||
if (!this._value) {
|
||||
this._value = new TPromise((resolve, reject) => {
|
||||
require(['v8-profiler'], resolve, reject);
|
||||
});
|
||||
}
|
||||
return this._value;
|
||||
}
|
||||
};
|
|
@ -8,6 +8,7 @@
|
|||
import * as path from 'path';
|
||||
import * as platform from 'vs/base/common/platform';
|
||||
import * as objects from 'vs/base/common/objects';
|
||||
import { stopProfiling } from 'vs/base/node/profiler';
|
||||
import nls = require('vs/nls');
|
||||
import { IStorageService } from 'vs/code/electron-main/storage';
|
||||
import { shell, screen, BrowserWindow, systemPreferences, app } from 'electron';
|
||||
|
@ -466,6 +467,10 @@ export class VSCodeWindow {
|
|||
}
|
||||
}, 10000);
|
||||
}
|
||||
|
||||
if (this.environmentService.args['performance-startup-profile']) {
|
||||
stopProfiling('startup-main').then(path => console.log(`cpu profile stored in ${path}`), err => console.error(err));
|
||||
}
|
||||
}
|
||||
|
||||
public reload(cli?: ParsedArgs): void {
|
||||
|
|
|
@ -22,6 +22,7 @@ export interface ParsedArgs {
|
|||
locale?: string;
|
||||
'user-data-dir'?: string;
|
||||
performance?: boolean;
|
||||
['performance-startup-profile']?: boolean;
|
||||
verbose?: boolean;
|
||||
logExtensionHostCommunication?: boolean;
|
||||
'disable-extensions'?: boolean;
|
||||
|
|
|
@ -34,6 +34,7 @@ const options: minimist.Opts = {
|
|||
'unity-launch',
|
||||
'reuse-window',
|
||||
'performance',
|
||||
'performance-startup-profile',
|
||||
'verbose',
|
||||
'logExtensionHostCommunication',
|
||||
'disable-extensions',
|
||||
|
@ -112,6 +113,7 @@ export const optionsHelp: { [name: string]: string; } = {
|
|||
'--locale <locale>': localize('locale', "The locale to use (e.g. en-US or zh-TW)."),
|
||||
'-n, --new-window': localize('newWindow', "Force a new instance of Code."),
|
||||
'-p, --performance': localize('performance', "Start with the 'Developer: Startup Performance' command enabled."),
|
||||
'--performance-startup-profile': localize('performance-startup-profile', "Run CPU profiler during startup"),
|
||||
'-r, --reuse-window': localize('reuseWindow', "Force opening a file or folder in the last active window."),
|
||||
'--user-data-dir <dir>': localize('userDataDir', "Specifies the directory that user data is kept in, useful when running as root."),
|
||||
'--verbose': localize('verbose', "Print verbose output (implies --wait)."),
|
||||
|
|
|
@ -7,6 +7,11 @@
|
|||
|
||||
'use strict';
|
||||
|
||||
if (window.location.search.indexOf('performance-startup-profile') >= 0) {
|
||||
var profiler = require('v8-profiler');
|
||||
profiler.startProfiling('startup-renderer', true);
|
||||
}
|
||||
|
||||
/*global window,document,define*/
|
||||
|
||||
const path = require('path');
|
||||
|
|
|
@ -16,6 +16,7 @@ import aria = require('vs/base/browser/ui/aria/aria');
|
|||
import { dispose, IDisposable, Disposables } from 'vs/base/common/lifecycle';
|
||||
import errors = require('vs/base/common/errors');
|
||||
import { toErrorMessage } from 'vs/base/common/errorMessage';
|
||||
import { stopProfiling } from 'vs/base/node/profiler';
|
||||
import product from 'vs/platform/node/product';
|
||||
import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors';
|
||||
import pkg from 'vs/platform/node/package';
|
||||
|
@ -123,6 +124,7 @@ export class WorkbenchShell {
|
|||
private contextService: IWorkspaceContextService;
|
||||
private telemetryService: ITelemetryService;
|
||||
private extensionService: MainProcessExtensionService;
|
||||
private windowsService: IWindowsService;
|
||||
private windowIPCService: IWindowIPCService;
|
||||
private timerService: ITimerService;
|
||||
|
||||
|
@ -230,6 +232,25 @@ export class WorkbenchShell {
|
|||
if ((platform.isLinux || platform.isMacintosh) && process.getuid() === 0) {
|
||||
this.messageService.show(Severity.Warning, nls.localize('runningAsRoot', "It is recommended not to run Code as 'root'."));
|
||||
}
|
||||
|
||||
// Profiler: startup cpu profile
|
||||
if (this.environmentService.args['performance-startup-profile']) {
|
||||
stopProfiling('startup-renderer').then(path => {
|
||||
console.log(`cpu profile stored in ${path}`);
|
||||
|
||||
const restart = this.messageService.confirm({
|
||||
type: 'info',
|
||||
message: nls.localize('prof.message', "Successfully created profiles."),
|
||||
detail: nls.localize('prof.detail', "To not lose unsaved work, we strongly recommended to restart '{0}' now.", this.environmentService.appNameLong),
|
||||
primaryButton: nls.localize('prof.restart', "&&Restart")
|
||||
});
|
||||
|
||||
if (restart) {
|
||||
this.windowsService.relaunch({ removeArgs: ['--performance-startup-profile'] });
|
||||
}
|
||||
|
||||
}, err => console.error(err));
|
||||
}
|
||||
}
|
||||
|
||||
private initServiceCollection(container: HTMLElement): [IInstantiationService, ServiceCollection] {
|
||||
|
@ -251,7 +272,8 @@ export class WorkbenchShell {
|
|||
disposables.add(mainProcessClient);
|
||||
|
||||
const windowsChannel = mainProcessClient.getChannel('windows');
|
||||
serviceCollection.set(IWindowsService, new SyncDescriptor(WindowsChannelClient, windowsChannel));
|
||||
this.windowsService = new WindowsChannelClient(windowsChannel);
|
||||
serviceCollection.set(IWindowsService, this.windowsService);
|
||||
|
||||
serviceCollection.set(IWindowService, new SyncDescriptor(WindowService, this.windowIPCService.getWindowId()));
|
||||
|
||||
|
|
Loading…
Reference in a new issue