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 |