25 #ifndef SHARE_GC_SHARED_SATBMARKQUEUE_HPP |
25 #ifndef SHARE_GC_SHARED_SATBMARKQUEUE_HPP |
26 #define SHARE_GC_SHARED_SATBMARKQUEUE_HPP |
26 #define SHARE_GC_SHARED_SATBMARKQUEUE_HPP |
27 |
27 |
28 #include "gc/shared/ptrQueue.hpp" |
28 #include "gc/shared/ptrQueue.hpp" |
29 #include "memory/allocation.hpp" |
29 #include "memory/allocation.hpp" |
|
30 #include "memory/padded.hpp" |
30 |
31 |
31 class Thread; |
32 class Thread; |
32 class Monitor; |
33 class Monitor; |
33 class SATBMarkQueueSet; |
34 class SATBMarkQueueSet; |
34 |
35 |
91 using PtrQueue::byte_width_of_active; |
92 using PtrQueue::byte_width_of_active; |
92 |
93 |
93 }; |
94 }; |
94 |
95 |
95 class SATBMarkQueueSet: public PtrQueueSet { |
96 class SATBMarkQueueSet: public PtrQueueSet { |
|
97 |
|
98 DEFINE_PAD_MINUS_SIZE(1, DEFAULT_CACHE_LINE_SIZE, 0); |
|
99 PaddedEnd<BufferNode::Stack> _list; |
|
100 volatile size_t _count_and_process_flag; |
|
101 // These are rarely (if ever) changed, so same cache line as count. |
|
102 size_t _process_completed_buffers_threshold; |
96 size_t _buffer_enqueue_threshold; |
103 size_t _buffer_enqueue_threshold; |
|
104 DEFINE_PAD_MINUS_SIZE(2, DEFAULT_CACHE_LINE_SIZE, 3 * sizeof(size_t)); |
|
105 |
|
106 BufferNode* get_completed_buffer(); |
|
107 void abandon_completed_buffers(); |
97 |
108 |
98 #ifdef ASSERT |
109 #ifdef ASSERT |
99 void dump_active_states(bool expected_active); |
110 void dump_active_states(bool expected_active); |
100 void verify_active_states(bool expected_active); |
111 void verify_active_states(bool expected_active); |
101 #endif // ASSERT |
112 #endif // ASSERT |
102 |
113 |
103 protected: |
114 protected: |
104 SATBMarkQueueSet(); |
115 SATBMarkQueueSet(); |
105 ~SATBMarkQueueSet() {} |
116 ~SATBMarkQueueSet(); |
106 |
117 |
107 template<typename Filter> |
118 template<typename Filter> |
108 void apply_filter(Filter filter, SATBMarkQueue* queue) { |
119 void apply_filter(Filter filter, SATBMarkQueue* queue) { |
109 queue->apply_filter(filter); |
120 queue->apply_filter(filter); |
110 } |
121 } |
111 |
122 |
112 void initialize(Monitor* cbl_mon, |
123 void initialize(BufferNode::Allocator* allocator, |
113 BufferNode::Allocator* allocator, |
|
114 size_t process_completed_buffers_threshold, |
124 size_t process_completed_buffers_threshold, |
115 uint buffer_enqueue_threshold_percentage); |
125 uint buffer_enqueue_threshold_percentage); |
116 |
126 |
117 public: |
127 public: |
118 virtual SATBMarkQueue& satb_queue_for_thread(Thread* const t) const = 0; |
128 virtual SATBMarkQueue& satb_queue_for_thread(Thread* const t) const = 0; |
129 // If there exists some completed buffer, pop and process it, and |
139 // If there exists some completed buffer, pop and process it, and |
130 // return true. Otherwise return false. Processing a buffer |
140 // return true. Otherwise return false. Processing a buffer |
131 // consists of applying the closure to the active range of the |
141 // consists of applying the closure to the active range of the |
132 // buffer; the leading entries may be excluded due to filtering. |
142 // buffer; the leading entries may be excluded due to filtering. |
133 bool apply_closure_to_completed_buffer(SATBBufferClosure* cl); |
143 bool apply_closure_to_completed_buffer(SATBBufferClosure* cl); |
|
144 |
|
145 virtual void enqueue_completed_buffer(BufferNode* node); |
|
146 |
|
147 // The number of buffers in the list. Racy and not updated atomically |
|
148 // with the set of completed buffers. |
|
149 size_t completed_buffers_num() const { |
|
150 return _count_and_process_flag >> 1; |
|
151 } |
|
152 |
|
153 // Return true if completed buffers should be processed. |
|
154 bool process_completed_buffers() const { |
|
155 return (_count_and_process_flag & 1) != 0; |
|
156 } |
134 |
157 |
135 #ifndef PRODUCT |
158 #ifndef PRODUCT |
136 // Helpful for debugging |
159 // Helpful for debugging |
137 void print_all(const char* msg); |
160 void print_all(const char* msg); |
138 #endif // PRODUCT |
161 #endif // PRODUCT |