summaryrefslogtreecommitdiff
path: root/src/tests/page_heap_test.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/tests/page_heap_test.cc')
-rw-r--r--src/tests/page_heap_test.cc103
1 files changed, 102 insertions, 1 deletions
diff --git a/src/tests/page_heap_test.cc b/src/tests/page_heap_test.cc
index 9f5f3c8..f08387c 100644
--- a/src/tests/page_heap_test.cc
+++ b/src/tests/page_heap_test.cc
@@ -3,17 +3,29 @@
#include "config_for_unittests.h"
#include "page_heap.h"
+#include "system-alloc.h"
#include <stdio.h>
#include "base/logging.h"
#include "common.h"
+DECLARE_int64(tcmalloc_heap_limit_mb);
+
namespace {
+static bool HaveSystemRelease =
+ TCMalloc_SystemRelease(TCMalloc_SystemAlloc(kPageSize, NULL, 0), kPageSize);
+
static void CheckStats(const tcmalloc::PageHeap* ph,
uint64_t system_pages,
uint64_t free_pages,
uint64_t unmapped_pages) {
tcmalloc::PageHeap::Stats stats = ph->stats();
+
+ if (!HaveSystemRelease) {
+ free_pages += unmapped_pages;
+ unmapped_pages = 0;
+ }
+
EXPECT_EQ(system_pages, stats.system_bytes >> kPageShift);
EXPECT_EQ(free_pages, stats.free_bytes >> kPageShift);
EXPECT_EQ(unmapped_pages, stats.unmapped_bytes >> kPageShift);
@@ -36,7 +48,7 @@ static void TestPageHeap_Stats() {
CheckStats(ph, 256, 128, 0);
// Unmap deleted span 's2'
- EXPECT_EQ(s2_len, ph->ReleaseAtLeastNPages(1));
+ ph->ReleaseAtLeastNPages(1);
CheckStats(ph, 256, 0, 128);
// Delete span 's1'
@@ -46,10 +58,99 @@ static void TestPageHeap_Stats() {
delete ph;
}
+static void TestPageHeap_Limit() {
+ tcmalloc::PageHeap* ph = new tcmalloc::PageHeap();
+
+ CHECK_EQ(kMaxPages, 1 << (20 - kPageShift));
+
+ // We do not know much is taken from the system for other purposes,
+ // so we detect the proper limit:
+ {
+ FLAGS_tcmalloc_heap_limit_mb = 1;
+ tcmalloc::Span* s = NULL;
+ while((s = ph->New(kMaxPages)) == NULL) {
+ FLAGS_tcmalloc_heap_limit_mb++;
+ }
+ FLAGS_tcmalloc_heap_limit_mb += 9;
+ ph->Delete(s);
+ // We are [10, 11) mb from the limit now.
+ }
+
+ // Test AllocLarge and GrowHeap first:
+ {
+ tcmalloc::Span * spans[10];
+ for (int i=0; i<10; ++i) {
+ spans[i] = ph->New(kMaxPages);
+ EXPECT_NE(spans[i], NULL);
+ }
+ EXPECT_EQ(ph->New(kMaxPages), NULL);
+
+ for (int i=0; i<10; i += 2) {
+ ph->Delete(spans[i]);
+ }
+
+ tcmalloc::Span *defragmented = ph->New(5 * kMaxPages);
+
+ if (HaveSystemRelease) {
+ // EnsureLimit should release deleted normal spans
+ EXPECT_NE(defragmented, NULL);
+ EXPECT_TRUE(ph->CheckExpensive());
+ ph->Delete(defragmented);
+ }
+ else
+ {
+ EXPECT_EQ(defragmented, NULL);
+ EXPECT_TRUE(ph->CheckExpensive());
+ }
+
+ for (int i=1; i<10; i += 2) {
+ ph->Delete(spans[i]);
+ }
+ }
+
+ // Once again, testing small lists this time (twice smaller spans):
+ {
+ tcmalloc::Span * spans[20];
+ for (int i=0; i<20; ++i) {
+ spans[i] = ph->New(kMaxPages >> 1);
+ EXPECT_NE(spans[i], NULL);
+ }
+ // one more half size allocation may be possible:
+ tcmalloc::Span * lastHalf = ph->New(kMaxPages >> 1);
+ EXPECT_EQ(ph->New(kMaxPages >> 1), NULL);
+
+ for (int i=0; i<20; i += 2) {
+ ph->Delete(spans[i]);
+ }
+
+ for(Length len = kMaxPages >> 2; len < 5 * kMaxPages; len = len << 1)
+ {
+ if(len <= kMaxPages >> 1 || HaveSystemRelease) {
+ tcmalloc::Span *s = ph->New(len);
+ EXPECT_NE(s, NULL);
+ ph->Delete(s);
+ }
+ }
+
+ EXPECT_TRUE(ph->CheckExpensive());
+
+ for (int i=1; i<20; i += 2) {
+ ph->Delete(spans[i]);
+ }
+
+ if (lastHalf != NULL) {
+ ph->Delete(lastHalf);
+ }
+ }
+
+ delete ph;
+}
+
} // namespace
int main(int argc, char **argv) {
TestPageHeap_Stats();
+ TestPageHeap_Limit();
printf("PASS\n");
return 0;
}