add performance-startup-profile flag

This commit is contained in:
Johannes Rieken 2017-02-28 14:50:34 +01:00
parent a8d477482e
commit b76c8bea27
9 changed files with 105 additions and 1 deletions

5
npm-shrinkwrap.json generated
View file

@ -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",

View file

@ -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",

View file

@ -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();

View 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;
}
};

View file

@ -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 {

View file

@ -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;

View file

@ -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)."),

View file

@ -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');

View file

@ -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()));