- Revision
- 117198
- Author
- [email protected]
- Date
- 2012-05-15 17:56:54 -0700 (Tue, 15 May 2012)
Log Message
shrinkToFit() is often not called for Vectors in CodeBlock
https://bugs.webkit.org/show_bug.cgi?id=86436
Source/_javascript_Core:
Reviewed by Oliver Hunt.
The vectors in CodeBlock are often appended to during various stages of
compilation, but we neglect to shrink them after compilation finishes. This
patch takes the most brutal possible approach: shrink all the vectors after
the bytecompile phase, and then shrink them again after the appropriate
JITing phase. The two shrinks are necessary because the JIT may append more
stuff, but may also generate code that directly references things in other
vectors; hence some can only be shrunk before JIT and some after. Also,
we may allow a CodeBlock to sit around for a long time - possibly forever -
before invoking the JIT, hence it makes sense to have two shrinks.
This is performance neutral on the major benchmarks we track.
* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::shrinkToFit):
* bytecode/CodeBlock.h:
(CodeBlock):
(JSC::CodeBlock::appendWeakReferenceTransition):
* bytecompiler/BytecodeGenerator.cpp:
(JSC::BytecodeGenerator::generate):
* dfg/DFGDriver.cpp:
(JSC::DFG::compile):
* dfg/DFGJITCompiler.cpp:
(JSC::DFG::JITCompiler::link):
* jit/JIT.cpp:
(JSC::JIT::privateCompile):
Source/WTF:
Reviewed by NOBODY (OOPS!).
Gave SegmentedVector a shrinkToFit() method. This only shrinks the segment
lookup table, which is likely to not be hugely profitable, but it is better
than nothing.
* wtf/SegmentedVector.h:
(SegmentedVector):
(WTF::SegmentedVector::shrinkToFit):
Modified Paths
Diff
Modified: trunk/Source/_javascript_Core/ChangeLog (117197 => 117198)
--- trunk/Source/_javascript_Core/ChangeLog 2012-05-16 00:56:34 UTC (rev 117197)
+++ trunk/Source/_javascript_Core/ChangeLog 2012-05-16 00:56:54 UTC (rev 117198)
@@ -1,3 +1,36 @@
+2012-05-15 Filip Pizlo <[email protected]>
+
+ shrinkToFit() is often not called for Vectors in CodeBlock
+ https://bugs.webkit.org/show_bug.cgi?id=86436
+
+ Reviewed by Oliver Hunt.
+
+ The vectors in CodeBlock are often appended to during various stages of
+ compilation, but we neglect to shrink them after compilation finishes. This
+ patch takes the most brutal possible approach: shrink all the vectors after
+ the bytecompile phase, and then shrink them again after the appropriate
+ JITing phase. The two shrinks are necessary because the JIT may append more
+ stuff, but may also generate code that directly references things in other
+ vectors; hence some can only be shrunk before JIT and some after. Also,
+ we may allow a CodeBlock to sit around for a long time - possibly forever -
+ before invoking the JIT, hence it makes sense to have two shrinks.
+
+ This is performance neutral on the major benchmarks we track.
+
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::shrinkToFit):
+ * bytecode/CodeBlock.h:
+ (CodeBlock):
+ (JSC::CodeBlock::appendWeakReferenceTransition):
+ * bytecompiler/BytecodeGenerator.cpp:
+ (JSC::BytecodeGenerator::generate):
+ * dfg/DFGDriver.cpp:
+ (JSC::DFG::compile):
+ * dfg/DFGJITCompiler.cpp:
+ (JSC::DFG::JITCompiler::link):
+ * jit/JIT.cpp:
+ (JSC::JIT::privateCompile):
+
2012-05-15 Oliver Hunt <[email protected]>
Make error information available even if all we have is line number information.
Modified: trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp (117197 => 117198)
--- trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp 2012-05-16 00:56:34 UTC (rev 117197)
+++ trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp 2012-05-16 00:56:54 UTC (rev 117198)
@@ -2092,23 +2092,34 @@
}
#endif
-void CodeBlock::shrinkToFit()
+void CodeBlock::shrinkToFit(ShrinkMode shrinkMode)
{
-#if ENABLE(CLASSIC_INTERPRETER)
m_propertyAccessInstructions.shrinkToFit();
m_globalResolveInstructions.shrinkToFit();
+#if ENABLE(LLINT)
+ m_llintCallLinkInfos.shrinkToFit();
#endif
#if ENABLE(JIT)
m_structureStubInfos.shrinkToFit();
m_globalResolveInfos.shrinkToFit();
m_callLinkInfos.shrinkToFit();
+ m_methodCallLinkInfos.shrinkToFit();
#endif
+#if ENABLE(VALUE_PROFILER)
+ if (shrinkMode == EarlyShrink)
+ m_argumentValueProfiles.shrinkToFit();
+ m_valueProfiles.shrinkToFit();
+ m_rareCaseProfiles.shrinkToFit();
+ m_specialFastCaseProfiles.shrinkToFit();
+#endif
+
+ if (shrinkMode == EarlyShrink) {
+ m_identifiers.shrinkToFit();
+ m_functionDecls.shrinkToFit();
+ m_functionExprs.shrinkToFit();
+ m_constantRegisters.shrinkToFit();
+ } // else don't shrink these, because we would have already pointed pointers into these tables.
- m_identifiers.shrinkToFit();
- m_functionDecls.shrinkToFit();
- m_functionExprs.shrinkToFit();
- m_constantRegisters.shrinkToFit();
-
if (m_rareData) {
m_rareData->m_exceptionHandlers.shrinkToFit();
m_rareData->m_regexps.shrinkToFit();
@@ -2117,7 +2128,24 @@
m_rareData->m_stringSwitchJumpTables.shrinkToFit();
m_rareData->m_expressionInfo.shrinkToFit();
m_rareData->m_lineInfo.shrinkToFit();
+#if ENABLE(JIT)
+ m_rareData->m_callReturnIndexVector.shrinkToFit();
+#endif
+#if ENABLE(DFG_JIT)
+ m_rareData->m_inlineCallFrames.shrinkToFit();
+ m_rareData->m_codeOrigins.shrinkToFit();
+#endif
}
+
+#if ENABLE(DFG_JIT)
+ if (m_dfgData) {
+ m_dfgData->osrEntry.shrinkToFit();
+ m_dfgData->osrExit.shrinkToFit();
+ m_dfgData->speculationRecovery.shrinkToFit();
+ m_dfgData->weakReferences.shrinkToFit();
+ m_dfgData->transitions.shrinkToFit();
+ }
+#endif
}
void CodeBlock::createActivation(CallFrame* callFrame)
Modified: trunk/Source/_javascript_Core/bytecode/CodeBlock.h (117197 => 117198)
--- trunk/Source/_javascript_Core/bytecode/CodeBlock.h 2012-05-16 00:56:34 UTC (rev 117197)
+++ trunk/Source/_javascript_Core/bytecode/CodeBlock.h 2012-05-16 00:56:54 UTC (rev 117198)
@@ -309,26 +309,12 @@
m_dfgData->weakReferences.append(WriteBarrier<JSCell>(*globalData(), ownerExecutable(), target));
}
- void shrinkWeakReferencesToFit()
- {
- if (!m_dfgData)
- return;
- m_dfgData->weakReferences.shrinkToFit();
- }
-
void appendWeakReferenceTransition(JSCell* codeOrigin, JSCell* from, JSCell* to)
{
createDFGDataIfNecessary();
m_dfgData->transitions.append(
WeakReferenceTransition(*globalData(), ownerExecutable(), codeOrigin, from, to));
}
-
- void shrinkWeakReferenceTransitionsToFit()
- {
- if (!m_dfgData)
- return;
- m_dfgData->transitions.shrinkToFit();
- }
#endif
unsigned bytecodeOffset(Instruction* returnAddress)
@@ -826,7 +812,16 @@
EvalCodeCache& evalCodeCache() { createRareDataIfNecessary(); return m_rareData->m_evalCodeCache; }
- void shrinkToFit();
+ enum ShrinkMode {
+ // Shrink prior to generating machine code that may point directly into vectors.
+ EarlyShrink,
+
+ // Shrink after generating machine code, and after possibly creating new vectors
+ // and appending to others. At this time it is not safe to shrink certain vectors
+ // because we would have generated machine code that references them directly.
+ LateShrink
+ };
+ void shrinkToFit(ShrinkMode);
void copyPostParseDataFrom(CodeBlock* alternative);
void copyPostParseDataFromAlternative();
Modified: trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.cpp (117197 => 117198)
--- trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.cpp 2012-05-16 00:56:34 UTC (rev 117197)
+++ trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.cpp 2012-05-16 00:56:54 UTC (rev 117198)
@@ -189,7 +189,7 @@
if ((m_codeType == FunctionCode && !m_codeBlock->needsFullScopeChain() && !m_codeBlock->usesArguments()) || m_codeType == EvalCode)
symbolTable().clear();
- m_codeBlock->shrinkToFit();
+ m_codeBlock->shrinkToFit(CodeBlock::EarlyShrink);
if (m_expressionTooDeep)
return createOutOfMemoryError(m_scopeChain->globalObject.get());
Modified: trunk/Source/_javascript_Core/dfg/DFGDriver.cpp (117197 => 117198)
--- trunk/Source/_javascript_Core/dfg/DFGDriver.cpp 2012-05-16 00:56:34 UTC (rev 117197)
+++ trunk/Source/_javascript_Core/dfg/DFGDriver.cpp 2012-05-16 00:56:54 UTC (rev 117198)
@@ -58,6 +58,12 @@
if (compileMode == CompileFunction)
dfg.predictArgumentTypes();
+
+ // By this point the DFG bytecode parser will have potentially mutated various tables
+ // in the CodeBlock. This is a good time to perform an early shrink, which is more
+ // powerful than a late one. It's safe to do so because we haven't generated any code
+ // that references any of the tables directly, yet.
+ codeBlock->shrinkToFit(CodeBlock::EarlyShrink);
performRedundantPhiElimination(dfg);
performPredictionPropagation(dfg);
Modified: trunk/Source/_javascript_Core/dfg/DFGJITCompiler.cpp (117197 => 117198)
--- trunk/Source/_javascript_Core/dfg/DFGJITCompiler.cpp 2012-05-16 00:56:34 UTC (rev 117197)
+++ trunk/Source/_javascript_Core/dfg/DFGJITCompiler.cpp 2012-05-16 00:56:54 UTC (rev 117198)
@@ -190,8 +190,7 @@
exit.m_check.correctLateJump(linkBuffer);
}
- codeBlock()->shrinkWeakReferencesToFit();
- codeBlock()->shrinkWeakReferenceTransitionsToFit();
+ codeBlock()->shrinkToFit(CodeBlock::LateShrink);
}
bool JITCompiler::compile(JITCode& entry)
Modified: trunk/Source/_javascript_Core/jit/JIT.cpp (117197 => 117198)
--- trunk/Source/_javascript_Core/jit/JIT.cpp 2012-05-16 00:56:34 UTC (rev 117197)
+++ trunk/Source/_javascript_Core/jit/JIT.cpp 2012-05-16 00:56:54 UTC (rev 117198)
@@ -749,6 +749,8 @@
static_cast<double>(result.size()) /
static_cast<double>(m_codeBlock->instructions().size()));
+ m_codeBlock->shrinkToFit(CodeBlock::LateShrink);
+
#if ENABLE(JIT_VERBOSE)
dataLog("JIT generated code for %p at [%p, %p).\n", m_codeBlock, result.executableMemory()->start(), result.executableMemory()->end());
#endif
Modified: trunk/Source/WTF/ChangeLog (117197 => 117198)
--- trunk/Source/WTF/ChangeLog 2012-05-16 00:56:34 UTC (rev 117197)
+++ trunk/Source/WTF/ChangeLog 2012-05-16 00:56:54 UTC (rev 117198)
@@ -1,3 +1,18 @@
+2012-05-15 Filip Pizlo <[email protected]>
+
+ shrinkToFit() is often not called for Vectors in CodeBlock
+ https://bugs.webkit.org/show_bug.cgi?id=86436
+
+ Reviewed by Oliver Hunt.
+
+ Gave SegmentedVector a shrinkToFit() method. This only shrinks the segment
+ lookup table, which is likely to not be hugely profitable, but it is better
+ than nothing.
+
+ * wtf/SegmentedVector.h:
+ (SegmentedVector):
+ (WTF::SegmentedVector::shrinkToFit):
+
2012-05-15 Andy Estes <[email protected]>
Add WTF_USE_SECURITY_FRAMEWORK and use it in place of the less specific PLATFORM(MAC)
Modified: trunk/Source/WTF/wtf/SegmentedVector.h (117197 => 117198)
--- trunk/Source/WTF/wtf/SegmentedVector.h 2012-05-16 00:56:34 UTC (rev 117197)
+++ trunk/Source/WTF/wtf/SegmentedVector.h 2012-05-16 00:56:54 UTC (rev 117198)
@@ -188,6 +188,11 @@
{
return Iterator(*this, 0, SegmentSize);
}
+
+ void shrinkToFit()
+ {
+ m_segments.shrinkToFit();
+ }
private:
typedef Vector<T, SegmentSize> Segment;