8152491: Convert TracePageSizes to use UL

Reviewed-by: sjohanss, pliden
This commit is contained in:
Stefan Karlsson 2016-04-12 07:17:44 +02:00
parent 3200059098
commit cf254af2fb
17 changed files with 255 additions and 111 deletions

View file

@ -3006,9 +3006,7 @@ static char* allocate_pages_individually(size_t bytes, char* addr, DWORD flags,
}
#ifdef ASSERT
if (should_inject_error) {
if (TracePageSizes && Verbose) {
tty->print_cr("Reserving pages individually failed.");
}
log_develop_debug(pagesize)("Reserving pages individually failed.");
}
#endif
return NULL;
@ -3192,9 +3190,8 @@ char* os::reserve_memory_special(size_t bytes, size_t alignment, char* addr,
// 1) the UseLargePagesIndividualAllocation flag is set (set by default on WS2003)
// 2) NUMA Interleaving is enabled, in which case we use a different node for each page
if (UseLargePagesIndividualAllocation || UseNUMAInterleaving) {
if (TracePageSizes && Verbose) {
tty->print_cr("Reserving large pages individually.");
}
log_debug(pagesize)("Reserving large pages individually.");
char * p_buf = allocate_pages_individually(bytes, addr, flags, prot, LargePagesIndividualAllocationInjectError);
if (p_buf == NULL) {
// give an appropriate warning message
@ -3211,9 +3208,8 @@ char* os::reserve_memory_special(size_t bytes, size_t alignment, char* addr,
return p_buf;
} else {
if (TracePageSizes && Verbose) {
tty->print_cr("Reserving large pages in a single large chunk.");
}
log_debug(pagesize)("Reserving large pages in a single large chunk.");
// normal policy just allocate it all at once
DWORD flag = MEM_RESERVE | MEM_COMMIT | MEM_LARGE_PAGES;
char * res = (char *)VirtualAlloc(addr, bytes, flag, prot);

View file

@ -1829,10 +1829,14 @@ G1RegionToSpaceMapper* G1CollectedHeap::create_aux_memory_mapper(const char* des
HeapRegion::GrainBytes,
translation_factor,
mtGC);
if (TracePageSizes) {
tty->print_cr("G1 '%s': pg_sz=" SIZE_FORMAT " base=" PTR_FORMAT " size=" SIZE_FORMAT " alignment=" SIZE_FORMAT " reqsize=" SIZE_FORMAT,
description, preferred_page_size, p2i(rs.base()), rs.size(), rs.alignment(), size);
}
os::trace_page_sizes_for_requested_size(description,
size,
preferred_page_size,
rs.alignment(),
rs.base(),
rs.size());
return result;
}
@ -1906,26 +1910,28 @@ jint G1CollectedHeap::initialize() {
HeapRegion::GrainBytes,
1,
mtJavaHeap);
os::trace_page_sizes("G1 Heap", collector_policy()->min_heap_byte_size(),
max_byte_size, page_size,
os::trace_page_sizes("Heap",
collector_policy()->min_heap_byte_size(),
max_byte_size,
page_size,
heap_rs.base(),
heap_rs.size());
heap_storage->set_mapping_changed_listener(&_listener);
// Create storage for the BOT, card table, card counts table (hot card cache) and the bitmaps.
G1RegionToSpaceMapper* bot_storage =
create_aux_memory_mapper("Block offset table",
create_aux_memory_mapper("Block Offset Table",
G1BlockOffsetTable::compute_size(g1_rs.size() / HeapWordSize),
G1BlockOffsetTable::heap_map_factor());
ReservedSpace cardtable_rs(G1SATBCardTableLoggingModRefBS::compute_size(g1_rs.size() / HeapWordSize));
G1RegionToSpaceMapper* cardtable_storage =
create_aux_memory_mapper("Card table",
create_aux_memory_mapper("Card Table",
G1SATBCardTableLoggingModRefBS::compute_size(g1_rs.size() / HeapWordSize),
G1SATBCardTableLoggingModRefBS::heap_map_factor());
G1RegionToSpaceMapper* card_counts_storage =
create_aux_memory_mapper("Card counts table",
create_aux_memory_mapper("Card Counts Table",
G1CardCounts::compute_size(g1_rs.size() / HeapWordSize),
G1CardCounts::heap_map_factor());

View file

@ -26,18 +26,6 @@
#include "gc/parallel/generationSizer.hpp"
#include "gc/shared/collectorPolicy.hpp"
void GenerationSizer::trace_gen_sizes(const char* const str) {
if (TracePageSizes) {
tty->print_cr("%s: " SIZE_FORMAT "," SIZE_FORMAT " "
SIZE_FORMAT "," SIZE_FORMAT " "
SIZE_FORMAT,
str,
_min_old_size / K, _max_old_size / K,
_min_young_size / K, _max_young_size / K,
_max_heap_byte_size / K);
}
}
void GenerationSizer::initialize_alignments() {
_space_alignment = _gen_alignment = default_gen_alignment();
_heap_alignment = compute_heap_alignment();
@ -60,7 +48,6 @@ void GenerationSizer::initialize_flags() {
}
void GenerationSizer::initialize_size_info() {
trace_gen_sizes("ps heap raw");
const size_t max_page_sz = os::page_size_for_region_aligned(_max_heap_byte_size, 8);
const size_t min_pages = 4; // 1 for eden + 1 for each survivor + 1 for old
const size_t min_page_sz = os::page_size_for_region_aligned(_min_heap_byte_size, min_pages);
@ -76,6 +63,4 @@ void GenerationSizer::initialize_size_info() {
initialize_flags();
}
GenCollectorPolicy::initialize_size_info();
trace_gen_sizes("ps heap rnd");
}

View file

@ -33,8 +33,6 @@
class GenerationSizer : public GenCollectorPolicy {
private:
void trace_gen_sizes(const char* const str);
// The alignment used for boundary between young gen and old gen
static size_t default_gen_alignment() { return 64 * K * HeapWordSize; }

View file

@ -49,7 +49,7 @@ ParMarkBitMap::initialize(MemRegion covered_region)
const size_t rs_align = page_sz == (size_t) os::vm_page_size() ? 0 :
MAX2(page_sz, granularity);
ReservedSpace rs(_reserved_byte_size, rs_align, rs_align > 0);
os::trace_page_sizes("par bitmap", raw_bytes, raw_bytes, page_sz,
os::trace_page_sizes("Mark Bitmap", raw_bytes, raw_bytes, page_sz,
rs.base(), rs.size());
MemTracker::record_virtual_memory_type((address)rs.base(), mtGC);

View file

@ -60,8 +60,10 @@ jint ParallelScavengeHeap::initialize() {
ReservedSpace heap_rs = Universe::reserve_heap(heap_size, _collector_policy->heap_alignment());
os::trace_page_sizes("ps main", _collector_policy->min_heap_byte_size(),
heap_size, generation_alignment(),
os::trace_page_sizes("Heap",
_collector_policy->min_heap_byte_size(),
heap_size,
generation_alignment(),
heap_rs.base(),
heap_rs.size());

View file

@ -426,7 +426,7 @@ ParallelCompactData::create_vspace(size_t count, size_t element_size)
const size_t rs_align = page_sz == (size_t) os::vm_page_size() ? 0 :
MAX2(page_sz, granularity);
ReservedSpace rs(_reserved_byte_size, rs_align, rs_align > 0);
os::trace_page_sizes("par compact", raw_bytes, raw_bytes, page_sz, rs.base(),
os::trace_page_sizes("Parallel Compact Data", raw_bytes, raw_bytes, page_sz, rs.base(),
rs.size());
MemTracker::record_virtual_memory_type((address)rs.base(), mtGC);

View file

@ -93,7 +93,7 @@ void CardTableModRefBS::initialize() {
MemTracker::record_virtual_memory_type((address)heap_rs.base(), mtGC);
os::trace_page_sizes("card table", _guard_index + 1, _guard_index + 1,
os::trace_page_sizes("Card Table", _guard_index + 1, _guard_index + 1,
_page_size, heap_rs.base(), heap_rs.size());
if (!heap_rs.is_reserved()) {
vm_exit_during_initialization("Could not reserve enough space for the "

View file

@ -167,6 +167,14 @@ char* GenCollectedHeap::allocate(size_t alignment,
SIZE_FORMAT, total_reserved, alignment);
*heap_rs = Universe::reserve_heap(total_reserved, alignment);
os::trace_page_sizes("Heap",
collector_policy()->min_heap_byte_size(),
total_reserved,
alignment,
heap_rs->base(),
heap_rs->size());
return heap_rs->base();
}

View file

@ -70,6 +70,7 @@
LOG_TAG(monitorinflation) \
LOG_TAG(monitormismatch) \
LOG_TAG(os) \
LOG_TAG(pagesize) \
LOG_TAG(phases) \
LOG_TAG(plab) \
LOG_TAG(promotion) \

View file

@ -685,9 +685,6 @@ public:
"Use large page memory in metaspace. " \
"Only used if UseLargePages is enabled.") \
\
develop(bool, TracePageSizes, false, \
"Trace page size selection and usage") \
\
product(bool, UseNUMA, false, \
"Use NUMA if available") \
\

View file

@ -33,6 +33,7 @@
#include "gc/shared/vmGCOperations.hpp"
#include "interpreter/interpreter.hpp"
#include "logging/log.hpp"
#include "logging/logStream.inline.hpp"
#include "memory/allocation.inline.hpp"
#ifdef ASSERT
#include "memory/guardedMemory.hpp"
@ -1494,31 +1495,63 @@ const char* os::errno_name(int e) {
return errno_to_string(e, true);
}
#ifndef PRODUCT
void os::trace_page_sizes(const char* str, const size_t* page_sizes, int count)
{
if (TracePageSizes) {
tty->print("%s: ", str);
void os::trace_page_sizes(const char* str, const size_t* page_sizes, int count) {
LogTarget(Info, pagesize) log;
if (log.is_enabled()) {
LogStreamCHeap out(log);
out.print("%s: ", str);
for (int i = 0; i < count; ++i) {
tty->print(" " SIZE_FORMAT, page_sizes[i]);
out.print(" " SIZE_FORMAT, page_sizes[i]);
}
tty->cr();
out.cr();
}
}
void os::trace_page_sizes(const char* str, const size_t region_min_size,
const size_t region_max_size, const size_t page_size,
const char* base, const size_t size)
{
if (TracePageSizes) {
tty->print_cr("%s: min=" SIZE_FORMAT " max=" SIZE_FORMAT
" pg_sz=" SIZE_FORMAT " base=" PTR_FORMAT
" size=" SIZE_FORMAT,
str, region_min_size, region_max_size,
page_size, p2i(base), size);
#define trace_page_size_params(size) byte_size_in_exact_unit(size), exact_unit_for_byte_size(size)
void os::trace_page_sizes(const char* str,
const size_t region_min_size,
const size_t region_max_size,
const size_t page_size,
const char* base,
const size_t size) {
log_info(pagesize)("%s: "
" min=" SIZE_FORMAT "%s"
" max=" SIZE_FORMAT "%s"
" base=" PTR_FORMAT
" page_size=" SIZE_FORMAT "%s"
" size=" SIZE_FORMAT "%s",
str,
trace_page_size_params(region_min_size),
trace_page_size_params(region_max_size),
p2i(base),
trace_page_size_params(page_size),
trace_page_size_params(size));
}
void os::trace_page_sizes_for_requested_size(const char* str,
const size_t requested_size,
const size_t page_size,
const size_t alignment,
const char* base,
const size_t size) {
log_info(pagesize)("%s:"
" req_size=" SIZE_FORMAT "%s"
" base=" PTR_FORMAT
" page_size=" SIZE_FORMAT "%s"
" alignment=" SIZE_FORMAT "%s"
" size=" SIZE_FORMAT "%s",
str,
trace_page_size_params(requested_size),
p2i(base),
trace_page_size_params(page_size),
trace_page_size_params(alignment),
trace_page_size_params(size));
}
#endif // #ifndef PRODUCT
// This is the working definition of a server class machine:
// >= 2 physical CPU's and >=2GB of memory, with some fuzz

View file

@ -286,18 +286,24 @@ class os: AllStatic {
return _page_sizes[0];
}
// Methods for tracing page sizes returned by the above method; enabled by
// TracePageSizes. The region_{min,max}_size parameters should be the values
// Methods for tracing page sizes returned by the above method.
// The region_{min,max}_size parameters should be the values
// passed to page_size_for_region() and page_size should be the result of that
// call. The (optional) base and size parameters should come from the
// ReservedSpace base() and size() methods.
static void trace_page_sizes(const char* str, const size_t* page_sizes,
int count) PRODUCT_RETURN;
static void trace_page_sizes(const char* str, const size_t region_min_size,
static void trace_page_sizes(const char* str, const size_t* page_sizes, int count);
static void trace_page_sizes(const char* str,
const size_t region_min_size,
const size_t region_max_size,
const size_t page_size,
const char* base = NULL,
const size_t size = 0) PRODUCT_RETURN;
const char* base,
const size_t size);
static void trace_page_sizes_for_requested_size(const char* str,
const size_t requested_size,
const size_t page_size,
const size_t alignment,
const char* base,
const size_t size);
static int vm_allocation_granularity();
static char* reserve_memory(size_t bytes, char* addr = 0,

View file

@ -374,12 +374,10 @@ STATIC_ASSERT(left_n_bits(1|2) == (intptr_t) LP64_ONLY(0xE000000000000000) NOT_L
#ifndef PRODUCT
// For unit testing only
class GlobalDefinitions {
public:
static void test_globals();
};
class TestGlobalDefinitions {
private:
void GlobalDefinitions::test_globals() {
static void test_clamp_address_in_page() {
intptr_t page_sizes[] = { os::vm_page_size(), 4096, 8192, 65536, 2*1024*1024 };
const int num_page_sizes = sizeof(page_sizes) / sizeof(page_sizes[0]);
@ -405,8 +403,60 @@ void GlobalDefinitions::test_globals() {
}
}
void GlobalDefinitions_test() {
GlobalDefinitions::test_globals();
static void test_exact_unit_for_byte_size() {
assert(strcmp(exact_unit_for_byte_size(0), "B") == 0, "incorrect");
assert(strcmp(exact_unit_for_byte_size(1), "B") == 0, "incorrect");
assert(strcmp(exact_unit_for_byte_size(K - 1), "B") == 0, "incorrect");
assert(strcmp(exact_unit_for_byte_size(K), "K") == 0, "incorrect");
assert(strcmp(exact_unit_for_byte_size(K + 1), "B") == 0, "incorrect");
assert(strcmp(exact_unit_for_byte_size(M - 1), "B") == 0, "incorrect");
assert(strcmp(exact_unit_for_byte_size(M), "M") == 0, "incorrect");
assert(strcmp(exact_unit_for_byte_size(M + 1), "B") == 0, "incorrect");
assert(strcmp(exact_unit_for_byte_size(M + K), "K") == 0, "incorrect");
#ifdef LP64
assert(strcmp(exact_unit_for_byte_size(G - 1), "B") == 0, "incorrect");
assert(strcmp(exact_unit_for_byte_size(G), "G") == 0, "incorrect");
assert(strcmp(exact_unit_for_byte_size(G + 1), "B") == 0, "incorrect");
assert(strcmp(exact_unit_for_byte_size(G + K), "K") == 0, "incorrect");
assert(strcmp(exact_unit_for_byte_size(G + M), "M") == 0, "incorrect");
assert(strcmp(exact_unit_for_byte_size(G + M + K), "K") == 0, "incorrect");
#endif
}
static void test_byte_size_in_exact_unit() {
assert(byte_size_in_exact_unit(0) == 0, "incorrect");
assert(byte_size_in_exact_unit(1) == 1, "incorrect");
assert(byte_size_in_exact_unit(K - 1) == K - 1, "incorrect");
assert(byte_size_in_exact_unit(K) == 1, "incorrect");
assert(byte_size_in_exact_unit(K + 1) == K + 1, "incorrect");
assert(byte_size_in_exact_unit(M - 1) == M - 1, "incorrect");
assert(byte_size_in_exact_unit(M) == 1, "incorrect");
assert(byte_size_in_exact_unit(M + 1) == M + 1, "incorrect");
assert(byte_size_in_exact_unit(M + K) == K + 1, "incorrect");
#ifdef LP64
assert(byte_size_in_exact_unit(G - 1) == G - 1, "incorrect");
assert(byte_size_in_exact_unit(G) == 1, "incorrect");
assert(byte_size_in_exact_unit(G + 1) == G + 1, "incorrect");
assert(byte_size_in_exact_unit(G + K) == M + 1, "incorrect");
assert(byte_size_in_exact_unit(G + M) == K + 1, "incorrect");
assert(byte_size_in_exact_unit(G + M + K) == M + K + 1, "incorrect");
#endif
}
static void test_exact_units() {
test_exact_unit_for_byte_size();
test_byte_size_in_exact_unit();
}
public:
static void test() {
test_clamp_address_in_page();
test_exact_units();
}
};
void TestGlobalDefinitions_test() {
TestGlobalDefinitions::test();
}
#endif // PRODUCT

View file

@ -243,6 +243,36 @@ inline T byte_size_in_proper_unit(T s) {
}
}
inline const char* exact_unit_for_byte_size(size_t s) {
#ifdef _LP64
if (s >= G && (s % G) == 0) {
return "G";
}
#endif
if (s >= M && (s % M) == 0) {
return "M";
}
if (s >= K && (s % K) == 0) {
return "K";
}
return "B";
}
inline size_t byte_size_in_exact_unit(size_t s) {
#ifdef _LP64
if (s >= G && (s % G) == 0) {
return s / G;
}
#endif
if (s >= M && (s % M) == 0) {
return s / M;
}
if (s >= K && (s % K) == 0) {
return s / K;
}
return s;
}
//----------------------------------------------------------------------------------------------------
// VM type definitions

View file

@ -50,7 +50,7 @@ void InternalVMTests::run() {
run_unit_test(TestMetaspaceAux_test);
run_unit_test(TestMetachunk_test);
run_unit_test(TestVirtualSpaceNode_test);
run_unit_test(GlobalDefinitions_test);
run_unit_test(TestGlobalDefinitions_test);
run_unit_test(GCTimer_test);
run_unit_test(arrayOopDesc_test);
run_unit_test(CollectedHeap_test);

View file

@ -36,6 +36,8 @@
*/
import java.lang.Math;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import jdk.test.lib.*;
import jdk.test.lib.Asserts;
@ -47,14 +49,29 @@ public class TestLargePageUseForAuxMemory {
static long smallPageSize;
static long allocGranularity;
static void checkSize(OutputAnalyzer output, long expectedSize, String pattern) {
String pageSizeStr = output.firstMatch(pattern, 1);
if (pageSizeStr == null) {
output.reportDiagnosticSummary();
throw new RuntimeException("Match from '" + pattern + "' got 'null' expected: " + expectedSize);
}
long size = parseMemoryString(pageSizeStr);
if (size != expectedSize) {
output.reportDiagnosticSummary();
throw new RuntimeException("Match from '" + pattern + "' got " + size + " expected: " + expectedSize);
}
}
static void checkSmallTables(OutputAnalyzer output, long expectedPageSize) throws Exception {
output.shouldContain("G1 'Block offset table': pg_sz=" + expectedPageSize);
output.shouldContain("G1 'Card counts table': pg_sz=" + expectedPageSize);
checkSize(output, expectedPageSize, "Block Offset Table: .*page_size=([^ ]+)");
checkSize(output, expectedPageSize, "Card Counts Table: .*page_size=([^ ]+)");
}
static void checkBitmaps(OutputAnalyzer output, long expectedPageSize) throws Exception {
output.shouldContain("G1 'Prev Bitmap': pg_sz=" + expectedPageSize);
output.shouldContain("G1 'Next Bitmap': pg_sz=" + expectedPageSize);
checkSize(output, expectedPageSize, "Prev Bitmap: .*page_size=([^ ]+)");
checkSize(output, expectedPageSize, "Next Bitmap: .*page_size=([^ ]+)");
}
static void testVM(String what, long heapsize, boolean cardsShouldUseLargePages, boolean bitmapShouldUseLargePages) throws Exception {
@ -66,7 +83,7 @@ public class TestLargePageUseForAuxMemory {
"-XX:G1HeapRegionSize=" + HEAP_REGION_SIZE,
"-Xms" + heapsize,
"-Xmx" + heapsize,
"-XX:+TracePageSizes",
"-Xlog:pagesize",
"-XX:+UseLargePages",
"-XX:+IgnoreUnrecognizedVMOptions", // there is no ObjectAlignmentInBytes in 32 bit builds
"-XX:ObjectAlignmentInBytes=8",
@ -82,7 +99,7 @@ public class TestLargePageUseForAuxMemory {
"-XX:G1HeapRegionSize=" + HEAP_REGION_SIZE,
"-Xms" + heapsize,
"-Xmx" + heapsize,
"-XX:+TracePageSizes",
"-Xlog:pagesize",
"-XX:-UseLargePages",
"-XX:+IgnoreUnrecognizedVMOptions", // there is no ObjectAlignmentInBytes in 32 bit builds
"-XX:ObjectAlignmentInBytes=8",
@ -108,11 +125,6 @@ public class TestLargePageUseForAuxMemory {
}
public static void main(String[] args) throws Exception {
if (!Platform.isDebugBuild()) {
System.out.println("Skip tests on non-debug builds because the required option TracePageSizes is a debug-only option.");
return;
}
// Size that a single card covers.
final int cardSize = 512;
WhiteBox wb = WhiteBox.getWhiteBox();
@ -159,4 +171,24 @@ public class TestLargePageUseForAuxMemory {
testVM("case5: only bitmap uses large pages (extra slack)", heapSizeForBitmapUsingLargePages + heapSizeDiffForBitmap, false, true);
testVM("case6: nothing uses large pages (barely not)", heapSizeForBitmapUsingLargePages - heapSizeDiffForBitmap, false, false);
}
public static long parseMemoryString(String value) {
long multiplier = 1;
if (value.endsWith("B")) {
multiplier = 1;
} else if (value.endsWith("K")) {
multiplier = 1024;
} else if (value.endsWith("M")) {
multiplier = 1024 * 1024;
} else if (value.endsWith("G")) {
multiplier = 1024 * 1024 * 1024;
} else {
throw new IllegalArgumentException("Expected memory string '" + value + "'to end with either of: B, K, M, G");
}
long longValue = Long.parseUnsignedLong(value.substring(0, value.length() - 1));
return longValue * multiplier;
}
}