8211424: Allocation of old generation of java heap on alternate memory devices - Parallel GC
8202286: Allocation of old generation of Java heap on alternate memory devices
Summary: Enable an experimental feature in HotSpot JVM to allocate old generation of Parallel GC on an alternative memory device, such as NV-DIMMs.
Reviewed-by: sangheki, sjohanss
Contributed-by: kishor.kharbas@intel.com
--- a/src/hotspot/share/gc/parallel/adjoiningGenerations.cpp Fri Dec 21 08:18:59 2018 -0800
+++ b/src/hotspot/share/gc/parallel/adjoiningGenerations.cpp Fri Dec 21 08:23:55 2018 -0800
@@ -24,6 +24,7 @@
#include "precompiled.hpp"
#include "gc/parallel/adjoiningGenerations.hpp"
+#include "gc/parallel/adjoiningGenerationsForHeteroHeap.hpp"
#include "gc/parallel/adjoiningVirtualSpaces.hpp"
#include "gc/parallel/generationSizer.hpp"
#include "gc/parallel/parallelScavengeHeap.hpp"
@@ -40,8 +41,8 @@
AdjoiningGenerations::AdjoiningGenerations(ReservedSpace old_young_rs,
GenerationSizer* policy,
size_t alignment) :
- _virtual_spaces(old_young_rs, policy->min_old_size(),
- policy->min_young_size(), alignment) {
+ _virtual_spaces(new AdjoiningVirtualSpaces(old_young_rs, policy->min_old_size(),
+ policy->min_young_size(), alignment)) {
size_t init_low_byte_size = policy->initial_old_size();
size_t min_low_byte_size = policy->min_old_size();
size_t max_low_byte_size = policy->max_old_size();
@@ -61,21 +62,21 @@
// generation.
// Does the actual creation of the virtual spaces
- _virtual_spaces.initialize(max_low_byte_size,
- init_low_byte_size,
- init_high_byte_size);
+ _virtual_spaces->initialize(max_low_byte_size,
+ init_low_byte_size,
+ init_high_byte_size);
// Place the young gen at the high end. Passes in the virtual space.
- _young_gen = new ASPSYoungGen(_virtual_spaces.high(),
- _virtual_spaces.high()->committed_size(),
+ _young_gen = new ASPSYoungGen(_virtual_spaces->high(),
+ _virtual_spaces->high()->committed_size(),
min_high_byte_size,
- _virtual_spaces.high_byte_size_limit());
+ _virtual_spaces->high_byte_size_limit());
// Place the old gen at the low end. Passes in the virtual space.
- _old_gen = new ASPSOldGen(_virtual_spaces.low(),
- _virtual_spaces.low()->committed_size(),
+ _old_gen = new ASPSOldGen(_virtual_spaces->low(),
+ _virtual_spaces->low()->committed_size(),
min_low_byte_size,
- _virtual_spaces.low_byte_size_limit(),
+ _virtual_spaces->low_byte_size_limit(),
"old", 1);
young_gen()->initialize_work();
@@ -92,8 +93,9 @@
} else {
// Layout the reserved space for the generations.
+ // If OldGen is allocated on nv-dimm, we need to split the reservation (this is required for windows).
ReservedSpace old_rs =
- virtual_spaces()->reserved_space().first_part(max_low_byte_size);
+ virtual_spaces()->reserved_space().first_part(max_low_byte_size, policy->is_hetero_heap() /* split */);
ReservedSpace heap_rs =
virtual_spaces()->reserved_space().last_part(max_low_byte_size);
ReservedSpace young_rs = heap_rs.first_part(max_high_byte_size);
@@ -117,6 +119,8 @@
}
}
+AdjoiningGenerations::AdjoiningGenerations() { }
+
size_t AdjoiningGenerations::reserved_byte_size() {
return virtual_spaces()->reserved_space().size();
}
@@ -279,3 +283,13 @@
}
}
}
+
+AdjoiningGenerations* AdjoiningGenerations::create_adjoining_generations(ReservedSpace old_young_rs,
+ GenerationSizer* policy,
+ size_t alignment) {
+ if (policy->is_hetero_heap() && UseAdaptiveGCBoundary) {
+ return new AdjoiningGenerationsForHeteroHeap(old_young_rs, policy, alignment);
+ } else {
+ return new AdjoiningGenerations(old_young_rs, policy, alignment);
+ }
+}
--- a/src/hotspot/share/gc/parallel/adjoiningGenerations.hpp Fri Dec 21 08:18:59 2018 -0800
+++ b/src/hotspot/share/gc/parallel/adjoiningGenerations.hpp Fri Dec 21 08:23:55 2018 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2018, 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
@@ -43,27 +43,29 @@
class AdjoiningGenerations : public CHeapObj<mtGC> {
friend class VMStructs;
private:
- // The young generation and old generation, respectively
- PSYoungGen* _young_gen;
- PSOldGen* _old_gen;
-
- // The spaces used by the two generations.
- AdjoiningVirtualSpaces _virtual_spaces;
-
// Move boundary up to expand old gen. Checks are made to
// determine if the move can be done with specified limits.
void request_old_gen_expansion(size_t desired_change_in_bytes);
// Move boundary down to expand young gen.
bool request_young_gen_expansion(size_t desired_change_in_bytes);
+ protected:
+ // The young generation and old generation, respectively
+ PSYoungGen* _young_gen;
+ PSOldGen* _old_gen;
+
+ // The spaces used by the two generations.
+ AdjoiningVirtualSpaces* _virtual_spaces;
+
public:
AdjoiningGenerations(ReservedSpace rs, GenerationSizer* policy, size_t alignment);
+ AdjoiningGenerations();
// Accessors
PSYoungGen* young_gen() { return _young_gen; }
PSOldGen* old_gen() { return _old_gen; }
- AdjoiningVirtualSpaces* virtual_spaces() { return &_virtual_spaces; }
+ AdjoiningVirtualSpaces* virtual_spaces() { return _virtual_spaces; }
// Additional space is needed in the old generation. Check
// the available space and attempt to move the boundary if more space
@@ -74,7 +76,9 @@
// Return the total byte size of the reserved space
// for the adjoining generations.
- size_t reserved_byte_size();
+ virtual size_t reserved_byte_size();
+
+ // Return new AdjoiningGenerations instance based on collector policy (specifically - whether heap is heterogeneous).
+ static AdjoiningGenerations* create_adjoining_generations(ReservedSpace rs, GenerationSizer* policy, size_t alignment);
};
-
#endif // SHARE_VM_GC_PARALLEL_ADJOININGGENERATIONS_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/parallel/adjoiningGenerationsForHeteroHeap.cpp Fri Dec 21 08:23:55 2018 -0800
@@ -0,0 +1,260 @@
+/*
+ * Copyright (c) 2018, 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.
+ *
+ */
+
+#include "precompiled.hpp"
+#include "gc/parallel/adjoiningGenerationsForHeteroHeap.hpp"
+#include "gc/parallel/adjoiningVirtualSpaces.hpp"
+#include "gc/parallel/generationSizer.hpp"
+#include "gc/parallel/parallelScavengeHeap.hpp"
+#include "gc/parallel/psFileBackedVirtualspace.hpp"
+#include "logging/log.hpp"
+#include "logging/logStream.hpp"
+#include "memory/resourceArea.hpp"
+#include "utilities/align.hpp"
+#include "utilities/ostream.hpp"
+
+// Create two virtual spaces (HeteroVirtualSpaces), low() on nv-dimm memory, high() on dram.
+// create ASPSOldGen and ASPSYoungGen the same way as in base class
+
+AdjoiningGenerationsForHeteroHeap::AdjoiningGenerationsForHeteroHeap(ReservedSpace old_young_rs, GenerationSizer* policy, size_t alignment) :
+ _total_size_limit(policy->max_heap_byte_size()) {
+ size_t init_old_byte_size = policy->initial_old_size();
+ size_t min_old_byte_size = policy->min_old_size();
+ size_t max_old_byte_size = policy->max_old_size();
+ size_t init_young_byte_size = policy->initial_young_size();
+ size_t min_young_byte_size = policy->min_young_size();
+ size_t max_young_byte_size = policy->max_young_size();
+ // create HeteroVirtualSpaces which is composed of non-overlapping virtual spaces.
+ HeteroVirtualSpaces* hetero_virtual_spaces = new HeteroVirtualSpaces(old_young_rs, min_old_byte_size,
+ min_young_byte_size, _total_size_limit, alignment);
+
+ assert(min_old_byte_size <= init_old_byte_size &&
+ init_old_byte_size <= max_old_byte_size, "Parameter check");
+ assert(min_young_byte_size <= init_young_byte_size &&
+ init_young_byte_size <= max_young_byte_size, "Parameter check");
+
+ assert(UseAdaptiveGCBoundary, "Should be used only when UseAdaptiveGCBoundary is true");
+
+ // Initialize the virtual spaces. Then pass a virtual space to each generation
+ // for initialization of the generation.
+
+ // Does the actual creation of the virtual spaces
+ hetero_virtual_spaces->initialize(max_old_byte_size, init_old_byte_size, init_young_byte_size);
+
+ _young_gen = new ASPSYoungGen(hetero_virtual_spaces->high(),
+ hetero_virtual_spaces->high()->committed_size() /* intial_size */,
+ min_young_byte_size,
+ hetero_virtual_spaces->max_young_size());
+
+ _old_gen = new ASPSOldGen(hetero_virtual_spaces->low(),
+ hetero_virtual_spaces->low()->committed_size() /* intial_size */,
+ min_old_byte_size,
+ hetero_virtual_spaces->max_old_size(), "old", 1);
+
+ young_gen()->initialize_work();
+ assert(young_gen()->reserved().byte_size() <= young_gen()->gen_size_limit(), "Consistency check");
+ assert(old_young_rs.size() >= young_gen()->gen_size_limit(), "Consistency check");
+
+ old_gen()->initialize_work("old", 1);
+ assert(old_gen()->reserved().byte_size() <= old_gen()->gen_size_limit(), "Consistency check");
+ assert(old_young_rs.size() >= old_gen()->gen_size_limit(), "Consistency check");
+
+ _virtual_spaces = hetero_virtual_spaces;
+}
+
+size_t AdjoiningGenerationsForHeteroHeap::required_reserved_memory(GenerationSizer* policy) {
+ // This is the size that young gen can grow to, when AdaptiveGCBoundary is true.
+ size_t max_yg_size = policy->max_heap_byte_size() - policy->min_old_size();
+ // This is the size that old gen can grow to, when AdaptiveGCBoundary is true.
+ size_t max_old_size = policy->max_heap_byte_size() - policy->min_young_size();
+
+ return max_yg_size + max_old_size;
+}
+
+// We override this function since size of reservedspace here is more than heap size and
+// callers expect this function to return heap size.
+size_t AdjoiningGenerationsForHeteroHeap::reserved_byte_size() {
+ return total_size_limit();
+}
+
+AdjoiningGenerationsForHeteroHeap::HeteroVirtualSpaces::HeteroVirtualSpaces(ReservedSpace rs, size_t min_old_byte_size, size_t min_yg_byte_size, size_t max_total_size, size_t alignment) :
+ AdjoiningVirtualSpaces(rs, min_old_byte_size, min_yg_byte_size, alignment),
+ _max_total_size(max_total_size),
+ _min_old_byte_size(min_old_byte_size), _min_young_byte_size(min_yg_byte_size),
+ _max_old_byte_size(_max_total_size - _min_young_byte_size),
+ _max_young_byte_size(_max_total_size - _min_old_byte_size) {
+}
+
+void AdjoiningGenerationsForHeteroHeap::HeteroVirtualSpaces::initialize(size_t initial_old_reserved_size, size_t init_old_byte_size,
+ size_t init_young_byte_size) {
+
+ // This is the reserved space exclusively for old generation.
+ ReservedSpace low_rs = _reserved_space.first_part(_max_old_byte_size, true);
+ // Intially we only assign 'initial_old_reserved_size' of the reserved space to old virtual space.
+ low_rs = low_rs.first_part(initial_old_reserved_size);
+
+ // This is the reserved space exclusively for young generation.
+ ReservedSpace high_rs = _reserved_space.last_part(_max_old_byte_size).first_part(_max_young_byte_size);
+
+ // Carve out 'initial_young_reserved_size' of reserved space.
+ size_t initial_young_reserved_size = _max_total_size - initial_old_reserved_size;
+ high_rs = high_rs.last_part(_max_young_byte_size - initial_young_reserved_size);
+
+ _low = new PSFileBackedVirtualSpace(low_rs, alignment(), AllocateOldGenAt);
+ if (!static_cast <PSFileBackedVirtualSpace*>(_low)->initialize()) {
+ vm_exit_during_initialization("Could not map space for old generation at given AllocateOldGenAt path");
+ }
+
+ if (!_low->expand_by(init_old_byte_size)) {
+ vm_exit_during_initialization("Could not reserve enough space for object heap");
+ }
+
+ _high = new PSVirtualSpaceHighToLow(high_rs, alignment());
+ if (!_high->expand_by(init_young_byte_size)) {
+ vm_exit_during_initialization("Could not reserve enough space for object heap");
+ }
+}
+
+// Since the virtual spaces are non-overlapping, there is no boundary as such.
+// We replicate the same behavior and maintain the same invariants as base class 'AdjoiningVirtualSpaces' by
+// increasing old generation size and decreasing young generation size by same amount.
+bool AdjoiningGenerationsForHeteroHeap::HeteroVirtualSpaces::adjust_boundary_up(size_t change_in_bytes) {
+ assert(UseAdaptiveSizePolicy && UseAdaptiveGCBoundary, "runtime check");
+ DEBUG_ONLY(size_t total_size_before = young_vs()->reserved_size() + old_vs()->reserved_size());
+
+ size_t bytes_needed = change_in_bytes;
+ size_t uncommitted_in_old = MIN2(old_vs()->uncommitted_size(), bytes_needed);
+ bool old_expanded = false;
+
+ // 1. Try to expand old within its reserved space.
+ if (uncommitted_in_old != 0) {
+ if (!old_vs()->expand_by(uncommitted_in_old)) {
+ return false;
+ }
+ old_expanded = true;
+ bytes_needed -= uncommitted_in_old;
+ if (bytes_needed == 0) {
+ return true;
+ }
+ }
+
+ size_t bytes_to_add_in_old = 0;
+
+ // 2. Get uncommitted memory from Young virtualspace.
+ size_t young_uncommitted = MIN2(young_vs()->uncommitted_size(), bytes_needed);
+ if (young_uncommitted > 0) {
+ young_vs()->set_reserved(young_vs()->reserved_low_addr() + young_uncommitted,
+ young_vs()->reserved_high_addr(),
+ young_vs()->special());
+ bytes_needed -= young_uncommitted;
+ bytes_to_add_in_old = young_uncommitted;
+ }
+
+ // 3. Get committed memory from Young virtualspace
+ if (bytes_needed > 0) {
+ size_t shrink_size = align_down(bytes_needed, young_vs()->alignment());
+ bool ret = young_vs()->shrink_by(shrink_size);
+ assert(ret, "We should be able to shrink young space");
+ young_vs()->set_reserved(young_vs()->reserved_low_addr() + shrink_size,
+ young_vs()->reserved_high_addr(),
+ young_vs()->special());
+
+ bytes_to_add_in_old += shrink_size;
+ }
+
+ // 4. Increase size of old space
+ old_vs()->set_reserved(old_vs()->reserved_low_addr(),
+ old_vs()->reserved_high_addr() + bytes_to_add_in_old,
+ old_vs()->special());
+ if (!old_vs()->expand_by(bytes_to_add_in_old) && !old_expanded) {
+ return false;
+ }
+
+ DEBUG_ONLY(size_t total_size_after = young_vs()->reserved_size() + old_vs()->reserved_size());
+ assert(total_size_after == total_size_before, "should be equal");
+
+ return true;
+}
+
+// Read comment for adjust_boundary_up()
+// Increase young generation size and decrease old generation size by same amount.
+bool AdjoiningGenerationsForHeteroHeap::HeteroVirtualSpaces::adjust_boundary_down(size_t change_in_bytes) {
+ assert(UseAdaptiveSizePolicy && UseAdaptiveGCBoundary, "runtime check");
+ DEBUG_ONLY(size_t total_size_before = young_vs()->reserved_size() + old_vs()->reserved_size());
+
+ size_t bytes_needed = change_in_bytes;
+ size_t uncommitted_in_young = MIN2(young_vs()->uncommitted_size(), bytes_needed);
+ bool young_expanded = false;
+
+ // 1. Try to expand old within its reserved space.
+ if (uncommitted_in_young > 0) {
+ if (!young_vs()->expand_by(uncommitted_in_young)) {
+ return false;
+ }
+ young_expanded = true;
+ bytes_needed -= uncommitted_in_young;
+ if (bytes_needed == 0) {
+ return true;
+ }
+ }
+
+ size_t bytes_to_add_in_young = 0;
+
+ // 2. Get uncommitted memory from Old virtualspace.
+ size_t old_uncommitted = MIN2(old_vs()->uncommitted_size(), bytes_needed);
+ if (old_uncommitted > 0) {
+ old_vs()->set_reserved(old_vs()->reserved_low_addr(),
+ old_vs()->reserved_high_addr() - old_uncommitted,
+ old_vs()->special());
+ bytes_needed -= old_uncommitted;
+ bytes_to_add_in_young = old_uncommitted;
+ }
+
+ // 3. Get committed memory from Old virtualspace
+ if (bytes_needed > 0) {
+ size_t shrink_size = align_down(bytes_needed, old_vs()->alignment());
+ bool ret = old_vs()->shrink_by(shrink_size);
+ assert(ret, "We should be able to shrink young space");
+ old_vs()->set_reserved(old_vs()->reserved_low_addr(),
+ old_vs()->reserved_high_addr() - shrink_size,
+ old_vs()->special());
+
+ bytes_to_add_in_young += shrink_size;
+ }
+
+ assert(bytes_to_add_in_young <= change_in_bytes, "should not be more than requested size");
+ // 4. Increase size of young space
+ young_vs()->set_reserved(young_vs()->reserved_low_addr() - bytes_to_add_in_young,
+ young_vs()->reserved_high_addr(),
+ young_vs()->special());
+ if (!young_vs()->expand_by(bytes_to_add_in_young) && !young_expanded) {
+ return false;
+ }
+
+ DEBUG_ONLY(size_t total_size_after = young_vs()->reserved_size() + old_vs()->reserved_size());
+ assert(total_size_after == total_size_before, "should be equal");
+
+ return true;
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/parallel/adjoiningGenerationsForHeteroHeap.hpp Fri Dec 21 08:23:55 2018 -0800
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2018, 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.
+ *
+ */
+
+#ifndef SHARE_VM_GC_PARALLEL_ADJOININGGENERATIONSFORHETEROHEAP_HPP
+#define SHARE_VM_GC_PARALLEL_ADJOININGGENERATIONSFORHETEROHEAP_HPP
+
+#include "gc/parallel/adjoiningGenerations.hpp"
+
+class AdjoiningGenerationsForHeteroHeap : public AdjoiningGenerations {
+ friend class VMStructs;
+private:
+ // Maximum total size of the generations. This is equal to the heap size specified by user.
+ // When adjusting young and old generation sizes, we need ensure that sum of the generation sizes does not exceed this.
+ size_t _total_size_limit;
+
+ size_t total_size_limit() const {
+ return _total_size_limit;
+ }
+
+ // HeteroVirtualSpaces creates non-overlapping virtual spaces. Here _low and _high do not share a reserved space, i.e. there is no boundary
+ // separating the two virtual spaces.
+ class HeteroVirtualSpaces : public AdjoiningVirtualSpaces {
+ size_t _max_total_size;
+ size_t _min_old_byte_size;
+ size_t _min_young_byte_size;
+ size_t _max_old_byte_size;
+ size_t _max_young_byte_size;
+
+ // Internally we access the virtual spaces using these methods. It increases readability, since we were not really
+ // dealing with adjoining virtual spaces separated by a boundary as is the case in base class.
+ // Externally they are accessed using low() and high() methods of base class.
+ PSVirtualSpace* young_vs() { return high(); }
+ PSVirtualSpace* old_vs() { return low(); }
+
+ public:
+ HeteroVirtualSpaces(ReservedSpace rs,
+ size_t min_old_byte_size,
+ size_t min_young_byte_size, size_t max_total_size,
+ size_t alignment);
+
+ // Increase old generation size and decrease young generation size by same amount
+ bool adjust_boundary_up(size_t size_in_bytes);
+ // Increase young generation size and decrease old generation size by same amount
+ bool adjust_boundary_down(size_t size_in_bytes);
+
+ size_t max_young_size() const { return _max_young_byte_size; }
+ size_t max_old_size() const { return _max_old_byte_size; }
+
+ void initialize(size_t initial_old_reserved_size, size_t init_low_byte_size,
+ size_t init_high_byte_size);
+ };
+
+public:
+ AdjoiningGenerationsForHeteroHeap(ReservedSpace rs, GenerationSizer* policy, size_t alignment);
+
+ // Given the size policy, calculate the total amount of memory that needs to be reserved.
+ // We need to reserve more memory than Xmx, since we use non-overlapping virtual spaces for the young and old generations.
+ static size_t required_reserved_memory(GenerationSizer* policy);
+
+ // Return the total byte size of the reserved space
+ size_t reserved_byte_size();
+};
+#endif // SHARE_VM_GC_PARALLEL_ADJOININGGENERATIONSFORHETEROHEAP_HPP
+
--- a/src/hotspot/share/gc/parallel/adjoiningVirtualSpaces.hpp Fri Dec 21 08:18:59 2018 -0800
+++ b/src/hotspot/share/gc/parallel/adjoiningVirtualSpaces.hpp Fri Dec 21 08:23:55 2018 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2018, 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
@@ -59,7 +59,8 @@
// moved up consistently. AdjoiningVirtualSpaces provide the
// interfaces for moving the this boundary.
-class AdjoiningVirtualSpaces {
+class AdjoiningVirtualSpaces : public CHeapObj<mtGC> {
+protected:
// space at the high end and the low end, respectively
PSVirtualSpace* _high;
PSVirtualSpace* _low;
@@ -84,17 +85,17 @@
size_t alignment);
// accessors
- PSVirtualSpace* high() { return _high; }
- PSVirtualSpace* low() { return _low; }
+ virtual PSVirtualSpace* high() { return _high; }
+ virtual PSVirtualSpace* low() { return _low; }
ReservedSpace reserved_space() { return _reserved_space; }
size_t min_low_byte_size() { return _min_low_byte_size; }
size_t min_high_byte_size() { return _min_high_byte_size; }
size_t alignment() const { return _alignment; }
// move boundary between the two spaces up
- bool adjust_boundary_up(size_t size_in_bytes);
+ virtual bool adjust_boundary_up(size_t size_in_bytes);
// and down
- bool adjust_boundary_down(size_t size_in_bytes);
+ virtual bool adjust_boundary_down(size_t size_in_bytes);
// Maximum byte size for the high space.
size_t high_byte_size_limit() {
@@ -107,9 +108,8 @@
// Sets the boundaries for the virtual spaces and commits and
// initial size;
- void initialize(size_t max_low_byte_size,
+ virtual void initialize(size_t max_low_byte_size,
size_t init_low_byte_size,
size_t init_high_byte_size);
};
-
#endif // SHARE_VM_GC_PARALLEL_ADJOININGVIRTUALSPACES_HPP
--- a/src/hotspot/share/gc/parallel/generationSizer.cpp Fri Dec 21 08:18:59 2018 -0800
+++ b/src/hotspot/share/gc/parallel/generationSizer.cpp Fri Dec 21 08:23:55 2018 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2018, 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
@@ -67,3 +67,11 @@
}
GenCollectorPolicy::initialize_size_info();
}
+
+bool GenerationSizer::is_hetero_heap() const {
+ return false;
+}
+
+size_t GenerationSizer::heap_reserved_size_bytes() const {
+ return _max_heap_byte_size;
+}
--- a/src/hotspot/share/gc/parallel/generationSizer.hpp Fri Dec 21 08:18:59 2018 -0800
+++ b/src/hotspot/share/gc/parallel/generationSizer.hpp Fri Dec 21 08:23:55 2018 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2018, 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
@@ -32,7 +32,6 @@
class GenerationSizer : public GenCollectorPolicy {
private:
-
// The alignment used for boundary between young gen and old gen
static size_t default_gen_alignment() { return 64 * K * HeapWordSize; }
@@ -41,5 +40,9 @@
void initialize_alignments();
void initialize_flags();
void initialize_size_info();
+
+ public:
+ virtual size_t heap_reserved_size_bytes() const;
+ virtual bool is_hetero_heap() const;
};
#endif // SHARE_VM_GC_PARALLEL_GENERATIONSIZER_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/parallel/heterogeneousGenerationSizer.cpp Fri Dec 21 08:23:55 2018 -0800
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2018, 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.
+ *
+ */
+
+#include "precompiled.hpp"
+#include "gc/parallel/heterogeneousGenerationSizer.hpp"
+#include "gc/shared/collectorPolicy.hpp"
+#include "logging/log.hpp"
+#include "runtime/globals_extension.hpp"
+#include "runtime/os.hpp"
+#include "utilities/align.hpp"
+#include "utilities/formatBuffer.hpp"
+#include "utilities/globalDefinitions.hpp"
+
+const double HeterogeneousGenerationSizer::MaxRamFractionForYoung = 0.8;
+
+// Check the available dram memory to limit NewSize and MaxNewSize before
+// calling base class initialize_flags().
+void HeterogeneousGenerationSizer::initialize_flags() {
+ FormatBuffer<100> calc_str("");
+
+ julong phys_mem;
+ // If MaxRam is specified, we use that as maximum physical memory available.
+ if (FLAG_IS_DEFAULT(MaxRAM)) {
+ phys_mem = os::physical_memory();
+ calc_str.append("Physical_Memory");
+ } else {
+ phys_mem = (julong)MaxRAM;
+ calc_str.append("MaxRAM");
+ }
+
+ julong reasonable_max = phys_mem;
+
+ // If either MaxRAMFraction or MaxRAMPercentage is specified, we use them to calculate
+ // reasonable max size of young generation.
+ if (!FLAG_IS_DEFAULT(MaxRAMFraction)) {
+ reasonable_max = (julong)(phys_mem / MaxRAMFraction);
+ calc_str.append(" / MaxRAMFraction");
+ } else if (!FLAG_IS_DEFAULT(MaxRAMPercentage)) {
+ reasonable_max = (julong)((phys_mem * MaxRAMPercentage) / 100);
+ calc_str.append(" * MaxRAMPercentage / 100");
+ } else {
+ // We use our own fraction to calculate max size of young generation.
+ reasonable_max = phys_mem * MaxRamFractionForYoung;
+ calc_str.append(" * %0.2f", MaxRamFractionForYoung);
+ }
+ reasonable_max = align_up(reasonable_max, _gen_alignment);
+
+ if (MaxNewSize > reasonable_max) {
+ if (FLAG_IS_CMDLINE(MaxNewSize)) {
+ log_warning(gc, ergo)("Setting MaxNewSize to " SIZE_FORMAT " based on dram available (calculation = align(%s))",
+ (size_t)reasonable_max, calc_str.buffer());
+ } else {
+ log_info(gc, ergo)("Setting MaxNewSize to " SIZE_FORMAT " based on dram available (calculation = align(%s)). "
+ "Dram usage can be lowered by setting MaxNewSize to a lower value", (size_t)reasonable_max, calc_str.buffer());
+ }
+ MaxNewSize = reasonable_max;
+ }
+ if (NewSize > reasonable_max) {
+ if (FLAG_IS_CMDLINE(NewSize)) {
+ log_warning(gc, ergo)("Setting NewSize to " SIZE_FORMAT " based on dram available (calculation = align(%s))",
+ (size_t)reasonable_max, calc_str.buffer());
+ }
+ NewSize = reasonable_max;
+ }
+
+ // After setting new size flags, call base class initialize_flags()
+ GenerationSizer::initialize_flags();
+}
+
+bool HeterogeneousGenerationSizer::is_hetero_heap() const {
+ return true;
+}
+
+size_t HeterogeneousGenerationSizer::heap_reserved_size_bytes() const {
+ if (UseAdaptiveGCBoundary) {
+ // This is the size that young gen can grow to, when UseAdaptiveGCBoundary is true.
+ size_t max_yg_size = _max_heap_byte_size - _min_old_size;
+ // This is the size that old gen can grow to, when UseAdaptiveGCBoundary is true.
+ size_t max_old_size = _max_heap_byte_size - _min_young_size;
+
+ return max_yg_size + max_old_size;
+ } else {
+ return _max_heap_byte_size;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/parallel/heterogeneousGenerationSizer.hpp Fri Dec 21 08:23:55 2018 -0800
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2018, 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.
+ *
+ */
+
+#ifndef SHARE_VM_GC_PARALLEL_HETEROGENEOUSGENERATIONSIZER_HPP
+#define SHARE_VM_GC_PARALLEL_HETEROGENEOUSGENERATIONSIZER_HPP
+
+#include "gc/parallel/generationSizer.hpp"
+
+// There is a nice batch of tested generation sizing code in
+// GenCollectorPolicy. Lets reuse it!
+
+class HeterogeneousGenerationSizer : public GenerationSizer {
+private:
+ // Max fraction of dram to use for young generation when MaxRAMFraction and
+ // MaxRAMPercentage are not specified on commandline.
+ static const double MaxRamFractionForYoung;
+
+protected:
+ virtual void initialize_flags();
+
+public:
+ virtual size_t heap_reserved_size_bytes() const;
+ virtual bool is_hetero_heap() const;
+};
+#endif // SHARE_VM_GC_PARALLEL_HETEROGENEOUSGENERATIONSIZER_HPP
--- a/src/hotspot/share/gc/parallel/parallelArguments.cpp Fri Dec 21 08:18:59 2018 -0800
+++ b/src/hotspot/share/gc/parallel/parallelArguments.cpp Fri Dec 21 08:23:55 2018 -0800
@@ -24,6 +24,7 @@
*/
#include "precompiled.hpp"
+#include "gc/parallel/heterogeneousGenerationSizer.hpp"
#include "gc/parallel/parallelArguments.hpp"
#include "gc/parallel/parallelScavengeHeap.hpp"
#include "gc/shared/adaptiveSizePolicy.hpp"
@@ -93,5 +94,9 @@
}
CollectedHeap* ParallelArguments::create_heap() {
- return create_heap_with_policy<ParallelScavengeHeap, GenerationSizer>();
+ if (AllocateOldGenAt != NULL) {
+ return create_heap_with_policy<ParallelScavengeHeap, HeterogeneousGenerationSizer>();
+ } else {
+ return create_heap_with_policy<ParallelScavengeHeap, GenerationSizer>();
+ }
}
--- a/src/hotspot/share/gc/parallel/parallelScavengeHeap.cpp Fri Dec 21 08:18:59 2018 -0800
+++ b/src/hotspot/share/gc/parallel/parallelScavengeHeap.cpp Fri Dec 21 08:23:55 2018 -0800
@@ -25,6 +25,7 @@
#include "precompiled.hpp"
#include "code/codeCache.hpp"
#include "gc/parallel/adjoiningGenerations.hpp"
+#include "gc/parallel/adjoiningGenerationsForHeteroHeap.hpp"
#include "gc/parallel/adjoiningVirtualSpaces.hpp"
#include "gc/parallel/gcTaskManager.hpp"
#include "gc/parallel/generationSizer.hpp"
@@ -58,7 +59,7 @@
GCTaskManager* ParallelScavengeHeap::_gc_task_manager = NULL;
jint ParallelScavengeHeap::initialize() {
- const size_t heap_size = _collector_policy->max_heap_byte_size();
+ size_t heap_size = _collector_policy->heap_reserved_size_bytes();
ReservedSpace heap_rs = Universe::reserve_heap(heap_size, _collector_policy->heap_alignment());
@@ -86,7 +87,7 @@
double max_gc_pause_sec = ((double) MaxGCPauseMillis)/1000.0;
double max_gc_minor_pause_sec = ((double) MaxGCMinorPauseMillis)/1000.0;
- _gens = new AdjoiningGenerations(heap_rs, _collector_policy, generation_alignment());
+ _gens = AdjoiningGenerations::create_adjoining_generations(heap_rs, _collector_policy, generation_alignment());
_old_gen = _gens->old_gen();
_young_gen = _gens->young_gen();
@@ -104,7 +105,7 @@
GCTimeRatio
);
- assert(!UseAdaptiveGCBoundary ||
+ assert(_collector_policy->is_hetero_heap() || !UseAdaptiveGCBoundary ||
(old_gen()->virtual_space()->high_boundary() ==
young_gen()->virtual_space()->low_boundary()),
"Boundaries must meet");
--- a/src/hotspot/share/gc/parallel/parallelScavengeHeap.hpp Fri Dec 21 08:18:59 2018 -0800
+++ b/src/hotspot/share/gc/parallel/parallelScavengeHeap.hpp Fri Dec 21 08:23:55 2018 -0800
@@ -111,6 +111,8 @@
virtual CollectorPolicy* collector_policy() const { return _collector_policy; }
+ virtual GenerationSizer* ps_collector_policy() const { return _collector_policy; }
+
virtual SoftRefPolicy* soft_ref_policy() { return &_soft_ref_policy; }
virtual GrowableArray<GCMemoryManager*> memory_managers();
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/parallel/psFileBackedVirtualspace.cpp Fri Dec 21 08:23:55 2018 -0800
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2018, 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.
+ *
+ */
+
+#include "precompiled.hpp"
+#include "gc/parallel/psFileBackedVirtualspace.hpp"
+#include "memory/virtualspace.hpp"
+#include "runtime/os.inline.hpp"
+
+PSFileBackedVirtualSpace::PSFileBackedVirtualSpace(ReservedSpace rs, size_t alignment, const char* path) : PSVirtualSpace(rs, alignment),
+ _file_path(path), _fd(-1), _mapping_succeeded(false) {
+ assert(!rs.special(), "ReservedSpace passed to PSFileBackedVirtualSpace cannot be special");
+}
+
+bool PSFileBackedVirtualSpace::initialize() {
+ _fd = os::create_file_for_heap(_file_path);
+ if (_fd == -1) {
+ return false;
+ }
+ // We map the reserved space to a file at initialization.
+ char* ret = os::replace_existing_mapping_with_file_mapping(reserved_low_addr(), reserved_size(), _fd);
+ if (ret != reserved_low_addr()) {
+ os::close(_fd);
+ return false;
+ }
+ // _mapping_succeeded is false if we return before this point.
+ // expand calls later check value of this flag and return error if it is false.
+ _mapping_succeeded = true;
+ _special = true;
+ os::close(_fd);
+ return true;
+}
+
+PSFileBackedVirtualSpace::PSFileBackedVirtualSpace(ReservedSpace rs, const char* path) {
+ PSFileBackedVirtualSpace(rs, os::vm_page_size(), path);
+}
+
+bool PSFileBackedVirtualSpace::expand_by(size_t bytes) {
+ assert(special(), "Since entire space is committed at initialization, _special should always be true for PSFileBackedVirtualSpace");
+
+ // if mapping did not succeed during intialization return false
+ if (!_mapping_succeeded) {
+ return false;
+ }
+ return PSVirtualSpace::expand_by(bytes);
+
+}
+
+bool PSFileBackedVirtualSpace::shrink_by(size_t bytes) {
+ assert(special(), "Since entire space is committed at initialization, _special should always be true for PSFileBackedVirtualSpace");
+ return PSVirtualSpace::shrink_by(bytes);
+}
+
+size_t PSFileBackedVirtualSpace::expand_into(PSVirtualSpace* space, size_t bytes) {
+ // not supported. Since doing this will change page mapping which will lead to large TLB penalties.
+ assert(false, "expand_into() should not be called for PSFileBackedVirtualSpace");
+ return 0;
+}
+
+void PSFileBackedVirtualSpace::release() {
+ os::close(_fd);
+ _fd = -1;
+ _file_path = NULL;
+
+ PSVirtualSpace::release();
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/parallel/psFileBackedVirtualspace.hpp Fri Dec 21 08:23:55 2018 -0800
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2018, 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.
+ *
+ */
+
+#ifndef SHARE_VM_GC_PARALLEL_PSFILEBACKEDVIRTUALSPACE_HPP
+#define SHARE_VM_GC_PARALLEL_PSFILEBACKEDVIRTUALSPACE_HPP
+
+#include "gc/parallel/psVirtualspace.hpp"
+
+class PSFileBackedVirtualSpace : public PSVirtualSpace {
+private:
+ const char* _file_path;
+ int _fd;
+ bool _mapping_succeeded;
+public:
+ PSFileBackedVirtualSpace(ReservedSpace rs, size_t alignment, const char* file_path);
+ PSFileBackedVirtualSpace(ReservedSpace rs, const char* file_path);
+
+ bool initialize();
+ bool expand_by(size_t bytes);
+ bool shrink_by(size_t bytes);
+ size_t expand_into(PSVirtualSpace* space, size_t bytes);
+ void release();
+};
+#endif // SHARE_VM_GC_PARALLEL_PSFILEBACKEDVIRTUALSPACE_HPP
+
--- a/src/hotspot/share/gc/parallel/psOldGen.cpp Fri Dec 21 08:18:59 2018 -0800
+++ b/src/hotspot/share/gc/parallel/psOldGen.cpp Fri Dec 21 08:23:55 2018 -0800
@@ -27,6 +27,7 @@
#include "gc/parallel/parallelScavengeHeap.hpp"
#include "gc/parallel/psAdaptiveSizePolicy.hpp"
#include "gc/parallel/psCardTable.hpp"
+#include "gc/parallel/psFileBackedVirtualspace.hpp"
#include "gc/parallel/psMarkSweepDecorator.hpp"
#include "gc/parallel/psOldGen.hpp"
#include "gc/shared/cardTableBarrierSet.hpp"
@@ -71,7 +72,14 @@
void PSOldGen::initialize_virtual_space(ReservedSpace rs, size_t alignment) {
- _virtual_space = new PSVirtualSpace(rs, alignment);
+ if(ParallelScavengeHeap::heap()->ps_collector_policy()->is_hetero_heap()) {
+ _virtual_space = new PSFileBackedVirtualSpace(rs, alignment, AllocateOldGenAt);
+ if (!(static_cast <PSFileBackedVirtualSpace*>(_virtual_space))->initialize()) {
+ vm_exit_during_initialization("Could not map space for PSOldGen at given AllocateOldGenAt path");
+ }
+ } else {
+ _virtual_space = new PSVirtualSpace(rs, alignment);
+ }
if (!_virtual_space->expand_by(_init_gen_size)) {
vm_exit_during_initialization("Could not reserve enough space for "
"object heap");
--- a/src/hotspot/share/gc/parallel/psParallelCompact.cpp Fri Dec 21 08:18:59 2018 -0800
+++ b/src/hotspot/share/gc/parallel/psParallelCompact.cpp Fri Dec 21 08:23:55 2018 -0800
@@ -1995,7 +1995,10 @@
assert(young_gen->virtual_space()->alignment() ==
old_gen->virtual_space()->alignment(), "alignments do not match");
- if (!(UseAdaptiveSizePolicy && UseAdaptiveGCBoundary)) {
+ // We also return false when it's a heterogenous heap because old generation cannot absorb data from eden
+ // when it is allocated on different memory (example, nv-dimm) than young.
+ if (!(UseAdaptiveSizePolicy && UseAdaptiveGCBoundary) ||
+ ParallelScavengeHeap::heap()->ps_collector_policy()->is_hetero_heap()) {
return false;
}
--- a/src/hotspot/share/prims/whitebox.cpp Fri Dec 21 08:18:59 2018 -0800
+++ b/src/hotspot/share/prims/whitebox.cpp Fri Dec 21 08:23:55 2018 -0800
@@ -500,7 +500,7 @@
#endif // INCLUDE_G1GC
-#if INCLUDE_G1GC
+#if INCLUDE_G1GC || INCLUDE_PARALLELGC
WB_ENTRY(jlong, WB_DramReservedStart(JNIEnv* env, jobject o))
if (UseG1GC) {
G1CollectedHeap* g1h = G1CollectedHeap::heap();
@@ -511,7 +511,16 @@
return (jlong)g1h->base();
}
}
- THROW_MSG_0(vmSymbols::java_lang_UnsupportedOperationException(), "WB_DramReservedStart: enabled only for G1");
+ if (UseParallelGC) {
+ ParallelScavengeHeap* ps_heap = ParallelScavengeHeap::heap();
+ if (AllocateOldGenAt != NULL) {
+ MemRegion reserved = ps_heap->young_gen()->reserved();
+ return (jlong)reserved.start();
+ } else {
+ return (jlong)ps_heap->base();
+ }
+ }
+ THROW_MSG_0(vmSymbols::java_lang_UnsupportedOperationException(), "WB_DramReservedStart: enabled only for G1 and Parallel GC");
WB_END
WB_ENTRY(jlong, WB_DramReservedEnd(JNIEnv* env, jobject o))
@@ -524,7 +533,16 @@
return (jlong)g1h->base() + g1h->collector_policy()->max_heap_byte_size();
}
}
- THROW_MSG_0(vmSymbols::java_lang_UnsupportedOperationException(), "WB_DramReservedEnd: enabled only for G1");
+ if (UseParallelGC) {
+ ParallelScavengeHeap* ps_heap = ParallelScavengeHeap::heap();
+ if (AllocateOldGenAt != NULL) {
+ MemRegion reserved = ps_heap->young_gen()->reserved();
+ return (jlong)reserved.end();
+ } else {
+ return (jlong)ps_heap->reserved_region().end();
+ }
+ }
+ THROW_MSG_0(vmSymbols::java_lang_UnsupportedOperationException(), "WB_DramReservedEnd: enabled only for G1 and Parallel GC");
WB_END
WB_ENTRY(jlong, WB_NvdimmReservedStart(JNIEnv* env, jobject o))
@@ -537,7 +555,16 @@
THROW_MSG_0(vmSymbols::java_lang_UnsupportedOperationException(), "WB_NvdimmReservedStart: Old gen is not allocated on NV-DIMM using AllocateOldGenAt flag");
}
}
- THROW_MSG_0(vmSymbols::java_lang_UnsupportedOperationException(), "WB_NvdimmReservedStart: enabled only for G1");
+ if (UseParallelGC) {
+ ParallelScavengeHeap* ps_heap = ParallelScavengeHeap::heap();
+ if (AllocateOldGenAt != NULL) {
+ MemRegion reserved = ps_heap->old_gen()->reserved();
+ return (jlong)reserved.start();
+ } else {
+ THROW_MSG_0(vmSymbols::java_lang_UnsupportedOperationException(), "WB_NvdimmReservedStart: Old gen is not allocated on NV-DIMM using AllocateOldGenAt flag");
+ }
+ }
+ THROW_MSG_0(vmSymbols::java_lang_UnsupportedOperationException(), "WB_NvdimmReservedStart: enabled only for G1 and Parallel GC");
WB_END
WB_ENTRY(jlong, WB_NvdimmReservedEnd(JNIEnv* env, jobject o))
@@ -550,10 +577,19 @@
THROW_MSG_0(vmSymbols::java_lang_UnsupportedOperationException(), "WB_NvdimmReservedEnd: Old gen is not allocated on NV-DIMM using AllocateOldGenAt flag");
}
}
- THROW_MSG_0(vmSymbols::java_lang_UnsupportedOperationException(), "WB_NvdimmReservedEnd: enabled only for G1");
+ if (UseParallelGC) {
+ ParallelScavengeHeap* ps_heap = ParallelScavengeHeap::heap();
+ if (AllocateOldGenAt != NULL) {
+ MemRegion reserved = ps_heap->old_gen()->reserved();
+ return (jlong)reserved.end();
+ } else {
+ THROW_MSG_0(vmSymbols::java_lang_UnsupportedOperationException(), "WB_NvdimmReservedEnd: Old gen is not allocated on NV-DIMM using AllocateOldGenAt flag");
+ }
+ }
+ THROW_MSG_0(vmSymbols::java_lang_UnsupportedOperationException(), "WB_NvdimmReservedEnd: enabled only for G1 and Parallel GC");
WB_END
-#endif // INCLUDE_G1GC
+#endif // INCLUDE_G1GC || INCLUDE_PARALLELGC
#if INCLUDE_PARALLELGC
@@ -2109,11 +2145,13 @@
{CC"g1AuxiliaryMemoryUsage", CC"()Ljava/lang/management/MemoryUsage;",
(void*)&WB_G1AuxiliaryMemoryUsage },
{CC"g1GetMixedGCInfo", CC"(I)[J", (void*)&WB_G1GetMixedGCInfo },
+#endif // INCLUDE_G1GC
+#if INCLUDE_G1GC || INCLUDE_PARALLELGC
{CC"dramReservedStart", CC"()J", (void*)&WB_DramReservedStart },
{CC"dramReservedEnd", CC"()J", (void*)&WB_DramReservedEnd },
{CC"nvdimmReservedStart", CC"()J", (void*)&WB_NvdimmReservedStart },
{CC"nvdimmReservedEnd", CC"()J", (void*)&WB_NvdimmReservedEnd },
-#endif // INCLUDE_G1GC
+#endif // INCLUDE_G1GC || INCLUDE_PARALLELGC
#if INCLUDE_PARALLELGC
{CC"psVirtualSpaceAlignment",CC"()J", (void*)&WB_PSVirtualSpaceAlignment},
{CC"psHeapGenerationAlignment",CC"()J", (void*)&WB_PSHeapGenerationAlignment},
--- a/test/hotspot/jtreg/gc/nvdimm/TestAllocateOldGenAt.java Fri Dec 21 08:18:59 2018 -0800
+++ b/test/hotspot/jtreg/gc/nvdimm/TestAllocateOldGenAt.java Fri Dec 21 08:23:55 2018 -0800
@@ -54,6 +54,8 @@
"-version"});
runTest("-XX:+UseG1GC");
+ runTest("-XX:+UseParallelOldGC -XX:-UseAdaptiveGCBoundary");
+ runTest("-XX:+UseParallelOldGC -XX:+UseAdaptiveGCBoundary");
}
private static void runTest(String... extraFlags) throws Exception {
--- a/test/hotspot/jtreg/gc/nvdimm/TestAllocateOldGenAtError.java Fri Dec 21 08:18:59 2018 -0800
+++ b/test/hotspot/jtreg/gc/nvdimm/TestAllocateOldGenAtError.java Fri Dec 21 08:23:55 2018 -0800
@@ -63,6 +63,7 @@
"-version"});
testG1();
+ testParallelOld();
}
private static void testG1() throws Exception {
@@ -73,6 +74,19 @@
output.shouldContain("Could not initialize G1 heap");
output.shouldContain("Error occurred during initialization of VM");
output.shouldNotHaveExitValue(0);
+
+ }
+
+ private static void testParallelOld() throws Exception {
+ System.out.println("Testing ParallelOld GC with UseAdaptiveGCBoundary disabled");
+ OutputAnalyzer output = runTest("-XX:+UseParallelOldGC -XX:-UseAdaptiveGCBoundary");
+ output.shouldContain("Error occurred during initialization of VM");
+ output.shouldNotHaveExitValue(0);
+
+ System.out.println("Testing ParallelOld GC with UseAdaptiveGCBoundary enabled");
+ output = runTest("-XX:+UseParallelOldGC -XX:+UseAdaptiveGCBoundary");
+ output.shouldContain("Error occurred during initialization of VM");
+ output.shouldNotHaveExitValue(0);
}
private static OutputAnalyzer runTest(String... extraFlags) throws Exception {
--- a/test/hotspot/jtreg/gc/nvdimm/TestOldObjectsOnNvdimm.java Fri Dec 21 08:18:59 2018 -0800
+++ b/test/hotspot/jtreg/gc/nvdimm/TestOldObjectsOnNvdimm.java Fri Dec 21 08:23:55 2018 -0800
@@ -72,6 +72,9 @@
// Test with G1 GC
runTest("-XX:+UseG1GC");
+ // Test with ParallelOld GC
+ runTest("-XX:+UseParallelOldGC -XX:-UseAdaptiveGCBoundary");
+ runTest("-XX:+UseParallelOldGC -XX:+UseAdaptiveGCBoundary");
}
private static void runTest(String... extraFlags) throws Exception {
--- a/test/hotspot/jtreg/gc/nvdimm/TestYoungObjectsOnDram.java Fri Dec 21 08:18:59 2018 -0800
+++ b/test/hotspot/jtreg/gc/nvdimm/TestYoungObjectsOnDram.java Fri Dec 21 08:23:55 2018 -0800
@@ -73,6 +73,9 @@
// Test with G1 GC
runTest("-XX:+UseG1GC");
+ // Test with ParallelOld GC
+ runTest("-XX:+UseParallelOldGC -XX:-UseAdaptiveGCBoundary");
+ runTest("-XX:+UseParallelOldGC -XX:+UseAdaptiveGCBoundary");
}
private static void runTest(String... extraFlags) throws Exception {