Diff
Modified: trunk/Source/_javascript_Core/API/JSBase.cpp (90414 => 90415)
--- trunk/Source/_javascript_Core/API/JSBase.cpp 2011-07-05 23:18:23 UTC (rev 90414)
+++ trunk/Source/_javascript_Core/API/JSBase.cpp 2011-07-05 23:55:45 UTC (rev 90415)
@@ -97,8 +97,10 @@
APIEntryShim entryShim(exec, false);
JSGlobalData& globalData = exec->globalData();
- if (!globalData.heap.isBusy())
- globalData.heap.collectAllGarbage();
+ if (!globalData.heap.isBusy()) {
+ // releaseExecutableMemory forces a full GC
+ globalData.releaseExecutableMemory();
+ }
// FIXME: Perhaps we should trigger a second mark and sweep
// once the garbage collector is done if this is called when
Modified: trunk/Source/_javascript_Core/ChangeLog (90414 => 90415)
--- trunk/Source/_javascript_Core/ChangeLog 2011-07-05 23:18:23 UTC (rev 90414)
+++ trunk/Source/_javascript_Core/ChangeLog 2011-07-05 23:55:45 UTC (rev 90415)
@@ -1,3 +1,33 @@
+2011-07-05 Oliver Hunt <[email protected]>
+
+ Don't throw out compiled code repeatedly
+ https://bugs.webkit.org/show_bug.cgi?id=63960
+
+ Reviewed by Gavin Barraclough.
+
+ Stop throwing away all compiled code every time
+ we're told to do a full GC. Instead unlink all
+ callsites during such GC passes to maximise the
+ number of collectable functions, but otherwise
+ leave compiled functions alone.
+
+ * API/JSBase.cpp:
+ (JSGarbageCollect):
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::visitAggregate):
+ * heap/Heap.cpp:
+ (JSC::Heap::collectAllGarbage):
+ * heap/MarkStack.h:
+ (JSC::MarkStack::shouldUnlinkCalls):
+ (JSC::MarkStack::setShouldUnlinkCalls):
+ * runtime/JSGlobalData.cpp:
+ (JSC::JSGlobalData::recompileAllJSFunctions):
+ (JSC::JSGlobalData::releaseExecutableMemory):
+ * runtime/RegExp.cpp:
+ (JSC::RegExp::compile):
+ (JSC::RegExp::invalidateCode):
+ * runtime/RegExp.h:
+
2011-07-05 Filip Pizlo <[email protected]>
JSC JIT has code duplication for the handling of call and construct
Modified: trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp (90414 => 90415)
--- trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp 2011-07-05 23:18:23 UTC (rev 90414)
+++ trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp 2011-07-05 23:55:45 UTC (rev 90415)
@@ -1536,6 +1536,8 @@
for (size_t i = 0; i < m_functionDecls.size(); ++i)
visitor.append(&m_functionDecls[i]);
#if ENABLE(JIT)
+ if (visitor.shouldUnlinkCalls())
+ unlinkCalls();
for (unsigned i = 0; i < numberOfCallLinkInfos(); ++i)
if (callLinkInfo(i).isLinked())
visitor.append(&callLinkInfo(i).callee);
Modified: trunk/Source/_javascript_Core/heap/Heap.cpp (90414 => 90415)
--- trunk/Source/_javascript_Core/heap/Heap.cpp 2011-07-05 23:18:23 UTC (rev 90414)
+++ trunk/Source/_javascript_Core/heap/Heap.cpp 2011-07-05 23:55:45 UTC (rev 90415)
@@ -525,10 +525,9 @@
void Heap::collectAllGarbage()
{
- if (!m_globalData->dynamicGlobalObject)
- m_globalData->recompileAllJSFunctions();
-
+ m_slotVisitor.setShouldUnlinkCalls(true);
collect(DoSweep);
+ m_slotVisitor.setShouldUnlinkCalls(false);
}
void Heap::collect(SweepToggle sweepToggle)
Modified: trunk/Source/_javascript_Core/heap/MarkStack.h (90414 => 90415)
--- trunk/Source/_javascript_Core/heap/MarkStack.h 2011-07-05 23:18:23 UTC (rev 90414)
+++ trunk/Source/_javascript_Core/heap/MarkStack.h 2011-07-05 23:55:45 UTC (rev 90415)
@@ -97,6 +97,9 @@
void reset();
+ bool shouldUnlinkCalls() const { return m_shouldUnlinkCalls; }
+ void setShouldUnlinkCalls(bool shouldUnlinkCalls) { m_shouldUnlinkCalls = shouldUnlinkCalls; }
+
protected:
#if ENABLE(GC_VALIDATION)
static void validateSet(JSValue*, size_t);
@@ -120,6 +123,9 @@
bool m_isCheckingForDefaultMarkViolation;
bool m_isDraining;
#endif
+
+ private:
+ bool m_shouldUnlinkCalls;
};
inline MarkStack::MarkStack(void* jsArrayVPtr)
Modified: trunk/Source/_javascript_Core/runtime/JSGlobalData.cpp (90414 => 90415)
--- trunk/Source/_javascript_Core/runtime/JSGlobalData.cpp 2011-07-05 23:18:23 UTC (rev 90414)
+++ trunk/Source/_javascript_Core/runtime/JSGlobalData.cpp 2011-07-05 23:55:45 UTC (rev 90415)
@@ -489,7 +489,9 @@
}
heap.forEachCell<StackPreservingRecompiler>(recompiler);
- }
+ } else
+ recompileAllJSFunctions();
+
m_regExpCache->invalidateCode();
heap.collectAllGarbage();
}
Modified: trunk/Source/_javascript_Core/runtime/RegExp.cpp (90414 => 90415)
--- trunk/Source/_javascript_Core/runtime/RegExp.cpp 2011-07-05 23:18:23 UTC (rev 90414)
+++ trunk/Source/_javascript_Core/runtime/RegExp.cpp 2011-07-05 23:55:45 UTC (rev 90415)
@@ -108,6 +108,7 @@
{
ASSERT(m_state == NotCompiled);
m_representation = adoptPtr(new RegExpRepresentation);
+ m_state = Compiling;
Yarr::YarrPattern pattern(m_patternString, ignoreCase(), multiline(), &m_constructionError);
if (m_constructionError) {
ASSERT_NOT_REACHED();
@@ -119,8 +120,6 @@
ASSERT(m_numSubpatterns == pattern.m_numSubpatterns);
- m_state = ByteCode;
-
#if ENABLE(YARR_JIT)
if (!pattern.m_containsBackreferences && globalData->canUseJIT()) {
Yarr::jitCompile(pattern, globalData, m_representation->m_regExpJITCode);
@@ -139,6 +138,8 @@
#endif
m_representation->m_regExpBytecode = Yarr::byteCompile(pattern, &globalData->m_regExpAllocator);
+
+ m_state = ByteCode;
}
int RegExp::match(JSGlobalData& globalData, const UString& s, int startOffset, Vector<int, 32>* ovector)
@@ -199,7 +200,7 @@
void RegExp::invalidateCode()
{
- if (!m_representation)
+ if (!m_representation || m_state == Compiling)
return;
m_state = NotCompiled;
m_representation.clear();
Modified: trunk/Source/_javascript_Core/runtime/RegExp.h (90414 => 90415)
--- trunk/Source/_javascript_Core/runtime/RegExp.h 2011-07-05 23:18:23 UTC (rev 90414)
+++ trunk/Source/_javascript_Core/runtime/RegExp.h 2011-07-05 23:55:45 UTC (rev 90415)
@@ -81,7 +81,8 @@
ParseError,
JITCode,
ByteCode,
- NotCompiled
+ NotCompiled,
+ Compiling
} m_state;
void compile(JSGlobalData*);