From df0d9d05a3c8ef382ceb9508a606b19cf9a47e77 Mon Sep 17 00:00:00 2001 From: Benedikt Meurer Date: Sat, 28 Oct 2017 22:16:05 +0200 Subject: [PATCH] Fix hasRest to not try to load "-1" from params array. (#6581) Similar in spirit to https://github.com/babel/babel/pull/6580, the current implementation did ```js node.params[node.params.length - 1] ``` where `node.params` can also be empty, which causes it to lookup the property `"-1"`, which is not found on the array itself and obviously also not in the `Object.prototype` and the `Array.prototype`. However since `"-1"` is not a valid array index, but has a valid integer representation, this is a very expensive lookup in V8 (and probably other engines too, but that is probably less relevant, since Babel most often runs on Node nowadays). In V8 this causes a call to the `%SetProperty` runtime function for each of these `"-1"` property lookups, and in addition sends the whole `KeyedLoadIC` to `MEGAMORPHIC` state, which also penalizes other accesses on this line. This is a small non-breaking performance fix. --- packages/babel-plugin-transform-es2015-parameters/src/rest.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/babel-plugin-transform-es2015-parameters/src/rest.js b/packages/babel-plugin-transform-es2015-parameters/src/rest.js index 6bd61d5707..9e4013e14f 100644 --- a/packages/babel-plugin-transform-es2015-parameters/src/rest.js +++ b/packages/babel-plugin-transform-es2015-parameters/src/rest.js @@ -155,7 +155,8 @@ const memberExpressionOptimisationVisitor = { }, }; function hasRest(node) { - return t.isRestElement(node.params[node.params.length - 1]); + const length = node.params.length; + return length > 0 && t.isRestElement(node.params[length - 1]); } function optimiseIndexGetter(path, argsId, offset) {