Wed, 11 Sep 2013 16:25:02 +0200
8010722: assert: failed: heap size is too big for compressed oops
Summary: Use conservative assumptions of required alignment for the various garbage collector components into account when determining the maximum heap size that supports compressed oops. Using this conservative value avoids several circular dependencies in the calculation.
Reviewed-by: stefank, dholmes
1.1 --- a/src/os/bsd/vm/os_bsd.cpp Wed Sep 11 12:03:41 2013 +0200 1.2 +++ b/src/os/bsd/vm/os_bsd.cpp Wed Sep 11 16:25:02 2013 +0200 1.3 @@ -3589,8 +3589,6 @@ 1.4 #endif 1.5 } 1.6 1.7 - os::large_page_init(); 1.8 - 1.9 // initialize suspend/resume support - must do this before signal_sets_init() 1.10 if (SR_initialize() != 0) { 1.11 perror("SR_initialize failed");
2.1 --- a/src/os/linux/vm/os_linux.cpp Wed Sep 11 12:03:41 2013 +0200 2.2 +++ b/src/os/linux/vm/os_linux.cpp Wed Sep 11 16:25:02 2013 +0200 2.3 @@ -4755,8 +4755,6 @@ 2.4 #endif 2.5 } 2.6 2.7 - os::large_page_init(); 2.8 - 2.9 // initialize suspend/resume support - must do this before signal_sets_init() 2.10 if (SR_initialize() != 0) { 2.11 perror("SR_initialize failed");
3.1 --- a/src/os/solaris/vm/os_solaris.cpp Wed Sep 11 12:03:41 2013 +0200 3.2 +++ b/src/os/solaris/vm/os_solaris.cpp Wed Sep 11 16:25:02 2013 +0200 3.3 @@ -5178,9 +5178,7 @@ 3.4 if(Verbose && PrintMiscellaneous) 3.5 tty->print("[Memory Serialize Page address: " INTPTR_FORMAT "]\n", (intptr_t)mem_serialize_page); 3.6 #endif 3.7 -} 3.8 - 3.9 - os::large_page_init(); 3.10 + } 3.11 3.12 // Check minimum allowable stack size for thread creation and to initialize 3.13 // the java system classes, including StackOverflowError - depends on page
4.1 --- a/src/os/windows/vm/os_windows.cpp Wed Sep 11 12:03:41 2013 +0200 4.2 +++ b/src/os/windows/vm/os_windows.cpp Wed Sep 11 16:25:02 2013 +0200 4.3 @@ -3920,8 +3920,6 @@ 4.4 #endif 4.5 } 4.6 4.7 - os::large_page_init(); 4.8 - 4.9 // Setup Windows Exceptions 4.10 4.11 // for debugging float code generation bugs
5.1 --- a/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Wed Sep 11 12:03:41 2013 +0200 5.2 +++ b/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Wed Sep 11 16:25:02 2013 +0200 5.3 @@ -2191,6 +2191,10 @@ 5.4 return JNI_OK; 5.5 } 5.6 5.7 +size_t G1CollectedHeap::conservative_max_heap_alignment() { 5.8 + return HeapRegion::max_region_size(); 5.9 +} 5.10 + 5.11 void G1CollectedHeap::ref_processing_init() { 5.12 // Reference processing in G1 currently works as follows: 5.13 //
6.1 --- a/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp Wed Sep 11 12:03:41 2013 +0200 6.2 +++ b/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp Wed Sep 11 16:25:02 2013 +0200 6.3 @@ -1092,6 +1092,9 @@ 6.4 // specified by the policy object. 6.5 jint initialize(); 6.6 6.7 + // Return the (conservative) maximum heap alignment for any G1 heap 6.8 + static size_t conservative_max_heap_alignment(); 6.9 + 6.10 // Initialize weak reference processing. 6.11 virtual void ref_processing_init(); 6.12
7.1 --- a/src/share/vm/gc_implementation/g1/heapRegion.cpp Wed Sep 11 12:03:41 2013 +0200 7.2 +++ b/src/share/vm/gc_implementation/g1/heapRegion.cpp Wed Sep 11 16:25:02 2013 +0200 7.3 @@ -1,5 +1,5 @@ 7.4 /* 7.5 - * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved. 7.6 + * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. 7.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 7.8 * 7.9 * This code is free software; you can redistribute it and/or modify it 7.10 @@ -149,6 +149,10 @@ 7.11 // many regions in the heap (based on the min heap size). 7.12 #define TARGET_REGION_NUMBER 2048 7.13 7.14 +size_t HeapRegion::max_region_size() { 7.15 + return (size_t)MAX_REGION_SIZE; 7.16 +} 7.17 + 7.18 void HeapRegion::setup_heap_region_size(size_t initial_heap_size, size_t max_heap_size) { 7.19 uintx region_size = G1HeapRegionSize; 7.20 if (FLAG_IS_DEFAULT(G1HeapRegionSize)) {
8.1 --- a/src/share/vm/gc_implementation/g1/heapRegion.hpp Wed Sep 11 12:03:41 2013 +0200 8.2 +++ b/src/share/vm/gc_implementation/g1/heapRegion.hpp Wed Sep 11 16:25:02 2013 +0200 8.3 @@ -1,5 +1,5 @@ 8.4 /* 8.5 - * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved. 8.6 + * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. 8.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 8.8 * 8.9 * This code is free software; you can redistribute it and/or modify it 8.10 @@ -355,6 +355,8 @@ 8.11 ~((1 << (size_t) LogOfHRGrainBytes) - 1); 8.12 } 8.13 8.14 + static size_t max_region_size(); 8.15 + 8.16 // It sets up the heap region size (GrainBytes / GrainWords), as 8.17 // well as other related fields that are based on the heap region 8.18 // size (LogOfHRGrainBytes / LogOfHRGrainWords /
9.1 --- a/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.hpp Wed Sep 11 12:03:41 2013 +0200 9.2 +++ b/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.hpp Wed Sep 11 16:25:02 2013 +0200 9.3 @@ -86,6 +86,11 @@ 9.4 set_alignment(_old_gen_alignment, intra_heap_alignment()); 9.5 } 9.6 9.7 + // Return the (conservative) maximum heap alignment 9.8 + static size_t conservative_max_heap_alignment() { 9.9 + return intra_heap_alignment(); 9.10 + } 9.11 + 9.12 // For use by VM operations 9.13 enum CollectionType { 9.14 Scavenge, 9.15 @@ -122,7 +127,7 @@ 9.16 9.17 // The alignment used for eden and survivors within the young gen 9.18 // and for boundary between young gen and old gen. 9.19 - size_t intra_heap_alignment() const { return 64 * K * HeapWordSize; } 9.20 + static size_t intra_heap_alignment() { return 64 * K * HeapWordSize; } 9.21 9.22 size_t capacity() const; 9.23 size_t used() const;
10.1 --- a/src/share/vm/memory/collectorPolicy.cpp Wed Sep 11 12:03:41 2013 +0200 10.2 +++ b/src/share/vm/memory/collectorPolicy.cpp Wed Sep 11 16:25:02 2013 +0200 10.3 @@ -145,6 +145,30 @@ 10.4 _all_soft_refs_clear = true; 10.5 } 10.6 10.7 +size_t CollectorPolicy::compute_max_alignment() { 10.8 + // The card marking array and the offset arrays for old generations are 10.9 + // committed in os pages as well. Make sure they are entirely full (to 10.10 + // avoid partial page problems), e.g. if 512 bytes heap corresponds to 1 10.11 + // byte entry and the os page size is 4096, the maximum heap size should 10.12 + // be 512*4096 = 2MB aligned. 10.13 + 10.14 + // There is only the GenRemSet in Hotspot and only the GenRemSet::CardTable 10.15 + // is supported. 10.16 + // Requirements of any new remembered set implementations must be added here. 10.17 + size_t alignment = GenRemSet::max_alignment_constraint(GenRemSet::CardTable); 10.18 + 10.19 + // Parallel GC does its own alignment of the generations to avoid requiring a 10.20 + // large page (256M on some platforms) for the permanent generation. The 10.21 + // other collectors should also be updated to do their own alignment and then 10.22 + // this use of lcm() should be removed. 10.23 + if (UseLargePages && !UseParallelGC) { 10.24 + // in presence of large pages we have to make sure that our 10.25 + // alignment is large page aware 10.26 + alignment = lcm(os::large_page_size(), alignment); 10.27 + } 10.28 + 10.29 + return alignment; 10.30 +} 10.31 10.32 // GenCollectorPolicy methods. 10.33 10.34 @@ -175,29 +199,6 @@ 10.35 GCTimeRatio); 10.36 } 10.37 10.38 -size_t GenCollectorPolicy::compute_max_alignment() { 10.39 - // The card marking array and the offset arrays for old generations are 10.40 - // committed in os pages as well. Make sure they are entirely full (to 10.41 - // avoid partial page problems), e.g. if 512 bytes heap corresponds to 1 10.42 - // byte entry and the os page size is 4096, the maximum heap size should 10.43 - // be 512*4096 = 2MB aligned. 10.44 - size_t alignment = GenRemSet::max_alignment_constraint(rem_set_name()); 10.45 - 10.46 - // Parallel GC does its own alignment of the generations to avoid requiring a 10.47 - // large page (256M on some platforms) for the permanent generation. The 10.48 - // other collectors should also be updated to do their own alignment and then 10.49 - // this use of lcm() should be removed. 10.50 - if (UseLargePages && !UseParallelGC) { 10.51 - // in presence of large pages we have to make sure that our 10.52 - // alignment is large page aware 10.53 - alignment = lcm(os::large_page_size(), alignment); 10.54 - } 10.55 - 10.56 - assert(alignment >= min_alignment(), "Must be"); 10.57 - 10.58 - return alignment; 10.59 -} 10.60 - 10.61 void GenCollectorPolicy::initialize_flags() { 10.62 // All sizes must be multiples of the generation granularity. 10.63 set_min_alignment((uintx) Generation::GenGrain);
11.1 --- a/src/share/vm/memory/collectorPolicy.hpp Wed Sep 11 12:03:41 2013 +0200 11.2 +++ b/src/share/vm/memory/collectorPolicy.hpp Wed Sep 11 16:25:02 2013 +0200 11.3 @@ -98,6 +98,9 @@ 11.4 {} 11.5 11.6 public: 11.7 + // Return maximum heap alignment that may be imposed by the policy 11.8 + static size_t compute_max_alignment(); 11.9 + 11.10 void set_min_alignment(size_t align) { _min_alignment = align; } 11.11 size_t min_alignment() { return _min_alignment; } 11.12 void set_max_alignment(size_t align) { _max_alignment = align; } 11.13 @@ -234,9 +237,6 @@ 11.14 // Try to allocate space by expanding the heap. 11.15 virtual HeapWord* expand_heap_and_allocate(size_t size, bool is_tlab); 11.16 11.17 - // compute max heap alignment 11.18 - size_t compute_max_alignment(); 11.19 - 11.20 // Scale the base_size by NewRation according to 11.21 // result = base_size / (NewRatio + 1) 11.22 // and align by min_alignment()
12.1 --- a/src/share/vm/memory/genCollectedHeap.hpp Wed Sep 11 12:03:41 2013 +0200 12.2 +++ b/src/share/vm/memory/genCollectedHeap.hpp Wed Sep 11 16:25:02 2013 +0200 12.3 @@ -1,5 +1,5 @@ 12.4 /* 12.5 - * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved. 12.6 + * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. 12.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 12.8 * 12.9 * This code is free software; you can redistribute it and/or modify it 12.10 @@ -148,6 +148,11 @@ 12.11 return gen_policy()->size_policy(); 12.12 } 12.13 12.14 + // Return the (conservative) maximum heap alignment 12.15 + static size_t conservative_max_heap_alignment() { 12.16 + return Generation::GenGrain; 12.17 + } 12.18 + 12.19 size_t capacity() const; 12.20 size_t used() const; 12.21
13.1 --- a/src/share/vm/memory/universe.cpp Wed Sep 11 12:03:41 2013 +0200 13.2 +++ b/src/share/vm/memory/universe.cpp Wed Sep 11 16:25:02 2013 +0200 13.3 @@ -872,6 +872,9 @@ 13.4 13.5 // Reserve the Java heap, which is now the same for all GCs. 13.6 ReservedSpace Universe::reserve_heap(size_t heap_size, size_t alignment) { 13.7 + assert(alignment <= Arguments::conservative_max_heap_alignment(), 13.8 + err_msg("actual alignment "SIZE_FORMAT" must be within maximum heap alignment "SIZE_FORMAT, 13.9 + alignment, Arguments::conservative_max_heap_alignment())); 13.10 size_t total_reserved = align_size_up(heap_size, alignment); 13.11 assert(!UseCompressedOops || (total_reserved <= (OopEncodingHeapMax - os::vm_page_size())), 13.12 "heap size is too big for compressed oops");
14.1 --- a/src/share/vm/prims/whitebox.cpp Wed Sep 11 12:03:41 2013 +0200 14.2 +++ b/src/share/vm/prims/whitebox.cpp Wed Sep 11 16:25:02 2013 +0200 14.3 @@ -33,6 +33,7 @@ 14.4 #include "prims/whitebox.hpp" 14.5 #include "prims/wbtestmethods/parserTests.hpp" 14.6 14.7 +#include "runtime/arguments.hpp" 14.8 #include "runtime/interfaceSupport.hpp" 14.9 #include "runtime/os.hpp" 14.10 #include "utilities/debug.hpp" 14.11 @@ -94,6 +95,11 @@ 14.12 return closure.found(); 14.13 WB_END 14.14 14.15 +WB_ENTRY(jlong, WB_GetCompressedOopsMaxHeapSize(JNIEnv* env, jobject o)) { 14.16 + return (jlong)Arguments::max_heap_for_compressed_oops(); 14.17 +} 14.18 +WB_END 14.19 + 14.20 WB_ENTRY(void, WB_PrintHeapSizes(JNIEnv* env, jobject o)) { 14.21 CollectorPolicy * p = Universe::heap()->collector_policy(); 14.22 gclog_or_tty->print_cr("Minimum heap "SIZE_FORMAT" Initial heap " 14.23 @@ -436,6 +442,8 @@ 14.24 CC"(Ljava/lang/String;[Lsun/hotspot/parser/DiagnosticCommand;)[Ljava/lang/Object;", 14.25 (void*) &WB_ParseCommandLine 14.26 }, 14.27 + {CC"getCompressedOopsMaxHeapSize", CC"()J", 14.28 + (void*)&WB_GetCompressedOopsMaxHeapSize}, 14.29 {CC"printHeapSizes", CC"()V", (void*)&WB_PrintHeapSizes }, 14.30 #if INCLUDE_ALL_GCS 14.31 {CC"g1InConcurrentMark", CC"()Z", (void*)&WB_G1InConcurrentMark},
15.1 --- a/src/share/vm/runtime/arguments.cpp Wed Sep 11 12:03:41 2013 +0200 15.2 +++ b/src/share/vm/runtime/arguments.cpp Wed Sep 11 16:25:02 2013 +0200 15.3 @@ -28,6 +28,7 @@ 15.4 #include "compiler/compilerOracle.hpp" 15.5 #include "memory/allocation.inline.hpp" 15.6 #include "memory/cardTableRS.hpp" 15.7 +#include "memory/genCollectedHeap.hpp" 15.8 #include "memory/referenceProcessor.hpp" 15.9 #include "memory/universe.inline.hpp" 15.10 #include "oops/oop.inline.hpp" 15.11 @@ -54,6 +55,8 @@ 15.12 #endif 15.13 #if INCLUDE_ALL_GCS 15.14 #include "gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp" 15.15 +#include "gc_implementation/g1/g1CollectedHeap.inline.hpp" 15.16 +#include "gc_implementation/parallelScavenge/parallelScavengeHeap.hpp" 15.17 #endif // INCLUDE_ALL_GCS 15.18 15.19 // Note: This is a special bug reporting site for the JVM 15.20 @@ -90,6 +93,7 @@ 15.21 SystemProperty* Arguments::_system_properties = NULL; 15.22 const char* Arguments::_gc_log_filename = NULL; 15.23 bool Arguments::_has_profile = false; 15.24 +size_t Arguments::_conservative_max_heap_alignment = 0; 15.25 uintx Arguments::_min_heap_size = 0; 15.26 Arguments::Mode Arguments::_mode = _mixed; 15.27 bool Arguments::_java_compiler = false; 15.28 @@ -1391,10 +1395,17 @@ 15.29 return true; 15.30 } 15.31 15.32 -inline uintx max_heap_for_compressed_oops() { 15.33 +uintx Arguments::max_heap_for_compressed_oops() { 15.34 // Avoid sign flip. 15.35 assert(OopEncodingHeapMax > (uint64_t)os::vm_page_size(), "Unusual page size"); 15.36 - LP64_ONLY(return OopEncodingHeapMax - os::vm_page_size()); 15.37 + // We need to fit both the NULL page and the heap into the memory budget, while 15.38 + // keeping alignment constraints of the heap. To guarantee the latter, as the 15.39 + // NULL page is located before the heap, we pad the NULL page to the conservative 15.40 + // maximum alignment that the GC may ever impose upon the heap. 15.41 + size_t displacement_due_to_null_page = align_size_up_(os::vm_page_size(), 15.42 + Arguments::conservative_max_heap_alignment()); 15.43 + 15.44 + LP64_ONLY(return OopEncodingHeapMax - displacement_due_to_null_page); 15.45 NOT_LP64(ShouldNotReachHere(); return 0); 15.46 } 15.47 15.48 @@ -1475,6 +1486,23 @@ 15.49 #endif // !ZERO 15.50 } 15.51 15.52 +void Arguments::set_conservative_max_heap_alignment() { 15.53 + // The conservative maximum required alignment for the heap is the maximum of 15.54 + // the alignments imposed by several sources: any requirements from the heap 15.55 + // itself, the collector policy and the maximum page size we may run the VM 15.56 + // with. 15.57 + size_t heap_alignment = GenCollectedHeap::conservative_max_heap_alignment(); 15.58 +#if INCLUDE_ALL_GCS 15.59 + if (UseParallelGC) { 15.60 + heap_alignment = ParallelScavengeHeap::conservative_max_heap_alignment(); 15.61 + } else if (UseG1GC) { 15.62 + heap_alignment = G1CollectedHeap::conservative_max_heap_alignment(); 15.63 + } 15.64 +#endif // INCLUDE_ALL_GCS 15.65 + _conservative_max_heap_alignment = MAX3(heap_alignment, os::max_page_size(), 15.66 + CollectorPolicy::compute_max_alignment()); 15.67 +} 15.68 + 15.69 void Arguments::set_ergonomics_flags() { 15.70 15.71 if (os::is_server_class_machine()) { 15.72 @@ -1503,6 +1531,8 @@ 15.73 } 15.74 } 15.75 15.76 + set_conservative_max_heap_alignment(); 15.77 + 15.78 #ifndef ZERO 15.79 #ifdef _LP64 15.80 set_use_compressed_oops(); 15.81 @@ -3506,6 +3536,11 @@ 15.82 no_shared_spaces(); 15.83 #endif // INCLUDE_CDS 15.84 15.85 + return JNI_OK; 15.86 +} 15.87 + 15.88 +jint Arguments::apply_ergo() { 15.89 + 15.90 // Set flags based on ergonomics. 15.91 set_ergonomics_flags(); 15.92
16.1 --- a/src/share/vm/runtime/arguments.hpp Wed Sep 11 12:03:41 2013 +0200 16.2 +++ b/src/share/vm/runtime/arguments.hpp Wed Sep 11 16:25:02 2013 +0200 16.3 @@ -280,6 +280,9 @@ 16.4 // Option flags 16.5 static bool _has_profile; 16.6 static const char* _gc_log_filename; 16.7 + // Value of the conservative maximum heap alignment needed 16.8 + static size_t _conservative_max_heap_alignment; 16.9 + 16.10 static uintx _min_heap_size; 16.11 16.12 // -Xrun arguments 16.13 @@ -327,6 +330,7 @@ 16.14 // Garbage-First (UseG1GC) 16.15 static void set_g1_gc_flags(); 16.16 // GC ergonomics 16.17 + static void set_conservative_max_heap_alignment(); 16.18 static void set_use_compressed_oops(); 16.19 static void set_use_compressed_klass_ptrs(); 16.20 static void set_ergonomics_flags(); 16.21 @@ -430,8 +434,10 @@ 16.22 static char* SharedArchivePath; 16.23 16.24 public: 16.25 - // Parses the arguments 16.26 + // Parses the arguments, first phase 16.27 static jint parse(const JavaVMInitArgs* args); 16.28 + // Apply ergonomics 16.29 + static jint apply_ergo(); 16.30 // Adjusts the arguments after the OS have adjusted the arguments 16.31 static jint adjust_after_os(); 16.32 // Check for consistency in the selection of the garbage collector. 16.33 @@ -445,6 +451,10 @@ 16.34 // Used by os_solaris 16.35 static bool process_settings_file(const char* file_name, bool should_exist, jboolean ignore_unrecognized); 16.36 16.37 + static size_t conservative_max_heap_alignment() { return _conservative_max_heap_alignment; } 16.38 + // Return the maximum size a heap with compressed oops can take 16.39 + static size_t max_heap_for_compressed_oops(); 16.40 + 16.41 // return a char* array containing all options 16.42 static char** jvm_flags_array() { return _jvm_flags_array; } 16.43 static char** jvm_args_array() { return _jvm_args_array; }
17.1 --- a/src/share/vm/runtime/os.cpp Wed Sep 11 12:03:41 2013 +0200 17.2 +++ b/src/share/vm/runtime/os.cpp Wed Sep 11 16:25:02 2013 +0200 17.3 @@ -314,6 +314,11 @@ 17.4 } 17.5 } 17.6 17.7 +void os::init_before_ergo() { 17.8 + // We need to initialize large page support here because ergonomics takes some 17.9 + // decisions depending on large page support and the calculated large page size. 17.10 + large_page_init(); 17.11 +} 17.12 17.13 void os::signal_init() { 17.14 if (!ReduceSignalUsage) {
18.1 --- a/src/share/vm/runtime/os.hpp Wed Sep 11 12:03:41 2013 +0200 18.2 +++ b/src/share/vm/runtime/os.hpp Wed Sep 11 16:25:02 2013 +0200 18.3 @@ -139,7 +139,10 @@ 18.4 18.5 public: 18.6 static void init(void); // Called before command line parsing 18.7 + static void init_before_ergo(void); // Called after command line parsing 18.8 + // before VM ergonomics processing. 18.9 static jint init_2(void); // Called after command line parsing 18.10 + // and VM ergonomics processing 18.11 static void init_globals(void) { // Called from init_globals() in init.cpp 18.12 init_globals_ext(); 18.13 } 18.14 @@ -254,6 +257,11 @@ 18.15 static size_t page_size_for_region(size_t region_min_size, 18.16 size_t region_max_size, 18.17 uint min_pages); 18.18 + // Return the largest page size that can be used 18.19 + static size_t max_page_size() { 18.20 + // The _page_sizes array is sorted in descending order. 18.21 + return _page_sizes[0]; 18.22 + } 18.23 18.24 // Methods for tracing page sizes returned by the above method; enabled by 18.25 // TracePageSizes. The region_{min,max}_size parameters should be the values
19.1 --- a/src/share/vm/runtime/thread.cpp Wed Sep 11 12:03:41 2013 +0200 19.2 +++ b/src/share/vm/runtime/thread.cpp Wed Sep 11 16:25:02 2013 +0200 19.3 @@ -3329,6 +3329,11 @@ 19.4 jint parse_result = Arguments::parse(args); 19.5 if (parse_result != JNI_OK) return parse_result; 19.6 19.7 + os::init_before_ergo(); 19.8 + 19.9 + jint ergo_result = Arguments::apply_ergo(); 19.10 + if (ergo_result != JNI_OK) return ergo_result; 19.11 + 19.12 if (PauseAtStartup) { 19.13 os::pause(); 19.14 }
20.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 20.2 +++ b/test/gc/arguments/TestUseCompressedOopsErgo.java Wed Sep 11 16:25:02 2013 +0200 20.3 @@ -0,0 +1,50 @@ 20.4 +/* 20.5 +* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. 20.6 +* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 20.7 +* 20.8 +* This code is free software; you can redistribute it and/or modify it 20.9 +* under the terms of the GNU General Public License version 2 only, as 20.10 +* published by the Free Software Foundation. 20.11 +* 20.12 +* This code is distributed in the hope that it will be useful, but WITHOUT 20.13 +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 20.14 +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 20.15 +* version 2 for more details (a copy is included in the LICENSE file that 20.16 +* accompanied this code). 20.17 +* 20.18 +* You should have received a copy of the GNU General Public License version 20.19 +* 2 along with this work; if not, write to the Free Software Foundation, 20.20 +* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20.21 +* 20.22 +* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20.23 +* or visit www.oracle.com if you need additional information or have any 20.24 +* questions. 20.25 +*/ 20.26 + 20.27 +/* 20.28 + * @test TestUseCompressedOopsErgo 20.29 + * @key gc 20.30 + * @bug 8010722 20.31 + * @summary Tests ergonomics for UseCompressedOops. 20.32 + * @library /testlibrary /testlibrary/whitebox 20.33 + * @build TestUseCompressedOopsErgo TestUseCompressedOopsErgoTools 20.34 + * @run main ClassFileInstaller sun.hotspot.WhiteBox 20.35 + * @run main/othervm TestUseCompressedOopsErgo -XX:+UseG1GC 20.36 + * @run main/othervm TestUseCompressedOopsErgo -XX:+UseParallelGC 20.37 + * @run main/othervm TestUseCompressedOopsErgo -XX:+UseParallelGC -XX:-UseParallelOldGC 20.38 + * @run main/othervm TestUseCompressedOopsErgo -XX:+UseConcMarkSweepGC 20.39 + * @run main/othervm TestUseCompressedOopsErgo -XX:+UseSerialGC 20.40 + */ 20.41 + 20.42 +public class TestUseCompressedOopsErgo { 20.43 + 20.44 + public static void main(String args[]) throws Exception { 20.45 + if (!TestUseCompressedOopsErgoTools.is64bitVM()) { 20.46 + // this test is relevant for 64 bit VMs only 20.47 + return; 20.48 + } 20.49 + final String[] gcFlags = args; 20.50 + TestUseCompressedOopsErgoTools.checkCompressedOopsErgo(gcFlags); 20.51 + } 20.52 +} 20.53 +
21.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 21.2 +++ b/test/gc/arguments/TestUseCompressedOopsErgoTools.java Wed Sep 11 16:25:02 2013 +0200 21.3 @@ -0,0 +1,179 @@ 21.4 +/* 21.5 +* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. 21.6 +* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 21.7 +* 21.8 +* This code is free software; you can redistribute it and/or modify it 21.9 +* under the terms of the GNU General Public License version 2 only, as 21.10 +* published by the Free Software Foundation. 21.11 +* 21.12 +* This code is distributed in the hope that it will be useful, but WITHOUT 21.13 +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 21.14 +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 21.15 +* version 2 for more details (a copy is included in the LICENSE file that 21.16 +* accompanied this code). 21.17 +* 21.18 +* You should have received a copy of the GNU General Public License version 21.19 +* 2 along with this work; if not, write to the Free Software Foundation, 21.20 +* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 21.21 +* 21.22 +* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 21.23 +* or visit www.oracle.com if you need additional information or have any 21.24 +* questions. 21.25 +*/ 21.26 + 21.27 +import sun.management.ManagementFactoryHelper; 21.28 +import com.sun.management.HotSpotDiagnosticMXBean; 21.29 +import com.sun.management.VMOption; 21.30 + 21.31 +import java.util.regex.Matcher; 21.32 +import java.util.regex.Pattern; 21.33 +import java.util.ArrayList; 21.34 +import java.util.Arrays; 21.35 + 21.36 +import com.oracle.java.testlibrary.*; 21.37 +import sun.hotspot.WhiteBox; 21.38 + 21.39 +class DetermineMaxHeapForCompressedOops { 21.40 + public static void main(String[] args) throws Exception { 21.41 + WhiteBox wb = WhiteBox.getWhiteBox(); 21.42 + System.out.print(wb.getCompressedOopsMaxHeapSize()); 21.43 + } 21.44 +} 21.45 + 21.46 +class TestUseCompressedOopsErgoTools { 21.47 + 21.48 + private static long getClassMetaspaceSize() { 21.49 + HotSpotDiagnosticMXBean diagnostic = ManagementFactoryHelper.getDiagnosticMXBean(); 21.50 + 21.51 + VMOption option = diagnostic.getVMOption("ClassMetaspaceSize"); 21.52 + return Long.parseLong(option.getValue()); 21.53 + } 21.54 + 21.55 + 21.56 + public static long getMaxHeapForCompressedOops(String[] vmargs) throws Exception { 21.57 + OutputAnalyzer output = runWhiteBoxTest(vmargs, DetermineMaxHeapForCompressedOops.class.getName(), new String[] {}, false); 21.58 + return Long.parseLong(output.getStdout()); 21.59 + } 21.60 + 21.61 + public static boolean is64bitVM() { 21.62 + String val = System.getProperty("sun.arch.data.model"); 21.63 + if (val == null) { 21.64 + throw new RuntimeException("Could not read sun.arch.data.model"); 21.65 + } 21.66 + if (val.equals("64")) { 21.67 + return true; 21.68 + } else if (val.equals("32")) { 21.69 + return false; 21.70 + } 21.71 + throw new RuntimeException("Unexpected value " + val + " of sun.arch.data.model"); 21.72 + } 21.73 + 21.74 + /** 21.75 + * Executes a new VM process with the given class and parameters. 21.76 + * @param vmargs Arguments to the VM to run 21.77 + * @param classname Name of the class to run 21.78 + * @param arguments Arguments to the class 21.79 + * @param useTestDotJavaDotOpts Use test.java.opts as part of the VM argument string 21.80 + * @return The OutputAnalyzer with the results for the invocation. 21.81 + */ 21.82 + public static OutputAnalyzer runWhiteBoxTest(String[] vmargs, String classname, String[] arguments, boolean useTestDotJavaDotOpts) throws Exception { 21.83 + ArrayList<String> finalargs = new ArrayList<String>(); 21.84 + 21.85 + String[] whiteboxOpts = new String[] { 21.86 + "-Xbootclasspath/a:.", 21.87 + "-XX:+UnlockDiagnosticVMOptions", "-XX:+WhiteBoxAPI", 21.88 + "-cp", System.getProperty("java.class.path"), 21.89 + }; 21.90 + 21.91 + if (useTestDotJavaDotOpts) { 21.92 + // System.getProperty("test.java.opts") is '' if no options is set, 21.93 + // we need to skip such a result 21.94 + String[] externalVMOpts = new String[0]; 21.95 + if (System.getProperty("test.java.opts") != null && System.getProperty("test.java.opts").length() != 0) { 21.96 + externalVMOpts = System.getProperty("test.java.opts").split(" "); 21.97 + } 21.98 + finalargs.addAll(Arrays.asList(externalVMOpts)); 21.99 + } 21.100 + 21.101 + finalargs.addAll(Arrays.asList(vmargs)); 21.102 + finalargs.addAll(Arrays.asList(whiteboxOpts)); 21.103 + finalargs.add(classname); 21.104 + finalargs.addAll(Arrays.asList(arguments)); 21.105 + 21.106 + ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(finalargs.toArray(new String[0])); 21.107 + OutputAnalyzer output = new OutputAnalyzer(pb.start()); 21.108 + output.shouldHaveExitValue(0); 21.109 + return output; 21.110 + } 21.111 + 21.112 + private static String[] join(String[] part1, String part2) { 21.113 + ArrayList<String> result = new ArrayList<String>(); 21.114 + result.addAll(Arrays.asList(part1)); 21.115 + result.add(part2); 21.116 + return result.toArray(new String[0]); 21.117 + } 21.118 + 21.119 + public static void checkCompressedOopsErgo(String[] gcflags) throws Exception { 21.120 + long maxHeapForCompressedOops = getMaxHeapForCompressedOops(gcflags); 21.121 + 21.122 + checkUseCompressedOops(gcflags, maxHeapForCompressedOops, true); 21.123 + checkUseCompressedOops(gcflags, maxHeapForCompressedOops - 1, true); 21.124 + checkUseCompressedOops(gcflags, maxHeapForCompressedOops + 1, false); 21.125 + 21.126 + // the use of HeapBaseMinAddress should not change the outcome 21.127 + checkUseCompressedOops(join(gcflags, "-XX:HeapBaseMinAddress=32G"), maxHeapForCompressedOops, true); 21.128 + checkUseCompressedOops(join(gcflags, "-XX:HeapBaseMinAddress=32G"), maxHeapForCompressedOops - 1, true); 21.129 + checkUseCompressedOops(join(gcflags, "-XX:HeapBaseMinAddress=32G"), maxHeapForCompressedOops + 1, false); 21.130 + 21.131 + // use a different object alignment 21.132 + maxHeapForCompressedOops = getMaxHeapForCompressedOops(join(gcflags, "-XX:ObjectAlignmentInBytes=16")); 21.133 + 21.134 + checkUseCompressedOops(join(gcflags, "-XX:ObjectAlignmentInBytes=16"), maxHeapForCompressedOops, true); 21.135 + checkUseCompressedOops(join(gcflags, "-XX:ObjectAlignmentInBytes=16"), maxHeapForCompressedOops - 1, true); 21.136 + checkUseCompressedOops(join(gcflags, "-XX:ObjectAlignmentInBytes=16"), maxHeapForCompressedOops + 1, false); 21.137 + 21.138 + // use a different ClassMetaspaceSize 21.139 + String classMetaspaceSizeArg = "-XX:ClassMetaspaceSize=" + 2 * getClassMetaspaceSize(); 21.140 + maxHeapForCompressedOops = getMaxHeapForCompressedOops(join(gcflags, classMetaspaceSizeArg)); 21.141 + 21.142 + checkUseCompressedOops(join(gcflags, classMetaspaceSizeArg), maxHeapForCompressedOops, true); 21.143 + checkUseCompressedOops(join(gcflags, classMetaspaceSizeArg), maxHeapForCompressedOops - 1, true); 21.144 + checkUseCompressedOops(join(gcflags, classMetaspaceSizeArg), maxHeapForCompressedOops + 1, false); 21.145 + } 21.146 + 21.147 + private static void checkUseCompressedOops(String[] args, long heapsize, boolean expectUseCompressedOops) throws Exception { 21.148 + ArrayList<String> finalargs = new ArrayList<String>(); 21.149 + finalargs.addAll(Arrays.asList(args)); 21.150 + finalargs.add("-Xmx" + heapsize); 21.151 + finalargs.add("-XX:+PrintFlagsFinal"); 21.152 + finalargs.add("-version"); 21.153 + 21.154 + String output = expectValid(finalargs.toArray(new String[0])); 21.155 + 21.156 + boolean actualUseCompressedOops = getFlagBoolValue(" UseCompressedOops", output); 21.157 + 21.158 + if (expectUseCompressedOops != actualUseCompressedOops) { 21.159 + throw new RuntimeException("Expected use of compressed oops: " + expectUseCompressedOops + " but was: " + actualUseCompressedOops); 21.160 + } 21.161 + } 21.162 + 21.163 + private static boolean getFlagBoolValue(String flag, String where) { 21.164 + Matcher m = Pattern.compile(flag + "\\s+:?= (true|false)").matcher(where); 21.165 + if (!m.find()) { 21.166 + throw new RuntimeException("Could not find value for flag " + flag + " in output string"); 21.167 + } 21.168 + String match = m.group(1).equals("true"); 21.169 + } 21.170 + 21.171 + private static String expect(String[] flags, boolean hasWarning, boolean hasError, int errorcode) throws Exception { 21.172 + ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(flags); 21.173 + OutputAnalyzer output = new OutputAnalyzer(pb.start()); 21.174 + output.shouldHaveExitValue(errorcode); 21.175 + return output.getStdout(); 21.176 + } 21.177 + 21.178 + private static String expectValid(String[] flags) throws Exception { 21.179 + return expect(flags, false, false, 0); 21.180 + } 21.181 +} 21.182 +
22.1 --- a/test/testlibrary/whitebox/sun/hotspot/WhiteBox.java Wed Sep 11 12:03:41 2013 +0200 22.2 +++ b/test/testlibrary/whitebox/sun/hotspot/WhiteBox.java Wed Sep 11 16:25:02 2013 +0200 22.3 @@ -61,6 +61,8 @@ 22.4 registerNatives(); 22.5 } 22.6 22.7 + // Get the maximum heap size supporting COOPs 22.8 + public native long getCompressedOopsMaxHeapSize(); 22.9 // Arguments 22.10 public native void printHeapSizes(); 22.11