Changeset 167272 in webkit
- Timestamp:
- Apr 14, 2014 3:05:44 PM (10 years ago)
- Location:
- trunk
- Files:
-
- 3 added
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r167261 r167272 1 2014-04-14 Oliver Hunt <oliver@apple.com> 2 3 Function.bind itself is too slow 4 https://bugs.webkit.org/show_bug.cgi?id=131636 5 6 Reviewed by Geoffrey Garen. 7 8 New test, and fix bogus log in old one 9 10 * js/regress/function-bind-create-expected.html: Added. 11 * js/regress/function-bind-create.html: Added. 12 * js/regress/script-tests/function-bind-create.js: Added. 13 (test): 14 * js/regress/script-tests/function-bind.js: 15 1 16 2014-04-14 Brian J. Burg <burg@cs.washington.edu> 2 17 -
trunk/LayoutTests/js/regress/script-tests/function-bind.js
r167199 r167272 7 7 var g2 = foo.bind({}, 1, 2); 8 8 var g3 = foo.bind({}, 1, 2, 3); 9 var start = new Date;10 9 11 10 var result = 0; … … 24 23 result |= 0; 25 24 } 26 print((new Date - start))27 25 if (result != 1596499010) 28 26 throw "Bad result: " + result; -
trunk/Source/JavaScriptCore/ChangeLog
r167269 r167272 1 2014-04-14 Oliver Hunt <oliver@apple.com> 2 3 Function.bind itself is too slow 4 https://bugs.webkit.org/show_bug.cgi?id=131636 5 6 Reviewed by Geoffrey Garen. 7 8 Rather than forcing creation of an activation, we now store 9 bound function properties directly on the returned closure. 10 This is necessary to deal with code that creates many function 11 bindings, but does not call them very often. 12 13 This is a 60% speed up in the included js/regress test. 14 15 * builtins/BuiltinExecutables.cpp: 16 (JSC::BuiltinExecutables::createBuiltinExecutable): 17 * builtins/Function.prototype.js: 18 (bind.bindingFunction): 19 (bind.else.switch.case.1.bindingFunction.bindingFunction.bindingFunction.boundOversizedCallThunk): 20 (bind.else.switch.case.1.bindingFunction): 21 (bind.else.switch.case.2.bindingFunction.bindingFunction.bindingFunction.boundOversizedCallThunk): 22 (bind.else.switch.case.2.bindingFunction): 23 (bind.else.switch.case.3.bindingFunction.bindingFunction.bindingFunction.boundOversizedCallThunk): 24 (bind.else.switch.case.3.bindingFunction): 25 (bind.else.switch.bindingFunction): 26 (bind): 27 (bind.else.switch.case.1.bindingFunction.oversizedCall): Deleted. 28 (bind.else.switch.case.2.bindingFunction.oversizedCall): Deleted. 29 (bind.else.switch.case.3.bindingFunction.oversizedCall): Deleted. 30 * runtime/CommonIdentifiers.h: 31 1 32 2014-04-14 Julien Brianceau <jbriance@cisco.com> 2 33 -
trunk/Source/JavaScriptCore/builtins/Function.prototype.js
r167199 r167272 41 41 throw new @TypeError("Cannot bind non-function object."); 42 42 var bindingFunction; 43 var oversizedCall = undefined;44 43 if (arguments.length <= 1) { 45 bindingFunction = function () { 44 bindingFunction = function bindingFunction() { 45 var thisValue = bindingFunction.@boundThisValue; 46 var boundFunction = bindingFunction.@boundFunction; 46 47 if (@IsConstructor) 47 48 return new boundFunction(...arguments); … … 52 53 switch (length - 1 /* skip thisValue */) { 53 54 case 1: { 54 var boundParameter = arguments[1]; 55 bindingFunction = function () { 55 bindingFunction = function bindingFunction() { 56 var thisValue = bindingFunction.@boundThisValue; 57 var boundFunction = bindingFunction.@boundFunction; 58 var boundParameter = bindingFunction.@boundParameter; 56 59 var argumentLength = arguments.length; 57 60 if (!argumentLength) { … … 76 79 } 77 80 var completeArguments = [boundParameter, ...arguments]; 78 if (! oversizedCall) {79 oversizedCall= function (isConstruct, boundFunction, thisValue, completeArguments) {81 if (!bindingFunction.@boundOversizedCallThunk) { 82 bindingFunction.@boundOversizedCallThunk = function (isConstruct, boundFunction, thisValue, completeArguments) { 80 83 if (isConstruct) 81 84 return new boundFunction(...completeArguments); … … 83 86 } 84 87 } 85 return oversizedCall(@IsConstructor, boundFunction, thisValue, completeArguments); 86 } 88 return bindingFunction.@boundOversizedCallThunk(@IsConstructor, boundFunction, thisValue, completeArguments); 89 } 90 bindingFunction.@boundParameter = arguments[1]; 87 91 break; 88 92 } 89 93 case 2: { 90 var boundParameter1 = arguments[1]; 91 var boundParameter2 = arguments[2]; 92 bindingFunction = function () { 94 bindingFunction = function bindingFunction() { 95 var thisValue = bindingFunction.@boundThisValue; 96 var boundFunction = bindingFunction.@boundFunction; 97 var boundParameter1 = bindingFunction.@boundParameter1; 98 var boundParameter2 = bindingFunction.@boundParameter2; 93 99 if (!arguments.length) { 94 100 if (@IsConstructor) … … 112 118 } 113 119 var completeArguments = [boundParameter1, boundParameter2, ...arguments]; 114 if (! oversizedCall) {115 oversizedCall= function (isConstruct, boundFunction, thisValue, completeArguments) {120 if (!bindingFunction.@boundOversizedCallThunk) { 121 bindingFunction.@boundOversizedCallThunk = function (isConstruct, boundFunction, thisValue, completeArguments) { 116 122 if (isConstruct) 117 123 return new boundFunction(...completeArguments); … … 119 125 } 120 126 } 121 return oversizedCall(@IsConstructor, boundFunction, thisValue, completeArguments); 122 } 127 return bindingFunction.@boundOversizedCallThunk(@IsConstructor, boundFunction, thisValue, completeArguments); 128 } 129 bindingFunction.@boundParameter1 = arguments[1]; 130 bindingFunction.@boundParameter2 = arguments[2]; 123 131 break; 124 132 } 125 133 case 3: { 126 var boundParameter1 = arguments[1]; 127 var boundParameter2 = arguments[2]; 128 var boundParameter3 = arguments[3]; 129 bindingFunction = function () { 134 bindingFunction = function bindingFunction() { 135 var thisValue = bindingFunction.@boundThisValue; 136 var boundFunction = bindingFunction.@boundFunction; 137 var boundParameter1 = bindingFunction.@boundParameter1; 138 var boundParameter2 = bindingFunction.@boundParameter2; 139 var boundParameter3 = bindingFunction.@boundParameter3; 130 140 if (!arguments.length) { 131 141 if (@IsConstructor) … … 149 159 } 150 160 var completeArguments = [boundParameter1, boundParameter2, boundParameter3, ...arguments]; 151 if (! oversizedCall) {152 oversizedCall= function (isConstruct, boundFunction, thisValue, completeArguments) {161 if (!bindingFunction.@boundOversizedCallThunk) { 162 bindingFunction.@boundOversizedCallThunk = function (isConstruct, boundFunction, thisValue, completeArguments) { 153 163 if (isConstruct) 154 164 return new boundFunction(...completeArguments); … … 156 166 } 157 167 } 158 return oversizedCall(@IsConstructor, boundFunction, thisValue, completeArguments); 159 } 168 return bindingFunction.@boundOversizedCallThunk(@IsConstructor, boundFunction, thisValue, completeArguments); 169 } 170 bindingFunction.@boundParameter1 = arguments[1]; 171 bindingFunction.@boundParameter2 = arguments[2]; 172 bindingFunction.@boundParameter3 = arguments[3]; 160 173 break; 161 174 } … … 165 178 boundParameters[i - 1] = arguments[i]; 166 179 167 bindingFunction = function () { 180 bindingFunction = function bindingFunction() { 181 var thisValue = bindingFunction.@boundThisValue; 182 var boundFunction = bindingFunction.@boundFunction; 183 var boundParameters = bindingFunction.@boundParameters; 168 184 if (!arguments.length) { 169 185 if (@IsConstructor) 170 return new boundFunction(... boundParameters);186 return new boundFunction(...@boundParameters); 171 187 return boundFunction.@apply(thisValue, boundParameters); 172 188 } 173 189 174 190 var completeArguments = []; 175 var localBoundParameters = boundParameters; 176 var boundLength = localBoundParameters.length; 191 var boundLength = boundParameters.length; 177 192 for (var i = 0; i < boundLength; i++) 178 completeArguments[i] = localBoundParameters[i];193 completeArguments[i] = boundParameters[i]; 179 194 for (var i = 0; i < arguments.length; i++) 180 195 completeArguments[i + boundLength] = arguments[i]; … … 184 199 return boundFunction.@apply(thisValue, completeArguments); 185 200 } 201 bindingFunction.@boundParameters = boundParameters; 186 202 } 187 203 } 204 bindingFunction.@boundThisValue = thisValue; 188 205 bindingFunction.@boundFunctionName = this.name; 189 206 bindingFunction.@boundFunction = boundFunction.@boundFunction || boundFunction; -
trunk/Source/JavaScriptCore/runtime/CommonIdentifiers.h
r167199 r167272 224 224 macro(boundFunctionName) \ 225 225 macro(boundFunctionParameters) \ 226 macro(boundThisValue) \ 227 macro(boundParameter) \ 228 macro(boundParameter1) \ 229 macro(boundParameter2) \ 230 macro(boundParameter3) \ 231 macro(boundParameters) \ 232 macro(boundOversizedCallThunk) \ 226 233 macro(boundFunction) \ 227 234 macro(boundFunctionLength) \
Note: See TracChangeset
for help on using the changeset viewer.