| 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 "v8.h" | 5 #include "v8.h" |
| 6 | 6 |
| 7 #include "full-codegen.h" | 7 #include "full-codegen.h" |
| 8 #include "macro-assembler.h" | 8 #include "macro-assembler.h" |
| 9 #include "mark-compact.h" | 9 #include "mark-compact.h" |
| 10 #include "msan.h" | 10 #include "msan.h" |
| (...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 149 | 149 |
| 150 int CodeRange::CompareFreeBlockAddress(const FreeBlock* left, | 150 int CodeRange::CompareFreeBlockAddress(const FreeBlock* left, |
| 151 const FreeBlock* right) { | 151 const FreeBlock* right) { |
| 152 // The entire point of CodeRange is that the difference between two | 152 // The entire point of CodeRange is that the difference between two |
| 153 // addresses in the range can be represented as a signed 32-bit int, | 153 // addresses in the range can be represented as a signed 32-bit int, |
| 154 // so the cast is semantically correct. | 154 // so the cast is semantically correct. |
| 155 return static_cast<int>(left->start - right->start); | 155 return static_cast<int>(left->start - right->start); |
| 156 } | 156 } |
| 157 | 157 |
| 158 | 158 |
| 159 void CodeRange::GetNextAllocationBlock(size_t requested) { | 159 bool CodeRange::GetNextAllocationBlock(size_t requested) { |
| 160 for (current_allocation_block_index_++; | 160 for (current_allocation_block_index_++; |
| 161 current_allocation_block_index_ < allocation_list_.length(); | 161 current_allocation_block_index_ < allocation_list_.length(); |
| 162 current_allocation_block_index_++) { | 162 current_allocation_block_index_++) { |
| 163 if (requested <= allocation_list_[current_allocation_block_index_].size) { | 163 if (requested <= allocation_list_[current_allocation_block_index_].size) { |
| 164 return; // Found a large enough allocation block. | 164 return true; // Found a large enough allocation block. |
| 165 } | 165 } |
| 166 } | 166 } |
| 167 | 167 |
| 168 // Sort and merge the free blocks on the free list and the allocation list. | 168 // Sort and merge the free blocks on the free list and the allocation list. |
| 169 free_list_.AddAll(allocation_list_); | 169 free_list_.AddAll(allocation_list_); |
| 170 allocation_list_.Clear(); | 170 allocation_list_.Clear(); |
| 171 free_list_.Sort(&CompareFreeBlockAddress); | 171 free_list_.Sort(&CompareFreeBlockAddress); |
| 172 for (int i = 0; i < free_list_.length();) { | 172 for (int i = 0; i < free_list_.length();) { |
| 173 FreeBlock merged = free_list_[i]; | 173 FreeBlock merged = free_list_[i]; |
| 174 i++; | 174 i++; |
| 175 // Add adjacent free blocks to the current merged block. | 175 // Add adjacent free blocks to the current merged block. |
| 176 while (i < free_list_.length() && | 176 while (i < free_list_.length() && |
| 177 free_list_[i].start == merged.start + merged.size) { | 177 free_list_[i].start == merged.start + merged.size) { |
| 178 merged.size += free_list_[i].size; | 178 merged.size += free_list_[i].size; |
| 179 i++; | 179 i++; |
| 180 } | 180 } |
| 181 if (merged.size > 0) { | 181 if (merged.size > 0) { |
| 182 allocation_list_.Add(merged); | 182 allocation_list_.Add(merged); |
| 183 } | 183 } |
| 184 } | 184 } |
| 185 free_list_.Clear(); | 185 free_list_.Clear(); |
| 186 | 186 |
| 187 for (current_allocation_block_index_ = 0; | 187 for (current_allocation_block_index_ = 0; |
| 188 current_allocation_block_index_ < allocation_list_.length(); | 188 current_allocation_block_index_ < allocation_list_.length(); |
| 189 current_allocation_block_index_++) { | 189 current_allocation_block_index_++) { |
| 190 if (requested <= allocation_list_[current_allocation_block_index_].size) { | 190 if (requested <= allocation_list_[current_allocation_block_index_].size) { |
| 191 return; // Found a large enough allocation block. | 191 return true; // Found a large enough allocation block. |
| 192 } | 192 } |
| 193 } | 193 } |
| 194 | 194 |
| 195 // Code range is full or too fragmented. | 195 // Code range is full or too fragmented. |
| 196 V8::FatalProcessOutOfMemory("CodeRange::GetNextAllocationBlock"); | 196 return false; |
| 197 } | 197 } |
| 198 | 198 |
| 199 | 199 |
| 200 Address CodeRange::AllocateRawMemory(const size_t requested_size, | 200 Address CodeRange::AllocateRawMemory(const size_t requested_size, |
| 201 const size_t commit_size, | 201 const size_t commit_size, |
| 202 size_t* allocated) { | 202 size_t* allocated) { |
| 203 ASSERT(commit_size <= requested_size); | 203 ASSERT(commit_size <= requested_size); |
| 204 ASSERT(current_allocation_block_index_ < allocation_list_.length()); | 204 ASSERT(current_allocation_block_index_ < allocation_list_.length()); |
| 205 if (requested_size > allocation_list_[current_allocation_block_index_].size) { | 205 if (requested_size > allocation_list_[current_allocation_block_index_].size) { |
| 206 // Find an allocation block large enough. This function call may | 206 // Find an allocation block large enough. |
| 207 // call V8::FatalProcessOutOfMemory if it cannot find a large enough block. | 207 if (!GetNextAllocationBlock(requested_size)) return NULL; |
| 208 GetNextAllocationBlock(requested_size); | |
| 209 } | 208 } |
| 210 // Commit the requested memory at the start of the current allocation block. | 209 // Commit the requested memory at the start of the current allocation block. |
| 211 size_t aligned_requested = RoundUp(requested_size, MemoryChunk::kAlignment); | 210 size_t aligned_requested = RoundUp(requested_size, MemoryChunk::kAlignment); |
| 212 FreeBlock current = allocation_list_[current_allocation_block_index_]; | 211 FreeBlock current = allocation_list_[current_allocation_block_index_]; |
| 213 if (aligned_requested >= (current.size - Page::kPageSize)) { | 212 if (aligned_requested >= (current.size - Page::kPageSize)) { |
| 214 // Don't leave a small free block, useless for a large object or chunk. | 213 // Don't leave a small free block, useless for a large object or chunk. |
| 215 *allocated = current.size; | 214 *allocated = current.size; |
| 216 } else { | 215 } else { |
| 217 *allocated = aligned_requested; | 216 *allocated = aligned_requested; |
| 218 } | 217 } |
| 219 ASSERT(*allocated <= current.size); | 218 ASSERT(*allocated <= current.size); |
| 220 ASSERT(IsAddressAligned(current.start, MemoryChunk::kAlignment)); | 219 ASSERT(IsAddressAligned(current.start, MemoryChunk::kAlignment)); |
| 221 if (!isolate_->memory_allocator()->CommitExecutableMemory(code_range_, | 220 if (!isolate_->memory_allocator()->CommitExecutableMemory(code_range_, |
| 222 current.start, | 221 current.start, |
| 223 commit_size, | 222 commit_size, |
| 224 *allocated)) { | 223 *allocated)) { |
| 225 *allocated = 0; | 224 *allocated = 0; |
| 226 return NULL; | 225 return NULL; |
| 227 } | 226 } |
| 228 allocation_list_[current_allocation_block_index_].start += *allocated; | 227 allocation_list_[current_allocation_block_index_].start += *allocated; |
| 229 allocation_list_[current_allocation_block_index_].size -= *allocated; | 228 allocation_list_[current_allocation_block_index_].size -= *allocated; |
| 230 if (*allocated == current.size) { | 229 if (*allocated == current.size) { |
| 231 GetNextAllocationBlock(0); // This block is used up, get the next one. | 230 // This block is used up, get the next one. |
| 231 if (!GetNextAllocationBlock(0)) return NULL; |
| 232 } | 232 } |
| 233 return current.start; | 233 return current.start; |
| 234 } | 234 } |
| 235 | 235 |
| 236 | 236 |
| 237 bool CodeRange::CommitRawMemory(Address start, size_t length) { | 237 bool CodeRange::CommitRawMemory(Address start, size_t length) { |
| 238 return isolate_->memory_allocator()->CommitMemory(start, length, EXECUTABLE); | 238 return isolate_->memory_allocator()->CommitMemory(start, length, EXECUTABLE); |
| 239 } | 239 } |
| 240 | 240 |
| 241 | 241 |
| (...skipping 2869 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3111 object->ShortPrint(); | 3111 object->ShortPrint(); |
| 3112 PrintF("\n"); | 3112 PrintF("\n"); |
| 3113 } | 3113 } |
| 3114 printf(" --------------------------------------\n"); | 3114 printf(" --------------------------------------\n"); |
| 3115 printf(" Marked: %x, LiveCount: %x\n", mark_size, LiveBytes()); | 3115 printf(" Marked: %x, LiveCount: %x\n", mark_size, LiveBytes()); |
| 3116 } | 3116 } |
| 3117 | 3117 |
| 3118 #endif // DEBUG | 3118 #endif // DEBUG |
| 3119 | 3119 |
| 3120 } } // namespace v8::internal | 3120 } } // namespace v8::internal |
| OLD | NEW |