mirror of
https://github.com/openjdk/jdk.git
synced 2026-07-20 07:58:55 +00:00
Merge
This commit is contained in:
commit
2317db6d5a
@ -3589,8 +3589,6 @@ jint os::init_2(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
os::large_page_init();
|
||||
|
||||
// initialize suspend/resume support - must do this before signal_sets_init()
|
||||
if (SR_initialize() != 0) {
|
||||
perror("SR_initialize failed");
|
||||
|
||||
@ -4755,8 +4755,6 @@ jint os::init_2(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
os::large_page_init();
|
||||
|
||||
// initialize suspend/resume support - must do this before signal_sets_init()
|
||||
if (SR_initialize() != 0) {
|
||||
perror("SR_initialize failed");
|
||||
|
||||
@ -5178,9 +5178,7 @@ jint os::init_2(void) {
|
||||
if(Verbose && PrintMiscellaneous)
|
||||
tty->print("[Memory Serialize Page address: " INTPTR_FORMAT "]\n", (intptr_t)mem_serialize_page);
|
||||
#endif
|
||||
}
|
||||
|
||||
os::large_page_init();
|
||||
}
|
||||
|
||||
// Check minimum allowable stack size for thread creation and to initialize
|
||||
// the java system classes, including StackOverflowError - depends on page
|
||||
|
||||
@ -3920,8 +3920,6 @@ jint os::init_2(void) {
|
||||
#endif
|
||||
}
|
||||
|
||||
os::large_page_init();
|
||||
|
||||
// Setup Windows Exceptions
|
||||
|
||||
// for debugging float code generation bugs
|
||||
|
||||
@ -2191,6 +2191,10 @@ jint G1CollectedHeap::initialize() {
|
||||
return JNI_OK;
|
||||
}
|
||||
|
||||
size_t G1CollectedHeap::conservative_max_heap_alignment() {
|
||||
return HeapRegion::max_region_size();
|
||||
}
|
||||
|
||||
void G1CollectedHeap::ref_processing_init() {
|
||||
// Reference processing in G1 currently works as follows:
|
||||
//
|
||||
|
||||
@ -1092,6 +1092,9 @@ public:
|
||||
// specified by the policy object.
|
||||
jint initialize();
|
||||
|
||||
// Return the (conservative) maximum heap alignment for any G1 heap
|
||||
static size_t conservative_max_heap_alignment();
|
||||
|
||||
// Initialize weak reference processing.
|
||||
virtual void ref_processing_init();
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* 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,
|
||||
// many regions in the heap (based on the min heap size).
|
||||
#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) {
|
||||
uintx region_size = G1HeapRegionSize;
|
||||
if (FLAG_IS_DEFAULT(G1HeapRegionSize)) {
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -355,6 +355,8 @@ class HeapRegion: public G1OffsetTableContigSpace {
|
||||
~((1 << (size_t) LogOfHRGrainBytes) - 1);
|
||||
}
|
||||
|
||||
static size_t max_region_size();
|
||||
|
||||
// It sets up the heap region size (GrainBytes / GrainWords), as
|
||||
// well as other related fields that are based on the heap region
|
||||
// size (LogOfHRGrainBytes / LogOfHRGrainWords /
|
||||
|
||||
@ -86,6 +86,11 @@ class ParallelScavengeHeap : public CollectedHeap {
|
||||
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
|
||||
enum CollectionType {
|
||||
Scavenge,
|
||||
@ -122,7 +127,7 @@ class ParallelScavengeHeap : public CollectedHeap {
|
||||
|
||||
// The alignment used for eden and survivors within the young 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 used() const;
|
||||
|
||||
@ -145,6 +145,30 @@ void CollectorPolicy::cleared_all_soft_refs() {
|
||||
_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.
|
||||
|
||||
@ -175,29 +199,6 @@ void GenCollectorPolicy::initialize_size_policy(size_t init_eden_size,
|
||||
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() {
|
||||
// All sizes must be multiples of the generation granularity.
|
||||
set_min_alignment((uintx) Generation::GenGrain);
|
||||
|
||||
@ -98,6 +98,9 @@ class CollectorPolicy : public CHeapObj<mtGC> {
|
||||
{}
|
||||
|
||||
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; }
|
||||
size_t min_alignment() { return _min_alignment; }
|
||||
void set_max_alignment(size_t align) { _max_alignment = align; }
|
||||
@ -234,9 +237,6 @@ class GenCollectorPolicy : public CollectorPolicy {
|
||||
// Try to allocate space by expanding the heap.
|
||||
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
|
||||
// result = base_size / (NewRatio + 1)
|
||||
// and align by min_alignment()
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -148,6 +148,11 @@ public:
|
||||
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 used() const;
|
||||
|
||||
|
||||
@ -872,6 +872,9 @@ jint Universe::initialize_heap() {
|
||||
|
||||
// Reserve the Java heap, which is now the same for all GCs.
|
||||
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);
|
||||
assert(!UseCompressedOops || (total_reserved <= (OopEncodingHeapMax - os::vm_page_size())),
|
||||
"heap size is too big for compressed oops");
|
||||
|
||||
@ -33,6 +33,7 @@
|
||||
#include "prims/whitebox.hpp"
|
||||
#include "prims/wbtestmethods/parserTests.hpp"
|
||||
|
||||
#include "runtime/arguments.hpp"
|
||||
#include "runtime/interfaceSupport.hpp"
|
||||
#include "runtime/os.hpp"
|
||||
#include "utilities/debug.hpp"
|
||||
@ -94,6 +95,11 @@ WB_ENTRY(jboolean, WB_IsClassAlive(JNIEnv* env, jobject target, jstring name))
|
||||
return closure.found();
|
||||
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)) {
|
||||
CollectorPolicy * p = Universe::heap()->collector_policy();
|
||||
gclog_or_tty->print_cr("Minimum heap "SIZE_FORMAT" Initial heap "
|
||||
@ -436,6 +442,8 @@ static JNINativeMethod methods[] = {
|
||||
CC"(Ljava/lang/String;[Lsun/hotspot/parser/DiagnosticCommand;)[Ljava/lang/Object;",
|
||||
(void*) &WB_ParseCommandLine
|
||||
},
|
||||
{CC"getCompressedOopsMaxHeapSize", CC"()J",
|
||||
(void*)&WB_GetCompressedOopsMaxHeapSize},
|
||||
{CC"printHeapSizes", CC"()V", (void*)&WB_PrintHeapSizes },
|
||||
#if INCLUDE_ALL_GCS
|
||||
{CC"g1InConcurrentMark", CC"()Z", (void*)&WB_G1InConcurrentMark},
|
||||
|
||||
@ -28,6 +28,7 @@
|
||||
#include "compiler/compilerOracle.hpp"
|
||||
#include "memory/allocation.inline.hpp"
|
||||
#include "memory/cardTableRS.hpp"
|
||||
#include "memory/genCollectedHeap.hpp"
|
||||
#include "memory/referenceProcessor.hpp"
|
||||
#include "memory/universe.inline.hpp"
|
||||
#include "oops/oop.inline.hpp"
|
||||
@ -54,6 +55,8 @@
|
||||
#endif
|
||||
#if INCLUDE_ALL_GCS
|
||||
#include "gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp"
|
||||
#include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
|
||||
#include "gc_implementation/parallelScavenge/parallelScavengeHeap.hpp"
|
||||
#endif // INCLUDE_ALL_GCS
|
||||
|
||||
// Note: This is a special bug reporting site for the JVM
|
||||
@ -90,6 +93,7 @@ char* Arguments::_java_command = NULL;
|
||||
SystemProperty* Arguments::_system_properties = NULL;
|
||||
const char* Arguments::_gc_log_filename = NULL;
|
||||
bool Arguments::_has_profile = false;
|
||||
size_t Arguments::_conservative_max_heap_alignment = 0;
|
||||
uintx Arguments::_min_heap_size = 0;
|
||||
Arguments::Mode Arguments::_mode = _mixed;
|
||||
bool Arguments::_java_compiler = false;
|
||||
@ -1391,10 +1395,17 @@ bool verify_object_alignment() {
|
||||
return true;
|
||||
}
|
||||
|
||||
inline uintx max_heap_for_compressed_oops() {
|
||||
uintx Arguments::max_heap_for_compressed_oops() {
|
||||
// Avoid sign flip.
|
||||
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);
|
||||
}
|
||||
|
||||
@ -1475,6 +1486,23 @@ void Arguments::set_use_compressed_klass_ptrs() {
|
||||
#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() {
|
||||
|
||||
if (os::is_server_class_machine()) {
|
||||
@ -1503,6 +1531,8 @@ void Arguments::set_ergonomics_flags() {
|
||||
}
|
||||
}
|
||||
|
||||
set_conservative_max_heap_alignment();
|
||||
|
||||
#ifndef ZERO
|
||||
#ifdef _LP64
|
||||
set_use_compressed_oops();
|
||||
@ -3506,6 +3536,11 @@ jint Arguments::parse(const JavaVMInitArgs* args) {
|
||||
no_shared_spaces();
|
||||
#endif // INCLUDE_CDS
|
||||
|
||||
return JNI_OK;
|
||||
}
|
||||
|
||||
jint Arguments::apply_ergo() {
|
||||
|
||||
// Set flags based on ergonomics.
|
||||
set_ergonomics_flags();
|
||||
|
||||
|
||||
@ -280,6 +280,9 @@ class Arguments : AllStatic {
|
||||
// Option flags
|
||||
static bool _has_profile;
|
||||
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;
|
||||
|
||||
// -Xrun arguments
|
||||
@ -327,6 +330,7 @@ class Arguments : AllStatic {
|
||||
// Garbage-First (UseG1GC)
|
||||
static void set_g1_gc_flags();
|
||||
// GC ergonomics
|
||||
static void set_conservative_max_heap_alignment();
|
||||
static void set_use_compressed_oops();
|
||||
static void set_use_compressed_klass_ptrs();
|
||||
static void set_ergonomics_flags();
|
||||
@ -430,8 +434,10 @@ class Arguments : AllStatic {
|
||||
static char* SharedArchivePath;
|
||||
|
||||
public:
|
||||
// Parses the arguments
|
||||
// Parses the arguments, first phase
|
||||
static jint parse(const JavaVMInitArgs* args);
|
||||
// Apply ergonomics
|
||||
static jint apply_ergo();
|
||||
// Adjusts the arguments after the OS have adjusted the arguments
|
||||
static jint adjust_after_os();
|
||||
// Check for consistency in the selection of the garbage collector.
|
||||
@ -445,6 +451,10 @@ class Arguments : AllStatic {
|
||||
// Used by os_solaris
|
||||
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
|
||||
static char** jvm_flags_array() { return _jvm_flags_array; }
|
||||
static char** jvm_args_array() { return _jvm_args_array; }
|
||||
|
||||
@ -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() {
|
||||
if (!ReduceSignalUsage) {
|
||||
|
||||
@ -139,7 +139,10 @@ class os: AllStatic {
|
||||
|
||||
public:
|
||||
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
|
||||
// and VM ergonomics processing
|
||||
static void init_globals(void) { // Called from init_globals() in init.cpp
|
||||
init_globals_ext();
|
||||
}
|
||||
@ -254,6 +257,11 @@ class os: AllStatic {
|
||||
static size_t page_size_for_region(size_t region_min_size,
|
||||
size_t region_max_size,
|
||||
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
|
||||
// TracePageSizes. The region_{min,max}_size parameters should be the values
|
||||
|
||||
@ -3329,6 +3329,11 @@ jint Threads::create_vm(JavaVMInitArgs* args, bool* canTryAgain) {
|
||||
jint parse_result = Arguments::parse(args);
|
||||
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) {
|
||||
os::pause();
|
||||
}
|
||||
|
||||
50
hotspot/test/gc/arguments/TestUseCompressedOopsErgo.java
Normal file
50
hotspot/test/gc/arguments/TestUseCompressedOopsErgo.java
Normal file
@ -0,0 +1,50 @@
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
}
|
||||
|
||||
179
hotspot/test/gc/arguments/TestUseCompressedOopsErgoTools.java
Normal file
179
hotspot/test/gc/arguments/TestUseCompressedOopsErgoTools.java
Normal file
@ -0,0 +1,179 @@
|
||||
/*
|
||||
* 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 {
|
||||
registerNatives();
|
||||
}
|
||||
|
||||
// Get the maximum heap size supporting COOPs
|
||||
public native long getCompressedOopsMaxHeapSize();
|
||||
// Arguments
|
||||
public native void printHeapSizes();
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user