Mercurial > hg > graal-compiler
view src/share/vm/gc_implementation/g1/g1BiasedArray.hpp @ 20543:e7d0505c8a30
8059758: Footprint regressions with JDK-8038423
Summary: Changes in JDK-8038423 always initialize (zero out) virtual memory used for auxiliary data structures. This causes a footprint regression for G1 in startup benchmarks. This is because they do not touch that memory at all, so the operating system does not actually commit these pages. The fix is to, if the initialization value of the data structures matches the default value of just committed memory (=0), do not do anything.
Reviewed-by: jwilhelm, brutisso
author | tschatzl |
---|---|
date | Fri, 10 Oct 2014 15:51:58 +0200 |
parents | 78bbf4d43a14 |
children | 52b4284cb496 |
line wrap: on
line source
/* * Copyright (c) 2013, 2014, 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_IMPLEMENTATION_G1_G1BIASEDARRAY_HPP #define SHARE_VM_GC_IMPLEMENTATION_G1_G1BIASEDARRAY_HPP #include "memory/allocation.hpp" #include "utilities/debug.hpp" // Implements the common base functionality for arrays that contain provisions // for accessing its elements using a biased index. // The element type is defined by the instantiating the template. class G1BiasedMappedArrayBase VALUE_OBJ_CLASS_SPEC { friend class VMStructs; public: typedef size_t idx_t; protected: address _base; // the real base address size_t _length; // the length of the array address _biased_base; // base address biased by "bias" elements size_t _bias; // the bias, i.e. the offset biased_base is located to the right in elements uint _shift_by; // the amount of bits to shift right when mapping to an index of the array. protected: G1BiasedMappedArrayBase() : _base(NULL), _length(0), _biased_base(NULL), _bias(0), _shift_by(0) { } // Allocate a new array, generic version. static address create_new_base_array(size_t length, size_t elem_size); // Initialize the members of this class. The biased start address of this array // is the bias (in elements) multiplied by the element size. void initialize_base(address base, size_t length, size_t bias, size_t elem_size, uint shift_by) { assert(base != NULL, "just checking"); assert(length > 0, "just checking"); assert(shift_by < sizeof(uintptr_t) * 8, err_msg("Shifting by " SSIZE_FORMAT ", larger than word size?", (size_t) shift_by)); _base = base; _length = length; _biased_base = base - (bias * elem_size); _bias = bias; _shift_by = shift_by; } // Allocate and initialize this array to cover the heap addresses in the range // of [bottom, end). void initialize(HeapWord* bottom, HeapWord* end, size_t target_elem_size_in_bytes, size_t mapping_granularity_in_bytes) { assert(mapping_granularity_in_bytes > 0, "just checking"); assert(is_power_of_2(mapping_granularity_in_bytes), err_msg("mapping granularity must be power of 2, is %zd", mapping_granularity_in_bytes)); assert((uintptr_t)bottom % mapping_granularity_in_bytes == 0, err_msg("bottom mapping area address must be a multiple of mapping granularity %zd, is " PTR_FORMAT, mapping_granularity_in_bytes, p2i(bottom))); assert((uintptr_t)end % mapping_granularity_in_bytes == 0, err_msg("end mapping area address must be a multiple of mapping granularity %zd, is " PTR_FORMAT, mapping_granularity_in_bytes, p2i(end))); size_t num_target_elems = (end - bottom) / (mapping_granularity_in_bytes / HeapWordSize); idx_t bias = (uintptr_t)bottom / mapping_granularity_in_bytes; address base = create_new_base_array(num_target_elems, target_elem_size_in_bytes); initialize_base(base, num_target_elems, bias, target_elem_size_in_bytes, log2_intptr(mapping_granularity_in_bytes)); } size_t bias() const { return _bias; } uint shift_by() const { return _shift_by; } void verify_index(idx_t index) const PRODUCT_RETURN; void verify_biased_index(idx_t biased_index) const PRODUCT_RETURN; void verify_biased_index_inclusive_end(idx_t biased_index) const PRODUCT_RETURN; public: // Return the length of the array in elements. size_t length() const { return _length; } }; // Array that provides biased access and mapping from (valid) addresses in the // heap into this array. template<class T> class G1BiasedMappedArray : public G1BiasedMappedArrayBase { public: typedef G1BiasedMappedArrayBase::idx_t idx_t; T* base() const { return (T*)G1BiasedMappedArrayBase::_base; } // Return the element of the given array at the given index. Assume // the index is valid. This is a convenience method that does sanity // checking on the index. T get_by_index(idx_t index) const { verify_index(index); return this->base()[index]; } // Set the element of the given array at the given index to the // given value. Assume the index is valid. This is a convenience // method that does sanity checking on the index. void set_by_index(idx_t index, T value) { verify_index(index); this->base()[index] = value; } // The raw biased base pointer. T* biased_base() const { return (T*)G1BiasedMappedArrayBase::_biased_base; } // Return the element of the given array that covers the given word in the // heap. Assumes the index is valid. T get_by_address(HeapWord* value) const { idx_t biased_index = ((uintptr_t)value) >> this->shift_by(); this->verify_biased_index(biased_index); return biased_base()[biased_index]; } // Set the value of the array entry that corresponds to the given array. void set_by_address(HeapWord * address, T value) { idx_t biased_index = ((uintptr_t)address) >> this->shift_by(); this->verify_biased_index(biased_index); biased_base()[biased_index] = value; } protected: // Returns the address of the element the given address maps to T* address_mapped_to(HeapWord* address) { idx_t biased_index = ((uintptr_t)address) >> this->shift_by(); this->verify_biased_index_inclusive_end(biased_index); return biased_base() + biased_index; } public: // Return the smallest address (inclusive) in the heap that this array covers. HeapWord* bottom_address_mapped() const { return (HeapWord*) ((uintptr_t)this->bias() << this->shift_by()); } // Return the highest address (exclusive) in the heap that this array covers. HeapWord* end_address_mapped() const { return (HeapWord*) ((uintptr_t)(this->bias() + this->length()) << this->shift_by()); } protected: virtual T default_value() const = 0; // Set all elements of the given array to the given value. void clear() { T value = default_value(); for (idx_t i = 0; i < length(); i++) { set_by_index(i, value); } } public: G1BiasedMappedArray() {} // Allocate and initialize this array to cover the heap addresses in the range // of [bottom, end). void initialize(HeapWord* bottom, HeapWord* end, size_t mapping_granularity) { G1BiasedMappedArrayBase::initialize(bottom, end, sizeof(T), mapping_granularity); this->clear(); } }; #endif // SHARE_VM_GC_IMPLEMENTATION_G1_G1BIASEDARRAY_HPP