Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(150)

Side by Side Diff: src/spaces.cc

Issue 7247002: Estimate a (close) upper bound on the size of black-marked objects on each page. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/gc
Patch Set: Address review comments. Make compile on x64. Created 9 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/spaces.h ('k') | src/spaces-inl.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/spaces.h ('k') | src/spaces-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698