Modified: trunk/Source/_javascript_Core/ChangeLog (89715 => 89716)
--- trunk/Source/_javascript_Core/ChangeLog 2011-06-25 00:09:37 UTC (rev 89715)
+++ trunk/Source/_javascript_Core/ChangeLog 2011-06-25 00:11:58 UTC (rev 89716)
@@ -1,3 +1,31 @@
+2011-06-24 Michael Saboff <[email protected]>
+
+ Reviewed by Geoffrey Garen.
+
+ releaseFastMallocFreeMemory doesn't adjust free counts for scavenger
+ https://bugs.webkit.org/show_bug.cgi?id=63015
+
+ Added code to adjust class TCMalloc_PageHeap variables free_committed_pages_ and
+ min_free_committed_pages_since_last_scavenge_ in ReleaseFreeList(). These
+ adjustments are a bug. These need to reflect the pages that are released
+ in ReleaseFreeLsit so that scavenge doesn't try to free that many pages as well.
+ Made ReleaseFreeList a member of TCMalloc_PageHeap in the process. Updated
+ Check() and helper method CheckList() to check the number of actual free pages
+ with free_committed_pages_.
+
+ The symptom of the problem of the existing code is that the scavenger may
+ run unneccesarily without any real work to do, i.e. pages on the free lists.
+ The scanvenger would also end up freeing too many pages, that is going below
+ the current 528 target free pages.
+
+ Note that the style of the changes was kept consistent with the
+ existing style.
+
+ * wtf/FastMalloc.cpp:
+ (WTF::TCMalloc_PageHeap::Check):
+ (WTF::TCMalloc_PageHeap::CheckList):
+ (WTF::TCMalloc_PageHeap::ReleaseFreeList):
+
2011-06-24 Abhishek Arya <[email protected]>
Reviewed by Darin Adler.
Modified: trunk/Source/_javascript_Core/wtf/FastMalloc.cpp (89715 => 89716)
--- trunk/Source/_javascript_Core/wtf/FastMalloc.cpp 2011-06-25 00:09:37 UTC (rev 89715)
+++ trunk/Source/_javascript_Core/wtf/FastMalloc.cpp 2011-06-25 00:11:58 UTC (rev 89716)
@@ -1357,10 +1357,11 @@
}
bool Check();
- bool CheckList(Span* list, Length min_pages, Length max_pages, bool decommitted);
+ size_t CheckList(Span* list, Length min_pages, Length max_pages, bool decommitted);
// Release all pages on the free list for reuse by the OS:
void ReleaseFreePages();
+ void ReleaseFreeList(Span*, Span*);
// Return 0 if we have no information, or else the correct sizeclass for p.
// Reads and writes to pagemap_cache_ do not require locking.
@@ -2117,23 +2118,38 @@
}
bool TCMalloc_PageHeap::Check() {
+#if USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY
+ size_t totalFreeCommitted = 0;
+#endif
ASSERT(free_[0].normal.next == &free_[0].normal);
ASSERT(free_[0].returned.next == &free_[0].returned);
+#if USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY
+ totalFreeCommitted = CheckList(&large_.normal, kMaxPages, 1000000000, false);
+#else
CheckList(&large_.normal, kMaxPages, 1000000000, false);
- CheckList(&large_.returned, kMaxPages, 1000000000, true);
+#endif
+ CheckList(&large_.returned, kMaxPages, 1000000000, true);
for (Length s = 1; s < kMaxPages; s++) {
+#if USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY
+ totalFreeCommitted += CheckList(&free_[s].normal, s, s, false);
+#else
CheckList(&free_[s].normal, s, s, false);
+#endif
CheckList(&free_[s].returned, s, s, true);
}
+#if USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY
+ ASSERT(totalFreeCommitted == free_committed_pages_);
+#endif
return true;
}
#if ASSERT_DISABLED
-bool TCMalloc_PageHeap::CheckList(Span*, Length, Length, bool) {
- return true;
+size_t TCMalloc_PageHeap::CheckList(Span*, Length, Length, bool) {
+ return 0;
}
#else
-bool TCMalloc_PageHeap::CheckList(Span* list, Length min_pages, Length max_pages, bool decommitted) {
+size_t TCMalloc_PageHeap::CheckList(Span* list, Length min_pages, Length max_pages, bool decommitted) {
+ size_t freeCount = 0;
for (Span* s = list->next; s != list; s = s->next) {
CHECK_CONDITION(s->free);
CHECK_CONDITION(s->length >= min_pages);
@@ -2141,22 +2157,37 @@
CHECK_CONDITION(GetDescriptor(s->start) == s);
CHECK_CONDITION(GetDescriptor(s->start+s->length-1) == s);
CHECK_CONDITION(s->decommitted == decommitted);
+ freeCount += s->length;
}
- return true;
+ return freeCount;
}
#endif
-static void ReleaseFreeList(Span* list, Span* returned) {
+void TCMalloc_PageHeap::ReleaseFreeList(Span* list, Span* returned) {
// Walk backwards through list so that when we push these
// spans on the "returned" list, we preserve the order.
+#if USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY
+ size_t freePageReduction = 0;
+#endif
+
while (!DLL_IsEmpty(list)) {
Span* s = list->prev;
+
DLL_Remove(s);
s->decommitted = true;
DLL_Prepend(returned, s);
TCMalloc_SystemRelease(reinterpret_cast<void*>(s->start << kPageShift),
static_cast<size_t>(s->length << kPageShift));
+#if USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY
+ freePageReduction += s->length;
+#endif
}
+
+#if USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY
+ free_committed_pages_ -= freePageReduction;
+ if (free_committed_pages_ < min_free_committed_pages_since_last_scavenge_)
+ min_free_committed_pages_since_last_scavenge_ = free_committed_pages_;
+#endif
}
void TCMalloc_PageHeap::ReleaseFreePages() {