mirror of
https://github.com/openjdk/jdk.git
synced 2026-05-11 22:19:43 +00:00
Merge
This commit is contained in:
commit
5821ebce57
@ -36,7 +36,7 @@ void G1HotCardCache::initialize(G1RegionToSpaceMapper* card_counts_storage) {
|
||||
_use_cache = true;
|
||||
|
||||
_hot_cache_size = (size_t)1 << G1ConcRSLogCacheSize;
|
||||
_hot_cache = _hot_cache_memory.allocate(_hot_cache_size);
|
||||
_hot_cache = ArrayAllocator<jbyte*, mtGC>::allocate(_hot_cache_size);
|
||||
|
||||
reset_hot_cache_internal();
|
||||
|
||||
@ -51,7 +51,7 @@ void G1HotCardCache::initialize(G1RegionToSpaceMapper* card_counts_storage) {
|
||||
G1HotCardCache::~G1HotCardCache() {
|
||||
if (default_use_cache()) {
|
||||
assert(_hot_cache != NULL, "Logic");
|
||||
_hot_cache_memory.free();
|
||||
ArrayAllocator<jbyte*, mtGC>::free(_hot_cache, _hot_cache_size);
|
||||
_hot_cache = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
@ -61,7 +61,6 @@ class G1HotCardCache: public CHeapObj<mtGC> {
|
||||
|
||||
G1CardCounts _card_counts;
|
||||
|
||||
ArrayAllocator<jbyte*, mtGC> _hot_cache_memory;
|
||||
|
||||
// The card cache table
|
||||
jbyte** _hot_cache;
|
||||
|
||||
@ -248,7 +248,6 @@ public:
|
||||
|
||||
template <class E, MEMFLAGS F, unsigned int N = TASKQUEUE_SIZE>
|
||||
class GenericTaskQueue: public TaskQueueSuper<N, F> {
|
||||
ArrayAllocator<E, F> _array_allocator;
|
||||
protected:
|
||||
typedef typename TaskQueueSuper<N, F>::Age Age;
|
||||
typedef typename TaskQueueSuper<N, F>::idx_t idx_t;
|
||||
|
||||
@ -44,12 +44,13 @@ inline GenericTaskQueueSet<T, F>::GenericTaskQueueSet(int n) : _n(n) {
|
||||
|
||||
template<class E, MEMFLAGS F, unsigned int N>
|
||||
inline void GenericTaskQueue<E, F, N>::initialize() {
|
||||
_elems = _array_allocator.allocate(N);
|
||||
_elems = ArrayAllocator<E, F>::allocate(N);
|
||||
}
|
||||
|
||||
template<class E, MEMFLAGS F, unsigned int N>
|
||||
inline GenericTaskQueue<E, F, N>::~GenericTaskQueue() {
|
||||
FREE_C_HEAP_ARRAY(E, _elems);
|
||||
assert(false, "This code is currently never called");
|
||||
ArrayAllocator<E, F>::free(const_cast<E*>(_elems), N);
|
||||
}
|
||||
|
||||
template<class E, MEMFLAGS F, unsigned int N>
|
||||
|
||||
@ -724,30 +724,23 @@ public:
|
||||
// is set so that we always use malloc except for Solaris where we set the
|
||||
// limit to get mapped memory.
|
||||
template <class E, MEMFLAGS F>
|
||||
class ArrayAllocator VALUE_OBJ_CLASS_SPEC {
|
||||
char* _addr;
|
||||
bool _use_malloc;
|
||||
size_t _size;
|
||||
bool _free_in_destructor;
|
||||
class ArrayAllocator : public AllStatic {
|
||||
private:
|
||||
static bool should_use_malloc(size_t length);
|
||||
|
||||
static bool should_use_malloc(size_t size) {
|
||||
return size < ArrayAllocatorMallocLimit;
|
||||
}
|
||||
static size_t size_for_malloc(size_t length);
|
||||
static size_t size_for_mmap(size_t length);
|
||||
|
||||
static E* allocate_malloc(size_t length);
|
||||
static E* allocate_mmap(size_t length);
|
||||
|
||||
static void free_malloc(E* addr, size_t length);
|
||||
static void free_mmap(E* addr, size_t length);
|
||||
|
||||
static char* allocate_inner(size_t& size, bool& use_malloc);
|
||||
public:
|
||||
ArrayAllocator(bool free_in_destructor = true) :
|
||||
_addr(NULL), _use_malloc(false), _size(0), _free_in_destructor(free_in_destructor) { }
|
||||
|
||||
~ArrayAllocator() {
|
||||
if (_free_in_destructor) {
|
||||
free();
|
||||
}
|
||||
}
|
||||
|
||||
E* allocate(size_t length);
|
||||
E* reallocate(size_t new_length);
|
||||
void free();
|
||||
static E* allocate(size_t length);
|
||||
static E* reallocate(E* old_addr, size_t old_length, size_t new_length);
|
||||
static void free(E* addr, size_t length);
|
||||
};
|
||||
|
||||
#endif // SHARE_VM_MEMORY_ALLOCATION_HPP
|
||||
|
||||
@ -151,66 +151,87 @@ template <MEMFLAGS F> void CHeapObj<F>::operator delete [](void* p){
|
||||
}
|
||||
|
||||
template <class E, MEMFLAGS F>
|
||||
char* ArrayAllocator<E, F>::allocate_inner(size_t &size, bool &use_malloc) {
|
||||
char* addr = NULL;
|
||||
|
||||
if (use_malloc) {
|
||||
addr = AllocateHeap(size, F);
|
||||
if (addr == NULL && size >= (size_t)os::vm_allocation_granularity()) {
|
||||
// malloc failed let's try with mmap instead
|
||||
use_malloc = false;
|
||||
} else {
|
||||
return addr;
|
||||
}
|
||||
}
|
||||
size_t ArrayAllocator<E, F>::size_for_malloc(size_t length) {
|
||||
return length * sizeof(E);
|
||||
}
|
||||
|
||||
template <class E, MEMFLAGS F>
|
||||
size_t ArrayAllocator<E, F>::size_for_mmap(size_t length) {
|
||||
size_t size = length * sizeof(E);
|
||||
int alignment = os::vm_allocation_granularity();
|
||||
size = align_size_up(size, alignment);
|
||||
return align_size_up(size, alignment);
|
||||
}
|
||||
|
||||
addr = os::reserve_memory(size, NULL, alignment, F);
|
||||
template <class E, MEMFLAGS F>
|
||||
bool ArrayAllocator<E, F>::should_use_malloc(size_t length) {
|
||||
return size_for_malloc(length) < ArrayAllocatorMallocLimit;
|
||||
}
|
||||
|
||||
template <class E, MEMFLAGS F>
|
||||
E* ArrayAllocator<E, F>::allocate_malloc(size_t length) {
|
||||
return (E*)AllocateHeap(size_for_malloc(length), F);
|
||||
}
|
||||
|
||||
template <class E, MEMFLAGS F>
|
||||
E* ArrayAllocator<E, F>::allocate_mmap(size_t length) {
|
||||
size_t size = size_for_mmap(length);
|
||||
int alignment = os::vm_allocation_granularity();
|
||||
|
||||
char* addr = os::reserve_memory(size, NULL, alignment, F);
|
||||
if (addr == NULL) {
|
||||
vm_exit_out_of_memory(size, OOM_MMAP_ERROR, "Allocator (reserve)");
|
||||
}
|
||||
|
||||
os::commit_memory_or_exit(addr, size, !ExecMem, "Allocator (commit)");
|
||||
return addr;
|
||||
|
||||
return (E*)addr;
|
||||
}
|
||||
|
||||
template <class E, MEMFLAGS F>
|
||||
E* ArrayAllocator<E, F>::allocate(size_t length) {
|
||||
assert(_addr == NULL, "Already in use");
|
||||
if (should_use_malloc(length)) {
|
||||
return allocate_malloc(length);
|
||||
}
|
||||
|
||||
_size = sizeof(E) * length;
|
||||
_use_malloc = should_use_malloc(_size);
|
||||
_addr = allocate_inner(_size, _use_malloc);
|
||||
|
||||
return (E*)_addr;
|
||||
return allocate_mmap(length);
|
||||
}
|
||||
|
||||
template <class E, MEMFLAGS F>
|
||||
E* ArrayAllocator<E, F>::reallocate(size_t new_length) {
|
||||
size_t new_size = sizeof(E) * new_length;
|
||||
bool use_malloc = should_use_malloc(new_size);
|
||||
char* new_addr = allocate_inner(new_size, use_malloc);
|
||||
E* ArrayAllocator<E, F>::reallocate(E* old_addr, size_t old_length, size_t new_length) {
|
||||
E* new_addr = (new_length > 0)
|
||||
? allocate(new_length)
|
||||
: NULL;
|
||||
|
||||
memcpy(new_addr, _addr, MIN2(new_size, _size));
|
||||
if (new_addr != NULL && old_addr != NULL) {
|
||||
memcpy(new_addr, old_addr, MIN2(old_length, new_length) * sizeof(E));
|
||||
}
|
||||
|
||||
free();
|
||||
_size = new_size;
|
||||
_use_malloc = use_malloc;
|
||||
_addr = new_addr;
|
||||
return (E*)new_addr;
|
||||
if (old_addr != NULL) {
|
||||
free(old_addr, old_length);
|
||||
}
|
||||
|
||||
return new_addr;
|
||||
}
|
||||
|
||||
template<class E, MEMFLAGS F>
|
||||
void ArrayAllocator<E, F>::free() {
|
||||
if (_addr != NULL) {
|
||||
if (_use_malloc) {
|
||||
FreeHeap(_addr);
|
||||
void ArrayAllocator<E, F>::free_malloc(E* addr, size_t /*length*/) {
|
||||
FreeHeap(addr);
|
||||
}
|
||||
|
||||
template<class E, MEMFLAGS F>
|
||||
void ArrayAllocator<E, F>::free_mmap(E* addr, size_t length) {
|
||||
bool result = os::release_memory((char*)addr, size_for_mmap(length));
|
||||
assert(result, "Failed to release memory");
|
||||
}
|
||||
|
||||
template<class E, MEMFLAGS F>
|
||||
void ArrayAllocator<E, F>::free(E* addr, size_t length) {
|
||||
if (addr != NULL) {
|
||||
if (should_use_malloc(length)) {
|
||||
free_malloc(addr, length);
|
||||
} else {
|
||||
os::release_memory(_addr, _size);
|
||||
free_mmap(addr, length);
|
||||
}
|
||||
_addr = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -29,20 +29,26 @@
|
||||
#include "utilities/bitMap.inline.hpp"
|
||||
#include "utilities/copy.hpp"
|
||||
|
||||
BitMap::BitMap(bm_word_t* map, idx_t size_in_bits) :
|
||||
_map(map), _size(size_in_bits), _map_allocator(false)
|
||||
{
|
||||
assert(sizeof(bm_word_t) == BytesPerWord, "Implementation assumption.");
|
||||
}
|
||||
|
||||
STATIC_ASSERT(sizeof(BitMap::bm_word_t) == BytesPerWord); // "Implementation assumption."
|
||||
|
||||
BitMap::BitMap(idx_t size_in_bits, bool in_resource_area) :
|
||||
_map(NULL), _size(0), _map_allocator(false)
|
||||
_map(NULL), _size(0)
|
||||
{
|
||||
assert(sizeof(bm_word_t) == BytesPerWord, "Implementation assumption.");
|
||||
resize(size_in_bits, in_resource_area);
|
||||
}
|
||||
|
||||
#ifdef ASSERT
|
||||
void BitMap::verify_index(idx_t index) const {
|
||||
assert(index < _size, "BitMap index out of bounds");
|
||||
}
|
||||
|
||||
void BitMap::verify_range(idx_t beg_index, idx_t end_index) const {
|
||||
assert(beg_index <= end_index, "BitMap range error");
|
||||
// Note that [0,0) and [size,size) are both valid ranges.
|
||||
if (end_index != _size) verify_index(end_index);
|
||||
}
|
||||
#endif // #ifdef ASSERT
|
||||
|
||||
void BitMap::resize(idx_t size_in_bits, bool in_resource_area) {
|
||||
idx_t old_size_in_words = size_in_words();
|
||||
bm_word_t* old_map = map();
|
||||
@ -54,7 +60,7 @@ void BitMap::resize(idx_t size_in_bits, bool in_resource_area) {
|
||||
Copy::disjoint_words((HeapWord*)old_map, (HeapWord*) _map,
|
||||
MIN2(old_size_in_words, new_size_in_words));
|
||||
} else {
|
||||
_map = _map_allocator.reallocate(new_size_in_words);
|
||||
_map = ArrayAllocator<bm_word_t, mtInternal>::reallocate(old_map, old_size_in_words, new_size_in_words);
|
||||
}
|
||||
|
||||
if (new_size_in_words > old_size_in_words) {
|
||||
|
||||
@ -48,7 +48,6 @@ class BitMap VALUE_OBJ_CLASS_SPEC {
|
||||
} RangeSizeHint;
|
||||
|
||||
private:
|
||||
ArrayAllocator<bm_word_t, mtInternal> _map_allocator;
|
||||
bm_word_t* _map; // First word in bitmap
|
||||
idx_t _size; // Size of bitmap (in bits)
|
||||
|
||||
@ -101,9 +100,8 @@ class BitMap VALUE_OBJ_CLASS_SPEC {
|
||||
idx_t word_index_round_up(idx_t bit) const;
|
||||
|
||||
// Verification.
|
||||
inline void verify_index(idx_t index) const NOT_DEBUG_RETURN;
|
||||
inline void verify_range(idx_t beg_index, idx_t end_index) const
|
||||
NOT_DEBUG_RETURN;
|
||||
void verify_index(idx_t index) const NOT_DEBUG_RETURN;
|
||||
void verify_range(idx_t beg_index, idx_t end_index) const NOT_DEBUG_RETURN;
|
||||
|
||||
// Statistics.
|
||||
static idx_t* _pop_count_table;
|
||||
@ -114,10 +112,10 @@ class BitMap VALUE_OBJ_CLASS_SPEC {
|
||||
public:
|
||||
|
||||
// Constructs a bitmap with no map, and size 0.
|
||||
BitMap() : _map(NULL), _size(0), _map_allocator(false) {}
|
||||
BitMap() : _map(NULL), _size(0) {}
|
||||
|
||||
// Constructs a bitmap with the given map and size.
|
||||
BitMap(bm_word_t* map, idx_t size_in_bits);
|
||||
BitMap(bm_word_t* map, idx_t size_in_bits) :_map(map), _size(size_in_bits) {}
|
||||
|
||||
// Constructs an empty bitmap of the given size (that is, this clears the
|
||||
// new bitmap). Allocates the map array in resource area if
|
||||
@ -307,36 +305,12 @@ class BitMap2D VALUE_OBJ_CLASS_SPEC {
|
||||
return _map.size() / _bits_per_slot;
|
||||
}
|
||||
|
||||
bool is_valid_index(idx_t slot_index, idx_t bit_within_slot_index) {
|
||||
verify_bit_within_slot_index(bit_within_slot_index);
|
||||
return (bit_index(slot_index, bit_within_slot_index) < size_in_bits());
|
||||
}
|
||||
|
||||
bool at(idx_t slot_index, idx_t bit_within_slot_index) const {
|
||||
verify_bit_within_slot_index(bit_within_slot_index);
|
||||
return _map.at(bit_index(slot_index, bit_within_slot_index));
|
||||
}
|
||||
|
||||
void set_bit(idx_t slot_index, idx_t bit_within_slot_index) {
|
||||
verify_bit_within_slot_index(bit_within_slot_index);
|
||||
_map.set_bit(bit_index(slot_index, bit_within_slot_index));
|
||||
}
|
||||
|
||||
void clear_bit(idx_t slot_index, idx_t bit_within_slot_index) {
|
||||
verify_bit_within_slot_index(bit_within_slot_index);
|
||||
_map.clear_bit(bit_index(slot_index, bit_within_slot_index));
|
||||
}
|
||||
|
||||
void at_put(idx_t slot_index, idx_t bit_within_slot_index, bool value) {
|
||||
verify_bit_within_slot_index(bit_within_slot_index);
|
||||
_map.at_put(bit_index(slot_index, bit_within_slot_index), value);
|
||||
}
|
||||
|
||||
void at_put_grow(idx_t slot_index, idx_t bit_within_slot_index, bool value) {
|
||||
verify_bit_within_slot_index(bit_within_slot_index);
|
||||
_map.at_put_grow(bit_index(slot_index, bit_within_slot_index), value);
|
||||
}
|
||||
|
||||
bool is_valid_index(idx_t slot_index, idx_t bit_within_slot_index);
|
||||
bool at(idx_t slot_index, idx_t bit_within_slot_index) const;
|
||||
void set_bit(idx_t slot_index, idx_t bit_within_slot_index);
|
||||
void clear_bit(idx_t slot_index, idx_t bit_within_slot_index);
|
||||
void at_put(idx_t slot_index, idx_t bit_within_slot_index, bool value);
|
||||
void at_put_grow(idx_t slot_index, idx_t bit_within_slot_index, bool value);
|
||||
void clear();
|
||||
};
|
||||
|
||||
|
||||
@ -28,18 +28,6 @@
|
||||
#include "runtime/atomic.inline.hpp"
|
||||
#include "utilities/bitMap.hpp"
|
||||
|
||||
#ifdef ASSERT
|
||||
inline void BitMap::verify_index(idx_t index) const {
|
||||
assert(index < _size, "BitMap index out of bounds");
|
||||
}
|
||||
|
||||
inline void BitMap::verify_range(idx_t beg_index, idx_t end_index) const {
|
||||
assert(beg_index <= end_index, "BitMap range error");
|
||||
// Note that [0,0) and [size,size) are both valid ranges.
|
||||
if (end_index != _size) verify_index(end_index);
|
||||
}
|
||||
#endif // #ifdef ASSERT
|
||||
|
||||
inline void BitMap::set_bit(idx_t bit) {
|
||||
verify_index(bit);
|
||||
*word_addr(bit) |= bit_mask(bit);
|
||||
@ -344,6 +332,36 @@ inline BitMap::idx_t BitMap::get_next_zero_offset(idx_t l_offset,
|
||||
return get_next_zero_offset_inline(l_offset, r_offset);
|
||||
}
|
||||
|
||||
inline bool BitMap2D::is_valid_index(idx_t slot_index, idx_t bit_within_slot_index) {
|
||||
verify_bit_within_slot_index(bit_within_slot_index);
|
||||
return (bit_index(slot_index, bit_within_slot_index) < size_in_bits());
|
||||
}
|
||||
|
||||
inline bool BitMap2D::at(idx_t slot_index, idx_t bit_within_slot_index) const {
|
||||
verify_bit_within_slot_index(bit_within_slot_index);
|
||||
return _map.at(bit_index(slot_index, bit_within_slot_index));
|
||||
}
|
||||
|
||||
inline void BitMap2D::set_bit(idx_t slot_index, idx_t bit_within_slot_index) {
|
||||
verify_bit_within_slot_index(bit_within_slot_index);
|
||||
_map.set_bit(bit_index(slot_index, bit_within_slot_index));
|
||||
}
|
||||
|
||||
inline void BitMap2D::clear_bit(idx_t slot_index, idx_t bit_within_slot_index) {
|
||||
verify_bit_within_slot_index(bit_within_slot_index);
|
||||
_map.clear_bit(bit_index(slot_index, bit_within_slot_index));
|
||||
}
|
||||
|
||||
inline void BitMap2D::at_put(idx_t slot_index, idx_t bit_within_slot_index, bool value) {
|
||||
verify_bit_within_slot_index(bit_within_slot_index);
|
||||
_map.at_put(bit_index(slot_index, bit_within_slot_index), value);
|
||||
}
|
||||
|
||||
inline void BitMap2D::at_put_grow(idx_t slot_index, idx_t bit_within_slot_index, bool value) {
|
||||
verify_bit_within_slot_index(bit_within_slot_index);
|
||||
_map.at_put_grow(bit_index(slot_index, bit_within_slot_index), value);
|
||||
}
|
||||
|
||||
inline void BitMap2D::clear() {
|
||||
_map.clear();
|
||||
}
|
||||
|
||||
@ -358,6 +358,20 @@ size_t lcm(size_t a, size_t b) {
|
||||
return size_t(result);
|
||||
}
|
||||
|
||||
|
||||
// Test that nth_bit macro and friends behave as
|
||||
// expected, even with low-precedence operators.
|
||||
|
||||
STATIC_ASSERT(nth_bit(3) == 0x8);
|
||||
STATIC_ASSERT(nth_bit(1|2) == 0x8);
|
||||
|
||||
STATIC_ASSERT(right_n_bits(3) == 0x7);
|
||||
STATIC_ASSERT(right_n_bits(1|2) == 0x7);
|
||||
|
||||
STATIC_ASSERT(left_n_bits(3) == (intptr_t) LP64_ONLY(0xE000000000000000) NOT_LP64(0xE0000000));
|
||||
STATIC_ASSERT(left_n_bits(1|2) == (intptr_t) LP64_ONLY(0xE000000000000000) NOT_LP64(0xE0000000));
|
||||
|
||||
|
||||
#ifndef PRODUCT
|
||||
// For unit testing only
|
||||
class GlobalDefinitions {
|
||||
|
||||
@ -1083,9 +1083,9 @@ const intptr_t OneBit = 1; // only right_most bit set in a word
|
||||
|
||||
// get a word with the n.th or the right-most or left-most n bits set
|
||||
// (note: #define used only so that they can be used in enum constant definitions)
|
||||
#define nth_bit(n) (n >= BitsPerWord ? 0 : OneBit << (n))
|
||||
#define nth_bit(n) (((n) >= BitsPerWord) ? 0 : (OneBit << (n)))
|
||||
#define right_n_bits(n) (nth_bit(n) - 1)
|
||||
#define left_n_bits(n) (right_n_bits(n) << (n >= BitsPerWord ? 0 : (BitsPerWord - n)))
|
||||
#define left_n_bits(n) (right_n_bits(n) << (((n) >= BitsPerWord) ? 0 : (BitsPerWord - (n))))
|
||||
|
||||
// bit-operations using a mask m
|
||||
inline void set_bits (intptr_t& x, intptr_t m) { x |= m; }
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user