35 // ThreadLocalAllocBuffer: a descriptor for thread-local storage used by |
35 // ThreadLocalAllocBuffer: a descriptor for thread-local storage used by |
36 // the threads for allocation. |
36 // the threads for allocation. |
37 // It is thread-private at any time, but maybe multiplexed over |
37 // It is thread-private at any time, but maybe multiplexed over |
38 // time across multiple threads. The park()/unpark() pair is |
38 // time across multiple threads. The park()/unpark() pair is |
39 // used to make it available for such multiplexing. |
39 // used to make it available for such multiplexing. |
|
40 // |
|
41 // Heap sampling is performed via the end and allocation_end |
|
42 // fields. |
|
43 // allocation_end contains the real end of the tlab allocation, |
|
44 // whereas end can be set to an arbitrary spot in the tlab to |
|
45 // trip the return and sample the allocation. |
40 class ThreadLocalAllocBuffer: public CHeapObj<mtThread> { |
46 class ThreadLocalAllocBuffer: public CHeapObj<mtThread> { |
41 friend class VMStructs; |
47 friend class VMStructs; |
42 friend class JVMCIVMStructs; |
48 friend class JVMCIVMStructs; |
43 private: |
49 private: |
44 HeapWord* _start; // address of TLAB |
50 HeapWord* _start; // address of TLAB |
45 HeapWord* _top; // address after last allocation |
51 HeapWord* _top; // address after last allocation |
46 HeapWord* _pf_top; // allocation prefetch watermark |
52 HeapWord* _pf_top; // allocation prefetch watermark |
47 HeapWord* _end; // allocation end (excluding alignment_reserve) |
53 HeapWord* _end; // allocation end (can be the sampling end point or _allocation_end) |
|
54 HeapWord* _allocation_end; // end for allocations (actual TLAB end, excluding alignment_reserve) |
|
55 |
48 size_t _desired_size; // desired size (including alignment_reserve) |
56 size_t _desired_size; // desired size (including alignment_reserve) |
49 size_t _refill_waste_limit; // hold onto tlab if free() is larger than this |
57 size_t _refill_waste_limit; // hold onto tlab if free() is larger than this |
50 size_t _allocated_before_last_gc; // total bytes allocated up until the last gc |
58 size_t _allocated_before_last_gc; // total bytes allocated up until the last gc |
|
59 size_t _bytes_since_last_sample_point; // bytes since last sample point. |
51 |
60 |
52 static size_t _max_size; // maximum size of any TLAB |
61 static size_t _max_size; // maximum size of any TLAB |
53 static int _reserve_for_allocation_prefetch; // Reserve at the end of the TLAB |
62 static int _reserve_for_allocation_prefetch; // Reserve at the end of the TLAB |
54 static unsigned _target_refills; // expected number of refills between GCs |
63 static unsigned _target_refills; // expected number of refills between GCs |
55 |
64 |
65 void accumulate_statistics(); |
74 void accumulate_statistics(); |
66 void initialize_statistics(); |
75 void initialize_statistics(); |
67 |
76 |
68 void set_start(HeapWord* start) { _start = start; } |
77 void set_start(HeapWord* start) { _start = start; } |
69 void set_end(HeapWord* end) { _end = end; } |
78 void set_end(HeapWord* end) { _end = end; } |
|
79 void set_allocation_end(HeapWord* ptr) { _allocation_end = ptr; } |
70 void set_top(HeapWord* top) { _top = top; } |
80 void set_top(HeapWord* top) { _top = top; } |
71 void set_pf_top(HeapWord* pf_top) { _pf_top = pf_top; } |
81 void set_pf_top(HeapWord* pf_top) { _pf_top = pf_top; } |
72 void set_desired_size(size_t desired_size) { _desired_size = desired_size; } |
82 void set_desired_size(size_t desired_size) { _desired_size = desired_size; } |
73 void set_refill_waste_limit(size_t waste) { _refill_waste_limit = waste; } |
83 void set_refill_waste_limit(size_t waste) { _refill_waste_limit = waste; } |
74 |
84 |
75 size_t initial_refill_waste_limit() { return desired_size() / TLABRefillWasteFraction; } |
85 size_t initial_refill_waste_limit() { return desired_size() / TLABRefillWasteFraction; } |
76 |
86 |
77 static int target_refills() { return _target_refills; } |
87 static int target_refills() { return _target_refills; } |
78 size_t initial_desired_size(); |
88 size_t initial_desired_size(); |
79 |
89 |
80 size_t remaining() const { return end() == NULL ? 0 : pointer_delta(hard_end(), top()); } |
90 size_t remaining(); |
81 |
91 |
82 bool is_last_allocation(HeapWord* obj, size_t size) { return pointer_delta(top(), obj) == size; } |
92 bool is_last_allocation(HeapWord* obj, size_t size) { return pointer_delta(top(), obj) == size; } |
83 |
93 |
84 // Make parsable and release it. |
94 // Make parsable and release it. |
85 void reset(); |
95 void reset(); |
116 static size_t max_size_in_bytes() { return max_size() * BytesPerWord; } |
126 static size_t max_size_in_bytes() { return max_size() * BytesPerWord; } |
117 static void set_max_size(size_t max_size) { _max_size = max_size; } |
127 static void set_max_size(size_t max_size) { _max_size = max_size; } |
118 |
128 |
119 HeapWord* start() const { return _start; } |
129 HeapWord* start() const { return _start; } |
120 HeapWord* end() const { return _end; } |
130 HeapWord* end() const { return _end; } |
121 HeapWord* hard_end() const { return _end + alignment_reserve(); } |
|
122 HeapWord* top() const { return _top; } |
131 HeapWord* top() const { return _top; } |
|
132 HeapWord* hard_end(); |
123 HeapWord* pf_top() const { return _pf_top; } |
133 HeapWord* pf_top() const { return _pf_top; } |
124 size_t desired_size() const { return _desired_size; } |
134 size_t desired_size() const { return _desired_size; } |
125 size_t used() const { return pointer_delta(top(), start()); } |
135 size_t used() const { return pointer_delta(top(), start()); } |
126 size_t used_bytes() const { return pointer_delta(top(), start(), 1); } |
136 size_t used_bytes() const { return pointer_delta(top(), start(), 1); } |
127 size_t free() const { return pointer_delta(end(), top()); } |
137 size_t free() const { return pointer_delta(end(), top()); } |
128 // Don't discard tlab if remaining space is larger than this. |
138 // Don't discard tlab if remaining space is larger than this. |
129 size_t refill_waste_limit() const { return _refill_waste_limit; } |
139 size_t refill_waste_limit() const { return _refill_waste_limit; } |
|
140 size_t bytes_since_last_sample_point() const { return _bytes_since_last_sample_point; } |
130 |
141 |
131 // Allocate size HeapWords. The memory is NOT initialized to zero. |
142 // Allocate size HeapWords. The memory is NOT initialized to zero. |
132 inline HeapWord* allocate(size_t size); |
143 inline HeapWord* allocate(size_t size); |
|
144 HeapWord* allocate_sampled_object(size_t size); |
133 |
145 |
134 // Undo last allocation. |
146 // Undo last allocation. |
135 inline bool undo_allocate(HeapWord* obj, size_t size); |
147 inline bool undo_allocate(HeapWord* obj, size_t size); |
136 |
148 |
137 // Reserve space at the end of TLAB |
149 // Reserve space at the end of TLAB |
168 // Resize tlabs for all threads |
180 // Resize tlabs for all threads |
169 static void resize_all_tlabs(); |
181 static void resize_all_tlabs(); |
170 |
182 |
171 void fill(HeapWord* start, HeapWord* top, size_t new_size); |
183 void fill(HeapWord* start, HeapWord* top, size_t new_size); |
172 void initialize(); |
184 void initialize(); |
|
185 |
|
186 void set_back_allocation_end(); |
|
187 void set_sample_end(); |
173 |
188 |
174 static size_t refill_waste_limit_increment() { return TLABWasteIncrement; } |
189 static size_t refill_waste_limit_increment() { return TLABWasteIncrement; } |
175 |
190 |
176 template <typename T> void addresses_do(T f) { |
191 template <typename T> void addresses_do(T f) { |
177 f(&_start); |
192 f(&_start); |
178 f(&_top); |
193 f(&_top); |
179 f(&_pf_top); |
194 f(&_pf_top); |
180 f(&_end); |
195 f(&_end); |
|
196 f(&_allocation_end); |
181 } |
197 } |
182 |
198 |
183 // Code generation support |
199 // Code generation support |
184 static ByteSize start_offset() { return byte_offset_of(ThreadLocalAllocBuffer, _start); } |
200 static ByteSize start_offset() { return byte_offset_of(ThreadLocalAllocBuffer, _start); } |
185 static ByteSize end_offset() { return byte_offset_of(ThreadLocalAllocBuffer, _end ); } |
201 static ByteSize end_offset() { return byte_offset_of(ThreadLocalAllocBuffer, _end ); } |