| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/pages.h" | 5 #include "vm/pages.h" |
| 6 | 6 |
| 7 #include "platform/address_sanitizer.h" | 7 #include "platform/address_sanitizer.h" |
| 8 #include "platform/assert.h" | 8 #include "platform/assert.h" |
| 9 #include "vm/compiler_stats.h" | 9 #include "vm/compiler_stats.h" |
| 10 #include "vm/gc_marker.h" | 10 #include "vm/gc_marker.h" |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 49 DEFINE_FLAG(bool, | 49 DEFINE_FLAG(bool, |
| 50 log_code_drop, | 50 log_code_drop, |
| 51 false, | 51 false, |
| 52 "Emit a log message when pointers to unused code are dropped."); | 52 "Emit a log message when pointers to unused code are dropped."); |
| 53 DEFINE_FLAG(bool, | 53 DEFINE_FLAG(bool, |
| 54 always_drop_code, | 54 always_drop_code, |
| 55 false, | 55 false, |
| 56 "Always try to drop code if the function's usage counter is >= 0"); | 56 "Always try to drop code if the function's usage counter is >= 0"); |
| 57 DEFINE_FLAG(bool, log_growth, false, "Log PageSpace growth policy decisions."); | 57 DEFINE_FLAG(bool, log_growth, false, "Log PageSpace growth policy decisions."); |
| 58 | 58 |
| 59 HeapPage* HeapPage::Initialize(VirtualMemory* memory, PageType type) { | 59 HeapPage* HeapPage::Initialize(VirtualMemory* memory, |
| 60 PageType type, |
| 61 const char* name) { |
| 60 ASSERT(memory != NULL); | 62 ASSERT(memory != NULL); |
| 61 ASSERT(memory->size() > VirtualMemory::PageSize()); | 63 ASSERT(memory->size() > VirtualMemory::PageSize()); |
| 62 bool is_executable = (type == kExecutable); | 64 bool is_executable = (type == kExecutable); |
| 63 // Create the new page executable (RWX) only if we're not in W^X mode | 65 // Create the new page executable (RWX) only if we're not in W^X mode |
| 64 bool create_executable = !FLAG_write_protect_code && is_executable; | 66 bool create_executable = !FLAG_write_protect_code && is_executable; |
| 65 if (!memory->Commit(create_executable)) { | 67 if (!memory->Commit(create_executable, name)) { |
| 66 return NULL; | 68 return NULL; |
| 67 } | 69 } |
| 68 HeapPage* result = reinterpret_cast<HeapPage*>(memory->address()); | 70 HeapPage* result = reinterpret_cast<HeapPage*>(memory->address()); |
| 69 ASSERT(result != NULL); | 71 ASSERT(result != NULL); |
| 70 result->memory_ = memory; | 72 result->memory_ = memory; |
| 71 result->next_ = NULL; | 73 result->next_ = NULL; |
| 72 result->type_ = type; | 74 result->type_ = type; |
| 73 | 75 |
| 74 LSAN_REGISTER_ROOT_REGION(result, sizeof(*result)); | 76 LSAN_REGISTER_ROOT_REGION(result, sizeof(*result)); |
| 75 | 77 |
| 76 return result; | 78 return result; |
| 77 } | 79 } |
| 78 | 80 |
| 79 | 81 |
| 80 HeapPage* HeapPage::Allocate(intptr_t size_in_words, PageType type) { | 82 HeapPage* HeapPage::Allocate(intptr_t size_in_words, |
| 83 PageType type, |
| 84 const char* name) { |
| 81 VirtualMemory* memory = | 85 VirtualMemory* memory = |
| 82 VirtualMemory::Reserve(size_in_words << kWordSizeLog2); | 86 VirtualMemory::Reserve(size_in_words << kWordSizeLog2); |
| 83 if (memory == NULL) { | 87 if (memory == NULL) { |
| 84 return NULL; | 88 return NULL; |
| 85 } | 89 } |
| 86 HeapPage* result = Initialize(memory, type); | 90 HeapPage* result = Initialize(memory, type, name); |
| 87 if (result == NULL) { | 91 if (result == NULL) { |
| 88 delete memory; // Release reservation to OS. | 92 delete memory; // Release reservation to OS. |
| 89 return NULL; | 93 return NULL; |
| 90 } | 94 } |
| 91 return result; | 95 return result; |
| 92 } | 96 } |
| 93 | 97 |
| 94 | 98 |
| 95 void HeapPage::Deallocate() { | 99 void HeapPage::Deallocate() { |
| 96 bool image_page = is_image_page(); | 100 bool image_page = is_image_page(); |
| (...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 221 | 225 |
| 222 | 226 |
| 223 intptr_t PageSpace::LargePageSizeInWordsFor(intptr_t size) { | 227 intptr_t PageSpace::LargePageSizeInWordsFor(intptr_t size) { |
| 224 intptr_t page_size = Utils::RoundUp(size + HeapPage::ObjectStartOffset(), | 228 intptr_t page_size = Utils::RoundUp(size + HeapPage::ObjectStartOffset(), |
| 225 VirtualMemory::PageSize()); | 229 VirtualMemory::PageSize()); |
| 226 return page_size >> kWordSizeLog2; | 230 return page_size >> kWordSizeLog2; |
| 227 } | 231 } |
| 228 | 232 |
| 229 | 233 |
| 230 HeapPage* PageSpace::AllocatePage(HeapPage::PageType type) { | 234 HeapPage* PageSpace::AllocatePage(HeapPage::PageType type) { |
| 231 HeapPage* page = HeapPage::Allocate(kPageSizeInWords, type); | 235 const bool is_exec = (type == HeapPage::kExecutable); |
| 236 const intptr_t kVmNameSize = 128; |
| 237 char vm_name[kVmNameSize]; |
| 238 Heap::RegionName(heap_, is_exec ? Heap::kCode : Heap::kOld, vm_name, |
| 239 kVmNameSize); |
| 240 HeapPage* page = HeapPage::Allocate(kPageSizeInWords, type, vm_name); |
| 232 if (page == NULL) { | 241 if (page == NULL) { |
| 233 return NULL; | 242 return NULL; |
| 234 } | 243 } |
| 235 | 244 |
| 236 bool is_exec = (type == HeapPage::kExecutable); | |
| 237 | |
| 238 MutexLocker ml(pages_lock_); | 245 MutexLocker ml(pages_lock_); |
| 239 if (!is_exec) { | 246 if (!is_exec) { |
| 240 if (pages_ == NULL) { | 247 if (pages_ == NULL) { |
| 241 pages_ = page; | 248 pages_ = page; |
| 242 } else { | 249 } else { |
| 243 pages_tail_->set_next(page); | 250 pages_tail_->set_next(page); |
| 244 } | 251 } |
| 245 pages_tail_ = page; | 252 pages_tail_ = page; |
| 246 } else { | 253 } else { |
| 247 // Should not allocate executable pages when running from a precompiled | 254 // Should not allocate executable pages when running from a precompiled |
| (...skipping 13 matching lines...) Expand all Loading... |
| 261 } | 268 } |
| 262 exec_pages_tail_ = page; | 269 exec_pages_tail_ = page; |
| 263 } | 270 } |
| 264 IncreaseCapacityInWordsLocked(kPageSizeInWords); | 271 IncreaseCapacityInWordsLocked(kPageSizeInWords); |
| 265 page->set_object_end(page->memory_->end()); | 272 page->set_object_end(page->memory_->end()); |
| 266 return page; | 273 return page; |
| 267 } | 274 } |
| 268 | 275 |
| 269 | 276 |
| 270 HeapPage* PageSpace::AllocateLargePage(intptr_t size, HeapPage::PageType type) { | 277 HeapPage* PageSpace::AllocateLargePage(intptr_t size, HeapPage::PageType type) { |
| 271 intptr_t page_size_in_words = LargePageSizeInWordsFor(size); | 278 const bool is_exec = (type == HeapPage::kExecutable); |
| 272 HeapPage* page = HeapPage::Allocate(page_size_in_words, type); | 279 const intptr_t page_size_in_words = LargePageSizeInWordsFor(size); |
| 280 const intptr_t kVmNameSize = 128; |
| 281 char vm_name[kVmNameSize]; |
| 282 Heap::RegionName(heap_, is_exec ? Heap::kCode : Heap::kOld, vm_name, |
| 283 kVmNameSize); |
| 284 HeapPage* page = HeapPage::Allocate(page_size_in_words, type, vm_name); |
| 273 if (page == NULL) { | 285 if (page == NULL) { |
| 274 return NULL; | 286 return NULL; |
| 275 } | 287 } |
| 276 page->set_next(large_pages_); | 288 page->set_next(large_pages_); |
| 277 large_pages_ = page; | 289 large_pages_ = page; |
| 278 IncreaseCapacityInWords(page_size_in_words); | 290 IncreaseCapacityInWords(page_size_in_words); |
| 279 // Only one object in this page (at least until String::MakeExternal or | 291 // Only one object in this page (at least until String::MakeExternal or |
| 280 // Array::MakeArray is called). | 292 // Array::MakeArray is called). |
| 281 page->set_object_end(page->object_start() + size); | 293 page->set_object_end(page->object_start() + size); |
| 282 return page; | 294 return page; |
| (...skipping 1024 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1307 return 0; | 1319 return 0; |
| 1308 } else { | 1320 } else { |
| 1309 ASSERT(total_time >= gc_time); | 1321 ASSERT(total_time >= gc_time); |
| 1310 int result = static_cast<int>( | 1322 int result = static_cast<int>( |
| 1311 (static_cast<double>(gc_time) / static_cast<double>(total_time)) * 100); | 1323 (static_cast<double>(gc_time) / static_cast<double>(total_time)) * 100); |
| 1312 return result; | 1324 return result; |
| 1313 } | 1325 } |
| 1314 } | 1326 } |
| 1315 | 1327 |
| 1316 } // namespace dart | 1328 } // namespace dart |
| OLD | NEW |