< prev index next >
src/hotspot/share/gc/z/zPageCache.cpp
Print this page
@@ -29,12 +29,21 @@
#include "gc/z/zStat.hpp"
#include "logging/log.hpp"
static const ZStatCounter ZCounterPageCacheHitL1("Memory", "Page Cache Hit L1", ZStatUnitOpsPerSecond);
static const ZStatCounter ZCounterPageCacheHitL2("Memory", "Page Cache Hit L2", ZStatUnitOpsPerSecond);
+static const ZStatCounter ZCounterPageCacheHitL3("Memory", "Page Cache Hit L3", ZStatUnitOpsPerSecond);
static const ZStatCounter ZCounterPageCacheMiss("Memory", "Page Cache Miss", ZStatUnitOpsPerSecond);
+ZPageCacheFlushClosure::ZPageCacheFlushClosure(size_t requested) :
+ _requested(requested),
+ _flushed(0) {}
+
+size_t ZPageCacheFlushClosure::overflushed() const {
+ return _flushed > _requested ? _flushed - _requested : 0;
+}
+
ZPageCache::ZPageCache() :
_available(0),
_small(),
_medium(),
_large() {}
@@ -65,69 +74,124 @@
}
remote_numa_id++;
}
- ZStatInc(ZCounterPageCacheMiss);
return NULL;
}
ZPage* ZPageCache::alloc_medium_page() {
- ZPage* const l1_page = _medium.remove_first();
- if (l1_page != NULL) {
+ ZPage* const page = _medium.remove_first();
+ if (page != NULL) {
ZStatInc(ZCounterPageCacheHitL1);
- return l1_page;
+ return page;
}
- ZStatInc(ZCounterPageCacheMiss);
return NULL;
}
ZPage* ZPageCache::alloc_large_page(size_t size) {
// Find a page with the right size
ZListIterator<ZPage> iter(&_large);
- for (ZPage* l1_page; iter.next(&l1_page);) {
- if (l1_page->size() == size) {
+ for (ZPage* page; iter.next(&page);) {
+ if (size == page->size()) {
// Page found
- _large.remove(l1_page);
+ _large.remove(page);
ZStatInc(ZCounterPageCacheHitL1);
- return l1_page;
+ return page;
+ }
+ }
+
+ return NULL;
+}
+
+ZPage* ZPageCache::alloc_oversized_medium_page(size_t size) {
+ if (size <= ZPageSizeMedium) {
+ return _medium.remove_first();
+ }
+
+ return NULL;
+}
+
+ZPage* ZPageCache::alloc_oversized_large_page(size_t size) {
+ // Find a page that is large enough
+ ZListIterator<ZPage> iter(&_large);
+ for (ZPage* page; iter.next(&page);) {
+ if (size <= page->size()) {
+ // Page found
+ _large.remove(page);
+ return page;
}
}
- ZStatInc(ZCounterPageCacheMiss);
return NULL;
}
+ZPage* ZPageCache::alloc_oversized_page(size_t size) {
+ ZPage* page = alloc_oversized_large_page(size);
+ if (page == NULL) {
+ page = alloc_oversized_medium_page(size);
+ }
+
+ if (page != NULL) {
+ ZStatInc(ZCounterPageCacheHitL3);
+ }
+
+ return page;
+}
+
ZPage* ZPageCache::alloc_page(uint8_t type, size_t size) {
ZPage* page;
+ // Try allocate exact page
if (type == ZPageTypeSmall) {
page = alloc_small_page();
} else if (type == ZPageTypeMedium) {
page = alloc_medium_page();
} else {
page = alloc_large_page(size);
}
+ if (page == NULL) {
+ // Try allocate potentially oversized page
+ ZPage* const oversized = alloc_oversized_page(size);
+ if (oversized != NULL) {
+ if (size < oversized->size()) {
+ // Split oversized page
+ page = oversized->split(type, size);
+
+ // Cache remainder
+ free_page_inner(oversized);
+ } else {
+ // Re-type correctly sized page
+ page = oversized->retype(type);
+ }
+ }
+ }
+
if (page != NULL) {
_available -= page->size();
+ } else {
+ ZStatInc(ZCounterPageCacheMiss);
}
return page;
}
-void ZPageCache::free_page(ZPage* page) {
+void ZPageCache::free_page_inner(ZPage* page) {
const uint8_t type = page->type();
if (type == ZPageTypeSmall) {
_small.get(page->numa_id()).insert_first(page);
} else if (type == ZPageTypeMedium) {
_medium.insert_first(page);
} else {
_large.insert_first(page);
}
+}
+void ZPageCache::free_page(ZPage* page) {
+ free_page_inner(page);
_available += page->size();
}
bool ZPageCache::flush_list_inner(ZPageCacheFlushClosure* cl, ZList<ZPage>* from, ZList<ZPage>* to) {
ZPage* const page = from->last();
< prev index next >