| 1 | /* | 
|---|
| 2 | * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved. | 
|---|
| 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | 
|---|
| 4 | * | 
|---|
| 5 | * This code is free software; you can redistribute it and/or modify it | 
|---|
| 6 | * under the terms of the GNU General Public License version 2 only, as | 
|---|
| 7 | * published by the Free Software Foundation. | 
|---|
| 8 | * | 
|---|
| 9 | * This code is distributed in the hope that it will be useful, but WITHOUT | 
|---|
| 10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | 
|---|
| 11 | * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License | 
|---|
| 12 | * version 2 for more details (a copy is included in the LICENSE file that | 
|---|
| 13 | * accompanied this code). | 
|---|
| 14 | * | 
|---|
| 15 | * You should have received a copy of the GNU General Public License version | 
|---|
| 16 | * 2 along with this work; if not, write to the Free Software Foundation, | 
|---|
| 17 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | 
|---|
| 18 | * | 
|---|
| 19 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | 
|---|
| 20 | * or visit www.oracle.com if you need additional information or have any | 
|---|
| 21 | * questions. | 
|---|
| 22 | * | 
|---|
| 23 | */ | 
|---|
| 24 |  | 
|---|
| 25 | #include "precompiled.hpp" | 
|---|
| 26 | #include "gc/shared/oopStorage.inline.hpp" | 
|---|
| 27 | #include "gc/shared/oopStorageParState.inline.hpp" | 
|---|
| 28 | #include "logging/log.hpp" | 
|---|
| 29 | #include "logging/logStream.hpp" | 
|---|
| 30 | #include "memory/allocation.inline.hpp" | 
|---|
| 31 | #include "runtime/atomic.hpp" | 
|---|
| 32 | #include "runtime/globals.hpp" | 
|---|
| 33 | #include "runtime/handles.inline.hpp" | 
|---|
| 34 | #include "runtime/interfaceSupport.inline.hpp" | 
|---|
| 35 | #include "runtime/mutex.hpp" | 
|---|
| 36 | #include "runtime/mutexLocker.hpp" | 
|---|
| 37 | #include "runtime/orderAccess.hpp" | 
|---|
| 38 | #include "runtime/os.hpp" | 
|---|
| 39 | #include "runtime/safepoint.hpp" | 
|---|
| 40 | #include "runtime/stubRoutines.hpp" | 
|---|
| 41 | #include "runtime/thread.hpp" | 
|---|
| 42 | #include "utilities/align.hpp" | 
|---|
| 43 | #include "utilities/count_trailing_zeros.hpp" | 
|---|
| 44 | #include "utilities/debug.hpp" | 
|---|
| 45 | #include "utilities/globalDefinitions.hpp" | 
|---|
| 46 | #include "utilities/macros.hpp" | 
|---|
| 47 | #include "utilities/ostream.hpp" | 
|---|
| 48 |  | 
|---|
| 49 | OopStorage::AllocationListEntry::AllocationListEntry() : _prev(NULL), _next(NULL) {} | 
|---|
| 50 |  | 
|---|
| 51 | OopStorage::AllocationListEntry::~AllocationListEntry() { | 
|---|
| 52 | assert(_prev == NULL, "deleting attached block"); | 
|---|
| 53 | assert(_next == NULL, "deleting attached block"); | 
|---|
| 54 | } | 
|---|
| 55 |  | 
|---|
| 56 | OopStorage::AllocationList::AllocationList() : _head(NULL), _tail(NULL) {} | 
|---|
| 57 |  | 
|---|
| 58 | OopStorage::AllocationList::~AllocationList() { | 
|---|
| 59 | // ~OopStorage() empties its lists before destroying them. | 
|---|
| 60 | assert(_head == NULL, "deleting non-empty block list"); | 
|---|
| 61 | assert(_tail == NULL, "deleting non-empty block list"); | 
|---|
| 62 | } | 
|---|
| 63 |  | 
|---|
| 64 | void OopStorage::AllocationList::push_front(const Block& block) { | 
|---|
| 65 | const Block* old = _head; | 
|---|
| 66 | if (old == NULL) { | 
|---|
| 67 | assert(_tail == NULL, "invariant"); | 
|---|
| 68 | _head = _tail = █ | 
|---|
| 69 | } else { | 
|---|
| 70 | block.allocation_list_entry()._next = old; | 
|---|
| 71 | old->allocation_list_entry()._prev = █ | 
|---|
| 72 | _head = █ | 
|---|
| 73 | } | 
|---|
| 74 | } | 
|---|
| 75 |  | 
|---|
| 76 | void OopStorage::AllocationList::push_back(const Block& block) { | 
|---|
| 77 | const Block* old = _tail; | 
|---|
| 78 | if (old == NULL) { | 
|---|
| 79 | assert(_head == NULL, "invariant"); | 
|---|
| 80 | _head = _tail = █ | 
|---|
| 81 | } else { | 
|---|
| 82 | old->allocation_list_entry()._next = █ | 
|---|
| 83 | block.allocation_list_entry()._prev = old; | 
|---|
| 84 | _tail = █ | 
|---|
| 85 | } | 
|---|
| 86 | } | 
|---|
| 87 |  | 
|---|
| 88 | void OopStorage::AllocationList::unlink(const Block& block) { | 
|---|
| 89 | const AllocationListEntry& block_entry = block.allocation_list_entry(); | 
|---|
| 90 | const Block* prev_blk = block_entry._prev; | 
|---|
| 91 | const Block* next_blk = block_entry._next; | 
|---|
| 92 | block_entry._prev = NULL; | 
|---|
| 93 | block_entry._next = NULL; | 
|---|
| 94 | if ((prev_blk == NULL) && (next_blk == NULL)) { | 
|---|
| 95 | assert(_head == &block, "invariant"); | 
|---|
| 96 | assert(_tail == &block, "invariant"); | 
|---|
| 97 | _head = _tail = NULL; | 
|---|
| 98 | } else if (prev_blk == NULL) { | 
|---|
| 99 | assert(_head == &block, "invariant"); | 
|---|
| 100 | next_blk->allocation_list_entry()._prev = NULL; | 
|---|
| 101 | _head = next_blk; | 
|---|
| 102 | } else if (next_blk == NULL) { | 
|---|
| 103 | assert(_tail == &block, "invariant"); | 
|---|
| 104 | prev_blk->allocation_list_entry()._next = NULL; | 
|---|
| 105 | _tail = prev_blk; | 
|---|
| 106 | } else { | 
|---|
| 107 | next_blk->allocation_list_entry()._prev = prev_blk; | 
|---|
| 108 | prev_blk->allocation_list_entry()._next = next_blk; | 
|---|
| 109 | } | 
|---|
| 110 | } | 
|---|
| 111 |  | 
|---|
| 112 | OopStorage::ActiveArray::ActiveArray(size_t size) : | 
|---|
| 113 | _size(size), | 
|---|
| 114 | _block_count(0), | 
|---|
| 115 | _refcount(0) | 
|---|
| 116 | {} | 
|---|
| 117 |  | 
|---|
| 118 | OopStorage::ActiveArray::~ActiveArray() { | 
|---|
| 119 | assert(_refcount == 0, "precondition"); | 
|---|
| 120 | } | 
|---|
| 121 |  | 
|---|
| 122 | OopStorage::ActiveArray* OopStorage::ActiveArray::create(size_t size, AllocFailType alloc_fail) { | 
|---|
| 123 | size_t size_in_bytes = blocks_offset() + sizeof(Block*) * size; | 
|---|
| 124 | void* mem = NEW_C_HEAP_ARRAY3(char, size_in_bytes, mtGC, CURRENT_PC, alloc_fail); | 
|---|
| 125 | if (mem == NULL) return NULL; | 
|---|
| 126 | return new (mem) ActiveArray(size); | 
|---|
| 127 | } | 
|---|
| 128 |  | 
|---|
| 129 | void OopStorage::ActiveArray::destroy(ActiveArray* ba) { | 
|---|
| 130 | ba->~ActiveArray(); | 
|---|
| 131 | FREE_C_HEAP_ARRAY(char, ba); | 
|---|
| 132 | } | 
|---|
| 133 |  | 
|---|
| 134 | size_t OopStorage::ActiveArray::size() const { | 
|---|
| 135 | return _size; | 
|---|
| 136 | } | 
|---|
| 137 |  | 
|---|
| 138 | size_t OopStorage::ActiveArray::block_count() const { | 
|---|
| 139 | return _block_count; | 
|---|
| 140 | } | 
|---|
| 141 |  | 
|---|
| 142 | size_t OopStorage::ActiveArray::block_count_acquire() const { | 
|---|
| 143 | return OrderAccess::load_acquire(&_block_count); | 
|---|
| 144 | } | 
|---|
| 145 |  | 
|---|
| 146 | void OopStorage::ActiveArray::increment_refcount() const { | 
|---|
| 147 | int new_value = Atomic::add(1, &_refcount); | 
|---|
| 148 | assert(new_value >= 1, "negative refcount %d", new_value - 1); | 
|---|
| 149 | } | 
|---|
| 150 |  | 
|---|
| 151 | bool OopStorage::ActiveArray::decrement_refcount() const { | 
|---|
| 152 | int new_value = Atomic::sub(1, &_refcount); | 
|---|
| 153 | assert(new_value >= 0, "negative refcount %d", new_value); | 
|---|
| 154 | return new_value == 0; | 
|---|
| 155 | } | 
|---|
| 156 |  | 
|---|
| 157 | bool OopStorage::ActiveArray::push(Block* block) { | 
|---|
| 158 | size_t index = _block_count; | 
|---|
| 159 | if (index < _size) { | 
|---|
| 160 | block->set_active_index(index); | 
|---|
| 161 | *block_ptr(index) = block; | 
|---|
| 162 | // Use a release_store to ensure all the setup is complete before | 
|---|
| 163 | // making the block visible. | 
|---|
| 164 | OrderAccess::release_store(&_block_count, index + 1); | 
|---|
| 165 | return true; | 
|---|
| 166 | } else { | 
|---|
| 167 | return false; | 
|---|
| 168 | } | 
|---|
| 169 | } | 
|---|
| 170 |  | 
|---|
| 171 | void OopStorage::ActiveArray::remove(Block* block) { | 
|---|
| 172 | assert(_block_count > 0, "array is empty"); | 
|---|
| 173 | size_t index = block->active_index(); | 
|---|
| 174 | assert(*block_ptr(index) == block, "block not present"); | 
|---|
| 175 | size_t last_index = _block_count - 1; | 
|---|
| 176 | Block* last_block = *block_ptr(last_index); | 
|---|
| 177 | last_block->set_active_index(index); | 
|---|
| 178 | *block_ptr(index) = last_block; | 
|---|
| 179 | _block_count = last_index; | 
|---|
| 180 | } | 
|---|
| 181 |  | 
|---|
| 182 | void OopStorage::ActiveArray::copy_from(const ActiveArray* from) { | 
|---|
| 183 | assert(_block_count == 0, "array must be empty"); | 
|---|
| 184 | size_t count = from->_block_count; | 
|---|
| 185 | assert(count <= _size, "precondition"); | 
|---|
| 186 | Block* const* from_ptr = from->block_ptr(0); | 
|---|
| 187 | Block** to_ptr = block_ptr(0); | 
|---|
| 188 | for (size_t i = 0; i < count; ++i) { | 
|---|
| 189 | Block* block = *from_ptr++; | 
|---|
| 190 | assert(block->active_index() == i, "invariant"); | 
|---|
| 191 | *to_ptr++ = block; | 
|---|
| 192 | } | 
|---|
| 193 | _block_count = count; | 
|---|
| 194 | } | 
|---|
| 195 |  | 
|---|
| 196 | // Blocks start with an array of BitsPerWord oop entries.  That array | 
|---|
| 197 | // is divided into conceptual BytesPerWord sections of BitsPerByte | 
|---|
| 198 | // entries.  Blocks are allocated aligned on section boundaries, for | 
|---|
| 199 | // the convenience of mapping from an entry to the containing block; | 
|---|
| 200 | // see block_for_ptr().  Aligning on section boundary rather than on | 
|---|
| 201 | // the full _data wastes a lot less space, but makes for a bit more | 
|---|
| 202 | // work in block_for_ptr(). | 
|---|
| 203 |  | 
|---|
| 204 | const unsigned section_size = BitsPerByte; | 
|---|
| 205 | const unsigned section_count = BytesPerWord; | 
|---|
| 206 | const unsigned block_alignment = sizeof(oop) * section_size; | 
|---|
| 207 |  | 
|---|
| 208 | OopStorage::Block::Block(const OopStorage* owner, void* memory) : | 
|---|
| 209 | _data(), | 
|---|
| 210 | _allocated_bitmask(0), | 
|---|
| 211 | _owner(owner), | 
|---|
| 212 | _memory(memory), | 
|---|
| 213 | _active_index(0), | 
|---|
| 214 | _allocation_list_entry(), | 
|---|
| 215 | _deferred_updates_next(NULL), | 
|---|
| 216 | _release_refcount(0) | 
|---|
| 217 | { | 
|---|
| 218 | STATIC_ASSERT(_data_pos == 0); | 
|---|
| 219 | STATIC_ASSERT(section_size * section_count == ARRAY_SIZE(_data)); | 
|---|
| 220 | assert(offset_of(Block, _data) == _data_pos, "invariant"); | 
|---|
| 221 | assert(owner != NULL, "NULL owner"); | 
|---|
| 222 | assert(is_aligned(this, block_alignment), "misaligned block"); | 
|---|
| 223 | } | 
|---|
| 224 |  | 
|---|
| 225 | OopStorage::Block::~Block() { | 
|---|
| 226 | assert(_release_refcount == 0, "deleting block while releasing"); | 
|---|
| 227 | assert(_deferred_updates_next == NULL, "deleting block with deferred update"); | 
|---|
| 228 | // Clear fields used by block_for_ptr and entry validation, which | 
|---|
| 229 | // might help catch bugs.  Volatile to prevent dead-store elimination. | 
|---|
| 230 | const_cast<uintx volatile&>(_allocated_bitmask) = 0; | 
|---|
| 231 | const_cast<OopStorage* volatile&>(_owner) = NULL; | 
|---|
| 232 | } | 
|---|
| 233 |  | 
|---|
| 234 | size_t OopStorage::Block::allocation_size() { | 
|---|
| 235 | // _data must be first member, so aligning Block aligns _data. | 
|---|
| 236 | STATIC_ASSERT(_data_pos == 0); | 
|---|
| 237 | return sizeof(Block) + block_alignment - sizeof(void*); | 
|---|
| 238 | } | 
|---|
| 239 |  | 
|---|
| 240 | size_t OopStorage::Block::allocation_alignment_shift() { | 
|---|
| 241 | return exact_log2(block_alignment); | 
|---|
| 242 | } | 
|---|
| 243 |  | 
|---|
| 244 | inline bool is_full_bitmask(uintx bitmask) { return ~bitmask == 0; } | 
|---|
| 245 | inline bool is_empty_bitmask(uintx bitmask) { return bitmask == 0; } | 
|---|
| 246 |  | 
|---|
| 247 | bool OopStorage::Block::is_full() const { | 
|---|
| 248 | return is_full_bitmask(allocated_bitmask()); | 
|---|
| 249 | } | 
|---|
| 250 |  | 
|---|
| 251 | bool OopStorage::Block::is_empty() const { | 
|---|
| 252 | return is_empty_bitmask(allocated_bitmask()); | 
|---|
| 253 | } | 
|---|
| 254 |  | 
|---|
| 255 | uintx OopStorage::Block::bitmask_for_entry(const oop* ptr) const { | 
|---|
| 256 | return bitmask_for_index(get_index(ptr)); | 
|---|
| 257 | } | 
|---|
| 258 |  | 
|---|
| 259 | // An empty block is not yet deletable if either: | 
|---|
| 260 | // (1) There is a release() operation currently operating on it. | 
|---|
| 261 | // (2) It is in the deferred updates list. | 
|---|
| 262 | // For interaction with release(), these must follow the empty check, | 
|---|
| 263 | // and the order of these checks is important. | 
|---|
| 264 | bool OopStorage::Block::is_safe_to_delete() const { | 
|---|
| 265 | assert(is_empty(), "precondition"); | 
|---|
| 266 | OrderAccess::loadload(); | 
|---|
| 267 | return (OrderAccess::load_acquire(&_release_refcount) == 0) && | 
|---|
| 268 | (OrderAccess::load_acquire(&_deferred_updates_next) == NULL); | 
|---|
| 269 | } | 
|---|
| 270 |  | 
|---|
| 271 | OopStorage::Block* OopStorage::Block::deferred_updates_next() const { | 
|---|
| 272 | return _deferred_updates_next; | 
|---|
| 273 | } | 
|---|
| 274 |  | 
|---|
| 275 | void OopStorage::Block::set_deferred_updates_next(Block* block) { | 
|---|
| 276 | _deferred_updates_next = block; | 
|---|
| 277 | } | 
|---|
| 278 |  | 
|---|
| 279 | bool OopStorage::Block::contains(const oop* ptr) const { | 
|---|
| 280 | const oop* base = get_pointer(0); | 
|---|
| 281 | return (base <= ptr) && (ptr < (base + ARRAY_SIZE(_data))); | 
|---|
| 282 | } | 
|---|
| 283 |  | 
|---|
| 284 | size_t OopStorage::Block::active_index() const { | 
|---|
| 285 | return _active_index; | 
|---|
| 286 | } | 
|---|
| 287 |  | 
|---|
| 288 | void OopStorage::Block::set_active_index(size_t index) { | 
|---|
| 289 | _active_index = index; | 
|---|
| 290 | } | 
|---|
| 291 |  | 
|---|
| 292 | size_t OopStorage::Block::active_index_safe(const Block* block) { | 
|---|
| 293 | STATIC_ASSERT(sizeof(intptr_t) == sizeof(block->_active_index)); | 
|---|
| 294 | assert(CanUseSafeFetchN(), "precondition"); | 
|---|
| 295 | return SafeFetchN((intptr_t*)&block->_active_index, 0); | 
|---|
| 296 | } | 
|---|
| 297 |  | 
|---|
| 298 | unsigned OopStorage::Block::get_index(const oop* ptr) const { | 
|---|
| 299 | assert(contains(ptr), PTR_FORMAT " not in block "PTR_FORMAT, p2i(ptr), p2i(this)); | 
|---|
| 300 | return static_cast<unsigned>(ptr - get_pointer(0)); | 
|---|
| 301 | } | 
|---|
| 302 |  | 
|---|
| 303 | oop* OopStorage::Block::allocate() { | 
|---|
| 304 | // Use CAS loop because release may change bitmask outside of lock. | 
|---|
| 305 | uintx allocated = allocated_bitmask(); | 
|---|
| 306 | while (true) { | 
|---|
| 307 | assert(!is_full_bitmask(allocated), "attempt to allocate from full block"); | 
|---|
| 308 | unsigned index = count_trailing_zeros(~allocated); | 
|---|
| 309 | uintx new_value = allocated | bitmask_for_index(index); | 
|---|
| 310 | uintx fetched = Atomic::cmpxchg(new_value, &_allocated_bitmask, allocated); | 
|---|
| 311 | if (fetched == allocated) { | 
|---|
| 312 | return get_pointer(index); // CAS succeeded; return entry for index. | 
|---|
| 313 | } | 
|---|
| 314 | allocated = fetched;       // CAS failed; retry with latest value. | 
|---|
| 315 | } | 
|---|
| 316 | } | 
|---|
| 317 |  | 
|---|
| 318 | OopStorage::Block* OopStorage::Block::new_block(const OopStorage* owner) { | 
|---|
| 319 | // _data must be first member: aligning block => aligning _data. | 
|---|
| 320 | STATIC_ASSERT(_data_pos == 0); | 
|---|
| 321 | size_t size_needed = allocation_size(); | 
|---|
| 322 | void* memory = NEW_C_HEAP_ARRAY_RETURN_NULL(char, size_needed, mtGC); | 
|---|
| 323 | if (memory == NULL) { | 
|---|
| 324 | return NULL; | 
|---|
| 325 | } | 
|---|
| 326 | void* block_mem = align_up(memory, block_alignment); | 
|---|
| 327 | assert(sizeof(Block) + pointer_delta(block_mem, memory, 1) <= size_needed, | 
|---|
| 328 | "allocated insufficient space for aligned block"); | 
|---|
| 329 | return ::new (block_mem) Block(owner, memory); | 
|---|
| 330 | } | 
|---|
| 331 |  | 
|---|
| 332 | void OopStorage::Block::delete_block(const Block& block) { | 
|---|
| 333 | void* memory = block._memory; | 
|---|
| 334 | block.Block::~Block(); | 
|---|
| 335 | FREE_C_HEAP_ARRAY(char, memory); | 
|---|
| 336 | } | 
|---|
| 337 |  | 
|---|
| 338 | // This can return a false positive if ptr is not contained by some | 
|---|
| 339 | // block.  For some uses, it is a precondition that ptr is valid, | 
|---|
| 340 | // e.g. contained in some block in owner's _active_array.  Other uses | 
|---|
| 341 | // require additional validation of the result. | 
|---|
| 342 | OopStorage::Block* | 
|---|
| 343 | OopStorage::Block::block_for_ptr(const OopStorage* owner, const oop* ptr) { | 
|---|
| 344 | assert(CanUseSafeFetchN(), "precondition"); | 
|---|
| 345 | STATIC_ASSERT(_data_pos == 0); | 
|---|
| 346 | // Const-ness of ptr is not related to const-ness of containing block. | 
|---|
| 347 | // Blocks are allocated section-aligned, so get the containing section. | 
|---|
| 348 | oop* section_start = align_down(const_cast<oop*>(ptr), block_alignment); | 
|---|
| 349 | // Start with a guess that the containing section is the last section, | 
|---|
| 350 | // so the block starts section_count-1 sections earlier. | 
|---|
| 351 | oop* section = section_start - (section_size * (section_count - 1)); | 
|---|
| 352 | // Walk up through the potential block start positions, looking for | 
|---|
| 353 | // the owner in the expected location.  If we're below the actual block | 
|---|
| 354 | // start position, the value at the owner position will be some oop | 
|---|
| 355 | // (possibly NULL), which can never match the owner. | 
|---|
| 356 | intptr_t owner_addr = reinterpret_cast<intptr_t>(owner); | 
|---|
| 357 | for (unsigned i = 0; i < section_count; ++i, section += section_size) { | 
|---|
| 358 | Block* candidate = reinterpret_cast<Block*>(section); | 
|---|
| 359 | intptr_t* candidate_owner_addr | 
|---|
| 360 | = reinterpret_cast<intptr_t*>(&candidate->_owner); | 
|---|
| 361 | if (SafeFetchN(candidate_owner_addr, 0) == owner_addr) { | 
|---|
| 362 | return candidate; | 
|---|
| 363 | } | 
|---|
| 364 | } | 
|---|
| 365 | return NULL; | 
|---|
| 366 | } | 
|---|
| 367 |  | 
|---|
| 368 | ////////////////////////////////////////////////////////////////////////////// | 
|---|
| 369 | // Allocation | 
|---|
| 370 | // | 
|---|
| 371 | // Allocation involves the _allocation_list, which contains a subset of the | 
|---|
| 372 | // blocks owned by a storage object.  This is a doubly-linked list, linked | 
|---|
| 373 | // through dedicated fields in the blocks.  Full blocks are removed from this | 
|---|
| 374 | // list, though they are still present in the _active_array.  Empty blocks are | 
|---|
| 375 | // kept at the end of the _allocation_list, to make it easy for empty block | 
|---|
| 376 | // deletion to find them. | 
|---|
| 377 | // | 
|---|
| 378 | // allocate(), and delete_empty_blocks() lock the | 
|---|
| 379 | // _allocation_mutex while performing any list and array modifications. | 
|---|
| 380 | // | 
|---|
| 381 | // allocate() and release() update a block's _allocated_bitmask using CAS | 
|---|
| 382 | // loops.  This prevents loss of updates even though release() performs | 
|---|
| 383 | // its updates without any locking. | 
|---|
| 384 | // | 
|---|
| 385 | // allocate() obtains the entry from the first block in the _allocation_list, | 
|---|
| 386 | // and updates that block's _allocated_bitmask to indicate the entry is in | 
|---|
| 387 | // use.  If this makes the block full (all entries in use), the block is | 
|---|
| 388 | // removed from the _allocation_list so it won't be considered by future | 
|---|
| 389 | // allocations until some entries in it are released. | 
|---|
| 390 | // | 
|---|
| 391 | // release() is performed lock-free. (Note: This means it can't notify the | 
|---|
| 392 | // service thread of pending cleanup work.  It must be lock-free because | 
|---|
| 393 | // it is called in all kinds of contexts where even quite low ranked locks | 
|---|
| 394 | // may be held.)  release() first looks up the block for | 
|---|
| 395 | // the entry, using address alignment to find the enclosing block (thereby | 
|---|
| 396 | // avoiding iteration over the _active_array).  Once the block has been | 
|---|
| 397 | // determined, its _allocated_bitmask needs to be updated, and its position in | 
|---|
| 398 | // the _allocation_list may need to be updated.  There are two cases: | 
|---|
| 399 | // | 
|---|
| 400 | // (a) If the block is neither full nor would become empty with the release of | 
|---|
| 401 | // the entry, only its _allocated_bitmask needs to be updated.  But if the CAS | 
|---|
| 402 | // update fails, the applicable case may change for the retry. | 
|---|
| 403 | // | 
|---|
| 404 | // (b) Otherwise, the _allocation_list also needs to be modified.  This requires | 
|---|
| 405 | // locking the _allocation_mutex.  To keep the release() operation lock-free, | 
|---|
| 406 | // rather than updating the _allocation_list itself, it instead performs a | 
|---|
| 407 | // lock-free push of the block onto the _deferred_updates list.  Entries on | 
|---|
| 408 | // that list are processed by allocate() and delete_empty_blocks(), while | 
|---|
| 409 | // they already hold the necessary lock.  That processing makes the block's | 
|---|
| 410 | // list state consistent with its current _allocated_bitmask.  The block is | 
|---|
| 411 | // added to the _allocation_list if not already present and the bitmask is not | 
|---|
| 412 | // full.  The block is moved to the end of the _allocation_list if the bitmask | 
|---|
| 413 | // is empty, for ease of empty block deletion processing. | 
|---|
| 414 |  | 
|---|
| 415 | oop* OopStorage::allocate() { | 
|---|
| 416 | MutexLocker ml(_allocation_mutex, Mutex::_no_safepoint_check_flag); | 
|---|
| 417 |  | 
|---|
| 418 | Block* block = block_for_allocation(); | 
|---|
| 419 | if (block == NULL) return NULL; // Block allocation failed. | 
|---|
| 420 | assert(!block->is_full(), "invariant"); | 
|---|
| 421 | if (block->is_empty()) { | 
|---|
| 422 | // Transitioning from empty to not empty. | 
|---|
| 423 | log_debug(oopstorage, blocks)( "%s: block not empty "PTR_FORMAT, name(), p2i(block)); | 
|---|
| 424 | } | 
|---|
| 425 | oop* result = block->allocate(); | 
|---|
| 426 | assert(result != NULL, "allocation failed"); | 
|---|
| 427 | assert(!block->is_empty(), "postcondition"); | 
|---|
| 428 | Atomic::inc(&_allocation_count); // release updates outside lock. | 
|---|
| 429 | if (block->is_full()) { | 
|---|
| 430 | // Transitioning from not full to full. | 
|---|
| 431 | // Remove full blocks from consideration by future allocates. | 
|---|
| 432 | log_debug(oopstorage, blocks)( "%s: block full "PTR_FORMAT, name(), p2i(block)); | 
|---|
| 433 | _allocation_list.unlink(*block); | 
|---|
| 434 | } | 
|---|
| 435 | log_trace(oopstorage, ref)( "%s: allocated "PTR_FORMAT, name(), p2i(result)); | 
|---|
| 436 | return result; | 
|---|
| 437 | } | 
|---|
| 438 |  | 
|---|
| 439 | bool OopStorage::try_add_block() { | 
|---|
| 440 | assert_lock_strong(_allocation_mutex); | 
|---|
| 441 | Block* block; | 
|---|
| 442 | { | 
|---|
| 443 | MutexUnlocker ul(_allocation_mutex, Mutex::_no_safepoint_check_flag); | 
|---|
| 444 | block = Block::new_block(this); | 
|---|
| 445 | } | 
|---|
| 446 | if (block == NULL) return false; | 
|---|
| 447 |  | 
|---|
| 448 | // Add new block to the _active_array, growing if needed. | 
|---|
| 449 | if (!_active_array->push(block)) { | 
|---|
| 450 | if (expand_active_array()) { | 
|---|
| 451 | guarantee(_active_array->push(block), "push failed after expansion"); | 
|---|
| 452 | } else { | 
|---|
| 453 | log_debug(oopstorage, blocks)( "%s: failed active array expand", name()); | 
|---|
| 454 | Block::delete_block(*block); | 
|---|
| 455 | return false; | 
|---|
| 456 | } | 
|---|
| 457 | } | 
|---|
| 458 | // Add to end of _allocation_list.  The mutex release allowed other | 
|---|
| 459 | // threads to add blocks to the _allocation_list.  We prefer to | 
|---|
| 460 | // allocate from non-empty blocks, to allow empty blocks to be | 
|---|
| 461 | // deleted.  But we don't bother notifying about the empty block | 
|---|
| 462 | // because we're (probably) about to allocate an entry from it. | 
|---|
| 463 | _allocation_list.push_back(*block); | 
|---|
| 464 | log_debug(oopstorage, blocks)( "%s: new block "PTR_FORMAT, name(), p2i(block)); | 
|---|
| 465 | return true; | 
|---|
| 466 | } | 
|---|
| 467 |  | 
|---|
| 468 | OopStorage::Block* OopStorage::block_for_allocation() { | 
|---|
| 469 | assert_lock_strong(_allocation_mutex); | 
|---|
| 470 | while (true) { | 
|---|
| 471 | // Use the first block in _allocation_list for the allocation. | 
|---|
| 472 | Block* block = _allocation_list.head(); | 
|---|
| 473 | if (block != NULL) { | 
|---|
| 474 | return block; | 
|---|
| 475 | } else if (reduce_deferred_updates()) { | 
|---|
| 476 | // Might have added a block to the _allocation_list, so retry. | 
|---|
| 477 | } else if (try_add_block()) { | 
|---|
| 478 | // Successfully added a new block to the list, so retry. | 
|---|
| 479 | assert(_allocation_list.chead() != NULL, "invariant"); | 
|---|
| 480 | } else if (_allocation_list.chead() != NULL) { | 
|---|
| 481 | // Trying to add a block failed, but some other thread added to the | 
|---|
| 482 | // list while we'd dropped the lock over the new block allocation. | 
|---|
| 483 | } else if (!reduce_deferred_updates()) { // Once more before failure. | 
|---|
| 484 | // Attempt to add a block failed, no other thread added a block, | 
|---|
| 485 | // and no deferred updated added a block, then allocation failed. | 
|---|
| 486 | log_debug(oopstorage, blocks)( "%s: failed block allocation", name()); | 
|---|
| 487 | return NULL; | 
|---|
| 488 | } | 
|---|
| 489 | } | 
|---|
| 490 | } | 
|---|
| 491 |  | 
|---|
| 492 | // Create a new, larger, active array with the same content as the | 
|---|
| 493 | // current array, and then replace, relinquishing the old array. | 
|---|
| 494 | // Return true if the array was successfully expanded, false to | 
|---|
| 495 | // indicate allocation failure. | 
|---|
| 496 | bool OopStorage::expand_active_array() { | 
|---|
| 497 | assert_lock_strong(_allocation_mutex); | 
|---|
| 498 | ActiveArray* old_array = _active_array; | 
|---|
| 499 | size_t new_size = 2 * old_array->size(); | 
|---|
| 500 | log_debug(oopstorage, blocks)( "%s: expand active array "SIZE_FORMAT, | 
|---|
| 501 | name(), new_size); | 
|---|
| 502 | ActiveArray* new_array = ActiveArray::create(new_size, AllocFailStrategy::RETURN_NULL); | 
|---|
| 503 | if (new_array == NULL) return false; | 
|---|
| 504 | new_array->copy_from(old_array); | 
|---|
| 505 | replace_active_array(new_array); | 
|---|
| 506 | relinquish_block_array(old_array); | 
|---|
| 507 | return true; | 
|---|
| 508 | } | 
|---|
| 509 |  | 
|---|
| 510 | // Make new_array the _active_array.  Increments new_array's refcount | 
|---|
| 511 | // to account for the new reference.  The assignment is atomic wrto | 
|---|
| 512 | // obtain_active_array; once this function returns, it is safe for the | 
|---|
| 513 | // caller to relinquish the old array. | 
|---|
| 514 | void OopStorage::replace_active_array(ActiveArray* new_array) { | 
|---|
| 515 | // Caller has the old array that is the current value of _active_array. | 
|---|
| 516 | // Update new_array refcount to account for the new reference. | 
|---|
| 517 | new_array->increment_refcount(); | 
|---|
| 518 | // Install new_array, ensuring its initialization is complete first. | 
|---|
| 519 | OrderAccess::release_store(&_active_array, new_array); | 
|---|
| 520 | // Wait for any readers that could read the old array from _active_array. | 
|---|
| 521 | // Can't use GlobalCounter here, because this is called from allocate(), | 
|---|
| 522 | // which may be called in the scope of a GlobalCounter critical section | 
|---|
| 523 | // when inserting a StringTable entry. | 
|---|
| 524 | _protect_active.synchronize(); | 
|---|
| 525 | // All obtain critical sections that could see the old array have | 
|---|
| 526 | // completed, having incremented the refcount of the old array.  The | 
|---|
| 527 | // caller can now safely relinquish the old array. | 
|---|
| 528 | } | 
|---|
| 529 |  | 
|---|
| 530 | // Atomically (wrto replace_active_array) get the active array and | 
|---|
| 531 | // increment its refcount.  This provides safe access to the array, | 
|---|
| 532 | // even if an allocate operation expands and replaces the value of | 
|---|
| 533 | // _active_array.  The caller must relinquish the array when done | 
|---|
| 534 | // using it. | 
|---|
| 535 | OopStorage::ActiveArray* OopStorage::obtain_active_array() const { | 
|---|
| 536 | SingleWriterSynchronizer::CriticalSection cs(&_protect_active); | 
|---|
| 537 | ActiveArray* result = OrderAccess::load_acquire(&_active_array); | 
|---|
| 538 | result->increment_refcount(); | 
|---|
| 539 | return result; | 
|---|
| 540 | } | 
|---|
| 541 |  | 
|---|
| 542 | // Decrement refcount of array and destroy if refcount is zero. | 
|---|
| 543 | void OopStorage::relinquish_block_array(ActiveArray* array) const { | 
|---|
| 544 | if (array->decrement_refcount()) { | 
|---|
| 545 | assert(array != _active_array, "invariant"); | 
|---|
| 546 | ActiveArray::destroy(array); | 
|---|
| 547 | } | 
|---|
| 548 | } | 
|---|
| 549 |  | 
|---|
| 550 | class OopStorage::WithActiveArray : public StackObj { | 
|---|
| 551 | const OopStorage* _storage; | 
|---|
| 552 | ActiveArray* _active_array; | 
|---|
| 553 |  | 
|---|
| 554 | public: | 
|---|
| 555 | WithActiveArray(const OopStorage* storage) : | 
|---|
| 556 | _storage(storage), | 
|---|
| 557 | _active_array(storage->obtain_active_array()) | 
|---|
| 558 | {} | 
|---|
| 559 |  | 
|---|
| 560 | ~WithActiveArray() { | 
|---|
| 561 | _storage->relinquish_block_array(_active_array); | 
|---|
| 562 | } | 
|---|
| 563 |  | 
|---|
| 564 | ActiveArray& active_array() const { | 
|---|
| 565 | return *_active_array; | 
|---|
| 566 | } | 
|---|
| 567 | }; | 
|---|
| 568 |  | 
|---|
| 569 | OopStorage::Block* OopStorage::find_block_or_null(const oop* ptr) const { | 
|---|
| 570 | assert(ptr != NULL, "precondition"); | 
|---|
| 571 | return Block::block_for_ptr(this, ptr); | 
|---|
| 572 | } | 
|---|
| 573 |  | 
|---|
| 574 | static void log_release_transitions(uintx releasing, | 
|---|
| 575 | uintx old_allocated, | 
|---|
| 576 | const OopStorage* owner, | 
|---|
| 577 | const void* block) { | 
|---|
| 578 | Log(oopstorage, blocks) log; | 
|---|
| 579 | LogStream ls(log.debug()); | 
|---|
| 580 | if (is_full_bitmask(old_allocated)) { | 
|---|
| 581 | ls.print_cr( "%s: block not full "PTR_FORMAT, owner->name(), p2i(block)); | 
|---|
| 582 | } | 
|---|
| 583 | if (releasing == old_allocated) { | 
|---|
| 584 | ls.print_cr( "%s: block empty "PTR_FORMAT, owner->name(), p2i(block)); | 
|---|
| 585 | } | 
|---|
| 586 | } | 
|---|
| 587 |  | 
|---|
| 588 | void OopStorage::Block::release_entries(uintx releasing, OopStorage* owner) { | 
|---|
| 589 | assert(releasing != 0, "preconditon"); | 
|---|
| 590 | // Prevent empty block deletion when transitioning to empty. | 
|---|
| 591 | Atomic::inc(&_release_refcount); | 
|---|
| 592 |  | 
|---|
| 593 | // Atomically update allocated bitmask. | 
|---|
| 594 | uintx old_allocated = _allocated_bitmask; | 
|---|
| 595 | while (true) { | 
|---|
| 596 | assert((releasing & ~old_allocated) == 0, "releasing unallocated entries"); | 
|---|
| 597 | uintx new_value = old_allocated ^ releasing; | 
|---|
| 598 | uintx fetched = Atomic::cmpxchg(new_value, &_allocated_bitmask, old_allocated); | 
|---|
| 599 | if (fetched == old_allocated) break; // Successful update. | 
|---|
| 600 | old_allocated = fetched;             // Retry with updated bitmask. | 
|---|
| 601 | } | 
|---|
| 602 |  | 
|---|
| 603 | // Now that the bitmask has been updated, if we have a state transition | 
|---|
| 604 | // (updated bitmask is empty or old bitmask was full), atomically push | 
|---|
| 605 | // this block onto the deferred updates list.  Some future call to | 
|---|
| 606 | // reduce_deferred_updates will make any needed changes related to this | 
|---|
| 607 | // block and _allocation_list.  This deferral avoids _allocation_list | 
|---|
| 608 | // updates and the associated locking here. | 
|---|
| 609 | if ((releasing == old_allocated) || is_full_bitmask(old_allocated)) { | 
|---|
| 610 | // Log transitions.  Both transitions are possible in a single update. | 
|---|
| 611 | if (log_is_enabled(Debug, oopstorage, blocks)) { | 
|---|
| 612 | log_release_transitions(releasing, old_allocated, _owner, this); | 
|---|
| 613 | } | 
|---|
| 614 | // Attempt to claim responsibility for adding this block to the deferred | 
|---|
| 615 | // list, by setting the link to non-NULL by self-looping.  If this fails, | 
|---|
| 616 | // then someone else has made such a claim and the deferred update has not | 
|---|
| 617 | // yet been processed and will include our change, so we don't need to do | 
|---|
| 618 | // anything further. | 
|---|
| 619 | if (Atomic::replace_if_null(this, &_deferred_updates_next)) { | 
|---|
| 620 | // Successfully claimed.  Push, with self-loop for end-of-list. | 
|---|
| 621 | Block* head = owner->_deferred_updates; | 
|---|
| 622 | while (true) { | 
|---|
| 623 | _deferred_updates_next = (head == NULL) ? this : head; | 
|---|
| 624 | Block* fetched = Atomic::cmpxchg(this, &owner->_deferred_updates, head); | 
|---|
| 625 | if (fetched == head) break; // Successful update. | 
|---|
| 626 | head = fetched;             // Retry with updated head. | 
|---|
| 627 | } | 
|---|
| 628 | // Only request cleanup for to-empty transitions, not for from-full. | 
|---|
| 629 | // There isn't any rush to process from-full transitions.  Allocation | 
|---|
| 630 | // will reduce deferrals before allocating new blocks, so may process | 
|---|
| 631 | // some.  And the service thread will drain the entire deferred list | 
|---|
| 632 | // if there are any pending to-empty transitions. | 
|---|
| 633 | if (releasing == old_allocated) { | 
|---|
| 634 | owner->record_needs_cleanup(); | 
|---|
| 635 | } | 
|---|
| 636 | log_debug(oopstorage, blocks)( "%s: deferred update "PTR_FORMAT, | 
|---|
| 637 | _owner->name(), p2i(this)); | 
|---|
| 638 | } | 
|---|
| 639 | } | 
|---|
| 640 | // Release hold on empty block deletion. | 
|---|
| 641 | Atomic::dec(&_release_refcount); | 
|---|
| 642 | } | 
|---|
| 643 |  | 
|---|
| 644 | // Process one available deferred update.  Returns true if one was processed. | 
|---|
| 645 | bool OopStorage::reduce_deferred_updates() { | 
|---|
| 646 | assert_lock_strong(_allocation_mutex); | 
|---|
| 647 | // Atomically pop a block off the list, if any available. | 
|---|
| 648 | // No ABA issue because this is only called by one thread at a time. | 
|---|
| 649 | // The atomicity is wrto pushes by release(). | 
|---|
| 650 | Block* block = OrderAccess::load_acquire(&_deferred_updates); | 
|---|
| 651 | while (true) { | 
|---|
| 652 | if (block == NULL) return false; | 
|---|
| 653 | // Try atomic pop of block from list. | 
|---|
| 654 | Block* tail = block->deferred_updates_next(); | 
|---|
| 655 | if (block == tail) tail = NULL; // Handle self-loop end marker. | 
|---|
| 656 | Block* fetched = Atomic::cmpxchg(tail, &_deferred_updates, block); | 
|---|
| 657 | if (fetched == block) break; // Update successful. | 
|---|
| 658 | block = fetched;             // Retry with updated block. | 
|---|
| 659 | } | 
|---|
| 660 | block->set_deferred_updates_next(NULL); // Clear tail after updating head. | 
|---|
| 661 | // Ensure bitmask read after pop is complete, including clearing tail, for | 
|---|
| 662 | // ordering with release().  Without this, we may be processing a stale | 
|---|
| 663 | // bitmask state here while blocking a release() operation from recording | 
|---|
| 664 | // the deferred update needed for its bitmask change. | 
|---|
| 665 | OrderAccess::fence(); | 
|---|
| 666 | // Process popped block. | 
|---|
| 667 | uintx allocated = block->allocated_bitmask(); | 
|---|
| 668 |  | 
|---|
| 669 | // Make membership in list consistent with bitmask state. | 
|---|
| 670 | if ((_allocation_list.ctail() != NULL) && | 
|---|
| 671 | ((_allocation_list.ctail() == block) || | 
|---|
| 672 | (_allocation_list.next(*block) != NULL))) { | 
|---|
| 673 | // Block is in the _allocation_list. | 
|---|
| 674 | assert(!is_full_bitmask(allocated), "invariant"); | 
|---|
| 675 | } else if (!is_full_bitmask(allocated)) { | 
|---|
| 676 | // Block is not in the _allocation_list, but now should be. | 
|---|
| 677 | _allocation_list.push_front(*block); | 
|---|
| 678 | } // Else block is full and not in list, which is correct. | 
|---|
| 679 |  | 
|---|
| 680 | // Move empty block to end of list, for possible deletion. | 
|---|
| 681 | if (is_empty_bitmask(allocated)) { | 
|---|
| 682 | _allocation_list.unlink(*block); | 
|---|
| 683 | _allocation_list.push_back(*block); | 
|---|
| 684 | } | 
|---|
| 685 |  | 
|---|
| 686 | log_debug(oopstorage, blocks)( "%s: processed deferred update "PTR_FORMAT, | 
|---|
| 687 | name(), p2i(block)); | 
|---|
| 688 | return true;              // Processed one pending update. | 
|---|
| 689 | } | 
|---|
| 690 |  | 
|---|
| 691 | inline void check_release_entry(const oop* entry) { | 
|---|
| 692 | assert(entry != NULL, "Releasing NULL"); | 
|---|
| 693 | assert(*entry == NULL, "Releasing uncleared entry: "PTR_FORMAT, p2i(entry)); | 
|---|
| 694 | } | 
|---|
| 695 |  | 
|---|
| 696 | void OopStorage::release(const oop* ptr) { | 
|---|
| 697 | check_release_entry(ptr); | 
|---|
| 698 | Block* block = find_block_or_null(ptr); | 
|---|
| 699 | assert(block != NULL, "%s: invalid release "PTR_FORMAT, name(), p2i(ptr)); | 
|---|
| 700 | log_trace(oopstorage, ref)( "%s: released "PTR_FORMAT, name(), p2i(ptr)); | 
|---|
| 701 | block->release_entries(block->bitmask_for_entry(ptr), this); | 
|---|
| 702 | Atomic::dec(&_allocation_count); | 
|---|
| 703 | } | 
|---|
| 704 |  | 
|---|
| 705 | void OopStorage::release(const oop* const* ptrs, size_t size) { | 
|---|
| 706 | size_t i = 0; | 
|---|
| 707 | while (i < size) { | 
|---|
| 708 | check_release_entry(ptrs[i]); | 
|---|
| 709 | Block* block = find_block_or_null(ptrs[i]); | 
|---|
| 710 | assert(block != NULL, "%s: invalid release "PTR_FORMAT, name(), p2i(ptrs[i])); | 
|---|
| 711 | log_trace(oopstorage, ref)( "%s: released "PTR_FORMAT, name(), p2i(ptrs[i])); | 
|---|
| 712 | size_t count = 0; | 
|---|
| 713 | uintx releasing = 0; | 
|---|
| 714 | for ( ; i < size; ++i) { | 
|---|
| 715 | const oop* entry = ptrs[i]; | 
|---|
| 716 | check_release_entry(entry); | 
|---|
| 717 | // If entry not in block, finish block and resume outer loop with entry. | 
|---|
| 718 | if (!block->contains(entry)) break; | 
|---|
| 719 | // Add entry to releasing bitmap. | 
|---|
| 720 | log_trace(oopstorage, ref)( "%s: released "PTR_FORMAT, name(), p2i(entry)); | 
|---|
| 721 | uintx entry_bitmask = block->bitmask_for_entry(entry); | 
|---|
| 722 | assert((releasing & entry_bitmask) == 0, | 
|---|
| 723 | "Duplicate entry: "PTR_FORMAT, p2i(entry)); | 
|---|
| 724 | releasing |= entry_bitmask; | 
|---|
| 725 | ++count; | 
|---|
| 726 | } | 
|---|
| 727 | // Release the contiguous entries that are in block. | 
|---|
| 728 | block->release_entries(releasing, this); | 
|---|
| 729 | Atomic::sub(count, &_allocation_count); | 
|---|
| 730 | } | 
|---|
| 731 | } | 
|---|
| 732 |  | 
|---|
| 733 | const char* dup_name(const char* name) { | 
|---|
| 734 | char* dup = NEW_C_HEAP_ARRAY(char, strlen(name) + 1, mtGC); | 
|---|
| 735 | strcpy(dup, name); | 
|---|
| 736 | return dup; | 
|---|
| 737 | } | 
|---|
| 738 |  | 
|---|
| 739 | const size_t initial_active_array_size = 8; | 
|---|
| 740 |  | 
|---|
| 741 | OopStorage::OopStorage(const char* name, | 
|---|
| 742 | Mutex* allocation_mutex, | 
|---|
| 743 | Mutex* active_mutex) : | 
|---|
| 744 | _name(dup_name(name)), | 
|---|
| 745 | _active_array(ActiveArray::create(initial_active_array_size)), | 
|---|
| 746 | _allocation_list(), | 
|---|
| 747 | _deferred_updates(NULL), | 
|---|
| 748 | _allocation_mutex(allocation_mutex), | 
|---|
| 749 | _active_mutex(active_mutex), | 
|---|
| 750 | _allocation_count(0), | 
|---|
| 751 | _concurrent_iteration_count(0), | 
|---|
| 752 | _needs_cleanup(false) | 
|---|
| 753 | { | 
|---|
| 754 | _active_array->increment_refcount(); | 
|---|
| 755 | assert(_active_mutex->rank() < _allocation_mutex->rank(), | 
|---|
| 756 | "%s: active_mutex must have lower rank than allocation_mutex", _name); | 
|---|
| 757 | assert(Service_lock->rank() < _active_mutex->rank(), | 
|---|
| 758 | "%s: active_mutex must have higher rank than Service_lock", _name); | 
|---|
| 759 | assert(_active_mutex->_safepoint_check_required == Mutex::_safepoint_check_never, | 
|---|
| 760 | "%s: active mutex requires never safepoint check", _name); | 
|---|
| 761 | assert(_allocation_mutex->_safepoint_check_required == Mutex::_safepoint_check_never, | 
|---|
| 762 | "%s: allocation mutex requires never safepoint check", _name); | 
|---|
| 763 | } | 
|---|
| 764 |  | 
|---|
| 765 | void OopStorage::delete_empty_block(const Block& block) { | 
|---|
| 766 | assert(block.is_empty(), "discarding non-empty block"); | 
|---|
| 767 | log_debug(oopstorage, blocks)( "%s: delete empty block "PTR_FORMAT, name(), p2i(&block)); | 
|---|
| 768 | Block::delete_block(block); | 
|---|
| 769 | } | 
|---|
| 770 |  | 
|---|
| 771 | OopStorage::~OopStorage() { | 
|---|
| 772 | Block* block; | 
|---|
| 773 | while ((block = _deferred_updates) != NULL) { | 
|---|
| 774 | _deferred_updates = block->deferred_updates_next(); | 
|---|
| 775 | block->set_deferred_updates_next(NULL); | 
|---|
| 776 | } | 
|---|
| 777 | while ((block = _allocation_list.head()) != NULL) { | 
|---|
| 778 | _allocation_list.unlink(*block); | 
|---|
| 779 | } | 
|---|
| 780 | bool unreferenced = _active_array->decrement_refcount(); | 
|---|
| 781 | assert(unreferenced, "deleting storage while _active_array is referenced"); | 
|---|
| 782 | for (size_t i = _active_array->block_count(); 0 < i; ) { | 
|---|
| 783 | block = _active_array->at(--i); | 
|---|
| 784 | Block::delete_block(*block); | 
|---|
| 785 | } | 
|---|
| 786 | ActiveArray::destroy(_active_array); | 
|---|
| 787 | FREE_C_HEAP_ARRAY(char, _name); | 
|---|
| 788 | } | 
|---|
| 789 |  | 
|---|
| 790 | // Managing service thread notifications. | 
|---|
| 791 | // | 
|---|
| 792 | // We don't want cleanup work to linger indefinitely, but we also don't want | 
|---|
| 793 | // to run the service thread too often.  We're also very limited in what we | 
|---|
| 794 | // can do in a release operation, where cleanup work is created. | 
|---|
| 795 | // | 
|---|
| 796 | // When a release operation changes a block's state to empty, it records the | 
|---|
| 797 | // need for cleanup in both the associated storage object and in the global | 
|---|
| 798 | // request state.  A safepoint cleanup task notifies the service thread when | 
|---|
| 799 | // there may be cleanup work for any storage object, based on the global | 
|---|
| 800 | // request state.  But that notification is deferred if the service thread | 
|---|
| 801 | // has run recently, and we also avoid duplicate notifications.  The service | 
|---|
| 802 | // thread updates the timestamp and resets the state flags on every iteration. | 
|---|
| 803 |  | 
|---|
| 804 | // Global cleanup request state. | 
|---|
| 805 | static volatile bool needs_cleanup_requested = false; | 
|---|
| 806 |  | 
|---|
| 807 | // Flag for avoiding duplicate notifications. | 
|---|
| 808 | static bool needs_cleanup_triggered = false; | 
|---|
| 809 |  | 
|---|
| 810 | // Time after which a notification can be made. | 
|---|
| 811 | static jlong cleanup_trigger_permit_time = 0; | 
|---|
| 812 |  | 
|---|
| 813 | // Minimum time since last service thread check before notification is | 
|---|
| 814 | // permitted.  The value of 500ms was an arbitrary choice; frequent, but not | 
|---|
| 815 | // too frequent. | 
|---|
| 816 | const jlong cleanup_trigger_defer_period = 500 * NANOSECS_PER_MILLISEC; | 
|---|
| 817 |  | 
|---|
| 818 | void OopStorage::trigger_cleanup_if_needed() { | 
|---|
| 819 | MonitorLocker ml(Service_lock, Monitor::_no_safepoint_check_flag); | 
|---|
| 820 | if (Atomic::load(&needs_cleanup_requested) && | 
|---|
| 821 | !needs_cleanup_triggered && | 
|---|
| 822 | (os::javaTimeNanos() > cleanup_trigger_permit_time)) { | 
|---|
| 823 | needs_cleanup_triggered = true; | 
|---|
| 824 | ml.notify_all(); | 
|---|
| 825 | } | 
|---|
| 826 | } | 
|---|
| 827 |  | 
|---|
| 828 | bool OopStorage::has_cleanup_work_and_reset() { | 
|---|
| 829 | assert_lock_strong(Service_lock); | 
|---|
| 830 | cleanup_trigger_permit_time = | 
|---|
| 831 | os::javaTimeNanos() + cleanup_trigger_defer_period; | 
|---|
| 832 | needs_cleanup_triggered = false; | 
|---|
| 833 | // Set the request flag false and return its old value. | 
|---|
| 834 | // Needs to be atomic to avoid dropping a concurrent request. | 
|---|
| 835 | // Can't use Atomic::xchg, which may not support bool. | 
|---|
| 836 | return Atomic::cmpxchg(false, &needs_cleanup_requested, true); | 
|---|
| 837 | } | 
|---|
| 838 |  | 
|---|
| 839 | // Record that cleanup is needed, without notifying the Service thread. | 
|---|
| 840 | // Used by release(), where we can't lock even Service_lock. | 
|---|
| 841 | void OopStorage::record_needs_cleanup() { | 
|---|
| 842 | // Set local flag first, else service thread could wake up and miss | 
|---|
| 843 | // the request.  This order may instead (rarely) unnecessarily notify. | 
|---|
| 844 | OrderAccess::release_store(&_needs_cleanup, true); | 
|---|
| 845 | OrderAccess::release_store_fence(&needs_cleanup_requested, true); | 
|---|
| 846 | } | 
|---|
| 847 |  | 
|---|
| 848 | bool OopStorage::delete_empty_blocks() { | 
|---|
| 849 | // Service thread might have oopstorage work, but not for this object. | 
|---|
| 850 | // Check for deferred updates even though that's not a service thread | 
|---|
| 851 | // trigger; since we're here, we might as well process them. | 
|---|
| 852 | if (!OrderAccess::load_acquire(&_needs_cleanup) && | 
|---|
| 853 | (OrderAccess::load_acquire(&_deferred_updates) == NULL)) { | 
|---|
| 854 | return false; | 
|---|
| 855 | } | 
|---|
| 856 |  | 
|---|
| 857 | MutexLocker ml(_allocation_mutex, Mutex::_no_safepoint_check_flag); | 
|---|
| 858 |  | 
|---|
| 859 | // Clear the request before processing. | 
|---|
| 860 | OrderAccess::release_store_fence(&_needs_cleanup, false); | 
|---|
| 861 |  | 
|---|
| 862 | // Other threads could be adding to the empty block count or the | 
|---|
| 863 | // deferred update list while we're working.  Set an upper bound on | 
|---|
| 864 | // how many updates we'll process and blocks we'll try to release, | 
|---|
| 865 | // so other threads can't cause an unbounded stay in this function. | 
|---|
| 866 | // We add a bit of slop because the reduce_deferred_updates clause | 
|---|
| 867 | // can cause blocks to be double counted.  If there are few blocks | 
|---|
| 868 | // and many of them are deferred and empty, we might hit the limit | 
|---|
| 869 | // and spin the caller without doing very much work.  Otherwise, | 
|---|
| 870 | // we don't normally hit the limit anyway, instead running out of | 
|---|
| 871 | // work to do. | 
|---|
| 872 | size_t limit = block_count() + 10; | 
|---|
| 873 |  | 
|---|
| 874 | for (size_t i = 0; i < limit; ++i) { | 
|---|
| 875 | // Process deferred updates, which might make empty blocks available. | 
|---|
| 876 | // Continue checking once deletion starts, since additional updates | 
|---|
| 877 | // might become available while we're working. | 
|---|
| 878 | if (reduce_deferred_updates()) { | 
|---|
| 879 | // Be safepoint-polite while looping. | 
|---|
| 880 | MutexUnlocker ul(_allocation_mutex, Mutex::_no_safepoint_check_flag); | 
|---|
| 881 | ThreadBlockInVM tbiv(JavaThread::current()); | 
|---|
| 882 | } else { | 
|---|
| 883 | Block* block = _allocation_list.tail(); | 
|---|
| 884 | if ((block == NULL) || !block->is_empty()) { | 
|---|
| 885 | return false; | 
|---|
| 886 | } else if (!block->is_safe_to_delete()) { | 
|---|
| 887 | // Look for other work while waiting for block to be deletable. | 
|---|
| 888 | break; | 
|---|
| 889 | } | 
|---|
| 890 |  | 
|---|
| 891 | // Try to delete the block.  First, try to remove from _active_array. | 
|---|
| 892 | { | 
|---|
| 893 | MutexLocker aml(_active_mutex, Mutex::_no_safepoint_check_flag); | 
|---|
| 894 | // Don't interfere with an active concurrent iteration. | 
|---|
| 895 | // Instead, give up immediately.  There is more work to do, | 
|---|
| 896 | // but don't re-notify, to avoid useless spinning of the | 
|---|
| 897 | // service thread.  Instead, iteration completion notifies. | 
|---|
| 898 | if (_concurrent_iteration_count > 0) return true; | 
|---|
| 899 | _active_array->remove(block); | 
|---|
| 900 | } | 
|---|
| 901 | // Remove block from _allocation_list and delete it. | 
|---|
| 902 | _allocation_list.unlink(*block); | 
|---|
| 903 | // Be safepoint-polite while deleting and looping. | 
|---|
| 904 | MutexUnlocker ul(_allocation_mutex, Mutex::_no_safepoint_check_flag); | 
|---|
| 905 | delete_empty_block(*block); | 
|---|
| 906 | ThreadBlockInVM tbiv(JavaThread::current()); | 
|---|
| 907 | } | 
|---|
| 908 | } | 
|---|
| 909 | // Exceeded work limit or can't delete last block.  This will | 
|---|
| 910 | // cause the service thread to loop, giving other subtasks an | 
|---|
| 911 | // opportunity to run too.  There's no need for a notification, | 
|---|
| 912 | // because we are part of the service thread (unless gtesting). | 
|---|
| 913 | record_needs_cleanup(); | 
|---|
| 914 | return true; | 
|---|
| 915 | } | 
|---|
| 916 |  | 
|---|
| 917 | OopStorage::EntryStatus OopStorage::allocation_status(const oop* ptr) const { | 
|---|
| 918 | const Block* block = find_block_or_null(ptr); | 
|---|
| 919 | if (block != NULL) { | 
|---|
| 920 | // Prevent block deletion and _active_array modification. | 
|---|
| 921 | MutexLocker ml(_allocation_mutex, Mutex::_no_safepoint_check_flag); | 
|---|
| 922 | // Block could be a false positive, so get index carefully. | 
|---|
| 923 | size_t index = Block::active_index_safe(block); | 
|---|
| 924 | if ((index < _active_array->block_count()) && | 
|---|
| 925 | (block == _active_array->at(index)) && | 
|---|
| 926 | block->contains(ptr)) { | 
|---|
| 927 | if ((block->allocated_bitmask() & block->bitmask_for_entry(ptr)) != 0) { | 
|---|
| 928 | return ALLOCATED_ENTRY; | 
|---|
| 929 | } else { | 
|---|
| 930 | return UNALLOCATED_ENTRY; | 
|---|
| 931 | } | 
|---|
| 932 | } | 
|---|
| 933 | } | 
|---|
| 934 | return INVALID_ENTRY; | 
|---|
| 935 | } | 
|---|
| 936 |  | 
|---|
| 937 | size_t OopStorage::allocation_count() const { | 
|---|
| 938 | return _allocation_count; | 
|---|
| 939 | } | 
|---|
| 940 |  | 
|---|
| 941 | size_t OopStorage::block_count() const { | 
|---|
| 942 | WithActiveArray wab(this); | 
|---|
| 943 | // Count access is racy, but don't care. | 
|---|
| 944 | return wab.active_array().block_count(); | 
|---|
| 945 | } | 
|---|
| 946 |  | 
|---|
| 947 | size_t OopStorage::total_memory_usage() const { | 
|---|
| 948 | size_t total_size = sizeof(OopStorage); | 
|---|
| 949 | total_size += strlen(name()) + 1; | 
|---|
| 950 | total_size += sizeof(ActiveArray); | 
|---|
| 951 | WithActiveArray wab(this); | 
|---|
| 952 | const ActiveArray& blocks = wab.active_array(); | 
|---|
| 953 | // Count access is racy, but don't care. | 
|---|
| 954 | total_size += blocks.block_count() * Block::allocation_size(); | 
|---|
| 955 | total_size += blocks.size() * sizeof(Block*); | 
|---|
| 956 | return total_size; | 
|---|
| 957 | } | 
|---|
| 958 |  | 
|---|
| 959 | // Parallel iteration support | 
|---|
| 960 |  | 
|---|
| 961 | uint OopStorage::BasicParState::default_estimated_thread_count(bool concurrent) { | 
|---|
| 962 | uint configured = concurrent ? ConcGCThreads : ParallelGCThreads; | 
|---|
| 963 | return MAX2(1u, configured);  // Never estimate zero threads. | 
|---|
| 964 | } | 
|---|
| 965 |  | 
|---|
| 966 | OopStorage::BasicParState::BasicParState(const OopStorage* storage, | 
|---|
| 967 | uint estimated_thread_count, | 
|---|
| 968 | bool concurrent) : | 
|---|
| 969 | _storage(storage), | 
|---|
| 970 | _active_array(_storage->obtain_active_array()), | 
|---|
| 971 | _block_count(0),              // initialized properly below | 
|---|
| 972 | _next_block(0), | 
|---|
| 973 | _estimated_thread_count(estimated_thread_count), | 
|---|
| 974 | _concurrent(concurrent) | 
|---|
| 975 | { | 
|---|
| 976 | assert(estimated_thread_count > 0, "estimated thread count must be positive"); | 
|---|
| 977 | update_concurrent_iteration_count(1); | 
|---|
| 978 | // Get the block count *after* iteration state updated, so concurrent | 
|---|
| 979 | // empty block deletion is suppressed and can't reduce the count.  But | 
|---|
| 980 | // ensure the count we use was written after the block with that count | 
|---|
| 981 | // was fully initialized; see ActiveArray::push. | 
|---|
| 982 | _block_count = _active_array->block_count_acquire(); | 
|---|
| 983 | } | 
|---|
| 984 |  | 
|---|
| 985 | OopStorage::BasicParState::~BasicParState() { | 
|---|
| 986 | _storage->relinquish_block_array(_active_array); | 
|---|
| 987 | update_concurrent_iteration_count(-1); | 
|---|
| 988 | if (_concurrent) { | 
|---|
| 989 | // We may have deferred some cleanup work. | 
|---|
| 990 | const_cast<OopStorage*>(_storage)->record_needs_cleanup(); | 
|---|
| 991 | } | 
|---|
| 992 | } | 
|---|
| 993 |  | 
|---|
| 994 | void OopStorage::BasicParState::update_concurrent_iteration_count(int value) { | 
|---|
| 995 | if (_concurrent) { | 
|---|
| 996 | MutexLocker ml(_storage->_active_mutex, Mutex::_no_safepoint_check_flag); | 
|---|
| 997 | _storage->_concurrent_iteration_count += value; | 
|---|
| 998 | assert(_storage->_concurrent_iteration_count >= 0, "invariant"); | 
|---|
| 999 | } | 
|---|
| 1000 | } | 
|---|
| 1001 |  | 
|---|
| 1002 | bool OopStorage::BasicParState::claim_next_segment(IterationData* data) { | 
|---|
| 1003 | data->_processed += data->_segment_end - data->_segment_start; | 
|---|
| 1004 | size_t start = OrderAccess::load_acquire(&_next_block); | 
|---|
| 1005 | if (start >= _block_count) { | 
|---|
| 1006 | return finish_iteration(data); // No more blocks available. | 
|---|
| 1007 | } | 
|---|
| 1008 | // Try to claim several at a time, but not *too* many.  We want to | 
|---|
| 1009 | // avoid deciding there are many available and selecting a large | 
|---|
| 1010 | // quantity, get delayed, and then end up claiming most or all of | 
|---|
| 1011 | // the remaining largish amount of work, leaving nothing for other | 
|---|
| 1012 | // threads to do.  But too small a step can lead to contention | 
|---|
| 1013 | // over _next_block, esp. when the work per block is small. | 
|---|
| 1014 | size_t max_step = 10; | 
|---|
| 1015 | size_t remaining = _block_count - start; | 
|---|
| 1016 | size_t step = MIN2(max_step, 1 + (remaining / _estimated_thread_count)); | 
|---|
| 1017 | // Atomic::add with possible overshoot.  This can perform better | 
|---|
| 1018 | // than a CAS loop on some platforms when there is contention. | 
|---|
| 1019 | // We can cope with the uncertainty by recomputing start/end from | 
|---|
| 1020 | // the result of the add, and dealing with potential overshoot. | 
|---|
| 1021 | size_t end = Atomic::add(step, &_next_block); | 
|---|
| 1022 | // _next_block may have changed, so recompute start from result of add. | 
|---|
| 1023 | start = end - step; | 
|---|
| 1024 | // _next_block may have changed so much that end has overshot. | 
|---|
| 1025 | end = MIN2(end, _block_count); | 
|---|
| 1026 | // _next_block may have changed so much that even start has overshot. | 
|---|
| 1027 | if (start < _block_count) { | 
|---|
| 1028 | // Record claimed segment for iteration. | 
|---|
| 1029 | data->_segment_start = start; | 
|---|
| 1030 | data->_segment_end = end; | 
|---|
| 1031 | return true;                // Success. | 
|---|
| 1032 | } else { | 
|---|
| 1033 | // No more blocks to claim. | 
|---|
| 1034 | return finish_iteration(data); | 
|---|
| 1035 | } | 
|---|
| 1036 | } | 
|---|
| 1037 |  | 
|---|
| 1038 | bool OopStorage::BasicParState::finish_iteration(const IterationData* data) const { | 
|---|
| 1039 | log_info(oopstorage, blocks, stats) | 
|---|
| 1040 | ( "Parallel iteration on %s: blocks = "SIZE_FORMAT | 
|---|
| 1041 | ", processed = "SIZE_FORMAT " (%2.f%%)", | 
|---|
| 1042 | _storage->name(), _block_count, data->_processed, | 
|---|
| 1043 | percent_of(data->_processed, _block_count)); | 
|---|
| 1044 | return false; | 
|---|
| 1045 | } | 
|---|
| 1046 |  | 
|---|
| 1047 | const char* OopStorage::name() const { return _name; } | 
|---|
| 1048 |  | 
|---|
| 1049 | #ifndef PRODUCT | 
|---|
| 1050 |  | 
|---|
| 1051 | void OopStorage::print_on(outputStream* st) const { | 
|---|
| 1052 | size_t allocations = _allocation_count; | 
|---|
| 1053 | size_t blocks = _active_array->block_count(); | 
|---|
| 1054 |  | 
|---|
| 1055 | double data_size = section_size * section_count; | 
|---|
| 1056 | double alloc_percentage = percent_of((double)allocations, blocks * data_size); | 
|---|
| 1057 |  | 
|---|
| 1058 | st->print( "%s: "SIZE_FORMAT " entries in "SIZE_FORMAT " blocks (%.F%%), "SIZE_FORMAT " bytes", | 
|---|
| 1059 | name(), allocations, blocks, alloc_percentage, total_memory_usage()); | 
|---|
| 1060 | if (_concurrent_iteration_count > 0) { | 
|---|
| 1061 | st->print( ", concurrent iteration active"); | 
|---|
| 1062 | } | 
|---|
| 1063 | } | 
|---|
| 1064 |  | 
|---|
| 1065 | #endif // !PRODUCT | 
|---|
| 1066 |  | 
|---|