< prev index next >
src/hotspot/share/gc/parallel/psVirtualspace.cpp
Print this page
rev 50554 : webrev.02
*** 1,7 ****
/*
! * Copyright (c) 2003, 2015, 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.
--- 1,7 ----
/*
! * 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*** 96,105 ****
--- 96,120 ----
}
return result;
}
+ bool PSVirtualSpace::expand_by(size_t bytes, int fd) {
+ assert(is_aligned(bytes), "arg not aligned");
+ DEBUG_ONLY(PSVirtualSpaceVerifier this_verifier(this));
+ if (uncommitted_size() < bytes) {
+ return false;
+ }
+ char* const base_addr = committed_high_addr();
+ bool commit_result = os::commit_memory(base_addr, bytes, alignment(), !ExecMem, fd, committed_size());
+ bool result = special() || commit_result;
+ if (result) {
+ _committed_high_addr += bytes;
+ }
+ return result;
+ }
+
bool PSVirtualSpace::shrink_by(size_t bytes) {
assert(is_aligned(bytes), "arg not aligned");
DEBUG_ONLY(PSVirtualSpaceVerifier this_verifier(this));
if (committed_size() < bytes) {
*** 174,183 ****
--- 189,258 ----
}
return bytes;
}
+ size_t
+ PSVirtualSpace::expand_into(PSVirtualSpace* other_space, size_t bytes, int fd) {
+ assert(is_aligned(bytes), "arg not aligned");
+ assert(grows_up(), "this space must grow up");
+ assert(other_space->grows_down(), "other space must grow down");
+ assert(reserved_high_addr() == other_space->reserved_low_addr(),
+ "spaces not contiguous");
+ assert(special() == other_space->special(), "one space is special, the other is not");
+ DEBUG_ONLY(PSVirtualSpaceVerifier this_verifier(this));
+ DEBUG_ONLY(PSVirtualSpaceVerifier other_verifier(other_space));
+
+ size_t bytes_needed = bytes;
+
+ // First use the uncommitted region in this space.
+ size_t tmp_bytes = MIN2(uncommitted_size(), bytes_needed);
+ if (tmp_bytes > 0) {
+ if (expand_by(tmp_bytes)) {
+ bytes_needed -= tmp_bytes;
+ } else {
+ return 0;
+ }
+ }
+
+ // Next take from the uncommitted region in the other space, and commit it.
+ tmp_bytes = MIN2(other_space->uncommitted_size(), bytes_needed);
+ if (tmp_bytes > 0) {
+ char* const commit_base = committed_high_addr();
+ if (other_space->special() ||
+ os::commit_memory(commit_base, tmp_bytes, alignment(), !ExecMem, fd, committed_size())) {
+ // Reduce the reserved region in the other space.
+ other_space->set_reserved(other_space->reserved_low_addr() + tmp_bytes,
+ other_space->reserved_high_addr(),
+ other_space->special());
+
+ // Grow both reserved and committed in this space.
+ _reserved_high_addr += tmp_bytes;
+ _committed_high_addr += tmp_bytes;
+ bytes_needed -= tmp_bytes;
+ } else {
+ return bytes - bytes_needed;
+ }
+ }
+
+ // Finally take from the already committed region in the other space.
+ tmp_bytes = bytes_needed;
+ if (tmp_bytes > 0) {
+ // Reduce both committed and reserved in the other space.
+ other_space->set_committed(other_space->committed_low_addr() + tmp_bytes,
+ other_space->committed_high_addr());
+ other_space->set_reserved(other_space->reserved_low_addr() + tmp_bytes,
+ other_space->reserved_high_addr(),
+ other_space->special());
+
+ // Grow both reserved and committed in this space.
+ _reserved_high_addr += tmp_bytes;
+ _committed_high_addr += tmp_bytes;
+ }
+ return bytes;
+ }
+
#ifndef PRODUCT
bool PSVirtualSpace::is_aligned(size_t value, size_t align) {
const size_t tmp_value = value + align - 1;
const size_t mask = ~(align - 1);
return (tmp_value & mask) == value;
< prev index next >