| 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 418 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 429 Executability executable, | 429 Executability executable, |
| 430 Space* owner) { | 430 Space* owner) { |
| 431 MemoryChunk* chunk = FromAddress(base); | 431 MemoryChunk* chunk = FromAddress(base); |
| 432 | 432 |
| 433 ASSERT(base == chunk->address()); | 433 ASSERT(base == chunk->address()); |
| 434 | 434 |
| 435 chunk->heap_ = heap; | 435 chunk->heap_ = heap; |
| 436 chunk->size_ = size; | 436 chunk->size_ = size; |
| 437 chunk->flags_ = 0; | 437 chunk->flags_ = 0; |
| 438 chunk->set_owner(owner); | 438 chunk->set_owner(owner); |
| 439 chunk->markbits()->Clear(); | 439 Bitmap::Clear(chunk); |
| 440 chunk->initialize_scan_on_scavenge(false); | 440 chunk->initialize_scan_on_scavenge(false); |
| 441 |
| 441 ASSERT(OFFSET_OF(MemoryChunk, flags_) == kFlagsOffset); | 442 ASSERT(OFFSET_OF(MemoryChunk, flags_) == kFlagsOffset); |
| 442 | 443 |
| 443 if (executable == EXECUTABLE) chunk->SetFlag(IS_EXECUTABLE); | 444 if (executable == EXECUTABLE) chunk->SetFlag(IS_EXECUTABLE); |
| 444 | 445 |
| 445 if (owner == heap->old_data_space()) chunk->SetFlag(CONTAINS_ONLY_DATA); | 446 if (owner == heap->old_data_space()) chunk->SetFlag(CONTAINS_ONLY_DATA); |
| 446 | 447 |
| 447 return chunk; | 448 return chunk; |
| 448 } | 449 } |
| 449 | 450 |
| 450 | 451 |
| (...skipping 346 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 797 while (page_iterator.has_next()) { | 798 while (page_iterator.has_next()) { |
| 798 Page* page = page_iterator.next(); | 799 Page* page = page_iterator.next(); |
| 799 ASSERT(page->owner() == this); | 800 ASSERT(page->owner() == this); |
| 800 if (page == Page::FromAllocationTop(allocation_info_.top)) { | 801 if (page == Page::FromAllocationTop(allocation_info_.top)) { |
| 801 allocation_pointer_found_in_space = true; | 802 allocation_pointer_found_in_space = true; |
| 802 } | 803 } |
| 803 ASSERT(!page->IsFlagSet(MemoryChunk::WAS_SWEPT_CONSERVATIVELY)); | 804 ASSERT(!page->IsFlagSet(MemoryChunk::WAS_SWEPT_CONSERVATIVELY)); |
| 804 HeapObjectIterator it(page, NULL); | 805 HeapObjectIterator it(page, NULL); |
| 805 Address end_of_previous_object = page->ObjectAreaStart(); | 806 Address end_of_previous_object = page->ObjectAreaStart(); |
| 806 Address top = page->ObjectAreaEnd(); | 807 Address top = page->ObjectAreaEnd(); |
| 808 int black_size = 0; |
| 807 for (HeapObject* object = it.Next(); object != NULL; object = it.Next()) { | 809 for (HeapObject* object = it.Next(); object != NULL; object = it.Next()) { |
| 808 ASSERT(end_of_previous_object <= object->address()); | 810 ASSERT(end_of_previous_object <= object->address()); |
| 809 | 811 |
| 810 // The first word should be a map, and we expect all map pointers to | 812 // The first word should be a map, and we expect all map pointers to |
| 811 // be in map space. | 813 // be in map space. |
| 812 Map* map = object->map(); | 814 Map* map = object->map(); |
| 813 ASSERT(map->IsMap()); | 815 ASSERT(map->IsMap()); |
| 814 ASSERT(heap()->map_space()->Contains(map)); | 816 ASSERT(heap()->map_space()->Contains(map)); |
| 815 | 817 |
| 816 // Perform space-specific object verification. | 818 // Perform space-specific object verification. |
| 817 VerifyObject(object); | 819 VerifyObject(object); |
| 818 | 820 |
| 819 // The object itself should look OK. | 821 // The object itself should look OK. |
| 820 object->Verify(); | 822 object->Verify(); |
| 821 | 823 |
| 822 // All the interior pointers should be contained in the heap. | 824 // All the interior pointers should be contained in the heap. |
| 823 int size = object->Size(); | 825 int size = object->Size(); |
| 824 object->IterateBody(map->instance_type(), size, visitor); | 826 object->IterateBody(map->instance_type(), size, visitor); |
| 827 if (Marking::IsBlack(Marking::MarkBitFrom(object))) { |
| 828 black_size += size; |
| 829 } |
| 825 | 830 |
| 826 ASSERT(object->address() + size <= top); | 831 ASSERT(object->address() + size <= top); |
| 827 end_of_previous_object = object->address() + size; | 832 end_of_previous_object = object->address() + size; |
| 828 } | 833 } |
| 834 CHECK_LE(black_size, page->LiveBytes()); |
| 829 } | 835 } |
| 830 } | 836 } |
| 831 #endif | 837 #endif |
| 832 | 838 |
| 833 | 839 |
| 834 // ----------------------------------------------------------------------------- | 840 // ----------------------------------------------------------------------------- |
| 835 // NewSpace implementation | 841 // NewSpace implementation |
| 836 | 842 |
| 837 | 843 |
| 838 bool NewSpace::Setup(int maximum_semispace_capacity) { | 844 bool NewSpace::Setup(int maximum_semispace_capacity) { |
| (...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1003 } | 1009 } |
| 1004 | 1010 |
| 1005 | 1011 |
| 1006 void NewSpace::ResetAllocationInfo() { | 1012 void NewSpace::ResetAllocationInfo() { |
| 1007 to_space_.Reset(); | 1013 to_space_.Reset(); |
| 1008 UpdateAllocationInfo(); | 1014 UpdateAllocationInfo(); |
| 1009 pages_used_ = 0; | 1015 pages_used_ = 0; |
| 1010 // Clear all mark-bits in the to-space. | 1016 // Clear all mark-bits in the to-space. |
| 1011 NewSpacePageIterator it(&to_space_); | 1017 NewSpacePageIterator it(&to_space_); |
| 1012 while (it.has_next()) { | 1018 while (it.has_next()) { |
| 1013 NewSpacePage* page = it.next(); | 1019 Bitmap::Clear(it.next()); |
| 1014 page->markbits()->Clear(); | |
| 1015 } | 1020 } |
| 1016 } | 1021 } |
| 1017 | 1022 |
| 1018 | 1023 |
| 1019 bool NewSpace::AddFreshPage() { | 1024 bool NewSpace::AddFreshPage() { |
| 1020 Address top = allocation_info_.top; | 1025 Address top = allocation_info_.top; |
| 1021 if (NewSpacePage::IsAtStart(top)) { | 1026 if (NewSpacePage::IsAtStart(top)) { |
| 1022 // The current page is already empty. Don't try to make another. | 1027 // The current page is already empty. Don't try to make another. |
| 1023 | 1028 |
| 1024 // We should only get here if someone asks to allocate more | 1029 // We should only get here if someone asks to allocate more |
| (...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1196 } | 1201 } |
| 1197 capacity_ = new_capacity; | 1202 capacity_ = new_capacity; |
| 1198 NewSpacePage* last_page = anchor()->prev_page(); | 1203 NewSpacePage* last_page = anchor()->prev_page(); |
| 1199 ASSERT(last_page != anchor()); | 1204 ASSERT(last_page != anchor()); |
| 1200 for (int i = pages_before + 1; i <= pages_after; i++) { | 1205 for (int i = pages_before + 1; i <= pages_after; i++) { |
| 1201 Address page_address = end - i * Page::kPageSize; | 1206 Address page_address = end - i * Page::kPageSize; |
| 1202 NewSpacePage* new_page = NewSpacePage::Initialize(heap(), | 1207 NewSpacePage* new_page = NewSpacePage::Initialize(heap(), |
| 1203 page_address, | 1208 page_address, |
| 1204 this); | 1209 this); |
| 1205 new_page->InsertAfter(last_page); | 1210 new_page->InsertAfter(last_page); |
| 1206 new_page->markbits()->Clear(); | 1211 Bitmap::Clear(new_page); |
| 1207 // Duplicate the flags that was set on the old page. | 1212 // Duplicate the flags that was set on the old page. |
| 1208 new_page->SetFlags(last_page->GetFlags(), | 1213 new_page->SetFlags(last_page->GetFlags(), |
| 1209 NewSpacePage::kCopyOnFlipFlagsMask); | 1214 NewSpacePage::kCopyOnFlipFlagsMask); |
| 1210 last_page = new_page; | 1215 last_page = new_page; |
| 1211 } | 1216 } |
| 1212 return true; | 1217 return true; |
| 1213 } | 1218 } |
| 1214 | 1219 |
| 1215 | 1220 |
| 1216 bool SemiSpace::ShrinkTo(int new_capacity) { | 1221 bool SemiSpace::ShrinkTo(int new_capacity) { |
| (...skipping 30 matching lines...) Expand all Loading... |
| 1247 bool becomes_to_space = (id_ == kFromSpace); | 1252 bool becomes_to_space = (id_ == kFromSpace); |
| 1248 id_ = becomes_to_space ? kToSpace : kFromSpace; | 1253 id_ = becomes_to_space ? kToSpace : kFromSpace; |
| 1249 NewSpacePage* page = anchor_.next_page(); | 1254 NewSpacePage* page = anchor_.next_page(); |
| 1250 while (page != &anchor_) { | 1255 while (page != &anchor_) { |
| 1251 page->set_owner(this); | 1256 page->set_owner(this); |
| 1252 page->SetFlags(flags, mask); | 1257 page->SetFlags(flags, mask); |
| 1253 if (becomes_to_space) { | 1258 if (becomes_to_space) { |
| 1254 page->ClearFlag(MemoryChunk::IN_FROM_SPACE); | 1259 page->ClearFlag(MemoryChunk::IN_FROM_SPACE); |
| 1255 page->SetFlag(MemoryChunk::IN_TO_SPACE); | 1260 page->SetFlag(MemoryChunk::IN_TO_SPACE); |
| 1256 page->ClearFlag(MemoryChunk::NEW_SPACE_BELOW_AGE_MARK); | 1261 page->ClearFlag(MemoryChunk::NEW_SPACE_BELOW_AGE_MARK); |
| 1262 page->ResetLiveBytes(); |
| 1257 } else { | 1263 } else { |
| 1258 page->SetFlag(MemoryChunk::IN_FROM_SPACE); | 1264 page->SetFlag(MemoryChunk::IN_FROM_SPACE); |
| 1259 page->ClearFlag(MemoryChunk::IN_TO_SPACE); | 1265 page->ClearFlag(MemoryChunk::IN_TO_SPACE); |
| 1260 } | 1266 } |
| 1261 ASSERT(page->IsFlagSet(MemoryChunk::SCAN_ON_SCAVENGE)); | 1267 ASSERT(page->IsFlagSet(MemoryChunk::SCAN_ON_SCAVENGE)); |
| 1262 ASSERT(page->IsFlagSet(MemoryChunk::IN_TO_SPACE) || | 1268 ASSERT(page->IsFlagSet(MemoryChunk::IN_TO_SPACE) || |
| 1263 page->IsFlagSet(MemoryChunk::IN_FROM_SPACE)); | 1269 page->IsFlagSet(MemoryChunk::IN_FROM_SPACE)); |
| 1264 page = page->next_page(); | 1270 page = page->next_page(); |
| 1265 } | 1271 } |
| 1266 } | 1272 } |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1322 CHECK(page->IsFlagSet(MemoryChunk::POINTERS_TO_HERE_ARE_INTERESTING)); | 1328 CHECK(page->IsFlagSet(MemoryChunk::POINTERS_TO_HERE_ARE_INTERESTING)); |
| 1323 if (!is_from_space) { | 1329 if (!is_from_space) { |
| 1324 // The pointers-from-here-are-interesting flag isn't updated dynamically | 1330 // The pointers-from-here-are-interesting flag isn't updated dynamically |
| 1325 // on from-space pages, so it might be out of sync with the marking state. | 1331 // on from-space pages, so it might be out of sync with the marking state. |
| 1326 if (page->heap()->incremental_marking()->IsMarking()) { | 1332 if (page->heap()->incremental_marking()->IsMarking()) { |
| 1327 CHECK(page->IsFlagSet(MemoryChunk::POINTERS_FROM_HERE_ARE_INTERESTING)); | 1333 CHECK(page->IsFlagSet(MemoryChunk::POINTERS_FROM_HERE_ARE_INTERESTING)); |
| 1328 } else { | 1334 } else { |
| 1329 CHECK(!page->IsFlagSet( | 1335 CHECK(!page->IsFlagSet( |
| 1330 MemoryChunk::POINTERS_FROM_HERE_ARE_INTERESTING)); | 1336 MemoryChunk::POINTERS_FROM_HERE_ARE_INTERESTING)); |
| 1331 } | 1337 } |
| 1338 // TODO(gc): Check that the live_bytes_count_ field matches the |
| 1339 // black marking on the page (if we make it match in new-space). |
| 1332 } | 1340 } |
| 1333 CHECK(page->IsFlagSet(MemoryChunk::SCAN_ON_SCAVENGE)); | 1341 CHECK(page->IsFlagSet(MemoryChunk::SCAN_ON_SCAVENGE)); |
| 1334 CHECK(page->prev_page()->next_page() == page); | 1342 CHECK(page->prev_page()->next_page() == page); |
| 1335 page = page->next_page(); | 1343 page = page->next_page(); |
| 1336 } | 1344 } |
| 1337 } | 1345 } |
| 1338 | 1346 |
| 1339 | 1347 |
| 1340 void SemiSpace::AssertValidRange(Address start, Address end) { | 1348 void SemiSpace::AssertValidRange(Address start, Address end) { |
| 1341 // Addresses belong to same semi-space | 1349 // Addresses belong to same semi-space |
| (...skipping 1025 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2367 LargePage* previous = NULL; | 2375 LargePage* previous = NULL; |
| 2368 LargePage* current = first_page_; | 2376 LargePage* current = first_page_; |
| 2369 while (current != NULL) { | 2377 while (current != NULL) { |
| 2370 HeapObject* object = current->GetObject(); | 2378 HeapObject* object = current->GetObject(); |
| 2371 // Can this large page contain pointers to non-trivial objects. No other | 2379 // Can this large page contain pointers to non-trivial objects. No other |
| 2372 // pointer object is this big. | 2380 // pointer object is this big. |
| 2373 bool is_pointer_object = object->IsFixedArray(); | 2381 bool is_pointer_object = object->IsFixedArray(); |
| 2374 MarkBit mark_bit = Marking::MarkBitFrom(object); | 2382 MarkBit mark_bit = Marking::MarkBitFrom(object); |
| 2375 if (mark_bit.Get()) { | 2383 if (mark_bit.Get()) { |
| 2376 mark_bit.Clear(); | 2384 mark_bit.Clear(); |
| 2385 MemoryChunk::IncrementLiveBytes(object->address(), -object->Size()); |
| 2377 previous = current; | 2386 previous = current; |
| 2378 current = current->next_page(); | 2387 current = current->next_page(); |
| 2379 } else { | 2388 } else { |
| 2380 LargePage* page = current; | 2389 LargePage* page = current; |
| 2381 // Cut the chunk out from the chunk list. | 2390 // Cut the chunk out from the chunk list. |
| 2382 current = current->next_page(); | 2391 current = current->next_page(); |
| 2383 if (previous == NULL) { | 2392 if (previous == NULL) { |
| 2384 first_page_ = current; | 2393 first_page_ = current; |
| 2385 } else { | 2394 } else { |
| 2386 previous->set_next_page(current); | 2395 previous->set_next_page(current); |
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2497 for (HeapObject* obj = obj_it.Next(); obj != NULL; obj = obj_it.Next()) { | 2506 for (HeapObject* obj = obj_it.Next(); obj != NULL; obj = obj_it.Next()) { |
| 2498 if (obj->IsCode()) { | 2507 if (obj->IsCode()) { |
| 2499 Code* code = Code::cast(obj); | 2508 Code* code = Code::cast(obj); |
| 2500 isolate->code_kind_statistics()[code->kind()] += code->Size(); | 2509 isolate->code_kind_statistics()[code->kind()] += code->Size(); |
| 2501 } | 2510 } |
| 2502 } | 2511 } |
| 2503 } | 2512 } |
| 2504 #endif // DEBUG | 2513 #endif // DEBUG |
| 2505 | 2514 |
| 2506 } } // namespace v8::internal | 2515 } } // namespace v8::internal |
| OLD | NEW |