OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/heap/spaces.h" | 5 #include "src/heap/spaces.h" |
6 | 6 |
7 #include "src/base/bits.h" | 7 #include "src/base/bits.h" |
8 #include "src/base/platform/platform.h" | 8 #include "src/base/platform/platform.h" |
9 #include "src/full-codegen/full-codegen.h" | 9 #include "src/full-codegen/full-codegen.h" |
10 #include "src/heap/mark-compact.h" | 10 #include "src/heap/mark-compact.h" |
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
156 | 156 |
157 bool CodeRange::GetNextAllocationBlock(size_t requested) { | 157 bool CodeRange::GetNextAllocationBlock(size_t requested) { |
158 for (current_allocation_block_index_++; | 158 for (current_allocation_block_index_++; |
159 current_allocation_block_index_ < allocation_list_.length(); | 159 current_allocation_block_index_ < allocation_list_.length(); |
160 current_allocation_block_index_++) { | 160 current_allocation_block_index_++) { |
161 if (requested <= allocation_list_[current_allocation_block_index_].size) { | 161 if (requested <= allocation_list_[current_allocation_block_index_].size) { |
162 return true; // Found a large enough allocation block. | 162 return true; // Found a large enough allocation block. |
163 } | 163 } |
164 } | 164 } |
165 | 165 |
166 { | 166 // Sort and merge the free blocks on the free list and the allocation list. |
167 base::LockGuard<base::Mutex> free_list_lock_guard(&free_list_mutex_); | 167 free_list_.AddAll(allocation_list_); |
168 | 168 allocation_list_.Clear(); |
169 // Sort and merge the free blocks on the free list and the allocation list. | 169 free_list_.Sort(&CompareFreeBlockAddress); |
170 free_list_.AddAll(allocation_list_); | 170 for (int i = 0; i < free_list_.length();) { |
171 allocation_list_.Clear(); | 171 FreeBlock merged = free_list_[i]; |
172 free_list_.Sort(&CompareFreeBlockAddress); | 172 i++; |
173 for (int i = 0; i < free_list_.length();) { | 173 // Add adjacent free blocks to the current merged block. |
174 FreeBlock merged = free_list_[i]; | 174 while (i < free_list_.length() && |
| 175 free_list_[i].start == merged.start + merged.size) { |
| 176 merged.size += free_list_[i].size; |
175 i++; | 177 i++; |
176 // Add adjacent free blocks to the current merged block. | |
177 while (i < free_list_.length() && | |
178 free_list_[i].start == merged.start + merged.size) { | |
179 merged.size += free_list_[i].size; | |
180 i++; | |
181 } | |
182 if (merged.size > 0) { | |
183 allocation_list_.Add(merged); | |
184 } | |
185 } | 178 } |
186 free_list_.Clear(); | 179 if (merged.size > 0) { |
| 180 allocation_list_.Add(merged); |
| 181 } |
187 } | 182 } |
| 183 free_list_.Clear(); |
188 | 184 |
189 for (current_allocation_block_index_ = 0; | 185 for (current_allocation_block_index_ = 0; |
190 current_allocation_block_index_ < allocation_list_.length(); | 186 current_allocation_block_index_ < allocation_list_.length(); |
191 current_allocation_block_index_++) { | 187 current_allocation_block_index_++) { |
192 if (requested <= allocation_list_[current_allocation_block_index_].size) { | 188 if (requested <= allocation_list_[current_allocation_block_index_].size) { |
193 return true; // Found a large enough allocation block. | 189 return true; // Found a large enough allocation block. |
194 } | 190 } |
195 } | 191 } |
196 current_allocation_block_index_ = 0; | 192 current_allocation_block_index_ = 0; |
197 // Code range is full or too fragmented. | 193 // Code range is full or too fragmented. |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
229 } | 225 } |
230 | 226 |
231 | 227 |
232 bool CodeRange::UncommitRawMemory(Address start, size_t length) { | 228 bool CodeRange::UncommitRawMemory(Address start, size_t length) { |
233 return code_range_->Uncommit(start, length); | 229 return code_range_->Uncommit(start, length); |
234 } | 230 } |
235 | 231 |
236 | 232 |
237 void CodeRange::FreeRawMemory(Address address, size_t length) { | 233 void CodeRange::FreeRawMemory(Address address, size_t length) { |
238 DCHECK(IsAddressAligned(address, MemoryChunk::kAlignment)); | 234 DCHECK(IsAddressAligned(address, MemoryChunk::kAlignment)); |
239 base::LockGuard<base::Mutex> free_list_lock_guard(&free_list_mutex_); | 235 base::LockGuard<base::Mutex> guard(&code_range_mutex_); |
240 free_list_.Add(FreeBlock(address, length)); | 236 free_list_.Add(FreeBlock(address, length)); |
241 code_range_->Uncommit(address, length); | 237 code_range_->Uncommit(address, length); |
242 } | 238 } |
243 | 239 |
244 | 240 |
245 void CodeRange::TearDown() { | 241 void CodeRange::TearDown() { |
246 delete code_range_; // Frees all memory in the virtual memory range. | 242 delete code_range_; // Frees all memory in the virtual memory range. |
247 code_range_ = NULL; | 243 code_range_ = NULL; |
248 base::LockGuard<base::Mutex> free_list_lock_guard(&free_list_mutex_); | 244 base::LockGuard<base::Mutex> guard(&code_range_mutex_); |
249 free_list_.Free(); | 245 free_list_.Free(); |
250 allocation_list_.Free(); | 246 allocation_list_.Free(); |
251 } | 247 } |
252 | 248 |
253 | 249 |
254 bool CodeRange::ReserveBlock(const size_t requested_size, FreeBlock* block) { | 250 bool CodeRange::ReserveBlock(const size_t requested_size, FreeBlock* block) { |
| 251 base::LockGuard<base::Mutex> guard(&code_range_mutex_); |
255 DCHECK(allocation_list_.length() == 0 || | 252 DCHECK(allocation_list_.length() == 0 || |
256 current_allocation_block_index_ < allocation_list_.length()); | 253 current_allocation_block_index_ < allocation_list_.length()); |
257 if (allocation_list_.length() == 0 || | 254 if (allocation_list_.length() == 0 || |
258 requested_size > allocation_list_[current_allocation_block_index_].size) { | 255 requested_size > allocation_list_[current_allocation_block_index_].size) { |
259 // Find an allocation block large enough. | 256 // Find an allocation block large enough. |
260 if (!GetNextAllocationBlock(requested_size)) return false; | 257 if (!GetNextAllocationBlock(requested_size)) return false; |
261 } | 258 } |
262 // Commit the requested memory at the start of the current allocation block. | 259 // Commit the requested memory at the start of the current allocation block. |
263 size_t aligned_requested = RoundUp(requested_size, MemoryChunk::kAlignment); | 260 size_t aligned_requested = RoundUp(requested_size, MemoryChunk::kAlignment); |
264 *block = allocation_list_[current_allocation_block_index_]; | 261 *block = allocation_list_[current_allocation_block_index_]; |
265 // Don't leave a small free block, useless for a large object or chunk. | 262 // Don't leave a small free block, useless for a large object or chunk. |
266 if (aligned_requested < (block->size - Page::kPageSize)) { | 263 if (aligned_requested < (block->size - Page::kPageSize)) { |
267 block->size = aligned_requested; | 264 block->size = aligned_requested; |
268 } | 265 } |
269 DCHECK(IsAddressAligned(block->start, MemoryChunk::kAlignment)); | 266 DCHECK(IsAddressAligned(block->start, MemoryChunk::kAlignment)); |
270 allocation_list_[current_allocation_block_index_].start += block->size; | 267 allocation_list_[current_allocation_block_index_].start += block->size; |
271 allocation_list_[current_allocation_block_index_].size -= block->size; | 268 allocation_list_[current_allocation_block_index_].size -= block->size; |
272 return true; | 269 return true; |
273 } | 270 } |
274 | 271 |
275 | 272 |
276 void CodeRange::ReleaseBlock(const FreeBlock* block) { | 273 void CodeRange::ReleaseBlock(const FreeBlock* block) { |
277 base::LockGuard<base::Mutex> free_list_lock_guard(&free_list_mutex_); | 274 base::LockGuard<base::Mutex> guard(&code_range_mutex_); |
278 free_list_.Add(*block); | 275 free_list_.Add(*block); |
279 } | 276 } |
280 | 277 |
281 | 278 |
282 void CodeRange::ReserveEmergencyBlock() { | 279 void CodeRange::ReserveEmergencyBlock() { |
283 const size_t requested_size = MemoryAllocator::CodePageAreaSize(); | 280 const size_t requested_size = MemoryAllocator::CodePageAreaSize(); |
284 if (emergency_block_.size == 0) { | 281 if (emergency_block_.size == 0) { |
285 ReserveBlock(requested_size, &emergency_block_); | 282 ReserveBlock(requested_size, &emergency_block_); |
286 } else { | 283 } else { |
287 DCHECK(emergency_block_.size >= requested_size); | 284 DCHECK(emergency_block_.size >= requested_size); |
(...skipping 2897 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3185 object->ShortPrint(); | 3182 object->ShortPrint(); |
3186 PrintF("\n"); | 3183 PrintF("\n"); |
3187 } | 3184 } |
3188 printf(" --------------------------------------\n"); | 3185 printf(" --------------------------------------\n"); |
3189 printf(" Marked: %x, LiveCount: %x\n", mark_size, LiveBytes()); | 3186 printf(" Marked: %x, LiveCount: %x\n", mark_size, LiveBytes()); |
3190 } | 3187 } |
3191 | 3188 |
3192 #endif // DEBUG | 3189 #endif // DEBUG |
3193 } // namespace internal | 3190 } // namespace internal |
3194 } // namespace v8 | 3191 } // namespace v8 |
OLD | NEW |