提交 58866ecd 编写于 作者: T tschatzl

Merge

...@@ -3589,8 +3589,6 @@ jint os::init_2(void) ...@@ -3589,8 +3589,6 @@ jint os::init_2(void)
#endif #endif
} }
os::large_page_init();
// initialize suspend/resume support - must do this before signal_sets_init() // initialize suspend/resume support - must do this before signal_sets_init()
if (SR_initialize() != 0) { if (SR_initialize() != 0) {
perror("SR_initialize failed"); perror("SR_initialize failed");
......
...@@ -4755,8 +4755,6 @@ jint os::init_2(void) ...@@ -4755,8 +4755,6 @@ jint os::init_2(void)
#endif #endif
} }
os::large_page_init();
// initialize suspend/resume support - must do this before signal_sets_init() // initialize suspend/resume support - must do this before signal_sets_init()
if (SR_initialize() != 0) { if (SR_initialize() != 0) {
perror("SR_initialize failed"); perror("SR_initialize failed");
......
...@@ -5178,9 +5178,7 @@ jint os::init_2(void) { ...@@ -5178,9 +5178,7 @@ jint os::init_2(void) {
if(Verbose && PrintMiscellaneous) if(Verbose && PrintMiscellaneous)
tty->print("[Memory Serialize Page address: " INTPTR_FORMAT "]\n", (intptr_t)mem_serialize_page); tty->print("[Memory Serialize Page address: " INTPTR_FORMAT "]\n", (intptr_t)mem_serialize_page);
#endif #endif
} }
os::large_page_init();
// Check minimum allowable stack size for thread creation and to initialize // Check minimum allowable stack size for thread creation and to initialize
// the java system classes, including StackOverflowError - depends on page // the java system classes, including StackOverflowError - depends on page
......
...@@ -3920,8 +3920,6 @@ jint os::init_2(void) { ...@@ -3920,8 +3920,6 @@ jint os::init_2(void) {
#endif #endif
} }
os::large_page_init();
// Setup Windows Exceptions // Setup Windows Exceptions
// for debugging float code generation bugs // for debugging float code generation bugs
......
...@@ -2191,6 +2191,10 @@ jint G1CollectedHeap::initialize() { ...@@ -2191,6 +2191,10 @@ jint G1CollectedHeap::initialize() {
return JNI_OK; return JNI_OK;
} }
size_t G1CollectedHeap::conservative_max_heap_alignment() {
return HeapRegion::max_region_size();
}
void G1CollectedHeap::ref_processing_init() { void G1CollectedHeap::ref_processing_init() {
// Reference processing in G1 currently works as follows: // Reference processing in G1 currently works as follows:
// //
......
...@@ -1092,6 +1092,9 @@ public: ...@@ -1092,6 +1092,9 @@ public:
// specified by the policy object. // specified by the policy object.
jint initialize(); jint initialize();
// Return the (conservative) maximum heap alignment for any G1 heap
static size_t conservative_max_heap_alignment();
// Initialize weak reference processing. // Initialize weak reference processing.
virtual void ref_processing_init(); virtual void ref_processing_init();
......
/* /*
* Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -149,6 +149,10 @@ void HeapRegionDCTOC::walk_mem_region_with_cl(MemRegion mr, ...@@ -149,6 +149,10 @@ void HeapRegionDCTOC::walk_mem_region_with_cl(MemRegion mr,
// many regions in the heap (based on the min heap size). // many regions in the heap (based on the min heap size).
#define TARGET_REGION_NUMBER 2048 #define TARGET_REGION_NUMBER 2048
size_t HeapRegion::max_region_size() {
return (size_t)MAX_REGION_SIZE;
}
void HeapRegion::setup_heap_region_size(size_t initial_heap_size, size_t max_heap_size) { void HeapRegion::setup_heap_region_size(size_t initial_heap_size, size_t max_heap_size) {
uintx region_size = G1HeapRegionSize; uintx region_size = G1HeapRegionSize;
if (FLAG_IS_DEFAULT(G1HeapRegionSize)) { if (FLAG_IS_DEFAULT(G1HeapRegionSize)) {
......
/* /*
* Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -355,6 +355,8 @@ class HeapRegion: public G1OffsetTableContigSpace { ...@@ -355,6 +355,8 @@ class HeapRegion: public G1OffsetTableContigSpace {
~((1 << (size_t) LogOfHRGrainBytes) - 1); ~((1 << (size_t) LogOfHRGrainBytes) - 1);
} }
static size_t max_region_size();
// It sets up the heap region size (GrainBytes / GrainWords), as // It sets up the heap region size (GrainBytes / GrainWords), as
// well as other related fields that are based on the heap region // well as other related fields that are based on the heap region
// size (LogOfHRGrainBytes / LogOfHRGrainWords / // size (LogOfHRGrainBytes / LogOfHRGrainWords /
......
...@@ -86,6 +86,11 @@ class ParallelScavengeHeap : public CollectedHeap { ...@@ -86,6 +86,11 @@ class ParallelScavengeHeap : public CollectedHeap {
set_alignment(_old_gen_alignment, intra_heap_alignment()); set_alignment(_old_gen_alignment, intra_heap_alignment());
} }
// Return the (conservative) maximum heap alignment
static size_t conservative_max_heap_alignment() {
return intra_heap_alignment();
}
// For use by VM operations // For use by VM operations
enum CollectionType { enum CollectionType {
Scavenge, Scavenge,
...@@ -122,7 +127,7 @@ class ParallelScavengeHeap : public CollectedHeap { ...@@ -122,7 +127,7 @@ class ParallelScavengeHeap : public CollectedHeap {
// The alignment used for eden and survivors within the young gen // The alignment used for eden and survivors within the young gen
// and for boundary between young gen and old gen. // and for boundary between young gen and old gen.
size_t intra_heap_alignment() const { return 64 * K * HeapWordSize; } static size_t intra_heap_alignment() { return 64 * K * HeapWordSize; }
size_t capacity() const; size_t capacity() const;
size_t used() const; size_t used() const;
......
...@@ -145,6 +145,30 @@ void CollectorPolicy::cleared_all_soft_refs() { ...@@ -145,6 +145,30 @@ void CollectorPolicy::cleared_all_soft_refs() {
_all_soft_refs_clear = true; _all_soft_refs_clear = true;
} }
size_t CollectorPolicy::compute_max_alignment() {
// The card marking array and the offset arrays for old generations are
// committed in os pages as well. Make sure they are entirely full (to
// avoid partial page problems), e.g. if 512 bytes heap corresponds to 1
// byte entry and the os page size is 4096, the maximum heap size should
// be 512*4096 = 2MB aligned.
// There is only the GenRemSet in Hotspot and only the GenRemSet::CardTable
// is supported.
// Requirements of any new remembered set implementations must be added here.
size_t alignment = GenRemSet::max_alignment_constraint(GenRemSet::CardTable);
// Parallel GC does its own alignment of the generations to avoid requiring a
// large page (256M on some platforms) for the permanent generation. The
// other collectors should also be updated to do their own alignment and then
// this use of lcm() should be removed.
if (UseLargePages && !UseParallelGC) {
// in presence of large pages we have to make sure that our
// alignment is large page aware
alignment = lcm(os::large_page_size(), alignment);
}
return alignment;
}
// GenCollectorPolicy methods. // GenCollectorPolicy methods.
...@@ -175,29 +199,6 @@ void GenCollectorPolicy::initialize_size_policy(size_t init_eden_size, ...@@ -175,29 +199,6 @@ void GenCollectorPolicy::initialize_size_policy(size_t init_eden_size,
GCTimeRatio); GCTimeRatio);
} }
size_t GenCollectorPolicy::compute_max_alignment() {
// The card marking array and the offset arrays for old generations are
// committed in os pages as well. Make sure they are entirely full (to
// avoid partial page problems), e.g. if 512 bytes heap corresponds to 1
// byte entry and the os page size is 4096, the maximum heap size should
// be 512*4096 = 2MB aligned.
size_t alignment = GenRemSet::max_alignment_constraint(rem_set_name());
// Parallel GC does its own alignment of the generations to avoid requiring a
// large page (256M on some platforms) for the permanent generation. The
// other collectors should also be updated to do their own alignment and then
// this use of lcm() should be removed.
if (UseLargePages && !UseParallelGC) {
// in presence of large pages we have to make sure that our
// alignment is large page aware
alignment = lcm(os::large_page_size(), alignment);
}
assert(alignment >= min_alignment(), "Must be");
return alignment;
}
void GenCollectorPolicy::initialize_flags() { void GenCollectorPolicy::initialize_flags() {
// All sizes must be multiples of the generation granularity. // All sizes must be multiples of the generation granularity.
set_min_alignment((uintx) Generation::GenGrain); set_min_alignment((uintx) Generation::GenGrain);
......
...@@ -98,6 +98,9 @@ class CollectorPolicy : public CHeapObj<mtGC> { ...@@ -98,6 +98,9 @@ class CollectorPolicy : public CHeapObj<mtGC> {
{} {}
public: public:
// Return maximum heap alignment that may be imposed by the policy
static size_t compute_max_alignment();
void set_min_alignment(size_t align) { _min_alignment = align; } void set_min_alignment(size_t align) { _min_alignment = align; }
size_t min_alignment() { return _min_alignment; } size_t min_alignment() { return _min_alignment; }
void set_max_alignment(size_t align) { _max_alignment = align; } void set_max_alignment(size_t align) { _max_alignment = align; }
...@@ -234,9 +237,6 @@ class GenCollectorPolicy : public CollectorPolicy { ...@@ -234,9 +237,6 @@ class GenCollectorPolicy : public CollectorPolicy {
// Try to allocate space by expanding the heap. // Try to allocate space by expanding the heap.
virtual HeapWord* expand_heap_and_allocate(size_t size, bool is_tlab); virtual HeapWord* expand_heap_and_allocate(size_t size, bool is_tlab);
// compute max heap alignment
size_t compute_max_alignment();
// Scale the base_size by NewRation according to // Scale the base_size by NewRation according to
// result = base_size / (NewRatio + 1) // result = base_size / (NewRatio + 1)
// and align by min_alignment() // and align by min_alignment()
......
/* /*
* Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -148,6 +148,11 @@ public: ...@@ -148,6 +148,11 @@ public:
return gen_policy()->size_policy(); return gen_policy()->size_policy();
} }
// Return the (conservative) maximum heap alignment
static size_t conservative_max_heap_alignment() {
return Generation::GenGrain;
}
size_t capacity() const; size_t capacity() const;
size_t used() const; size_t used() const;
......
...@@ -872,6 +872,9 @@ jint Universe::initialize_heap() { ...@@ -872,6 +872,9 @@ jint Universe::initialize_heap() {
// Reserve the Java heap, which is now the same for all GCs. // Reserve the Java heap, which is now the same for all GCs.
ReservedSpace Universe::reserve_heap(size_t heap_size, size_t alignment) { ReservedSpace Universe::reserve_heap(size_t heap_size, size_t alignment) {
assert(alignment <= Arguments::conservative_max_heap_alignment(),
err_msg("actual alignment "SIZE_FORMAT" must be within maximum heap alignment "SIZE_FORMAT,
alignment, Arguments::conservative_max_heap_alignment()));
size_t total_reserved = align_size_up(heap_size, alignment); size_t total_reserved = align_size_up(heap_size, alignment);
assert(!UseCompressedOops || (total_reserved <= (OopEncodingHeapMax - os::vm_page_size())), assert(!UseCompressedOops || (total_reserved <= (OopEncodingHeapMax - os::vm_page_size())),
"heap size is too big for compressed oops"); "heap size is too big for compressed oops");
......
...@@ -33,6 +33,7 @@ ...@@ -33,6 +33,7 @@
#include "prims/whitebox.hpp" #include "prims/whitebox.hpp"
#include "prims/wbtestmethods/parserTests.hpp" #include "prims/wbtestmethods/parserTests.hpp"
#include "runtime/arguments.hpp"
#include "runtime/interfaceSupport.hpp" #include "runtime/interfaceSupport.hpp"
#include "runtime/os.hpp" #include "runtime/os.hpp"
#include "utilities/debug.hpp" #include "utilities/debug.hpp"
...@@ -94,6 +95,11 @@ WB_ENTRY(jboolean, WB_IsClassAlive(JNIEnv* env, jobject target, jstring name)) ...@@ -94,6 +95,11 @@ WB_ENTRY(jboolean, WB_IsClassAlive(JNIEnv* env, jobject target, jstring name))
return closure.found(); return closure.found();
WB_END WB_END
WB_ENTRY(jlong, WB_GetCompressedOopsMaxHeapSize(JNIEnv* env, jobject o)) {
return (jlong)Arguments::max_heap_for_compressed_oops();
}
WB_END
WB_ENTRY(void, WB_PrintHeapSizes(JNIEnv* env, jobject o)) { WB_ENTRY(void, WB_PrintHeapSizes(JNIEnv* env, jobject o)) {
CollectorPolicy * p = Universe::heap()->collector_policy(); CollectorPolicy * p = Universe::heap()->collector_policy();
gclog_or_tty->print_cr("Minimum heap "SIZE_FORMAT" Initial heap " gclog_or_tty->print_cr("Minimum heap "SIZE_FORMAT" Initial heap "
...@@ -436,6 +442,8 @@ static JNINativeMethod methods[] = { ...@@ -436,6 +442,8 @@ static JNINativeMethod methods[] = {
CC"(Ljava/lang/String;[Lsun/hotspot/parser/DiagnosticCommand;)[Ljava/lang/Object;", CC"(Ljava/lang/String;[Lsun/hotspot/parser/DiagnosticCommand;)[Ljava/lang/Object;",
(void*) &WB_ParseCommandLine (void*) &WB_ParseCommandLine
}, },
{CC"getCompressedOopsMaxHeapSize", CC"()J",
(void*)&WB_GetCompressedOopsMaxHeapSize},
{CC"printHeapSizes", CC"()V", (void*)&WB_PrintHeapSizes }, {CC"printHeapSizes", CC"()V", (void*)&WB_PrintHeapSizes },
#if INCLUDE_ALL_GCS #if INCLUDE_ALL_GCS
{CC"g1InConcurrentMark", CC"()Z", (void*)&WB_G1InConcurrentMark}, {CC"g1InConcurrentMark", CC"()Z", (void*)&WB_G1InConcurrentMark},
......
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
#include "compiler/compilerOracle.hpp" #include "compiler/compilerOracle.hpp"
#include "memory/allocation.inline.hpp" #include "memory/allocation.inline.hpp"
#include "memory/cardTableRS.hpp" #include "memory/cardTableRS.hpp"
#include "memory/genCollectedHeap.hpp"
#include "memory/referenceProcessor.hpp" #include "memory/referenceProcessor.hpp"
#include "memory/universe.inline.hpp" #include "memory/universe.inline.hpp"
#include "oops/oop.inline.hpp" #include "oops/oop.inline.hpp"
...@@ -54,6 +55,8 @@ ...@@ -54,6 +55,8 @@
#endif #endif
#if INCLUDE_ALL_GCS #if INCLUDE_ALL_GCS
#include "gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp" #include "gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp"
#include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
#include "gc_implementation/parallelScavenge/parallelScavengeHeap.hpp"
#endif // INCLUDE_ALL_GCS #endif // INCLUDE_ALL_GCS
// Note: This is a special bug reporting site for the JVM // Note: This is a special bug reporting site for the JVM
...@@ -90,6 +93,7 @@ char* Arguments::_java_command = NULL; ...@@ -90,6 +93,7 @@ char* Arguments::_java_command = NULL;
SystemProperty* Arguments::_system_properties = NULL; SystemProperty* Arguments::_system_properties = NULL;
const char* Arguments::_gc_log_filename = NULL; const char* Arguments::_gc_log_filename = NULL;
bool Arguments::_has_profile = false; bool Arguments::_has_profile = false;
size_t Arguments::_conservative_max_heap_alignment = 0;
uintx Arguments::_min_heap_size = 0; uintx Arguments::_min_heap_size = 0;
Arguments::Mode Arguments::_mode = _mixed; Arguments::Mode Arguments::_mode = _mixed;
bool Arguments::_java_compiler = false; bool Arguments::_java_compiler = false;
...@@ -1391,10 +1395,17 @@ bool verify_object_alignment() { ...@@ -1391,10 +1395,17 @@ bool verify_object_alignment() {
return true; return true;
} }
inline uintx max_heap_for_compressed_oops() { uintx Arguments::max_heap_for_compressed_oops() {
// Avoid sign flip. // Avoid sign flip.
assert(OopEncodingHeapMax > (uint64_t)os::vm_page_size(), "Unusual page size"); assert(OopEncodingHeapMax > (uint64_t)os::vm_page_size(), "Unusual page size");
LP64_ONLY(return OopEncodingHeapMax - os::vm_page_size()); // We need to fit both the NULL page and the heap into the memory budget, while
// keeping alignment constraints of the heap. To guarantee the latter, as the
// NULL page is located before the heap, we pad the NULL page to the conservative
// maximum alignment that the GC may ever impose upon the heap.
size_t displacement_due_to_null_page = align_size_up_(os::vm_page_size(),
Arguments::conservative_max_heap_alignment());
LP64_ONLY(return OopEncodingHeapMax - displacement_due_to_null_page);
NOT_LP64(ShouldNotReachHere(); return 0); NOT_LP64(ShouldNotReachHere(); return 0);
} }
...@@ -1475,6 +1486,23 @@ void Arguments::set_use_compressed_klass_ptrs() { ...@@ -1475,6 +1486,23 @@ void Arguments::set_use_compressed_klass_ptrs() {
#endif // !ZERO #endif // !ZERO
} }
void Arguments::set_conservative_max_heap_alignment() {
// The conservative maximum required alignment for the heap is the maximum of
// the alignments imposed by several sources: any requirements from the heap
// itself, the collector policy and the maximum page size we may run the VM
// with.
size_t heap_alignment = GenCollectedHeap::conservative_max_heap_alignment();
#if INCLUDE_ALL_GCS
if (UseParallelGC) {
heap_alignment = ParallelScavengeHeap::conservative_max_heap_alignment();
} else if (UseG1GC) {
heap_alignment = G1CollectedHeap::conservative_max_heap_alignment();
}
#endif // INCLUDE_ALL_GCS
_conservative_max_heap_alignment = MAX3(heap_alignment, os::max_page_size(),
CollectorPolicy::compute_max_alignment());
}
void Arguments::set_ergonomics_flags() { void Arguments::set_ergonomics_flags() {
if (os::is_server_class_machine()) { if (os::is_server_class_machine()) {
...@@ -1503,6 +1531,8 @@ void Arguments::set_ergonomics_flags() { ...@@ -1503,6 +1531,8 @@ void Arguments::set_ergonomics_flags() {
} }
} }
set_conservative_max_heap_alignment();
#ifndef ZERO #ifndef ZERO
#ifdef _LP64 #ifdef _LP64
set_use_compressed_oops(); set_use_compressed_oops();
...@@ -3506,6 +3536,11 @@ jint Arguments::parse(const JavaVMInitArgs* args) { ...@@ -3506,6 +3536,11 @@ jint Arguments::parse(const JavaVMInitArgs* args) {
no_shared_spaces(); no_shared_spaces();
#endif // INCLUDE_CDS #endif // INCLUDE_CDS
return JNI_OK;
}
jint Arguments::apply_ergo() {
// Set flags based on ergonomics. // Set flags based on ergonomics.
set_ergonomics_flags(); set_ergonomics_flags();
......
...@@ -280,6 +280,9 @@ class Arguments : AllStatic { ...@@ -280,6 +280,9 @@ class Arguments : AllStatic {
// Option flags // Option flags
static bool _has_profile; static bool _has_profile;
static const char* _gc_log_filename; static const char* _gc_log_filename;
// Value of the conservative maximum heap alignment needed
static size_t _conservative_max_heap_alignment;
static uintx _min_heap_size; static uintx _min_heap_size;
// -Xrun arguments // -Xrun arguments
...@@ -327,6 +330,7 @@ class Arguments : AllStatic { ...@@ -327,6 +330,7 @@ class Arguments : AllStatic {
// Garbage-First (UseG1GC) // Garbage-First (UseG1GC)
static void set_g1_gc_flags(); static void set_g1_gc_flags();
// GC ergonomics // GC ergonomics
static void set_conservative_max_heap_alignment();
static void set_use_compressed_oops(); static void set_use_compressed_oops();
static void set_use_compressed_klass_ptrs(); static void set_use_compressed_klass_ptrs();
static void set_ergonomics_flags(); static void set_ergonomics_flags();
...@@ -430,8 +434,10 @@ class Arguments : AllStatic { ...@@ -430,8 +434,10 @@ class Arguments : AllStatic {
static char* SharedArchivePath; static char* SharedArchivePath;
public: public:
// Parses the arguments // Parses the arguments, first phase
static jint parse(const JavaVMInitArgs* args); static jint parse(const JavaVMInitArgs* args);
// Apply ergonomics
static jint apply_ergo();
// Adjusts the arguments after the OS have adjusted the arguments // Adjusts the arguments after the OS have adjusted the arguments
static jint adjust_after_os(); static jint adjust_after_os();
// Check for consistency in the selection of the garbage collector. // Check for consistency in the selection of the garbage collector.
...@@ -445,6 +451,10 @@ class Arguments : AllStatic { ...@@ -445,6 +451,10 @@ class Arguments : AllStatic {
// Used by os_solaris // Used by os_solaris
static bool process_settings_file(const char* file_name, bool should_exist, jboolean ignore_unrecognized); static bool process_settings_file(const char* file_name, bool should_exist, jboolean ignore_unrecognized);
static size_t conservative_max_heap_alignment() { return _conservative_max_heap_alignment; }
// Return the maximum size a heap with compressed oops can take
static size_t max_heap_for_compressed_oops();
// return a char* array containing all options // return a char* array containing all options
static char** jvm_flags_array() { return _jvm_flags_array; } static char** jvm_flags_array() { return _jvm_flags_array; }
static char** jvm_args_array() { return _jvm_args_array; } static char** jvm_args_array() { return _jvm_args_array; }
......
...@@ -314,6 +314,11 @@ static void signal_thread_entry(JavaThread* thread, TRAPS) { ...@@ -314,6 +314,11 @@ static void signal_thread_entry(JavaThread* thread, TRAPS) {
} }
} }
void os::init_before_ergo() {
// We need to initialize large page support here because ergonomics takes some
// decisions depending on large page support and the calculated large page size.
large_page_init();
}
void os::signal_init() { void os::signal_init() {
if (!ReduceSignalUsage) { if (!ReduceSignalUsage) {
......
...@@ -139,7 +139,10 @@ class os: AllStatic { ...@@ -139,7 +139,10 @@ class os: AllStatic {
public: public:
static void init(void); // Called before command line parsing static void init(void); // Called before command line parsing
static void init_before_ergo(void); // Called after command line parsing
// before VM ergonomics processing.
static jint init_2(void); // Called after command line parsing static jint init_2(void); // Called after command line parsing
// and VM ergonomics processing
static void init_globals(void) { // Called from init_globals() in init.cpp static void init_globals(void) { // Called from init_globals() in init.cpp
init_globals_ext(); init_globals_ext();
} }
...@@ -254,6 +257,11 @@ class os: AllStatic { ...@@ -254,6 +257,11 @@ class os: AllStatic {
static size_t page_size_for_region(size_t region_min_size, static size_t page_size_for_region(size_t region_min_size,
size_t region_max_size, size_t region_max_size,
uint min_pages); uint min_pages);
// Return the largest page size that can be used
static size_t max_page_size() {
// The _page_sizes array is sorted in descending order.
return _page_sizes[0];
}
// Methods for tracing page sizes returned by the above method; enabled by // Methods for tracing page sizes returned by the above method; enabled by
// TracePageSizes. The region_{min,max}_size parameters should be the values // TracePageSizes. The region_{min,max}_size parameters should be the values
......
...@@ -3329,6 +3329,11 @@ jint Threads::create_vm(JavaVMInitArgs* args, bool* canTryAgain) { ...@@ -3329,6 +3329,11 @@ jint Threads::create_vm(JavaVMInitArgs* args, bool* canTryAgain) {
jint parse_result = Arguments::parse(args); jint parse_result = Arguments::parse(args);
if (parse_result != JNI_OK) return parse_result; if (parse_result != JNI_OK) return parse_result;
os::init_before_ergo();
jint ergo_result = Arguments::apply_ergo();
if (ergo_result != JNI_OK) return ergo_result;
if (PauseAtStartup) { if (PauseAtStartup) {
os::pause(); os::pause();
} }
......
/*
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test TestUseCompressedOopsErgo
* @key gc
* @bug 8010722
* @summary Tests ergonomics for UseCompressedOops.
* @library /testlibrary /testlibrary/whitebox
* @build TestUseCompressedOopsErgo TestUseCompressedOopsErgoTools
* @run main ClassFileInstaller sun.hotspot.WhiteBox
* @run main/othervm TestUseCompressedOopsErgo -XX:+UseG1GC
* @run main/othervm TestUseCompressedOopsErgo -XX:+UseParallelGC
* @run main/othervm TestUseCompressedOopsErgo -XX:+UseParallelGC -XX:-UseParallelOldGC
* @run main/othervm TestUseCompressedOopsErgo -XX:+UseConcMarkSweepGC
* @run main/othervm TestUseCompressedOopsErgo -XX:+UseSerialGC
*/
public class TestUseCompressedOopsErgo {
public static void main(String args[]) throws Exception {
if (!TestUseCompressedOopsErgoTools.is64bitVM()) {
// this test is relevant for 64 bit VMs only
return;
}
final String[] gcFlags = args;
TestUseCompressedOopsErgoTools.checkCompressedOopsErgo(gcFlags);
}
}
/*
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import sun.management.ManagementFactoryHelper;
import com.sun.management.HotSpotDiagnosticMXBean;
import com.sun.management.VMOption;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.ArrayList;
import java.util.Arrays;
import com.oracle.java.testlibrary.*;
import sun.hotspot.WhiteBox;
class DetermineMaxHeapForCompressedOops {
public static void main(String[] args) throws Exception {
WhiteBox wb = WhiteBox.getWhiteBox();
System.out.print(wb.getCompressedOopsMaxHeapSize());
}
}
class TestUseCompressedOopsErgoTools {
private static long getClassMetaspaceSize() {
HotSpotDiagnosticMXBean diagnostic = ManagementFactoryHelper.getDiagnosticMXBean();
VMOption option = diagnostic.getVMOption("ClassMetaspaceSize");
return Long.parseLong(option.getValue());
}
public static long getMaxHeapForCompressedOops(String[] vmargs) throws Exception {
OutputAnalyzer output = runWhiteBoxTest(vmargs, DetermineMaxHeapForCompressedOops.class.getName(), new String[] {}, false);
return Long.parseLong(output.getStdout());
}
public static boolean is64bitVM() {
String val = System.getProperty("sun.arch.data.model");
if (val == null) {
throw new RuntimeException("Could not read sun.arch.data.model");
}
if (val.equals("64")) {
return true;
} else if (val.equals("32")) {
return false;
}
throw new RuntimeException("Unexpected value " + val + " of sun.arch.data.model");
}
/**
* Executes a new VM process with the given class and parameters.
* @param vmargs Arguments to the VM to run
* @param classname Name of the class to run
* @param arguments Arguments to the class
* @param useTestDotJavaDotOpts Use test.java.opts as part of the VM argument string
* @return The OutputAnalyzer with the results for the invocation.
*/
public static OutputAnalyzer runWhiteBoxTest(String[] vmargs, String classname, String[] arguments, boolean useTestDotJavaDotOpts) throws Exception {
ArrayList<String> finalargs = new ArrayList<String>();
String[] whiteboxOpts = new String[] {
"-Xbootclasspath/a:.",
"-XX:+UnlockDiagnosticVMOptions", "-XX:+WhiteBoxAPI",
"-cp", System.getProperty("java.class.path"),
};
if (useTestDotJavaDotOpts) {
// System.getProperty("test.java.opts") is '' if no options is set,
// we need to skip such a result
String[] externalVMOpts = new String[0];
if (System.getProperty("test.java.opts") != null && System.getProperty("test.java.opts").length() != 0) {
externalVMOpts = System.getProperty("test.java.opts").split(" ");
}
finalargs.addAll(Arrays.asList(externalVMOpts));
}
finalargs.addAll(Arrays.asList(vmargs));
finalargs.addAll(Arrays.asList(whiteboxOpts));
finalargs.add(classname);
finalargs.addAll(Arrays.asList(arguments));
ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(finalargs.toArray(new String[0]));
OutputAnalyzer output = new OutputAnalyzer(pb.start());
output.shouldHaveExitValue(0);
return output;
}
private static String[] join(String[] part1, String part2) {
ArrayList<String> result = new ArrayList<String>();
result.addAll(Arrays.asList(part1));
result.add(part2);
return result.toArray(new String[0]);
}
public static void checkCompressedOopsErgo(String[] gcflags) throws Exception {
long maxHeapForCompressedOops = getMaxHeapForCompressedOops(gcflags);
checkUseCompressedOops(gcflags, maxHeapForCompressedOops, true);
checkUseCompressedOops(gcflags, maxHeapForCompressedOops - 1, true);
checkUseCompressedOops(gcflags, maxHeapForCompressedOops + 1, false);
// the use of HeapBaseMinAddress should not change the outcome
checkUseCompressedOops(join(gcflags, "-XX:HeapBaseMinAddress=32G"), maxHeapForCompressedOops, true);
checkUseCompressedOops(join(gcflags, "-XX:HeapBaseMinAddress=32G"), maxHeapForCompressedOops - 1, true);
checkUseCompressedOops(join(gcflags, "-XX:HeapBaseMinAddress=32G"), maxHeapForCompressedOops + 1, false);
// use a different object alignment
maxHeapForCompressedOops = getMaxHeapForCompressedOops(join(gcflags, "-XX:ObjectAlignmentInBytes=16"));
checkUseCompressedOops(join(gcflags, "-XX:ObjectAlignmentInBytes=16"), maxHeapForCompressedOops, true);
checkUseCompressedOops(join(gcflags, "-XX:ObjectAlignmentInBytes=16"), maxHeapForCompressedOops - 1, true);
checkUseCompressedOops(join(gcflags, "-XX:ObjectAlignmentInBytes=16"), maxHeapForCompressedOops + 1, false);
// use a different ClassMetaspaceSize
String classMetaspaceSizeArg = "-XX:ClassMetaspaceSize=" + 2 * getClassMetaspaceSize();
maxHeapForCompressedOops = getMaxHeapForCompressedOops(join(gcflags, classMetaspaceSizeArg));
checkUseCompressedOops(join(gcflags, classMetaspaceSizeArg), maxHeapForCompressedOops, true);
checkUseCompressedOops(join(gcflags, classMetaspaceSizeArg), maxHeapForCompressedOops - 1, true);
checkUseCompressedOops(join(gcflags, classMetaspaceSizeArg), maxHeapForCompressedOops + 1, false);
}
private static void checkUseCompressedOops(String[] args, long heapsize, boolean expectUseCompressedOops) throws Exception {
ArrayList<String> finalargs = new ArrayList<String>();
finalargs.addAll(Arrays.asList(args));
finalargs.add("-Xmx" + heapsize);
finalargs.add("-XX:+PrintFlagsFinal");
finalargs.add("-version");
String output = expectValid(finalargs.toArray(new String[0]));
boolean actualUseCompressedOops = getFlagBoolValue(" UseCompressedOops", output);
if (expectUseCompressedOops != actualUseCompressedOops) {
throw new RuntimeException("Expected use of compressed oops: " + expectUseCompressedOops + " but was: " + actualUseCompressedOops);
}
}
private static boolean getFlagBoolValue(String flag, String where) {
Matcher m = Pattern.compile(flag + "\\s+:?= (true|false)").matcher(where);
if (!m.find()) {
throw new RuntimeException("Could not find value for flag " + flag + " in output string");
}
String match = m.group(1).equals("true");
}
private static String expect(String[] flags, boolean hasWarning, boolean hasError, int errorcode) throws Exception {
ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(flags);
OutputAnalyzer output = new OutputAnalyzer(pb.start());
output.shouldHaveExitValue(errorcode);
return output.getStdout();
}
private static String expectValid(String[] flags) throws Exception {
return expect(flags, false, false, 0);
}
}
...@@ -61,6 +61,8 @@ public class WhiteBox { ...@@ -61,6 +61,8 @@ public class WhiteBox {
registerNatives(); registerNatives();
} }
// Get the maximum heap size supporting COOPs
public native long getCompressedOopsMaxHeapSize();
// Arguments // Arguments
public native void printHeapSizes(); public native void printHeapSizes();
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册