/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* 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_implementation/g1/g1AllocRegion.inline.hpp"
#include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
// Make sure that any allocation attempt on this region will fail
// and will not trigger any asserts.
}
bool bot_updates) {
"pre-condition");
// Other threads might still be trying to allocate using a CAS out
// of the region we are trying to retire, as they can do so without
// holding the lock. So, we first have to make sure that noone else
// can allocate out of it by doing a maximal allocation. Even if our
// CAS attempt fails a few times, we'll succeed sooner or later
// given that failed CAS attempts mean that the region is getting
// closed to being full.
// This is the minimum free chunk we can turn into a dummy
// object. If the free space falls below this, then noone can
// allocate in this region anyway (all allocation requests will be
// of a size larger than this) so we won't have to perform the dummy
// allocation.
while (free_word_size >= min_word_size_to_fill) {
// If the allocation was successful we should fill in the space.
break;
}
// It's also possible that someone else beats us to the
// allocation and they fill up the region. In that case, we can
// just get out of the loop.
}
"post-condition");
}
trace("retiring");
if (alloc_region != _dummy_region) {
// We never have to check whether the active region is empty or not,
// and potentially free it if it is, given that it's guaranteed that
// it will never be empty.
ar_ext_msg(this, "the alloc region should never be empty"));
if (fill_up) {
}
ar_ext_msg(this, "invariant"));
_used_bytes_before = 0;
}
trace("retired");
}
bool force) {
trace("attempting region allocation");
if (new_alloc_region != NULL) {
// Need to do this before the allocation
// Note that we first perform the allocation and then we store the
// region in _alloc_region. This is the reason why an active region
// can never be empty.
_count += 1;
trace("region allocation successful");
return result;
} else {
trace("region allocation failed");
return NULL;
}
}
}
trace("initializing");
ar_ext_msg(this, "pre-condition"));
_count = 0;
trace("initialized");
}
trace("setting");
// We explicitly check that the region is not empty to make sure we
// maintain the "the alloc region cannot be empty" invariant.
ar_ext_msg(this, "pre-condition"));
_used_bytes_before == 0 && _count == 0,
ar_ext_msg(this, "pre-condition"));
_count += 1;
trace("set");
}
trace("releasing");
retire(false /* fill_up */);
ar_ext_msg(this, "post-condition of retire()"));
trace("released");
}
// All the calls to trace that set either just the size or the size
// and the result are considered part of level 2 tracing and are
// skipped during level 1 tracing.
if (alloc_region == NULL) {
} else if (alloc_region == _dummy_region) {
} else {
}
if (G1_ALLOC_REGION_TRACING > 1) {
} else if (word_size != 0) {
} else {
}
} else {
}
}
}
#endif // G1_ALLOC_REGION_TRACING
bool bot_updates)