Title: [140945] trunk/Source/_javascript_Core
- Revision
- 140945
- Author
- [email protected]
- Date
- 2013-01-27 22:34:03 -0800 (Sun, 27 Jan 2013)
Log Message
JSC: SourceProviderCache is memory hungry.
<http://webkit.org/b/108029>
<rdar://problem/13094806>
Reviewed by Sam Weinig.
Use fixed-size arrays for SourceProviderCacheItem's lists of captured variables.
Since the lists never change after the object is created, there's no need to keep them in Vectors
and we can instead create the whole cache item in a single allocation.
13.37 MB progression on Membuster3.
* parser/Parser.cpp:
(JSC::::parseFunctionInfo):
* parser/Parser.h:
(JSC::Scope::copyCapturedVariablesToVector):
(JSC::Scope::fillParametersForSourceProviderCache):
(JSC::Scope::restoreFromSourceProviderCache):
* parser/SourceProviderCacheItem.h:
(SourceProviderCacheItemCreationParameters):
(SourceProviderCacheItem):
(JSC::SourceProviderCacheItem::approximateByteSize):
(JSC::SourceProviderCacheItem::usedVariables):
(JSC::SourceProviderCacheItem::writtenVariables):
(JSC::SourceProviderCacheItem::~SourceProviderCacheItem):
(JSC::SourceProviderCacheItem::create):
(JSC::SourceProviderCacheItem::SourceProviderCacheItem):
Modified Paths
Diff
Modified: trunk/Source/_javascript_Core/ChangeLog (140944 => 140945)
--- trunk/Source/_javascript_Core/ChangeLog 2013-01-28 06:15:45 UTC (rev 140944)
+++ trunk/Source/_javascript_Core/ChangeLog 2013-01-28 06:34:03 UTC (rev 140945)
@@ -1,3 +1,33 @@
+2013-01-27 Andreas Kling <[email protected]>
+
+ JSC: SourceProviderCache is memory hungry.
+ <http://webkit.org/b/108029>
+ <rdar://problem/13094806>
+
+ Reviewed by Sam Weinig.
+
+ Use fixed-size arrays for SourceProviderCacheItem's lists of captured variables.
+ Since the lists never change after the object is created, there's no need to keep them in Vectors
+ and we can instead create the whole cache item in a single allocation.
+
+ 13.37 MB progression on Membuster3.
+
+ * parser/Parser.cpp:
+ (JSC::::parseFunctionInfo):
+ * parser/Parser.h:
+ (JSC::Scope::copyCapturedVariablesToVector):
+ (JSC::Scope::fillParametersForSourceProviderCache):
+ (JSC::Scope::restoreFromSourceProviderCache):
+ * parser/SourceProviderCacheItem.h:
+ (SourceProviderCacheItemCreationParameters):
+ (SourceProviderCacheItem):
+ (JSC::SourceProviderCacheItem::approximateByteSize):
+ (JSC::SourceProviderCacheItem::usedVariables):
+ (JSC::SourceProviderCacheItem::writtenVariables):
+ (JSC::SourceProviderCacheItem::~SourceProviderCacheItem):
+ (JSC::SourceProviderCacheItem::create):
+ (JSC::SourceProviderCacheItem::SourceProviderCacheItem):
+
2013-01-27 Zoltan Arvai <[email protected]>
Fixing atomicIncrement implementation for Windows by dropping support before XP SP2.
Modified: trunk/Source/_javascript_Core/parser/Parser.cpp (140944 => 140945)
--- trunk/Source/_javascript_Core/parser/Parser.cpp 2013-01-28 06:15:45 UTC (rev 140944)
+++ trunk/Source/_javascript_Core/parser/Parser.cpp 2013-01-28 06:34:03 UTC (rev 140945)
@@ -838,7 +838,7 @@
ASSERT(!strictMode() || cachedInfo->strictMode);
body = context.createFunctionBody(location, cachedInfo->strictMode);
- functionScope->restoreFunctionInfo(cachedInfo);
+ functionScope->restoreFromSourceProviderCache(cachedInfo);
failIfFalse(popScope(functionScope, TreeBuilder::NeedsFreeVariableInfo));
closeBracePos = cachedInfo->closeBracePos;
@@ -867,8 +867,12 @@
OwnPtr<SourceProviderCacheItem> newInfo;
int functionLength = closeBracePos - openBracePos;
if (TreeBuilder::CanUseFunctionCache && m_functionCache && functionLength > minimumFunctionLengthToCache) {
- newInfo = adoptPtr(new SourceProviderCacheItem(functionStart, m_token.m_location.line, closeBracePos));
- functionScope->saveFunctionInfo(newInfo.get());
+ SourceProviderCacheItemCreationParameters parameters;
+ parameters.functionStart = functionStart;
+ parameters.closeBraceLine = m_token.m_location.line;
+ parameters.closeBracePos = closeBracePos;
+ functionScope->fillParametersForSourceProviderCache(parameters);
+ newInfo = SourceProviderCacheItem::create(parameters);
}
context.setFunctionStart(body, functionStart);
Modified: trunk/Source/_javascript_Core/parser/Parser.h (140944 => 140945)
--- trunk/Source/_javascript_Core/parser/Parser.h 2013-01-28 06:15:45 UTC (rev 140944)
+++ trunk/Source/_javascript_Core/parser/Parser.h 2013-01-28 06:34:03 UTC (rev 140945)
@@ -328,31 +328,28 @@
continue;
vector.append(*it);
}
- vector.shrinkToFit();
}
- void saveFunctionInfo(SourceProviderCacheItem* info)
+ void fillParametersForSourceProviderCache(SourceProviderCacheItemCreationParameters& parameters)
{
ASSERT(m_isFunction);
- info->usesEval = m_usesEval;
- info->strictMode = m_strictMode;
- info->needsFullActivation = m_needsFullActivation;
- copyCapturedVariablesToVector(m_writtenVariables, info->writtenVariables);
- copyCapturedVariablesToVector(m_usedVariables, info->usedVariables);
+ parameters.usesEval = m_usesEval;
+ parameters.strictMode = m_strictMode;
+ parameters.needsFullActivation = m_needsFullActivation;
+ copyCapturedVariablesToVector(m_writtenVariables, parameters.writtenVariables);
+ copyCapturedVariablesToVector(m_usedVariables, parameters.usedVariables);
}
- void restoreFunctionInfo(const SourceProviderCacheItem* info)
+ void restoreFromSourceProviderCache(const SourceProviderCacheItem* info)
{
ASSERT(m_isFunction);
m_usesEval = info->usesEval;
m_strictMode = info->strictMode;
m_needsFullActivation = info->needsFullActivation;
- unsigned size = info->usedVariables.size();
- for (unsigned i = 0; i < size; ++i)
- m_usedVariables.add(info->usedVariables[i]);
- size = info->writtenVariables.size();
- for (unsigned i = 0; i < size; ++i)
- m_writtenVariables.add(info->writtenVariables[i]);
+ for (unsigned i = 0; i < info->usedVariablesCount; ++i)
+ m_usedVariables.add(info->usedVariables()[i]);
+ for (unsigned i = 0; i < info->writtenVariablesCount; ++i)
+ m_writtenVariables.add(info->writtenVariables()[i]);
}
private:
Modified: trunk/Source/_javascript_Core/parser/SourceProviderCacheItem.h (140944 => 140945)
--- trunk/Source/_javascript_Core/parser/SourceProviderCacheItem.h 2013-01-28 06:15:45 UTC (rev 140944)
+++ trunk/Source/_javascript_Core/parser/SourceProviderCacheItem.h 2013-01-28 06:34:03 UTC (rev 140945)
@@ -27,27 +27,41 @@
#define SourceProviderCacheItem_h
#include "ParserTokens.h"
+#include <wtf/PassOwnPtr.h>
#include <wtf/Vector.h>
#include <wtf/text/WTFString.h>
namespace JSC {
+struct SourceProviderCacheItemCreationParameters {
+ unsigned functionStart;
+ unsigned closeBraceLine;
+ unsigned closeBracePos;
+ bool needsFullActivation;
+ bool usesEval;
+ bool strictMode;
+ Vector<RefPtr<StringImpl> > usedVariables;
+ Vector<RefPtr<StringImpl> > writtenVariables;
+};
+
+#if COMPILER(MSVC)
+#pragma warning(push)
+#pragma warning(disable: 4200) // Disable "zero-sized array in struct/union" warning
+#endif
+
class SourceProviderCacheItem {
WTF_MAKE_FAST_ALLOCATED;
public:
- SourceProviderCacheItem(unsigned functionStart, unsigned closeBraceLine, unsigned closeBracePos)
- : functionStart(functionStart)
- , closeBraceLine(closeBraceLine)
- , closeBracePos(closeBracePos)
- {
- }
+ static PassOwnPtr<SourceProviderCacheItem> create(const SourceProviderCacheItemCreationParameters&);
+ ~SourceProviderCacheItem();
+
unsigned approximateByteSize() const
{
// The identifiers are uniqued strings so most likely there are few names that actually use any additional memory.
- static const unsigned assummedAverageIdentifierSize = sizeof(RefPtr<StringImpl>) + 2;
+ static const unsigned assumedAverageIdentifierSize = sizeof(StringImpl*) + 2;
unsigned size = sizeof(*this);
- size += usedVariables.size() * assummedAverageIdentifierSize;
- size += writtenVariables.size() * assummedAverageIdentifierSize;
+ size += usedVariablesCount * assumedAverageIdentifierSize;
+ size += writtenVariablesCount * assumedAverageIdentifierSize;
return size;
}
JSToken closeBraceToken() const
@@ -70,10 +84,57 @@
unsigned closeBracePos : 31;
bool strictMode : 1;
- Vector<RefPtr<StringImpl> > usedVariables;
- Vector<RefPtr<StringImpl> > writtenVariables;
+ unsigned usedVariablesCount;
+ unsigned writtenVariablesCount;
+
+ StringImpl** usedVariables() const { return const_cast<StringImpl**>(m_variables); }
+ StringImpl** writtenVariables() const { return const_cast<StringImpl**>(&m_variables[usedVariablesCount]); }
+
+private:
+ SourceProviderCacheItem(const SourceProviderCacheItemCreationParameters&);
+
+ StringImpl* m_variables[0];
};
+inline SourceProviderCacheItem::~SourceProviderCacheItem()
+{
+ for (unsigned i = 0; i < usedVariablesCount + writtenVariablesCount; ++i)
+ m_variables[i]->deref();
}
+inline PassOwnPtr<SourceProviderCacheItem> SourceProviderCacheItem::create(const SourceProviderCacheItemCreationParameters& parameters)
+{
+ size_t variableCount = parameters.writtenVariables.size() + parameters.usedVariables.size();
+ size_t objectSize = sizeof(SourceProviderCacheItem) + sizeof(StringImpl*) * variableCount;
+ void* slot = fastMalloc(objectSize);
+ return adoptPtr(new (slot) SourceProviderCacheItem(parameters));
+}
+
+inline SourceProviderCacheItem::SourceProviderCacheItem(const SourceProviderCacheItemCreationParameters& parameters)
+ : functionStart(parameters.functionStart)
+ , needsFullActivation(parameters.needsFullActivation)
+ , closeBraceLine(parameters.closeBraceLine)
+ , usesEval(parameters.usesEval)
+ , closeBracePos(parameters.closeBracePos)
+ , strictMode(parameters.strictMode)
+ , usedVariablesCount(parameters.usedVariables.size())
+ , writtenVariablesCount(parameters.writtenVariables.size())
+{
+ unsigned j = 0;
+ for (unsigned i = 0; i < usedVariablesCount; ++i, ++j) {
+ m_variables[j] = parameters.usedVariables[i].get();
+ m_variables[j]->ref();
+ }
+ for (unsigned i = 0; i < writtenVariablesCount; ++i, ++j) {
+ m_variables[j] = parameters.writtenVariables[i].get();
+ m_variables[j]->ref();
+ }
+}
+
+#if COMPILER(MSVC)
+#pragma warning(pop)
+#endif
+
+}
+
#endif // SourceProviderCacheItem_h
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo/webkit-changes