Title: [140947] trunk/Source/_javascript_Core
Revision
140947
Author
[email protected]
Date
2013-01-27 22:46:36 -0800 (Sun, 27 Jan 2013)

Log Message

JSC: FunctionParameters are memory hungry.
<http://webkit.org/b/108033>
<rdar://problem/13094803>

Reviewed by Sam Weinig.

Instead of inheriting from Vector<Identifier>, make FunctionParameters a simple fixed-size array
with a custom-allocating create() function. Removes one step of indirection and cuts memory usage
roughly in half.

2.73 MB progression on Membuster3.

* bytecode/UnlinkedCodeBlock.cpp:
(JSC::UnlinkedFunctionExecutable::paramString):
* bytecompiler/BytecodeGenerator.cpp:
(JSC::BytecodeGenerator::BytecodeGenerator):
* parser/Nodes.cpp:
(JSC::FunctionParameters::create):
(JSC::FunctionParameters::FunctionParameters):
(JSC::FunctionParameters::~FunctionParameters):
* parser/Nodes.h:
(FunctionParameters):
(JSC::FunctionParameters::size):
(JSC::FunctionParameters::at):
(JSC::FunctionParameters::identifiers):

Modified Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (140946 => 140947)


--- trunk/Source/_javascript_Core/ChangeLog	2013-01-28 06:38:14 UTC (rev 140946)
+++ trunk/Source/_javascript_Core/ChangeLog	2013-01-28 06:46:36 UTC (rev 140947)
@@ -1,5 +1,33 @@
 2013-01-27  Andreas Kling  <[email protected]>
 
+        JSC: FunctionParameters are memory hungry.
+        <http://webkit.org/b/108033>
+        <rdar://problem/13094803>
+
+        Reviewed by Sam Weinig.
+
+        Instead of inheriting from Vector<Identifier>, make FunctionParameters a simple fixed-size array
+        with a custom-allocating create() function. Removes one step of indirection and cuts memory usage
+        roughly in half.
+
+        2.73 MB progression on Membuster3.
+
+        * bytecode/UnlinkedCodeBlock.cpp:
+        (JSC::UnlinkedFunctionExecutable::paramString):
+        * bytecompiler/BytecodeGenerator.cpp:
+        (JSC::BytecodeGenerator::BytecodeGenerator):
+        * parser/Nodes.cpp:
+        (JSC::FunctionParameters::create):
+        (JSC::FunctionParameters::FunctionParameters):
+        (JSC::FunctionParameters::~FunctionParameters):
+        * parser/Nodes.h:
+        (FunctionParameters):
+        (JSC::FunctionParameters::size):
+        (JSC::FunctionParameters::at):
+        (JSC::FunctionParameters::identifiers):
+
+2013-01-27  Andreas Kling  <[email protected]>
+
         JSC: SourceProviderCache is memory hungry.
         <http://webkit.org/b/108029>
         <rdar://problem/13094806>

Modified: trunk/Source/_javascript_Core/bytecode/UnlinkedCodeBlock.cpp (140946 => 140947)


--- trunk/Source/_javascript_Core/bytecode/UnlinkedCodeBlock.cpp	2013-01-28 06:38:14 UTC (rev 140946)
+++ trunk/Source/_javascript_Core/bytecode/UnlinkedCodeBlock.cpp	2013-01-28 06:46:36 UTC (rev 140947)
@@ -150,7 +150,7 @@
     for (size_t pos = 0; pos < parameters.size(); ++pos) {
         if (!builder.isEmpty())
             builder.appendLiteral(", ");
-        builder.append(parameters[pos].string());
+        builder.append(parameters.at(pos).string());
     }
     return builder.toString();
 }

Modified: trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.cpp (140946 => 140947)


--- trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.cpp	2013-01-28 06:38:14 UTC (rev 140946)
+++ trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.cpp	2013-01-28 06:46:36 UTC (rev 140947)
@@ -360,7 +360,7 @@
         capturedArguments.resize(parameters.size());
         for (size_t i = 0; i < parameters.size(); ++i) {
             capturedArguments[i] = 0;
-            if (!functionBody->captures(parameters[i]) && !shouldCaptureAllTheThings)
+            if (!functionBody->captures(parameters.at(i)) && !shouldCaptureAllTheThings)
                 continue;
             capturesAnyArgumentByName = true;
             capturedArguments[i] = addVar();
@@ -461,12 +461,12 @@
     for (size_t i = 0; i < parameters.size(); ++i, --nextParameterIndex) {
         int index = nextParameterIndex;
         if (capturedArguments.size() && capturedArguments[i]) {
-            ASSERT((functionBody->hasCapturedVariables() && functionBody->captures(parameters[i])) || shouldCaptureAllTheThings);
+            ASSERT((functionBody->hasCapturedVariables() && functionBody->captures(parameters.at(i))) || shouldCaptureAllTheThings);
             index = capturedArguments[i]->index();
             RegisterID original(nextParameterIndex);
             emitMove(capturedArguments[i], &original);
         }
-        addParameter(parameters[i], index);
+        addParameter(parameters.at(i), index);
     }
     preserveLastVar();
 

Modified: trunk/Source/_javascript_Core/parser/Nodes.cpp (140946 => 140947)


--- trunk/Source/_javascript_Core/parser/Nodes.cpp	2013-01-28 06:38:14 UTC (rev 140946)
+++ trunk/Source/_javascript_Core/parser/Nodes.cpp	2013-01-28 06:46:36 UTC (rev 140947)
@@ -151,18 +151,31 @@
 
 // ------------------------------ FunctionBodyNode -----------------------------
 
-FunctionParameters::FunctionParameters(ParameterNode* firstParameter)
+PassRefPtr<FunctionParameters> FunctionParameters::create(ParameterNode* firstParameter)
 {
     unsigned parameterCount = 0;
     for (ParameterNode* parameter = firstParameter; parameter; parameter = parameter->nextParam())
         ++parameterCount;
 
-    reserveInitialCapacity(parameterCount);
+    size_t objectSize = sizeof(FunctionParameters) - sizeof(void*) + sizeof(StringImpl*) * parameterCount;
+    void* slot = fastMalloc(objectSize);
+    return adoptRef(new (slot) FunctionParameters(firstParameter, parameterCount));
+}
 
+FunctionParameters::FunctionParameters(ParameterNode* firstParameter, unsigned size)
+    : m_size(size)
+{
+    unsigned i = 0;
     for (ParameterNode* parameter = firstParameter; parameter; parameter = parameter->nextParam())
-        uncheckedAppend(parameter->ident());
+        new (&identifiers()[i++]) Identifier(parameter->ident());
 }
 
+FunctionParameters::~FunctionParameters()
+{
+    for (unsigned i = 0; i < m_size; ++i)
+        identifiers()[i].~Identifier();
+}
+
 inline FunctionBodyNode::FunctionBodyNode(JSGlobalData* globalData, const JSTokenLocation& location, bool inStrictContext)
     : ScopeNode(globalData, location, inStrictContext)
 {

Modified: trunk/Source/_javascript_Core/parser/Nodes.h (140946 => 140947)


--- trunk/Source/_javascript_Core/parser/Nodes.h	2013-01-28 06:38:14 UTC (rev 140946)
+++ trunk/Source/_javascript_Core/parser/Nodes.h	2013-01-28 06:46:36 UTC (rev 140947)
@@ -1393,13 +1393,23 @@
         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
     };
 
-    class FunctionParameters : public Vector<Identifier>, public RefCounted<FunctionParameters> {
+    class FunctionParameters : public RefCounted<FunctionParameters> {
         WTF_MAKE_FAST_ALLOCATED;
     public:
-        static PassRefPtr<FunctionParameters> create(ParameterNode* firstParameter) { return adoptRef(new FunctionParameters(firstParameter)); }
+        static PassRefPtr<FunctionParameters> create(ParameterNode*);
+        ~FunctionParameters();
 
+        unsigned size() const { return m_size; }
+        const Identifier& at(unsigned index) const { ASSERT(index < m_size); return identifiers()[index]; }
+
     private:
-        FunctionParameters(ParameterNode*);
+        FunctionParameters(ParameterNode*, unsigned size);
+
+        Identifier* identifiers() { return reinterpret_cast<Identifier*>(&m_storage); }
+        const Identifier* identifiers() const { return reinterpret_cast<const Identifier*>(&m_storage); }
+
+        unsigned m_size;
+        void* m_storage;
     };
 
     enum FunctionNameIsInScopeToggle { FunctionNameIsNotInScope, FunctionNameIsInScope };
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to