OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
135 if (heap_->InNewSpace(*reinterpret_cast<Object**>(current))) { | 135 if (heap_->InNewSpace(*reinterpret_cast<Object**>(current))) { |
136 *write++ = current; | 136 *write++ = current; |
137 } | 137 } |
138 } | 138 } |
139 previous = current; | 139 previous = current; |
140 } | 140 } |
141 old_top_ = write; | 141 old_top_ = write; |
142 } | 142 } |
143 | 143 |
144 | 144 |
| 145 bool StoreBuffer::SpaceAvailable(intptr_t space_needed) { |
| 146 return old_limit_ - old_top_ >= space_needed; |
| 147 } |
| 148 |
| 149 |
145 void StoreBuffer::EnsureSpace(intptr_t space_needed) { | 150 void StoreBuffer::EnsureSpace(intptr_t space_needed) { |
146 while (old_limit_ - old_top_ < space_needed && | 151 while (old_limit_ - old_top_ < space_needed && |
147 old_limit_ < old_reserved_limit_) { | 152 old_limit_ < old_reserved_limit_) { |
148 size_t grow = old_limit_ - old_start_; // Double size. | 153 size_t grow = old_limit_ - old_start_; // Double size. |
149 CHECK(old_virtual_memory_->Commit(reinterpret_cast<void*>(old_limit_), | 154 CHECK(old_virtual_memory_->Commit(reinterpret_cast<void*>(old_limit_), |
150 grow * kPointerSize, | 155 grow * kPointerSize, |
151 false)); | 156 false)); |
152 old_limit_ += grow; | 157 old_limit_ += grow; |
153 } | 158 } |
154 | 159 |
155 if (old_limit_ - old_top_ >= space_needed) return; | 160 if (SpaceAvailable(space_needed)) return; |
156 | 161 |
157 if (old_buffer_is_filtered_) return; | 162 if (old_buffer_is_filtered_) return; |
158 ASSERT(may_move_store_buffer_entries_); | 163 ASSERT(may_move_store_buffer_entries_); |
159 Compact(); | 164 Compact(); |
160 | 165 |
161 old_buffer_is_filtered_ = true; | 166 old_buffer_is_filtered_ = true; |
162 bool page_has_scan_on_scavenge_flag = false; | 167 bool page_has_scan_on_scavenge_flag = false; |
163 | 168 |
164 PointerChunkIterator it(heap_); | 169 PointerChunkIterator it(heap_); |
165 MemoryChunk* chunk; | 170 MemoryChunk* chunk; |
166 while ((chunk = it.next()) != NULL) { | 171 while ((chunk = it.next()) != NULL) { |
167 if (chunk->scan_on_scavenge()) page_has_scan_on_scavenge_flag = true; | 172 if (chunk->scan_on_scavenge()) page_has_scan_on_scavenge_flag = true; |
168 } | 173 } |
169 | 174 |
170 if (page_has_scan_on_scavenge_flag) { | 175 if (page_has_scan_on_scavenge_flag) { |
171 Filter(MemoryChunk::SCAN_ON_SCAVENGE); | 176 Filter(MemoryChunk::SCAN_ON_SCAVENGE); |
172 } | 177 } |
173 | 178 |
174 // If filtering out the entries from scan_on_scavenge pages got us down to | 179 if (SpaceAvailable(space_needed)) return; |
175 // less than half full, then we are satisfied with that. | |
176 if (old_limit_ - old_top_ > old_top_ - old_start_) return; | |
177 | 180 |
178 // Sample 1 entry in 97 and filter out the pages where we estimate that more | 181 // Sample 1 entry in 97 and filter out the pages where we estimate that more |
179 // than 1 in 8 pointers are to new space. | 182 // than 1 in 8 pointers are to new space. |
180 static const int kSampleFinenesses = 5; | 183 static const int kSampleFinenesses = 5; |
181 static const struct Samples { | 184 static const struct Samples { |
182 int prime_sample_step; | 185 int prime_sample_step; |
183 int threshold; | 186 int threshold; |
184 } samples[kSampleFinenesses] = { | 187 } samples[kSampleFinenesses] = { |
185 { 97, ((Page::kPageSize / kPointerSize) / 97) / 8 }, | 188 { 97, ((Page::kPageSize / kPointerSize) / 97) / 8 }, |
186 { 23, ((Page::kPageSize / kPointerSize) / 23) / 16 }, | 189 { 23, ((Page::kPageSize / kPointerSize) / 23) / 16 }, |
187 { 7, ((Page::kPageSize / kPointerSize) / 7) / 32 }, | 190 { 7, ((Page::kPageSize / kPointerSize) / 7) / 32 }, |
188 { 3, ((Page::kPageSize / kPointerSize) / 3) / 256 }, | 191 { 3, ((Page::kPageSize / kPointerSize) / 3) / 256 }, |
189 { 1, 0} | 192 { 1, 0} |
190 }; | 193 }; |
191 for (int i = 0; i < kSampleFinenesses; i++) { | 194 for (int i = 0; i < kSampleFinenesses; i++) { |
192 ExemptPopularPages(samples[i].prime_sample_step, samples[i].threshold); | 195 ExemptPopularPages(samples[i].prime_sample_step, samples[i].threshold); |
193 // As a last resort we mark all pages as being exempt from the store buffer. | 196 // As a last resort we mark all pages as being exempt from the store buffer. |
194 ASSERT(i != (kSampleFinenesses - 1) || old_top_ == old_start_); | 197 ASSERT(i != (kSampleFinenesses - 1) || old_top_ == old_start_); |
195 if (old_limit_ - old_top_ > old_top_ - old_start_) return; | 198 if (SpaceAvailable(space_needed)) return; |
196 } | 199 } |
197 UNREACHABLE(); | 200 UNREACHABLE(); |
198 } | 201 } |
199 | 202 |
200 | 203 |
201 // Sample the store buffer to see if some pages are taking up a lot of space | 204 // Sample the store buffer to see if some pages are taking up a lot of space |
202 // in the store buffer. | 205 // in the store buffer. |
203 void StoreBuffer::ExemptPopularPages(int prime_sample_step, int threshold) { | 206 void StoreBuffer::ExemptPopularPages(int prime_sample_step, int threshold) { |
204 PointerChunkIterator it(heap_); | 207 PointerChunkIterator it(heap_); |
205 MemoryChunk* chunk; | 208 MemoryChunk* chunk; |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
287 ClearFilteringHashSets(); | 290 ClearFilteringHashSets(); |
288 | 291 |
289 return page_has_scan_on_scavenge_flag; | 292 return page_has_scan_on_scavenge_flag; |
290 } | 293 } |
291 | 294 |
292 | 295 |
293 #ifdef DEBUG | 296 #ifdef DEBUG |
294 void StoreBuffer::Clean() { | 297 void StoreBuffer::Clean() { |
295 ClearFilteringHashSets(); | 298 ClearFilteringHashSets(); |
296 Uniq(); // Also removes things that no longer point to new space. | 299 Uniq(); // Also removes things that no longer point to new space. |
297 CheckForFullBuffer(); | 300 EnsureSpace(kStoreBufferSize / 2); |
298 } | 301 } |
299 | 302 |
300 | 303 |
301 static Address* in_store_buffer_1_element_cache = NULL; | 304 static Address* in_store_buffer_1_element_cache = NULL; |
302 | 305 |
303 | 306 |
304 bool StoreBuffer::CellIsInStoreBuffer(Address cell_address) { | 307 bool StoreBuffer::CellIsInStoreBuffer(Address cell_address) { |
305 if (!FLAG_enable_slow_asserts) return true; | 308 if (!FLAG_enable_slow_asserts) return true; |
306 if (in_store_buffer_1_element_cache != NULL && | 309 if (in_store_buffer_1_element_cache != NULL && |
307 *in_store_buffer_1_element_cache == cell_address) { | 310 *in_store_buffer_1_element_cache == cell_address) { |
(...skipping 372 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
680 // cause some duplicates to remain undetected. | 683 // cause some duplicates to remain undetected. |
681 hash_set_1_[hash1] = int_addr; | 684 hash_set_1_[hash1] = int_addr; |
682 hash_set_2_[hash2] = 0; | 685 hash_set_2_[hash2] = 0; |
683 } | 686 } |
684 old_buffer_is_sorted_ = false; | 687 old_buffer_is_sorted_ = false; |
685 old_buffer_is_filtered_ = false; | 688 old_buffer_is_filtered_ = false; |
686 *old_top_++ = reinterpret_cast<Address>(int_addr << kPointerSizeLog2); | 689 *old_top_++ = reinterpret_cast<Address>(int_addr << kPointerSizeLog2); |
687 ASSERT(old_top_ <= old_limit_); | 690 ASSERT(old_top_ <= old_limit_); |
688 } | 691 } |
689 heap_->isolate()->counters()->store_buffer_compactions()->Increment(); | 692 heap_->isolate()->counters()->store_buffer_compactions()->Increment(); |
690 CheckForFullBuffer(); | |
691 } | |
692 | |
693 | |
694 void StoreBuffer::CheckForFullBuffer() { | |
695 EnsureSpace(kStoreBufferSize * 2); | |
696 } | 693 } |
697 | 694 |
698 } } // namespace v8::internal | 695 } } // namespace v8::internal |
OLD | NEW |