Title: [181060] trunk/Source/_javascript_Core
Revision
181060
Author
[email protected]
Date
2015-03-04 18:19:14 -0800 (Wed, 04 Mar 2015)

Log Message

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:

Modified Paths

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 = &registers;
-    void* registersEnd = reinterpret_cast<void*>(roundUpToMultipleOf<sizeof(void*)>(reinterpret_cast<uintptr_t>(&registers + 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*);
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to