From 6c89cd3fdecaf5709b8f7b9f4dd1afb6c6a5cab5 Mon Sep 17 00:00:00 2001 From: "fpizlo@apple.com" Date: Tue, 26 Jun 2012 19:42:05 +0000 Subject: [PATCH] DFG::operationNewArray is unnecessarily slow, and may use the wrong array prototype when inlined https://bugs.webkit.org/show_bug.cgi?id=89821 Source/JavaScriptCore: Reviewed by Geoffrey Garen. Fixes all array allocations to use the right structure, and hence the right prototype. Adds inlining of new Array(...) with a non-zero number of arguments. Optimizes allocations of empty arrays. * dfg/DFGAbstractState.cpp: (JSC::DFG::AbstractState::execute): * dfg/DFGByteCodeParser.cpp: (JSC::DFG::ByteCodeParser::handleConstantInternalFunction): * dfg/DFGCCallHelpers.h: (JSC::DFG::CCallHelpers::setupArgumentsWithExecState): (CCallHelpers): * dfg/DFGNodeType.h: (DFG): * dfg/DFGOperations.cpp: * dfg/DFGOperations.h: * dfg/DFGPredictionPropagationPhase.cpp: (JSC::DFG::PredictionPropagationPhase::propagate): * dfg/DFGSpeculativeJIT.h: (JSC::DFG::SpeculativeJIT::callOperation): * dfg/DFGSpeculativeJIT32_64.cpp: (JSC::DFG::SpeculativeJIT::compile): * dfg/DFGSpeculativeJIT64.cpp: (JSC::DFG::SpeculativeJIT::compile): * runtime/JSArray.h: (JSC): (JSC::constructArray): * runtime/JSGlobalObject.h: (JSC): (JSC::constructArray): LayoutTests: Rubber stamped by Geoffrey Garen. * fast/js/dfg-cross-global-object-inline-new-array-expected.txt: Added. * fast/js/dfg-cross-global-object-inline-new-array-literal-expected.txt: Added. * fast/js/dfg-cross-global-object-inline-new-array-literal-with-variables-expected.txt: Added. * fast/js/dfg-cross-global-object-inline-new-array-literal-with-variables.html: Added. * fast/js/dfg-cross-global-object-inline-new-array-literal.html: Added. * fast/js/dfg-cross-global-object-inline-new-array-with-elements-expected.txt: Added. * fast/js/dfg-cross-global-object-inline-new-array-with-elements.html: Added. * fast/js/dfg-cross-global-object-inline-new-array-with-size-expected.txt: Added. * fast/js/dfg-cross-global-object-inline-new-array-with-size.html: Added. * fast/js/dfg-cross-global-object-inline-new-array.html: Added. * fast/js/script-tests/cross-global-object-inline-global-var.js: (done): * fast/js/script-tests/dfg-cross-global-object-inline-new-array-literal-with-variables.js: Added. (foo): (done): (doit): * fast/js/script-tests/dfg-cross-global-object-inline-new-array-literal.js: Added. (foo): (done): (doit): * fast/js/script-tests/dfg-cross-global-object-inline-new-array-with-elements.js: Added. (foo): (done): (doit): * fast/js/script-tests/dfg-cross-global-object-inline-new-array-with-size.js: Added. (foo): (done): (doit): * fast/js/script-tests/dfg-cross-global-object-inline-new-array.js: Added. (foo): (done): (doit): git-svn-id: http://svn.webkit.org/repository/webkit/trunk@121280 268f45cc-cd09-0410-ab3c-d52691b4dbfc --- LayoutTests/ChangeLog | 41 ++++++++++ ...oss-global-object-inline-new-array-expected.txt | 10 +++ ...al-object-inline-new-array-literal-expected.txt | 10 +++ ...e-new-array-literal-with-variables-expected.txt | 10 +++ ...ct-inline-new-array-literal-with-variables.html | 11 +++ ...oss-global-object-inline-new-array-literal.html | 11 +++ ...ect-inline-new-array-with-elements-expected.txt | 10 +++ ...obal-object-inline-new-array-with-elements.html | 11 +++ ...-object-inline-new-array-with-size-expected.txt | 10 +++ ...s-global-object-inline-new-array-with-size.html | 11 +++ .../dfg-cross-global-object-inline-new-array.html | 11 +++ .../cross-global-object-inline-global-var.js | 2 +- ...ject-inline-new-array-literal-with-variables.js | 47 ++++++++++++ ...cross-global-object-inline-new-array-literal.js | 47 ++++++++++++ ...global-object-inline-new-array-with-elements.js | 47 ++++++++++++ ...oss-global-object-inline-new-array-with-size.js | 47 ++++++++++++ .../dfg-cross-global-object-inline-new-array.js | 45 +++++++++++ Source/JavaScriptCore/ChangeLog | 38 +++++++++ Source/JavaScriptCore/dfg/DFGAbstractState.cpp | 10 ++- Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp | 12 ++- Source/JavaScriptCore/dfg/DFGCCallHelpers.h | 25 ++++++ Source/JavaScriptCore/dfg/DFGNodeType.h | 1 + Source/JavaScriptCore/dfg/DFGOperations.cpp | 14 +++- Source/JavaScriptCore/dfg/DFGOperations.h | 7 +- .../dfg/DFGPredictionPropagationPhase.cpp | 6 ++ Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h | 30 ++++++++ .../JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp | 89 +++++++++++++++++----- Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp | 79 ++++++++++++++----- Source/JavaScriptCore/runtime/JSArray.h | 37 ++++++++- Source/JavaScriptCore/runtime/JSGlobalObject.h | 31 +------- 30 files changed, 684 insertions(+), 76 deletions(-) create mode 100644 LayoutTests/fast/js/dfg-cross-global-object-inline-new-array-expected.txt create mode 100644 LayoutTests/fast/js/dfg-cross-global-object-inline-new-array-literal-expected.txt create mode 100644 LayoutTests/fast/js/dfg-cross-global-object-inline-new-array-literal-with-variables-expected.txt create mode 100644 LayoutTests/fast/js/dfg-cross-global-object-inline-new-array-literal-with-variables.html create mode 100644 LayoutTests/fast/js/dfg-cross-global-object-inline-new-array-literal.html create mode 100644 LayoutTests/fast/js/dfg-cross-global-object-inline-new-array-with-elements-expected.txt create mode 100644 LayoutTests/fast/js/dfg-cross-global-object-inline-new-array-with-elements.html create mode 100644 LayoutTests/fast/js/dfg-cross-global-object-inline-new-array-with-size-expected.txt create mode 100644 LayoutTests/fast/js/dfg-cross-global-object-inline-new-array-with-size.html create mode 100644 LayoutTests/fast/js/dfg-cross-global-object-inline-new-array.html create mode 100644 LayoutTests/fast/js/script-tests/dfg-cross-global-object-inline-new-array-literal-with-variables.js create mode 100644 LayoutTests/fast/js/script-tests/dfg-cross-global-object-inline-new-array-literal.js create mode 100644 LayoutTests/fast/js/script-tests/dfg-cross-global-object-inline-new-array-with-elements.js create mode 100644 LayoutTests/fast/js/script-tests/dfg-cross-global-object-inline-new-array-with-size.js create mode 100644 LayoutTests/fast/js/script-tests/dfg-cross-global-object-inline-new-array.js diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog index a01cac9..e12d7b9 100644 --- a/LayoutTests/ChangeLog +++ b/LayoutTests/ChangeLog @@ -1,3 +1,44 @@ +2012-06-26 Filip Pizlo + + DFG::operationNewArray is unnecessarily slow, and may use the wrong array + prototype when inlined + https://bugs.webkit.org/show_bug.cgi?id=89821 + + Rubber stamped by Geoffrey Garen. + + * fast/js/dfg-cross-global-object-inline-new-array-expected.txt: Added. + * fast/js/dfg-cross-global-object-inline-new-array-literal-expected.txt: Added. + * fast/js/dfg-cross-global-object-inline-new-array-literal-with-variables-expected.txt: Added. + * fast/js/dfg-cross-global-object-inline-new-array-literal-with-variables.html: Added. + * fast/js/dfg-cross-global-object-inline-new-array-literal.html: Added. + * fast/js/dfg-cross-global-object-inline-new-array-with-elements-expected.txt: Added. + * fast/js/dfg-cross-global-object-inline-new-array-with-elements.html: Added. + * fast/js/dfg-cross-global-object-inline-new-array-with-size-expected.txt: Added. + * fast/js/dfg-cross-global-object-inline-new-array-with-size.html: Added. + * fast/js/dfg-cross-global-object-inline-new-array.html: Added. + * fast/js/script-tests/cross-global-object-inline-global-var.js: + (done): + * fast/js/script-tests/dfg-cross-global-object-inline-new-array-literal-with-variables.js: Added. + (foo): + (done): + (doit): + * fast/js/script-tests/dfg-cross-global-object-inline-new-array-literal.js: Added. + (foo): + (done): + (doit): + * fast/js/script-tests/dfg-cross-global-object-inline-new-array-with-elements.js: Added. + (foo): + (done): + (doit): + * fast/js/script-tests/dfg-cross-global-object-inline-new-array-with-size.js: Added. + (foo): + (done): + (doit): + * fast/js/script-tests/dfg-cross-global-object-inline-new-array.js: Added. + (foo): + (done): + (doit): + 2012-06-26 Adam Klein MutationObserver.observe should treat a null or undefined options argument as empty diff --git a/LayoutTests/fast/js/dfg-cross-global-object-inline-new-array-expected.txt b/LayoutTests/fast/js/dfg-cross-global-object-inline-new-array-expected.txt new file mode 100644 index 0000000..5c3c32d --- /dev/null +++ b/LayoutTests/fast/js/dfg-cross-global-object-inline-new-array-expected.txt @@ -0,0 +1,10 @@ +This tests that function inlining in the DFG JIT doesn't get confused about the global object to use for array allocation. + +On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". + + +PASS successfullyParsed is true + +TEST COMPLETE +PASS done() called with 4800 + diff --git a/LayoutTests/fast/js/dfg-cross-global-object-inline-new-array-literal-expected.txt b/LayoutTests/fast/js/dfg-cross-global-object-inline-new-array-literal-expected.txt new file mode 100644 index 0000000..a821b43 --- /dev/null +++ b/LayoutTests/fast/js/dfg-cross-global-object-inline-new-array-literal-expected.txt @@ -0,0 +1,10 @@ +This tests that function inlining in the DFG JIT doesn't get confused about the global object to use for array allocation. + +On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". + + +PASS successfullyParsed is true + +TEST COMPLETE +PASS done() called with 6600 + diff --git a/LayoutTests/fast/js/dfg-cross-global-object-inline-new-array-literal-with-variables-expected.txt b/LayoutTests/fast/js/dfg-cross-global-object-inline-new-array-literal-with-variables-expected.txt new file mode 100644 index 0000000..ebfb059 --- /dev/null +++ b/LayoutTests/fast/js/dfg-cross-global-object-inline-new-array-literal-with-variables-expected.txt @@ -0,0 +1,10 @@ +This tests that function inlining in the DFG JIT doesn't get confused about the global object to use for array allocation. + +On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". + + +PASS successfullyParsed is true + +TEST COMPLETE +PASS done() called with 85200 + diff --git a/LayoutTests/fast/js/dfg-cross-global-object-inline-new-array-literal-with-variables.html b/LayoutTests/fast/js/dfg-cross-global-object-inline-new-array-literal-with-variables.html new file mode 100644 index 0000000..768c292 --- /dev/null +++ b/LayoutTests/fast/js/dfg-cross-global-object-inline-new-array-literal-with-variables.html @@ -0,0 +1,11 @@ + + + + + + +
+ + + + diff --git a/LayoutTests/fast/js/dfg-cross-global-object-inline-new-array-literal.html b/LayoutTests/fast/js/dfg-cross-global-object-inline-new-array-literal.html new file mode 100644 index 0000000..da12ec0 --- /dev/null +++ b/LayoutTests/fast/js/dfg-cross-global-object-inline-new-array-literal.html @@ -0,0 +1,11 @@ + + + + + + +
+ + + + diff --git a/LayoutTests/fast/js/dfg-cross-global-object-inline-new-array-with-elements-expected.txt b/LayoutTests/fast/js/dfg-cross-global-object-inline-new-array-with-elements-expected.txt new file mode 100644 index 0000000..a821b43 --- /dev/null +++ b/LayoutTests/fast/js/dfg-cross-global-object-inline-new-array-with-elements-expected.txt @@ -0,0 +1,10 @@ +This tests that function inlining in the DFG JIT doesn't get confused about the global object to use for array allocation. + +On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". + + +PASS successfullyParsed is true + +TEST COMPLETE +PASS done() called with 6600 + diff --git a/LayoutTests/fast/js/dfg-cross-global-object-inline-new-array-with-elements.html b/LayoutTests/fast/js/dfg-cross-global-object-inline-new-array-with-elements.html new file mode 100644 index 0000000..6ae416c --- /dev/null +++ b/LayoutTests/fast/js/dfg-cross-global-object-inline-new-array-with-elements.html @@ -0,0 +1,11 @@ + + + + + + +
+ + + + diff --git a/LayoutTests/fast/js/dfg-cross-global-object-inline-new-array-with-size-expected.txt b/LayoutTests/fast/js/dfg-cross-global-object-inline-new-array-with-size-expected.txt new file mode 100644 index 0000000..9657740 --- /dev/null +++ b/LayoutTests/fast/js/dfg-cross-global-object-inline-new-array-with-size-expected.txt @@ -0,0 +1,10 @@ +This tests that function inlining in the DFG JIT doesn't get confused about the global object to use for array allocation. + +On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". + + +PASS successfullyParsed is true + +TEST COMPLETE +PASS done() called with 204800 + diff --git a/LayoutTests/fast/js/dfg-cross-global-object-inline-new-array-with-size.html b/LayoutTests/fast/js/dfg-cross-global-object-inline-new-array-with-size.html new file mode 100644 index 0000000..901f765 --- /dev/null +++ b/LayoutTests/fast/js/dfg-cross-global-object-inline-new-array-with-size.html @@ -0,0 +1,11 @@ + + + + + + +
+ + + + diff --git a/LayoutTests/fast/js/dfg-cross-global-object-inline-new-array.html b/LayoutTests/fast/js/dfg-cross-global-object-inline-new-array.html new file mode 100644 index 0000000..d07fb90 --- /dev/null +++ b/LayoutTests/fast/js/dfg-cross-global-object-inline-new-array.html @@ -0,0 +1,11 @@ + + + + + + +
+ + + + diff --git a/LayoutTests/fast/js/script-tests/cross-global-object-inline-global-var.js b/LayoutTests/fast/js/script-tests/cross-global-object-inline-global-var.js index bedd549..23fefd1 100644 --- a/LayoutTests/fast/js/script-tests/cross-global-object-inline-global-var.js +++ b/LayoutTests/fast/js/script-tests/cross-global-object-inline-global-var.js @@ -18,7 +18,7 @@ function done(value) { if (value == expected) testPassed("done() called with " + expected); else - testFailed("done() is " + value + " and should be " + expected + "."); + testFailed("done() called with " + value + ", but expected " + expected); layoutTestController.notifyDone(); } diff --git a/LayoutTests/fast/js/script-tests/dfg-cross-global-object-inline-new-array-literal-with-variables.js b/LayoutTests/fast/js/script-tests/dfg-cross-global-object-inline-new-array-literal-with-variables.js new file mode 100644 index 0000000..09f135a --- /dev/null +++ b/LayoutTests/fast/js/script-tests/dfg-cross-global-object-inline-new-array-literal-with-variables.js @@ -0,0 +1,47 @@ +description( +"This tests that function inlining in the DFG JIT doesn't get confused about the global object to use for array allocation." +); + +if (window.layoutTestController) + layoutTestController.waitUntilDone(); + +function foo(x) { + return [x, x + 1, x * 2]; +} + +Array.prototype.thingy = 24; + +function done(value) { + var expected = (24 + 3) * 200 + 19900 + 20100 + 39800; + if (value == expected) + testPassed("done() called with " + expected); + else + testFailed("done() called with " + value + ", but expected " + expected); + layoutTestController.notifyDone(); +} + +function doit() { + document.getElementById("frameparent").innerHTML = ""; + document.getElementById("frameparent").innerHTML = "