From d3cc119901554c48b9fc609ca3d22de8d26f2352 Mon Sep 17 00:00:00 2001 From: Tobias Koppers Date: Wed, 12 Sep 2018 09:56:14 +0200 Subject: [PATCH 1/3] Fix a memory leak in Error objects https://crbug.com/v8/7142 --- packages/jest-jasmine2/src/jasmine/Spec.js | 6 ++++++ packages/jest-jasmine2/src/jasmine_async.js | 12 ++++++++++++ 2 files changed, 18 insertions(+) diff --git a/packages/jest-jasmine2/src/jasmine/Spec.js b/packages/jest-jasmine2/src/jasmine/Spec.js index e9016b7e9fb0..807c3c168f75 100644 --- a/packages/jest-jasmine2/src/jasmine/Spec.js +++ b/packages/jest-jasmine2/src/jasmine/Spec.js @@ -66,6 +66,12 @@ export default function Spec(attrs: Object) { this.initError = new Error(); this.initError.name = ''; + // Without this line v8 stores references to all closures + // in the stack in the Error object. This line stringifies the stack + // property to allow garbage-collecting objects on the stack + // https://crbug.com/v8/7142 + this.initError.stack = this.initError.stack; + this.queueableFn.initError = this.initError; this.result = { diff --git a/packages/jest-jasmine2/src/jasmine_async.js b/packages/jest-jasmine2/src/jasmine_async.js index d7bb10c481b0..1eaf0a8f2a4f 100644 --- a/packages/jest-jasmine2/src/jasmine_async.js +++ b/packages/jest-jasmine2/src/jasmine_async.js @@ -37,6 +37,12 @@ function promisifyLifeCycleFunction(originalFn, env) { const extraError = new Error(); + // Without this line v8 stores references to all closures + // in the stack in the Error object. This line stringifies the stack + // property to allow garbage-collecting objects on the stack + // https://crbug.com/v8/7142 + extraError.stack = extraError.stack; + // We make *all* functions async and run `done` right away if they // didn't return a promise. const asyncJestLifecycle = function(done) { @@ -79,6 +85,12 @@ function promisifyIt(originalFn, env) { const extraError = new Error(); + // Without this line v8 stores references to all closures + // in the stack in the Error object. This line stringifies the stack + // property to allow garbage-collecting objects on the stack + // https://crbug.com/v8/7142 + extraError.stack = extraError.stack; + const asyncJestTest = function(done) { const wrappedFn = isGeneratorFn(fn) ? co.wrap(fn) : fn; const returnValue = wrappedFn.call({}); From f4f4ed1a482cc2b7147e4b9f3b0eece09aa203b9 Mon Sep 17 00:00:00 2001 From: Tobias Koppers Date: Wed, 12 Sep 2018 10:34:32 +0200 Subject: [PATCH 2/3] Fix stack when changing message Stack was evaluated early, so we need to fix it when changing the message --- packages/jest-jasmine2/src/queue_runner.js | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/jest-jasmine2/src/queue_runner.js b/packages/jest-jasmine2/src/queue_runner.js index 5155a43374ef..d72ec1bfabbd 100644 --- a/packages/jest-jasmine2/src/queue_runner.js +++ b/packages/jest-jasmine2/src/queue_runner.js @@ -73,6 +73,7 @@ export default function queueRunner(options: Options) { 'Timeout - Async callback was not invoked within the ' + timeoutMs + 'ms timeout specified by jest.setTimeout.'; + initError.stack = initError.message + initError.stack; options.onException(initError); }, ); From 57b557a708c44331b7062f26255615132cc2e5d1 Mon Sep 17 00:00:00 2001 From: Tobias Koppers Date: Sat, 15 Sep 2018 21:38:55 +0200 Subject: [PATCH 3/3] Update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 37191ffdcc36..0cc18fc14391 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ### Fixes - `[jest-haste-map]` [**BREAKING**] Replaced internal data structures to improve performance ([#6960](https://github.com/facebook/jest/pull/6960)) +- `[jest-jasmine2]` Fix memory leak in Error objects hold by the framework ([#6965](https://github.com/facebook/jest/pull/6965)) ### Chore & Maintenance