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 #ifndef SHARE_GC_SHARED_OOPSTORAGE_INLINE_HPP
26 #define SHARE_GC_SHARED_OOPSTORAGE_INLINE_HPP
27
28 #include "gc/shared/oopStorage.hpp"
29 #include "metaprogramming/conditional.hpp"
30 #include "metaprogramming/isConst.hpp"
31 #include "oops/oop.hpp"
32 #include "runtime/safepoint.hpp"
33 #include "utilities/align.hpp"
34 #include "utilities/count_trailing_zeros.hpp"
35 #include "utilities/debug.hpp"
36 #include "utilities/globalDefinitions.hpp"
37
38 // Array of all active blocks. Refcounted for lock-free reclaim of
39 // old array when a new array is allocated for expansion.
40 class OopStorage::ActiveArray {
41 friend class OopStorage::TestAccess;
42
43 size_t _size;
44 volatile size_t _block_count;
45 mutable volatile int _refcount;
46 // Block* _blocks[1]; // Pseudo flexible array member.
47
48 ActiveArray(size_t size);
49 ~ActiveArray();
50
51 // Noncopyable
52 ActiveArray(const ActiveArray&);
53 ActiveArray& operator=(const ActiveArray&);
54
55 static size_t blocks_offset();
56 Block* const* base_ptr() const;
57
58 Block* const* block_ptr(size_t index) const;
59 Block** block_ptr(size_t index);
60
61 public:
62 static ActiveArray* create(size_t size, AllocFailType alloc_fail = AllocFailStrategy::EXIT_OOM);
63 static void destroy(ActiveArray* ba);
64
65 inline Block* at(size_t i) const;
66
67 size_t size() const;
68 size_t block_count() const;
69 size_t block_count_acquire() const;
70 void increment_refcount() const;
71 bool decrement_refcount() const; // Return true if zero, otherwise false
72
73 // Support for OopStorage::allocate.
101 inline OopStorage::Block** OopStorage::ActiveArray::block_ptr(size_t index) {
102 return const_cast<Block**>(base_ptr() + index);
103 }
104
105 inline OopStorage::Block* OopStorage::ActiveArray::at(size_t index) const {
106 assert(index < _block_count, "precondition");
107 return *block_ptr(index);
108 }
109
110 // A Block has an embedded AllocationListEntry to provide the links between
111 // Blocks in an AllocationList.
112 class OopStorage::AllocationListEntry {
113 friend class OopStorage::AllocationList;
114
115 // Members are mutable, and we deal exclusively with pointers to
116 // const, to make const blocks easier to use; a block being const
117 // doesn't prevent modifying its list state.
118 mutable const Block* _prev;
119 mutable const Block* _next;
120
121 // Noncopyable.
122 AllocationListEntry(const AllocationListEntry&);
123 AllocationListEntry& operator=(const AllocationListEntry&);
124
125 public:
126 AllocationListEntry();
127 ~AllocationListEntry();
128 };
129
130 // Fixed-sized array of oops, plus bookkeeping data.
131 // All blocks are in the storage's _active_array, at the block's _active_index.
132 // Non-full blocks are in the storage's _allocation_list, linked through the
133 // block's _allocation_list_entry. Empty blocks are at the end of that list.
134 class OopStorage::Block /* No base class, to avoid messing up alignment. */ {
135 // _data must be the first non-static data member, for alignment.
136 oop _data[BitsPerWord];
137 static const unsigned _data_pos = 0; // Position of _data.
138
139 volatile uintx _allocated_bitmask; // One bit per _data element.
140 intptr_t _owner_address;
141 void* _memory; // Unaligned storage containing block.
142 size_t _active_index;
143 AllocationListEntry _allocation_list_entry;
144 Block* volatile _deferred_updates_next;
145 volatile uintx _release_refcount;
146
147 Block(const OopStorage* owner, void* memory);
148 ~Block();
149
150 void check_index(unsigned index) const;
151 unsigned get_index(const oop* ptr) const;
152
153 template<typename F, typename BlockPtr>
154 static bool iterate_impl(F f, BlockPtr b);
155
156 // Noncopyable.
157 Block(const Block&);
158 Block& operator=(const Block&);
159
160 public:
161 const AllocationListEntry& allocation_list_entry() const;
162
163 static size_t allocation_size();
164 static size_t allocation_alignment_shift();
165
166 oop* get_pointer(unsigned index);
167 const oop* get_pointer(unsigned index) const;
168
169 uintx bitmask_for_index(unsigned index) const;
170 uintx bitmask_for_entry(const oop* ptr) const;
171
172 // Allocation bitmask accessors are racy.
173 bool is_full() const;
174 bool is_empty() const;
175 uintx allocated_bitmask() const;
176
177 bool is_safe_to_delete() const;
178
|
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 #ifndef SHARE_GC_SHARED_OOPSTORAGE_INLINE_HPP
26 #define SHARE_GC_SHARED_OOPSTORAGE_INLINE_HPP
27
28 #include "gc/shared/oopStorage.hpp"
29 #include "metaprogramming/conditional.hpp"
30 #include "metaprogramming/isConst.hpp"
31 #include "oops/oop.hpp"
32 #include "runtime/safepoint.hpp"
33 #include "utilities/align.hpp"
34 #include "utilities/count_trailing_zeros.hpp"
35 #include "utilities/debug.hpp"
36 #include "utilities/globalDefinitions.hpp"
37 #include "utilities/macros.hpp"
38
39 // Array of all active blocks. Refcounted for lock-free reclaim of
40 // old array when a new array is allocated for expansion.
41 class OopStorage::ActiveArray {
42 friend class OopStorage::TestAccess;
43
44 size_t _size;
45 volatile size_t _block_count;
46 mutable volatile int _refcount;
47 // Block* _blocks[1]; // Pseudo flexible array member.
48
49 ActiveArray(size_t size);
50 ~ActiveArray();
51
52 NONCOPYABLE(ActiveArray);
53
54 static size_t blocks_offset();
55 Block* const* base_ptr() const;
56
57 Block* const* block_ptr(size_t index) const;
58 Block** block_ptr(size_t index);
59
60 public:
61 static ActiveArray* create(size_t size, AllocFailType alloc_fail = AllocFailStrategy::EXIT_OOM);
62 static void destroy(ActiveArray* ba);
63
64 inline Block* at(size_t i) const;
65
66 size_t size() const;
67 size_t block_count() const;
68 size_t block_count_acquire() const;
69 void increment_refcount() const;
70 bool decrement_refcount() const; // Return true if zero, otherwise false
71
72 // Support for OopStorage::allocate.
100 inline OopStorage::Block** OopStorage::ActiveArray::block_ptr(size_t index) {
101 return const_cast<Block**>(base_ptr() + index);
102 }
103
104 inline OopStorage::Block* OopStorage::ActiveArray::at(size_t index) const {
105 assert(index < _block_count, "precondition");
106 return *block_ptr(index);
107 }
108
109 // A Block has an embedded AllocationListEntry to provide the links between
110 // Blocks in an AllocationList.
111 class OopStorage::AllocationListEntry {
112 friend class OopStorage::AllocationList;
113
114 // Members are mutable, and we deal exclusively with pointers to
115 // const, to make const blocks easier to use; a block being const
116 // doesn't prevent modifying its list state.
117 mutable const Block* _prev;
118 mutable const Block* _next;
119
120 NONCOPYABLE(AllocationListEntry);
121
122 public:
123 AllocationListEntry();
124 ~AllocationListEntry();
125 };
126
127 // Fixed-sized array of oops, plus bookkeeping data.
128 // All blocks are in the storage's _active_array, at the block's _active_index.
129 // Non-full blocks are in the storage's _allocation_list, linked through the
130 // block's _allocation_list_entry. Empty blocks are at the end of that list.
131 class OopStorage::Block /* No base class, to avoid messing up alignment. */ {
132 // _data must be the first non-static data member, for alignment.
133 oop _data[BitsPerWord];
134 static const unsigned _data_pos = 0; // Position of _data.
135
136 volatile uintx _allocated_bitmask; // One bit per _data element.
137 intptr_t _owner_address;
138 void* _memory; // Unaligned storage containing block.
139 size_t _active_index;
140 AllocationListEntry _allocation_list_entry;
141 Block* volatile _deferred_updates_next;
142 volatile uintx _release_refcount;
143
144 Block(const OopStorage* owner, void* memory);
145 ~Block();
146
147 void check_index(unsigned index) const;
148 unsigned get_index(const oop* ptr) const;
149
150 template<typename F, typename BlockPtr>
151 static bool iterate_impl(F f, BlockPtr b);
152
153 NONCOPYABLE(Block);
154
155 public:
156 const AllocationListEntry& allocation_list_entry() const;
157
158 static size_t allocation_size();
159 static size_t allocation_alignment_shift();
160
161 oop* get_pointer(unsigned index);
162 const oop* get_pointer(unsigned index) const;
163
164 uintx bitmask_for_index(unsigned index) const;
165 uintx bitmask_for_entry(const oop* ptr) const;
166
167 // Allocation bitmask accessors are racy.
168 bool is_full() const;
169 bool is_empty() const;
170 uintx allocated_bitmask() const;
171
172 bool is_safe_to_delete() const;
173
|