1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/share/vm/gc_implementation/g1/g1BiasedArray.hpp Wed Apr 27 01:25:04 2016 +0800 1.3 @@ -0,0 +1,177 @@ 1.4 +/* 1.5 + * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. 1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.7 + * 1.8 + * This code is free software; you can redistribute it and/or modify it 1.9 + * under the terms of the GNU General Public License version 2 only, as 1.10 + * published by the Free Software Foundation. 1.11 + * 1.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 1.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1.15 + * version 2 for more details (a copy is included in the LICENSE file that 1.16 + * accompanied this code). 1.17 + * 1.18 + * You should have received a copy of the GNU General Public License version 1.19 + * 2 along with this work; if not, write to the Free Software Foundation, 1.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1.21 + * 1.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 1.23 + * or visit www.oracle.com if you need additional information or have any 1.24 + * questions. 1.25 + * 1.26 + */ 1.27 + 1.28 +#ifndef SHARE_VM_GC_IMPLEMENTATION_G1_G1BIASEDARRAY_HPP 1.29 +#define SHARE_VM_GC_IMPLEMENTATION_G1_G1BIASEDARRAY_HPP 1.30 + 1.31 +#include "memory/allocation.hpp" 1.32 +#include "utilities/debug.hpp" 1.33 + 1.34 +// Implements the common base functionality for arrays that contain provisions 1.35 +// for accessing its elements using a biased index. 1.36 +// The element type is defined by the instantiating the template. 1.37 +class G1BiasedMappedArrayBase VALUE_OBJ_CLASS_SPEC { 1.38 + friend class VMStructs; 1.39 +public: 1.40 + typedef size_t idx_t; 1.41 +protected: 1.42 + address _base; // the real base address 1.43 + size_t _length; // the length of the array 1.44 + address _biased_base; // base address biased by "bias" elements 1.45 + size_t _bias; // the bias, i.e. the offset biased_base is located to the right in elements 1.46 + uint _shift_by; // the amount of bits to shift right when mapping to an index of the array. 1.47 + 1.48 +protected: 1.49 + 1.50 + G1BiasedMappedArrayBase() : _base(NULL), _length(0), _biased_base(NULL), 1.51 + _bias(0), _shift_by(0) { } 1.52 + 1.53 + // Allocate a new array, generic version. 1.54 + static address create_new_base_array(size_t length, size_t elem_size); 1.55 + 1.56 + // Initialize the members of this class. The biased start address of this array 1.57 + // is the bias (in elements) multiplied by the element size. 1.58 + void initialize_base(address base, size_t length, size_t bias, size_t elem_size, uint shift_by) { 1.59 + assert(base != NULL, "just checking"); 1.60 + assert(length > 0, "just checking"); 1.61 + assert(shift_by < sizeof(uintptr_t) * 8, err_msg("Shifting by " SSIZE_FORMAT ", larger than word size?", (size_t) shift_by)); 1.62 + _base = base; 1.63 + _length = length; 1.64 + _biased_base = base - (bias * elem_size); 1.65 + _bias = bias; 1.66 + _shift_by = shift_by; 1.67 + } 1.68 + 1.69 + // Allocate and initialize this array to cover the heap addresses in the range 1.70 + // of [bottom, end). 1.71 + void initialize(HeapWord* bottom, HeapWord* end, size_t target_elem_size_in_bytes, size_t mapping_granularity_in_bytes) { 1.72 + assert(mapping_granularity_in_bytes > 0, "just checking"); 1.73 + assert(is_power_of_2(mapping_granularity_in_bytes), 1.74 + err_msg("mapping granularity must be power of 2, is %zd", mapping_granularity_in_bytes)); 1.75 + assert((uintptr_t)bottom % mapping_granularity_in_bytes == 0, 1.76 + err_msg("bottom mapping area address must be a multiple of mapping granularity %zd, is " PTR_FORMAT, 1.77 + mapping_granularity_in_bytes, p2i(bottom))); 1.78 + assert((uintptr_t)end % mapping_granularity_in_bytes == 0, 1.79 + err_msg("end mapping area address must be a multiple of mapping granularity %zd, is " PTR_FORMAT, 1.80 + mapping_granularity_in_bytes, p2i(end))); 1.81 + size_t num_target_elems = (end - bottom) / (mapping_granularity_in_bytes / HeapWordSize); 1.82 + idx_t bias = (uintptr_t)bottom / mapping_granularity_in_bytes; 1.83 + address base = create_new_base_array(num_target_elems, target_elem_size_in_bytes); 1.84 + initialize_base(base, num_target_elems, bias, target_elem_size_in_bytes, log2_intptr(mapping_granularity_in_bytes)); 1.85 + } 1.86 + 1.87 + size_t bias() const { return _bias; } 1.88 + uint shift_by() const { return _shift_by; } 1.89 + 1.90 + void verify_index(idx_t index) const PRODUCT_RETURN; 1.91 + void verify_biased_index(idx_t biased_index) const PRODUCT_RETURN; 1.92 + void verify_biased_index_inclusive_end(idx_t biased_index) const PRODUCT_RETURN; 1.93 + 1.94 +public: 1.95 + // Return the length of the array in elements. 1.96 + size_t length() const { return _length; } 1.97 +}; 1.98 + 1.99 +// Array that provides biased access and mapping from (valid) addresses in the 1.100 +// heap into this array. 1.101 +template<class T> 1.102 +class G1BiasedMappedArray : public G1BiasedMappedArrayBase { 1.103 +public: 1.104 + typedef G1BiasedMappedArrayBase::idx_t idx_t; 1.105 + 1.106 + T* base() const { return (T*)G1BiasedMappedArrayBase::_base; } 1.107 + // Return the element of the given array at the given index. Assume 1.108 + // the index is valid. This is a convenience method that does sanity 1.109 + // checking on the index. 1.110 + T get_by_index(idx_t index) const { 1.111 + verify_index(index); 1.112 + return this->base()[index]; 1.113 + } 1.114 + 1.115 + // Set the element of the given array at the given index to the 1.116 + // given value. Assume the index is valid. This is a convenience 1.117 + // method that does sanity checking on the index. 1.118 + void set_by_index(idx_t index, T value) { 1.119 + verify_index(index); 1.120 + this->base()[index] = value; 1.121 + } 1.122 + 1.123 + // The raw biased base pointer. 1.124 + T* biased_base() const { return (T*)G1BiasedMappedArrayBase::_biased_base; } 1.125 + 1.126 + // Return the element of the given array that covers the given word in the 1.127 + // heap. Assumes the index is valid. 1.128 + T get_by_address(HeapWord* value) const { 1.129 + idx_t biased_index = ((uintptr_t)value) >> this->shift_by(); 1.130 + this->verify_biased_index(biased_index); 1.131 + return biased_base()[biased_index]; 1.132 + } 1.133 + 1.134 + // Set the value of the array entry that corresponds to the given array. 1.135 + void set_by_address(HeapWord * address, T value) { 1.136 + idx_t biased_index = ((uintptr_t)address) >> this->shift_by(); 1.137 + this->verify_biased_index(biased_index); 1.138 + biased_base()[biased_index] = value; 1.139 + } 1.140 + 1.141 +protected: 1.142 + // Returns the address of the element the given address maps to 1.143 + T* address_mapped_to(HeapWord* address) { 1.144 + idx_t biased_index = ((uintptr_t)address) >> this->shift_by(); 1.145 + this->verify_biased_index_inclusive_end(biased_index); 1.146 + return biased_base() + biased_index; 1.147 + } 1.148 + 1.149 +public: 1.150 + // Return the smallest address (inclusive) in the heap that this array covers. 1.151 + HeapWord* bottom_address_mapped() const { 1.152 + return (HeapWord*) ((uintptr_t)this->bias() << this->shift_by()); 1.153 + } 1.154 + 1.155 + // Return the highest address (exclusive) in the heap that this array covers. 1.156 + HeapWord* end_address_mapped() const { 1.157 + return (HeapWord*) ((uintptr_t)(this->bias() + this->length()) << this->shift_by()); 1.158 + } 1.159 + 1.160 +protected: 1.161 + virtual T default_value() const = 0; 1.162 + // Set all elements of the given array to the given value. 1.163 + void clear() { 1.164 + T value = default_value(); 1.165 + for (idx_t i = 0; i < length(); i++) { 1.166 + set_by_index(i, value); 1.167 + } 1.168 + } 1.169 +public: 1.170 + G1BiasedMappedArray() {} 1.171 + 1.172 + // Allocate and initialize this array to cover the heap addresses in the range 1.173 + // of [bottom, end). 1.174 + void initialize(HeapWord* bottom, HeapWord* end, size_t mapping_granularity) { 1.175 + G1BiasedMappedArrayBase::initialize(bottom, end, sizeof(T), mapping_granularity); 1.176 + this->clear(); 1.177 + } 1.178 +}; 1.179 + 1.180 +#endif // SHARE_VM_GC_IMPLEMENTATION_G1_G1BIASEDARRAY_HPP