Diff
Modified: trunk/Source/_javascript_Core/ChangeLog (181059 => 181060)
--- trunk/Source/_javascript_Core/ChangeLog 2015-03-05 01:51:57 UTC (rev 181059)
+++ trunk/Source/_javascript_Core/ChangeLog 2015-03-05 02:19:14 UTC (rev 181060)
@@ -1,3 +1,31 @@
+2015-03-04 Andreas Kling <[email protected]>
+
+ GC should compute stack bounds and dump registers at the earliest opportunity.
+ <https://webkit.org/b/142310>
+ <rdar://problem/20045624>
+
+ Reviewed by Geoffrey Garen.
+
+ Make Heap::collect() a wrapper function around a collectImpl() where the work is actually done.
+ The wrapper function that grabs a snapshot of the current stack boundaries and register values
+ on entry, and sanitizes the stack on exit.
+
+ This is a speculative fix for what appears to be overly conservative behavior in the garbage
+ collector following r178364 which caused a measurable regression in memory usage on Membuster.
+ The theory being that we were putting pointers to dead things on the stack before scanning it,
+ and by doing that ended up marking things that we'd otherwise discover to be garbage.
+
+ * heap/Heap.cpp:
+ (JSC::Heap::markRoots):
+ (JSC::Heap::gatherStackRoots):
+ (JSC::Heap::collect):
+ (JSC::Heap::collectImpl):
+ * heap/Heap.h:
+ * heap/MachineStackMarker.cpp:
+ (JSC::MachineThreads::gatherFromCurrentThread):
+ (JSC::MachineThreads::gatherConservativeRoots):
+ * heap/MachineStackMarker.h:
+
2015-03-04 Debarshi Ray <[email protected]>
Silence GCC's -Wstrict-prototypes
Modified: trunk/Source/_javascript_Core/heap/Heap.cpp (181059 => 181060)
--- trunk/Source/_javascript_Core/heap/Heap.cpp 2015-03-05 01:51:57 UTC (rev 181059)
+++ trunk/Source/_javascript_Core/heap/Heap.cpp 2015-03-05 02:19:14 UTC (rev 181060)
@@ -513,7 +513,7 @@
}
}
-void Heap::markRoots(double gcStartTime)
+void Heap::markRoots(double gcStartTime, void* stackOrigin, void* stackTop, MachineThreads::RegisterState& calleeSavedRegisters)
{
SamplingRegion samplingRegion("Garbage Collection: Marking");
@@ -534,15 +534,11 @@
// We gather conservative roots before clearing mark bits because conservative
// gathering uses the mark bits to determine whether a reference is valid.
- void* dummy;
- ALLOCATE_AND_GET_REGISTER_STATE(registers);
ConservativeRoots conservativeRoots(&m_objectSpace.blocks(), &m_storageSpace);
- gatherStackRoots(conservativeRoots, &dummy, registers);
+ gatherStackRoots(conservativeRoots, stackOrigin, stackTop, calleeSavedRegisters);
gatherJSStackRoots(conservativeRoots);
gatherScratchBufferRoots(conservativeRoots);
- sanitizeStackForVM(m_vm);
-
clearLivenessData();
m_sharedData.didStartMarking();
@@ -598,11 +594,11 @@
m_storageSpace.doneCopying();
}
-void Heap::gatherStackRoots(ConservativeRoots& roots, void** dummy, MachineThreads::RegisterState& registers)
+void Heap::gatherStackRoots(ConservativeRoots& roots, void* stackOrigin, void* stackTop, MachineThreads::RegisterState& calleeSavedRegisters)
{
GCPHASE(GatherStackRoots);
m_jitStubRoutines.clearMarks();
- m_machineThreads.gatherConservativeRoots(roots, m_jitStubRoutines, m_codeBlocks, dummy, registers);
+ m_machineThreads.gatherConservativeRoots(roots, m_jitStubRoutines, m_codeBlocks, stackOrigin, stackTop, calleeSavedRegisters);
}
void Heap::gatherJSStackRoots(ConservativeRoots& roots)
@@ -1003,8 +999,18 @@
static double minute = 60.0;
-void Heap::collect(HeapOperation collectionType)
+NEVER_INLINE void Heap::collect(HeapOperation collectionType)
{
+ void* stackTop;
+ ALLOCATE_AND_GET_REGISTER_STATE(registers);
+
+ collectImpl(collectionType, wtfThreadData().stack().origin(), &stackTop, registers);
+
+ sanitizeStackForVM(m_vm);
+}
+
+NEVER_INLINE void Heap::collectImpl(HeapOperation collectionType, void* stackOrigin, void* stackTop, MachineThreads::RegisterState& calleeSavedRegisters)
+{
#if ENABLE(ALLOCATION_LOGGING)
dataLogF("JSC GC starting collection.\n");
#endif
@@ -1048,7 +1054,7 @@
stopAllocation();
flushWriteBarrierBuffer();
- markRoots(gcStartTime);
+ markRoots(gcStartTime, stackOrigin, stackTop, calleeSavedRegisters);
if (m_verifier) {
m_verifier->gatherLiveObjects(HeapVerifier::Phase::AfterMarking);
Modified: trunk/Source/_javascript_Core/heap/Heap.h (181059 => 181060)
--- trunk/Source/_javascript_Core/heap/Heap.h 2015-03-05 01:51:57 UTC (rev 181059)
+++ trunk/Source/_javascript_Core/heap/Heap.h 2015-03-05 02:19:14 UTC (rev 181060)
@@ -273,6 +273,8 @@
JS_EXPORT_PRIVATE bool isValidAllocation(size_t);
JS_EXPORT_PRIVATE void reportExtraMemoryCostSlowCase(size_t);
+ void collectImpl(HeapOperation, void* stackOrigin, void* stackTop, MachineThreads::RegisterState&);
+
void suspendCompilerThreads();
void willStartCollection(HeapOperation collectionType);
void deleteOldCode(double gcStartTime);
@@ -280,8 +282,8 @@
void flushWriteBarrierBuffer();
void stopAllocation();
- void markRoots(double gcStartTime);
- void gatherStackRoots(ConservativeRoots&, void** dummy, MachineThreads::RegisterState& registers);
+ void markRoots(double gcStartTime, void* stackOrigin, void* stackTop, MachineThreads::RegisterState&);
+ void gatherStackRoots(ConservativeRoots&, void* stackOrigin, void* stackTop, MachineThreads::RegisterState&);
void gatherJSStackRoots(ConservativeRoots&);
void gatherScratchBufferRoots(ConservativeRoots&);
void clearLivenessData();
Modified: trunk/Source/_javascript_Core/heap/MachineStackMarker.cpp (181059 => 181060)
--- trunk/Source/_javascript_Core/heap/MachineStackMarker.cpp 2015-03-05 01:51:57 UTC (rev 181059)
+++ trunk/Source/_javascript_Core/heap/MachineStackMarker.cpp 2015-03-05 02:19:14 UTC (rev 181060)
@@ -276,15 +276,13 @@
}
}
-void MachineThreads::gatherFromCurrentThread(ConservativeRoots& conservativeRoots, JITStubRoutineSet& jitStubRoutines, CodeBlockSet& codeBlocks, void* stackCurrent, RegisterState& registers)
+void MachineThreads::gatherFromCurrentThread(ConservativeRoots& conservativeRoots, JITStubRoutineSet& jitStubRoutines, CodeBlockSet& codeBlocks, void* stackOrigin, void* stackTop, RegisterState& calleeSavedRegisters)
{
- void* registersBegin = ®isters;
- void* registersEnd = reinterpret_cast<void*>(roundUpToMultipleOf<sizeof(void*)>(reinterpret_cast<uintptr_t>(®isters + 1)));
+ void* registersBegin = &calleeSavedRegisters;
+ void* registersEnd = reinterpret_cast<void*>(roundUpToMultipleOf<sizeof(void*)>(reinterpret_cast<uintptr_t>(&calleeSavedRegisters + 1)));
conservativeRoots.add(registersBegin, registersEnd, jitStubRoutines, codeBlocks);
- void* stackBegin = stackCurrent;
- void* stackEnd = wtfThreadData().stack().origin();
- conservativeRoots.add(stackBegin, stackEnd, jitStubRoutines, codeBlocks);
+ conservativeRoots.add(stackTop, stackOrigin, jitStubRoutines, codeBlocks);
}
static inline bool suspendThread(const PlatformThread& platformThread)
@@ -614,9 +612,9 @@
*buffer = fastMalloc(*capacity);
}
-void MachineThreads::gatherConservativeRoots(ConservativeRoots& conservativeRoots, JITStubRoutineSet& jitStubRoutines, CodeBlockSet& codeBlocks, void* stackCurrent, RegisterState& currentThreadRegisters)
+void MachineThreads::gatherConservativeRoots(ConservativeRoots& conservativeRoots, JITStubRoutineSet& jitStubRoutines, CodeBlockSet& codeBlocks, void* stackOrigin, void* stackTop, RegisterState& calleeSavedRegisters)
{
- gatherFromCurrentThread(conservativeRoots, jitStubRoutines, codeBlocks, stackCurrent, currentThreadRegisters);
+ gatherFromCurrentThread(conservativeRoots, jitStubRoutines, codeBlocks, stackOrigin, stackTop, calleeSavedRegisters);
size_t size;
size_t capacity = 0;
Modified: trunk/Source/_javascript_Core/heap/MachineStackMarker.h (181059 => 181060)
--- trunk/Source/_javascript_Core/heap/MachineStackMarker.h 2015-03-05 01:51:57 UTC (rev 181059)
+++ trunk/Source/_javascript_Core/heap/MachineStackMarker.h 2015-03-05 02:19:14 UTC (rev 181060)
@@ -42,14 +42,14 @@
MachineThreads(Heap*);
~MachineThreads();
- void gatherConservativeRoots(ConservativeRoots&, JITStubRoutineSet&, CodeBlockSet&, void* stackCurrent, RegisterState& registers);
+ void gatherConservativeRoots(ConservativeRoots&, JITStubRoutineSet&, CodeBlockSet&, void* stackOrigin, void* stackTop, RegisterState& calleeSavedRegisters);
JS_EXPORT_PRIVATE void addCurrentThread(); // Only needs to be called by clients that can use the same heap from multiple threads.
private:
class Thread;
- void gatherFromCurrentThread(ConservativeRoots&, JITStubRoutineSet&, CodeBlockSet&, void* stackCurrent, RegisterState& registers);
+ void gatherFromCurrentThread(ConservativeRoots&, JITStubRoutineSet&, CodeBlockSet&, void* stackOrigin, void* stackTop, RegisterState& calleeSavedRegisters);
void tryCopyOtherThreadStack(Thread*, void*, size_t capacity, size_t*);
bool tryCopyOtherThreadStacks(MutexLocker&, void*, size_t capacity, size_t*);