Title: [153763] trunk
Revision
153763
Author
[email protected]
Date
2013-08-06 14:20:10 -0700 (Tue, 06 Aug 2013)

Log Message

Delay Arguments creation in strict mode
https://bugs.webkit.org/show_bug.cgi?id=119505

Reviewed by Geoffrey Garen.

Source/_javascript_Core:

Make use of the write tracking performed by the parser to
allow us to know if we're modifying the parameters to a function.
Then use that information to make strict mode function opt out
of eager arguments creation.

* bytecompiler/BytecodeGenerator.cpp:
(JSC::BytecodeGenerator::BytecodeGenerator):
(JSC::BytecodeGenerator::createArgumentsIfNecessary):
(JSC::BytecodeGenerator::emitReturn):
* bytecompiler/BytecodeGenerator.h:
(JSC::BytecodeGenerator::shouldTearOffArgumentsEagerly):
* parser/Nodes.h:
(JSC::ScopeNode::modifiesParameter):
* parser/Parser.cpp:
(JSC::::parseInner):
* parser/Parser.h:
(JSC::Scope::declareParameter):
(JSC::Scope::getCapturedVariables):
(JSC::Parser::declareWrite):
* parser/ParserModes.h:

LayoutTests:

Add performance testcase for lazy creation of arguments in strict mode

* fast/js/regress/delay-tear-off-arguments-strictmode-expected.txt: Added.
* fast/js/regress/delay-tear-off-arguments-strictmode.html: Added.
* fast/js/regress/script-tests/delay-tear-off-arguments-strictmode.js: Added.
(bar):

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (153762 => 153763)


--- trunk/LayoutTests/ChangeLog	2013-08-06 20:51:22 UTC (rev 153762)
+++ trunk/LayoutTests/ChangeLog	2013-08-06 21:20:10 UTC (rev 153763)
@@ -1,3 +1,17 @@
+2013-08-06  Oliver Hunt  <[email protected]>
+
+        Delay Arguments creation in strict mode
+        https://bugs.webkit.org/show_bug.cgi?id=119505
+
+        Reviewed by Geoffrey Garen.
+
+        Add performance testcase for lazy creation of arguments in strict mode
+
+        * fast/js/regress/delay-tear-off-arguments-strictmode-expected.txt: Added.
+        * fast/js/regress/delay-tear-off-arguments-strictmode.html: Added.
+        * fast/js/regress/script-tests/delay-tear-off-arguments-strictmode.js: Added.
+        (bar):
+
 2013-08-06  Bem Jones-Bey  <[email protected]>
 
         [CSS Shapes] New positioning model: support for shape-margin

Added: trunk/LayoutTests/fast/js/regress/delay-tear-off-arguments-strictmode-expected.txt (0 => 153763)


--- trunk/LayoutTests/fast/js/regress/delay-tear-off-arguments-strictmode-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/js/regress/delay-tear-off-arguments-strictmode-expected.txt	2013-08-06 21:20:10 UTC (rev 153763)
@@ -0,0 +1,10 @@
+JSRegress/delay-tear-off-arguments-strictmode
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS no exception thrown
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Added: trunk/LayoutTests/fast/js/regress/delay-tear-off-arguments-strictmode.html (0 => 153763)


--- trunk/LayoutTests/fast/js/regress/delay-tear-off-arguments-strictmode.html	                        (rev 0)
+++ trunk/LayoutTests/fast/js/regress/delay-tear-off-arguments-strictmode.html	2013-08-06 21:20:10 UTC (rev 153763)
@@ -0,0 +1,12 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<script src=""
+</head>
+<body>
+<script src=""
+<script src=""
+<script src=""
+<script src=""
+</body>
+</html>

Added: trunk/LayoutTests/fast/js/regress/script-tests/delay-tear-off-arguments-strictmode.js (0 => 153763)


--- trunk/LayoutTests/fast/js/regress/script-tests/delay-tear-off-arguments-strictmode.js	                        (rev 0)
+++ trunk/LayoutTests/fast/js/regress/script-tests/delay-tear-off-arguments-strictmode.js	2013-08-06 21:20:10 UTC (rev 153763)
@@ -0,0 +1,15 @@
+function bar(x)
+{
+	"use strict";
+    var result = 0;
+    for (var i = 0; i < arguments.length; ++i)
+        result += arguments[i];
+    return result;
+}
+
+var result = 0;
+for (var i = 0; i < 100000; ++i)
+    result += bar(i, i + 1, i + 2, i + 3);
+
+if (result != 20000400000)
+    throw "Bad result: " + result;

Modified: trunk/Source/_javascript_Core/ChangeLog (153762 => 153763)


--- trunk/Source/_javascript_Core/ChangeLog	2013-08-06 20:51:22 UTC (rev 153762)
+++ trunk/Source/_javascript_Core/ChangeLog	2013-08-06 21:20:10 UTC (rev 153763)
@@ -1,3 +1,31 @@
+2013-08-05  Oliver Hunt  <[email protected]>
+
+        Delay Arguments creation in strict mode
+        https://bugs.webkit.org/show_bug.cgi?id=119505
+
+        Reviewed by Geoffrey Garen.
+
+        Make use of the write tracking performed by the parser to
+        allow us to know if we're modifying the parameters to a function.
+        Then use that information to make strict mode function opt out
+        of eager arguments creation.
+
+        * bytecompiler/BytecodeGenerator.cpp:
+        (JSC::BytecodeGenerator::BytecodeGenerator):
+        (JSC::BytecodeGenerator::createArgumentsIfNecessary):
+        (JSC::BytecodeGenerator::emitReturn):
+        * bytecompiler/BytecodeGenerator.h:
+        (JSC::BytecodeGenerator::shouldTearOffArgumentsEagerly):
+        * parser/Nodes.h:
+        (JSC::ScopeNode::modifiesParameter):
+        * parser/Parser.cpp:
+        (JSC::::parseInner):
+        * parser/Parser.h:
+        (JSC::Scope::declareParameter):
+        (JSC::Scope::getCapturedVariables):
+        (JSC::Parser::declareWrite):
+        * parser/ParserModes.h:
+
 2013-08-06  Patrick Gansterer  <[email protected]>
 
         Remove useless code from COMPILER(RVCT) JITStubs

Modified: trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.cpp (153762 => 153763)


--- trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.cpp	2013-08-06 20:51:22 UTC (rev 153762)
+++ trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.cpp	2013-08-06 21:20:10 UTC (rev 153763)
@@ -238,7 +238,7 @@
         emitInitLazyRegister(argumentsRegister);
         emitInitLazyRegister(unmodifiedArgumentsRegister);
         
-        if (m_codeBlock->isStrictMode()) {
+        if (shouldTearOffArgumentsEagerly()) {
             emitOpcode(op_create_arguments);
             instructions().append(argumentsRegister->index());
         }
@@ -268,7 +268,7 @@
         }
     }
 
-    if (capturesAnyArgumentByName && !codeBlock->isStrictMode()) {
+    if (capturesAnyArgumentByName && !shouldTearOffArgumentsEagerly()) {
         size_t parameterCount = m_symbolTable->parameterCount();
         OwnArrayPtr<SlowArgument> slowArguments = adoptArrayPtr(new SlowArgument[parameterCount]);
         for (size_t i = 0; i < parameterCount; ++i) {
@@ -1559,10 +1559,7 @@
     if (!m_codeBlock->usesArguments())
         return;
 
-    // If we're in strict mode we tear off the arguments on function
-    // entry, so there's no need to check if we need to create them
-    // now
-    if (m_codeBlock->isStrictMode())
+    if (shouldTearOffArgumentsEagerly())
         return;
 
     emitOpcode(op_create_arguments);
@@ -1749,7 +1746,7 @@
         instructions().append(m_activationRegister->index());
     }
 
-    if (m_codeBlock->usesArguments() && m_codeBlock->numParameters() != 1 && !m_codeBlock->isStrictMode()) {
+    if (m_codeBlock->usesArguments() && m_codeBlock->numParameters() != 1 && !isStrictMode()) {
         emitOpcode(op_tear_off_arguments);
         instructions().append(m_codeBlock->argumentsRegister());
         instructions().append(m_activationRegister ? m_activationRegister->index() : emitLoad(0, JSValue())->index());

Modified: trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.h (153762 => 153763)


--- trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.h	2013-08-06 20:51:22 UTC (rev 153762)
+++ trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.h	2013-08-06 21:20:10 UTC (rev 153763)
@@ -554,6 +554,11 @@
             return true;
         }
 
+        bool shouldTearOffArgumentsEagerly()
+        {
+            return m_codeType == FunctionCode && isStrictMode() && m_scopeNode->modifiesParameter();
+        }
+
         RegisterID* emitThrowExpressionTooDeepException();
 
         void createArgumentsIfNecessary();

Modified: trunk/Source/_javascript_Core/parser/Nodes.h (153762 => 153763)


--- trunk/Source/_javascript_Core/parser/Nodes.h	2013-08-06 20:51:22 UTC (rev 153762)
+++ trunk/Source/_javascript_Core/parser/Nodes.h	2013-08-06 21:20:10 UTC (rev 153763)
@@ -1385,6 +1385,7 @@
 
         bool usesEval() const { return m_features & EvalFeature; }
         bool usesArguments() const { return (m_features & ArgumentsFeature) && !(m_features & ShadowsArgumentsFeature); }
+        bool modifiesParameter() const { return m_features & ModifiedParameterFeature; }
         bool isStrictMode() const { return m_features & StrictModeFeature; }
         void setUsesArguments() { m_features |= ArgumentsFeature; }
         bool usesThis() const { return m_features & ThisFeature; }

Modified: trunk/Source/_javascript_Core/parser/Parser.cpp (153762 => 153763)


--- trunk/Source/_javascript_Core/parser/Parser.cpp	2013-08-06 20:51:22 UTC (rev 153762)
+++ trunk/Source/_javascript_Core/parser/Parser.cpp	2013-08-06 21:20:10 UTC (rev 153763)
@@ -121,12 +121,15 @@
     }
 
     IdentifierSet capturedVariables;
-    scope->getCapturedVariables(capturedVariables);
+    bool modifiedParameter = false;
+    scope->getCapturedVariables(capturedVariables, modifiedParameter);
     CodeFeatures features = context.features();
     if (scope->strictMode())
         features |= StrictModeFeature;
     if (scope->shadowsArguments())
         features |= ShadowsArgumentsFeature;
+    if (modifiedParameter)
+        features |= ModifiedParameterFeature;
 
     didFinishParsing(sourceElements, context.varDeclarations(), context.funcDeclarations(), features,
         context.numConstants(), capturedVariables);

Modified: trunk/Source/_javascript_Core/parser/Parser.h (153762 => 153763)


--- trunk/Source/_javascript_Core/parser/Parser.h	2013-08-06 20:51:22 UTC (rev 153762)
+++ trunk/Source/_javascript_Core/parser/Parser.h	2013-08-06 21:20:10 UTC (rev 153763)
@@ -217,6 +217,8 @@
         bool isArguments = m_vm->propertyNames->arguments == *ident;
         bool isValidStrictMode = m_declaredVariables.add(ident->string().impl()).isNewEntry && m_vm->propertyNames->eval != *ident && !isArguments;
         m_isValidStrictMode = m_isValidStrictMode && isValidStrictMode;
+        m_declaredParameters.add(ident->string().impl());
+
         if (isArguments)
             m_shadowsArguments = true;
         return isValidStrictMode;
@@ -254,18 +256,10 @@
         return true;
     }
 
-    void getUncapturedWrittenVariables(IdentifierSet& writtenVariables)
+    void getCapturedVariables(IdentifierSet& capturedVariables, bool& modifiedParameter)
     {
-        IdentifierSet::iterator end = m_writtenVariables.end();
-        for (IdentifierSet::iterator ptr = m_writtenVariables.begin(); ptr != end; ++ptr) {
-            if (!m_declaredVariables.contains(*ptr))
-                writtenVariables.add(*ptr);
-        }
-    }
-
-    void getCapturedVariables(IdentifierSet& capturedVariables)
-    {
         if (m_needsFullActivation || m_usesEval) {
+            modifiedParameter = true;
             capturedVariables.swap(m_declaredVariables);
             return;
         }
@@ -274,6 +268,16 @@
                 continue;
             capturedVariables.add(*ptr);
         }
+        modifiedParameter = false;
+        if (m_declaredParameters.size()) {
+            IdentifierSet::iterator end = m_writtenVariables.end();
+            for (IdentifierSet::iterator ptr = m_writtenVariables.begin(); ptr != end; ++ptr) {
+                if (!m_declaredParameters.contains(*ptr))
+                    continue;
+                modifiedParameter = true;
+                break;
+            }
+        }
     }
     void setStrictMode() { m_strictMode = true; }
     bool strictMode() const { return m_strictMode; }
@@ -327,6 +331,7 @@
 
     typedef Vector<ScopeLabelInfo, 2> LabelStack;
     OwnPtr<LabelStack> m_labels;
+    IdentifierSet m_declaredParameters;
     IdentifierSet m_declaredVariables;
     IdentifierSet m_usedVariables;
     IdentifierSet m_closedVariables;
@@ -460,7 +465,7 @@
     
     void declareWrite(const Identifier* ident)
     {
-        if (!m_syntaxAlreadyValidated)
+        if (!m_syntaxAlreadyValidated || strictMode())
             m_scopeStack.last().declareWrite(ident);
     }
     

Modified: trunk/Source/_javascript_Core/parser/ParserModes.h (153762 => 153763)


--- trunk/Source/_javascript_Core/parser/ParserModes.h	2013-08-06 20:51:22 UTC (rev 153762)
+++ trunk/Source/_javascript_Core/parser/ParserModes.h	2013-08-06 21:20:10 UTC (rev 153763)
@@ -47,8 +47,9 @@
 const CodeFeatures ThisFeature = 1 << 4;
 const CodeFeatures StrictModeFeature = 1 << 5;
 const CodeFeatures ShadowsArgumentsFeature = 1 << 6;
+const CodeFeatures ModifiedParameterFeature = 1 << 7;
 
-const CodeFeatures AllFeatures = EvalFeature | ArgumentsFeature | WithFeature | CatchFeature | ThisFeature | StrictModeFeature | ShadowsArgumentsFeature;
+const CodeFeatures AllFeatures = EvalFeature | ArgumentsFeature | WithFeature | CatchFeature | ThisFeature | StrictModeFeature | ShadowsArgumentsFeature | ModifiedParameterFeature;
 
 } // namespace JSC
 
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to