diff --git a/build/gulpfile.vscode.js b/build/gulpfile.vscode.js index d2c53d94ce6..87aa631d3a1 100644 --- a/build/gulpfile.vscode.js +++ b/build/gulpfile.vscode.js @@ -302,7 +302,6 @@ function packageTask(platform, arch, opts) { .pipe(util.cleanNodeModule('windows-foreground-love', ['binding.gyp', 'build/**', 'src/**'], ['**/*.node'])) .pipe(util.cleanNodeModule('windows-process-tree', ['binding.gyp', 'build/**', 'src/**'], ['**/*.node'])) .pipe(util.cleanNodeModule('gc-signals', ['binding.gyp', 'build/**', 'src/**', 'deps/**'], ['**/*.node', 'src/index.js'])) - .pipe(util.cleanNodeModule('v8-profiler', ['binding.gyp', 'build/**', 'src/**', 'deps/**'], ['**/*.node', 'src/index.js'])) .pipe(util.cleanNodeModule('keytar', ['binding.gyp', 'build/**', 'src/**', 'script/**', 'node_modules/**'], ['**/*.node'])) .pipe(util.cleanNodeModule('node-pty', ['binding.gyp', 'build/**', 'src/**', 'tools/**'], ['build/Release/**'])) .pipe(util.cleanNodeModule('nsfw', ['binding.gyp', 'build/**', 'src/**', 'openpa/**', 'includes/**'], ['**/*.node', '**/*.a'])) diff --git a/package.json b/package.json index d902790fbfe..b9e22ab7d44 100644 --- a/package.json +++ b/package.json @@ -37,7 +37,7 @@ "node-pty": "0.7.3", "nsfw": "1.0.16", "semver": "4.3.6", - "v8-profiler": "jrieken/v8-profiler#vscode", + "v8-inspect-profiler": "^0.0.6", "vscode-chokidar": "1.6.2", "vscode-debugprotocol": "1.25.0-pre.0", "vscode-ripgrep": "^0.6.0-patch.0.5", diff --git a/src/main.js b/src/main.js index 7b31fc5dcab..3192f1f086c 100644 --- a/src/main.js +++ b/src/main.js @@ -5,13 +5,6 @@ 'use strict'; -if (process.argv.indexOf('--prof-startup') >= 0) { - var profiler = require('v8-profiler'); - var prefix = require('crypto').randomBytes(2).toString('hex'); - process.env.VSCODE_PROFILES_PREFIX = prefix; - profiler.startProfiling('main', true); -} - var perf = require('./vs/base/common/performance'); perf.mark('main:started'); @@ -122,6 +115,10 @@ function getNLSConfiguration() { } function getNodeCachedDataDir() { + // flag to disable cached data support + if (process.argv.indexOf('--no-cached-data') > 0) { + return Promise.resolve(undefined); + } // IEnvironmentService.isBuilt if (process.env['VSCODE_DEV']) { diff --git a/src/typings/v8-inspect-profiler.d.ts b/src/typings/v8-inspect-profiler.d.ts new file mode 100644 index 00000000000..4828ef9af9a --- /dev/null +++ b/src/typings/v8-inspect-profiler.d.ts @@ -0,0 +1,12 @@ +declare module 'v8-inspect-profiler' { + + export interface Profile { } + + export interface ProfilingSession { + stop(afterDelay?: number): PromiseLike; + } + + export function startProfiling(options: { port: number, tries?: number, retyWait?: number }): PromiseLike; + export function writeProfile(profile: Profile, name?: string): PromiseLike; + export function rewriteAbsolutePaths(profile, replaceWith?); +} diff --git a/src/vs/base/node/ports.ts b/src/vs/base/node/ports.ts index 1ab7de9ab2c..94e6cfb01dc 100644 --- a/src/vs/base/node/ports.ts +++ b/src/vs/base/node/ports.ts @@ -11,24 +11,24 @@ import net = require('net'); * Given a start point and a max number of retries, will find a port that * is openable. Will return 0 in case no free port can be found. */ -export function findFreePort(startPort: number, giveUpAfter: number, timeout: number, clb: (port: number) => void): void { +export function findFreePort(startPort: number, giveUpAfter: number, timeout: number): Thenable { let done = false; - const timeoutHandle = setTimeout(() => { - if (!done) { - done = true; + return new Promise(resolve => { + const timeoutHandle = setTimeout(() => { + if (!done) { + done = true; + return resolve(0); + } + }, timeout); - return clb(0); - } - }, timeout); - - doFindFreePort(startPort, giveUpAfter, (port) => { - if (!done) { - done = true; - clearTimeout(timeoutHandle); - - return clb(port); - } + doFindFreePort(startPort, giveUpAfter, (port) => { + if (!done) { + done = true; + clearTimeout(timeoutHandle); + return resolve(port); + } + }); }); } diff --git a/src/vs/base/node/profiler.ts b/src/vs/base/node/profiler.ts deleted file mode 100644 index 782c20e28f1..00000000000 --- a/src/vs/base/node/profiler.ts +++ /dev/null @@ -1,100 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * 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 { join, basename } from 'path'; -import { writeFile } from 'vs/base/node/pfs'; - -export function startProfiling(name: string): TPromise { - return lazyV8Profiler.value.then(profiler => { - profiler.startProfiling(name); - return true; - }); -} - -const _isRunningOutOfDev = process.env['VSCODE_DEV']; - -export function stopProfiling(dir: string, prefix: string): TPromise { - return lazyV8Profiler.value.then(profiler => { - return profiler.stopProfiling(); - }).then(profile => { - return new TPromise((resolve, reject) => { - - // remove pii paths - if (!_isRunningOutOfDev) { - removePiiPaths(profile); // remove pii from our users - } - - profile.export(function (error, result) { - profile.delete(); - if (error) { - reject(error); - return; - } - let filepath = join(dir, `${prefix}_${profile.title}.cpuprofile`); - if (!_isRunningOutOfDev) { - filepath += '.txt'; // github issues must be: txt, zip, png, gif - } - writeFile(filepath, result).then(() => resolve(filepath), reject); - }); - }); - }); -} - -export function removePiiPaths(profile: Profile) { - const stack = [profile.head]; - while (stack.length > 0) { - const element = stack.pop(); - if (element.url) { - const shortUrl = basename(element.url); - if (element.url !== shortUrl) { - element.url = `pii_removed/${shortUrl}`; - } - } - if (element.children) { - stack.push(...element.children); - } - } -} - -declare interface Profiler { - startProfiling(name: string): void; - stopProfiling(): Profile; -} - -export declare interface Profile { - title: string; - export(callback: (err, data) => void): void; - delete(): void; - head: ProfileSample; -} - -export declare interface ProfileSample { - // bailoutReason:"" - // callUID:2333 - // children:Array[39] - // functionName:"(root)" - // hitCount:0 - // id:1 - // lineNumber:0 - // scriptId:0 - // url:"" - url: string; - children: ProfileSample[]; -} - -const lazyV8Profiler = new class { - private _value: TPromise; - get value() { - if (!this._value) { - this._value = new TPromise((resolve, reject) => { - require(['v8-profiler'], resolve, reject); - }); - } - return this._value; - } -}; diff --git a/src/vs/base/test/node/port.test.ts b/src/vs/base/test/node/port.test.ts index 24906c66662..7c2d3678d11 100644 --- a/src/vs/base/test/node/port.test.ts +++ b/src/vs/base/test/node/port.test.ts @@ -18,7 +18,7 @@ suite('Ports', () => { } // get an initial freeport >= 7000 - ports.findFreePort(7000, 100, 300000, (initialPort) => { + ports.findFreePort(7000, 100, 300000).then(initialPort => { assert.ok(initialPort >= 7000); // create a server to block this port @@ -26,7 +26,7 @@ suite('Ports', () => { server.listen(initialPort, null, null, () => { // once listening, find another free port and assert that the port is different from the opened one - ports.findFreePort(7000, 50, 300000, (freePort) => { + ports.findFreePort(7000, 50, 300000).then(freePort => { assert.ok(freePort >= 7000 && freePort !== initialPort); server.close(); diff --git a/src/vs/code/electron-main/window.ts b/src/vs/code/electron-main/window.ts index f89884a9179..5374b058e05 100644 --- a/src/vs/code/electron-main/window.ts +++ b/src/vs/code/electron-main/window.ts @@ -7,7 +7,6 @@ import * as path from 'path'; import * as objects from 'vs/base/common/objects'; -import { stopProfiling } from 'vs/base/node/profiler'; import nls = require('vs/nls'); import URI from 'vs/base/common/uri'; import { IStorageService } from 'vs/platform/storage/node/storage'; @@ -522,12 +521,6 @@ export class CodeWindow implements ICodeWindow { } }, 10000); } - - // (--prof-startup) save profile to disk - const { profileStartup } = this.environmentService; - if (profileStartup) { - stopProfiling(profileStartup.dir, profileStartup.prefix).done(undefined, err => this.logService.error(err)); - } } public reload(configuration?: IWindowConfiguration, cli?: ParsedArgs): void { diff --git a/src/vs/code/node/cli.ts b/src/vs/code/node/cli.ts index 4e02f3a3548..b635c77d602 100644 --- a/src/vs/code/node/cli.ts +++ b/src/vs/code/node/cli.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { spawn } from 'child_process'; +import { spawn, ChildProcess } from 'child_process'; import { TPromise } from 'vs/base/common/winjs.base'; import { assign } from 'vs/base/common/objects'; import { parseCLIProcessArgv, buildHelpMessage } from 'vs/platform/environment/node/argv'; @@ -15,6 +15,7 @@ import * as paths from 'path'; import * as os from 'os'; import { whenDeleted } from 'vs/base/node/pfs'; import { writeFileAndFlushSync } from 'vs/base/node/extfs'; +import { findFreePort } from 'vs/base/node/ports'; function shouldSpawnCliProcess(argv: ParsedArgs): boolean { return !!argv['install-source'] @@ -27,7 +28,7 @@ interface IMainCli { main: (argv: ParsedArgs) => TPromise; } -export function main(argv: string[]): TPromise { +export async function main(argv: string[]): TPromise { let args: ParsedArgs; try { @@ -53,8 +54,16 @@ export function main(argv: string[]): TPromise { delete env['ELECTRON_RUN_AS_NODE']; + let processCallbacks: ((child: ChildProcess) => Thenable)[] = []; + if (args.verbose) { env['ELECTRON_ENABLE_LOGGING'] = '1'; + + processCallbacks.push(child => { + child.stdout.on('data', (data: Buffer) => console.log(data.toString('utf8').trim())); + child.stderr.on('data', (data: Buffer) => console.log(data.toString('utf8').trim())); + return new TPromise(c => child.once('exit', () => c(null))); + }); } // If we are started with --wait create a random temporary file @@ -82,6 +91,50 @@ export function main(argv: string[]): TPromise { } } + // If we have been started with `--prof-startup` we need to find free ports to profile + // the main process, the renderer, and the extension host. We also disable v8 cached data + // to get better profile traces. Last, we listen on stdout for a signal that tells us to + // stop profiling. + if (args['prof-startup']) { + + const portMain = await findFreePort(9222, 10, 6000); + const portRenderer = await findFreePort(portMain + 1, 10, 6000); + const portExthost = await findFreePort(portRenderer + 1, 10, 6000); + + if (!portMain || !portRenderer || !portExthost) { + console.error('Failed to find free ports for profiler to connect to do.'); + return; + } + + const filenamePrefix = paths.join(os.homedir(), Math.random().toString(16).slice(-4)); + + argv.push(`--inspect-brk=${portMain}`); + argv.push(`--remote-debugging-port=${portRenderer}`); + argv.push(`--inspect-brk-extensions=${portExthost}`); + argv.push(`--prof-startup-prefix`, filenamePrefix); + argv.push(`--no-cached-data`); + + writeFileAndFlushSync(filenamePrefix, argv.slice(-6).join('|')); + + processCallbacks.push(async child => { + + // load and start profiler + const profiler = await import('v8-inspect-profiler'); + const main = await profiler.startProfiling({ port: portMain }); + const renderer = await profiler.startProfiling({ port: portRenderer, tries: 200 }); + const extHost = await profiler.startProfiling({ port: portExthost, tries: 300 }); + + // wait for the renderer to delete the + // marker file + whenDeleted(filenamePrefix); + + // finally stop profiling and save profiles to disk + await profiler.writeProfile(await main.stop(), `${filenamePrefix}-main.cpuprofile`); + await profiler.writeProfile(await renderer.stop(), `${filenamePrefix}-renderer.cpuprofile`); + await profiler.writeProfile(await extHost.stop(), `${filenamePrefix}-exthost.cpuprofile`); + }); + } + const options = { detached: true, env @@ -93,15 +146,6 @@ export function main(argv: string[]): TPromise { const child = spawn(process.execPath, argv.slice(2), options); - if (args.verbose) { - child.stdout.on('data', (data: Buffer) => console.log(data.toString('utf8').trim())); - child.stderr.on('data', (data: Buffer) => console.log(data.toString('utf8').trim())); - } - - if (args.verbose) { - return new TPromise(c => child.once('exit', () => c(null))); - } - if (args.wait && waitMarkerFilePath) { return new TPromise(c => { @@ -112,6 +156,8 @@ export function main(argv: string[]): TPromise { whenDeleted(waitMarkerFilePath).done(c, c); }); } + + return TPromise.join(processCallbacks.map(callback => callback(child))); } return TPromise.as(null); diff --git a/src/vs/platform/environment/common/environment.ts b/src/vs/platform/environment/common/environment.ts index 8783ac3a2ce..b9ed89196da 100644 --- a/src/vs/platform/environment/common/environment.ts +++ b/src/vs/platform/environment/common/environment.ts @@ -22,6 +22,7 @@ export interface ParsedArgs { 'user-data-dir'?: string; performance?: boolean; 'prof-startup'?: string; + 'prof-startup-prefix'?: string; verbose?: boolean; logExtensionHostCommunication?: boolean; 'disable-extensions'?: boolean; @@ -100,7 +101,6 @@ export interface IEnvironmentService { verbose: boolean; wait: boolean; performance: boolean; - profileStartup: { prefix: string, dir: string } | undefined; skipGettingStarted: boolean | undefined; diff --git a/src/vs/platform/environment/node/environmentService.ts b/src/vs/platform/environment/node/environmentService.ts index d674d6af54f..60b5baba452 100644 --- a/src/vs/platform/environment/node/environmentService.ts +++ b/src/vs/platform/environment/node/environmentService.ts @@ -118,18 +118,6 @@ export class EnvironmentService implements IEnvironmentService { get performance(): boolean { return this._args.performance; } - @memoize - get profileStartup(): { prefix: string, dir: string } | undefined { - if (this._args['prof-startup']) { - return { - prefix: process.env.VSCODE_PROFILES_PREFIX, - dir: os.homedir() - }; - } else { - return undefined; - } - } - @memoize get mainIPCHandle(): string { return getIPCHandle(this.userDataPath, 'main'); } diff --git a/src/vs/workbench/electron-browser/bootstrap/index.js b/src/vs/workbench/electron-browser/bootstrap/index.js index 81bc8dd1fbb..b0b879e7371 100644 --- a/src/vs/workbench/electron-browser/bootstrap/index.js +++ b/src/vs/workbench/electron-browser/bootstrap/index.js @@ -7,11 +7,6 @@ 'use strict'; -if (window.location.search.indexOf('prof-startup') >= 0) { - var profiler = require('v8-profiler'); - profiler.startProfiling('renderer', true); -} - /*global window,document,define,Monaco_Loader_Init*/ const perf = require('../../../base/common/performance'); diff --git a/src/vs/workbench/parts/performance/electron-browser/performance.contribution.ts b/src/vs/workbench/parts/performance/electron-browser/performance.contribution.ts index e1444989978..f2cb7c7ee5b 100644 --- a/src/vs/workbench/parts/performance/electron-browser/performance.contribution.ts +++ b/src/vs/workbench/parts/performance/electron-browser/performance.contribution.ts @@ -15,10 +15,10 @@ import { IWorkbenchContributionsRegistry, IWorkbenchContribution, Extensions } f import { Registry } from 'vs/platform/registry/common/platform'; import { ReportPerformanceIssueAction } from 'vs/workbench/electron-browser/actions'; import { TPromise } from 'vs/base/common/winjs.base'; -import { join } from 'path'; +import { join, dirname } from 'path'; import { localize } from 'vs/nls'; -import { readdir } from 'vs/base/node/pfs'; -import { stopProfiling } from 'vs/base/node/profiler'; +import { readdir, del, readFile } from 'vs/base/node/pfs'; +import { basename } from 'vs/base/common/paths'; class StartupProfiler implements IWorkbenchContribution { @@ -31,55 +31,64 @@ class StartupProfiler implements IWorkbenchContribution { @IExtensionService extensionService: IExtensionService, ) { // wait for everything to be ready - extensionService.whenInstalledExtensionsRegistered().then(() => { + Promise.all([ + lifecycleService.when(LifecyclePhase.Eventually), + extensionService.whenInstalledExtensionsRegistered() + ]).then(() => { this._stopProfiling(); }); } private _stopProfiling(): void { - const { profileStartup } = this._environmentService; - if (!profileStartup) { + const profileFilenamePrefix = this._environmentService.args['prof-startup-prefix']; + if (!profileFilenamePrefix) { return; } - stopProfiling(profileStartup.dir, profileStartup.prefix).then(() => { - readdir(profileStartup.dir).then(files => { - return files.filter(value => value.indexOf(profileStartup.prefix) === 0); - }).then(files => { - const profileFiles = files.reduce((prev, cur) => `${prev}${join(profileStartup.dir, cur)}\n`, '\n'); + const dir = dirname(profileFilenamePrefix); + const prefix = basename(profileFilenamePrefix); - const primaryButton = this._messageService.confirmSync({ - type: 'info', - message: localize('prof.message', "Successfully created profiles."), - detail: localize('prof.detail', "Please create an issue and manually attach the following files:\n{0}", profileFiles), - primaryButton: localize('prof.restartAndFileIssue', "Create Issue and Restart"), - secondaryButton: localize('prof.restart', "Restart") + const removeArgs: string[] = ['--prof-startup']; + const markerFile = readFile(profileFilenamePrefix).then(value => removeArgs.push(...value.toString().split('|'))) + .then(() => del(profileFilenamePrefix)) + .then(() => TPromise.timeout(1000)); + + markerFile.then(() => { + return readdir(dir).then(files => files.filter(value => value.indexOf(prefix) === 0)); + }).then(files => { + const profileFiles = files.reduce((prev, cur) => `${prev}${join(dir, cur)}\n`, '\n'); + + const primaryButton = this._messageService.confirmSync({ + type: 'info', + message: localize('prof.message', "Successfully created profiles."), + detail: localize('prof.detail', "Please create an issue and manually attach the following files:\n{0}", profileFiles), + primaryButton: localize('prof.restartAndFileIssue', "Create Issue and Restart"), + secondaryButton: localize('prof.restart', "Restart") + }); + + if (primaryButton) { + const action = this._instantiationService.createInstance(ReportPerformanceIssueAction, ReportPerformanceIssueAction.ID, ReportPerformanceIssueAction.LABEL); + TPromise.join([ + this._windowsService.showItemInFolder(join(dir, files[0])), + action.run(`:warning: Make sure to **attach** these files from your *home*-directory: :warning:\n${files.map(file => `-\`${file}\``).join('\n')}`) + ]).then(() => { + // keep window stable until restart is selected + this._messageService.confirmSync({ + type: 'info', + message: localize('prof.thanks', "Thanks for helping us."), + detail: localize('prof.detail.restart', "A final restart is required to continue to use '{0}'. Again, thank you for your contribution.", this._environmentService.appNameLong), + primaryButton: localize('prof.restart', "Restart"), + secondaryButton: null + }); + // now we are ready to restart + this._windowsService.relaunch({ removeArgs }); }); - if (primaryButton) { - const action = this._instantiationService.createInstance(ReportPerformanceIssueAction, ReportPerformanceIssueAction.ID, ReportPerformanceIssueAction.LABEL); - TPromise.join([ - this._windowsService.showItemInFolder(join(profileStartup.dir, files[0])), - action.run(`:warning: Make sure to **attach** these files from your *home*-directory: :warning:\n${files.map(file => `-\`${file}\``).join('\n')}`) - ]).then(() => { - // keep window stable until restart is selected - this._messageService.confirmSync({ - type: 'info', - message: localize('prof.thanks', "Thanks for helping us."), - detail: localize('prof.detail.restart', "A final restart is required to continue to use '{0}'. Again, thank you for your contribution.", this._environmentService.appNameLong), - primaryButton: localize('prof.restart', "Restart"), - secondaryButton: null - }); - // now we are ready to restart - this._windowsService.relaunch({ removeArgs: ['--prof-startup'] }); - }); - - } else { - // simply restart - this._windowsService.relaunch({ removeArgs: ['--prof-startup'] }); - } - }); + } else { + // simply restart + this._windowsService.relaunch({ removeArgs }); + } }); } } diff --git a/src/vs/workbench/services/extensions/electron-browser/extensionHost.ts b/src/vs/workbench/services/extensions/electron-browser/extensionHost.ts index df0c9c7e0e5..5ba3c86b6e2 100644 --- a/src/vs/workbench/services/extensions/electron-browser/extensionHost.ts +++ b/src/vs/workbench/services/extensions/electron-browser/extensionHost.ts @@ -265,7 +265,7 @@ export class ExtensionHostProcessWorker { return TPromise.wrap(0); } return new TPromise((c, e) => { - findFreePort(extensionHostPort, 10 /* try 10 ports */, 5000 /* try up to 5 seconds */, (port) => { + return findFreePort(extensionHostPort, 10 /* try 10 ports */, 5000 /* try up to 5 seconds */).then(port => { if (!port) { console.warn('%c[Extension Host] %cCould not find a free port for debugging', 'color: blue', 'color: black'); return c(void 0); diff --git a/yarn.lock b/yarn.lock index d86b8a9d90a..bf3f72e0dc3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -252,6 +252,10 @@ async-each@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.1.tgz#19d386a1d9edc6e7c1c85d388aedbcc56d33602d" +async-limiter@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.0.tgz#78faed8c3d074ab81f22b4e985d79e8738f720f8" + async@1.x, async@^1.4.0, async@^1.5.0: version "1.5.2" resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a" @@ -580,6 +584,13 @@ cheerio@^1.0.0-rc.1: lodash "^4.15.0" parse5 "^3.0.1" +chrome-remote-interface@^0.25.3: + version "0.25.3" + resolved "https://registry.yarnpkg.com/chrome-remote-interface/-/chrome-remote-interface-0.25.3.tgz#b692ae538cd5af3a6dd285636bfab3d29a7006c1" + dependencies: + commander "2.11.x" + ws "3.3.x" + ci-info@^1.0.0: version "1.1.1" resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-1.1.1.tgz#47b44df118c48d2597b56d342e7e25791060171a" @@ -741,6 +752,10 @@ commander@0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/commander/-/commander-0.6.1.tgz#fa68a14f6a945d54dbbe50d8cdb3320e9e3b1a06" +commander@2.11.x, commander@^2.8.1, commander@^2.9.0, commander@~2.11.0: + version "2.11.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.11.0.tgz#157152fd1e7a6c8d98a5b715cf376df928004563" + commander@2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/commander/-/commander-2.3.0.tgz#fd430e889832ec353b9acd1de217c11cb3eef873" @@ -751,10 +766,6 @@ commander@2.8.x: dependencies: graceful-readlink ">= 1.0.0" -commander@^2.8.1, commander@^2.9.0, commander@~2.11.0: - version "2.11.0" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.11.0.tgz#157152fd1e7a6c8d98a5b715cf376df928004563" - commandpost@^1.0.0: version "1.2.1" resolved "https://registry.yarnpkg.com/commandpost/-/commandpost-1.2.1.tgz#2e9c4c7508b9dc704afefaa91cab92ee6054cc68" @@ -3719,7 +3730,7 @@ nan@^2.0.0, nan@^2.6.2: version "2.6.2" resolved "https://registry.yarnpkg.com/nan/-/nan-2.6.2.tgz#e4ff34e6c95fdfb5aecc08de6596f43605a7db45" -nan@^2.0.9, nan@^2.3.0, nan@^2.3.2: +nan@^2.0.9, nan@^2.3.0: version "2.4.0" resolved "https://registry.yarnpkg.com/nan/-/nan-2.4.0.tgz#fb3c59d45fe4effe215f0b890f8adf6eb32d2232" @@ -5466,6 +5477,10 @@ uglify-to-browserify@~1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz#6e0924d6bda6b5afe349e39a6d632850a0f882b7" +ultron@~1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/ultron/-/ultron-1.1.0.tgz#b07a2e6a541a815fc6a34ccd4533baec307ca864" + unc-path-regex@^0.1.0: version "0.1.2" resolved "https://registry.yarnpkg.com/unc-path-regex/-/unc-path-regex-0.1.2.tgz#e73dd3d7b0d7c5ed86fbac6b0ae7d8c6a69d50fa" @@ -5559,11 +5574,11 @@ uuid@^3.0.0, uuid@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.1.0.tgz#3dd3d3e790abc24d7b0d3a034ffababe28ebbc04" -v8-profiler@jrieken/v8-profiler#vscode: - version "5.6.5" - resolved "https://codeload.github.com/jrieken/v8-profiler/tar.gz/5e4a336693e1d5b079c7aecd286a1abcfbc10421" +v8-inspect-profiler@^0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/v8-inspect-profiler/-/v8-inspect-profiler-0.0.6.tgz#7885de7e9c3304118bde25d5b3d6ec5116467f2c" dependencies: - nan "^2.3.2" + chrome-remote-interface "^0.25.3" v8flags@^2.0.2: version "2.1.1" @@ -5850,6 +5865,14 @@ write@^0.2.1: dependencies: mkdirp "^0.5.1" +ws@3.3.x: + version "3.3.2" + resolved "https://registry.yarnpkg.com/ws/-/ws-3.3.2.tgz#96c1d08b3fefda1d5c1e33700d3bfaa9be2d5608" + dependencies: + async-limiter "~1.0.0" + safe-buffer "~5.1.0" + ultron "~1.1.0" + xml-name-validator@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-1.0.0.tgz#dcf82ee092322951ef8cc1ba596c9cbfd14a83f1"